Skip to content
This repository has been archived by the owner on Feb 15, 2023. It is now read-only.

diff key must be scalar #190

Merged
merged 3 commits into from
Oct 19, 2018
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

### Changed

#### `graphql`

- Object key must now be scalar. ([#190](https://github.com/samsarahq/thunder/pull/190))

#### `livesql`

- Support filter types that serialize into `[]byte`. ([#172](https://github.com/samsarahq/thunder/pull/172))
Expand Down
17 changes: 17 additions & 0 deletions graphql/schemabuilder/reflect.go
Original file line number Diff line number Diff line change
Expand Up @@ -839,6 +839,16 @@ func (sb *schemaBuilder) buildStruct(typ reflect.Type) error {
}
}

isScalarType := func(typ graphql.Type) bool {
if nonNull, ok := typ.(*graphql.NonNull); ok {
typ = nonNull.Type
}
if _, ok := typ.(*graphql.Scalar); !ok {
return false
}
return true
}

object := &graphql.Object{
Name: name,
Description: description,
Expand Down Expand Up @@ -888,6 +898,9 @@ func (sb *schemaBuilder) buildStruct(typ reflect.Type) error {
if object.Key != nil {
return fmt.Errorf("bad type %s: multiple key fields", typ)
}
if !isScalarType(built.Type) {
return fmt.Errorf("bad type %s: key type must be scalar, got %T", typ, built.Type)
}
object.Key = built.Resolve
}
}
Expand Down Expand Up @@ -921,6 +934,10 @@ func (sb *schemaBuilder) buildStruct(typ reflect.Type) error {
if !ok {
return fmt.Errorf("key field doesn't exist on object")
}

if !isScalarType(keyPtr.Type) {
return fmt.Errorf("bad type %s: key type must be scalar, got %s", typ, keyPtr.Type.String())
}
object.Key = keyPtr.Resolve
}

Expand Down
87 changes: 79 additions & 8 deletions graphql/schemabuilder/reflect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -370,13 +370,13 @@ type kitchenSinkArgs struct {
Hello int64
Hello32 int32
Hello16 int16
HelloFloat32 float32
HelloFloat64 float64
HelloFloat32 float32
HelloFloat64 float64
FooBar string
Bool bool
OptionalInt *int64
OptionalFloat32 *float32
OptionalFloat64 *float64
OptionalFloat32 *float32
OptionalFloat64 *float64
OptionalStruct *inner
Ints []int64
OptionalStructs *[]*inner
Expand Down Expand Up @@ -448,8 +448,8 @@ func TestArgParser(t *testing.T) {
Hello: 20,
Hello32: 20,
Hello16: 20,
HelloFloat32: 42.0,
HelloFloat64: 42.0,
HelloFloat32: 42.0,
HelloFloat64: 42.0,
FooBar: "foo!",
Bool: true,
OptionalInt: nil,
Expand Down Expand Up @@ -500,8 +500,8 @@ func TestArgParser(t *testing.T) {
Hello: 40,
Hello32: 40,
Hello16: 40,
HelloFloat64: 40.0,
HelloFloat32: 40.0,
HelloFloat64: 40.0,
HelloFloat32: 40.0,
FooBar: "bar!",
Bool: false,
OptionalInt: &ten,
Expand Down Expand Up @@ -603,3 +603,74 @@ func TestBadArguments(t *testing.T) {
t.Errorf("expected non-struct args argument to fail, but received %s", err.Error())
}
}

func TestObjectKeyMustBeScalar(t *testing.T) {
t.Run("struct key tag", func(t *testing.T) {
type key struct{ Name string }
type object struct {
Key key `graphql:",key"`
}
builder := NewSchema()
builder.Object("object", object{})
builder.Query().FieldFunc("objects", func(ctx context.Context) []*object { return []*object(nil) })
_, err := builder.Build()
assert.Error(t, err, "key type must be scalar")
})

t.Run("string key tag", func(t *testing.T) {
type object struct {
Key string `graphql:",key"`
}
builder := NewSchema()
builder.Object("object", object{})
builder.Query().FieldFunc("objects", func(ctx context.Context) []*object { return []*object(nil) })
_, err := builder.Build()
assert.NoError(t, err)
})

t.Run("pointer string key tag", func(t *testing.T) {
type object struct {
Key *string `graphql:",key"`
}
builder := NewSchema()
builder.Object("object", object{})
builder.Query().FieldFunc("objects", func(ctx context.Context) []*object { return []*object(nil) })
_, err := builder.Build()
assert.NoError(t, err)
})

t.Run("struct key", func(t *testing.T) {
type key struct{ Name string }
type object struct {
Key key
}
builder := NewSchema()
builder.Object("object", object{}).Key("key")
builder.Query().FieldFunc("objects", func(ctx context.Context) []*object { return []*object(nil) })
_, err := builder.Build()
assert.Error(t, err, "key type must be scalar")
})

t.Run("string key", func(t *testing.T) {
type object struct {
Key string
}
builder := NewSchema()
builder.Object("object", object{}).Key("key")
builder.Query().FieldFunc("objects", func(ctx context.Context) []*object { return []*object(nil) })
_, err := builder.Build()
assert.NoError(t, err)
})

t.Run("pointer string key", func(t *testing.T) {
type object struct {
Key *string
}
builder := NewSchema()
builder.Object("object", object{}).Key("key")
builder.Query().FieldFunc("objects", func(ctx context.Context) []*object { return []*object(nil) })
_, err := builder.Build()
assert.NoError(t, err)
})

}
22 changes: 22 additions & 0 deletions vendor/github.com/samsarahq/go/oops/LICENSE

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

3 changes: 3 additions & 0 deletions vendor/github.com/samsarahq/go/oops/README.md

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

84 changes: 84 additions & 0 deletions vendor/github.com/samsarahq/go/oops/doc.go

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

Loading