jackbox 0.9.6.3 → 0.9.6.6

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.
@@ -4,7 +4,7 @@ require "spec_helper"
4
4
  VIRTUAL METHOD CACHE
5
5
 
6
6
  Virtual methods are methods that have not beeen applied as part of any injection as of yet. They are not part of a version, execpt for the current one.
7
- In as such, they are common to all injectors, and can service any of them. They stop being virtual when they become part of an injector application.
7
+ In as such, they are common to all traits, and can service any of them. They stop being virtual when they become part of an trait application.
8
8
  =end
9
9
  include Injectors
10
10
 
@@ -155,7 +155,7 @@ describe "VMC (Virtual Method Cache)" do
155
155
  def j1 # they becomen part of the
156
156
  :j1
157
157
  end # following application of
158
- end # this injector
158
+ end # this trait
159
159
 
160
160
  K1 do
161
161
  def k1
@@ -163,7 +163,7 @@ describe "VMC (Virtual Method Cache)" do
163
163
  end
164
164
  end
165
165
  J1 do
166
- inject K1() # injector application!
166
+ inject K1() # trait application!
167
167
  end
168
168
 
169
169
  L1 do
@@ -172,7 +172,7 @@ describe "VMC (Virtual Method Cache)" do
172
172
  end
173
173
  end
174
174
  K1 do
175
- inject L1() # injector application
175
+ inject L1() # trait application
176
176
  end
177
177
 
178
178
  M1() do
@@ -205,26 +205,28 @@ describe "VMC (Virtual Method Cache)" do
205
205
  Object.inject J1()
206
206
 
207
207
  J1 do
208
- def j1 # virtual methods
208
+ def j1 # virtual cache methods
209
209
  :j1
210
210
  end
211
211
  def meth
212
- super + "#{j1}"
212
+ "#{j1}-" + super
213
213
  end
214
+ inject(K1())
214
215
  end
215
216
 
216
- J1().inject K1()
217
+ expect{J1().inject K1()}.to raise_error(NoMethodError)
217
218
 
218
219
  K1 do
219
220
  def k1 # virtual methods
220
221
  :k1
221
222
  end
222
223
  def meth
223
- super + "#{k1}"
224
+ "#{k1}-" + super
224
225
  end
226
+ inject(L1())
225
227
  end
226
228
 
227
- K1().inject L1()
229
+ expect{K1().inject L1()}.to raise_error(NoMethodError)
228
230
 
229
231
  L1 do
230
232
  def meth # virtual methods
@@ -233,10 +235,167 @@ describe "VMC (Virtual Method Cache)" do
233
235
  end
234
236
 
235
237
  o = Object.new
236
- o.meth.should == 'l1k1j1' # this call is on the VMC!!!
238
+ o.meth.should == 'j1-k1-l1' # this call is on the VMC!!!
237
239
 
238
240
  end
239
241
 
