mcmire-shoulda-matchers 2.5.0 → 2.6.1.docs.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +9 -0
  4. data/.yardopts +2 -1
  5. data/Appraisals +62 -22
  6. data/Gemfile +1 -1
  7. data/Gemfile.lock +3 -3
  8. data/NEWS.md +87 -4
  9. data/README.md +2 -2
  10. data/Rakefile +18 -0
  11. data/features/activemodel_integration.feature +15 -0
  12. data/features/rails_integration.feature +1 -1
  13. data/features/step_definitions/activemodel_steps.rb +21 -0
  14. data/features/step_definitions/rails_steps.rb +5 -4
  15. data/gemfiles/3.0.gemfile +6 -3
  16. data/gemfiles/3.0.gemfile.lock +14 -4
  17. data/gemfiles/3.1.gemfile +10 -4
  18. data/gemfiles/3.1.gemfile.lock +32 -5
  19. data/gemfiles/3.1_1.9.2.gemfile +21 -0
  20. data/gemfiles/3.1_1.9.2.gemfile.lock +191 -0
  21. data/gemfiles/3.2.gemfile +9 -4
  22. data/gemfiles/3.2.gemfile.lock +28 -5
  23. data/gemfiles/4.0.0.gemfile +11 -3
  24. data/gemfiles/4.0.0.gemfile.lock +42 -5
  25. data/gemfiles/4.0.1.gemfile +11 -3
  26. data/gemfiles/4.0.1.gemfile.lock +42 -5
  27. data/gemfiles/4.1.gemfile +37 -0
  28. data/gemfiles/4.1.gemfile.lock +216 -0
  29. data/lib/shoulda/matchers/action_controller/callback_matcher.rb +202 -0
  30. data/lib/shoulda/matchers/action_controller/rescue_from_matcher.rb +1 -1
  31. data/lib/shoulda/matchers/action_controller/set_the_flash_matcher.rb +2 -1
  32. data/lib/shoulda/matchers/action_controller/strong_parameters_matcher.rb +165 -0
  33. data/lib/shoulda/matchers/action_controller.rb +2 -0
  34. data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +26 -4
  35. data/lib/shoulda/matchers/active_model/disallow_value_matcher.rb +6 -0
  36. data/lib/shoulda/matchers/active_model/ensure_exclusion_of_matcher.rb +2 -0
  37. data/lib/shoulda/matchers/active_model/ensure_inclusion_of_matcher.rb +60 -18
  38. data/lib/shoulda/matchers/active_model/errors.rb +43 -1
  39. data/lib/shoulda/matchers/active_model/numericality_matchers/comparison_matcher.rb +14 -3
  40. data/lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb +2 -1
  41. data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +100 -45
  42. data/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +38 -5
  43. data/lib/shoulda/matchers/active_model/validate_uniqueness_of_matcher.rb +27 -20
  44. data/lib/shoulda/matchers/active_record/association_matcher.rb +12 -2
  45. data/lib/shoulda/matchers/active_record/association_matchers/inverse_of_matcher.rb +41 -0
  46. data/lib/shoulda/matchers/active_record/association_matchers/model_reflection.rb +24 -1
  47. data/lib/shoulda/matchers/active_record/association_matchers/model_reflector.rb +1 -1
  48. data/lib/shoulda/matchers/active_record/have_db_index_matcher.rb +1 -1
  49. data/lib/shoulda/matchers/active_record.rb +1 -0
  50. data/lib/shoulda/matchers/assertion_error.rb +8 -3
  51. data/lib/shoulda/matchers/doublespeak/double.rb +75 -0
  52. data/lib/shoulda/matchers/doublespeak/double_collection.rb +55 -0
  53. data/lib/shoulda/matchers/doublespeak/double_implementation_registry.rb +28 -0
  54. data/lib/shoulda/matchers/doublespeak/object_double.rb +33 -0
  55. data/lib/shoulda/matchers/doublespeak/proxy_implementation.rb +31 -0
  56. data/lib/shoulda/matchers/doublespeak/structs.rb +10 -0
  57. data/lib/shoulda/matchers/doublespeak/stub_implementation.rb +35 -0
  58. data/lib/shoulda/matchers/doublespeak/world.rb +39 -0
  59. data/lib/shoulda/matchers/doublespeak.rb +28 -0
  60. data/lib/shoulda/matchers/error.rb +20 -1
  61. data/lib/shoulda/matchers/independent/delegate_matcher/stubbed_target.rb +35 -0
  62. data/lib/shoulda/matchers/independent/delegate_matcher.rb +293 -0
  63. data/lib/shoulda/matchers/independent.rb +10 -0
  64. data/lib/shoulda/matchers/integrations/nunit_test_case_detection.rb +38 -0
  65. data/lib/shoulda/matchers/integrations/rspec.rb +13 -14
  66. data/lib/shoulda/matchers/integrations/test_unit.rb +19 -15
  67. data/lib/shoulda/matchers/integrations.rb +13 -0
  68. data/lib/shoulda/matchers/rails_shim.rb +16 -0
  69. data/lib/shoulda/matchers/version.rb +1 -1
  70. data/lib/shoulda/matchers.rb +15 -3
  71. data/spec/shoulda/matchers/action_controller/callback_matcher_spec.rb +82 -0
  72. data/spec/shoulda/matchers/action_controller/redirect_to_matcher_spec.rb +2 -2
  73. data/spec/shoulda/matchers/action_controller/render_template_matcher_spec.rb +5 -5
  74. data/spec/shoulda/matchers/action_controller/render_with_layout_matcher_spec.rb +4 -4
  75. data/spec/shoulda/matchers/action_controller/rescue_from_matcher_spec.rb +38 -11
  76. data/spec/shoulda/matchers/action_controller/respond_with_matcher_spec.rb +1 -1
  77. data/spec/shoulda/matchers/action_controller/set_session_matcher_spec.rb +1 -1
  78. data/spec/shoulda/matchers/action_controller/set_the_flash_matcher_spec.rb +6 -6
  79. data/spec/shoulda/matchers/action_controller/strong_parameters_matcher_spec.rb +314 -0
  80. data/spec/shoulda/matchers/active_model/allow_value_matcher_spec.rb +32 -0
  81. data/spec/shoulda/matchers/active_model/ensure_inclusion_of_matcher_spec.rb +553 -211
  82. data/spec/shoulda/matchers/active_model/validate_numericality_of_matcher_spec.rb +22 -0
  83. data/spec/shoulda/matchers/active_model/validate_presence_of_matcher_spec.rb +38 -0
  84. data/spec/shoulda/matchers/active_model/validate_uniqueness_of_matcher_spec.rb +42 -36
  85. data/spec/shoulda/matchers/active_record/association_matcher_spec.rb +15 -1
  86. data/spec/shoulda/matchers/active_record/association_matchers/model_reflection_spec.rb +4 -0
  87. data/spec/shoulda/matchers/active_record/have_db_index_matcher_spec.rb +4 -0
  88. data/spec/shoulda/matchers/doublespeak/double_collection_spec.rb +102 -0
  89. data/spec/shoulda/matchers/doublespeak/double_implementation_registry_spec.rb +21 -0
  90. data/spec/shoulda/matchers/doublespeak/double_spec.rb +144 -0
  91. data/spec/shoulda/matchers/doublespeak/object_double_spec.rb +77 -0
  92. data/spec/shoulda/matchers/doublespeak/proxy_implementation_spec.rb +40 -0
  93. data/spec/shoulda/matchers/doublespeak/stub_implementation_spec.rb +88 -0
  94. data/spec/shoulda/matchers/doublespeak/world_spec.rb +88 -0
  95. data/spec/shoulda/matchers/doublespeak_spec.rb +19 -0
  96. data/spec/shoulda/matchers/independent/delegate_matcher/stubbed_target_spec.rb +43 -0
  97. data/spec/shoulda/matchers/independent/delegate_matcher_spec.rb +250 -0
  98. data/spec/spec_helper.rb +15 -0
  99. data/spec/support/activemodel_helpers.rb +6 -2
  100. data/spec/support/controller_builder.rb +29 -1
  101. data/spec/support/rails_versions.rb +4 -0
  102. data/spec/support/test_application.rb +1 -1
  103. metadata +59 -10
