surrogate 0.5.5 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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:
|