Skip to content

Commit

Permalink
Add the ability to distinguish map key violations (#55)
Browse files Browse the repository at this point in the history
Example output from running new conformance tests against current
protovalidate-go:

![image](https://github.com/bufbuild/protovalidate/assets/4567082/431c9aa4-eefc-4ced-952f-ccd18a4bdc7b)
  • Loading branch information
Alfus authored Jul 20, 2023
1 parent 216bb61 commit e7350f1
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 22 deletions.
3 changes: 3 additions & 0 deletions proto/protovalidate/buf/validate/expression.proto
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,7 @@ message Violation {
// `message` is a human-readable error message that describes the nature of the violation.
// This can be the default error message from the violated `Constraint`, or it can be a custom message that gives more context about the violation.
string message = 3;

// `for_key` indicates whether the violation was caused by a map key, rather than a value.
bool for_key = 4;
}
51 changes: 31 additions & 20 deletions tools/internal/gen/buf/validate/expression.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions tools/protovalidate-conformance/internal/cases/cases_map.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ func mapSuite() suites.Suite {
FieldPath: "val[1]",
ConstraintId: "sint64.lt",
Message: "value must be less than 0",
ForKey: true,
},
),
},
Expand All @@ -148,6 +149,7 @@ func mapSuite() suites.Suite {
FieldPath: "val[\"!@#$%^&*()\"]",
ConstraintId: "string.pattern",
Message: "value does not match regex pattern `(?i)^[a-z0-9]+$`",
ForKey: true,
},
),
},
Expand Down
8 changes: 6 additions & 2 deletions tools/protovalidate-conformance/internal/results/result.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,11 @@ func (v violationsResult) String() string {
errs := v.inner.GetValidationError().GetViolations()
_, _ = fmt.Fprintf(bldr, "%d validation error(s)", len(errs))
for i, err := range errs {
_, _ = fmt.Fprintf(bldr, "\n%s %2d. %s: %s", resultPadding, i+1, err.FieldPath, err.ConstraintId)
forKey := ""
if err.ForKey {
forKey = " (key)"
}
_, _ = fmt.Fprintf(bldr, "\n%s %2d. %s%s: %s", resultPadding, i+1, err.FieldPath, forKey, err.ConstraintId)
_, _ = fmt.Fprintf(bldr, "\n%s %s", resultPadding, err.Message)
}
return bldr.String()
Expand All @@ -128,7 +132,7 @@ func (v violationsResult) IsSuccessWith(other Result, options *harness.ResultOpt
return false
}
for i := 0; i < len(want); i++ {
matchingField := want[i].FieldPath == got[i].FieldPath
matchingField := want[i].FieldPath == got[i].FieldPath && want[i].ForKey == got[i].ForKey
matchingConstraint := want[i].ConstraintId == got[i].ConstraintId
if !matchingField || !matchingConstraint {
return false
Expand Down

0 comments on commit e7350f1

Please sign in to comment.