rspec-rails 3.0.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.
Files changed (105) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data/.document +1 -1
  4. data/.yardopts +3 -1
  5. data/Capybara.md +6 -55
  6. data/Changelog.md +805 -47
  7. data/{License.txt → LICENSE.md} +5 -3
  8. data/README.md +278 -444
  9. data/lib/generators/rspec/channel/channel_generator.rb +12 -0
  10. data/lib/generators/rspec/{observer/templates/observer_spec.rb → channel/templates/channel_spec.rb.erb} +1 -1
  11. data/lib/generators/rspec/controller/controller_generator.rb +24 -7
  12. data/lib/generators/rspec/controller/templates/controller_spec.rb +3 -3
  13. data/lib/generators/rspec/controller/templates/request_spec.rb +19 -0
  14. data/lib/generators/rspec/controller/templates/routing_spec.rb +13 -0
  15. data/lib/generators/rspec/controller/templates/view_spec.rb +1 -1
  16. data/lib/generators/rspec/feature/feature_generator.rb +15 -2
  17. data/lib/generators/rspec/feature/templates/feature_singular_spec.rb +5 -0
  18. data/lib/generators/rspec/feature/templates/feature_spec.rb +1 -1
  19. data/lib/generators/rspec/generator/generator_generator.rb +24 -0
  20. data/lib/generators/rspec/generator/templates/generator_spec.rb +5 -0
  21. data/lib/generators/rspec/helper/helper_generator.rb +2 -2
  22. data/lib/generators/rspec/helper/templates/helper_spec.rb +1 -1
  23. data/lib/generators/rspec/install/install_generator.rb +41 -7
  24. data/lib/generators/rspec/install/templates/spec/rails_helper.rb +63 -22
  25. data/lib/generators/rspec/job/job_generator.rb +13 -0
  26. data/lib/generators/rspec/job/templates/job_spec.rb.erb +7 -0
  27. data/lib/generators/rspec/mailbox/mailbox_generator.rb +14 -0
  28. data/lib/generators/rspec/mailbox/templates/mailbox_spec.rb.erb +7 -0
  29. data/lib/generators/rspec/mailer/mailer_generator.rb +12 -3
  30. data/lib/generators/rspec/mailer/templates/mailer_spec.rb +2 -2
  31. data/lib/generators/rspec/mailer/templates/preview.rb +13 -0
  32. data/lib/generators/rspec/model/model_generator.rb +20 -6
  33. data/lib/generators/rspec/model/templates/fixtures.yml +1 -1
  34. data/lib/generators/rspec/model/templates/model_spec.rb +1 -1
  35. data/lib/generators/rspec/request/request_generator.rb +17 -0
  36. data/lib/generators/rspec/request/templates/request_spec.rb +10 -0
  37. data/lib/generators/rspec/scaffold/scaffold_generator.rb +90 -113
  38. data/lib/generators/rspec/scaffold/templates/api_controller_spec.rb +129 -0
  39. data/lib/generators/rspec/scaffold/templates/api_request_spec.rb +131 -0
  40. data/lib/generators/rspec/scaffold/templates/controller_spec.rb +46 -64
  41. data/lib/generators/rspec/scaffold/templates/edit_spec.rb +11 -7
  42. data/lib/generators/rspec/scaffold/templates/index_spec.rb +4 -3
  43. data/lib/generators/rspec/scaffold/templates/new_spec.rb +4 -4
  44. data/lib/generators/rspec/scaffold/templates/request_spec.rb +138 -0
  45. data/lib/generators/rspec/scaffold/templates/routing_spec.rb +18 -11
  46. data/lib/generators/rspec/scaffold/templates/show_spec.rb +3 -3
  47. data/lib/generators/rspec/system/system_generator.rb +24 -0
  48. data/lib/generators/rspec/system/templates/system_spec.rb +9 -0
  49. data/lib/generators/rspec/view/templates/view_spec.rb +1 -1
  50. data/lib/generators/rspec/view/view_generator.rb +4 -4
  51. data/lib/generators/rspec.rb +30 -11
  52. data/lib/rspec/rails/active_record.rb +25 -0
  53. data/lib/rspec/rails/adapters.rb +46 -29
  54. data/lib/rspec/rails/configuration.rb +165 -41
  55. data/lib/rspec/rails/example/channel_example_group.rb +93 -0
  56. data/lib/rspec/rails/example/controller_example_group.rb +185 -149
  57. data/lib/rspec/rails/example/feature_example_group.rb +43 -23
  58. data/lib/rspec/rails/example/helper_example_group.rb +28 -25
  59. data/lib/rspec/rails/example/job_example_group.rb +23 -0
  60. data/lib/rspec/rails/example/mailbox_example_group.rb +80 -0
  61. data/lib/rspec/rails/example/mailer_example_group.rb +27 -22
  62. data/lib/rspec/rails/example/model_example_group.rb +9 -6
  63. data/lib/rspec/rails/example/rails_example_group.rb +9 -2
  64. data/lib/rspec/rails/example/request_example_group.rb +21 -17
  65. data/lib/rspec/rails/example/routing_example_group.rb +47 -39
  66. data/lib/rspec/rails/example/system_example_group.rb +180 -0
  67. data/lib/rspec/rails/example/view_example_group.rb +179 -134
  68. data/lib/rspec/rails/example.rb +4 -0
  69. data/lib/rspec/rails/extensions/active_record/proxy.rb +5 -11
  70. data/lib/rspec/rails/feature_check.rb +51 -0
  71. data/lib/rspec/rails/file_fixture_support.rb +18 -0
  72. data/lib/rspec/rails/fixture_file_upload_support.rb +45 -0
  73. data/lib/rspec/rails/fixture_support.rb +70 -14
  74. data/lib/rspec/rails/matchers/action_cable/have_broadcasted_to.rb +180 -0
  75. data/lib/rspec/rails/matchers/action_cable/have_streams.rb +58 -0
  76. data/lib/rspec/rails/matchers/action_cable.rb +70 -0
  77. data/lib/rspec/rails/matchers/action_mailbox.rb +73 -0
  78. data/lib/rspec/rails/matchers/active_job.rb +526 -0
  79. data/lib/rspec/rails/matchers/base_matcher.rb +179 -0
  80. data/lib/rspec/rails/matchers/be_a_new.rb +70 -64
  81. data/lib/rspec/rails/matchers/be_new_record.rb +25 -20
  82. data/lib/rspec/rails/matchers/be_valid.rb +39 -34
  83. data/lib/rspec/rails/matchers/have_enqueued_mail.rb +259 -0
  84. data/lib/rspec/rails/matchers/have_http_status.rb +359 -333
  85. data/lib/rspec/rails/matchers/have_rendered.rb +55 -32
  86. data/lib/rspec/rails/matchers/redirect_to.rb +30 -27
  87. data/lib/rspec/rails/matchers/relation_match_array.rb +1 -1
  88. data/lib/rspec/rails/matchers/routing_matchers.rb +107 -101
  89. data/lib/rspec/rails/matchers/send_email.rb +122 -0
  90. data/lib/rspec/rails/matchers.rb +21 -12
  91. data/lib/rspec/rails/tasks/rspec.rake +9 -17
  92. data/lib/rspec/rails/vendor/capybara.rb +10 -11
  93. data/lib/rspec/rails/version.rb +1 -1
  94. data/lib/rspec/rails/view_assigns.rb +1 -20
  95. data/lib/rspec/rails/view_path_builder.rb +29 -0
  96. data/lib/rspec/rails/view_rendering.rb +89 -27
  97. data/lib/rspec/rails/view_spec_methods.rb +56 -0
  98. data/lib/rspec/rails.rb +9 -1
  99. data/lib/rspec-rails.rb +83 -3
  100. data.tar.gz.sig +0 -0
  101. metadata +108 -78
  102. metadata.gz.sig +3 -2
  103. data/lib/generators/rspec/integration/integration_generator.rb +0 -17
  104. data/lib/generators/rspec/integration/templates/request_spec.rb +0 -10
  105. data/lib/generators/rspec/observer/observer_generator.rb +0 -13
