Skip to content

Commit

Permalink
setter.go,main_test.go: Relax oneof validation on set
Browse files Browse the repository at this point in the history
  • Loading branch information
adriansmares committed Mar 28, 2022
1 parent 2b5cd3f commit e06448e
Show file tree
Hide file tree
Showing 3 changed files with 284 additions and 86 deletions.
244 changes: 238 additions & 6 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"time"

"github.com/TheThingsIndustries/protoc-gen-fieldmask/testdata"
"github.com/gogo/protobuf/types"
"github.com/kr/pretty"
"github.com/mohae/deepcopy"
"github.com/smartystreets/assertions"
Expand Down Expand Up @@ -490,12 +491,29 @@ var setFieldsTestCases = []struct {
},
Paths: []string{"testOneof.d"},
Result: &testdata.Test{
TestOneof: &testdata.Test_CustomNameOneof{
CustomNameOneof: 42,
TestOneof: &testdata.Test_D{
D: 42,
},
G: &testdata.Empty{},
},
},
{
Name: "destination testOneof empty",
Destination: &testdata.Test{
G: &testdata.Empty{},
},
Source: &testdata.Test{
TestOneof: &testdata.Test_D{
D: 42,
},
},
Paths: []string{"testOneof.d"},
Result: &testdata.Test{
TestOneof: &testdata.Test_D{
D: 42,
},
G: &testdata.Empty{},
},
ErrorAssertion: func(t *testing.T, err error) bool { return assertions.New(t).So(err, should.BeError) },
},
{
Name: "source testOneof mismatch",
Expand All @@ -512,12 +530,48 @@ var setFieldsTestCases = []struct {
},
Paths: []string{"testOneof.d"},
Result: &testdata.Test{
TestOneof: &testdata.Test_D{
D: 42,
G: &testdata.Empty{},
},
},
{
Name: "source testOneof empty",
Destination: &testdata.Test{
G: &testdata.Empty{},
},
Source: &testdata.Test{},
Paths: []string{"testOneof.d"},
Result: &testdata.Test{
G: &testdata.Empty{},
},
},
{
Name: "source+destination testOneof mismatch",
Destination: &testdata.Test{
TestOneof: &testdata.Test_F{
F: []byte{0x42},
},
G: &testdata.Empty{},
},
ErrorAssertion: func(t *testing.T, err error) bool { return assertions.New(t).So(err, should.BeError) },
Source: &testdata.Test{
TestOneof: &testdata.Test_CustomNameOneof{
CustomNameOneof: 42,
},
},
Paths: []string{"testOneof.d"},
Result: &testdata.Test{
G: &testdata.Empty{},
},
},
{
Name: "source+destination testOneof empty",
Destination: &testdata.Test{
G: &testdata.Empty{},
},
Source: &testdata.Test{},
Paths: []string{"testOneof.d"},
Result: &testdata.Test{
G: &testdata.Empty{},
},
},
{
Name: "unset testOneof",
Expand Down Expand Up @@ -567,6 +621,184 @@ var setFieldsTestCases = []struct {
},
},
},
{
Name: "source testOneof.k.a.testNestedNestedOneOf.g mismatch",
Destination: &testdata.Test{},
Source: &testdata.Test{
TestOneof: &testdata.Test_K{
K: &testdata.Test_TestNested{
A: &testdata.Test_TestNested_TestNestedNested{
TestNestedNestedOneOf: &testdata.Test_TestNested_TestNestedNested_F{
F: 42,
},
},
},
},
},
Paths: []string{"testOneof.k.a.testNestedNestedOneOf.g"},
Result: &testdata.Test{
TestOneof: &testdata.Test_K{
K: &testdata.Test_TestNested{
A: &testdata.Test_TestNested_TestNestedNested{},
},
},
},
},
{
Name: "source testOneof.k.a.testNestedNestedOneOf.g empty",
Destination: &testdata.Test{},
Source: &testdata.Test{
TestOneof: &testdata.Test_K{
K: &testdata.Test_TestNested{
A: &testdata.Test_TestNested_TestNestedNested{},
},
},
},
Paths: []string{"testOneof.k.a.testNestedNestedOneOf.g"},
Result: &testdata.Test{
TestOneof: &testdata.Test_K{
K: &testdata.Test_TestNested{
A: &testdata.Test_TestNested_TestNestedNested{},
},
},
},
},
{
Name: "destination testOneof.k.a.testNestedNestedOneOf.g mismatch",
Destination: &testdata.Test{
TestOneof: &testdata.Test_K{
K: &testdata.Test_TestNested{
A: &testdata.Test_TestNested_TestNestedNested{
TestNestedNestedOneOf: &testdata.Test_TestNested_TestNestedNested_F{
F: 42,
},
},
},
},
},
Source: &testdata.Test{
TestOneof: &testdata.Test_K{
K: &testdata.Test_TestNested{
A: &testdata.Test_TestNested_TestNestedNested{
TestNestedNestedOneOf: &testdata.Test_TestNested_TestNestedNested_G{
G: &types.UInt64Value{
Value: 42,
},
},
},
},
},
},
Paths: []string{"testOneof.k.a.testNestedNestedOneOf.g"},
Result: &testdata.Test{
TestOneof: &testdata.Test_K{
K: &testdata.Test_TestNested{
A: &testdata.Test_TestNested_TestNestedNested{
TestNestedNestedOneOf: &testdata.Test_TestNested_TestNestedNested_G{
G: &types.UInt64Value{
Value: 42,
},
},
},
},
},
},
},
{
Name: "destination testOneof.k.a.testNestedNestedOneOf.g empty",
Destination: &testdata.Test{
TestOneof: &testdata.Test_K{
K: &testdata.Test_TestNested{
A: &testdata.Test_TestNested_TestNestedNested{},
},
},
},
Source: &testdata.Test{
TestOneof: &testdata.Test_K{
K: &testdata.Test_TestNested{
A: &testdata.Test_TestNested_TestNestedNested{
TestNestedNestedOneOf: &testdata.Test_TestNested_TestNestedNested_G{
G: &types.UInt64Value{
Value: 42,
},
},
},
},
},
},
Paths: []string{"testOneof.k.a.testNestedNestedOneOf.g"},
Result: &testdata.Test{
TestOneof: &testdata.Test_K{
K: &testdata.Test_TestNested{
A: &testdata.Test_TestNested_TestNestedNested{
TestNestedNestedOneOf: &testdata.Test_TestNested_TestNestedNested_G{
G: &types.UInt64Value{
Value: 42,
},
},
},
},
},
},
},
{
Name: "source+destination testOneof.k.a.testNestedNestedOneOf.g mismatch",
Destination: &testdata.Test{
TestOneof: &testdata.Test_K{
K: &testdata.Test_TestNested{
A: &testdata.Test_TestNested_TestNestedNested{
TestNestedNestedOneOf: &testdata.Test_TestNested_TestNestedNested_F{
F: 42,
},
},
},
},
},
Source: &testdata.Test{
TestOneof: &testdata.Test_K{
K: &testdata.Test_TestNested{
A: &testdata.Test_TestNested_TestNestedNested{
TestNestedNestedOneOf: &testdata.Test_TestNested_TestNestedNested_E{
E: &testdata.Empty{},
},
},
},
},
},
Paths: []string{"testOneof.k.a.testNestedNestedOneOf.g"},
Result: &testdata.Test{
TestOneof: &testdata.Test_K{
K: &testdata.Test_TestNested{
A: &testdata.Test_TestNested_TestNestedNested{},
},
},
},
},
{
Name: "source+destination testOneof.k.a.testNestedNestedOneOf.g empty",
Destination: &testdata.Test{
TestOneof: &testdata.Test_K{
K: &testdata.Test_TestNested{
A: &testdata.Test_TestNested_TestNestedNested{},
},
},
},
Source: &testdata.Test{
TestOneof: &testdata.Test_K{
K: &testdata.Test_TestNested{
A: &testdata.Test_TestNested_TestNestedNested{},
},
},
},
Paths: []string{"testOneof.k.a.testNestedNestedOneOf.g"},
Result: &testdata.Test{
TestOneof: &testdata.Test_K{
K: &testdata.Test_TestNested{
A: &testdata.Test_TestNested_TestNestedNested{},
},
},
},
},
{
Name: "non-nullable c.a",
Destination: &testdata.Test{
Expand Down
41 changes: 21 additions & 20 deletions module/setter.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,10 @@ func (m *setterModule) buildSetFieldsCase(buf *strings.Builder, imports importMa

if f.InOneOf() {
buildIndented(buf, tabCount+1, fmt.Sprintf(`_, srcOk := src.%s.(*%s)
if !srcOk && src.%s != nil {
return fmt.Errorf("attempt to set oneof '%s', while different oneof is set in source")
}
_, dstOk := dst.%s.(*%s)
if !dstOk && dst.%s != nil {
return fmt.Errorf("attempt to set oneof '%s', while different oneof is set in destination")
}`,
m.ctx.Name(f.OneOf()), m.ctx.OneofOption(f), m.ctx.Name(f.OneOf()),
f.Name(),
_ = dstOk`,
m.ctx.Name(f.OneOf()), m.ctx.OneofOption(f),
m.ctx.Name(f.OneOf()), m.ctx.OneofOption(f),
m.ctx.Name(f.OneOf()),
f.Name(),
))
}

Expand All @@ -70,11 +62,19 @@ if !dstOk && dst.%s != nil {
fPath = m.ctx.Name(f.OneOf()).String()
}

buildIndented(buf, tabCount, fmt.Sprintf(`if src != nil {
if f.InOneOf() {
buildIndented(buf, tabCount, fmt.Sprintf(`if srcOk {
dst.%s = src.%s
} else {`,
fPath, fPath,
))
} else {
buildIndented(buf, tabCount, fmt.Sprintf(`if src != nil {
dst.%s = src.%s
} else {`,
fPath, fPath,
))
fPath, fPath,
))
}

if goType.IsPointer() {
buildIndented(buf, tabCount, fmt.Sprintf(` dst.%s = nil
Expand All @@ -91,9 +91,9 @@ if !dstOk && dst.%s != nil {
}

if f.InOneOf() {
buildIndented(buf, tabCount, fmt.Sprintf(` dst.%s = &%s{}
buildIndented(buf, tabCount, fmt.Sprintf(` dst.%s = nil
}`,
fPath, m.ctx.OneofOption(f),
fPath,
))
return nil
}
Expand Down Expand Up @@ -128,22 +128,23 @@ if !dstOk && dst.%s != nil {
switch {
case f.InOneOf():
fPath := fmt.Sprintf("%s.(*%s).%s", m.ctx.Name(f.OneOf()), m.ctx.OneofOption(f), fName)
buildIndented(buf, tabCount+2, fmt.Sprintf(`if !srcOk && !dstOk {
continue
}
if srcOk {
buildIndented(buf, tabCount+2, fmt.Sprintf(`if srcOk {
newSrc = src.%s
}
if dstOk {
newDst = dst.%s
} else {
} else if srcOk {
newDst = &%s{}
dst.%s = &%s{%s: newDst}
} else {
dst.%s = nil
continue
}`,
fPath,
fPath,
goType.Value(),
m.ctx.Name(f.OneOf()), m.ctx.OneofOption(f), fName,
m.ctx.Name(f.OneOf()),
))

case goType.IsPointer():
Expand Down
Loading

0 comments on commit e06448e

Please sign in to comment.