ekino / jcv

JSON Content Validator (JCV) allows you to compare JSON contents with embedded validation.
https://ekino.github.io/jcv
MIT License
21 stars 0 forks source link

Make jsonMatcher strict by default #25

Open clemstoquart opened 2 years ago

clemstoquart commented 2 years ago

Hello, I was wondering if it would be nicer to have the usually used jsonMatcher() method strict by default (.mode(JSONCompareMode.STRICT)). Moreover we could add another method like unorderedJsonMatcher() to perform assertions when the order can change.

This would be somehow like what we have in assertj.

What do you think about that ?

leomillon commented 2 years ago

Hello!

Could you provide examples of code to show how you would like to use it?

First of all, I think that it would be a bad thing to change the actual behavior of jsonMatcher() (assuming you are talking about com.ekino.oss.jcv.assertion.hamcrest.JsonMatchers#jsonMatcher) because that would be a breaking change.

But if you want we can add other default methods like jsonStrictMatcher() for example.

And if you don't already know, it's possible to use the provided com.ekino.oss.jcv.assertion.hamcrest.JsonMatcherBuilder like this in your project:

import org.hamcrest.Matcher;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.skyscreamer.jsonassert.JSONCompareMode;

import static org.hamcrest.MatcherAssert.assertThat;

    @Test
    void should_match_with_custom_comparator() {

        assertThat(
            // language=json
            "{\"field_name\": \"hello world!\"}",
            jsonStrictMatcher(
                // language=json
                "{\"field_name\": \"{#contains:llo wor#}\"}"
            )
        );
    }

    private static Matcher<String> jsonStrictMatcher(String expectedJson) {
        return JsonMatcherBuilder.create()
            .mode(JSONCompareMode.STRICT)
            .build(expectedJson);
    }

Just keep in mind also that the "mode" is a matrix of multiple configurations so if we add unorderedJsonMatcher() does it mean that it allows extensibility or not?


org.skyscreamer.jsonassert.JSONCompareMode

These different modes define different behavior for the comparison of JSON for testing. Each mode encapsulates two underlying behaviors: extensibility and strict ordering.

  Extensible Strict Ordering
STRICT no yes
LENIENT yes no
NON_EXTENSIBLE no no
STRICT_ORDER yes yes

If extensibility not allowed, then all of the expected values must match in what's being tested, but any additional fields will cause the test to fail. When extensibility is allowed, all values must still match. For example, if you're expecting:

{id:1,name:"Carter"}

Then the following will pass when extensible, and will fail when not:

{id:1,name:"Carter",favoriteColor:"blue"}

If strict ordering is enabled, JSON arrays must be in strict sequence. For example, if you're expecting:

{id:1,friends:[{id:2},{id:3}]}

Then the following will fail strict ordering, but will otherwise pass:

{id:1,friends:[{id:3},{id:2}]}


Knowing that the actual default behavior across all JCV modules is: NON_EXTENSIBLE