Pact matchers.
Each function returns a map in the pact_ffi "integration JSON" format. Put the map where you would put a plain value, in a body, header, query value or path. The mock server matches by rule instead of by equality, and the example value is what it returns to the consumer.
import PactEx.Matchers
%{
"id" => integer(1),
"name" => like("Ada"),
"email" => regex("ada@example.com", ".+@.+"),
"tags" => each_like(like("admin"), min: 1)
}Matchers nest, and the results are plain maps that encode to JSON.
Summary
Functions
Matches any boolean. value is the example.
Matches a date or time string in the given Java DateTimeFormatter format.
Matches any decimal number. value is the example and must be a float.
Matches a map whose keys all match the regular expression pattern.
Matches a list in which every element looks like value.
Matches any string that contains substring. substring is also the example.
Matches any integer. value is the example.
Matches any value of the same type as value.
Matches a value against the regular expression pattern. The value is
usually a string.
Types
Functions
Matches any boolean. value is the example.
iex> PactEx.Matchers.boolean(true)
%{"pact:matcher:type" => "boolean", "value" => true}
Matches a date or time string in the given Java DateTimeFormatter format.
value is the example string. It should follow format.
iex> PactEx.Matchers.datetime("2026-10-22", "yyyy-MM-dd")
%{"pact:matcher:type" => "datetime", "value" => "2026-10-22", "format" => "yyyy-MM-dd"}
Matches any decimal number. value is the example and must be a float.
Integers are rejected: pact_matching checks decimals with a float test, and
an integer such as 2 encodes as 2, which fails its own rule. Use
2.0.
iex> PactEx.Matchers.decimal(1.5)
%{"pact:matcher:type" => "decimal", "value" => 1.5}
Matches a map whose keys all match the regular expression pattern.
value is the example map. Raises FunctionClauseError if it is not a map.
iex> PactEx.Matchers.each_key(%{"happy" => true}, "(happy|ferocious)")
%{
"pact:matcher:type" => "eachKey",
"value" => %{"happy" => true},
"rules" => [%{"pact:matcher:type" => "regex", "regex" => "(happy|ferocious)"}]
}
@spec each_like(term(), [{:min, pos_integer()}]) :: t()
Matches a list in which every element looks like value.
value is the example element. The list needs at least :min elements
(default 1). The example list repeats value :min times, because the
mock server does not pad it and would reject a shorter example.
Raises ArgumentError if :min is not a positive integer, or if opts
has any key other than :min. Raises FunctionClauseError if opts is
not a list.
iex> PactEx.Matchers.each_like("x", min: 2)
%{"pact:matcher:type" => "type", "value" => ["x", "x"], "min" => 2}
Matches any string that contains substring. substring is also the example.
iex> PactEx.Matchers.include("ell")
%{"pact:matcher:type" => "include", "value" => "ell"}
Matches any integer. value is the example.
iex> PactEx.Matchers.integer(1)
%{"pact:matcher:type" => "integer", "value" => 1}
Matches any value of the same type as value.
iex> PactEx.Matchers.like(1)
%{"pact:matcher:type" => "type", "value" => 1}
Matches a value against the regular expression pattern. The value is
usually a string.
value is the example value. It should match pattern.
value is typed term() and not guarded, because a regex rule also applies
to values that are not strings. In a JSON body, pact_matching matches the
pattern against the string form of a number, a boolean or null (the text it
has in JSON: 42, 1.5, true, null), so regex(42, "\d+") is valid.
For a list or a map example, the pattern applies to each scalar inside it,
not to the JSON text of the whole list or map. Path and query values are
matched as strings.
iex> PactEx.Matchers.regex("male", "(male|female)")
%{"pact:matcher:type" => "regex", "value" => "male", "regex" => "(male|female)"}