@@ -0,0 +1,88 @@
1
+ require 'spec_helper'
2
+
3
+ module Shoulda::Matchers::Doublespeak
4
+ describe StubImplementation do
5
+ describe '#call' do
6
+ it 'calls #record_call on the double' do
7
+ implementation = described_class.new
8
+ double = build_double
9
+
10
+ double.expects(:record_call).with(:args, :block)
11
+
12
+ implementation.call(double, :object, :args, :block)
13
+ end
14
+
15
+ context 'if no explicit implementation was set' do
16
+ it 'returns nil' do
17
+ implementation = described_class.new
18
+ double = build_double
19
+
20
+ return_value = implementation.call(double, :object, :args, :block)
21
+
22
+ expect(return_value).to eq nil
23
+ end
24
+ end
25
+
26
+ context 'if the implementation was set as a value' do
27
+ it 'returns the set return value' do
28
+ implementation = described_class.new
29
+ implementation.returns(42)
30
+ double = build_double
31
+
32
+ return_value = implementation.call(double, :object, :args, :block)
33
+
34
+ expect(return_value).to eq 42
35
+ end
36
+ end
37
+
38
+ context 'if the implementation was set as a block' do
39
+ it 'calls the block with the object and args/block passed to the method' do
40
+ double = build_double
41
+ expected_object, expected_args, expected_block = :object, :args, :block
42
+ actual_object, actual_args, actual_block = []
43
+ implementation = described_class.new
44
+ implementation.returns do |object, args, block|
45
+ actual_object, actual_args, actual_block = object, args, block
46
+ end
47
+
48
+ implementation.call(
49
+ double,
50
+ expected_object,
51
+ expected_args,
52
+ expected_block
53
+ )
54
+
55
+ expect(actual_object).to eq expected_object
56
+ expect(actual_args).to eq expected_args
57
+ expect(actual_block).to eq expected_block
58
+ end
59
+
60
+ it 'returns the return value of the block' do
61
+ implementation = described_class.new
62
+ implementation.returns { 42 }
63
+ double = build_double
64
+
65
+ return_value = implementation.call(double, :object, :args, :block)
66
+
67
+ expect(return_value).to eq 42
68
+ end
69
+ end
70
+
71
+ context 'if the implementation was set as both a value and a block' do
72
+ it 'prefers the block over the value' do
73
+ implementation = described_class.new
74
+ implementation.returns(:something_else) { 42 }
75
+ double = build_double
76
+
77
+ return_value = implementation.call(double, :object, :args, :block)
78
+
79
+ expect(return_value).to eq 42
80
+ end
81
+ end
82
+ end
83
+
84
+ def build_double
85
+ stub(record_call: nil)
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,88 @@
1
+ require 'spec_helper'
2
+
3
+ module Shoulda::Matchers::Doublespeak
4
+ describe World do
5
+ describe '#register_double_collection' do
6
+ it 'calls DoubleCollection.new with the given class' do
7
+ DoubleCollection.expects(:new).with(:klass)
8
+ world = described_class.new
9
+ world.register_double_collection(:klass)
10
+ end
11
+
12
+ it 'returns the newly created DoubleCollection' do
13
+ double_collection = Object.new
14
+ DoubleCollection.stubs(:new).with(:klass).returns(double_collection)
15
+ world = described_class.new
16
+ expect(world.register_double_collection(:klass)).to be double_collection
17
+ end
18
+ end
19
+
20
+ describe '#with_doubles_activated' do
21
+ it 'installs all doubles, yields the block, then uninstalls them all' do
22
+ block_called = false
23
+
24
+ double_collections = Array.new(3) do
25
+ stub.tap do |double_collection|
26
+ sequence = sequence('with_doubles_activated')
27
+ double_collection.expects(:activate).in_sequence(sequence)
28
+ double_collection.expects(:deactivate).in_sequence(sequence)
29
+ end
30
+ end
31
+
32
+ world = described_class.new
33
+
34
+ DoubleCollection.stubs(:new).
35
+ with(:klass1).
36
+ returns(double_collections[0])
37
+ DoubleCollection.stubs(:new).
38
+ with(:klass2).
39
+ returns(double_collections[1])
40
+ DoubleCollection.stubs(:new).
41
+ with(:klass3).
42
+ returns(double_collections[2])
43
+ world.register_double_collection(:klass1)
44
+ world.register_double_collection(:klass2)
45
+ world.register_double_collection(:klass3)
46
+
47
+ world.with_doubles_activated { block_called = true }
48
+
49
+ expect(block_called).to eq true
50
+ end
51
+
52
+ it 'still makes sure to uninstall all doubles even if the block raises an error' do
53
+ double_collection = stub()
54
+ double_collection.stubs(:activate)
55
+ double_collection.expects(:deactivate)
56
+
57
+ world = described_class.new
58
+
59
+ DoubleCollection.stubs(:new).returns(double_collection)
60
+ world.register_double_collection(:klass)
61
+
62
+ begin
63
+ world.with_doubles_activated { raise 'error' }
64
+ rescue RuntimeError
65
+ end
66
+ end
67
+
68
+ it 'does not allow multiple DoubleCollections to be registered that represent the same class' do
69
+ double_collections = [stub, stub]
70
+ sequence = sequence('with_doubles_activated')
71
+ double_collections[0].expects(:activate).never
72
+ double_collections[0].expects(:deactivate).never
73
+ double_collections[1].expects(:activate).in_sequence(sequence)
74
+ double_collections[1].expects(:deactivate).in_sequence(sequence)
75
+
76
+ world = described_class.new
77
+
78
+ DoubleCollection.stubs(:new).
79
+ returns(double_collections[0]).then.
80
+ returns(double_collections[1])
81
+ world.register_double_collection(:klass1)
82
+ world.register_double_collection(:klass1)
83
+
84
+ world.with_doubles_activated { }
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ module Shoulda::Matchers
4
+ describe Doublespeak do
5
+ describe '.register_double_collection' do
6
+ it 'delegates to its world' do
7
+ Doublespeak.world.expects(:register_double_collection).with(:klass)
8
+ described_class.register_double_collection(:klass)
9
+ end
10
+ end
11
+
12
+ describe '.with_doubles_activated' do
13
+ it 'delegates to its world' do
14
+ Doublespeak.world.expects(:with_doubles_activated)
15
+ described_class.with_doubles_activated
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+
3
+ describe Shoulda::Matchers::Independent::DelegateMatcher::StubbedTarget do
4
+ subject(:target) { described_class.new(:stubbed_method) }
5
+
6
+ describe '#has_received_method?' do
7
+ it 'returns true when the method has been called on the target' do
8
+ target.stubbed_method
9
+
10
+ expect(target).to have_received_method
11
+ end
12
+
13
+ it 'returns false when the method has not been called on the target' do
14
+ expect(target).not_to have_received_method
15
+ end
16
+ end
17
+
18
+ describe '#has_received_arguments?' do
19
+ context 'method is called with specified arguments' do
20
+ it 'returns true' do
21
+ target.stubbed_method(:arg1, :arg2)
22
+
23
+ expect(target).to have_received_arguments(:arg1, :arg2)
24
+ end
25
+ end
26
+
27
+ context 'method is not called with specified arguments' do
28
+ it 'returns false' do
29
+ target.stubbed_method
30
+
31
+ expect(target).not_to have_received_arguments(:arg1)
32
+ end
33
+ end
34
+
35
+ context 'method is called with arguments in incorrect order' do
36
+ it 'returns false' do
37
+ target.stubbed_method(:arg2, :arg1)
38
+
39
+ expect(target).not_to have_received_arguments(:arg1, :arg2)
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,250 @@
1
+ require 'spec_helper'
2
+
3
+ describe Shoulda::Matchers::Independent::DelegateMatcher do
4
+ describe '#description' do
5
+ context 'by default' do
6
+ it 'states that it should delegate method to the right object' do
7
+ matcher = delegate_method(:method_name).to(:target)
8
+
9
+ expect(matcher.description).
10
+ to eq 'delegate method #method_name to :target'
11
+ end
12
+ end
13
+
14
+ context 'with #as chain' do
15
+ it 'states that it should delegate method to the right object and method' do
16
+ matcher = delegate_method(:method_name).to(:target).as(:alternate)
17
+ message = 'delegate method #method_name to :target as #alternate'
18
+
19
+ expect(matcher.description).to eq message
20
+ end
21
+ end
22
+
23
+ context 'with #with_argument chain' do
24
+ it 'states that it should delegate method to the right object with right argument' do
25
+ matcher = delegate_method(:method_name).to(:target).
26
+ with_arguments(:foo, bar: [1, 2])
27
+ message = 'delegate method #method_name to :target with arguments: [:foo, {:bar=>[1, 2]}]'
28
+
29
+ expect(matcher.description).to eq message
30
+ end
31
+ end
32
+ end
33
+
34
+ it 'raises an error if the target method was never specified before matching' do
35
+ expect {
36
+ expect(Object.new).to delegate_method(:name)
37
+ }.to raise_error described_class::TargetNotDefinedError
38
+ end
39
+
40
+ context 'stubbing an instance delegating method' do
41
+ it 'only happens temporarily and is removed after the match' do
42
+ define_class(:company) do
43
+ def name
44
+ 'Acme Company'
45
+ end
46
+ end
47
+
48
+ define_class(:person) do
49
+ def company_name
50
+ company.name
51
+ end
52
+
53
+ def company
54
+ Company.new
55
+ end
56
+ end
57
+
58
+ person = Person.new
59
+ matcher = delegate_method(:company_name).to(:company).as(:name)
60
+ matcher.matches?(person)
61
+
62
+ expect(person.company.name).to eq 'Acme Company'
63
+ end
64
+ end
65
+
66
+ context 'given a method that does not delegate' do
67
+ before do
68
+ define_class(:post_office) do
69
+ def deliver_mail
70
+ :delivered
71
+ end
72
+ end
73
+ end
74
+
75
+ it 'rejects' do
76
+ post_office = PostOffice.new
77
+ expect(post_office).not_to delegate_method(:deliver_mail).to(:mailman)
78
+ end
79
+
80
+ it 'has a failure message that indicates which method should have been delegated' do
81
+ post_office = PostOffice.new
82
+ message = [
83
+ 'Expected PostOffice#deliver_mail to delegate to PostOffice#mailman',
84
+ 'Calls on PostOffice#mailman: (none)'
85
+ ].join("\n")
86
+
87
+ expect {
88
+ expect(post_office).to delegate_method(:deliver_mail).to(:mailman)
89
+ }.to fail_with_message(message)
90
+ end
91
+
92
+ it 'uses the proper syntax for class methods in errors' do
93
+ message = [
94
+ 'Expected PostOffice.deliver_mail to delegate to PostOffice.mailman',
95
+ 'Calls on PostOffice.mailman: (none)'
96
+ ].join("\n")
97
+
98
+ expect {
99
+ expect(PostOffice).to delegate_method(:deliver_mail).to(:mailman)
100
+ }.to fail_with_message(message)
101
+ end
102
+ end
103
+
104
+ context 'given a method that delegates properly' do
105
+ before do
106
+ define_class(:mailman)
107
+
108
+ define_class(:post_office) do
109
+ def deliver_mail
110
+ mailman.deliver_mail
111
+ end
112
+
113
+ def mailman
114
+ Mailman.new
115
+ end
116
+ end
117
+ end
118
+
119
+ it 'accepts' do
120
+ post_office = PostOffice.new
121
+ expect(post_office).to delegate_method(:deliver_mail).to(:mailman)
122
+ end
123
+
124
+ it 'produces the correct failure message if the assertion was negated' do
125
+ post_office = PostOffice.new
126
+ message = 'Expected PostOffice#deliver_mail not to delegate to PostOffice#mailman, but it did'
127
+
128
+ expect {
129
+ expect(post_office).not_to delegate_method(:deliver_mail).to(:mailman)
130
+ }.to fail_with_message(message)
131
+ end
132
+ end
133
+
134
+ context 'given a method that delegates properly with arguments' do
135
+ before do
136
+ define_class(:mailman)
137
+
138
+ define_class(:post_office) do
139
+ def deliver_mail(*args)
140
+ mailman.deliver_mail('221B Baker St.', hastily: true)
141
+ end
142
+
143
+ def mailman
144
+ Mailman.new
145
+ end
146
+ end
147
+ end
148
+
149
+ context 'when given the correct arguments' do
150
+ it 'accepts' do
151
+ post_office = PostOffice.new
152
+ expect(post_office).to delegate_method(:deliver_mail).
153
+ to(:mailman).with_arguments('221B Baker St.', hastily: true)
154
+ end
155
+
156
+ it 'produces the correct failure message if the assertion was negated' do
157
+ post_office = PostOffice.new
158
+ message = 'Expected PostOffice#deliver_mail not to delegate to PostOffice#mailman with arguments: ["221B Baker St.", {:hastily=>true}], but it did'
159
+
160
+ expect {
161
+ expect(post_office).
162
+ not_to delegate_method(:deliver_mail).
163
+ to(:mailman).
164
+ with_arguments('221B Baker St.', hastily: true)
165
+ }.to fail_with_message(message)
166
+ end
167
+ end
168
+
169
+ context 'when not given the correct arguments' do
170
+ it 'rejects' do
171
+ post_office = PostOffice.new
172
+ expect(post_office).
173
+ not_to delegate_method(:deliver_mail).to(:mailman).
174
+ with_arguments('123 Nowhere Ln.')
175
+ end
176
+
177
+ it 'has a failure message that indicates which arguments were expected' do
178
+ post_office = PostOffice.new
179
+ message = [
180
+ 'Expected PostOffice#deliver_mail to delegate to PostOffice#mailman with arguments: ["123 Nowhere Ln."]',
181
+ 'Calls on PostOffice#mailman:',
182
+ '1) deliver_mail("221B Baker St.", {:hastily=>true})'
183
+ ].join("\n")
184
+
185
+ expect {
186
+ expect(post_office).to delegate_method(:deliver_mail).
187
+ to(:mailman).with_arguments('123 Nowhere Ln.')
188
+ }.to fail_with_message(message)
189
+ end
190
+ end
191
+ end
192
+
193
+ context 'given a method that delegates properly to a method of a different name' do
194
+ before do
195
+ define_class(:mailman)
196
+
197
+ define_class(:post_office) do
198
+ def deliver_mail
199
+ mailman.deliver_mail_and_avoid_dogs
200
+ end
201
+
202
+ def mailman
203
+ Mailman.new
204
+ end
205
+ end
206
+ end
207
+
208
+ context 'when given the correct method name' do
209
+ it 'accepts' do
210
+ post_office = PostOffice.new
211
+ expect(post_office).to delegate_method(:deliver_mail).
212
+ to(:mailman).as(:deliver_mail_and_avoid_dogs)
213
+ end
214
+
215
+ it 'produces the correct failure message if the assertion was negated' do
216
+ post_office = PostOffice.new
217
+ message = 'Expected PostOffice#deliver_mail not to delegate to PostOffice#mailman as #deliver_mail_and_avoid_dogs, but it did'
218
+
219
+ expect {
220
+ expect(post_office).
221
+ not_to delegate_method(:deliver_mail).
222
+ to(:mailman).
223
+ as(:deliver_mail_and_avoid_dogs)
224
+ }.to fail_with_message(message)
225
+ end
226
+ end
227
+
228
+ context 'when given an incorrect method name' do
229
+ it 'rejects' do
230
+ post_office = PostOffice.new
231
+ expect(post_office).
232
+ not_to delegate_method(:deliver_mail).to(:mailman).as(:watch_tv)
233
+ end
234
+
235
+ it 'has a failure message that indicates which method was expected' do
236
+ post_office = PostOffice.new
237
+ message = [
238
+ 'Expected PostOffice#deliver_mail to delegate to PostOffice#mailman as #watch_tv',
239
+ 'Calls on PostOffice#mailman:',
240
+ '1) deliver_mail_and_avoid_dogs()'
241
+ ].join("\n")
242
+
243
+ expect {
244
+ expect(post_office).to delegate_method(:deliver_mail).
245
+ to(:mailman).as(:watch_tv)
246
+ }.to fail_with_message(message)
247
+ end
248
+ end
249
+ end
250
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,9 +1,24 @@
1
1
  require File.expand_path('../support/test_application', __FILE__)
