rspec-rails 6.0.3 → 6.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7ea5e598eb640cb98f6c236d15d50ebf4eb2b2a9b3933f9d54e26c641a02a883
4
- data.tar.gz: 1cc9b5c8781149e0e1d0c4ef11d4b39289aef77e01fdd0fe88db1936060134e1
3
+ metadata.gz: deeeefe5add9c88c1d8709df6f4859a0280fe1a74b7d422c446bae6edd84940e
4
+ data.tar.gz: 970418fa92cdd51b634a9ed55a701ca3432657e3ea5b4bfba8629910a041f885
5
5
  SHA512:
6
- metadata.gz: 738369d092e738e50c111b93a1fdc2e02ecacce35cd1595a5e1c00453dad3901ed6a69f162b01d20e5265edda7dbcdb34a2c772f198d1b2a8c1d46d1e9c0ca0f
7
- data.tar.gz: dcd63e6c5faf232419774b29406ffc3492bfb28367a629fd792245227899b07afe12adc13249b29ee9ef3077ec261f6210f6c53b2413f291e57b0d63182a4436
6
+ metadata.gz: f6e156b4ad6e766af357bddbe10bac0fa3a2336fea1eb5f24c9cb4da637a4e630ede7bcd906d03e9175a6e2c8641754d180d67551fc0d97842b9497d72143b9c
7
+ data.tar.gz: 74e6a50c6d9b2329772280dc95c82ea94df55cdab0aa57aad3c9085faf5b15e2155d6f5e5f223e0b5165955472fd0d9447e25b8d9b8db2cb0dc914fa6c5ab3e4
checksums.yaml.gz.sig CHANGED
Binary file
data/Changelog.md CHANGED
@@ -1,5 +1,66 @@
1
1
  ### Development
