rspec-rails 5.1.2 → 6.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/Changelog.md +103 -6
  4. data/README.md +37 -36
  5. data/lib/generators/rspec/channel/channel_generator.rb +1 -1
  6. data/lib/generators/rspec/controller/controller_generator.rb +4 -4
  7. data/lib/generators/rspec/feature/feature_generator.rb +1 -1
  8. data/lib/generators/rspec/generator/generator_generator.rb +1 -1
  9. data/lib/generators/rspec/helper/helper_generator.rb +1 -1
  10. data/lib/generators/rspec/install/install_generator.rb +19 -2
  11. data/lib/generators/rspec/install/templates/spec/rails_helper.rb +12 -7
  12. data/lib/generators/rspec/integration/integration_generator.rb +10 -3
  13. data/lib/generators/rspec/job/job_generator.rb +1 -1
  14. data/lib/generators/rspec/mailbox/mailbox_generator.rb +1 -1
  15. data/lib/generators/rspec/mailer/mailer_generator.rb +3 -3
  16. data/lib/generators/rspec/model/model_generator.rb +3 -3
  17. data/lib/generators/rspec/request/request_generator.rb +10 -3
  18. data/lib/generators/rspec/scaffold/scaffold_generator.rb +4 -4
  19. data/lib/generators/rspec/scaffold/templates/controller_spec.rb +15 -0
  20. data/lib/generators/rspec/scaffold/templates/edit_spec.rb +8 -4
  21. data/lib/generators/rspec/scaffold/templates/index_spec.rb +2 -1
  22. data/lib/generators/rspec/scaffold/templates/new_spec.rb +1 -1
  23. data/lib/generators/rspec/scaffold/templates/request_spec.rb +15 -0
  24. data/lib/generators/rspec/scaffold/templates/show_spec.rb +1 -1
  25. data/lib/generators/rspec/system/system_generator.rb +1 -1
  26. data/lib/generators/rspec/view/view_generator.rb +2 -2
  27. data/lib/generators/rspec.rb +18 -1
  28. data/lib/rspec/rails/adapters.rb +11 -0
  29. data/lib/rspec/rails/configuration.rb +43 -14
  30. data/lib/rspec/rails/example/rails_example_group.rb +8 -0
  31. data/lib/rspec/rails/example/system_example_group.rb +58 -11
  32. data/lib/rspec/rails/example/view_example_group.rb +6 -5
  33. data/lib/rspec/rails/feature_check.rb +6 -2
  34. data/lib/rspec/rails/file_fixture_support.rb +3 -0
  35. data/lib/rspec/rails/fixture_file_upload_support.rb +20 -31
  36. data/lib/rspec/rails/fixture_support.rb +43 -15
  37. data/lib/rspec/rails/matchers/action_cable/have_broadcasted_to.rb +6 -3
  38. data/lib/rspec/rails/matchers/active_job.rb +4 -4
  39. data/lib/rspec/rails/matchers/have_enqueued_mail.rb +3 -2
  40. data/lib/rspec/rails/matchers/have_http_status.rb +1 -1
  41. data/lib/rspec/rails/matchers/routing_matchers.rb +2 -2
  42. data/lib/rspec/rails/matchers/send_email.rb +122 -0
  43. data/lib/rspec/rails/matchers.rb +1 -0
  44. data/lib/rspec/rails/vendor/capybara.rb +1 -3
  45. data/lib/rspec/rails/version.rb +1 -1
  46. data/lib/rspec/rails/view_assigns.rb +0 -18
  47. data/lib/rspec/rails/view_rendering.rb +13 -11
  48. data/lib/rspec-rails.rb +12 -8
  49. data.tar.gz.sig +0 -0
  50. metadata +28 -39
  51. metadata.gz.sig +0 -0
  52. /data/lib/generators/rspec/{integration → request}/templates/request_spec.rb +0 -0
