rspec-rails 5.1.2 → 7.1.1
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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/Changelog.md +355 -173
- data/README.md +40 -40
- data/lib/generators/rspec/channel/channel_generator.rb +1 -1
- data/lib/generators/rspec/controller/controller_generator.rb +4 -4
- data/lib/generators/rspec/feature/feature_generator.rb +1 -1
- data/lib/generators/rspec/generator/generator_generator.rb +3 -3
- data/lib/generators/rspec/generator/templates/generator_spec.rb +1 -2
- data/lib/generators/rspec/helper/helper_generator.rb +1 -1
- data/lib/generators/rspec/install/install_generator.rb +19 -2
- data/lib/generators/rspec/install/templates/spec/rails_helper.rb +27 -15
- data/lib/generators/rspec/job/job_generator.rb +1 -1
- data/lib/generators/rspec/mailbox/mailbox_generator.rb +1 -1
- data/lib/generators/rspec/mailer/mailer_generator.rb +5 -3
- data/lib/generators/rspec/mailer/templates/preview.rb +3 -3
- data/lib/generators/rspec/model/model_generator.rb +3 -3
- data/lib/generators/rspec/request/request_generator.rb +10 -3
- data/lib/generators/rspec/scaffold/scaffold_generator.rb +4 -4
- data/lib/generators/rspec/scaffold/templates/controller_spec.rb +4 -4
- data/lib/generators/rspec/scaffold/templates/edit_spec.rb +8 -4
- data/lib/generators/rspec/scaffold/templates/index_spec.rb +2 -1
- data/lib/generators/rspec/scaffold/templates/new_spec.rb +1 -1
- data/lib/generators/rspec/scaffold/templates/request_spec.rb +4 -4
- data/lib/generators/rspec/scaffold/templates/show_spec.rb +1 -1
- data/lib/generators/rspec/system/system_generator.rb +1 -1
- data/lib/generators/rspec/view/view_generator.rb +2 -2
- data/lib/generators/rspec.rb +18 -1
- data/lib/rspec/rails/adapters.rb +11 -0
- data/lib/rspec/rails/configuration.rb +43 -14
- data/lib/rspec/rails/example/mailbox_example_group.rb +1 -1
- data/lib/rspec/rails/example/rails_example_group.rb +6 -0
- data/lib/rspec/rails/example/routing_example_group.rb +0 -2
- data/lib/rspec/rails/example/system_example_group.rb +67 -12
- data/lib/rspec/rails/example/view_example_group.rb +6 -5
- data/lib/rspec/rails/feature_check.rb +6 -2
- data/lib/rspec/rails/file_fixture_support.rb +3 -0
- data/lib/rspec/rails/fixture_file_upload_support.rb +20 -31
- data/lib/rspec/rails/fixture_support.rb +44 -17
- data/lib/rspec/rails/matchers/action_cable/have_broadcasted_to.rb +16 -6
- data/lib/rspec/rails/matchers/action_cable.rb +6 -1
- data/lib/rspec/rails/matchers/active_job.rb +73 -12
- data/lib/rspec/rails/matchers/have_enqueued_mail.rb +40 -7
- data/lib/rspec/rails/matchers/have_http_status.rb +4 -8
- data/lib/rspec/rails/matchers/routing_matchers.rb +2 -2
- data/lib/rspec/rails/matchers/send_email.rb +122 -0
- data/lib/rspec/rails/matchers.rb +1 -0
- data/lib/rspec/rails/tasks/rspec.rake +3 -1
- data/lib/rspec/rails/vendor/capybara.rb +1 -3
- data/lib/rspec/rails/version.rb +1 -1
- data/lib/rspec/rails/view_assigns.rb +0 -18
- data/lib/rspec/rails/view_rendering.rb +13 -11
- data/lib/rspec-rails.rb +28 -7
- data.tar.gz.sig +0 -0
- metadata +42 -58
- metadata.gz.sig +0 -0
- data/lib/generators/rspec/integration/integration_generator.rb +0 -22
- /data/lib/generators/rspec/{integration → request}/templates/request_spec.rb +0 -0
@@ -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
|
-
|
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,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
|
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
|
-
|
17
|
+
target_path("views", file_path, "#{@action}.html.#{options[:template_engine]}_spec.rb")
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
data/lib/generators/rspec.rb
CHANGED
@@ -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
|
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
|
data/lib/rspec/rails/adapters.rb
CHANGED
@@ -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:
|
29
|
+
channel: %w[spec channels],
|
30
30
|
controller: %w[spec controllers],
|
31
|
-
generator:
|
32
|
-
helper:
|
33
|
-
job:
|
34
|
-
mailer:
|
35
|
-
model:
|
36
|
-
request:
|
37
|
-
routing:
|
38
|
-
view:
|
39
|
-
feature:
|
40
|
-
system:
|
41
|
-
mailbox:
|
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
|
-
|
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 [
|
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,9 @@
|
|
2
2
|
# suite and ammeter.
|
3
3
|
require 'rspec/rails/matchers'
|
4
4
|
|
5
|
+
require 'active_support/current_attributes/test_helper'
|
6
|
+
require 'active_support/execution_context/test_helper'
|
7
|
+
|
5
8
|
module RSpec
|
6
9
|
module Rails
|
7
10
|
# @api public
|
@@ -12,6 +15,9 @@ module RSpec
|
|
12
15
|
include RSpec::Rails::MinitestLifecycleAdapter
|
13
16
|
include RSpec::Rails::MinitestAssertionAdapter
|
14
17
|
include RSpec::Rails::FixtureSupport
|
18
|
+
include RSpec::Rails::TaggedLoggingAdapter
|
19
|
+
include ActiveSupport::CurrentAttributes::TestHelper
|
20
|
+
include ActiveSupport::ExecutionContext::TestHelper
|
15
21
|
end
|
16
22
|
end
|
17
23
|
end
|
@@ -44,33 +44,86 @@ 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
|
50
96
|
end
|
51
97
|
|
98
|
+
# Default driver to assign if none specified.
|
99
|
+
DEFAULT_DRIVER =
|
100
|
+
if ::Rails::VERSION::STRING.to_f >= 7.2
|
101
|
+
:selenium_chrome_headless
|
102
|
+
else
|
103
|
+
:selenium
|
104
|
+
end
|
105
|
+
|
52
106
|
included do |other|
|
53
107
|
ActiveSupport.on_load(:action_dispatch_system_test_case) do
|
54
108
|
ActionDispatch::SystemTesting::Server.silence_puma = true
|
55
109
|
end
|
56
110
|
|
111
|
+
require 'action_dispatch/system_test_case'
|
112
|
+
|
57
113
|
begin
|
58
114
|
require 'capybara'
|
59
|
-
require 'action_dispatch/system_test_case'
|
60
115
|
rescue LoadError => e
|
61
116
|
abort """
|
62
117
|
LoadError: #{e.message}
|
63
|
-
System test integration
|
118
|
+
System test integration has a hard
|
64
119
|
dependency on a webserver and `capybara`, please add capybara to
|
65
120
|
your Gemfile and configure a webserver (e.g. `Capybara.server =
|
66
|
-
:
|
121
|
+
:puma`) before attempting to use system specs.
|
67
122
|
""".gsub(/\s+/, ' ').strip
|
68
123
|
end
|
69
124
|
|
70
|
-
|
71
|
-
|
72
|
-
::ActionDispatch::SystemTesting::TestHelpers::SetupAndTeardown.instance_method(:before_teardown)
|
73
|
-
end
|
125
|
+
original_before_teardown =
|
126
|
+
::ActionDispatch::SystemTesting::TestHelpers::SetupAndTeardown.instance_method(:before_teardown)
|
74
127
|
|
75
128
|
original_after_teardown =
|
76
129
|
::ActionDispatch::SystemTesting::TestHelpers::SetupAndTeardown.instance_method(:after_teardown)
|
@@ -92,7 +145,7 @@ module RSpec
|
|
92
145
|
self.class.before do
|
93
146
|
# A user may have already set the driver, so only default if driver
|
94
147
|
# is not set
|
95
|
-
driven_by(
|
148
|
+
driven_by(DEFAULT_DRIVER) unless @driver
|
96
149
|
end
|
97
150
|
end
|
98
151
|
|
@@ -108,10 +161,7 @@ module RSpec
|
|
108
161
|
orig_stdout = $stdout
|
109
162
|
$stdout = StringIO.new
|
110
163
|
begin
|
111
|
-
|
112
|
-
original_before_teardown.bind(self).call
|
113
|
-
end
|
114
|
-
original_after_teardown.bind(self).call
|
164
|
+
original_before_teardown.bind(self).call
|
115
165
|
ensure
|
116
166
|
myio = $stdout
|
117
167
|
myio.rewind
|
@@ -119,6 +169,11 @@ module RSpec
|
|
119
169
|
$stdout = orig_stdout
|
120
170
|
end
|
121
171
|
end
|
172
|
+
|
173
|
+
around do |example|
|
174
|
+
example.run
|
175
|
+
original_after_teardown.bind(self).call
|
176
|
+
end
|
122
177
|
end
|
123
178
|
end
|
124
179
|
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
|
-
|
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)
|
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
|
@@ -6,44 +6,33 @@ module RSpec
|
|
6
6
|
|
7
7
|
private
|
8
8
|
|
9
|
-
# In Rails
|
10
|
-
# was brought in with a deprecation warning on 6.1. In Rails
|
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
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
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
|
-
|
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
|
@@ -10,8 +10,7 @@ module RSpec
|
|
10
10
|
include ActiveRecord::TestFixtures
|
11
11
|
|
12
12
|
# @private prevent ActiveSupport::TestFixtures to start a DB transaction.
|
13
|
-
# Monkey patched to avoid collisions with 'let(:name)'
|
14
|
-
# and let(:method_name) before Rails 6.1.
|
13
|
+
# Monkey patched to avoid collisions with 'let(:name)' since Rails 6.1
|
15
14
|
def run_in_transaction?
|
16
15
|
current_example_name = (RSpec.current_example && RSpec.current_example.metadata[:description])
|
17
16
|
use_transactional_tests && !self.class.uses_transaction?(current_example_name)
|
@@ -21,7 +20,13 @@ module RSpec
|
|
21
20
|
if RSpec.configuration.use_active_record?
|
22
21
|
include Fixtures
|
23
22
|
|
24
|
-
|
23
|
+
# TestFixtures#fixture_path is deprecated and will be removed in Rails 7.2
|
24
|
+
if respond_to?(:fixture_paths=)
|
25
|
+
self.fixture_paths = RSpec.configuration.fixture_paths
|
26
|
+
else
|
27
|
+
self.fixture_path = RSpec.configuration.fixture_path
|
28
|
+
end
|
29
|
+
|
25
30
|
self.use_transactional_tests = RSpec.configuration.use_transactional_fixtures
|
26
31
|
self.use_instantiated_fixtures = RSpec.configuration.use_instantiated_fixtures
|
27
32
|
|
@@ -32,28 +37,50 @@ module RSpec
|
|
32
37
|
module Fixtures
|
33
38
|
extend ActiveSupport::Concern
|
34
39
|
|
40
|
+
# rubocop:disable Metrics/BlockLength
|
35
41
|
class_methods do
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
+
if ::Rails.version.to_f >= 7.1
|
43
|
+
def fixtures(*args)
|
44
|
+
super.tap do
|
45
|
+
fixture_sets.each_pair do |method_name, fixture_name|
|
46
|
+
proxy_method_warning_if_called_in_before_context_scope(method_name, fixture_name)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def proxy_method_warning_if_called_in_before_context_scope(method_name, fixture_name)
|
52
|
+
define_method(method_name) do |*args, **kwargs, &blk|
|
53
|
+
if RSpec.current_scope == :before_context_hook
|
54
|
+
RSpec.warn_with("Calling fixture method in before :context ")
|
55
|
+
else
|
56
|
+
access_fixture(fixture_name, *args, **kwargs, &blk)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
else
|
61
|
+
def fixtures(*args)
|
62
|
+
orig_methods = private_instance_methods
|
63
|
+
super.tap do
|
64
|
+
new_methods = private_instance_methods - orig_methods
|
65
|
+
new_methods.each do |method_name|
|
66
|
+
proxy_method_warning_if_called_in_before_context_scope(method_name)
|
67
|
+
end
|
42
68
|
end
|
43
69
|
end
|
44
|
-
end
|
45
70
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
71
|
+
def proxy_method_warning_if_called_in_before_context_scope(method_name)
|
72
|
+
orig_implementation = instance_method(method_name)
|
73
|
+
define_method(method_name) do |*args, &blk|
|
74
|
+
if RSpec.current_scope == :before_context_hook
|
75
|
+
RSpec.warn_with("Calling fixture method in before :context ")
|
76
|
+
else
|
77
|
+
orig_implementation.bind(self).call(*args, &blk)
|
78
|
+
end
|
53
79
|
end
|
54
80
|
end
|
55
81
|
end
|
56
82
|
end
|
83
|
+
# rubocop:enable Metrics/BlockLength
|
57
84
|
end
|
58
85
|
end
|
59
86
|
end
|
@@ -51,6 +51,10 @@ module RSpec
|
|
51
51
|
exactly(:thrice)
|
52
52
|
end
|
53
53
|
|
54
|
+
def description
|
55
|
+
"have broadcasted #{base_description}"
|
56
|
+
end
|
57
|
+
|
54
58
|
def failure_message
|
55
59
|
"expected to broadcast #{base_message}".tap do |msg|
|
56
60
|
if @unmatching_msgs.any?
|
@@ -96,8 +100,11 @@ module RSpec
|
|
96
100
|
private
|
97
101
|
|
98
102
|
def stream
|
99
|
-
@stream ||=
|
103
|
+
@stream ||= case @target
|
104
|
+
when String
|
100
105
|
@target
|
106
|
+
when Symbol
|
107
|
+
@target.to_s
|
101
108
|
else
|
102
109
|
check_channel_presence
|
103
110
|
@channel.broadcasting_for(@target)
|
@@ -109,7 +116,7 @@ module RSpec
|
|
109
116
|
decoded = ActiveSupport::JSON.decode(msg)
|
110
117
|
decoded = decoded.with_indifferent_access if decoded.is_a?(Hash)
|
111
118
|
|
112
|
-
if @data.nil? || @data
|
119
|
+
if @data.nil? || values_match?(@data, decoded)
|
113
120
|
@block.call(decoded)
|
114
121
|
true
|
115
122
|
else
|
@@ -137,18 +144,21 @@ module RSpec
|
|
137
144
|
end
|
138
145
|
end
|
139
146
|
|
140
|
-
def
|
147
|
+
def base_description
|
141
148
|
"#{message_expectation_modifier} #{@expected_number} messages to #{stream}".tap do |msg|
|
142
149
|
msg << " with #{data_description(@data)}" unless @data.nil?
|
143
|
-
msg << ", but broadcast #{@matching_msgs_count}"
|
144
150
|
end
|
145
151
|
end
|
146
152
|
|
153
|
+
def base_message
|
154
|
+
"#{base_description}, but broadcast #{@matching_msgs_count}"
|
155
|
+
end
|
156
|
+
|
147
157
|
def data_description(data)
|
148
158
|
if data.is_a?(RSpec::Matchers::Composable)
|
149
159
|
data.description
|
150
160
|
else
|
151
|
-
data
|
161
|
+
data.inspect
|
152
162
|
end
|
153
163
|
end
|
154
164
|
|
@@ -159,7 +169,7 @@ module RSpec
|
|
159
169
|
def check_channel_presence
|
160
170
|
return if @channel.present? && @channel.respond_to?(:channel_name)
|
161
171
|
|
162
|
-
error_msg = "Broadcasting channel can't be
|
172
|
+
error_msg = "Broadcasting channel can't be inferred. Please, specify it with `from_channel`"
|
163
173
|
raise ArgumentError, error_msg
|
164
174
|
end
|
165
175
|
end
|
@@ -3,6 +3,8 @@ require "rspec/rails/matchers/action_cable/have_broadcasted_to"
|
|
3
3
|
module RSpec
|
4
4
|
module Rails
|
5
5
|
module Matchers
|
6
|
+
extend RSpec::Matchers::DSL
|
7
|
+
|
6
8
|
# Namespace for various implementations of ActionCable features
|
7
9
|
#
|
8
10
|
# @api private
|
@@ -50,7 +52,10 @@ module RSpec
|
|
50
52
|
|
51
53
|
ActionCable::HaveBroadcastedTo.new(target, channel: described_class)
|
52
54
|
end
|
53
|
-
|
55
|
+
|
56
|
+
alias_matcher :broadcast_to, :have_broadcasted_to do |desc|
|
57
|
+
desc.gsub("have broadcasted", "broadcast")
|
58
|
+
end
|
54
59
|
|
55
60
|
private
|
56
61
|
|