{"id":23613699,"url":"https://github.com/freckle/hspec-expectations-json","last_synced_at":"2025-05-12T21:42:30.694Z","repository":{"id":40349544,"uuid":"267911772","full_name":"freckle/hspec-expectations-json","owner":"freckle","description":"Hspec expectations on JSON Values","archived":false,"fork":false,"pushed_at":"2025-05-07T17:02:44.000Z","size":52,"stargazers_count":11,"open_issues_count":0,"forks_count":1,"subscribers_count":19,"default_branch":"main","last_synced_at":"2025-05-07T18:22:23.475Z","etag":null,"topics":["ghvm-managed"],"latest_commit_sha":null,"homepage":"","language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/freckle.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-05-29T17:03:35.000Z","updated_at":"2025-05-07T17:02:46.000Z","dependencies_parsed_at":"2023-01-29T04:30:57.079Z","dependency_job_id":"804a9952-bc91-4c98-ad31-7974984dafa4","html_url":"https://github.com/freckle/hspec-expectations-json","commit_stats":{"total_commits":28,"total_committers":3,"mean_commits":9.333333333333334,"dds":0.25,"last_synced_commit":"5c29ea5a3d1261a1f6ffc489bbcc7f332ade033c"},"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/freckle%2Fhspec-expectations-json","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/freckle%2Fhspec-expectations-json/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/freckle%2Fhspec-expectations-json/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/freckle%2Fhspec-expectations-json/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/freckle","download_url":"https://codeload.github.com/freckle/hspec-expectations-json/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253827874,"owners_count":21970595,"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":["ghvm-managed"],"created_at":"2024-12-27T17:18:49.286Z","updated_at":"2025-05-12T21:42:30.665Z","avatar_url":"https://github.com/freckle.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Hspec Expectations for JSON Values\n\n[![Hackage](https://img.shields.io/hackage/v/hspec-expectations-json.svg?style=flat)](https://hackage.haskell.org/package/hspec-expectations-json)\n[![Stackage Nightly](http://stackage.org/package/hspec-expectations-json/badge/nightly)](http://stackage.org/nightly/package/hspec-expectations-json)\n[![Stackage LTS](http://stackage.org/package/hspec-expectations-json/badge/lts)](http://stackage.org/lts/package/hspec-expectations-json)\n[![CI](https://github.com/freckle/hspec-expectations-json/actions/workflows/ci.yml/badge.svg)](https://github.com/freckle/hspec-expectations-json/actions/workflows/ci.yml)\n\nComparing JSON `Value`s in Haskell tests comes with some challenges:\n\n- In API responses, additive changes are typically safe and an important way to\n  evolve responses without breaking clients. Therefore, assertions against such\n  responses often want to ignore any unexpected keys in `Object`s (at any\n  depth), as any clients would.\n\n- Order often doesn't matter in API responses either, so it should be possible\n  to assert equality regardless of `Array` ordering (again, at any depth).\n\n- When an assertion fails, showing the difference clearly needs to take the\n  above into account (i.e. it can't show keys you've ignored, or ordering\n  differences you didn't care about), and it has to display things clearly, e.g.\n  as a diff.\n\nThis library handles all these things.\n\n## Usage\n\n**NOTE**: this is effectively a distillation of the [Haddocks][], please\nview them directly for your installed version, to ensure accurate information.\n\n[haddocks]: http://hackage.haskell.org/package/hspec-expectations-json/docs/Test-Hspec-Expectations-Json.html\n\nFour expectations exist with the following behaviors:\n\n| Assertion that **fails** on: | extra `Object` keys | wrong `Array` order |\n| ---------------------------- | ------------------- | ------------------- |\n| `shouldBeJson`               | Yes                 | Yes                 |\n| `shouldBeUnorderedJson`      | Yes                 | No                  |\n| `shouldMatchJson`            | No                  | No                  |\n| `shouldMatchOrderedJson`     | No                  | Yes                 |\n\nEach of these, when they fail, print a difference between the objects, where the\nexpected-on object has been normalized to avoid indicating any of the\ndifferences your expectation is ignoring.\n\n### `shouldBeJson`\n\nPassing:\n\n```hs\ncatchFailure $\n  [aesonQQ| { \"a\": true, \"b\": false } |] `shouldBeJson`\n  [aesonQQ| { \"a\": true, \"b\": false } |]\n```\n\nFailing:\n\n```hs\ncatchFailure $\n  [aesonQQ| { \"a\": true, \"b\": false } |] `shouldBeJson`\n  [aesonQQ| { \"a\": true, \"b\": true  } |]\n```\n\n```diff\n   {\n       \"a\": true,\n---    \"b\": true\n+++    \"b\": false\n   }\n```\n\n### `shouldBeUnorderedJson`\n\nPassing:\n\n```hs\ncatchFailure $\n  [aesonQQ| { \"a\": [true, false], \"b\": false } |] `shouldBeUnorderedJson`\n  [aesonQQ| { \"a\": [false, true], \"b\": false } |]\n```\n\nFailing:\n\n```hs\ncatchFailure $\n  [aesonQQ| { \"a\": [true, false], \"b\": false, \"c\": true } |] `shouldBeUnorderedJson`\n  [aesonQQ| { \"a\": [false, true], \"b\": true             } |]\n```\n\n```diff\n   {\n       \"a\": [\n           false,\n           true\n       ],\n---    \"b\": true\n+++    \"b\": false,\n+++    \"c\": true\n   }\n```\n\n### `shouldMatchJson`\n\nPassing:\n\n```hs\ncatchFailure $\n  [aesonQQ| { \"a\": [true, false], \"b\": false, \"c\": true } |] `shouldMatchJson`\n  [aesonQQ| { \"a\": [false, true], \"b\": false            } |]\n```\n\nFailing:\n\n```hs\ncatchFailure $\n  [aesonQQ| { \"a\": [true, false], \"b\": false, \"c\": true } |] `shouldMatchJson`\n  [aesonQQ| { \"a\": [false, true], \"b\": true             } |]\n```\n\n```diff\n   {\n       \"a\": [\n           false,\n           true\n       ],\n---    \"b\": true\n+++    \"b\": false\n   }\n```\n\n### `shouldMatchOrderedJson`\n\nPassing:\n\n```hs\ncatchFailure $\n  [aesonQQ| { \"a\": [true, false], \"b\": false, \"c\": true } |] `shouldMatchOrderedJson`\n  [aesonQQ| { \"a\": [true, false], \"b\": false            } |]\n```\n\nFailing:\n\n```hs\ncatchFailure $\n  [aesonQQ| { \"a\": [true, false], \"b\": false, \"c\": true } |] `shouldMatchOrderedJson`\n  [aesonQQ| { \"a\": [false, true], \"b\": true             } |]\n```\n\n```diff\n   {\n       \"a\": [\n---        false,\n---        true\n+++        true,\n+++        false\n       ],\n---    \"b\": true\n+++    \"b\": false\n   }\n```\n\n---\n\n[LICENSE](./LICENSE) | [CHANGELOG](./CHANGELOG.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffreckle%2Fhspec-expectations-json","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffreckle%2Fhspec-expectations-json","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffreckle%2Fhspec-expectations-json/lists"}