thoughtbot/shoulda-matchers
56.0
Adequate · 28 September 2026
17.1k
lines of production code
Ruby
primary language
2
measurements over time
What this system is
This system is the Shoulda Matchers library, a testing tool for Ruby on Rails applications that provides a suite of matchers for validating controller behavior, model validations, and ActiveRecord associations. It supports multiple test frameworks like RSpec and Minitest, offering extensive coverage for features such as Active Storage, encryption, and routing. The project also includes robust infrastructure for automated documentation generation and multi-version compatibility testing across various Rails and Ruby releases.
How it got here
2007–2014 — Version 8.0 release and modernization
38 changes.
This period focused on the major release of version 8.0, introducing extensive new matchers for Rails 8 features like Active Storage, encryption, and controller callbacks. The library underwent significant internal refactoring, including a modular architecture for matchers, a migration to RSpec 3, and the adoption of modern Ruby and Rails version requirements. Documentation was also overhauled with custom templates and improved navigation to enhance developer experience.
2015–2024 — Explicit configuration and test infrastructure
14 changes.
The project shifted from auto-detection to explicit configuration for test frameworks and library integrations, requiring users to specify their environment. Significant effort was invested in refactoring the test suite, including extracting model creation strategies, adding support for multiple database adapters, and expanding unit test coverage. The period also saw the addition of a setup script and updated Appraisal configurations to support newer Rails versions.
Features
Add custom YARD documentation templates for improved UI and navigation
The project now includes a custom YARD HTML template set (located in doc\_config/yard/templates/default/fulldoc/html) that enhances the generated API documentation. This change introduces a full-list view for classes and methods, adds sticky headers for better navigation in long pages, and implements interactive features such as collapsible source code views, inheritance tree toggles, and keyboard shortcuts (c, m, f) for quick navigation. It also bundles necessary JavaScript libraries (jQuery, Underscore.js) and CSS assets (Bootstrap, Solarized theme) to support these UI improvements.
_doc\config/yard/templates/default/fulldoc/html · high confidence
Add support for Rails 8.0 and 8.1
The gem now supports testing against Rails 8.0 and 8.1. This is enabled by new Appraisal configurations that define the necessary dependencies for these versions, including \rails-controller-testing\, \rspec-rails\, and Rails-specific gems like \importmap-rails\, \turbo-rails\, and \stimulus-rails\ for 8.0, and additional gems like \solid\_cache\, \solid\_queue\, and \kamal\ for 8.1.
(repo-wide) · high confidence
New automated project setup script for Ruby environments
A new \bin/setup\ script has been added to automate the initial configuration of the development environment. It detects the operating system (macOS or Linux) and package manager (Homebrew, apt, or yum) to install required system libraries, then provisions the Ruby version based on \.tool-versions\ or \.ruby-version\ files, and finally runs project-specific setup steps like installing Appraisals.
bin · high confidence
New independent delegate\_method matcher with advanced options
The \delegate\_method\ matcher is now available as an independent matcher, allowing it to be used without the full Shoulda-Matchers gem. This new implementation supports additional qualifiers including \with\_prefix\ for Rails delegate helpers with prefixes, \allow\_nil\ to handle nil delegation targets, and \with\_private\ to verify private delegation methods. The matcher also includes improved error handling for Ruby 3.3 format changes and works correctly with globally enabled frozen-string-literals.
lib/shoulda/matchers/independent · high confidence
New matchers for Active Storage, encryption, serialization, and nested attributes
This release adds several new test matchers to the ActiveRecord suite: \have\_one\_attached\ and \have\_many\_attached\ for Active Storage associations (with qualifiers for \service\, \dependent\, and \strict\_loading\), \encrypt\ for Rails 7+ encrypted attributes (supporting \deterministic\, \downcase\, \ignore\_case\, \with\_key\_provider\, \with\_previous\, \with\_compressor\, \without\_compression\, and \supporting\_unencrypted\_data\), \serialize\ for custom serializer classes or instances, \accept\_nested\_attributes\_for\ with \allow\_destroy\, \limit\, and \update\_only\ qualifiers, \have\_secure\_token\ with an option to ignore database index checks, and \have\_readonly\_attribute\ for \attr\_readonly\. These matchers allow users to explicitly verify the configuration and behavior of these specific ActiveRecord macros in their models.
_lib/shoulda/matchers/active\record · high confidence
New utility scripts for managing Ruby versions and gem appraisals
Added a set of new developer utility scripts to streamline multi-Ruby testing and gem management. The \supported\_ruby\_versions\ script dynamically reads the list of supported Ruby versions from \.travis.yml\. This list is used by \install\_gems\_in\_all\_appraisals\ to install dependencies across all supported Ruby versions, \run\_all\_tests\ to execute the test suite on each version, and \update\_gem\_in\_all\_appraisals\ / \update\_gems\_in\_all\_appraisals\ to update specific or all gems across all appraisals and Ruby versions.
script · high confidence
Behavioural changes
Add canonical require entry point for shoulda-matchers
A new top-level entry point file has been added to the library, allowing users to load the entire shoulda-matchers gem using the canonical require statement 'require "shoulda/matchers"'. This simplifies the setup process by providing a single, standard way to include the library in a project.
lib · high confidence
Association matchers now support inverse\_of, source, counter\_cache, dependent, order, and through options
The association matchers in the library have been refactored to support additional Active Record association options. Users can now verify the \inverse\_of\, \source\, \counter\_cache\, \dependent\, \order\, and \through\ options on their associations. This includes specific handling for \counter\_cache\ to support Rails 7.2's new hash-based configuration format, and improved validation for \dependent\ qualifiers and \order\ clauses using relation methods.
_lib/shoulda/matchers/active\_record/association\matchers · high confidence
Docs now redirect to the latest version
Visiting the documentation root now automatically redirects users to the latest version of the docs instead of serving static content at the root path. This change ensures that users always see the most up-to-date documentation without needing to manually select a version.
_doc\config/gh-pages · high confidence
Enhanced documentation templates for inheritance and source code display
The generated documentation now includes a detailed inheritance tree for classes, displaying the superclass, modules included, and modules that extend the class, along with a toggle to show the full hierarchy. Additionally, method detail pages now render the original source code with syntax highlighting and file/line references, improving code navigation and understanding.
_doc\_config/yard/templates/default/method\_details, doc\config/yard/templates/default/module · high confidence
Explicit configuration required for test frameworks and libraries
The integration layer now requires users to explicitly configure the test framework and libraries via \Shoulda::Matchers.configure\ instead of relying on auto-detection. The new \Integrations::Configuration\ class enforces this by raising a \ConfigurationError\ if no test framework or library is specified, ensuring matchers are correctly integrated for the chosen environment (e.g., RSpec, Minitest, Rails).
lib/shoulda/matchers/integrations · high confidence
Explicit test framework integration via dedicated modules
The library now uses dedicated integration modules for RSpec, Test::Unit, Minitest 4, and Minitest 5, replacing the previous auto-detection mechanism. Users must explicitly configure their test framework in the setup block (e.g., \with.test\_framework :rspec\ or \with.test\_framework :minitest\_5\). If no framework is configured, the library raises a \TestFrameworkNotConfigured\ error with instructions on how to set one.
_lib/shoulda/matchers/integrations/test\frameworks · high confidence
Extracted documentation generation into a dedicated Rake task file
The documentation generation logic has been moved from the main Rakefile into a new \tasks/documentation.rb\ file. This change introduces a \DocumentationPublisher\ class and a \docs\ namespace with tasks for generating (\docs:generate\), publishing (\docs:publish\), and autogenerating (\docs:autogenerate\) documentation. The new tasks require explicit \version\ and \latest\_version\ arguments for generation and publishing, and the autogenerate task now watches a specific list of source files (including \README.md\, \CHANGELOG.md\, and library code) to trigger regeneration.
tasks · high confidence
Improved error reporting and enum compatibility in allow\_value matcher
The allow\_value matcher now provides clearer, more specific error messages when an attribute value is changed by the model (e.g., by typecasting or a custom writer) or when the attribute does not exist, helping users diagnose test failures more easily. Additionally, the matcher now correctly handles ActiveRecord enum columns, preventing false positives when the stored value differs from the written value due to enum typecasting, and includes an option to ignore such interference by writers.
_lib/shoulda/matchers/active\_model/allow\_value\matcher · high confidence
New and updated Action Controller matchers
This release introduces several new matchers for testing Rails controllers, including \filter\_param\ to verify parameter filtering configuration, \render\_with\_layout\ to assert on layout usage, and \respond\_with\ to check HTTP status codes (including support for deprecated status code symbols like \:success\ or \:redirect\). Existing matchers have been refactored and updated: \redirect\_to\ and \render\_template\ now provide more expressive syntax compatible with both RSpec and Minitest, while \set\_session\ and \set\_flash\ APIs have been consolidated into \SessionStore\ and \FlashStore\ classes for better internal organization and reliability.
_lib/shoulda/matchers/action\controller · high confidence
New modular integration structure for Rails libraries
The library integration layer has been restructured into distinct modules for Action Controller, Active Model, Active Record, Routing, and a generic Rails wrapper. This change introduces explicit registration of these sub-libraries and configures how their matchers are included into specific test frameworks (e.g., including Action Controller matchers into \ActionController::TestCase\ via lazy loading). Users benefit from a more organized and potentially faster-loading integration setup, as the previous auto-detection mechanism is replaced by this explicit module-based wiring.
lib/shoulda/matchers/integrations/libraries · high confidence
New top-level require path for matchers
A new \lib/shoulda/matchers.rb\ file has been added, providing a single entry point that loads the core configuration, integrations, and all matcher modules (ActionController, ActiveModel, ActiveRecord, Routing). This change allows users to include the entire suite of matchers via a single require statement, simplifying setup compared to loading individual components.
lib/shoulda · high confidence
Redesign generated documentation with Bootstrap 3 and Solarized theme
The YARD documentation template has been completely restyled to use Bootstrap v3.0.3 for layout and structure, replacing the previous default appearance. The visual theme now uses Solarized colors for syntax highlighting and code blocks, while the typography has been updated to import Source Sans Pro from Google Fonts for headings and body text, with Droid Sans Mono for code. These CSS changes improve the readability and modern look of the generated API documentation.
_doc\config/yard/templates/default/fulldoc/html/css · high confidence
Refactor numericality matchers into a modular submatcher architecture
The \validate\_numericality\_of\ matcher has been refactored to use a new internal structure located in \lib/shoulda/matchers/active\_model/numericality\_matchers\. This change introduces specific submatchers for distinct validation rules—such as \EvenNumberMatcher\, \OddNumberMatcher\, \OnlyIntegerMatcher\, and \RangeMatcher\—which delegate to a shared \NumericTypeMatcher\ base class. This modularization allows for more precise error messages and handling of specific numerical constraints (like even/odd checks or range boundaries) while maintaining the existing public API for users.
_lib/shoulda/matchers/active\_model/numericality\matchers · high confidence
Refactored ActiveModel matchers with new validation and qualifier support
The ActiveModel matcher library has been restructured to improve modularity and expand testing capabilities. The \allow\_value\ matcher now supports the \against\ qualifier to test validations on aliased attributes and includes the \ignoring\_interference\_by\_writer\ qualifier by default to handle custom attribute writers more gracefully. New matchers have been added for \validate\_absence\_of\, \validate\_confirmation\_of\, and \validate\_comparison\_of\ (covering operators like \greater\_than\, \less\_than\, etc.), alongside a \have\_secure\_password\ matcher that supports testing \validations: false\ and reset token configurations. The \validate\_numericality\_of\ matcher has been refactored to use submatchers, supporting \only\integer\, \odd\/\even\ checks, and custom messages, while deprecated \ensure\\\ matchers have been removed in favor of the \validate\\*\ naming convention.
_lib/shoulda/matchers/active\model · high confidence
Refactored Doublespeak internals to support return value storage and method call tracking
The Doublespeak stubbing library has been refactored to improve how method calls and return values are handled. A new \MethodCall\ object now explicitly stores the return value and tracks call details (arguments, block, caller), allowing for more precise inspection of stubbed behavior. The \Double\ class has been updated to record these calls and pass them to the implementation, while the \World\ class manages the activation state and storage of original methods. This change ensures that stubbed methods can properly return values and that call history is accurately maintained, fixing issues where return values were not being stored or propagated correctly.
lib/shoulda/matchers/doublespeak · high confidence
Shoulda Matchers v6.2.0: Major refactoring and new controller matchers
This release introduces a significant architectural overhaul of the library, most notably the introduction of new Action Controller matchers including \use\_before\_action\, \use\_after\_action\, \use\_around\_action\, \rescue\_from\, \set\_flash\, and \set\_session\. The \permit\ matcher has been renamed to \permit\_matcher\ and refactored to support subparameters and multiple instances. Additionally, the \set\_the\_flash\ API has been consolidated into \set\_flash\, and the library has dropped support for older Ruby and Rails versions while adding support for newer releases like Ruby 3.4 and Rails 7.2.
shoulda-matchers · high confidence
Shoulda Matchers version 8.0.1 release
This update bumps the library version to 8.0.1. The diff shows a complete restructuring of the library's internal organization, introducing dedicated entry-point files for \ActionController\, \ActiveModel\, and \ActiveRecord\ matchers, alongside new modules for \Doublespeak\ (mocking), \Integrations\, and \Routing\. This change consolidates the matcher definitions into specific namespaces and updates the core version constant.
lib/shoulda/matchers · high confidence
Fixes
Custom YARD documentation layout and link fixes
The documentation generation now uses a custom YARD layout template set that improves navigation and styling. The new layout includes a breadcrumb navigation bar, a dedicated search section, and a footer. Additionally, the README index links are now correctly processed to generate proper method links (e.g., \Module\#method\) in the generated HTML, ensuring that documentation links work correctly both on GitHub and in the local YARD output.
_doc\config/yard/templates/default/layout · high confidence
Migrate documentation syntax highlighting to Rouge
The YARD documentation setup now uses the Rouge library for syntax highlighting instead of the previous implementation. This change updates the \HtmlSyntaxHighlightHelper\ to leverage Rouge's lexers and HTML formatters, ensuring code snippets in the generated documentation are highlighted correctly using the Rouge engine.
_doc\config/yard · high confidence
Test coverage
Added RSpec acceptance test matchers for command output validation; Added RSpec acceptance tests to replace Cucumber; Added acceptance tests for library and framework integrations; Added internal RSpec matchers for testing deprecations and failure messages; Added shared test examples for validation matchers and session/flash assertions; Added test helper for creating database tables with array column support; Added test model isolation for uniqueness validation tests; Added test support classes for ActiveRecord model creation strategies; Added test support for PostgreSQL and SQLite3 database adapters; Added unit tests for ActionController matchers; Added unit tests for Doublespeak and MatcherCollection internals; Added unit tests for Doublespeak internal components; Added unit tests for ModelReflection association matcher; Added unit tests for the delegate\_method matcher; Added unit tests for the routing route matcher; Added unit tests for the word\_wrap utility; Comprehensive unit tests for Active Model matchers; Expanded unit test coverage for ActiveRecord matchers; Extracted model creation strategies for unit tests; Extracted test model creation logic into dedicated classes; New acceptance test helper modules for Rails and Ruby version detection; New test support infrastructure for acceptance testing; Refactored test infrastructure with dedicated spec helpers and RSpec 3 migration; Reorganized unit test helpers into modular components; Reorganized unit test infrastructure with extracted helper classes.
Dependencies
Add Appraisal configurations for Rails 7.2, 8.0, and 8.1
The gemfiles directory now includes new Appraisal configurations for testing against Rails 7.2, 8.0, and 8.1. These files define the specific gem dependencies and locked versions required to run the test suite against each of these Rails versions, ensuring compatibility across the supported framework releases.
gemfiles · high confidence
Update development dependencies and drop support for older Ruby versions
The project has updated its development dependencies to modern versions, including RSpec (\~\> 3.9), Rubocop (1.84.2), and Rake (13.3.1), while adding Rubocop-packaging and Rubocop-rails for improved code quality checks. Support for older Ruby versions has been removed, with the gemspec now requiring Ruby \>= 3.3 and Active Support \>= 7.2, aligning the development environment with current standards.
(dependencies) · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
Score
- CAI 68 → 56 (-12.4)
- Rubric changed (rubric-2026.09.8 → rubric-2026.09.16) — scores are not directly comparable.
Lenses
- Code Health 93 → 93 (+0.0)
- Architecture 100 → 74 (-25.6)
- Maturity 62 → 62 (+0.0)
- Readiness 60 → 58 (-2.3)
- Security 79 → 79 (+0.3)
- Domain Modelling 100 → 100 (+0.0)
- Accessibility 45 (new)
Resolved (3)
- Documentation: no installation or build instructions (README.md)
- Documentation: no usage examples (README.md)
- Off-boarding risk: anonymized user #1
New (5)
- End-of-life runtime: Python 2.7
- Inconsistent method naming for the same configuration intent across different matcher types. AllowValueMatcher and DisallowValueMatcher use the gerund form ignoring_interference_by_writer, while the dedicated qualifier class IgnoreInterferenceByWriter uses the imperative set and default_to. Furthermore, IgnoringInterferenceByWriter uses the gerund form again. This creates confusion for users migrating between using the direct matcher methods vs. the explicit qualifier classes.
- Inconsistent naming convention for qualifier methods. One uses the full phrase 'allow_blank' while the other uses the abbreviated 'allow_nil'. Given that 'allow_nil' is a standard Rails convention and 'allow_blank' is the semantic equivalent for blankness, the inconsistency is minor but breaks the pattern of using the full descriptive phrase or the abbreviated phrase consistently across the board.
- Off-boarding risk: anonymized user #1
- Projects may be oversized for their cohesion
Architecture
- Unchanged — 0 containers · 1 contexts · 0 edges
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
thoughtbot/shoulda-matchers was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 28 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit 79cdfbc326e97c9b43991b644434ca53c1f62c4c — the exact code this score is about.
- Scored under rubric-2026.09.16 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-2d9048c36d26.