webcompere / model-assert

Assertions for data models
MIT License
28 stars 3 forks source link

Problem with single and double quotes #44

Closed ghost closed 8 months ago

ghost commented 1 year ago

Summary

I am trying Model Assert for the first time, and I got this kind of errors, which I don't have with other Test packages (like com.toomuchcoding.jsonassert or the SpringBoot JsonAssert test library). Basically if I have a string with double quote is works, but if I use single quotes it doesn't work.

Json Examples

Doesn't works:

{name: 'duke', age: 42}

and this one works:

{name: "duke", age: 42}

Expected green or red test

Basically if I have this simple test:

    @Test
    void itWorksModelAssert() throws Exception {
        String result = "{name: \"duke\", age: 42}";
        JsonAssertions.assertJson(result).at("/name").isText("duke");
    }

    @Test
    void itDoesNotWorkModelAssert() throws Exception {
        String result = "{name: 'duke', age: 42}";
        JsonAssertions.assertJson(result).at("/name").isText("duke");
    }

I get the following error:

Caused by: com.fasterxml.jackson.core.JsonParseException: Unexpected character (''' (code 39)): expected a valid value (JSON String, Number, Array, Object or token 'null', 'true' or 'false')

I understand this is an jackson json parsing exception, but when I am using other test libraries, I don't have such errors, even with a single quote. Should I change something somewhere, or is it a bug on your side?

Basically I am expecting that both tests works...

ghost commented 1 year ago

Just for the sake of being complete, here are other libraries where is works:

    @Test
    void dukeAgeJsonAssert() throws Exception {
        String result = "{name: 'duke', age: 42}";
        org.skyscreamer.jsonassert.JSONAssert.assertEquals("{name: 'duke'}", result, false);
    }

    @Test
    void dukeAgeJsonAssertion() throws Exception {
        String result = "{name: 'duke', age: 42}";
        com.toomuchcoding.jsonassert.JsonAssertion.assertThat(result).field("name").isEqualTo("duke");
    }
ashleyfrieze commented 1 year ago

Hey @AlessandroPerucchi - it's worth noting that the ' notation isn't valid JSON. However, I think there's a workaround, and maybe we can extend the library in the future to make the workaround a default, or easier.

The assertThat( ) function will take a string, but it will also take a parsed bit of JSON as a JsonNode. So the workaround is to create your own ObjectMapper in jackson, work out the configuration that you need to make Jackson accept ' and then use that ObjectMapper to produce the JsonNode.

ashleyfrieze commented 1 year ago

As it stands, the OBJECTMAPPER instance here - https://github.com/webcompere/model-assert/blob/main/src/main/java/uk/org/webcompere/modelassert/json/JsonProviders.java#L16 is used to parse JSON and has been set up to allow unquoted field names. We could relax this further, or provide some sort of customisation function for it.

Why don't you have a play around with ObjectMapper and see what you need, then if you can turn it into a more precise request, or even a PR, we can look at how to accommodate you.

I'd be interested in feedback on the library in general, and whether it's meeting your needs for more flexible and fluent JSON assertions.

ashleyfrieze commented 1 year ago

c.f. #41

ashleyfrieze commented 1 year ago

@AlessandroPerucchi - any further thoughts on this one?