evilr 1.0.0-x86-mingw32

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.
@@ -0,0 +1,7 @@
1
+ require 'mkmf'
2
+ $CFLAGS << " -DRUBY19" if RUBY_VERSION >= '1.9.0'
3
+ $CFLAGS << " -Wall " unless RUBY_PLATFORM =~ /solaris/
4
+ $CFLAGS << ' -g -ggdb -O0 -DDEBUG' if ENV['DEBUG']
5
+ $CFLAGS << " -Wconversion -Wsign-compare -Wno-unused-parameter -Wwrite-strings -Wpointer-arith -fno-common -pedantic -Wno-long-long" if ENV['STRICT']
6
+ $CFLAGS << (ENV['CFLAGS'] || '')
7
+ create_makefile("evilr")
data/lib/1.8/evilr.so ADDED
Binary file
data/lib/1.9/evilr.so ADDED
Binary file
data/lib/evilr.rb ADDED
@@ -0,0 +1 @@
1
+ require "#{RUBY_VERSION[0...3]}/evilr"
@@ -0,0 +1,1157 @@
1
+ $:.unshift(File.join(File.dirname(File.dirname(File.expand_path(__FILE__)))), 'lib')
2
+ require 'evilr'
3
+
4
+ describe "" do
5
+ after{GC.start} # GC after spec to make sure nothing broke
6
+
7
+ describe "Proc#self" do
8
+ specify "should be the object the proc will call methods on by default" do
9
+ c = Class.new
10
+ c.class_eval{proc{}}.self.should == c
11
+ c.instance_eval{proc{}}.self.should == c
12
+ o = c.new
13
+ o.instance_eval{proc{}}.self.should == o
14
+ end
15
+ end
16
+
17
+ describe "Proc#self=" do
18
+ specify "should change the object the proc will call methods on by default" do
19
+ o1 = Object.new
20
+ o2 = Object.new
21
+ pr1 = o1.instance_eval{def a() 1 end; proc{a}}
22
+ pr2 = o2.instance_eval{def a() 2 end; proc{a}}
23
+ pr1.call.should == 1
24
+ pr2.call.should == 2
25
+ pr1.self = o2
26
+ pr2.self = o1
27
+ pr1.call.should == 2
28
+ pr2.call.should == 1
29
+ end
30
+ end
31
+
32
+ describe "UnboundMethod#force_bind" do
33
+ specify "should make the method bindable to another object even if the class differs" do
34
+ c = Class.new{def a() self.class end}
35
+ um = c.instance_method(:a)
36
+ c2 = Class.new
37
+ o = c2.new
38
+ proc{um.bind(o)}.should raise_error(TypeError)
39
+ m = um.force_bind(o)
40
+ m.should be_a_kind_of(Method)
41
+ m.call.should == c2
42
+ end
43
+ end
44
+
45
+ describe "Object#class=" do
46
+ before do
47
+ @o = Class.new.new
48
+ @c = Class.new
49
+ end
50
+
51
+ specify "should make given object this object's class" do
52
+ @o.should_not be_a_kind_of(@c)
53
+ @o.class = @c
54
+ @o.should be_a_kind_of(@c)
55
+ end
56
+
57
+ specify "should raise an exception for immediate objects" do
58
+ [0, :a, true, false, nil].each do |x|
59
+ proc{x.class = @c}.should raise_error(TypeError)
60
+ end
61
+ end
62
+
63
+ specify "should raise an exception if a class is not used as an argument" do
64
+ proc{@o.class = @o}.should raise_error(TypeError)
65
+ end
66
+
67
+ specify "should raise an exception if a class used is not the same underlying type" do
68
+ proc{@o.class = Hash}.should raise_error(TypeError)
69
+ end
70
+ end
71
+
72
+ describe "Object#dup_singleton_class" do
73
+ specify "should raise an exception for immediate values" do
74
+ proc{nil.dup_singleton_class}.should raise_error(TypeError)
75
+ end
76
+
77
+ specify "should return nil if the object has no singleton class" do
78
+ Object.new.dup_singleton_class.should == nil
79
+ end
80
+
81
+ specify "should return a copy of the singleton class as a non-singleton class" do
82
+ o = Object.new
83
+ o.instance_eval{def a() 1 end}
84
+ o.dup_singleton_class.new.a.should == 1
85
+ end
86
+
87
+ specify "should make the given class a subclass of Object by default" do
88
+ o = Object.new
89
+ o.instance_eval{def a() 1 end}
90
+ o.dup_singleton_class.superclass.should == Object
91
+ end
92
+
93
+ specify "should accept a class argument to make the dup a subclass of" do
94
+ o = Object.new
95
+ o.instance_eval{def a() 1 end}
96
+ c = Class.new
97
+ o.dup_singleton_class(c).superclass.should == c
98
+ end
99
+
100
+ specify "should handle extended modules by making them included modules in the class" do
101
+ o = Object.new
102
+ o.instance_eval{def a() [1] + super end}
103
+ o.extend(Module.new{def a() [2] + super end})
104
+ c = Class.new{def a() [4] + super end; include Module.new{def a() [8] end}}
105
+ o.dup_singleton_class(c).new.a.should == [1, 2, 4, 8]
106
+ end
107
+ end
108
+
109
+ describe "Object\#{push,pop}_singleton_class" do
110
+ specify "both should raise an exception for immediate values" do
111
+ proc{nil.push_singleton_class(Class.new)}.should raise_error(TypeError)
112
+ proc{nil.pop_singleton_class}.should raise_error(TypeError)
113
+ end
114
+
115
+ specify "push_singleton_class should raise an exception if a class is not given" do
116
+ proc{{}.push_singleton_class(Object.new)}.should raise_error(TypeError)
117
+ end
118
+
119
+ specify "both should return the class" do
120
+ c = Class.new
121
+ o = {}
122
+ o.push_singleton_class(c).should == c
123
+ o.pop_singleton_class.should == c
124
+ end
125
+
126
+ specify "pop_singleton_class should return nil if no singleton class exists" do
127
+ {}.pop_singleton_class.should == nil
128
+ end
129
+
130
+ specify "should add and remove singleton classes" do
131
+ o = Class.new{def a() [1] end}.new
132
+ o.a.should == [1]
133
+ o.push_singleton_class(Class.new{def a() [2] + super end})
134
+ o.a.should == [2, 1]
135
+ o.push_singleton_class(Class.new{def a() [4] + super end})
136
+ o.a.should == [4, 2, 1]
137
+ o.push_singleton_class(Class.new{def a() [8] + super end})
138
+ o.a.should == [8, 4, 2, 1]
139
+ o.pop_singleton_class
140
+ o.a.should == [4, 2, 1]
141
+ o.push_singleton_class(Class.new{def a() [16] + super end})
142
+ o.a.should == [16, 4, 2, 1]
143
+ o.pop_singleton_class
144
+ o.a.should == [4, 2, 1]
145
+ o.pop_singleton_class
146
+ o.a.should == [2, 1]
147
+ o.pop_singleton_class
148
+ o.a.should == [1]
149
+ end
150
+
151
+ specify "should handle modules included in the classes" do
152
+ o = Class.new{def a() [1] end}.new
153
+ o.a.should == [1]
154
+ o.push_singleton_class(Class.new{def a() [2] + super end; include Module.new{def a() [32] + super end}})
155
+ o.a.should == [2, 32, 1]
156
+ o.push_singleton_class(Class.new{def a() [4] + super end; include Module.new{def a() [64] + super end}})
157
+ o.a.should == [4, 64, 2, 32, 1]
158
+ o.push_singleton_class(Class.new{def a() [8] + super end; include Module.new{def a() [128] + super end}})
159
+ o.a.should == [8, 128, 4, 64, 2, 32, 1]
160
+ o.pop_singleton_class
161
+ o.a.should == [4, 64, 2, 32, 1]
162
+ o.push_singleton_class(Class.new{def a() [16] + super end; include Module.new{def a() [256] + super end}})
163
+ o.a.should == [16, 256, 4, 64, 2, 32, 1]
164
+ o.pop_singleton_class
165
+ o.a.should == [4, 64, 2, 32, 1]
166
+ o.pop_singleton_class
167
+ o.a.should == [2, 32, 1]
168
+ o.pop_singleton_class
169
+ o.a.should == [1]
170
+ end
171
+
172
+ specify "pop_singleton_class should have no effect if the object has no singleton class" do
173
+ o = Class.new{def a() [1] end}.new
174
+ o.pop_singleton_class
175
+ o.a.should == [1]
176
+ end
177
+ end
178
+
179
+ describe "Objec#remove_singleton_classes" do
180
+ specify "should raise an exception for immediate values" do
181
+ proc{nil.remove_singleton_classes}.should raise_error(TypeError)
182
+ end
183
+
184
+ specify "should return nil" do
185
+ {}.remove_singleton_classes.should == nil
186
+ end
187
+
188
+ specify "should add and remove singleton classes" do
189
+ o = Class.new{def a() [1] end}.new
190
+ o.a.should == [1]
191
+ o.push_singleton_class(Class.new{def a() [2] + super end})
192
+ o.a.should == [2, 1]
193
+ o.push_singleton_class(Class.new{def a() [4] + super end})
194
+ o.a.should == [4, 2, 1]
195
+ o.push_singleton_class(Class.new{def a() [8] + super end})
196
+ o.a.should == [8, 4, 2, 1]
197
+ o.remove_singleton_classes
198
+ o.a.should == [1]
199
+ end
200
+
201
+ specify "should handle modules included in the classes" do
202
+ o = Class.new{def a() [1] end}.new
203
+ o.a.should == [1]
204
+ o.push_singleton_class(Class.new{def a() [2] + super end; include Module.new{def a() [32] + super end}})
205
+ o.a.should == [2, 32, 1]
206
+ o.push_singleton_class(Class.new{def a() [4] + super end; include Module.new{def a() [64] + super end}})
207
+ o.a.should == [4, 64, 2, 32, 1]
208
+ o.push_singleton_class(Class.new{def a() [8] + super end; include Module.new{def a() [128] + super end}})
209
+ o.a.should == [8, 128, 4, 64, 2, 32, 1]
210
+ o.remove_singleton_classes
211
+ o.a.should == [1]
212
+ end
213
+
214
+ specify "should have no effect if the object has no singleton classes" do
215
+ o = Class.new{def a() [1] end}.new
216
+ o.remove_singleton_classes
217
+ o.a.should == [1]
218
+ end
219
+ end
220
+
221
+ describe "Object#swap_singleton_class" do
222
+ before do
223
+ @o1 = Class.new.new
224
+ @o2 = Class.new.new
225
+ end
226
+
227
+ specify "should swap singleton class with argument" do
228
+ def @o2.a; 1; end
229
+ def @o1.b; 2; end
230
+ @o1.swap_singleton_class(@o2)
231
+ @o1.a.should == 1
232
+ @o2.b.should == 2
233
+ proc{@o1.b}.should raise_error(NoMethodError)
234
+ proc{@o2.a}.should raise_error(NoMethodError)
235
+
236
+ def @o2.c; 3; end
237
+ def @o1.d; 4; end
238
+ @o2.c.should == 3
239
+ @o1.d.should == 4
240
+ proc{@o2.d}.should raise_error(NoMethodError)
241
+ proc{@o1.c}.should raise_error(NoMethodError)
242
+ end
243
+
244
+ specify "should handle singleton classes that don't exist" do
245
+ @o2.swap_singleton_class(@o1)
246
+ def @o2.c; 3; end
247
+ def @o1.d; 4; end
248
+ @o2.c.should == 3
249
+ @o1.d.should == 4
250
+ proc{@o2.d}.should raise_error(NoMethodError)
251
+ proc{@o1.c}.should raise_error(NoMethodError)
252
+ end
253
+
254
+ specify "should raise an exception for immediate objects" do
255
+ [0, :a, true, false, nil].each do |x|
256
+ proc{x.swap_singleton_class(@o2)}.should raise_error(TypeError)
257
+ proc{@o1.swap_singleton_class(x)}.should raise_error(TypeError)
258
+ end
259
+ end
260
+
261
+ specify "should return self" do
262
+ @o2.swap_singleton_class(@o1).should equal(@o2)
263
+ end
264
+
265
+ specify "should keep existing class hierarchy the same, other than the singleton classes" do
266
+ oc1 = Class.new
267
+ oc2 = Class.new
268
+ o1 = oc1.new
269
+ o2 = oc2.new
270
+ o1.swap_singleton_class(o2)
271
+ o1.class.should == oc1
272
+ o2.class.should == oc2
273
+ end
274
+
275
+ specify "should also swap modules that extend the class" do
276
+ oc1 = Class.new{def a() [16] end}
277
+ oc2 = Class.new{def a() [32] end}
278
+ o1 = oc1.new
279
+ o2 = oc2.new
280
+ o1.instance_eval{def a() [1] + super end; extend Module.new{def a() [2] + super end}}
281
+ o2.instance_eval{def a() [4] + super end; extend Module.new{def a() [8] + super end}}
282
+ o1.swap_singleton_class(o2)
283
+ o1.a.should == [4, 8, 16]
284
+ o2.a.should == [1, 2, 32]
285
+ end
286
+ end
287
+
288
+ describe "Object#unfreeze" do
289
+ before do
290
+ @o = Object.new
291
+ @o.freeze
292
+ end
293
+
294
+ specify "should unfreeze object" do
295
+ @o.unfreeze
296
+ @o.frozen?.should == false
297
+ @o.instance_variable_set(:@a, 1)
298
+ @o.instance_variable_get(:@a).should == 1
299
+ end
300
+
301
+ specify "should be idempotent" do
302
+ @o.frozen?.should == true
303
+ @o.unfreeze
304
+ @o.frozen?.should == false
305
+ @o.unfreeze
306
+ @o.frozen?.should == false
307
+ @o.instance_variable_set(:@a, 1)
308
+ @o.instance_variable_get(:@a).should == 1
309
+ end
310
+
311
+ specify "should be no-op for immediate objects" do
312
+ [0, :a, true, false, nil].each do |x|
313
+ proc{x.unfreeze}.should_not raise_error
314
+ end
315
+ end
316
+
317
+ specify "should not be allowed if $SAFE > 0" do
318
+ x = @o
319
+ Thread.new do
320
+ $SAFE = 1
321
+ proc{x.unfreeze}.should raise_error(SecurityError)
322
+ end.join
323
+ end
324
+
325
+ specify "should return self" do
326
+ @o.unfreeze.should equal(@o)
327
+ end
328
+ end
329
+
330
+ describe "Kernel#set_safe_level" do
331
+ specify "should allow the lowering of the $SAFE level" do
332
+ $SAFE = 1
333
+ set_safe_level(0)
334
+ $SAFE.should == 0
335
+ end
336
+ end
337
+
338
+ describe "Module#to_class" do
339
+ specify "should return the module in class form" do
340
+ Module.new{def a() 1 end}.to_class.new.a.should == 1
341
+ end
342
+
343
+ specify "should accept an optional argument for the new class type" do
344
+ Module.new{def a() 1 end}.to_class(Object).new.a.should == 1
345
+ Module.new{def a() super + 2 end}.to_class(Class.new{def a() 1 end}).new.a.should == 3
346
+ end
347
+
348
+ specify "should raise exception if attempting to instantiate a builtin class other than Object" do
349
+ proc{Module.new.to_class(Hash)}.should raise_error(TypeError)
350
+ proc{Module.new.to_class(Array)}.should raise_error(TypeError)
351
+ proc{Module.new.to_class(String)}.should raise_error(TypeError)
352
+ end
353
+
354
+ specify "should return copy of self (possibly reparented) if already a class" do
355
+ Class.new{def a() 1 end}.to_class.new.a.should == 1
356
+ Class.new{def a() 1 end}.to_class(Object).new.a.should == 1
357
+ Class.new{def a() super + 2 end}.to_class(Class.new{def a() 1 end}).new.a.should == 3
358
+
359
+ osc = Class.new
360
+ c = Class.new(osc)
361
+ sc = Class.new
362
+ c.to_class(sc).superclass.should == sc
363
+ c.superclass.should == osc
364
+ end
365
+
366
+ specify "should use Object as the default superclass" do
367
+ Module.new.to_class.superclass.should == Object
368
+ end
369
+
370
+ specify "should use given class as the superclass" do
371
+ c = Class.new
372
+ Module.new.to_class(c).superclass.should == c
373
+ end
374
+ end
375
+
376
+ describe "Class#to_module" do
377
+ specify "should return the class in module form" do
378
+ c = Class.new{def a() 1 end}
379
+ Class.new{include c.to_module}.new.a.should == 1
380
+ end
381
+
382
+ specify "should not modify the class's superclass" do
383
+ c = Class.new{def a() [1] end}
384
+ sc = Class.new(c){def a() [2] + (super rescue [0]) end}
385
+ Class.new{include sc.to_module}.new.a.should == [2, 0]
386
+ sc.superclass.should == c
387
+ sc.new.a.should == [2, 1]
388
+ end
389
+
390
+ specify "should not modify the class's superclass if modules are included" do
391
+ c = Class.new{def a() [1] end}
392
+ sc = Class.new(c){def a() [2] + (super rescue [0]) end; include Module.new}
393
+ Class.new{include sc.to_module}.new.a.should == [2, 0]
394
+ sc.superclass.should == c
395
+ sc.new.a.should == [2, 1]
396
+ end
397
+
398
+ specify "should handle the order of multiple included modules correctly" do
399
+ c = Class.new{def a() [1] end}
400
+ sc = Class.new(c){def a() [2] + (super rescue [0]) end}
401
+ sc.send :include, Module.new{def a() [4] + (super rescue [0]) end}
402
+ sc.send :include, Module.new{def a() [8] + (super rescue [0]) end}
403
+ Class.new{include sc.to_module}.new.a.should == [2, 8, 4, 0]
404
+ sc.superclass.should == c
405
+ sc.new.a.should == [2, 8, 4, 1]
406
+ end
407
+
408
+ specify "should handle singleton classes without modifying them" do
409
+ o = Object.new
410
+ o.instance_eval{def a() 1 end}
411
+ Class.new{include((class << o; self; end).to_module)}.new.a.should == 1
412
+ o.instance_eval{def a() super end}
413
+ proc{o.a}.should raise_error(NoMethodError)
414
+ end
415
+
416
+ specify "should handle singleton classes without modifying them if modules are included" do
417
+ o = Object.new
418
+ o.instance_eval{def a() 1 end}
419
+ o.extend Module.new
420
+ Class.new{include((class << o; self; end).to_module)}.new.a.should == 1
421
+ o.instance_eval{def a() super end}
422
+ proc{o.a}.should raise_error(NoMethodError)
423
+ end
424
+
425
+ specify "should include modules included in class" do
426
+ c = Class.new{def a() [1] + super end; include Module.new{def a() [2] + (super rescue [0]) end}}
427
+ Class.new{def a() [4] + super end; include c.to_module}.new.a.should == [4, 1, 2, 0]
428
+ end
429
+
430
+ specify "should not include superclass or modules included in superclass" do
431
+ c = Class.new{def a() [1] + super end; include Module.new{def a() [2] end}}
432
+ sc = Class.new(c){def a() [4] + super end; include Module.new{def a() [8] + (super rescue [0]) end}}
433
+ Class.new{def a() [16] + super end; include sc.to_module}.new.a.should == [16, 4, 8, 0]
434
+ end
435
+ end
436
+
437
+ describe "Class#detach_singleton" do
438
+ specify "should be a no-op on a non-singleton class" do
439
+ Class.new{def a() 1 end}.detach_singleton.new.a.should == 1
440
+ end
441
+
442
+ specify "should detach singleton class from object" do
443
+ o = Object.new
444
+ o.instance_eval{def a() 1 end}
445
+ sc = (class << o; self; end)
446
+ sc.detach_singleton.singleton_class_instance.should == nil
447
+ end
448
+
449
+ specify "should allow another singleton class to be created" do
450
+ o = Object.new
451
+ o.instance_eval{def a() 1 end}
452
+ sc = (class << o; self; end)
453
+ sc.detach_singleton
454
+ o.instance_eval{def a() super + 2 end}
455
+ o.a.should == 3
456
+ end
457
+ end
458
+
459
+ describe "Object#set_singleton_class" do
460
+ specify "should raise an exception for immediate values" do
461
+ proc{nil.set_singleton_class(Class.new)}.should raise_error(TypeError)
462
+ end
463
+
464
+ specify "should raise an exception for non-class arguments" do
465
+ proc{Object.new.set_singleton_class(Object.new)}.should raise_error(TypeError)
466
+ end
467
+
468
+ specify "should return the class" do
469
+ c = Class.new
470
+ Object.new.set_singleton_class(c).should == c
471
+ end
472
+
473
+ specify "should make object the new singleton class's instance" do
474
+ o = Object.new
475
+ o.set_singleton_class(Class.new).singleton_class_instance.should == o
476
+ end
477
+
478
+ specify "should make class the object's singleton class" do
479
+ o = Object.new
480
+ c = Class.new{def a() 1 end}
481
+ o.set_singleton_class(c)
482
+ (class << o; self; end).should == c
483
+ o.a.should == 1
484
+ end
485
+
486
+ specify "should replace an existing singleton class" do
487
+ o = Object.new
488
+ o.instance_eval{def a() 3 end}
489
+ c = Class.new{def a() 1 + (super rescue 10) end}
490
+ o.set_singleton_class(c)
491
+ o.a.should == 11
492
+ end
493
+
494
+ specify "should remove any modules currently extending the class" do
495
+ o = Object.new
496
+ o.instance_eval{def a() 3 end}
497
+ o.extend(Module.new{def a() 4 end})
498
+ c = Class.new{def a() 1 + (super rescue 10) end}
499
+ o.set_singleton_class(c)
500
+ o.a.should == 11
501
+ end
502
+
503
+ specify "should keep any existing class" do
504
+ oc = Class.new
505
+ o = oc.new
506
+ c = Class.new
507
+ sc = Class.new(c)
508
+ o.set_singleton_class(sc)
509
+ o.class.should == oc
510
+ end
511
+
512
+ specify "should make modules included in class as modules that extend the new class" do
513
+ oc = Class.new{def a() [1] end}
514
+ o = oc.new
515
+ c = Class.new{def a() [2] + super end}
516
+ sc = Class.new(c){def a() [4] + super end; include Module.new{def a() [8] + super end}}
517
+ o.set_singleton_class(sc)
518
+ o.a.should == [4, 8, 1]
519
+ end
520
+ end
521
+
522
+ describe "Object#swap" do
523
+ specify "should raise an exception for immediate values" do
524
+ proc{nil.swap(Object.new)}.should raise_error(TypeError)
525
+ proc{Object.new.swap(nil)}.should raise_error(TypeError)
526
+ end
527
+
528
+ specify "should raise an exception for swapping a class with a non-class value" do
529
+ proc{Object.new.swap(Class.new)}.should raise_error(TypeError)
530
+ proc{Class.new.swap(Object.new)}.should raise_error(TypeError)
531
+ proc{Class.new.swap(Module.new)}.should raise_error(TypeError)
532
+ end
533
+
534
+ specify "should raise an exception for swapping a module with a non-module value" do
535
+ proc{Object.new.swap(Module.new)}.should raise_error(TypeError)
536
+ proc{Module.new.swap(Object.new)}.should raise_error(TypeError)
537
+ proc{Module.new.swap(Class.new)}.should raise_error(TypeError)
538
+ end
539
+
540
+ specify "should swap the objects' classes, singleton classes, and instance variables" do
541
+ c1 = Class.new{attr_accessor :b; def a() 1 end}
542
+ c2 = Class.new{attr_accessor :b; def a() 2 end}
543
+ o1 = c1.new
544
+ o2 = c2.new
545
+ o1.instance_eval{def a() 4 + super end}
546
+ o2.instance_eval{def a() 8 + super end}
547
+ o1.b = 3
548
+ o2.b = 4
549
+ o1.swap(o2)
550
+ o1.b.should == 4
551
+ o1.a.should == 10
552
+ o1.class.should == c2
553
+ o2.b.should == 3
554
+ o2.a.should == 5
555
+ o2.class.should == c1
556
+ end
557
+
558
+ specify "should work for classes" do
559
+ c1 = Class.new{def a() 1 end}
560
+ c2 = Class.new{def a() 2 end}
561
+ c1.instance_eval{@a = 16; def a() 4 end}
562
+ c2.instance_eval{@a = 32; def a() 8 end}
563
+ c1.swap(c2)
564
+ c1.a.should == 8
565
+ c2.a.should == 4
566
+ c1.instance_eval{@a.should == 32}
567
+ c2.instance_eval{@a.should == 16}
568
+ c1.new.a.should == 2
569
+ c2.new.a.should == 1
570
+ end
571
+
572
+ specify "should work for different types of objects" do
573
+ a = {}
574
+ b = []
575
+ a.swap(b)
576
+ a.should == []
577
+ b.should == {}
578
+ end
579
+
580
+ specify "should return self (the new self)" do
581
+ o = Object.new
582
+ i = o.object_id
583
+ no = o.swap(Class.new{def a() 1 end}.new)
584
+ no.should == o
585
+ no.object_id.should == i
586
+ no.a.should == 1
587
+ end
588
+ end
589
+
590
+ describe "Object#detach_singleton_class" do
591
+ specify "should raise an exception for immediate values" do
592
+ proc{nil.detach_singleton_class}.should raise_error(TypeError)
593
+ end
594
+
595
+ specify "should be a no-op an object without a singleton class" do
596
+ a = {:a=>1}
597
+ a.detach_singleton_class
598
+ a[:a].should == 1
599
+ end
600
+
601
+ specify "should return the class" do
602
+ Object.new.detach_singleton_class.should == Object
603
+ o = Object.new
604
+ sc = (class << o; self; end)
605
+ o.detach_singleton_class.should == sc
606
+ end
607
+
608
+ specify "should remove singleton status from singleton class" do
609
+ o = Object.new
610
+ o.instance_eval{def a() 1 end}
611
+ o.detach_singleton_class.new.a.should == 1
612
+ end
613
+
614
+ specify "should detach singleton class from object, becoming the object's actual class" do
615
+ o = Object.new
616
+ o.instance_eval{def a() 1 end}
617
+ sc = (class << o; self; end)
618
+ o.detach_singleton_class
619
+ o.class.should == sc
620
+ end
621
+
622
+ specify "should have singleton class's methods remain in the method chain" do
623
+ o = Object.new
624
+ o.instance_eval{def a() 1 end}
625
+ o.detach_singleton_class
626
+ o.instance_eval{def a() super + 2 end}
627
+ o.a.should == 3
628
+ end
629
+ end
630
+
631
+ describe "Object#remove_singleton_class" do
632
+ specify "should raise an exception for immediate values" do
633
+ proc{nil.remove_singleton_class}.should raise_error(TypeError)
634
+ end
635
+
636
+ specify "should be a no-op an object without a singleton class" do
637
+ a = {:a=>1}
638
+ a.remove_singleton_class
639
+ a[:a].should == 1
640
+ end
641
+
642
+ specify "should return nil if the class does not exist" do
643
+ Object.new.remove_singleton_class.should == nil
644
+ end
645
+
646
+ specify "should return the class if it exists" do
647
+ o = Object.new
648
+ sc = (class << o; self; end)
649
+ o.remove_singleton_class.should == sc
650
+ end
651
+
652
+ specify "should remove singleton status from singleton class" do
653
+ o = Object.new
654
+ o.instance_eval{def a() 1 end}
655
+ o.remove_singleton_class.new.a.should == 1
656
+ end
657
+
658
+ specify "should remove singleton class from object, restoring the object's original class" do
659
+ o = Object.new
660
+ o.instance_eval{def a() 1 end}
661
+ sc = (class << o; self; end)
662
+ o.remove_singleton_class
663
+ o.class.should == Object
664
+ end
665
+
666
+ specify "should have singleton class's methods not remain in the method chain" do
667
+ o = Object.new
668
+ o.instance_eval{def a() 1 end}
669
+ o.remove_singleton_class
670
+ o.instance_eval{def a() super + 2 end}
671
+ proc{o.a}.should raise_error(NoMethodError)
672
+ end
673
+
674
+ specify "should handle modules that extend the object" do
675
+ o = Object.new
676
+ o.instance_eval{def a() 1 end}
677
+ o.extend(Module.new{def b() 2 end})
678
+ o.remove_singleton_class
679
+ proc{o.a}.should raise_error(NoMethodError)
680
+ proc{o.b}.should raise_error(NoMethodError)
681
+ end
682
+ end
683
+
684
+ describe "Class#singleton_class_instance" do
685
+ specify "should return nil for a non-singleton class" do
686
+ Class.new.singleton_class_instance.should == nil
687
+ end
688
+
689
+ specify "should return instance attached to singleton class" do
690
+ o = Object.new.instance_eval{def a() 1 end}
691
+ (class << o; self; end).singleton_class_instance.should equal(o)
692
+ end
693
+ end
694
+
695
+ describe "Class#superclass=" do
696
+ specify "should raise an exception for immediate values" do
697
+ proc{Class.new.superclass = nil}.should raise_error(TypeError)
698
+ end
699
+
700
+ specify "should raise an exception for non-class arguments" do
701
+ proc{Class.new.superclass = Object.new}.should raise_error(TypeError)
702
+ end
703
+
704
+ specify "should raise an exception for incompatible types" do
705
+ proc{Class.new.superclass = String}.should raise_error(TypeError)
706
+ end
707
+
708
+ specify "should change the superclass of the class" do
709
+ c = Class.new
710
+ c2 = Class.new
711
+ c.superclass.should == Object
712
+ c.superclass = c2
713
+ c.superclass.should == c2
714
+ end
715
+
716
+ specify "should keep any included modules" do
717
+ c = Class.new{def a() [1] + super end; include Module.new{def a() [2] + (super rescue [0]) end}}
718
+ c2 = Class.new{def a() [4] + super end; include Module.new{def a() [8] + (super rescue [0]) end}}
719
+ c.new.a.should == [1, 2, 0]
720
+ c2.new.a.should == [4, 8, 0]
721
+ c.superclass = c2
722
+ c.new.a.should == [1, 2, 4, 8, 0]
723
+ end
724
+
725
+ specify "should ignore existing superclasses and modules included in them" do
726
+ c = Class.new{def a() [1] + super end; include Module.new{def a() [2] + (super rescue [0]) end}}
727
+ c2 = Class.new(c){def a() [4] + super end; include Module.new{def a() [8] + (super rescue [0]) end}}
728
+ c2.new.a.should == [4, 8, 1, 2, 0]
729
+ c2.superclass = Object
730
+ c2.new.a.should == [4, 8, 0]
731
+ end
732
+ end
733
+
734
+ describe "Class#inherit" do
735
+ specify "should raise an exception for immediate values" do
736
+ proc{Class.new.inherit nil}.should raise_error(TypeError)
737
+ end
738
+
739
+ specify "should raise an exception for non-class arguments" do
740
+ proc{Class.new.inherit Object.new}.should raise_error(TypeError)
741
+ end
742
+
743
+ specify "should raise an exception for incompatible types" do
744
+ proc{Class.new.inherit String}.should raise_error(TypeError)
745
+ end
746
+
747
+ specify "should include the classes as modules" do
748
+ c = Class.new{def a() [1] + (super rescue [0]) end}
749
+ c2 = Class.new{def a() [2] + super end}
750
+ sc = Class.new{def a() [4] + super end; inherit c, c2}
751
+ sc.new.a.should == [4, 2, 1, 0]
752
+ end
753
+
754
+ specify "should keep any included modules" do
755
+ c = Class.new{def a() [1] + super end; include Module.new{def a() [2] + (super rescue [0]) end}}
756
+ c2 = Class.new{def a() [4] + super end; include Module.new{def a() [8] + (super rescue [0]) end}}
757
+ sc = Class.new{def a() [16] + super end; inherit c, c2}
758
+ sc.new.a.should == [16, 4, 8, 1, 2, 0]
759
+ end
760
+
761
+ specify "should ignore superclasses of arguments, and keep superclass of current class" do
762
+ c = Class.new{def a() [1] + super end; include Module.new{def a() [2] + (super rescue [0]) end}}
763
+ sc1 = Class.new(c){def a() [4] + super end; include Module.new{def a() [8] + (super rescue [0]) end}}
764
+ sc2 = Class.new(c){def a() [16] + super end; include Module.new{def a() [32] + (super rescue [0]) end}}
765
+ Class.new{def a() [64] + super end; inherit sc1, sc2}.new.a.should == [64, 16, 32, 4, 8, 0]
766
+ Class.new(sc2){def a() [64] + super end; inherit sc1}.new.a.should == [64, 4, 8, 16, 32, 1, 2, 0]
767
+ Class.new(sc2){def a() [64] + super end; inherit sc1}.superclass.should == sc2
768
+ end
769
+ end
770
+
771
+ describe "Object#flags" do
772
+ specify "should raise an exception for immediate values" do
773
+ proc{nil.flags}.should raise_error(TypeError)
774
+ end
775
+
776
+ specify "should return a Fixnum" do
777
+ Object.new.flags.should be_a_kind_of(Fixnum)
778
+ Class.new.flags.should be_a_kind_of(Fixnum)
779
+ Module.new.flags.should be_a_kind_of(Fixnum)
780
+ Object.new.flags.should_not == Class.new.flags
781
+ Module.new.flags.should_not == Class.new.flags
782
+ end
783
+ end
784
+
785
+ describe "Object#swap_instance_variables" do
786
+ specify "should raise an exception for immediate values" do
787
+ proc{nil.swap_instance_variables(Object.new)}.should raise_error(TypeError)
788
+ proc{Object.new.swap_instance_variables(nil)}.should raise_error(TypeError)
789
+ end
790
+
791
+ specify "should raise an exception for swapping between modules and objects" do
792
+ proc{Class.new.swap_instance_variables(Object.new)}.should raise_error(TypeError)
793
+ proc{Object.new.swap_instance_variables(Class.new)}.should raise_error(TypeError)
794
+ end
795
+
796
+ specify "should raise an exception for other types" do
797
+ proc{{}.swap_instance_variables([])}.should raise_error(TypeError)
798
+ proc{"".swap_instance_variables(//)}.should raise_error(TypeError)
799
+ end
800
+
801
+ specify "should swap the instance's instance variables" do
802
+ o1 = Object.new
803
+ o2 = Object.new
804
+ o1.instance_eval{@a = 1; @c = 3}
805
+ o2.instance_eval{@a = 4; @b = 2}
806
+ o1.swap_instance_variables(o2)
807
+ o2.instance_eval{@a.should == 1; @c.should == 3}
808
+ o1.instance_eval{@a.should == 4; @b.should == 2}
809
+ end
810
+
811
+ specify "should allow swapping between modules" do
812
+ c = Class.new
813
+ m = Module.new
814
+ c.instance_eval{@a = 1; @c = 3}
815
+ m.instance_eval{@a = 4; @b = 2}
816
+ c.swap_instance_variables(m)
817
+ m.instance_eval{@a.should == 1; @c.should == 3}
818
+ c.instance_eval{@a.should == 4; @b.should == 2}
819
+ end
820
+
821
+ specify "should return self" do
822
+ o = Object.new
823
+ o.swap_instance_variables(Object.new).should equal(o)
824
+ end
825
+ end
826
+
827
+ describe "Module#swap_method_tables" do
828
+ specify "should raise an exception for immediate values" do
829
+ proc{Class.new.swap_method_tables(nil)}.should raise_error(TypeError)
830
+ end
831
+
832
+ specify "should raise an exception for non-module arguments" do
833
+ proc{Class.new.swap_method_tables(Object.new)}.should raise_error(TypeError)
834
+ end
835
+
836
+ specify "should swap the module's method tables" do
837
+ c1 = Class.new{def a() 1 end; def b() 3 end}
838
+ c2 = Class.new{def a() 4 end; def c() 2 end}
839
+ c1.new.a.should == 1
840
+ c2.new.a.should == 4
841
+ c1.new.b.should == 3
842
+ c2.new.c.should == 2
843
+ proc{c1.new.c}.should raise_error(NoMethodError)
844
+ proc{c2.new.b}.should raise_error(NoMethodError)
845
+ c1.swap_method_tables(c2)
846
+ c2.new.a.should == 1
847
+ c1.new.a.should == 4
848
+ c2.new.b.should == 3
849
+ c1.new.c.should == 2
850
+ proc{c2.new.c}.should raise_error(NoMethodError)
851
+ proc{c1.new.b}.should raise_error(NoMethodError)
852
+ end
853
+
854
+ specify "should return self" do
855
+ c = Class.new
856
+ c.swap_method_tables(Class.new).should equal(c)
857
+ end
858
+ end
859
+
860
+ describe "Module#uninclude" do
861
+ specify "should raise an exception for immediate values" do
862
+ proc{Module.new.uninclude nil}.should raise_error(TypeError)
863
+ end
864
+
865
+ specify "should raise an exception for non-module arguments" do
866
+ proc{Module.new.uninclude Object.new}.should raise_error(TypeError)
867
+ proc{Module.new.uninclude Class.new}.should raise_error(TypeError)
868
+ end
869
+
870
+ specify "should uninclude the given module from the module/class" do
871
+ m1 = Module.new{def a() [1] + (super rescue [0]) end}
872
+ m2 = Module.new{def a() [2] + (super rescue [0]) end}
873
+ m3 = Module.new{def a() [4] + (super rescue [0]) end}
874
+ m1.send :include, m2
875
+ m1.send :include, m3
876
+
877
+ c = Class.new{include m1}
878
+ c.new.a.should == [1, 4, 2, 0]
879
+ c.uninclude m1
880
+ c.new.a.should == [4, 2, 0]
881
+ c.uninclude m2
882
+ c.new.a.should == [4, 0]
883
+
884
+ m1.uninclude m3
885
+ Class.new{include m1}.new.a.should == [1, 2, 0]
886
+ m1.uninclude m2
887
+ Class.new{include m1}.new.a.should == [1, 0]
888
+ end
889
+
890
+ specify "should traverse into superclasses" do
891
+ m1 = Module.new{def a() [1] + (super rescue [0]) end}
892
+ m2 = Module.new{def a() [2] + (super rescue [0]) end}
893
+ m3 = Module.new{def a() [4] + (super rescue [0]) end}
894
+ m1.send :include, m2
895
+
896
+ c = Class.new{def a() [8] + (super rescue [0]) end; include m1}
897
+ c = Class.new(c){def a() [16] + (super rescue [0]) end; include m3}
898
+ c.new.a.should == [16, 4, 8, 1, 2, 0]
899
+ c.uninclude m1
900
+ c.new.a.should == [16, 4, 8, 2, 0]
901
+ c.uninclude m2
902
+ c.new.a.should == [16, 4, 8, 0]
903
+ c.uninclude m3
904
+ c.new.a.should == [16, 8, 0]
905
+ end
906
+
907
+ specify "should return module if module included" do
908
+ m = Module.new
909
+ m2 = Module.new{include m}
910
+ m2.uninclude(m).should == m
911
+ end
912
+
913
+ specify "should return nil if module not included" do
914
+ Module.new.uninclude(Module.new).should == nil
915
+ end
916
+ end
917
+
918
+ describe "Module#include_between" do
919
+ specify "should raise an exception for immediate values" do
920
+ proc{Module.new.include_between(nil){|p,c|}}.should raise_error(TypeError)
921
+ end
922
+
923
+ specify "should raise an exception for non-module arguments" do
924
+ proc{Module.new.include_between(Object.new){|p,c|}}.should raise_error(TypeError)
925
+ proc{Module.new.include_between(Class.new){|p,c|}}.should raise_error(TypeError)
926
+ end
927
+
928
+ specify "should raise an exception if a block is not given" do
929
+ proc{Module.new.include_between(Module.new)}.should raise_error(LocalJumpError)
930
+ end
931
+
932
+ specify "should include the module between the block's modules if the block returns true" do
933
+ m1 = Module.new{def a() [1] + (super rescue [0]) end}
934
+ m2 = Module.new{def a() [2] + (super rescue [0]) end}
935
+ m3 = Module.new{def a() [4] + (super rescue [0]) end}
936
+
937
+ c = Class.new
938
+ c.include_between(m1){|prev, cur| true}
939
+ c.include_between(m2){|prev, cur| cur == Object}
940
+ c.include_between(m3){|prev, cur| prev == m1}
941
+ c.new.a.should == [1, 4, 2, 0]
942
+ end
943
+
944
+ specify "should traverse into superclasses" do
945
+ m1 = Module.new{def a() [1] + (super rescue [0]) end}
946
+ m2 = Module.new{def a() [2] + (super rescue [0]) end}
947
+ m3 = Module.new{def a() [4] + (super rescue [0]) end}
948
+
949
+ c = Class.new{def a() [8] + (super rescue [0]) end}
950
+ sc = Class.new(c){def a() [16] + (super rescue [0]) end}
951
+ sc.include_between(m1){|prev, cur| prev == c}
952
+ sc.include_between(m2){|prev, cur| cur == m1}
953
+ sc.include_between(m3){|prev, cur| true}
954
+ c.new.a.should == [8, 2, 1, 0]
955
+ sc.new.a.should == [16, 4, 8, 2, 1, 0]
956
+ end
957
+
958
+ specify "should have first block call first argument be current module/class" do
959
+ c = Class.new
960
+ c.include_between(Module.new){|prev, cur| prev.should == c; break}
961
+ end
962
+
963
+ specify "should have last block call last argument be nil" do
964
+ c = Class.new
965
+ x = 1
966
+ c.include_between(Module.new){|prev, cur| x = cur}
967
+ x.should == nil
968
+ end
969
+
970
+ specify "should have superclass as both last and first argument at some point, if not returned" do
971
+ c = Class.new
972
+ a = []
973
+ c.include_between(Module.new){|prev, cur| a << :prev if prev == c.superclass; a << :cur if cur == c.superclass}
974
+ a.should == [:cur, :prev]
975
+ end
976
+
977
+ specify "should return module if module included" do
978
+ m = Module.new
979
+ m2 = Module.new{include m}
980
+ m2.include_between(m){|p, c| true}.should == m
981
+ end
982
+
983
+ specify "should return nil if module not included" do
984
+ Module.new.include_between(Module.new){|p, c|}.should == nil
985
+ end
986
+ end
987
+
988
+ describe "Object#unextend" do
989
+ specify "should raise an exception if called on immediate values" do
990
+ proc{nil.unextend Module.new}.should raise_error(TypeError)
991
+ end
992
+
993
+ specify "should raise an exception for immediate value arguments" do
994
+ proc{Object.new.unextend nil}.should raise_error(TypeError)
995
+ end
996
+
997
+ specify "should raise an exception for non-module arguments" do
998
+ proc{Object.new.unextend Object.new}.should raise_error(TypeError)
999
+ proc{Object.new.unextend Class.new}.should raise_error(TypeError)
1000
+ end
1001
+
1002
+ specify "should unextend the given module from the object" do
1003
+ m1 = Module.new{def a() [1] + (super rescue [0]) end}
1004
+ m2 = Module.new{def a() [2] + (super rescue [0]) end}
1005
+ m3 = Module.new{def a() [4] + (super rescue [0]) end}
1006
+ m1.send :include, m2
1007
+ m1.send :include, m3
1008
+
1009
+ o = Object.new
1010
+ o.extend m1
1011
+ o.a.should == [1, 4, 2, 0]
1012
+ o.unextend m1
1013
+ o.a.should == [4, 2, 0]
1014
+ o.unextend m2
1015
+ o.a.should == [4, 0]
1016
+ end
1017
+
1018
+ specify "should not traverse above the object's class" do
1019
+ m1 = Module.new{def a() [1] + (super rescue [0]) end}
1020
+ m2 = Module.new{def a() [2] + (super rescue [0]) end}
1021
+ m3 = Module.new{def a() [4] + (super rescue [0]) end}
1022
+ m1.send :include, m2
1023
+
1024
+ c = Class.new{def a() [8] + (super rescue [0]) end; include m1}
1025
+ o = c.new
1026
+ o.extend m3
1027
+ o.a.should == [4, 8, 1, 2, 0]
1028
+ o.unextend m3
1029
+ o.a.should == [8, 1, 2, 0]
1030
+ o.unextend m2
1031
+ o.a.should == [8, 1, 2, 0]
1032
+ end
1033
+
1034
+ specify "should return module if module extended the object" do
1035
+ m = Module.new
1036
+ o = Object.new
1037
+ o.extend(m)
1038
+ o.unextend(m).should == m
1039
+ end
1040
+
1041
+ specify "should return nil if module did not extend the object" do
1042
+ Object.new.unextend(Module.new).should == nil
1043
+ end
1044
+
1045
+ specify "should correctly handle objects without existing singleton classes" do
1046
+ m = Module.new{def a() [2] + (super rescue [0]) end}
1047
+ c = Class.new{def a() [1] + (super rescue [0]) end; include m}
1048
+ o = c.new
1049
+ o.unextend(Module.new).should == nil
1050
+ o.a.should == [1, 2, 0]
1051
+ end
1052
+ end
1053
+
1054
+ describe "Object#extend_between" do
1055
+ specify "should raise an exception if called on an immediate value" do
1056
+ proc{nil.extend_between(Module.new){|p,c|}}.should raise_error(TypeError)
1057
+ end
1058
+
1059
+ specify "should raise an exception for immediate value arguments" do
1060
+ proc{Object.new.extend_between(nil){|p,c|}}.should raise_error(TypeError)
1061
+ end
1062
+
1063
+ specify "should raise an exception for non-module arguments" do
1064
+ proc{Object.new.extend_between(Object.new){|p,c|}}.should raise_error(TypeError)
1065
+ proc{Object.new.extend_between(Class.new){|p,c|}}.should raise_error(TypeError)
1066
+ end
1067
+
1068
+ specify "should raise an exception if a block is not given" do
1069
+ proc{Object.new.extend_between(Module.new)}.should raise_error(LocalJumpError)
1070
+ end
1071
+
1072
+ specify "should raise an exception if module already included in object's class or superclass" do
1073
+ m = Module.new
1074
+ c = Class.new{include m}
1075
+ proc{c.new.extend_between(m){|p, c|}}.should raise_error(ArgumentError)
1076
+ end
1077
+
1078
+ specify "should include the module between the block's modules if the block returns true" do
1079
+ m1 = Module.new{def a() [1] + (super rescue [0]) end}
1080
+ m2 = Module.new{def a() [2] + (super rescue [0]) end}
1081
+ m3 = Module.new{def a() [4] + (super rescue [0]) end}
1082
+
1083
+ o = Object.new
1084
+ o.extend_between(m1){|prev, cur| true}
1085
+ o.extend_between(m2){|prev, cur| cur == Object}
1086
+ o.extend_between(m3){|prev, cur| prev == m1}
1087
+ o.a.should == [1, 4, 2, 0]
1088
+ def o.a() [8] + super end
1089
+ o.a.should == [8, 1, 4, 2, 0]
1090
+ end
1091
+
1092
+ specify "should have first block call first argument be the receiver's singleton class" do
1093
+ o = Object.new
1094
+ o.extend_between(Module.new){|prev, cur| prev.should == class << o; self end; break}
1095
+ end
1096
+
1097
+ specify "should have last block call last argument be object's class" do
1098
+ c = Class.new
1099
+ x = 1
1100
+ c.new.extend_between(Module.new){|prev, cur| x = cur}
1101
+ x.should == c
1102
+ end
1103
+
1104
+ specify "should have extended modules as both last and first argument at some point" do
1105
+ m = Module.new
1106
+ c = Class.new
1107
+ o = c.new
1108
+ o.extend m
1109
+ a = []
1110
+ o.extend_between(Module.new){|prev, cur| a << :prev if prev == m; a << :cur if cur == m}
1111
+ a.should == [:cur, :prev]
1112
+ end
1113
+
1114
+ specify "should return module if module included" do
1115
+ m = Module.new
1116
+ Object.new.extend_between(m){|p, c| true}.should == m
1117
+ end
1118
+
1119
+ specify "should return nil if module not included" do
1120
+ Object.new.extend_between(Module.new){|p, c|}.should == nil
1121
+ end
1122
+
1123
+ specify "should handle objects without existing singleton classes" do
1124
+ o = Object.new
1125
+ i = 0
1126
+ o.extend_between(Module.new){|p, c| p.should == (class << o; self end); c.should == Object; i += 1}
1127
+ i.should == 1
1128
+ end
1129
+ end
1130
+
1131
+ describe "Empty" do
1132
+ specify "should be able to be instantiated" do
1133
+ proc{Empty.new}.should_not raise_error
1134
+ end
1135
+
1136
+ specify "should raise an error if instantiated with arguments" do
1137
+ proc{Empty.new 1}.should raise_error(ArgumentError)
1138
+ end
1139
+
1140
+ specify "should not raise an error if subclass instantiated with arguments and supports those arguments" do
1141
+ c = Class.new(Empty){def initialize(*) end}
1142
+ proc{c.new 1, 2, 3}.should_not raise_error
1143
+ end
1144
+
1145
+ specify "should have nil superclass" do
1146
+ Empty.superclass.should == nil
1147
+ end
1148
+
1149
+ specify "subclasses should have correct superclass" do
1150
+ Class.new(Empty).superclass.should == Empty
1151
+ end
1152
+
1153
+ specify "should have instances that aren't objects" do
1154
+ Object.instance_method(:is_a?).force_bind(Empty.new).call(Object).should be_false
1155
+ end
1156
+ end
1157
+ end