242
+ it 'works accross compound traits' do
243
+
244
+ jack :S1
245
+
246
+ S1 do
247
+ include jack :s2 do
248
+ def s2m1
249
+ :s2m1
250
+ end
251
+ include jack :s3 do
252
+ def s3m1
253
+ :s3m1
254
+ end
255
+ include jack :s4 do
256
+ def s4m1
257
+ :s4m1
258
+ end
259
+ end
260
+ end
261
+ end
262
+ end
263
+
264
+ S1().s2.s3.s4 # trait pipeline!
265
+
266
+
267
+ # Apply the traits
268
+
269
+ class CompoundContainer
270
+ include S1()
271
+ end
272
+
273
+ CompoundContainer.new.s2m1.should == :s2m1
274
+ CompoundContainer.new.s3m1.should == :s3m1
275
+ CompoundContainer.new.s4m1.should == :s4m1
276
+
277
+
278
+ # Add methods to the VMC of s3
279
+
280
+ S1().s2.s3 do
281
+ def s3m2
282
+ :s3m2
283
+ end
284
+ end
285
+
286
+ CompoundContainer.new.s3m2.should == :s3m2
287
+
288
+
289
+ # Create a version Tag
290
+
291
+ AccessTag = S1()
292
+
293
+ class SecondContainer
294
+ include AccessTag
295
+ end
296
+
297
+ SecondContainer.new.s3m2.should == :s3m2
298
+
299
+ end
300
+
301
+ it 'works in different ways' do
302
+
303
+ expect{
304
+
305
+ trait :J1
306
+ trait :J2
307
+ trait :J3
308
+
309
+ class AA1
310
+ end
311
+ J1 do
312
+ include J2()
313
+ end
314
+ J2 do
315
+ def mJ2 # virtual cache method
316
+ :mJ2
317
+ end
318
+ end
319
+ J1 do
320
+ def mJ1 # applied method
321
+ :mJ1
322
+ end
323
+ end
324
+ class AA1
325
+ include J1()
326
+ end
327
+
328
+ AA1.new.mJ2.should == :mJ2
329
+ AA1.new.mJ1.should == :mJ1
330
+
331
+ }.not_to raise_error
332
+
333
+ end
334
+
335
+ a 'different example' do
336
+
337
+ expect{
338
+
339
+ trait :K1
340
+ trait :K2
341
+ trait :K3
342
+
343
+ K1 do
344
+ include K2() do
345
+ def mj2 # applied method
346
+ :mj2
347
+ end
348
+ end
349
+ end
350
+ class AA2
351
+ include K1()
352
+ end
353
+ AA2.new.mj2.should == :mj2
354
+ K2 do
355
+ include K3() do
356
+ def mj3 # virtual cache method with another indirect
357
+ :mj3
358
+ end
359
+ end
360
+ end
361
+ AA2.new.mj3.should == :mj3
362
+
363
+ }.not_to raise_error
364
+
365
+ end
366
+
367
+ a 'yet different one' do
368
+
369
+ expect{
370
+
371
+ trait :M1
372
+ trait :M2
373
+ trait :M3
374
+
375
+ M1 do
376
+ include M2() do
377
+ def mk2 # applied method
378
+ :mk2
379
+ end
380
+ end
381
+ end
382
+ class AA3
383
+ include M1()
384
+ end
385
+ AA3.new.mk2.should == :mk2
386
+ M2 do
387
+ include M3()
388
+ end
389
+ M3 do
390
+ def mk3 # virtual cache method
391
+ :mk3
392
+ end
393
+ end
394
+ AA3.new.mk3.should == :mk3
395
+
396
+ }.not_to raise_error
397
+
398
+ end
240
399
 
241
400
  end
242
401
 
@@ -39,27 +39,6 @@ describe Jackbox, 'jackbox library', :library do
39
39
 
40
40
  end
41
41
 
42
- it 'allows decorating the same method multiple times' do
43
-
44
- class T
45
- def bar
46
- 'bar '
47
- end
48
- end
49
- class T
50
- decorate :bar do # <- GETS CLOBERED
51
- super() + 'none '
52
- end
53
- end
54
- class T
55
- decorate :bar do
56
- super() + 'and then some'
57
- end
58
- end
59
- expect{T.new.bar.should == 'bar and then some'}.to_not raise_error
60
-
61
- end
62
-
63
42
  it 'is available at the object instance level during execution' do
64
43
 
65
44
  class One
@@ -80,99 +59,58 @@ describe Jackbox, 'jackbox library', :library do
80
59
 
81
60
  end
82
61
 
62
+ it 'also works like so' do
63
+
64
+ Object.decorate :to_s do
65
+ super() + " is your object"
66
+ end
67
+ Object.new.to_s.should match(/is your object/)
68
+
69
+ end
70
+
83
71
  it 'allows ruby_c objects and singleton classes to be decorated as well' do
84
72
 
85
- STDOUT.should_receive(:puts).with("Changing directory...")
86
-
87
- Dir.singleton_class.instance_eval do
88
- decorate :chdir do |*args|
89
- puts 'Changing directory...'
90
- super(*args)
91
- end
73
+ Dir.singleton_class.decorate :chdir do |*args|
74
+ puts 'Changing directory...'
75
+ super(*args)
92
76
  end
77
+
78
+ STDOUT.should_receive(:puts).with("Changing directory...")
93
79
  Dir.chdir('.').should == 0
