rspec-rails 3.8.2 → 7.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/Capybara.md +5 -54
  4. data/Changelog.md +440 -76
  5. data/README.md +281 -500
  6. data/lib/generators/rspec/channel/channel_generator.rb +12 -0
  7. data/lib/generators/rspec/{observer/templates/observer_spec.rb → channel/templates/channel_spec.rb.erb} +1 -1
  8. data/lib/generators/rspec/controller/controller_generator.rb +24 -7
  9. data/lib/generators/rspec/controller/templates/request_spec.rb +19 -0
  10. data/lib/generators/rspec/controller/templates/routing_spec.rb +13 -0
  11. data/lib/generators/rspec/feature/feature_generator.rb +3 -3
  12. data/lib/generators/rspec/generator/generator_generator.rb +24 -0
  13. data/lib/generators/rspec/generator/templates/generator_spec.rb +5 -0
  14. data/lib/generators/rspec/helper/helper_generator.rb +2 -2
  15. data/lib/generators/rspec/install/install_generator.rb +23 -6
  16. data/lib/generators/rspec/install/templates/spec/rails_helper.rb +32 -17
  17. data/lib/generators/rspec/job/job_generator.rb +2 -1
  18. data/lib/generators/rspec/job/templates/job_spec.rb.erb +1 -1
  19. data/lib/generators/rspec/mailbox/mailbox_generator.rb +14 -0
  20. data/lib/generators/rspec/mailbox/templates/mailbox_spec.rb.erb +7 -0
  21. data/lib/generators/rspec/mailer/mailer_generator.rb +7 -4
  22. data/lib/generators/rspec/mailer/templates/mailer_spec.rb +2 -2
  23. data/lib/generators/rspec/mailer/templates/preview.rb +4 -4
  24. data/lib/generators/rspec/model/model_generator.rb +8 -7
  25. data/lib/generators/rspec/model/templates/fixtures.yml +1 -1
  26. data/lib/generators/rspec/request/request_generator.rb +10 -3
  27. data/lib/generators/rspec/scaffold/scaffold_generator.rb +36 -22
  28. data/lib/generators/rspec/scaffold/templates/api_controller_spec.rb +13 -49
  29. data/lib/generators/rspec/scaffold/templates/api_request_spec.rb +131 -0
  30. data/lib/generators/rspec/scaffold/templates/controller_spec.rb +14 -62
  31. data/lib/generators/rspec/scaffold/templates/edit_spec.rb +9 -9
  32. data/lib/generators/rspec/scaffold/templates/index_spec.rb +3 -2
  33. data/lib/generators/rspec/scaffold/templates/new_spec.rb +2 -6
  34. data/lib/generators/rspec/scaffold/templates/request_spec.rb +138 -0
  35. data/lib/generators/rspec/scaffold/templates/routing_spec.rb +8 -10
  36. data/lib/generators/rspec/scaffold/templates/show_spec.rb +2 -2
  37. data/lib/generators/rspec/system/system_generator.rb +24 -0
  38. data/lib/generators/rspec/system/templates/system_spec.rb +9 -0
  39. data/lib/generators/rspec/view/view_generator.rb +4 -4
  40. data/lib/generators/rspec.rb +16 -5
  41. data/lib/rspec/rails/adapters.rb +22 -76
  42. data/lib/rspec/rails/configuration.rb +112 -38
  43. data/lib/rspec/rails/example/channel_example_group.rb +93 -0
  44. data/lib/rspec/rails/example/controller_example_group.rb +5 -4
  45. data/lib/rspec/rails/example/feature_example_group.rb +6 -26
  46. data/lib/rspec/rails/example/helper_example_group.rb +2 -9
  47. data/lib/rspec/rails/example/mailbox_example_group.rb +80 -0
  48. data/lib/rspec/rails/example/mailer_example_group.rb +2 -2
  49. data/lib/rspec/rails/example/rails_example_group.rb +7 -1
  50. data/lib/rspec/rails/example/request_example_group.rb +1 -4
  51. data/lib/rspec/rails/example/routing_example_group.rb +0 -2
  52. data/lib/rspec/rails/example/system_example_group.rb +88 -16
  53. data/lib/rspec/rails/example/view_example_group.rb +40 -28
  54. data/lib/rspec/rails/example.rb +2 -0
  55. data/lib/rspec/rails/extensions/active_record/proxy.rb +5 -10
  56. data/lib/rspec/rails/feature_check.rb +16 -29
  57. data/lib/rspec/rails/file_fixture_support.rb +11 -10
  58. data/lib/rspec/rails/fixture_file_upload_support.rb +20 -15
  59. data/lib/rspec/rails/fixture_support.rb +64 -34
  60. data/lib/rspec/rails/matchers/action_cable/have_broadcasted_to.rb +173 -0
  61. data/lib/rspec/rails/matchers/action_cable/have_streams.rb +58 -0
  62. data/lib/rspec/rails/matchers/action_cable.rb +65 -0
  63. data/lib/rspec/rails/matchers/action_mailbox.rb +73 -0
  64. data/lib/rspec/rails/matchers/active_job.rb +224 -24
  65. data/lib/rspec/rails/matchers/base_matcher.rb +179 -0
  66. data/lib/rspec/rails/matchers/be_a_new.rb +1 -1
  67. data/lib/rspec/rails/matchers/be_new_record.rb +1 -1
  68. data/lib/rspec/rails/matchers/be_valid.rb +1 -1
  69. data/lib/rspec/rails/matchers/have_enqueued_mail.rb +258 -0
  70. data/lib/rspec/rails/matchers/have_http_status.rb +23 -32
  71. data/lib/rspec/rails/matchers/have_rendered.rb +2 -1
  72. data/lib/rspec/rails/matchers/redirect_to.rb +1 -1
  73. data/lib/rspec/rails/matchers/relation_match_array.rb +1 -1
  74. data/lib/rspec/rails/matchers/routing_matchers.rb +13 -13
  75. data/lib/rspec/rails/matchers/send_email.rb +122 -0
  76. data/lib/rspec/rails/matchers.rb +12 -0
  77. data/lib/rspec/rails/tasks/rspec.rake +9 -17
  78. data/lib/rspec/rails/vendor/capybara.rb +10 -17
  79. data/lib/rspec/rails/version.rb +1 -1
  80. data/lib/rspec/rails/view_assigns.rb +0 -18
  81. data/lib/rspec/rails/view_path_builder.rb +1 -1
  82. data/lib/rspec/rails/view_rendering.rb +20 -7
  83. data/lib/rspec-rails.rb +36 -18
  84. data.tar.gz.sig +0 -0
  85. metadata +55 -37
  86. metadata.gz.sig +0 -0
  87. data/lib/generators/rspec/integration/integration_generator.rb +0 -22
  88. data/lib/generators/rspec/observer/observer_generator.rb +0 -13
  89. /data/lib/generators/rspec/{integration → request}/templates/request_spec.rb +0 -0