@@ -1,41 +1,64 @@
1
- module RSpec::Rails::Matchers
2
- # Matcher for template rendering.
3
- module RenderTemplate
4
- # @private
5
- class RenderTemplateMatcher < RSpec::Matchers::BuiltIn::BaseMatcher
1
+ module RSpec
2
+ module Rails
3
+ module Matchers
4
+ # Matcher for template rendering.
5
+ module RenderTemplate
6
+ # @private
7
+ class RenderTemplateMatcher < RSpec::Rails::Matchers::BaseMatcher
8
+ def initialize(scope, expected, message = nil)
9
+ @expected = Symbol === expected ? expected.to_s : expected
10
+ @message = message
11
+ @scope = scope
12
+ @redirect_is = nil
13
+ end
6
14
 
7
- def initialize(scope, expected, message=nil)
8
- @expected = Symbol === expected ? expected.to_s : expected
9
- @message = message
10
- @scope = scope
11
- end
15
+ # @api private
16
+ def matches?(*)
17
+ match_check = match_unless_raises ActiveSupport::TestCase::Assertion do
18
+ @scope.assert_template expected, @message
19
+ end
20
+ check_redirect unless match_check
21
+ match_check
22
+ end
23
+
24
+ # Uses normalize_argument_to_redirection to find and format
25
+ # the redirect location. normalize_argument_to_redirection is private
26
+ # in ActionDispatch::Assertions::ResponseAssertions so we call it
27
+ # here using #send. This will keep the error message format consistent
28
+ # @api private
29
+ def check_redirect
30
+ response = @scope.response
31
+ return unless response.respond_to?(:redirect?) && response.redirect?
32
+
33
+ @redirect_is = @scope.send(:normalize_argument_to_redirection, response.location)
34
+ end
12
35
 
