Giter VIP home page Giter VIP logo

jsonassert's Introduction

JSONassert

Write JSON unit tests in less code. Great for testing REST interfaces.

Summary

Write JSON tests as if you are comparing a string. Under the covers, JSONassert converts your string into a JSON object and compares the logical structure and data with the actual JSON. When strict is set to false (recommended), it forgives reordering data and extending results (as long as all the expected elements are there), making tests less brittle.

Supported test frameworks:

Examples

In JSONassert you write and maintain something like this:

JSONObject data = getRESTData("/friends/367.json");
String expected = "{friends:[{id:123,name:\"Corby Page\"},{id:456,name:\"Carter Page\"}]}";
JSONAssert.assertEquals(expected, data, false);

instead of all this:


JSONObject data = getRESTData("/friends/367.json");
Assert.assertTrue(data.has("friends"));
Object friendsObject = data.get("friends");
Assert.assertTrue(friendsObject instanceof JSONArray);
JSONArray friends = (JSONArray) friendsObject;
Assert.assertEquals(2, friends.length());
JSONObject friend1Obj = friends.getJSONObject(0);
Assert.assertTrue(friend1Obj.has("id"));
Assert.assertTrue(friend1Obj.has("name"));
JSONObject friend2Obj = friends.getJSONObject(1);
Assert.assertTrue(friend2Obj.has("id"));
Assert.assertTrue(friend2Obj.has("name"));

if ("Carter Page".equals(friend1Obj.getString("name"))) {
    Assert.assertEquals(456, friend1Obj.getInt("id"));
    Assert.assertEquals("Corby Page", friend2Obj.getString("name"));
    Assert.assertEquals(123, friend2Obj.getInt("id"));
}
else if ("Corby Page".equals(friend1Obj.getString("name"))) {
    Assert.assertEquals(123, friend1Obj.getInt("id"));
    Assert.assertEquals("Carter Page", friend2Obj.getString("name"));
    Assert.assertEquals(456, friend2Obj.getInt("id"));
}
else {
    Assert.fail("Expected either Carter or Corby, Got: " + friend1Obj.getString("name"));
}

Error Messages

We tried to make error messages easy to understand. This is really important, since it gets hard for the eye to pick out the difference, particularly in long JSON strings. For example:

String expected = "{id:1,name:\"Joe\",friends:[{id:2,name:\"Pat\",pets:[\"dog\"]},{id:3,name:\"Sue\",pets:[\"bird\",\"fish\"]}],pets:[]}";
String actual = "{id:1,name:\"Joe\",friends:[{id:2,name:\"Pat\",pets:[\"dog\"]},{id:3,name:\"Sue\",pets:[\"cat\",\"fish\"]}],pets:[]}"
JSONAssert.assertEquals(expected, actual, false);

returns the following:

friends[id=3].pets[]: Expected bird, but not found ; friends[id=3].pets[]: Contains cat, but not expected

Which tells you that the pets array under the friend where id=3 was supposed to contain "bird", but had "cat" instead. (Maybe the cat ate the bird?)


QuickStart

To use, download the JAR or add the following to your project's pom.xml:

<dependency>
    <groupId>org.skyscreamer</groupId>
    <artifactId>jsonassert</artifactId>
    <version>1.5.1</version>
    <scope>test</scope>
</dependency>

Write tests like this:

JSONAssert.assertEquals(expectedJSONString, actualJSON, strictMode);

More examples in our cookbook


Who uses JSONassert?


org.json

This implementation uses a clean-room implementation of the org.json library implemented for the Android system, released under the Apache 2.0 license. See com.vaadin.external.google:android-json That jar does not include the org.json.JSONString interface, so a new implementation of that interface is added to this source.

Resources

JavaDoc

jsonassert's People

Contributors

acourtneybrown avatar adrianacala avatar aivean avatar anantharaman-g-3327 avatar aukevanleeuwen avatar billmag avatar carterpage avatar dependabot[bot] avatar hertzsprung avatar imanushin avatar jakob-o avatar martinvw avatar puntogil avatar riccorazza avatar rushikeshnaiknaware avatar ststo avatar sv3ndk avatar twr avatar yasin3061 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jsonassert's Issues

