rails-controller-testing 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +7 -0
  2. data/Rakefile +18 -0
  3. data/lib/rails-controller-testing.rb +15 -0
  4. data/lib/rails/controller/testing/integration.rb +18 -0
  5. data/lib/rails/controller/testing/template_assertions.rb +192 -0
  6. data/lib/rails/controller/testing/test_process.rb +15 -0
  7. data/lib/rails/controller/testing/version.rb +7 -0
  8. data/test/controllers/assigns_test.rb +30 -0
  9. data/test/controllers/template_assertions_test.rb +214 -0
  10. data/test/dummy/README.rdoc +28 -0
  11. data/test/dummy/Rakefile +6 -0
  12. data/test/dummy/app/assets/javascripts/application.js +13 -0
  13. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  14. data/test/dummy/app/controllers/assigns_controller.rb +7 -0
  15. data/test/dummy/app/controllers/template_assertions_controller.rb +34 -0
  16. data/test/dummy/app/controllers/view_assigns_controller.rb +10 -0
  17. data/test/dummy/app/helpers/application_helper.rb +2 -0
  18. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  19. data/test/dummy/app/views/layouts/standard.html.erb +0 -0
  20. data/test/dummy/app/views/test/_directory/_partial_with_locales.html.erb +1 -0
  21. data/test/dummy/app/views/test/_layout_for_partial.html.erb +3 -0
  22. data/test/dummy/app/views/test/_partial.html.erb +0 -0
  23. data/test/dummy/app/views/test/_partial_for_use_in_layout.html.erb +1 -0
  24. data/test/dummy/app/views/test/calling_partial_with_layout.html.erb +1 -0
  25. data/test/dummy/app/views/test/hello/hello.html.erb +0 -0
  26. data/test/dummy/app/views/test/hello_world.html.erb +0 -0
  27. data/test/dummy/app/views/test/hello_world_with_partial.html.erb +1 -0
  28. data/test/dummy/app/views/test/render_partial_inside_directory.html.erb +1 -0
  29. data/test/dummy/app/views/test/render_two_partials.html.erb +2 -0
  30. data/test/dummy/bin/bundle +3 -0
  31. data/test/dummy/bin/rails +4 -0
  32. data/test/dummy/bin/rake +4 -0
  33. data/test/dummy/bin/setup +29 -0
  34. data/test/dummy/config.ru +4 -0
  35. data/test/dummy/config/application.rb +26 -0
  36. data/test/dummy/config/boot.rb +5 -0
  37. data/test/dummy/config/database.yml +25 -0
  38. data/test/dummy/config/environment.rb +5 -0
  39. data/test/dummy/config/environments/development.rb +41 -0
  40. data/test/dummy/config/environments/production.rb +79 -0
  41. data/test/dummy/config/environments/test.rb +42 -0
  42. data/test/dummy/config/initializers/assets.rb +11 -0
  43. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  44. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  45. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  46. data/test/dummy/config/initializers/inflections.rb +16 -0
  47. data/test/dummy/config/initializers/mime_types.rb +4 -0
  48. data/test/dummy/config/initializers/session_store.rb +3 -0
  49. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  50. data/test/dummy/config/locales/en.yml +23 -0
  51. data/test/dummy/config/routes.rb +57 -0
  52. data/test/dummy/config/secrets.yml +22 -0
  53. data/test/dummy/db/test.sqlite3 +0 -0
  54. data/test/dummy/log/test.log +33855 -0
  55. data/test/dummy/public/404.html +67 -0
  56. data/test/dummy/public/422.html +67 -0
  57. data/test/dummy/public/500.html +66 -0
  58. data/test/dummy/public/favicon.ico +0 -0
  59. data/test/helpers/template_assertions_test.rb +61 -0
  60. data/test/integration/template_assertions_test.rb +90 -0
  61. data/test/test_helper.rb +19 -0
  62. metadata +187 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b486570e7d0fa1e6cbd86cad49274c879bf19641
