rspec-rails 4.0.0.beta4 → 4.1.0

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 (36) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/Capybara.md +5 -54
  5. data/Changelog.md +72 -37
  6. data/README.md +23 -18
  7. data/lib/generators/rspec/controller/controller_generator.rb +1 -1
  8. data/lib/generators/rspec/controller/templates/request_spec.rb +6 -1
  9. data/lib/generators/rspec/{generators → generator}/generator_generator.rb +2 -2
  10. data/lib/generators/rspec/{generators → generator}/templates/generator_spec.rb +0 -0
  11. data/lib/generators/rspec/install/templates/spec/rails_helper.rb +15 -1
  12. data/lib/generators/rspec/scaffold/scaffold_generator.rb +18 -10
  13. data/lib/generators/rspec/scaffold/templates/api_request_spec.rb +131 -0
  14. data/lib/generators/rspec/scaffold/templates/request_spec.rb +137 -0
  15. data/lib/rspec-rails.rb +2 -2
  16. data/lib/rspec/rails/adapters.rb +3 -3
  17. data/lib/rspec/rails/configuration.rb +40 -4
  18. data/lib/rspec/rails/example/channel_example_group.rb +2 -2
  19. data/lib/rspec/rails/example/feature_example_group.rb +5 -23
  20. data/lib/rspec/rails/example/mailbox_example_group.rb +1 -1
  21. data/lib/rspec/rails/example/mailer_example_group.rb +2 -2
  22. data/lib/rspec/rails/example/system_example_group.rb +8 -4
  23. data/lib/rspec/rails/example/view_example_group.rb +1 -1
  24. data/lib/rspec/rails/extensions/active_record/proxy.rb +4 -1
  25. data/lib/rspec/rails/fixture_file_upload_support.rb +7 -12
  26. data/lib/rspec/rails/fixture_support.rb +38 -27
  27. data/lib/rspec/rails/matchers/action_cable/have_broadcasted_to.rb +3 -3
  28. data/lib/rspec/rails/matchers/active_job.rb +31 -5
  29. data/lib/rspec/rails/matchers/have_enqueued_mail.rb +4 -4
  30. data/lib/rspec/rails/matchers/relation_match_array.rb +1 -1
  31. data/lib/rspec/rails/matchers/routing_matchers.rb +2 -2
  32. data/lib/rspec/rails/tasks/rspec.rake +4 -4
  33. data/lib/rspec/rails/vendor/capybara.rb +0 -5
  34. data/lib/rspec/rails/version.rb +1 -1
  35. metadata +30 -28
  36. metadata.gz.sig +0 -0
