JsonComparator

Hex.pmHex Docs

A robust Elixir library for deep comparison of JSON-like structures with configurable comparison options.

Features

Installation

Add json_comparator to your list of dependencies in mix.exs:

def deps do
[
{:json_comparator, "~> 1.0.0"}
]
end

Then run:

$ mix deps.get

Configuration Options

The compare function accepts the following options:

Usage Examples

Basic comparison:

iex> JsonComparator.compare(%{a: 1, b: 2}, %{a: 1, b: 2})
:ok
iex> JsonComparator.compare(%{a: 1, b: 2}, %{a: 1, b: 3})
{:error, "Submitted JSONs do not match: b"}

Unordered list comparison (default behavior):

iex> JsonComparator.compare([1, 2, 3], [3, 2, 1])
:ok

Ordered list comparison:

iex> JsonComparator.compare([1, 2, 3], [1, 2, 3], strict_list_order: true)
:ok
iex> JsonComparator.compare([1, 2, 3], [3, 2, 1], strict_list_order: true)
{:error, "Submitted JSONs do not match: [0]"}

DateTime comparison:

iex> dt1 = DateTime.from_naive!(~N[2024-01-01 00:00:00.123456], "Etc/UTC")
iex> dt2 = DateTime.from_naive!(~N[2024-01-01 00:00:00.789012], "Etc/UTC")
# By default microseconds are truncated
iex> JsonComparator.compare(dt1, dt2)
:ok
# Comparing with exact microseconds
iex> JsonComparator.compare(dt1, dt2, truncate_datetime_microseconds: false)
{:error, "Submitted JSONs do not match: "}

Custom error messages:

iex> JsonComparator.compare(%{a: 1}, %{a: 2}, error_message: "Values differ at: %{path}")
{:error, "Values differ at: a"}

Complex nested structures:

iex> complex1 = %{
...> user: %{
...> name: "Alice",
...> roles: ["admin", "editor"],
...> metadata: %{joined_at: DateTime.from_naive!(~N[2024-01-01 00:00:00], "Etc/UTC")}
...> }
...> }
iex> complex2 = %{
...> user: %{
...> name: "Alice",
...> roles: ["editor", "admin"],
...> metadata: %{joined_at: DateTime.from_naive!(~N[2024-01-01 00:00:00.500000], "Etc/UTC")}
...> }
...> }
iex> JsonComparator.compare(complex1, complex2)
:ok