empathy 0.0.1.RC0

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