@@ -0,0 +1,131 @@
1
+ require 'rails_helper'
2
+
3
+ # This spec was generated by rspec-rails when you ran the scaffold generator.
4
+ # It demonstrates how one might use RSpec to test the controller code that
5
+ # was generated by Rails when you ran the scaffold generator.
6
+ #
7
+ # It assumes that the implementation code is generated by the rails scaffold
8
+ # generator. If you are using any extension libraries to generate different
9
+ # controller code, this generated spec may or may not pass.
10
+ #
11
+ # It only uses APIs available in rails and/or rspec-rails. There are a number
12
+ # of tools you can use to make these specs even more expressive, but we're
13
+ # sticking to rails and rspec-rails APIs to keep things simple and stable.
14
+
15
+ <% module_namespacing do -%>
16
+ RSpec.describe "/<%= name.underscore.pluralize %>", <%= type_metatag(:request) %> do
17
+ # This should return the minimal set of attributes required to create a valid
18
+ # <%= class_name %>. As you add validations to <%= class_name %>, be sure to
19
+ # adjust the attributes here as well.
20
+ let(:valid_attributes) {
21
+ skip("Add a hash of attributes valid for your model")
22
+ }
23
+
24
+ let(:invalid_attributes) {
25
+ skip("Add a hash of attributes invalid for your model")
26
+ }
27
+
28
+ # This should return the minimal set of values that should be in the headers
29
+ # in order to pass any filters (e.g. authentication) defined in
30
+ # <%= controller_class_name %>Controller, or in your router and rack
31
+ # middleware. Be sure to keep this updated too.
32
+ let(:valid_headers) {
33
+ {}
34
+ }
35
+
36
+ <% unless options[:singleton] -%>
37
+ describe "GET /index" do
38
+ it "renders a successful response" do
39
+ <%= class_name %>.create! valid_attributes
40
+ get <%= index_helper %>_url, headers: valid_headers, as: :json
41
+ expect(response).to be_successful
42
+ end
43
+ end
44
+ <% end -%>
45
+
46
+ describe "GET /show" do
47
+ it "renders a successful response" do
48
+ <%= file_name %> = <%= class_name %>.create! valid_attributes
49
+ get <%= show_helper.tr('@', '') %>, as: :json
50
+ expect(response).to be_successful
51
+ end
52
+ end
53
+
54
+ describe "POST /create" do
55
+ context "with valid parameters" do
56
+ it "creates a new <%= class_name %>" do
57
+ expect {
58
+ post <%= index_helper %>_url,
59
+ params: { <%= ns_file_name %>: valid_attributes }, headers: valid_headers, as: :json
60
+ }.to change(<%= class_name %>, :count).by(1)
61
+ end
62
+
63
+ it "renders a JSON response with the new <%= ns_file_name %>" do
64
+ post <%= index_helper %>_url,
65
+ params: { <%= ns_file_name %>: valid_attributes }, headers: valid_headers, as: :json
66
+ expect(response).to have_http_status(:created)
67
+ expect(response.content_type).to match(a_string_including("application/json"))
68
+ end
69
+ end
70
+
71
+ context "with invalid parameters" do
72
+ it "does not create a new <%= class_name %>" do
73
+ expect {
74
+ post <%= index_helper %>_url,
75
+ params: { <%= ns_file_name %>: invalid_attributes }, as: :json
76
+ }.to change(<%= class_name %>, :count).by(0)
77
+ end
78
+
79
+ it "renders a JSON response with errors for the new <%= ns_file_name %>" do
80
+ post <%= index_helper %>_url,
81
+ params: { <%= ns_file_name %>: invalid_attributes }, headers: valid_headers, as: :json
82
+ expect(response).to have_http_status(:unprocessable_entity)
83
+ expect(response.content_type).to eq("application/json")
84
+ end
85
+ end
86
+ end
87
+
88
+ describe "PATCH /update" do
89
+ context "with valid parameters" do
90
+ let(:new_attributes) {
91
+ skip("Add a hash of attributes valid for your model")
92
+ }
93
+
94
+ it "updates the requested <%= ns_file_name %>" do
95
+ <%= file_name %> = <%= class_name %>.create! valid_attributes
96
+ patch <%= show_helper.tr('@', '') %>,
97
+ params: { <%= singular_table_name %>: new_attributes }, headers: valid_headers, as: :json
98
+ <%= file_name %>.reload
99
+ skip("Add assertions for updated state")
100
+ end
101
+
102
+ it "renders a JSON response with the <%= ns_file_name %>" do
103
+ <%= file_name %> = <%= class_name %>.create! valid_attributes
104
+ patch <%= show_helper.tr('@', '') %>,
105
+ params: { <%= singular_table_name %>: new_attributes }, headers: valid_headers, as: :json
106
+ expect(response).to have_http_status(:ok)
107
+ expect(response.content_type).to match(a_string_including("application/json"))
108
+ end
109
+ end
110
+
111
+ context "with invalid parameters" do
112
+ it "renders a JSON response with errors for the <%= ns_file_name %>" do
113
+ <%= file_name %> = <%= class_name %>.create! valid_attributes
114
+ patch <%= show_helper.tr('@', '') %>,
115
+ params: { <%= singular_table_name %>: invalid_attributes }, headers: valid_headers, as: :json
116
+ expect(response).to have_http_status(:unprocessable_entity)
117
+ expect(response.content_type).to eq("application/json")
118
+ end
119
+ end
120
+ end
121
+
122
+ describe "DELETE /destroy" do
123
+ it "destroys the requested <%= ns_file_name %>" do
124
+ <%= file_name %> = <%= class_name %>.create! valid_attributes
125
+ expect {
126
+ delete <%= show_helper.tr('@', '') %>, headers: valid_headers, as: :json
127
+ }.to change(<%= class_name %>, :count).by(-1)
128
+ end
129
+ end
130
+ end
131
+ <% end -%>
@@ -0,0 +1,137 @@
1
+ require 'rails_helper'
2
+
3
+ # This spec was generated by rspec-rails when you ran the scaffold generator.
4
+ # It demonstrates how one might use RSpec to test the controller code that
5
+ # was generated by Rails when you ran the scaffold generator.
6
+ #
7
+ # It assumes that the implementation code is generated by the rails scaffold
8
+ # generator. If you are using any extension libraries to generate different
9
+ # controller code, this generated spec may or may not pass.
10
+ #
11
+ # It only uses APIs available in rails and/or rspec-rails. There are a number
12
+ # of tools you can use to make these specs even more expressive, but we're
13
+ # sticking to rails and rspec-rails APIs to keep things simple and stable.
14
+
15
+ <% module_namespacing do -%>
16
+ RSpec.describe "/<%= name.underscore.pluralize %>", <%= type_metatag(:request) %> do
17
+ <% if mountable_engine? -%>
18
+ include Engine.routes.url_helpers
19
+ <% end -%>
20
+
21
+ # <%= class_name %>. As you add validations to <%= class_name %>, be sure to
22
+ # adjust the attributes here as well.
23
+ let(:valid_attributes) {
24
+ skip("Add a hash of attributes valid for your model")
25
+ }
26
+
27
+ let(:invalid_attributes) {
28
+ skip("Add a hash of attributes invalid for your model")
29
+ }
30
+
31
+ <% unless options[:singleton] -%>
32
+ describe "GET /index" do
33
+ it "renders a successful response" do
34
+ <%= class_name %>.create! valid_attributes
35
+ get <%= index_helper %>_url
36
+ expect(response).to be_successful
37
+ end
38
+ end
39
+ <% end -%>
40
+
41
+ describe "GET /show" do
42
+ it "renders a successful response" do
43
+ <%= file_name %> = <%= class_name %>.create! valid_attributes
44
+ get <%= show_helper.tr('@', '') %>
45
+ expect(response).to be_successful
46
+ end
47
+ end
48
+
49
+ describe "GET /new" do
50
+ it "renders a successful response" do
51
+ get <%= new_helper %>
52
+ expect(response).to be_successful
53
+ end
54
+ end
55
+
56
+ describe "GET /edit" do
57
+ it "render a successful response" do
58
+ <%= file_name %> = <%= class_name %>.create! valid_attributes
59
+ get <%= edit_helper.tr('@','') %>
60
+ expect(response).to be_successful
61
+ end
62
+ end
63
+
64
+ describe "POST /create" do
65
+ context "with valid parameters" do
66
+ it "creates a new <%= class_name %>" do
67
+ expect {
68
+ post <%= index_helper %>_url, params: { <%= ns_file_name %>: valid_attributes }
69
+ }.to change(<%= class_name %>, :count).by(1)
70
+ end
71
+
72
+ it "redirects to the created <%= ns_file_name %>" do
73
+ post <%= index_helper %>_url, params: { <%= ns_file_name %>: valid_attributes }
74
+ expect(response).to redirect_to(<%= show_helper.gsub("\@#{file_name}", class_name+".last") %>)
75
+ end
76
+ end
77
+
78
+ context "with invalid parameters" do
79
+ it "does not create a new <%= class_name %>" do
80
+ expect {
81
+ post <%= index_helper %>_url, params: { <%= ns_file_name %>: invalid_attributes }
82
+ }.to change(<%= class_name %>, :count).by(0)
83
+ end
84
+
85
+ it "renders a successful response (i.e. to display the 'new' template)" do
86
+ post <%= index_helper %>_url, params: { <%= ns_file_name %>: invalid_attributes }
87
+ expect(response).to be_successful
88
+ end
89
+ end
90
+ end
91
+
92
+ describe "PATCH /update" do
93
+ context "with valid parameters" do
94
+ let(:new_attributes) {
95
+ skip("Add a hash of attributes valid for your model")
96
+ }
97
+
98
+ it "updates the requested <%= ns_file_name %>" do
99
+ <%= file_name %> = <%= class_name %>.create! valid_attributes
100
+ patch <%= show_helper.tr('@', '') %>, params: { <%= singular_table_name %>: new_attributes }
101
+ <%= file_name %>.reload
102
+ skip("Add assertions for updated state")
103
+ end
104
+
105
+ it "redirects to the <%= ns_file_name %>" do
106
+ <%= file_name %> = <%= class_name %>.create! valid_attributes
107
+ patch <%= show_helper.tr('@', '') %>, params: { <%= singular_table_name %>: new_attributes }
108
+ <%= file_name %>.reload
109
+ expect(response).to redirect_to(<%= singular_table_name %>_url(<%= file_name %>))
110
+ end
111
+ end
112
+
113
+ context "with invalid parameters" do
114
+ it "renders a successful response (i.e. to display the 'edit' template)" do
115
+ <%= file_name %> = <%= class_name %>.create! valid_attributes
116
+ patch <%= show_helper.tr('@', '') %>, params: { <%= singular_table_name %>: invalid_attributes }
117
+ expect(response).to be_successful
118
+ end
119
+ end
120
+ end
121
+
122
+ describe "DELETE /destroy" do
123
+ it "destroys the requested <%= ns_file_name %>" do
124
+ <%= file_name %> = <%= class_name %>.create! valid_attributes
125
+ expect {
126
+ delete <%= show_helper.tr('@', '') %>
127
+ }.to change(<%= class_name %>, :count).by(-1)
128
+ end
129
+
130
+ it "redirects to the <%= table_name %> list" do
131
+ <%= file_name %> = <%= class_name %>.create! valid_attributes
132
+ delete <%= show_helper.tr('@', '') %>
133
+ expect(response).to redirect_to(<%= index_helper %>_url)
134
+ end
135
+ end
136
+ end
137
+ <% end -%>
data/lib/rspec-rails.rb CHANGED
@@ -31,8 +31,8 @@ module RSpec
31
31
  # sets the default for the `preview_path`
