class-action 0.0.1 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +33 -16
- data/.travis.yml +6 -0
- data/CHANGELOG.md +31 -0
- data/Gemfile.lock +62 -0
- data/README.md +42 -11
- data/class-action.gemspec +1 -0
- data/lib/class-action/rspec.rb +2 -0
- data/lib/class_action/action.rb +113 -63
- data/lib/class_action/rspec/class_action_example_group.rb +57 -0
- data/lib/class_action/rspec/have_class_action_matcher.rb +67 -0
- data/lib/class_action/rspec/respond_to_format_matcher.rb +72 -0
- data/lib/class_action/rspec/respond_with_matcher.rb +60 -0
- data/lib/class_action/rspec.rb +3 -0
- data/lib/class_action/version.rb +1 -1
- data/lib/class_action.rb +12 -8
- data/spec/class_action/action_spec.rb +202 -29
- data/spec/class_action/rspec/have_class_action_matcher_spec.rb +69 -0
- data/spec/class_action/rspec/respond_to_format_matcher_spec.rb +76 -0
- data/spec/class_action/rspec/respond_with_matcher_spec.rb +84 -0
- data/spec/class_action_spec.rb +8 -1
- data/spec/spec_helper.rb +6 -0
- metadata +32 -7
- data/.ruby-gemset +0 -1
- data/.ruby-version +0 -1
- data/ClassAction.sublime-project +0 -10
- data/ClassAction.sublime-workspace +0 -1873
@@ -0,0 +1,72 @@
|
|
1
|
+
module ClassAction
|
2
|
+
module RSpec
|
3
|
+
|
4
|
+
class RespondToFormatMatcher
|
5
|
+
|
6
|
+
def initialize(format)
|
7
|
+
@format = format.to_sym
|
8
|
+
end
|
9
|
+
|
10
|
+
def on(condition)
|
11
|
+
@condition = condition
|
12
|
+
self
|
13
|
+
end
|
14
|
+
|
15
|
+
def matches?(action, &block)
|
16
|
+
@action = action
|
17
|
+
|
18
|
+
if action.class._responders.key?([@format, @condition])
|
19
|
+
|
20
|
+
if block
|
21
|
+
# Response defined, we return true but we need to also execute the block,
|
22
|
+
# as it might contain additional checks. First run the action's response
|
23
|
+
# block, for this.
|
24
|
+
respond_block = action.class._responders[ [@format, @condition] ]
|
25
|
+
action.instance_exec &respond_block if respond_block
|
26
|
+
action.send :copy_assigns_to_controller
|
27
|
+
block.call
|
28
|
+
end
|
29
|
+
|
30
|
+
true
|
31
|
+
else
|
32
|
+
false
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def description
|
37
|
+
if @condition
|
38
|
+
"respond to format :#{@format} on :#{@condition}"
|
39
|
+
else
|
40
|
+
"respond to format :#{@format}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def failure_message_for_should
|
45
|
+
if @condition
|
46
|
+
"expected action of class #{@action.class} to respond to format :#{@format} on :#{@condition}"
|
47
|
+
else
|
48
|
+
"expected action of class #{@action.class} to respond to format :#{@format}"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def failure_message_for_should_not
|
53
|
+
if @condition
|
54
|
+
"expected action of class #{@action.class} not to respond to format :#{@format} on :#{@condition}"
|
55
|
+
else
|
56
|
+
"expected action of class #{@action.class} not to respond to format :#{@format}"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
RSpec::Matchers.module_eval do
|
66
|
+
def respond_to_format(format)
|
67
|
+
ClassAction::RSpec::RespondToFormatMatcher.new(format)
|
68
|
+
end
|
69
|
+
def respond_to_any_format
|
70
|
+
ClassAction::RSpec::RespondToFormatMatcher.new(:any)
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module ClassAction
|
2
|
+
module RSpec
|
3
|
+
|
4
|
+
class RespondWithMatcher
|
5
|
+
|
6
|
+
def initialize(expected)
|
7
|
+
@expected = expected.to_sym
|
8
|
+
end
|
9
|
+
|
10
|
+
def on(condition)
|
11
|
+
@condition = condition
|
12
|
+
self
|
13
|
+
end
|
14
|
+
|
15
|
+
def matches?(action)
|
16
|
+
@action = action
|
17
|
+
@actual = action.class._responses[@condition].try(:to_sym)
|
18
|
+
@actual == @expected
|
19
|
+
end
|
20
|
+
|
21
|
+
def description
|
22
|
+
if @condition
|
23
|
+
"respond with method :#{@expected} on :#{@condition}"
|
24
|
+
else
|
25
|
+
"respond with method :#{@expected}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def failure_message_for_should
|
30
|
+
suffix = if @actual
|
31
|
+
", but it responds with :#{@actual}"
|
32
|
+
else
|
33
|
+
", but it has no response method"
|
34
|
+
end
|
35
|
+
|
36
|
+
if @condition
|
37
|
+
"expected action of class #{@action.class} to respond with :#{@expected} on :#{@condition}#{suffix}"
|
38
|
+
else
|
39
|
+
"expected action of class #{@action.class} to respond with :#{@expected}#{suffix}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def failure_message_for_should_not
|
44
|
+
if @condition
|
45
|
+
"expected action of class #{@action.class} not to respond with :#{@expected} on :#{@condition}"
|
46
|
+
else
|
47
|
+
"expected action of class #{@action.class} not to respond with :#{@expected}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
RSpec::Matchers.module_eval do
|
57
|
+
def respond_with(expected)
|
58
|
+
ClassAction::RSpec::RespondWithMatcher.new(expected)
|
59
|
+
end
|
60
|
+
end
|
data/lib/class_action/version.rb
CHANGED
data/lib/class_action.rb
CHANGED
@@ -28,8 +28,13 @@ module ClassAction
|
|
28
28
|
raise ArgumentError, "ClassAction does not support anonymous classes" if action_class.name.nil?
|
29
29
|
|
30
30
|
class_eval <<-RUBY, __FILE__, __LINE__+1
|
31
|
+
def _#{action}_action_class
|
32
|
+
@_class_action ||= #{action_class.name}.new self
|
33
|
+
end
|
34
|
+
private :_#{action}_action_class
|
35
|
+
|
31
36
|
def #{action}
|
32
|
-
|
37
|
+
_#{action}_action_class._execute
|
33
38
|
end
|
34
39
|
RUBY
|
35
40
|
|
@@ -43,18 +48,18 @@ module ClassAction
|
|
43
48
|
# mimes_for_respond_to hash.
|
44
49
|
def inject_class_action_mimes(action, klass)
|
45
50
|
# If no responders or a default responder is given, we don't do anything.
|
46
|
-
return if klass.
|
51
|
+
return if klass._responders.empty? || klass._responders.any? { |(mime, _condition), _block| mime == :any }
|
47
52
|
|
48
53
|
mimes = mimes_for_respond_to.dup
|
49
54
|
|
50
55
|
# Make sure no extra mimes are allowed for the action.
|
51
56
|
mimes.each do |mime, restrictions|
|
52
|
-
next if klass.
|
57
|
+
next if klass._responders.any? { |(m, _codition), _block| m == mime }
|
53
58
|
exclude_class_action_in_mime_type mime, restrictions, action
|
54
59
|
end
|
55
60
|
|
56
61
|
# Include all action mimes.
|
57
|
-
klass.
|
62
|
+
klass._responders.each do |(mime, _condition), _block|
|
58
63
|
mimes[mime] ||= { :only => [] }
|
59
64
|
include_class_action_in_mime_type mime, mimes[mime], action
|
60
65
|
end
|
@@ -64,7 +69,7 @@ module ClassAction
|
|
64
69
|
|
65
70
|
def include_class_action_in_mime_type(mime, restrictions, action)
|
66
71
|
if restrictions && restrictions[:except] && restrictions[:except].include?(action)
|
67
|
-
logger.warn "Warning: action #{action} (ClassAction) responds to `#{mime}` but it does not accept this mime type"
|
72
|
+
logger.warn "Warning: action #{action} (ClassAction) responds to `#{mime}` but it does not accept this mime type" if logger
|
68
73
|
elsif restrictions && restrictions[:only] && !restrictions[:only].include?(action)
|
69
74
|
restrictions[:only] << action
|
70
75
|
end
|
@@ -90,9 +95,8 @@ module ClassAction
|
|
90
95
|
|
91
96
|
private
|
92
97
|
|
93
|
-
def
|
94
|
-
|
95
|
-
@_class_action._execute
|
98
|
+
def _class_action
|
99
|
+
send(:"_#{action_name}_action_class")
|
96
100
|
end
|
97
101
|
|
98
102
|
end
|
@@ -5,6 +5,7 @@ describe ClassAction::Action do
|
|
5
5
|
let(:controller) { double(:controller, :view_assigns => {}, :response_body => nil) }
|
6
6
|
let(:action_class) { Class.new(ClassAction::Action) }
|
7
7
|
let(:action) { action_class.new(controller) }
|
8
|
+
before { allow(controller).to receive(:class_action).and_return(action) }
|
8
9
|
|
9
10
|
it "should by default be available" do
|
10
11
|
expect(action).to be_available
|
@@ -15,14 +16,16 @@ describe ClassAction::Action do
|
|
15
16
|
expect(action_class.helpers).to be_a(Module)
|
16
17
|
end
|
17
18
|
|
18
|
-
|
19
|
+
before do
|
19
20
|
action_class.class_eval do
|
20
21
|
def helper1
|
21
22
|
'HELPER RESULT'
|
22
23
|
end
|
23
24
|
helper_method :helper1
|
24
25
|
end
|
26
|
+
end
|
25
27
|
|
28
|
+
it "should define the helper method in the action's helpers module, which should call the method on the controller action" do
|
26
29
|
helpers = action_class.helpers
|
27
30
|
klass = Class.new do
|
28
31
|
include helpers
|
@@ -38,20 +41,45 @@ describe ClassAction::Action do
|
|
38
41
|
expect(controller).to receive(:class_action).and_return(action)
|
39
42
|
expect(obj.helper1).to eql('HELPER RESULT')
|
40
43
|
end
|
44
|
+
|
45
|
+
it "should also expose helper methods on the controller" do
|
46
|
+
action # Load the action up to include the helpers module.
|
47
|
+
expect(controller).to respond_to(:helper1)
|
48
|
+
expect(controller.helper1).to eql('HELPER RESULT')
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should also expose helper methods defined in a superclass" do
|
52
|
+
action_subclass = Class.new(action_class) do
|
53
|
+
def helper2
|
54
|
+
'HELPER2'
|
55
|
+
end
|
56
|
+
helper_method :helper2
|
57
|
+
end
|
58
|
+
|
59
|
+
obj= Class.new{ include action_subclass.helpers }.new
|
60
|
+
expect(obj).to respond_to(:helper1)
|
61
|
+
expect(obj).to respond_to(:helper2)
|
62
|
+
end
|
63
|
+
|
41
64
|
end
|
42
65
|
|
43
|
-
describe '
|
44
|
-
|
45
|
-
before {
|
66
|
+
describe 'controller methods' do
|
67
|
+
let(:result) { double(:result) }
|
68
|
+
before { allow(controller).to receive(:load_post).and_return(result) }
|
46
69
|
|
47
|
-
it "should
|
48
|
-
expect(action
|
70
|
+
it "should make the action respond to :load_post, but protectedly" do
|
71
|
+
expect(action).not_to respond_to(:load_post)
|
72
|
+
expect(action.respond_to?(:load_post, true)).to be_true # matcher doesn't work with second argument
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should pass the method :load_post on to the controller" do
|
76
|
+
expect(action.load_post).to be(result)
|
49
77
|
end
|
50
78
|
|
51
|
-
it "should create a
|
52
|
-
|
53
|
-
|
54
|
-
expect(action.
|
79
|
+
it "should create a protected method :load_post the first time it is called" do
|
80
|
+
expect(action.protected_methods).not_to include(:load_post)
|
81
|
+
action.load_post
|
82
|
+
expect(action.protected_methods).to include(:load_post)
|
55
83
|
end
|
56
84
|
|
57
85
|
it "should copy assigns to the controller before executing the controller method, and copy them back afterwards" do
|
@@ -68,7 +96,6 @@ describe ClassAction::Action do
|
|
68
96
|
end
|
69
97
|
|
70
98
|
action_class.class_eval do
|
71
|
-
controller_method :increase_var
|
72
99
|
def execute
|
73
100
|
@var = 2
|
74
101
|
increase_var
|
@@ -98,7 +125,7 @@ describe ClassAction::Action do
|
|
98
125
|
def method4; end
|
99
126
|
end
|
100
127
|
|
101
|
-
expect(action_class.
|
128
|
+
expect(action_class._action_methods).to eql([ :method1, :method2 ])
|
102
129
|
end
|
103
130
|
end
|
104
131
|
|
@@ -111,22 +138,65 @@ describe ClassAction::Action do
|
|
111
138
|
it "should execute all action methods in the action, and call #copy_assigns_to_controller finally" do
|
112
139
|
called = []
|
113
140
|
|
114
|
-
expect(action_class).to receive(:
|
115
|
-
|
116
|
-
|
141
|
+
expect(action_class).to receive(:_action_methods).and_return([:method1, :method2])
|
142
|
+
|
143
|
+
action_class.class_eval do
|
144
|
+
def method1
|
145
|
+
@called << :method1
|
146
|
+
end
|
147
|
+
def method2
|
148
|
+
@called << :method2
|
149
|
+
end
|
150
|
+
end
|
117
151
|
|
152
|
+
action.instance_variable_set '@called', called
|
118
153
|
action._execute
|
119
154
|
expect(called).to eql([:method1, :method2])
|
120
155
|
end
|
121
156
|
|
157
|
+
it "should skip methods that take arguments" do
|
158
|
+
action_class.class_eval do
|
159
|
+
def one
|
160
|
+
@called = []
|
161
|
+
@called << :one
|
162
|
+
end
|
163
|
+
def two(*args)
|
164
|
+
@called << :two
|
165
|
+
end
|
166
|
+
def three(arg)
|
167
|
+
@called << :three
|
168
|
+
end
|
169
|
+
def three(arg = nil)
|
170
|
+
@called << :four
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
action._execute
|
175
|
+
called = action.instance_variable_get('@called')
|
176
|
+
expect(called).to eql([:one])
|
177
|
+
end
|
178
|
+
|
122
179
|
it "should stop executing when a response body is set" do
|
123
180
|
called = []; response_body = nil
|
124
181
|
|
125
182
|
allow(controller).to receive(:response_body) { response_body }
|
126
|
-
|
127
|
-
|
128
|
-
|
183
|
+
allow(controller).to receive(:response).and_return(double())
|
184
|
+
allow(controller.response).to receive(:body) { response_body }
|
185
|
+
allow(controller.response).to receive(:body=) { |val| response_body = val }
|
186
|
+
|
187
|
+
expect(action_class).to receive(:_action_methods).and_return([:method1, :method2])
|
129
188
|
|
189
|
+
action_class.class_eval do
|
190
|
+
def method1
|
191
|
+
@called << :method1
|
192
|
+
response.body = '<html></html>'
|
193
|
+
end
|
194
|
+
def method2
|
195
|
+
@called << :method2
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
action.instance_variable_set '@called', called
|
130
200
|
action._execute
|
131
201
|
expect(called).to eql([:method1])
|
132
202
|
end
|
@@ -134,11 +204,20 @@ describe ClassAction::Action do
|
|
134
204
|
it "should call _respond at the end" do
|
135
205
|
called = []
|
136
206
|
|
137
|
-
expect(action_class).to receive(:
|
138
|
-
|
139
|
-
|
207
|
+
expect(action_class).to receive(:_action_methods).and_return([:method1, :method2])
|
208
|
+
|
209
|
+
action_class.class_eval do
|
210
|
+
def method1
|
211
|
+
@called << :method1
|
212
|
+
end
|
213
|
+
def method2
|
214
|
+
@called << :method2
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
140
218
|
expect(action).to receive(:_respond) { called << :_respond }
|
141
219
|
|
220
|
+
action.instance_variable_set '@called', called
|
142
221
|
action._execute
|
143
222
|
expect(called).to eql([:method1, :method2, :_respond])
|
144
223
|
end
|
@@ -168,7 +247,7 @@ describe ClassAction::Action do
|
|
168
247
|
action._execute
|
169
248
|
end
|
170
249
|
|
171
|
-
context "with no
|
250
|
+
context "with no response method or responders" do
|
172
251
|
it "should not call a respond method, but copy all instance variables into the controller at the end" do
|
173
252
|
expect(controller).not_to receive(:respond_with)
|
174
253
|
expect(controller).not_to receive(:respond_to)
|
@@ -176,16 +255,21 @@ describe ClassAction::Action do
|
|
176
255
|
end
|
177
256
|
end
|
178
257
|
|
179
|
-
context "having set a
|
258
|
+
context "having set a response method" do
|
180
259
|
let(:response) { double(:response) }
|
181
260
|
before do
|
182
261
|
action_class.class_eval do
|
183
262
|
respond_with :response
|
263
|
+
respond_with :invalid_response, on: :invalid
|
264
|
+
|
265
|
+
protected
|
266
|
+
|
267
|
+
def invalid?() false end
|
184
268
|
end
|
185
|
-
expect(action).to receive(:response).and_return(response)
|
186
269
|
end
|
187
270
|
|
188
|
-
it "should
|
271
|
+
it "should use the value of #response" do
|
272
|
+
expect(action).to receive(:response).and_return(response)
|
189
273
|
expect(controller).to receive(:respond_with).with(response) do |&blk|
|
190
274
|
expect(blk).to be_nil
|
191
275
|
end
|
@@ -193,10 +277,27 @@ describe ClassAction::Action do
|
|
193
277
|
action._execute
|
194
278
|
end
|
195
279
|
|
280
|
+
it "should use the value of #invalid_response if invalid? returns true" do
|
281
|
+
allow(action).to receive(:invalid?).and_return(true)
|
282
|
+
expect(action).to receive(:invalid_response).and_return(response)
|
283
|
+
expect(controller).to receive(:respond_with).with(response)
|
284
|
+
action._execute
|
285
|
+
end
|
286
|
+
|
287
|
+
it "should read an instance variable if this is set" do
|
288
|
+
action_class.class_eval do
|
289
|
+
respond_with :@response
|
290
|
+
end
|
291
|
+
action.instance_variable_set '@response', response
|
292
|
+
expect(controller).to receive(:respond_with).with(response)
|
293
|
+
action._execute
|
294
|
+
end
|
295
|
+
|
196
296
|
it "should use the _respond_block if it is set" do
|
197
297
|
block = proc{}
|
198
298
|
allow(action).to receive(:_respond_block).and_return(block)
|
199
299
|
|
300
|
+
expect(action).to receive(:response).and_return(response)
|
200
301
|
expect(controller).to receive(:respond_with).with(response) do |&blk|
|
201
302
|
expect(blk).to be(block)
|
202
303
|
end
|
@@ -227,18 +328,29 @@ describe ClassAction::Action do
|
|
227
328
|
|
228
329
|
# Private method, but specced individually to make spec terser.
|
229
330
|
|
230
|
-
|
331
|
+
def respond_block
|
332
|
+
action.send(:_respond_block)
|
333
|
+
end
|
231
334
|
|
232
335
|
it "should create a block using the given responders, which is executed on the action" do
|
233
336
|
called = nil; receiver = nil
|
234
337
|
json_block = proc { receiver = self; called = :json }
|
235
338
|
html_block = proc { receiver = self; called = :html }
|
236
|
-
|
339
|
+
html_invalid_block = proc { receiver = self; called = :html_invalid }
|
340
|
+
any_ok_block = proc { receiver = self; called = :any_ok }
|
237
341
|
|
238
342
|
action_class.class_eval do
|
239
343
|
respond_to :json, &json_block
|
240
344
|
respond_to :html, &html_block
|
241
|
-
|
345
|
+
respond_to :html, on: :invalid, &html_invalid_block
|
346
|
+
respond_to_any on: :ok, &any_ok_block
|
347
|
+
|
348
|
+
attr_accessor :status
|
349
|
+
|
350
|
+
protected
|
351
|
+
|
352
|
+
def ok?() status == :ok end
|
353
|
+
def invalid?() status == :invalid end
|
242
354
|
end
|
243
355
|
|
244
356
|
# Simulate ActionController's format collector.
|
@@ -247,16 +359,77 @@ describe ClassAction::Action do
|
|
247
359
|
def collector.html(&block) @html_block = block end
|
248
360
|
def collector.any(&block) @any_block = block end
|
249
361
|
|
362
|
+
action.status = :ok
|
250
363
|
respond_block.call collector
|
364
|
+
collector.json_block.call
|
365
|
+
expect(receiver).to be(action); expect(called).to be(:json)
|
251
366
|
|
367
|
+
action.status = :invalid
|
368
|
+
respond_block.call collector
|
252
369
|
collector.json_block.call
|
253
370
|
expect(receiver).to be(action); expect(called).to be(:json)
|
254
371
|
|
372
|
+
action.status = :ok
|
373
|
+
respond_block.call collector
|
255
374
|
collector.html_block.call
|
256
375
|
expect(receiver).to be(action); expect(called).to be(:html)
|
257
376
|
|
377
|
+
action.status = :invalid
|
378
|
+
respond_block.call collector
|
379
|
+
collector.html_block.call
|
380
|
+
expect(receiver).to be(action); expect(called).to be(:html_invalid)
|
381
|
+
|
382
|
+
action.status = :ok
|
383
|
+
respond_block.call collector
|
258
384
|
collector.any_block.call
|
259
|
-
expect(receiver).to be(action); expect(called).to be(:
|
385
|
+
expect(receiver).to be(action); expect(called).to be(:any_ok)
|
386
|
+
|
387
|
+
receiver = nil
|
388
|
+
called = nil
|
389
|
+
|
390
|
+
action.status = :invalid
|
391
|
+
expect(collector).not_to receive(:any)
|
392
|
+
respond_block.call collector
|
393
|
+
end
|
394
|
+
|
395
|
+
it "should copy assigns back to the controller after responding" do
|
396
|
+
action_class.class_eval do
|
397
|
+
respond_to :html do
|
398
|
+
@my_var = :value
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
402
|
+
collector = Class.new{ attr_reader :html_block }.new
|
403
|
+
def collector.html(&block) @html_block = block end
|
404
|
+
respond_block.call collector
|
405
|
+
|
406
|
+
collector.html_block.call
|
407
|
+
expect(controller.instance_variable_get('@my_var')).to be(:value)
|
408
|
+
end
|
409
|
+
|
410
|
+
it "should take responders to a subclass" do
|
411
|
+
action_class.class_eval do
|
412
|
+
respond_to :html
|
413
|
+
end
|
414
|
+
action_subclass = Class.new(action_class) do
|
415
|
+
respond_to :json
|
416
|
+
end
|
417
|
+
|
418
|
+
expect(action_subclass._responders).to eql(
|
419
|
+
[ :html, nil ] => nil,
|
420
|
+
[ :json, nil ] => nil
|
421
|
+
)
|
422
|
+
end
|
423
|
+
|
424
|
+
it "should copy the respond_with_method to a subclass" do
|
425
|
+
action_class.class_eval do
|
426
|
+
respond_with :post
|
427
|
+
end
|
428
|
+
|
429
|
+
action_subclass = Class.new(action_class)
|
430
|
+
expect(action_subclass).to have(1)._response
|
431
|
+
expect(action_subclass._responses.keys[0]).to be_nil
|
432
|
+
expect(action_subclass._responses.values[0]).to be(:post)
|
260
433
|
end
|
261
434
|
|
262
435
|
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'class_action/rspec'
|
3
|
+
|
4
|
+
describe ClassAction::RSpec::HaveClassActionMatcher do
|
5
|
+
|
6
|
+
class ClassActionTestController < ActionController::Base
|
7
|
+
class Index < ClassAction::Action
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:controller) { ClassActionTestController.new }
|
12
|
+
|
13
|
+
it "should fail if the controller does not support class actions" do
|
14
|
+
expect { expect(controller).to have_class_action(:index) }.to \
|
15
|
+
raise_error(
|
16
|
+
RSpec::Expectations::ExpectationNotMetError,
|
17
|
+
"expected controller of class ClassActionTestController to have class action :index, but it does not support class actions"
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
context "having included ClassAction" do
|
22
|
+
before { ClassActionTestController.send :include, ClassAction }
|
23
|
+
|
24
|
+
it "should fail if the controller does not have an index action" do
|
25
|
+
expect { expect(controller).to have_class_action(:index) }.to \
|
26
|
+
raise_error(
|
27
|
+
RSpec::Expectations::ExpectationNotMetError,
|
28
|
+
"expected controller of class ClassActionTestController to have class action :index"
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should fail if the controller's index action is not a class action" do
|
33
|
+
ClassActionTestController.class_eval do
|
34
|
+
def index
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
expect { expect(controller).to have_class_action(:index) }.to \
|
39
|
+
raise_error(
|
40
|
+
RSpec::Expectations::ExpectationNotMetError,
|
41
|
+
"expected action ClassActionTestController#index to be a class action"
|
42
|
+
)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should pass if the index action is a class action" do
|
46
|
+
ClassActionTestController.class_eval do
|
47
|
+
class_action :index
|
48
|
+
end
|
49
|
+
|
50
|
+
expect { expect(controller).to have_class_action(:index) }.not_to raise_error
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should fail if the controller's index action uses a different class" do
|
54
|
+
ClassActionTestController.class_eval do
|
55
|
+
class Index2 < ClassAction::Action
|
56
|
+
end
|
57
|
+
|
58
|
+
class_action :index2, Index2
|
59
|
+
end
|
60
|
+
|
61
|
+
expect { expect(controller).to have_class_action(:index2).using_class(ClassActionTestController::Index) }.to \
|
62
|
+
raise_error(
|
63
|
+
RSpec::Expectations::ExpectationNotMetError,
|
64
|
+
"expected action ClassActionTestController#index2 to use class ClassActionTestController::Index, but it used Index2"
|
65
|
+
)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|