Skip to content

Commit

Permalink
add utility to set ignore-order for integration tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Andy2003 committed Dec 12, 2024
1 parent 797a974 commit 79c8c83
Show file tree
Hide file tree
Showing 28 changed files with 137 additions and 72 deletions.
56 changes: 36 additions & 20 deletions core/src/test/kotlin/org/neo4j/graphql/utils/AsciiDocTestSuite.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import kotlin.reflect.KMutableProperty1
* @param relevantBlocks a list of pairs of filter functions and properties to set the found code blocks
*/
abstract class AsciiDocTestSuite<T>(
private val fileName: String,
protected val fileName: String,
private val relevantBlocks: List<CodeBlockMatcher<T>>,
private val createMissingBlocks: Boolean = true
) {
Expand Down Expand Up @@ -69,9 +69,14 @@ abstract class AsciiDocTestSuite<T>(
)
}

addAdditionalTests(tests)

return if (FLATTEN_TESTS) flatten(tests.stream(), "$fileName:") else tests.stream()
}

open fun addAdditionalTests(tests: MutableList<DynamicNode>) {
}

private fun createTestsOfSection(section: Section, parentIgnoreReason: String? = null): List<DynamicNode> {

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

is Table -> {
if (testCase != null){
if (testCase != null) {
setTableData(testCase, node)
}
}
Expand Down Expand Up @@ -148,21 +153,17 @@ abstract class AsciiDocTestSuite<T>(
}

private fun writeAdjustedTestFile() {
val content = generateAdjustedFileContent({ block ->
block.generatedContent.takeIf {
when {
UPDATE_SEMANTIC_EQUALLY_BLOCKS -> block.semanticEqual && (block.tandemUpdate?.semanticEqual ?: true)
else -> true
}
}
})
val content = generateAdjustedFileContent(
{ it.generatedContent },
{ !UPDATE_SEMANTIC_EQUALLY_BLOCKS || (it.semanticEqual && (it.tandemUpdate?.semanticEqual ?: true)) }
)
FileWriter(File("src/test/resources/", fileName)).use {
it.write(content)
}
}

private fun reformatTestFile() {
val content = generateAdjustedFileContent { it.reformattedContent }
val content = generateAdjustedFileContent({ it.reformattedContent })
FileWriter(File("src/test/resources/", fileName)).use {
it.write(content)
}
Expand All @@ -179,19 +180,25 @@ abstract class AsciiDocTestSuite<T>(
}
}

private fun generateAdjustedFileContent(extractor: (CodeBlock) -> String? = { it.generatedContent }): String {
protected fun generateAdjustedFileContent(
extractor: (CodeBlock) -> String? = { it.generatedContent },
matcher: (CodeBlock) -> Boolean = { extractor(it) != null }
): String {
knownBlocks.sortWith(compareByDescending { it.start })
val rebuildTest = StringBuffer(document.content)
knownBlocks.filter { extractor(it) != null }
knownBlocks.filter { matcher(it) }
.forEach { block ->
val start = block.start ?: error("unknown start position")
if (block.end == null) {
rebuildTest.insert(
start,
".${block.caption}\n${block.marker}\n----\n${extractor(block)}\n----\n\n"
".${block.caption}\n${block.adjustedMarker}\n----\n${extractor(block)}\n----\n\n"
)
} else {
rebuildTest.replace(start, block.end!!, extractor(block) + "\n")
if (block.markerStart != null) {
rebuildTest.replace(block.markerStart!!, block.markerEnd!!, block.adjustedMarker)
}
}
}
return rebuildTest.toString()
Expand Down Expand Up @@ -221,19 +228,28 @@ abstract class AsciiDocTestSuite<T>(
* to find broken tests easy by its console output, enable this feature
*/
val FLATTEN_TESTS = System.getProperty("neo4j-graphql-java.flatten-tests", "false") == "true"
val GENERATE_TEST_FILE_DIFF = System.getProperty("neo4j-graphql-java.generate-test-file-diff", "false") == "true"
val GENERATE_TEST_FILE_DIFF =
System.getProperty("neo4j-graphql-java.generate-test-file-diff", "false") == "true"
val REFORMAT_TEST_FILE = System.getProperty("neo4j-graphql-java.reformat", "false") == "true"
val UPDATE_TEST_FILE = System.getProperty("neo4j-graphql-java.update-test-file", "false") == "true"
val UPDATE_SEMANTIC_EQUALLY_BLOCKS =
System.getProperty("neo4j-graphql-java.update-semantic-equally-blocks", "false") == "true"
val MAPPER = ObjectMapper()
.registerKotlinModule()
.registerModules(JavaTimeModule())
.registerModule(SimpleModule().addSerializer(TemporalAmount::class.java, object : JsonSerializer<TemporalAmount?>() {
override fun serialize(value: TemporalAmount?, gen: JsonGenerator?, serializers: SerializerProvider?) {
gen?.writeString(value.toString())
}
}))
.registerModule(
SimpleModule().addSerializer(
TemporalAmount::class.java,
object : JsonSerializer<TemporalAmount?>() {
override fun serialize(
value: TemporalAmount?,
gen: JsonGenerator?,
serializers: SerializerProvider?
) {
gen?.writeString(value.toString())
}
})
)
.disable(com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.disable(com.fasterxml.jackson.databind.SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS)

Expand Down
47 changes: 44 additions & 3 deletions core/src/test/kotlin/org/neo4j/graphql/utils/CypherTestSuite.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.neo4j.graphql.utils

import com.fasterxml.jackson.module.kotlin.readValue
import com.jayway.jsonpath.JsonPath
import demo.org.neo4j.graphql.utils.InvalidQueryException
import demo.org.neo4j.graphql.utils.asciidoc.ast.CodeBlock
Expand Down Expand Up @@ -35,6 +36,7 @@ import org.neo4j.graphql.scalars.TemporalScalar
import org.opentest4j.AssertionFailedError
import org.threeten.extra.PeriodDuration
import java.io.File
import java.io.FileWriter
import java.math.BigInteger
import java.time.*
import java.time.format.DateTimeFormatter
Expand All @@ -43,7 +45,6 @@ import java.time.temporal.TemporalAccessor
import java.util.*
import java.util.concurrent.FutureTask
import java.util.function.Consumer
import java.util.regex.Pattern
import kotlin.reflect.full.findAnnotation

class CypherTestSuite(fileName: String, val driver: Driver? = null, createMissingBlocks: Boolean = true) :
Expand Down Expand Up @@ -91,6 +92,12 @@ class CypherTestSuite(fileName: String, val driver: Driver? = null, createMissin
}
}

override fun addAdditionalTests(tests: MutableList<DynamicNode>) {
if (ADD_IGNORE_ORDER_TO_INTEGRATION_TESTS) {
tests += DynamicTest.dynamicTest("Create ignore-order", srcLocation, this::reformatMarker)
}
}

override fun createTests(testCase: TestCase, section: Section, ignoreReason: String?): List<DynamicNode> {
if (testCase.graphqlRequest == null) {
return emptyList()
Expand All @@ -104,6 +111,18 @@ class CypherTestSuite(fileName: String, val driver: Driver? = null, createMissin
val result = createTransformationTask(testCase)

val tests = mutableListOf<DynamicNode>()

if (ADD_IGNORE_ORDER_TO_INTEGRATION_TESTS) {
val hasOrder = testCase.cypher.any { it.content.contains("ORDER BY") }
val graphqlResponse = testCase.graphqlResponse
if (!hasOrder && graphqlResponse != null
&& hasArrayWithMoreThenOneItems(MAPPER.readValue<Any>(graphqlResponse.content))
) {
graphqlResponse.adjustedAttributes = graphqlResponse.attributes.toMutableMap()
.also { it["ignore-order"] = null }
}
}

if (DEBUG) {
tests.add(printGeneratedQuery(result))
tests.add(printReplacedParameter(result))
Expand Down Expand Up @@ -153,6 +172,22 @@ class CypherTestSuite(fileName: String, val driver: Driver? = null, createMissin
return tests
}

private fun hasArrayWithMoreThenOneItems(value: Any): Boolean {
when (value) {
is Map<*, *> -> {
return value.any {
val mapValue = it.value
mapValue != null && hasArrayWithMoreThenOneItems(mapValue)
}
}

is Collection<*> -> {
return value.size > 1 || value.filterNotNull().any { hasArrayWithMoreThenOneItems(it) }
}
}
return false
}

private fun createSchema(
schemaBlock: CodeBlock,
schemaConfigBlock: CodeBlock?,
Expand Down Expand Up @@ -509,11 +544,17 @@ class CypherTestSuite(fileName: String, val driver: Driver? = null, createMissin
}
}


private fun reformatMarker() {
val content = generateAdjustedFileContent({ it.content }, { it.adjustedAttributes != null })
FileWriter(File("src/test/resources/", fileName)).use { it.write(content) }
}

companion object {
private val DEBUG = System.getProperty("neo4j-graphql-java.debug", "false") == "true"
private val CONVERT_NUMBER = System.getProperty("neo4j-graphql-java.convert-number", "true") == "true"

private val DURATION_PATTERN: Pattern = Pattern.compile("^P(.*?)(?:T(.*))?$")
private val ADD_IGNORE_ORDER_TO_INTEGRATION_TESTS =
System.getProperty("neo4j-graphql-java.add-ignore-order-to-integration-tests", "false") == "true"

private val PARSE_OPTIONS = Options.newOptions()
.createSortedMaps(true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ class AsciiDocParser(

currentCodeBlock = CodeBlock(uri, language, currentSection, attributes).also {
it.caption = caption
it.markerStart = offset
it.markerEnd = offset + line.length
currentSection.blocks.add(it)
}
caption = null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ class CodeBlock(

var caption: String? = null

var markerStart: Int? = null
var markerEnd: Int? = null
var start: Int? = null
var end: Int? = null

Expand All @@ -33,11 +35,15 @@ class CodeBlock(
*/
var tandemUpdate: CodeBlock? = null

val marker: String
get() = "[source,$language${attributes.map { ",${it.key}${it.value?.let { "=${it}" } ?: ""}" }.joinToString()}]"
var adjustedAttributes: MutableMap<String, String?>? = null

val adjustedMarker: String
get() = "[source,$language${
(adjustedAttributes ?: attributes).map { ",${it.key}${it.value?.let { "=${it}" } ?: ""}" }.joinToString("")
}]"

override fun toString(): String {
return "CodeBlock(language='$language', attributes=$attributes)"
return "CodeBlock(language='$language', attributes=$attributes${adjustedAttributes?.let { ", adjustedAttributes=$it" } ?: ""})"
}

fun matches(language: String, filter: Map<String, String?> = emptyMap(), exactly: Boolean = false) =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ RETURN this {
----

.GraphQL-Response
[source,json,response=true]
[source,json,response=true,ignore-order]
----
{
"movies": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1431,7 +1431,7 @@ RETURN this {
----

.GraphQL-Response
[source,json,response=true]
[source,json,response=true,ignore-order]
----
{
"posts": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ RETURN this {
----

.GraphQL-Response
[source,json,response=true]
[source,json,response=true,ignore-order]
----
{
"authors": [
Expand Down Expand Up @@ -927,7 +927,7 @@ RETURN this {
----

.GraphQL-Response
[source,json,response=true]
[source,json,response=true,ignore-order]
----
{
"authors": [
Expand Down Expand Up @@ -1172,7 +1172,7 @@ RETURN this {
----

.GraphQL-Response
[source,json,response=true]
[source,json,response=true,ignore-order]
----
{
"authors": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ RETURN this {
----

.GraphQL-Response
[source,json,response=true]
[source,json,response=true,ignore-order]
----
{
"movies": [
Expand Down Expand Up @@ -229,7 +229,7 @@ RETURN this {
----

.GraphQL-Response
[source,json,response=true]
[source,json,response=true,ignore-order]
----
{
"movies": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -658,7 +658,7 @@ RETURN this {
----

.GraphQL-Response
[source,json,response=true]
[source,json,response=true,ignore-order]
----
{
"users": [
Expand Down Expand Up @@ -772,7 +772,7 @@ RETURN this {
----

.GraphQL-Response
[source,json,response=true]
[source,json,response=true,ignore-order]
----
{
"users": [
Expand Down
Loading

0 comments on commit 79c8c83

Please sign in to comment.