rspec-rails 3.8.2 → 6.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/Capybara.md +5 -54
  4. data/Changelog.md +339 -75
  5. data/README.md +278 -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 +6 -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 +20 -16
  17. data/lib/generators/rspec/integration/integration_generator.rb +13 -6
  18. data/lib/generators/rspec/job/job_generator.rb +2 -1
  19. data/lib/generators/rspec/job/templates/job_spec.rb.erb +1 -1
  20. data/lib/generators/rspec/mailbox/mailbox_generator.rb +14 -0
  21. data/lib/generators/rspec/mailbox/templates/mailbox_spec.rb.erb +7 -0
  22. data/lib/generators/rspec/mailer/mailer_generator.rb +5 -4
  23. data/lib/generators/rspec/mailer/templates/mailer_spec.rb +2 -2
  24. data/lib/generators/rspec/mailer/templates/preview.rb +1 -1
  25. data/lib/generators/rspec/model/model_generator.rb +8 -7
  26. data/lib/generators/rspec/model/templates/fixtures.yml +1 -1
  27. data/lib/generators/rspec/request/request_generator.rb +10 -3
  28. data/lib/generators/rspec/scaffold/scaffold_generator.rb +36 -22
  29. data/lib/generators/rspec/scaffold/templates/api_controller_spec.rb +13 -49
  30. data/lib/generators/rspec/scaffold/templates/api_request_spec.rb +131 -0
  31. data/lib/generators/rspec/scaffold/templates/controller_spec.rb +25 -58
  32. data/lib/generators/rspec/scaffold/templates/edit_spec.rb +9 -9
  33. data/lib/generators/rspec/scaffold/templates/index_spec.rb +3 -2
  34. data/lib/generators/rspec/scaffold/templates/new_spec.rb +1 -5
  35. data/lib/generators/rspec/scaffold/templates/request_spec.rb +153 -0
  36. data/lib/generators/rspec/scaffold/templates/routing_spec.rb +8 -10
  37. data/lib/generators/rspec/scaffold/templates/show_spec.rb +2 -2
  38. data/lib/generators/rspec/system/system_generator.rb +24 -0
  39. data/lib/generators/rspec/system/templates/system_spec.rb +9 -0
  40. data/lib/generators/rspec/view/view_generator.rb +4 -4
  41. data/lib/generators/rspec.rb +16 -5
  42. data/lib/rspec/rails/adapters.rb +22 -76
  43. data/lib/rspec/rails/configuration.rb +82 -37
  44. data/lib/rspec/rails/example/channel_example_group.rb +93 -0
  45. data/lib/rspec/rails/example/controller_example_group.rb +5 -4
  46. data/lib/rspec/rails/example/feature_example_group.rb +6 -26
  47. data/lib/rspec/rails/example/helper_example_group.rb +2 -9
  48. data/lib/rspec/rails/example/mailbox_example_group.rb +80 -0
  49. data/lib/rspec/rails/example/mailer_example_group.rb +2 -2
  50. data/lib/rspec/rails/example/rails_example_group.rb +2 -1
  51. data/lib/rspec/rails/example/request_example_group.rb +1 -4
  52. data/lib/rspec/rails/example/system_example_group.rb +34 -16
  53. data/lib/rspec/rails/example/view_example_group.rb +38 -27
  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 +14 -15
  59. data/lib/rspec/rails/fixture_support.rb +40 -32
  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 +173 -25
  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 +227 -0
  70. data/lib/rspec/rails/matchers/have_http_status.rb +21 -26
  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.rb +11 -0
  76. data/lib/rspec/rails/tasks/rspec.rake +7 -17
  77. data/lib/rspec/rails/vendor/capybara.rb +10 -17
  78. data/lib/rspec/rails/version.rb +1 -1
  79. data/lib/rspec/rails/view_assigns.rb +0 -18
  80. data/lib/rspec/rails/view_path_builder.rb +1 -1
  81. data/lib/rspec/rails/view_rendering.rb +20 -7
  82. data/lib/rspec-rails.rb +10 -17
  83. data.tar.gz.sig +0 -0
  84. metadata +51 -33
  85. metadata.gz.sig +0 -0
  86. data/lib/generators/rspec/observer/observer_generator.rb +0 -13
  87. /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(:<%= ns_file_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,44 +26,47 @@ 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
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
72
  config.add_setting :fixture_path
@@ -77,10 +81,8 @@ module RSpec
77
81
  # `RSpec::Rails::FixtureSupport` directly instead
78
82
  config.include RSpec::Rails::FixtureSupport
79
83
 
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
84
+ config.add_setting :file_fixture_path, default: 'spec/fixtures/files'
85
+ config.include RSpec::Rails::FileFixtureSupport
84
86
 
85
87
  # Add support for fixture_path on fixture_file_upload
86
88
  config.include RSpec::Rails::FixtureFileUploadSupport
@@ -91,7 +93,7 @@ module RSpec
91
93
  # as a getter. This makes it easier for rspec-rails users because we use
92
94
  # `render_views` directly in example groups, so this aligns the two APIs,
93
95
  # but requires this workaround:
94
- config.add_setting :rendering_views, :default => false
96
+ config.add_setting :rendering_views, default: false
95
97
 
96
98
  config.instance_exec do
97
99
  def render_views=(val)
@@ -103,13 +105,47 @@ module RSpec
103
105
  end
104
106
 
105
107
  def render_views?
106
- rendering_views
108
+ rendering_views?
109
+ end
110
+
111
+ undef :rendering_views? if respond_to?(:rendering_views?)
112
+ def rendering_views?
113
+ !!rendering_views
114
+ end
115
+
116
+ # Define boolean predicates rather than relying on rspec-core due
117
+ # to the bug fix in rspec/rspec-core#2736, note some of these
118
+ # predicates are a bit nonsensical, but they exist for backwards
119
+ # compatibility, we can tidy these up in `rspec-rails` 5.
120
+ undef :fixture_path? if respond_to?(:fixture_path?)
121
+ def fixture_path?
122
+ !!fixture_path
123
+ end
124
+
125
+ undef :global_fixtures? if respond_to?(:global_fixtures?)
126
+ def global_fixtures?
127
+ !!global_fixtures
128
+ end
129
+
130
+ undef :infer_base_class_for_anonymous_controllers? if respond_to?(:infer_base_class_for_anonymous_controllers?)
131
+ def infer_base_class_for_anonymous_controllers?
132
+ !!infer_base_class_for_anonymous_controllers
133
+ end
134
+
135
+ undef :use_instantiated_fixtures? if respond_to?(:use_instantiated_fixtures?)
136
+ def use_instantiated_fixtures?
137
+ !!use_instantiated_fixtures
138
+ end
139
+
140
+ undef :use_transactional_fixtures? if respond_to?(:use_transactional_fixtures?)
141
+ def use_transactional_fixtures?
142
+ !!use_transactional_fixtures
107
143
  end
108
144
 
109
145
  def infer_spec_type_from_file_location!
110
146
  DIRECTORY_MAPPINGS.each do |type, dir_parts|
111
147
  escaped_path = Regexp.compile(dir_parts.join('[\\\/]') + '[\\\/]')
112
- define_derived_metadata(:file_path => escaped_path) do |metadata|
148
+ define_derived_metadata(file_path: escaped_path) do |metadata|
113
149
  metadata[:type] ||= type
114
150
  end
115
151
  end
@@ -127,22 +163,31 @@ module RSpec
127
163
 
128
164
  if defined?(::Rails::Controller::Testing)
129
165
  [: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
166
+ config.include ::Rails::Controller::Testing::TestProcess, type: type
167
+ config.include ::Rails::Controller::Testing::TemplateAssertions, type: type
168
+ config.include ::Rails::Controller::Testing::Integration, type: type
133
169
  end
134
170
  end
135
171
 
136
- if defined?(ActionMailer)
137
- config.include RSpec::Rails::MailerExampleGroup, :type => :mailer
172
+ if RSpec::Rails::FeatureCheck.has_action_mailer?
173
+ config.include RSpec::Rails::MailerExampleGroup, type: :mailer
174
+ config.after { ActionMailer::Base.deliveries.clear }
175
+ end
176
+
177
+ if RSpec::Rails::FeatureCheck.has_active_job?
178
+ config.include RSpec::Rails::JobExampleGroup, type: :job
179
+ end
180
+
181
+ if RSpec::Rails::FeatureCheck.has_action_cable_testing?
182
+ config.include RSpec::Rails::ChannelExampleGroup, type: :channel
138
183
  end
139
184
 
140
- if defined?(ActiveJob)
141
- config.include RSpec::Rails::JobExampleGroup, :type => :job
185
+ if RSpec::Rails::FeatureCheck.has_action_mailbox?
186
+ config.include RSpec::Rails::MailboxExampleGroup, type: :mailbox
142
187
  end
143
188
  end
144
- # rubocop:enable Style/MethodLength
145
189
 
146
190
  initialize_configuration RSpec.configuration
147
191
  end
148
192
  end
193
+ # 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 }
@@ -37,37 +37,17 @@ end
37
37
 
38
38
  unless RSpec.respond_to?(:feature)
39
39
  opts = {
40
- :capybara_feature => true,
41
- :type => :feature,
42
- :skip => <<-EOT.squish
43
- Feature specs require the Capybara (http://github.com/jnicklas/capybara)
44
- gem, version 2.2.0 or later. We recommend version 2.4.0 or later to avoid
45
- some deprecation warnings and have support for
46
- `config.expose_dsl_globally = false`.
40
+ capybara_feature: true,
41
+ type: :feature,
42
+ skip: <<-EOT.squish
43
+ Feature specs require the Capybara (https://github.com/teamcapybara/capybara)
44
+ gem, version 2.13.0 or later.
47
45
  EOT
48
46
  }
49
47
 
50
- # Capybara's monkey patching causes us to have to jump through some hoops
51
- top_level = self
52
- main_feature = nil
53
- if defined?(Capybara) && ::Capybara::VERSION.to_f < 2.4
54
- # Capybara 2.2 and 2.3 do not use `alias_example_xyz`
55
- opts[:skip] = <<-EOT.squish
56
- Capybara < 2.4.0 does not support RSpec's namespace or
57
- `config.expose_dsl_globally = false`. Upgrade to Capybara >= 2.4.0.
58
- EOT
59
- main_feature = top_level.method(:feature) if top_level.respond_to?(:feature)
60
- end
61
-
62
48
  RSpec.configure do |c|
63
- main_feature = nil unless c.expose_dsl_globally?
64
49
  c.alias_example_group_to :feature, opts
65
50
  c.alias_example_to :scenario
66
- c.alias_example_to :xscenario, :skip => 'Temporarily skipped with xscenario'
51
+ c.alias_example_to :xscenario, skip: 'Temporarily skipped with xscenario'
67
52
  end
68
-
69
- # Due to load order issues and `config.expose_dsl_globally?` defaulting to
70
- # `true` we need to put Capybara's monkey patch method back. Otherwise,
71
- # app upgrades have a high likelyhood of having all feature specs skipped.
72
- top_level.define_singleton_method(:feature, &main_feature) if main_feature
73
53
  end
@@ -12,15 +12,8 @@ module RSpec
12
12
 
13
13
  # @private
14
14
  module ClassMethods
15
- if ::Rails::VERSION::MAJOR > 3
16
- def determine_constant_from_test_name(_ignore)
17
- described_class if yield(described_class)
18
- end
19
- else
20
- def determine_default_helper_class(_ignore)
21
- return unless Module === described_class && !(Class === described_class)
22
- described_class
23
- end
15
+ def determine_constant_from_test_name(_ignore)
16
+ described_class if yield(described_class)
24
17
  end
25
18
  end
26
19