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
@@ -380,7 +380,7 @@ describe Injectors, :injectors do
|
|
380
380
|
include Color
|
381
381
|
|
382
382
|
end
|
383
|
-
Widget.injectors.sym_list.should == [:
|
383
|
+
Widget.injectors.sym_list.should == [:color, :layout]
|
384
384
|
|
385
385
|
expect{Widget.new.expand}.to_not raise_error
|
386
386
|
expect{Widget.new.tint}.to_not raise_error
|
@@ -418,7 +418,7 @@ describe Injectors, :injectors do
|
|
418
418
|
injector :vanilla
|
419
419
|
|
420
420
|
cup = Coffee.new.enrich(milk).enrich(vanilla)
|
421
|
-
cup.injectors.sym_list.should == [:
|
421
|
+
cup.injectors.sym_list.should == [:vanilla, :milk]
|
422
422
|
|
423
423
|
end
|
424
424
|
|
@@ -428,14 +428,14 @@ describe Injectors, :injectors do
|
|
428
428
|
inject injector :one
|
429
429
|
inject injector :two
|
430
430
|
end
|
431
|
-
SomeClass.injectors.sym_list.should == [:
|
431
|
+
SomeClass.injectors.sym_list.should == [:two, :one]
|
432
432
|
|
433
433
|
end
|
434
434
|
|
435
435
|
the 'same is true at the class instance level' do
|
436
436
|
|
437
437
|
# from above
|
438
|
-
SomeClassInstance.injectors.sym_list.should == [:class_instance_injector]
|
438
|
+
SomeClassInstance.injectors(:all).sym_list.should == [:class_instance_injector]
|
439
439
|
|
440
440
|
end
|
441
441
|
|
@@ -480,7 +480,7 @@ describe Injectors, :injectors do
|
|
480
480
|
end
|
481
481
|
|
482
482
|
the 'functionality removed from a class INSTANCE
|
483
|
-
Note: when applied via the enrich
|
483
|
+
Note: when applied via the enrich keyword on the class' do
|
484
484
|
|
485
485
|
injector :part do
|
486
486
|
def connector
|
@@ -492,7 +492,7 @@ describe Injectors, :injectors do
|
|
492
492
|
Whole.extend part
|
493
493
|
|
494
494
|
Whole.connector.should == 'connected'
|
495
|
-
Whole.injectors.sym_list.should == [:part]
|
495
|
+
Whole.injectors(:all).sym_list.should == [:part]
|
496
496
|
|
497
497
|
# eject the part
|
498
498
|
|
@@ -526,7 +526,7 @@ describe Injectors, :injectors do
|
|
526
526
|
end
|
527
527
|
end
|
528
528
|
end
|
529
|
-
Home.injectors.sym_list.should == [:
|
529
|
+
Home.injectors.sym_list.should == [:materials, :layout ]
|
530
530
|
|
531
531
|
# build
|
532
532
|
my_home = Home.new
|
@@ -602,7 +602,7 @@ describe Injectors, :injectors do
|
|
602
602
|
tester1.order(50).should match( /|tester1| label for 50/ ) # call decorated method extended to self
|
603
603
|
|
604
604
|
|
605
|
-
$stdout.should_receive(:puts).with(
|
605
|
+
$stdout.should_receive(:puts).with( /|tester1| label for 30/ )
|
606
606
|
with tester1 do # with self(tester1)
|
607
607
|
puts order 30 # execute method
|
608
608
|
def receive weight # define singleton method
|
@@ -685,49 +685,49 @@ describe Injectors, :injectors do
|
|
685
685
|
|
686
686
|
the 'following class injection forms are all equivalent' do
|
687
687
|
|
688
|
-
injector :
|
688
|
+
injector :Base do
|
689
689
|
def meth
|
690
690
|
:meth
|
691
691
|
end
|
692
692
|
end
|
693
|
-
Injected.inject
|
693
|
+
Injected.inject Base()
|
694
694
|
Injected.new.meth.should == :meth
|
695
695
|
|
696
|
-
Injected.eject
|
696
|
+
Injected.eject Base()
|
697
697
|
end
|
698
698
|
the 'following class injection forms are all equivalent' do
|
699
699
|
|
700
|
-
Injected.inject
|
700
|
+
Injected.inject Base() do
|
701
701
|
def meth
|
702
702
|
:meth
|
703
703
|
end
|
704
704
|
end
|
705
705
|
Injected.new.meth.should == :meth
|
706
706
|
|
707
|
-
Injected.eject
|
707
|
+
Injected.eject Base()
|
708
708
|
end
|
709
709
|
the 'following class injection forms are all equivalent' do
|
710
710
|
|
711
|
-
injector( :
|
711
|
+
injector( :Base ){
|
712
712
|
def meth
|
713
713
|
:meth
|
714
714
|
end
|
715
715
|
}
|
716
|
-
Injected.inject
|
716
|
+
Injected.inject Base()
|
717
717
|
Injected.new.meth.should == :meth
|
718
718
|
|
719
|
-
Injected.eject
|
719
|
+
Injected.eject Base()
|
720
720
|
end
|
721
721
|
the 'following class injection forms are all equivalent' do
|
722
722
|
|
723
|
-
Injected.inject injector( :
|
723
|
+
Injected.inject injector( :Base ){
|
724
724
|
def meth
|
725
725
|
:meth
|
726
726
|
end
|
727
727
|
}
|
728
728
|
Injected.new.meth.should == :meth
|
729
729
|
|
730
|
-
Injected.eject
|
730
|
+
Injected.eject Base()
|
731
731
|
end
|
732
732
|
end
|
733
733
|
|
@@ -735,49 +735,49 @@ describe Injectors, :injectors do
|
|
735
735
|
|
736
736
|
the 'following instance enrichment forms are all equvalent' do
|
737
737
|
|
738
|
-
injector :
|
738
|
+
injector :base do
|
739
739
|
def meth
|
740
740
|
:meth
|
741
741
|
end
|
742
742
|
end
|
743
|
-
enrich
|
743
|
+
enrich base
|
744
744
|
meth.should == :meth
|
745
745
|
|
746
|
-
eject
|
746
|
+
eject base
|
747
747
|
end
|
748
748
|
the 'following instance enrichment forms are all equvalent' do
|
749
749
|
|
750
|
-
enrich injector :
|
750
|
+
enrich injector :base do
|
751
751
|
def meth
|
752
752
|
:meth
|
753
753
|
end
|
754
754
|
end
|
755
755
|
meth.should == :meth
|
756
756
|
|
757
|
-
eject
|
757
|
+
eject base
|
758
758
|
end
|
759
759
|
the 'following instance enrichment forms are all equvalent' do
|
760
760
|
|
761
|
-
injector( :
|
761
|
+
injector( :base ){
|
762
762
|
def meth
|
763
763
|
:meth
|
764
764
|
end
|
765
765
|
}
|
766
|
-
enrich
|
766
|
+
enrich base
|
767
767
|
meth.should == :meth
|
768
768
|
|
769
|
-
eject
|
769
|
+
eject base
|
770
770
|
end
|
771
771
|
the 'following instance enrichment forms are all equvalent' do
|
772
772
|
|
773
|
-
enrich injector( :
|
773
|
+
enrich injector( :base ){
|
774
774
|
def meth
|
775
775
|
:meth
|
776
776
|
end
|
777
777
|
}
|
778
778
|
meth.should == :meth
|
779
779
|
|
780
|
-
eject
|
780
|
+
eject base
|
781
781
|
end
|
782
782
|
|
783
783
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require "spec_helper"
|
2
|
+
|
2
3
|
=begin rdoc
|
3
4
|
This file contains the specs for the GOF Decorator Pattern and
|
4
5
|
Strategy Pattern use cases for injectors.
|
@@ -19,7 +20,8 @@ describe 'some use cases', :injectors do
|
|
19
20
|
1.50
|
20
21
|
end
|
21
22
|
end
|
22
|
-
|
23
|
+
|
24
|
+
# debugger
|
23
25
|
injector :milk do
|
24
26
|
def cost
|
25
27
|
super() + 0.30
|
@@ -57,7 +59,7 @@ describe 'some use cases', :injectors do
|
|
57
59
|
end
|
58
60
|
|
59
61
|
cup = Coffee.new.enrich(milk).enrich(vanilla).enrich(vanilla)
|
60
|
-
cup.injectors.sym_list.should == [:
|
62
|
+
cup.injectors.sym_list.should == [:vanilla, :vanilla, :milk]
|
61
63
|
cup.cost.should == 2.10
|
62
64
|
cup.should be_instance_of(Coffee)
|
63
65
|
|
@@ -94,13 +96,13 @@ describe 'some use cases', :injectors do
|
|
94
96
|
end
|
95
97
|
|
96
98
|
cup.enrich(vanilla)
|
97
|
-
cup.injectors.sym_list.should == [:
|
99
|
+
cup.injectors.sym_list.should == [:vanilla, :vanilla, :milk]
|
98
100
|
cup.cost.should == 2.10
|
99
101
|
cup.appearance.should == 'extra red vanilla'
|
100
102
|
|
101
103
|
end
|
102
104
|
|
103
|
-
a 'bigger example' do
|
105
|
+
a 'bigger example using normal Injector inheritance' do
|
104
106
|
|
105
107
|
# some data
|
106
108
|
|
@@ -130,7 +132,7 @@ describe 'some use cases', :injectors do
|
|
130
132
|
|
131
133
|
DesktopDecorator = WidgetDecorator do
|
132
134
|
def render
|
133
|
-
dim '600px', '200px'
|
135
|
+
dim '600px', '200px' # inherited
|
134
136
|
%{
|
135
137
|
<style>
|
136
138
|
#MyWidget{
|
@@ -146,7 +148,7 @@ describe 'some use cases', :injectors do
|
|
146
148
|
|
147
149
|
MobileDecorator = WidgetDecorator do
|
148
150
|
def render content
|
149
|
-
dim '200px', '600px'
|
151
|
+
dim '200px', '600px' # inherited
|
150
152
|
%{
|
151
153
|
<style>
|
152
154
|
#MyWidget{
|
@@ -165,6 +167,8 @@ describe 'some use cases', :injectors do
|
|
165
167
|
|
166
168
|
browser = 'Safari'
|
167
169
|
@content = database_content
|
170
|
+
|
171
|
+
# apply the decorators
|
168
172
|
|
169
173
|
my_widget = case browser
|
170
174
|
when match(/Safari|Firefox|IE/)
|
@@ -187,8 +191,144 @@ describe 'some use cases', :injectors do
|
|
187
191
|
}.split.join
|
188
192
|
)
|
189
193
|
|
194
|
+
WidgetDecorator(:implode)
|
195
|
+
|
190
196
|
end
|
191
197
|
|
198
|
+
a 'different way of doing it using: JIT inheritance' do
|
199
|
+
|
200
|
+
# some data
|
201
|
+
|
202
|
+
def database_content
|
203
|
+
%{car truck airplane boat}
|
204
|
+
end
|
205
|
+
|
206
|
+
# rendering helper controls
|
207
|
+
|
208
|
+
class MyWidgetClass
|
209
|
+
def initialize(content)
|
210
|
+
@content = content
|
211
|
+
end
|
212
|
+
|
213
|
+
def render
|
214
|
+
"<div id='MyWidget'>#{@content}</div>"
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
|
219
|
+
MainDecorator = injector :WidgetDecorator do
|
220
|
+
|
221
|
+
attr_accessor :font, :width, :height
|
222
|
+
|
223
|
+
def dim(width, heigth)
|
224
|
+
@width, @heigth = width, heigth
|
225
|
+
end
|
226
|
+
|
227
|
+
def render
|
228
|
+
%{
|
229
|
+
<style>
|
230
|
+
#MyWidget{
|
231
|
+
font: 14px, #{@font};
|
232
|
+
width:#{@width};
|
233
|
+
height: #{@heigth}
|
234
|
+
}
|
235
|
+
</style>
|
236
|
+
#{super()}
|
237
|
+
}
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
# somewhere in a view
|
242
|
+
|
243
|
+
browser = 'Safari'
|
244
|
+
@content = database_content
|
245
|
+
|
246
|
+
my_widget = case browser
|
247
|
+
when match(/Safari|Firefox|IE/)
|
248
|
+
# debugger
|
249
|
+
MyWidgetClass.new(@content).enrich(WidgetDecorator() do
|
250
|
+
|
251
|
+
def render # override invoking JIT inheritance
|
252
|
+
dim '600px', '200px' # normal inherited method call
|
253
|
+
@font = 'helvetica'
|
254
|
+
|
255
|
+
super()
|
256
|
+
end
|
257
|
+
end)
|
258
|
+
|
259
|
+
else
|
260
|
+
MyWidgetClass.new(@content).enrich(WidgetDecorator() do
|
261
|
+
|
262
|
+
def render # override invoking JIT inheritance
|
263
|
+
dim '200px', '600px' # normal inherited method call
|
264
|
+
@font ='arial'
|
265
|
+
|
266
|
+
super()
|
267
|
+
end
|
268
|
+
end)
|
269
|
+
end
|
270
|
+
|
271
|
+
expect(WidgetDecorator().ancestors).to eq([WidgetDecorator(), MainDecorator])
|
272
|
+
|
273
|
+
expect(
|
274
|
+
my_widget.render.split.join).to eq( # split.join used for comparison
|
275
|
+
%{
|
276
|
+
<style>
|
277
|
+
#MyWidget {
|
278
|
+
font: 14px, helvetica;
|
279
|
+
width:600px;
|
280
|
+
height:200px
|
281
|
+
}
|
282
|
+
</style>
|
283
|
+
<div id='MyWidget'>car truck airplane boat</div>
|
284
|
+
}.split.join
|
285
|
+
)
|
286
|
+
|
287
|
+
|
288
|
+
# browser = 'mobile'
|
289
|
+
# @content = database_content
|
290
|
+
#
|
291
|
+
# my_widget = case browser
|
292
|
+
# when match(/Safari|Firefox|IE/)
|
293
|
+
# # debugger
|
294
|
+
# MyWidgetClass.new(@content).enrich(WidgetDecorator() do
|
295
|
+
#
|
296
|
+
# def render
|
297
|
+
# dim '600px', '200px'
|
298
|
+
# @font ='helvetica'
|
299
|
+
#
|
300
|
+
# super()
|
301
|
+
# end
|
302
|
+
# end)
|
303
|
+
# else
|
304
|
+
# MyWidgetClass.new(@content).enrich(WidgetDecorator() do
|
305
|
+
# def render
|
306
|
+
# dim '200px', '600px'
|
307
|
+
# @font ='arial'
|
308
|
+
#
|
309
|
+
# super()
|
310
|
+
# end
|
311
|
+
# end)
|
312
|
+
# end
|
313
|
+
# expect(
|
314
|
+
#
|
315
|
+
# my_widget.render.split.join).to eq( # split.join used for comparison
|
316
|
+
# %{
|
317
|
+
# <style>
|
318
|
+
# #MyWidget {
|
319
|
+
# font: 14px, arial;
|
320
|
+
# width:200px;
|
321
|
+
# height:600px
|
322
|
+
# }
|
323
|
+
# </style>
|
324
|
+
# <div id='MyWidget'>car truck airplane boat</div>
|
325
|
+
# }.split.join
|
326
|
+
# )
|
327
|
+
|
328
|
+
WidgetDecorator(:implode)
|
329
|
+
|
330
|
+
end
|
331
|
+
|
192
332
|
end
|
193
333
|
|
194
334
|
describe 'strategy pattern.' do
|
@@ -396,15 +536,7 @@ describe 'some use cases', :injectors do
|
|
396
536
|
Client.solve
|
397
537
|
|
398
538
|
end
|
399
|
-
|
400
539
|
end
|
401
540
|
|
402
|
-
# describe 'use in rails' do
|
403
|
-
#
|
404
|
-
# it 'allows replacing draper'
|
405
|
-
# it 'allows decorating anything not just models'
|
406
|
-
#
|
407
|
-
# end
|
408
|
-
|
409
541
|
end
|
410
542
|
|
@@ -1,14 +1,153 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
=begin rdoc
|
3
|
-
|
3
|
+
|
4
|
+
This file represents a different approach to refining a class using Jackbox Modular Closures.
|
4
5
|
|
5
6
|
lha
|
7
|
+
|
6
8
|
=end
|
7
9
|
|
10
|
+
|
8
11
|
# Jackbox Reclassings
|
9
12
|
############################################
|
10
13
|
|
11
14
|
# RubyProf.start
|
15
|
+
describe 're-classings' do
|
16
|
+
|
17
|
+
it 'refines classes within namespaces' do
|
18
|
+
|
19
|
+
module Work
|
20
|
+
lets String do
|
21
|
+
def self.new(*args)
|
22
|
+
"+++#{super}+++"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class WorkAholic
|
28
|
+
include Work
|
29
|
+
|
30
|
+
def work_method
|
31
|
+
String('Men-At-Work')
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
str = WorkAholic.new.work_method
|
36
|
+
str.should == '+++Men-At-Work+++'
|
37
|
+
|
38
|
+
str = String('Men-At-Work') # Regular Kernel version
|
39
|
+
str = 'Men-At-Work'
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'works with Ruby Code Injectors' do
|
44
|
+
#
|
45
|
+
# Our first Injector
|
46
|
+
#
|
47
|
+
Sr1 = jack :StringRefinements do
|
48
|
+
lets String do
|
49
|
+
def self.new *args, &code
|
50
|
+
super(*args, &code) + ' is a special string'
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class OurClass
|
56
|
+
include Sr1 # include Tag
|
57
|
+
|
58
|
+
def foo_bar
|
59
|
+
String('foo and bar')
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
c = OurClass.new
|
64
|
+
|
65
|
+
c.foo_bar.class.should == String
|
66
|
+
c.foo_bar.should == 'foo and bar is a special string'
|
67
|
+
expect{c.foo_bar.extra.should == :extra}.to raise_error(NoMethodError)
|
68
|
+
|
69
|
+
#
|
70
|
+
# A second injector in the mix
|
71
|
+
#
|
72
|
+
jack :Log do
|
73
|
+
require 'logger'
|
74
|
+
def to_log arg
|
75
|
+
(@log ||= Logger.new($stdout)).warn(arg)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
StringRefinements do
|
80
|
+
String() do
|
81
|
+
inject Log()
|
82
|
+
|
83
|
+
def show
|
84
|
+
to_log self
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
c.foo_bar.class.should == String
|
90
|
+
c.foo_bar.should == 'foo and bar is a special string'
|
91
|
+
|
92
|
+
$stdout.should_receive(:write).with(/foo and bar is a special string/).at_least(1)
|
93
|
+
|
94
|
+
c.foo_bar.show
|
95
|
+
|
96
|
+
#
|
97
|
+
# lets redfine our first String()
|
98
|
+
# -- SR1 and SR2 are different injectable String()
|
99
|
+
#
|
100
|
+
Sr2 = StringRefinements do # New String refinement
|
101
|
+
lets String do
|
102
|
+
inject Log()
|
103
|
+
|
104
|
+
def self.new *args
|
105
|
+
super + '****'
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
class OurOtherClass
|
111
|
+
include Sr2 # Apply new tag
|
112
|
+
|
113
|
+
def foo_bar
|
114
|
+
String('foo and bar')
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
d = OurOtherClass.new
|
119
|
+
|
120
|
+
d.foo_bar.class.should == String
|
121
|
+
d.foo_bar.should == 'foo and bar****'
|
122
|
+
|
123
|
+
expect{ d.foo_bar.show }.to raise_error(NoMethodError)
|
124
|
+
$stdout.should_receive(:write).with(/foo/).at_least(1)
|
125
|
+
expect{ d.foo_bar.to_log 'foo' }.to_not raise_error
|
126
|
+
|
127
|
+
# c is still the same
|
128
|
+
|
129
|
+
c.foo_bar.class.should == String
|
130
|
+
c.foo_bar.should == 'foo and bar is a special string'
|
131
|
+
|
132
|
+
|
133
|
+
# String is untouched
|
134
|
+
|
135
|
+
String("foo").should == 'foo'
|
136
|
+
String.new("foo").should == 'foo'
|
137
|
+
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
|
142
|
+
# ################################# IMPORTANT ########################################
|
143
|
+
# #
|
144
|
+
# Although the above is for what reclassings are designed, in the following exmaples #
|
145
|
+
# we test some of the more basic and ruby integration aspects of re-classings. #
|
146
|
+
# Note: reclassings used on a top level will hide any Kernel methods by the same #
|
147
|
+
# type name. Their use case is like the above or in some name space. See below. #
|
148
|
+
# #
|
149
|
+
# ################################# IMPORTANT ########################################
|
150
|
+
|
12
151
|
|
13
152
|
injector :StringExtensions do # define injector
|
14
153
|
def to_s
|
@@ -16,8 +155,9 @@ injector :StringExtensions do # define injector
|
|
16
155
|
end
|
17
156
|
end
|
18
157
|
|
19
|
-
#
|
20
|
-
|
158
|
+
# Note: This reclassing hides Kernel.String() -- use
|
159
|
+
# fully qualified name to access original version
|
160
|
+
lets String do # apply injector
|
21
161
|
include StringExtensions()
|
22
162
|
end
|
23
163
|
|
@@ -35,7 +175,8 @@ describe :String do
|
|
35
175
|
end
|
36
176
|
|
37
177
|
|
38
|
-
# Another Reclassing
|
178
|
+
# Another Top-level Reclassing
|
179
|
+
# Note: same as above
|
39
180
|
|
40
181
|
jack :ArrayExtensions do
|
41
182
|
def to_s
|
@@ -122,6 +263,7 @@ module M7
|
|
122
263
|
def foo_bar
|
123
264
|
Array(2)
|
124
265
|
end
|
266
|
+
|
125
267
|
end
|
126
268
|
|
127
269
|
class A6
|
@@ -142,9 +284,9 @@ end
|
|
142
284
|
|
143
285
|
|
144
286
|
|
145
|
-
#
|
287
|
+
# Introspection
|
146
288
|
##################################################
|
147
|
-
|
289
|
+
|
148
290
|
assert( A6.new.foo_bar.injectors.by_name == [:NameSpacedArrayExtensions] )
|
149
291
|
|
150
292
|
describe "introspection" do
|
@@ -152,11 +294,23 @@ describe "introspection" do
|
|
152
294
|
# introspecting on capabilities
|
153
295
|
|
154
296
|
it 'should allow injector introspection' do
|
155
|
-
|
297
|
+
|
298
|
+
StringRefinements do
|
299
|
+
(reclass? String).should == true
|
300
|
+
|
301
|
+
String() do
|
302
|
+
injectors.by_name.should == [:Log]
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
end
|
307
|
+
|
308
|
+
it 'should allow injector introspection' do
|
309
|
+
# top level re-class
|
156
310
|
Array() do
|
157
311
|
injectors.by_name.should == [:ArrayExtensions]
|
158
312
|
end
|
159
|
-
|
313
|
+
|
160
314
|
Array(){injectors.by_name}.should == [:ArrayExtensions]
|
161
315
|
|
162
316
|
# top level re-class instances
|
@@ -165,11 +319,13 @@ describe "introspection" do
|
|
165
319
|
end
|
166
320
|
|
167
321
|
it 'works on namespaced reclassings' do
|
322
|
+
|
168
323
|
module M7
|
169
|
-
|
324
|
+
|
170
325
|
Array() do
|
171
326
|
injectors.by_name.should == [:NameSpacedArrayExtensions]
|
172
327
|
end
|
328
|
+
|
173
329
|
end
|
174
330
|
end
|
175
331
|
|
@@ -192,75 +348,6 @@ describe "introspection" do
|
|
192
348
|
|
193
349
|
end
|
194
350
|
|
195
|
-
it 'works' do
|
196
|
-
|
197
|
-
# Injector declaration
|
198
|
-
|
199
|
-
jack :StringRefinements do
|
200
|
-
lets String do
|
201
|
-
with singleton_class do
|
202
|
-
alias _new new
|
203
|
-
def new *args, &code
|
204
|
-
super(*args, &code) + ' is a special string'
|
205
|
-
end
|
206
|
-
end
|
207
|
-
end
|
208
|
-
end
|
209
|
-
|
210
|
-
class OurClass
|
211
|
-
include StringRefinements()
|
212
|
-
|
213
|
-
def foo_bar
|
214
|
-
String('foo and bar')
|
215
|
-
end
|
216
|
-
end
|
217
|
-
|
218
|
-
c = OurClass.new
|
219
|
-
c.foo_bar.class.should == String
|
220
|
-
c.foo_bar.should == 'foo and bar is a special string'
|
221
|
-
expect{c.foo_bar.extra.should == :extra}.to raise_error(NoMethodError)
|
222
|
-
|
223
|
-
StringRefinements do
|
224
|
-
String() do
|
225
|
-
def extra
|
226
|
-
:extra
|
227
|
-
end
|
228
|
-
end
|
229
|
-
end
|
230
|
-
|
231
|
-
c.foo_bar.should == 'foo and bar is a special string'
|
232
|
-
c.foo_bar.class.should == String
|
233
|
-
c.foo_bar.extra.should == :extra
|
234
|
-
|
235
|
-
SR = StringRefinements do # New Version
|
236
|
-
lets String do
|
237
|
-
def to_s
|
238
|
-
super + '****'
|
239
|
-
end
|
240
|
-
end
|
241
|
-
end
|
242
|
-
|
243
|
-
# c is still the same
|
244
|
-
|
245
|
-
c.foo_bar.should == 'foo and bar is a special string'
|
246
|
-
c.foo_bar.class.should == String
|
247
|
-
c.foo_bar.extra.should == :extra
|
248
|
-
|
249
|
-
|
250
|
-
class OurOtherClass
|
251
|
-
include SR # Apply new version
|
252
|
-
# to another class
|
253
|
-
def foo_bar
|
254
|
-
String('foo and bar')
|
255
|
-
end
|
256
|
-
end
|
257
|
-
|
258
|
-
d = OurOtherClass.new
|
259
|
-
d.foo_bar.should == 'foo and bar'
|
260
|
-
d.foo_bar.to_s.should == 'foo and bar****'
|
261
|
-
expect{ d.extra }.to raise_error(NoMethodError)
|
262
|
-
|
263
|
-
end
|
264
351
|
end
|
265
352
|
|
266
353
|
|