1 package gqlerror
2
3 import (
4 "reflect"
5 "testing"
6
7 "github.com/stretchr/testify/require"
8 "github.com/vektah/gqlparser/v2/ast"
9 )
10
11 type testError struct {
12 message string
13 }
14
15 func (e testError) Error() string {
16 return e.message
17 }
18
19 var (
20 underlyingError = testError{
21 "Underlying error",
22 }
23
24 error1 = &Error{
25 Message: "Some error 1",
26 }
27 error2 = &Error{
28 Err: underlyingError,
29 Message: "Some error 2",
30 }
31 )
32
33 func TestErrorFormatting(t *testing.T) {
34 t.Run("without filename", func(t *testing.T) {
35 err := ErrorLocf("", 66, 2, "kabloom")
36
37 require.Equal(t, `input:66: kabloom`, err.Error())
38 require.Equal(t, nil, err.Extensions["file"])
39 })
40
41 t.Run("with filename", func(t *testing.T) {
42 err := ErrorLocf("schema.graphql", 66, 2, "kabloom")
43
44 require.Equal(t, `schema.graphql:66: kabloom`, err.Error())
45 require.Equal(t, "schema.graphql", err.Extensions["file"])
46 })
47
48 t.Run("with path", func(t *testing.T) {
49 err := ErrorPathf(ast.Path{ast.PathName("a"), ast.PathIndex(1), ast.PathName("b")}, "kabloom")
50
51 require.Equal(t, `input: a[1].b kabloom`, err.Error())
52 })
53 }
54
55 func TestList_As(t *testing.T) {
56 t.Parallel()
57
58 tests := []struct {
59 name string
60 errs List
61 target any
62 wantsTarget any
63 targetFound bool
64 }{
65 {
66 name: "Empty list",
67 errs: List{},
68 },
69 {
70 name: "List with one error",
71 errs: List{error1},
72 target: new(*Error),
73 wantsTarget: &error1,
74 targetFound: true,
75 },
76 {
77 name: "List with multiple errors 1",
78 errs: List{error1, error2},
79 target: new(*Error),
80 wantsTarget: &error1,
81 targetFound: true,
82 },
83 {
84 name: "List with multiple errors 2",
85 errs: List{error1, error2},
86 target: new(testError),
87 wantsTarget: &underlyingError,
88 targetFound: true,
89 },
90 }
91
92 for _, tt := range tests {
93 tt := tt
94
95 t.Run(tt.name, func(t *testing.T) {
96 t.Parallel()
97
98 targetFound := tt.errs.As(tt.target)
99
100 if targetFound != tt.targetFound {
101 t.Errorf("List.As() = %v, want %v", targetFound, tt.targetFound)
102 }
103
104 if tt.targetFound && !reflect.DeepEqual(tt.target, tt.wantsTarget) {
105 t.Errorf("target = %v, want %v", tt.target, tt.wantsTarget)
106 }
107 })
108 }
109 }
110
111 func TestList_Is(t *testing.T) {
112 t.Parallel()
113
114 tests := []struct {
115 name string
116 errs List
117 target error
118 hasMatchingError bool
119 }{
120 {
121 name: "Empty list",
122 errs: List{},
123 target: new(Error),
124 hasMatchingError: false,
125 },
126 {
127 name: "List with one error",
128 errs: List{
129 error1,
130 },
131 target: error1,
132 hasMatchingError: true,
133 },
134 {
135 name: "List with multiple errors 1",
136 errs: List{
137 error1,
138 error2,
139 },
140 target: error2,
141 hasMatchingError: true,
142 },
143 {
144 name: "List with multiple errors 2",
145 errs: List{
146 error1,
147 error2,
148 },
149 target: underlyingError,
150 hasMatchingError: true,
151 },
152 }
153
154 for _, tt := range tests {
155 tt := tt
156 t.Run(tt.name, func(t *testing.T) {
157 t.Parallel()
158
159 hasMatchingError := tt.errs.Is(tt.target)
160 if hasMatchingError != tt.hasMatchingError {
161 t.Errorf("List.Is() = %v, want %v", hasMatchingError, tt.hasMatchingError)
162 }
163 if hasMatchingError && tt.target == nil {
164 t.Errorf("List.Is() returned nil target, wants concrete error")
165 }
166 })
167 }
168 }
169
View as plain text