Skip to content

Commit

Permalink
Merge pull request #105 from lucianjon/use_bramble_typename
Browse files Browse the repository at this point in the history
Use `_bramble__typename` alias for bramble injected __typename
  • Loading branch information
Lucian Jones authored Nov 9, 2021
2 parents 0df917f + 60ea308 commit e0e24cc
Show file tree
Hide file tree
Showing 8 changed files with 482 additions and 61 deletions.
57 changes: 30 additions & 27 deletions execution_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,7 @@ func TestFederatedQueryFragmentSpreads(t *testing.T) {
"id": "100",
"name": "foo",
"gizmos": [{ "_bramble_id": "GIZMO1", "id": "GIZMO1" }],
"__typename": "GizmoImplementation"
"_bramble__typename": "GizmoImplementation"
}
}
}`))
Expand All @@ -614,7 +614,7 @@ func TestFederatedQueryFragmentSpreads(t *testing.T) {
"id": "100",
"name": "foo",
"gadgets": [{ "_bramble_id": "GADGET1", "id": "GADGET1" }],
"__typename": "GadgetImplementation"
"_bramble__typename": "GadgetImplementation"
}
}
}`))
Expand Down Expand Up @@ -672,7 +672,7 @@ func TestFederatedQueryFragmentSpreads(t *testing.T) {
{
"name": "James Bond",
"country": "UK",
"__typename": "Agent"
"_bramble__typename": "Agent"
}
]
}
Expand Down Expand Up @@ -1055,7 +1055,7 @@ func TestQueryExecutionNamespaceAndFragmentSpread(t *testing.T) {
"movies": [
{"title": "The Big Blue"}
],
"__typename": "Director"
"_bramble__typename": "Director"
}
}
}
Expand Down Expand Up @@ -2852,9 +2852,9 @@ func TestBubbleUpNullValuesInPlace(t *testing.T) {

resultJSON := `{
"gizmos": [
{ "id": "GIZMO1", "color": "RED", "__typename": "Gizmo" },
{ "id": "GIZMO2", "color": "GREEN", "__typename": "Gizmo" },
{ "id": "GIZMO3", "color": null, "__typename": "Gizmo" }
{ "id": "GIZMO1", "color": "RED", "_bramble__typename": "Gizmo" },
{ "id": "GIZMO2", "color": "GREEN", "_bramble__typename": "Gizmo" },
{ "id": "GIZMO3", "color": null, "_bramble__typename": "Gizmo" }
]
}`

Expand Down Expand Up @@ -2885,7 +2885,7 @@ func TestBubbleUpNullValuesInPlace(t *testing.T) {
Path: ast.Path{ast.PathName("gizmos"), ast.PathIndex(2), ast.PathName("color")},
Extensions: nil,
}}), errs)
require.Equal(t, jsonToInterfaceMap(`{ "gizmos": [ { "id": "GIZMO1", "color": "RED", "__typename": "Gizmo" }, { "id": "GIZMO2", "color": "GREEN", "__typename": "Gizmo" }, null ] }`), result)
require.Equal(t, jsonToInterfaceMap(`{ "gizmos": [ { "id": "GIZMO1", "color": "RED", "_bramble__typename": "Gizmo" }, { "id": "GIZMO2", "color": "GREEN", "_bramble__typename": "Gizmo" }, null ] }`), result)
})