13
- # @api private
14
- def matches?(*)
15
- match_unless_raises ActiveSupport::TestCase::Assertion do
16
- @scope.assert_template expected, @message
36
+ # @api private
37
+ def failure_message
38
+ if @redirect_is
39
+ rescued_exception.message[/(.*?)( but|$)/, 1] +
40
+ " but was a redirect to <#{@redirect_is}>"
41
+ else
42
+ rescued_exception.message
43
+ end
44
+ end
45
+
46
+ # @api private
47
+ def failure_message_when_negated
48
+ "expected not to render #{expected.inspect}, but did"
49
+ end
17
50
  end
18
- end
19
51
 
20
- # @api private
21
- def failure_message
22
- rescued_exception.message
23
- end
52
+ # Delegates to `assert_template`.
53
+ #
54
+ # @example
55
+ # expect(response).to have_rendered("new")
56
+ def have_rendered(options, message = nil)
57
+ RenderTemplateMatcher.new(self, options, message)
58
+ end
24
59
 
25
- # @api private
26
- def failure_message_when_negated
27
- "expected not to render #{expected.inspect}, but did"
60
+ alias_method :render_template, :have_rendered
28
61
  end
29
62
  end
30
-
31
- # Delegates to `assert_template`.
32
- #
33
- # @example
34
- # expect(response).to have_rendered("new")
35
- def have_rendered(options, message=nil)
36
- RenderTemplateMatcher.new(self, options, message)
37
- end
38
-
39
- alias_method :render_template, :have_rendered
40
63
  end
41
64
  end
@@ -1,35 +1,38 @@
1
- module RSpec::Rails::Matchers
2
- # Matcher for redirects.
3
- module RedirectTo
4
- # @private
5
- class RedirectTo < RSpec::Matchers::BuiltIn::BaseMatcher
1
+ module RSpec
2
+ module Rails
3
+ module Matchers
4
+ # Matcher for redirects.
5
+ module RedirectTo
6
+ # @private
7
+ class RedirectTo < RSpec::Rails::Matchers::BaseMatcher
8
+ def initialize(scope, expected)
9
+ @expected = expected
10
+ @scope = scope
11
+ end
6
12
 
