Skip to content

Commit 79c8c83

Browse files
committed
add utility to set ignore-order for integration tests
1 parent 797a974 commit 79c8c83

File tree

28 files changed

+137
-72
lines changed

28 files changed

+137
-72
lines changed

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

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import kotlin.reflect.KMutableProperty1
2525
* @param relevantBlocks a list of pairs of filter functions and properties to set the found code blocks
2626
*/
2727
abstract class AsciiDocTestSuite<T>(
28-
private val fileName: String,
28+
protected val fileName: String,
2929
private val relevantBlocks: List<CodeBlockMatcher<T>>,
3030
private val createMissingBlocks: Boolean = true
3131
) {
@@ -69,9 +69,14 @@ abstract class AsciiDocTestSuite<T>(
6969
)
7070
}
7171

72+
addAdditionalTests(tests)
73+
7274
return if (FLATTEN_TESTS) flatten(tests.stream(), "$fileName:") else tests.stream()
7375
}
7476

77+
open fun addAdditionalTests(tests: MutableList<DynamicNode>) {
78+
}
79+
7580
private fun createTestsOfSection(section: Section, parentIgnoreReason: String? = null): List<DynamicNode> {
7681

7782
val tests = mutableListOf<DynamicNode>()
@@ -90,7 +95,7 @@ abstract class AsciiDocTestSuite<T>(
9095
}
9196

9297
is Table -> {
93-
if (testCase != null){
98+
if (testCase != null) {
9499
setTableData(testCase, node)
95100
}
96101
}
@@ -148,21 +153,17 @@ abstract class AsciiDocTestSuite<T>(
148153
}
149154

150155
private fun writeAdjustedTestFile() {
151-
val content = generateAdjustedFileContent({ block ->
152-
block.generatedContent.takeIf {
153-
when {
154-
UPDATE_SEMANTIC_EQUALLY_BLOCKS -> block.semanticEqual && (block.tandemUpdate?.semanticEqual ?: true)
155-
else -> true
156-
}
157-
}
158-
})
156+
val content = generateAdjustedFileContent(
157+
{ it.generatedContent },
158+
{ !UPDATE_SEMANTIC_EQUALLY_BLOCKS || (it.semanticEqual && (it.tandemUpdate?.semanticEqual ?: true)) }
159+
)
159160
FileWriter(File("src/test/resources/", fileName)).use {
160161
it.write(content)
161162
}
162163
}
163164

164165
private fun reformatTestFile() {
165-
val content = generateAdjustedFileContent { it.reformattedContent }
166+
val content = generateAdjustedFileContent({ it.reformattedContent })
166167
FileWriter(File("src/test/resources/", fileName)).use {
167168
it.write(content)
168169
}
@@ -179,19 +180,25 @@ abstract class AsciiDocTestSuite<T>(
179180
}
180181
}
181182

182-
private fun generateAdjustedFileContent(extractor: (CodeBlock) -> String? = { it.generatedContent }): String {
183+
protected fun generateAdjustedFileContent(
184+
extractor: (CodeBlock) -> String? = { it.generatedContent },
185+
matcher: (CodeBlock) -> Boolean = { extractor(it) != null }
186+
): String {
183187
knownBlocks.sortWith(compareByDescending { it.start })
184188
val rebuildTest = StringBuffer(document.content)
185-
knownBlocks.filter { extractor(it) != null }
189+
knownBlocks.filter { matcher(it) }
186190
.forEach { block ->
187191
val start = block.start ?: error("unknown start position")
188192
if (block.end == null) {
189193
rebuildTest.insert(
190194
start,
191-
".${block.caption}\n${block.marker}\n----\n${extractor(block)}\n----\n\n"
195+
".${block.caption}\n${block.adjustedMarker}\n----\n${extractor(block)}\n----\n\n"
192196
)
193197
} else {
194198
rebuildTest.replace(start, block.end!!, extractor(block) + "\n")
199+
if (block.markerStart != null) {
200+
rebuildTest.replace(block.markerStart!!, block.markerEnd!!, block.adjustedMarker)
201+
}
195202
}
196203
}
197204
return rebuildTest.toString()
@@ -221,19 +228,28 @@ abstract class AsciiDocTestSuite<T>(
221228
* to find broken tests easy by its console output, enable this feature
222229
*/
223230
val FLATTEN_TESTS = System.getProperty("neo4j-graphql-java.flatten-tests", "false") == "true"
224-
val GENERATE_TEST_FILE_DIFF = System.getProperty("neo4j-graphql-java.generate-test-file-diff", "false") == "true"
231+
val GENERATE_TEST_FILE_DIFF =
232+
System.getProperty("neo4j-graphql-java.generate-test-file-diff", "false") == "true"
225233
val REFORMAT_TEST_FILE = System.getProperty("neo4j-graphql-java.reformat", "false") == "true"
226234
val UPDATE_TEST_FILE = System.getProperty("neo4j-graphql-java.update-test-file", "false") == "true"
227235
val UPDATE_SEMANTIC_EQUALLY_BLOCKS =
228236
System.getProperty("neo4j-graphql-java.update-semantic-equally-blocks", "false") == "true"
229237
val MAPPER = ObjectMapper()
230238
.registerKotlinModule()
231239
.registerModules(JavaTimeModule())
232-
.registerModule(SimpleModule().addSerializer(TemporalAmount::class.java, object : JsonSerializer<TemporalAmount?>() {
233-
override fun serialize(value: TemporalAmount?, gen: JsonGenerator?, serializers: SerializerProvider?) {
234-
gen?.writeString(value.toString())
235-
}
236-
}))
240+
.registerModule(
241+
SimpleModule().addSerializer(
242+
TemporalAmount::class.java,
243+
object : JsonSerializer<TemporalAmount?>() {
244+
override fun serialize(
245+
value: TemporalAmount?,
246+
gen: JsonGenerator?,
247+
serializers: SerializerProvider?
248+
) {
249+
gen?.writeString(value.toString())
250+
}
251+
})
252+
)
237253
.disable(com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
238254
.disable(com.fasterxml.jackson.databind.SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS)
239255

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

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.neo4j.graphql.utils
22

3+
import com.fasterxml.jackson.module.kotlin.readValue
34
import com.jayway.jsonpath.JsonPath
45
import demo.org.neo4j.graphql.utils.InvalidQueryException
56
import demo.org.neo4j.graphql.utils.asciidoc.ast.CodeBlock
@@ -35,6 +36,7 @@ import org.neo4j.graphql.scalars.TemporalScalar
3536
import org.opentest4j.AssertionFailedError
3637
import org.threeten.extra.PeriodDuration
3738
import java.io.File
39+
import java.io.FileWriter
3840
import java.math.BigInteger
3941
import java.time.*
4042
import java.time.format.DateTimeFormatter
@@ -43,7 +45,6 @@ import java.time.temporal.TemporalAccessor
4345
import java.util.*
4446
import java.util.concurrent.FutureTask
4547
import java.util.function.Consumer
46-
import java.util.regex.Pattern
4748
import kotlin.reflect.full.findAnnotation
4849

4950
class CypherTestSuite(fileName: String, val driver: Driver? = null, createMissingBlocks: Boolean = true) :
@@ -91,6 +92,12 @@ class CypherTestSuite(fileName: String, val driver: Driver? = null, createMissin
9192
}
9293
}
9394

95+
override fun addAdditionalTests(tests: MutableList<DynamicNode>) {
96+
if (ADD_IGNORE_ORDER_TO_INTEGRATION_TESTS) {
97+
tests += DynamicTest.dynamicTest("Create ignore-order", srcLocation, this::reformatMarker)
98+
}
99+
}
100+
94101
override fun createTests(testCase: TestCase, section: Section, ignoreReason: String?): List<DynamicNode> {
95102
if (testCase.graphqlRequest == null) {
96103
return emptyList()
@@ -104,6 +111,18 @@ class CypherTestSuite(fileName: String, val driver: Driver? = null, createMissin
104111
val result = createTransformationTask(testCase)
105112

106113
val tests = mutableListOf<DynamicNode>()
114+
115+
if (ADD_IGNORE_ORDER_TO_INTEGRATION_TESTS) {
116+
val hasOrder = testCase.cypher.any { it.content.contains("ORDER BY") }
117+
val graphqlResponse = testCase.graphqlResponse
118+
if (!hasOrder && graphqlResponse != null
119+
&& hasArrayWithMoreThenOneItems(MAPPER.readValue<Any>(graphqlResponse.content))
120+
) {
121+
graphqlResponse.adjustedAttributes = graphqlResponse.attributes.toMutableMap()
122+
.also { it["ignore-order"] = null }
123+
}
124+
}
125+
107126
if (DEBUG) {
108127
tests.add(printGeneratedQuery(result))
109128
tests.add(printReplacedParameter(result))
@@ -153,6 +172,22 @@ class CypherTestSuite(fileName: String, val driver: Driver? = null, createMissin
153172
return tests
154173
}
155174

175+
private fun hasArrayWithMoreThenOneItems(value: Any): Boolean {
176+
when (value) {
177+
is Map<*, *> -> {
178+
return value.any {
179+
val mapValue = it.value
180+
mapValue != null && hasArrayWithMoreThenOneItems(mapValue)
181+
}
182+
}
183+
184+
is Collection<*> -> {
185+
return value.size > 1 || value.filterNotNull().any { hasArrayWithMoreThenOneItems(it) }
186+
}
187+
}
188+
return false
189+
}
190+
156191
private fun createSchema(
157192
schemaBlock: CodeBlock,
158193
schemaConfigBlock: CodeBlock?,
@@ -509,11 +544,17 @@ class CypherTestSuite(fileName: String, val driver: Driver? = null, createMissin
509544
}
510545
}
511546

547+
548+
private fun reformatMarker() {
549+
val content = generateAdjustedFileContent({ it.content }, { it.adjustedAttributes != null })
550+
FileWriter(File("src/test/resources/", fileName)).use { it.write(content) }
551+
}
552+
512553
companion object {
513554
private val DEBUG = System.getProperty("neo4j-graphql-java.debug", "false") == "true"
514555
private val CONVERT_NUMBER = System.getProperty("neo4j-graphql-java.convert-number", "true") == "true"
515-
516-
private val DURATION_PATTERN: Pattern = Pattern.compile("^P(.*?)(?:T(.*))?$")
556+
private val ADD_IGNORE_ORDER_TO_INTEGRATION_TESTS =
557+
System.getProperty("neo4j-graphql-java.add-ignore-order-to-integration-tests", "false") == "true"
517558

518559
private val PARSE_OPTIONS = Options.newOptions()
519560
.createSortedMaps(true)

core/src/test/kotlin/org/neo4j/graphql/utils/asciidoc/AsciiDocParser.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ class AsciiDocParser(
9393

9494
currentCodeBlock = CodeBlock(uri, language, currentSection, attributes).also {
9595
it.caption = caption
96+
it.markerStart = offset
97+
it.markerEnd = offset + line.length
9698
currentSection.blocks.add(it)
9799
}
98100
caption = null

core/src/test/kotlin/org/neo4j/graphql/utils/asciidoc/ast/CodeBlock.kt

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ class CodeBlock(
1111

1212
var caption: String? = null
1313

14+
var markerStart: Int? = null
15+
var markerEnd: Int? = null
1416
var start: Int? = null
1517
var end: Int? = null
1618

@@ -33,11 +35,15 @@ class CodeBlock(
3335
*/
3436
var tandemUpdate: CodeBlock? = null
3537

36-
val marker: String
37-
get() = "[source,$language${attributes.map { ",${it.key}${it.value?.let { "=${it}" } ?: ""}" }.joinToString()}]"
38+
var adjustedAttributes: MutableMap<String, String?>? = null
39+
40+
val adjustedMarker: String
41+
get() = "[source,$language${
42+
(adjustedAttributes ?: attributes).map { ",${it.key}${it.value?.let { "=${it}" } ?: ""}" }.joinToString("")
43+
}]"
3844

3945
override fun toString(): String {
40-
return "CodeBlock(language='$language', attributes=$attributes)"
46+
return "CodeBlock(language='$language', attributes=$attributes${adjustedAttributes?.let { ", adjustedAttributes=$it" } ?: ""})"
4147
}
4248

4349
fun matches(language: String, filter: Map<String, String?> = emptyMap(), exactly: Boolean = false) =

core/src/test/resources/integration-test-files/config-options/query-options.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ RETURN this {
6565
----
6666

6767
.GraphQL-Response
68-
[source,json,response=true]
68+
[source,json,response=true,ignore-order]
6969
----
7070
{
7171
"movies": [

core/src/test/resources/integration-test-files/connections/alias.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1431,7 +1431,7 @@ RETURN this {
14311431
----
14321432

14331433
.GraphQL-Response
1434-
[source,json,response=true]
1434+
[source,json,response=true,ignore-order]
14351435
----
14361436
{
14371437
"posts": [

core/src/test/resources/integration-test-files/connections/unions.adoc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ RETURN this {
133133
----
134134

135135
.GraphQL-Response
136-
[source,json,response=true]
136+
[source,json,response=true,ignore-order]
137137
----
138138
{
139139
"authors": [
@@ -927,7 +927,7 @@ RETURN this {
927927
----
928928

929929
.GraphQL-Response
930-
[source,json,response=true]
930+
[source,json,response=true,ignore-order]
931931
----
932932
{
933933
"authors": [
@@ -1172,7 +1172,7 @@ RETURN this {
11721172
----
11731173

11741174
.GraphQL-Response
1175-
[source,json,response=true]
1175+
[source,json,response=true,ignore-order]
11761176
----
11771177
{
11781178
"authors": [

core/src/test/resources/integration-test-files/custom-scalar-filtering.adoc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ RETURN this {
113113
----
114114

115115
.GraphQL-Response
116-
[source,json,response=true]
116+
[source,json,response=true,ignore-order]
117117
----
118118
{
119119
"movies": [
@@ -229,7 +229,7 @@ RETURN this {
229229
----
230230

231231
.GraphQL-Response
232-
[source,json,response=true]
232+
[source,json,response=true,ignore-order]
233233
----
234234
{
235235
"movies": [

core/src/test/resources/integration-test-files/directives/customResolver.adoc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,7 @@ RETURN this {
658658
----
659659

660660
.GraphQL-Response
661-
[source,json,response=true]
661+
[source,json,response=true,ignore-order]
662662
----
663663
{
664664
"users": [
@@ -772,7 +772,7 @@ RETURN this {
772772
----
773773

774774
.GraphQL-Response
775-
[source,json,response=true]
775+
[source,json,response=true,ignore-order]
776776
----
777777
{
778778
"users": [

0 commit comments

Comments
 (0)