Skip to content

Commit 25a3b9f

Browse files
Include more thorough testing of GraphqlErrorImpl#equals/hashCode
This now tests the other attributes, and also checks inequality explicitly.
1 parent 7e576b1 commit 25a3b9f

File tree

2 files changed

+61
-40
lines changed

2 files changed

+61
-40
lines changed

src/main/java/graphql/GraphqlErrorBuilder.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,13 @@ public GraphQLError build() {
137137
* A simple implementation of a {@link GraphQLError}.
138138
* <p>
139139
* This provides {@link #hashCode()} and {@link #equals(Object)} methods that afford comparison with other
140-
* {@link GraphQLError} implementations. However, the values in the {@link #getExtensions()} {@link Map} <b>must</b>
141-
* in turn implement {@code hashCode()} and {@link #equals(Object)} for this to function correctly.
140+
* {@link GraphQLError} implementations. However, the values provided in the following fields <b>must</b>
141+
* in turn implement {@link #hashCode()} and {@link #equals(Object)} for this to function correctly:
142+
* <ul>
143+
* <li>the values in the {@link #getPath()} {@link List}.
144+
* <li>the {@link #getErrorType()} {@link ErrorClassification}.
145+
* <li>the values in the {@link #getExtensions()} {@link Map}.
146+
* </ul>
142147
*/
143148
private static class GraphqlErrorImpl implements GraphQLError {
144149
private final String message;

src/test/groovy/graphql/GraphqlErrorBuilderTest.groovy

Lines changed: 54 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -153,49 +153,65 @@ class GraphqlErrorBuilderTest extends Specification {
153153

154154
}
155155

156-
def "implements equals correctly"() {
156+
def "implements equals/hashCode correctly for matching errors"() {
157157
when:
158-
def error1 = GraphQLError.newError().message("msg")
159-
.locations(null)
160-
.extensions([x : "y"])
161-
.path(null)
162-
.build()
163-
def error2 = GraphQLError.newError().message("msg")
164-
.locations(null)
165-
.extensions([x : "y"])
166-
.path(null)
167-
.build()
168-
def error3 = GraphQLError.newError().message("msg3")
169-
.locations(null)
170-
.extensions([x : "y"])
171-
.path(null)
172-
.build()
158+
def firstError = toGraphQLError(first)
159+
def secondError = toGraphQLError(second)
160+
173161
then:
174-
error1 == error2
175-
error1 != error3
176-
error2 != error3
162+
firstError == secondError
163+
firstError.hashCode() == secondError.hashCode()
164+
165+
where:
166+
first | second
167+
[message: "msg"] | [message: "msg"]
168+
[message: "msg", locations: [new SourceLocation(1, 2)]] | [message: "msg", locations: [new SourceLocation(1, 2)]]
169+
[message: "msg", errorType: ErrorType.InvalidSyntax] | [message: "msg", errorType: ErrorType.InvalidSyntax]
170+
[message: "msg", path: ["items", 1, "item"]] | [message: "msg", path: ["items", 1, "item"]]
171+
[message: "msg", extensions: [aBoolean: true, aString: "foo"]] | [message: "msg", extensions: [aBoolean: true, aString: "foo"]]
177172
}
178173

179-
def "implements hashCode correctly"() {
174+
def "implements equals/hashCode correctly for different errors"() {
180175
when:
181-
def error1 = GraphQLError.newError().message("msg")
182-
.locations(null)
183-
.extensions([x : "y"])
184-
.path(null)
185-
.build()
186-
def error2 = GraphQLError.newError().message("msg")
187-
.locations(null)
188-
.extensions([x : "y"])
189-
.path(null)
190-
.build()
191-
def error3 = GraphQLError.newError().message("msg3")
192-
.locations(null)
193-
.extensions([x : "y"])
194-
.path(null)
195-
.build()
196-
def errors = [error1, error2, error3] as Set
176+
def firstError = toGraphQLError(first)
177+
def secondError = toGraphQLError(second)
178+
197179
then:
198-
errors == [error1, error3] as Set
199-
errors == [error2, error3] as Set
180+
firstError != secondError
181+
firstError.hashCode() != secondError.hashCode()
182+
183+
where:
184+
first | second
185+
[message: "msg"] | [message: "different msg"]
186+
[message: "msg", locations: [new SourceLocation(1, 2)]] | [message: "msg", locations: [new SourceLocation(3, 4)]]
187+
[message: "msg", errorType: ErrorType.InvalidSyntax] | [message: "msg", errorType: ErrorType.DataFetchingException]
188+
[message: "msg", path: ["items", "1", "item"]] | [message: "msg", path: ["items"]]
189+
[message: "msg", extensions: [aBoolean: false]] | [message: "msg", extensions: [aString: "foo"]]
190+
}
191+
192+
private static GraphQLError toGraphQLError(Map<String, Object> errorFields) {
193+
def errorBuilder = GraphQLError.newError();
194+
errorFields.forEach { key, value ->
195+
if (value != null) {
196+
switch (key) {
197+
case "message":
198+
errorBuilder.message(value as String);
199+
break;
200+
case "locations":
201+
errorBuilder.locations(value as List<SourceLocation>);
202+
break;
203+
case "errorType":
204+
errorBuilder.errorType(value as ErrorClassification);
205+
break;
206+
case "path":
207+
errorBuilder.path(value as List<Object>);
208+
break;
209+
case "extensions":
210+
errorBuilder.extensions(value as Map<String, Object>);
211+
break;
212+
}
213+
}
214+
}
215+
return errorBuilder.build();
200216
}
201217
}

0 commit comments

Comments
 (0)