t.Run("works with inline fragments", func(t *testing.T) {
Expand All @@ -2908,9 +2908,9 @@ func TestBubbleUpNullValuesInPlace(t *testing.T) {

resultJSON := `{
"gizmos": [
{ "id": "GIZMO1", "color": "RED", "__typename": "Gizmo" },
{ "id": "GIZMO2", "color": "GREEN", "__typename": "Gizmo" },
{ "id": "GIZMO3", "color": null, "__typename": "Gizmo" }
{ "id": "GIZMO1", "color": "RED", "_bramble__typename": "Gizmo" },
{ "id": "GIZMO2", "color": "GREEN", "_bramble__typename": "Gizmo" },
{ "id": "GIZMO3", "color": null, "_bramble__typename": "Gizmo" }
]
}`

Expand Down Expand Up @@ -2938,7 +2938,7 @@ func TestBubbleUpNullValuesInPlace(t *testing.T) {
Path: ast.Path{ast.PathName("gizmos"), ast.PathIndex(2), ast.PathName("color")},
Extensions: nil,
}}), errs)
require.Equal(t, jsonToInterfaceMap(`{ "gizmos": [ { "id": "GIZMO1", "color": "RED", "__typename": "Gizmo" }, { "id": "GIZMO2", "color": "GREEN", "__typename": "Gizmo" }, null ] }`), result)
require.Equal(t, jsonToInterfaceMap(`{ "gizmos": [ { "id": "GIZMO1", "color": "RED", "_bramble__typename": "Gizmo" }, { "id": "GIZMO2", "color": "GREEN", "_bramble__typename": "Gizmo" }, null ] }`), result)
})

t.Run("inline fragment inside interface", func(t *testing.T) {
Expand All @@ -2963,9 +2963,9 @@ func TestBubbleUpNullValuesInPlace(t *testing.T) {

resultJSON := `{
"critters": [
{ "id": "GIZMO1", "color": "RED", "__typename": "Gizmo" },
{ "id": "GREMLIN1", "name": "Spikey", "__typename": "Gremlin" },
{ "id": "GIZMO2", "color": null, "__typename": "Gizmo" }
{ "id": "GIZMO1", "color": "RED", "_bramble__typename": "Gizmo" },
{ "id": "GREMLIN1", "name": "Spikey", "_bramble__typename": "Gremlin" },
{ "id": "GIZMO2", "color": null, "_bramble__typename": "Gizmo" }
]
}`

Expand Down Expand Up @@ -2997,7 +2997,7 @@ func TestBubbleUpNullValuesInPlace(t *testing.T) {
Path: ast.Path{ast.PathName("critters"), ast.PathIndex(2), ast.PathName("color")},
Extensions: nil,
}}), errs)
require.Equal(t, jsonToInterfaceMap(`{ "critters": [ { "id": "GIZMO1", "color": "RED", "__typename": "Gizmo" }, { "id": "GREMLIN1", "name": "Spikey", "__typename": "Gremlin" }, null ] }`), result)
require.Equal(t, jsonToInterfaceMap(`{ "critters": [ { "id": "GIZMO1", "color": "RED", "_bramble__typename": "Gizmo" }, { "id": "GREMLIN1", "name": "Spikey", "_bramble__typename": "Gremlin" }, null ] }`), result)
})

t.Run("fragment spread inside interface", func(t *testing.T) {
Expand All @@ -3022,9 +3022,9 @@ func TestBubbleUpNullValuesInPlace(t *testing.T) {

resultJSON := `{
"critters": [
{ "id": "GIZMO1", "color": "RED", "__typename": "Gizmo" },
{ "id": "GREMLIN1", "name": "Spikey", "__typename": "Gremlin" },
{ "id": "GIZMO2", "color": null, "__typename": "Gizmo" }
{ "id": "GIZMO1", "color": "RED", "_bramble__typename": "Gizmo" },
{ "id": "GREMLIN1", "name": "Spikey", "_bramble__typename": "Gremlin" },
{ "id": "GIZMO2", "color": null, "_bramble__typename": "Gizmo" }
]
}`

Expand Down Expand Up @@ -3060,7 +3060,7 @@ func TestBubbleUpNullValuesInPlace(t *testing.T) {
Path: ast.Path{ast.PathName("critters"), ast.PathIndex(2), ast.PathName("color")},
Extensions: nil,
}}), errs)
require.Equal(t, jsonToInterfaceMap(`{ "critters": [ { "id": "GIZMO1", "color": "RED", "__typename": "Gizmo" }, { "id": "GREMLIN1", "name": "Spikey", "__typename": "Gremlin" }, null ] }`), result)
require.Equal(t, jsonToInterfaceMap(`{ "critters": [ { "id": "GIZMO1", "color": "RED", "_bramble__typename": "Gizmo" }, { "id": "GREMLIN1", "name": "Spikey", "_bramble__typename": "Gremlin" }, null ] }`), result)
})
}