32
32
  initializer "rspec_rails.action_mailer",
33
33
  before: "action_mailer.set_configs" do |app|
34
- setup_preview_path(app)
35
- end
34
+ setup_preview_path(app)
35
+ end
36
36
 
37
37
  private
38
38
 
@@ -146,9 +146,9 @@ module RSpec
146
146
  # examples without exposing non-assertion methods in Test::Unit or
147
147
  # Minitest.
148
148
  def assertion_method_names
149
- ::RSpec::Rails::Assertions.
150
- public_instance_methods.
151
- select do |m|
149
+ ::RSpec::Rails::Assertions
150
+ .public_instance_methods
151
+ .select do |m|
152
152
  m.to_s =~ /^(assert|flunk|refute)/
153
153
  end
154
154
  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,
@@ -55,8 +56,7 @@ module RSpec
55
56
  end
56
57
 
57
58
  # @private
58
- # rubocop:disable Metrics/MethodLength
59
- def self.initialize_configuration(config)
59
+ def self.initialize_configuration(config) # rubocop:disable Metrics/MethodLength,Metrics/CyclomaticComplexity
60
60
  config.backtrace_exclusion_patterns << /vendor\//
61
61
  config.backtrace_exclusion_patterns << %r{lib/rspec/rails}
62
62
 
