Caution
This gem has been deprecated in favor of minitest-holdify. Please migrate to the new gem for future updates and support.
Declutter your test files and automatically update expected values when your code changes.
Don't copy-paste large outputs or structures into your tests. Rematch saves you hours of tedious maintenance by storing expected values in separate files and verifying them for you.
it 'generates the pagination nav tag' do
assert_equal "<nav id=" test - nav - id " class=" pagy - nav
pagination " aria-label=" pager "><span class=" page prev "><a href=" / foo? page = 9 " link-extra
rel=" prev " aria-label=" previous ">‹ Prev</a></span> <span class=" page "><a
href=" / foo? page = 1 " link-extra >1</a></span> <span class=" page gap ">…</span>
<span class=" page "><a href=" / foo? page = 6 " link-extra >6</a></span> <span class=" page "><a
href=" / foo? page = 7 " link-extra >7</a></span> <span class=" page "><a href=" / foo? page = 8 " link-extra
>8</a></span> <span class=" page "><a href=" / foo? page = 9 " link-extra rel=" prev " >9</a></span>
<span class=" page active ">10</span> <span class=" page "><a href=" / foo? page = 11 " link-extra
rel=" next " >11</a></span> <span class=" page "><a href=" / foo? page = 12 " link-extra
>12</a></span> <span class=" page "><a href=" / foo? page = 13 " link-extra >13</a></span>
<span class=" page "><a href=" / foo? page = 14 " link-extra >14</a></span> <span class=" page
gap ">…</span> <span class=" page "><a href=" / foo? page = 50 " link-extra >50</a></span>
<span class=" page next "><a href=" / foo? page = 11 " link-extra rel=" next " aria-label=" next ">Next ›</a></span></nav>",
view.pagy_nav(pagy)
end
it 'generates the metadata hash' do
assert_equal(
{
:scaffold_url => "http://www.example.com/subdir?page=__pagy_page__",
:first_url => "http://www.example.com/subdir?page=1",
:prev_url => "http://www.example.com/subdir?page=",
:page_url => "http://www.example.com/subdir?page=1",
:next_url => "http://www.example.com/subdir?page=2",
:last_url => "http://www.example.com/subdir?page=50",
:count => 1000,
:page => 1,
:items => 20,
:vars =>
{ :page => 1,
:items => 20,
:outset => 0,
:size => [1, 4, 4, 1],
:page_param => :page,
:params => {},
:fragment => "",
:link_extra => "",
:i18n_key => "pagy.item_name",
:cycle => false,
:url => "http://www.example.com/subdir",
:headers =>
{ :page => "Current-Page",
:items => "Page-Items",
:count => "Total-Count",
:pages => "Total-Pages" },
:metadata =>
[:scaffold_url,
:first_url,
:prev_url,
:page_url,
:next_url,
:last_url,
:count,
:page,
:items,
:vars,
:pages,
:last,
:from,
:to,
:prev,
:next,
:series],
:count => 1000 },
:pages => 50,
:last => 50,
:from => 1,
:to => 20,
:prev => nil,
:next => 2,
:series => ["1", 2, 3, 4, 5, :gap, 50]
},
controller.pagy_metadata)
endit 'generates the pagination nav tag' do
# Assertion
assert_rematch view.pagy_nav(pagy)
# Expectation (standard)
_(view.pagy_nav(pagy)).must_rematch
# Expectation (fluent / RSpec-style)
value(view.pagy_nav(pagy)).must_rematch
expect(view.pagy_nav(pagy)).to_rematch
endAdd rematch to your Gemfile (usually in the :test group).
Minitest < 6.0 loads it automatically. For Minitest >= 6.0, add Minitest.load :rematch to your test_helper.rb.
The first time a test runs, Rematch records the returned value in a *.yaml file next to the test. The key is automatically generated from the line number and a test ID. Subsequent runs compare the fresh value against the recording, passing or failing as usual.
When your code changes, you can update the store without editing test files:
-
Rebuild all: Run tests with the
--rematch-rebuildoption.rake test TESTOPTS=--rematch-rebuild[!WARNING] Only use this when you are sure the new output is correct: it will be stored!
-
Manual deletion: Delete the specific
*.yamlstore file and re-run the test. -
Selective update: Temporarily replace the check with its
store_counterpart:assert_rematch→store_assert_rematchmust_rematch→store_must_rematchto_rematch→store_to_rematch
[!WARNING] This stores the new value and fails the test (to prevent committing the
store_call). Revert to the original method to pass the test.
By default, Rematch wraps assert_equal (or assert_nil, depending on the value). You can also specify a different equality assertion (e.g., assert_equal_unordered).
# Standard usage
assert_rematch actual
_(actual).must_rematch
# With custom assertion
assert_rematch actual, :assert_equal_unordered
_(actual).must_rematch :assert_equal_unordered
expect(actual).to_rematch :assert_equal_unordered
# With message
assert_rematch actual, 'message'
_(actual).must_rematch 'message'Note: The custom assertion must be a symbol (e.g., :assert_something). The order of arguments (assertion symbol vs message) is flexible.
Rematch stores values in a standard YAML file named after your test file (e.g., test_file.rb.yaml). The keys are designed to be human-readable, allowing you to easily correlate stored values with your source code:
- Line Matching: Keys start with
L<num>corresponding to the line number of the assertion in your test file (e.g.,L10). - Multiple Hits: If a single assertion line is executed multiple times (e.g., inside a loop), Rematch automatically appends a counter to the key (e.g.,
L15,L15.2,L15.3). - Labels: You can make keys self-documenting by passing the
label:option, which appears in brackets within the key.
Example:
---
# Simple assertion at line 10
L10 8a93...: "simple value"
# Loop executing line 15 twice
L15 2b4c...: "iteration 1"
L15.2 2b4c...: "iteration 2"
# Assertion at line 20 using `label: 'custom_id'`
L20 [custom_id] 9d1e...: "labeled value"- Check the stores: If you are unsure about the output, check the readable
*.yamlfiles. Keys starting withL<num>make it easy to find the corresponding test case at the line indicated. - Update flow: Ensure tests pass before rebuilding. If there are expected failures, use the
store_*methods to reconcile specific tests. - Test the whole: Don't pick apart complex structures. Test the whole output with a single line. Rematch handles the complexity for you.
- Dos and Don'ts: Use Rematch for large, stable outputs (HTML, JSON, Hashes). Stick to standard assertions for simple values (integers, short strings).
- Equality: Stored values are compared using standard Minitest assertions. Custom objects must implement
==. - Ruby Versions: Complex objects with
ivarsmight serialize differently across Ruby versions due toPsych. Store raw data (hashes/attributes) to avoid this.
Tested on 3.2+, but compatible with 2.1+.
Follows Semantic Versioning 2.0.0. See the Changelog.
Pull Requests are welcome! Ensure tests, Codecov, and Rubocop pass.
master: Latest published release. Never force-pushed.dev: Development branch. May be force-pushed.