94
- Dir.singleton_class.instance_eval { undecorate :chdir }
80
+
81
+ Dir.metaclass.undecorate :chdir
95
82
 
83
+ STDOUT.should_not_receive(:puts).with("Changing directory...")
84
+ Dir.chdir('.').should == 0
85
+
96
86
  end
97
87
 
98
88
  it 'raises an error when decorating singleton classes without returning them properly' do
99
89
 
100
90
  expect {
101
91
 
102
- class File
92
+ class File # MUST USE #singleton_class or #metaclass
103
93
  class << self
104
94
  decorate :chown do |*args| end
105
95
  end
106
96
  end
107
97
 
108
- }.to raise_error
98
+ }.to raise_error(UserError)
99
+
109
100
  expect {
110
101
 
111
102
  class File
112
- singleton_class.instance_eval do # MUST USE #singleton_class or #metaclass
113
- decorate :chown do |*args| end
103
+ metaclass.decorate :chown do |*args|
104
+ puts 'Changing ownership...'
105
+ super(*args)
114
106
  end
115
107
  end
116
108
 
109
+ File.metaclass.undecorate :chown
110
+
117
111
  }.to_not raise_error
118
112
 
119
113
  end
120
-
121
- the 'decoration can be rolled back' do
122
-
123
- class F
124
- def bar
125
- 'bar '
126
- end
127
- end
128
- class F
129
- decorate :bar do
130
- super() + 'the unforseen'
131
- end
132
- end
133
- F.new.bar.should == 'bar the unforseen'
134
- class F
135
- # remove_method :bar
136
- undecorate :bar
137
- end
138
- F.new.bar.should == 'bar '
139
-
140
- end
141
-
142
- this 'roll-back works on singleton_class also' do
143
-
144
- class G
145
- class << self
146
- def moo
147
- 'moooo'
148
- end
149
- end
150
- end
151
- class G
152
- singleton_class.instance_eval do
153
- decorate :moo do
154
- super() + ' maaaa'
155
- end
156
- end
157
- end
158
- G.moo.should == 'moooo maaaa'
159
- class G
160
- singleton_class.instance_eval do
161
- undecorate :moo
162
- end
163
- end
164
- G.moo.should == 'moooo'
165
-
166
- end
167
-
168
- it 'also works like so' do
169
-
170
- Object.decorate :inspect do
171
- super() + " is your object"
172
- end
173
- Object.new.inspect.should =~ /is your object/
174
-
175
- end
176
114
 
177
115
  it 'does not work on undefined methods' do
178
116
 
@@ -185,7 +123,7 @@ describe Jackbox, 'jackbox library', :library do
185
123
  :boo
186
124
  end
187
125
  end
188
- }.to raise_error
126
+ }.to raise_error(NameError)
189
127
  end
190
128
 
191
129
  it 'is not intended to work on plain modules' do
@@ -212,13 +150,13 @@ describe Jackbox, 'jackbox library', :library do
212
150
 
213
151
  B.new.off.should == 'offon' #fails!!
214
152
 
215
- }.to raise_error
153
+ }.to raise_error(RSpec::Expectations::ExpectationNotMetError)
216
154
 
217
155
  end
218
156
 
219
- it 'is not intended for plain injectors either' do
157
+ it 'is not intended for plain traits either' do
220
158
 
221
- Aj = injector :aj do
159
+ Aj = trait :aj do
222
160
  def off
223
161
  'off'
224
162
  end
@@ -241,33 +179,177 @@ describe Jackbox, 'jackbox library', :library do
241
179
 
242
180
  Bj.new.off.should == 'offon' #fails!!
243
181
 
244
- }.to raise_error
182
+ }.to raise_error(RSpec::Expectations::ExpectationNotMetError)
245
183
 
246
184
  end
247
185
 
248
- it 'does work on self-extended injectors/modules' do
186
+ it 'does work on trait/module metaclass' do
249
187
 
250
- include Injectors
251
-
252
- injector :tester
188
+ trait :tester
253
189
 
254
190
  tester do
255
191
  extend self # extend self
256
- # Note: you cannot self enrich an injector
192
+ # Note: you cannot self enrich an trait
257
193
  def order weight