@@ -64,6 +64,7 @@ module RSpec
64
64
  config.add_setting :infer_base_class_for_anonymous_controllers, default: true
65
65
 
66
66
  # fixture support
67
+ config.add_setting :use_active_record, default: true
67
68
  config.add_setting :use_transactional_fixtures, alias_with: :use_transactional_examples
68
69
  config.add_setting :use_instantiated_fixtures
69
70
  config.add_setting :global_fixtures
@@ -105,7 +106,41 @@ module RSpec
105
106
  end
106
107
 
107
108
  def render_views?
108
- rendering_views
109
+ rendering_views?
110
+ end
111
+
112
+ undef :rendering_views? if respond_to?(:rendering_views?)
113
+ def rendering_views?
114
+ !!rendering_views
115
+ end
116
+
117
+ # Define boolean predicates rather than relying on rspec-core due
118
+ # to the bug fix in rspec/rspec-core#2736, note some of these
119
+ # predicates are a bit nonsensical, but they exist for backwards
120
+ # compatibility, we can tidy these up in `rspec-rails` 5.
121
+ undef :fixture_path? if respond_to?(:fixture_path?)
122
+ def fixture_path?
123
+ !!fixture_path
124
+ end
125
+
126
+ undef :global_fixtures? if respond_to?(:global_fixtures?)
127
+ def global_fixtures?
128
+ !!global_fixtures
129
+ end
130
+
131
+ undef :infer_base_class_for_anonymous_controllers? if respond_to?(:infer_base_class_for_anonymous_controllers?)
132
+ def infer_base_class_for_anonymous_controllers?
133
+ !!infer_base_class_for_anonymous_controllers
134
+ end
135
+
136
+ undef :use_instantiated_fixtures? if respond_to?(:use_instantiated_fixtures?)
137
+ def use_instantiated_fixtures?
138
+ !!use_instantiated_fixtures
139
+ end
140
+
141
+ undef :use_transactional_fixtures? if respond_to?(:use_transactional_fixtures?)
142
+ def use_transactional_fixtures?
143
+ !!use_transactional_fixtures
109
144
  end
110
145
 
111
146
  def infer_spec_type_from_file_location!
@@ -137,6 +172,7 @@ module RSpec
137
172
 
138
173
  if RSpec::Rails::FeatureCheck.has_action_mailer?