RegularExpressionValueMatcher + Array = Bug? Missing Feature?

During evaluation of JSON assert tools I figured out that seems RegularExpressionValueMatcher seems not working as designed. Here are some minimal codes:

Simpe test checking if the value x is a digit.

// Working - example without Array
JSONAssert.assertEquals("{\"entry\":{\"id\":x}}", "{\"entry\":{\"id\":1}}", new CustomComparator(JSONCompareMode.STRICT_ORDER, new Customization("entry.id", new RegularExpressionValueMatcher<Object>("\\d"))));

// Working - example with Array (only one item)
JSONAssert.assertEquals("{\"entries\":[{\"id\":x}]}", "{\"entries\":[{\"id\":1}]}", new CustomComparator(JSONCompareMode.STRICT_ORDER, new Customization("entries[0].id", new RegularExpressionValueMatcher<Object>("\\d"))));

// NOT Working - example with Array (multiple items)
JSONAssert.assertEquals("{\"entries\":[{\"id\":x}]}", "{\"entries\":[{\"id\":1},{\"id\":2},{\"id\":3}]}", new CustomComparator(JSONCompareMode.STRICT_ORDER, new Customization("entries[0].id", new RegularExpressionValueMatcher<Object>("\\d"))));

The error message of non-working example is

java.lang.AssertionError: entries[]: Expected 1 values but got 3
at org.skyscreamer.jsonassert.JSONAssert.assertEquals(JSONAssert.java:262)
at pitschrmock.JsonTest.testJsonPersons(JsonTest.java:67)

Although I explicitly set that only the first array item should be taken.

Looking at your test suite the assertion of array is missing at all:
https://github.com/skyscreamer/JSONassert/blob/master/src/test/java/org/skyscreamer/jsonassert/RegularExpressionValueMatcherTest.java

Therefore, I'm not sure if it is a missing feature or should be considered as a bug.

To resolve the issue I had to write a much more complex lines:

	final Customization[] customizations = new Customization[3];
	for (int i = 0; i < customizations.length; i++) {
		customizations[i] = new Customization("entries[" + i + "].id", new RegularExpressionValueMatcher<Object>("\\d"));
	}
	final CustomComparator regExComparator = new CustomComparator(JSONCompareMode.STRICT_ORDER, customizations);
	final ArrayValueMatcher<Object> regExArrayValueMatcher = new ArrayValueMatcher<Object>(regExComparator);
	final Customization regExArrayValueCustomization = new Customization("entries", regExArrayValueMatcher);
	final CustomComparator regExCustomArrayValueComparator = new CustomComparator(JSONCompareMode.STRICT_ORDER,
	                new Customization[] { regExArrayValueCustomization });

	JSONAssert.assertEquals("{\"entries\":[{\"id\":x}]}", "{\"entries\":[{\"id\":1},{\"id\":2},{\"id\":3}]}", regExCustomArrayValueComparator);

At least I could not find a simpler way :-/

KR,
Christoph

nลn-free json.org code used

Hi,

my coworkers want to use JSONassert in their project, but (as the person responsible for insisting on proper licences) I need to tell them not to, because your code pulls in code from json.org under Douglas Crockfordโ€™s bad licence.

Please replace this; the Debian Wiki page https://wiki.debian.org/qa.debian.org/jsonevil contains background information and a list of alternative implementations. Apparently, https://android.googlesource.com/platform/libcore/+/master/json is a drop-in replacement. I asked a coworker (@tkrille) whether it would be possible to just write a pom.xml file for http://ftp.de.debian.org/debian/pool/main/liba/libandroid-json-org-java/libandroid-json-org-java_20121204-20090211.orig.tar.gz and upload that to Maven Central. It appears to be (note: Iโ€™m not a Javaโ„ข developer myself) a drop-in replacement, so youโ€™d โ€œjustโ€ have to change the reference in your own pom.xml afterwards (and test).

Would also be nice if you could do that yourself.

Thanks for your consideration!

compare failure, complex structure