7
- def initialize(scope, expected)
8
- @expected = expected
9
- @scope = scope
10
- end
13
+ def matches?(_)
14
+ match_unless_raises ActiveSupport::TestCase::Assertion do
15
+ @scope.assert_redirected_to(@expected)
16
+ end
17
+ end
11
18
 
12
- def matches?(_)
13
- match_unless_raises ActiveSupport::TestCase::Assertion do
14
- @scope.assert_redirected_to(@expected)
15
- end
16
- end
19
+ def failure_message
20
+ rescued_exception.message
21
+ end
17
22
 
18
- def failure_message
19
- rescued_exception.message
20
- end
23
+ def failure_message_when_negated
24
+ "expected not to redirect to #{@expected.inspect}, but did"
25
+ end
26
+ end
21
27
 
22
- def failure_message_when_negated
23
- "expected not to redirect to #{@expected.inspect}, but did"
28
+ # Delegates to `assert_redirected_to`.
29
+ #
30
+ # @example
31
+ # expect(response).to redirect_to(:action => "new")
32
+ def redirect_to(target)
33
+ RedirectTo.new(self, target)
34
+ end
24
35
  end
25
36
  end
26
-
27
- # Delegates to `assert_redirected_to`.
28
- #
29
- # @example
30
- # expect(response).to redirect_to(:action => "new")
31
- def redirect_to(target)
32
- RedirectTo.new(self, target)
33
- end
34
37
  end
35
38
  end
@@ -1,3 +1,3 @@
1
- if defined?(ActiveRecord::Relation)
1
+ if defined?(ActiveRecord::Relation) && defined?(RSpec::Matchers::BuiltIn::OperatorMatcher) # RSpec 4 removed OperatorMatcher
2
2
  RSpec::Matchers::BuiltIn::OperatorMatcher.register(ActiveRecord::Relation, '=~', RSpec::Matchers::BuiltIn::ContainExactly)
3
3
  end
@@ -1,117 +1,123 @@
1
- module RSpec::Rails::Matchers
2
- # Matchers to help with specs for routing code.
3
- module RoutingMatchers
4
- extend RSpec::Matchers::DSL
1
+ module RSpec
2
+ module Rails
3
+ module Matchers
4
+ # Matchers to help with specs for routing code.
5
+ module RoutingMatchers
6
+ extend RSpec::Matchers::DSL
5
7
 
6
- # @private
7
- class RouteToMatcher < RSpec::Matchers::BuiltIn::BaseMatcher
8
+ # @private
9
+ class RouteToMatcher < RSpec::Rails::Matchers::BaseMatcher
10
+ def initialize(scope, *expected)
11
+ @scope = scope
12
+ @expected = expected[1] || {}
13
+ if Hash === expected[0]
14
+ @expected.merge!(expected[0])
15
+ else
16
+ controller, action = expected[0].split('#')
17
+ @expected.merge!(controller: controller, action: action)
18
+ end
19
+ end
8
20
 
9
- def initialize(scope, *expected)
10
- @scope = scope
11
- @expected = expected[1] || {}
12
- if Hash === expected[0]
13
- @expected.merge!(expected[0])
14
- else
15
- controller, action = expected[0].split('#')
16
- @expected.merge!(:controller => controller, :action => action)
17
- end
18
- end
21
+ def matches?(verb_to_path_map)
22
+ @actual = verb_to_path_map
23
+ # assert_recognizes does not consider ActionController::RoutingError an
24
+ # assertion failure, so we have to capture that and Assertion here.
25
+ match_unless_raises ActiveSupport::TestCase::Assertion, ActionController::RoutingError do
26
+ path, query = *verb_to_path_map.values.first.split('?')
27
+ @scope.assert_recognizes(
28
+ @expected,
29
+ { method: verb_to_path_map.keys.first, path: path },
30
+ Rack::Utils.parse_nested_query(query)
31
+ )
32
+ end
33
+ end
19
34
 
