pact-foundation / pact-jvm

JVM version of Pact. Enables consumer driven contract testing, providing a mock service and DSL for the consumer project, and interaction playback and verification for the service provider project.
https://docs.pact.io
Apache License 2.0
1.08k stars 479 forks source link

JsonParser does not handle encoding properly on pactbroker.consumerversionselectors.rawjson #1827

Open ksawerykarwacki opened 1 week ago

ksawerykarwacki commented 1 week ago

I tried to pass pactbroker.consumerversionselectors.rawjson parameter to Gradle Test task as system property for my junit tests.

I tried raw string without success, I tried building in with Gson like this:

internal fun getRawPactVersionSelector(): String {
    val jsonArray = JsonArray()

    val mainBranch = JsonObject().apply { addProperty("mainBranch", true) }
    val deployedOrReleased = JsonObject().apply { addProperty("deployedOrReleased", true) }
    val matchingBranch = JsonObject().apply { addProperty("matchingBranch", true) }

    jsonArray.add(mainBranch)
    jsonArray.add(deployedOrReleased)
    jsonArray.add(matchingBranch)

    return Gson().toJson(jsonArray)
}

Finally, after some more debugging it seems it does not properly handle escaping acrost multiple systems. Currently the only working solution looks like this:

internal fun getRawPactVersionSelector(): String {
    if(Os.isFamily(Os.FAMILY_WINDOWS)) {
        return "[{\\\"mainBranch\\\": true}, {\\\"deployedOrReleased\\\": true}, {\\\"matchingBranch\\\": true}]"
    }
    return "[{\"mainBranch\": true}, {\"deployedOrReleased\": true}, {\"matchingBranch\": true}]"
}

If I use windows one then Linux will keep complain about unrecognized \ character

au.com.dius.pact.core.support.json.JsonException: Invalid JSON (1:4), found unexpected character '\'
    at app//au.com.dius.pact.core.support.json.JsonLexer.unexpectedCharacter(JsonParser.kt:87)
    at app//au.com.dius.pact.core.support.json.JsonLexer.nextToken(JsonParser.kt:78)
    at app//au.com.dius.pact.core.support.json.JsonParser.nextTokenOrThrow(JsonParser.kt:278)
    at app//au.com.dius.pact.core.support.json.JsonParser.parseObject(JsonParser.kt:183)
    at app//au.com.dius.pact.core.support.json.JsonParser.parseArray(JsonParser.kt:254)
    at app//au.com.dius.pact.core.support.json.JsonParser.parse(JsonParser.kt:158)
    at app//au.com.dius.pact.core.support.json.JsonParser.parseString(JsonParser.kt:130)

if I use linux version (single ) or any standard lib implementation (like Gson) windows will complain:

 (1:4), found unexpected character 'm'
au.com.dius.pact.core.support.json.JsonException: Invalid JSON (1:4), found unexpected character 'm'
    at au.com.dius.pact.core.support.json.JsonLexer.unexpectedCharacter(JsonParser.kt:87)
    at au.com.dius.pact.core.support.json.JsonLexer.nextToken(JsonParser.kt:78)
    at au.com.dius.pact.core.support.json.JsonParser.nextTokenOrThrow(JsonParser.kt:278)
    at au.com.dius.pact.core.support.json.JsonParser.parseObject(JsonParser.kt:183)
    at au.com.dius.pact.core.support.json.JsonParser.parseArray(JsonParser.kt:254)
    at au.com.dius.pact.core.support.json.JsonParser.parse(JsonParser.kt:158)
    at au.com.dius.pact.core.support.json.JsonParser.parseString(JsonParser.kt:130)
rholshausen commented 1 week ago

What version of Pact-JVM are you using?

ksawerykarwacki commented 6 days ago

4.6.13

rholshausen commented 5 days ago

I have no idea how to replicate this. This test https://github.com/pact-foundation/pact-jvm/blob/master/core/support/src/test/java/au/com/dius/pact/core/support/json/JsonParserTest.java runs on my Windows machine and also on the GitHub Windows agent (see https://github.com/pact-foundation/pact-jvm/actions/runs/11043621468/job/30678203735) without any issue.

The JSON parser uses java.lang.Character to check the chars in the string, and according to the Java docs the escape sequences are platform independent. There must be something on your system that is modifying the string values on Windows.

MitchelNijdam-Rockstars commented 3 days ago

I have the same problem. I have a feeling it's because of how the shells handle systemProperties in Windows differently than on MacOS.

Also there seems to be a difference when run from Intellij or from shell directly.