I am supporting wildcards (*) (to allow any data in that spot, in particular places in a json document.

I have one where the compare returns confusing info.

source content

[
{
  "commodities":[
       {
              "reason":"initial",
              "merchantComRefId":"Soccer01",
              "quantity":1,
              "recordIndex":2
       }
  ],
  "merchantParcelId":"46545100015600",
  "orderNumber":"ORMUSP111295059BR",
  "parcelSize":
  {
            "length":2,
            "weightUnit":"lb",
            "distanceUnit":"in",
            "weight":2,
            "height":2,
            "width":2
  },
  "dcId":"2622",  
  "shipper":
  {
            "name":"UPS",
            "service":"UPS Ground",
            "trackingNumber":"1ZW6X8760324049789"
  },
  "returnAddress":
  {
             "countryCode":"US",
             "firstName":"John",
             "lastName":"Doe",
             "phoneNumber":"1-317-123-4567",
             "email":"[email protected]",
             "street1":"3333 N Franklin Road",
             "street2":null,
             "street3":null,
             "city":"Indianapolis",
             "provinceOrState":"IN",
             "countyOrRegion":"US",
             "postalOrZipCode":"46226"
  }
}
]

model to compare to (the source looks good in the editor before save)

[{  
   "commodities":[  
      "_"
   ],
   "merchantParcelId":"_",
   "orderNumber":"_",
   "parcelSize":{  
      "length":"_",
      "weightUnit":"_",
      "distanceUnit":"_",
      "weight":"_",
      "height":"_",
      "width":"_"
   },
   "shipper":{  
      "name":"_",
      "service":"_",
      "trackingNumber":"_"
   },
   "dcId":""_"",  <----------field with trouble
      "returnAddress":{  
      "countryCode":"_",
      "firstName":"_",
      "lastName":"_",
      "phoneNumber":"_",
      "email":"_",
      "street1":"_",
      "street2":"_",
      "street3":"_",
      "city":"_",
      "countyOrRegion":"_",
      "provinceOrState":"_",
      "postalOrZipCode":"*"
   }
} 
]

I should get a compare error for every place there is an * in the model.

but it appears we lost a pointer to the error for some reason

error returned (<-- with comments)

Assert matching failed [dcId=*] <--- right, * in model
Expected: a JSON object <--- yes
but none found <---- what????
; [dcId=2622] <---- input is correct
Unexpected: a JSON object <--- say what??

using version 1.2.3
jsonassert-1.2.3.jar

Assertion not failing if actual child object is null

The following assertion passes but should fail:

String expected = "{\"foo\":\"superfoo\",\"bar\":{\"bar\":\"superfoo\"}}";
String actual = "{\"foo\":\"superfoo\",\"bar\":null}";
JSONAssert.assertEquals(expected, actual, false);

Returns true with strict option turned on when different JSON strings given.

I've just noticed that JSONAssert returns true when one json contains another - FIRST contains SECOND. Can you confirm that this is NOT a correct behavior?

Also FIRST is not even a valid JSON.

import org.skyscreamer.jsonassert.JSONAssert
import spock.lang.Specification

class JsonAssertTest extends Specification {

    def "should return false when comparing different Jsons"() {
        when:
        JSONAssert.assertEquals(FIRST, SECOND, true)

        then:
        thrown(AssertionError)
    }

    def static String FIRST = """
        {
           "wasSuccessful":true,
           "data":[],
           "message":"Success"
        }
    ],
    "message":"Success"
    }
    """

    def static String SECOND = """
        {
            "wasSuccessful":true,
            "data":[],
            "message":"Success"
        }
    """
}

Regards,
ลukasz

Should fail on JSON fields duplication

There is an issue with comparion of JSON with duplicated fields:

    @Test
    public void testJSONAssert() throws JSONException {
        String expected = "{\"field\":\"val1\"}";
        String actual = "{\"field\":\"val2\",\"field\":\"val1\"}";
        JSONAssert.assertEquals(expected, actual, JSONCompareMode.STRICT);
    }

This test has passed but it don't looks like expected behavior.

The issue is actual for Jackson serializer in java. It behaves incorrect in some cases and I would like to check it in my tests.

Add possibility to override/extend comparison behavior

Currently all comparison logic resides in JSONCompare utility class. There is no simple way to override or extend it's private static methods. (For example, my problem was in adding custom comparison for arrays with different length).

I suggest to make JSONCompare class some kind of comparator (comparison handler), make it's methods protected and allow JSONAssert to accept custom implementations of such comparators.

P.S. Thank you for this useful tool

"null" is valid JSON

The following example:

JSONAssert.assertEquals("null", "null", false);

result in this exception:

org.json.JSONException: Unparsable JSON string: null

but null is valid JSON, even at the "root" level according to THIS

Support very strict ordering where an Object's keys must appear in the same order.

JSONassert's Objects are org.json.JSONObject, which store the name-value pairs in a HashMap, losing the order of the keys. This matches the json spec, which says that objects are unordered collections of key/values. However, I have tests where I want to make sure that nothing about an api changes, not even the order of keys in objects. I'm looking for something more strict than strict ordering.

This is probably a big change since it means not using org.json.JSONObject, and instead using something where we can configure the Map to be a LinkedHashMap. What do you think? Is that too big of a change for this library?

Feature Request - Compare JSON Structure but not "Leaf Values"

Comparing JSON strings that have timestamps is a fundamental challenge for some unit testing scenarios. It would be very nice if there was an option that was "extra-non-strict" that simply validated all the same keys existed in a nested structure, but ignored their values.

I have not found any library that can do this natively. JSONassert is the closest I've found. If anyone knows of another library that can do this, please let me know.

Hamcrest Matchers?

Rationale:

Let me begin by saying I love the JSONassert library as it has saved me lots of time reinventing the wheel.
I also love hamcrest style asserts. To me they are more fluent than 'classic' assertions.
Some people online seem to agree.

I would love to see some hamcrest-style matchers added to this library.
In case you are too busy yourself, I am willing to create a pull-request for review. Just let me know in that case.

Allow field values to be ignored by specifying a JSON path

We often have a requirement where we're not interested in the value of a field, but we do care that the field exists. This might be an autogenerated ID or a timestamp for example.

It would be useful to specify the field(s) as a JSON path expression so that we can be selective in which fields get ignored.

Must the data be consistent๏ผŸ

Hi,

I have two jsons. they have the same element,but have the different data.

now, i hope ignore the data compare, the same element is just ok.

are there any options

thanks

No detailed error message when number of JSON Objects is high?

I observed that when the number of JSON Objects is higher ( > 1500) the error message is lacks enough information. i.e. instead of getting expected and actual comparison, the error message only consists of Could not find match for element and the offending JSON Object.

After much of head scratching the issue was found to be missing attribute. :) . Is there a way we can enable deeper comparison at the cost of performance?