139
174
  config.include RSpec::Rails::MailerExampleGroup, type: :mailer
175
+ config.after { ActionMailer::Base.deliveries.clear }
140
176
  end
141
177
 
142
178
  if RSpec::Rails::FeatureCheck.has_active_job?
@@ -151,8 +187,8 @@ module RSpec
151
187
  config.include RSpec::Rails::MailboxExampleGroup, type: :mailbox
152
188
  end
153
189
  end
154
- # rubocop:enable Metrics/MethodLength
155
190
 
156
191
  initialize_configuration RSpec.configuration
157
192
  end
158
193
  end
194
+ # rubocop: enable Metrics/ModuleLength
@@ -34,7 +34,7 @@ if RSpec::Rails::FeatureCheck.has_action_cable_testing?
34
34
  next if klass <= ::ActionCable::Channel::Base
35
35
 
36
36
  raise "Described class is not a channel class.\n" \
37
- "Specify the channel class in the `describe` statement "\
37
+ "Specify the channel class in the `describe` statement " \
38
38
  "or set it manually using `tests MyChannelClass`"
39
39
  end
40
40
  end
@@ -45,7 +45,7 @@ if RSpec::Rails::FeatureCheck.has_action_cable_testing?
45
45
  next if klass <= ::ActionCable::Connection::Base
46
46
 
47
47
  raise "Described class is not a connection class.\n" \
48
- "Specify the connection class in the `describe` statement "\
48
+ "Specify the connection class in the `describe` statement " \
49
49
  "or set it manually using `tests MyConnectionClass`"
50
50
  end
51
51
  end
@@ -15,7 +15,9 @@ module RSpec
15
15
  include app.routes.url_helpers if app.routes.respond_to?(:url_helpers)
16
16
  include app.routes.mounted_helpers if app.routes.respond_to?(:mounted_helpers)
17
17
 
18
- default_url_options[:host] ||= ::RSpec::Rails::FeatureExampleGroup::DEFAULT_HOST
18
+ if respond_to?(:default_url_options)
19
+ default_url_options[:host] ||= ::RSpec::Rails::FeatureExampleGroup::DEFAULT_HOST
20
+ end
19
21
  end
20
22
  end
21
23
 
@@ -38,34 +40,14 @@ unless RSpec.respond_to?(:feature)
38
40
  capybara_feature: true,
39
41
  type: :feature,
40
42
  skip: <<-EOT.squish
41
- Feature specs require the Capybara (https://github.com/jnicklas/capybara)
42
- gem, version 2.2.0 or later. We recommend version 2.4.0 or later to avoid
43
- some deprecation warnings and have support for
44
- `config.expose_dsl_globally = false`.
43
+ Feature specs require the Capybara (https://github.com/teamcapybara/capybara)
44
+ gem, version 2.13.0 or later.
45
45
  EOT
46
46
  }
47
47
 
48
- # Capybara's monkey patching causes us to have to jump through some hoops
49
- top_level = self
50
- main_feature = nil
51
- if defined?(Capybara) && ::Capybara::VERSION.to_f < 2.4
52
- # Capybara 2.2 and 2.3 do not use `alias_example_xyz`
53
- opts[:skip] = <<-EOT.squish
54
- Capybara < 2.4.0 does not support RSpec's namespace or
55
- `config.expose_dsl_globally = false`. Upgrade to Capybara >= 2.4.0.
56
- EOT
57
- main_feature = top_level.method(:feature) if top_level.respond_to?(:feature)
58
- end
59
-
60
48
  RSpec.configure do |c|
61
- main_feature = nil unless c.expose_dsl_globally?
62
49
  c.alias_example_group_to :feature, opts
63
50
  c.alias_example_to :scenario
64
51
  c.alias_example_to :xscenario, skip: 'Temporarily skipped with xscenario'
65
52
  end
66
-
67
- # Due to load order issues and `config.expose_dsl_globally?` defaulting to
68
- # `true` we need to put Capybara's monkey patch method back. Otherwise,
69
- # app upgrades have a high likelyhood of having all feature specs skipped.
70
- top_level.define_singleton_method(:feature, &main_feature) if main_feature
71
53
  end
@@ -13,7 +13,7 @@ module RSpec
13
13
  def self.create_inbound_email(arg)
14
14
  case arg
15
15
  when Hash
16
- create_inbound_email_from_mail(arg)
16
+ create_inbound_email_from_mail(**arg)
17
17
  else
18
18
  create_inbound_email_from_source(arg.to_s)
19
19
  end