utilrb 1.6.6 → 2.0

Sign up to get free protection for your applications and to get access to all the features.
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
+