Feature request: Add support for JSONP

Our application has both JSON and JSONP strings to verify. Could you please implement support for handling jsonp callbacks as well? I can't imagine it's very difficult, and there's not really any comparable frameworks out there.

More verbose diff view on assertion error

We'd like to have an ability to provide more verbose, or generally custom json diff view on assertion error (such like un*x diff -y does).

For example, given two jsons:

{
  "id": "101",
  "key": {
    "a": "value",
    "b": "xyz",
    "c": 201
  }
}

and:

{
  "id": "102",
  "key": {
    "a": "value",
    "d": [1, 2]
  }
}

calling:

DiffViewProvider diffViewProvider = new LinuxAlikeDiffViewProvider();
JSONAssert.assertEquals(json1, json2, true, diffViewProvider);

would throw an AssertionError with original message and additionally (optionally) more verbose diff:

java.lang.AssertionError: id
Expected: 101
     got: 102
 ; key
Expected: b
     but none found
 ; key
Expected: c
     but none found
 ; key
Unexpected: d

Actual json vs expected json:
{                        {
  "id": "101",        |    "id": "102",
  "key": {                 "key": {
    "a": "value",            "a": "value",
    "b": "xyz",       |      "d": [1, 2]
    "c": 201          <
  }                        }
}                        }

More json-conscious diff:

{                        {
  "id": "101",        |    "id": "102",
  "key": {                 "key": {
    "a": "value",            "a": "value",
    "b": "xyz",       <
    "c": 201          <
                      >      "d": [1, 2]
  }                        }
}                        }

Fork: Use Jackson instead of org.json

We have a toolchain based on Jackson; I'd like to use JSONassert with Jackson JSON objects. I've forked the skyscreamer/JSONassert repo and replaced org.json with FasterXML/jackson-core and FasterXML/jackson-databind.

The biggest hurdle is the unit tests; Jackson is more strict and does not allow unquoted object names and unquoted values; but requires double quotes. This requires updating all the unit tests to use quoted names/values such as

{"a":[{"background":"white","id":1,"type":"row"} ...

instead of

{a:[{background:white,id:1,type:row}

(While Jackson has Feature.ALLOW_UNQUOTED_FIELD_NAMES, it does not have a Feature to allow unquoted values.)

My real question is: is that fork reasonable to push back to skyscreamer/JSONassert, perhaps in a different branch, or would it be better to push the fork elsewhere as a separate project (because current users of skyscreamer/JSONassert may depend on using unquoted strings)? If I do publish a different fork on GitHub, would you prefer I change the package names as well? I would certainly provide attribution to skyscreamer/JSONassert as the base of the fork, and release it under the same Apache 2.0 license.

thanks.

AssertEquals doesn't report all errors for elements in arrays.

this is an element in an anonymous structure inside an array

model
{
"provisioningType": "OEM",
"productId": "MIPro",
"contacts": [{
"role": "Subscription_Admin",
**"email": em,
"firstName": ,
"lastName": ,

*"displayName": ,
"locale": "en_US",
"companyName": *
}],
"pbPlanIds": [
],
"productSpecificData": [
{
"name": "SerialNumber",
"value": *
},
{
"name": "LicenseNumber",
"value": *
}
]
}

data
{
"provisioningType": "OEM",
"productId": "MIPro",
"contacts": [{
"email": "[email protected]",
"role": "Subscription_Admin",
"firstName": "John",
"lastName": "Smith",
"displayName": "John Smith",
"locale": "en_US",
"companyName": "Acme Inc",
"companyName2": "asdfasdf"
}],

"pbPlanIds": [
"MIPro_Basic"
],
"productSpecificData": [
{
"name": "SerialNumber",
"value": "12345678"
},
{
"name": "LicenseNumber",
"value": "123456789"
}
]
}

----- expect a failure, with all fields not matching
Assert matching failed contacts[companyName=*] <---- last field in array not matched. appears to be alphabetical.. c before d before e etc.. (if I rename the fields with z as the first char.. next field alphabetically gets reported as error)
Expected: a JSON object
but none found
; contacts[companyName=Acme Inc]
Unexpected: a JSON object
; pbPlanIds[]
Expected: *
but none found
; pbPlanIds[]
Unexpected: MIPro_Basic
; productSpecificData[name=SerialNumber].value
Expected: *
got: 12345678
; productSpecificData[name=LicenseNumber].value
Expected: *

got: 123456789

I need the failure reported so I can handle the processing of allowing values if * is specified.
is this a bug, or a feature, or controllable?

if this is a structure (not a structure in an array) all structure errors are reported correctly

Add clearer failure messages

Hi,

Sometimes the failure message message does not express the issue clearly. For example, comparing {"id":"1"} against {"id":"1 "} or {"id": 1} yields

java.lang.AssertionError: id
Expected: 1
 but got: 1

This kept me scratching my head until I realised that there was an extra space or a difference in types. As a quick dirty workaround, I extended the DefaultComparator to also "wrap" the values and print their type:

@Override
    public void compareValues(String prefix, Object expectedValue, Object actualValue, JSONCompareResult result) throws JSONException {
        if (expectedValue instanceof Number && actualValue instanceof Number) {
            if (((Number) expectedValue).doubleValue() != ((Number) actualValue).doubleValue()) {
                result.fail(prefix, ((Number) expectedValue).doubleValue(), ((Number) actualValue).doubleValue());
            }
        } else if (expectedValue.getClass().isAssignableFrom(actualValue.getClass())) {
            if (expectedValue instanceof JSONArray) {
                compareJSONArray(prefix, (JSONArray) expectedValue, (JSONArray) actualValue, result);
            } else if (expectedValue instanceof JSONObject) {
                compareJSON(prefix, (JSONObject) expectedValue, (JSONObject) actualValue, result);
            } else if (!expectedValue.equals(actualValue)) {
                result.fail(prefix + "\nExpected: [" + expectedValue + "]\n but got: [" + actualValue + "]");            }
        } else {
            result.fail(prefix + "\nExpected: [" + expectedValue + "] of type [" + expectedValue.getClass() + "]\n but got: [" + actualValue + "] of type [" + actualValue.getClass() + "]");
        }
    }

which now produces:

java.lang.AssertionError: id
Expected: [1]
 but got: [1 ]

and

java.lang.AssertionError: id
Expected: [1] of type [class java.lang.String]
 but got: [1] of type [class java.lang.Integer]

Since I didn't get the chance to familiarize with the code I'm not sure this is the best approach, but I was wondering whether you'd include something similar in a future version, or if this is is acceptable I could provide a push.

Kind regards

Number comparision broken when having decimals

I have this code:

String expected =
            "{\"priceOffers\":[" +
                "{\"name\":\"HELTHJEM\",\"price\":{" +
                    "\"freightPrice\":{\"exclVAT\":\"23.00\",\"inclVAT\":\"28.75\",\"VAT\":\"5.75\"}," +
                    "\"customerPrice\":{\"exclVAT\":\"19.20\",\"inclVAT\":\"24.00\",\"VAT\":\"4.80\"}},\"servicePoints\":null}," +
                "{\"name\":\"POSTNORD\",\"price\":{" +
                    "\"freightPrice\":{\"exclVAT\":\"25.00\",\"inclVAT\":\"31.25\",\"VAT\":\"6.25\"}," +
                    "\"customerPrice\":{\"exclVAT\":\"20.80\",\"inclVAT\":\"26.00\",\"VAT\":\"5.20\"}},\"servicePoints\":null}]," +
            "\"statusMessages\":{}}";

JSONAssert.assertEquals(expected, ok.readEntity(String.class), false);

And that gives the following error messages:

priceOffers[name=POSTNORD].price.customerPrice.VAT
Expected: 5.20
got: 5,20
; priceOffers[name=POSTNORD].price.customerPrice.exclVAT
Expected: 20.80
got: 20,80
; priceOffers[name=POSTNORD].price.customerPrice.inclVAT
Expected: 26.00
got: 26,00
; priceOffers[name=POSTNORD].price.freightPrice.VAT
Expected: 6.25
got: 6,25
; priceOffers[name=POSTNORD].price.freightPrice.exclVAT
Expected: 25.00
got: 25,00
; priceOffers[name=POSTNORD].price.freightPrice.inclVAT
Expected: 31.25
got: 31,25

If I compare the raw string representations of the input and the output they are equal.

Regex validation in json?

Hi,

I have a scenario where the json that I want to compare against contains some fields with varying values like an asset path with a version number or a date in the path e.g.:

{
      "href": "https://my.website.com/some/path/with/date/20170306.xml",
      "title": "Some title"
}

or

{
      "href": "https://some.cdn-server.com/assets/3.0/carousel_button.png",
      "title": "Some title"
}

In the expected json file I would like to handle them as regex, so by defining the expected value as the following, and having the respective fields marked with something that reflects that it is a regex:

{
      "href": "<regex>https://some.cdn-server.com/assets/\d+\.\d/carousel_button.png",
      "title": "Some title"
}

Then it wouldn't do an exact match comparison on them, rather a regex pattern match.

Is something like this achievable currently, maybe via Customization?
The naive approach would be to extend DefaultComparator and add the custom check into the compareValues method but I hope there is a more sophisticated solution than that.

cannot compare object with empty field

If, in two compared object, two field have an empty field, then there is an error:

the issue is, you can do a get on an empty field of a Json object. You need to check first if it's not empty.

wording (typo in quickstart.html)

is:

It is recommended that you leave strictMode
off, so your will be tests less brittle.

should be (something like this):

It is recommended that you leave strictMode
off, so your tests will be less brittle.

Add ability to choose JSON library

There's a dependency in pom.xml

    <dependency>
        <groupId>com.vaadin.external.google</groupId>
        <artifactId>android-json</artifactId>
        <version>0.0.20131108.vaadin1</version>
    </dependency>`

Not all projects use it.
Need to have ability to choose between this one and more popular like Gson & Jackson.

More options of what to ignore by assert.

Please add more options of what to be ignored and what not.

At the moment there only seems to be "strict" vs "non-strict" mode. The problem is that in most cases neither is good enough :( . E.g. in the case of sub-arrays, sometimes is the number of elements that's important, other times only that an array is present there (so that the Client code doesn't break), etc.

Since "strict" vs "non-strict" is just to limiting, one option would be to allow in the "Expected String" a special syntax. E.g.

String expected = "{name:\"aaa\",no:42,arr:[?,?,1]}";

could validate sub-arrays with 3 elements where element 1 and 2 can be whatever value

or

String expected = "{name:\"aaa\",no:42,arr:[?(string),?(int),1]}";

could validate sub-arrays with 3 elements where element 1 and 2 can be whatever value but of expected types.

or

String expected = "{name:\"aaa\",no:42,arr:[?,*]}";

could validate sub-arrays with at least 1 elements

or

String expected = "{name:\"aaa\",no:42,arr:[?(int),*(int)]}";

could validate sub-arrays with at least 1 elements but all of the expected value.

IMO this could be extremely flexible since it would allot very easily to validate complex structures.

regards.

JSONCompareResult.getFieldFailures() does not return missing attributes

If an attribute is missing, the comparison will fail and the field will be returned on the message:
"Expected: but none found".

However, this field is not included on the list of field failures from getFieldFailures().

Is this expected?

This is in STRICT mode. The missing() method does not appear to be adding anything to the _fieldFailures list.

match fails due to Long/Integer discrepency in map keys.

I tried JSONassert this morning. The first thing I did was to take something that was output from a test an an org.json.JSONObject structure. I serialized this using toString(), and pasted that string as the expected value parameter to JSONAssert.assertEquals, passing the JSONObject as the actual value.
Unfortunately the comparison failed, so I stepped into the code and found the problem in compareJSONArrayOfJsonObjects. My structure was using long values but the string was being parsed into Integer values. The keys of expectedValueMap were Integer whereas the keys of actualValueMap were Long. #27 partially fixes this issue but fails to fix it in the case where the Integer/Long conflict occurs in a property identified as a unique key.

Update version of org.json

As @hertzsprung pointed out, we're running an ages-old version of org.json. We're looking into helping them update the version they have in maven. If that doesn't work, we may need to either fork it ourselves, or look at other libraries. (We chose org.json for it's simplicity and lack of additional dependencies, so we'd like to stick with it if possible.)

History of API changes for JSONassert

Hi,

I'd like to share report on API changes and backward compatibility for the JSONassert library: https://abi-laboratory.pro/java/tracker/timeline/jsonassert/

The report is generated by the https://github.com/lvc/japi-tracker tool for jars at http://central.maven.org/maven2/org/skyscreamer/jsonassert/. The tool checks for API changes in the latest versions of the library according to the article https://wiki.eclipse.org/Evolving_Java-based_APIs_2.

Hope it will be helpful for users and maintainers of the library.

Thank you.

jsonassert-2
jsonassert-1

Add JSONCompareMode to JSONAssert.assertEquals(...)

For all of the JSONAssert.assertEquals methods, we should further overload them to replace the boolean strict flag with JSONCompareMode like so:

JSONAssert.assertEquals(String expected, String actual, JSONCompareMode compareMode)

This will allow for more fine-grained control of the tests.

Dependency on android-json breaks my code

Hi,

My application functionality depends on org.json.JSONTokener#JSONTokener(java.io.Reader) that is provided by org.json:json:20140107.
After adding the dependency on JSONassert I have my functionality broken in the tests, but not in the application, because android-json doesn't have the method above.
Could this library be made dependent on a newer version of json? For example on org.json:json:20160810.
If it is not possible for some reason, maybe a warning in the readme for those using json library in the main code would be helpful?

Thanks,
Serhiy

comparison failing on array of boolean

I've attached console output from my program. The expect value is what I read from a file, the got value is from the network. They are identical. expectedStr.equals(jsonStr) returns true. JSONAssert.assertEquals() says they aren't equal. This is with version 1.1.0 in my pom.

log.info("got: " + jsonStr);
log.info("expect:" + expectedStr);
log.info("comparing:" + jsonStr.equals(expectedStr));
JSONAssert.assertEquals(expectedStr, jsonStr, false);
14:56:30.806 [main] INFO  RServerTest - got: {
    "values" : [
        {
            "name" : "logicA",
            "length" : 4,
            "primitive" : true,
            "class" : "logical",
            "type" : "b",
            "value" : [
                true,
                false,
                true,
                true
            ]
        }
    ]
}
14:56:30.806 [main] INFO  RServerTest - expect:{
    "values" : [
        {
            "name" : "logicA",
            "length" : 4,
            "primitive" : true,
            "class" : "logical",
            "type" : "b",
            "value" : [
                true,
                false,
                true,
                true
            ]
        }
    ]
}
14:56:30.806 [main] INFO  RServerTest - comparing:true
14:56:30.826 [main] INFO  ComputeServer - R shutdown
Tests run: 4, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 2.004 sec <<< FAILURE!

Results :

Failed tests: 
  testRPackage(edu.wvu.stat.rc2.compute.RServerTest): values[class=logical].value[]: Expected contains 3 true actual contains 3

Problem comparing Integer and Long JSONObjects

In order to test a JSON API I am using JSONAssert. The actual and
expected output are already JSONObject objects, so I am just comparing
them:

JSONObject expected = new JSONObject(expectedString);
JSONAssert.assertEquals(expected, actual, false);

However, one of the properties in the actual object are Longs, while
the created expected object uses Integers. The solution I came up with
is to convert the actual object to a string and use this:

JSONAssert.assertEquals(expectedString, actual.toString(), false);

Possibly related to issue #23.

JsonAssert.assertEquals Faliure

Error that I am getting:
While the values of both the strings are same. but still assertion is failing.
Expected: a JSON object but none found

Code:
JSONParser parser = new JSONParser();
try

    {

      JSONArray jsonArray = (JSONArray) parser.parse(new FileReader("/path_to_file"));

       String abc = jsonArray.toJSONString();


        Headers allHeaders = response.getHeaders();
        Gson gson = new Gson();
        String headerList = gson.toJson(allHeaders.getList("Session"));
        JSONArray jsonArray2 = (JSONArray) parser.parse(headerList);
        String abcd = jsonArray2.toJSONString();

JSONAssert.assertEquals(abc,abcd,false);

Add message to JSONAssert

I would love to be able to include a message to JSONAssert.assertEquals in the beginning of the method invocation:

assertEquals("expected should equal actual", expected, actual, false);

JSONObject.getLong broken for very large values

Very large positive or negative long values do not parse correctly. org.json.JSONObject.getLong() does not handle anything longer than 16 significant decimal digits. It does not matter if the value is positive or negative, although Long.MAX_VALUE and Long.MIN_VALUE do work. Here's a test snippet to reproduce the problem:

    @Test
    public void testJSonGetLong() throws Exception {
        Long target = -4611686018427386614L;
        String targetString = target.toString();

        JSONObject value = new JSONObject().put("id", target);
        Assert.assertEquals(target, (Long) value.getLong("id"));  //Correct: when put as long getLong is correct

        value = new JSONObject().put("id", targetString);
        Assert.assertEquals(target, (Long) Long.parseLong(value.getString("id"))); //Correct: when put as String getString is correct
        Assert.assertEquals(target, (Long) value.getLong("id")); //Bug: Having json convert the string to long fails
    }

Fix numerical comparisons

If a field appears to be an integer, and a double of the same value appears, JsonAssert reports something like:

Values of geo.coordinates[0] have different types: expected java.lang.Integer, but got java.lang.Double ; Values of geo.coordinates[1] have different types: expected java.lang.Integer, but got java.lang.Double

In this case, the value expected value is 0 (an integer) and the given value is 0.0 (a double).

The key observation is that the double can be coerced into the integer without loss of precision, and therefore should be allowed.

Add support for current unsupported tests

Currently non-strict checking of a few cases are not supported:

  • Array of arrays
  • Arrays containing a mix of simple and complex types
  • Arrays containing objects that have no unique ID's

Add support for these cases, and update the unit tests.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.