surrogate 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/.rvmrc +7 -0
- data/Gemfile +4 -0
- data/Rakefile +1 -0
- data/Readme.md +54 -0
- data/lib/surrogate/api_comparer.rb +126 -0
- data/lib/surrogate/endower.rb +108 -0
- data/lib/surrogate/hatchery.rb +48 -0
- data/lib/surrogate/hatchling.rb +78 -0
- data/lib/surrogate/method_queue.rb +14 -0
- data/lib/surrogate/options.rb +28 -0
- data/lib/surrogate/rspec/api_method_matchers.rb +246 -0
- data/lib/surrogate/rspec/substitutability_matchers.rb +24 -0
- data/lib/surrogate/rspec.rb +2 -0
- data/lib/surrogate/version.rb +3 -0
- data/lib/surrogate.rb +17 -0
- data/spec/acceptance_spec.rb +131 -0
- data/spec/defining_api_methods_spec.rb +295 -0
- data/spec/rspec/have_been_asked_for_its_spec.rb +143 -0
- data/spec/rspec/have_been_initialized_with_spec.rb +29 -0
- data/spec/rspec/have_been_told_to_spec.rb +133 -0
- data/spec/rspec/messages_spec.rb +33 -0
- data/spec/rspec/substitute_for_spec.rb +73 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/unit/api_comparer_spec.rb +138 -0
- data/surrogate.gemspec +24 -0
- metadata +92 -0
@@ -0,0 +1,295 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'define' do
|
4
|
+
describe 'in the block' do
|
5
|
+
it 'is an api method for the class' do
|
6
|
+
pristine_klass = Class.new do
|
7
|
+
Surrogate.endow self do
|
8
|
+
define(:find) { 123 }
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
klass1 = pristine_klass.reprise
|
13
|
+
klass1.should_not have_been_told_to :find
|
14
|
+
klass1.find(1).should == 123
|
15
|
+
klass1.should have_been_told_to(:find).with(1)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
describe 'out of the block' do
|
21
|
+
let(:mocked_class) { Surrogate.endow Class.new }
|
22
|
+
let(:instance) { mocked_class.new }
|
23
|
+
|
24
|
+
it 'is an api method for the instance' do
|
25
|
+
mocked_class.define(:book) { 'book' }
|
26
|
+
instance.book.should == 'book'
|
27
|
+
end
|
28
|
+
|
29
|
+
describe 'declaring the behaviour' do
|
30
|
+
describe 'for verbs' do
|
31
|
+
before { mocked_class.define :wink }
|
32
|
+
|
33
|
+
describe 'will_<api_method>' do
|
34
|
+
it 'overrides the default value for the api method' do
|
35
|
+
mock1 = mocked_class.new
|
36
|
+
mock2 = mocked_class.new
|
37
|
+
mock1.will_wink :quickly
|
38
|
+
mock2.will_wink :slowly
|
39
|
+
mock1.wink.should == :quickly
|
40
|
+
mock2.wink.should == :slowly
|
41
|
+
mock1.wink.should == :quickly
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'returns the object' do
|
45
|
+
instance = mocked_class.new
|
46
|
+
instance.will_wink(:quickly).should equal instance
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe 'will_<api_method> with multiple arguments' do
|
51
|
+
it 'returns the object' do
|
52
|
+
instance = mocked_class.new
|
53
|
+
instance.will_wink(1, 2, 3).should equal instance
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'it creates a queue of things to find then returns to normal behaviour' do
|
57
|
+
specify 'when there is no default block' do
|
58
|
+
mock = mocked_class.new
|
59
|
+
mock.will_wink :quickly, :slowly
|
60
|
+
mock.wink.should == :quickly
|
61
|
+
mock.wink.should == :slowly
|
62
|
+
expect { mock.wink }.to raise_error Surrogate::UnpreparedMethodError
|
63
|
+
end
|
64
|
+
|
65
|
+
specify 'when there is a default block' do
|
66
|
+
mocked_class = Surrogate.endow(Class.new)
|
67
|
+
mocked_class.define(:connect) { :default }
|
68
|
+
mock = mocked_class.new
|
69
|
+
mock.will_connect 1, 2
|
70
|
+
mock.connect.should == 1
|
71
|
+
mock.connect.should == 2
|
72
|
+
mock.connect.should == :default
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
describe 'for nouns' do
|
80
|
+
before { mocked_class.define :age }
|
81
|
+
|
82
|
+
describe 'will_have_<api_method>' do
|
83
|
+
it 'defines will_have_<api_method> which overrides the default block' do
|
84
|
+
mock1 = mocked_class.new
|
85
|
+
mock2 = mocked_class.new
|
86
|
+
mock1.will_have_age 12
|
87
|
+
mock2.will_have_age 34
|
88
|
+
mock1.age.should == 12
|
89
|
+
mock2.age.should == 34
|
90
|
+
mock1.age.should == 12
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'returns the object' do
|
94
|
+
instance = mocked_class.new
|
95
|
+
instance.will_have_age(123).should equal instance
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe 'wil_have_<api_method> with multiple arguments' do
|
100
|
+
it 'returns the object' do
|
101
|
+
instance = mocked_class.new
|
102
|
+
instance.will_have_age(1,2,3).should equal instance
|
103
|
+
end
|
104
|
+
|
105
|
+
context 'it creates a queue of things to find then returns to normal behaviour' do
|
106
|
+
specify 'when there is no default block' do
|
107
|
+
mock = mocked_class.new
|
108
|
+
mock.will_have_age 12, 34
|
109
|
+
mock.age.should == 12
|
110
|
+
mock.age.should == 34
|
111
|
+
expect { mock.age }.to raise_error Surrogate::UnpreparedMethodError
|
112
|
+
end
|
113
|
+
|
114
|
+
specify 'when there is a default block' do
|
115
|
+
mocked_class = Surrogate.endow(Class.new)
|
116
|
+
mocked_class.define(:name) { 'default' }
|
117
|
+
mock = mocked_class.new
|
118
|
+
mock.will_have_name 'a', 'b'
|
119
|
+
mock.name.should == 'a'
|
120
|
+
mock.name.should == 'b'
|
121
|
+
mock.name.should == 'default'
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
|
129
|
+
|
130
|
+
context 'the api method' do
|
131
|
+
it 'takes any number of arguments' do
|
132
|
+
mocked_class.define(:meth) { 1 }
|
133
|
+
mocked_class.new.meth.should == 1
|
134
|
+
mocked_class.new.meth(1).should == 1
|
135
|
+
mocked_class.new.meth(1, 2).should == 1
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'raises an UnpreparedMethodError when it has no default block' do
|
139
|
+
mocked_class.define :meth
|
140
|
+
expect { mocked_class.new.meth }.to raise_error(Surrogate::UnpreparedMethodError, /meth/)
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'considers ivars of the same name to be its default' do
|
144
|
+
mocked_class.define :meth
|
145
|
+
mocked = mocked_class.new
|
146
|
+
mocked.instance_variable_set :@meth, 123
|
147
|
+
mocked.meth.should == 123
|
148
|
+
end
|
149
|
+
|
150
|
+
it 'reverts to the default block if invoked and having no ivar' do
|
151
|
+
mocked_class.define(:meth) { 123 }
|
152
|
+
mocked = mocked_class.new
|
153
|
+
mocked.instance_variable_get(:@meth).should be_nil
|
154
|
+
mocked.meth.should == 123
|
155
|
+
end
|
156
|
+
|
157
|
+
describe 'initialization' do
|
158
|
+
specify 'api methods can be an initialize method' do
|
159
|
+
mocked_class.define(:initialize) { @abc = 123 }
|
160
|
+
mocked_class.new.instance_variable_get(:@abc).should == 123
|
161
|
+
end
|
162
|
+
|
163
|
+
specify 'initialize exsits even if error is raised' do
|
164
|
+
mocked_class.define(:initialize) { raise "simulate runtime error" }
|
165
|
+
expect { mocked_class.new }.to raise_error(RuntimeError, /simulate/)
|
166
|
+
expect { mocked_class.new }.to raise_error(RuntimeError, /simulate/)
|
167
|
+
end
|
168
|
+
|
169
|
+
specify 'receives args' do
|
170
|
+
mocked_class.define(:initialize) { |num1, num2| @num = num1 + num2 }
|
171
|
+
mocked_class.new(25, 75).instance_variable_get(:@num).should == 100
|
172
|
+
end
|
173
|
+
|
174
|
+
specify 'even works with inheritance' do
|
175
|
+
superclass = Class.new
|
176
|
+
superclass.send(:define_method, :initialize) { @a = 1 }
|
177
|
+
subclass = Class.new superclass
|
178
|
+
mocked_subclass = Surrogate.endow Class.new subclass
|
179
|
+
mocked_subclass.define :abc
|
180
|
+
mocked_subclass.new.instance_variable_get(:@a).should == 1
|
181
|
+
end
|
182
|
+
|
183
|
+
context 'when not an api method' do
|
184
|
+
it 'respects arity (this is probably 1.9.3 only)' do
|
185
|
+
expect { mocked_class.new(1) }.to raise_error ArgumentError, 'wrong number of arguments(1 for 0)'
|
186
|
+
end
|
187
|
+
|
188
|
+
specify 'recorded regardless of when initialize is defined in relation to mock' do
|
189
|
+
klass = Class.new do
|
190
|
+
Surrogate.endow self
|
191
|
+
def initialize(a)
|
192
|
+
@a = a
|
193
|
+
end
|
194
|
+
end
|
195
|
+
klass.new(1).should have_been_initialized_with 1
|
196
|
+
klass.new(1).instance_variable_get(:@a).should == 1
|
197
|
+
|
198
|
+
klass = Class.new do
|
199
|
+
def initialize(a)
|
200
|
+
@a = a
|
201
|
+
end
|
202
|
+
Surrogate.endow self
|
203
|
+
end
|
204
|
+
klass.new(1).should have_been_initialized_with 1
|
205
|
+
klass.new(1).instance_variable_get(:@a).should == 1
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
describe 'it takes a block whos return value will be used as the default' do
|
211
|
+
specify 'the block is instance evaled' do
|
212
|
+
mocked_class.define(:meth) { self }
|
213
|
+
instance = mocked_class.new
|
214
|
+
instance.meth.should equal instance
|
215
|
+
end
|
216
|
+
|
217
|
+
specify 'arguments passed to the method will be passed to the block' do
|
218
|
+
mocked_class.define(:meth) { |*args| args }
|
219
|
+
instance = mocked_class.new
|
220
|
+
instance.meth(1).should == [1]
|
221
|
+
instance.meth(1, 2).should == [1, 2]
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
it 'remembers what it was invoked with' do
|
226
|
+
mocked_class.define(:meth) { nil }
|
227
|
+
mock = mocked_class.new
|
228
|
+
mock.meth 1
|
229
|
+
mock.meth 1, 2
|
230
|
+
mock.meth [1, 2]
|
231
|
+
mock.invocations(:meth).should == [
|
232
|
+
[1],
|
233
|
+
[1, 2],
|
234
|
+
[[1, 2]],
|
235
|
+
]
|
236
|
+
end
|
237
|
+
|
238
|
+
it 'raises an error if asked about invocations for api methods it does not know' do
|
239
|
+
mocked_class.define :meth1
|
240
|
+
mocked_class.define :meth2
|
241
|
+
mock = mocked_class.new
|
242
|
+
expect { mock.invocations(:meth1) }.to_not raise_error
|
243
|
+
expect { mock.invocations(:meth3) }.to raise_error Surrogate::UnknownMethod, /doesn't know "meth3", only knows "initialize", "meth1", "meth2"/
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
|
249
|
+
describe 'reprise' do
|
250
|
+
it 'a repetition or further performance of the klass' do
|
251
|
+
pristine_klass = Class.new do
|
252
|
+
Surrogate.endow self do
|
253
|
+
define(:find) { 123 }
|
254
|
+
define(:bind) { 'abc' }
|
255
|
+
end
|
256
|
+
define(:peat) { true }
|
257
|
+
define(:repeat) { 321 }
|
258
|
+
end
|
259
|
+
|
260
|
+
klass1 = pristine_klass.reprise
|
261
|
+
klass1.should_not have_been_told_to :find
|
262
|
+
klass1.find(1).should == 123
|
263
|
+
klass1.should have_been_told_to(:find).with(1)
|
264
|
+
klass1.bind.should == 'abc'
|
265
|
+
|
266
|
+
klass2 = pristine_klass.reprise
|
267
|
+
klass2.will_find 456
|
268
|
+
klass2.find(2).should == 456
|
269
|
+
klass1.find.should == 123
|
270
|
+
|
271
|
+
klass1.should have_been_told_to(:find).with(1)
|
272
|
+
klass2.should have_been_told_to(:find).with(2)
|
273
|
+
klass1.should_not have_been_told_to(:find).with(2)
|
274
|
+
klass2.should_not have_been_told_to(:find).with(1)
|
275
|
+
|
276
|
+
klass1.new.peat.should == true
|
277
|
+
klass1.new.repeat.should == 321
|
278
|
+
end
|
279
|
+
|
280
|
+
it 'is a subclass of the reprised class' do
|
281
|
+
superclass = Surrogate.endow Class.new
|
282
|
+
superclass.reprise.new.should be_a_kind_of superclass
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
describe '#api_method_names' do
|
287
|
+
it 'returns the names of the api methods as symbols' do
|
288
|
+
mocked_class = Class.new do
|
289
|
+
Surrogate.endow self
|
290
|
+
define :abc
|
291
|
+
end
|
292
|
+
mocked_class.api_method_names.should == [:abc]
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'RSpec matchers', 'have_been_asked_for_its' do
|
4
|
+
let(:mocked_class) { Surrogate.endow Class.new }
|
5
|
+
let(:instance) { mocked_class.new }
|
6
|
+
|
7
|
+
describe 'default use case' do
|
8
|
+
before { mocked_class.define :name, default: 'Ayaan' }
|
9
|
+
|
10
|
+
example 'passes if has been invoked at least once' do
|
11
|
+
instance.should_not have_been_asked_for_its :name
|
12
|
+
instance.name
|
13
|
+
instance.should have_been_asked_for_its :name
|
14
|
+
instance.name
|
15
|
+
instance.should have_been_asked_for_its :name
|
16
|
+
end
|
17
|
+
|
18
|
+
example 'failure message for should' do
|
19
|
+
expect { instance.should have_been_asked_for_its :name }.to \
|
20
|
+
raise_error(RSpec::Expectations::ExpectationNotMetError, /was never asked for its name/)
|
21
|
+
end
|
22
|
+
|
23
|
+
example 'failure message for should not' do
|
24
|
+
instance.name
|
25
|
+
expect { instance.should_not have_been_asked_for_its :name }.to \
|
26
|
+
raise_error(RSpec::Expectations::ExpectationNotMetError, /shouldn't have been asked for its name, but was asked 1 time/)
|
27
|
+
|
28
|
+
instance.name
|
29
|
+
expect { instance.should_not have_been_asked_for_its :name }.to \
|
30
|
+
raise_error(RSpec::Expectations::ExpectationNotMetError, /shouldn't have been asked for its name, but was asked 2 times/)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
describe 'specifying which arguments it should have been invoked with' do
|
36
|
+
before { mocked_class.define :size, default: nil }
|
37
|
+
|
38
|
+
example 'default use case' do
|
39
|
+
instance.should_not have_been_asked_for_its(:size).with(1, 2, 3)
|
40
|
+
instance.size 1, 2
|
41
|
+
instance.should_not have_been_asked_for_its(:size).with(1, 2, 3)
|
42
|
+
instance.size 1, 2, 3
|
43
|
+
instance.should have_been_asked_for_its(:size).with(1, 2, 3)
|
44
|
+
end
|
45
|
+
|
46
|
+
example 'failure message for should' do
|
47
|
+
expect { instance.should have_been_asked_for_its(:size).with(1, '2') }.to \
|
48
|
+
raise_error(RSpec::Expectations::ExpectationNotMetError, /should have been asked for its size with `1, "2"', but was never asked/)
|
49
|
+
|
50
|
+
instance.size 3
|
51
|
+
instance.size 4, '5'
|
52
|
+
expect { instance.should have_been_asked_for_its(:size).with(1, '2') }.to \
|
53
|
+
raise_error(RSpec::Expectations::ExpectationNotMetError, /should have been asked for its size with `1, "2"', but got `3', `4, "5"'/)
|
54
|
+
end
|
55
|
+
|
56
|
+
example 'failure message for should not' do
|
57
|
+
instance.size 1, '2'
|
58
|
+
expect { instance.should_not have_been_asked_for_its(:size).with(1, '2') }.to \
|
59
|
+
raise_error(RSpec::Expectations::ExpectationNotMetError, /should not have been asked for its size with `1, "2"'/)
|
60
|
+
end
|
61
|
+
|
62
|
+
describe 'integration with rspec argument_matchers' do
|
63
|
+
it 'works with no_args' do
|
64
|
+
instance.should_not have_been_asked_for_its(:size).with(no_args)
|
65
|
+
instance.size(1)
|
66
|
+
instance.should_not have_been_asked_for_its(:size).with(no_args)
|
67
|
+
instance.size
|
68
|
+
instance.should have_been_asked_for_its(:size).with(no_args)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
describe 'specifying number of times invoked' do
|
75
|
+
before { mocked_class.define :value, default: nil }
|
76
|
+
|
77
|
+
example 'default use case' do
|
78
|
+
instance.should have_been_asked_for_its(:value).times(0)
|
79
|
+
instance.value
|
80
|
+
instance.should have_been_asked_for_its(:value).times(1)
|
81
|
+
instance.value
|
82
|
+
instance.should have_been_asked_for_its(:value).times(2)
|
83
|
+
end
|
84
|
+
|
85
|
+
example 'failure message for should' do
|
86
|
+
expect { instance.should have_been_asked_for_its(:value).times(1) }.to \
|
87
|
+
raise_error(RSpec::Expectations::ExpectationNotMetError, /should have been asked for its value 1 time, but was asked 0 times/)
|
88
|
+
|
89
|
+
instance.value
|
90
|
+
expect { instance.should have_been_asked_for_its(:value).times(2) }.to \
|
91
|
+
raise_error(RSpec::Expectations::ExpectationNotMetError, /should have been asked for its value 2 times, but was asked 1 time/)
|
92
|
+
end
|
93
|
+
|
94
|
+
example 'failure message for should not' do
|
95
|
+
expect { instance.should_not have_been_asked_for_its(:value).times(0) }.to \
|
96
|
+
raise_error(RSpec::Expectations::ExpectationNotMetError, /shouldn't have been asked for its value 0 times, but was/)
|
97
|
+
|
98
|
+
instance.value
|
99
|
+
expect { instance.should_not have_been_asked_for_its(:value).times(1) }.to \
|
100
|
+
raise_error(RSpec::Expectations::ExpectationNotMetError, /shouldn't have been asked for its value 1 time, but was/)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe 'conjunction of with(args) and times(n)' do
|
105
|
+
before { mocked_class.define :value, default: nil }
|
106
|
+
|
107
|
+
example 'default use case' do
|
108
|
+
instance.should have_been_asked_for_its(:value).times(0).with(1, '2')
|
109
|
+
instance.should_not have_been_asked_for_its(:value).times(1).with(1, '2')
|
110
|
+
instance.value
|
111
|
+
instance.should have_been_asked_for_its(:value).times(0).with(1, '2')
|
112
|
+
instance.should_not have_been_asked_for_its(:value).times(1).with(1, '2')
|
113
|
+
instance.value 1, '2'
|
114
|
+
instance.should have_been_asked_for_its(:value).times(1).with(1, '2')
|
115
|
+
instance.value 1, '2' # correct one
|
116
|
+
instance.value 1, '3'
|
117
|
+
instance.value 2, '2'
|
118
|
+
instance.value 1, '2', 3
|
119
|
+
instance.should have_been_asked_for_its(:value).times(2).with(1, '2')
|
120
|
+
instance.should have_been_asked_for_its(:value).with(1, '2').times(2)
|
121
|
+
end
|
122
|
+
|
123
|
+
example 'failure message for should' do
|
124
|
+
expect { instance.should have_been_asked_for_its(:value).times(1).with(1, '2') }.to \
|
125
|
+
raise_error(RSpec::Expectations::ExpectationNotMetError, /should have been asked for its value 1 time with `1, "2"', but was never asked/)
|
126
|
+
|
127
|
+
instance.value 1, '2'
|
128
|
+
expect { instance.should have_been_asked_for_its(:value).times(0).with(1, '2') }.to \
|
129
|
+
raise_error(RSpec::Expectations::ExpectationNotMetError, /should have been asked for its value 0 times with `1, "2"', but was asked 1 time/)
|
130
|
+
|
131
|
+
instance.value 1, '2'
|
132
|
+
expect { instance.should have_been_asked_for_its(:value).times(1).with(1, '2') }.to \
|
133
|
+
raise_error(RSpec::Expectations::ExpectationNotMetError, /should have been asked for its value 1 time with `1, "2"', but was asked 2 times/)
|
134
|
+
end
|
135
|
+
|
136
|
+
example 'failure message for should not' do
|
137
|
+
instance.value 1, '2'
|
138
|
+
instance.value 1, '2'
|
139
|
+
expect { instance.should_not have_been_asked_for_its(:value).times(2).with(1, '2') }.to \
|
140
|
+
raise_error(RSpec::Expectations::ExpectationNotMetError, /should not have been asked for its value 2 times with `1, "2"'/)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'RSpec matchers', 'have_been_initialized_with' do
|
4
|
+
let(:mocked_class) { Surrogate.endow Class.new }
|
5
|
+
before { mocked_class.module_eval { def initialize(*) end } } # b/c 1.9.3 will have arity issues otherwise
|
6
|
+
|
7
|
+
it 'is the same as have_been_told_to(:initialize).with(...)' do
|
8
|
+
mocked_class.new.should have_been_initialized_with no_args
|
9
|
+
mocked_class.new.should_not have_been_initialized_with(1)
|
10
|
+
mocked_class.new(1).should have_been_initialized_with 1
|
11
|
+
mocked_class.new(1, '2').should have_been_initialized_with 1, '2'
|
12
|
+
end
|
13
|
+
|
14
|
+
def failure_message_for
|
15
|
+
yield
|
16
|
+
rescue RSpec::Expectations::ExpectationNotMetError
|
17
|
+
$!.message
|
18
|
+
end
|
19
|
+
|
20
|
+
example 'failure message for should' do
|
21
|
+
failure_message_for { mocked_class.new("1").should have_been_initialized_with 2 }.should ==
|
22
|
+
failure_message_for { mocked_class.new("1").should have_been_told_to(:initialize).with(2) }
|
23
|
+
end
|
24
|
+
|
25
|
+
example 'failure message for should not' do
|
26
|
+
failure_message_for { mocked_class.new("1").should_not have_been_initialized_with('1') }.should ==
|
27
|
+
failure_message_for { mocked_class.new("1").should_not have_been_told_to(:initialize).with('1') }
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'RSpec matchers', 'have_been_told_to' do
|
4
|
+
let(:mocked_class) { Surrogate.endow Class.new }
|
5
|
+
let(:instance) { mocked_class.new }
|
6
|
+
|
7
|
+
describe 'default use case' do
|
8
|
+
before { mocked_class.define :kick, default: [] }
|
9
|
+
|
10
|
+
example 'passes if has been invoked at least once' do
|
11
|
+
instance.should_not have_been_told_to :kick
|
12
|
+
instance.kick
|
13
|
+
instance.should have_been_told_to :kick
|
14
|
+
instance.kick
|
15
|
+
instance.should have_been_told_to :kick
|
16
|
+
end
|
17
|
+
|
18
|
+
example 'failure message for should' do
|
19
|
+
expect { instance.should have_been_told_to :kick }.to \
|
20
|
+
raise_error(RSpec::Expectations::ExpectationNotMetError, /was never told to kick/)
|
21
|
+
end
|
22
|
+
|
23
|
+
example 'failure message for should not' do
|
24
|
+
instance.kick
|
25
|
+
expect { instance.should_not have_been_told_to :kick }.to \
|
26
|
+
raise_error(RSpec::Expectations::ExpectationNotMetError, /shouldn't have been told to kick, but was told to kick 1 time/)
|
27
|
+
|
28
|
+
instance.kick
|
29
|
+
expect { instance.should_not have_been_told_to :kick }.to \
|
30
|
+
raise_error(RSpec::Expectations::ExpectationNotMetError, /shouldn't have been told to kick, but was told to kick 2 times/)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
describe 'specifying which arguments it should have been invoked with' do
|
36
|
+
before { mocked_class.define :smile, default: nil }
|
37
|
+
|
38
|
+
example 'default use case' do
|
39
|
+
instance.should_not have_been_told_to(:smile).with(1, 2, 3)
|
40
|
+
instance.smile 1, 2
|
41
|
+
instance.should_not have_been_told_to(:smile).with(1, 2, 3)
|
42
|
+
instance.smile 1, 2, 3
|
43
|
+
instance.should have_been_told_to(:smile).with(1, 2, 3)
|
44
|
+
end
|
45
|
+
|
46
|
+
example 'failure message for should' do
|
47
|
+
expect { instance.should have_been_told_to(:smile).with(1, '2') }.to \
|
48
|
+
raise_error(RSpec::Expectations::ExpectationNotMetError, /should have been told to smile with `1, "2"', but was never told to/)
|
49
|
+
|
50
|
+
instance.smile 3
|
51
|
+
instance.smile 4, '5'
|
52
|
+
expect { instance.should have_been_told_to(:smile).with(1, '2') }.to \
|
53
|
+
raise_error(RSpec::Expectations::ExpectationNotMetError, /should have been told to smile with `1, "2"', but got `3', `4, "5"'/)
|
54
|
+
end
|
55
|
+
|
56
|
+
example 'failure message for should not' do
|
57
|
+
instance.smile 1, '2'
|
58
|
+
expect { instance.should_not have_been_told_to(:smile).with(1, '2') }.to \
|
59
|
+
raise_error(RSpec::Expectations::ExpectationNotMetError, /should not have been told to smile with `1, "2"'/)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
describe 'specifying number of times invoked' do
|
65
|
+
before { mocked_class.define :wink, default: nil }
|
66
|
+
|
67
|
+
example 'default use case' do
|
68
|
+
instance.should have_been_told_to(:wink).times(0)
|
69
|
+
instance.wink
|
70
|
+
instance.should have_been_told_to(:wink).times(1)
|
71
|
+
instance.wink
|
72
|
+
instance.should have_been_told_to(:wink).times(2)
|
73
|
+
end
|
74
|
+
|
75
|
+
example 'failure message for should' do
|
76
|
+
expect { instance.should have_been_told_to(:wink).times(1) }.to \
|
77
|
+
raise_error(RSpec::Expectations::ExpectationNotMetError, /should have been told to wink 1 time but was told to wink 0 times/)
|
78
|
+
|
79
|
+
instance.wink
|
80
|
+
expect { instance.should have_been_told_to(:wink).times(2) }.to \
|
81
|
+
raise_error(RSpec::Expectations::ExpectationNotMetError, /should have been told to wink 2 times but was told to wink 1 time/)
|
82
|
+
end
|
83
|
+
|
84
|
+
example 'failure message for should not' do
|
85
|
+
expect { instance.should_not have_been_told_to(:wink).times(0) }.to \
|
86
|
+
raise_error(RSpec::Expectations::ExpectationNotMetError, /shouldn't have been told to wink 0 times, but was/)
|
87
|
+
|
88
|
+
instance.wink
|
89
|
+
expect { instance.should_not have_been_told_to(:wink).times(1) }.to \
|
90
|
+
raise_error(RSpec::Expectations::ExpectationNotMetError, /shouldn't have been told to wink 1 time, but was/)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe 'conjunction of with(args) and times(n)' do
|
95
|
+
before { mocked_class.define :wink, default: nil }
|
96
|
+
|
97
|
+
example 'default use case' do
|
98
|
+
instance.should have_been_told_to(:wink).times(0).with(1, '2')
|
99
|
+
instance.should_not have_been_told_to(:wink).times(1).with(1, '2')
|
100
|
+
instance.wink
|
101
|
+
instance.should have_been_told_to(:wink).times(0).with(1, '2')
|
102
|
+
instance.should_not have_been_told_to(:wink).times(1).with(1, '2')
|
103
|
+
instance.wink 1, '2'
|
104
|
+
instance.should have_been_told_to(:wink).times(1).with(1, '2')
|
105
|
+
instance.wink 1, '2' # correct one
|
106
|
+
instance.wink 1, '3'
|
107
|
+
instance.wink 2, '2'
|
108
|
+
instance.wink 1, '2', 3
|
109
|
+
instance.should have_been_told_to(:wink).times(2).with(1, '2')
|
110
|
+
instance.should have_been_told_to(:wink).with(1, '2').times(2)
|
111
|
+
end
|
112
|
+
|
113
|
+
example 'failure message for should' do
|
114
|
+
expect { instance.should have_been_told_to(:wink).times(1).with(1, '2') }.to \
|
115
|
+
raise_error(RSpec::Expectations::ExpectationNotMetError, /should have been told to wink 1 time with `1, "2"', but was never told to/)
|
116
|
+
|
117
|
+
instance.wink 1, '2'
|
118
|
+
expect { instance.should have_been_told_to(:wink).times(0).with(1, '2') }.to \
|
119
|
+
raise_error(RSpec::Expectations::ExpectationNotMetError, /should have been told to wink 0 times with `1, "2"', but got it 1 time/)
|
120
|
+
|
121
|
+
instance.wink 1, '2'
|
122
|
+
expect { instance.should have_been_told_to(:wink).times(1).with(1, '2') }.to \
|
123
|
+
raise_error(RSpec::Expectations::ExpectationNotMetError, /should have been told to wink 1 time with `1, "2"', but got it 2 times/)
|
124
|
+
end
|
125
|
+
|
126
|
+
example 'failure message for should not' do
|
127
|
+
instance.wink 1, '2'
|
128
|
+
instance.wink 1, '2'
|
129
|
+
expect { instance.should_not have_been_told_to(:wink).times(2).with(1, '2') }.to \
|
130
|
+
raise_error(RSpec::Expectations::ExpectationNotMetError, /should not have been told to wink 2 times with `1, "2"'/)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
messages_for = Surrogate::RSpec::MessagesFor
|
4
|
+
|
5
|
+
describe messages_for, 'argument inspection' do
|
6
|
+
|
7
|
+
describe 'individual argument inspection inspection' do
|
8
|
+
it 'inspects non RSpec matchers as their default inspection' do
|
9
|
+
messages_for.inspect_argument("1").should == '"1"'
|
10
|
+
messages_for.inspect_argument(1).should == "1"
|
11
|
+
messages_for.inspect_argument([/a/]).should == "[/a/]"
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'inspects no_args matcher' do
|
15
|
+
messages_for.inspect_argument(no_args).should == 'no_args'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
describe 'multiple argument inspection' do
|
21
|
+
it "wraps individual arguments in `'" do
|
22
|
+
messages_for.inspect_arguments([/a/]).should == "`/a/'"
|
23
|
+
end
|
24
|
+
|
25
|
+
it "joins arguments with commas" do
|
26
|
+
messages_for.inspect_arguments(['x', no_args]).should == "`\"x\", no_args'"
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'returns no_args when the array is empty' do
|
30
|
+
messages_for.inspect_arguments([]).should == "`no_args'"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|