utilrb 1.6.6 → 2.0

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 (51) hide show
  1. data/Manifest.txt +10 -9
  2. data/README.rd +23 -0
  3. data/Rakefile +40 -37
  4. data/ext/utilrb/extconf.rb +36 -0
  5. data/ext/{proc.cc → utilrb/proc.c} +7 -6
  6. data/ext/utilrb/ruby_allocator.hh +76 -0
  7. data/ext/{ruby_internals-1.8.h → utilrb/ruby_internals-1.8.h} +0 -0
  8. data/ext/{ruby_internals-1.9.h → utilrb/ruby_internals-1.9.h} +0 -0
  9. data/ext/{swap.cc → utilrb/swap.cc} +0 -0
  10. data/ext/utilrb/utilrb.cc +79 -0
  11. data/ext/{value_set.cc → utilrb/value_set.cc} +5 -5
  12. data/ext/{weakref.cc → utilrb/weakref.cc} +0 -0
  13. data/lib/utilrb/common.rb +7 -2
  14. data/lib/utilrb/doc/rake.rb +46 -15
  15. data/lib/utilrb/kernel/load_dsl_file.rb +2 -2
  16. data/lib/utilrb/kernel/options.rb +6 -0
  17. data/lib/utilrb/logger/forward.rb +7 -0
  18. data/lib/utilrb/logger/hierarchy.rb +100 -42
  19. data/lib/utilrb/logger/indent.rb +38 -3
  20. data/lib/utilrb/logger/log_pp.rb +1 -1
  21. data/lib/utilrb/logger/root.rb +27 -12
  22. data/lib/utilrb/module/inherited_enumerable.rb +2 -196
  23. data/lib/utilrb/objectstats.rb +4 -1
  24. data/lib/utilrb/pkgconfig.rb +42 -6
  25. data/lib/utilrb/rake_common.rb +12 -0
  26. data/lib/utilrb/ruby_object_graph.rb +195 -46
  27. data/lib/utilrb/yard.rb +89 -89
  28. data/test/test_array.rb +1 -1
  29. data/test/test_dir.rb +1 -1
  30. data/test/test_enumerable.rb +7 -1
  31. data/test/test_event_loop.rb +407 -0
  32. data/test/test_exception.rb +1 -1
  33. data/test/test_gc.rb +1 -1
  34. data/test/test_hash.rb +57 -1
  35. data/test/test_kernel.rb +52 -21
  36. data/test/test_logger.rb +150 -1
  37. data/test/test_misc.rb +1 -1
  38. data/test/test_models.rb +212 -0
  39. data/test/test_module.rb +41 -71
  40. data/test/test_object.rb +1 -1
  41. data/test/test_objectstats.rb +1 -1
  42. data/test/test_pkgconfig.rb +7 -5
  43. data/test/test_proc.rb +1 -1
  44. data/test/test_set.rb +1 -1
  45. data/test/test_thread_pool.rb +409 -0
  46. data/test/test_time.rb +6 -6
  47. data/test/test_unbound_method.rb +1 -1
  48. metadata +157 -131
  49. data/README.txt +0 -45
  50. data/ext/extconf.rb +0 -29
  51. data/ext/utilrb_ext.cc +0 -144
data/lib/utilrb/yard.rb CHANGED
@@ -2,93 +2,11 @@ require 'pp'
2
2
  module Utilrb
3
3
  module YARD
4
4
  include ::YARD
5
- class InheritedEnumerableHandler < YARD::Handlers::Ruby::AttributeHandler
6
- handles method_call(:inherited_enumerable)
5
+ class InheritedAttributeHandler < YARD::Handlers::Ruby::AttributeHandler
6
+ handles method_call(:inherited_attribute)
7
7
  namespace_only
8
8
 
9
9
  def self.process(handler, name, attr_name, is_map, key_name = nil, return_type = nil)
