Skip to content

Commit 1612698

Browse files
authored
Add ability to assert result of integration test with ignoring the order of lists (#209)
1 parent a92b8ca commit 1612698

File tree

6 files changed

+154
-106
lines changed

6 files changed

+154
-106
lines changed

.github/workflows/pr-build.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
java-version: 11
2121
distribution: adopt
2222
- name: Run Maven build
23-
run: ./mvnw --no-transfer-progress -Dneo4j-graphql-java.integration-tests=true -Dneo4j-graphql-java.generate-test-file-diff=false clean compile test
23+
run: ./mvnw --no-transfer-progress -Dneo4j-graphql-java.integration-tests=true -Dneo4j-graphql-java.generate-test-file-diff=false -Dneo4j-graphql-java.flatten-tests=true clean compile test
2424
- name: Publish Unit Test Results
2525
uses: EnricoMi/publish-unit-test-result-action@v1
2626
if: always()

core/src/test/kotlin/org/neo4j/graphql/utils/AsciiDocTestSuite.kt

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,20 @@ open class AsciiDocTestSuite(
3232
*/
3333
private val knownBlocks: MutableList<ParsedBlock> = mutableListOf()
3434

35-
fun generateTests(): Stream<DynamicNode> = FileParser().parse()
35+
fun generateTests(): Stream<DynamicNode> {
36+
val stream = FileParser().parse()
37+
return if (FLATTEN_TESTS) flatten(stream, "$fileName:") else stream
38+
}
39+
40+
private fun flatten(stream: Stream<out DynamicNode>, name: String): Stream<DynamicNode> {
41+
return stream.flatMap {
42+
when (it) {
43+
is DynamicContainer -> flatten(it.children, "$name[${it.displayName}]")
44+
is DynamicTest -> Stream.of(DynamicTest.dynamicTest("$name[${it.displayName}]", it.executable))
45+
else -> throw IllegalArgumentException("unknown type ${it.javaClass.name}")
46+
}
47+
}
48+
}
3649

3750
class ParsedBlock(
3851
val marker: String,
@@ -227,6 +240,10 @@ open class AsciiDocTestSuite(
227240
}
228241

229242
companion object {
243+
/**
244+
* to find broken tests easy by its console output, enable this feature
245+
*/
246+
val FLATTEN_TESTS = System.getProperty("neo4j-graphql-java.flatten-tests", "false") == "true"
230247
val GENERATE_TEST_FILE_DIFF = System.getProperty("neo4j-graphql-java.generate-test-file-diff", "true") == "true"
231248
val UPDATE_TEST_FILE = System.getProperty("neo4j-graphql-java.update-test-file", "false") == "true"
232249
val MAPPER = ObjectMapper()

core/src/test/kotlin/org/neo4j/graphql/utils/CypherTestSuite.kt

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import graphql.schema.DataFetcher
66
import graphql.schema.DataFetchingEnvironment
77
import graphql.schema.GraphQLSchema
88
import org.assertj.core.api.Assertions
9+
import org.assertj.core.api.InstanceOfAssertFactories
910
import org.junit.jupiter.api.Assumptions
1011
import org.junit.jupiter.api.DynamicNode
1112
import org.junit.jupiter.api.DynamicTest
@@ -14,6 +15,7 @@ import org.neo4j.harness.Neo4j
1415
import org.opentest4j.AssertionFailedError
1516
import java.util.*
1617
import java.util.concurrent.FutureTask
18+
import java.util.function.Consumer
1719
import kotlin.streams.toList
1820

1921
class CypherTestSuite(fileName: String, val neo4j: Neo4j? = null) : AsciiDocTestSuite(
@@ -23,6 +25,7 @@ class CypherTestSuite(fileName: String, val neo4j: Neo4j? = null) : AsciiDocTest
2325
GRAPHQL_MARKER,
2426
GRAPHQL_VARIABLES_MARKER,
2527
GRAPHQL_RESPONSE_MARKER,
28+
GRAPHQL_RESPONSE_IGNORE_ORDER_MARKER,
2629
QUERY_CONFIG_MARKER,
2730
CYPHER_PARAMS_MARKER,
2831
CYPHER_MARKER
@@ -48,9 +51,15 @@ class CypherTestSuite(fileName: String, val neo4j: Neo4j? = null) : AsciiDocTest
4851
}
4952
if (neo4j != null) {
5053
val testData = globalBlocks[TEST_DATA_MARKER]
51-
val response = getOrCreateBlock(codeBlocks, GRAPHQL_RESPONSE_MARKER, "GraphQL-Response")
54+
var response = codeBlocks[GRAPHQL_RESPONSE_IGNORE_ORDER_MARKER]
55+
var ignoreOrder = false;
56+
if (response != null) {
57+
ignoreOrder = true;
58+
} else {
59+
response = getOrCreateBlock(codeBlocks, GRAPHQL_RESPONSE_MARKER, "GraphQL-Response")
60+
}
5261
if (testData != null && response != null) {
53-
tests.add(integrationTest(title, globalBlocks, codeBlocks, testData, response))
62+
tests.add(integrationTest(title, globalBlocks, codeBlocks, testData, response, ignoreOrder))
5463
}
5564
}
5665

@@ -183,7 +192,8 @@ class CypherTestSuite(fileName: String, val neo4j: Neo4j? = null) : AsciiDocTest
183192
globalBlocks: Map<String, ParsedBlock>,
184193
codeBlocks: Map<String, ParsedBlock>,
185194
testData: ParsedBlock,
186-
response: ParsedBlock
195+
response: ParsedBlock,
196+
ignoreOrder: Boolean
187197
): DynamicNode = DynamicTest.dynamicTest("Integration Test", response.uri) {
188198
val dataFetchingInterceptor = setupDataFetchingInterceptor(testData)
189199
val request = codeBlocks[GRAPHQL_MARKER]?.code()
@@ -218,7 +228,27 @@ class CypherTestSuite(fileName: String, val neo4j: Neo4j? = null) : AsciiDocTest
218228
val actualCode = MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(values)
219229
response.adjustedCode = actualCode
220230
}
221-
Assertions.assertThat(actual).isEqualTo(expected)
231+
if (ignoreOrder) {
232+
assertEqualIgnoreOrder(expected, actual)
233+
} else {
234+
Assertions.assertThat(actual).isEqualTo(expected)
235+
}
236+
}
237+
}
238+
239+
private fun assertEqualIgnoreOrder(expected: Any?, actual: Any?) {
240+
when (expected) {
241+
is Map<*, *> -> Assertions.assertThat(actual).asInstanceOf(InstanceOfAssertFactories.MAP)
242+
.hasSize(expected.size)
243+
.containsOnlyKeys(*expected.keys.toTypedArray())
244+
.satisfies { it.forEach { (key, value) -> assertEqualIgnoreOrder(expected[key], value) } }
245+
is Collection<*> -> {
246+
val assertions: List<Consumer<Any>> = expected.map{ e -> Consumer<Any> { a -> assertEqualIgnoreOrder(e, a) } }
247+
Assertions.assertThat(actual).asInstanceOf(InstanceOfAssertFactories.LIST)
248+
.hasSize(expected.size)
249+
.satisfiesExactlyInAnyOrder(*assertions.toTypedArray())
250+
}
251+
else -> Assertions.assertThat(actual).isEqualTo(expected)
222252
}
223253
}
224254

@@ -230,6 +260,7 @@ class CypherTestSuite(fileName: String, val neo4j: Neo4j? = null) : AsciiDocTest
230260
private const val GRAPHQL_MARKER = "[source,graphql]"
231261
private const val GRAPHQL_VARIABLES_MARKER = "[source,json,request=true]"
232262
private const val GRAPHQL_RESPONSE_MARKER = "[source,json,response=true]"
263+
private const val GRAPHQL_RESPONSE_IGNORE_ORDER_MARKER = "[source,json,response=true,ignore-order]"
233264
private const val QUERY_CONFIG_MARKER = "[source,json,query-config=true]"
234265
private const val CYPHER_PARAMS_MARKER = "[source,json]"
235266
}

0 commit comments

Comments
 (0)