Skip to content

Commit

Permalink
Update oneof required semantics to be exactly one field passes field …
Browse files Browse the repository at this point in the history
…required
  • Loading branch information
oliversun9 committed Nov 1, 2023
1 parent b0c0e8a commit d7fa79e
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ syntax = "proto3";
package buf.validate.conformance.cases;

import "buf/validate/validate.proto";
import "google/protobuf/duration.proto";

message TestOneofMsg {
bool val = 1 [(buf.validate.field).bool.const = true];
Expand Down Expand Up @@ -45,6 +46,7 @@ message OneofRequired {
int32 y = 2;
int32 name_with_underscores = 3;
int32 under_and_1_number = 4;
google.protobuf.Duration duration = 5;
}
}

Expand Down
8 changes: 4 additions & 4 deletions proto/protovalidate/buf/validate/validate.proto
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,12 @@ message MessageConstraints {

// The `OneofConstraints` message type enables you to manage constraints for
// oneof fields in your protobuf messages. Use the `required` constraint to ensure
// that exactly one of the fields within a oneof is set; validation will fail
// if none of the fields in the oneof are set:
// that exactly one of the fields within a oneof is not empty; validation will fail
// if all of the fields in the oneof are empty:
message OneofConstraints {
// `required` is an optional boolean attribute that ensures that
// exactly one of the field options in a oneof is set; validation fails if
// no fields in the oneof are set.
// exactly one of the field options in a oneof is not empty; validation fails if
// all fields in the oneof are empty.
//
// ```proto
// message MyMessage {
Expand Down
104 changes: 64 additions & 40 deletions tools/internal/gen/buf/validate/conformance/cases/oneofs.pb.go

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

8 changes: 4 additions & 4 deletions tools/internal/gen/buf/validate/validate.pb.go

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

15 changes: 14 additions & 1 deletion tools/protovalidate-conformance/internal/cases/cases_oneof.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/bufbuild/protovalidate/tools/internal/gen/buf/validate/conformance/cases"
"github.com/bufbuild/protovalidate/tools/protovalidate-conformance/internal/results"
"github.com/bufbuild/protovalidate/tools/protovalidate-conformance/internal/suites"
"google.golang.org/protobuf/types/known/durationpb"
)

func oneofSuite() suites.Suite {
Expand Down Expand Up @@ -59,10 +60,22 @@ func oneofSuite() suites.Suite {
Message: &cases.Oneof{O: &cases.Oneof_Z{Z: &cases.TestOneofMsg{}}},
Expected: results.Violations(&validate.Violation{FieldPath: "z.val", ConstraintId: "bool.const"}),
},
"required/valid": {
"required/valid_scalar": {
Message: &cases.OneofRequired{O: &cases.OneofRequired_X{X: "foo"}},
Expected: results.Success(true),
},
"required/empty_scalar": {
Message: &cases.OneofRequired{O: &cases.OneofRequired_X{X: ""}},
Expected: results.Violations(&validate.Violation{FieldPath: "o", ConstraintId: "required"}),
},
"required/valid_message": {
Message: &cases.OneofRequired{O: &cases.OneofRequired_Duration{Duration: &durationpb.Duration{}}},
Expected: results.Success(true),
},
"required/empty_message": {
Message: &cases.OneofRequired{O: &cases.OneofRequired_Duration{Duration: nil}},
Expected: results.Violations(&validate.Violation{FieldPath: "o", ConstraintId: "required"}),
},
"required/invalid": {
Message: &cases.OneofRequired{},
Expected: results.Violations(&validate.Violation{FieldPath: "o", ConstraintId: "required"}),
Expand Down

0 comments on commit d7fa79e

Please sign in to comment.