Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make jsonMatcher strict by default #25

Open
clemstoquart opened this issue Mar 30, 2022 · 1 comment
Open

Make jsonMatcher strict by default #25

clemstoquart opened this issue Mar 30, 2022 · 1 comment
Labels
enhancement New feature or request question Further information is requested

Comments

@clemstoquart
Copy link
Collaborator

clemstoquart commented Mar 30, 2022

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
Copy link
Collaborator

leomillon commented Mar 30, 2022

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

@leomillon leomillon added enhancement New feature or request question Further information is requested labels Mar 30, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants