{"id":16994212,"url":"https://github.com/kvnxiao/jsonequals","last_synced_at":"2025-04-12T05:08:50.255Z","repository":{"id":61950700,"uuid":"82075195","full_name":"kvnxiao/jsonequals","owner":"kvnxiao","description":"A flexible JSON deep-equality comparator with optional ignoring of JSON keys and values","archived":false,"fork":false,"pushed_at":"2017-10-30T18:58:27.000Z","size":157,"stargazers_count":13,"open_issues_count":0,"forks_count":7,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-26T00:36:12.868Z","etag":null,"topics":["comparison","deep-equals","diff","equality","equals","inequality","json","pruning"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kvnxiao.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-02-15T15:26:53.000Z","updated_at":"2024-08-24T07:58:22.000Z","dependencies_parsed_at":"2022-10-24T03:00:16.918Z","dependency_job_id":null,"html_url":"https://github.com/kvnxiao/jsonequals","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kvnxiao%2Fjsonequals","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kvnxiao%2Fjsonequals/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kvnxiao%2Fjsonequals/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kvnxiao%2Fjsonequals/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kvnxiao","download_url":"https://codeload.github.com/kvnxiao/jsonequals/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248519545,"owners_count":21117761,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["comparison","deep-equals","diff","equality","equals","inequality","json","pruning"],"created_at":"2024-10-14T03:44:55.188Z","updated_at":"2025-04-12T05:08:50.233Z","avatar_url":"https://github.com/kvnxiao.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# JsonEquals \n\n[![CircleCI](https://circleci.com/gh/kvnxiao/jsonequals.svg?style=shield)](https://circleci.com/gh/kvnxiao/jsonequals)\n[![Release](https://jitpack.io/v/kvnxiao/jsonequals.svg)](https://jitpack.io/#kvnxiao/jsonequals)\n\nA simple, flexible JSON deep-equality comparator with optional settings to ignore and prune specific JSON fields.\n\n## Overview\n\nJsonEquals is a simple JSON deep-equality comparator for Java. It parses two JSON inputs and does a thorough comparison between each key, value, and array index, ignoring the ordering of JSON keys during comparison. In addition, one can **selectively define** what **equality** consists of by providing certain fields to **ignore** and certain array indices to **prune** (see examples below).\n\n_Example use cases:_ JsonEquals is perfect for comparing JSON responses between production and staging environments when your project is due for an API upgrade.\n\nThe current version of JsonEquals is used in production under the same scenario listed above, to compare JSON responses between different environments, which helps accelerate the upgrade process for updating API dependencies to newer versions by indicating differences in response data.\n\n[Javadocs here](https://kvnxiao.github.io/jsonequals/)\n\n## Usage\n\nJsonEquals uses [LazyJSON](https://github.com/doubledutch/LazyJSON), a simple and lightweight Java library to *parse (read)* JSON.\n\nTo compare two JSON strings, simply create JsonRoot objects: `JsonRoot.from(jsonString)` and use `JsonRoot#compareTo(another JsonRoot)`\n \nThe `JsonRoot#compareTo` method returns a JsonCompareResult, which holds information regarding the comparison (isEqual boolean, success messages list, failure (inequality) messages list)\n\n## Settings\n\nJsonEquals is capable of *ignoring* fields and *pruning* JSON objects within JSON arrays before comparison.\nFor example, responses with different timestamps can be ignored (ignore list), and array objects containing JSON objects with certain field values can be ignored (pruned list with expected value to be filtered out).\n\n### Ignoring JSON Fields\n\nSupply a `List\u003cString\u003e` of strings in a dot-notated JSON path format to have JsonEquals ignore these nodes during comparison. Use `JsonRoot#compareToWithIgnore()`\n\n```java\nList\u003cString\u003e ignoreList = new ArrayList\u003c\u003e();\n\nignoreList.add(... see below comment block);\n/*\nignoreList.add(\"$\");    // Ignores root element and all sub-children\nignoreList.add(\"$[1]\"); // If root element is an array, ignore the second object in the array including all its sub-children\nignoreList.add(\"$[*]\"); // Use * as a wildcard to specify all elements in an array\nignoreList.add(\"$.data.timestamp\");\n// Ignores the root -\u003e data -\u003e timestamp values during comparison, e.g. the two JSONs below will be equal\n{\n    \"data\": {\n        \"name\": \"John Smith\"\n        \"timestamp\": 12345\n    }\n}\n\n    versus\n    \n{\n    \"data\": {\n        \"name\": \"John Smith\"\n        \"timestamp\": 23456\n    }\n}\n*/\n\nJsonCompareResult result = jsonRootA.compareToWithIgnore(jsonRootB, ignoreList);\n```\n\n### Pruning JSON Arrays\n\nSupply a `Map\u003cString, String\u003e` in a dot-notated JSON path format to expected value in string form to act as a predicate. Any matches will be _**filtered out (read: removed)**_ before the comparison starts, and therefore ignored during comparison. Note that this _will_ shift the array indices. Use `JsonRoot#compareToWithPrune()`\n\nFormat: `Map\u003cString, String\u003e` -\u003e `(\"arrayIndexObjectPath:fieldName\", \"valueToFilterInStringForm\")`\n\ne.g.\n```java\n    Map\u003cString, String\u003e pruneMap = new HashMap\u003c\u003e();\n    pruneMap.put(\"$.someObject.someArray[*]:booleanName\", \"false\"); // * is a wildcard to select all array elements\n    \n    JsonCompareResult result = jsonRootA.compareToWithPrune(jsonRootB, pruneMap);\n    // Or combine both pruning and ignore list\n    JsonCompareResult ignoreAndPruneResult = jsonRootA.compareTo(jsonRootB, ignoreList, pruneMap);\n```\nthe JSON string:\n```\n{\n    \"someObject\": {\n        \"someArray\": [\n            ... // Objects from index 0 to 5 go here\n            {   // Object with index 6 in someArray\n                \"someString\": \"hello\",\n                \"booleanName\": \"false\"\n            },\n            {   // Object with index 7 in someArray\n                \"someString\": \"world\",\n                \"booleanName\": \"true\"\n            }\n            ... // Objects from index 8 and beyond go here\n        ]\n    }\n}\n```\nIn the above example, after pruning the JSON file before comparison, the object `$.someObject.someArray[6]` will be removed from comparison, which shifts object `$.someObject.someArray[7]` down to index 6, and so on, until everything that matches has been pruned from the array.\nThis can be useful when checking a list of responses from two different environments where there can be gaps in the arrays, for example, if we have an array of applications installed, we can define equality as having the same installed apps from both responses by pruning the apps that are not installed.\n\nFor a thorough example, see [`IgnoreAndPruneTest.java`](https://github.com/kvnxiao/jsonequals/blob/master/src/test/java/com/github/kvnxiao/jsonequals/tests/IgnoreAndPruneTest.java), along with [`ignore_prune_a.json`](https://github.com/kvnxiao/jsonequals/blob/master/tests/ignore_prune_a.json) and [`ignore_prune_b.json`](https://github.com/kvnxiao/jsonequals/blob/master/tests/ignore_prune_b.json)\n\n#### Debug Mode\n\nDebug mode can be enabled with `JsonEquals.setDebugMode(true)`, which will continuously log each leaf object or array primitive value being checked to the console.\n\n#### See Examples\n\nCheck out the test files for examples.\n\n## Installation\n\nJsonEquals uses JitPack for distribution. See https://jitpack.io/#kvnxiao/jsonequals for more information.\n\nReplace `@VERSION@` with the version number or commit hash.\n\n#### Gradle\n```gradle\n    allprojects {\n        repositories {\n            jcenter()\n            maven { url 'https://jitpack.io' }\n        }\n    }\n```\n```gradle\n    dependencies {\n        compile 'com.github.kvnxiao:jsonequals:1.0.1'\n    }\n```\n#### Maven\n```xml\n    \u003crepositories\u003e\n        \u003crepository\u003e\n            \u003cid\u003ejitpack.io\u003c/id\u003e\n            \u003curl\u003ehttps://jitpack.io\u003c/url\u003e\n        \u003c/repository\u003e\n    \u003c/repositories\u003e\n```\n```xml\n    \u003cdependency\u003e\n        \u003cgroupId\u003ecom.github.kvnxiao\u003c/groupId\u003e\n        \u003cartifactId\u003ejsonequals\u003c/artifactId\u003e\n        \u003cversion\u003e1.0.1\u003c/version\u003e\n    \u003c/dependency\u003e\n```\n\n## Contributing\n\nHave suggestions? See problems? Got new ideas or improvements? Feel free to submit an issue or pull request!\n\n## License\n\nThis project is licensed under Apache 2.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkvnxiao%2Fjsonequals","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkvnxiao%2Fjsonequals","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkvnxiao%2Fjsonequals/lists"}