@@ -5,43 +5,41 @@ RSpec.describe <%= controller_class_name %>Controller, <%= type_metatag(:routing
5
5
  describe "routing" do
6
6
  <% unless options[:singleton] -%>
7
7
  it "routes to #index" do
8
- expect(:get => "/<%= ns_table_name %>").to route_to("<%= ns_table_name %>#index")
8
+ expect(get: "/<%= ns_table_name %>").to route_to("<%= ns_table_name %>#index")
9
9
  end
10
10
 
11
11
  <% end -%>
12
12
  <% unless options[:api] -%>
13
13
  it "routes to #new" do
14
- expect(:get => "/<%= ns_table_name %>/new").to route_to("<%= ns_table_name %>#new")
14
+ expect(get: "/<%= ns_table_name %>/new").to route_to("<%= ns_table_name %>#new")
15
15
  end
16
16
 
17
17
  <% end -%>
18
18
  it "routes to #show" do
19
- expect(:get => "/<%= ns_table_name %>/1").to route_to("<%= ns_table_name %>#show", :id => "1")
19
+ expect(get: "/<%= ns_table_name %>/1").to route_to("<%= ns_table_name %>#show", id: "1")
20
20
  end
21
21
 
22
22
  <% unless options[:api] -%>
23
23
  it "routes to #edit" do
24
- expect(:get => "/<%= ns_table_name %>/1/edit").to route_to("<%= ns_table_name %>#edit", :id => "1")
24
+ expect(get: "/<%= ns_table_name %>/1/edit").to route_to("<%= ns_table_name %>#edit", id: "1")
25
25
  end
26
26
 
27
27
  <% end -%>
28
28
 
29
29
  it "routes to #create" do
30
- expect(:post => "/<%= ns_table_name %>").to route_to("<%= ns_table_name %>#create")
30
+ expect(post: "/<%= ns_table_name %>").to route_to("<%= ns_table_name %>#create")
31
31
  end
32
32
 
33
33
  it "routes to #update via PUT" do
34
- expect(:put => "/<%= ns_table_name %>/1").to route_to("<%= ns_table_name %>#update", :id => "1")
34
+ expect(put: "/<%= ns_table_name %>/1").to route_to("<%= ns_table_name %>#update", id: "1")
35
35
  end
36
36
 
37
- <% if Rails::VERSION::STRING > '4' -%>
38
37
  it "routes to #update via PATCH" do
39
- expect(:patch => "/<%= ns_table_name %>/1").to route_to("<%= ns_table_name %>#update", :id => "1")
38
+ expect(patch: "/<%= ns_table_name %>/1").to route_to("<%= ns_table_name %>#update", id: "1")
40
39
  end
41
40
 
42
- <% end -%>
43
41
  it "routes to #destroy" do
44
- expect(:delete => "/<%= ns_table_name %>/1").to route_to("<%= ns_table_name %>#destroy", :id => "1")
42
+ expect(delete: "/<%= ns_table_name %>/1").to route_to("<%= ns_table_name %>#destroy", id: "1")
45
43
  end
46
44
  end
47
45
  end
@@ -3,9 +3,9 @@ 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
- :<%= attribute.name %> => <%= value_for(attribute) %><%= attribute_index == output_attributes.length - 1 ? '' : ','%>
8
+ <%= attribute.name %>: <%= value_for(attribute) %><%= attribute_index == output_attributes.length - 1 ? '' : ','%>
9
9
  <% end -%>
10
10
  <% if !output_attributes.empty? -%>
11
11
  ))
