|
1 | 1 | require_relative '../../spec_helper'
|
2 | 2 |
|
3 |
| -platform_is_not :windows do |
4 |
| - describe "Signal.trap" do |
| 3 | +describe "Signal.trap" do |
| 4 | + platform_is_not :windows do |
5 | 5 | before :each do
|
6 | 6 | ScratchPad.clear
|
7 | 7 | @proc = -> {}
|
8 | 8 | @saved_trap = Signal.trap(:HUP, @proc)
|
| 9 | + @hup_number = Signal.list["HUP"] |
9 | 10 | end
|
10 | 11 |
|
11 | 12 | after :each do
|
|
16 | 17 | Signal.trap(:HUP, @saved_trap).should equal(@proc)
|
17 | 18 | end
|
18 | 19 |
|
19 |
| - it "accepts a block in place of a proc/command argument" do |
| 20 | + it "accepts a block" do |
20 | 21 | done = false
|
21 | 22 |
|
22 |
| - Signal.trap(:HUP) do |
| 23 | + Signal.trap(:HUP) do |signo| |
| 24 | + signo.should == @hup_number |
23 | 25 | ScratchPad.record :block_trap
|
24 | 26 | done = true
|
25 | 27 | end
|
|
30 | 32 | ScratchPad.recorded.should == :block_trap
|
31 | 33 | end
|
32 | 34 |
|
| 35 | + it "accepts a proc" do |
| 36 | + done = false |
| 37 | + |
| 38 | + handler = ->(signo) { |
| 39 | + signo.should == @hup_number |
| 40 | + ScratchPad.record :proc_trap |
| 41 | + done = true |
| 42 | + } |
| 43 | + |
| 44 | + Signal.trap(:HUP, handler) |
| 45 | + |
| 46 | + Process.kill :HUP, Process.pid |
| 47 | + Thread.pass until done |
| 48 | + |
| 49 | + ScratchPad.recorded.should == :proc_trap |
| 50 | + end |
| 51 | + |
| 52 | + it "accepts a method" do |
| 53 | + done = false |
| 54 | + |
| 55 | + handler_class = Class.new |
| 56 | + hup_number = @hup_number |
| 57 | + |
| 58 | + handler_class.define_method :handler_method do |signo| |
| 59 | + signo.should == hup_number |
| 60 | + ScratchPad.record :method_trap |
| 61 | + done = true |
| 62 | + end |
| 63 | + |
| 64 | + handler_method = handler_class.new.method(:handler_method) |
| 65 | + |
| 66 | + Signal.trap(:HUP, handler_method) |
| 67 | + |
| 68 | + Process.kill :HUP, Process.pid |
| 69 | + Thread.pass until done |
| 70 | + |
| 71 | + ScratchPad.recorded.should == :method_trap |
| 72 | + end |
| 73 | + |
| 74 | + it "accepts anything you can call" do |
| 75 | + done = false |
| 76 | + |
| 77 | + callable = Object.new |
| 78 | + hup_number = @hup_number |
| 79 | + |
| 80 | + callable.singleton_class.define_method :call do |signo| |
| 81 | + signo.should == hup_number |
| 82 | + ScratchPad.record :callable_trap |
| 83 | + done = true |
| 84 | + end |
| 85 | + |
| 86 | + Signal.trap(:HUP, callable) |
| 87 | + |
| 88 | + Process.kill :HUP, Process.pid |
| 89 | + Thread.pass until done |
| 90 | + |
| 91 | + ScratchPad.recorded.should == :callable_trap |
| 92 | + end |
| 93 | + |
| 94 | + it "raises an exception for a non-callable at the point of use" do |
| 95 | + not_callable = Object.new |
| 96 | + Signal.trap(:HUP, not_callable) |
| 97 | + -> { |
| 98 | + Process.kill :HUP, Process.pid |
| 99 | + loop { Thread.pass } |
| 100 | + }.should raise_error(NoMethodError) |
| 101 | + end |
| 102 | + |
| 103 | + it "accepts a non-callable that becomes callable when used" do |
| 104 | + done = false |
| 105 | + |
| 106 | + late_callable = Object.new |
| 107 | + hup_number = @hup_number |
| 108 | + |
| 109 | + Signal.trap(:HUP, late_callable) |
| 110 | + |
| 111 | + late_callable.singleton_class.define_method :call do |signo| |
| 112 | + signo.should == hup_number |
| 113 | + ScratchPad.record :late_callable_trap |
| 114 | + done = true |
| 115 | + end |
| 116 | + |
| 117 | + Process.kill :HUP, Process.pid |
| 118 | + Thread.pass until done |
| 119 | + |
| 120 | + ScratchPad.recorded.should == :late_callable_trap |
| 121 | + end |
| 122 | + |
33 | 123 | it "is possible to create a new Thread when the handler runs" do
|
34 | 124 | done = false
|
35 | 125 |
|
|
130 | 220 | Signal.trap :HUP, @proc
|
131 | 221 | Signal.trap(:HUP, @saved_trap).should equal(@proc)
|
132 | 222 | end
|
133 |
| - end |
134 | 223 |
|
135 |
| - describe "Signal.trap" do |
136 | 224 | # See man 2 signal
|
137 | 225 | %w[KILL STOP].each do |signal|
|
138 | 226 | it "raises ArgumentError or Errno::EINVAL for SIG#{signal}" do
|
139 | 227 | -> {
|
140 |
| - trap(signal, -> {}) |
| 228 | + Signal.trap(signal, -> {}) |
141 | 229 | }.should raise_error(StandardError) { |e|
|
142 | 230 | [ArgumentError, Errno::EINVAL].should include(e.class)
|
143 | 231 | e.message.should =~ /Invalid argument|Signal already used by VM or OS/
|
|
152 | 240 | end
|
153 | 241 |
|
154 | 242 | it "returns 'DEFAULT' for the initial SIGINT handler" do
|
155 |
| - ruby_exe('print trap(:INT) { abort }').should == 'DEFAULT' |
| 243 | + ruby_exe("print Signal.trap(:INT) { abort }").should == 'DEFAULT' |
156 | 244 | end
|
157 | 245 |
|
158 | 246 | it "returns SYSTEM_DEFAULT if passed DEFAULT and no handler was ever set" do
|
|
174 | 262 | Signal.signame(status.termsig).should == "PIPE"
|
175 | 263 | end
|
176 | 264 | end
|
177 |
| -end |
178 | 265 |
|
179 |
| -describe "Signal.trap" do |
180 | 266 | describe "the special EXIT signal code" do
|
181 | 267 | it "accepts the EXIT code" do
|
182 |
| - code = "trap(:EXIT, proc { print 1 })" |
| 268 | + code = "Signal.trap(:EXIT, proc { print 1 })" |
183 | 269 | ruby_exe(code).should == "1"
|
184 | 270 | end
|
185 | 271 |
|
186 | 272 | it "runs the proc before at_exit handlers" do
|
187 |
| - code = "at_exit {print 1}; trap(:EXIT, proc {print 2}); at_exit {print 3}" |
| 273 | + code = "at_exit {print 1}; Signal.trap(:EXIT, proc {print 2}); at_exit {print 3}" |
188 | 274 | ruby_exe(code).should == "231"
|
189 | 275 | end
|
190 | 276 |
|
191 | 277 | it "can unset the handler" do
|
192 |
| - code = "trap(:EXIT, proc { print 1 }); trap(:EXIT, 'DEFAULT')" |
| 278 | + code = "Signal.trap(:EXIT, proc { print 1 }); Signal.trap(:EXIT, 'DEFAULT')" |
193 | 279 | ruby_exe(code).should == ""
|
194 | 280 | end
|
195 | 281 | end
|
| 282 | + |
196 | 283 | end
|
0 commit comments