Skip to content

Commit

Permalink
[TT-5117] Corrected comparison of nested field values.
Browse files Browse the repository at this point in the history
[changelog]
internal: Field values are deeply compared; added more tests.
  • Loading branch information
David Stutt committed May 3, 2022
1 parent 06e0c87 commit a68d94d
Show file tree
Hide file tree
Showing 2 changed files with 198 additions and 18 deletions.
198 changes: 189 additions & 9 deletions pkg/federation/sdlmerge/remove_duplicate_fielded_value_types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,35 @@ func TestRemoveDuplicateFieldedValueTypes(t *testing.T) {
)
})

t.Run("Identical same name inputs are merged into a single input regardless of field order", func(t *testing.T) {
run(t, newRemoveDuplicateFieldedValueTypesVisitor(), `
input Trainer {
age: Int!
name: String!
}
input Trainer {
name: String!
age: Int!
}
input Trainer {
name: String!
age: Int!
}
`, `
input Trainer {
age: Int!
name: String!
}
`,
)
})

t.Run("Groups of identical same name inputs are respectively merged into single inputs", func(t *testing.T) {
run(t, newRemoveDuplicateFieldedValueTypesVisitor(), `
input Pokemon {
type: Type!
type: [Type!]!
isEvolved: Boolean!
}
Expand All @@ -65,12 +90,12 @@ func TestRemoveDuplicateFieldedValueTypes(t *testing.T) {
}
input Pokemon {
type: Type!
type: [Type!]!
isEvolved: Boolean!
}
`, `
input Pokemon {
type: Type!
type: [Type!]!
isEvolved: Boolean!
}
Expand Down Expand Up @@ -121,6 +146,41 @@ func TestRemoveDuplicateFieldedValueTypes(t *testing.T) {
`, FederatingValueTypeErrorMessage("Trainer"))
})

t.Run("Same name inputs with a slight difference in nested field values return an error", func(t *testing.T) {
runAndExpectError(t, newRemoveDuplicateFieldedValueTypesVisitor(), `
input Pokemon {
type: [[[[Type!]]!]!]!
}
input Pokemon {
type: [[[[Type!]]]!]!
}
input Pokemon {
type: [[[[Type!]]!]!]!
}
`, FederatingValueTypeErrorMessage("Pokemon"))
})

t.Run("Same name inputs with different non-nullable field values return an error", func(t *testing.T) {
runAndExpectError(t, newRemoveDuplicateFieldedValueTypesVisitor(), `
input Trainer {
name: String!
age: Int!
}
input Trainer {
name: String!
age: Int!
}
input Trainer {
name: String!
age: String!
}
`, FederatingValueTypeErrorMessage("Trainer"))
})