@@ -90,10 +90,17 @@ RSpec.describe <%= controller_class_name %>Controller, <%= type_metatag(:control
90
90
  end
91
91
 
92
92
  context "with invalid params" do
93
+ <% if Rails.version.to_f < 7.0 %>
93
94
  it "returns a success response (i.e. to display the 'new' template)" do
94
95
  post :create, params: {<%= singular_table_name %>: invalid_attributes}, session: valid_session
95
96
  expect(response).to be_successful
96
97
  end
98
+ <% else %>
99
+ it "renders a response with 422 status (i.e. to display the 'new' template)" do
100
+ post :create, params: {<%= singular_table_name %>: invalid_attributes}, session: valid_session
101
+ expect(response).to have_http_status(:unprocessable_entity)
102
+ end
103
+ <% end %>
97
104
  end
98
105
  end
99
106
 
@@ -118,11 +125,19 @@ RSpec.describe <%= controller_class_name %>Controller, <%= type_metatag(:control
118
125
  end
119
126
 
120
127
  context "with invalid params" do
128
+ <% if Rails.version.to_f < 7.0 %>
121
129
  it "returns a success response (i.e. to display the 'edit' template)" do
122
130
  <%= file_name %> = <%= class_name %>.create! valid_attributes
123
131
  put :update, params: {id: <%= file_name %>.to_param, <%= singular_table_name %>: invalid_attributes}, session: valid_session
124
132
  expect(response).to be_successful
125
133
  end
134
+ <% else %>
135
+ it "renders a response with 422 status (i.e. to display the 'edit' template)" do
136
+ <%= file_name %> = <%= class_name %>.create! valid_attributes
137
+ put :update, params: {id: <%= file_name %>.to_param, <%= singular_table_name %>: invalid_attributes}, session: valid_session
138
+ expect(response).to have_http_status(:unprocessable_entity)
139
+ end
140
+ <% end %>
126
141
  end
127
142
  end
128
143
 
@@ -2,18 +2,22 @@ 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
- before(:each) do
6
- @<%= ns_file_name %> = assign(:<%= ns_file_name %>, <%= class_name %>.create!(<%= '))' if output_attributes.empty? %>
5
+ let(:<%= singular_table_name %>) {
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 ? '' : ','%>
9
9
  <% end -%>
10
- <%= output_attributes.empty? ? "" : " ))\n" -%>
10
+ <%= " )\n" unless output_attributes.empty? -%>
11
+ }
12
+
13
+ before(:each) do
14
+ assign(:<%= singular_table_name %>, <%= singular_table_name %>)
11
15
  end
12
16
 
13
17
  it "renders the edit <%= ns_file_name %> form" do
14
18
  render
15
19
 
16
- 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
17
21
  <% for attribute in output_attributes -%>
18
22
  <%- name = attribute.respond_to?(:column_name) ? attribute.column_name : attribute.name %>
19
23
  assert_select "<%= attribute.input_type -%>[name=?]", "<%= ns_file_name %>[<%= name %>]"
@@ -18,8 +18,9 @@ RSpec.describe "<%= ns_table_name %>/index", <%= type_metatag(:view) %> do
18
18
 
19
19
  it "renders a list of <%= ns_table_name %>" do
20
20
  render
21
+ cell_selector = Rails::VERSION::STRING >= '7' ? 'div>p' : 'tr>td'
21
22
  <% for attribute in output_attributes -%>
22
- assert_select "tr>td", text: <%= value_for(attribute) %>.to_s, count: 2
23
+ assert_select cell_selector, text: Regexp.new(<%= value_for(attribute) %>.to_s), count: 2
23
24
  <% end -%>
24
25
  end
25
26
  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 %>/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 -%>
@@ -83,10 +83,17 @@ RSpec.describe "/<%= name.underscore.pluralize %>", <%= type_metatag(:request) %
83
83
  }.to change(<%= class_name %>, :count).by(0)
84
84
  end
85
85
 
86
+ <% if Rails.version.to_f < 7.0 %>
86
87
  it "renders a successful response (i.e. to display the 'new' template)" do
87
88
  post <%= index_helper %>_url, params: { <%= singular_table_name %>: invalid_attributes }
88
89
  expect(response).to be_successful
89
90
  end
91
+ <% else %>
92
+ it "renders a response with 422 status (i.e. to display the 'new' template)" do
93
+ post <%= index_helper %>_url, params: { <%= singular_table_name %>: invalid_attributes }
94
+ expect(response).to have_http_status(:unprocessable_entity)
95
+ end
96
+ <% end %>
90
97
  end
91
98
  end
92
99
 
@@ -112,11 +119,19 @@ RSpec.describe "/<%= name.underscore.pluralize %>", <%= type_metatag(:request) %
112
119
  end
113
120
 
114
121
  context "with invalid parameters" do
122
+ <% if Rails.version.to_f < 7.0 %>
115
123
  it "renders a successful response (i.e. to display the 'edit' template)" do
116
124
  <%= file_name %> = <%= class_name %>.create! valid_attributes
117
125
  patch <%= show_helper %>, params: { <%= singular_table_name %>: invalid_attributes }
118
126
  expect(response).to be_successful
119
127
  end
128
+ <% else %>
129
+ it "renders a response with 422 status (i.e. to display the 'edit' template)" do
130
+ <%= file_name %> = <%= class_name %>.create! valid_attributes
131
+ patch <%= show_helper %>, params: { <%= singular_table_name %>: invalid_attributes }
132
+ expect(response).to have_http_status(:unprocessable_entity)
133
+ end
134
+ <% end %>
120
135
  end
121
136
  end
122
137
 
@@ -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
- @<%= ns_file_name %> = 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 -%>
@@ -9,7 +9,7 @@ module Rspec
9
9
  def generate_system_spec
10
10
  return unless options[:system_specs]
11
11
 
12
- template template_name, File.join('spec/system', class_path, filename)
12
+ template template_name, target_path('system', class_path, filename)
13
13
  end
14
14
 
15
15
  def template_name
@@ -9,12 +9,12 @@ module Rspec
9
9
  class_option :template_engine, desc: "Template engine to generate view files"
10
10
 
11
11
  def create_view_specs
12
- empty_directory File.join("spec", "views", file_path)
12
+ empty_directory target_path("views", file_path)
13
13
 
14
14
  actions.each do |action|
15
15
  @action = action
16
16
  template 'view_spec.rb',
17
- File.join("spec", "views", file_path, "#{@action}.html.#{options[:template_engine]}_spec.rb")
17
+ target_path("views", file_path, "#{@action}.html.#{options[:template_engine]}_spec.rb")
18
18
  end
19
19
  end
20
20
  end
@@ -1,8 +1,9 @@
1
1
  require 'rails/generators/named_base'
2
+ require 'rspec/core'
2
3
  require 'rspec/rails/feature_check'
3
4
 
4
5
  # @private
5
- # Weirdly named generators namespace (should be `RSpec`) for compatability with
6
+ # Weirdly named generators namespace (should be `RSpec`) for compatibility with
6
7
  # rails loading.
7
8
  module Rspec
8
9
  # @private
@@ -18,6 +19,22 @@ module Rspec
18
19
  @_rspec_source_root ||= File.expand_path(File.join(File.dirname(__FILE__), 'rspec', generator_name, 'templates'))
19
20
  end
20
21
  end
22
+
23
+ # @private
24
+ # Load configuration from RSpec to ensure `--default-path` is set
25
+ def self.configuration
26
+ @configuration ||=
27
+ begin
28
+ configuration = RSpec.configuration
29
+ options = RSpec::Core::ConfigurationOptions.new({})
30
+ options.configure(configuration)
31
+ configuration
32
+ end
33
+ end
34
+
35
+ def target_path(*paths)
36
+ File.join(self.class.configuration.default_path, *paths)
37
+ end
21
38
  end
22
39
  end
23
40
  end
@@ -181,5 +181,16 @@ module RSpec
181
181
  #
182
182
  # @private
183
183
  TestUnitAssertionAdapter = MinitestAssertionAdapter
184
+
185
+ # @private
186
+ module TaggedLoggingAdapter
187
+ private
188
+ # Vendored from activesupport/lib/active_support/testing/tagged_logging.rb
189
+ # This implements the tagged_logger method where it is expected, but
190
+ # doesn't call `name` or set it up like Rails does.
191
+ def tagged_logger
192
+ @tagged_logger ||= (defined?(Rails.logger) && Rails.logger)
193
+ end
194
+ end
184
195
  end
185
196
  end
@@ -26,19 +26,19 @@ module RSpec
26
26
  #
27
27
  # @api private
28
28
  DIRECTORY_MAPPINGS = {
29
- channel: %w[spec channels],
29
+ channel: %w[spec channels],
30
30
  controller: %w[spec controllers],
31
- generator: %w[spec generator],
32
- helper: %w[spec helpers],
33
- job: %w[spec jobs],
34
- mailer: %w[spec mailers],
35
- model: %w[spec models],
36
- request: %w[spec (requests|integration|api)],
37
- routing: %w[spec routing],
38
- view: %w[spec views],
39
- feature: %w[spec features],
40
- system: %w[spec system],
41
- mailbox: %w[spec mailboxes]
31
+ generator: %w[spec generator],
32
+ helper: %w[spec helpers],
33
+ job: %w[spec jobs],
34
+ mailer: %w[spec mailers],
35
+ model: %w[spec models],
36
+ request: %w[spec (requests|integration|api)],
37
+ routing: %w[spec routing],
38
+ view: %w[spec views],
39
+ feature: %w[spec features],
40
+ system: %w[spec system],
41
+ mailbox: %w[spec mailboxes]
42
42
  }
43
43
 
44
44
  # Sets up the different example group modules for the different spec types
@@ -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)
@@ -2,6 +2,10 @@
2
2
  # suite and ammeter.
3
3
  require 'rspec/rails/matchers'
4
4
 
5
+ if ::Rails::VERSION::MAJOR >= 7
6
+ require 'active_support/execution_context/test_helper'
7
+ end
8
+
5
9
  module RSpec
6
10
  module Rails
7
11
  # @api public
@@ -12,6 +16,10 @@ module RSpec
12
16
  include RSpec::Rails::MinitestLifecycleAdapter
13
17
  include RSpec::Rails::MinitestAssertionAdapter
14
18
  include RSpec::Rails::FixtureSupport
19
+ if ::Rails::VERSION::MAJOR >= 7
20
+ include RSpec::Rails::TaggedLoggingAdapter
21
+ include ActiveSupport::ExecutionContext::TestHelper
22
+ end
15
23
  end
16
24
  end
17
25
  end
@@ -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
@@ -54,23 +100,22 @@ module RSpec
54
100
  ActionDispatch::SystemTesting::Server.silence_puma = true
55
101
  end
56
102
 
103
+ require 'action_dispatch/system_test_case'
104
+
57
105
  begin
58
106
  require 'capybara'
59
- require 'action_dispatch/system_test_case'
60
107
  rescue LoadError => e
61
108
  abort """
62
109
  LoadError: #{e.message}
63
- System test integration requires Rails >= 5.1 and has a hard
110
+ System test integration has a hard
64
111
  dependency on a webserver and `capybara`, please add capybara to
65
112
  your Gemfile and configure a webserver (e.g. `Capybara.server =
66
- :webrick`) before attempting to use system specs.
113
+ :puma`) before attempting to use system specs.
67
114
  """.gsub(/\s+/, ' ').strip
68
115
  end
69
116
 
70
- if ::Rails::VERSION::STRING >= '6.0'
71
- original_before_teardown =
72
- ::ActionDispatch::SystemTesting::TestHelpers::SetupAndTeardown.instance_method(:before_teardown)
73
- end
117
+ original_before_teardown =
118
+ ::ActionDispatch::SystemTesting::TestHelpers::SetupAndTeardown.instance_method(:before_teardown)
74
119
 
75
120
  original_after_teardown =
76
121
  ::ActionDispatch::SystemTesting::TestHelpers::SetupAndTeardown.instance_method(:after_teardown)
@@ -108,10 +153,7 @@ module RSpec
108
153
  orig_stdout = $stdout
109
154
  $stdout = StringIO.new
110
155
  begin
111
- if ::Rails::VERSION::STRING >= '6.0'
112
- original_before_teardown.bind(self).call
113
- end
114
- original_after_teardown.bind(self).call
156
+ original_before_teardown.bind(self).call
115
157
  ensure
116
158
  myio = $stdout
117
159
  myio.rewind
@@ -119,6 +161,11 @@ module RSpec
119
161
  $stdout = orig_stdout
120
162
  end
121
163
  end
164
+
165
+ around do |example|
166
+ example.run
167
+ original_after_teardown.bind(self).call
168
+ end
122
169
  end
123
170
  end
124
171
  end
@@ -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
@@ -149,11 +150,11 @@ module RSpec
149
150
  # the original string.
150
151
  match = path_regex.match(_default_file_to_render)
151
152
 
152
- render_options = {template: match[:template]}
153
- render_options[:handlers] = [match[:handler]] if match[:handler]
153
+ render_options = { template: match[:template] }
154
+ render_options[:handlers] = [match[:handler].to_sym] if match[:handler]
154
155
  render_options[:formats] = [match[:format].to_sym] if match[:format]
155
- render_options[:locales] = [match[:locale]] if match[:locale]
156
- render_options[:variants] = [match[:variant]] if match[:variant]
156
+ render_options[:locales] = [match[:locale].to_sym] if match[:locale]
157
+ render_options[:variants] = [match[:variant].to_sym] if match[:variant]
157
158
 
158
159
  render_options
159
160
  end
@@ -24,17 +24,21 @@ module RSpec
24
24
  end
25
25
 
26
26
  def has_action_cable_testing?
27
- defined?(::ActionCable) && ActionCable::VERSION::MAJOR >= 6
27
+ defined?(::ActionCable)
28
28
  end
29
29
 
30
30
  def has_action_mailer_parameterized?
31
- has_action_mailer? && defined?(::ActionMailer::Parameterized)
31
+ has_action_mailer? && defined?(::ActionMailer::Parameterized::DeliveryJob)
32
32
  end
33
33
 
34
34
  def has_action_mailer_unified_delivery?
35
35
  has_action_mailer? && defined?(::ActionMailer::MailDeliveryJob)
36
36
  end
37
37
 
38
+ def has_action_mailer_legacy_delivery_job?
39
+ defined?(ActionMailer::DeliveryJob)
40
+ end
41
+
38
42
  def has_action_mailbox?
39
43
  defined?(::ActionMailbox)
40
44
  end
@@ -9,6 +9,9 @@ module RSpec
9
9
 
10
10
  included do
11
11
  self.file_fixture_path = RSpec.configuration.file_fixture_path
12
+ if defined?(ActiveStorage::FixtureSet)
13
+ ActiveStorage::FixtureSet.file_fixture_path = RSpec.configuration.file_fixture_path
14
+ end
12
15
  end
13
16
  end
14
17
  end
@@ -6,44 +6,33 @@ module RSpec
6
6
 
7
7
  private
8
8
 
9
- # In Rails 6.2 fixture file path needs to be relative to `file_fixture_path` instead, this change
10
- # was brought in with a deprecation warning on 6.1. In Rails 6.2 expect to rework this to remove
9
+ # In Rails 7.0 fixture file path needs to be relative to `file_fixture_path` instead, this change
10
+ # was brought in with a deprecation warning on 6.1. In Rails 7.0 expect to rework this to remove
11
11
  # the old accessor.
12
- if ::Rails.version.to_f >= 6.1
13
- def rails_fixture_file_wrapper
14
- RailsFixtureFileWrapper.file_fixture_path = nil
15
- resolved_fixture_path =
16
- if respond_to?(:file_fixture_path) && !file_fixture_path.nil?
17
- file_fixture_path.to_s
18
- else
19
- (RSpec.configuration.fixture_path || '').to_s
20
- end
21
- RailsFixtureFileWrapper.file_fixture_path = File.join(resolved_fixture_path, '') unless resolved_fixture_path.strip.empty?
22
- RailsFixtureFileWrapper.instance
23
- end
24
- else
25
- def rails_fixture_file_wrapper
26
- RailsFixtureFileWrapper.fixture_path = nil
27
- resolved_fixture_path =
28
- if respond_to?(:fixture_path) && !fixture_path.nil?
29
- fixture_path.to_s
30
- else
31
- (RSpec.configuration.fixture_path || '').to_s
32
- end
33
- RailsFixtureFileWrapper.fixture_path = File.join(resolved_fixture_path, '') unless resolved_fixture_path.strip.empty?
34
- RailsFixtureFileWrapper.instance
35
- end
12
+ def rails_fixture_file_wrapper
13
+ RailsFixtureFileWrapper.file_fixture_path = nil
14
+ resolved_fixture_path =
15
+ if respond_to?(:file_fixture_path) && !file_fixture_path.nil?
16
+ file_fixture_path.to_s
17
+ elsif respond_to?(:fixture_paths)
18
+ (RSpec.configuration.fixture_paths&.first || '').to_s
19
+ else
20
+ (RSpec.configuration.fixture_path || '').to_s
21
+ end
22
+ RailsFixtureFileWrapper.file_fixture_path = File.join(resolved_fixture_path, '') unless resolved_fixture_path.strip.empty?
23
+ RailsFixtureFileWrapper.instance
36
24
  end
37
25
 
38
26
  class RailsFixtureFileWrapper
39
27
  include ActionDispatch::TestProcess if defined?(ActionDispatch::TestProcess)
40
-
41
- if ::Rails.version.to_f >= 6.1
42
- include ActiveSupport::Testing::FileFixtures
43
- end
28
+ include ActiveSupport::Testing::FileFixtures
44
29
 
45
30
  class << self
46
- 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
47
36
 
48
37
  # Get instance of wrapper
49
38
  def instance
@@ -21,7 +21,13 @@ module RSpec
21
21
  if RSpec.configuration.use_active_record?
22
22
  include Fixtures
23
23
 
24
- self.fixture_path = RSpec.configuration.fixture_path
24
+ # TestFixtures#fixture_path is deprecated and will be removed in Rails 7.2
25
+ if respond_to?(:fixture_paths=)
26
+ self.fixture_paths = RSpec.configuration.fixture_paths
27
+ else
28
+ self.fixture_path = RSpec.configuration.fixture_path
29
+ end
30
+
25
31
  self.use_transactional_tests = RSpec.configuration.use_transactional_fixtures
26
32
  self.use_instantiated_fixtures = RSpec.configuration.use_instantiated_fixtures
27
33
 
@@ -32,28 +38,50 @@ module RSpec
32
38
  module Fixtures
33
39
  extend ActiveSupport::Concern
34
40
 
41
+ # rubocop:disable Metrics/BlockLength
35
42
  class_methods do
36
- def fixtures(*args)
37
- orig_methods = private_instance_methods
38
- super.tap do
39
- new_methods = private_instance_methods - orig_methods
40
- new_methods.each do |method_name|
41
- 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
42
69
  end
43
70
  end
44
- end
45
71
 
46
- def proxy_method_warning_if_called_in_before_context_scope(method_name)
47
- orig_implementation = instance_method(method_name)
48
- define_method(method_name) do |*args, &blk|
49
- if inspect.include?("before(:context)")
50
- RSpec.warn_with("Calling fixture method in before :context ")
51
- else
52
- 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
53
80
  end
54
81
  end
55
82
  end
56
83
  end
84
+ # rubocop:enable Metrics/BlockLength
57
85
  end
58
86
  end
59
87
  end