20
- def matches?(verb_to_path_map)
21
- @actual = @verb_to_path_map = verb_to_path_map
22
- # assert_recognizes does not consider ActionController::RoutingError an
23
- # assertion failure, so we have to capture that and Assertion here.
24
- match_unless_raises ActiveSupport::TestCase::Assertion, ActionController::RoutingError do
25
- path, query = *verb_to_path_map.values.first.split('?')
26
- @scope.assert_recognizes(
27
- @expected,
28
- {:method => verb_to_path_map.keys.first, :path => path},
29
- Rack::Utils::parse_nested_query(query)
30
- )
31
- end
32
- end
35
+ def failure_message
36
+ rescued_exception.message
37
+ end
33
38
 
34
- def failure_message
35
- rescued_exception.message
36
- end
39
+ def failure_message_when_negated
40
+ "expected #{@actual.inspect} not to route to #{@expected.inspect}"
41
+ end
37
42
 
38
- def failure_message_when_negated
39
- "expected #{@actual.inspect} not to route to #{@expected.inspect}"
40
- end
41
-
42
- def description
43
- "route #{@actual.inspect} to #{@expected.inspect}"
44
- end
45
- end
43
+ def description
44
+ "route #{@actual.inspect} to #{@expected.inspect}"
45
+ end
46
+ end
46
47
 
47
- # Delegates to `assert_recognizes`. Supports short-hand controller/action
48
- # declarations (e.g. `"controller#action"`).
49
- #
50
- # @example
51
- #
52
- # expect(:get => "/things/special").to route_to(
53
- # :controller => "things",
54
- # :action => "special"
55
- # )
56
- #
57
- # expect(:get => "/things/special").to route_to("things#special")
58
- #
59
- # @see http://api.rubyonrails.org/classes/ActionDispatch/Assertions/RoutingAssertions.html#method-i-assert_recognizes
60
- def route_to(*expected)
61
- RouteToMatcher.new(self, *expected)
62
- end
48
+ # Delegates to `assert_recognizes`. Supports short-hand controller/action
49
+ # declarations (e.g. `"controller#action"`).
50
+ #
51
+ # @example
52
+ #
53
+ # expect(get: "/things/special").to route_to(
54
+ # controller: "things",
55
+ # action: "special"
56
+ # )
57
+ #
58
+ # expect(get: "/things/special").to route_to("things#special")
59
+ #
60
+ # @see https://api.rubyonrails.org/classes/ActionDispatch/Assertions/RoutingAssertions.html#method-i-assert_recognizes
61
+ def route_to(*expected)
62
+ RouteToMatcher.new(self, *expected)
63
+ end
63
64
 
64
- # @private
65
- class BeRoutableMatcher < RSpec::Matchers::BuiltIn::BaseMatcher
65
+ # @private
66
+ class BeRoutableMatcher < RSpec::Rails::Matchers::BaseMatcher
67
+ def initialize(scope)
68
+ @scope = scope
69
+ end
66
70
 
67
- def initialize(scope)
68
- @scope = scope
69
- end
71
+ def matches?(path)
72
+ @actual = path
73
+ match_unless_raises ActionController::RoutingError do
74
+ @routing_options = @scope.routes.recognize_path(
75
+ path.values.first, method: path.keys.first
76
+ )
77
+ end
78
+ end
70
79
 
71
- def matches?(path)
72
- @actual = path
73
- match_unless_raises ActionController::RoutingError do
74
- @routing_options = @scope.routes.recognize_path(
75
- path.values.first, :method => path.keys.first
76
- )
77
- end
78
- end
80
+ def failure_message
81
+ "expected #{@actual.inspect} to be routable"
82
+ end
79
83
 
80
- def failure_message
81
- "expected #{@actual.inspect} to be routable"
82
- end
84
+ def failure_message_when_negated
85
+ "expected #{@actual.inspect} not to be routable, but it routes to #{@routing_options.inspect}"
86
+ end
83
87
 