@@ -0,0 +1,24 @@
1
+ require 'generators/rspec'
2
+
3
+ module Rspec
4
+ module Generators
5
+ # @private
6
+ class SystemGenerator < Base
7
+ class_option :system_specs, type: :boolean, default: true, desc: "Generate system specs"
8
+
9
+ def generate_system_spec
10
+ return unless options[:system_specs]
11
+
12
+ template template_name, target_path('system', class_path, filename)
13
+ end
14
+
15
+ def template_name
16
+ 'system_spec.rb'
17
+ end
18
+
19
+ def filename
20
+ "#{table_name}_spec.rb"
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,9 @@
1
+ require 'rails_helper'
2
+
3
+ RSpec.describe "<%= class_name.pluralize %>", <%= type_metatag(:system) %> do
4
+ before do
5
+ driven_by(:rack_test)
6
+ end
7
+
8
+ pending "add some scenarios (or delete) #{__FILE__}"
9
+ end
@@ -4,17 +4,17 @@ module Rspec
4
4
  module Generators
5
5
  # @private
6
6
  class ViewGenerator < Base
7
- argument :actions, :type => :array, :default => [], :banner => "action action"
7
+ argument :actions, type: :array, default: [], banner: "action action"
8
8
 
9
- class_option :template_engine, :desc => "Template engine to generate view files"
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
@@ -19,10 +20,20 @@ module Rspec
19
20
  end
20
21
  end
21
22
 
22
- if ::Rails::VERSION::STRING < '3.1'
23
- def module_namespacing
24
- yield if block_given?
25
- end
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)
26
37
  end
27
38
  end
28
39
  end
@@ -19,68 +19,15 @@ module RSpec
19
19
  end
20
20
  private_class_method :disable_testunit_autorun
21
21
 
