empathy 0.0.1.RC0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. data/.gitignore +17 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE.txt +22 -0
  4. data/README.rdoc +135 -0
  5. data/Rakefile +33 -0
  6. data/TESTING.rdoc +11 -0
  7. data/empathy.gemspec +23 -0
  8. data/empathy.mspec +34 -0
  9. data/lib/empathy.rb +162 -0
  10. data/lib/empathy/em/condition_variable.rb +57 -0
  11. data/lib/empathy/em/mutex.rb +70 -0
  12. data/lib/empathy/em/queue.rb +84 -0
  13. data/lib/empathy/em/thread.rb +363 -0
  14. data/lib/empathy/object.rb +19 -0
  15. data/lib/empathy/thread.rb +8 -0
  16. data/lib/empathy/version.rb +3 -0
  17. data/mspec/lib/mspec/empathy.rb +19 -0
  18. data/mspec/lib/mspec/guards/empathy.rb +10 -0
  19. data/rubyspec/core/kernel/fixtures/__method__.rb +25 -0
  20. data/rubyspec/core/kernel/fixtures/autoload_b.rb +5 -0
  21. data/rubyspec/core/kernel/fixtures/autoload_c.rb +5 -0
  22. data/rubyspec/core/kernel/fixtures/autoload_d.rb +5 -0
  23. data/rubyspec/core/kernel/fixtures/caller_fixture1.rb +42 -0
  24. data/rubyspec/core/kernel/fixtures/caller_fixture2.rb +26 -0
  25. data/rubyspec/core/kernel/fixtures/chomp.rb +4 -0
  26. data/rubyspec/core/kernel/fixtures/chomp_f.rb +4 -0
  27. data/rubyspec/core/kernel/fixtures/chop.rb +4 -0
  28. data/rubyspec/core/kernel/fixtures/chop_f.rb +4 -0
  29. data/rubyspec/core/kernel/fixtures/classes.rb +410 -0
  30. data/rubyspec/core/kernel/fixtures/eval_locals.rb +6 -0
  31. data/rubyspec/core/kernel/fixtures/eval_return_with_lambda.rb +12 -0
  32. data/rubyspec/core/kernel/fixtures/eval_return_without_lambda.rb +14 -0
  33. data/rubyspec/core/kernel/fixtures/test.rb +362 -0
  34. data/rubyspec/core/kernel/sleep_spec.rb +43 -0
  35. data/rubyspec/core/mutex/lock_spec.rb +8 -0
  36. data/rubyspec/core/mutex/locked_spec.rb +8 -0
  37. data/rubyspec/core/mutex/sleep_spec.rb +56 -0
  38. data/rubyspec/core/mutex/synchronize_spec.rb +8 -0
  39. data/rubyspec/core/mutex/try_lock_spec.rb +8 -0
  40. data/rubyspec/core/mutex/unlock_spec.rb +8 -0
  41. data/rubyspec/core/thread/abort_on_exception_spec.rb +126 -0
  42. data/rubyspec/core/thread/add_trace_func_spec.rb +7 -0
  43. data/rubyspec/core/thread/alive_spec.rb +60 -0
  44. data/rubyspec/core/thread/allocate_spec.rb +9 -0
  45. data/rubyspec/core/thread/backtrace_spec.rb +7 -0
  46. data/rubyspec/core/thread/critical_spec.rb +96 -0
  47. data/rubyspec/core/thread/current_spec.rb +15 -0
  48. data/rubyspec/core/thread/element_reference_spec.rb +53 -0
  49. data/rubyspec/core/thread/element_set_spec.rb +46 -0
  50. data/rubyspec/core/thread/exclusive_spec.rb +20 -0
  51. data/rubyspec/core/thread/exit_spec.rb +21 -0
  52. data/rubyspec/core/thread/fixtures/classes.rb +291 -0
  53. data/rubyspec/core/thread/fork_spec.rb +9 -0
  54. data/rubyspec/core/thread/group_spec.rb +5 -0
  55. data/rubyspec/core/thread/initialize_spec.rb +26 -0
  56. data/rubyspec/core/thread/inspect_spec.rb +48 -0
  57. data/rubyspec/core/thread/join_spec.rb +63 -0
  58. data/rubyspec/core/thread/key_spec.rb +64 -0
  59. data/rubyspec/core/thread/keys_spec.rb +47 -0
  60. data/rubyspec/core/thread/kill_spec.rb +21 -0
  61. data/rubyspec/core/thread/list_spec.rb +38 -0
  62. data/rubyspec/core/thread/main_spec.rb +10 -0
  63. data/rubyspec/core/thread/new_spec.rb +56 -0
  64. data/rubyspec/core/thread/pass_spec.rb +8 -0
  65. data/rubyspec/core/thread/priority_spec.rb +9 -0
  66. data/rubyspec/core/thread/raise_spec.rb +225 -0
  67. data/rubyspec/core/thread/run_spec.rb +9 -0
  68. data/rubyspec/core/thread/safe_level_spec.rb +6 -0
  69. data/rubyspec/core/thread/set_trace_func_spec.rb +7 -0
  70. data/rubyspec/core/thread/shared/exit.rb +173 -0
  71. data/rubyspec/core/thread/shared/start.rb +51 -0
  72. data/rubyspec/core/thread/shared/wakeup.rb +59 -0
  73. data/rubyspec/core/thread/start_spec.rb +9 -0
  74. data/rubyspec/core/thread/status_spec.rb +48 -0
  75. data/rubyspec/core/thread/stop_spec.rb +66 -0
  76. data/rubyspec/core/thread/terminate_spec.rb +11 -0
  77. data/rubyspec/core/thread/value_spec.rb +36 -0
  78. data/rubyspec/core/thread/wakeup_spec.rb +7 -0
  79. data/rubyspec/empathy_spec.rb +26 -0
  80. data/rubyspec/library/conditionvariable/broadcast_spec.rb +62 -0
  81. data/rubyspec/library/conditionvariable/signal_spec.rb +64 -0
  82. data/rubyspec/library/conditionvariable/wait_spec.rb +21 -0
  83. data/rubyspec/library/mutex/lock_spec.rb +10 -0
  84. data/rubyspec/library/mutex/locked_spec.rb +10 -0
  85. data/rubyspec/library/mutex/synchronize_spec.rb +10 -0
  86. data/rubyspec/library/mutex/try_lock_spec.rb +10 -0
  87. data/rubyspec/library/mutex/unlock_spec.rb +10 -0
  88. data/rubyspec/library/queue/append_spec.rb +7 -0
  89. data/rubyspec/library/queue/clear_spec.rb +15 -0
  90. data/rubyspec/library/queue/deq_spec.rb +7 -0
  91. data/rubyspec/library/queue/empty_spec.rb +15 -0
  92. data/rubyspec/library/queue/enq_spec.rb +7 -0
  93. data/rubyspec/library/queue/length_spec.rb +7 -0
  94. data/rubyspec/library/queue/num_waiting_spec.rb +19 -0
  95. data/rubyspec/library/queue/pop_spec.rb +7 -0
  96. data/rubyspec/library/queue/push_spec.rb +7 -0
  97. data/rubyspec/library/queue/shared/deque.rb +37 -0
  98. data/rubyspec/library/queue/shared/enque.rb +10 -0
  99. data/rubyspec/library/queue/shared/length.rb +9 -0
  100. data/rubyspec/library/queue/shift_spec.rb +7 -0
  101. data/rubyspec/library/queue/size_spec.rb +7 -0
  102. data/rubyspec/shared/kernel/raise.rb +68 -0
  103. data/rubyspec/shared/mutex/lock.rb +52 -0
  104. data/rubyspec/shared/mutex/locked.rb +31 -0
  105. data/rubyspec/shared/mutex/synchronize.rb +23 -0
  106. data/rubyspec/shared/mutex/try_lock.rb +30 -0
  107. data/rubyspec/shared/mutex/unlock.rb +35 -0
  108. data/rubyspec/spec_helper.rb +48 -0
  109. data/spec/empathy_spec.rb +129 -0
  110. data/spec/library_spec.rb +79 -0
  111. data/spec/spec_helper.rb +6 -0
  112. metadata +222 -0
