Skip to content

Commit

Permalink
- Add protocol to allow custom type matching rules (#43)
Browse files Browse the repository at this point in the history
- Update README with example

Co-authored-by: Ryan Spore <[email protected]>
  • Loading branch information
idlehands and ry4n1m3 authored Sep 10, 2024
1 parent 98735c1 commit 145417e
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 7 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# Changelog

## ## [1.2.1] - 2024-02-11
## [1.3.0] - 2024-02-11
- Add protocol to allow custom type matching rules
- Update README with example

## [1.2.1] - 2024-02-11
- Update documentation config for better hex_doc experience

## [1.2.0] - 2024-02-07
Expand Down
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,32 @@ def deps do
end
```

## Custom Type Matching
The default implementation to compare values in CheckerCab is to use `==/2`.
If you need to compare types where that won't work, you can add additional
implementations for the CheckerCab.MatchTypes in your application.

```elixir
defimpl CheckerCab.MatchTypes, for: Decimal do
def values_match?(expected, actual) do
Decimal.equal?(expected, actual)
end
end
```

You can then use `assert_values_for/1` as you normally would:

```elixir
test "success: with equivalent Decimal values" do
expected = %{key1: Decimal.new("1.10")}
actual = %{key1: Decimal.new("1.1")}

input = [expected: expected, actual: actual, fields: Map.keys(expected)]

assert :ok == CheckerCab.assert_values_for(input)
end
```

## Integrating into a test suite
Import `CheckerCab` to your test case file:
```elixir
Expand Down
4 changes: 2 additions & 2 deletions lib/checker_cab.ex
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,8 @@ defmodule CheckerCab do
!match?({:ok, _}, expected) || !match?({:ok, _}, actual)
end

defp mismatched?(%{expected: expected, actual: actual}) do
expected != actual
defp mismatched?(%{expected: {:ok, expected}, actual: {:ok, actual}}) do
not CheckerCab.MatchTypes.values_match?(expected, actual)
end

defp fetch_and_convert(map, field_name, opts) do
Expand Down
11 changes: 11 additions & 0 deletions lib/match_types.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
defprotocol CheckerCab.MatchTypes do
@fallback_to_any true
@spec values_match?(any(), any()) :: boolean()
def values_match?(expected, actual)
end

defimpl CheckerCab.MatchTypes, for: Any do
def values_match?(expected, actual) do
expected == actual
end
end
12 changes: 9 additions & 3 deletions mix.exs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
defmodule CheckerCab.MixProject do
use Mix.Project

@version "1.2.1"
@version "1.3.0"

def project do
[
app: :checker_cab,
version: @version,
elixir: "~> 1.11",
elixirc_paths: elixirc_paths(Mix.env()),
test_coverage: [tool: ExCoveralls],
preferred_cli_env: [
coveralls: :test,
Expand All @@ -22,7 +23,8 @@ defmodule CheckerCab.MixProject do
plt_add_apps: [:ex_unit]
],
docs: docs(),
package: package()
package: package(),
consolidate_protocols: Mix.env() != :test
]
end

Expand All @@ -48,10 +50,14 @@ defmodule CheckerCab.MixProject do
{:ecto, "~> 3.11"},
{:ex_doc, "~> 0.31.2", only: :dev},
{:dialyxir, "~> 1.4", only: [:dev, :test], runtime: false},
{:excoveralls, "~> 0.18", only: :test}
{:excoveralls, "~> 0.18", only: :test},
{:decimal, "~> 2.0"}
]
end

defp elixirc_paths(:test), do: ["lib", "test/support"]
defp elixirc_paths(_), do: ["lib"]

defp docs do
[
main: "readme",
Expand Down
13 changes: 12 additions & 1 deletion test/checker_cab_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ defmodule CheckerCabTest do
end
end

describe "assert_values for with options" do
describe "assert_values_for with options" do
test "success: with :convert_dates set to true" do
datetime = DateTime.utc_now()
date = datetime |> DateTime.to_date()
Expand All @@ -312,6 +312,17 @@ defmodule CheckerCabTest do
end
end

describe "assert_values_for with custom matchers" do
test "success: with custom matchers" do
expected = %{key1: Decimal.new("1.10")}
actual = %{key1: Decimal.new("1.1")}

input = [expected: expected, actual: actual, fields: Map.keys(expected)]

assert :ok == CheckerCab.assert_values_for(input)
end
end

defp assert_messages_are_equal(expected, actual) do
expected_list = expected |> String.trim_trailing() |> String.split("\n")
actual_list = actual |> String.split("\n")
Expand Down
5 changes: 5 additions & 0 deletions test/support/match_types_decimal_impl.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
defimpl CheckerCab.MatchTypes, for: Decimal do
def values_match?(expected, actual) do
Decimal.equal?(expected, actual)
end
end

0 comments on commit 145417e

Please sign in to comment.