jackbox 0.9.6.2 → 0.9.6.3
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.
- checksums.yaml +13 -5
- data/CHANGES.txt +41 -1
- data/LICENSE.lic +0 -0
- data/README.md +244 -149
- data/Rakefile +6 -6
- data/jackbox.gemspec +3 -2
- data/lib/jackbox.rb +1 -1
- data/lib/jackbox/injectors.rb +1 -1
- data/lib/jackbox/rake.rb +1 -1
- data/lib/jackbox/tools/prefs.rb +1 -1
- data/lib/jackbox/version.rb +1 -1
- data/spec/lib/abtract_spec.rb +6 -6
- data/spec/lib/jackbox/injector_composition_spec.rb +106 -88
- data/spec/lib/jackbox/injector_directives_spec.rb +46 -0
- data/spec/lib/jackbox/injector_inheritance_spec.rb +980 -410
- data/spec/lib/jackbox/injector_introspection_spec.rb +333 -208
- data/spec/lib/jackbox/injector_spec.rb +28 -28
- data/spec/lib/jackbox/injector_versioning_spec.rb +1 -0
- data/spec/lib/jackbox/patterns_spec.rb +146 -14
- data/spec/lib/jackbox/reclassing_spec.rb +165 -78
- data/spec/lib/jackbox/vmc_spec.rb +246 -0
- metadata +32 -28
@@ -7,16 +7,16 @@ describe "the introspection api in further detail" do
|
|
7
7
|
|
8
8
|
describe :injectors do
|
9
9
|
|
10
|
-
# . Name.injectors == [j,......]
|
11
|
-
# . Name.injectors.by_name == [:name, ......]
|
12
|
-
# . Name.injectors.sym_list == [:name, ......]
|
13
|
-
# . Name.injectors.collect_by_name(:name) == [j,......] (default method)
|
14
|
-
# . same as Name.injectors :name
|
15
|
-
# . Name.injectors.all_by_sym(:name) == [j,......] (default method)
|
16
|
-
# . Name.injectors.find_by_name(:name) == j
|
17
|
-
# . Name.injectors.#Enumerable...
|
18
|
-
|
19
10
|
describe "base injectors call" do
|
11
|
+
|
12
|
+
# . Name.injectors == [j,......]
|
13
|
+
# . Name.injectors.by_name == [:name, ......]
|
14
|
+
# . Name.injectors.sym_list == [:name, ......]
|
15
|
+
# . Name.injectors.collect_by_name(:name) == [j,......] (default method)
|
16
|
+
# . same as Name.injectors :name
|
17
|
+
# . Name.injectors.all_by_sym(:name) == [j,......] (default method)
|
18
|
+
# . Name.injectors.find_by_name(:name) == j
|
19
|
+
# . Name.injectors.#Enumerable...
|
20
20
|
|
21
21
|
before do
|
22
22
|
class InjectorContainer
|
@@ -47,13 +47,6 @@ describe "the introspection api in further detail" do
|
|
47
47
|
|
48
48
|
# . Name.injectors.by_name == [:name, ......]
|
49
49
|
|
50
|
-
# class InjectorContainer
|
51
|
-
# injector :function
|
52
|
-
# injector :style
|
53
|
-
#
|
54
|
-
# inject function, style
|
55
|
-
# end
|
56
|
-
|
57
50
|
expect(InjectorContainer.injectors.by_name).to all( be_an(Symbol))
|
58
51
|
expect(InjectorContainer.injectors.by_name).to eql([:function, :style])
|
59
52
|
# alias
|
@@ -63,16 +56,11 @@ describe "the introspection api in further detail" do
|
|
63
56
|
|
64
57
|
the 'injectors.collect_by_name returns a list of injector objects matching the name' do
|
65
58
|
|
66
|
-
|
67
|
-
# injector :function
|
68
|
-
# injector :style
|
69
|
-
#
|
70
|
-
# inject function, style
|
71
|
-
# end
|
59
|
+
# . Name.injectors.collect_by_name(:name) == [j,......] (default method)
|
72
60
|
|
73
61
|
ic = InjectorContainer.new
|
74
62
|
ic.enrich InjectorContainer.style
|
75
|
-
ic.injectors.by_name.should == [:
|
63
|
+
ic.injectors.by_name.should == [:style, :function, :style]
|
76
64
|
|
77
65
|
# returns [Injector.name == :style, Injector.name == :style] only !!
|
78
66
|
ic.injectors.collect_by_name(:style).should all(be_an(Injector).and have_attributes(:name => :style))
|
@@ -83,18 +71,13 @@ describe "the introspection api in further detail" do
|
|
83
71
|
|
84
72
|
the 'injectors.find_by_name call returns one item of class Injector by name <sym>' do
|
85
73
|
|
86
|
-
|
87
|
-
# injector :function
|
88
|
-
# injector :style
|
89
|
-
#
|
90
|
-
# inject function, style
|
91
|
-
# end
|
74
|
+
# . Name.injectors.find_by_name(:name) == j
|
92
75
|
|
93
76
|
ic = InjectorContainer.new
|
94
77
|
ic.enrich InjectorContainer.style
|
95
78
|
|
96
79
|
# result
|
97
|
-
ic.injectors.by_name.should == [:
|
80
|
+
ic.injectors.by_name.should == [:style, :function, :style]
|
98
81
|
ic.injectors.find_by_name(:style).should be_an(Injector).and( have_attributes(:name => :style)) # the last one !!!
|
99
82
|
|
100
83
|
# also aliased
|
@@ -104,12 +87,7 @@ describe "the introspection api in further detail" do
|
|
104
87
|
|
105
88
|
the 'default calls injectors :name/injectors :name, :othername, ... get resolved to the previous methods' do
|
106
89
|
|
107
|
-
|
108
|
-
# injector :function
|
109
|
-
# injector :style
|
110
|
-
#
|
111
|
-
# inject function, style
|
112
|
-
# end
|
90
|
+
# . Name.injectors.#Enumerable...
|
113
91
|
|
114
92
|
ic = InjectorContainer.new
|
115
93
|
ic.enrich InjectorContainer.style
|
@@ -122,151 +100,185 @@ describe "the introspection api in further detail" do
|
|
122
100
|
|
123
101
|
end
|
124
102
|
|
125
|
-
describe '#injectors at the class singleton level' do
|
126
|
-
|
127
|
-
the 'injectors applied at the class INSTANCE level show only on the class not the object instances' do
|
128
103
|
|
129
|
-
|
130
|
-
def new *args
|
131
|
-
puts "--done--"
|
132
|
-
super(*args)
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
class InjectorUser
|
137
|
-
# ...
|
138
|
-
end
|
139
|
-
|
140
|
-
InjectorUser.extend class_injector
|
141
|
-
|
142
|
-
$stdout.should_receive(:puts).with("--done--")
|
143
|
-
iu = InjectorUser.new
|
144
|
-
|
145
|
-
InjectorUser.injectors.size.should == 1
|
146
|
-
InjectorUser.injectors.should all(be_an(Injector).and have_attributes(:name => :class_injector))
|
147
|
-
|
148
|
-
if iu.respond_to? :injectors # done to run this file independent of the others
|
149
|
-
iu.injectors.should be_empty
|
150
|
-
else
|
151
|
-
expect{
|
152
|
-
iu.injectors
|
153
|
-
}.to raise_error(NoMethodError)
|
154
|
-
end
|
104
|
+
describe "#injectors(:all) call" do
|
155
105
|
|
106
|
+
before do
|
107
|
+
injector :Example1
|
108
|
+
injector :Example2
|
109
|
+
Object.inject Example1()
|
156
110
|
end
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
injector :one
|
162
|
-
|
163
|
-
Array.inject two # injected on objects of the class
|
164
|
-
Array.extend one # extended on the class instance itself
|
165
|
-
|
166
|
-
# result
|
167
|
-
|
168
|
-
Array.injectors.sym_list.should == [:one, :two]
|
169
|
-
|
111
|
+
|
112
|
+
after do
|
113
|
+
Example1(:implode)
|
114
|
+
Example2(:implode)
|
170
115
|
end
|
171
116
|
|
172
|
-
end
|
173
|
-
|
174
|
-
describe "#injectors(:all) call" do
|
175
|
-
|
176
|
-
injector :Example1
|
177
|
-
injector :Example2
|
178
|
-
|
179
117
|
it 'returns all the injectors in the ancestor chain of an object' do
|
180
118
|
|
181
|
-
Object.eject *Object.injectors rescue [] # clear all injectors from other tests
|
119
|
+
# Object.eject *Object.injectors rescue [] # clear all injectors from other tests
|
182
120
|
|
183
|
-
Object.inject Example1()
|
184
121
|
Hash.inject Example2()
|
185
122
|
|
186
123
|
Hash.new.injectors(:all).should all(be_an(Injector))
|
187
|
-
Hash.new.injectors(:all).
|
124
|
+
Hash.new.injectors(:all).should eql [Example2(), Example1()] # from Object, and Hash
|
188
125
|
|
189
126
|
# as opposed to simple #injectors call
|
190
|
-
|
127
|
+
|
128
|
+
Hash.new.injectors.should eql [Example2()] # with no :all option
|
191
129
|
|
192
130
|
end
|
193
131
|
|
194
|
-
it '
|
132
|
+
it 'with any class' do
|
195
133
|
|
196
134
|
# Object.eject *Object.injectors # clear all injectors from other tests
|
197
135
|
|
198
|
-
class
|
136
|
+
class AnyClass
|
199
137
|
inject Example2()
|
200
138
|
end
|
201
139
|
|
202
|
-
|
203
|
-
|
140
|
+
AnyClass.injectors(:all).should all(be_an(Injector))
|
141
|
+
AnyClass.injectors(:all).should eql [Example2(), Example1()]
|
204
142
|
|
205
143
|
# as opposed to simple #injectors call
|
206
|
-
|
144
|
+
|
145
|
+
AnyClass.new.injectors.should eql [Example2()]
|
207
146
|
|
208
147
|
end
|
209
148
|
|
210
149
|
it 'returns all the injectors in the ancestors chain of a module' do
|
211
150
|
|
212
|
-
module
|
151
|
+
module AnyModule
|
152
|
+
|
213
153
|
inject Example2() do
|
214
|
-
include injector :
|
154
|
+
include injector :Example3 # compond injector
|
215
155
|
end
|
156
|
+
|
216
157
|
end
|
217
158
|
|
218
|
-
|
219
|
-
|
220
|
-
|
159
|
+
AnyModule.injectors(:all).should all(be_an(Injector))
|
160
|
+
AnyModule.injectors(:all).should eql [Example2(), Example3()]
|
161
|
+
|
221
162
|
# as opposed to simple #injectors call
|
222
|
-
|
163
|
+
|
164
|
+
AnyModule.injectors.should eql [Example2()]
|
223
165
|
|
224
166
|
end
|
225
167
|
|
226
168
|
it 'returns all the injectors in the ancestors chain of a Injector' do
|
227
169
|
|
228
|
-
|
170
|
+
Example1 do
|
171
|
+
|
229
172
|
include injector :Example2 do
|
230
|
-
include injector :
|
173
|
+
include injector :Example3 # triple compound injector
|
231
174
|
end
|
175
|
+
|
232
176
|
end
|
233
177
|
|
234
178
|
Example1().injectors(:all).should all(be_an(Injector))
|
235
|
-
Example1().injectors(:all).
|
179
|
+
Example1().injectors(:all).should eql [Example2(), Example3()]
|
236
180
|
|
237
181
|
# as opposed to simple #injectors call
|
238
|
-
|
182
|
+
|
183
|
+
Example1().injectors.should eql [Example2()]
|
239
184
|
|
240
185
|
end
|
241
186
|
|
242
187
|
it 'allows the rest of the api on the entire list' do
|
243
188
|
|
244
|
-
Example1
|
245
|
-
|
246
|
-
|
189
|
+
Example1 do
|
190
|
+
|
191
|
+
include injector :Example2 do
|
192
|
+
include injector :Example3 # triple compound injector
|
193
|
+
end
|
194
|
+
|
195
|
+
end
|
196
|
+
|
197
|
+
Example1().injectors(:all).by_name.should == [:Example2, :Example3]
|
198
|
+
Example1().injectors(:all).collect_by_name(:Example3).should all(be_an(Injector).and have_attributes(:name => :Example3))
|
199
|
+
Example1().injectors(:all).find_by_name(:Example2).should == Example2()
|
247
200
|
|
248
201
|
end
|
249
202
|
end
|
250
203
|
|
204
|
+
|
205
|
+
describe '#injectors at the class singleton level' do
|
206
|
+
|
207
|
+
the 'injectors applied at the CLASS instance level, ie: using extend on the class, show up only on the CLASS instance not
|
208
|
+
its object instances and this only after using the :all directive like above' do
|
209
|
+
|
210
|
+
injector :class_Instance_injector do
|
211
|
+
def new *args
|
212
|
+
puts "--done--"
|
213
|
+
super(*args)
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
class InjectorUser
|
218
|
+
# ...
|
219
|
+
end
|
220
|
+
|
221
|
+
# extend the class singleton
|
222
|
+
|
223
|
+
InjectorUser.extend class_Instance_injector
|
224
|
+
|
225
|
+
# run tests
|
226
|
+
|
227
|
+
InjectorUser.injectors.size.should == 0 # not using the :all directive
|
228
|
+
|
229
|
+
InjectorUser.injectors(:all).size.should == 1
|
230
|
+
InjectorUser.injectors(:all).should all(be_an(Injector).and have_attributes(:name => :class_Instance_injector))
|
231
|
+
|
232
|
+
# on the class instance
|
233
|
+
|
234
|
+
$stdout.should_receive(:puts).with("--done--")
|
235
|
+
|
236
|
+
iu = InjectorUser.new
|
237
|
+
expect(iu.injectors).to be_empty
|
238
|
+
expect(iu.injectors(:all)).to be_empty
|
239
|
+
|
240
|
+
end
|
241
|
+
|
242
|
+
the ':all injector list for classes lists CLASS instance injectors first and then OBJECT instance injectors' do
|
243
|
+
|
244
|
+
injector :two
|
245
|
+
injector :one
|
246
|
+
|
247
|
+
Array.inject two # injected on objects of the class
|
248
|
+
Array.extend one # extended on the class instance itself
|
249
|
+
|
250
|
+
# result
|
251
|
+
|
252
|
+
Array.injectors(:all).sym_list.should == [:one, :two]
|
253
|
+
|
254
|
+
Array.new.injectors.sym_list.should == [:two] # :one is member of Array.singleton_class
|
255
|
+
# and does not become part of Array.instances
|
256
|
+
end
|
257
|
+
|
258
|
+
end
|
251
259
|
end
|
252
260
|
|
261
|
+
|
253
262
|
describe :history do
|
254
263
|
|
255
|
-
|
264
|
+
|
265
|
+
jack :Histample
|
266
|
+
|
256
267
|
|
257
268
|
it 'does not show original jack' do
|
258
269
|
expect(Histample().history.first).to eq(nil)
|
259
270
|
end
|
260
271
|
|
261
|
-
it "shows additional jacks after
|
272
|
+
it "shows additional jacks once hosted, i.e.: after extend/include" do
|
262
273
|
|
263
|
-
extend(Histample(), Histample())
|
274
|
+
extend(Histample(), Histample()) # host two items
|
264
275
|
|
265
|
-
injectors.should == Histample().history
|
276
|
+
injectors.should == Histample().history # equal at this point
|
266
277
|
|
267
278
|
expect(Histample().history.size).to eq(2)
|
268
|
-
expect(Histample().history.last).to eql(
|
269
|
-
expect(Histample().history.
|
279
|
+
expect(Histample().history.last).to eql(injectors.last)
|
280
|
+
expect(Histample().history.first).to eq(injectors.first)
|
281
|
+
expect(injectors.size).to eq(2)
|
270
282
|
|
271
283
|
eject *injectors
|
272
284
|
|
@@ -280,13 +292,6 @@ describe "the introspection api in further detail" do
|
|
280
292
|
|
281
293
|
expect(Histample().history.slice(0)).to be_instance_of(Injector)
|
282
294
|
expect(Histample().history.slice(1)).to be_instance_of(Injector)
|
283
|
-
expect(Histample().history.slice(0)).to eq(Histample())
|
284
|
-
expect(Histample().history.slice(1)).to eq(Histample())
|
285
|
-
|
286
|
-
# values are different than spec
|
287
|
-
|
288
|
-
expect(Histample().history.slice(0)).not_to eq(Histample().spec)
|
289
|
-
expect(Histample().history.slice(1)).not_to eq(Histample().spec)
|
290
295
|
|
291
296
|
eject Histample(), Histample()
|
292
297
|
|
@@ -296,37 +301,33 @@ describe "the introspection api in further detail" do
|
|
296
301
|
|
297
302
|
extend(Histample(), Histample())
|
298
303
|
|
304
|
+
injectors.should == Histample().history
|
305
|
+
|
299
306
|
expect(Histample().history.size).to eq(2)
|
300
|
-
expect(
|
301
|
-
expect(Histample().history.last).to_not eq(Histample().spec)
|
307
|
+
expect(injectors.size).to eq(2)
|
302
308
|
|
303
309
|
eject *injectors
|
304
310
|
|
305
311
|
expect(injectors).to be_empty # target injectors
|
306
|
-
|
307
|
-
expect(Histample().history.size).to eq(0) # Injector history
|
308
|
-
expect(Histample().history.first).to eq(nil)
|
309
|
-
expect(Histample().history.last).to eq(nil)
|
312
|
+
expect(Histample().history).to be_empty # Injector history
|
310
313
|
|
311
314
|
end
|
312
315
|
|
313
|
-
it 'swallows un-hosted elements other than original' do
|
316
|
+
it 'swallows un-hosted elements other than original one' do
|
314
317
|
|
315
318
|
Histample() #un-hosted Histample
|
316
319
|
Histample() #un-hosted Histample
|
317
320
|
|
318
|
-
expect(Histample().history.first).to eq(nil)
|
319
321
|
expect(Histample().history.size).to eq(0)
|
320
|
-
expect(Histample().history.last).to eq(nil)
|
321
322
|
|
322
323
|
end
|
323
324
|
|
324
|
-
it 'shows
|
325
|
+
it 'shows hosted items upon inspection' do
|
325
326
|
|
326
327
|
extend Histample()
|
327
328
|
|
329
|
+
expect(Histample().history.inspect).to match(/\[\(\|Histample\|.+\)\]/)
|
328
330
|
expect(Histample().history.size).to eq(1)
|
329
|
-
expect(Histample().history.inspect).to match(/\[\(.+\|Histample\|\)\]/)
|
330
331
|
|
331
332
|
eject Histample()
|
332
333
|
|
@@ -337,26 +338,46 @@ describe "the introspection api in further detail" do
|
|
337
338
|
it 'points to the previous injector in the history' do
|
338
339
|
|
339
340
|
extend Histample(), Histample()
|
340
|
-
|
341
|
+
|
342
|
+
# Given that
|
341
343
|
injectors.should == Histample().history
|
342
344
|
|
345
|
+
# Then
|
343
346
|
expect(Histample().history.last.precedent).to equal(Histample().history.first)
|
344
347
|
expect(Histample().history.last.pre).to equal(injectors.first)
|
345
348
|
expect(injectors.last.precedent).to equal(Histample().history.first)
|
346
349
|
expect(injectors.last.pre).to equal(injectors.first)
|
350
|
+
|
351
|
+
eject *injectors
|
352
|
+
|
353
|
+
end
|
354
|
+
|
355
|
+
it 'has spec as the first precedent' do
|
356
|
+
|
357
|
+
extend Histample(), Histample()
|
358
|
+
|
359
|
+
injectors.should == Histample().history
|
360
|
+
|
347
361
|
expect(Histample().history.first.precedent).to equal(Histample().spec)
|
348
362
|
expect(injectors.first.precedent).to equal(Histample().spec)
|
349
|
-
expect(Histample().spec.pre).to eq(nil)
|
350
363
|
|
351
364
|
eject *injectors
|
352
365
|
|
353
366
|
end
|
367
|
+
|
368
|
+
# but then... aka: its a circular list
|
354
369
|
|
355
|
-
it 'has
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
370
|
+
it 'has the latest version as the precedent to spec' do
|
371
|
+
|
372
|
+
extend Histample(), Histample()
|
373
|
+
|
374
|
+
injectors.should == Histample().history
|
375
|
+
|
376
|
+
expect(Histample().history.first.precedent).to equal(Histample().spec)
|
377
|
+
expect(Histample().precedent.pre.pre).to equal(Histample().spec)
|
378
|
+
expect(Histample().spec.pre).to eq(Histample().history.last)
|
379
|
+
|
380
|
+
eject *injectors
|
360
381
|
|
361
382
|
end
|
362
383
|
|
@@ -377,65 +398,80 @@ describe "the introspection api in further detail" do
|
|
377
398
|
expect(Progample().history).to be_empty
|
378
399
|
expect(Progample().progenitor).to equal(Progample().spec)
|
379
400
|
|
401
|
+
# apply the injector
|
402
|
+
|
380
403
|
extend Progample(), Progample()
|
381
404
|
|
382
405
|
expect(Progample().history.size).to eq(2)
|
406
|
+
|
407
|
+
|
408
|
+
# both generated form spec
|
409
|
+
|
383
410
|
expect(Progample().history.first.progenitor).to equal(Progample().spec)
|
384
411
|
expect(Progample().history.last.progenitor).to equal(Progample().spec)
|
385
412
|
|
386
|
-
|
413
|
+
|
414
|
+
# create a tag
|
415
|
+
|
416
|
+
suppress_warnings do # used because of rspec
|
387
417
|
ProgenitorsTag = Progample()
|
388
418
|
end
|
389
419
|
|
390
420
|
expect(Progample().history.size).to eq(3)
|
421
|
+
|
391
422
|
expect(Progample().history.first.progenitor).to equal(Progample().spec)
|
392
|
-
expect(Progample().history.
|
423
|
+
expect(Progample().history.last).to equal(ProgenitorsTag)
|
393
424
|
expect(Progample().history.last.progenitor).to equal(Progample().spec)
|
425
|
+
expect(ProgenitorsTag.progenitor).to equal(Progample().spec)
|
394
426
|
|
427
|
+
|
428
|
+
# apply the tag
|
429
|
+
|
395
430
|
extend ProgenitorsTag
|
396
431
|
|
397
432
|
expect(Progample().history.size).to eq(4)
|
398
|
-
expect(Progample().history.last).to equal(injectors.
|
433
|
+
expect(Progample().history.last).to equal(injectors.first)
|
399
434
|
|
400
435
|
expect(Progample().history.last.progenitor).to equal(ProgenitorsTag)
|
401
|
-
expect(Progample().history.last.progenitor).to equal(Progample().history.slice(2))
|
402
|
-
expect(Progample().history.slice(2).progenitor).to equal(Progample().spec)
|
403
|
-
expect(Progample().history.slice(1).progenitor).to equal(Progample().spec)
|
404
436
|
expect(Progample().history.first.progenitor).to equal(Progample().spec)
|
405
|
-
expect(Progample().spec.progenitor).to equal(nil)
|
406
|
-
expect(ProgenitorsTag.progenitor).to equal(Progample().spec)
|
407
|
-
expect(ProgenitorsTag.progenitor.progenitor).to equal(nil)
|
408
437
|
|
409
|
-
|
438
|
+
end
|
439
|
+
|
440
|
+
it 'points the last progenitor to nil' do
|
441
|
+
|
442
|
+
expect(Progample().spec.progenitor).to equal(nil)
|
410
443
|
|
411
444
|
end
|
412
445
|
|
413
|
-
it '
|
446
|
+
it 'works the same with soft tags' do
|
414
447
|
|
415
448
|
suppress_warnings do
|
416
449
|
ProgenitorsTag = Progample()
|
417
450
|
end
|
418
451
|
|
419
452
|
expect(Progample().history.size).to eq(1)
|
420
|
-
expect(Progample().history.slice(0)).to equal(ProgenitorsTag)
|
421
453
|
|
422
|
-
|
454
|
+
|
455
|
+
# soft tag
|
456
|
+
# debugger
|
457
|
+
Progample(:tag) { 'some code'}
|
423
458
|
|
424
459
|
expect(Progample().history.size).to eq(2)
|
425
|
-
|
426
|
-
|
460
|
+
|
461
|
+
# progenitors are the same
|
462
|
+
|
427
463
|
expect(Progample().history.first.progenitor).to eq(Progample().spec)
|
428
464
|
expect(Progample().history.last.progenitor).to eq(Progample().spec)
|
429
465
|
expect(Progample().history.first.progenitor.progenitor).to eq(nil)
|
430
466
|
expect(Progample().history.last.progenitor.progenitor).to eq(nil)
|
431
|
-
expect(ProgenitorsTag.progenitor).to equal(Progample().spec)
|
432
|
-
expect(ProgenitorsTag.progenitor.progenitor).to equal(nil)
|
433
467
|
|
468
|
+
# tags call
|
469
|
+
|
434
470
|
expect(Progample().tags.size).to eq(2)
|
435
471
|
|
436
472
|
end
|
437
473
|
|
438
|
-
it '
|
474
|
+
it 'carries on the metaphor with injectors are shared from other objects' do
|
439
475
|
|
440
476
|
suppress_warnings do
|
441
477
|
ProgenitorsTag = Progample()
|
@@ -446,20 +482,13 @@ describe "the introspection api in further detail" do
|
|
446
482
|
end
|
447
483
|
|
448
484
|
class ProgenitorTester2
|
449
|
-
include *ProgenitorTester1.injectors
|
485
|
+
include *ProgenitorTester1.injectors # copying injectors from second class
|
450
486
|
end
|
451
487
|
|
452
488
|
expect(ProgenitorTester2.injectors.first.progenitor).to equal(ProgenitorTester1.injectors.first)
|
453
489
|
expect(ProgenitorTester1.injectors.first.progenitor).to equal(ProgenitorsTag)
|
454
490
|
expect(ProgenitorsTag.progenitor).to equal(Progample().spec)
|
455
491
|
|
456
|
-
with ProgenitorTester1 do
|
457
|
-
eject *injectors
|
458
|
-
end
|
459
|
-
|
460
|
-
expect(ProgenitorTester2.injectors.first.progenitor).to equal(ProgenitorsTag)
|
461
|
-
expect(ProgenitorsTag.progenitor).to equal(Progample().spec)
|
462
|
-
|
463
492
|
end
|
464
493
|
|
465
494
|
end
|
@@ -511,101 +540,197 @@ describe "the introspection api in further detail" do
|
|
511
540
|
end
|
512
541
|
|
513
542
|
# For now this is how equality is defined
|
514
|
-
describe 'equality' do
|
543
|
+
describe 'equality and inequality' do
|
515
544
|
|
516
545
|
it 'allows comparison between injectors' do
|
517
546
|
|
547
|
+
# equality
|
548
|
+
##################################
|
518
549
|
E().should == E()
|
519
|
-
E().
|
550
|
+
E().should == E().spec
|
520
551
|
|
521
552
|
E(:tag).should == E()
|
522
|
-
ETag1 = E()
|
523
|
-
|
524
|
-
|
553
|
+
if ETag1 = E()
|
554
|
+
ETag1.should == E()
|
555
|
+
end
|
525
556
|
extend E()
|
526
557
|
injectors.first.should == E()
|
527
558
|
|
559
|
+
|
560
|
+
# ** definition **
|
528
561
|
E() do
|
529
|
-
def foo
|
562
|
+
def foo
|
530
563
|
end
|
531
564
|
end
|
532
|
-
|
565
|
+
# ** definition **
|
566
|
+
|
567
|
+
|
568
|
+
# inequality
|
569
|
+
##################################
|
533
570
|
E().should == E()
|
534
571
|
ETag1.should_not == E()
|
535
572
|
injectors.first.should_not == E()
|
536
|
-
E(:tag).should == E()
|
537
573
|
|
574
|
+
E(:tag).should == E()
|
538
575
|
E().should_not == F()
|
539
576
|
|
540
577
|
end
|
541
578
|
|
542
579
|
end
|
543
580
|
|
544
|
-
describe
|
581
|
+
describe :diff do
|
545
582
|
|
546
583
|
it 'shows the difference between injectors' do
|
547
|
-
|
548
|
-
E().diff.
|
584
|
+
|
585
|
+
E().diff.class.should be(Array)
|
586
|
+
|
587
|
+
# equality in the converse expression
|
588
|
+
##################################
|
589
|
+
# debugger
|
590
|
+
E().diff(E()).should be_empty
|
591
|
+
|
592
|
+
# because
|
593
|
+
E().should == E() # like above
|
594
|
+
|
595
|
+
|
596
|
+
# unless changed E should be == E().pre or E().spec
|
597
|
+
##################################
|
598
|
+
E().diff.should be_empty
|
599
|
+
|
549
600
|
# because
|
550
|
-
E().
|
601
|
+
E().diff.should == E().diff(E().pre)
|
602
|
+
E().pre.should equal( E().spec )
|
603
|
+
# and
|
604
|
+
E().should == E().spec # like above
|
551
605
|
|
552
606
|
|
607
|
+
# unless there is a delta it cannot be loaded?
|
553
608
|
##################################
|
554
609
|
E().diff.should_not be_loaded
|
610
|
+
|
555
611
|
# because
|
556
|
-
E().diff.
|
557
|
-
E().diff.delta.should_not be_empty
|
558
|
-
|
612
|
+
E().diff.delta.should be_empty
|
559
613
|
|
614
|
+
|
615
|
+
# tags are the same
|
560
616
|
##################################
|
561
|
-
E().diff(E()).should be_empty
|
562
|
-
# because
|
563
|
-
E().should == E() # like above
|
564
|
-
|
565
617
|
ETag2 = E()
|
566
618
|
|
567
|
-
|
568
|
-
##################################
|
569
619
|
E().diff(ETag2).should be_empty
|
570
620
|
ETag2.diff(E()).should be_empty
|
621
|
+
|
571
622
|
# because
|
572
|
-
ETag2.should == E()
|
623
|
+
ETag2.should == E()
|
624
|
+
E().should == ETag2 # like above
|
573
625
|
|
626
|
+
end
|
627
|
+
|
628
|
+
it 'differs once a definition is present' do
|
629
|
+
|
630
|
+
# a tag to compare
|
631
|
+
##################################
|
632
|
+
ETag3 = E()
|
633
|
+
|
634
|
+
|
635
|
+
# ** definition **
|
574
636
|
E do
|
575
|
-
def foo
|
637
|
+
def foo
|
576
638
|
end
|
577
639
|
end
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
E
|
640
|
+
# ** definition **
|
641
|
+
|
642
|
+
|
643
|
+
# E is changed so...
|
644
|
+
####################################
|
645
|
+
E().diff(ETag3).should_not be_empty
|
646
|
+
|
582
647
|
# because
|
583
|
-
|
648
|
+
ETag3.should_not == E()
|
649
|
+
# and
|
650
|
+
E().diff(ETag3).delta.should == [:foo]
|
584
651
|
|
585
|
-
|
586
|
-
|
652
|
+
|
653
|
+
# Still not loaded
|
654
|
+
##################################
|
655
|
+
E().diff(ETag3).should_not be_loaded
|
656
|
+
|
587
657
|
# because
|
588
|
-
E().diff(
|
589
|
-
#
|
590
|
-
E().diff(
|
658
|
+
E().diff(ETag3).join.should == []
|
659
|
+
# even though
|
660
|
+
E().diff(ETag3).delta.should == [:foo]
|
591
661
|
|
592
|
-
|
662
|
+
|
663
|
+
# conversely
|
593
664
|
######################################
|
594
|
-
E().diff.should be_loaded
|
595
|
-
# because
|
596
665
|
E().diff.join.should == [:foo]
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
#
|
601
|
-
E().diff.
|
602
|
-
#
|
603
|
-
E().
|
604
|
-
|
666
|
+
# and
|
667
|
+
E().diff.delta.should == []
|
668
|
+
|
669
|
+
# because
|
670
|
+
E().diff.should_not be_loaded
|
671
|
+
# and
|
672
|
+
E().diff.should == [[:foo], []]
|
673
|
+
|
605
674
|
# being that
|
675
|
+
E().diff.should eq( E().diff(E().progenitor) )
|
606
676
|
E().progenitor.should equal(E().spec)
|
607
677
|
|
608
678
|
end
|
679
|
+
|
680
|
+
it 'works with more methods' do
|
681
|
+
|
682
|
+
# a tag to compare
|
683
|
+
##################################
|
684
|
+
ETag4 = E()
|
685
|
+
|
686
|
+
|
687
|
+
# ** definition **
|
688
|
+
E do
|
689
|
+
def foo
|
690
|
+
end
|
691
|
+
def bar
|
692
|
+
end
|
693
|
+
end
|
694
|
+
# ** definition **
|
695
|
+
|
696
|
+
|
697
|
+
#
|
698
|
+
##################################
|
699
|
+
E().diff(ETag4).join.should == []
|
700
|
+
E().diff(ETag4).delta.should == [:foo, :bar]
|
701
|
+
E().diff.join.should == [:foo, :bar]
|
702
|
+
E().diff.delta.should == []
|
703
|
+
|
704
|
+
# being that
|
705
|
+
E().diff.should eq( E().diff( E().progenitor) )
|
706
|
+
E().progenitor.should equal( E().spec )
|
707
|
+
|
708
|
+
end
|
709
|
+
|
710
|
+
it 'creates injectors for inclusion' do
|
711
|
+
|
712
|
+
# a tag to compare
|
713
|
+
##################################
|
714
|
+
ETag5 = E()
|
715
|
+
|
716
|
+
|
717
|
+
# ** definition **
|
718
|
+
E do
|
719
|
+
def foo
|
720
|
+
end
|
721
|
+
def bar
|
722
|
+
end
|
723
|
+
end
|
724
|
+
# ** definition **
|
725
|
+
|
726
|
+
|
727
|
+
E().diff.should be_empty
|
728
|
+
E().diff.join.should_not be_empty
|
729
|
+
E().diff.delta.should be_empty
|
730
|
+
E().diff.delta.injector.should_not eq(E().diff.join.injector)
|
731
|
+
|
732
|
+
end
|
733
|
+
|
609
734
|
end
|
610
735
|
|
611
736
|
end
|