t.Run("Same name empty interfaces are merged into a single interface", func(t *testing.T) {
run(t, newRemoveDuplicateFieldedValueTypesVisitor(), `
interface Trainer {
Expand Down Expand Up @@ -160,10 +220,35 @@ func TestRemoveDuplicateFieldedValueTypes(t *testing.T) {
)
})

t.Run("Identical same name interfaces are merged into a single input regardless of field order", func(t *testing.T) {
run(t, newRemoveDuplicateFieldedValueTypesVisitor(), `
interface Trainer {
age: Int!
name: String!
}
interface Trainer {
name: String!
age: Int!
}
interface Trainer {
name: String!
age: Int!
}
`, `
interface Trainer {
age: Int!
name: String!
}
`,
)
})

t.Run("Groups of identical same name interfaces are respectively merged into single interfaces", func(t *testing.T) {
run(t, newRemoveDuplicateFieldedValueTypesVisitor(), `
interface Pokemon {
type: Type!
type: [Type!]!
isEvolved: Boolean!
}
Expand All @@ -183,12 +268,12 @@ func TestRemoveDuplicateFieldedValueTypes(t *testing.T) {
}
interface Pokemon {
type: Type!
type: [Type!]!
isEvolved: Boolean!
}
`, `
interface Pokemon {
type: Type!
type: [Type!]!
isEvolved: Boolean!
}
Expand Down Expand Up @@ -239,6 +324,41 @@ func TestRemoveDuplicateFieldedValueTypes(t *testing.T) {
`, FederatingValueTypeErrorMessage("Trainer"))
})

t.Run("Same name interfaces with a slight difference in nested field values return an error", func(t *testing.T) {
runAndExpectError(t, newRemoveDuplicateFieldedValueTypesVisitor(), `
interface Pokemon {
type: [[[[Type!]]!]!]!
}
interface Pokemon {
type: [[[[Type!]]]!]!
}
interface Pokemon {
type: [[[[Type!]]!]!]!
}
`, FederatingValueTypeErrorMessage("Pokemon"))
})

t.Run("Same name interfaces with different non-nullable field values return an error", func(t *testing.T) {
runAndExpectError(t, newRemoveDuplicateFieldedValueTypesVisitor(), `
interface Trainer {
name: String!
age: Int!
}
interface Trainer {
name: String!
age: Int!
}
interface Trainer {
name: String!
age: String!
}
`, FederatingValueTypeErrorMessage("Trainer"))
})

t.Run("Same name empty objects are merged into a single object", func(t *testing.T) {
run(t, newRemoveDuplicateFieldedValueTypesVisitor(), `
type Trainer {
Expand Down Expand Up @@ -278,10 +398,35 @@ func TestRemoveDuplicateFieldedValueTypes(t *testing.T) {
)
})

t.Run("Identical same name objects are merged into a single input regardless of field order", func(t *testing.T) {
run(t, newRemoveDuplicateFieldedValueTypesVisitor(), `
type Trainer {
age: Int!
name: String!
}
type Trainer {
name: String!
age: Int!
}
type Trainer {
name: String!
age: Int!
}
`, `
type Trainer {
age: Int!
name: String!
}
`,
)
})

t.Run("Groups of identical same name objects are respectively merged into single objects", func(t *testing.T) {
run(t, newRemoveDuplicateFieldedValueTypesVisitor(), `
type Pokemon {
type: Type!
type: [Type!]!
isEvolved: Boolean!
}
Expand All @@ -301,12 +446,12 @@ func TestRemoveDuplicateFieldedValueTypes(t *testing.T) {
}
type Pokemon {
type: Type!
type: [Type!]!
isEvolved: Boolean!
}
`, `
type Pokemon {
type: Type!
type: [Type!]!
isEvolved: Boolean!
}
Expand Down Expand Up @@ -356,4 +501,39 @@ func TestRemoveDuplicateFieldedValueTypes(t *testing.T) {
}
`, FederatingValueTypeErrorMessage("Trainer"))
})

t.Run("Same name objects with a slight difference in nested field values return an error", func(t *testing.T) {
runAndExpectError(t, newRemoveDuplicateFieldedValueTypesVisitor(), `
type Pokemon {
type: [[[[Type!]]!]!]!
}
type Pokemon {
type: [[[[Type!]]]!]!
}
type Pokemon {
type: [[[[Type!]]!]!]!
}
`, FederatingValueTypeErrorMessage("Pokemon"))
})

t.Run("Same name objects with different non-nullable field values return an error", func(t *testing.T) {
runAndExpectError(t, newRemoveDuplicateFieldedValueTypesVisitor(), `
type Trainer {
name: String!
age: Int!
}
type Trainer {
name: String!
age: Int!
}
type Trainer {
name: String!
age: String!
}
`, FederatingValueTypeErrorMessage("Trainer"))
})
}
18 changes: 9 additions & 9 deletions pkg/federation/sdlmerge/sdlmerge.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ type FieldedValueType struct {
document *ast.Document
fieldKind ast.NodeKind
fieldRefs []int
fieldSet map[string]string
fieldSet map[string]int
}

func NewFieldedValueType(document *ast.Document, fieldKind ast.NodeKind, fieldRefs []int) FieldedValueType {
Expand All @@ -127,22 +127,22 @@ func (f FieldedValueType) AreFieldsIdentical(fieldRefsToCompare []int) bool {
}
for _, fieldRef := range fieldRefsToCompare {
actualFieldName := f.fieldName(fieldRef)
expectedTypeName, exists := f.fieldSet[actualFieldName]
expectedTypeRef, exists := f.fieldSet[actualFieldName]
if !exists {
return false
}
actualTypeName := f.fieldTypeName(fieldRef)
if expectedTypeName != actualTypeName {
actualTypeRef := f.fieldTypeRef(fieldRef)
if !f.document.TypesAreCompatibleDeep(expectedTypeRef, actualTypeRef) {
return false
}
}
return true
}

func (f *FieldedValueType) createFieldSet() {
fieldSet := make(map[string]string)
fieldSet := make(map[string]int)
for _, fieldRef := range f.fieldRefs {
fieldSet[f.fieldName(fieldRef)] = f.fieldTypeName(fieldRef)
fieldSet[f.fieldName(fieldRef)] = f.fieldTypeRef(fieldRef)
}
f.fieldSet = fieldSet
}
Expand All @@ -156,13 +156,13 @@ func (f FieldedValueType) fieldName(ref int) string {
}
}

func (f FieldedValueType) fieldTypeName(ref int) string {
func (f FieldedValueType) fieldTypeRef(ref int) int {
document := f.document
switch f.fieldKind {
case ast.NodeKindInputValueDefinition:
return document.TypeNameString(document.InputValueDefinitions[ref].Type)
return document.InputValueDefinitions[ref].Type
default:
return document.TypeNameString(document.FieldDefinitions[ref].Type)
return document.FieldDefinitions[ref].Type
}
}

Expand Down

0 comments on commit a68d94d

Please sign in to comment.