-
Notifications
You must be signed in to change notification settings - Fork 10
/
shared.rb
129 lines (111 loc) · 3.03 KB
/
shared.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
require 'rspec'
require 'promise'
shared_examples_for "A Promise" do
it "should be createable" do
lambda {x = @method.call { 3 + 5 }}.should_not raise_error
end
it "should not accept a block requiring arguments" do
lambda {x = @method.call { | x | 3 + 5 }}.should raise_error
end
it "should be forceable" do
x = @method.call { 3 + 5 }
x.__force__.should == 8
x.should == 8
end
it "should respond_to? force" do
x = @method.call { 3 + 5 }
x.respond_to?(:force).should be_true
end
it "should respond_to? __force__" do
x = @method.call { 3 + 5 }
x.respond_to?(:__force__).should be_true
end
it "should respond_to? a method on the result" do
x = @method.call { 3 + 5 }
x.respond_to?(:+).should be_true
end
it "should not respond_to? a method not on the result" do
x = @method.call { 3 + 5 }
x.respond_to?(:asdf).should be_false
end
it "should evaluate to a value" do
(5 + @method.call { 1 + 2 }).should == 8
end
it "should hold its value" do
y = 5
x = @method.call { y = y + 5 }
x.should == 10
x.should == 10
end
it "should only execute once" do
y = 1
x = @method.call { (y += 1) && false }
x.should == false
x.should == false
y.should == 2
end
it "should raise exceptions raised during execution when accessed" do
y = Object.new
y = @method.call { 1 / 0 }
lambda { y.inspect }.should raise_error ZeroDivisionError
lambda { y.inspect }.should raise_error ZeroDivisionError
end
it "should only execute once when execptions are raised" do
y = 1
x = @method.call { (y += 1) && (1 / 0) }
lambda { x.inspect }.should raise_error ZeroDivisionError
lambda { x.inspect }.should raise_error ZeroDivisionError
y.should == 2
end
it "should remain the same for an object reference" do
h = {}
x = Object.new
h[:test] = @method.call { x }
h[:test].should == x
end
it "should be eql? for results" do
x = Object.new
y = @method.call { x }
y.should eql x
# this would be ideal, but it can't be done in Ruby. result
# objects that have a redefined #eql? should do fine.
#x.should eql y
end
it "should be equal? for results" do
x = Object.new
y = @method.call { x }
y.should equal x
# this would be ideal, but it can't be done in Ruby.
#x.should equal y
end
it "should be thread safe" do
x = @method.call { res = 1; 3.times { res = res * 5 ; sleep 1 } ; res}
threads = []
results = []
changeds = []
10.times do
threads << Thread.new do
changed = false
res = old_res = 125
10.times do |i|
old_res = res
res = x + 5
changed ||= res != old_res && i != 0
sleep 0.3
end
results << res
changeds << changed
end
end
threads.each do |t|
t.join
end
results.each do |result|
result.should == 130
end
changeds.each do |changed|
changed.should == false
end
changeds.size.should == 10
end
end