diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 70b310f2a..32bb17b21 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,12 +18,12 @@ concurrency: jobs: rubocop: name: Rubocop - runs-on: 'ubuntu-20.04' + runs-on: 'ubuntu-latest' steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: ruby/setup-ruby@v1 with: - ruby-version: '3.0' + ruby-version: '3.3' - run: script/update_rubygems_and_install_bundler - run: bundle install --standalone - run: bundle binstubs --all @@ -31,67 +31,47 @@ jobs: test: name: 'Ruby: ${{ matrix.ruby }}, Rails: ${{ matrix.env.RAILS_VERSION }}' - runs-on: ubuntu-20.04 + runs-on: 'ubuntu-latest' strategy: fail-fast: false matrix: include: # Edge Rails (?) builds >= 3.1 - - ruby: 3.3 + - ruby: 3.4 env: RAILS_VERSION: 'main' - - ruby: 3.2 + - ruby: 3.3 env: RAILS_VERSION: 'main' - - ruby: 3.1 + - ruby: 3.2 env: RAILS_VERSION: 'main' - # Rails 7.2 builds >= 3.1 + # Rails 8.0 builds >= 3.2 + - ruby: 3.4 + env: + RAILS_VERSION: '~> 8.0.0' - ruby: 3.3 env: - RAILS_VERSION: '~> 7.2.0' + RAILS_VERSION: '~> 8.0.0' - ruby: 3.2 env: - RAILS_VERSION: '~> 7.2.0' - - ruby: 3.1 - env: - RAILS_VERSION: '~> 7.2.0' + RAILS_VERSION: '~> 8.0.0' - # Rails 7.1 builds >= 2.7 + # Rails 7.2 builds >= 3.1 - ruby: 3.3 env: - RAILS_VERSION: '~> 7.1.0' - - ruby: 3.2 - env: - RAILS_VERSION: '~> 7.1.0' - - ruby: 3.1 - env: - RAILS_VERSION: '~> 7.1.0' - - ruby: '3.0' - env: - RAILS_VERSION: '~> 7.1.0' - - ruby: 2.7 - env: - RAILS_VERSION: '~> 7.1.0' - - # Rails 7.0 builds >= 2.7 + RAILS_VERSION: '~> 7.2.0' - ruby: 3.2 env: - RAILS_VERSION: '~> 7.0.0' + RAILS_VERSION: '~> 7.2.0' - ruby: 3.1 env: - RAILS_VERSION: '~> 7.0.0' - - ruby: '3.0' - env: - RAILS_VERSION: '~> 7.0.0' - - ruby: 2.7 - env: - RAILS_VERSION: '~> 7.0.0' + RAILS_VERSION: '~> 7.2.0' env: ${{ matrix.env }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby }} diff --git a/.github/workflows/depsreview.yaml b/.github/workflows/depsreview.yaml index b9d6d20ff..8461b453c 100644 --- a/.github/workflows/depsreview.yaml +++ b/.github/workflows/depsreview.yaml @@ -9,6 +9,6 @@ jobs: runs-on: ubuntu-latest steps: - name: 'Checkout Repository' - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: 'Dependency Review' uses: actions/dependency-review-action@v4 diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 246ac1b03..156a33670 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -5,50 +5,179 @@ values contributions from anyone, the RSpec project has adopted the following code of conduct. All contributors and participants (including maintainers!) are expected to abide by its terms. -As contributors and maintainers of this project, and in the interest of -fostering an open and welcoming community, we pledge to respect all people who -contribute through reporting issues, posting feature requests, updating -documentation, submitting pull requests or patches, and other activities. - -We are committed to making participation in this project a harassment-free -experience for everyone, regardless of level of experience, gender, gender -identity and expression, sexual orientation, disability, personal appearance, -body size, race, ethnicity, age, religion, or nationality. - -Examples of unacceptable behavior by participants include: - -* The use of sexualized language or imagery -* Personal attacks -* Trolling or insulting/derogatory comments -* Public or private harassment -* Publishing other's private information, such as physical or electronic - addresses, without explicit permission -* Other unethical or unprofessional conduct +As contributors and maintainers of this project, we pledge to make our community +welcoming, safe, and equitable for all. -Project maintainers have the right and responsibility to remove, edit, or -reject comments, commits, code, wiki edits, issues, and other contributions -that are not aligned to this Code of Conduct, or to ban temporarily or -permanently any contributor for other behaviors that they deem inappropriate, -threatening, offensive, or harmful. +We are committed to fostering an environment that respects and promotes the +dignity, rights, and contributions of all individuals, regardless of +characteristics including race, ethnicity, caste, color, age, physical +characteristics, neurodiversity, disability, sex or gender, gender identity +or expression, sexual orientation, language, philosophy or religion, national +or social origin, socio-economic position, level of education, or other status. +The same privileges of participation are extended to everyone who participates +in good faith and in accordance with this Covenant. By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team. -This Code of Conduct applies both within project spaces and in public spaces -when an individual is representing the project or its community. +## Encouraged Behaviors + +While acknowledging differences in social norms, we all strive to meet our +community's expectations for positive behavior. We also understand that our +words and actions may be interpreted differently than we intend based on +culture, background, or native language. + +With these considerations in mind, we agree to behave mindfully toward each +other and act in ways that center our shared values, including: + +1. Respecting the **purpose of our community**, our activities, + and our ways of gathering. +2. Engaging **kindly and honestly** with others. +3. Respecting **different viewpoints** and experiences. +4. **Taking responsibility** for our actions and contributions. +5. Gracefully giving and accepting **constructive feedback**. +6. Committing to **repairing harm** when it occurs. +7. Behaving in other ways that promote and sustain the + **well-being of our community**. + +## Restricted Behaviors -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting one of the project maintainers listed at +We agree to restrict the following behaviors in our community. Instances, +threats, and promotion of these behaviors are violations of this +Code of Conduct. + +1. **Harassment.** Violating explicitly expressed boundaries or engaging in + unnecessary personal attention after any clear request to stop. +2. **Character attacks.** Making insulting, demeaning, or pejorative comments + directed at a community member or group of people. +3. **Stereotyping or discrimination.** Characterizing anyone’s personality or + behavior on the basis of immutable identities or traits. +4. **Sexualization.** Behaving in a way that would generally be considered + inappropriately intimate in the context or purpose of the community. +5. **Violating confidentiality**. Sharing or acting on someone's personal or + private information without their permission. +6. **Endangerment.** Causing, encouraging, or threatening violence or other harm + toward any person or group. +7. Behaving in other ways that **threaten the well-being** of our community. + +### Other Restrictions + +1. **Misleading identity.** Impersonating someone else for any reason, or + pretending to be someone else to evade enforcement actions. +2. **Failing to credit sources.** Not properly crediting the sources of content + you contribute, including but not limited to the use of LLMs. +3. **Promotional materials**. Sharing marketing or other commercial content in + a way that is outside the norms of the community. +4. **Irresponsible communication.** Failing to responsibly present content which + includes, links or describes any other restricted behaviors. + +## Reporting an Issue + +Tensions can occur between community members even when they are trying their +best to collaborate. Not every conflict represents a code of conduct violation, +and this Code of Conduct reinforces encouraged behaviors and norms that can +help avoid conflicts and minimize harm. + +When an incident does occur, it is important to report it promptly. + +To report a possible violation contact one of the project maintainers listed at https://rspec.info/about/. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the -circumstances. Maintainers are obligated to maintain confidentiality with -regard to the reporter of an incident. +circumstances. + +Maintainers take reports of violations seriously and will make every effort to +respond in a timely manner. They will investigate all reports of code of conduct +violations, reviewing messages, logs, and recordings, or interviewing witnesses +and other participants. Maintainers will keep investigation and enforcement +actions as transparent as possible while prioritizing safety and +confidentiality. In order to honor these values, enforcement actions are carried +out in private with the involved parties, but communicating to the whole +community may be part of a mutually agreed upon resolution. + +## Addressing and Repairing Harm + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +If an investigation that this Code of Conduct has been violated, the following +enforcement ladder may be used to determine how best to repair harm, based on +the incident's impact on the individuals involved and the community as a whole. +Depending on the severity of a violation, lower rungs on the ladder may be +skipped. + +1) Warning + 1) Event: A violation involving a single incident or series of incidents. + 2) Consequence: A private, written warning. + 3) Repair: Examples of repair include a private written apology, + acknowledgement of responsibility, and seeking clarification on + expectations. + +2) Temporarily Limited Activities + 1) Event: A repeated incidence of a violation that previously resulted in a + warning, or the first incidence of a more serious violation. + 2) Consequence: A private, written warning with a time-limited cooldown + period designed to underscore the seriousness of the situation and give + the community members involved time to process the incident. The cooldown + period may be limited to particular communication channels or interactions + with particular community members. + 3) Repair: Examples of repair may include making an apology, using the + cooldown period to reflect on actions and impact, and being thoughtful + about re-entering community spaces after the period is over. + +3) Temporary Suspension + 1) Event: A pattern of repeated violation which have been issued warnings, + or a single serious violation. + 2) Consequence: A private written warning with conditions for return from + suspension. In general, temporary suspensions give the person being + suspended time to reflect upon their behavior and possible corrective + actions. + 3) Repair: Examples of repair include respecting the spirit of the + suspension, meeting the specified conditions for return, and being + thoughtful about how to reintegrate with the community when the suspension + is lifted. + +4) Permanent Ban + 1) Event: A pattern of repeated code of conduct violations that other steps + on the ladder have failed to resolve, or a violation so serious that it + is determined there is no way to keep the community safe with this person + as a member. + 2) Consequence: Access to all community spaces, tools, and communication + channels is removed. In general, permanent bans should be rarely used, + should have strong reasoning behind them, and should only be resorted to + if working through other remedies has failed to change the behavior. + 3) Repair: There is no possible repair in cases of this severity. + +This enforcement ladder is intended as a guideline. It does not limit the +ability of maintainers to use their discretion and judgment, in keeping +with the best interests of our community. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public or other +spaces. Examples of representing our community include using an official email +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], -version 1.3.0, available at -[https://contributor-covenant.org/version/1/3/0/][version] +version 3.0, available at +[https://www.contributor-covenant.org/version/3/0/][version] + +Contributor Covenant is stewarded by the Organization for Ethical Source and +licensed under CC BY-SA 4.0. To view a copy of this license, visit +[https://creativecommons.org/licenses/by-sa/4.0/][cc-by-sa] + +For answers to common questions about Contributor Covenant, see their +[FAQ][faq]. +[cc-by-sa]: https://creativecommons.org/licenses/by-sa/4.0/ [homepage]: https://contributor-covenant.org -[version]: https://contributor-covenant.org/version/1/3/0/ +[faq]: https://www.contributor-covenant.org/faq +[version]: https://www.contributor-covenant.org/version/3/0/ diff --git a/Changelog.md b/Changelog.md index 5e968764d..3f28c574b 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,22 +1,94 @@ ### Development -[Full Changelog](https://github.com/rspec/rspec-rails/compare/v7.0.0...main) +[Full Changelog](https://github.com/rspec/rspec-rails/compare/v8.0.2...main) + +### 8.0.2 / 2025-08-12 +[Full Changelog](https://github.com/rspec/rspec-rails/compare/v8.0.1...v8.0.2) + +Bug Fixes: + +* Fix scaffold generator producing deprecated Rack http statuses. + (Taketo Takashima, rspec/rspec-rails#2860) + +### 8.0.1 / 2025-06-19 +[Full Changelog](https://github.com/rspec/rspec-rails/compare/v8.0.0...v8.0.1) + +Bug Fixes: + +* Make the `have_been_performed` / `have_been_enqueued` return `false` for + `supports_block_expectations?` as they don't supporting block expectations. + (Sam Kidman, rspec/rspec-rails#2851) + +### 8.0.0 / 2025-04-30 +[Full Changelog](https://github.com/rspec/rspec-rails/compare/v7.1.1...v8.0.0) + +Enhancements: + +* Add Rails 8 authentication generator support. (Jerome Dalbert, rspec/rspec-rails#2811) +* Improve install generator comment for `ActiveRecord::Migration.maintain_test_schema!` +(rspec/rspec-rails#2832) +* Add support for `served_by` in system specs. (Sam Giffney, rspec/rspec-rails#2841) + +Breaking Changes: + +* Minimum supported Rails version is 7.2.0 + +### 7.1.1 / 2025-02-06 +[Full Changelog](https://github.com/rspec/rspec-rails/compare/v7.1.0...v7.1.1) + +Bug Fixes: + +* Check wether rspec-mocks has been loaded before enabling signature + verification for `have_enqueued_job` et al (Jon Rowe, rspec/rspec-rails#2823) + +### 7.1.0 / 2024-11-09 +[Full Changelog](https://github.com/rspec/rspec-rails/compare/v7.0.2...v7.1.0) + +Enhancements: + +* Improve implicit description for ActionCable matchers `have_broadcasted_to` / + `have_broadcast`. (Simon Fish, rspec/rspec-rails#2795) +* Comment out `infer_spec_type_from_file_location!` in newly generated + `rails_helper.rb` files. (Jon Rowe, rspec/rspec-rails#2804) +* Allow turning off active job / mailer argument validation. + (Oli Peate, rspec/rspec-rails#2808) + +### 7.0.2 / 2024-11-09 +[Full Changelog](https://github.com/rspec/rspec-rails/compare/v7.0.1...v7.0.2) + +Bug Fixes: + +* Fix issue with `have_enqueued_mail` when jobs were incorrectly matched due + to refactoring in rspec/rspec-rails#2780. (David Runger, rspec/rspec-rails#2793) + +### 7.0.1 / 2024-09-03 +[Full Changelog](https://github.com/rspec/rspec-rails/compare/v7.0.0...v7.0.1) + +Bug Fixes: + +* Remove mutation of Rails constant in favour of public api. (Petrik de Heus, rspec/rspec-rails#2789) +* Cleanup Rails scaffold for unsupported versions. (Matt Jankowski, rspec/rspec-rails#2790) +* Remove deprecated scaffold that was unintentionally included in 7.0.0 + (Jon Rowe, rspec/rspec-rails#2791) + +### 7.0.0 / 2024-09-02 +[Full Changelog](https://github.com/rspec/rspec-rails/compare/v6.1.5...v7.0.0) Enhancements: * Change default driver for system specs on Rails 7.2 to match its default. - (Steve Polito, #2746) -* Verify ActiveJob arguments by comparing to the method signature. (Oli Peate, #2745) -* Add suggestion to rails_helper.rb to skip when not in test most. (Glauco Custódio, #2751) -* Add `at_priority` qualifier to `have_enqueued_job` set of matchers. (mbajur, #2759) -* Add spec directories to `rails stats` on Rails main / 8.0.0. (Petrik de Heus, #2781) + (Steve Polito, rspec/rspec-rails#2746) +* Verify ActiveJob arguments by comparing to the method signature. (Oli Peate, rspec/rspec-rails#2745) +* Add suggestion to rails_helper.rb to skip when not in test mode. (Glauco Custódio, rspec/rspec-rails#2751) +* Add `at_priority` qualifier to `have_enqueued_job` set of matchers. (mbajur, rspec/rspec-rails#2759) +* Add spec directories to `rails stats` on Rails main / 8.0.0. (Petrik de Heus, rspec/rspec-rails#2781) ### 6.1.5 / 2024-09-02 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v6.1.4...v6.1.5) Bug Fixes: -* Restore old order of requiring support files. (Franz Liedke, #2785) -* Prevent running `rake spec:statsetup` on Rails main / 8.0.0. (Petrik de Heus, #2781) +* Restore old order of requiring support files. (Franz Liedke, rspec/rspec-rails#2785) +* Prevent running `rake spec:statsetup` on Rails main / 8.0.0. (Petrik de Heus, rspec/rspec-rails#2781) ### 6.1.4 / 2024-08-15 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v6.1.3...v6.1.4) @@ -24,26 +96,26 @@ Bug Fixes: Bug Fixes: * Prevent `have_http_status` matcher raising an error when encountering a raw `Rack::MockResponse`. - (Christophe Bliard, #2771) -* Move Rails version conditional from index scaffold generated file to template. (Matt Jankowski, #2777) + (Christophe Bliard, rspec/rspec-rails#2771) +* Move Rails version conditional from index scaffold generated file to template. (Matt Jankowski, rspec/rspec-rails#2777) ### 6.1.3 / 2024-06-19 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v6.1.2...v6.1.3) Bug Fixes: -* Reset `ActiveSupport::CurrentAttributes` between examples. (Javier Julio, #2752) -* Fix a broken link in generated mailer previews. (Chiara Núñez, #2764) +* Reset `ActiveSupport::CurrentAttributes` between examples. (Javier Julio, rspec/rspec-rails#2752) +* Fix a broken link in generated mailer previews. (Chiara Núñez, rspec/rspec-rails#2764) * Fix `have_status_code` behaviour with deprecated status names by delegating - to `Rack::Utils.status_code/1` to set the expected status code. (Darren Boyd, #2765) + to `Rack::Utils.status_code/1` to set the expected status code. (Darren Boyd, rspec/rspec-rails#2765) ### 6.1.2 / 2024-03-19 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v6.1.1...v6.1.2) Bug Fixes: -* Fix generated mailer paths to match Rails convention. (Patrício dos Santos, #2735) -* Fix class in template for generator specs. (Nicolas Buduroi, #2744) +* Fix generated mailer paths to match Rails convention. (Patrício dos Santos, rspec/rspec-rails#2735) +* Fix class in template for generator specs. (Nicolas Buduroi, rspec/rspec-rails#2744) ### 6.1.1 / 2024-01-25 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v6.1.0...v6.1.1) @@ -51,8 +123,8 @@ Bug Fixes: Bug Fixes: * Improved deprecation message for `RSpec::Rails::Configuration.fixture_paths` - (Benoit Tigeot, #2720) -* Fix support for namespaced fixtures in Rails 7.1. (Benedikt Deicke, #2716) + (Benoit Tigeot, rspec/rspec-rails#2720) +* Fix support for namespaced fixtures in Rails 7.1. (Benedikt Deicke, rspec/rspec-rails#2716) ### 6.1.0 / 2023-11-21 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v6.0.4...v6.1.0) @@ -61,17 +133,17 @@ Enhancements: * Support for Rails 7.1 * Minor tweak to generated `rails_helper.rb` to use `Rails.root.join`. - (@masato-bkn, Ryo Nakamura, #2640, #2678) + (@masato-bkn, Ryo Nakamura, rspec/rspec-rails#2640, rspec/rspec-rails#2678) * Add `RSpec::Rails::Configuration.fixture_paths` configuration to support the matching change to `ActiveRecord::TestFixtures`, previous singular - form is deprecated and will be removed in Rails 7.2. (Juan Gueçaimburu, #2673) + form is deprecated and will be removed in Rails 7.2. (Juan Gueçaimburu, rspec/rspec-rails#2673) * Add `send_email` matcher to match emails rather than specific jobs. - (Andrei Kaleshka, #2670) + (Andrei Kaleshka, rspec/rspec-rails#2670) * When using `render` in view specs, `:locals` will now be merged into the default implicit template, allowing `render locals: {...}` style calls. - (Jon Rowe, #2686) + (Jon Rowe, rspec/rspec-rails#2686) * Add support for `Rails.config.action_mailer.preview_paths` on Rails 7.1/ - (Jon Rowe, #2706) + (Jon Rowe, rspec/rspec-rails#2706) ### 6.0.4 / 2023-11-21 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v6.0.3...v6.0.4) @@ -79,14 +151,14 @@ Enhancements: Bug Fixes: * Fuzzy match `have_broadcasted_to` so that argument matchers can be used. - (Timothy Peraza, #2684) -* Fix fixture warning during `:context` hooks on Rails `main`. (Jon Rowe, #2685) -* Fix `stub_template` on Rails `main`. (Jon Rowe, #2685) -* Fix variable name in scaffolded view specs when namespaced. (Taketo Takashima, #2694) + (Timothy Peraza, rspec/rspec-rails#2684) +* Fix fixture warning during `:context` hooks on Rails `main`. (Jon Rowe, rspec/rspec-rails#2685) +* Fix `stub_template` on Rails `main`. (Jon Rowe, rspec/rspec-rails#2685) +* Fix variable name in scaffolded view specs when namespaced. (Taketo Takashima, rspec/rspec-rails#2694) * Prevent `take_failed_screenshot` producing an additional error through `metadata` - access. (Jon Rowe, #2704) -* Use `ActiveSupport::ExecutionContext::TestHelper` on Rails 7+. (Jon Rowe, #2711) -* Fix leak of templates stubbed with `stub_template` on Rails 7.1. (Jon Rowe, #2714) + access. (Jon Rowe, rspec/rspec-rails#2704) +* Use `ActiveSupport::ExecutionContext::TestHelper` on Rails 7+. (Jon Rowe, rspec/rspec-rails#2711) +* Fix leak of templates stubbed with `stub_template` on Rails 7.1. (Jon Rowe, rspec/rspec-rails#2714) ### 6.0.3 / 2023-05-31 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v6.0.2...v6.0.3) @@ -94,8 +166,8 @@ Bug Fixes: Bug Fixes: * Set `ActiveStorage::FixtureSet.file_fixture_path` when including file fixture support. - (Jason Yates, #2671) -* Allow `broadcast_to` matcher to take Symbols. (@Vagab, #2680) + (Jason Yates, rspec/rspec-rails#2671) +* Allow `broadcast_to` matcher to take Symbols. (@Vagab, rspec/rspec-rails#2680) ### 6.0.2 / 2023-05-04 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v6.0.1...v6.0.2) @@ -103,18 +175,18 @@ Bug Fixes: Bug Fixes: * Fix ActionView::PathSet when `render_views` is off for Rails 7.1. - (Eugene Kenny, Iliana, #2631) + (Eugene Kenny, Iliana, rspec/rspec-rails#2631) * Support Rails 7.1's `#fixtures_paths` in example groups (removes a deprecation warning). - (Nicholas Simmons, #2664) + (Nicholas Simmons, rspec/rspec-rails#2664) * Fix `have_enqueued_job` to properly detect enqueued jobs when other jobs were - performed inside the expectation block. (Slava Kardakov, Phil Pirozhkov, #2573) + performed inside the expectation block. (Slava Kardakov, Phil Pirozhkov, rspec/rspec-rails#2573) ### 6.0.1 / 2022-10-18 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v6.0.0...v6.0.1) Bug Fixes: -* Prevent tagged logged support in Rails 7 calling `#name`. (Jon Rowe, #2625) +* Prevent tagged logged support in Rails 7 calling `#name`. (Jon Rowe, rspec/rspec-rails#2625) ### 6.0.0 / 2022-10-10 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v5.1.2...v6.0.0) @@ -122,29 +194,29 @@ Bug Fixes: Enhancements: * Support Rails 7 -* Template tweaks to remove instance variables from generated specs. (Takuma Ishikawa, #2599) -* Generators now respects default path configuration option. (@vivekmiyani, #2508) +* Template tweaks to remove instance variables from generated specs. (Takuma Ishikawa, rspec/rspec-rails#2599) +* Generators now respects default path configuration option. (@vivekmiyani, rspec/rspec-rails#2508) Breaking Changes: * Drop support for Rails below 6.1 * Drop support for Ruby below 2.5 (following supported versions of Rails 6.1) * Change the order of `after_teardown` from `after` to `around` in system - specs to improve compatibility with extensions and Capybara. (Tim Diggins, #2596) + specs to improve compatibility with extensions and Capybara. (Tim Diggins, rspec/rspec-rails#2596) Deprecations: * Deprecates integration spec generator (`rspec:integration`) which was an alias of request spec generator (`rspec:request`) - (Luka Lüdicke, #2374) + (Luka Lüdicke, rspec/rspec-rails#2374) ### 5.1.2 / 2022-04-24 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v5.1.1...v5.1.2) Bug Fixes: -* Fix controller scaffold templates parameter name. (Taketo Takashima, #2591) -* Include generator specs in the inferred list of specs. (Jason Karns, #2597) +* Fix controller scaffold templates parameter name. (Taketo Takashima, rspec/rspec-rails#2591) +* Include generator specs in the inferred list of specs. (Jason Karns, rspec/rspec-rails#2597) ### 5.1.1 / 2022-03-07 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v5.1.0...v5.1.1) @@ -152,7 +224,7 @@ Bug Fixes: Bug Fixes: * Properly handle global id serialised arguments in `have_enqueued_mail`. - (Jon Rowe, #2578) + (Jon Rowe, rspec/rspec-rails#2578) ### 5.1.0 / 2022-01-26 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v5.0.3...v5.1.0) @@ -160,9 +232,9 @@ Bug Fixes: Enhancements: * Make the API request scaffold template more consistent and compatible with - Rails 6.1. (Naoto Hamada, #2484) + Rails 6.1. (Naoto Hamada, rspec/rspec-rails#2484) * Change the scaffold `rails_helper.rb` template to use `require_relative`. - (Jon Dufresne, #2528) + (Jon Dufresne, rspec/rspec-rails#2528) ### 5.0.3 / 2022-01-26 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v5.0.2...v5.0.3) @@ -170,10 +242,10 @@ Enhancements: Bug Fixes: * Properly name params in controller and request spec templates when - using the `--model-name` parameter. (@kenzo-tanaka, #2534) + using the `--model-name` parameter. (@kenzo-tanaka, rspec/rspec-rails#2534) * Fix parameter matching with mail delivery job and - ActionMailer::MailDeliveryJob. (Fabio Napoleoni, #2516, #2546) -* Fix Rails 7 `have_enqueued_mail` compatibility (Mikael Henriksson, #2537, #2546) + ActionMailer::MailDeliveryJob. (Fabio Napoleoni, rspec/rspec-rails#2516, rspec/rspec-rails#2546) +* Fix Rails 7 `have_enqueued_mail` compatibility (Mikael Henriksson, rspec/rspec-rails#2537, rspec/rspec-rails#2546) ### 5.0.2 / 2021-08-14 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v5.0.1...v5.0.2) @@ -181,12 +253,12 @@ Bug Fixes: Bug Fixes: * Prevent generated job specs from duplicating `_job` in filenames. - (Nick Flückiger, #2496) + (Nick Flückiger, rspec/rspec-rails#2496) * Fix `ActiveRecord::TestFixture#uses_transaction` by using example description to replace example name rather than example in our monkey patched - `run_in_transaction?` method. (Stan Lo, #2495) + `run_in_transaction?` method. (Stan Lo, rspec/rspec-rails#2495) * Prevent keyword arguments being lost when methods are invoked dynamically - in controller specs. (Josh Cheek, #2509, #2514) + in controller specs. (Josh Cheek, rspec/rspec-rails#2509, rspec/rspec-rails#2514) ### 5.0.1 / 2021-03-18 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v5.0.0...v5.0.1) @@ -194,15 +266,15 @@ Bug Fixes: Bug Fixes: * Limit multibyte example descriptions when used in system tests for #method_name - which ends up as screenshot names etc. (@y-yagi, #2405, #2487) + which ends up as screenshot names etc. (@y-yagi, rspec/rspec-rails#2405, rspec/rspec-rails#2487) ### 5.0.0 / 2021-03-09 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v4.1.1...v5.0.0) Enhancements: -* Support new #file_fixture_path and new fixture test support code. (Jon Rowe, #2398) -* Support for Rails 6.1. (Benoit Tigeot, Jon Rowe, Phil Pirozhkov, and more #2398) +* Support new #file_fixture_path and new fixture test support code. (Jon Rowe, rspec/rspec-rails#2398) +* Support for Rails 6.1. (Benoit Tigeot, Jon Rowe, Phil Pirozhkov, and more rspec/rspec-rails#2398) Breaking Changes: @@ -213,102 +285,102 @@ Breaking Changes: Bug Fixes: * Remove generated specs when destroying a generated controller. - (@Naokimi, #2475) + (@Naokimi, rspec/rspec-rails#2475) ### 4.1.0 / 2021-03-06 Enhancements: * Issue a warning when using job matchers with `#at` mismatch on `usec` precision. - (Jon Rowe, #2350) + (Jon Rowe, rspec/rspec-rails#2350) * Generated request specs now have a bare `_spec` suffix instead of `request_spec`. - (Eloy Espinaco, Luka Lüdicke, #2355, #2356, #2378) + (Eloy Espinaco, Luka Lüdicke, rspec/rspec-rails#2355, rspec/rspec-rails#2356, rspec/rspec-rails#2378) * Generated scaffold now includes engine route helpers when inside a mountable engine. - (Andrew W. Lee, #2372) + (Andrew W. Lee, rspec/rspec-rails#2372) * Improve request spec "controller" scaffold when no action is specified. - (Thomas Hareau, #2399) -* Introduce testing snippets concept (Phil Pirozhkov, Benoit Tigeot, #2423) + (Thomas Hareau, rspec/rspec-rails#2399) +* Introduce testing snippets concept (Phil Pirozhkov, Benoit Tigeot, rspec/rspec-rails#2423) * Prevent collisions with `let(:name)` for Rails 6.1 and `let(:method_name)` on older - Rails. (Benoit Tigeot, #2461) + Rails. (Benoit Tigeot, rspec/rspec-rails#2461) ### 4.0.2 / 2020-12-26 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v4.0.1...v4.0.2) Bug Fixes: -* Indent all extra failure lines output from system specs. (Alex Robbin, #2321) -* Generated request spec for update now uses the correct let. (Paul Hanyzewski, #2344) +* Indent all extra failure lines output from system specs. (Alex Robbin, rspec/rspec-rails#2321) +* Generated request spec for update now uses the correct let. (Paul Hanyzewski, rspec/rspec-rails#2344) * Return `true`/`false` from predicate methods in config rather than raw values. - (Phil Pirozhkov, Jon Rowe, #2353, #2354) + (Phil Pirozhkov, Jon Rowe, rspec/rspec-rails#2353, rspec/rspec-rails#2354) * Remove old #fixture_path feature detection code which broke under newer Rails. - (Koen Punt, Jon Rowe, #2370) -* Fix an error when `use_active_record` is `false` (Phil Pirozhkov, #2423) + (Koen Punt, Jon Rowe, rspec/rspec-rails#2370) +* Fix an error when `use_active_record` is `false` (Phil Pirozhkov, rspec/rspec-rails#2423) ### 4.0.1 / 2020-05-16 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v4.0.0...v4.0.1) Bug Fixes: -* Remove warning when calling `driven_by` in system specs. (Aubin Lorieux, #2302) -* Fix comparison of times for `#at` in job matchers. (Jon Rowe, Markus Doits, #2304) +* Remove warning when calling `driven_by` in system specs. (Aubin Lorieux, rspec/rspec-rails#2302) +* Fix comparison of times for `#at` in job matchers. (Jon Rowe, Markus Doits, rspec/rspec-rails#2304) * Allow `have_enqueued_mail` to match when a sub class of `ActionMailer::DeliveryJob` - is set using `.delivery_job=`. (Atsushi Yoshida #2305) -* Restore Ruby 2.2.x compatibility. (Jon Rowe, #2332) -* Add `required_ruby_version` to gem spec. (Marc-André Lafortune, #2319, #2338) + is set using `.delivery_job=`. (Atsushi Yoshida rspec/rspec-rails#2305) +* Restore Ruby 2.2.x compatibility. (Jon Rowe, rspec/rspec-rails#2332) +* Add `required_ruby_version` to gem spec. (Marc-André Lafortune, rspec/rspec-rails#2319, rspec/rspec-rails#2338) ### 4.0.0 / 2020-03-24 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v3.9.1...v4.0.0) Enhancements: -* Adds support for Rails 6. (Penelope Phippen, Benoit Tigeot, Jon Rowe, #2071) +* Adds support for Rails 6. (Penelope Phippen, Benoit Tigeot, Jon Rowe, rspec/rspec-rails#2071) * Adds support for JRuby on Rails 5.2 and 6 -* Add support for parameterised mailers (Ignatius Reza, #2125) -* Add ActionMailbox spec helpers and test type (James Dabbs, #2119) -* Add ActionCable spec helpers and test type (Vladimir Dementyev, #2113) +* Add support for parameterised mailers (Ignatius Reza, rspec/rspec-rails#2125) +* Add ActionMailbox spec helpers and test type (James Dabbs, rspec/rspec-rails#2119) +* Add ActionCable spec helpers and test type (Vladimir Dementyev, rspec/rspec-rails#2113) * Add support for partial args when using `have_enqueued_mail` - (Ignatius Reza, #2118, #2125) -* Add support for time arguments for `have_enqueued_job` (@alpaca-tc, #2157) -* Improve path parsing in view specs render options. (John Hawthorn, #2115) + (Ignatius Reza, rspec/rspec-rails#2118, rspec/rspec-rails#2125) +* Add support for time arguments for `have_enqueued_job` (@alpaca-tc, rspec/rspec-rails#2157) +* Improve path parsing in view specs render options. (John Hawthorn, rspec/rspec-rails#2115) * Add routing spec template as an option for generating controller specs. - (David Revelo, #2134) -* Add argument matcher support to `have_enqueued_*` matchers. (Phil Pirozhkov, #2206) -* Switch generated templates to use ruby 1.9 hash keys. (Tanbir Hasan, #2224) + (David Revelo, rspec/rspec-rails#2134) +* Add argument matcher support to `have_enqueued_*` matchers. (Phil Pirozhkov, rspec/rspec-rails#2206) +* Switch generated templates to use ruby 1.9 hash keys. (Tanbir Hasan, rspec/rspec-rails#2224) * Add `have_been_performed`/`have_performed_job`/`perform_job` ActiveJob - matchers (Isaac Seymour, #1785) + matchers (Isaac Seymour, rspec/rspec-rails#1785) * Default to generating request specs rather than controller specs when - generating a controller (Luka Lüdicke, #2222) -* Allow `ActiveJob` matchers `#on_queue` modifier to take symbolic queue names. (Nils Sommer, #2283) + generating a controller (Luka Lüdicke, rspec/rspec-rails#2222) +* Allow `ActiveJob` matchers `#on_queue` modifier to take symbolic queue names. (Nils Sommer, rspec/rspec-rails#2283) * The scaffold generator now generates request specs in preference to controller specs. - (Luka Lüdicke, #2288) -* Add configuration option to disable ActiveRecord. (Jon Rowe, Phil Pirozhkov, Hermann Mayer, #2266) + (Luka Lüdicke, rspec/rspec-rails#2288) +* Add configuration option to disable ActiveRecord. (Jon Rowe, Phil Pirozhkov, Hermann Mayer, rspec/rspec-rails#2266) * Set `ActionDispatch::SystemTesting::Server.silence_puma = true` when running system specs. - (ta1kt0me, Benoit Tigeot, #2289) + (ta1kt0me, Benoit Tigeot, rspec/rspec-rails#2289) Bug Fixes: * `EmptyTemplateHandler.call` now needs to support an additional argument in - Rails 6. (Pavel Rosický, #2089) + Rails 6. (Pavel Rosický, rspec/rspec-rails#2089) * Suppress warning from `SQLite3Adapter.represent_boolean_as_integer` which is - deprecated. (Pavel Rosický, #2092) + deprecated. (Pavel Rosický, rspec/rspec-rails#2092) * `ActionView::Template#formats` has been deprecated and replaced by - `ActionView::Template#format`(Seb Jacobs, #2100) + `ActionView::Template#format`(Seb Jacobs, rspec/rspec-rails#2100) * Replace `before_teardown` as well as `after_teardown` to ensure screenshots - are generated correctly. (Jon Rowe, #2164) + are generated correctly. (Jon Rowe, rspec/rspec-rails#2164) * `ActionView::FixtureResolver#hash` has been renamed to `ActionView::FixtureResolver#data`. - (Penelope Phippen, #2076) + (Penelope Phippen, rspec/rspec-rails#2076) * Prevent `driven_by(:selenium)` being called due to hook precedence. - (Takumi Shotoku, #2188) + (Takumi Shotoku, rspec/rspec-rails#2188) * Prevent a `WrongScopeError` being thrown during loading fixtures on Rails - 6.1 development version. (Edouard Chin, #2215) -* Fix Mocha mocking support with `should`. (Phil Pirozhkov, #2256) + 6.1 development version. (Edouard Chin, rspec/rspec-rails#2215) +* Fix Mocha mocking support with `should`. (Phil Pirozhkov, rspec/rspec-rails#2256) * Restore previous conditional check for setting `default_url_options` in feature - specs, prevents a `NoMethodError` in some scenarios. (Eugene Kenny, #2277) + specs, prevents a `NoMethodError` in some scenarios. (Eugene Kenny, rspec/rspec-rails#2277) * Allow changing `ActiveJob::Base.queue_adapter` inside a system spec. - (Jonathan Rochkind, #2242) -* `rails generate generator` command now creates related spec file (Joel Azemar, #2217) -* Relax upper `capybara` version constraint to allow for Capybara 3.x (Phil Pirozhkov, #2281) -* Clear ActionMailer test mailbox after each example (Benoit Tigeot, #2293) + (Jonathan Rochkind, rspec/rspec-rails#2242) +* `rails generate generator` command now creates related spec file (Joel Azemar, rspec/rspec-rails#2217) +* Relax upper `capybara` version constraint to allow for Capybara 3.x (Phil Pirozhkov, rspec/rspec-rails#2281) +* Clear ActionMailer test mailbox after each example (Benoit Tigeot, rspec/rspec-rails#2293) Breaking Changes: @@ -320,7 +392,7 @@ Breaking Changes: Bug Fixes: -* Add missing require for have_enqueued_mail matcher. (Ignatius Reza, #2117) +* Add missing require for have_enqueued_mail matcher. (Ignatius Reza, rspec/rspec-rails#2117) ### 3.9.0 / 2019-10-08 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v3.8.3...v3.9.0) @@ -328,18 +400,18 @@ Bug Fixes: Enhancements * Use `__dir__` instead of `__FILE__` in generated `rails_helper.rb` where - supported. (OKURA Masafumi, #2048) + supported. (OKURA Masafumi, rspec/rspec-rails#2048) * Add `have_enqueued_mail` matcher as a "super" matcher to the `ActiveJob` matchers - making it easier to match on `ActiveJob` delivered emails. (Joel Lubrano, #2047) -* Add generator for system specs on Rails 5.1 and above. (Andrzej Sliwa, #1933) -* Add generator for generator specs. (@ConSou, #2085) -* Add option to generate routes when generating controller specs. (David Revelo, #2134) + making it easier to match on `ActiveJob` delivered emails. (Joel Lubrano, rspec/rspec-rails#2047) +* Add generator for system specs on Rails 5.1 and above. (Andrzej Sliwa, rspec/rspec-rails#1933) +* Add generator for generator specs. (@ConSou, rspec/rspec-rails#2085) +* Add option to generate routes when generating controller specs. (David Revelo, rspec/rspec-rails#2134) Bug Fixes: * Make the `ActiveJob` matchers fail when multiple jobs are queued for negated matches. e.g. `expect { job; job; }.to_not have_enqueued_job`. - (Emric Istanful, #2069) + (Emric Istanful, rspec/rspec-rails#2069) ### 3.8.3 / 2019-10-03 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v3.8.2...v3.8.3) @@ -347,9 +419,9 @@ Bug Fixes: Bug Fixes: * Namespaced fixtures now generate a `/` separated path rather than an `_`. - (@nxlith, #2077) + (@nxlith, rspec/rspec-rails#2077) * Check the arity of `errors` before attempting to use it to generate the `be_valid` - error message. (Kevin Kuchta, #2096) + error message. (Kevin Kuchta, rspec/rspec-rails#2096) ### 3.8.2 / 2019-01-13 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v3.8.1...v3.8.2) @@ -357,13 +429,13 @@ Bug Fixes: Bug Fixes: * Fix issue with generator for preview specs where `Mailer` would be duplicated - in the name. (Kohei Sugi, #2037) -* Fix the request spec generator to handle namespaced files. (Kohei Sugi, #2057) + in the name. (Kohei Sugi, rspec/rspec-rails#2037) +* Fix the request spec generator to handle namespaced files. (Kohei Sugi, rspec/rspec-rails#2057) * Further truncate system test filenames to handle cases when extra words are - prepended. (Takumi Kaji, #2058) + prepended. (Takumi Kaji, rspec/rspec-rails#2058) * Backport: Make the `ActiveJob` matchers fail when multiple jobs are queued for negated matches. e.g. `expect { job; job; }.to_not have_enqueued_job - (Emric Istanful, #2069) + (Emric Istanful, rspec/rspec-rails#2069) ### 3.8.1 / 2018-10-23 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v3.8.0...v3.8.1) @@ -371,11 +443,11 @@ Bug Fixes: Bug Fixes: * Fix `NoMethodError: undefined method 'strip'` when using a `Pathname` object - as the fixture file path. (Aaron Kromer, #2026) + as the fixture file path. (Aaron Kromer, rspec/rspec-rails#2026) * When generating feature specs, do not duplicate namespace in the path name. - (Laura Paakkinen, #2034) + (Laura Paakkinen, rspec/rspec-rails#2034) * Prevent `ActiveJob::DeserializationError` from being issued when `ActiveJob` - matchers de-serialize arguments. (@aymeric-ledorze, #2036) + matchers de-serialize arguments. (@aymeric-ledorze, rspec/rspec-rails#2036) ### 3.8.0 / 2018-08-04 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v3.7.2...v3.8.0) @@ -383,25 +455,25 @@ Bug Fixes: Enhancements: * Improved message when migrations are pending in the default `rails_helper.rb` - (Koichi ITO, #1924) + (Koichi ITO, rspec/rspec-rails#1924) * `have_http_status` matcher now supports Rails 5.2 style response symbols - (Douglas Lovell, #1951) + (Douglas Lovell, rspec/rspec-rails#1951) * Change generated Rails helper to match Rails standards for Rails.root - (Alessandro Rodi, #1960) + (Alessandro Rodi, rspec/rspec-rails#1960) * At support for asserting enqueued jobs have no wait period attached. - (Brad Charna, #1977) + (Brad Charna, rspec/rspec-rails#1977) * Cache instances of `ActionView::Template` used in `stub_template` resulting - in increased performance due to less allocations and setup. (Simon Coffey, #1979) + in increased performance due to less allocations and setup. (Simon Coffey, rspec/rspec-rails#1979) * Rails scaffold generator now respects longer namespaces (e.g. api/v1/\). - (Laura Paakkinen, #1958) + (Laura Paakkinen, rspec/rspec-rails#1958) Bug Fixes: * Escape quotation characters when producing method names for system spec - screenshots. (Shane Cavanaugh, #1955) + screenshots. (Shane Cavanaugh, rspec/rspec-rails#1955) * Use relative path for resolving fixtures when `fixture_path` is not set. - (Laurent Cobos, #1943) -* Allow custom template resolvers in view specs. (@ahorek, #1941) + (Laurent Cobos, rspec/rspec-rails#1943) +* Allow custom template resolvers in view specs. (@ahorek, rspec/rspec-rails#1941) ### 3.7.2 / 2017-11-20 @@ -409,16 +481,16 @@ Bug Fixes: Bug Fixes: -* Delay loading system test integration until used. (Jon Rowe, #1903) +* Delay loading system test integration until used. (Jon Rowe, rspec/rspec-rails#1903) * Ensure specs using the aggregate failures feature take screenshots on failure. - (Matt Brictson, #1907) + (Matt Brictson, rspec/rspec-rails#1907) ### 3.7.1 / 2017-10-18 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v3.7.0...v3.7.1) Bug Fixes: -* Prevent system test integration loading when puma or capybara are missing (Sam Phippen, #1884) +* Prevent system test integration loading when puma or capybara are missing (Sam Phippen, rspec/rspec-rails#1884) ### 3.7.0 / 2017-10-17 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v3.6.0...v3.7.0) @@ -426,27 +498,27 @@ Bug Fixes: Bug Fixes: * Prevent "template not rendered" log message from erroring in threaded - environments. (Samuel Cochran, #1831) -* Correctly generate job name in error message. (Wojciech Wnętrzak, #1814) + environments. (Samuel Cochran, rspec/rspec-rails#1831) +* Correctly generate job name in error message. (Wojciech Wnętrzak, rspec/rspec-rails#1814) Enhancements: * Allow `be_a_new(...).with(...)` matcher to accept matchers for - attribute values. (Britni Alexander, #1811) -* Only configure RSpec Mocks if it is fully loaded. (James Adam, #1856) -* Integrate with `ActionDispatch::SystemTestCase`. (Sam Phippen, #1813) + attribute values. (Britni Alexander, rspec/rspec-rails#1811) +* Only configure RSpec Mocks if it is fully loaded. (James Adam, rspec/rspec-rails#1856) +* Integrate with `ActionDispatch::SystemTestCase`. (Sam Phippen, rspec/rspec-rails#1813) ### 3.6.0 / 2017-05-04 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v3.6.0.beta2...v3.6.0) Enhancements: -* Add compatibility for Rails 5.1. (Sam Phippen, Yuichiro Kaneko, #1790) +* Add compatibility for Rails 5.1. (Sam Phippen, Yuichiro Kaneko, rspec/rspec-rails#1790) Bug Fixes: * Fix scaffold generator so that it does not generate broken controller specs - on Rails 3.x and 4.x. (Yuji Nakayama, #1710) + on Rails 3.x and 4.x. (Yuji Nakayama, rspec/rspec-rails#1710) ### 3.6.0.beta2 / 2016-12-12 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v3.6.0.beta1...v3.6.0.beta2) @@ -454,19 +526,19 @@ Bug Fixes: Enhancements: * Improve failure output of ActiveJob matchers by listing queued jobs. - (Wojciech Wnętrzak, #1722) + (Wojciech Wnętrzak, rspec/rspec-rails#1722) * Load `spec_helper.rb` earlier in `rails_helper.rb` by default. - (Kevin Glowacz, #1795) + (Kevin Glowacz, rspec/rspec-rails#1795) ### 3.6.0.beta1 / 2016-10-09 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v3.5.2...v3.6.0.beta1) Enhancements: -* Add support for `rake notes` in Rails `>= 5.1`. (John Meehan, #1661) +* Add support for `rake notes` in Rails `>= 5.1`. (John Meehan, rspec/rspec-rails#1661) * Remove `assigns` and `assert_template` from scaffold spec generators (Josh - Justice, #1689) -* Add support for generating scaffolds for api app specs. (Krzysztof Zych, #1685) + Justice, rspec/rspec-rails#1689) +* Add support for generating scaffolds for api app specs. (Krzysztof Zych, rspec/rspec-rails#1685) ### 3.5.2 / 2016-08-26 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v3.5.1...v3.5.2) @@ -474,9 +546,9 @@ Enhancements: Bug Fixes: * Stop unnecessarily loading `rspec/core` from `rspec/rails` to avoid - IRB context warning. (Myron Marston, #1678) + IRB context warning. (Myron Marston, rspec/rspec-rails#1678) * Deserialize arguments within ActiveJob matchers correctly. - (Wojciech Wnętrzak, #1684) + (Wojciech Wnętrzak, rspec/rspec-rails#1684) ### 3.5.1 / 2016-07-08 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v3.5.0...v3.5.1) @@ -497,30 +569,30 @@ Bug Fixes: Enhancements: -* Add support for block when using `with` on `have_enqueued_job`. (John Schroeder, #1578) -* Add support for `file_fixture(...)`. (Wojciech Wnętrzak, #1587) -* Add support for `setup` and `teardown` with blocks (Miklós Fazekas, #1598) +* Add support for block when using `with` on `have_enqueued_job`. (John Schroeder, rspec/rspec-rails#1578) +* Add support for `file_fixture(...)`. (Wojciech Wnętrzak, rspec/rspec-rails#1587) +* Add support for `setup` and `teardown` with blocks (Miklós Fazekas, rspec/rspec-rails#1598) * Add `enqueue_job ` alias for `have_enqueued_job`, support `once`/`twice`/ `thrice`, add `have_been_enqueued` matcher to support use without blocks. - (Sergey Alexandrovich, #1613) + (Sergey Alexandrovich, rspec/rspec-rails#1613) Bug fixes: -* Prevent asset helpers from taking precedence over route helpers. (Prem Sichanugrist, #1496) +* Prevent asset helpers from taking precedence over route helpers. (Prem Sichanugrist, rspec/rspec-rails#1496) * Prevent `NoMethodError` during failed `have_rendered` assertions on weird templates. - (Jon Rowe, #1623). + (Jon Rowe, rspec/rspec-rails#1623). ### 3.5.0.beta3 / 2016-04-02 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v3.5.0.beta2...v3.5.0.beta3) Enhancements: -* Add support for Rails 5 Beta 3 (Sam Phippen, Benjamin Quorning, Koen Punt, #1589, #1573) +* Add support for Rails 5 Beta 3 (Sam Phippen, Benjamin Quorning, Koen Punt, rspec/rspec-rails#1589, rspec/rspec-rails#1573) Bug fixes: * Support custom resolvers when preventing views from rendering. - (Jon Rowe, Benjamin Quorning, #1580) + (Jon Rowe, Benjamin Quorning, rspec/rspec-rails#1580) ### 3.5.0.beta2 / 2016-03-10 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v3.5.0.beta1...v3.5.0.beta2) @@ -529,12 +601,12 @@ Enhancements: * Include `ActionDispatch::IntegrationTest::Behavior` in request spec example groups when on Rails 5, allowing integration test helpers - to be used in request specs. (Scott Bronson, #1560) + to be used in request specs. (Scott Bronson, rspec/rspec-rails#1560) Bug fixes: * Make it possible to use floats in auto generated (scaffold) tests. - (Alwahsh, #1550) + (Alwahsh, rspec/rspec-rails#1550) ### 3.5.0.beta1 / 2016-02-06 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v3.4.2...v3.5.0.beta1) @@ -542,20 +614,20 @@ Bug fixes: Enhancements: * Add a `--singularize` option for the feature spec generator (Felicity McCabe, - #1503) -* Prevent leaking TestUnit methods in Rails 4+ (Fernando Seror Garcia, #1512) -* Add support for Rails 5 (Sam Phippen, #1492) + rspec/rspec-rails#1503) +* Prevent leaking TestUnit methods in Rails 4+ (Fernando Seror Garcia, rspec/rspec-rails#1512) +* Add support for Rails 5 (Sam Phippen, rspec/rspec-rails#1492) Bug fixes: * Make it possible to write nested specs within helper specs on classes that are - internal to helper classes. (Sam Phippen, Peter Swan, #1499). + internal to helper classes. (Sam Phippen, Peter Swan, rspec/rspec-rails#1499). * Warn if a fixture method is called from a `before(:context)` block, instead of - crashing with a `undefined method for nil:NilClass`. (Sam Phippen, #1501) -* Expose path to view specs (Ryan Clark, Sarah Mei, Sam Phippen, #1402) -* Prevent installing Rails 3.2.22.1 on Ruby 1.8.7. (Jon Rowe, #1540) + crashing with a `undefined method for nil:NilClass`. (Sam Phippen, rspec/rspec-rails#1501) +* Expose path to view specs (Ryan Clark, Sarah Mei, Sam Phippen, rspec/rspec-rails#1402) +* Prevent installing Rails 3.2.22.1 on Ruby 1.8.7. (Jon Rowe, rspec/rspec-rails#1540) * Raise a clear error when `have_enqueued_job` is used with non-test - adapter. (Wojciech Wnętrzak, #1489) + adapter. (Wojciech Wnętrzak, rspec/rspec-rails#1489) ### 3.4.2 / 2016-02-02 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v3.4.1...v3.4.2) @@ -563,7 +635,7 @@ Bug fixes: Bug Fixes: * Cache template resolvers during path lookup to prevent performance - regression from #1535. (Andrew White, #1544) + regression from rspec/rspec-rails#1535. (Andrew White, rspec/rspec-rails#1544) ### 3.4.1 / 2016-01-25 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v3.4.0...v3.4.1) @@ -571,7 +643,7 @@ Bug Fixes: Bug Fixes: * Fix no method error when rendering templates with explicit `:file` - parameters for Rails version `4.2.5.1`. (Andrew White, Sam Phippen, #1535) + parameters for Rails version `4.2.5.1`. (Andrew White, Sam Phippen, rspec/rspec-rails#1535) ### 3.4.0 / 2015-11-11 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v3.3.3...v3.4.0) @@ -579,20 +651,20 @@ Bug Fixes: Enhancements: * Improved the failure message for `have_rendered` matcher on a redirect - response. (Alex Egan, #1440) + response. (Alex Egan, rspec/rspec-rails#1440) * Add configuration option to filter out Rails gems from backtraces. - (Bradley Schaefer, #1458) + (Bradley Schaefer, rspec/rspec-rails#1458) * Enable resolver cache for view specs for a large speed improvement - (Chris Zetter, #1452) + (Chris Zetter, rspec/rspec-rails#1452) * Add `have_enqueued_job` matcher for checking if a block has queued jobs. - (Wojciech Wnętrzak, #1464) + (Wojciech Wnętrzak, rspec/rspec-rails#1464) Bug Fixes: * Fix another load order issued which causes an undefined method `fixture_path` error - when loading rspec-rails after a spec has been created. (Nikki Murray, #1430) + when loading rspec-rails after a spec has been created. (Nikki Murray, rspec/rspec-rails#1430) * Removed incorrect surrounding whitespace in the rspec-rails backtrace - exclusion pattern for its own `lib` code. (Jam Black, #1439) + exclusion pattern for its own `lib` code. (Jam Black, rspec/rspec-rails#1439) ### 3.3.3 / 2015-07-15 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v3.3.2...v3.3.3) @@ -600,7 +672,7 @@ Bug Fixes: Bug Fixes: * Fix issue with generators caused by `Rails.configuration.hidden_namespaces` - including symbols. (Dan Kohn, #1414) + including symbols. (Dan Kohn, rspec/rspec-rails#1414) ### 3.3.2 / 2015-06-18 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v3.3.1...v3.3.2) @@ -610,7 +682,7 @@ Bug Fixes: * Fix regression that caused stubbing abstract ActiveRecord model classes to trigger internal errors in rails due the the verifying double lifecycle wrongly calling `define_attribute_methods` on the - abstract AR class. (Jon Rowe, #1396) + abstract AR class. (Jon Rowe, rspec/rspec-rails#1396) ### 3.3.1 / 2015-06-14 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v3.3.0...v3.3.1) @@ -618,25 +690,25 @@ Bug Fixes: Bug Fixes: * Fix regression that caused stubbing ActiveRecord model classes to - trigger internal errors in rails. (Myron Marston, Aaron Kromer, #1395) + trigger internal errors in rails. (Myron Marston, Aaron Kromer, rspec/rspec-rails#1395) ### 3.3.0 / 2015-06-12 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v3.2.3...v3.3.0) Enhancements: -* Add support for PATCH to route specs created via scaffold. (Igor Zubkov, #1336) +* Add support for PATCH to route specs created via scaffold. (Igor Zubkov, rspec/rspec-rails#1336) * Improve controller and routing spec calls to `routes` by using `yield` - instead of `call`. (Anton Davydov, #1308) + instead of `call`. (Anton Davydov, rspec/rspec-rails#1308) * Add support for `ActiveJob` specs as standard `RSpec::Rails::RailsExampleGroup`s via both `type: :job` and inferring type from spec directory `spec/jobs`. - (Gabe Martin-Dempesy, #1361) + (Gabe Martin-Dempesy, rspec/rspec-rails#1361) * Include `RSpec::Rails::FixtureSupport` into example groups using metadata - `use_fixtures: true`. (Aaron Kromer, #1372) + `use_fixtures: true`. (Aaron Kromer, rspec/rspec-rails#1372) * Include `rspec:request` generator for generating request specs; this is an - alias of `rspec:integration` (Aaron Kromer, #1378) + alias of `rspec:integration` (Aaron Kromer, rspec/rspec-rails#1378) * Update `rails_helper` generator with a default check to abort the spec run - when the Rails environment is production. (Aaron Kromer, #1383) + when the Rails environment is production. (Aaron Kromer, rspec/rspec-rails#1383) ### 3.2.3 / 2015-06-06 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v3.2.2...v3.2.3) @@ -644,7 +716,7 @@ Enhancements: Bug Fixes: * Fix regression with the railtie resulting in undefined method `preview_path=` - on Rails 3.x and 4.0 (Aaron Kromer, #1388) + on Rails 3.x and 4.0 (Aaron Kromer, rspec/rspec-rails#1388) ### 3.2.2 / 2015-06-03 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v3.2.1...v3.2.2) @@ -652,12 +724,12 @@ Bug Fixes: Bug Fixes: * Fix auto-including of generic `Helper` object for view specs sitting in the - `app/views` root (David Daniell, #1289) -* Remove pre-loading of ActionMailer in the Railtie (Aaron Kromer, #1327) + `app/views` root (David Daniell, rspec/rspec-rails#1289) +* Remove pre-loading of ActionMailer in the Railtie (Aaron Kromer, rspec/rspec-rails#1327) * Fix undefined method `need_auto_run=` error when using Ruby 2.1 and Rails 3.2 - without the test-unit gem (Orien Madgwick, #1350) + without the test-unit gem (Orien Madgwick, rspec/rspec-rails#1350) * Fix load order issued which causes an undefined method `fixture_path` error - when loading rspec-rails after a spec has been created. (Aaron Kromer, #1372) + when loading rspec-rails after a spec has been created. (Aaron Kromer, rspec/rspec-rails#1372) ### 3.2.1 / 2015-02-23 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v3.2.0...v3.2.1) @@ -665,71 +737,71 @@ Bug Fixes: Bug Fixes: * Add missing `require` to RSpec generator root fixing an issue where Rail's - autoload does not find it in some environments. (Aaron Kromer, #1305) -* `be_routable` matcher now has the correct description. (Tony Ta, #1310) -* Fix dependency to allow Rails 4.2.x patches / pre-releases (Lucas Mazza, #1318) + autoload does not find it in some environments. (Aaron Kromer, rspec/rspec-rails#1305) +* `be_routable` matcher now has the correct description. (Tony Ta, rspec/rspec-rails#1310) +* Fix dependency to allow Rails 4.2.x patches / pre-releases (Lucas Mazza, rspec/rspec-rails#1318) * Disable the `test-unit` gem's autorunner on projects running Rails < 4.1 and - Ruby < 2.2 (Aaron Kromer, #1320) + Ruby < 2.2 (Aaron Kromer, rspec/rspec-rails#1320) ### 3.2.0 / 2015-02-03 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v3.1.0...v3.2.0) Enhancements: -* Include generator for `ActionMailer` mailer previews (Takashi Nakagawa, #1185) -* Configure the `ActionMailer` preview path via a Railtie (Aaron Kromer, #1236) -* Show all RSpec generators when running `rails generate` (Eliot Sykes, #1248) -* Support Ruby 2.2 with Rails 3.2 and 4.x (Aaron Kromer, #1264, #1277) +* Include generator for `ActionMailer` mailer previews (Takashi Nakagawa, rspec/rspec-rails#1185) +* Configure the `ActionMailer` preview path via a Railtie (Aaron Kromer, rspec/rspec-rails#1236) +* Show all RSpec generators when running `rails generate` (Eliot Sykes, rspec/rspec-rails#1248) +* Support Ruby 2.2 with Rails 3.2 and 4.x (Aaron Kromer, rspec/rspec-rails#1264, rspec/rspec-rails#1277) * Improve `instance_double` to support verifying dynamic column methods defined - by `ActiveRecord` (Jon Rowe, #1238) + by `ActiveRecord` (Jon Rowe, rspec/rspec-rails#1238) * Mirror the use of Ruby 1.9 hash syntax for the `type` tags in the spec - generators on Rails 4. (Michael Stock, #1292) + generators on Rails 4. (Michael Stock, rspec/rspec-rails#1292) Bug Fixes: * Fix `rspec:feature` generator to use `RSpec` namespace preventing errors when - monkey-patching is disabled. (Rebecca Skinner, #1231) + monkey-patching is disabled. (Rebecca Skinner, rspec/rspec-rails#1231) * Fix `NoMethodError` caused by calling `RSpec.feature` when Capybara is not - available or the Capybara version is < 2.4.0. (Aaron Kromer, #1261) + available or the Capybara version is < 2.4.0. (Aaron Kromer, rspec/rspec-rails#1261) * Fix `ArgumentError` when using an anonymous controller which inherits an - outer group's anonymous controller. (Yuji Nakayama, #1260) + outer group's anonymous controller. (Yuji Nakayama, rspec/rspec-rails#1260) * Fix "Test is not a class (TypeError)" error when using a custom `Test` class - in Rails 4.1 and 4.2. (Aaron Kromer, #1295) + in Rails 4.1 and 4.2. (Aaron Kromer, rspec/rspec-rails#1295) ### 3.1.0 / 2014-09-04 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v3.0.2...v3.1.0) Enhancements: -* Switch to using the `have_http_status` matcher in spec generators. (Aaron Kromer, #1086) +* Switch to using the `have_http_status` matcher in spec generators. (Aaron Kromer, rspec/rspec-rails#1086) * Update `rails_helper` generator to allow users to opt-in to auto-loading - `spec/support` files instead of forcing it upon them. (Aaron Kromer, #1137) -* Include generator for `ActiveJob`. (Abdelkader Boudih, #1155) + `spec/support` files instead of forcing it upon them. (Aaron Kromer, rspec/rspec-rails#1137) +* Include generator for `ActiveJob`. (Abdelkader Boudih, rspec/rspec-rails#1155) * Improve support for non-ActiveRecord apps by not loading ActiveRecord related - settings in the generated `rails_helper`. (Aaron Kromer, #1150) -* Remove Ruby warnings as a suggested configuration. (Aaron Kromer, #1163) -* Improve the semantics of the controller spec for scaffolds. (Griffin Smith, #1204) -* Use `#method` syntax in all generated controller specs. (Griffin Smith, #1206) + settings in the generated `rails_helper`. (Aaron Kromer, rspec/rspec-rails#1150) +* Remove Ruby warnings as a suggested configuration. (Aaron Kromer, rspec/rspec-rails#1163) +* Improve the semantics of the controller spec for scaffolds. (Griffin Smith, rspec/rspec-rails#1204) +* Use `#method` syntax in all generated controller specs. (Griffin Smith, rspec/rspec-rails#1206) Bug Fixes: -* Fix controller route lookup for Rails 4.2. (Tomohiro Hashidate, #1142) +* Fix controller route lookup for Rails 4.2. (Tomohiro Hashidate, rspec/rspec-rails#1142) ### 3.0.2 / 2014-07-21 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v3.0.1...v3.0.2) Bug Fixes: -* Suppress warning in `SetupAndTeardownAdapter`. (André Arko, #1085) -* Remove dependency on Rubygems. (Andre Arko & Doc Riteze, #1099) -* Standardize controller spec template style. (Thomas Kriechbaumer, #1122) +* Suppress warning in `SetupAndTeardownAdapter`. (André Arko, rspec/rspec-rails#1085) +* Remove dependency on Rubygems. (Andre Arko & Doc Riteze, rspec/rspec-rails#1099) +* Standardize controller spec template style. (Thomas Kriechbaumer, rspec/rspec-rails#1122) ### 3.0.1 / 2014-06-02 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v3.0.0...v3.0.1) Bug Fixes: -* Fix missing require in `rails g rspec:install`. (Sam Phippen, #1058) +* Fix missing require in `rails g rspec:install`. (Sam Phippen, rspec/rspec-rails#1058) ### 3.0.0 / 2014-06-01 [Full Changelog](https://github.com/rspec/rspec-rails/compare/v3.0.0.rc1...v3.0.0) diff --git a/Gemfile b/Gemfile index 688f8d499..5df5cc6e4 100644 --- a/Gemfile +++ b/Gemfile @@ -12,7 +12,7 @@ group :documentation do end gem 'capybara' -gem 'ffi', '~> 1.15.5' +gem 'ffi', '> 1.15.5' gem 'rake', '> 12' gem 'rubocop', '~> 1.28.2' diff --git a/Gemfile-rails-dependencies b/Gemfile-rails-dependencies index d8487f7fa..97e7b4514 100644 --- a/Gemfile-rails-dependencies +++ b/Gemfile-rails-dependencies @@ -11,21 +11,19 @@ def add_net_gems_dependency end end -def add_sqlite3_gem_dependency - # sqlite3 is an optional, unspecified, dependency and Rails 6.0 only supports `~> 1.4` +def add_sqlite3_gem_dependency(rails_version) + # sqlite3 is an optional, unspecified, dependency and Rails 8.0 only supports `~> 2.0` if RUBY_VERSION.to_f < 3 # sqlite3 1.7.x doesn't work on all platforms for Ruby 2.x gem 'sqlite3', '~> 1.4', '< 1.7', platforms: [:ruby] + elsif rails_version.to_f >= 8 + gem 'sqlite3', '~> 2.0', platforms: [:ruby] else - gem 'sqlite3', '~> 1.4', platforms: [:ruby] + gem 'sqlite3', '~> 1.7', platforms: [:ruby] end end -if RUBY_VERSION.to_f < 2.7 - gem 'puma', '< 6.0.0' -else - gem 'puma' -end +gem 'puma' case version = ENV['RAILS_VERSION'] || (File.exist?(version_file) && File.read(version_file).chomp) || '' when /main/ @@ -33,34 +31,24 @@ when /main/ gem 'activerecord-jdbcsqlite3-adapter', git: 'https://github.com/jruby/activerecord-jdbc-adapter', platforms: [:jruby] gem 'selenium-webdriver', require: false - # Rails 8 requires 2.0.0 gem 'sqlite3', '~> 2.0', platforms: [:ruby] -when /stable$/ - gem_list = %w[rails railties actionmailer actionpack activerecord activesupport activejob actionview] - gem 'activerecord-jdbcsqlite3-adapter', git: 'https://github.com/jruby/activerecord-jdbc-adapter', platforms: [:jruby] - - gem_list.each do |rails_gem| - gem rails_gem, :git => "https://github.com/rails/rails.git", :branch => version - end - add_sqlite3_gem_dependency when nil, false, "" - gem "rails", "~> 7.0.0" + if RUBY_VERSION.to_f > 3.1 + gem "rails", "~> 8.0.0" + gem 'sqlite3', '~> 2.0', platforms: [:ruby] + else + gem "rails", "~> 7.2.0" + gem 'sqlite3', '~> 1.7', platforms: [:ruby] + end + gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby] gem 'selenium-webdriver', require: false - add_sqlite3_gem_dependency else version_number = version.split(' ').last - add_net_gems_dependency if version_number < '7.0' gem "rails", version gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby] - # This version number reflects our build version not our actual version, - # this will be fixed in 7.1.4 and should be removed then. - if version_number == '7.1.0' - gem 'selenium-webdriver', '< 4.20.0', require: false - else - gem 'selenium-webdriver', require: false - end - add_sqlite3_gem_dependency + gem 'selenium-webdriver', require: false + add_sqlite3_gem_dependency(version_number) end diff --git a/Gemfile-rspec-dependencies b/Gemfile-rspec-dependencies index a0af7b2f5..e68e5fdb8 100644 --- a/Gemfile-rspec-dependencies +++ b/Gemfile-rspec-dependencies @@ -1,13 +1,9 @@ branch = File.read(File.expand_path("../maintenance-branch", __FILE__)).chomp %w[rspec rspec-core rspec-expectations rspec-mocks rspec-support].each do |lib| - library_path = File.expand_path("../../#{lib}", __FILE__) + library_path = File.expand_path("../../rspec/#{lib}", __FILE__) if File.exist?(library_path) && !ENV['USE_GIT_REPOS'] - gem lib, :path => library_path, :require => false + gem lib, path: library_path, require: false else - if lib == 'rspec' - gem 'rspec', :git => "https://github.com/rspec/rspec-metagem.git", :branch => branch, :require => false - else - gem lib, :git => "https://github.com/rspec/#{lib}.git", :branch => branch, :require => false - end + gem lib, git: "https://github.com/rspec/rspec", glob: "#{lib}/#{lib}.gemspec" end end diff --git a/README.md b/README.md index 2d8e271f8..9c44ed811 100644 --- a/README.md +++ b/README.md @@ -8,9 +8,20 @@ They’re also specifications (or _specs,_ for short): detailed explanations of how the application is supposed to behave, expressed in plain English. -According to [RSpec Rails new versioning strategy][] use: +## Supported Versions + +We follow a versioning strategy as defined by [RSpec Rails versioning strategy][] the +TL;DR of which is that we support currently supported versions of Rails, and will +issue a major version change when removing older versions from support. + +**Note** Rails 7.1 is supported by the Rails team until October 2025, and thus `rspec-rails` +will support bug fixes for this version in the `7-2-maintenance` branch until that time. + +Accordingly you should use: + +* **[`rspec-rails` 8.x][]** for Rails 8.0 or 7.2. * **[`rspec-rails` 7.x][]** for Rails 7.x. -* **[`rspec-rails` 6.x][]** for Rails 6.1. +* **[`rspec-rails` 6.x][]** for Rails 6.1, 7.0 or 7.1. * **[`rspec-rails` 5.x][]** for Rails 5.2 or 6.x. * **[`rspec-rails` 4.x][]** for Rails from 5.x or 6.x. * **[`rspec-rails` 3.x][]** for Rails earlier than 5.0. @@ -27,13 +38,14 @@ According to [RSpec Rails new versioning strategy][] use: [`rspec-rails` 4.x]: https://github.com/rspec/rspec-rails/tree/4-1-maintenance [`rspec-rails` 5.x]: https://github.com/rspec/rspec-rails/tree/5-1-maintenance [`rspec-rails` 6.x]: https://github.com/rspec/rspec-rails/tree/6-1-maintenance -[`rspec-rails` 7.x]: https://github.com/rspec/rspec-rails/tree/7-0-maintenance -[RSpec Rails new versioning strategy]: https://github.com/rspec/rspec-rails/blob/main/rfcs/versioning-strategy.md +[`rspec-rails` 7.x]: https://github.com/rspec/rspec-rails/tree/7-1-maintenance +[`rspec-rails` 8.x]: https://github.com/rspec/rspec-rails/tree/8-0-maintenance +[RSpec Rails versioning strategy]: https://github.com/rspec/rspec-rails/blob/main/rfcs/versioning-strategy.md ## Installation **IMPORTANT** This README / branch refers to the current development build. -See the [`7-0-maintenance` branch on Github](https://github.com/rspec/rspec-rails/tree/7-0-maintenance) if you want or require the latest stable release. +See the [`8-0-maintenance` branch on Github](https://github.com/rspec/rspec-rails/tree/8-0-maintenance) if you want or require the latest stable release. 1. Add `rspec-rails` to **both** the `:development` and `:test` groups of your app’s `Gemfile`: @@ -41,15 +53,12 @@ See the [`7-0-maintenance` branch on Github](https://github.com/rspec/rspec-rail ```ruby # Run against this stable release group :development, :test do - gem 'rspec-rails', '~> 7.0.0' + gem 'rspec-rails', '~> 8.0.0' end # Or, run against the main branch - # (requires main-branch versions of all related RSpec libraries) group :development, :test do - %w[rspec-core rspec-expectations rspec-mocks rspec-rails rspec-support].each do |lib| - gem lib, git: "https://github.com/rspec/#{lib}.git", branch: 'main' - end + gem 'rspec-rails', git: 'https://github.com/rspec/rspec-rails' end ``` @@ -88,7 +97,7 @@ read the [`rspec-rails` upgrade notes][] to find out what to watch out for. Be sure to check the general [RSpec upgrade notes][] as well. -[`rspec-rails` upgrade notes]: https://rspec.info/features/7-0/rspec-rails/upgrade +[`rspec-rails` upgrade notes]: https://rspec.info/features/8-0/rspec-rails/upgrade [RSpec upgrade notes]: https://rspec.info/upgrading-from-rspec-2/ ## Usage @@ -210,22 +219,22 @@ to test the various parts of a Rails system: Follow the links above for examples of how each matcher is used. [the matchers that come standard in RSpec]: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers -[`be_a_new`]: https://rspec.info/features/7-0/rspec-rails/matchers/new-record-matcher -[`render_template`]: https://rspec.info/features/7-0/rspec-rails/matchers/render-template-matcher -[`redirect_to`]: https://rspec.info/features/7-0/rspec-rails/matchers/redirect-to-matcher -[`route_to`]: https://rspec.info/features/7-0/rspec-rails/routing-specs/route-to-matcher -[`be_routable`]: https://rspec.info/features/7-0/rspec-rails/routing-specs/be-routable-matcher -[`have_http_status`]: https://rspec.info/features/7-0/rspec-rails/matchers/have-http-status-matcher -[`match_array`]: https://rspec.info/features/7-0/rspec-rails/matchers/relation-match-array -[`have_been_enqueued`]: https://rspec.info/features/7-0/rspec-rails/matchers/have-been-enqueued-matcher -[`have_enqueued_job`]: https://rspec.info/features/7-0/rspec-rails/matchers/have-enqueued-job-matcher +[`be_a_new`]: https://rspec.info/features/8-0/rspec-rails/matchers/new-record-matcher +[`render_template`]: https://rspec.info/features/8-0/rspec-rails/matchers/render-template-matcher +[`redirect_to`]: https://rspec.info/features/8-0/rspec-rails/matchers/redirect-to-matcher +[`route_to`]: https://rspec.info/features/8-0/rspec-rails/routing-specs/route-to-matcher +[`be_routable`]: https://rspec.info/features/8-0/rspec-rails/routing-specs/be-routable-matcher +[`have_http_status`]: https://rspec.info/features/8-0/rspec-rails/matchers/have-http-status-matcher +[`match_array`]: https://rspec.info/features/8-0/rspec-rails/matchers/relation-match-array +[`have_been_enqueued`]: https://rspec.info/features/8-0/rspec-rails/matchers/have-been-enqueued-matcher +[`have_enqueued_job`]: https://rspec.info/features/8-0/rspec-rails/matchers/have-enqueued-job-matcher ### What else does RSpec Rails add? For a comprehensive look at RSpec Rails’ features, read the [official Cucumber documentation][]. -[official Cucumber documentation]: https://rspec.info/features/7-0/rspec-rails +[official Cucumber documentation]: https://rspec.info/features/8-0/rspec-rails ## What tests should I write? @@ -270,20 +279,20 @@ RSpec.describe User, type: :model do ... ``` -[request]: https://rspec.info/features/7-0/rspec-rails/request-specs/request-spec -[feature]: https://rspec.info/features/7-0/rspec-rails/feature-specs/feature-spec -[system]: https://rspec.info/features/7-0/rspec-rails/system-specs/system-specs -[model]: https://rspec.info/features/7-0/rspec-rails/model-specs -[controller]: https://rspec.info/features/7-0/rspec-rails/controller-specs -[mailer]: https://rspec.info/features/7-0/rspec-rails/mailer-specs -[job]: https://rspec.info/features/7-0/rspec-rails/job-specs/job-spec -[view]: https://rspec.info/features/7-0/rspec-rails/view-specs/view-spec -[routing]: https://rspec.info/features/7-0/rspec-rails/routing-specs -[helper]: https://rspec.info/features/7-0/rspec-rails/helper-specs/helper-spec +[request]: https://rspec.info/features/8-0/rspec-rails/request-specs/request-spec +[feature]: https://rspec.info/features/8-0/rspec-rails/feature-specs/feature-spec +[system]: https://rspec.info/features/8-0/rspec-rails/system-specs/system-specs +[model]: https://rspec.info/features/8-0/rspec-rails/model-specs +[controller]: https://rspec.info/features/8-0/rspec-rails/controller-specs +[mailer]: https://rspec.info/features/8-0/rspec-rails/mailer-specs +[job]: https://rspec.info/features/8-0/rspec-rails/job-specs/job-spec +[view]: https://rspec.info/features/8-0/rspec-rails/view-specs/view-spec +[routing]: https://rspec.info/features/8-0/rspec-rails/routing-specs +[helper]: https://rspec.info/features/8-0/rspec-rails/helper-specs/helper-spec [`ActionDispatch::IntegrationTest`]: https://api.rubyonrails.org/classes/ActionDispatch/IntegrationTest.html [`ActionDispatch::SystemTestCase`]: https://api.rubyonrails.org/classes/ActionDispatch/SystemTestCase.html [`ActionController::TestCase`]: https://api.rubyonrails.org/classes/ActionController/TestCase.html -[in the appropriate folder]: https://rspec.info/features/7-0/rspec-rails/directory-structure +[in the appropriate folder]: https://rspec.info/features/8-0/rspec-rails/directory-structure ### System specs, feature specs, request specs–what’s the difference? @@ -367,9 +376,6 @@ you can run the specs and Cucumber features, or submit a pull request. ### RSpec base libraries * https://github.com/rspec/rspec -* https://github.com/rspec/rspec-core -* https://github.com/rspec/rspec-expectations -* https://github.com/rspec/rspec-mocks ### Recommended third-party extensions diff --git a/Rakefile b/Rakefile index da1a6fc94..35aac1bdf 100644 --- a/Rakefile +++ b/Rakefile @@ -105,6 +105,11 @@ namespace :smoke do in_example_app args.cmd.to_s end + desc "run rake routes in example app" + task :routes do + in_example_app "bin/rails routes" + end + desc "run RSPEC_OPTS environment variable in the example app for local dev" task :rspec do in_example_app "LOCATION='../../example_app_generator/run_specs.rb' bin/rspec #{ENV.fetch("RSPEC_OPTS")}" @@ -144,6 +149,11 @@ namespace :no_active_record do "no_active_record:smoke", ] + desc "run rake routes in example app" + task :routes do + in_example_app "bin/rails routes", app_dir: example_app_dir + end + desc "run RSPEC_OPTS environment variable in the example app for local dev" task :rspec do in_example_app "LOCATION='../../example_app_generator/run_specs.rb' bin/rspec #{ENV.fetch("RSPEC_OPTS")}", app_dir: example_app_dir @@ -165,7 +175,7 @@ namespace :no_active_record do sh "rm -f #{bindir}/rails" sh "bundle exec rails new #{example_app_dir} --no-rc --skip-active-record --skip-javascript --skip-bootsnap " \ "--skip-sprockets --skip-git --skip-test-unit --skip-listen --skip-bundle --skip-spring " \ - "--skip-action-text --template=example_app_generator/generate_app.rb" + "--skip-action-text --skip-solid --template=example_app_generator/generate_app.rb" in_example_app(app_dir: example_app_dir) do sh "./ci_retry_bundle_install.sh 2>&1" @@ -188,7 +198,7 @@ namespace :no_active_record do desc "generate a bunch of stuff with generators" task :stuff do - in_example_app "bin/rake #{rails_template_command} LOCATION='../../example_app_generator/generate_stuff.rb'", app_dir: example_app_dir + in_example_app "bin/rake #{rails_template_command} LOCATION='../../example_app_generator/generate_stuff.rb' __RSPEC_NO_AR=true", app_dir: example_app_dir end end end diff --git a/benchmarks/before_block_capture_block_vs_yield.rb b/benchmarks/before_block_capture_block_vs_yield.rb index e294c0683..e8be2954a 100644 --- a/benchmarks/before_block_capture_block_vs_yield.rb +++ b/benchmarks/before_block_capture_block_vs_yield.rb @@ -42,11 +42,11 @@ def capture_block_and_call_n_times(n, &block) example context. rspec-core has already performed [many related benchmarks about -this](https://github.com/rspec/rspec-core/tree/main/benchmarks): +this](https://github.com/rspec/rspec/tree/main/rspec-core/benchmarks): -- [call vs yield](https://github.com/rspec/rspec-core/blob/main/benchmarks/call_v_yield.rb) -- [capture block vs yield](https://github.com/rspec/rspec-core/blob/main/benchmarks/capture_block_vs_yield.rb) -- [flat map vs inject](https://github.com/rspec/rspec-core/blob/main/benchmarks/flat_map_vs_inject.rb) +- [call vs yield](https://github.com/rspec/rspec/blob/main/rspec-core/benchmarks/call_v_yield.rb) +- [capture block vs yield](https://github.com/rspec/rspec/blob/main/rspec-core/benchmarks/capture_block_vs_yield.rb) +- [flat map vs inject](https://github.com/rspec/rspec/blob/main/rspec-core/benchmarks/flat_map_vs_inject.rb) The results are very interesting: @@ -64,7 +64,7 @@ def capture_block_and_call_n_times(n, &block) > See also `flat_map_vs_inject.rb`, which appears to contradict these > results a little bit. > -> -- https://github.com/rspec/rspec-core/blob/main/benchmarks/capture_block_vs_yield.rb#L83-L95 +> -- https://github.com/rspec/rspec/blob/main/rspec-core/benchmarks/capture_block_vs_yield.rb#L83-L95 and @@ -75,7 +75,7 @@ def capture_block_and_call_n_times(n, &block) > version remains faster in my benchmarks here no matter how small > I shrink the `words` array. I'm not sure why! > -> -- https://github.com/rspec/rspec-core/blob/main/benchmarks/flat_map_vs_inject.rb#L37-L42 +> -- https://github.com/rspec/rspec/blob/main/rspec-core/benchmarks/flat_map_vs_inject.rb#L37-L42 This seems to show that the error margin is enough to negate any benefit from capturing the block initially. It also shows that not capturing the block is diff --git a/example_app_generator/generate_app.rb b/example_app_generator/generate_app.rb index 5ffdca72a..ea9039a9b 100644 --- a/example_app_generator/generate_app.rb +++ b/example_app_generator/generate_app.rb @@ -11,7 +11,6 @@ 'ci_retry_bundle_install.sh' ) function_script_file = File.join(rspec_rails_repo_path, 'script/functions.sh') -capybara_backport_path = File.join(rspec_rails_repo_path, 'example_app_generator/spec/support/capybara.rb') in_root do prepend_to_file "Rakefile", "require 'active_support/all'" @@ -29,13 +28,11 @@ gsub_file "Gemfile", /.*rails-controller-testing.*/, "gem 'rails-controller-testing', git: 'https://github.com/rails/rails-controller-testing'" - # sqlite3 is an optional, unspecified, dependency of which Rails 6.0 only supports `~> 1.4`, Ruby 2.7 only supports < 1.7 and Rails 8.0 only supports `~> 2.0` - if RUBY_VERSION.to_f < 3 - gsub_file "Gemfile", /.*gem..sqlite3.*/, "gem 'sqlite3', '~> 1.4', '< 1.7'" - elsif Rails::VERSION::STRING > '8' + # sqlite3 is an optional, unspecified, dependency of which Rails 8.0 only supports `~> 2.0` + if Rails::VERSION::STRING > '8' gsub_file "Gemfile", /.*gem..sqlite3.*/, "gem 'sqlite3', '~> 2.0'" else - gsub_file "Gemfile", /.*gem..sqlite3.*/, "gem 'sqlite3', '~> 1.4'" + gsub_file "Gemfile", /.*gem..sqlite3.*/, "gem 'sqlite3', '~> 1.7'" end # remove webdrivers @@ -66,13 +63,4 @@ 'REPLACE_BUNDLE_PATH', bundle_install_path chmod 'ci_retry_bundle_install.sh', 0755 - - copy_file capybara_backport_path, 'spec/support/capybara.rb' - - if Rails::VERSION::STRING > '7' && Rails::VERSION::STRING < '7.2' - create_file 'app/assets/config/manifest.js' do - "//= link application.css" - end - create_file 'app/assets/stylesheets/application.css' - end end diff --git a/example_app_generator/generate_stuff.rb b/example_app_generator/generate_stuff.rb index 57e2f705d..77d5a3ef9 100644 --- a/example_app_generator/generate_stuff.rb +++ b/example_app_generator/generate_stuff.rb @@ -57,10 +57,10 @@ def skip_active_record? end def self.environment_hooks - if defined?(ActiveRecord) - AR - else + if ENV['__RSPEC_NO_AR'] NoAR + else + AR end end end diff --git a/example_app_generator/spec/support/capybara.rb b/example_app_generator/spec/support/capybara.rb deleted file mode 100644 index 1857791f9..000000000 --- a/example_app_generator/spec/support/capybara.rb +++ /dev/null @@ -1,51 +0,0 @@ -# This is a backport of a fix that was included in capybara 3.40.0 which was also Ruby version locked to 3.0+ -if RUBY_VERSION.to_f < 3 && Rails::VERSION::STRING.to_f >= 7.1 - Capybara.register_server :puma do |app, port, host, **options| - begin - require 'rackup' - rescue LoadError # rubocop:disable Lint/SuppressedException - end - begin - require 'rack/handler/puma' - rescue LoadError - raise LoadError, 'Capybara is unable to load `puma` for its server, please add `puma` ' \ - 'to your project or specify a different server via something like `Capybara.server = :webrick`.' - end - puma_rack_handler = defined?(Rackup::Handler::Puma) ? Rackup::Handler::Puma : Rack::Handler::Puma - - unless puma_rack_handler.respond_to?(:config) - raise LoadError, 'Capybara requires `puma` version 3.8.0 or higher,' \ - ' please upgrade `puma` or register and specify your own server block' - end - - # If we just run the Puma Rack handler it installs signal handlers which prevent us from being able to interrupt tests. - # Therefore construct and run the Server instance ourselves. - # puma_rack_handler.run(app, { Host: host, Port: port, Threads: "0:4", workers: 0, daemon: false }.merge(options)) - default_options = { Host: host, Port: port, Threads: '0:4', workers: 0, daemon: false } - options = default_options.merge(options) - - conf = puma_rack_handler.config(app, options) - conf.clamp - - puma_ver = Gem::Version.new(Puma::Const::PUMA_VERSION) - require 'capybara/registrations/patches/puma_ssl' if Gem::Requirement.new('>=4.0.0', '< 4.1.0').satisfied_by?(puma_ver) - - logger = (defined?(Puma::LogWriter) ? Puma::LogWriter : Puma::Events).then do |cls| - conf.options[:Silent] ? cls.strings : cls.stdio - end - conf.options[:log_writer] = logger - - logger.log 'Capybara starting Puma...' - logger.log "* Version #{Puma::Const::PUMA_VERSION}, codename: #{Puma::Const::CODE_NAME}" - logger.log "* Min threads: #{conf.options[:min_threads]}, max threads: #{conf.options[:max_threads]}" - - Puma::Server.new( - conf.app, - defined?(Puma::LogWriter) ? nil : logger, - conf.options - ).tap do |s| - s.binder.parse conf.options[:binds], (s.log_writer rescue s.events) # rubocop:disable Style/RescueModifier - s.min_threads, s.max_threads = conf.options[:min_threads], conf.options[:max_threads] if s.respond_to? :min_threads= - end.run.join - end -end diff --git a/example_app_generator/spec/support/default_preview_path b/example_app_generator/spec/support/default_preview_path index 7bfc2c5cf..419c89a56 100755 --- a/example_app_generator/spec/support/default_preview_path +++ b/example_app_generator/spec/support/default_preview_path @@ -7,6 +7,7 @@ end ENV['RAILS_ENV'] ||= 'development' # Pick the frameworks you want: begin + require "openssl" require "active_storage" require "active_storage/engine" rescue LoadError @@ -37,24 +38,16 @@ require_file_stub 'config/environment' do module ExampleApp class Application < Rails::Application config.eager_load = false - if Rails::VERSION::STRING.to_f >= 7.0 - config.active_support.cache_format_version = 7.0 - end + config.active_support.cache_format_version = 7.0 # Don't care if the mailer can't send. config.action_mailer.raise_delivery_errors = false unless ENV['NO_ACTION_MAILER'] if ENV['CUSTOM_PREVIEW_PATH'] - if Rails::VERSION::STRING.to_f >= 7.1 - config.action_mailer.preview_paths = [ENV['CUSTOM_PREVIEW_PATH']] - else - config.action_mailer.preview_path = ENV['CUSTOM_PREVIEW_PATH'] - end + config.action_mailer.preview_paths = [ENV['CUSTOM_PREVIEW_PATH']] end if ENV['SHOW_PREVIEWS'] config.action_mailer.show_previews = (ENV['SHOW_PREVIEWS'] == 'true') end - - config.active_record.legacy_connection_handling = false if Rails::VERSION::STRING.start_with?('7.0') end end @@ -69,11 +62,7 @@ exit(0) if ENV['NO_ACTION_MAILER'] if ENV['DEFAULT_URL'] puts ActionMailer::Base.default_url_options[:host] elsif defined?(::ActionMailer::Preview) - if Rails::VERSION::STRING.to_f >= 7.1 - puts Rails.application.config.action_mailer.preview_paths - else - puts Rails.application.config.action_mailer.preview_path - end + puts Rails.application.config.action_mailer.preview_paths end # This will force the loading of ActionMailer settings to ensure we do not diff --git a/example_app_generator/spec/verify_mailer_preview_path_spec.rb b/example_app_generator/spec/verify_mailer_preview_path_spec.rb index b35b285fa..0cc360521 100644 --- a/example_app_generator/spec/verify_mailer_preview_path_spec.rb +++ b/example_app_generator/spec/verify_mailer_preview_path_spec.rb @@ -33,37 +33,24 @@ def capture_exec(*ops) .reject { |line| line =~ /DEPRECATION WARNING/ } .reject { |line| line =~ /warning: previous/ } .reject { |line| line =~ /warning: already/ } + .reject { |line| line =~ /but will no longer be part of the default gems / } + .reject { |line| line =~ /You can add .* to your Gemfile/ } .join .chomp CaptureExec.new(out, $?.exitstatus) end - if ENV['RAILS_VERSION'] == 'main' && Rails::VERSION::STRING == "8.0.0.alpha" - before do - skip('This is broken on Rails main but is skipped for green builds of 7.1.x, please fix') - end - end - - if Rails::VERSION::STRING.to_f >= 7.1 - let(:expected_custom_path) { "/custom/path\n#{::Rails.root}/test/mailers/previews" } - let(:expected_rspec_path) { "#{::Rails.root}/spec/mailers/previews\n#{::Rails.root}/test/mailers/previews" } - - def have_no_preview(opts = {}) - expected_io = - if opts[:actually_blank] - be_blank - else - "#{::Rails.root}/test/mailers/previews" - end - have_attributes(io: expected_io, exit_status: 0) - end - else - let(:expected_custom_path) { '/custom/path' } - let(:expected_rspec_path) { "#{::Rails.root}/spec/mailers/previews" } + let(:expected_custom_path) { "/custom/path\n#{::Rails.root}/test/mailers/previews" } + let(:expected_rspec_path) { "#{::Rails.root}/spec/mailers/previews\n#{::Rails.root}/test/mailers/previews" } - def have_no_preview(_opts = {}) - have_attributes(io: be_blank, exit_status: 0) - end + def have_no_preview(opts = {}) + expected_io = + if opts[:actually_blank] + be_blank + else + "#{::Rails.root}/test/mailers/previews" + end + have_attributes(io: expected_io, exit_status: 0) end let(:exec_script) { @@ -139,17 +126,6 @@ def have_no_preview(_opts = {}) ) ).to eq('test-host') end - - it 'handles action mailer not being available' do - skip "Rails 7 forces eager loading on CI, loads app/mailers and fails" if Rails::VERSION::STRING.to_f >= 7.0 - - expect( - capture_exec( - custom_env.merge('NO_ACTION_MAILER' => 'true'), - exec_script - ) - ).to have_no_preview - end end else context 'in the development environment' do diff --git a/features/Generators.md b/features/Generators.md index 61fc83fec..74f96b241 100644 --- a/features/Generators.md +++ b/features/Generators.md @@ -1,7 +1,7 @@ # Using generators -RSpec spec are normally generated alongside other application components. -For instance, `rails generate model` will also generate an RSpec spec file +RSpec `_spec.rb` files are normally generated alongside other application components. +For instance, `rails generate model` will also generate an RSpec `_spec.rb` file for the model. Note that the generators are there to help you get started, but they are no @@ -18,17 +18,16 @@ will create a new spec file in `spec/models/widget_spec.rb`. The same generator pattern is available for all specs: -* scaffold -* model +* channel * controller -* helper -* view -* mailer -* integration * feature -* job -* channel * generator +* helper +* job * mailbox +* mailer +* model * request +* scaffold * system +* view diff --git a/features/GettingStarted.md b/features/Getting_started.md similarity index 100% rename from features/GettingStarted.md rename to features/Getting_started.md diff --git a/features/Transactions.md b/features/Transactions.md index 1fcc34fcb..c5237b07d 100644 --- a/features/Transactions.md +++ b/features/Transactions.md @@ -17,6 +17,9 @@ The idea is to start each example with a clean database, create whatever data is necessary for that example, and then remove that data by simply rolling back the transaction at the end of the example. +For how this affects methods exposing transaction visibility see: +https://guides.rubyonrails.org/testing.html#transactions + ### Disabling transactions If you prefer to manage the data yourself, or using another tool like diff --git a/features/backtrace_filtering.feature b/features/backtrace_filtering.feature index 58ef79802..360481a3f 100644 --- a/features/backtrace_filtering.feature +++ b/features/backtrace_filtering.feature @@ -39,9 +39,9 @@ Feature: Backtrace filtering Scenario: Using the bare `rspec` command When I run `rspec` Then the output should contain "1 example, 1 failure" - And the output should not contain "activesupport" + And the output should not contain "actionpack" Scenario: Using `rspec --backtrace` When I run `rspec --backtrace` Then the output should contain "1 example, 1 failure" - And the output should contain "activesupport" + And the output should contain "actionpack" diff --git a/features/file_fixture.feature b/features/file_fixture.feature index c6a765a53..2606c76e0 100644 --- a/features/file_fixture.feature +++ b/features/file_fixture.feature @@ -37,7 +37,6 @@ Feature: Using `file_fixture` When I run `rspec spec/lib/file_spec.rb` Then the examples should all pass - @rails_post_7 Scenario: Creating a ActiveStorage::Blob from a file fixture Given a file named "spec/fixtures/files/sample.txt" with: """ diff --git a/features/generator_specs/integration_specs.feature b/features/generator_specs/integration_specs.feature deleted file mode 100644 index ea9c14242..000000000 --- a/features/generator_specs/integration_specs.feature +++ /dev/null @@ -1,21 +0,0 @@ -Feature: Integration generator spec - - Scenario: Integration generator - When I run `bundle exec rails generate rspec:integration posts` - Then the features should pass - Then the output should contain: - """ - create spec/requests/posts_spec.rb - """ - - Scenario: Integration generator with customized `default-path` - Given a file named ".rspec" with: - """ - --default-path behaviour - """ - And I run `bundle exec rails generate rspec:integration posts` - Then the features should pass - Then the output should contain: - """ - create behaviour/requests/posts_spec.rb - """ diff --git a/features/matchers/redirect_to_matcher.feature b/features/matchers/redirect_to_matcher.feature index 5abfe3eef..7b620b725 100644 --- a/features/matchers/redirect_to_matcher.feature +++ b/features/matchers/redirect_to_matcher.feature @@ -12,7 +12,7 @@ Feature: `redirect_to` matcher """ruby require "rails_helper" - RSpec.describe WidgetsController do + RSpec.describe WidgetsController , type: :controller do describe "#create" do subject { post :create, :params => { :widget => { :name => "Foo" } } } diff --git a/features/matchers/render_template_matcher.feature b/features/matchers/render_template_matcher.feature index e8f7f3f91..4407f0b3a 100644 --- a/features/matchers/render_template_matcher.feature +++ b/features/matchers/render_template_matcher.feature @@ -14,7 +14,7 @@ Feature: `render_template` matcher """ruby require "rails_helper" - RSpec.describe GadgetsController do + RSpec.describe GadgetsController , type: :controller do describe "GET #index" do subject { get :index } @@ -38,7 +38,7 @@ Feature: `render_template` matcher """ruby require "rails_helper" - RSpec.describe GadgetsController do + RSpec.describe GadgetsController , type: :controller do describe "GET #index" do subject { get :index } @@ -60,7 +60,7 @@ Feature: `render_template` matcher """ruby require "rails_helper" - RSpec.describe "gadgets/index" do + RSpec.describe "gadgets/index" , type: :view do it "renders the index template" do assign(:gadgets, [Gadget.create!]) render diff --git a/features/matchers/send_email_matcher.feature b/features/matchers/send_email_matcher.feature index 84bb066ef..0b81092dd 100644 --- a/features/matchers/send_email_matcher.feature +++ b/features/matchers/send_email_matcher.feature @@ -16,7 +16,7 @@ Feature: `send_email` matcher """ruby require "rails_helper" - RSpec.describe NotificationsMailer do + RSpec.describe NotificationsMailer , type: :mailer do it "checks email sending by multiple params" do expect { NotificationsMailer.signup.deliver_now @@ -36,7 +36,7 @@ Feature: `send_email` matcher """ruby require "rails_helper" - RSpec.describe NotificationsMailer do + RSpec.describe NotificationsMailer , type: :mailer do it "checks email sending by one param only" do expect { NotificationsMailer.signup.deliver_now @@ -54,7 +54,7 @@ Feature: `send_email` matcher """ruby require "rails_helper" - RSpec.describe NotificationsMailer do + RSpec.describe NotificationsMailer , type: :mailer do it "checks email not sent" do expect { NotificationsMailer.signup.deliver_now diff --git a/features/support/env.rb b/features/support/env.rb index efac1e71e..d2dd4bf4d 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -2,13 +2,14 @@ require 'fileutils' module ArubaExt - def run_command(cmd, timeout = nil) + def run_command_and_stop(cmd, opts = {}) exec_cmd = cmd =~ /^rspec/ ? "bin/#{cmd}" : cmd + unset_bundler_env_vars # Ensure the correct Gemfile and binstubs are found in_current_directory do with_unbundled_env do - super(exec_cmd, timeout) + super(exec_cmd, opts) end end end @@ -59,7 +60,7 @@ def with_unbundled_env # We want fresh `example_app` project with empty `spec` dir except helpers. # FileUtils.cp_r on Ruby 1.9.2 doesn't preserve permissions. system('cp', '-r', example_app_dir, aruba_dir) - helpers = %w[spec/spec_helper.rb spec/rails_helper.rb spec/support/capybara.rb] + helpers = %w[spec/spec_helper.rb spec/rails_helper.rb] directories = [] Dir["#{aruba_dir}/spec/**/*"].each do |path| diff --git a/features/support/rails_versions.rb b/features/support/rails_versions.rb deleted file mode 100644 index 95354a0b3..000000000 --- a/features/support/rails_versions.rb +++ /dev/null @@ -1,15 +0,0 @@ -def rails_version - string_version = ENV.fetch("RAILS_VERSION", "~> 7.0.0") - if string_version == "main" || string_version.nil? - Float::INFINITY - else - string_version[/\d[.-]\d/].tr('-', '.') - end -end - -Before "@rails_post_7" do |scenario| - if rails_version.to_f < 7.0 - warn "Skipping scenario #{scenario.name} on Rails v#{rails_version}" - skip_this_scenario - end -end diff --git a/features/system_specs/system_specs.feature b/features/system_specs/system_specs.feature index bb729ac3f..33b893010 100644 --- a/features/system_specs/system_specs.feature +++ b/features/system_specs/system_specs.feature @@ -19,7 +19,21 @@ Feature: System specs RSpec **does not** use your `ApplicationSystemTestCase` helper. Instead it uses the default `driven_by(:selenium)` from Rails. If you want to override - this behaviour you can call `driven_by` manually in a test. + this behaviour you need to call `driven_by` in your specs. + + This can either be done manually in the spec files themselves or + you can use the configuration helpers to do this for every system spec, + for example by adding the following to `spec/rails_helper.rb`: + + ```ruby + RSpec.configure do |config| + ... + config.before(type: :system) do + driven_by :selenium_headless # Or your preferred default driver + end + ... + end + ``` System specs run in a transaction. So unlike feature specs with javascript, you do not need [DatabaseCleaner](https://github.com/DatabaseCleaner/database_cleaner). diff --git a/features/view_specs/inferred_controller_path.feature b/features/view_specs/inferred_controller_path.feature index 90c14dbbe..137edb9b9 100644 --- a/features/view_specs/inferred_controller_path.feature +++ b/features/view_specs/inferred_controller_path.feature @@ -5,7 +5,7 @@ Feature: View specs infer controller's path and action """ruby require "rails_helper" - RSpec.describe "widgets/new" do + RSpec.describe "widgets/new" , type: :view do it "infers the controller path" do expect(controller.request.path_parameters[:controller]).to eq("widgets") expect(controller.controller_path).to eq("widgets") @@ -20,7 +20,7 @@ Feature: View specs infer controller's path and action """ruby require "rails_helper" - RSpec.describe "widgets/new" do + RSpec.describe "widgets/new" , type: :view do it "infers the controller action" do expect(controller.request.path_parameters[:action]).to eq("new") end @@ -34,7 +34,7 @@ Feature: View specs infer controller's path and action """ruby require "rails_helper" - RSpec.describe "widgets/_form" do + RSpec.describe "widgets/_form" , type: :view do it "includes a link to new" do expect(controller.request.path_parameters[:action]).to be_nil end diff --git a/features/view_specs/stub_template.feature b/features/view_specs/stub_template.feature index 72fe75798..a134922ed 100644 --- a/features/view_specs/stub_template.feature +++ b/features/view_specs/stub_template.feature @@ -8,7 +8,7 @@ Feature: Using `stub_template` """ruby require "rails_helper" - RSpec.describe "gadgets/list" do + RSpec.describe "gadgets/list" , type: :view do it "renders the gadget partial for each gadget" do assign(:gadgets, [ double(:name => "First"), @@ -34,7 +34,7 @@ Feature: Using `stub_template` """ruby require "rails_helper" - RSpec.describe "gadgets/edit" do + RSpec.describe "gadgets/edit" , type: :view do before(:each) do @gadget = assign(:gadget, Gadget.create!) end diff --git a/features/view_specs/view_spec.feature b/features/view_specs/view_spec.feature index ecbd6d4de..2758baef1 100644 --- a/features/view_specs/view_spec.feature +++ b/features/view_specs/view_spec.feature @@ -27,7 +27,7 @@ Feature: View specs """ruby require "rails_helper" - RSpec.describe "widgets/index" do + RSpec.describe "widgets/index" , type: :view do it "displays all the widgets" do assign(:widgets, [ Widget.create!(:name => "slicer"), @@ -49,7 +49,7 @@ Feature: View specs """ruby require "rails_helper" - RSpec.describe "widgets/index" do + RSpec.describe "widgets/index" , type: :view do context "with 2 widgets" do before(:each) do @@ -76,7 +76,7 @@ Feature: View specs """ruby require "rails_helper" - RSpec.describe "rendering the widget template" do + RSpec.describe "rendering the widget template" , type: :view do it "displays the widget" do assign(:widget, Widget.create!(:name => "slicer")) @@ -98,7 +98,7 @@ Feature: View specs """ruby require "rails_helper" - RSpec.describe "rendering the widget template" do + RSpec.describe "rendering the widget template" , type: :view do context "with the inventory layout" do it "displays the widget" do assign(:widget, Widget.create!(:name => "slicer")) @@ -126,7 +126,7 @@ Feature: View specs """ruby require "rails_helper" - RSpec.describe "widgets/widget.html.erb" do + RSpec.describe "widgets/widget.html.erb" , type: :view do it "renders the HTML template" do render @@ -134,7 +134,7 @@ Feature: View specs end end - RSpec.describe "widgets/widget.xml.erb" do + RSpec.describe "widgets/widget.xml.erb" , type: :view do it "renders the XML template" do render @@ -158,7 +158,7 @@ Feature: View specs """ruby require "rails_helper" - RSpec.describe "widgets/index" do + RSpec.describe "widgets/index" , type: :view do it "displays the widget" do widget = Widget.create!(:name => "slicer") @@ -180,7 +180,7 @@ Feature: View specs """ruby require "rails_helper" - RSpec.describe "rendering locals in a partial" do + RSpec.describe "rendering locals in a partial" , type: :view do it "displays the widget" do widget = Widget.create!(:name => "slicer") @@ -202,7 +202,7 @@ Feature: View specs """ruby require "rails_helper" - RSpec.describe "rendering locals in a partial" do + RSpec.describe "rendering locals in a partial" , type: :view do it "displays the widget" do widget = Widget.create!(:name => "slicer") @@ -224,7 +224,7 @@ Feature: View specs """ruby require "rails_helper" - RSpec.describe "rendering text directly" do + RSpec.describe "rendering text directly" , type: :view do it "displays the given text" do render :plain => "This is directly rendered" @@ -255,7 +255,7 @@ Feature: View specs """ruby require 'rails_helper' - RSpec.describe 'secrets/index' do + RSpec.describe 'secrets/index' , type: :view do before do allow(view).to receive(:admin?).and_return(true) end @@ -274,7 +274,7 @@ Feature: View specs """ruby require "rails_helper" - RSpec.describe "controller.request.path_parameters" do + RSpec.describe "controller.request.path_parameters" , type: :view do it "matches the Rails environment by using symbols for keys" do [:controller, :action].each { |k| expect(controller.request.path_parameters.keys).to include(k) } end @@ -288,7 +288,7 @@ Feature: View specs """ruby require "rails_helper" - RSpec.describe "widgets/index" do + RSpec.describe "widgets/index" , type: :view do it "has a request.fullpath that is defined" do expect(controller.request.fullpath).to eq widgets_path end @@ -302,7 +302,7 @@ Feature: View specs """ruby require "rails_helper" - RSpec.describe "widgets/show" do + RSpec.describe "widgets/show" , type: :view do it "displays the widget with id: 1" do widget = Widget.create!(:name => "slicer") controller.extra_params = { :id => widget.id } diff --git a/lib/generators/rspec/authentication/authentication_generator.rb b/lib/generators/rspec/authentication/authentication_generator.rb new file mode 100644 index 000000000..f653c5c4e --- /dev/null +++ b/lib/generators/rspec/authentication/authentication_generator.rb @@ -0,0 +1,25 @@ +require 'generators/rspec' + +module Rspec + module Generators + # @private + class AuthenticationGenerator < Base + def initialize(args, *options) + args.replace(['User']) + super + end + + def create_user_spec + template 'user_spec.rb', target_path('models', 'user_spec.rb') + end + + hook_for :fixture_replacement + + def create_fixture_file + return if options[:fixture_replacement] + + template 'users.yml', target_path('fixtures', 'users.yml') + end + end + end +end diff --git a/lib/generators/rspec/authentication/templates/user_spec.rb b/lib/generators/rspec/authentication/templates/user_spec.rb new file mode 100644 index 000000000..4dfb2b069 --- /dev/null +++ b/lib/generators/rspec/authentication/templates/user_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe User, <%= type_metatag(:model) %> do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/lib/generators/rspec/authentication/templates/users.yml b/lib/generators/rspec/authentication/templates/users.yml new file mode 100644 index 000000000..d2eae44a2 --- /dev/null +++ b/lib/generators/rspec/authentication/templates/users.yml @@ -0,0 +1,11 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +<%% password_digest = BCrypt::Password.create("password") %> + +one: + email_address: one@example.com + password_digest: <%%= password_digest %> + +two: + email_address: two@example.com + password_digest: <%%= password_digest %> diff --git a/lib/generators/rspec/install/templates/spec/rails_helper.rb b/lib/generators/rspec/install/templates/spec/rails_helper.rb index ade688cfb..0840d3dc2 100644 --- a/lib/generators/rspec/install/templates/spec/rails_helper.rb +++ b/lib/generators/rspec/install/templates/spec/rails_helper.rb @@ -28,7 +28,9 @@ # Rails.root.glob('spec/support/**/*.rb').sort_by(&:to_s).each { |f| require f } <% if RSpec::Rails::FeatureCheck.has_active_record_migration? -%> -# Checks for pending migrations and applies them before tests are run. +# Ensures that the test database schema matches the current schema file. +# If there are pending migrations it will invoke `db:test:prepare` to +# recreate the test database by loading the schema. # If you are not using ActiveRecord, you can remove these lines. begin ActiveRecord::Migration.maintain_test_schema! @@ -39,13 +41,9 @@ RSpec.configure do |config| <% if RSpec::Rails::FeatureCheck.has_active_record? -%> # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures -<% if ::Rails::VERSION::STRING < "7.1.0" -%> - config.fixture_path = Rails.root.join('spec/fixtures') -<% else -%> config.fixture_paths = [ Rails.root.join('spec/fixtures') ] -<% end -%> # If you're not using ActiveRecord, or you'd prefer not to run each of your # examples within a transaction, remove the following line or assign false @@ -63,24 +61,28 @@ # note if you'd prefer not to run each example within a transaction, you # should set use_transactional_fixtures to false. # - # config.fixture_path = Rails.root.join('spec/fixtures') + # config.fixture_paths = [ + # Rails.root.join('spec/fixtures') + # ] # config.use_transactional_fixtures = true <% end -%> - # RSpec Rails can automatically mix in different behaviours to your tests - # based on their file location, for example enabling you to call `get` and - # `post` in specs under `spec/controllers`. - # - # You can disable this behaviour by removing the line below, and instead - # explicitly tag your specs with their type, e.g.: + # RSpec Rails uses metadata to mix in different behaviours to your tests, + # for example enabling you to call `get` and `post` in request specs. e.g.: # - # RSpec.describe UsersController, type: :controller do + # RSpec.describe UsersController, type: :request do # # ... # end # # The different available types are documented in the features, such as in - # https://rspec.info/features/7-0/rspec-rails - config.infer_spec_type_from_file_location! + # https://rspec.info/features/8-0/rspec-rails + # + # You can also infer these behaviours automatically by location, e.g. + # /spec/models would pull in the same behaviour as `type: :model` but this + # behaviour is considered legacy and will be removed in a future version. + # + # To enable this behaviour uncomment the line below. + # config.infer_spec_type_from_file_location! # Filter lines from Rails gems in backtraces. config.filter_rails_from_backtrace! diff --git a/lib/generators/rspec/integration/integration_generator.rb b/lib/generators/rspec/integration/integration_generator.rb deleted file mode 100644 index ed281e832..000000000 --- a/lib/generators/rspec/integration/integration_generator.rb +++ /dev/null @@ -1,29 +0,0 @@ -require 'generators/rspec' -require 'rspec/core/warnings' - -module Rspec - module Generators - # @private - class IntegrationGenerator < Base - class_option :request_specs, - type: :boolean, - default: true, - desc: "Generate request specs" - - source_paths << File.expand_path('../request/templates', __dir__) - - def generate_request_spec - return unless options[:request_specs] - - RSpec.warn_deprecation <<-WARNING.gsub(/\s*\|/, ' ') - |The integration generator is deprecated - |and will be deleted in RSpec-Rails 7. - |Please use the request generator instead. - WARNING - - template 'request_spec.rb', - target_path('requests', "#{name.underscore.pluralize}_spec.rb") - end - end - end -end diff --git a/lib/generators/rspec/scaffold/templates/api_controller_spec.rb b/lib/generators/rspec/scaffold/templates/api_controller_spec.rb index c8e519d5f..1a53e3e85 100644 --- a/lib/generators/rspec/scaffold/templates/api_controller_spec.rb +++ b/lib/generators/rspec/scaffold/templates/api_controller_spec.rb @@ -79,7 +79,7 @@ context "with invalid params" do it "renders a JSON response with errors for the new <%= singular_table_name %>" do post :create, params: {<%= singular_table_name %>: invalid_attributes}, session: valid_session - expect(response).to have_http_status(:unprocessable_entity) + expect(response).to have_http_status(<%= Rack::Utils::SYMBOL_TO_STATUS_CODE.key(422).inspect %>) expect(response.content_type).to eq('application/json') end end @@ -110,7 +110,7 @@ it "renders a JSON response with errors for the <%= singular_table_name %>" do <%= file_name %> = <%= class_name %>.create! valid_attributes put :update, params: {id: <%= file_name %>.to_param, <%= singular_table_name %>: invalid_attributes}, session: valid_session - expect(response).to have_http_status(:unprocessable_entity) + expect(response).to have_http_status(<%= Rack::Utils::SYMBOL_TO_STATUS_CODE.key(422).inspect %>) expect(response.content_type).to eq('application/json') end end diff --git a/lib/generators/rspec/scaffold/templates/api_request_spec.rb b/lib/generators/rspec/scaffold/templates/api_request_spec.rb index 065bbc98e..5b42a5146 100644 --- a/lib/generators/rspec/scaffold/templates/api_request_spec.rb +++ b/lib/generators/rspec/scaffold/templates/api_request_spec.rb @@ -79,7 +79,7 @@ it "renders a JSON response with errors for the new <%= singular_table_name %>" do post <%= index_helper %>_url, params: { <%= singular_table_name %>: invalid_attributes }, headers: valid_headers, as: :json - expect(response).to have_http_status(:unprocessable_entity) + expect(response).to have_http_status(<%= Rack::Utils::SYMBOL_TO_STATUS_CODE.key(422).inspect %>) expect(response.content_type).to match(a_string_including("application/json")) end end @@ -113,7 +113,7 @@ <%= file_name %> = <%= class_name %>.create! valid_attributes patch <%= show_helper %>, params: { <%= singular_table_name %>: invalid_attributes }, headers: valid_headers, as: :json - expect(response).to have_http_status(:unprocessable_entity) + expect(response).to have_http_status(<%= Rack::Utils::SYMBOL_TO_STATUS_CODE.key(422).inspect %>) expect(response.content_type).to match(a_string_including("application/json")) end end diff --git a/lib/generators/rspec/scaffold/templates/controller_spec.rb b/lib/generators/rspec/scaffold/templates/controller_spec.rb index 7f4320bd0..f8b135dc2 100644 --- a/lib/generators/rspec/scaffold/templates/controller_spec.rb +++ b/lib/generators/rspec/scaffold/templates/controller_spec.rb @@ -90,17 +90,10 @@ end context "with invalid params" do - <% if Rails.version.to_f < 7.0 %> - it "returns a success response (i.e. to display the 'new' template)" do - post :create, params: {<%= singular_table_name %>: invalid_attributes}, session: valid_session - expect(response).to be_successful - end - <% else %> it "renders a response with 422 status (i.e. to display the 'new' template)" do post :create, params: {<%= singular_table_name %>: invalid_attributes}, session: valid_session - expect(response).to have_http_status(:unprocessable_entity) + expect(response).to have_http_status(<%= Rack::Utils::SYMBOL_TO_STATUS_CODE.key(422).inspect %>) end - <% end %> end end @@ -125,19 +118,11 @@ end context "with invalid params" do - <% if Rails.version.to_f < 7.0 %> - it "returns a success response (i.e. to display the 'edit' template)" do - <%= file_name %> = <%= class_name %>.create! valid_attributes - put :update, params: {id: <%= file_name %>.to_param, <%= singular_table_name %>: invalid_attributes}, session: valid_session - expect(response).to be_successful - end - <% else %> it "renders a response with 422 status (i.e. to display the 'edit' template)" do <%= file_name %> = <%= class_name %>.create! valid_attributes put :update, params: {id: <%= file_name %>.to_param, <%= singular_table_name %>: invalid_attributes}, session: valid_session - expect(response).to have_http_status(:unprocessable_entity) + expect(response).to have_http_status(<%= Rack::Utils::SYMBOL_TO_STATUS_CODE.key(422).inspect %>) end - <% end %> end end diff --git a/lib/generators/rspec/scaffold/templates/index_spec.rb b/lib/generators/rspec/scaffold/templates/index_spec.rb index 627b475cf..bf0381078 100644 --- a/lib/generators/rspec/scaffold/templates/index_spec.rb +++ b/lib/generators/rspec/scaffold/templates/index_spec.rb @@ -18,7 +18,11 @@ it "renders a list of <%= ns_table_name %>" do render - cell_selector = <%= Rails::VERSION::STRING >= '7' ? "'div>p'" : "'tr>td'" %> +<% if Rails.version.to_f < 8.1 -%> + cell_selector = 'div>p' +<% else -%> + cell_selector = 'div>div>div' +<% end -%> <% for attribute in output_attributes -%> assert_select cell_selector, text: Regexp.new(<%= value_for(attribute) %>.to_s), count: 2 <% end -%> diff --git a/lib/generators/rspec/scaffold/templates/request_spec.rb b/lib/generators/rspec/scaffold/templates/request_spec.rb index 6d6fdab9e..2103e143b 100644 --- a/lib/generators/rspec/scaffold/templates/request_spec.rb +++ b/lib/generators/rspec/scaffold/templates/request_spec.rb @@ -83,17 +83,10 @@ }.to change(<%= class_name %>, :count).by(0) end - <% if Rails.version.to_f < 7.0 %> - it "renders a successful response (i.e. to display the 'new' template)" do - post <%= index_helper %>_url, params: { <%= singular_table_name %>: invalid_attributes } - expect(response).to be_successful - end - <% else %> it "renders a response with 422 status (i.e. to display the 'new' template)" do post <%= index_helper %>_url, params: { <%= singular_table_name %>: invalid_attributes } - expect(response).to have_http_status(:unprocessable_entity) + expect(response).to have_http_status(<%= Rack::Utils::SYMBOL_TO_STATUS_CODE.key(422).inspect %>) end - <% end %> end end @@ -119,19 +112,11 @@ end context "with invalid parameters" do - <% if Rails.version.to_f < 7.0 %> - it "renders a successful response (i.e. to display the 'edit' template)" do - <%= file_name %> = <%= class_name %>.create! valid_attributes - patch <%= show_helper %>, params: { <%= singular_table_name %>: invalid_attributes } - expect(response).to be_successful - end - <% else %> it "renders a response with 422 status (i.e. to display the 'edit' template)" do <%= file_name %> = <%= class_name %>.create! valid_attributes patch <%= show_helper %>, params: { <%= singular_table_name %>: invalid_attributes } - expect(response).to have_http_status(:unprocessable_entity) + expect(response).to have_http_status(<%= Rack::Utils::SYMBOL_TO_STATUS_CODE.key(422).inspect %>) end - <% end %> end end diff --git a/lib/rspec-rails.rb b/lib/rspec-rails.rb index 4d6ce04cf..e59cc5da2 100644 --- a/lib/rspec-rails.rb +++ b/lib/rspec-rails.rb @@ -22,8 +22,7 @@ class Railtie < ::Rails::Railtie Hash[dirs.map { |d| [d.split('/').last, d] }].each do |type, dir| name = type.singularize.capitalize - ::Rails::CodeStatistics.register_directory "#{name} specs", dir - ::Rails::CodeStatistics::TEST_TYPES << "#{name} specs" + ::Rails::CodeStatistics.register_directory "#{name} specs", dir, test_directory: true end end @@ -65,18 +64,10 @@ def config_preview_path?(options) end end - if ::Rails::VERSION::STRING >= "7.1.0" - def config_default_preview_path(options) - return unless options.preview_paths.empty? + def config_default_preview_path(options) + return unless options.preview_paths.empty? - options.preview_paths << "#{::Rails.root}/spec/mailers/previews" - end - else - def config_default_preview_path(options) - return unless options.preview_path.blank? - - options.preview_path = "#{::Rails.root}/spec/mailers/previews" - end + options.preview_paths << "#{::Rails.root}/spec/mailers/previews" end def supports_action_mailer_previews?(config) diff --git a/lib/rspec/rails/configuration.rb b/lib/rspec/rails/configuration.rb index 79f64e38d..b166027d8 100644 --- a/lib/rspec/rails/configuration.rb +++ b/lib/rspec/rails/configuration.rb @@ -1,4 +1,3 @@ -# rubocop: disable Metrics/ModuleLength module RSpec module Rails # Fake class to document RSpec Rails configuration options. In practice, @@ -57,7 +56,7 @@ def self.add_test_type_configurations(config) end # @private - def self.initialize_configuration(config) # rubocop:disable Metrics/MethodLength,Metrics/CyclomaticComplexity,Metrics/AbcSize,Metrics/PerceivedComplexity + def self.initialize_configuration(config) # rubocop:disable Metrics/MethodLength config.backtrace_exclusion_patterns << /vendor\// config.backtrace_exclusion_patterns << %r{lib/rspec/rails} @@ -69,12 +68,7 @@ def self.initialize_configuration(config) # rubocop:disable Metrics/MethodLength config.add_setting :use_transactional_fixtures, alias_with: :use_transactional_examples config.add_setting :use_instantiated_fixtures config.add_setting :global_fixtures - - if ::Rails::VERSION::STRING < "7.1.0" - config.add_setting :fixture_path - else - config.add_setting :fixture_paths - end + config.add_setting :fixture_paths config.include RSpec::Rails::FixtureSupport, :use_fixtures @@ -90,7 +84,7 @@ def self.initialize_configuration(config) # rubocop:disable Metrics/MethodLength config.add_setting :file_fixture_path, default: 'spec/fixtures/files' config.include RSpec::Rails::FileFixtureSupport - # Add support for fixture_path on fixture_file_upload + # Add support for fixture_paths on fixture_file_upload config.include RSpec::Rails::FixtureFileUploadSupport # This allows us to expose `render_views` as a config option even though it @@ -114,40 +108,6 @@ def render_views? rendering_views? end - undef :rendering_views? if respond_to?(:rendering_views?) - def rendering_views? - !!rendering_views - end - - # Define boolean predicates rather than relying on rspec-core due - # to the bug fix in rspec/rspec-core#2736, note some of these - # predicates are a bit nonsensical, but they exist for backwards - # compatibility, we can tidy these up in `rspec-rails` 5. - undef :fixture_path? if respond_to?(:fixture_path?) - def fixture_path? - !!fixture_path - end - - undef :global_fixtures? if respond_to?(:global_fixtures?) - def global_fixtures? - !!global_fixtures - end - - undef :infer_base_class_for_anonymous_controllers? if respond_to?(:infer_base_class_for_anonymous_controllers?) - def infer_base_class_for_anonymous_controllers? - !!infer_base_class_for_anonymous_controllers - end - - undef :use_instantiated_fixtures? if respond_to?(:use_instantiated_fixtures?) - def use_instantiated_fixtures? - !!use_instantiated_fixtures - end - - undef :use_transactional_fixtures? if respond_to?(:use_transactional_fixtures?) - def use_transactional_fixtures? - !!use_transactional_fixtures - end - def infer_spec_type_from_file_location! DIRECTORY_MAPPINGS.each do |type, dir_parts| escaped_path = Regexp.compile(dir_parts.join('[\\\/]') + '[\\\/]') @@ -163,29 +123,6 @@ def filter_rails_from_backtrace! filter_gems_from_backtrace "activemodel", "activerecord", "activesupport", "activejob" end - - # @deprecated TestFixtures#fixture_path is deprecated and will be removed in Rails 7.2 - if ::Rails::VERSION::STRING >= "7.1.0" - def fixture_path - RSpec.deprecate( - "config.fixture_path", - replacement: "config.fixture_paths", - message: "Rails 7.1 has deprecated the singular fixture_path in favour of an array." \ - "You should migrate to plural:" - ) - fixture_paths&.first - end - - def fixture_path=(path) - RSpec.deprecate( - "config.fixture_path = #{path.inspect}", - replacement: "config.fixture_paths = [#{path.inspect}]", - message: "Rails 7.1 has deprecated the singular fixture_path in favour of an array." \ - "You should migrate to plural:" - ) - self.fixture_paths = Array(path) - end - end end add_test_type_configurations(config) @@ -219,4 +156,3 @@ def fixture_path=(path) initialize_configuration RSpec.configuration end end -# rubocop: enable Metrics/ModuleLength diff --git a/lib/rspec/rails/example/rails_example_group.rb b/lib/rspec/rails/example/rails_example_group.rb index ed343de35..07c8ec421 100644 --- a/lib/rspec/rails/example/rails_example_group.rb +++ b/lib/rspec/rails/example/rails_example_group.rb @@ -2,10 +2,8 @@ # suite and ammeter. require 'rspec/rails/matchers' -if ::Rails::VERSION::MAJOR >= 7 - require 'active_support/current_attributes/test_helper' - require 'active_support/execution_context/test_helper' -end +require 'active_support/current_attributes/test_helper' +require 'active_support/execution_context/test_helper' module RSpec module Rails @@ -17,11 +15,9 @@ module RailsExampleGroup include RSpec::Rails::MinitestLifecycleAdapter include RSpec::Rails::MinitestAssertionAdapter include RSpec::Rails::FixtureSupport - if ::Rails::VERSION::MAJOR >= 7 - include RSpec::Rails::TaggedLoggingAdapter - include ActiveSupport::CurrentAttributes::TestHelper - include ActiveSupport::ExecutionContext::TestHelper - end + include RSpec::Rails::TaggedLoggingAdapter + include ActiveSupport::CurrentAttributes::TestHelper + include ActiveSupport::ExecutionContext::TestHelper end end end diff --git a/lib/rspec/rails/example/system_example_group.rb b/lib/rspec/rails/example/system_example_group.rb index b66b8fbbf..1f918e0fd 100644 --- a/lib/rspec/rails/example/system_example_group.rb +++ b/lib/rspec/rails/example/system_example_group.rb @@ -44,64 +44,57 @@ def method_name ].join("_").tr(CHARS_TO_TRANSLATE.join, "_").byteslice(0...200).scrub("") + "_#{rand(1000)}" end - if ::Rails::VERSION::STRING.to_f >= 7.1 - # @private - # Allows failure screenshot to work whilst not exposing metadata - class SuppressRailsScreenshotMetadata - def initialize - @example_data = {} - end - - def [](key) - if @example_data.key?(key) - @example_data[key] - else - raise_wrong_scope_error - end - end + # @private + # Allows failure screenshot to work whilst not exposing metadata + class SuppressRailsScreenshotMetadata + def initialize + @example_data = {} + end - def []=(key, value) - if key == :failure_screenshot_path - @example_data[key] = value - else - raise_wrong_scope_error - end + def [](key) + if @example_data.key?(key) + @example_data[key] + else + raise_wrong_scope_error end + end - def method_missing(_name, *_args, &_block) + def []=(key, value) + if key == :failure_screenshot_path + @example_data[key] = value + else raise_wrong_scope_error end + end - private - - def raise_wrong_scope_error - raise RSpec::Core::ExampleGroup::WrongScopeError, - "`metadata` is not available from within an example " \ - "(e.g. an `it` block) or from constructs that run in the " \ - "scope of an example (e.g. `before`, `let`, etc). It is " \ - "only available on an example group (e.g. a `describe` or "\ - "`context` block)" - end + def method_missing(_name, *_args, &_block) + raise_wrong_scope_error end - # @private - def metadata - @metadata ||= SuppressRailsScreenshotMetadata.new + private + + def raise_wrong_scope_error + raise RSpec::Core::ExampleGroup::WrongScopeError, + "`metadata` is not available from within an example " \ + "(e.g. an `it` block) or from constructs that run in the " \ + "scope of an example (e.g. `before`, `let`, etc). It is " \ + "only available on an example group (e.g. a `describe` or "\ + "`context` block)" end end + # @private + def metadata + @metadata ||= SuppressRailsScreenshotMetadata.new + end + # Delegates to `Rails.application`. def app ::Rails.application end # Default driver to assign if none specified. - DEFAULT_DRIVER = - if ::Rails::VERSION::STRING.to_f >= 7.2 - :selenium_chrome_headless - else - :selenium - end + DEFAULT_DRIVER = :selenium_chrome_headless included do |other| ActiveSupport.on_load(:action_dispatch_system_test_case) do @@ -153,6 +146,10 @@ def driven_by(driver, **driver_options, &blk) @driver = ::ActionDispatch::SystemTestCase.driven_by(driver, **driver_options, &blk).tap(&:use) end + def served_by(**options) + ::ActionDispatch::SystemTestCase.served_by(**options) + end + before do @routes = ::Rails.application.routes end diff --git a/lib/rspec/rails/fixture_file_upload_support.rb b/lib/rspec/rails/fixture_file_upload_support.rb index c7c4262ff..e4a49ed95 100644 --- a/lib/rspec/rails/fixture_file_upload_support.rb +++ b/lib/rspec/rails/fixture_file_upload_support.rb @@ -14,10 +14,8 @@ def rails_fixture_file_wrapper resolved_fixture_path = if respond_to?(:file_fixture_path) && !file_fixture_path.nil? file_fixture_path.to_s - elsif respond_to?(:fixture_paths) - (RSpec.configuration.fixture_paths&.first || '').to_s else - (RSpec.configuration.fixture_path || '').to_s + (RSpec.configuration.fixture_paths&.first || '').to_s end RailsFixtureFileWrapper.file_fixture_path = File.join(resolved_fixture_path, '') unless resolved_fixture_path.strip.empty? RailsFixtureFileWrapper.instance @@ -28,11 +26,7 @@ class RailsFixtureFileWrapper include ActiveSupport::Testing::FileFixtures class << self - if ::Rails::VERSION::STRING < "7.1.0" - attr_accessor :fixture_path - else - attr_accessor :fixture_paths - end + attr_accessor :fixture_paths # Get instance of wrapper def instance diff --git a/lib/rspec/rails/fixture_support.rb b/lib/rspec/rails/fixture_support.rb index e56fabeb1..564a829b7 100644 --- a/lib/rspec/rails/fixture_support.rb +++ b/lib/rspec/rails/fixture_support.rb @@ -20,12 +20,7 @@ def run_in_transaction? if RSpec.configuration.use_active_record? include Fixtures - # TestFixtures#fixture_path is deprecated and will be removed in Rails 7.2 - if respond_to?(:fixture_paths=) - self.fixture_paths = RSpec.configuration.fixture_paths - else - self.fixture_path = RSpec.configuration.fixture_path - end + self.fixture_paths = RSpec.configuration.fixture_paths self.use_transactional_tests = RSpec.configuration.use_transactional_fixtures self.use_instantiated_fixtures = RSpec.configuration.use_instantiated_fixtures @@ -37,50 +32,25 @@ def run_in_transaction? module Fixtures extend ActiveSupport::Concern - # rubocop:disable Metrics/BlockLength class_methods do - if ::Rails.version.to_f >= 7.1 - def fixtures(*args) - super.tap do - fixture_sets.each_pair do |method_name, fixture_name| - proxy_method_warning_if_called_in_before_context_scope(method_name, fixture_name) - end - end - end - - def proxy_method_warning_if_called_in_before_context_scope(method_name, fixture_name) - define_method(method_name) do |*args, **kwargs, &blk| - if RSpec.current_scope == :before_context_hook - RSpec.warn_with("Calling fixture method in before :context ") - else - access_fixture(fixture_name, *args, **kwargs, &blk) - end - end - end - else - def fixtures(*args) - orig_methods = private_instance_methods - super.tap do - new_methods = private_instance_methods - orig_methods - new_methods.each do |method_name| - proxy_method_warning_if_called_in_before_context_scope(method_name) - end + def fixtures(*args) + super.tap do + fixture_sets.each_pair do |method_name, fixture_name| + proxy_method_warning_if_called_in_before_context_scope(method_name, fixture_name) end end + end - def proxy_method_warning_if_called_in_before_context_scope(method_name) - orig_implementation = instance_method(method_name) - define_method(method_name) do |*args, &blk| - if RSpec.current_scope == :before_context_hook - RSpec.warn_with("Calling fixture method in before :context ") - else - orig_implementation.bind(self).call(*args, &blk) - end + def proxy_method_warning_if_called_in_before_context_scope(method_name, fixture_name) + define_method(method_name) do |*args, **kwargs, &blk| + if RSpec.current_scope == :before_context_hook + RSpec.warn_with("Calling fixture method in before :context ") + else + access_fixture(fixture_name, *args, **kwargs, &blk) end end end end - # rubocop:enable Metrics/BlockLength end end end diff --git a/lib/rspec/rails/matchers/action_cable.rb b/lib/rspec/rails/matchers/action_cable.rb index 12b811d7b..d33de16bf 100644 --- a/lib/rspec/rails/matchers/action_cable.rb +++ b/lib/rspec/rails/matchers/action_cable.rb @@ -3,6 +3,8 @@ module RSpec module Rails module Matchers + extend RSpec::Matchers::DSL + # Namespace for various implementations of ActionCable features # # @api private @@ -50,7 +52,10 @@ def have_broadcasted_to(target = nil) ActionCable::HaveBroadcastedTo.new(target, channel: described_class) end - alias_method :broadcast_to, :have_broadcasted_to + + alias_matcher :broadcast_to, :have_broadcasted_to do |desc| + desc.gsub("have broadcasted", "broadcast") + end private diff --git a/lib/rspec/rails/matchers/action_cable/have_broadcasted_to.rb b/lib/rspec/rails/matchers/action_cable/have_broadcasted_to.rb index 297d7cfcf..090065c2a 100644 --- a/lib/rspec/rails/matchers/action_cable/have_broadcasted_to.rb +++ b/lib/rspec/rails/matchers/action_cable/have_broadcasted_to.rb @@ -51,6 +51,10 @@ def thrice exactly(:thrice) end + def description + "have broadcasted #{base_description}" + end + def failure_message "expected to broadcast #{base_message}".tap do |msg| if @unmatching_msgs.any? @@ -140,18 +144,21 @@ def set_expected_number(relativity, count) end end - def base_message + def base_description "#{message_expectation_modifier} #{@expected_number} messages to #{stream}".tap do |msg| msg << " with #{data_description(@data)}" unless @data.nil? - msg << ", but broadcast #{@matching_msgs_count}" end end + def base_message + "#{base_description}, but broadcast #{@matching_msgs_count}" + end + def data_description(data) if data.is_a?(RSpec::Matchers::Composable) data.description else - data + data.inspect end end diff --git a/lib/rspec/rails/matchers/active_job.rb b/lib/rspec/rails/matchers/active_job.rb index 40c676c0c..f1c2347b1 100644 --- a/lib/rspec/rails/matchers/active_job.rb +++ b/lib/rspec/rails/matchers/active_job.rb @@ -178,6 +178,8 @@ def arguments_match?(job) end def detect_args_signature_mismatch(jobs) + return if skip_signature_verification? + jobs.each do |job| args = deserialize_arguments(job) @@ -189,6 +191,13 @@ def detect_args_signature_mismatch(jobs) nil end + def skip_signature_verification? + return true unless defined?(::RSpec::Mocks) && (::RSpec::Mocks.respond_to?(:configuration)) + + !RSpec::Mocks.configuration.verify_partial_doubles? || + RSpec::Mocks.configuration.temporarily_suppress_partial_double_verification + end + def check_args_signature_mismatch(job_class, job_method, args) signature = Support::MethodSignature.new(job_class.public_instance_method(job_method)) verifier = Support::StrictSignatureVerifier.new(signature, args) @@ -311,6 +320,10 @@ def does_not_match?(proc) !matches?(proc) end + + def supports_block_expectations? + false + end end # @private @@ -343,6 +356,10 @@ def matches?(job) @job = job check(queue_adapter.performed_jobs) end + + def supports_block_expectations? + false + end end end diff --git a/lib/rspec/rails/matchers/have_enqueued_mail.rb b/lib/rspec/rails/matchers/have_enqueued_mail.rb index 9d2c405b3..14f8f0111 100644 --- a/lib/rspec/rails/matchers/have_enqueued_mail.rb +++ b/lib/rspec/rails/matchers/have_enqueued_mail.rb @@ -72,7 +72,7 @@ def mailer_class_name @mailer_class ? @mailer_class.name : 'ActionMailer::Base' end - def job_match?(job) + def job_matches?(job) legacy_mail?(job) || parameterized_mail?(job) || unified_mail?(job) end @@ -93,6 +93,7 @@ def arguments_match?(job) def detect_args_signature_mismatch(jobs) return if @method_name.nil? + return if skip_signature_verification? mailer_class = mailer_class_name.constantize @@ -123,18 +124,18 @@ def check_active_job_adapter def unmatching_mail_jobs @unmatching_jobs.select do |job| - job_match?(job) + job_matches?(job) end end def unmatching_mail_jobs_message - msg = "Queued deliveries:" + messages = ["Queued deliveries:"] unmatching_mail_jobs.each do |job| - msg << "\n #{mail_job_message(job)}" + messages << " #{mail_job_message(job)}" end - msg + messages.join("\n") end def mail_job_message(job) diff --git a/lib/rspec/rails/version.rb b/lib/rspec/rails/version.rb index cd746b581..be0bf69d6 100644 --- a/lib/rspec/rails/version.rb +++ b/lib/rspec/rails/version.rb @@ -3,7 +3,7 @@ module Rails # Version information for RSpec Rails. module Version # Current version of RSpec Rails, in semantic versioning format. - STRING = '7.0.0.pre' + STRING = '8.1.0.pre' end end end diff --git a/rspec-rails.gemspec b/rspec-rails.gemspec index 788977e11..6e30a5180 100644 --- a/rspec-rails.gemspec +++ b/rspec-rails.gemspec @@ -11,7 +11,7 @@ Gem::Specification.new do |s| s.homepage = "https://github.com/rspec/rspec-rails" s.summary = "RSpec for Rails" s.description = "rspec-rails integrates the Rails testing helpers into RSpec." - s.required_ruby_version = ">= 2.7.0" + s.required_ruby_version = ">= 3.0.0" s.metadata = { 'bug_tracker_uri' => 'https://github.com/rspec/rspec-rails/issues', @@ -33,7 +33,7 @@ Gem::Specification.new do |s| s.cert_chain = [File.expand_path('~/.gem/rspec-gem-public_cert.pem')] end - version_string = ['>= 7.0'] + version_string = ['>= 7.2'] s.add_runtime_dependency 'actionpack', version_string s.add_runtime_dependency 'activesupport', version_string @@ -48,12 +48,11 @@ Gem::Specification.new do |s| if ENV['RSPEC_CI'] s.add_runtime_dependency "rspec-#{name}", ENV.fetch('RSPEC_VERSION', '3.14.0.pre') else - expected_rspec_version = "3.13.0" - s.add_runtime_dependency "rspec-#{name}", "~> #{expected_rspec_version.split(".")[0..1].join(".")}" + s.add_runtime_dependency "rspec-#{name}", "~> 3.13" end end s.add_development_dependency 'ammeter', '~> 1.1.5' - s.add_development_dependency 'aruba', '~> 0.14.12' - s.add_development_dependency 'cucumber', '~> 7.0' + s.add_development_dependency 'aruba', '~> 2.3.1' + s.add_development_dependency 'cucumber', '>= 10.0' end diff --git a/script/update_rubygems_and_install_bundler b/script/update_rubygems_and_install_bundler index c85e5dcc4..aa87daca6 100755 --- a/script/update_rubygems_and_install_bundler +++ b/script/update_rubygems_and_install_bundler @@ -11,22 +11,22 @@ function is_ruby_3_plus { fi } -function is_ruby_26_plus { - if ruby -e "exit(RUBY_VERSION.to_f >= 2.6)"; then +function is_ruby_3_1_plus { + if ruby -e "exit(RUBY_VERSION.to_f >= 3.1)"; then return 0 else return 1 fi } -if is_ruby_3_plus; then + +if is_ruby_3_1_plus; then gem update --no-document --system gem install --no-document bundler -elif is_ruby_26_plus; then - gem update --no-document --system '3.4.22' +elif is_ruby_3_plus; then + gem update --no-document --system '3.5.23' gem install --no-document bundler else - echo "Warning installing older versions of Rubygems / Bundler" - gem update --system '3.3.26' - gem install bundler -v '2.3.26' + gem update --no-document --system '3.4.22' + gem install --no-document bundler fi diff --git a/spec/generators/rspec/authentication/authentication_generator_spec.rb b/spec/generators/rspec/authentication/authentication_generator_spec.rb new file mode 100644 index 000000000..e5590aedd --- /dev/null +++ b/spec/generators/rspec/authentication/authentication_generator_spec.rb @@ -0,0 +1,34 @@ +# Generators are not automatically loaded by Rails +require 'generators/rspec/authentication/authentication_generator' +require 'support/generators' + +RSpec.describe Rspec::Generators::AuthenticationGenerator, type: :generator do + setup_default_destination + + it 'runs both the model and fixture tasks' do + gen = generator + expect(gen).to receive :create_user_spec + expect(gen).to receive :create_fixture_file + gen.invoke_all + end + + describe 'the generated files' do + it 'creates the user spec' do + run_generator + + expect(File.exist?(file('spec/models/user_spec.rb'))).to be true + end + + describe 'with fixture replacement' do + before do + run_generator ['--fixture-replacement=factory_bot'] + end + + describe 'the fixtures' do + it "will skip the file" do + expect(File.exist?(file('spec/fixtures/users.yml'))).to be false + end + end + end + end +end diff --git a/spec/generators/rspec/install/install_generator_spec.rb b/spec/generators/rspec/install/install_generator_spec.rb index 65b424427..f4543f9f3 100644 --- a/spec/generators/rspec/install/install_generator_spec.rb +++ b/spec/generators/rspec/install/install_generator_spec.rb @@ -88,11 +88,7 @@ def filter_rails_from_backtrace specify "with default fixture path" do run_generator - if ::Rails::VERSION::STRING < "7.1.0" - expect(rails_helper).to have_a_fixture_path - else - expect(rails_helper).to have_fixture_paths - end + expect(rails_helper).to have_fixture_paths end specify "with transactional fixtures" do diff --git a/spec/generators/rspec/integration/integration_generator_spec.rb b/spec/generators/rspec/integration/integration_generator_spec.rb deleted file mode 100644 index e0777bb85..000000000 --- a/spec/generators/rspec/integration/integration_generator_spec.rb +++ /dev/null @@ -1,14 +0,0 @@ -# Generators are not automatically loaded by Rails -require 'generators/rspec/integration/integration_generator' -require 'support/generators' -require 'rspec/core/warnings' - -RSpec.describe Rspec::Generators::IntegrationGenerator, type: :generator do - setup_default_destination - it_behaves_like "a request spec generator" - - it 'is deprecated' do - expect(RSpec).to receive(:warn_deprecation) - run_generator %w[posts] - end -end diff --git a/spec/generators/rspec/scaffold/scaffold_generator_spec.rb b/spec/generators/rspec/scaffold/scaffold_generator_spec.rb index 4e02682e3..0d2d07d9b 100644 --- a/spec/generators/rspec/scaffold/scaffold_generator_spec.rb +++ b/spec/generators/rspec/scaffold/scaffold_generator_spec.rb @@ -7,6 +7,12 @@ include RSpec::Support::InSubProcess setup_default_destination + if Rack::RELEASE < "3.1.0" + let(:unprocessable_status) { ":unprocessable_entity" } + else + let(:unprocessable_status) { ":unprocessable_content" } + end + describe 'standard request specs' do subject(:filename) { file('spec/requests/posts_spec.rb') } @@ -26,21 +32,14 @@ .and(contain(/"redirects to the \w+ list"/)) ) - if ::Rails::VERSION::STRING >= '7.0.0' - expect( - filename - ).to( - contain(/renders a response with 422 status \(i.e. to display the 'new' template\)/) - .and(contain(/renders a response with 422 status \(i.e. to display the 'edit' template\)/)) - ) - else - expect( - filename - ).to( - contain(/renders a successful response \(i.e. to display the 'new' template\)/) - .and(contain(/renders a successful response \(i.e. to display the 'edit' template\)/)) - ) - end + expect( + filename + ).to( + contain(/renders a response with 422 status \(i.e. to display the 'new' template\)/) + .and(contain(/renders a response with 422 status \(i.e. to display the 'edit' template\)/)) + ) + + expect(filename).to contain(/expect\(response\).to have_http_status\(#{unprocessable_status}\)/) end end @@ -105,14 +104,10 @@ .and(contain(/"redirects to the \w+ list"/)) ) - if ::Rails::VERSION::STRING >= '7.0.0' - expect(filename).to contain(/renders a response with 422 status \(i.e. to display the 'new' template\)/) - .and(contain(/renders a response with 422 status \(i.e. to display the 'edit' template\)/)) - else - expect(filename).to contain(/returns a success response \(i.e. to display the 'new' template\)/) - .and(contain(/returns a success response \(i.e. to display the 'edit' template\)/)) - end + expect(filename).to contain(/renders a response with 422 status \(i.e. to display the 'new' template\)/) + .and(contain(/renders a response with 422 status \(i.e. to display the 'edit' template\)/)) + expect(filename).to contain(/expect\(response\).to have_http_status\(#{unprocessable_status}\)/) expect(filename).not_to contain(/"renders a JSON response with the new \w+"/) expect(filename).not_to contain(/"renders a JSON response with errors for the new \w+"/) expect(filename).not_to contain(/"renders a JSON response with the \w+"/) @@ -269,11 +264,14 @@ .and(contain(/assign\(:posts, /)) .and(contain(/it "renders a list of (.*)"/)) - if ::Rails::VERSION::STRING >= '7.0.0' - expect(filename).to contain(/'div>p'/) - else - expect(filename).to contain(/'tr>td'/) - end + selector = + if Rails.version.to_f < 8.1 + /'div>p'/ + else + /'div>div>div'/ + end + + expect(filename).to contain(selector) end end diff --git a/spec/rspec/rails/configuration_spec.rb b/spec/rspec/rails/configuration_spec.rb index b61b54cf3..a2b2dd09d 100644 --- a/spec/rspec/rails/configuration_spec.rb +++ b/spec/rspec/rails/configuration_spec.rb @@ -78,11 +78,7 @@ include_examples "adds setting", :global_fixtures - if ::Rails::VERSION::STRING < "7.1.0" - include_examples "adds setting", :fixture_path - else - include_examples "adds setting", :fixture_paths - end + include_examples "adds setting", :fixture_paths include_examples "adds setting", :rendering_views @@ -161,101 +157,28 @@ def in_inferring_type_from_location_environment include_examples "infers type from location", :feature, "spec/features" end - if ::Rails::VERSION::STRING >= "7.2.0" - it "fixture support is included with metadata `:use_fixtures`" do - RSpec.configuration.global_fixtures = [:foo] - RSpec.configuration.fixture_paths = ["custom/path"] - - group = RSpec.describe("Arbitrary Description", :use_fixtures) - - expect(group.fixture_paths).to eq(["custom/path"]) - - expect(group.new.respond_to?(:foo, true)).to be(true) - end - elsif ::Rails::VERSION::STRING >= "7.1.0" - it "fixture support is included with metadata `:use_fixtures`" do - in_sub_process do - a_hash = an_instance_of(Hash) - if ::Rails::VERSION::STRING >= "7.1.0" - expect(RSpec).to receive(:deprecate).with("config.fixture_path = \"custom/path\"", a_hash) - end - - RSpec.configuration.global_fixtures = [:foo] - RSpec.configuration.fixture_path = "custom/path" + it "fixture support is included with metadata `:use_fixtures`" do + RSpec.configuration.global_fixtures = [:foo] + RSpec.configuration.fixture_paths = ["custom/path"] - group = RSpec.describe("Arbitrary Description", :use_fixtures) + group = RSpec.describe("Arbitrary Description", :use_fixtures) - if ::Rails::VERSION::STRING <= "7.2.0" - expect(group).to respond_to(:fixture_path) - end + expect(group.fixture_paths).to eq(["custom/path"]) - if ::Rails::VERSION::STRING >= "7.1.0" - with_isolated_stderr { expect(group.fixture_path).to eq("custom/path") } - else - expect(group.fixture_path).to eq("custom/path") - end + expect(group.new.respond_to?(:foo, true)).to be(true) + end - expect(group.new.respond_to?(:foo, true)).to be(true) - end - end - else - it "fixture support is included with metadata `:use_fixtures`" do + it "fixture support is included with metadata `:use_fixtures` and fixture_paths configured" do + in_sub_process do RSpec.configuration.global_fixtures = [:foo] - RSpec.configuration.fixture_path = "custom/path" + RSpec.configuration.fixture_paths = ["custom/path", "other/custom/path"] group = RSpec.describe("Arbitrary Description", :use_fixtures) - expect(group).to respond_to(:fixture_path) - expect(group.fixture_path).to eq("custom/path") - expect(group.new.respond_to?(:foo, true)).to be(true) - end - end - - if ::Rails::VERSION::STRING >= "7.1.0" - it "deprecates fixture_path" do - expect_deprecation_with_call_site(__FILE__, __LINE__ + 1, "config.fixture_path") - RSpec.configuration.fixture_path + expect(group).to respond_to(:fixture_paths) + expect(group.fixture_paths).to eq(["custom/path", "other/custom/path"]) - RSpec.configuration.fixture_paths = [] - expect_deprecation_with_call_site(__FILE__, __LINE__ + 1, "config.fixture_path") - RSpec.configuration.fixture_path - end - - it "deprecates fixture_path =" do - expect_deprecation_with_call_site(__FILE__, __LINE__ + 1, /config.fixture_path =/) - RSpec.configuration.fixture_path = "some path" - - expect(RSpec.configuration.fixture_paths).to eq(["some path"]) - end - - it "fixture support is included with metadata `:use_fixtures` and fixture_paths configured" do - in_sub_process do - RSpec.configuration.global_fixtures = [:foo] - RSpec.configuration.fixture_paths = ["custom/path", "other/custom/path"] - - group = RSpec.describe("Arbitrary Description", :use_fixtures) - - expect(group).to respond_to(:fixture_paths) - expect(group.fixture_paths).to eq(["custom/path", "other/custom/path"]) - - expect(group.new.respond_to?(:foo, true)).to be(true) - end - end - - it "fixture support is included with metadata `:use_fixtures` and deprecated fixture_path configured" do - in_sub_process do - expect(RSpec).to receive(:deprecate) - - RSpec.configuration.global_fixtures = [:foo] - RSpec.configuration.fixture_path = "custom/path" - - group = RSpec.describe("Arbitrary Description", :use_fixtures) - - expect(group).to respond_to(:fixture_paths) - expect(group.fixture_paths).to eq(["custom/path"]) - - expect(group.new.respond_to?(:foo, true)).to be(true) - end + expect(group.new.respond_to?(:foo, true)).to be(true) end end diff --git a/spec/rspec/rails/example/rails_example_group_spec.rb b/spec/rspec/rails/example/rails_example_group_spec.rb index 7dbe13788..d21dc2c3b 100644 --- a/spec/rspec/rails/example/rails_example_group_spec.rb +++ b/spec/rspec/rails/example/rails_example_group_spec.rb @@ -1,10 +1,10 @@ module RSpec::Rails RSpec.describe RailsExampleGroup do - it 'supports tagged_logger', if: ::Rails::VERSION::MAJOR >= 7 do + it 'supports tagged_logger' do expect(described_class.private_instance_methods).to include(:tagged_logger) end - it 'does not leak context between example groups', if: ::Rails::VERSION::MAJOR >= 7 do + it 'does not leak context between example groups' do groups = [ RSpec::Core::ExampleGroup.describe("A group") do @@ -31,7 +31,7 @@ module RSpec::Rails expect(results).to all be true end - it 'will not leak ActiveSupport::CurrentAttributes between examples', if: ::Rails::VERSION::MAJOR >= 7 do + it 'will not leak ActiveSupport::CurrentAttributes between examples' do group = RSpec::Core::ExampleGroup.describe("A group", order: :defined) do include RSpec::Rails::RailsExampleGroup diff --git a/spec/rspec/rails/example/system_example_group_spec.rb b/spec/rspec/rails/example/system_example_group_spec.rb index d9f3306c7..bba10512d 100644 --- a/spec/rspec/rails/example/system_example_group_spec.rb +++ b/spec/rspec/rails/example/system_example_group_spec.rb @@ -30,27 +30,31 @@ module RSpec::Rails end describe '#driver' do - it 'uses :selenium driver by default', if: ::Rails::VERSION::STRING.to_f < 7.2 do + it 'uses :selenium_chrome_headless driver by default' do group = RSpec::Core::ExampleGroup.describe do include SystemExampleGroup end example = group.new group.hooks.run(:before, :example, example) - expect(Capybara.current_driver).to eq :selenium + expect(Capybara.current_driver).to eq :selenium_chrome_headless end - it 'uses :selenium_chrome_headless driver by default', if: ::Rails::VERSION::STRING.to_f >= 7.2 do + it 'sets :rack_test driver using by before_action' do group = RSpec::Core::ExampleGroup.describe do include SystemExampleGroup + + before do + driven_by(:rack_test) + end end example = group.new group.hooks.run(:before, :example, example) - expect(Capybara.current_driver).to eq :selenium_chrome_headless + expect(Capybara.current_driver).to eq :rack_test end - it 'sets :rack_test driver using by before_action' do + it 'calls :driven_by method only once' do group = RSpec::Core::ExampleGroup.describe do include SystemExampleGroup @@ -59,24 +63,25 @@ module RSpec::Rails end end example = group.new + allow(example).to receive(:driven_by).and_call_original group.hooks.run(:before, :example, example) - expect(Capybara.current_driver).to eq :rack_test + expect(example).to have_received(:driven_by).once end - it 'calls :driven_by method only once' do + it 'calls :served_by method only once' do group = RSpec::Core::ExampleGroup.describe do include SystemExampleGroup before do - driven_by(:rack_test) + served_by(host: 'rails', port: 8080) end end example = group.new - allow(example).to receive(:driven_by).and_call_original + allow(example).to receive(:served_by).and_call_original group.hooks.run(:before, :example, example) - expect(example).to have_received(:driven_by).once + expect(example).to have_received(:served_by).once end end @@ -102,7 +107,7 @@ def take_screenshot end end - describe '#take_screenshot', if: ::Rails::VERSION::STRING.to_f >= 7.1 do + describe '#take_screenshot' do it 'handles Rails calling metadata' do allow(Capybara::Session).to receive(:instance_created?).and_return(true) group = RSpec::Core::ExampleGroup.describe do @@ -123,7 +128,7 @@ def page end end - describe '#metadata', if: ::Rails::VERSION::STRING.to_f >= 7.1 do + describe '#metadata' do let(:group) do RSpec::Core::ExampleGroup.describe do include SystemExampleGroup diff --git a/spec/rspec/rails/fixture_file_upload_support_spec.rb b/spec/rspec/rails/fixture_file_upload_support_spec.rb index 2a139fe0c..d28e29d32 100644 --- a/spec/rspec/rails/fixture_file_upload_support_spec.rb +++ b/spec/rspec/rails/fixture_file_upload_support_spec.rb @@ -1,54 +1,27 @@ module RSpec::Rails RSpec.describe FixtureFileUploadSupport do - if ::Rails::VERSION::STRING < "7.1.0" - context 'with fixture path set in config' do - it 'resolves fixture file' do - RSpec.configuration.fixture_path = File.dirname(__FILE__) - expect_to_pass fixture_file_upload_resolved('fixture_file_upload_support_spec.rb') - end - - it 'resolves supports `Pathname` objects' do - RSpec.configuration.fixture_path = Pathname(File.dirname(__FILE__)) - expect_to_pass fixture_file_upload_resolved('fixture_file_upload_support_spec.rb') - end - end - - context 'with fixture path set in spec' do - it 'resolves fixture file' do - expect_to_pass fixture_file_upload_resolved('fixture_file_upload_support_spec.rb', File.dirname(__FILE__)) - end + context 'with fixture paths set in config' do + it 'resolves fixture file' do + RSpec.configuration.fixture_paths = [File.dirname(__FILE__)] + expect_to_pass fixture_file_upload_resolved('fixture_file_upload_support_spec.rb') end - context 'with fixture path not set' do - it 'resolves fixture using relative path' do - RSpec.configuration.fixture_path = nil - expect_to_pass fixture_file_upload_resolved('spec/rspec/rails/fixture_file_upload_support_spec.rb') - end + it 'resolves supports `Pathname` objects' do + RSpec.configuration.fixture_paths = [Pathname(File.dirname(__FILE__))] + expect_to_pass fixture_file_upload_resolved('fixture_file_upload_support_spec.rb') end - else - context 'with fixture paths set in config' do - it 'resolves fixture file' do - RSpec.configuration.fixture_paths = [File.dirname(__FILE__)] - expect_to_pass fixture_file_upload_resolved('fixture_file_upload_support_spec.rb') - end + end - it 'resolves supports `Pathname` objects' do - RSpec.configuration.fixture_paths = [Pathname(File.dirname(__FILE__))] - expect_to_pass fixture_file_upload_resolved('fixture_file_upload_support_spec.rb') - end - end - - context 'with fixture path set in spec' do - it 'resolves fixture file' do - expect_to_pass fixture_file_upload_resolved('fixture_file_upload_support_spec.rb', File.dirname(__FILE__)) - end + context 'with fixture paths set in spec' do + it 'resolves fixture file' do + expect_to_pass fixture_file_upload_resolved('fixture_file_upload_support_spec.rb', File.dirname(__FILE__)) end + end - context 'with fixture path not set' do - it 'resolves fixture using relative path' do - RSpec.configuration.fixture_path = nil - expect_to_pass fixture_file_upload_resolved('spec/rspec/rails/fixture_file_upload_support_spec.rb') - end + context 'with fixture paths not set' do + it 'resolves fixture using relative path' do + RSpec.configuration.fixture_paths = [] + expect_to_pass fixture_file_upload_resolved('spec/rspec/rails/fixture_file_upload_support_spec.rb') end end diff --git a/spec/rspec/rails/fixture_support_spec.rb b/spec/rspec/rails/fixture_support_spec.rb index 236c8df28..8621b5da5 100644 --- a/spec/rspec/rails/fixture_support_spec.rb +++ b/spec/rspec/rails/fixture_support_spec.rb @@ -7,20 +7,8 @@ module RSpec::Rails include FixtureSupport end - if ::Rails::VERSION::STRING >= "7.2.0" - expect(group).to respond_to(:fixture_paths) - expect(group).to respond_to(:fixture_paths=) - elsif ::Rails::VERSION::STRING >= "7.1.0" - expect(group).to respond_to(:fixture_paths) - expect(group).to respond_to(:fixture_paths=) - - # These are deprecated when Rails is 7.1.0 but still exist - expect(group).to respond_to(:fixture_path) - expect(group).to respond_to(:fixture_path=) - else - expect(group).to respond_to(:fixture_path) - expect(group).to respond_to(:fixture_path=) - end + expect(group).to respond_to(:fixture_paths) + expect(group).to respond_to(:fixture_paths=) end end @@ -71,11 +59,7 @@ module RSpec::Rails namespaced_model(:one) end end - if Rails.version.to_f >= 7.1 - group.fixture_paths = [File.expand_path('../../support/fixtures', __dir__)] - else - group.fixture_path = File.expand_path('../../support/fixtures', __dir__) - end + group.fixture_paths = [File.expand_path('../../support/fixtures', __dir__)] expect_to_pass(group) end diff --git a/spec/rspec/rails/matchers/action_cable/have_broadcasted_to_spec.rb b/spec/rspec/rails/matchers/action_cable/have_broadcasted_to_spec.rb index 815a9225a..fb37fec13 100644 --- a/spec/rspec/rails/matchers/action_cable/have_broadcasted_to_spec.rb +++ b/spec/rspec/rails/matchers/action_cable/have_broadcasted_to_spec.rb @@ -226,5 +226,38 @@ def broadcast(stream, msg) end end end + + it "has an appropriate description" do + expect(have_broadcasted_to("my_stream").description).to eq("have broadcasted exactly 1 messages to my_stream") + end + + it "has an appropriate description when aliased" do + expect(broadcast_to("my_stream").description).to eq("broadcast exactly 1 messages to my_stream") + end + + it "has an appropriate description when stream name is passed as an array" do + expect(have_broadcasted_to(%w[my_stream stream_2]).from_channel(channel).description).to eq("have broadcasted exactly 1 messages to broadcast:my_stream:stream_2") + end + + it "has an appropriate description not mentioning the channel when qualified with `#from_channel`" do + expect(have_broadcasted_to("my_stream").from_channel(channel).description).to eq("have broadcasted exactly 1 messages to my_stream") + end + + it "has an appropriate description including the expected contents when qualified with `#with`" do + expect(have_broadcasted_to("my_stream").from_channel(channel).with("hello world").description).to eq("have broadcasted exactly 1 messages to my_stream with \"hello world\"") + end + + it "has an appropriate description including the matcher's description when qualified with `#with` and a composable matcher" do + description = have_broadcasted_to("my_stream") + .from_channel(channel) + .with(a_hash_including(a: :b)) + .description + + if RUBY_VERSION >= '3.4' + expect(description).to eq("have broadcasted exactly 1 messages to my_stream with a hash including {a: :b}") + else + expect(description).to eq("have broadcasted exactly 1 messages to my_stream with a hash including {:a => :b}") + end + end end end diff --git a/spec/rspec/rails/matchers/action_cable/have_stream_spec.rb b/spec/rspec/rails/matchers/action_cable/have_stream_spec.rb index f257d2c9a..c592ea82e 100644 --- a/spec/rspec/rails/matchers/action_cable/have_stream_spec.rb +++ b/spec/rspec/rails/matchers/action_cable/have_stream_spec.rb @@ -158,9 +158,16 @@ def subscribed it "fails with message" do subscribe user: 42 + broadcast_preamble = + if Rails.version.to_f < 8.1 + "broadcast:StreamModel#" + else + "broadcast:" + end + expect { expect(subscription).to have_stream_for(StreamModel.new(31_337)) - }.to raise_error(/expected to have stream "broadcast:StreamModel#31337" started, but have \["broadcast:StreamModel#42"\]/) + }.to raise_error(/expected to have stream "#{broadcast_preamble}31337" started, but have \["#{broadcast_preamble}42"\]/) end context "with negated form" do @@ -173,9 +180,16 @@ def subscribed it "fails with message" do subscribe user: 42 + broadcast_id = + if Rails.version.to_f < 8.1 + "broadcast:StreamModel#42" + else + "broadcast:42" + end + expect { expect(subscription).not_to have_stream_for(StreamModel.new(42)) - }.to raise_error(/expected not to have stream "broadcast:StreamModel#42" started, but have \["broadcast:StreamModel#42"\]/) + }.to raise_error(/expected not to have stream "#{broadcast_id}" started, but have \["#{broadcast_id}"\]/) end end end diff --git a/spec/rspec/rails/matchers/active_job_spec.rb b/spec/rspec/rails/matchers/active_job_spec.rb index 86e191ae5..cbf947fba 100644 --- a/spec/rspec/rails/matchers/active_job_spec.rb +++ b/spec/rspec/rails/matchers/active_job_spec.rb @@ -42,6 +42,13 @@ def self.find(_id) ActiveJob::Base.logger = original_logger end + around do |example| + original_value = RSpec::Mocks.configuration.verify_partial_doubles? + example.run + ensure + RSpec::Mocks.configuration.verify_partial_doubles = original_value + end + let(:heavy_lifting_job) do Class.new(ActiveJob::Base) do def perform; end @@ -372,20 +379,54 @@ def perform; raise StandardError; end }.to have_enqueued_job.with(42, "David") end - it "fails if the arguments do not match the job's signature" do - expect { + describe "verifying the arguments passed match the job's signature" do + it "fails if there is an arity mismatch" do expect { - two_args_job.perform_later(1) - }.to have_enqueued_job.with(1) - }.to fail_with(/Incorrect arguments passed to TwoArgsJob: Wrong number of arguments/) - end + expect { + two_args_job.perform_later(1) + }.to have_enqueued_job.with(1) + }.to fail_with(/Incorrect arguments passed to TwoArgsJob: Wrong number of arguments/) + end - it "fails if the job's signature/arguments are mismatched keyword/positional arguments" do - expect { + it "fails if there is a keyword/positional arguments mismatch" do expect { - keyword_args_job.perform_later(1, 2) - }.to have_enqueued_job.with(1, 2) - }.to fail_with(/Incorrect arguments passed to KeywordArgsJob: Missing required keyword arguments/) + expect { + keyword_args_job.perform_later(1, 2) + }.to have_enqueued_job.with(1, 2) + }.to fail_with(/Incorrect arguments passed to KeywordArgsJob: Missing required keyword arguments/) + end + + context "with partial double verification disabled" do + before do + RSpec::Mocks.configuration.verify_partial_doubles = false + end + + it "skips signature checks" do + expect { two_args_job.perform_later(1) }.to have_enqueued_job.with(1) + end + end + + context "when partial double verification is temporarily suspended" do + it "skips signature checks" do + without_partial_double_verification { + expect { + two_args_job.perform_later(1) + }.to have_enqueued_job.with(1) + } + end + end + + context "without rspec-mocks loaded" do + before do + # Its hard for us to unload this, but its fairly safe to assume that we can run + # a defined? check, this just mocks the "short circuit" + allow(::RSpec::Mocks).to receive(:respond_to?).with(:configuration) { false } + end + + it "skips signature checks" do + expect { two_args_job.perform_later(1) }.to have_enqueued_job.with(1) + end + end end it "passes with provided arguments containing global id object" do @@ -500,6 +541,12 @@ def perform; raise StandardError; end describe "have_been_enqueued" do before { ActiveJob::Base.queue_adapter.enqueued_jobs.clear } + it "raises RSpec::Expectations::ExpectationNotMetError when Proc passed to expect" do + expect { + expect { heavy_lifting_job }.to have_been_enqueued + }.to raise_error(RSpec::Expectations::ExpectationNotMetError) + end + it "passes with default jobs count (exactly one)" do heavy_lifting_job.perform_later expect(heavy_lifting_job).to have_been_enqueued @@ -521,20 +568,44 @@ def perform; raise StandardError; end }.to fail_with(/expected to enqueue exactly 1 jobs, but enqueued 0/) end - it "fails if the arguments do not match the job's signature" do - two_args_job.perform_later(1) + describe "verifying the arguments passed match the job's signature" do + it "fails if there is an arity mismatch" do + two_args_job.perform_later(1) - expect { - expect(two_args_job).to have_been_enqueued.with(1) - }.to fail_with(/Incorrect arguments passed to TwoArgsJob: Wrong number of arguments/) - end + expect { + expect(two_args_job).to have_been_enqueued.with(1) + }.to fail_with(/Incorrect arguments passed to TwoArgsJob: Wrong number of arguments/) + end - it "fails if the job's signature/arguments are mismatched keyword/positional arguments" do - keyword_args_job.perform_later(1, 2) + it "fails if there is a keyword/positional arguments mismatch" do + keyword_args_job.perform_later(1, 2) - expect { - expect(keyword_args_job).to have_been_enqueued.with(1, 2) - }.to fail_with(/Incorrect arguments passed to KeywordArgsJob: Missing required keyword arguments/) + expect { + expect(keyword_args_job).to have_been_enqueued.with(1, 2) + }.to fail_with(/Incorrect arguments passed to KeywordArgsJob: Missing required keyword arguments/) + end + + context "with partial double verification disabled" do + before do + RSpec::Mocks.configuration.verify_partial_doubles = false + end + + it "skips signature checks" do + keyword_args_job.perform_later(1, 2) + + expect(keyword_args_job).to have_been_enqueued.with(1, 2) + end + end + + context "when partial double verification is temporarily suspended" do + it "skips signature checks" do + keyword_args_job.perform_later(1, 2) + + without_partial_double_verification { + expect(keyword_args_job).to have_been_enqueued.with(1, 2) + } + end + end end it "fails when negated and several jobs enqueued" do @@ -796,6 +867,12 @@ def perform; raise StandardError; end stub_const('HeavyLiftingJob', heavy_lifting_job) end + it "raises RSpec::Expectations::ExpectationNotMetError when Proc passed to expect" do + expect { + expect { heavy_lifting_job }.to have_been_performed + }.to raise_error(RSpec::Expectations::ExpectationNotMetError) + end + it "passes with default jobs count (exactly one)" do heavy_lifting_job.perform_later expect(heavy_lifting_job).to have_been_performed diff --git a/spec/rspec/rails/matchers/be_a_new_spec.rb b/spec/rspec/rails/matchers/be_a_new_spec.rb index 76906a56f..d24e3c699 100644 --- a/spec/rspec/rails/matchers/be_a_new_spec.rb +++ b/spec/rspec/rails/matchers/be_a_new_spec.rb @@ -71,10 +71,16 @@ def new_record?; true; end end it "fails" do + message = + if RUBY_VERSION >= '3.4' + "attribute {\"foo\" => (a string matching \"bar\")} was not set on #{record.inspect}" + else + "attribute {\"foo\"=>(a string matching \"bar\")} was not set on #{record.inspect}" + end expect { expect(record).to be_a_new(record.class).with( foo: a_string_matching("bar")) - }.to raise_error("attribute {\"foo\"=>(a string matching \"bar\")} was not set on #{record.inspect}") + }.to raise_error(message) end context "matcher is wrong type" do @@ -101,12 +107,18 @@ def new_record?; true; end context "only one matcher present in actual" do it "fails" do + message = + if RUBY_VERSION >= '3.4' + "attribute {\"bar\" => (a string matching \"barn\")} was not set on #{record.inspect}" + else + "attribute {\"bar\"=>(a string matching \"barn\")} was not set on #{record.inspect}" + end expect { expect(record).to be_a_new(record.class).with( foo: a_string_matching("foo"), bar: a_string_matching("barn") ) - }.to raise_error("attribute {\"bar\"=>(a string matching \"barn\")} was not set on #{record.inspect}") + }.to raise_error(message) end end end @@ -118,19 +130,29 @@ def new_record?; true; end expect(record).to be_a_new(record.class).with(zoo: 'zoo', car: 'car') }.to raise_error { |e| expect(e.message).to match(/attributes \{.*\} were not set on #{Regexp.escape record.inspect}/) - expect(e.message).to match(/"zoo"=>"zoo"/) - expect(e.message).to match(/"car"=>"car"/) + if RUBY_VERSION >= '3.4' + expect(e.message).to match(/"zoo" => "zoo"/) + expect(e.message).to match(/"car" => "car"/) + else + expect(e.message).to match(/"zoo"=>"zoo"/) + expect(e.message).to match(/"car"=>"car"/) + end } end end context "one attribute value not the same" do it "fails" do + message = + if RUBY_VERSION >= '3.4' + %(attribute {"foo" => "bar"} was not set on #{record.inspect}) + else + %(attribute {"foo"=>"bar"} was not set on #{record.inspect}) + end + expect { expect(record).to be_a_new(record.class).with(foo: 'bar') - }.to raise_error( - %(attribute {"foo"=>"bar"} was not set on #{record.inspect}) - ) + }.to raise_error(message) end end end @@ -166,20 +188,30 @@ def new_record?; false; end expect(record).to be_a_new(String).with(zoo: 'zoo', car: 'car') }.to raise_error { |e| expect(e.message).to match(/expected #{Regexp.escape record.inspect} to be a new String and attributes \{.*\} were not set on #{Regexp.escape record.inspect}/) - expect(e.message).to match(/"zoo"=>"zoo"/) - expect(e.message).to match(/"car"=>"car"/) + if RUBY_VERSION >= '3.4' + expect(e.message).to match(/"zoo" => "zoo"/) + expect(e.message).to match(/"car" => "car"/) + else + expect(e.message).to match(/"zoo"=>"zoo"/) + expect(e.message).to match(/"car"=>"car"/) + end } end end context "one attribute value not the same" do it "fails" do + message = + "expected #{record.inspect} to be a new String and " + + if RUBY_VERSION >= '3.4' + %(attribute {"foo" => "bar"} was not set on #{record.inspect}) + else + %(attribute {"foo"=>"bar"} was not set on #{record.inspect}) + end + expect { expect(record).to be_a_new(String).with(foo: 'bar') - }.to raise_error( - "expected #{record.inspect} to be a new String and " + - %(attribute {"foo"=>"bar"} was not set on #{record.inspect}) - ) + }.to raise_error(message) end end end diff --git a/spec/rspec/rails/matchers/be_routable_spec.rb b/spec/rspec/rails/matchers/be_routable_spec.rb index c3a6a1b15..65edb2bb5 100644 --- a/spec/rspec/rails/matchers/be_routable_spec.rb +++ b/spec/rspec/rails/matchers/be_routable_spec.rb @@ -18,9 +18,17 @@ it "fails if routes do not recognize the path" do allow(routes).to receive(:recognize_path) { raise ActionController::RoutingError, 'ignore' } + + message = + if RUBY_VERSION >= '3.4' + /expected \{get: "\/a\/path"\} to be routable/ + else + /expected \{:get=>"\/a\/path"\} to be routable/ + end + expect do expect({ get: "/a/path" }).to be_routable - end.to raise_error(/expected \{:get=>"\/a\/path"\} to be routable/) + end.to raise_error(message) end end @@ -35,9 +43,17 @@ it "fails if routes recognize the path" do allow(routes).to receive(:recognize_path) { { controller: "foo" } } + + message = + if RUBY_VERSION >= '3.4' + /expected \{get: "\/a\/path"\} not to be routable, but it routes to \{controller: "foo"\}/ + else + /expected \{:get=>"\/a\/path"\} not to be routable, but it routes to \{:controller=>"foo"\}/ + end + expect do expect({ get: "/a/path" }).not_to be_routable - end.to raise_error(/expected \{:get=>"\/a\/path"\} not to be routable, but it routes to \{:controller=>"foo"\}/) + end.to raise_error(message) end end end diff --git a/spec/rspec/rails/matchers/have_enqueued_mail_spec.rb b/spec/rspec/rails/matchers/have_enqueued_mail_spec.rb index cc4b05a06..d2cc57ba4 100644 --- a/spec/rspec/rails/matchers/have_enqueued_mail_spec.rb +++ b/spec/rspec/rails/matchers/have_enqueued_mail_spec.rb @@ -20,6 +20,10 @@ class AnotherTestMailer < ActionMailer::Base def test_email; end end + class NonMailerJob < ActiveJob::Base + def perform; end + end + if RSpec::Rails::FeatureCheck.has_action_mailer_unified_delivery? class UnifiedMailer < ActionMailer::Base self.delivery_job = ActionMailer::MailDeliveryJob @@ -56,6 +60,13 @@ def test_email; end ActiveJob::Base.logger = original_logger end + around do |example| + original_value = RSpec::Mocks.configuration.verify_partial_doubles? + example.run + ensure + RSpec::Mocks.configuration.verify_partial_doubles = original_value + end + describe "have_enqueued_mail" do it "passes when a mailer method is called with deliver_later" do expect { @@ -95,6 +106,10 @@ def test_email; end expect { }.not_to have_enqueued_email end + it "passes when negated with 0 arguments and a non-mailer job is enqueued" do + expect { NonMailerJob.perform_later }.not_to have_enqueued_email + end + it "passes when only given mailer argument" do expect { TestMailer.test_email.deliver_later @@ -243,12 +258,35 @@ def test_email; end }.not_to have_enqueued_mail(TestMailer, :email_with_args).with(3, 4) end - it "fails if the arguments do not match the mailer method's signature" do - expect { + describe "verifying the arguments passed match the mailer's signature" do + it "fails if there is a mismatch" do expect { - TestMailer.email_with_args(1).deliver_later - }.to have_enqueued_mail(TestMailer, :email_with_args).with(1) - }.to fail_with(/Incorrect arguments passed to TestMailer: Wrong number of arguments/) + expect { + TestMailer.email_with_args(1).deliver_later + }.to have_enqueued_mail(TestMailer, :email_with_args).with(1) + }.to fail_with(/Incorrect arguments passed to TestMailer: Wrong number of arguments/) + end + + context "with partial double verification disabled" do + before do + RSpec::Mocks.configuration.verify_partial_doubles = false + end + + it "skips signature checks" do + expect { TestMailer.email_with_args(1).deliver_later } + .to have_enqueued_mail(TestMailer, :email_with_args).with(1) + end + end + + context "when partial double verification is temporarily suspended" do + it "skips signature checks" do + without_partial_double_verification { + expect { + TestMailer.email_with_args(1).deliver_later + }.to have_enqueued_mail(TestMailer, :email_with_args).with(1) + } + end + end end it "generates a failure message" do @@ -305,11 +343,6 @@ def test_email; end end it "generates a failure message with unmatching enqueued mail jobs" do - non_mailer_job = Class.new(ActiveJob::Base) do - def perform; end - def self.name; "NonMailerJob"; end - end - send_time = Date.tomorrow.noon queue = 'urgent_mail' @@ -320,7 +353,7 @@ def self.name; "NonMailerJob"; end expect { expect { - non_mailer_job.perform_later + NonMailerJob.perform_later TestMailer.test_email.deliver_later TestMailer.email_with_args(3, 4).deliver_later(wait_until: send_time, queue: queue) }.to have_enqueued_email(TestMailer, :email_with_args).with(1, 2) @@ -373,7 +406,13 @@ def self.name; "NonMailerJob"; end } end - context 'when parameterized', skip: !RSpec::Rails::FeatureCheck.has_action_mailer_parameterized? do + context 'when parameterized' do + before do + unless RSpec::Rails::FeatureCheck.has_action_mailer_parameterized? + skip "This version of Rails does not support parameterized mailers" + end + end + it "passes when mailer is parameterized" do expect { TestMailer.with('foo' => 'bar').test_email.deliver_later diff --git a/spec/rspec/rails/matchers/have_http_status_spec.rb b/spec/rspec/rails/matchers/have_http_status_spec.rb index 82333c74c..dfb8a301b 100644 --- a/spec/rspec/rails/matchers/have_http_status_spec.rb +++ b/spec/rspec/rails/matchers/have_http_status_spec.rb @@ -502,6 +502,7 @@ def create_response(opts = {}) context 'with deprecated rack status codes' do it 'supports the original names' do + allow(Rack::Utils).to receive(:warn).with(/unprocessable_entity is deprecated/, anything) expect(create_response(status: 422)).to have_http_status(:unprocessable_entity) end end diff --git a/spec/rspec/rails/matchers/route_to_spec.rb b/spec/rspec/rails/matchers/route_to_spec.rb index ae49791f8..8b1d7836b 100644 --- a/spec/rspec/rails/matchers/route_to_spec.rb +++ b/spec/rspec/rails/matchers/route_to_spec.rb @@ -9,7 +9,15 @@ def assert_recognizes(*) it "provides a description" do matcher = route_to("these" => "options") matcher.matches?(get: "path") - expect(matcher.description).to eq("route {:get=>\"path\"} to {\"these\"=>\"options\"}") + + description = + if RUBY_VERSION >= '3.4' + "route {get: \"path\"} to {\"these\" => \"options\"}" + else + "route {:get=>\"path\"} to {\"these\"=>\"options\"}" + end + + expect(matcher.description).to eq(description) end it "delegates to assert_recognizes" do @@ -107,9 +115,16 @@ def assert_recognizes(*) context "with should_not" do context "when assert_recognizes passes" do it "fails with custom message" do + message = + if RUBY_VERSION >= '3.4' + /expected \{get: "path"\} not to route to \{"these" => "options"\}/ + else + /expected \{:get=>"path"\} not to route to \{"these"=>"options"\}/ + end + expect { expect({ get: "path" }).not_to route_to("these" => "options") - }.to raise_error(/expected \{:get=>"path"\} not to route to \{"these"=>"options"\}/) + }.to raise_error(message) end end diff --git a/spec/sanity_check_spec.rb b/spec/sanity_check_spec.rb index 4746a157e..7faef98a8 100644 --- a/spec/sanity_check_spec.rb +++ b/spec/sanity_check_spec.rb @@ -29,6 +29,7 @@ def with_clean_env .to match(/uninitialized constant RSpec::Support/) .or match(/undefined method `require_rspec_core' for RSpec::Support:Module/) .or match(/undefined method `require_rspec_core' for module RSpec::Support/) + .or match(/undefined method 'require_rspec_core' for module RSpec::Support/) expect($?.exitstatus).to eq(1) end