2
2
 
3
+ def monkey_patch_minitest_to_do_nothing
4
+ # Rails 3.1's test_help file requires Turn, which loads Minitest in autorun
5
+ # mode. This means that Minitest tests will run after these RSpec tests are
6
+ # finished running. This will break on CI since we pass --color to the `rspec`
7
+ # command.
8
+
9
+ if defined?(MiniTest)
10
+ MiniTest::Unit.class_eval do
11
+ def run(*); end
12
+ end
13
+ end
14
+ end
15
+
3
16
  $test_app = TestApplication.new
4
17
  $test_app.create
5
18
  $test_app.load
6
19
 
20
+ monkey_patch_minitest_to_do_nothing
21
+
7
22
  ENV['BUNDLE_GEMFILE'] ||= app.gemfile_path
8
23
  ENV['RAILS_ENV'] = 'test'
9
24
 
@@ -1,11 +1,15 @@
1
1
  module ActiveModelHelpers
2
- def custom_validation(&block)
3
- define_model(:example, attr: :integer) do
2
+ def custom_validation(options = {}, &block)
3
+ attribute_name = options.fetch(:attribute_name, :attr)
4
+ attribute_type = options.fetch(:attribute_type, :integer)
5
+
6
+ define_model(:example, attribute_name => attribute_type) do
4
7
  validate :custom_validation