Expand Down Expand Up @@ -3265,10 +3265,10 @@ func TestFormatResponseBody(t *testing.T) {
"id": "OWNER1",
"fullName": "James Bond"
},
"_bramble__typename": "Gadget",
"__typename": "Gadget"
}
}
`)
}`)

schema := gqlparser.MustLoadSchema(&ast.Source{Name: "fixture", Input: ddl})

Expand Down Expand Up @@ -3339,6 +3339,7 @@ func TestFormatResponseBody(t *testing.T) {
"gizmo": {
"id": "GADGET1",
"name": "Gadget #1",
"_bramble__typename": "Gadget",
"__typename": "Gadget"
}
}
Expand Down Expand Up @@ -3411,7 +3412,8 @@ func TestFormatResponseBody(t *testing.T) {
"gizmo": {
"id": "GADGET1",
"name": "Gadget #1",
"__typename": "Gadget"
"__typename": "Gadget",
"_bramble__typename": "Gadget"
}
}
`)
Expand Down Expand Up @@ -3487,6 +3489,7 @@ func TestFormatResponseBody(t *testing.T) {
"id": "TOOL1",
"name": "Tool #1",
"category": "Screwdriver",
"_bramble__typename": "Tool",
"__typename": "Tool"
}
}
Expand Down Expand Up @@ -4764,9 +4767,9 @@ func TestQueryExecutionWithUnions(t *testing.T) {
w.Write([]byte(`{
"data": {
"foo": [
{ "name": "fido", "age": 4, "__typename": "Dog" },
{ "name": "felix", "age": 2, "__typename": "Cat" },
{ "age": 20, "name": "ka", "__typename": "Snake" }
{ "name": "fido", "age": 4, "_bramble__typename": "Dog" },
{ "name": "felix", "age": 2, "_bramble__typename": "Cat" },
{ "age": 20, "name": "ka", "_bramble__typename": "Snake" }
]
}
}
Expand All @@ -4779,7 +4782,7 @@ func TestQueryExecutionWithUnions(t *testing.T) {
"pet": {
"name": "felix",
"age": 2,
"__typename": "Cat"
"_bramble__typename": "Cat"
}
}
}
Expand Down
10 changes: 5 additions & 5 deletions plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,8 @@ func createSteps(ctx *PlanningContext, insertionPoint []string, parentType strin
}

var reservedAliases = map[string]string{
"__typename": "__typename",
"_bramble_id": "id",
"_bramble__typename": "__typename",
"_bramble_id": "id",
}