4
+ data.tar.gz: 9f4c782aa60594ab5972199e086f0bf3ddbeb144
5
+ SHA512:
6
+ metadata.gz: 35d62afcdc8d780b29b335504e3de0af159fbf4e70c2495a3ce74bfa396e91cbf23968bab6c0ad7e4825a24bc7eb4364582488cec0a4c0ef586943c8014ed8b8
7
+ data.tar.gz: d88b18199421f8140160327b8e0525382863f2c4470632a61e1b3801d8d5bcf7d7fbaeeab288bcdb04e277067fa0e2ccebd4f0c5c7d472398afe443ff99c7a30
@@ -0,0 +1,18 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ Bundler::GemHelper.install_tasks
8
+
9
+ require 'rake/testtask'
10
+
11
+ Rake::TestTask.new(:test) do |t|
12
+ t.libs << 'lib'
13
+ t.libs << 'test'
14
+ t.pattern = 'test/**/*_test.rb'
15
+ t.verbose = false
16
+ end
17
+
18
+ task default: :test
@@ -0,0 +1,15 @@
1
+ module Rails
2
+ module Controller
3
+ module Testing
4
+ autoload :TemplateAssertions, 'rails/controller/testing/template_assertions'
5
+ autoload :Integration, 'rails/controller/testing/integration'
6
+ autoload :TestProcess, 'rails/controller/testing/test_process'
7
+
8
+ extend ActiveSupport::Concern
9
+
10
+ include TemplateAssertions
11
+ include Integration
12
+ include TestProcess
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,18 @@
1
+ module Rails
2
+ module Controller
3
+ module Testing
4
+ module Integration
5
+ %w(
6
+ get post patch put head delete xml_http_request
7
+ xhr get_via_redirect post_via_redirect
8
+ ).each do |method|
9
+
10
+ define_method(method) do |*args|
11
+ reset_template_assertion
12
+ super(*args)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,192 @@
1
+ module Rails
2
+ module Controller
3
+ module Testing
4
+ module TemplateAssertions
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ setup :setup_subscriptions
9
+ teardown :teardown_subscriptions
10
+ end
11
+
12
+ RENDER_TEMPLATE_INSTANCE_VARIABLES = %w{partials templates layouts files}.freeze
13
+
14
+ def setup_subscriptions
15
+ RENDER_TEMPLATE_INSTANCE_VARIABLES.each do |instance_variable|
16
+ instance_variable_set("@_#{instance_variable}", Hash.new(0))
17
+ end
18
+
19
+ @_subscribers = []
20
+
21
+ @_subscribers << ActiveSupport::Notifications.subscribe("render_template.action_view") do |_name, _start, _finish, _id, payload|
22
+ path = payload[:layout]
23
+ if path
24
+ @_layouts[path] += 1
25
+ if path =~ /^layouts\/(.*)/
26
+ @_layouts[$1] += 1
27
+ end
28
+ end
29
+ end
30
+
31
+ @_subscribers << ActiveSupport::Notifications.subscribe("!render_template.action_view") do |_name, _start, _finish, _id, payload|
32
+ if virtual_path = payload[:virtual_path]
33
+ partial = virtual_path =~ /^.*\/_[^\/]*$/
34
+
35
+ if partial
36
+ @_partials[virtual_path] += 1
37
+ @_partials[virtual_path.split("/").last] += 1
38
+ end
39
+
40
+ @_templates[virtual_path] += 1
41
+ else
42
+ path = payload[:identifier]
43
+ if path
44
+ @_files[path] += 1
45
+ @_files[path.split("/").last] += 1
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ def teardown_subscriptions
52
+ @_subscribers.each do |subscriber|
53
+ ActiveSupport::Notifications.unsubscribe(subscriber)
54
+ end
55
+ end
56
+
57
+ def process(*args)
58
+ reset_template_assertion
59
+ super
60
+ end
61
+
62
+ def reset_template_assertion
63
+ RENDER_TEMPLATE_INSTANCE_VARIABLES.each do |instance_variable|
64
+ ivar_name = "@_#{instance_variable}"
65
+ if instance_variable_defined?(ivar_name)
66
+ instance_variable_get(ivar_name).clear
67
+ end
68
+ end
69
+ end
70
+
71
+ # Asserts that the request was rendered with the appropriate template file or partials.
72
+ #
73
+ # # assert that the "new" view template was rendered
74
+ # assert_template "new"
75
+ #
76
+ # # assert that the exact template "admin/posts/new" was rendered
77
+ # assert_template %r{\Aadmin/posts/new\Z}
78
+ #
79
+ # # assert that the layout 'admin' was rendered
80
+ # assert_template layout: 'admin'
81
+ # assert_template layout: 'layouts/admin'
82
+ # assert_template layout: :admin
83
+ #
84
+ # # assert that no layout was rendered
85
+ # assert_template layout: nil
86
+ # assert_template layout: false
87
+ #
88
+ # # assert that the "_customer" partial was rendered twice
89
+ # assert_template partial: '_customer', count: 2
90
+ #
91
+ # # assert that no partials were rendered
92
+ # assert_template partial: false
93
+ #
94
+ # # assert that a file was rendered
95
+ # assert_template file: "README.rdoc"
96
+ #
97
+ # # assert that no file was rendered
98
+ # assert_template file: nil
99
+ # assert_template file: false
100
+ #
101
+ # In a view test case, you can also assert that specific locals are passed
102
+ # to partials:
103
+ #
104
+ # # assert that the "_customer" partial was rendered with a specific object
105
+ # assert_template partial: '_customer', locals: { customer: @customer }
106
+ def assert_template(options = {}, message = nil)
107
+ # Force body to be read in case the template is being streamed.
108
+ response.body
109
+
110
+ case options
111
+ when NilClass, Regexp, String, Symbol
112
+ options = options.to_s if Symbol === options
113
+ rendered = @_templates
114
+ msg = message || sprintf("expecting <%s> but rendering with <%s>",
115
+ options.inspect, rendered.keys)
116
+ matches_template =
117
+ case options
118
+ when String
119
+ !options.empty? && rendered.any? do |t, num|
120
+ options_splited = options.split(File::SEPARATOR)
121
+ t_splited = t.split(File::SEPARATOR)
122
+ t_splited.last(options_splited.size) == options_splited
123
+ end
124
+ when Regexp
125
+ rendered.any? { |t,num| t.match(options) }
126
+ when NilClass
127
+ rendered.blank?
128
+ end
129
+ assert matches_template, msg
130
+ when Hash
131
+ options.assert_valid_keys(:layout, :partial, :locals, :count, :file)
132
+
133
+ if options.key?(:layout)
134
+ expected_layout = options[:layout]
135
+ msg = message || sprintf("expecting layout <%s> but action rendered <%s>",
136
+ expected_layout, @_layouts.keys)
137
+
138
+ case expected_layout
139
+ when String, Symbol
140
+ assert_includes @_layouts.keys, expected_layout.to_s, msg
141
+ when Regexp
142
+ assert(@_layouts.keys.any? {|l| l =~ expected_layout }, msg)
143
+ when nil, false
144
+ assert(@_layouts.empty?, msg)
145
+ else
146
+ raise ArgumentError, "assert_template only accepts a String, Symbol, Regexp, nil or false for :layout"
147
+ end
148
+ end
149
+
150
+ if options[:file]
151
+ assert_includes @_files.keys, options[:file]
152
+ elsif options.key?(:file)
153
+ assert @_files.blank?, "expected no files but #{@_files.keys} was rendered"
154
+ end
155
+
156
+ if expected_partial = options[:partial]
157
+ if expected_locals = options[:locals]
158
+ if defined?(@_rendered_views)
159
+ view = expected_partial.to_s.sub(/^_/, '').sub(/\/_(?=[^\/]+\z)/, '/')
160
+
161
+ partial_was_not_rendered_msg = "expected %s to be rendered but it was not." % view
162
+ assert_includes @_rendered_views.rendered_views, view, partial_was_not_rendered_msg
163
+
164
+ msg = 'expecting %s to be rendered with %s but was with %s' % [expected_partial,
165
+ expected_locals,
166
+ @_rendered_views.locals_for(view)]
167
+ assert(@_rendered_views.view_rendered?(view, options[:locals]), msg)
168
+ else
169
+ warn "the :locals option to #assert_template is only supported in a ActionView::TestCase"
170
+ end
171
+ elsif expected_count = options[:count]
172
+ actual_count = @_partials[expected_partial]
173
+ msg = message || sprintf("expecting %s to be rendered %s time(s) but rendered %s time(s)",
174
+ expected_partial, expected_count, actual_count)
175
+ assert(actual_count == expected_count.to_i, msg)
176
+ else
177
+ msg = message || sprintf("expecting partial <%s> but action rendered <%s>",
178
+ options[:partial], @_partials.keys)
179
+ assert_includes @_partials, expected_partial, msg
180
+ end
181
+ elsif options.key?(:partial)
182
+ assert @_partials.empty?,
183
+ "Expected no partials to be rendered"
184
+ end
185
+ else
186
+ raise ArgumentError, "assert_template only accepts a String, Symbol, Hash, Regexp, or nil"
187
+ end
188
+ end
189
+ end
190
+ end
191
+ end
192
+ end
@@ -0,0 +1,15 @@
1
+ require 'active_support/core_ext/hash/indifferent_access'
2
+
3
+ module Rails
4
+ module Controller
5
+ module Testing
6
+ module TestProcess
7
+ def assigns(key = nil)
8
+ assigns = {}.with_indifferent_access
9
+ @controller.view_assigns.each { |k, v| assigns.regular_writer(k, v) }
10
+ key.nil? ? assigns : assigns[key]
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,7 @@
1
+ module Rails
2
+ module Controller
3
+ module Testing
4
+ VERSION = "0.0.2"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,30 @@
1
+ require 'test_helper'
2
+ require 'rails-controller-testing'
3
+
4
+ class AssignsControllerTest < ActionController::TestCase
5
+ include Rails::Controller::Testing
6
+
7
+ def test_assigns
8
+ process :test_assigns
9
+ # assigns can be accessed using assigns(key)
10
+ # or assigns[key], where key is a string or
11
+ # a symbol
12
+ assert_equal "foo", assigns(:foo)
13
+ assert_equal "foo", assigns("foo")
14
+ assert_equal "foo", assigns[:foo]
15
+ assert_equal "foo", assigns["foo"]
16
+
17
+ # but the assigned variable should not have its own keys stringified
18
+ expected_hash = { foo: :bar }
19
+ assert_equal expected_hash, assigns(:foo_hash)
20
+ end
21
+
22
+ def test_view_assigns
23
+ @controller = ViewAssignsController.new
24
+ process :test_assigns
25
+ assert_equal nil, assigns(:foo)
26
+ assert_equal nil, assigns[:foo]
27
+ assert_equal "bar", assigns(:bar)
28
+ assert_equal "bar", assigns[:bar]
29
+ end
30
+ end
@@ -0,0 +1,214 @@
1
+ require 'test_helper'
2
+ require 'rails-controller-testing'
3
+
4
+ class TemplateAssertionsControllerTest < ActionController::TestCase
5
+ include Rails::Controller::Testing
6
+
7
+ def test_with_invalid_hash_keys_raises_argument_error
8
+ assert_raise(ArgumentError) do
9
+ assert_template foo: "bar"
10
+ end
11
+ end
12
+
13
+ def test_with_partial
14
+ get :render_with_partial
15
+ assert_template partial: '_partial'
16
+ end
17
+
18
+ def test_file_with_absolute_path_success
19
+ get :render_file_absolute_path
20
+ assert_template file: File.expand_path('../../dummy/README.rdoc', __FILE__)
21
+ end
22
+
23
+ def test_file_with_relative_path_success
24
+ get :render_file_relative_path
25
+ assert_template file: 'README.rdoc'
26
+ end
27
+
28
+ def test_with_file_failure
29
+ get :render_file_absolute_path
30
+
31
+ assert_raise(ActiveSupport::TestCase::Assertion) do
32
+ assert_template :file => 'test/hello_world'
33
+ end
34
+
35
+ get :render_file_absolute_path
36
+
37
+ assert_raise(ActiveSupport::TestCase::Assertion) do
38
+ assert_template file: nil
39
+ end
40
+ end
41
+
42
+ def test_with_nil_passes_when_no_template_rendered
43
+ get :render_nothing
44
+ assert_template nil
45
+ end
46
+
47
+ def test_with_nil_fails_when_template_rendered
48
+ get :render_with_template
49
+
50
+ assert_raise(ActiveSupport::TestCase::Assertion) do
51
+ assert_template nil
52
+ end
53
+ end
54
+
55
+ def test_with_empty_string_fails_when_template_rendered
56
+ get :render_with_template
57
+
58
+ assert_raise(ActiveSupport::TestCase::Assertion) do
59
+ assert_template ""
60
+ end
61
+ end
62
+
63
+ def test_with_empty_string_fails_when_no_template_rendered
64
+ get :render_nothing
65
+
66
+ assert_raise(ActiveSupport::TestCase::Assertion) do
67
+ assert_template ""
68
+ end
69
+ end
70
+
71
+ def test_passes_with_correct_string
72
+ get :render_with_template
73
+ assert_template 'hello_world'
74
+ assert_template 'test/hello_world'
75
+ end
76
+
77
+ def test_passes_with_correct_symbol
78
+ get :render_with_template
79
+ assert_template :hello_world
80
+ end
81
+
82
+ def test_fails_with_incorrect_string
83
+ get :render_with_template
84
+
85
+ assert_raise(ActiveSupport::TestCase::Assertion) do
86
+ assert_template 'hello_planet'
87
+ end
88
+ end
89
+
90
+ def test_fails_with_incorrect_string_that_matches
91
+ get :render_with_template
92
+
93
+ assert_raise(ActiveSupport::TestCase::Assertion) do
94
+ assert_template 'est/he'
95
+ end
96
+ end
97
+
98
+ def test_fails_with_repeated_name_in_path
99
+ get :render_with_template_repeating_in_path
100
+
101
+ assert_raise(ActiveSupport::TestCase::Assertion) do
102
+ assert_template 'test/hello'
103
+ end
104
+ end
105
+
106
+ def test_fails_with_incorrect_symbol
107
+ get :render_with_template
108
+
109
+ assert_raise(ActiveSupport::TestCase::Assertion) do
110
+ assert_template :hello_planet
111
+ end
112
+ end
113
+
114
+ def test_fails_with_incorrect_symbol_that_matches
115
+ get :render_with_template
116
+
117
+ assert_raise(ActiveSupport::TestCase::Assertion) do
118
+ assert_template :"est/he"
119
+ end
120
+ end
121
+
122
+ def test_fails_with_wrong_layout
123
+ get :render_with_layout
124
+
125
+ assert_raise(ActiveSupport::TestCase::Assertion) do
126
+ assert_template layout: "application"
127
+ end
128
+ end
129
+
130
+ def test_fails_expecting_no_layout
131
+ get :render_with_layout
132
+
133
+ assert_raise(ActiveSupport::TestCase::Assertion) do
134
+ assert_template layout: nil
135
+ end
136
+ end
137
+
138
+ def test_fails_expecting_not_known_layout
139
+ get :render_with_layout
140
+
141
+ assert_raise(ArgumentError) do
142
+ assert_template layout: 1
143
+ end
144
+ end
145
+
146
+ def test_passes_with_correct_layout
147
+ get :render_with_layout
148
+ assert_template layout: "layouts/standard"
149
+ end
150
+
151
+ def test_passes_with_layout_and_partial
152
+ get :render_with_layout_and_partial
153
+ assert_template layout: "layouts/standard"
154
+ assert_template partial: "test/_partial"
155
+ end
156
+
157
+ def test_passed_with_no_layout
158
+ get :render_with_template
159
+ assert_template layout: nil
160
+ end
161
+
162
+ def test_passed_with_no_layout_false
163
+ get :render_with_template
164
+ assert_template layout: false
165
+ end
166
+
167
+ def test_passes_with_correct_layout_without_layouts_prefix
168
+ get :render_with_layout
169
+ assert_template layout: "standard"
170
+ end
171
+
172
+ def test_passes_with_correct_layout_symbol
173
+ get :render_with_layout
174
+ assert_template layout: :standard
175
+ end
176
+
177
+ def test_assert_template_reset_between_requests
178
+ get :render_with_template
179
+ assert_template 'test/hello_world'
180
+
181
+ get :render_nothing
182
+ assert_template nil
183
+
184
+ get :render_with_partial
185
+ assert_template partial: 'test/_partial'
186
+
187
+ get :render_nothing
188
+ assert_template partial: nil
189
+
190
+ get :render_with_layout
191
+ assert_template layout: 'layouts/standard'
192
+
193
+ get :render_nothing
194
+ assert_template layout: nil
195
+
196
+ get :render_file_relative_path
197
+ assert_template file: 'README.rdoc'
198
+
199
+ get :render_nothing
200
+ assert_template file: nil
201
+ end
202
+
203
+ def test_locals_option_to_assert_template_is_not_supported
204
+ get :render_nothing
205
+
206
+ warning_buffer = StringIO.new
207
+ $stderr = warning_buffer
208
+
209
+ assert_template partial: 'customer_greeting', locals: { greeting: 'Bonjour' }
210
+ assert_includes warning_buffer.string, "the :locals option to #assert_template is only supported in a ActionView::TestCase\n"
211
+ ensure
212
+ $stderr = STDERR
213
+ end
214
+ end