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.
- checksums.yaml +5 -13
- data/CHANGES.txt +38 -4
- data/LICENSE.lic +0 -0
- data/README.md +568 -364
- data/lib/jackbox.rb +1 -1
- data/lib/jackbox/injectors.rb +1 -1
- data/lib/jackbox/injectors/coda.rb +2 -0
- data/lib/jackbox/injectors/prelude.rb +2 -0
- 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/jackbox/injector_composition_spec.rb +111 -111
- data/spec/lib/jackbox/injector_directives_spec.rb +25 -27
- data/spec/lib/jackbox/injector_inheritance_spec.rb +610 -1004
- data/spec/lib/jackbox/injector_introspection_spec.rb +265 -219
- data/spec/lib/jackbox/injector_namespacing_spec.rb +17 -17
- data/spec/lib/jackbox/injector_spec.rb +26 -0
- data/spec/lib/jackbox/injector_versioning_spec.rb +37 -37
- data/spec/lib/jackbox/jiti_rules_spec.rb +663 -0
- data/spec/lib/jackbox/patterns_spec.rb +224 -122
- data/spec/lib/jackbox/prefs_spec.rb +4 -4
- data/spec/lib/jackbox/reclassing_spec.rb +154 -406
- data/spec/lib/jackbox/vmc_spec.rb +169 -10
- data/spec/lib/jackbox_spec.rb +241 -131
- metadata +26 -26
- data/spec/lib/jackbox/examples/dx_spec.rb +0 -346
@@ -172,14 +172,14 @@ describe 'what Prefs does' do
|
|
172
172
|
end
|
173
173
|
|
174
174
|
it 'should also allow classes to be used' do
|
175
|
-
class
|
175
|
+
class PrefC
|
176
176
|
extend Prefs
|
177
177
|
|
178
178
|
pref :boo => "something"
|
179
179
|
end
|
180
|
-
|
181
|
-
lambda{
|
182
|
-
lambda{
|
180
|
+
PrefC.boo.should == 'something'
|
181
|
+
lambda{PrefC.boo=(3)}.should_not raise_error
|
182
|
+
lambda{PrefC.new.boo}.should raise_error(NoMethodError)
|
183
183
|
end
|
184
184
|
|
185
185
|
it 'should be possible to reset the prefs to their defaults' do
|
@@ -3,16 +3,15 @@ require "spec_helper"
|
|
3
3
|
|
4
4
|
This file represents a different approach to refining a class using Jackbox Modular Closures.
|
5
5
|
|
6
|
+
The examples are necessarily long because we are testing lifecycle changes for these construct.
|
7
|
+
If we were to have simple unit testing we could have false positives form some of these tests.
|
8
|
+
|
6
9
|
lha
|
7
10
|
|
8
11
|
=end
|
9
12
|
|
10
|
-
|
11
|
-
# Jackbox Reclassings
|
12
|
-
############################################
|
13
|
-
|
14
13
|
# RubyProf.start
|
15
|
-
describe 're-
|
14
|
+
describe 're-classes' do
|
16
15
|
|
17
16
|
it 'refines classes within namespaces' do
|
18
17
|
|
@@ -38,444 +37,193 @@ describe 're-classings' do
|
|
38
37
|
str = String('Men-At-Work') # Regular Kernel version
|
39
38
|
str = 'Men-At-Work'
|
40
39
|
|
40
|
+
str = String.new('Men-At-Work') # Regular class version
|
41
|
+
str = 'Men-At-Work'
|
42
|
+
|
41
43
|
end
|
42
44
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
45
|
+
describe "interaction with Ruby Code Injector" do
|
46
|
+
before do
|
47
|
+
#
|
48
|
+
# Our first Injector
|
49
|
+
#
|
50
|
+
Sr1 = jack :StringRefinements do
|
51
|
+
lets String do
|
52
|
+
def self.new *args, &code
|
53
|
+
super + ' is a special string'
|
54
|
+
end
|
51
55
|
end
|
52
56
|
end
|
53
|
-
end
|
54
|
-
|
55
|
-
class OurClass
|
56
|
-
include Sr1 # include Tag
|
57
57
|
|
58
|
-
|
59
|
-
|
58
|
+
#
|
59
|
+
# A second trait in the mix
|
60
|
+
#
|
61
|
+
jack :Log do
|
62
|
+
require 'logger'
|
63
|
+
def to_log arg
|
64
|
+
(@log ||= Logger.new($stdout)).warn(arg)
|
65
|
+
end
|
60
66
|
end
|
61
|
-
end
|
62
67
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
+
#
|
69
|
+
# refine our re-class
|
70
|
+
StringRefinements do
|
71
|
+
String() do # add function to same String() reclass
|
72
|
+
inject Log()
|
73
|
+
|
74
|
+
def glow
|
75
|
+
to_log self
|
76
|
+
end
|
77
|
+
def foo
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
68
81
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
82
|
+
#
|
83
|
+
# lets redfine our first String()
|
84
|
+
# -- SR1 and SR2 are different injectable String()
|
85
|
+
#
|
86
|
+
Sr2 = StringRefinements do # New String refinement
|
87
|
+
lets String do
|
88
|
+
inject Log()
|
89
|
+
def self.new *args, &code
|
90
|
+
'--' + super + '--'
|
91
|
+
end
|
92
|
+
def glow
|
93
|
+
to_log self
|
94
|
+
end
|
95
|
+
end
|
76
96
|
end
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
97
|
+
|
98
|
+
#
|
99
|
+
# refine our re-class
|
100
|
+
StringRefinements do
|
101
|
+
String() do # add function to same String() reclass
|
102
|
+
# inject Log()
|
103
|
+
#
|
104
|
+
# def glow
|
105
|
+
# to_log self
|
106
|
+
# end
|
107
|
+
def foo
|
108
|
+
end
|
85
109
|
end
|
86
110
|
end
|
111
|
+
|
112
|
+
end
|
113
|
+
after do
|
114
|
+
StringRefinements(:implode)
|
87
115
|
end
|
88
116
|
|
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
117
|
|
94
|
-
|
118
|
+
it 'works with Ruby Code Injectors' do
|
95
119
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
inject Log()
|
103
|
-
|
104
|
-
def self.new *args
|
105
|
-
super + '****'
|
120
|
+
|
121
|
+
class OurClass
|
122
|
+
include Sr1 # Apply Tag
|
123
|
+
|
124
|
+
def foo_bar
|
125
|
+
String('foo and bar')
|
106
126
|
end
|
107
127
|
end
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
128
|
+
|
129
|
+
c = OurClass.new
|
130
|
+
|
131
|
+
# test it with our object
|
132
|
+
c.foo_bar.should == 'foo and bar is a special string'
|
133
|
+
c.foo_bar.class.should == String
|
134
|
+
|
135
|
+
# test stdout
|
136
|
+
$stdout.should_receive(:write).with(/foo and bar is a special string/).at_least(1)
|
137
|
+
c.foo_bar.glow
|
112
138
|
|
113
|
-
|
114
|
-
|
139
|
+
|
140
|
+
class OurOtherClass
|
141
|
+
include Sr2 # Apply other tag
|
142
|
+
|
143
|
+
def foo_bar
|
144
|
+
String('foo and bar')
|
145
|
+
end
|
115
146
|
end
|
147
|
+
|
148
|
+
d = OurOtherClass.new
|
149
|
+
|
150
|
+
# test it with our object
|
151
|
+
d.foo_bar.should == '--foo and bar--'
|
152
|
+
d.foo_bar.class.should == String
|
153
|
+
|
154
|
+
# test stdout
|
155
|
+
$stdout.should_receive(:write).with(/foo and bar--/).at_least(1)
|
156
|
+
d.foo_bar.glow
|
157
|
+
|
158
|
+
#
|
159
|
+
# c is still the same
|
160
|
+
#
|
161
|
+
c.foo_bar.should == 'foo and bar is a special string'
|
162
|
+
c.foo_bar.class.should == String
|
163
|
+
|
164
|
+
#
|
165
|
+
# String is untouched
|
166
|
+
#
|
167
|
+
String("foo").should == 'foo'
|
168
|
+
String.new("foo").should == 'foo'
|
169
|
+
|
116
170
|
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
171
|
|
133
|
-
#
|
172
|
+
# introspecting on capabilities
|
134
173
|
|
135
|
-
|
136
|
-
String.new("foo").should == 'foo'
|
137
|
-
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
174
|
+
it 'should allow trait introspection' do
|
141
175
|
|
142
|
-
|
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 ########################################
|
176
|
+
StringRefinements do
|
177
|
+
(reclass? String).should == true
|
150
178
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
lets String do # apply injector
|
161
|
-
include StringExtensions()
|
162
|
-
end
|
163
|
-
|
164
|
-
assert( String('boo').to_s == 'boo++++' )
|
165
|
-
assert( String("").class == String )
|
166
|
-
|
167
|
-
describe :String do
|
168
|
-
it 'should pass' do
|
169
|
-
String('boo').to_s.should == 'boo++++'
|
170
|
-
end
|
171
|
-
# introspecting on Type
|
172
|
-
it 'should be class String' do
|
173
|
-
String('boo').class.should be(String)
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
|
178
|
-
# Another Top-level Reclassing
|
179
|
-
# Note: same as above
|
180
|
-
|
181
|
-
jack :ArrayExtensions do
|
182
|
-
def to_s
|
183
|
-
super + '####'
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
|
-
lets Array do
|
188
|
-
inject ArrayExtensions()
|
189
|
-
end
|
190
|
-
|
191
|
-
assert(Array(3).to_s == "[nil, nil, nil]####")
|
192
|
-
assert(Array(3).class == Array)
|
193
|
-
|
194
|
-
describe :Array do
|
195
|
-
it 'allows the following' do
|
196
|
-
Array(3).to_s.should == "[nil, nil, nil]####"
|
197
|
-
end
|
198
|
-
# introspecting on Type
|
199
|
-
it 'should be Array' do
|
200
|
-
Array(3).class.should be(Array)
|
201
|
-
end
|
202
|
-
end
|
203
|
-
|
204
|
-
# ORIGINAL CLASSES REMAIN UNTOUCHED!!!
|
205
|
-
##################################################
|
206
|
-
assert( String.new.to_s == '' ) #
|
207
|
-
assert( Array.new(3).to_s == '[nil, nil, nil]' ) #
|
208
|
-
#
|
209
|
-
describe String do #
|
210
|
-
it 'should remain untouched' do #
|
211
|
-
String.new('bar').should == 'bar' #
|
212
|
-
end #
|
213
|
-
end #
|
214
|
-
#
|
215
|
-
describe Array do #
|
216
|
-
it 'should remain untouched' do #
|
217
|
-
Array.new(3).should == [nil, nil, nil] #
|
218
|
-
end #
|
219
|
-
end #
|
220
|
-
##################################################
|
221
|
-
# ORIGINAL CLASSES REMAIN UNTOUCHED!!!
|
222
|
-
|
223
|
-
# ORIGINAL KERNEL METHODS REMAIN UNTOUCHED!!!
|
224
|
-
##################################################
|
225
|
-
assert( Kernel.String(123) == '123' ) #
|
226
|
-
assert( Kernel.Array(3) == [3]) #
|
227
|
-
#
|
228
|
-
describe :'Kernel.String' do #
|
229
|
-
it 'should reamain untouched' do #
|
230
|
-
Kernel.String(123).should == '123' #
|
231
|
-
end #
|
232
|
-
end #
|
233
|
-
#
|
234
|
-
describe :'Kernel.Array' do #
|
235
|
-
it 'should reamain untouched' do #
|
236
|
-
Kernel.Array([1,2,3]).should == [1,2,3] #
|
237
|
-
end #
|
238
|
-
end #
|
239
|
-
##################################################
|
240
|
-
# ORIGINAL KERNEL METHODS REMAIN UNTOUCHED!!!
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
# Namespaced Reclassings
|
247
|
-
##################################################
|
248
|
-
|
249
|
-
jack :NameSpacedArrayExtensions do
|
250
|
-
def to_s
|
251
|
-
super + '!!!!'
|
252
|
-
end
|
253
|
-
end
|
254
|
-
|
255
|
-
module M7
|
256
|
-
|
257
|
-
# Internal reclassing
|
258
|
-
|
259
|
-
lets Array do
|
260
|
-
inject NameSpacedArrayExtensions()
|
261
|
-
end
|
262
|
-
|
263
|
-
def foo_bar
|
264
|
-
Array(2)
|
265
|
-
end
|
266
|
-
|
267
|
-
end
|
268
|
-
|
269
|
-
class A6
|
270
|
-
include M7
|
271
|
-
end
|
272
|
-
|
273
|
-
|
274
|
-
describe "Internal Array()" do
|
275
|
-
it 'should pass' do
|
276
|
-
A6.new.foo_bar.to_s.should == '[nil, nil]!!!!'
|
277
|
-
end
|
278
|
-
# introspecting on Type
|
279
|
-
it 'should be an Array' do
|
280
|
-
A6.new.foo_bar.class.should be(Array)
|
281
|
-
end
|
282
|
-
end
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
# Introspection
|
288
|
-
##################################################
|
289
|
-
|
290
|
-
assert( A6.new.foo_bar.injectors.by_name == [:NameSpacedArrayExtensions] )
|
291
|
-
|
292
|
-
describe "introspection" do
|
293
|
-
|
294
|
-
# introspecting on capabilities
|
295
|
-
|
296
|
-
it 'should allow injector introspection' do
|
297
|
-
|
298
|
-
StringRefinements do
|
299
|
-
(reclass? String).should == true
|
300
|
-
|
301
|
-
String() do
|
302
|
-
injectors.by_name.should == [:Log]
|
179
|
+
if reclass? String
|
180
|
+
String() do
|
181
|
+
traits.by_name.should == [:Log]
|
182
|
+
end
|
183
|
+
else
|
184
|
+
lets String do
|
185
|
+
#...
|
186
|
+
end
|
187
|
+
end
|
303
188
|
end
|
304
|
-
end
|
305
189
|
|
306
|
-
|
307
|
-
|
308
|
-
it 'should allow injector introspection' do
|
309
|
-
# top level re-class
|
310
|
-
Array() do
|
311
|
-
injectors.by_name.should == [:ArrayExtensions]
|
312
|
-
end
|
313
|
-
|
314
|
-
Array(){injectors.by_name}.should == [:ArrayExtensions]
|
190
|
+
class SRClass
|
191
|
+
inject StringRefinements()
|
315
192
|
|
316
|
-
|
317
|
-
|
193
|
+
def m1
|
194
|
+
String('m1')
|
195
|
+
end
|
196
|
+
end
|
318
197
|
|
319
|
-
|
320
|
-
|
321
|
-
it 'works on namespaced reclassings' do
|
198
|
+
SRClass.new.m1.should == '--m1--'
|
322
199
|
|
323
|
-
|
200
|
+
end
|
324
201
|
|
325
|
-
|
326
|
-
|
202
|
+
it 'should allow trait introspection' do
|
203
|
+
|
204
|
+
lets Array do
|
205
|
+
inject jack :ArrayExtensions do
|
206
|
+
def to_s
|
207
|
+
super + '--boo'
|
208
|
+
end
|
209
|
+
end
|
327
210
|
end
|
328
211
|
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
reclass?(String).should == true
|
335
|
-
reclass?(Array).should == true
|
336
|
-
|
337
|
-
module M7
|
338
|
-
reclass? Array
|
339
|
-
end.should == true
|
212
|
+
# re-class
|
213
|
+
Array() do
|
214
|
+
traits.by_name.should == [:ArrayExtensions]
|
215
|
+
end
|
340
216
|
|
341
|
-
|
342
|
-
reclass? Array
|
343
|
-
end.should == false
|
217
|
+
Array(){traits.by_name}.should == [:ArrayExtensions]
|
344
218
|
|
345
|
-
|
346
|
-
|
347
|
-
|
219
|
+
# re-class instances
|
220
|
+
Array(1).traits.by_name == [:ArrayExtensions]
|
221
|
+
|
222
|
+
Array(2).to_s.should == '[nil, nil]--boo'
|
348
223
|
|
349
|
-
end
|
350
|
-
|
351
|
-
end
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
# Calls deeper down the hierarchy
|
358
|
-
##################################################
|
359
|
-
|
360
|
-
module M5
|
361
|
-
def self.foo
|
362
|
-
String('foo').to_s
|
363
|
-
end
|
364
|
-
end
|
365
|
-
|
366
|
-
assert( M5.foo == 'foo++++' )
|
367
|
-
|
368
|
-
describe M5 do
|
369
|
-
it 'works' do
|
370
|
-
M5.foo.should == 'foo++++'
|
371
|
-
end
|
372
|
-
it 'should be String' do
|
373
|
-
M5.foo.class.should be(String)
|
374
|
-
end
|
375
|
-
end
|
376
|
-
|
377
|
-
# even deeper
|
378
|
-
|
379
|
-
class A5
|
380
|
-
module M6
|
381
|
-
def meth arg
|
382
|
-
String(arg).to_s
|
383
224
|
end
|
384
|
-
|
385
|
-
include M6
|
386
|
-
end
|
387
|
-
|
388
|
-
assert(A5.new.meth("meth")== 'meth++++')
|
389
|
-
|
390
|
-
describe A5 do
|
391
|
-
it "shold pass" do
|
392
|
-
A5.new.meth("meth").should == 'meth++++'
|
393
|
-
end
|
394
|
-
# introspecting on Type
|
395
|
-
it 'should be a String' do
|
396
|
-
A5.new.meth("meth").class.should be(String)
|
397
|
-
end
|
398
|
-
|
399
|
-
it 'should hold access to top level re-class' do
|
400
|
-
class A5
|
401
|
-
module M6
|
402
|
-
String(){injectors.by_name}.should == [:StringExtensions]
|
403
|
-
end
|
404
|
-
end
|
405
|
-
end
|
406
|
-
end
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
# re- Reclassing
|
412
|
-
################################################
|
413
|
-
|
414
|
-
MyStringExtensions = StringExtensions() do
|
415
|
-
def to_s
|
416
|
-
super + '----'
|
417
|
-
end
|
418
|
-
end
|
419
|
-
|
420
|
-
describe 're-reclassing' do
|
421
|
-
it 'should pass' do
|
422
|
-
String() do
|
423
|
-
update MyStringExtensions
|
424
|
-
end
|
425
|
-
|
426
|
-
String('standard').to_s.should == 'standard----'
|
427
|
-
end
|
428
|
-
# introspecting on Type
|
429
|
-
it 'should be a String' do
|
430
|
-
String('standard').class.should be(String)
|
431
|
-
end
|
432
|
-
|
433
|
-
it 'should introspect' do
|
434
|
-
String(){injectors}.first.should == MyStringExtensions
|
225
|
+
|
435
226
|
end
|
436
227
|
end
|
437
228
|
|
438
229
|
|
439
|
-
|
440
|
-
# TOP LEVEL RECLASSINGS REMAIN UNTOUCHED!!!
|
441
|
-
##################################################
|
442
|
-
#
|
443
|
-
assert( String('test').to_s == 'test++++' ) #
|
444
|
-
assert( Array(3).to_s == '[nil, nil, nil]####' ) #
|
445
|
-
#
|
446
|
-
##################################################
|
447
|
-
# TOP LEVEL RECLASSINGS REMAIN UNTOUCHED!!!
|
448
|
-
|
449
|
-
# TOP LEVEL RECLASSING TYPES REMAIN UNTOUCHED!!!
|
450
|
-
##################################################
|
451
|
-
#
|
452
|
-
assert( String('test').class == String ) #
|
453
|
-
assert( Array(3).class == Array ) #
|
454
|
-
#
|
455
|
-
##################################################
|
456
|
-
# TOP LEVEL RECLASSING TYPES REMAIN UNTOUCHED!!!
|
457
|
-
|
458
|
-
# ORIGINAL CLASSES REMAIN UNTOUCHED!!!
|
459
|
-
##################################################
|
460
|
-
#
|
461
|
-
assert(String.new.to_s == '') #
|
462
|
-
assert(Array.new(3).to_s == '[nil, nil, nil]') #
|
463
|
-
#
|
464
|
-
##################################################
|
465
|
-
# ORIGINAL CLASSES REMAIN UNTOUCHED!!!
|
466
|
-
|
467
|
-
# ORIGINAL KERNEL METHODS REMAIN UNTOUCHED!!!
|
468
|
-
##################################################
|
469
|
-
#
|
470
|
-
assert( Kernel.String(123) == '123' ) #
|
471
|
-
assert( Kernel.Array(3) == [3]) #
|
472
|
-
#
|
473
|
-
##################################################
|
474
|
-
# ORIGINAL KERNEL METHODS REMAIN UNTOUCHED!!!
|
475
|
-
|
476
|
-
# profile = RubyProf.stop
|
477
|
-
# RubyProf::FlatPrinter.new(profile).print(STDOUT)
|
478
|
-
# RubyProf::GraphHtmlPrinter.new(profile).print(open('profile.html', 'w+'))
|
479
|
-
# RubyProf::CallStackPrinter.new(profile).print(open('profile.html', 'w+'))
|
480
|
-
|
481
|
-
|