func extractSelectionSet(ctx *PlanningContext, insertionPoint []string, parentType string, input ast.SelectionSet, location string) (ast.SelectionSet, []*QueryPlanStep, error) {
Expand Down Expand Up @@ -183,7 +183,7 @@ func extractSelectionSet(ctx *PlanningContext, insertionPoint []string, parentTy
if err != nil {
return nil, nil, err
}
selectionSet = append(selectionSet, &ast.Field{Alias: "__typename", Name: "__typename", Definition: &ast.FieldDefinition{Name: "__typename", Type: ast.NamedType("String", nil)}})
selectionSet = append(selectionSet, &ast.Field{Alias: "_bramble__typename", Name: "__typename", Definition: &ast.FieldDefinition{Name: "__typename", Type: ast.NamedType("String", nil)}})
inlineFragment := *selection
inlineFragment.SelectionSet = selectionSet
selectionSetResult = append(selectionSetResult, &inlineFragment)
Expand All @@ -199,7 +199,7 @@ func extractSelectionSet(ctx *PlanningContext, insertionPoint []string, parentTy
if err != nil {
return nil, nil, err
}
selectionSet = append(selectionSet, &ast.Field{Alias: "__typename", Name: "__typename", Definition: &ast.FieldDefinition{Name: "__typename", Type: ast.NamedType("String", nil)}})
selectionSet = append(selectionSet, &ast.Field{Alias: "_bramble__typename", Name: "__typename", Definition: &ast.FieldDefinition{Name: "__typename", Type: ast.NamedType("String", nil)}})
inlineFragment := ast.InlineFragment{
TypeCondition: selection.Definition.TypeCondition,
SelectionSet: selectionSet,
Expand Down Expand Up @@ -264,7 +264,7 @@ func extractSelectionSet(ctx *PlanningContext, insertionPoint []string, parentTy
}
}
selectionSetResult = append(selectionSetResult, &ast.Field{
Alias: "__typename",
Alias: "_bramble__typename",
Name: "__typename",
Definition: &ast.FieldDefinition{Name: "__typename", Type: ast.NamedType("String", nil)},
})
Expand Down
35 changes: 17 additions & 18 deletions plan_fixtures_test.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
package bramble

import (
"context"
"encoding/json"
"fmt"
"sort"
"testing"
"context"
"fmt"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/99designs/gqlgen/graphql"
"github.com/vektah/gqlparser/v2"
"github.com/vektah/gqlparser/v2/ast"
"github.com/99designs/gqlgen/graphql"
)

type PlanTestFixture struct {
Expand Down Expand Up @@ -247,23 +247,22 @@ var PlanTestFixture6 = &PlanTestFixture{
}`,

Locations: map[string]string{
"Query.shop1": "A",
"Shop.id": "A",
"Shop.name": "A",
"Shop.products": "A",
"Product.name": "B",
"Product.collection": "B",
"Collection.name": "C",
"Query.shop1": "A",
"Shop.id": "A",
"Shop.name": "A",
"Shop.products": "A",
"Product.name": "B",
"Product.collection": "B",
"Collection.name": "C",
},

IsBoundary: map[string]bool{
"Shop": false,
"Product": true,
"Collection": true,
"Shop": false,
"Product": true,
"Collection": true,
},
}


func (f *PlanTestFixture) Plan(t *testing.T, query string) (*QueryPlan, error) {
t.Helper()
schema := gqlparser.MustLoadSchema(&ast.Source{Name: "fixture", Input: f.Schema})
Expand Down Expand Up @@ -304,10 +303,10 @@ func (f *PlanTestFixture) CheckUnorderedRootFieldSelections(t *testing.T, query
var foundSelection string
expectedSelection = fmt.Sprintf("{ %s }", expectedSelection)
for _, selection := range rootField.SelectionSet {
if expectedSelection == formatSelectionSetSingleLine(ctx, nil, []ast.Selection{selection}) {
foundSelection = expectedSelection
break
}
if expectedSelection == formatSelectionSetSingleLine(ctx, nil, []ast.Selection{selection}) {
foundSelection = expectedSelection
break
}
}
assert.Equal(t, expectedSelection, foundSelection)
}
Expand Down
20 changes: 10 additions & 10 deletions plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ func TestQueryPlanInlineFragment(t *testing.T) {
{
"ServiceURL": "A",
"ParentType": "Query",
"SelectionSet": "{ movies { ... on Movie { id title(language: French) _bramble_id: id __typename } _bramble_id: id } }",
"SelectionSet": "{ movies { ... on Movie { id title(language: French) _bramble_id: id _bramble__typename: __typename } _bramble_id: id } }",
"InsertionPoint": null,
"Then": null
}
Expand All @@ -288,7 +288,7 @@ func TestQueryPlanInlineFragmentDoesNotDuplicateTypename(t *testing.T) {
{
"ServiceURL": "A",
"ParentType": "Query",
"SelectionSet": "{ movies { ... on Movie { __typename id title(language: French) _bramble_id: id __typename } _bramble_id: id } }",
"SelectionSet": "{ movies { ... on Movie { __typename id title(language: French) _bramble_id: id _bramble__typename: __typename } _bramble_id: id } }",
"InsertionPoint": null,
"Then": null
}
Expand All @@ -314,7 +314,7 @@ func TestQueryPlanInlineFragmentPlan(t *testing.T) {
{
"ServiceURL": "A",
"ParentType": "Query",
"SelectionSet": "{ movies { ... on Movie { id title(language: French) _bramble_id: id __typename } _bramble_id: id } }",
"SelectionSet": "{ movies { ... on Movie { id title(language: French) _bramble_id: id _bramble__typename: __typename } _bramble_id: id } }",
"InsertionPoint": null,
"Then": [
{
Expand Down Expand Up @@ -347,7 +347,7 @@ func TestQueryPlanFragmentSpread1(t *testing.T) {
{
"ServiceURL": "A",
"ParentType": "Query",
"SelectionSet": "{ movies { ... on Movie { id title(language: French) _bramble_id: id __typename } _bramble_id: id } }",
"SelectionSet": "{ movies { ... on Movie { id title(language: French) _bramble_id: id _bramble__typename: __typename } _bramble_id: id } }",
"InsertionPoint": null,
"Then": null
}
Expand Down Expand Up @@ -470,7 +470,7 @@ func TestQueryPlanExpandAbstractTypesWithPossibleBoundaryIds(t *testing.T) {
"name",
"... on Lion { _bramble_id: id }",
"... on Snake { _bramble_id: id }",
"__typename",
"_bramble__typename: __typename",
}
PlanTestFixture3.CheckUnorderedRootFieldSelections(t, query, rootFieldSelections)
}
Expand All @@ -492,9 +492,9 @@ func TestQueryPlanInlineFragmentSpreadOfInterface(t *testing.T) {
"name",
"... on Lion { _bramble_id: id }",
"... on Snake { _bramble_id: id }",
"... on Lion { maneColor _bramble_id: id __typename }",
"... on Snake { _bramble_id: id __typename }",
"__typename",
"... on Lion { maneColor _bramble_id: id _bramble__typename: __typename }",
"... on Snake { _bramble_id: id _bramble__typename: __typename }",
"_bramble__typename: __typename",
}
PlanTestFixture3.CheckUnorderedRootFieldSelections(t, query, rootFieldSelections)
}
Expand Down Expand Up @@ -614,7 +614,7 @@ func TestQueryPlanSupportsUnions(t *testing.T) {
{
"ServiceURL": "A",
"ParentType": "Query",
"SelectionSet": "{ animals { ... on Dog { name __typename } ... on Cat { name __typename } ... on Snake { name __typename } __typename } }",
"SelectionSet": "{ animals { ... on Dog { name _bramble__typename: __typename } ... on Cat { name _bramble__typename: __typename } ... on Snake { name _bramble__typename: __typename } _bramble__typename: __typename } }",
"InsertionPoint": null,
"Then": null
}
Expand Down Expand Up @@ -834,5 +834,5 @@ func TestQueryPlanValidateReservedIdAlias(t *testing.T) {
}

func TestQueryPlanValidateReservedTypenameAlias(t *testing.T) {
PlanTestFixture1.CheckError(t, "{ movies { __typename: title } }")
PlanTestFixture1.CheckError(t, "{ movies { _bramble__typename: title } }")
}
2 changes: 1 addition & 1 deletion query_execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -866,7 +866,7 @@ func unionAndTrimSelectionSetRec(objectTypename string, schema *ast.Schema, sele
}

func extractAndCastTypenameField(result map[string]interface{}) string {
typeNameInterface, ok := result["__typename"]
typeNameInterface, ok := result["_bramble__typename"]
if !ok {
return ""
}
Expand Down
Loading

0 comments on commit e0e24cc

Please sign in to comment.