22
- if ::Rails::VERSION::STRING >= '4.1.0'
23
- if defined?(Kernel.gem)
24
- gem 'minitest'
25
- else
26
- require 'minitest'
27
- end
28
- require 'minitest/assertions'
29
- # Constant aliased to either Minitest or TestUnit, depending on what is
30
- # loaded.
31
- Assertions = Minitest::Assertions
32
- elsif RUBY_VERSION >= '2.2.0'
33
- # Minitest / TestUnit has been removed from ruby core. However, we are
34
- # on an old Rails version and must load the appropriate gem
35
- if ::Rails::VERSION::STRING >= '4.0.0'
36
- # ActiveSupport 4.0.x has the minitest '~> 4.2' gem as a dependency
37
- # This gem has no `lib/minitest.rb` file.
38
- gem 'minitest' if defined?(Kernel.gem)
39
- require 'minitest/unit'
40
- Assertions = MiniTest::Assertions
41
- elsif ::Rails::VERSION::STRING >= '3.2.21'
42
- # TODO: Change the above check to >= '3.2.22' once it's released
43
- begin
44
- # Test::Unit "helpfully" sets up autoload for its `AutoRunner`.
45
- # While we do not reference it directly, when we load the `TestCase`
46
- # classes from AS (ActiveSupport), AS kindly references `AutoRunner`
47
- # for everyone.
48
- #
49
- # To handle this we need to pre-emptively load 'test/unit' and make
50
- # sure the version installed has `AutoRunner` (the 3.x line does to
51
- # date). If so, we turn the auto runner off.
52
- require 'test/unit'
53
- require 'test/unit/assertions'
54
- disable_testunit_autorun
55
- rescue LoadError => e
56
- raise LoadError, <<-ERR.squish, e.backtrace
57
- Ruby 2.2+ has removed test/unit from the core library. Rails
58
- requires this as a dependency. Please add test-unit gem to your
59
- Gemfile: `gem 'test-unit', '~> 3.0'` (#{e.message})"
60
- ERR
61
- end
62
- Assertions = Test::Unit::Assertions
63
- else
64
- abort <<-MSG.squish
65
- Ruby 2.2+ is not supported on Rails #{::Rails::VERSION::STRING}.
66
- Check the Rails release notes for the appropriate update with
67
- support.
68
- MSG
69
- end
22
+ if defined?(Kernel.gem)
23
+ gem 'minitest'
70
24
  else
71
- begin
72
- require 'test/unit/assertions'
73
- rescue LoadError
74
- # work around for Rubinius not having a std std-lib
75
- require 'rubysl-test-unit' if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx'
76
- require 'test/unit/assertions'
77
- end
78
- # Turn off test unit's auto runner for those using the gem
79
- disable_testunit_autorun
80
- # Constant aliased to either Minitest or TestUnit, depending on what is
81
- # loaded.
82
- Assertions = Test::Unit::Assertions
25
+ require 'minitest'
83
26
  end
27
+ require 'minitest/assertions'
28
+ # Constant aliased to either Minitest or TestUnit, depending on what is
29
+ # loaded.
30
+ Assertions = Minitest::Assertions
84
31
 
85
32
  # @private
86
33
  class AssertionDelegator < Module
@@ -103,6 +50,7 @@ module RSpec
103
50
  assertion_modules.each do |mod|
104
51
  mod.public_instance_methods.each do |method|
105
52
  next if method == :method_missing || method == "method_missing"
53
+
106
54
  define_method(method.to_sym) do |*args, &block|
107
55
  assertion_instance.send(method.to_sym, *args, &block)
108
56
  end
@@ -198,12 +146,11 @@ module RSpec
198
146
  # examples without exposing non-assertion methods in Test::Unit or
199
147
  # Minitest.
200
148
  def assertion_method_names
201
- methods = ::RSpec::Rails::Assertions.
202
- public_instance_methods.
203
- select do |m|
149
+ ::RSpec::Rails::Assertions
150
+ .public_instance_methods
151
+ .select do |m|
204
152
  m.to_s =~ /^(assert|flunk|refute)/
205
153
  end
206
- methods + test_unit_specific_methods
207
154
  end
208
155
 
209
156
  def define_assertion_delegators
@@ -213,18 +160,6 @@ module RSpec
213
160
  end
214
161
  end
215
162
  end
216
-
217
- # Starting on Rails 4, Minitest is the default testing framework so no
218
- # need to add TestUnit specific methods.
219
- if ::Rails::VERSION::STRING >= '4.0.0'
220
- def test_unit_specific_methods
221
- []
222
- end
223
- else
224
- def test_unit_specific_methods
225
- [:build_message]
226
- end
227
- end
228
163
  end
229
164
 
230
165
  class AssertionDelegator
@@ -246,5 +181,16 @@ module RSpec
246
181
  #
247
182
  # @private
248
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
249
195
  end
250
196
  end
@@ -1,3 +1,4 @@
1
+ # rubocop: disable Metrics/ModuleLength
1
2
  module RSpec
2
3
  module Rails
3
4
  # Fake class to document RSpec Rails configuration options. In practice,
@@ -25,47 +26,56 @@ module RSpec
25
26
  #
26
27
  # @api private
27
28
  DIRECTORY_MAPPINGS = {
28
- :controller => %w[spec controllers],
29
- :helper => %w[spec helpers],
30
- :job => %w[spec jobs],
31
- :mailer => %w[spec mailers],
32
- :model => %w[spec models],
33
- :request => %w[spec (requests|integration|api)],
34
- :routing => %w[spec routing],
35
- :view => %w[spec views],
36
- :feature => %w[spec features],
37
- :system => %w[spec system]
29
+ channel: %w[spec channels],
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]
38
42
  }
