temporaries 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,672 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe Temporaries::Values do
4
+ before do
5
+ @context_class = Class.new(TestContext) do
6
+ include Temporaries::Values
7
+ end
8
+ @context = @context_class.new
9
+ end
10
+
11
+ describe "#push_constant_value and #pop_constant_value" do
12
+ before do
13
+ @mod = Module.new
14
+ end
15
+
16
+ describe "when the constant already exists" do
17
+ before do
18
+ @mod.const_set(:CONSTANT, 2)
19
+ end
20
+
21
+ it "should set the given module's constant to the pushed value until it is popped" do
22
+ @mod::CONSTANT.should == 2
23
+ @context.push_constant_value @mod, :CONSTANT, 3
24
+ @mod::CONSTANT.should == 3
25
+ @context.pop_constant_value @mod, :CONSTANT
26
+ @mod::CONSTANT.should == 2
27
+ end
28
+
29
+ it "should be nestable" do
30
+ @mod::CONSTANT.should == 2
31
+ @context.push_constant_value @mod, :CONSTANT, 3
32
+ @mod::CONSTANT.should == 3
33
+ @context.push_constant_value @mod, :CONSTANT, 5
34
+ @mod::CONSTANT.should == 5
35
+ @context.pop_constant_value @mod, :CONSTANT
36
+ @mod::CONSTANT.should == 3
37
+ @context.pop_constant_value @mod, :CONSTANT
38
+ @mod::CONSTANT.should == 2
39
+ end
40
+ end
41
+
42
+ describe "when the constant does not already exist" do
43
+ it "should set the given module's constant to the pushed value, and remove it when popped" do
44
+ @mod.const_defined?(:CONSTANT).should be_false
45
+ @context.push_constant_value @mod, :CONSTANT, 3
46
+ @mod::CONSTANT.should == 3
47
+ @context.pop_constant_value @mod, :CONSTANT
48
+ @mod.const_defined?(:CONSTANT).should be_false
49
+ end
50
+ end
51
+ end
52
+
53
+ describe "#with_constant_value" do
54
+ before do
55
+ @mod = Module.new
56
+ @mod.const_set(:CONSTANT, 2)
57
+ end
58
+
59
+ it "should set the given module's constant to the given value only during the given block" do
60
+ @mod::CONSTANT.should == 2
61
+ block_run = false
62
+ @context.with_constant_value @mod, :CONSTANT, 3 do
63
+ block_run = true
64
+ @mod::CONSTANT.should == 3
65
+ end
66
+ block_run.should be_true
67
+ @mod::CONSTANT.should == 2
68
+ end
69
+
70
+ it "should be nestable" do
71
+ @mod::CONSTANT.should == 2
72
+ blocks_run = []
73
+ @context.with_constant_value @mod, :CONSTANT, 3 do
74
+ blocks_run << 1
75
+ @mod::CONSTANT.should == 3
76
+ @context.with_constant_value @mod, :CONSTANT, 5 do
77
+ blocks_run << 2
78
+ @mod::CONSTANT.should == 5
79
+ end
80
+ @mod::CONSTANT.should == 3
81
+ end
82
+ blocks_run.should == [1, 2]
83
+ @mod::CONSTANT.should == 2
84
+ end
85
+
86
+ it "should handle nonlocal exits" do
87
+ exception_class = Class.new(Exception)
88
+ @mod::CONSTANT.should == 2
89
+ begin
90
+ @context.with_constant_value @mod, :CONSTANT, 3 do
91
+ @mod::CONSTANT.should == 3
92
+ raise exception_class, 'boom'
93
+ end
94
+ rescue exception_class => e
95
+ end
96
+ @mod::CONSTANT.should == 2
97
+ end
98
+ end
99
+
100
+ describe "#push_attribute_value and #pop_attribute_value" do
101
+ before do
102
+ @klass = Class.new{attr_accessor :attribute}
103
+ @object = @klass.new
104
+ @object.attribute = 2
105
+ end
106
+
107
+ it "should set the given object's attribute to the pushed value until it is popped" do
108
+ @object.attribute.should == 2
109
+ @context.push_attribute_value @object, :attribute, 3
110
+ @object.attribute.should == 3
111
+ @context.pop_attribute_value @object, :attribute
112
+ @object.attribute.should == 2
113
+ end
114
+
115
+ it "should be nestable" do
116
+ @object.attribute.should == 2
117
+ @context.push_attribute_value @object, :attribute, 3
118
+ @object.attribute.should == 3
119
+ @context.push_attribute_value @object, :attribute, 5
120
+ @object.attribute.should == 5
121
+ @context.pop_attribute_value @object, :attribute
122
+ @object.attribute.should == 3
123
+ @context.pop_attribute_value @object, :attribute
124
+ @object.attribute.should == 2
125
+ end
126
+ end
127
+
128
+ describe "#with_attribute_value" do
129
+ before do
130
+ @klass = Class.new{attr_accessor :attribute}
131
+ @object = @klass.new
132
+ @object.attribute = 2
133
+ end
134
+
135
+ it "should set the given object's attribute to the given value only during the given block" do
136
+ @object.attribute.should == 2
137
+ block_run = false
138
+ @context.with_attribute_value @object, :attribute, 3 do
139
+ block_run = true
140
+ @object.attribute.should == 3
141
+ end
142
+ block_run.should be_true
143
+ @object.attribute.should == 2
144
+ end
145
+
146
+ it "should be nestable" do
147
+ @object.attribute.should == 2
148
+ blocks_run = []
149
+ @context.with_attribute_value @object, :attribute, 3 do
150
+ blocks_run << 1
151
+ @object.attribute.should == 3
152
+ @context.with_attribute_value @object, :attribute, 5 do
153
+ blocks_run << 2
154
+ @object.attribute.should == 5
155
+ end
156
+ @object.attribute.should == 3
157
+ end
158
+ blocks_run.should == [1, 2]
159
+ @object.attribute.should == 2
160
+ end
161
+
162
+ it "should handle nonlocal exits" do
163
+ exception_class = Class.new(Exception)
164
+ @object.attribute.should == 2
165
+ begin
166
+ @context.with_attribute_value @object, :attribute, 3 do
167
+ @object.attribute.should == 3
168
+ raise exception_class, 'boom'
169
+ end
170
+ rescue exception_class => e
171
+ end
172
+ @object.attribute.should == 2
173
+ end
174
+ end
175
+
176
+ describe "#push_hash_value and #pop_hash_value" do
177
+ before do
178
+ @hash = {}
179
+ end
180
+
181
+ describe "when the hash key already exists" do
182
+ before do
183
+ @hash[:key] = 2
184
+ end
185
+
186
+ it "should set the given hash's key to the pushed value until it is popped" do
187
+ @hash[:key].should == 2
188
+ @context.push_hash_value @hash, :key, 3
189
+ @hash[:key].should == 3
190
+ @context.pop_hash_value @hash, :key
191
+ @hash[:key].should == 2
192
+ end
193
+
194
+ it "should be nestable" do
195
+ @hash[:key].should == 2
196
+ @context.push_hash_value @hash, :key, 3
197
+ @hash[:key].should == 3
198
+ @context.push_hash_value @hash, :key, 5
199
+ @hash[:key].should == 5
200
+ @context.pop_hash_value @hash, :key
201
+ @hash[:key].should == 3
202
+ @context.pop_hash_value @hash, :key
203
+ @hash[:key].should == 2
204
+ end
205
+ end
206
+
207
+ describe "when the hash key does not already exist" do
208
+ it "should set the given hash's key to the pushed value, and remove it when popped" do
209
+ @hash.key?(:key).should be_false
210
+ @context.push_hash_value @hash, :key, 3
211
+ @hash[:key].should == 3
212
+ @context.pop_hash_value @hash, :key
213
+ @hash.key?(:key).should be_false
214
+ end
215
+ end
216
+ end
217
+
218
+ describe "#with_hash_value" do
219
+ before do
220
+ @hash = {:key => 2}
221
+ end
222
+
223
+ it "should set the given hash's key to the given value only during the given block" do
224
+ @hash[:key].should == 2
225
+ block_run = false
226
+ @context.with_hash_value @hash, :key, 3 do
227
+ block_run = true
228
+ @hash[:key].should == 3
229
+ end
230
+ block_run.should be_true
231
+ @hash[:key].should == 2
232
+ end
233
+
234
+ it "should be nestable" do
235
+ @hash[:key].should == 2
236
+ blocks_run = []
237
+ @context.with_hash_value @hash, :key, 3 do
238
+ blocks_run << 1
239
+ @hash[:key].should == 3
240
+ @context.with_hash_value @hash, :key, 5 do
241
+ blocks_run << 2
242
+ @hash[:key].should == 5
243
+ end
244
+ @hash[:key].should == 3
245
+ end
246
+ blocks_run.should == [1, 2]
247
+ @hash[:key].should == 2
248
+ end
249
+
250
+ it "should handle nonlocal exits" do
251
+ exception_class = Class.new(Exception)
252
+ @hash[:key].should == 2
253
+ begin
254
+ @context.with_hash_value @hash, :key, 3 do
255
+ @hash[:key].should == 3
256
+ raise exception_class, 'boom'
257
+ end
258
+ rescue exception_class => e
259
+ end
260
+ @hash[:key].should == 2
261
+ end
262
+ end
263
+
264
+ describe "#push_instance_variable_value and #pop_instance_variable_value" do
265
+ before do
266
+ @object = Object.new
267
+ end
268
+
269
+ describe "when the instance variable already exists" do
270
+ before do
271
+ @object.instance_eval{@variable = 2}
272
+ end
273
+
274
+ it "should set the given object's ivar to the pushed value until it is popped" do
275
+ @object.instance_variable_get(:@variable).should == 2
276
+ @context.push_instance_variable_value @object, :variable, 3
277
+ @object.instance_variable_get(:@variable).should == 3
278
+ @context.pop_instance_variable_value @object, :variable
279
+ @object.instance_variable_get(:@variable).should == 2
280
+ end
281
+
282
+ it "should be nestable" do
283
+ @object.instance_variable_get(:@variable).should == 2
284
+ @context.push_instance_variable_value @object, :variable, 3
285
+ @object.instance_variable_get(:@variable).should == 3
286
+ @context.push_instance_variable_value @object, :variable, 5
287
+ @object.instance_variable_get(:@variable).should == 5
288
+ @context.pop_instance_variable_value @object, :variable
289
+ @object.instance_variable_get(:@variable).should == 3
290
+ @context.pop_instance_variable_value @object, :variable
291
+ @object.instance_variable_get(:@variable).should == 2
292
+ end
293
+ end
294
+
295
+ describe "when the instance variable does not already exist" do
296
+ it "should set the given instance variable to the pushed value, and remove it when popped" do
297
+ @object.instance_variable_defined?(:@variable).should be_false
298
+ @context.push_instance_variable_value @object, :variable, 3
299
+ @object.instance_variable_get(:@variable).should == 3
300
+ @context.pop_instance_variable_value @object, :variable
301
+ @object.instance_variable_defined?(:@variable).should be_false
302
+ end
303
+ end
304
+ end
305
+
306
+ describe "#with_instance_variable_value" do
307
+ before do
308
+ @object = Object.new
309
+ @object.instance_eval{@variable = 2}
310
+ end
311
+
312
+ it "should set the given object's ivar to the given value only during the given block" do
313
+ @object.instance_variable_get(:@variable).should == 2
314
+ block_run = false
315
+ @context.with_instance_variable_value @object, :variable, 3 do
316
+ block_run = true
317
+ @object.instance_variable_get(:@variable).should == 3
318
+ end
319
+ block_run.should be_true
320
+ @object.instance_variable_get(:@variable).should == 2
321
+ end
322
+
323
+ it "should be nestable" do
324
+ @object.instance_variable_get(:@variable).should == 2
325
+ blocks_run = []
326
+ @context.with_instance_variable_value @object, :variable, 3 do
327
+ blocks_run << 1
328
+ @object.instance_variable_get(:@variable).should == 3
329
+ @context.with_instance_variable_value @object, :variable, 5 do
330
+ blocks_run << 2
331
+ @object.instance_variable_get(:@variable).should == 5
332
+ end
333
+ @object.instance_variable_get(:@variable).should == 3
334
+ end
335
+ blocks_run.should == [1, 2]
336
+ @object.instance_variable_get(:@variable).should == 2
337
+ end
338
+
339
+ it "should handle nonlocal exits" do
340
+ exception_class = Class.new(Exception)
341
+ @object.instance_variable_get(:@variable).should == 2
342
+ begin
343
+ @context.with_instance_variable_value @object, :variable, 3 do
344
+ @object.instance_variable_get(:@variable).should == 3
345
+ raise exception_class, 'boom'
346
+ end
347
+ rescue exception_class => e
348
+ end
349
+ @object.instance_variable_get(:@variable).should == 2
350
+ end
351
+ end
352
+
353
+ describe "#push_class_variable_value and #pop_class_variable_value" do
354
+ before do
355
+ @class = Class.new
356
+ end
357
+
358
+ describe "when the class variable already exists" do
359
+ before do
360
+ # Did you know...?
361
+ #
362
+ # * class C; @@x; end refers to @@x in C
363
+ # * C.class_eval '@@x' refers to @@x in C
364
+ # * C.class_eval{@@x} refers to @@x in Object
365
+ # * Class.new{@@x} refers to @@x in Object
366
+ @class.class_eval '@@variable = 2'
367
+ end
368
+
369
+ it "should set the given object's cvar to the pushed value until it is popped" do
370
+ @class.class_eval('@@variable').should == 2
371
+ @context.push_class_variable_value @class, :variable, 3
372
+ @class.class_eval('@@variable').should == 3
373
+ @context.pop_class_variable_value @class, :variable
374
+ @class.class_eval('@@variable').should == 2
375
+ end
376
+
377
+ it "should be nestable" do
378
+ @class.class_eval('@@variable').should == 2
379
+ @context.push_class_variable_value @class, :variable, 3
380
+ @class.class_eval('@@variable').should == 3
381
+ @context.push_class_variable_value @class, :variable, 5
382
+ @class.class_eval('@@variable').should == 5
383
+ @context.pop_class_variable_value @class, :variable
384
+ @class.class_eval('@@variable').should == 3
385
+ @context.pop_class_variable_value @class, :variable
386
+ @class.class_eval('@@variable').should == 2
387
+ end
388
+ end
389
+
390
+ describe "when the class variable does not already exist" do
391
+ it "should set the given class variable to the pushed value, and remove it when popped" do
392
+ @class.class_variable_defined?('@@variable').should be_false
393
+ @context.push_class_variable_value @class, :variable, 3
394
+ @class.class_eval('@@variable').should == 3
395
+ @context.pop_class_variable_value @class, :variable
396
+ @class.class_variable_defined?('@@variable').should be_false
397
+ end
398
+ end
399
+ end
400
+
401
+ describe "#with_class_variable_value" do
402
+ before do
403
+ @class = Class.new
404
+ @class.class_eval '@@variable = 2'
405
+ end
406
+
407
+ it "should set the given object's cvar to the given value only during the given block" do
408
+ @class.class_eval('@@variable').should == 2
409
+ block_run = false
410
+ @context.with_class_variable_value @class, :variable, 3 do
411
+ block_run = true
412
+ @class.class_eval('@@variable').should == 3
413
+ end
414
+ block_run.should be_true
415
+ @class.class_eval('@@variable').should == 2
416
+ end
417
+
418
+ it "should be nestable" do
419
+ @class.class_eval('@@variable').should == 2
420
+ blocks_run = []
421
+ @context.with_class_variable_value @class, :variable, 3 do
422
+ blocks_run << 1
423
+ @class.class_eval('@@variable').should == 3
424
+ @context.with_class_variable_value @class, :variable, 5 do
425
+ blocks_run << 2
426
+ @class.class_eval('@@variable').should == 5
427
+ end
428
+ @class.class_eval('@@variable').should == 3
429
+ end
430
+ blocks_run.should == [1, 2]
431
+ @class.class_eval('@@variable').should == 2
432
+ end
433
+
434
+ it "should handle nonlocal exits" do
435
+ exception_class = Class.new(Exception)
436
+ @class.class_eval('@@variable').should == 2
437
+ begin
438
+ @context.with_class_variable_value @class, :variable, 3 do
439
+ @class.class_eval('@@variable').should == 3
440
+ raise exception_class, 'boom'
441
+ end
442
+ rescue exception_class => e
443
+ end
444
+ @class.class_eval('@@variable').should == 2
445
+ end
446
+ end
447
+
448
+ describe "#push_global_value and #pop_global_value" do
449
+ before do
450
+ $variable = 2
451
+ end
452
+
453
+ after do
454
+ $variable = nil
455
+ end
456
+
457
+ it "should set the given global to the pushed value until it is popped" do
458
+ $variable.should == 2
459
+ @context.push_global_value :variable, 3
460
+ $variable.should == 3
461
+ @context.pop_global_value :variable
462
+ $variable.should == 2
463
+ end
464
+
465
+ it "should be nestable" do
466
+ $variable.should == 2
467
+ @context.push_global_value :variable, 3
468
+ $variable.should == 3
469
+ @context.push_global_value :variable, 5
470
+ $variable.should == 5
471
+ @context.pop_global_value :variable
472
+ $variable.should == 3
473
+ @context.pop_global_value :variable
474
+ $variable.should == 2
475
+ end
476
+ end
477
+
478
+ describe "#with_global_value" do
479
+ before do
480
+ $variable = 2
481
+ end
482
+
483
+ it "should set the given global to the given value only during the given block" do
484
+ $variable.should == 2
485
+ block_run = false
486
+ @context.with_global_value :variable, 3 do
487
+ block_run = true
488
+ $variable.should == 3
489
+ end
490
+ block_run.should be_true
491
+ $variable.should == 2
492
+ end
493
+
494
+ it "should be nestable" do
495
+ $variable.should == 2
496
+ blocks_run = []
497
+ @context.with_global_value :variable, 3 do
498
+ blocks_run << 1
499
+ $variable.should == 3
500
+ @context.with_global_value :variable, 5 do
501
+ blocks_run << 2
502
+ $variable.should == 5
503
+ end
504
+ $variable.should == 3
505
+ end
506
+ blocks_run.should == [1, 2]
507
+ $variable.should == 2
508
+ end
509
+
510
+ it "should handle nonlocal exits" do
511
+ exception_class = Class.new(Exception)
512
+ $variable.should == 2
513
+ begin
514
+ @context.with_global_value :variable, 3 do
515
+ $variable.should == 3
516
+ raise exception_class, 'boom'
517
+ end
518
+ rescue exception_class => e
519
+ end
520
+ $variable.should == 2
521
+ end
522
+ end
523
+ end
524
+
525
+ describe Temporaries::Values do
526
+ describe ".use_constant_value" do
527
+ before do
528
+ @mod = mod = Module.new
529
+ mod.const_set(:CONSTANT, 2)
530
+
531
+ @context_class = Class.new(TestContext) do
532
+ include Temporaries::Values
533
+ use_constant_value mod, :CONSTANT, 3
534
+ end
535
+ @context = @context_class.new
536
+ end
537
+
538
+ it "should set the given module's constant to the given value for the duration of the run" do
539
+ @mod::CONSTANT.should == 2
540
+ block_run = false
541
+ @context.run do
542
+ block_run = true
543
+ @mod::CONSTANT.should == 3
544
+ end
545
+ block_run.should be_true
546
+ @mod::CONSTANT.should == 2
547
+ end
548
+ end
549
+
550
+ describe ".use_attribute_value" do
551
+ before do
552
+ @klass = Class.new{attr_accessor :attribute}
553
+ @object = object = @klass.new
554
+ @object.attribute = 2
555
+
556
+ @context_class = Class.new(TestContext) do
557
+ include Temporaries::Values
558
+ use_attribute_value object, :attribute, 3
559
+ end
560
+ @context = @context_class.new
561
+ end
562
+
563
+ it "should set the given object's attribute to the given value for the duration of the run" do
564
+ @object.attribute.should == 2
565
+ block_run = false
566
+ @context.run do
567
+ block_run = true
568
+ @object.attribute.should == 3
569
+ end
570
+ block_run.should be_true
571
+ @object.attribute.should == 2
572
+ end
573
+ end
574
+
575
+ describe ".use_hash_value" do
576
+ before do
577
+ @hash = hash = {:key => 2}
578
+
579
+ @context_class = Class.new(TestContext) do
580
+ include Temporaries::Values
581
+ use_hash_value hash, :key, 3
582
+ end
583
+ @context = @context_class.new
584
+ end
585
+
586
+ it "should set the given hash's key to the given value for the duration of the run" do
587
+ @hash[:key].should == 2
588
+ block_run = false
589
+ @context.run do
590
+ block_run = true
591
+ @hash[:key].should == 3
592
+ end
593
+ block_run.should be_true
594
+ @hash[:key].should == 2
595
+ end
596
+ end
597
+
598
+ describe ".use_instance_variable_value" do
599
+ before do
600
+ @object = object = Object.new
601
+ @object.instance_eval{@variable = 2}
602
+
603
+ @context_class = Class.new(TestContext) do
604
+ include Temporaries::Values
605
+ use_instance_variable_value object, :variable, 3
606
+ end
607
+ @context = @context_class.new
608
+ end
609
+
610
+ it "should set the given object's ivar to the given value for the duration of the run" do
611
+ @object.instance_variable_get(:@variable).should == 2
612
+ block_run = false
613
+ @context.run do
614
+ block_run = true
615
+ @object.instance_variable_get(:@variable).should == 3
616
+ end
617
+ block_run.should be_true
618
+ @object.instance_variable_get(:@variable).should == 2
619
+ end
620
+ end
621
+
622
+ describe ".use_class_variable_value" do
623
+ before do
624
+ @class = klass = Class.new
625
+ @class.class_eval '@@variable = 2'
626
+
627
+ @context_class = Class.new(TestContext) do
628
+ include Temporaries::Values
629
+ use_class_variable_value klass, :variable, 3
630
+ end
631
+ @context = @context_class.new
632
+ end
633
+
634
+ it "should set the given object's cvar to the given value for the duration of the run" do
635
+ @class.class_eval('@@variable').should == 2
636
+ block_run = false
637
+ @context.run do
638
+ block_run = true
639
+ @class.class_eval('@@variable').should == 3
640
+ end
641
+ block_run.should be_true
642
+ @class.class_eval('@@variable').should == 2
643
+ end
644
+ end
645
+
646
+ describe ".use_global_value" do
647
+ before do
648
+ $variable = 2
649
+
650
+ @context_class = Class.new(TestContext) do
651
+ include Temporaries::Values
652
+ use_global_value :variable, 3
653
+ end
654
+ @context = @context_class.new
655
+ end
656
+
657
+ after do
658
+ $variable = nil
659
+ end
660
+
661
+ it "should set the given global to the given value for the duration of the run" do
662
+ $variable.should == 2
663
+ block_run = false
664
+ @context.run do
665
+ block_run = true
666
+ $variable.should == 3
667
+ end
668
+ block_run.should be_true
669
+ $variable.should == 2
670
+ end
671
+ end
672
+ end