Skip to content

Commit a3a932c

Browse files
authored
Add NullID nullable type (#627)
* Add NullID nullable type * Replace *string with *graphql.ID
1 parent a226fe8 commit a3a932c

File tree

2 files changed

+110
-0
lines changed

2 files changed

+110
-0
lines changed

nullable_types.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,31 @@ import (
55
"math"
66
)
77

8+
// NullID is an ID that can be null. Use it in input structs to
9+
// differentiate a value explicitly set to null from an omitted value.
10+
// When the value is defined (either null or a value) Set is true.
11+
type NullID struct {
12+
Value *ID
13+
Set bool
14+
}
15+
16+
func (NullID) ImplementsGraphQLType(name string) bool {
17+
return name == "ID"
18+
}
19+
20+
func (s *NullID) UnmarshalGraphQL(input interface{}) error {
21+
s.Set = true
22+
23+
if input == nil {
24+
return nil
25+
}
26+
27+
s.Value = new(ID)
28+
return s.Value.UnmarshalGraphQL(input)
29+
}
30+
31+
func (s *NullID) Nullable() {}
32+
833
// NullString is a string that can be null. Use it in input structs to
934
// differentiate a value explicitly set to null from an omitted value.
1035
// When the value is defined (either null or a value) Set is true.

nullable_types_test.go

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,91 @@ import (
88
"github.com/graph-gophers/graphql-go/decode"
99
)
1010

11+
func TestNullID_ImplementsUnmarshaler(t *testing.T) {
12+
defer func() {
13+
if err := recover(); err != nil {
14+
t.Error(err)
15+
}
16+
}()
17+
18+
// assert *NullID implements decode.Unmarshaler interface
19+
var _ decode.Unmarshaler = (*graphql.NullID)(nil)
20+
}
21+
22+
func TestNullID_UnmarshalGraphQL(t *testing.T) {
23+
type args struct {
24+
input interface{}
25+
}
26+
27+
good := graphql.ID("1234")
28+
ref := graphql.NullID{
29+
Value: &good,
30+
Set: true,
31+
}
32+
33+
t.Run("invalid", func(t *testing.T) {
34+
tests := []struct {
35+
name string
36+
args args
37+
wantErr string
38+
}{
39+
{
40+
name: "boolean",
41+
args: args{input: true},
42+
wantErr: "wrong type for ID: bool",
43+
},
44+
{
45+
name: "int",
46+
args: args{input: 1},
47+
wantErr: "wrong type for ID: int",
48+
},
49+
}
50+
51+
for _, tt := range tests {
52+
t.Run(tt.name, func(t *testing.T) {
53+
gt := &graphql.NullID{}
54+
if err := gt.UnmarshalGraphQL(tt.args.input); err != nil {
55+
if err.Error() != tt.wantErr {
56+
t.Errorf("UnmarshalGraphQL() error = %v, want = %s", err, tt.wantErr)
57+
}
58+
59+
return
60+
}
61+
62+
t.Error("UnmarshalGraphQL() expected error not raised")
63+
})
64+
}
65+
})
66+
67+
tests := []struct {
68+
name string
69+
args args
70+
wantEq graphql.NullID
71+
}{
72+
{
73+
name: "string",
74+
args: args{
75+
input: string(good),
76+
},
77+
wantEq: ref,
78+
},
79+
}
80+
81+
for _, tt := range tests {
82+
t.Run(tt.name, func(t *testing.T) {
83+
gt := new(graphql.NullID)
84+
if err := gt.UnmarshalGraphQL(tt.args.input); err != nil {
85+
t.Errorf("UnmarshalGraphQL() error = %v", err)
86+
return
87+
}
88+
89+
if *gt.Value != *tt.wantEq.Value {
90+
t.Errorf("UnmarshalGraphQL() got = %v, want = %v", *gt.Value, *tt.wantEq.Value)
91+
}
92+
})
93+
}
94+
}
95+
1196
func TestNullInt_ImplementsUnmarshaler(t *testing.T) {
1297
defer func() {
1398
if err := recover(); err != nil {

0 commit comments

Comments
 (0)