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.
- data/Manifest.txt +10 -9
- data/README.rd +23 -0
- data/Rakefile +40 -37
- data/ext/utilrb/extconf.rb +36 -0
- data/ext/{proc.cc → utilrb/proc.c} +7 -6
- data/ext/utilrb/ruby_allocator.hh +76 -0
- data/ext/{ruby_internals-1.8.h → utilrb/ruby_internals-1.8.h} +0 -0
- data/ext/{ruby_internals-1.9.h → utilrb/ruby_internals-1.9.h} +0 -0
- data/ext/{swap.cc → utilrb/swap.cc} +0 -0
- data/ext/utilrb/utilrb.cc +79 -0
- data/ext/{value_set.cc → utilrb/value_set.cc} +5 -5
- data/ext/{weakref.cc → utilrb/weakref.cc} +0 -0
- data/lib/utilrb/common.rb +7 -2
- data/lib/utilrb/doc/rake.rb +46 -15
- data/lib/utilrb/kernel/load_dsl_file.rb +2 -2
- data/lib/utilrb/kernel/options.rb +6 -0
- data/lib/utilrb/logger/forward.rb +7 -0
- data/lib/utilrb/logger/hierarchy.rb +100 -42
- data/lib/utilrb/logger/indent.rb +38 -3
- data/lib/utilrb/logger/log_pp.rb +1 -1
- data/lib/utilrb/logger/root.rb +27 -12
- data/lib/utilrb/module/inherited_enumerable.rb +2 -196
- data/lib/utilrb/objectstats.rb +4 -1
- data/lib/utilrb/pkgconfig.rb +42 -6
- data/lib/utilrb/rake_common.rb +12 -0
- data/lib/utilrb/ruby_object_graph.rb +195 -46
- data/lib/utilrb/yard.rb +89 -89
- data/test/test_array.rb +1 -1
- data/test/test_dir.rb +1 -1
- data/test/test_enumerable.rb +7 -1
- data/test/test_event_loop.rb +407 -0
- data/test/test_exception.rb +1 -1
- data/test/test_gc.rb +1 -1
- data/test/test_hash.rb +57 -1
- data/test/test_kernel.rb +52 -21
- data/test/test_logger.rb +150 -1
- data/test/test_misc.rb +1 -1
- data/test/test_models.rb +212 -0
- data/test/test_module.rb +41 -71
- data/test/test_object.rb +1 -1
- data/test/test_objectstats.rb +1 -1
- data/test/test_pkgconfig.rb +7 -5
- data/test/test_proc.rb +1 -1
- data/test/test_set.rb +1 -1
- data/test/test_thread_pool.rb +409 -0
- data/test/test_time.rb +6 -6
- data/test/test_unbound_method.rb +1 -1
- metadata +157 -131
- data/README.txt +0 -45
- data/ext/extconf.rb +0 -29
- 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
|
6
|
-
handles method_call(:
|
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
|
-
|
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
|
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.
|
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.
|
163
|
-
object.docstring.
|
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
data/test/test_dir.rb
CHANGED
data/test/test_enumerable.rb
CHANGED
@@ -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
|
+
|