84
- def failure_message_when_negated
85
- "expected #{@actual.inspect} not to be routable, but it routes to #{@routing_options.inspect}"
86
- end
87
- end
88
+ def description
89
+ "be routable"
90
+ end
91
+ end
88
92
 
89
- # Passes if the route expression is recognized by the Rails router based on
90
- # the declarations in `config/routes.rb`. Delegates to
91
- # `RouteSet#recognize_path`.
92
- #
93
- # @example You can use route helpers provided by rspec-rails.
94
- # expect(:get => "/a/path").to be_routable
95
- # expect(:post => "/another/path").to be_routable
96
- # expect(:put => "/yet/another/path").to be_routable
97
- def be_routable
98
- BeRoutableMatcher.new(self)
99
- end
93
+ # Passes if the route expression is recognized by the Rails router based on
94
+ # the declarations in `config/routes.rb`. Delegates to
95
+ # `RouteSet#recognize_path`.
96
+ #
97
+ # @example You can use route helpers provided by rspec-rails.
98
+ # expect(get: "/a/path").to be_routable
99
+ # expect(post: "/another/path").to be_routable
100
+ # expect(put: "/yet/another/path").to be_routable
101
+ def be_routable
102
+ BeRoutableMatcher.new(self)
103
+ end
100
104
 
101
- # Helpers for matching different route types.
102
- module RouteHelpers
103
- # @!method get
104
- # @!method post
105
- # @!method put
106
- # @!method patch
107
- # @!method delete
108
- # @!method options
109
- # @!method head
110
- #
111
- # Shorthand method for matching this type of route.
112
- %w(get post put patch delete options head).each do |method|
113
- define_method method do |path|
114
- { method.to_sym => path }
105
+ # Helpers for matching different route types.
106
+ module RouteHelpers
107
+ # @!method get
108
+ # @!method post
109
+ # @!method put
110
+ # @!method patch
111
+ # @!method delete
112
+ # @!method options
113
+ # @!method head
114
+ #
115
+ # Shorthand method for matching this type of route.
116
+ %w[get post put patch delete options head].each do |method|
117
+ define_method method do |path|
118
+ { method.to_sym => path }
119
+ end
120
+ end
115
121
  end
116
122
  end
117
123
  end