2
- [Full Changelog](https://github.com/rspec/rspec-rails/compare/v6.0.3...6-0-maintenance)
2
+ [Full Changelog](https://github.com/rspec/rspec-rails/compare/v6.1.3...6-1-maintenance)
3
+
4
+ ### 6.1.3 / 2024-06-19
5
+ [Full Changelog](https://github.com/rspec/rspec-rails/compare/v6.1.2...v6.1.3)
6
+
7
+ Bug Fixes:
8
+
9
+ * Reset `ActiveSupport::CurrentAttributes` between examples. (Javier Julio, #2752)
10
+ * Fix a broken link in generated mailer previews. (Chiara Núñez, #2764)
11
+ * Fix `have_status_code` behaviour with deprecated status names by delegating
12
+ to `Rack::Utils.status_code/1` to set the expected status code. (Darren Boyd, #2765)
13
+
14
+ ### 6.1.2 / 2024-03-19
15
+ [Full Changelog](https://github.com/rspec/rspec-rails/compare/v6.1.1...v6.1.2)
16
+
17
+ Bug Fixes:
18
+
19
+ * Fix generated mailer paths to match Rails convention. (Patrício dos Santos, #2735)
20
+ * Fix class in template for generator specs. (Nicolas Buduroi, #2744)
21
+
22
+ ### 6.1.1 / 2024-01-25
23
+ [Full Changelog](https://github.com/rspec/rspec-rails/compare/v6.1.0...v6.1.1)
24
+
25
+ Bug Fixes:
26
+
27
+ * Improved deprecation message for `RSpec::Rails::Configuration.fixture_paths`
28
+ (Benoit Tigeot, #2720)
29
+ * Fix support for namespaced fixtures in Rails 7.1. (Benedikt Deicke, #2716)
30
+
31
+ ### 6.1.0 / 2023-11-21
32
+ [Full Changelog](https://github.com/rspec/rspec-rails/compare/v6.0.4...v6.1.0)
33
+
34
+ Enhancements:
35
+
36
+ * Support for Rails 7.1
37
+ * Minor tweak to generated `rails_helper.rb` to use `Rails.root.join`.
38
+ (@masato-bkn, Ryo Nakamura, #2640, #2678)
39
+ * Add `RSpec::Rails::Configuration.fixture_paths` configuration to support
40
+ the matching change to `ActiveRecord::TestFixtures`, previous singular
41
+ form is deprecated and will be removed in Rails 7.2. (Juan Gueçaimburu, #2673)
42
+ * Add `send_email` matcher to match emails rather than specific jobs.
43
+ (Andrei Kaleshka, #2670)
44
+ * When using `render` in view specs, `:locals` will now be merged into the
45
+ default implicit template, allowing `render locals: {...}` style calls.
46
+ (Jon Rowe, #2686)
47
+ * Add support for `Rails.config.action_mailer.preview_paths` on Rails 7.1/
48
+ (Jon Rowe, #2706)
49
+
50
+ ### 6.0.4 / 2023-11-21
51
+ [Full Changelog](https://github.com/rspec/rspec-rails/compare/v6.0.3...v6.0.4)
52
+
53
+ Bug Fixes:
54
+
55
+ * Fuzzy match `have_broadcasted_to` so that argument matchers can be used.
56
+ (Timothy Peraza, #2684)
57
+ * Fix fixture warning during `:context` hooks on Rails `main`. (Jon Rowe, #2685)
58
+ * Fix `stub_template` on Rails `main`. (Jon Rowe, #2685)
59
+ * Fix variable name in scaffolded view specs when namespaced. (Taketo Takashima, #2694)
60
+ * Prevent `take_failed_screenshot` producing an additional error through `metadata`
61
+ access. (Jon Rowe, #2704)
62
+ * Use `ActiveSupport::ExecutionContext::TestHelper` on Rails 7+. (Jon Rowe, #2711)
63
+ * Fix leak of templates stubbed with `stub_template` on Rails 7.1. (Jon Rowe, #2714)
3
64
 
4
65
  ### 6.0.3 / 2023-05-31
5
66
  [Full Changelog](https://github.com/rspec/rspec-rails/compare/v6.0.2...v6.0.3)
@@ -138,7 +199,7 @@ Enhancements:
138
199
  (Eloy Espinaco, Luka Lüdicke, #2355, #2356, #2378)
139
200
  * Generated scaffold now includes engine route helpers when inside a mountable engine.
140
201
  (Andrew W. Lee, #2372)
141
- * Improve request spec "controller" scafold when no action is specified.
202
+ * Improve request spec "controller" scaffold when no action is specified.
142
203
  (Thomas Hareau, #2399)
143
204
  * Introduce testing snippets concept (Phil Pirozhkov, Benoit Tigeot, #2423)
144
205
  * Prevent collisions with `let(:name)` for Rails 6.1 and `let(:method_name)` on older
@@ -541,7 +602,7 @@ Enhancements:
541
602
  * Add support for PATCH to route specs created via scaffold. (Igor Zubkov, #1336)
542
603
  * Improve controller and routing spec calls to `routes` by using `yield`
543
604
  instead of `call`. (Anton Davydov, #1308)
544
- * Add support for `ActiveJob` specs as standard `RSpec::Rails::RailsExampleGoup`s
605
+ * Add support for `ActiveJob` specs as standard `RSpec::Rails::RailsExampleGroup`s
545
606
  via both `type: :job` and inferring type from spec directory `spec/jobs`.
546
607
  (Gabe Martin-Dempesy, #1361)
547
608
  * Include `RSpec::Rails::FixtureSupport` into example groups using metadata
data/README.md CHANGED
@@ -25,13 +25,14 @@ According to [RSpec Rails new versioning strategy][] use:
25
25
  [`rspec-rails` 3.x]: https://github.com/rspec/rspec-rails/tree/3-9-maintenance
26
26
  [`rspec-rails` 4.x]: https://github.com/rspec/rspec-rails/tree/4-1-maintenance
27
27
  [`rspec-rails` 5.x]: https://github.com/rspec/rspec-rails/tree/5-1-maintenance
28
- [`rspec-rails` 6.x]: https://github.com/rspec/rspec-rails/tree/6-0-maintenance
28
+ [`rspec-rails` 6.x]: https://github.com/rspec/rspec-rails/tree/6-1-maintenance
29
29
  [RSpec Rails new versioning strategy]: https://github.com/rspec/rspec-rails/blob/main/rfcs/versioning-strategy.md
30
30
 
31
31
  ## Installation
32
32
 
33
- **IMPORTANT** This README / branch refers to the current development build.
34
- See the [`6-0-maintenance` branch on Github](https://github.com/rspec/rspec-rails/tree/6-0-maintenance) if you want or require the latest stable release.
33
+ **IMPORTANT** This README / branch refers to the 6.1.x stable release series, only bugfixes from this series will
34
+ be added here. See the [`main` branch on Github](https://github.com/rspec/rspec-rails/tree/main) if you want or
35
+ require the latest unstable features.
35
36
 
36
37
  1. Add `rspec-rails` to **both** the `:development` and `:test` groups
37
38
  of your app’s `Gemfile`:
@@ -39,7 +40,7 @@ See the [`6-0-maintenance` branch on Github](https://github.com/rspec/rspec-rail
39
40
  ```ruby
40
41
  # Run against this stable release
41
42
  group :development, :test do
42
- gem 'rspec-rails', '~> 6.0.0'
43
+ gem 'rspec-rails', '~> 6.1.0'
43
44
  end
44
45
 
45
46
  # Or, run against the main branch
@@ -4,7 +4,7 @@ module Rspec
4
4
  module Generators
5
5
  # @private
6
6
  class GeneratorGenerator < Base
7
- class_option :generator_specs, type: :boolean, default: true, desc: "Generate generator specs"
7
+ class_option :generator_specs, type: :boolean, default: true, desc: 'Generate generator specs'
8
8
 
9
9
  def generate_generator_spec
10
10
  return unless options[:generator_specs]
@@ -17,7 +17,7 @@ module Rspec
17
17
  end
18
18
 
19
19
  def filename
20
- "#{table_name}_generator_spec.rb"
20
+ "#{file_name}_generator_spec.rb"
21
21
  end
22
22
  end
23
23
  end
@@ -1,6 +1,5 @@
1
1
  require 'rails_helper'
2
2
 
3
- RSpec.describe "<%= class_name.pluralize %>", <%= type_metatag(:generator) %> do
4
-
3
+ RSpec.describe "<%= class_name %>Generator", <%= type_metatag(:generator) %> do
5
4
  pending "add some scenarios (or delete) #{__FILE__}"
6
5
  end
@@ -20,7 +20,7 @@ require 'rspec/rails'
20
20
  # directory. Alternatively, in the individual `*_spec.rb` files, manually
21
21
  # require only the support files necessary.
22
22
  #
23
- # Dir[Rails.root.join('spec', 'support', '**', '*.rb')].sort.each { |f| require f }
23
+ # Rails.root.glob('spec/support/**/*.rb').sort.each { |f| require f }
24
24
 
25
25
  <% if RSpec::Rails::FeatureCheck.has_active_record_migration? -%>
26
26
  # Checks for pending migrations and applies them before tests are run.
@@ -34,7 +34,13 @@ end
34
34
  RSpec.configure do |config|
35
35
  <% if RSpec::Rails::FeatureCheck.has_active_record? -%>
36
36
  # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
37
- config.fixture_path = "#{::Rails.root}/spec/fixtures"
37
+ <% if ::Rails::VERSION::STRING < "7.1.0" -%>
38
+ config.fixture_path = Rails.root.join('spec/fixtures')
39
+ <% else -%>
40
+ config.fixture_paths = [
41
+ Rails.root.join('spec/fixtures')
42
+ ]
43
+ <% end -%>
38
44
 
39
45
  # If you're not using ActiveRecord, or you'd prefer not to run each of your
40
46
  # examples within a transaction, remove the following line or assign false
@@ -52,7 +58,7 @@ RSpec.configure do |config|
52
58
  # note if you'd prefer not to run each example within a transaction, you
53
59
  # should set use_transactional_fixtures to false.
54
60
  #
55
- # config.fixture_path = "#{::Rails.root}/spec/fixtures"
61
+ # config.fixture_path = Rails.root.join('spec/fixtures')
56
62
  # config.use_transactional_fixtures = true
57
63
 
58
64
  <% end -%>
@@ -8,7 +8,8 @@ module Rspec
8
8
  argument :actions, type: :array, default: [], banner: "method method"
9
9
 
10
10
  def generate_mailer_spec
11
- template "mailer_spec.rb", target_path('mailers', class_path, "#{file_name}_spec.rb")
11
+ file_suffix = file_name.end_with?('mailer') ? 'spec.rb' : 'mailer_spec.rb'
12
+ template "mailer_spec.rb", target_path('mailers', class_path, [file_name, file_suffix].join('_'))
12
13
  end
13
14
 
14
15
  def generate_fixtures_files
@@ -21,7 +22,8 @@ module Rspec
21
22
  def generate_preview_files
22
23
  return unless RSpec::Rails::FeatureCheck.has_action_mailer_preview?
23
24
 
24
- template "preview.rb", target_path("mailers/previews", class_path, "#{file_name}_preview.rb")
25
+ file_suffix = file_name.end_with?('mailer') ? 'preview.rb' : 'mailer_preview.rb'
26
+ template "preview.rb", target_path("mailers/previews", class_path, [file_name, file_suffix].join('_'))
25
27
  end
26
28
  end
27
29
  end
@@ -1,9 +1,9 @@
1
1
  <% module_namespacing do -%>
2
- # Preview all emails at http://localhost:3000/rails/mailers/<%= file_path %>
3
- class <%= class_name %>Preview < ActionMailer::Preview
2
+ # Preview all emails at http://localhost:3000/rails/mailers/<%= file_path %>_mailer
3
+ class <%= class_name %><%= 'Mailer' unless class_name.end_with?('Mailer') %>Preview < ActionMailer::Preview
4
4
  <% actions.each do |action| -%>
5
5
 
6
- # Preview this email at http://localhost:3000/rails/mailers/<%= file_path %>/<%= action %>
6
+ # Preview this email at http://localhost:3000/rails/mailers/<%= file_path %>_mailer/<%= action %>
7
7
  def <%= action %>
8
8
  <%= class_name.sub(/(Mailer)?$/, 'Mailer') %>.<%= action %>
9
9
  end
@@ -2,7 +2,7 @@ require 'rails_helper'
2
2
 
3
3
  <% output_attributes = attributes.reject{|attribute| [:datetime, :timestamp, :time, :date].index(attribute.type) } -%>
4
4
  RSpec.describe "<%= ns_table_name %>/edit", <%= type_metatag(:view) %> do
5
- let(:<%= ns_file_name %>) {
5
+ let(:<%= singular_table_name %>) {
6
6
  <%= class_name %>.create!(<%= ')' if output_attributes.empty? %>
7
7
  <% output_attributes.each_with_index do |attribute, attribute_index| -%>
8
8
  <%= attribute.name %>: <%= attribute.default.inspect %><%= attribute_index == output_attributes.length - 1 ? '' : ','%>
@@ -11,13 +11,13 @@ RSpec.describe "<%= ns_table_name %>/edit", <%= type_metatag(:view) %> do
11
11
  }
12
12
 
13
13
  before(:each) do
14
- assign(:<%= ns_file_name %>, <%= ns_file_name %>)
14
+ assign(:<%= singular_table_name %>, <%= singular_table_name %>)
15
15
  end
16
16
 
17
17
  it "renders the edit <%= ns_file_name %> form" do
18
18
  render
19
19
 
20
- assert_select "form[action=?][method=?]", <%= ns_file_name %>_path(<%= ns_file_name %>), "post" do
20
+ assert_select "form[action=?][method=?]", <%= ns_file_name %>_path(<%= singular_table_name %>), "post" do
21
21
  <% for attribute in output_attributes -%>
22
22
  <%- name = attribute.respond_to?(:column_name) ? attribute.column_name : attribute.name %>
23
23
  assert_select "<%= attribute.input_type -%>[name=?]", "<%= ns_file_name %>[<%= name %>]"
@@ -3,7 +3,7 @@ require 'rails_helper'
3
3
  <% output_attributes = attributes.reject{|attribute| [:datetime, :timestamp, :time, :date].index(attribute.type) } -%>
4
4
  RSpec.describe "<%= ns_table_name %>/new", <%= type_metatag(:view) %> do
5
5
  before(:each) do
6
- assign(:<%= ns_file_name %>, <%= class_name %>.new(<%= '))' if output_attributes.empty? %>
6
+ assign(:<%= singular_table_name %>, <%= class_name %>.new(<%= '))' if output_attributes.empty? %>
7
7
  <% output_attributes.each_with_index do |attribute, attribute_index| -%>
8
8
  <%= attribute.name %>: <%= attribute.default.inspect %><%= attribute_index == output_attributes.length - 1 ? '' : ','%>
9
9
  <% end -%>
@@ -3,7 +3,7 @@ require 'rails_helper'
3
3
  <% output_attributes = attributes.reject{|attribute| [:datetime, :timestamp, :time, :date].index(attribute.type) } -%>
4
4
  RSpec.describe "<%= ns_table_name %>/show", <%= type_metatag(:view) %> do
5
5
  before(:each) do
6
- assign(:<%= ns_file_name %>, <%= class_name %>.create!(<%= '))' if output_attributes.empty? %>
6
+ assign(:<%= singular_table_name %>, <%= class_name %>.create!(<%= '))' if output_attributes.empty? %>
7
7
  <% output_attributes.each_with_index do |attribute, attribute_index| -%>
8
8
  <%= attribute.name %>: <%= value_for(attribute) %><%= attribute_index == output_attributes.length - 1 ? '' : ','%>
9
9
  <% end -%>
@@ -57,7 +57,7 @@ module RSpec
57
57
  end
58
58
 
59
59
  # @private
60
- def self.initialize_configuration(config) # rubocop:disable Metrics/MethodLength,Metrics/CyclomaticComplexity
60
+ def self.initialize_configuration(config) # rubocop:disable Metrics/MethodLength,Metrics/CyclomaticComplexity,Metrics/AbcSize,Metrics/PerceivedComplexity
61
61
  config.backtrace_exclusion_patterns << /vendor\//
62
62
  config.backtrace_exclusion_patterns << %r{lib/rspec/rails}
63
63
 
@@ -69,7 +69,13 @@ module RSpec
69
69
  config.add_setting :use_transactional_fixtures, alias_with: :use_transactional_examples
70
70
  config.add_setting :use_instantiated_fixtures
71
71
  config.add_setting :global_fixtures
72
- config.add_setting :fixture_path
72
+
73
+ if ::Rails::VERSION::STRING < "7.1.0"
74
+ config.add_setting :fixture_path
75
+ else
76
+ config.add_setting :fixture_paths
77
+ end
78
+
73
79
  config.include RSpec::Rails::FixtureSupport, :use_fixtures
74
80
 
75
81
  # We'll need to create a deprecated module in order to properly report to
@@ -157,6 +163,29 @@ module RSpec
157
163
  filter_gems_from_backtrace "activemodel", "activerecord",
158
164
  "activesupport", "activejob"
159
165
  end
166
+
167
+ # @deprecated TestFixtures#fixture_path is deprecated and will be removed in Rails 7.2
168
+ if ::Rails::VERSION::STRING >= "7.1.0"
169
+ def fixture_path
170
+ RSpec.deprecate(
171
+ "config.fixture_path",
172
+ replacement: "config.fixture_paths",
173
+ message: "Rails 7.1 has deprecated the singular fixture_path in favour of an array." \
174
+ "You should migrate to plural:"
175
+ )
176
+ fixture_paths&.first
177
+ end
178
+
179
+ def fixture_path=(path)
180
+ RSpec.deprecate(
181
+ "config.fixture_path = #{path.inspect}",
182
+ replacement: "config.fixture_paths = [#{path.inspect}]",
183
+ message: "Rails 7.1 has deprecated the singular fixture_path in favour of an array." \
184
+ "You should migrate to plural:"
185
+ )
186
+ self.fixture_paths = Array(path)
187
+ end
188
+ end
160
189
  end
161
190
 
162
191
  add_test_type_configurations(config)
@@ -69,7 +69,7 @@ module RSpec
69
69
  #
70
70
  # @param message [Hash, Mail::Message] a mail message or hash of
71
71
  # attributes used to build one
72
- # @return [ActionMaibox::InboundMessage]
72
+ # @return [ActionMailbox::InboundMessage]
73
73
  def process(message)
74
74
  MailboxExampleGroup.create_inbound_email(message).tap do |mail|
75
75
  self.class.mailbox_class.receive(mail)
@@ -2,6 +2,11 @@
2
2
  # suite and ammeter.
3
3
  require 'rspec/rails/matchers'
4
4
 
5
+ if ::Rails::VERSION::MAJOR >= 7
6
+ require 'active_support/current_attributes/test_helper'
7
+ require 'active_support/execution_context/test_helper'
8
+ end
9
+
5
10
  module RSpec
6
11
  module Rails
7
12
  # @api public
@@ -12,7 +17,11 @@ module RSpec
12
17
  include RSpec::Rails::MinitestLifecycleAdapter
13
18
  include RSpec::Rails::MinitestAssertionAdapter
14
19
  include RSpec::Rails::FixtureSupport
15
- include RSpec::Rails::TaggedLoggingAdapter if ::Rails::VERSION::MAJOR >= 7
20
+ if ::Rails::VERSION::MAJOR >= 7
21
+ include RSpec::Rails::TaggedLoggingAdapter
22
+ include ActiveSupport::CurrentAttributes::TestHelper
23
+ include ActiveSupport::ExecutionContext::TestHelper
24
+ end
16
25
  end
17
26
  end
18
27
  end
@@ -1,5 +1,3 @@
1
- require "action_dispatch/testing/assertions/routing"
2
-
3
1
  module RSpec
4
2
  module Rails
5
3
  # @private
@@ -44,6 +44,52 @@ module RSpec
44
44
  ].join("_").tr(CHARS_TO_TRANSLATE.join, "_").byteslice(0...200).scrub("") + "_#{rand(1000)}"
45
45
  end
46
46
 
47
+ if ::Rails::VERSION::STRING.to_f >= 7.1
48
+ # @private
49
+ # Allows failure screenshot to work whilst not exposing metadata
50
+ class SuppressRailsScreenshotMetadata
51
+ def initialize
52
+ @example_data = {}
53
+ end
54
+
55
+ def [](key)
56
+ if @example_data.key?(key)
57
+ @example_data[key]
58
+ else
59
+ raise_wrong_scope_error
60
+ end
61
+ end
62
+
63
+ def []=(key, value)
64
+ if key == :failure_screenshot_path
65
+ @example_data[key] = value
66
+ else
67
+ raise_wrong_scope_error
68
+ end
69
+ end
70
+
71
+ def method_missing(_name, *_args, &_block)
72
+ raise_wrong_scope_error
73
+ end
74
+
75
+ private
76
+
77
+ def raise_wrong_scope_error
78
+ raise RSpec::Core::ExampleGroup::WrongScopeError,
79
+ "`metadata` is not available from within an example " \
80
+ "(e.g. an `it` block) or from constructs that run in the " \
81
+ "scope of an example (e.g. `before`, `let`, etc). It is " \
82
+ "only available on an example group (e.g. a `describe` or "\
83
+ "`context` block)"
84
+ end
85
+ end
86
+
87
+ # @private
88
+ def metadata
89
+ @metadata ||= SuppressRailsScreenshotMetadata.new
90
+ end
91
+ end
92
+
47
93
  # Delegates to `Rails.application`.
48
94
  def app
49
95
  ::Rails.application
@@ -65,6 +65,7 @@ module RSpec
65
65
  # end
66
66
  def render(options = {}, local_assigns = {}, &block)
67
67
  options = _default_render_options if Hash === options && options.empty?
68
+ options = options.merge(_default_render_options) if Hash === options && options.keys == [:locals]
68
69
  super(options, local_assigns, &block)
69
70
  end
70
71
 
@@ -89,7 +90,7 @@ module RSpec
89
90
  #
90
91
  # stub_template("widgets/_widget.html.erb" => "This content.")
91
92
  def stub_template(hash)
92
- view.view_paths.unshift(StubResolverCache.resolver_for(hash))
93
+ controller.prepend_view_path(StubResolverCache.resolver_for(hash))
93
94
  end
94
95
 
95
96
  # Provides access to the params hash that will be available within the
@@ -14,6 +14,8 @@ module RSpec
14
14
  resolved_fixture_path =
15
15
  if respond_to?(:file_fixture_path) && !file_fixture_path.nil?
16
16
  file_fixture_path.to_s
17
+ elsif respond_to?(:fixture_paths)
18
+ (RSpec.configuration.fixture_paths&.first || '').to_s
17
19
  else
18
20
  (RSpec.configuration.fixture_path || '').to_s
19
21
  end
@@ -26,7 +28,11 @@ module RSpec
26
28
  include ActiveSupport::Testing::FileFixtures
27
29
 
28
30
  class << self
29
- attr_accessor :fixture_path
31
+ if ::Rails::VERSION::STRING < "7.1.0"
32
+ attr_accessor :fixture_path
33
+ else
34
+ attr_accessor :fixture_paths
35
+ end
30
36
 
31
37
  # Get instance of wrapper
32
38
  def instance
@@ -23,10 +23,11 @@ module RSpec
23
23
 
24
24
  # TestFixtures#fixture_path is deprecated and will be removed in Rails 7.2
25
25
  if respond_to?(:fixture_paths=)
26
- fixture_paths << RSpec.configuration.fixture_path
26
+ self.fixture_paths = RSpec.configuration.fixture_paths
27
27
  else
28
28
  self.fixture_path = RSpec.configuration.fixture_path
29
29
  end
30
+
30
31
  self.use_transactional_tests = RSpec.configuration.use_transactional_fixtures
31
32
  self.use_instantiated_fixtures = RSpec.configuration.use_instantiated_fixtures
32
33
 
@@ -37,28 +38,50 @@ module RSpec
37
38
  module Fixtures
38
39
  extend ActiveSupport::Concern
39
40
 
41
+ # rubocop:disable Metrics/BlockLength
40
42
  class_methods do
41
- def fixtures(*args)
42
- orig_methods = private_instance_methods
43
- super.tap do
44
- new_methods = private_instance_methods - orig_methods
45
- new_methods.each do |method_name|
46
- proxy_method_warning_if_called_in_before_context_scope(method_name)
43
+ if ::Rails.version.to_f >= 7.1
44
+ def fixtures(*args)
45
+ super.tap do
46
+ fixture_sets.each_pair do |method_name, fixture_name|
47
+ proxy_method_warning_if_called_in_before_context_scope(method_name, fixture_name)
48
+ end
49
+ end
50
+ end
51
+
52
+ def proxy_method_warning_if_called_in_before_context_scope(method_name, fixture_name)
53
+ define_method(method_name) do |*args, **kwargs, &blk|
54
+ if RSpec.current_scope == :before_context_hook
55
+ RSpec.warn_with("Calling fixture method in before :context ")
56
+ else
57
+ access_fixture(fixture_name, *args, **kwargs, &blk)
58
+ end
59
+ end
60
+ end
61
+ else
62
+ def fixtures(*args)
63
+ orig_methods = private_instance_methods
64
+ super.tap do
65
+ new_methods = private_instance_methods - orig_methods
66
+ new_methods.each do |method_name|
67
+ proxy_method_warning_if_called_in_before_context_scope(method_name)
68
+ end
47
69
  end
48
70
  end
49
- end
50
71
 
51
- def proxy_method_warning_if_called_in_before_context_scope(method_name)
52
- orig_implementation = instance_method(method_name)
53
- define_method(method_name) do |*args, &blk|
54
- if RSpec.current_scope == :before_context_hook
55
- RSpec.warn_with("Calling fixture method in before :context ")
56
- else
57
- orig_implementation.bind(self).call(*args, &blk)
72
+ def proxy_method_warning_if_called_in_before_context_scope(method_name)
73
+ orig_implementation = instance_method(method_name)
74
+ define_method(method_name) do |*args, &blk|
75
+ if RSpec.current_scope == :before_context_hook
76
+ RSpec.warn_with("Calling fixture method in before :context ")
77
+ else
78
+ orig_implementation.bind(self).call(*args, &blk)
79
+ end
58
80
  end
59
81
  end
60
82
  end
61
83
  end
84
+ # rubocop:enable Metrics/BlockLength
62
85
  end
63
86
  end
64
87
  end
@@ -112,7 +112,7 @@ module RSpec
112
112
  decoded = ActiveSupport::JSON.decode(msg)
113
113
  decoded = decoded.with_indifferent_access if decoded.is_a?(Hash)
114
114
 
115
- if @data.nil? || @data === decoded
115
+ if @data.nil? || values_match?(@data, decoded)
116
116
  @block.call(decoded)
117
117
  true
118
118
  else
@@ -216,11 +216,7 @@ module RSpec
216
216
  # @see Rack::Utils::SYMBOL_TO_STATUS_CODE
217
217
  # @raise [ArgumentError] if an associated code could not be found
218
218
  def set_expected_code!
219
- @expected ||=
220
- Rack::Utils::SYMBOL_TO_STATUS_CODE.fetch(expected_status) do
221
- raise ArgumentError,
222
- "Invalid HTTP status: #{expected_status.inspect}"
223
- end
219
+ @expected ||= Rack::Utils.status_code(expected_status)
224
220
  end
225
221
  end
226
222
 
@@ -0,0 +1,122 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RSpec
4
+ module Rails
5
+ module Matchers
6
+ # @api private
7
+ #
8
+ # Matcher class for `send_email`. Should not be instantiated directly.
9
+ #
10
+ # @see RSpec::Rails::Matchers#send_email
11
+ class SendEmail < RSpec::Rails::Matchers::BaseMatcher
12
+ # @api private
13
+ # Define the email attributes that should be included in the inspection output.
14
+ INSPECT_EMAIL_ATTRIBUTES = %i[subject from to cc bcc].freeze
15
+
16
+ def initialize(criteria)
17
+ @criteria = criteria
18
+ end
19
+
20
+ # @api private
21
+ def supports_value_expectations?
22
+ false
23
+ end
24
+
25
+ # @api private
26
+ def supports_block_expectations?
27
+ true
28
+ end
29
+
30
+ def matches?(block)
31
+ define_matched_emails(block)
32
+
33
+ @matched_emails.one?
34
+ end
35
+
36
+ # @api private
37
+ # @return [String]
38
+ def failure_message
39
+ result =
40
+ if multiple_match?
41
+ "More than 1 matching emails were sent."
42
+ else
43
+ "No matching emails were sent."
44
+ end
45
+ "#{result}#{sent_emails_message}"
46
+ end
47
+
48
+ # @api private
49
+ # @return [String]
50
+ def failure_message_when_negated
51
+ "Expected not to send an email but it was sent."
52
+ end
53
+
54
+ private
55
+
56
+ def diffable?
57
+ true
58
+ end
59
+
60
+ def deliveries
61
+ ActionMailer::Base.deliveries
62
+ end
63
+
64
+ def define_matched_emails(block)
65
+ before = deliveries.dup
66
+
67
+ block.call
68
+
69
+ after = deliveries
70
+
71
+ @diff = after - before
72
+ @matched_emails = @diff.select(&method(:matched_email?))
73
+ end
74
+
75
+ def matched_email?(email)
76
+ @criteria.all? do |attr, value|
77
+ expected =
78
+ case attr
79
+ when :to, :from, :cc, :bcc then Array(value)
80
+ else
81
+ value
82
+ end
83
+
84
+ values_match?(expected, email.public_send(attr))
85
+ end
86
+ end
87
+
88
+ def multiple_match?
89
+ @matched_emails.many?
90
+ end
91
+
92
+ def sent_emails_message
93
+ if @diff.empty?
94
+ "\n\nThere were no any emails sent inside the expectation block."
95
+ else
96
+ sent_emails =
97
+ @diff.map do |email|
98
+ inspected = INSPECT_EMAIL_ATTRIBUTES.map { |attr| "#{attr}: #{email.public_send(attr)}" }.join(", ")
99
+ "- #{inspected}"
100
+ end.join("\n")
101
+ "\n\nThe following emails were sent:\n#{sent_emails}"
102
+ end
103
+ end
104
+ end
105
+
106
+ # @api public
107
+ # Check email sending with specific parameters.
108
+ #
109
+ # @example Positive expectation
110
+ # expect { action }.to send_email
111
+ #
112
+ # @example Negative expectations
113
+ # expect { action }.not_to send_email
114
+ #
115
+ # @example More precise expectation with attributes to match
116
+ # expect { action }.to send_email(to: 'test@example.com', subject: 'Confirm email')
117
+ def send_email(criteria = {})
118
+ SendEmail.new(criteria)
119
+ end
120
+ end
121
+ end
122
+ end
@@ -20,6 +20,7 @@ require 'rspec/rails/matchers/be_a_new'
20
20
  require 'rspec/rails/matchers/relation_match_array'
21
21
  require 'rspec/rails/matchers/be_valid'
22
22
  require 'rspec/rails/matchers/have_http_status'
23
+ require 'rspec/rails/matchers/send_email'
23
24
 
24
25
  if RSpec::Rails::FeatureCheck.has_active_job?
25
26
  require 'rspec/rails/matchers/active_job'
@@ -3,7 +3,7 @@ module RSpec
3
3
  # Version information for RSpec Rails.
4
4
  module Version
5
5
  # Current version of RSpec Rails, in semantic versioning format.
6
- STRING = '6.0.3'
6
+ STRING = '6.1.3'
7
7
  end
8
8
  end
9
9
  end
data/lib/rspec-rails.rb CHANGED
@@ -47,10 +47,18 @@ module RSpec
47
47
  end
48
48
  end
49
49
 
50
- def config_default_preview_path(options)
51
- return unless options.preview_path.blank?
50
+ if ::Rails::VERSION::STRING >= "7.1.0"
51
+ def config_default_preview_path(options)
52
+ return unless options.preview_paths.empty?
52
53
 
53
- options.preview_path = "#{::Rails.root}/spec/mailers/previews"
54
+ options.preview_paths << "#{::Rails.root}/spec/mailers/previews"
55
+ end
56
+ else
57
+ def config_default_preview_path(options)
58
+ return unless options.preview_path.blank?
59
+
60
+ options.preview_path = "#{::Rails.root}/spec/mailers/previews"
61
+ end
54
62
  end
55
63
 
56
64
  def supports_action_mailer_previews?(config)
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,12 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.0.3
4
+ version: 6.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Chelimsky
8
8
  - Andy Lindeman
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain:
12
12
  - |
@@ -44,7 +44,7 @@ cert_chain:
44
44
  ZsVDj6a7lH3cNqtWXZxrb2wO38qV5AkYj8SQK7Hj3/Yui9myUX3crr+PdetazSqQ
45
45
  F3MdtaDehhjC
46
46
  -----END CERTIFICATE-----
47
- date: 2023-05-31 00:00:00.000000000 Z
47
+ date: 2024-06-19 00:00:00.000000000 Z
48
48
  dependencies:
49
49
  - !ruby/object:Gem::Dependency
50
50
  name: actionpack
@@ -94,56 +94,56 @@ dependencies:
94
94
  requirements:
95
95
  - - "~>"
96
96
  - !ruby/object:Gem::Version
97
- version: '3.12'
97
+ version: '3.13'
98
98
  type: :runtime
99
99
  prerelease: false
100
100
  version_requirements: !ruby/object:Gem::Requirement
101
101
  requirements:
102
102
  - - "~>"
103
103
  - !ruby/object:Gem::Version
104
- version: '3.12'
104
+ version: '3.13'
105
105
  - !ruby/object:Gem::Dependency
106
106
  name: rspec-expectations
107
107
  requirement: !ruby/object:Gem::Requirement
108
108
  requirements:
109
109
  - - "~>"
110
110
  - !ruby/object:Gem::Version
111
- version: '3.12'
111
+ version: '3.13'
112
112
  type: :runtime
113
113
  prerelease: false
114
114
  version_requirements: !ruby/object:Gem::Requirement
115
115
  requirements:
116
116
  - - "~>"
117
117
  - !ruby/object:Gem::Version
118
- version: '3.12'
118
+ version: '3.13'
119
119
  - !ruby/object:Gem::Dependency
120
120
  name: rspec-mocks
121
121
  requirement: !ruby/object:Gem::Requirement
122
122
  requirements:
123
123
  - - "~>"
124
124
  - !ruby/object:Gem::Version
125
- version: '3.12'
125
+ version: '3.13'
126
126
  type: :runtime
127
127
  prerelease: false
128
128
  version_requirements: !ruby/object:Gem::Requirement
129
129
  requirements:
130
130
  - - "~>"
131
131
  - !ruby/object:Gem::Version
132
- version: '3.12'
132
+ version: '3.13'
133
133
  - !ruby/object:Gem::Dependency
134
134
  name: rspec-support
135
135
  requirement: !ruby/object:Gem::Requirement
136
136
  requirements:
137
137
  - - "~>"
138
138
  - !ruby/object:Gem::Version
139
- version: '3.12'
139
+ version: '3.13'
140
140
  type: :runtime
141
141
  prerelease: false
142
142
  version_requirements: !ruby/object:Gem::Requirement
143
143
  requirements:
144
144
  - - "~>"
145
145
  - !ruby/object:Gem::Version
146
- version: '3.12'
146
+ version: '3.13'
147
147
  - !ruby/object:Gem::Dependency
148
148
  name: ammeter
149
149
  requirement: !ruby/object:Gem::Requirement
@@ -284,6 +284,7 @@ files:
284
284
  - lib/rspec/rails/matchers/redirect_to.rb
285
285
  - lib/rspec/rails/matchers/relation_match_array.rb
286
286
  - lib/rspec/rails/matchers/routing_matchers.rb
287
+ - lib/rspec/rails/matchers/send_email.rb
287
288
  - lib/rspec/rails/tasks/rspec.rake
288
289
  - lib/rspec/rails/vendor/capybara.rb
289
290
  - lib/rspec/rails/version.rb
@@ -296,11 +297,11 @@ licenses:
296
297
  - MIT
297
298
  metadata:
298
299
  bug_tracker_uri: https://github.com/rspec/rspec-rails/issues
299
- changelog_uri: https://github.com/rspec/rspec-rails/blob/v6.0.3/Changelog.md
300
+ changelog_uri: https://github.com/rspec/rspec-rails/blob/v6.1.3/Changelog.md
300
301
  documentation_uri: https://rspec.info/documentation/
301
302
  mailing_list_uri: https://groups.google.com/forum/#!forum/rspec
302
303
  source_code_uri: https://github.com/rspec/rspec-rails
303
- post_install_message:
304
+ post_install_message:
304
305
  rdoc_options:
305
306
  - "--charset=UTF-8"
306
307
  require_paths:
@@ -317,7 +318,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
317
318
  version: '0'
318
319
  requirements: []
319
320
  rubygems_version: 3.1.6
320
- signing_key:
321
+ signing_key:
321
322
  specification_version: 4
322
323
  summary: RSpec for Rails
323
324
  test_files: []
metadata.gz.sig CHANGED
Binary file