temporaries 0.0.1

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,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