258
- lets manus =->(){"manus for #{weight}"}
259
- manus[]
194
+ lets price =->(weight){ 10 * weight }
195
+ "price for #{weight} is #{price[weight]}"
260
196
  end
261
197
  end
262
- tester.order(50).should == 'manus for 50' # call method extended to self
198
+ tester.order(50).should == 'price for 50 is 500' # call method extended to self
263
199
 
264
200
 
265
201
  tester do
266
202
  decorate :order do |num| # decorate the same method
267
- self.to_s + super(num)
203
+ "#{self} says: " + super(num) + ' dollars'
268
204
  end
269
205
  end
270
- tester.order(50).should =~ /^|manus| for 50/ # call decorated method extended to self
206
+ tester.order(50).should match(/^\(|tester|.+\) says: price for 50 is 500 dollars/) # call decorated method extended to self
207
+
208
+ # undecorate
209
+
210
+ tester.undecorate :order
211
+ tester.order(30).should == 'price for 30 is 300'
212
+ end
213
+
214
+ end
215
+
216
+ describe 'redecoration' do
217
+
218
+ before do
219
+ class T
220
+ def bar
221
+ 'bar '
222
+ end
223
+ end
224
+ class U
225
+ def bar
226
+ 'bar'
227
+ end
228
+ end
229
+ end
230
+
231
+ it 'allows decorating the same method multiple times' do
232
+
233
+ class T
234
+ decorate :bar do # <- GETS CLOBERED
235
+ super() + 'none '
236
+ end
237
+ end
238
+ class T
239
+ decorate :bar do
240
+ super() + 'and then some'
241
+ end
242
+ end
243
+ expect{T.new.bar.should == 'bar and then some'}.to_not raise_error
244
+
245
+ end
246
+
247
+ it 'also works on instances' do
248
+
249
+ u = U.new
250
+
251
+ u.decorate :bar do
252
+ 'large ' + super()
253
+ end
254
+
255
+ u.bar.should == 'large bar'
256
+
257
+ u.decorate :bar do
258
+ 'small ' + super()
259
+ end
260
+
261
+ u.bar.should == 'small bar'
262
+
263
+ end
264
+
265
+
266
+ end
267
+
268
+ describe 'undecoration' do
269
+
270
+ the 'decoration can be rolled back' do
271
+
272
+ class F
273
+ def bar
274
+ 'bar '
275
+ end
276
+ end
277
+ class F
278
+ decorate :bar do
279
+ super() + 'the unforseen'
280
+ end
281
+ end
282
+ F.new.bar.should == 'bar the unforseen'
283
+ class F
284
+ undecorate :bar
285
+ end
286
+ F.new.bar.should == 'bar '
287
+
288
+ end
289
+
290
+ this 'roll-back works on singleton_class also' do
291
+
292
+ class G
293
+ class << self
294
+ def moo
295
+ 'moooo'
296
+ end
297
+ end
298
+ end
299
+ class G
300
+ singleton_class.instance_eval do
301
+ decorate :moo do
302
+ super() + ' maaaa'
303
+ end
304
+ end
305
+ end
306
+ G.moo.should == 'moooo maaaa'
307
+ class G
308
+ singleton_class.instance_eval do
309
+ undecorate :moo
310
+ end
311
+ end
312
+ G.moo.should == 'moooo'
313
+
314
+ end
315
+
316
+ it 'also works like so' do
317
+
318
+ Object.decorate :to_s do
319
+ super() + " is your object"
320
+ end
321
+ Object.new.to_s.should match(/is your object/)
322
+
323
+ # undecorate
324
+
325
+ Object.undecorate :to_s
326
+ Object.new.to_s.should_not match(/is your object/)
327
+
328
+ end
329
+
330
+ it 'also works on object instances' do
331
+
332
+ class Base
333
+ def foo
334
+ 'foo'
335
+ end
336
+ end
337
+
338
+ o = Base.new
339
+ o.decorate :foo do
340
+ super() + 'oof'
341
+ end
342
+ o.foo.should == 'foooof'
343
+
344
+ o.decorate :foo do
345
+ super() + 'foo'
346
+ end
347
+ o.foo.should == 'foofoo'
348
+
349
+ # undecorate
350
+
351
+ o.undecorate :foo
352
+ o.foo.should == 'foo'
271
353
 
