Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support for cyclic fields on defintion #229

Merged
merged 1 commit into from
Aug 6, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 19 additions & 6 deletions definition.go
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,7 @@ type ObjectConfig struct {
IsTypeOf IsTypeOfFn `json:"isTypeOf"`
Description string `json:"description"`
}

type FieldsThunk func() Fields

func NewObject(config ObjectConfig) *Object {
Expand Down Expand Up @@ -506,19 +507,26 @@ func defineInterfaces(ttype *Object, interfaces []*Interface) ([]*Interface, err
return ifaces, nil
}

func defineFieldMap(ttype Named, fields Fields) (FieldDefinitionMap, error) {
func defineFieldMap(ttype Named, fields interface{}) (FieldDefinitionMap, error) {
var fieldMap Fields
switch fields.(type) {
case Fields:
fieldMap = fields.(Fields)
case FieldsThunk:
fieldMap = fields.(FieldsThunk)()
}

resultFieldMap := FieldDefinitionMap{}

err := invariant(
len(fields) > 0,
len(fieldMap) > 0,
fmt.Sprintf(`%v fields must be an object with field names as keys or a function which return such an object.`, ttype),
)
if err != nil {
return resultFieldMap, err
}

for fieldName, field := range fields {
for fieldName, field := range fieldMap {
if field == nil {
continue
}
Expand Down Expand Up @@ -1080,8 +1088,8 @@ type InputObject struct {

typeConfig InputObjectConfig
fields InputObjectFieldMap

err error
init bool
err error
}
type InputObjectFieldConfig struct {
Type Input `json:"type"`
Expand Down Expand Up @@ -1129,7 +1137,7 @@ func NewInputObject(config InputObjectConfig) *InputObject {
gt.PrivateName = config.Name
gt.PrivateDescription = config.Description
gt.typeConfig = config
gt.fields = gt.defineFieldMap()
//gt.fields = gt.defineFieldMap()
return gt
}

Expand Down Expand Up @@ -1175,9 +1183,14 @@ func (gt *InputObject) defineFieldMap() InputObjectFieldMap {
field.DefaultValue = fieldConfig.DefaultValue
resultFieldMap[fieldName] = field
}
gt.init = true
return resultFieldMap
}

func (gt *InputObject) Fields() InputObjectFieldMap {
if !gt.init {
gt.fields = gt.defineFieldMap()
}
return gt.fields
}
func (gt *InputObject) Name() string {
Expand Down
22 changes: 22 additions & 0 deletions definition_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -619,3 +619,25 @@ func TestTypeSystem_DefinitionExample_IncludesFieldsThunk(t *testing.T) {
t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(fieldMap["s"].Type, someObject))
}
}

func TestTypeSystem_DefinitionExampe_AllowsCyclicFieldTypes(t *testing.T) {
personType := graphql.NewObject(graphql.ObjectConfig{
Name: "Person",
Fields: (graphql.FieldsThunk)(func() graphql.Fields {
return graphql.Fields{
"name": &graphql.Field{
Type: graphql.String,
},
"bestFriend": &graphql.Field{
Type: personType,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chris-ramon Type: personType is using the personType defined in union_interface_test.go, not the local variable defined just above. If personType hadn't been defined in that other file, you would get an undefined: personType error.

},
}
}),
})

fieldMap := personType.Fields()
if !reflect.DeepEqual(fieldMap["name"].Type, graphql.String) {
t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(fieldMap["bestFriend"].Type, personType))
}

}