5
8
 
6
9
  define_method(:custom_validation, &block)
7
10
  end.new
8
11
  end
12
+ alias record_with_custom_validation custom_validation
9
13
 
10
14
  def validating_format(options)
11
15
  define_model :example, attr: :string do
@@ -21,7 +21,7 @@ module ControllerBuilder
21
21
  end
22
22
  end
23
23
 
24
- def build_response(opts = {}, &block)
24
+ def build_fake_response(opts = {}, &block)
25
25
  action = opts[:action] || 'example'
26
26
  partial = opts[:partial] || '_partial'
27
27
  block ||= lambda { render nothing: true }
@@ -58,6 +58,34 @@ module ControllerBuilder
58
58
  $test_app.create_temp_view(path, contents)
59
59
  end
60
60
 
61
+ def controller_for_resource_with_strong_parameters(options = {}, &action_body)
62
+ model_name = options.fetch(:model_name, 'User')
63
+ controller_name = options.fetch(:controller_name, 'UsersController')
64
+ collection_name = controller_name.
65
+ to_s.sub(/Controller$/, '').underscore.
66
+ to_sym
67
+ action_name = options.fetch(:action, :some_action)
68
+ routes ||= options.fetch(:routes, -> { resources collection_name })
69
+
70
+ define_model(model_name)
71
+
72
+ controller_class = define_controller(controller_name) do
73
+ define_method action_name do
74
+ if action_body
75
+ instance_eval(&action_body)
76
+ end
77
+
78
+ render nothing: true
79
+ end
80
+ end
81
+
82
+ setup_rails_controller_test(controller_class)
83
+
84
+ define_routes(&routes)
85
+
86
+ controller_class
87
+ end
88
+
61
89
  private
62
90
 
63
91
  def delete_temporary_views
@@ -10,6 +10,10 @@ module RailsVersions
10
10
  def rails_4_x?
11
11
  Gem::Requirement.new('~> 4.0').satisfied_by?(rails_version)
12
12
  end
13
+
14
+ def rails_gte_4_1?
15
+ Gem::Requirement.new('>= 4.1').satisfied_by?(rails_version)
16
+ end
13
17
  end
14
18
 
15
19
  RSpec.configure do |config|
@@ -92,7 +92,7 @@ EOT
92
92
  end
93
93
 
94
94
  def install_gems
95
- retrying('bundle install') do |command|
95
+ retrying('bundle install --local') do |command|
96
96
  Bundler.with_clean_env { `#{command}` }
97
97
  end
98
98
  end