surrogate 0.5.5 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.rvmrc +0 -3
- data/Changelog.md +21 -0
- data/Readme.md +64 -76
- data/Readme.md.mountain_berry_fields +70 -77
- data/gemfiles/rspec_mocks_2.11 +1 -1
- data/lib/surrogate.rb +1 -1
- data/lib/surrogate/api_comparer.rb +59 -61
- data/lib/surrogate/argument_errorizer.rb +43 -0
- data/lib/surrogate/endower.rb +41 -37
- data/lib/surrogate/hatchery.rb +6 -1
- data/lib/surrogate/hatchling.rb +5 -0
- data/lib/surrogate/method_definition.rb +55 -0
- data/lib/surrogate/porc_reflector.rb +43 -0
- data/lib/surrogate/rspec/invocation_matcher.rb +2 -1
- data/lib/surrogate/rspec/substitute_for.rb +23 -7
- data/lib/surrogate/rspec/with_filter.rb +0 -1
- data/lib/surrogate/surrogate_class_reflector.rb +65 -0
- data/lib/surrogate/surrogate_instance_reflector.rb +15 -0
- data/lib/surrogate/version.rb +1 -1
- data/spec/acceptance_spec.rb +1 -1
- data/spec/defining_api_methods_spec.rb +51 -77
- data/spec/other_shit_spec.rb +131 -0
- data/spec/rspec/block_support_spec.rb +2 -2
- data/spec/rspec/initialization_matcher_spec.rb +12 -4
- data/spec/rspec/rspec_mocks_integration_spec.rb +1 -1
- data/spec/rspec/substitute_for_spec.rb +90 -4
- data/spec/unit/api_comparer_spec.rb +120 -4
- data/spec/unit/argument_errorizer_spec.rb +50 -0
- data/surrogate.gemspec +0 -2
- data/todo +44 -0
- metadata +21 -24
- data/lib/surrogate/options.rb +0 -41
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
# these all need error messages
|
4
4
|
describe 'RSpec matchers', 'have_been_told_to(...).with { |block| }' do
|
5
5
|
|
6
|
-
let(:dir) { Surrogate.endow(Class.new) { define(:chdir) { nil }}}
|
6
|
+
let(:dir) { Surrogate.endow(Class.new) { define(:chdir) { |dir_path| nil }}}
|
7
7
|
let(:dir_path) { '/some/dir/path' }
|
8
8
|
|
9
9
|
it 'fails if no submitted_blocks were found' do
|
@@ -57,7 +57,7 @@ describe 'RSpec matchers', 'have_been_told_to(...).with { |block| }' do
|
|
57
57
|
end
|
58
58
|
|
59
59
|
|
60
|
-
let(:file) { Surrogate.endow(Class.new) { define(:write) { true }}}
|
60
|
+
let(:file) { Surrogate.endow(Class.new) { define(:write) { |name, body| true }}}
|
61
61
|
let(:file_name) { 'some_file_name.ext' }
|
62
62
|
let(:file_body) { 'some file body' }
|
63
63
|
|
@@ -1,8 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe 'should/should_not have_been_initialized_with' do
|
4
|
-
let(:mocked_class) { Surrogate.endow
|
5
|
-
before { mocked_class.module_eval { def initialize(*) end } } # b/c 1.9.3 will have arity issues otherwise
|
4
|
+
let(:mocked_class) { Surrogate.endow(Class.new).define(:initialize) { |*| } }
|
6
5
|
|
7
6
|
it 'is the same as have_been_told_to(:initialize).with(...)' do
|
8
7
|
mocked_class.new.should have_been_initialized_with no_args
|
@@ -26,11 +25,15 @@ describe 'should/should_not have_been_initialized_with' do
|
|
26
25
|
failure_message_for { mocked_class.new("1").should_not have_been_initialized_with('1') }.should ==
|
27
26
|
failure_message_for { mocked_class.new("1").should_not have_been_told_to(:initialize).with('1') }
|
28
27
|
end
|
28
|
+
|
29
|
+
example "informs you when it wasn't defined" do
|
30
|
+
expect { Surrogate.endow(Class.new).new.should have_been_initialized_with no_args }
|
31
|
+
.to raise_error Surrogate::UnknownMethod
|
32
|
+
end
|
29
33
|
end
|
30
34
|
|
31
35
|
describe 'was/was_not initialized_with' do
|
32
|
-
let(:mocked_class) { Surrogate.endow
|
33
|
-
before { mocked_class.module_eval { def initialize(*) end } } # b/c 1.9.3 will have arity issues otherwise
|
36
|
+
let(:mocked_class) { Surrogate.endow(Class.new).define(:initialize) { |*| } }
|
34
37
|
|
35
38
|
it 'is the same as have_been_told_to(:initialize).with(...)' do
|
36
39
|
mocked_class.new.was initialized_with no_args
|
@@ -54,4 +57,9 @@ describe 'was/was_not initialized_with' do
|
|
54
57
|
failure_message_for { mocked_class.new("1").was_not initialized_with('1') }.should ==
|
55
58
|
failure_message_for { mocked_class.new("1").was_not told_to(:initialize).with('1') }
|
56
59
|
end
|
60
|
+
|
61
|
+
example "informs you when it wasn't defined" do
|
62
|
+
expect { Surrogate.endow(Class.new).new.was initialized_with no_args }
|
63
|
+
.to raise_error Surrogate::UnknownMethod
|
64
|
+
end
|
57
65
|
end
|
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe 'integration with rspec-mocks' do
|
4
4
|
|
5
|
-
let(:mp3) { Surrogate.endow(Class.new).define(:play) { }.new }
|
5
|
+
let(:mp3) { Surrogate.endow(Class.new).define(:play) { |artist| }.new }
|
6
6
|
|
7
7
|
it 'knows that rspec-mocks is loaded' do
|
8
8
|
Surrogate::RSpec.rspec_mocks_loaded?.should equal true
|
@@ -102,9 +102,9 @@ describe 'substitute_for' do
|
|
102
102
|
surrogate = Surrogate.endow(Class.new) { define :surrogate_class_meth }.define :surrogate_instance_meth
|
103
103
|
klass = Class.new { def self.api_class_meth()end; def api_instance_meth() end }
|
104
104
|
expect { surrogate.should substitute_for klass }.to \
|
105
|
-
raise_error(RSpec::Expectations::ExpectationNotMetError, "Was not substitutable because surrogate has extra instance methods: [:surrogate_instance_meth]
|
106
|
-
"has extra class methods: [:surrogate_class_meth]
|
107
|
-
"is missing instance methods: [:api_instance_meth]
|
105
|
+
raise_error(RSpec::Expectations::ExpectationNotMetError, "Was not substitutable because surrogate has extra instance methods: [:surrogate_instance_meth]\n"\
|
106
|
+
"has extra class methods: [:surrogate_class_meth]\n"\
|
107
|
+
"is missing instance methods: [:api_instance_meth]\n"\
|
108
108
|
"is missing class methods: [:api_class_meth]")
|
109
109
|
end
|
110
110
|
|
@@ -145,7 +145,93 @@ describe 'substitute_for' do
|
|
145
145
|
klass = Class.new { def self.extra_method()end; def extra_method()end }
|
146
146
|
expect { Surrogate.endow(Class.new) { define :class_meth }.define(:instance_meth).should substitute_for klass, subset: true }.to \
|
147
147
|
raise_error(RSpec::Expectations::ExpectationNotMetError,
|
148
|
-
"Was not substitutable because surrogate has extra instance methods: [:instance_meth]
|
148
|
+
"Was not substitutable because surrogate has extra instance methods: [:instance_meth]\nhas extra class methods: [:class_meth]")
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
|
154
|
+
|
155
|
+
context 'type substitutability -- specified with types: true/false option (DEFAULTS TO TRUE)' do
|
156
|
+
it 'is turned on by default' do
|
157
|
+
klass = Class.new { def instance_meth(a) end }
|
158
|
+
surrogate = Surrogate.endow(Class.new).define(:instance_meth) { }
|
159
|
+
surrogate.should_not substitute_for klass
|
160
|
+
surrogate.should substitute_for klass, types: false
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'disregards when argument names differ' do
|
164
|
+
klass = Class.new { def instance_meth(a) end }
|
165
|
+
surrogate = Surrogate.endow(Class.new).define(:instance_meth) { |b| }
|
166
|
+
surrogate.should substitute_for klass, names: false, types: true
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'disregards when surrogate has no body for an api method' do
|
170
|
+
klass = Class.new { def instance_meth(a) end }
|
171
|
+
surrogate = Surrogate.endow(Class.new).define :instance_meth
|
172
|
+
surrogate.should substitute_for klass, types: true
|
173
|
+
end
|
174
|
+
|
175
|
+
it 'disregards when real object has natively implemented methods that cannot be reflected on' do
|
176
|
+
Array.method(:[]).parameters.should == [[:rest]] # make sure Array signatures aren't changing across versions or something
|
177
|
+
Array.instance_method(:insert).parameters.should == [[:rest]]
|
178
|
+
surrogate = Surrogate.endow(Class.new) { define(:[]) { |a,b,c| } }.define(:insert) { |a,b,c| }
|
179
|
+
surrogate.should substitute_for Array, subset: true, types: true
|
180
|
+
end
|
181
|
+
|
182
|
+
context 'returns true if argument types match exactly. Examples:' do
|
183
|
+
example 'true when exact match' do
|
184
|
+
klass = Class.new { def instance_meth(a, b=1, *c, d, &e) end }
|
185
|
+
surrogate = Surrogate.endow(Class.new).define(:instance_meth) { |a, b=1, *c, d, &e| }
|
186
|
+
surrogate.should substitute_for klass, types: true
|
187
|
+
end
|
188
|
+
|
189
|
+
example 'false when missing block' do
|
190
|
+
klass = Class.new { def instance_meth(a, b=1, *c, d) end }
|
191
|
+
surrogate = Surrogate.endow(Class.new).define(:instance_meth) { |a, b=1, *c, d, &e| }
|
192
|
+
surrogate.should_not substitute_for klass, types: true
|
193
|
+
|
194
|
+
klass = Class.new { def instance_meth(a, b=1, *c, d, &e) end }
|
195
|
+
surrogate = Surrogate.endow(Class.new).define(:instance_meth) { |a, b=1, *c, d| }
|
196
|
+
surrogate.should_not substitute_for klass, types: true
|
197
|
+
end
|
198
|
+
|
199
|
+
example 'false when missing splatted args' do
|
200
|
+
klass = Class.new { def instance_meth(a, b=1, d, &e) end }
|
201
|
+
surrogate = Surrogate.endow(Class.new).define(:instance_meth) { |a, b=1, *c, d, &e| }
|
202
|
+
surrogate.should_not substitute_for klass, types: true
|
203
|
+
|
204
|
+
klass = Class.new { def instance_meth(a, b=1, *c, d, &e) end }
|
205
|
+
surrogate = Surrogate.endow(Class.new).define(:instance_meth) { |a, b=1, d, &e| }
|
206
|
+
surrogate.should_not substitute_for klass
|
207
|
+
end
|
208
|
+
|
209
|
+
example 'false when missing optional args' do
|
210
|
+
klass = Class.new { def instance_meth(a, *c, d, &e) end }
|
211
|
+
surrogate = Surrogate.endow(Class.new).define(:instance_meth) { |a, b=1, *c, d, &e| }
|
212
|
+
surrogate.should_not substitute_for klass
|
213
|
+
|
214
|
+
klass = Class.new { def instance_meth(a, b=1, *c, d, &e) end }
|
215
|
+
surrogate = Surrogate.endow(Class.new).define(:instance_meth) { |a, *c, d, &e| }
|
216
|
+
surrogate.should_not substitute_for klass, types: true
|
217
|
+
end
|
218
|
+
|
219
|
+
example 'false when missing required args' do
|
220
|
+
klass = Class.new { def instance_meth(b=1, *c, d, &e) end }
|
221
|
+
surrogate = Surrogate.endow(Class.new).define(:instance_meth) { |a, b=1, *c, d, &e| }
|
222
|
+
surrogate.should_not substitute_for klass, types: true
|
223
|
+
|
224
|
+
klass = Class.new { def instance_meth(a, b=1, *c, d, &e) end }
|
225
|
+
surrogate = Surrogate.endow(Class.new).define(:instance_meth) { |b=1, *c, d, &e| }
|
226
|
+
surrogate.should_not substitute_for klass, types: true
|
227
|
+
|
228
|
+
klass = Class.new { def instance_meth(a, b=1, *c, &e) end }
|
229
|
+
surrogate = Surrogate.endow(Class.new).define(:instance_meth) { |a, b=1, *c, d, &e| }
|
230
|
+
surrogate.should_not substitute_for klass, types: true
|
231
|
+
|
232
|
+
klass = Class.new { def instance_meth(a, b=1, *c, d, &e) end }
|
233
|
+
surrogate = Surrogate.endow(Class.new).define(:instance_meth) { |a, b=1, *c, &e| }
|
234
|
+
surrogate.should_not substitute_for klass, types: true
|
149
235
|
end
|
150
236
|
end
|
151
237
|
end
|
@@ -3,33 +3,47 @@ require 'spec_helper'
|
|
3
3
|
describe Surrogate::ApiComparer do
|
4
4
|
|
5
5
|
def set_assertion(set, expectations)
|
6
|
-
expectations[:include].each { |meth| set.should include meth }
|
7
|
-
expectations[:exclude].each { |meth| set.should_not include meth }
|
6
|
+
Array(expectations[:include]).each { |meth| set.should include meth }
|
7
|
+
Array(expectations[:exclude]).each { |meth| set.should_not include meth }
|
8
8
|
end
|
9
9
|
|
10
|
+
context 'when identifying types' do
|
11
|
+
it 'uses :req, :opt, :rest, and :block' do
|
12
|
+
surrogate = Surrogate.endow(Class.new).define(:to_s) { |a, b, c, d=1, e=2, *f, g, &h| }
|
13
|
+
comparer = described_class.new(surrogate, Class.new)
|
14
|
+
comparer.compare[:instance][:types][:to_s][:surrogate].should ==
|
15
|
+
[:req, :req, :req, :opt, :opt, :rest, :req, :block]
|
16
|
+
end
|
17
|
+
end
|
10
18
|
|
11
19
|
describe 'its knowlege about the surrogate' do
|
12
20
|
|
13
21
|
let :surrogate do
|
14
22
|
parent = Class.new do
|
15
23
|
def inherited_instance_meth()end
|
24
|
+
def inherited_instance_meth_with_signature(a1, b1=1, *c1, d1, &e1)end
|
16
25
|
def self.inherited_class_meth()end
|
26
|
+
def self.inherited_class_meth_with_signature(a2, b2=1, *c2, d2, &e2)end
|
17
27
|
end
|
18
28
|
|
19
29
|
Class.new parent do
|
20
30
|
Surrogate.endow self do
|
21
31
|
define :api_class_meth
|
32
|
+
define(:api_class_meth_with_signature) { |a3, b3=1, *c3, d3, &e3| }
|
22
33
|
def class_meth()end
|
34
|
+
def self.class_meth_with_signature(a4, b4=1, *c4, d4, &e4)end
|
23
35
|
end
|
24
36
|
define :api_instance_meth
|
37
|
+
define(:api_instance_meth_with_signature) { |a5, b5=1, *c5, d5, &e5| }
|
25
38
|
def instance_meth()end
|
39
|
+
def instance_meth_with_signature(a6, b6=1, *c6, d6, &e6)end
|
26
40
|
end
|
27
41
|
end
|
28
42
|
|
29
43
|
let(:comparer) { described_class.new surrogate, Class.new }
|
30
44
|
|
31
45
|
it "knows the surrogate's instance level api methods" do
|
32
|
-
comparer.surrogate_methods[:instance][:api].should == Set[:api_instance_meth]
|
46
|
+
comparer.surrogate_methods[:instance][:api].should == Set[:api_instance_meth, :api_instance_meth_with_signature]
|
33
47
|
end
|
34
48
|
|
35
49
|
it "knows the surrogate's inherited instance methods" do
|
@@ -45,7 +59,7 @@ describe Surrogate::ApiComparer do
|
|
45
59
|
end
|
46
60
|
|
47
61
|
it "knows the surrogate's class level api methods" do
|
48
|
-
comparer.surrogate_methods[:class][:api].should == Set[:api_class_meth]
|
62
|
+
comparer.surrogate_methods[:class][:api].should == Set[:api_class_meth, :api_class_meth_with_signature]
|
49
63
|
end
|
50
64
|
|
51
65
|
it "knows the surrogate's inherited class methods" do
|
@@ -134,5 +148,107 @@ describe Surrogate::ApiComparer do
|
|
134
148
|
it 'tells me about api class methods on surrogate that are not on actual' do
|
135
149
|
comparer.compare[:class][:not_on_actual].should == Set[:class_not_on_actual]
|
136
150
|
end
|
151
|
+
|
152
|
+
|
153
|
+
context "it tells me the difference when types don't match. Examples:" do
|
154
|
+
example 'nothing when arguments are the same' do
|
155
|
+
klass = Class.new do
|
156
|
+
def self.class_meth1(a1, b1=1, *c1, &d1)end
|
157
|
+
def self.class_meth2(a2, b2=1, *c2, &d2)end
|
158
|
+
def self.class_meth3(a3, b3=1, *c3, &d3)end
|
159
|
+
def instance_meth1(e1, f1=1, *c1, &d1)end
|
160
|
+
def instance_meth2(e2, f2=1, *c2, &d2)end
|
161
|
+
def instance_meth3(e3, f3=1, *c3, &d3)end
|
162
|
+
end
|
163
|
+
|
164
|
+
parent = Class.new do
|
165
|
+
def self.class_meth1(a1, b1=1, *c1, &d1)end
|
166
|
+
def instance_meth1(e1, f1=1, *c1, &d1)end
|
167
|
+
end
|
168
|
+
|
169
|
+
surrogate = Class.new parent do
|
170
|
+
Surrogate.endow self do
|
171
|
+
define(:class_meth2) { |a2, b2=1, *c2, &d2| }
|
172
|
+
end
|
173
|
+
def self.class_meth3(a3, b3=1, *c3, &d3)end
|
174
|
+
define(:instance_meth2) { |e2, f2=1, *c2, &d2| }
|
175
|
+
def instance_meth3(e3, f3=1, *c3, &d3)end
|
176
|
+
end
|
177
|
+
|
178
|
+
comparer = described_class.new surrogate, klass
|
179
|
+
comparer.compare[:instance][:types].should == {}
|
180
|
+
comparer.compare[:class][:types].should == {}
|
181
|
+
end
|
182
|
+
|
183
|
+
it 'ignores methods that are not on both the surrogate and the actual' do
|
184
|
+
klass = Class.new do
|
185
|
+
def self.class_meth1(a)end
|
186
|
+
def instance_meth1(a, b)end
|
187
|
+
end
|
188
|
+
surrogate = Class.new do
|
189
|
+
Surrogate.endow self do
|
190
|
+
define(:class_meth2) { |a, b, c| }
|
191
|
+
end
|
192
|
+
define(:instance_meth2) { |a, b, c, d| }
|
193
|
+
end
|
194
|
+
|
195
|
+
described_class.new(surrogate, klass).compare
|
196
|
+
comparer.compare[:class][:types].should == {}
|
197
|
+
comparer.compare[:instance][:types].should == {}
|
198
|
+
end
|
199
|
+
|
200
|
+
it 'ignores methods with no default block' do
|
201
|
+
klass = Class.new { def instance_meth(a)end }
|
202
|
+
surrogate = Surrogate.endow(Class.new).define(:instance_meth)
|
203
|
+
described_class.new(surrogate, klass).compare
|
204
|
+
comparer.compare[:class][:types].should == {}
|
205
|
+
comparer.compare[:instance][:types].should == {}
|
206
|
+
end
|
207
|
+
|
208
|
+
it 'tells me about class methods with different types' do
|
209
|
+
klass = Class.new do
|
210
|
+
def self.class_meth1(a, b=1, *c, &d)end
|
211
|
+
def self.class_meth2(a, b=1, *c, &d)end
|
212
|
+
end
|
213
|
+
parent = Class.new { def self.class_meth1(b=1, *c, &d)end }
|
214
|
+
surrogate = Class.new parent do
|
215
|
+
Surrogate.endow self do
|
216
|
+
define(:class_meth2) { |a, *c, &d| }
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
comparer = described_class.new surrogate, klass
|
221
|
+
comparer.compare[:class][:types].should == {
|
222
|
+
class_meth1: { actual: [:req, :opt, :rest, :block],
|
223
|
+
surrogate: [ :opt, :rest, :block],
|
224
|
+
},
|
225
|
+
class_meth2: { actual: [:req, :opt, :rest, :block],
|
226
|
+
surrogate: [:req, :rest, :block],
|
227
|
+
},
|
228
|
+
}
|
229
|
+
end
|
230
|
+
|
231
|
+
it 'tells me about class methods with different types' do
|
232
|
+
klass = Class.new do
|
233
|
+
def instance_meth1(a, b=1, *c, &d)end
|
234
|
+
def instance_meth2(a, b=1, *c, &d)end
|
235
|
+
end
|
236
|
+
parent = Class.new { def instance_meth1(b=1, *c, &d)end }
|
237
|
+
surrogate = Class.new parent do
|
238
|
+
Surrogate.endow self
|
239
|
+
define(:instance_meth2) { |a, *c, &d| }
|
240
|
+
end
|
241
|
+
|
242
|
+
comparer = described_class.new surrogate, klass
|
243
|
+
comparer.compare[:instance][:types].should == {
|
244
|
+
instance_meth1: { actual: [:req, :opt, :rest, :block],
|
245
|
+
surrogate: [ :opt, :rest, :block],
|
246
|
+
},
|
247
|
+
instance_meth2: { actual: [:req, :opt, :rest, :block],
|
248
|
+
surrogate: [:req, :rest, :block],
|
249
|
+
},
|
250
|
+
}
|
251
|
+
end
|
252
|
+
end
|
137
253
|
end
|
138
254
|
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'surrogate/argument_errorizer'
|
2
|
+
|
3
|
+
describe Surrogate::ArgumentErrorizer do
|
4
|
+
let(:meth_name) { :some_name }
|
5
|
+
|
6
|
+
describe 'match!' do
|
7
|
+
it 'raises an argument error if the arguments do not match' do
|
8
|
+
expect { described_class.new(meth_name, ->(){}).match! 1 }.to raise_error ArgumentError
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'does not raise any errors if the arguments do match' do
|
12
|
+
described_class.new(meth_name, ->(){}).match!
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'does not execute the actual lambda' do
|
16
|
+
described_class.new(meth_name, ->{ raise }).match!
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'cares about required, optional, and block arguments' do
|
20
|
+
errorizer = described_class.new meth_name, ->(a, b=1, c, &d){}
|
21
|
+
expect { errorizer.match! }.to raise_error ArgumentError
|
22
|
+
expect { errorizer.match! 1 }.to raise_error ArgumentError
|
23
|
+
errorizer.match! 1, 2
|
24
|
+
errorizer.match! 1, 2, 3
|
25
|
+
expect { errorizer.match! 1, 2, 3, 4 }.to raise_error ArgumentError
|
26
|
+
|
27
|
+
errorizer = described_class.new meth_name, ->(a, b=1, *c, d, &e){}
|
28
|
+
errorizer.match! *1..10
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'does not care whether the block was provided' do
|
32
|
+
described_class.new(meth_name, ->(&b){}).match!
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def assert_message(the_lambda, args, message)
|
37
|
+
expect { described_class.new(meth_name, the_lambda).match! *args }
|
38
|
+
.to raise_error ArgumentError, message
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'has useful error messages' do
|
42
|
+
assert_message ->(){}, [1], "wrong number of arguments (1 for 0) in #{meth_name}()"
|
43
|
+
assert_message ->(a){}, [], "wrong number of arguments (0 for 1) in #{meth_name}(a)"
|
44
|
+
assert_message ->(a){}, [], "wrong number of arguments (0 for 1) in #{meth_name}(a)"
|
45
|
+
assert_message ->(a=1){}, [1,2], "wrong number of arguments (2 for 1) in #{meth_name}(a='?')"
|
46
|
+
assert_message ->(a, *b){}, [], "wrong number of arguments (0 for 1) in #{meth_name}(a, *b)"
|
47
|
+
assert_message ->(a, *b, &c){}, [], "wrong number of arguments (0 for 1) in #{meth_name}(a, *b, &c)"
|
48
|
+
assert_message ->(a, b, c=1, d=1, *e, f, &g){}, [], "wrong number of arguments (0 for 3) in #{meth_name}(a, b, c='?', d='?', *e, f, &g)"
|
49
|
+
end
|
50
|
+
end
|
data/surrogate.gemspec
CHANGED
@@ -18,8 +18,6 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
19
|
s.require_paths = ["lib"]
|
20
20
|
|
21
|
-
s.add_runtime_dependency 'bindable_block', '= 0.0.5.1'
|
22
|
-
|
23
21
|
s.add_development_dependency "rake"
|
24
22
|
s.add_development_dependency "rspec", "~> 2.4"
|
25
23
|
s.add_development_dependency "mountain_berry_fields", "~> 1.0.3"
|
data/todo
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
Urgent (things I want to do immediately, formatted as the git commits I will use)
|
2
|
+
---------------------------------------------------------------------------------
|
3
|
+
|
4
|
+
* be smart enough to handle method missing
|
5
|
+
* still check method args, even when value is overridden
|
6
|
+
* tests around the error messages of types
|
7
|
+
* Substitutability can check argument names
|
8
|
+
* substitute_for should not depend on rspec-expectations
|
9
|
+
* Error messages on blocks are actually useful
|
10
|
+
* Defined methods params must match arguments (BREAKING CHANGE)
|
11
|
+
* Update the readme (new syntax, and move the script into the changelog)
|
12
|
+
* error message
|
13
|
+
"Doesn't know initialize, only knows " <-- fix that shit
|
14
|
+
* blocks assertions can specify raising
|
15
|
+
|
16
|
+
TODO (next up after urgent, these will happen whenever I get around to it)
|
17
|
+
--------------------------------------------------------------------------
|
18
|
+
|
19
|
+
* Eventually it should be smart enough to not ignore natively implemented code with a [[:req]] argument
|
20
|
+
* Remove dependency on all of RSpec and only depend on rspec-core, then have AC tests for the other shit
|
21
|
+
* Add a better explanation for motivations
|
22
|
+
* Figure out whether I'm supposed to be using clone or dup for the object -.^ (looks like there may also be an `initialize_copy` method I can take advantage of instead of crazy stupid shit I'm doing now)
|
23
|
+
* don't blow up when delegating to the Object#initialize with args (do I still want this, or do I want to force arity matching (and maybe even variable name matching)?)
|
24
|
+
* config: rspec_mocks loaded, whether unprepared blocks should raise or just return nil
|
25
|
+
* extract surrogate/rspec into its own gem
|
26
|
+
* support subset-substitutabilty not being able to touch real methods (e.g. #respond_to?)
|
27
|
+
* make substitutability matcher go either way
|
28
|
+
* make substitutability matcher not care whether either are surrogates
|
29
|
+
* Add support for operators
|
30
|
+
|
31
|
+
|
32
|
+
Future Features (Things that probably should eventually happen, but not anytime soon unless I get really inspired to work on this shit)
|
33
|
+
---------------------------------------------------------------------------------------------------------------------------------------
|
34
|
+
|
35
|
+
* Can endow a class multiple times, results aggregate instead of override
|
36
|
+
* figure out how to talk about callbacks like #on_success
|
37
|
+
* have some sort of reinitialization that can hook into setup/teardown steps of test suite
|
38
|
+
* Support arity checking as part of substitutability
|
39
|
+
* Ability to disassociate the method name from the test (e.g. you shouldn't need to change a test just because you change a name)
|
40
|
+
* ability to declare normal methods as being part of the API
|
41
|
+
* ability to declare a define that uses the overridden method as the body, but can still act like an api method
|
42
|
+
* assertions for order of invocations & methods
|
43
|
+
* class generator? (supports a top-down style of development for when you write your mocks before you write your implementations)
|
44
|
+
* deal with hard dependency on rspec-mocks
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: surrogate
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,22 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-09-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
-
- !ruby/object:Gem::Dependency
|
15
|
-
name: bindable_block
|
16
|
-
requirement: &70355417643520 !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
|
-
requirements:
|
19
|
-
- - =
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
version: 0.0.5.1
|
22
|
-
type: :runtime
|
23
|
-
prerelease: false
|
24
|
-
version_requirements: *70355417643520
|
25
14
|
- !ruby/object:Gem::Dependency
|
26
15
|
name: rake
|
27
|
-
requirement: &
|
16
|
+
requirement: &70261539914140 !ruby/object:Gem::Requirement
|
28
17
|
none: false
|
29
18
|
requirements:
|
30
19
|
- - ! '>='
|
@@ -32,10 +21,10 @@ dependencies:
|
|
32
21
|
version: '0'
|
33
22
|
type: :development
|
34
23
|
prerelease: false
|
35
|
-
version_requirements: *
|
24
|
+
version_requirements: *70261539914140
|
36
25
|
- !ruby/object:Gem::Dependency
|
37
26
|
name: rspec
|
38
|
-
requirement: &
|
27
|
+
requirement: &70261539929980 !ruby/object:Gem::Requirement
|
39
28
|
none: false
|
40
29
|
requirements:
|
41
30
|
- - ~>
|
@@ -43,10 +32,10 @@ dependencies:
|
|
43
32
|
version: '2.4'
|
44
33
|
type: :development
|
45
34
|
prerelease: false
|
46
|
-
version_requirements: *
|
35
|
+
version_requirements: *70261539929980
|
47
36
|
- !ruby/object:Gem::Dependency
|
48
37
|
name: mountain_berry_fields
|
49
|
-
requirement: &
|
38
|
+
requirement: &70261539929360 !ruby/object:Gem::Requirement
|
50
39
|
none: false
|
51
40
|
requirements:
|
52
41
|
- - ~>
|
@@ -54,10 +43,10 @@ dependencies:
|
|
54
43
|
version: 1.0.3
|
55
44
|
type: :development
|
56
45
|
prerelease: false
|
57
|
-
version_requirements: *
|
46
|
+
version_requirements: *70261539929360
|
58
47
|
- !ruby/object:Gem::Dependency
|
59
48
|
name: mountain_berry_fields-rspec
|
60
|
-
requirement: &
|
49
|
+
requirement: &70261539928860 !ruby/object:Gem::Requirement
|
61
50
|
none: false
|
62
51
|
requirements:
|
63
52
|
- - ~>
|
@@ -65,10 +54,10 @@ dependencies:
|
|
65
54
|
version: 1.0.3
|
66
55
|
type: :development
|
67
56
|
prerelease: false
|
68
|
-
version_requirements: *
|
57
|
+
version_requirements: *70261539928860
|
69
58
|
- !ruby/object:Gem::Dependency
|
70
59
|
name: mountain_berry_fields-magic_comments
|
71
|
-
requirement: &
|
60
|
+
requirement: &70261539928300 !ruby/object:Gem::Requirement
|
72
61
|
none: false
|
73
62
|
requirements:
|
74
63
|
- - ~>
|
@@ -76,7 +65,7 @@ dependencies:
|
|
76
65
|
version: 1.0.1
|
77
66
|
type: :development
|
78
67
|
prerelease: false
|
79
|
-
version_requirements: *
|
68
|
+
version_requirements: *70261539928300
|
80
69
|
description: Framework to aid in handrolling mock/spy objects.
|
81
70
|
email:
|
82
71
|
- josh.cheek@gmail.com
|
@@ -87,6 +76,7 @@ files:
|
|
87
76
|
- .gitignore
|
88
77
|
- .rvmrc
|
89
78
|
- .travis.yml
|
79
|
+
- Changelog.md
|
90
80
|
- Rakefile
|
91
81
|
- Readme.md
|
92
82
|
- Readme.md.mountain_berry_fields
|
@@ -95,11 +85,13 @@ files:
|
|
95
85
|
- gemfiles/rspec_mocks_2.2
|
96
86
|
- lib/surrogate.rb
|
97
87
|
- lib/surrogate/api_comparer.rb
|
88
|
+
- lib/surrogate/argument_errorizer.rb
|
98
89
|
- lib/surrogate/endower.rb
|
99
90
|
- lib/surrogate/hatchery.rb
|
100
91
|
- lib/surrogate/hatchling.rb
|
101
92
|
- lib/surrogate/invocation.rb
|
102
|
-
- lib/surrogate/
|
93
|
+
- lib/surrogate/method_definition.rb
|
94
|
+
- lib/surrogate/porc_reflector.rb
|
103
95
|
- lib/surrogate/rspec.rb
|
104
96
|
- lib/surrogate/rspec/abstract_failure_message.rb
|
105
97
|
- lib/surrogate/rspec/initialization_matcher.rb
|
@@ -110,6 +102,8 @@ files:
|
|
110
102
|
- lib/surrogate/rspec/times_predicate.rb
|
111
103
|
- lib/surrogate/rspec/verb_matcher.rb
|
112
104
|
- lib/surrogate/rspec/with_filter.rb
|
105
|
+
- lib/surrogate/surrogate_class_reflector.rb
|
106
|
+
- lib/surrogate/surrogate_instance_reflector.rb
|
113
107
|
- lib/surrogate/values.rb
|
114
108
|
- lib/surrogate/version.rb
|
115
109
|
- spec/acceptance_spec.rb
|
@@ -125,7 +119,9 @@ files:
|
|
125
119
|
- spec/rspec/verb_matcher_spec.rb
|
126
120
|
- spec/spec_helper.rb
|
127
121
|
- spec/unit/api_comparer_spec.rb
|
122
|
+
- spec/unit/argument_errorizer_spec.rb
|
128
123
|
- surrogate.gemspec
|
124
|
+
- todo
|
129
125
|
homepage: https://github.com/JoshCheek/surrogate
|
130
126
|
licenses: []
|
131
127
|
post_install_message:
|
@@ -164,4 +160,5 @@ test_files:
|
|
164
160
|
- spec/rspec/verb_matcher_spec.rb
|
165
161
|
- spec/spec_helper.rb
|
166
162
|
- spec/unit/api_comparer_spec.rb
|
163
|
+
- spec/unit/argument_errorizer_spec.rb
|
167
164
|
has_rdoc:
|