39
43
 
40
44
  # Sets up the different example group modules for the different spec types
41
45
  #
42
46
  # @api private
43
47
  def self.add_test_type_configurations(config)
44
- config.include RSpec::Rails::ControllerExampleGroup, :type => :controller
45
- config.include RSpec::Rails::HelperExampleGroup, :type => :helper
46
- config.include RSpec::Rails::ModelExampleGroup, :type => :model
47
- config.include RSpec::Rails::RequestExampleGroup, :type => :request
48
- config.include RSpec::Rails::RoutingExampleGroup, :type => :routing
49
- config.include RSpec::Rails::ViewExampleGroup, :type => :view
50
- config.include RSpec::Rails::FeatureExampleGroup, :type => :feature
48
+ config.include RSpec::Rails::ControllerExampleGroup, type: :controller
49
+ config.include RSpec::Rails::HelperExampleGroup, type: :helper
50
+ config.include RSpec::Rails::ModelExampleGroup, type: :model
51
+ config.include RSpec::Rails::RequestExampleGroup, type: :request
52
+ config.include RSpec::Rails::RoutingExampleGroup, type: :routing
53
+ config.include RSpec::Rails::ViewExampleGroup, type: :view
54
+ config.include RSpec::Rails::FeatureExampleGroup, type: :feature
51
55
  config.include RSpec::Rails::Matchers
52
- config.include RSpec::Rails::SystemExampleGroup, :type => :system
56
+ config.include RSpec::Rails::SystemExampleGroup, type: :system
53
57
  end
54
58
 
55
59
  # @private
56
- # rubocop:disable Style/MethodLength
57
- def self.initialize_configuration(config)
60
+ def self.initialize_configuration(config) # rubocop:disable Metrics/MethodLength,Metrics/CyclomaticComplexity,Metrics/AbcSize,Metrics/PerceivedComplexity
58
61
  config.backtrace_exclusion_patterns << /vendor\//
59
62
  config.backtrace_exclusion_patterns << %r{lib/rspec/rails}
60
63
 
61
64
  # controller settings
62
- config.add_setting :infer_base_class_for_anonymous_controllers, :default => true
65
+ config.add_setting :infer_base_class_for_anonymous_controllers, default: true
63
66
 
64
67
  # fixture support
65
- config.add_setting :use_transactional_fixtures, :alias_with => :use_transactional_examples
68
+ config.add_setting :use_active_record, default: true
69
+ config.add_setting :use_transactional_fixtures, alias_with: :use_transactional_examples
66
70
  config.add_setting :use_instantiated_fixtures
67
71
  config.add_setting :global_fixtures
68
- 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
+
69
79
  config.include RSpec::Rails::FixtureSupport, :use_fixtures
70
80
 
71
81
  # We'll need to create a deprecated module in order to properly report to
@@ -77,10 +87,8 @@ module RSpec
77
87
  # `RSpec::Rails::FixtureSupport` directly instead
78
88
  config.include RSpec::Rails::FixtureSupport
79
89
 
80
- if ::Rails::VERSION::STRING > '5'
81
- config.add_setting :file_fixture_path, :default => 'spec/fixtures/files'
82
- config.include RSpec::Rails::FileFixtureSupport
83
- end
90
+ config.add_setting :file_fixture_path, default: 'spec/fixtures/files'
91
+ config.include RSpec::Rails::FileFixtureSupport
84
92
 
85
93
  # Add support for fixture_path on fixture_file_upload
86
94
  config.include RSpec::Rails::FixtureFileUploadSupport
@@ -91,7 +99,7 @@ module RSpec
91
99
  # as a getter. This makes it easier for rspec-rails users because we use
92
100
  # `render_views` directly in example groups, so this aligns the two APIs,
93
101
  # but requires this workaround:
94
- config.add_setting :rendering_views, :default => false
102
+ config.add_setting :rendering_views, default: false
95
103
 