@@ -0,0 +1,122 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RSpec
4
+ module Rails
5
+ module Matchers
6
+ # @api private
7
+ #
8
+ # Matcher class for `send_email`. Should not be instantiated directly.
9
+ #
10
+ # @see RSpec::Rails::Matchers#send_email
11
+ class SendEmail < RSpec::Rails::Matchers::BaseMatcher
12
+ # @api private
13
+ # Define the email attributes that should be included in the inspection output.
14
+ INSPECT_EMAIL_ATTRIBUTES = %i[subject from to cc bcc].freeze
15
+
16
+ def initialize(criteria)
17
+ @criteria = criteria
18
+ end
19
+
20
+ # @api private
21
+ def supports_value_expectations?
22
+ false
23
+ end
24
+
25
+ # @api private
26
+ def supports_block_expectations?
27
+ true
28
+ end
29
+
30
+ def matches?(block)
31
+ define_matched_emails(block)
32
+
33
+ @matched_emails.one?
34
+ end
35
+
36
+ # @api private
37
+ # @return [String]
38
+ def failure_message
39
+ result =
40
+ if multiple_match?
41
+ "More than 1 matching emails were sent."
42
+ else
43
+ "No matching emails were sent."
44
+ end
45
+ "#{result}#{sent_emails_message}"
46
+ end
47
+
48
+ # @api private
49
+ # @return [String]
50
+ def failure_message_when_negated
51
+ "Expected not to send an email but it was sent."
52
+ end
53
+
54
+ private
55
+
56
+ def diffable?
57
+ true
58
+ end
59
+
60
+ def deliveries
61
+ ActionMailer::Base.deliveries
62
+ end
63
+
64
+ def define_matched_emails(block)
65
+ before = deliveries.dup
66
+
67
+ block.call
68
+
69
+ after = deliveries
70
+
71
+ @diff = after - before
72
+ @matched_emails = @diff.select(&method(:matched_email?))
73
+ end
74
+
75
+ def matched_email?(email)
76
+ @criteria.all? do |attr, value|
77
+ expected =
78
+ case attr
79
+ when :to, :from, :cc, :bcc then Array(value)
80
+ else
81
+ value
82
+ end
83
+
84
+ values_match?(expected, email.public_send(attr))
85
+ end
86
+ end
87
+
88
+ def multiple_match?
89
+ @matched_emails.many?
90
+ end
91
+
92
+ def sent_emails_message
93
+ if @diff.empty?
94
+ "\n\nThere were no any emails sent inside the expectation block."
95
+ else
96
+ sent_emails =
97
+ @diff.map do |email|
98
+ inspected = INSPECT_EMAIL_ATTRIBUTES.map { |attr| "#{attr}: #{email.public_send(attr)}" }.join(", ")
99
+ "- #{inspected}"
100
+ end.join("\n")
101
+ "\n\nThe following emails were sent:\n#{sent_emails}"
102
+ end
103
+ end
104
+ end
105
+
106
+ # @api public
107
+ # Check email sending with specific parameters.
108
+ #
109
+ # @example Positive expectation
110
+ # expect { action }.to send_email
111
+ #
112
+ # @example Negative expectations
113
+ # expect { action }.not_to send_email
114
+ #
115
+ # @example More precise expectation with attributes to match
116
+ # expect { action }.to send_email(to: 'test@example.com', subject: 'Confirm email')
117
+ def send_email(criteria = {})
118
+ SendEmail.new(criteria)
119
+ end
120
+ end
121
+ end
122
+ end
@@ -1,22 +1,17 @@
1
1
  require 'rspec/core/warnings'
2
2
  require 'rspec/expectations'
3
+ require 'rspec/rails/feature_check'
3
4
 
4
- module RSpec::Rails
5
- module Matchers
6
- end
7
- end
8
-
9
- begin
10
- require 'test/unit/assertionfailederror'
11
- rescue LoadError
12
- module Test
13
- module Unit
14
- class AssertionFailedError < StandardError
15
- end
5
+ module RSpec
6
+ module Rails
7
+ # @api public
8
+ # Container module for Rails specific matchers.
9
+ module Matchers
16
10
  end
17
11
  end
18
12
  end
19
13
 
14
+ require 'rspec/rails/matchers/base_matcher'
20
15
  require 'rspec/rails/matchers/have_rendered'
21
16
  require 'rspec/rails/matchers/redirect_to'
22
17
  require 'rspec/rails/matchers/routing_matchers'
@@ -25,3 +20,17 @@ require 'rspec/rails/matchers/be_a_new'
25
20
  require 'rspec/rails/matchers/relation_match_array'
26
21
  require 'rspec/rails/matchers/be_valid'
27
22
  require 'rspec/rails/matchers/have_http_status'
23
+ require 'rspec/rails/matchers/send_email'
24
+
25
+ if RSpec::Rails::FeatureCheck.has_active_job?
26
+ require 'rspec/rails/matchers/active_job'
27
+ require 'rspec/rails/matchers/have_enqueued_mail'
28
+ end
29
+
30
+ if RSpec::Rails::FeatureCheck.has_action_cable_testing?
31
+ require 'rspec/rails/matchers/action_cable'
32
+ end
33
+
34
+ if RSpec::Rails::FeatureCheck.has_action_mailbox?
35
+ require 'rspec/rails/matchers/action_mailbox'
36
+ end
@@ -3,19 +3,21 @@ if default = Rake.application.instance_variable_get('@tasks')['default']
3
3
  default.prerequisites.delete('test')
4
4
  end
5
5
 
6
- task :default => :spec
6
+ task default: :spec
7
7
 