10
- key_type, value_type = nil
11
- handler.send(:push_state, :scope => :class) do
12
- namespace = handler.send(:namespace)
13
- scope = handler.send(:scope)
14
-
15
- object = YARD::CodeObjects::MethodObject.new(namespace, attr_name, scope) do |o|
16
- o.dynamic = true
17
- o.aliases << "self_#{name}"
18
- end
19
- handler.send(:register, object)
20
- key_name ||=
21
- if object.docstring.has_tag?('key_name')
22
- object.docstring.tag('key_name').text
23
- else
24
- 'key'
25
- end
26
- return_type ||=
27
- if object.docstring.has_tag?('return')
28
- object.docstring.tag('return').types.first
29
- elsif is_map
30
- 'Hash<Object,Object>'
31
- else
32
- 'Array<Object>'
33
- end
34
- if return_type =~ /^\w+\<(.*)\>$/
35
- if is_map
36
- key_type, value_type = $1.split(',')
37
- else
38
- value_type = $1
39
- end
40
- else
41
- key_type = "Object"
42
- value_type = "Object"
43
- end
44
-
45
- object = YARD::CodeObjects::MethodObject.new(namespace, "all_#{name}", scope)
46
- object.dynamic = true
47
- handler.send(:register, object)
48
- object.docstring.replace("The union, along the class hierarchy, of all the values stored in #{name}\n@return [Array<#{value_type}>]")
49
-
50
- if is_map
51
- object = YARD::CodeObjects::MethodObject.new(namespace, "find_#{name}", scope)
52
- object.dynamic = true
53
- handler.send(:register, object)
54
- object.parameters << [key_name]
55
- object.docstring.replace("Looks for objects registered in #{name} under the given key, and returns the first one in the ancestor chain (i.e. the one tha thas been registered in the most specialized class)\n@return [#{value_type},nil] the found object, or nil if none is registered under that key")
56
-
57
- object = YARD::CodeObjects::MethodObject.new(namespace, "has_#{name}?", scope)
58
- object.dynamic = true
59
- handler.send(:register, object)
60
- object.parameters << [key_name]
61
- object.docstring.replace("Returns true if an object is registered in #{name} anywhere in the class hierarchy\n@return [Boolean]")
62
- object.signature = "def has_#{name}?(key)"
63
-
64
- object = YARD::CodeObjects::MethodObject.new(namespace, "each_#{name}", scope)
65
- object.dynamic = true
66
- handler.send(:register, object)
67
- object.parameters << [key_name, "nil"] << ["uniq", "true"]
68
- object.docstring.replace("
69
- @overload each_#{name}(#{key_name}, uniq = true)
70
- Enumerates all objects registered in #{name} under the given key
71
- @yield [element]
72
- @yieldparam [#{value_type}] element
73
- @overload each_#{name}(nil, uniq = true)
74
- Enumerates all objects registered in #{name}
75
- @yield [#{key_name}, element]
76
- @yieldparam [#{key_type}] #{key_name}
77
- @yieldparam [#{value_type}] element
78
- ")
79
- else
80
- object = YARD::CodeObjects::MethodObject.new(namespace, "each_#{name}", scope)
81
- object.dynamic = true
82
- handler.send(:register, object)
83
- object.docstring.replace("Enumerates all objects registered in #{name}\n@return []\n@yield [element]\n@yieldparam [#{value_type}] element")
84
- end
85
- end
86
-
87
- if is_map
88
- return key_type, value_type
89
- else
90
- return value_type
91
- end
92
10
  end
93
11
 
94
12
  def process
@@ -109,10 +27,91 @@ module Utilrb
109
27
  end
110
28
  end
111
29
 
112
- self.class.process(self, name, attr_name, is_map)
30
+ key_type, value_type = nil
31
+
32
+ object = YARD::CodeObjects::MethodObject.new(namespace, attr_name, scope) do |o|
33
+ o.dynamic = true
34
+ o.aliases << "self_#{name}"
35
+ end
36
+ register(object)
37
+ key_name ||=
38
+ if object.docstring.has_tag?('key_name')
39
+ object.docstring.tag('key_name').text
40
+ else
41
+ 'key'
42
+ end
43
+ return_type ||=
44
+ if object.docstring.has_tag?('return')
45
+ object.docstring.tag('return').types.first
46
+ elsif is_map
47
+ 'Hash<Object,Object>'
48
+ else
49
+ 'Array<Object>'
50
+ end
51
+ if return_type =~ /^\w+\<(.*)\>$/
52
+ if is_map
53
+ key_type, value_type = $1.split(',')
54
+ else
55
+ value_type = $1
56
+ end
57
+ else
58
+ key_type = "Object"
59
+ value_type = "Object"
60
+ end
61
+
62
+ object = YARD::CodeObjects::MethodObject.new(namespace, "all_#{name}", scope)
63
+ object.dynamic = true
64
+ register(object)
65
+ object.docstring.replace("The union, along the class hierarchy, of all the values stored in #{name}\n@return [Array<#{value_type}>]")
66
+
67
+ if is_map
68
+ object = YARD::CodeObjects::MethodObject.new(namespace, "find_#{name}", scope)
69
+ object.dynamic = true
70
+ register(object)
71
+ object.parameters << [key_name]
72
+ object.docstring.replace("
73
+ Looks for objects registered in #{name} under the given key, and returns the first one in the ancestor chain
74
+ (i.e. the one tha thas been registered in the most specialized class)
75
+
76
+ @return [#{value_type},nil] the found object, or nil if none is registered under that key")
77
+
78
+ object = YARD::CodeObjects::MethodObject.new(namespace, "has_#{name}?", scope)
79
+ object.dynamic = true
80
+ register(object)
81
+ object.parameters << [key_name]
82
+ object.docstring.replace("Returns true if an object is registered in #{name} anywhere in the class hierarchy\n@return [Boolean]")
83
+ object.signature = "def has_#{name}?(key)"
84
+
85
+ object = YARD::CodeObjects::MethodObject.new(namespace, "each_#{name}", scope)
86
+ object.dynamic = true
87
+ register(object)
88
+ object.parameters << [key_name, "nil"] << ["uniq", "true"]
89
+ object.docstring.replace("
90
+ @overload each_#{name}(#{key_name}, uniq = true)
91
+ Enumerates all objects registered in #{name} under the given key
92
+ @yield [element]
93
+ @yieldparam [#{value_type}] element
94
+ @overload each_#{name}(nil, uniq = true)
95
+ Enumerates all objects registered in #{name}
96
+ @yield [#{key_name}, element]
97
+ @yieldparam [#{key_type}] #{key_name}
98
+ @yieldparam [#{value_type}] element
99
+ ")
100
+ else
101
+ object = YARD::CodeObjects::MethodObject.new(namespace, "each_#{name}", scope)
102
+ object.dynamic = true
103
+ register(object)
104
+ object.docstring.replace("Enumerates all objects registered in #{name}\n@return []\n@yield [element]\n@yieldparam [#{value_type}] element")
105
+ end
106
+
107
+ if is_map
108
+ return key_type, value_type
109
+ else
110
+ return value_type
111
+ end
113
112
  end
114
113
  end
115
- YARD::Tags::Library.define_tag("Key for inherited_enumerable(_, :map => true)", :key_name)
114
+ YARD::Tags::Library.define_tag("Key for inherited_attribute(_, :map => true)", :key_name)
116
115
 
117
116
  class AttrEnumerableHandler < YARD::Handlers::Ruby::AttributeHandler
118
117
  handles method_call(:attr_enumerable)
@@ -153,14 +152,15 @@ module Utilrb
153
152
  object = YARD::CodeObjects::MethodObject.new(namespace, pname, scope)
154
153
  object.dynamic = true
155
154
  register(object)
156
- object.docstring.create_tag("return", "[Boolean]")
155
+ object.docstring.add_tag(YARD::Tags::Tag.new(:return, nil, ['Boolean']))
157
156
  if rw
158
157
  object = YARD::CodeObjects::MethodObject.new(namespace, wname, scope)
159
158
  object.dynamic = true
160
159
  object.parameters << ["value", nil]
161
160
  object.signature
162
- object.docstring.create_tag("param", "[Boolean] value")
163
- object.docstring.create_tag("return", "[Boolean]")
161
+ object.docstring.add_tag(YARD::Tags::Tag.new(:param, 'value', ['Boolean'], nil))
162
+ object.docstring.add_tag(YARD::Tags::Tag.new(:return, nil, ['Boolean'], nil))
163
+ register(object)
164
164
  end
165
165
  end
166
166
  end
data/test/test_array.rb CHANGED
@@ -1,4 +1,4 @@
1
- require 'test_config'
1
+ require 'test/test_config'
2
2
  require 'utilrb/array'
3
3
 
4
4
  class TC_Array < Test::Unit::TestCase
data/test/test_dir.rb CHANGED
@@ -1,4 +1,4 @@
1
- require 'test_config'
1
+ require 'test/test_config'
2
2
 
3
3
  require 'utilrb/dir'
4
4
  require 'enumerator'
@@ -1,4 +1,4 @@
1
- require 'test_config'
1
+ require 'test/test_config'
2
2
 
3
3
  require 'utilrb/enumerable'
4
4
  require 'utilrb/value_set'
@@ -93,6 +93,12 @@ class TC_Enumerable < Test::Unit::TestCase
93
93
  assert_equal([1,3,5].to_value_set, [1, 2, 3, 4, 5, 6].to_value_set.delete_if { |v| v % 2 == 0 })
94
94
  end
95
95
 
96
+ def test_value_set_hash
97
+ a = [(obj = Object.new), 3, 4, [(obj2 = Object.new), Hash.new]].to_value_set
98
+ b = [obj, 3, 4, [obj2, Hash.new]].to_value_set
99
+ assert_equal a.hash, b.hash
100
+ end
101
+
96
102
  def test_value_set_to_s
97
103
  obj = ValueSet.new
98
104
  obj << 1
@@ -0,0 +1,407 @@
1
+ require 'test/test_config'
2
+ require 'utilrb/event_loop'
3
+ require 'minitest/spec'
4
+
5
+ MiniTest::Unit.autorun
6
+
7
+ describe Utilrb::EventLoop::Forwardable do
8
+ class Dummy
9
+ def test(wait)
10
+ sleep wait
11
+ Thread.current
12
+ end
13
+
14
+ def error
15
+ raise
16
+ end
17
+ end
18
+
19
+ class DummyAsync
20
+ extend Utilrb::EventLoop::Forwardable
21
+ def_event_loop_delegator :@obj,:@event_loop,:test,:alias => :atest
22
+ def_event_loop_delegators :@obj,:@event_loop,[:bla1,:bla2]
23
+ def_event_loop_delegator :@obj,:@event_loop,:error,:on_error => :on_error2,:known_errors => RuntimeError
24
+
25
+ forward_to :@obj, :@event_loop do
26
+ thread_safe do
27
+ def_delegators :bla3,:bla4
28
+ end
29
+ def_delegators :bla5
30
+ end
31
+
32
+ attr_accessor :last_error
33
+
34
+ def initialize(event_loop,obj = Dummy.new)
35
+ @event_loop = event_loop
36
+ @obj = obj
37
+ end
38
+
39
+ def on_error2(error)
40
+ @last_error = error
41
+ end
42
+
43
+ end
44
+
45
+ class DummyAsyncFilter
46
+ extend Utilrb::EventLoop::Forwardable
47
+
48
+ def do_not_overwrite
49
+ 222
50
+ end
51
+
52
+ def_event_loop_delegator :@obj,:@event_loop,:test,:alias => :atest2
53
+ def_event_loop_delegator :@obj,:@event_loop,:test,:alias => :atest,:filter => :test_filter
54
+ def_event_loop_delegator :@obj,:@event_loop,:test,:alias => :do_not_overwrite
55
+
56
+ def initialize(event_loop,obj = Dummy.new)
57
+ @event_loop = event_loop
58
+ @obj = obj
59
+ end
60
+
61
+ # the result is always returned as array to check
62
+ # that the filer is working
63
+ def test_filter(result)
64
+ [result,result]
65
+ end
66
+ end
67
+
68
+ describe "when a class is extend but the designated object is nil" do
69
+ it "must raise if a method call is delegated." do
70
+ event_loop = Utilrb::EventLoop.new
71
+ obj = DummyAsync.new(event_loop,nil)
72
+ assert_raises Utilrb::EventLoop::Forwardable::DesignatedObjectNotFound do
73
+ obj.atest(0.1)
74
+ end
75
+ assert_raises Utilrb::EventLoop::Forwardable::DesignatedObjectNotFound do
76
+ obj.atest(0.1) do |_|
77
+ end
78
+ sleep 0.1
79
+ event_loop.step
80
+ end
81
+ end
82
+
83
+ it "must raise if a method call is delegated but the underlying object is nil." do
84
+ event_loop = Utilrb::EventLoop.new
85
+ obj = DummyAsyncFilter.new(event_loop,nil)
86
+ assert_raises Utilrb::EventLoop::Forwardable::DesignatedObjectNotFound do
87
+ obj.atest(0.1)
88
+ end
89
+ end
90
+ end
91
+
92
+ describe "when a class is extend" do
93
+ it "must delegate the method call directly to the real object." do
94
+ event_loop = Utilrb::EventLoop.new
95
+ obj = DummyAsyncFilter.new(event_loop)
96
+ assert_equal Thread.current,obj.atest(0.1).first
97
+ end
98
+
99
+ it 'must call the error callback' do
100
+ event_loop = Utilrb::EventLoop.new
101
+ obj = DummyAsync.new(event_loop)
102
+ assert_raises RuntimeError do
103
+ obj.error
104
+ end
105
+ obj.last_error.must_be_instance_of RuntimeError
106
+ obj.last_error = nil
107
+ error = nil
108
+ obj.error do |_,e|
109
+ error = e
110
+ end
111
+ sleep 0.1
112
+ event_loop.step
113
+ error.must_be_instance_of RuntimeError
114
+ obj.last_error.must_be_instance_of RuntimeError
115
+ end
116
+
117
+ it 'must not overwrite instance methods' do
118
+ event_loop = Utilrb::EventLoop.new
119
+ obj = DummyAsyncFilter.new(event_loop)
120
+ assert_equal 222,obj.do_not_overwrite
121
+ end
122
+
123
+ it "must defer the method call to a thread pool if a block is given." do
124
+ event_loop = Utilrb::EventLoop.new
125
+ obj = DummyAsync.new(event_loop)
126
+ thread = nil
127
+ task = obj.atest(0.05) do |result|
128
+ thread = result
129
+ end
130
+ assert_equal Utilrb::ThreadPool::Task,task.class
131
+ sleep 0.1
132
+ event_loop.step
133
+ assert task.successfull?
134
+ assert thread != Thread.current
135
+ end
136
+ end
137
+ end
138
+
139
+ describe Utilrb::EventLoop do
140
+ describe "when executed" do
141
+ it "must call the timers at the right point in time." do
142
+ event_loop = Utilrb::EventLoop.new
143
+ val1 = nil
144
+ val2 = nil
145
+ val3 = nil
146
+ timer1 = event_loop.every 0.1 do
147
+ val1 = 123
148
+ end
149
+ timer2 = event_loop.every 0.2 do
150
+ val2 = 345
151
+ end
152
+ event_loop.once 0.3 do
153
+ val3 = 444
154
+ end
155
+
156
+ time = Time.now
157
+ while Time.now - time < 0.101
158
+ event_loop.step
159
+ end
160
+ event_loop.steps
161
+ assert_equal 123,val1
162
+ assert_equal nil,val2
163
+ assert_equal nil,val3
164
+ val1 = nil
165
+
166
+ time = Time.now
167
+ while Time.now - time < 0.101
168
+ event_loop.step
169
+ end
170
+ assert_equal 123,val1
171
+ assert_equal 345,val2
172
+ assert_equal nil,val3
173
+
174
+ time = Time.now
175
+ while Time.now - time < 0.101
176
+ event_loop.step
177
+ end
178
+ assert_equal 444,val3
179
+ event_loop.clear
180
+ end
181
+
182
+ it 'must call a given block for every step' do
183
+ event_loop = Utilrb::EventLoop.new
184
+ val = nil
185
+ event_loop.every_step do
186
+ val = 123
187
+ end
188
+ event_loop.step
189
+ assert_equal 123,val
190
+ val = nil
191
+ event_loop.step
192
+ assert_equal 123,val
193
+ val = nil
194
+ event_loop.step
195
+ assert_equal 123,val
196
+ end
197
+
198
+ it "must be able to start and stop timers." do
199
+ event_loop = Utilrb::EventLoop.new
200
+ val1 = nil
201
+ val2 = nil
202
+ timer1 = event_loop.every 0.1 do
203
+ val1 = 123
204
+ end
205
+ assert timer1.running?
206
+ timer2 = event_loop.every 0.2 do
207
+ val2 = 345
208
+ end
209
+ assert timer2.running?
210
+
211
+ timer1.cancel
212
+ assert !timer1.running?
213
+ time = Time.now
214
+ event_loop.wait_for do
215
+ Time.now - time >= 0.22
216
+ end
217
+ assert_equal nil,val1
218
+ assert_equal 345,val2
219
+ val2 = nil
220
+ timer1.start
221
+ timer2.cancel
222
+
223
+ time = Time.now
224
+ while Time.now - time < 0.201
225
+ event_loop.step
226
+ end
227
+ assert_equal 123,val1
228
+ assert_equal nil,val2
229
+ end
230
+
231
+ it "must defer blocking calls to a thread pool" do
232
+ event_loop = Utilrb::EventLoop.new
233
+ main_thread = Thread.current
234
+ val = nil
235
+ val2 = nil
236
+ callback = Proc.new do |result|
237
+ assert_equal main_thread,Thread.current
238
+ assert main_thread != result
239
+ val = result
240
+ end
241
+ event_loop.defer({:callback => callback},123,333) do |a,b|
242
+ assert_equal 123,a
243
+ assert_equal 333,b
244
+ sleep 0.2
245
+ assert main_thread != Thread.current
246
+ val2 = Thread.current
247
+ end
248
+ sleep 0.1
249
+ event_loop.step
250
+ assert !val
251
+
252
+ sleep 0.11
253
+ event_loop.step
254
+ assert val
255
+ assert_equal val,val2
256
+ end
257
+ it "must peridically defer blocking calls to a thread pool" do
258
+ event_loop = Utilrb::EventLoop.new
259
+ main_thread = Thread.current
260
+ work = Proc.new do
261
+ Thread.current
262
+ end
263
+ val = nil
264
+ event_loop.async_every work,:period => 0.1 do |result,e|
265
+ val = result
266
+ end
267
+ sleep 0.11
268
+ event_loop.step
269
+ assert !val
270
+ sleep 0.01
271
+ event_loop.step
272
+ assert val
273
+ assert val != main_thread
274
+ val = nil
275
+
276
+ sleep 0.11
277
+ event_loop.step
278
+ sleep 0.01
279
+ event_loop.step
280
+ assert val
281
+ assert val != main_thread
282
+ end
283
+
284
+ it 'must be able to overwrite an error' do
285
+ event_loop = Utilrb::EventLoop.new
286
+ work = Proc.new do
287
+ raise ArgumentError
288
+ end
289
+ event_loop.async work do |r,e|
290
+ if e
291
+ RuntimeError.new
292
+ end
293
+ end
294
+ sleep 0.1
295
+ assert_raises RuntimeError do
296
+ event_loop.step
297
+ end
298
+ end
299
+
300
+ it 'must be able to ignore an error' do
301
+ event_loop = Utilrb::EventLoop.new
302
+ work = Proc.new do
303
+ raise ArgumentError
304
+ end
305
+ event_loop.async work do |r,e|
306
+ if e
307
+ :ignore_error
308
+ end
309
+ end
310
+ sleep 0.1
311
+ event_loop.step
312
+ end
313
+
314
+ it 'must inform on_error block in an event of an error' do
315
+ event_loop = Utilrb::EventLoop.new
316
+ error = nil
317
+ event_loop.on_error ArgumentError do |e|
318
+ error = e
319
+ end
320
+
321
+ #check super class
322
+ error2 = nil
323
+ event_loop.on_error Exception do |e|
324
+ error2 = e
325
+ end
326
+ work = Proc.new do
327
+ raise ArgumentError
328
+ end
329
+ event_loop.async_with_options work, :default => :default_value,:known_errors => ArgumentError do |r,e|
330
+ end
331
+ sleep 0.1
332
+ event_loop.step
333
+ assert error
334
+ assert error2
335
+ end
336
+
337
+ it 'must re-raise an error' do
338
+ event_loop = Utilrb::EventLoop.new
339
+ event_loop.once do
340
+ raise ArgumentError
341
+ end
342
+ event_loop.once do
343
+ raise ArgumentError
344
+ end
345
+ event_loop.once do
346
+ raise ArgumentError
347
+ end
348
+ assert_raises ArgumentError do
349
+ event_loop.step
350
+ end
351
+ assert_raises ArgumentError do
352
+ event_loop.step
353
+ end
354
+ event_loop.clear_errors
355
+ event_loop.step
356
+
357
+ event_loop.defer Hash.new, 123,22,333 do |a,b,c|
358
+ assert_equal 123,a
359
+ assert_equal 22,b
360
+ assert_equal 333,c
361
+ raise ArgumentError
362
+ end
363
+ sleep 0.1
364
+ assert_raises ArgumentError do
365
+ event_loop.step
366
+ end
367
+ end
368
+
369
+ it 'must automatically step' do
370
+ event_loop = Utilrb::EventLoop.new
371
+ event_loop.once 0.2 do
372
+ event_loop.stop
373
+ end
374
+ event_loop.exec
375
+ end
376
+
377
+ it 'must raise if step is called from a wrong thread' do
378
+ event_loop = Utilrb::EventLoop.new
379
+ event_loop.defer do
380
+ event_loop.step
381
+ end
382
+ sleep 0.1
383
+ assert_raises RuntimeError do
384
+ event_loop.step
385
+ end
386
+ end
387
+
388
+ it 'must call a given block from the event loop thread' do
389
+ event_loop = Utilrb::EventLoop.new
390
+ event_loop.thread = Thread.current
391
+ result1,result2 = [nil,nil]
392
+ event_loop.defer do
393
+ result1 = Thread.current
394
+ event_loop.call do
395
+ result2 = Thread.current
396
+ assert event_loop.thread?
397
+ end
398
+ end
399
+ sleep 0.1
400
+ event_loop.step
401
+ assert result1
402
+ assert result1 != result2
403
+ assert_equal Thread.current,result2
404
+ end
405
+ end
406
+ end
407
+