96
104
  config.instance_exec do
97
105
  def render_views=(val)
@@ -103,13 +111,47 @@ module RSpec
103
111
  end
104
112
 
105
113
  def render_views?
106
- rendering_views
114
+ rendering_views?
115
+ end
116
+
117
+ undef :rendering_views? if respond_to?(:rendering_views?)
118
+ def rendering_views?
119
+ !!rendering_views
120
+ end
121
+
122
+ # Define boolean predicates rather than relying on rspec-core due
123
+ # to the bug fix in rspec/rspec-core#2736, note some of these
124
+ # predicates are a bit nonsensical, but they exist for backwards
125
+ # compatibility, we can tidy these up in `rspec-rails` 5.
126
+ undef :fixture_path? if respond_to?(:fixture_path?)
127
+ def fixture_path?
128
+ !!fixture_path
129
+ end
130
+
131
+ undef :global_fixtures? if respond_to?(:global_fixtures?)
132
+ def global_fixtures?
133
+ !!global_fixtures
134
+ end
135
+
136
+ undef :infer_base_class_for_anonymous_controllers? if respond_to?(:infer_base_class_for_anonymous_controllers?)
137
+ def infer_base_class_for_anonymous_controllers?
138
+ !!infer_base_class_for_anonymous_controllers
139
+ end
140
+
141
+ undef :use_instantiated_fixtures? if respond_to?(:use_instantiated_fixtures?)
142
+ def use_instantiated_fixtures?
143
+ !!use_instantiated_fixtures
144
+ end
145
+
146
+ undef :use_transactional_fixtures? if respond_to?(:use_transactional_fixtures?)
147
+ def use_transactional_fixtures?
148
+ !!use_transactional_fixtures
107
149
  end
108
150
 
109
151
  def infer_spec_type_from_file_location!
110
152
  DIRECTORY_MAPPINGS.each do |type, dir_parts|
111
153
  escaped_path = Regexp.compile(dir_parts.join('[\\\/]') + '[\\\/]')
112
- define_derived_metadata(:file_path => escaped_path) do |metadata|
154
+ define_derived_metadata(file_path: escaped_path) do |metadata|
113
155
  metadata[:type] ||= type
114
156
  end
115
157
  end
@@ -121,28 +163,60 @@ module RSpec
121
163
  filter_gems_from_backtrace "activemodel", "activerecord",
122
164
  "activesupport", "activejob"
123
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
124
189
  end
125
190
 
126
191
  add_test_type_configurations(config)
127
192
 
128
193
  if defined?(::Rails::Controller::Testing)
129
194
  [:controller, :view, :request].each do |type|
130
- config.include ::Rails::Controller::Testing::TestProcess, :type => type
131
- config.include ::Rails::Controller::Testing::TemplateAssertions, :type => type
132
- config.include ::Rails::Controller::Testing::Integration, :type => type
195
+ config.include ::Rails::Controller::Testing::TestProcess, type: type
196
+ config.include ::Rails::Controller::Testing::TemplateAssertions, type: type
197
+ config.include ::Rails::Controller::Testing::Integration, type: type
133
198
  end
134
199
  end
135
200
 
136
- if defined?(ActionMailer)
137
- config.include RSpec::Rails::MailerExampleGroup, :type => :mailer
201
+ if RSpec::Rails::FeatureCheck.has_action_mailer?
202
+ config.include RSpec::Rails::MailerExampleGroup, type: :mailer
203
+ config.after { ActionMailer::Base.deliveries.clear }
204
+ end
205
+
206
+ if RSpec::Rails::FeatureCheck.has_active_job?
207
+ config.include RSpec::Rails::JobExampleGroup, type: :job
208
+ end
209
+
210
+ if RSpec::Rails::FeatureCheck.has_action_cable_testing?
211
+ config.include RSpec::Rails::ChannelExampleGroup, type: :channel
138
212
  end
139
213
 
140
- if defined?(ActiveJob)
141
- config.include RSpec::Rails::JobExampleGroup, :type => :job
214
+ if RSpec::Rails::FeatureCheck.has_action_mailbox?
215
+ config.include RSpec::Rails::MailboxExampleGroup, type: :mailbox
142
216
  end
143
217
  end
144
- # rubocop:enable Style/MethodLength
145
218
 
146
219
  initialize_configuration RSpec.configuration
147
220
  end
