Skip to content

Commit

Permalink
Add NullID nullable type (#627)
Browse files Browse the repository at this point in the history
* Add NullID nullable type

* Replace *string with *graphql.ID
  • Loading branch information
Slessi committed Dec 20, 2023
1 parent a226fe8 commit a3a932c
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 0 deletions.
25 changes: 25 additions & 0 deletions nullable_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,31 @@ import (
"math"
)

// NullID is an ID that can be null. Use it in input structs to
// differentiate a value explicitly set to null from an omitted value.
// When the value is defined (either null or a value) Set is true.
type NullID struct {
Value *ID
Set bool
}

func (NullID) ImplementsGraphQLType(name string) bool {
return name == "ID"
}

func (s *NullID) UnmarshalGraphQL(input interface{}) error {
s.Set = true

if input == nil {
return nil
}

s.Value = new(ID)
return s.Value.UnmarshalGraphQL(input)
}

func (s *NullID) Nullable() {}

// NullString is a string that can be null. Use it in input structs to
// differentiate a value explicitly set to null from an omitted value.
// When the value is defined (either null or a value) Set is true.
Expand Down
85 changes: 85 additions & 0 deletions nullable_types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,91 @@ import (
"github.com/graph-gophers/graphql-go/decode"
)

func TestNullID_ImplementsUnmarshaler(t *testing.T) {
defer func() {
if err := recover(); err != nil {
t.Error(err)
}
}()

// assert *NullID implements decode.Unmarshaler interface
var _ decode.Unmarshaler = (*graphql.NullID)(nil)
}

func TestNullID_UnmarshalGraphQL(t *testing.T) {
type args struct {
input interface{}
}

good := graphql.ID("1234")
ref := graphql.NullID{
Value: &good,
Set: true,
}

t.Run("invalid", func(t *testing.T) {
tests := []struct {
name string
args args
wantErr string
}{
{
name: "boolean",
args: args{input: true},
wantErr: "wrong type for ID: bool",
},
{
name: "int",
args: args{input: 1},
wantErr: "wrong type for ID: int",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gt := &graphql.NullID{}
if err := gt.UnmarshalGraphQL(tt.args.input); err != nil {
if err.Error() != tt.wantErr {
t.Errorf("UnmarshalGraphQL() error = %v, want = %s", err, tt.wantErr)
}

return
}

t.Error("UnmarshalGraphQL() expected error not raised")
})
}
})

tests := []struct {
name string
args args
wantEq graphql.NullID
}{
{
name: "string",
args: args{
input: string(good),
},
wantEq: ref,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gt := new(graphql.NullID)
if err := gt.UnmarshalGraphQL(tt.args.input); err != nil {
t.Errorf("UnmarshalGraphQL() error = %v", err)
return
}

if *gt.Value != *tt.wantEq.Value {
t.Errorf("UnmarshalGraphQL() got = %v, want = %v", *gt.Value, *tt.wantEq.Value)
}
})
}
}

func TestNullInt_ImplementsUnmarshaler(t *testing.T) {
defer func() {
if err := recover(); err != nil {
Expand Down

0 comments on commit a3a932c

Please sign in to comment.