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.
- checksums.yaml +5 -5
- checksums.yaml.gz.sig +0 -0
- data/.document +1 -1
- data/.yardopts +3 -1
- data/Capybara.md +6 -55
- data/Changelog.md +805 -47
- data/{License.txt → LICENSE.md} +5 -3
- data/README.md +278 -444
- data/lib/generators/rspec/channel/channel_generator.rb +12 -0
- data/lib/generators/rspec/{observer/templates/observer_spec.rb → channel/templates/channel_spec.rb.erb} +1 -1
- data/lib/generators/rspec/controller/controller_generator.rb +24 -7
- data/lib/generators/rspec/controller/templates/controller_spec.rb +3 -3
- data/lib/generators/rspec/controller/templates/request_spec.rb +19 -0
- data/lib/generators/rspec/controller/templates/routing_spec.rb +13 -0
- data/lib/generators/rspec/controller/templates/view_spec.rb +1 -1
- data/lib/generators/rspec/feature/feature_generator.rb +15 -2
- data/lib/generators/rspec/feature/templates/feature_singular_spec.rb +5 -0
- data/lib/generators/rspec/feature/templates/feature_spec.rb +1 -1
- data/lib/generators/rspec/generator/generator_generator.rb +24 -0
- data/lib/generators/rspec/generator/templates/generator_spec.rb +5 -0
- data/lib/generators/rspec/helper/helper_generator.rb +2 -2
- data/lib/generators/rspec/helper/templates/helper_spec.rb +1 -1
- data/lib/generators/rspec/install/install_generator.rb +41 -7
- data/lib/generators/rspec/install/templates/spec/rails_helper.rb +63 -22
- data/lib/generators/rspec/job/job_generator.rb +13 -0
- data/lib/generators/rspec/job/templates/job_spec.rb.erb +7 -0
- data/lib/generators/rspec/mailbox/mailbox_generator.rb +14 -0
- data/lib/generators/rspec/mailbox/templates/mailbox_spec.rb.erb +7 -0
- data/lib/generators/rspec/mailer/mailer_generator.rb +12 -3
- data/lib/generators/rspec/mailer/templates/mailer_spec.rb +2 -2
- data/lib/generators/rspec/mailer/templates/preview.rb +13 -0
- data/lib/generators/rspec/model/model_generator.rb +20 -6
- data/lib/generators/rspec/model/templates/fixtures.yml +1 -1
- data/lib/generators/rspec/model/templates/model_spec.rb +1 -1
- data/lib/generators/rspec/request/request_generator.rb +17 -0
- data/lib/generators/rspec/request/templates/request_spec.rb +10 -0
- data/lib/generators/rspec/scaffold/scaffold_generator.rb +90 -113
- data/lib/generators/rspec/scaffold/templates/api_controller_spec.rb +129 -0
- data/lib/generators/rspec/scaffold/templates/api_request_spec.rb +131 -0
- data/lib/generators/rspec/scaffold/templates/controller_spec.rb +46 -64
- data/lib/generators/rspec/scaffold/templates/edit_spec.rb +11 -7
- data/lib/generators/rspec/scaffold/templates/index_spec.rb +4 -3
- data/lib/generators/rspec/scaffold/templates/new_spec.rb +4 -4
- data/lib/generators/rspec/scaffold/templates/request_spec.rb +138 -0
- data/lib/generators/rspec/scaffold/templates/routing_spec.rb +18 -11
- data/lib/generators/rspec/scaffold/templates/show_spec.rb +3 -3
- data/lib/generators/rspec/system/system_generator.rb +24 -0
- data/lib/generators/rspec/system/templates/system_spec.rb +9 -0
- data/lib/generators/rspec/view/templates/view_spec.rb +1 -1
- data/lib/generators/rspec/view/view_generator.rb +4 -4
- data/lib/generators/rspec.rb +30 -11
- data/lib/rspec/rails/active_record.rb +25 -0
- data/lib/rspec/rails/adapters.rb +46 -29
- data/lib/rspec/rails/configuration.rb +165 -41
- data/lib/rspec/rails/example/channel_example_group.rb +93 -0
- data/lib/rspec/rails/example/controller_example_group.rb +185 -149
- data/lib/rspec/rails/example/feature_example_group.rb +43 -23
- data/lib/rspec/rails/example/helper_example_group.rb +28 -25
- data/lib/rspec/rails/example/job_example_group.rb +23 -0
- data/lib/rspec/rails/example/mailbox_example_group.rb +80 -0
- data/lib/rspec/rails/example/mailer_example_group.rb +27 -22
- data/lib/rspec/rails/example/model_example_group.rb +9 -6
- data/lib/rspec/rails/example/rails_example_group.rb +9 -2
- data/lib/rspec/rails/example/request_example_group.rb +21 -17
- data/lib/rspec/rails/example/routing_example_group.rb +47 -39
- data/lib/rspec/rails/example/system_example_group.rb +180 -0
- data/lib/rspec/rails/example/view_example_group.rb +179 -134
- data/lib/rspec/rails/example.rb +4 -0
- data/lib/rspec/rails/extensions/active_record/proxy.rb +5 -11
- data/lib/rspec/rails/feature_check.rb +51 -0
- data/lib/rspec/rails/file_fixture_support.rb +18 -0
- data/lib/rspec/rails/fixture_file_upload_support.rb +45 -0
- data/lib/rspec/rails/fixture_support.rb +70 -14
- data/lib/rspec/rails/matchers/action_cable/have_broadcasted_to.rb +180 -0
- data/lib/rspec/rails/matchers/action_cable/have_streams.rb +58 -0
- data/lib/rspec/rails/matchers/action_cable.rb +70 -0
- data/lib/rspec/rails/matchers/action_mailbox.rb +73 -0
- data/lib/rspec/rails/matchers/active_job.rb +526 -0
- data/lib/rspec/rails/matchers/base_matcher.rb +179 -0
- data/lib/rspec/rails/matchers/be_a_new.rb +70 -64
- data/lib/rspec/rails/matchers/be_new_record.rb +25 -20
- data/lib/rspec/rails/matchers/be_valid.rb +39 -34
- data/lib/rspec/rails/matchers/have_enqueued_mail.rb +259 -0
- data/lib/rspec/rails/matchers/have_http_status.rb +359 -333
- data/lib/rspec/rails/matchers/have_rendered.rb +55 -32
- data/lib/rspec/rails/matchers/redirect_to.rb +30 -27
- data/lib/rspec/rails/matchers/relation_match_array.rb +1 -1
- data/lib/rspec/rails/matchers/routing_matchers.rb +107 -101
- data/lib/rspec/rails/matchers/send_email.rb +122 -0
- data/lib/rspec/rails/matchers.rb +21 -12
- data/lib/rspec/rails/tasks/rspec.rake +9 -17
- data/lib/rspec/rails/vendor/capybara.rb +10 -11
- data/lib/rspec/rails/version.rb +1 -1
- data/lib/rspec/rails/view_assigns.rb +1 -20
- data/lib/rspec/rails/view_path_builder.rb +29 -0
- data/lib/rspec/rails/view_rendering.rb +89 -27
- data/lib/rspec/rails/view_spec_methods.rb +56 -0
- data/lib/rspec/rails.rb +9 -1
- data/lib/rspec-rails.rb +83 -3
- data.tar.gz.sig +0 -0
- metadata +108 -78
- metadata.gz.sig +3 -2
- data/lib/generators/rspec/integration/integration_generator.rb +0 -17
- data/lib/generators/rspec/integration/templates/request_spec.rb +0 -10
- data/lib/generators/rspec/observer/observer_generator.rb +0 -13
@@ -1,41 +1,64 @@
|
|
1
|
-
module RSpec
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
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
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
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
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
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
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
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
|
-
|
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
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
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
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
13
|
+
def matches?(_)
|
14
|
+
match_unless_raises ActiveSupport::TestCase::Assertion do
|
15
|
+
@scope.assert_redirected_to(@expected)
|
16
|
+
end
|
17
|
+
end
|
11
18
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
end
|
16
|
-
end
|
19
|
+
def failure_message
|
20
|
+
rescued_exception.message
|
21
|
+
end
|
17
22
|
|
18
|
-
|
19
|
-
|
20
|
-
|
23
|
+
def failure_message_when_negated
|
24
|
+
"expected not to redirect to #{@expected.inspect}, but did"
|
25
|
+
end
|
26
|
+
end
|
21
27
|
|
22
|
-
|
23
|
-
|
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
|
2
|
-
|
3
|
-
|
4
|
-
|
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
|
-
|
7
|
-
|
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
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
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
|
-
|
21
|
-
|
22
|
-
|
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
|
-
|
35
|
-
|
36
|
-
|
39
|
+
def failure_message_when_negated
|
40
|
+
"expected #{@actual.inspect} not to route to #{@expected.inspect}"
|
41
|
+
end
|
37
42
|
|
38
|
-
|
39
|
-
|
40
|
-
|
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
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
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
|
-
|
65
|
-
|
65
|
+
# @private
|
66
|
+
class BeRoutableMatcher < RSpec::Rails::Matchers::BaseMatcher
|
67
|
+
def initialize(scope)
|
68
|
+
@scope = scope
|
69
|
+
end
|
66
70
|
|
67
|
-
|
68
|
-
|
69
|
-
|
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
|
-
|
72
|
-
|
73
|
-
|
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
|
-
|
81
|
-
|
82
|
-
|
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
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
+
def description
|
89
|
+
"be routable"
|
90
|
+
end
|
91
|
+
end
|
88
92
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
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
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
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
|
data/lib/rspec/rails/matchers.rb
CHANGED
@@ -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
|
5
|
-
module
|
6
|
-
|
7
|
-
|
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 :
|
6
|
+
task default: :spec
|
7
7
|
|
8
|
-
|
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(:
|
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, :
|
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, :
|
22
|
-
c.include Capybara::RSpecMatchers, :
|
23
|
-
c.include Capybara::RSpecMatchers, :
|
24
|
-
c.include Capybara::RSpecMatchers, :
|
25
|
-
c.include Capybara::RSpecMatchers, :
|
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, :
|
30
|
-
c.include Capybara, :
|
28
|
+
c.include Capybara, type: :request
|
29
|
+
c.include Capybara, type: :controller
|
31
30
|
end
|
32
31
|
end
|
33
32
|
end
|