@@ -0,0 +1,63 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+ require File.expand_path('../fixtures/classes', __FILE__)
3
+
4
+ describe "Thread#join" do
5
+ it "returns the thread when it is finished" do
6
+ t = Thread.new {}
7
+ t.join.should equal(t)
8
+ end
9
+
10
+ it "returns the thread when it is finished when given a timeout" do
11
+ t = Thread.new {}
12
+ t.join
13
+ t.join(0).should equal(t)
14
+ end
15
+
16
+ it "returns nil if it is not finished when given a timeout" do
17
+ c = Channel.new
18
+ t = Thread.new { c.receive }
19
+ begin
20
+ t.join(0).should == nil
21
+ ensure
22
+ c << true
23
+ end
24
+ t.join.should == t
25
+ end
26
+
27
+ it "accepts a floating point timeout length" do
28
+ c = Channel.new
29
+ t = Thread.new { c.receive }
30
+ begin
31
+ t.join(0.01).should == nil
32
+ ensure
33
+ c << true
34
+ end
35
+ t.join.should == t
36
+ end
37
+
38
+ it "raises any exceptions encountered in the thread body" do
39
+ t = Thread.new { raise NotImplementedError.new("Just kidding") }
40
+ lambda { t.join }.should raise_error(NotImplementedError)
41
+ end
42
+
43
+ it "returns the dead thread" do
44
+ t = Thread.new { Thread.current.kill }
45
+ t.join.should equal(t)
46
+ end
47
+
48
+ ruby_version_is "" ... "1.9" do
49
+ not_compliant_on :rubinius do
50
+ it "returns the dead thread even if an uncaught exception is thrown from ensure block" do
51
+ t = ThreadSpecs.dying_thread_ensures { raise "In dying thread" }
52
+ t.join.should equal(t)
53
+ end
54
+ end
55
+ end
56
+
57
+ ruby_version_is "1.9" do
58
+ it "raises any uncaught exception encountered in ensure block" do
59
+ t = ThreadSpecs.dying_thread_ensures { raise NotImplementedError.new("Just kidding") }
60
+ lambda { t.join }.should raise_error(NotImplementedError)
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,64 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+ require File.expand_path('../fixtures/classes', __FILE__)
3
+
4
+ describe "Thread#key?" do
5
+ before :each do
6
+ @th = Thread.new do
7
+ Thread.current[:oliver] = "a"
8
+ end
9
+ @th.join
10
+ end
11
+
12
+ it "tests for existance of thread local variables using symbols or strings" do
13
+ @th.key?(:oliver).should == true
14
+ @th.key?("oliver").should == true
15
+ @th.key?(:stanley).should == false
16
+ @th.key?(:stanley.to_s).should == false
17
+ end
18
+
19
+ quarantine! do
20
+ ruby_version_is ""..."1.9" do
21
+ it "raises exceptions on the wrong type of keys" do
22
+ lambda { Thread.current.key? nil }.should raise_error(TypeError)
23
+ lambda { Thread.current.key? 5 }.should raise_error(ArgumentError)
24
+ end
25
+ end
26
+ end
27
+
28
+ ruby_version_is "1.9" do
29
+ it "raises exceptions on the wrong type of keys" do
30
+ lambda { Thread.current.key? nil }.should raise_error(TypeError)
31
+ lambda { Thread.current.key? 5 }.should raise_error(TypeError)
32
+ end
33
+
34
+ it "is not shared across fibers" do
35
+ fib = Fiber.new do
36
+ Thread.current[:val1] = 1
37
+ Fiber.yield
38
+ Thread.current.key?(:val1).should be_true
39
+ Thread.current.key?(:val2).should be_false
40
+ end
41
+ Thread.current.key?(:val1).should_not be_true
42
+ fib.resume
43
+ Thread.current[:val2] = 2
44
+ fib.resume
45
+ Thread.current.key?(:val1).should be_false
46
+ Thread.current.key?(:val2).should be_true
47
+ end
48
+
49
+ it "stores a local in another thread when in a fiber" do
50
+ fib = Fiber.new do
51
+ t = Thread.new do
52
+ sleep
53
+ Thread.current.key?(:value).should be_true
54
+ end
55
+
56
+ Thread.pass while t.status and t.status != "sleep"
57
+ t[:value] = 1
58
+ t.wakeup
59
+ t.join
60
+ end
61
+ fib.resume
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,47 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+ require File.expand_path('../fixtures/classes', __FILE__)
3
+
4
+ describe "Thread#keys" do
5
+ it "returns an array of the names of the thread-local variables as symbols" do
6
+ th = Thread.new do
7
+ Thread.current["cat"] = 'woof'
8
+ Thread.current[:cat] = 'meow'
9
+ Thread.current[:dog] = 'woof'
10
+ end
11
+ th.join
12
+ th.keys.sort_by {|x| x.to_s}.should == [:cat,:dog]
13
+ end
14
+
15
+ ruby_version_is "1.9" do
16
+ it "is not shared across fibers" do
17
+ fib = Fiber.new do
18
+ Thread.current[:val1] = 1
19
+ Fiber.yield
20
+ Thread.current.keys.should include(:val1)
21
+ Thread.current.keys.should_not include(:val2)
22
+ end
23
+ Thread.current.keys.should_not include(:val1)
24
+ fib.resume
25
+ Thread.current[:val2] = 2
26
+ fib.resume
27
+ Thread.current.keys.should include(:val2)
28
+ Thread.current.keys.should_not include(:val1)
29
+ end
30
+
31
+ it "stores a local in another thread when in a fiber" do
32
+ fib = Fiber.new do
33
+ t = Thread.new do
34
+ sleep
35
+ Thread.current.keys.should include(:value)
36
+ end
37
+
38
+ Thread.pass while t.status and t.status != "sleep"
39
+ t[:value] = 1
40
+ t.wakeup
41
+ t.join
42
+ end
43
+ fib.resume
44
+ end
45
+ end
46
+
47
+ end
@@ -0,0 +1,21 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+ require File.expand_path('../fixtures/classes', __FILE__)
3
+ require File.expand_path('../shared/exit', __FILE__)
4
+
5
+ describe "Thread#kill" do
6
+ it_behaves_like :thread_exit, :kill
7
+ end
8
+
9
+ describe "Thread#kill!" do
10
+ it "needs to be reviewed for spec completeness"
11
+ end
12
+
13
+ describe "Thread.kill" do
14
+ it "causes the given thread to exit" do
15
+ thread = Thread.new { sleep }
16
+ Thread.pass while thread.status and thread.status != "sleep"
17
+ Thread.kill(thread)
18
+ thread.join
19
+ thread.status.should be_false
20
+ end
21
+ end
@@ -0,0 +1,38 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+ require File.expand_path('../fixtures/classes', __FILE__)
3
+
4
+ describe "Thread::list" do
5
+ it "includes the current and main thread" do
6
+ Thread.list.should include(Thread.current)
7
+ Thread.list.should include(Thread.main)
8
+ end
9
+
10
+ it "includes threads of non-default thread groups" do
11
+ t = Thread.new { sleep }
12
+ ThreadGroup.new.add(t)
13
+ Thread.list.should include(t)
14
+ t.kill
15
+ end
16
+
17
+ it "does not include deceased threads" do
18
+ t = Thread.new { 1; }
19
+ t.join
20
+ Thread.list.should_not include(t)
21
+ end
22
+
23
+ it "includes waiting threads" do
24
+ c = Channel.new
25
+ t = Thread.new { c.receive }
26
+ begin
27
+ Thread.pass while t.status and t.status != 'sleep'
28
+ Thread.list.should include(t)
29
+ ensure
30
+ c << nil
31
+ t.join
32
+ end
33
+ end
34
+ end
35
+
36
+ describe "Thread.list" do
37
+ it "needs to be reviewed for spec completeness"
38
+ end
@@ -0,0 +1,10 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+ require File.expand_path('../fixtures/classes', __FILE__)
3
+
4
+ describe "Thread.main" do
5
+ it "returns the main thread" do
6
+ Thread.new { @main = Thread.main ; @current = Thread.current}.join
7
+ @main.should_not == @current
8
+ @main.should == Thread.current
9
+ end
10
+ end
@@ -0,0 +1,56 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+ require File.expand_path('../fixtures/classes', __FILE__)
3
+
4
+ describe "Thread.new" do
5
+ it "creates a thread executing the given block" do
6
+ c = Channel.new
7
+ Thread.new { c << true }.join
8
+ c << false
9
+ c.receive.should == true
10
+ end
11
+
12
+ it "can pass arguments to the thread block" do
13
+ arr = []
14
+ a, b, c = 1, 2, 3
15
+ t = Thread.new(a,b,c) {|d,e,f| arr << d << e << f }
16
+ t.join
17
+ arr.should == [a,b,c]
18
+ end
19
+
20
+ it "raises an exception when not given a block" do
21
+ lambda { Thread.new }.should raise_error(ThreadError)
22
+ end
23
+
24
+ it "creates a subclass of thread calls super with a block in initialize" do
25
+ arr = []
26
+ t = ThreadSpecs::SubThread.new(arr)
27
+ t.join
28
+ arr.should == [1]
29
+ end
30
+
31
+ it "calls #initialize and raises an error if super not used" do
32
+ c = Class.new(Thread) do
33
+ def initialize
34
+ end
35
+ end
36
+
37
+ lambda {
38
+ c.new
39
+ }.should raise_error(ThreadError)
40
+ end
41
+
42
+ it "calls and respects #initialize for the block to use" do
43
+ c = Class.new(Thread) do
44
+ def initialize
45
+ ScratchPad.record [:good]
46
+ super { ScratchPad << :in_thread }
47
+ end
48
+ end
49
+
50
+ t = c.new
51
+ t.join
52
+
53
+ ScratchPad.recorded.should == [:good, :in_thread]
54
+ end
55
+
56
+ end
@@ -0,0 +1,8 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+ require File.expand_path('../fixtures/classes', __FILE__)
3
+
4
+ describe "Thread.pass" do
5
+ it "returns nil" do
6
+ Thread.pass.should == nil
7
+ end
8
+ end
@@ -0,0 +1,9 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+ require File.expand_path('../fixtures/classes', __FILE__)
3
+ describe "Thread#priority" do
4
+ it "needs to be reviewed for spec completeness"
5
+ end
6
+
7
+ describe "Thread#priority=" do
8
+ it "needs to be reviewed for spec completeness"
9
+ end
@@ -0,0 +1,225 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+ require File.expand_path('../fixtures/classes', __FILE__)
3
+ require File.expand_path('../../../shared/kernel/raise', __FILE__)
4
+
5
+ describe "Thread#raise" do
6
+ it "ignores dead threads" do
7
+ t = Thread.new { :dead }
8
+ Thread.pass while t.alive?
9
+ lambda {t.raise("Kill the thread")}.should_not raise_error
10
+ lambda {t.value}.should_not raise_error
11
+ end
12
+ end
13
+
14
+ describe "Thread#raise on a sleeping thread" do
15
+ before :each do
16
+ ScratchPad.clear
17
+ @thr = ThreadSpecs.sleeping_thread
18
+ Thread.pass while @thr.status and @thr.status != "sleep"
19
+ end
20
+
21
+ after :each do
22
+ @thr.kill
23
+ end
24
+
25
+ it "raises a RuntimeError if no exception class is given" do
26
+ @thr.raise
27
+ Thread.pass while @thr.status
28
+ ScratchPad.recorded.should be_kind_of(RuntimeError)
29
+ end
30
+
31
+ it "raises the given exception" do
32
+ @thr.raise Exception
33
+ Thread.pass while @thr.status
34
+ ScratchPad.recorded.should be_kind_of(Exception)
35
+ end
36
+
37
+ it "raises the given exception with the given message" do
38
+ @thr.raise Exception, "get to work"
39
+ Thread.pass while @thr.status
40
+ ScratchPad.recorded.should be_kind_of(Exception)
41
+ ScratchPad.recorded.message.should == "get to work"
42
+ end
43
+
44
+ it "is captured and raised by Thread#value" do
45
+ t = Thread.new do
46
+ sleep
47
+ end
48
+
49
+ ThreadSpecs.spin_until_sleeping(t)
50
+
51
+ t.raise
52
+ lambda { t.value }.should raise_error(RuntimeError)
53
+ end
54
+
55
+ ruby_version_is "" ... "1.9" do
56
+ it "raises a ZeroDivisionError when called with no arguments inside rescue" do
57
+ t = Thread.new do
58
+ begin
59
+ 1/0
60
+ rescue ZeroDivisionError
61
+ sleep
62
+ end
63
+ end
64
+ begin
65
+ raise RangeError
66
+ rescue
67
+ ThreadSpecs.spin_until_sleeping(t)
68
+ t.raise
69
+ end
70
+ lambda {t.value}.should raise_error(ZeroDivisionError)
71
+ end
72
+ end
73
+
74
+ ruby_version_is "1.9" do
75
+ it "raises a RuntimeError when called with no arguments inside rescue" do
76
+ t = Thread.new do
77
+ begin
78
+ 1/0
79
+ rescue ZeroDivisionError
80
+ sleep
81
+ end
82
+ end
83
+ begin
84
+ raise RangeError
85
+ rescue
86
+ ThreadSpecs.spin_until_sleeping(t)
87
+ t.raise
88
+ end
89
+ lambda {t.value}.should raise_error(RuntimeError)
90
+ end
91
+ end
92
+ end
93
+
94
+ describe "Thread#raise on a running thread" do
95
+ before :each do
96
+ ScratchPad.clear
97
+ ThreadSpecs.clear_state
98
+
99
+ @thr = ThreadSpecs.running_thread
100
+ Thread.pass until ThreadSpecs.state == :running
101
+ end
102
+
103
+ after :each do
104
+ @thr.kill
105
+ end
106
+
107
+ it "raises a RuntimeError if no exception class is given" do
108
+ @thr.raise
109
+ Thread.pass while @thr.status
110
+ ScratchPad.recorded.should be_kind_of(RuntimeError)
111
+ end
112
+
113
+ it "raises the given exception" do
114
+ @thr.raise Exception
115
+ Thread.pass while @thr.status
116
+ ScratchPad.recorded.should be_kind_of(Exception)
117
+ end
118
+
119
+ it "raises the given exception with the given message" do
120
+ @thr.raise Exception, "get to work"
121
+ Thread.pass while @thr.status
122
+ ScratchPad.recorded.should be_kind_of(Exception)
123
+ ScratchPad.recorded.message.should == "get to work"
124
+ end
125
+
126
+ it "can go unhandled" do
127
+ t = Thread.new do
128
+ loop {}
129
+ end
130
+
131
+ t.raise
132
+ lambda {t.value}.should raise_error(RuntimeError)
133
+ end
134
+
135
+ it "raise the given argument even when there is an active exception" do
136
+ raised = false
137
+ t = Thread.new do
138
+ begin
139
+ 1/0
140
+ rescue ZeroDivisionError
141
+ raised = true
142
+ loop { }
143
+ end
144
+ end
145
+ begin
146
+ raise "Create an active exception for the current thread too"
147
+ rescue
148
+ Thread.pass until raised
149
+ t.raise RangeError
150
+ lambda {t.value}.should raise_error(RangeError)
151
+ end
152
+ end
153
+
154
+ ruby_version_is "" ... "1.9" do
155
+ it "raises a ZeroDivisionError when called with no arguments inside rescue" do
156
+ raised = false
157
+ t = Thread.new do
158
+ begin
159
+ 1/0
160
+ rescue ZeroDivisionError
161
+ raised = true
162
+ loop { }
163
+ end
164
+ end
165
+ begin
166
+ raise RangeError
167
+ rescue
168
+ Thread.pass until raised
169
+ t.raise
170
+ end
171
+ lambda {t.value}.should raise_error(ZeroDivisionError)
172
+ end
173
+ end
174
+
175
+ ruby_version_is "1.9" do
176
+ it "raises a RuntimeError when called with no arguments inside rescue" do
177
+ raised = false
178
+ t = Thread.new do
179
+ begin
180
+ 1/0
181
+ rescue ZeroDivisionError
182
+ raised = true
183
+ loop { }
184
+ end
185
+ end
186
+ begin
187
+ raise RangeError
188
+ rescue
189
+ Thread.pass until raised
190
+ t.raise
191
+ end
192
+ lambda {t.value}.should raise_error(RuntimeError)
193
+ end
194
+ end
195
+ end
196
+
197
+ describe "Thread#raise on same thread" do
198
+ it_behaves_like :kernel_raise, :raise, Thread.current
199
+
200
+ ruby_version_is "" ... "1.9" do
201
+ it "raises a ZeroDivisionError when called with no arguments inside rescue" do
202
+ t = Thread.new do
203
+ begin
204
+ 1/0
205
+ rescue ZeroDivisionError
206
+ Thread.current.raise
207
+ end
208
+ end
209
+ lambda {t.value}.should raise_error(ZeroDivisionError)
210
+ end
211
+ end
212
+
213
+ ruby_version_is "1.9" do
214
+ it "raises a RuntimeError when called with no arguments inside rescue" do
215
+ t = Thread.new do
216
+ begin
217
+ 1/0
218
+ rescue ZeroDivisionError
219
+ Thread.current.raise
220
+ end
221
+ end
222
+ lambda {t.value}.should raise_error(RuntimeError)
223
+ end
224
+ end
225
+ end