272
354
  end
273
355
 
@@ -312,6 +394,7 @@ describe Jackbox, 'jackbox library', :library do
312
394
  end
313
395
 
314
396
  it 'should not forbid the following' do
397
+
315
398
  # does work at the instance level
316
399
  expect {
317
400
 
@@ -319,7 +402,7 @@ describe Jackbox, 'jackbox library', :library do
319
402
  lets(:foo){ 'foo bar'}
320
403
  }
321
404
 
322
- }.to_not raise_error(Jackbox::UserError)
405
+ }.to_not raise_error
323
406
 
324
407
  end
325
408
 
@@ -331,7 +414,7 @@ describe Jackbox, 'jackbox library', :library do
331
414
 
332
415
  expect{
333
416
  make[:nothing]
334
- }.to raise_error
417
+ }.to raise_error(TypeError)
335
418
 
336
419
  end
337
420
  end
@@ -367,51 +450,51 @@ describe Jackbox, 'jackbox library', :library do
367
450
 
368
451
  end
369
452
 
370
- it 'allows passing instance variables' do
371
-
372
- STDOUT.should_receive(:puts).with('in One#foo with arg tester')
373
- STDOUT.should_receive(:puts).with('in One#foo with arg mester')
374
- STDOUT.should_receive(:puts).with('in One#foo with arg in Two#faa with arg me')
453
+ it 'allows the following' do
375
454
 
376
- class One
377
- def foo(arg)
378
- 'in One#foo with arg ' + arg
455
+ a = Object.new
456
+ with a do
457
+ def m1
379
458
  end
380
459
  end
381
- class Two
382
-
383
- def faa arg='nothing'
384
- 'in Two#faa with arg ' + arg
385
- end
386
-
387
- def fii
388
- @tester = 'tester'
389
- @mester = 'mester'
390
-
391
- with One.new, @tester, @mester do |*args|
392
- args.each { |e| puts foo e }
393
- puts foo faa 'me'
394
- end
460
+ b = Object.new
461
+ with b do
462
+ def m1
395
463
  end
396
-
397
464
  end
398
- Two.new.fii
465
+
466
+ with a, b do
467
+ m1
468
+ end
469
+
399
470
  end
400
471
 
401
472
  it 'raises an error if used with no block' do
473
+
402
474
  expect{with Object.new}.to raise_error(LocalJumpError)
475
+
403
476
  end
404
477
 
405
478
  it 'raises an error if used on self' do
406
479
  expect{
407
480
 
408
481
  with self do
409
-
482
+ # ...
410
483
  end
411
484
 
412
485
  }.to raise_error(ArgumentError)
413
486
  end
414
487
 
488
+ describe "with and include" do
489
+ it "should raise error" do
490
+ expect{
491
+ with Object.new do
492
+ include Module.new
493
+ end
494
+ }.to raise_error(NoMethodError)
495
+ end
496
+ end
497
+
415
498
  it 'works with decorate on an object multiple times' do
416
499
 
417
500
  class Object
@@ -431,7 +514,26 @@ describe Jackbox, 'jackbox library', :library do
431
514
  end
432
515
  o.foo.should == 'foo'
433
516
  o.moo.should == 'moo'
517
+
434
518
  end
519
+
520
+ it 'works with method_missing' do
521
+
522
+ o = Object.new
523
+ def o.method_missing sym, *args, &code
524
+ :mm
525
+ end
526
+ #existing mm
527
+ o.crap.should == :mm
528
+
529
+ with o do
530
+ crap.should == :mm
531
+ end
532
+
533
+ # still working
534
+ o.crap.should == :mm
535
+
536
+ end
435
537
 
436
538
  end
437
539
 
@@ -508,6 +610,14 @@ describe Jackbox, 'jackbox library', :library do
508
610
 
509
611
  end
510
612
 
613
+ it 'is porous to warnings' do
614
+
615
+ with Object.new do
616
+ warn 'test warning' # it works (check standard output)
617
+ end
618
+
619
+ end
620
+
511
621
  end
512
622
 
513
623