148
221
  end
222
+ # rubocop: enable Metrics/ModuleLength
@@ -0,0 +1,93 @@
1
+ require "rspec/rails/matchers/action_cable/have_streams"
2
+
3
+ module RSpec
4
+ module Rails
5
+ # @api public
6
+ # Container module for channel spec functionality. It is only available if
7
+ # ActionCable has been loaded before it.
8
+ module ChannelExampleGroup
9
+ # @private
10
+ module ClassMethods
11
+ # These blank modules are only necessary for YARD processing. It doesn't
12
+ # handle the conditional check below very well and reports undocumented objects.
13
+ end
14
+ end
15
+ end
16
+ end
17
+
18
+ if RSpec::Rails::FeatureCheck.has_action_cable_testing?
19
+ module RSpec
20
+ module Rails
21
+ # @api public
22
+ # Container module for channel spec functionality.
23
+ module ChannelExampleGroup
24
+ extend ActiveSupport::Concern
25
+ include RSpec::Rails::RailsExampleGroup
26
+ include ActionCable::Connection::TestCase::Behavior
27
+ include ActionCable::Channel::TestCase::Behavior
28
+
29
+ # Class-level DSL for channel specs.
30
+ module ClassMethods
31
+ # @private
32
+ def channel_class
33
+ (_channel_class || described_class).tap do |klass|
34
+ next if klass <= ::ActionCable::Channel::Base
35
+
36
+ raise "Described class is not a channel class.\n" \
37
+ "Specify the channel class in the `describe` statement " \
38
+ "or set it manually using `tests MyChannelClass`"
39
+ end
40
+ end
41
+
42
+ # @private
43
+ def connection_class
44
+ (_connection_class || described_class).tap do |klass|
45
+ next if klass <= ::ActionCable::Connection::Base
46
+
47
+ raise "Described class is not a connection class.\n" \
48
+ "Specify the connection class in the `describe` statement " \
49
+ "or set it manually using `tests MyConnectionClass`"
50
+ end
51
+ end
52
+ end
53
+
54
+ # Checks that the connection attempt has been rejected.
55
+ #
56
+ # @example
57
+ # expect { connect }.to have_rejected_connection
58
+ def have_rejected_connection
59
+ raise_error(::ActionCable::Connection::Authorization::UnauthorizedError)
60
+ end
61
+
62
+ # Checks that the subscription is subscribed to at least one stream.
63
+ #
64
+ # @example
65
+ # expect(subscription).to have_streams
66
+ def have_streams
67
+ check_subscribed!
68
+
69
+ RSpec::Rails::Matchers::ActionCable::HaveStream.new
70
+ end
71
+
72
+ # Checks that the channel has been subscribed to the given stream
73
+ #
74
+ # @example
75
+ # expect(subscription).to have_stream_from("chat_1")
76
+ def have_stream_from(stream)
77
+ check_subscribed!
78
+
79
+ RSpec::Rails::Matchers::ActionCable::HaveStream.new(stream)
80
+ end
81
+
82
+ # Checks that the channel has been subscribed to a stream for the given model
83
+ #
84
+ # @example
85
+ # expect(subscription).to have_stream_for(user)
86
+ def have_stream_for(object)
87
+ check_subscribed!
88
+ RSpec::Rails::Matchers::ActionCable::HaveStream.new(broadcasting_for(object))
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
@@ -94,9 +94,9 @@ module RSpec
94
94
  self.routes = ActionDispatch::Routing::RouteSet.new.tap do |r|
95
95
  r.draw do
96
96
  resources resource_name,
97
- :as => resource_as,
98
- :module => resource_module,
99
- :path => resource_path
97
+ as: resource_as,
98
+ module: resource_module,
99
+ path: resource_path
100
100
  end
101
101
  end
102
102
  end
@@ -159,7 +159,7 @@ module RSpec
159
159
  #
160
160
  # expect do
161
161
  # bypass_rescue
162
- # get :show, :id => profile.id + 1
162
+ # get :show, id: profile.id + 1
163
163
  # end.to raise_error(/403 Forbidden/)
164
164
  # end
165
165
  # end
@@ -176,6 +176,7 @@ module RSpec
176
176
  super
177
177
  end
178
178
  end
179
+ ruby2_keywords :method_missing if respond_to?(:ruby2_keywords, true)
179
180
 
180
181
  included do
181
182
  subject { controller }