8
- task :stats => "spec:statsetup"
8
+ if ::Rails::VERSION::STRING < "8.0.0"
9
+ task stats: "spec:statsetup"
10
+ end
9
11
 
10
12
  desc "Run all specs in spec directory (excluding plugin specs)"
11
- RSpec::Core::RakeTask.new(:spec => "spec:prepare")
13
+ RSpec::Core::RakeTask.new(spec: "spec:prepare")
12
14
 
13
15
  namespace :spec do
14
16
  types = begin
15
- dirs = Dir['./spec/**/*_spec.rb'].
16
- map { |f| f.sub(/^\.\/(spec\/\w+)\/.*/, '\\1') }.
17
- uniq.
18
- select { |f| File.directory?(f) }
17
+ dirs = Dir['./spec/**/*_spec.rb']
18
+ .map { |f| f.sub(/^\.\/(spec\/\w+)\/.*/, '\\1') }
19
+ .uniq
20
+ .select { |f| File.directory?(f) }
19
21
  Hash[dirs.map { |d| [d.split('/').last, d] }]
20
22
  end
21
23
 
@@ -35,16 +37,6 @@ namespace :spec do
35
37
  end
36
38
  end
37
39
 
38
- # RCov task only enabled for Ruby 1.8
39
- if RUBY_VERSION < '1.9'
40
- desc "Run all specs with rcov"
41
- RSpec::Core::RakeTask.new(:rcov => "spec:prepare") do |t|
42
- t.rcov = true
43
- t.pattern = "./spec/**/*_spec.rb"
44
- t.rcov_opts = '--exclude /gems/,/Library/,/usr/,lib/tasks,.bundle,config,/lib/rspec/,/lib/rspec-,spec'
45
- end
46
- end
47
-
48
40
  task :statsetup do
49
41
  require 'rails/code_statistics'
50
42
  types.each do |type, dir|
@@ -9,25 +9,24 @@ rescue LoadError
9
9
  end
10
10
 
11
11
  if defined?(Capybara)
12
- require 'rspec/support/version_checker'
13
- RSpec::Support::VersionChecker.new('capybara', Capybara::VERSION, '2.2.0').check_version!
14
-
15
12
  RSpec.configure do |c|
16
13
  if defined?(Capybara::DSL)
17
- c.include Capybara::DSL, :type => :feature
14
+ c.include Capybara::DSL, type: :feature
15
+ c.include Capybara::DSL, type: :system
18
16
  end
19
17
 
20
18
  if defined?(Capybara::RSpecMatchers)
21
- c.include Capybara::RSpecMatchers, :type => :view
22
- c.include Capybara::RSpecMatchers, :type => :helper
23
- c.include Capybara::RSpecMatchers, :type => :mailer
24
- c.include Capybara::RSpecMatchers, :type => :controller
25
- c.include Capybara::RSpecMatchers, :type => :feature
19
+ c.include Capybara::RSpecMatchers, type: :view
20
+ c.include Capybara::RSpecMatchers, type: :helper
21
+ c.include Capybara::RSpecMatchers, type: :mailer
22
+ c.include Capybara::RSpecMatchers, type: :controller
23
+ c.include Capybara::RSpecMatchers, type: :feature
24
+ c.include Capybara::RSpecMatchers, type: :system
26
25
  end
27
26
 
28
27
  unless defined?(Capybara::RSpecMatchers) || defined?(Capybara::DSL)
29
- c.include Capybara, :type => :request
30
- c.include Capybara, :type => :controller
28
+ c.include Capybara, type: :request
29
+ c.include Capybara, type: :controller
31
30
  end
32
31
  end
33
32
  end
@@ -3,7 +3,7 @@ module RSpec
3
3
  # Version information for RSpec Rails.
4
4
  module Version
5
5
  # Current version of RSpec Rails, in semantic versioning format.
6
- STRING = '3.0.2'
6
+ STRING = '7.1.1'
7
7
  end
8
8
  end
9
9
  end