utilrb 1.6.6 → 2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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/test/test_exception.rb
CHANGED
data/test/test_gc.rb
CHANGED
data/test/test_hash.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require 'test_config'
|
1
|
+
require 'test/test_config'
|
2
2
|
require 'enumerator'
|
3
3
|
require 'set'
|
4
4
|
|
@@ -42,5 +42,61 @@ class TC_Hash < Test::Unit::TestCase
|
|
42
42
|
assert_equal({ 'a' => 1, 'b' => 2 }, base)
|
43
43
|
assert_equal({ 'a' => 2, 'b' => 3 }, result)
|
44
44
|
end
|
45
|
+
|
46
|
+
def test_recursive_merge
|
47
|
+
base = { 'a' => 1, 'b' => { 'c' => 10, 'd' => 20 }, 'c' => 2 }
|
48
|
+
base_orig = base.dup
|
49
|
+
to_merge = { 'a' => 10, 'b' => { 'c' => 100 }, 'd' => 3 }
|
50
|
+
to_merge_orig = to_merge.dup
|
51
|
+
result = base.recursive_merge(to_merge)
|
52
|
+
|
53
|
+
assert_equal(base, base_orig)
|
54
|
+
assert_equal(to_merge, to_merge_orig)
|
55
|
+
assert_equal({'a' => 10, 'b' => { 'c' => 100, 'd' => 20 }, 'c' => 2, 'd' => 3}, result)
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_recursive_merge_with_block
|
59
|
+
base = { 'a' => 1, 'b' => { 'c' => 10, 'd' => 20 }, 'c' => 2 }
|
60
|
+
base_orig = base.dup
|
61
|
+
to_merge = { 'a' => 10, 'b' => { 'c' => 100 }, 'd' => 3 }
|
62
|
+
to_merge_orig = to_merge.dup
|
63
|
+
args = []
|
64
|
+
result = base.recursive_merge(to_merge) do |v, k1, k2|
|
65
|
+
args << [v, k1, k2]
|
66
|
+
k1
|
67
|
+
end
|
68
|
+
|
69
|
+
assert_equal(base, base_orig)
|
70
|
+
assert_equal(to_merge, to_merge_orig)
|
71
|
+
assert_equal([['a', 1, 10], ['c', 10, 100]].to_set, args.to_set)
|
72
|
+
assert_equal({'a' => 1, 'b' => { 'c' => 10, 'd' => 20 }, 'c' => 2, 'd' => 3}, result)
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_recursive_merge_bang
|
76
|
+
base = { 'a' => 1, 'b' => { 'c' => 10, 'd' => 20 }, 'c' => 2 }
|
77
|
+
to_merge = { 'a' => 10, 'b' => { 'c' => 100 }, 'd' => 3 }
|
78
|
+
to_merge_orig = to_merge.dup
|
79
|
+
result = base.recursive_merge!(to_merge)
|
80
|
+
|
81
|
+
assert_equal(result, base)
|
82
|
+
assert_equal(to_merge, to_merge_orig)
|
83
|
+
assert_equal({'a' => 10, 'b' => { 'c' => 100, 'd' => 20 }, 'c' => 2, 'd' => 3}, result)
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_recursive_merge_bang_with_block
|
87
|
+
base = { 'a' => 1, 'b' => { 'c' => 10, 'd' => 20 }, 'c' => 2 }
|
88
|
+
to_merge = { 'a' => 10, 'b' => { 'c' => 100 }, 'd' => 3 }
|
89
|
+
to_merge_orig = to_merge.dup
|
90
|
+
args = []
|
91
|
+
result = base.recursive_merge!(to_merge) do |v, k1, k2|
|
92
|
+
args << [v, k1, k2]
|
93
|
+
k1
|
94
|
+
end
|
95
|
+
|
96
|
+
assert_equal(result, base)
|
97
|
+
assert_equal(to_merge, to_merge_orig)
|
98
|
+
assert_equal([['a', 1, 10], ['c', 10, 100]].to_set, args.to_set)
|
99
|
+
assert_equal({'a' => 1, 'b' => { 'c' => 10, 'd' => 20 }, 'c' => 2, 'd' => 3}, result)
|
100
|
+
end
|
45
101
|
end
|
46
102
|
|
data/test/test_kernel.rb
CHANGED
@@ -1,14 +1,27 @@
|
|
1
|
-
require 'test_config'
|
1
|
+
require 'test/test_config'
|
2
2
|
require 'flexmock'
|
3
3
|
require 'tempfile'
|
4
4
|
|
5
|
-
require 'utilrb/kernel
|
6
|
-
|
7
|
-
require '
|
8
|
-
require 'utilrb/kernel/with_module'
|
9
|
-
require 'utilrb/kernel/load_dsl_file'
|
5
|
+
require 'utilrb/kernel'
|
6
|
+
|
7
|
+
require 'flexmock/test_unit'
|
10
8
|
|
11
9
|
class TC_Kernel < Test::Unit::TestCase
|
10
|
+
# Do NOT move this block. Some tests are checking the error lines in the
|
11
|
+
# backtraces
|
12
|
+
DSL_EXEC_BLOCK = Proc.new do
|
13
|
+
real_method
|
14
|
+
if KnownConstant != 10
|
15
|
+
raise ArgumentError, "invalid constant value"
|
16
|
+
end
|
17
|
+
class Submod::Klass
|
18
|
+
def my_method
|
19
|
+
end
|
20
|
+
end
|
21
|
+
name('test')
|
22
|
+
unknown_method
|
23
|
+
end
|
24
|
+
|
12
25
|
def test_validate_options
|
13
26
|
valid_options = [ :a, :b, :c ]
|
14
27
|
valid_test = { :a => 1, :c => 2 }
|
@@ -167,6 +180,7 @@ class TC_Kernel < Test::Unit::TestCase
|
|
167
180
|
end
|
168
181
|
end
|
169
182
|
|
183
|
+
if !Utilrb::RUBY_IS_19
|
170
184
|
def test_eval_dsl_file_does_not_allow_class_definition
|
171
185
|
obj = Class.new do
|
172
186
|
def real_method
|
@@ -190,18 +204,6 @@ class TC_Kernel < Test::Unit::TestCase
|
|
190
204
|
end
|
191
205
|
end
|
192
206
|
end
|
193
|
-
|
194
|
-
DSL_EXEC_BLOCK = Proc.new do
|
195
|
-
real_method
|
196
|
-
if KnownConstant != 10
|
197
|
-
raise ArgumentError, "invalid constant value"
|
198
|
-
end
|
199
|
-
class Submod::Klass
|
200
|
-
def my_method
|
201
|
-
end
|
202
|
-
end
|
203
|
-
name('test')
|
204
|
-
unknown_method
|
205
207
|
end
|
206
208
|
|
207
209
|
def test_dsl_exec
|
@@ -220,8 +222,8 @@ class TC_Kernel < Test::Unit::TestCase
|
|
220
222
|
flunk("did not raise NameError for KnownConstant")
|
221
223
|
rescue NameError => e
|
222
224
|
assert e.message =~ /KnownConstant/, e.message
|
223
|
-
expected = "test_kernel.rb:
|
224
|
-
assert e.backtrace.first =~ /#{expected}/, "wrong backtrace when checking constant resolution: #{e.backtrace
|
225
|
+
expected = "test_kernel.rb:14"
|
226
|
+
assert e.backtrace.first =~ /#{expected}/, "wrong backtrace when checking constant resolution: #{e.backtrace.join("\n")}, expected #{expected}"
|
225
227
|
end
|
226
228
|
|
227
229
|
begin
|
@@ -229,7 +231,7 @@ class TC_Kernel < Test::Unit::TestCase
|
|
229
231
|
flunk("did not raise NoMethodError for unknown_method")
|
230
232
|
rescue NoMethodError => e
|
231
233
|
assert e.message =~ /unknown_method/
|
232
|
-
expected = "test_kernel.rb:
|
234
|
+
expected = "test_kernel.rb:22"
|
233
235
|
assert e.backtrace.first =~ /#{expected}/, "wrong backtrace when checking method resolution: #{e.backtrace[0]}, expected #{expected}"
|
234
236
|
end
|
235
237
|
|
@@ -301,5 +303,34 @@ class TC_Kernel < Test::Unit::TestCase
|
|
301
303
|
GC.start
|
302
304
|
end
|
303
305
|
end
|
306
|
+
|
307
|
+
def test_poll
|
308
|
+
flexmock(Kernel).should_receive(:sleep).with(2).twice
|
309
|
+
counter = 0
|
310
|
+
Kernel.poll(2) do
|
311
|
+
counter += 1
|
312
|
+
if counter > 2
|
313
|
+
break
|
314
|
+
end
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
def test_wait_until
|
319
|
+
flexmock(Kernel).should_receive(:sleep).with(2).twice
|
320
|
+
counter = 0
|
321
|
+
Kernel.wait_until(2) do
|
322
|
+
counter += 1
|
323
|
+
counter > 2
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
def test_wait_while
|
328
|
+
flexmock(Kernel).should_receive(:sleep).with(2).twice
|
329
|
+
counter = 0
|
330
|
+
Kernel.wait_while(2) do
|
331
|
+
counter += 1
|
332
|
+
counter <= 2
|
333
|
+
end
|
334
|
+
end
|
304
335
|
end
|
305
336
|
|
data/test/test_logger.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
-
require 'test_config'
|
1
|
+
require './test/test_config'
|
2
2
|
require 'utilrb/logger'
|
3
|
+
require 'flexmock/test_unit'
|
3
4
|
|
4
5
|
class TC_Logger < Test::Unit::TestCase
|
5
6
|
module Root
|
@@ -8,10 +9,15 @@ class TC_Logger < Test::Unit::TestCase
|
|
8
9
|
module Child
|
9
10
|
extend Logger::Hierarchy
|
10
11
|
end
|
12
|
+
class Klass
|
13
|
+
extend Logger::Hierarchy
|
14
|
+
end
|
11
15
|
end
|
12
16
|
|
13
17
|
def teardown
|
18
|
+
Root.reset_own_logger
|
14
19
|
Root::Child.reset_own_logger
|
20
|
+
super
|
15
21
|
end
|
16
22
|
|
17
23
|
def test_logger_root
|
@@ -31,6 +37,33 @@ class TC_Logger < Test::Unit::TestCase
|
|
31
37
|
assert child.respond_to?(:warn)
|
32
38
|
end
|
33
39
|
|
40
|
+
def test_logger_hierarchy_on_anonymous_classes
|
41
|
+
child = Class.new(Root::Klass)
|
42
|
+
assert_same Root.logger, child.logger
|
43
|
+
assert child.respond_to?(:warn)
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_logger_hierarchy_on_instances_of_anonymous_classes
|
47
|
+
child_m = Class.new(Root::Klass) do
|
48
|
+
include Logger::Hierarchy
|
49
|
+
end
|
50
|
+
child = child_m.new
|
51
|
+
assert_same Root.logger, child.logger
|
52
|
+
assert child.respond_to?(:warn)
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_logger_hierarchy_on_classes_that_have_almost_a_class_name
|
56
|
+
child_m = Class.new(Root::Klass) do
|
57
|
+
include Logger::Hierarchy
|
58
|
+
def self.name
|
59
|
+
"A::NonExistent::Constant::Name"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
child = child_m.new
|
63
|
+
assert_same Root.logger, child.logger
|
64
|
+
assert child.respond_to?(:warn)
|
65
|
+
end
|
66
|
+
|
34
67
|
def test_logger_hierarch_make_own
|
35
68
|
child = Root::Child
|
36
69
|
assert_same Root.logger, child.logger
|
@@ -45,6 +78,13 @@ class TC_Logger < Test::Unit::TestCase
|
|
45
78
|
assert child.has_own_logger?
|
46
79
|
end
|
47
80
|
|
81
|
+
def test_logger_hierarch_make_own_propagates_to_children
|
82
|
+
child = Root::Child
|
83
|
+
assert_same Root.logger, child.logger
|
84
|
+
Root.make_own_logger('root', Logger::DEBUG)
|
85
|
+
assert_same Root.logger, child.logger
|
86
|
+
end
|
87
|
+
|
48
88
|
def test_logger_hierarch_reset_own
|
49
89
|
child = Root::Child
|
50
90
|
child.make_own_logger('child', Logger::DEBUG)
|
@@ -52,4 +92,113 @@ class TC_Logger < Test::Unit::TestCase
|
|
52
92
|
child.reset_own_logger
|
53
93
|
test_logger_hierarchy
|
54
94
|
end
|
95
|
+
|
96
|
+
def test_logger_nest_size
|
97
|
+
logger = Logger.new(StringIO.new)
|
98
|
+
logger.formatter = flexmock
|
99
|
+
logger.formatter.should_receive(:call).with(any, any, any, "msg0").once.ordered
|
100
|
+
logger.formatter.should_receive(:call).with(any, any, any, " msg1").once.ordered
|
101
|
+
logger.formatter.should_receive(:call).with(any, any, any, " msg2").once.ordered
|
102
|
+
logger.formatter.should_receive(:call).with(any, any, any, "msg3").once.ordered
|
103
|
+
logger.nest_size = 0
|
104
|
+
logger.warn("msg0")
|
105
|
+
logger.nest_size = 3
|
106
|
+
logger.warn("msg1")
|
107
|
+
logger.nest_size = 1
|
108
|
+
logger.warn("msg2")
|
109
|
+
logger.nest_size = 0
|
110
|
+
logger.warn("msg3")
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_logger_nest
|
114
|
+
logger = Logger.new(StringIO.new)
|
115
|
+
logger.formatter = flexmock
|
116
|
+
logger.formatter.should_receive(:call).with(any, any, any, "msg0").once.ordered
|
117
|
+
logger.formatter.should_receive(:call).with(any, any, any, " msg1").once.ordered
|
118
|
+
logger.formatter.should_receive(:call).with(any, any, any, " msg2").once.ordered
|
119
|
+
logger.formatter.should_receive(:call).with(any, any, any, " msg3").once.ordered
|
120
|
+
logger.formatter.should_receive(:call).with(any, any, any, "msg4").once.ordered
|
121
|
+
logger.warn("msg0")
|
122
|
+
logger.nest(2) do
|
123
|
+
logger.warn("msg1")
|
124
|
+
logger.nest(1) do
|
125
|
+
logger.warn("msg2")
|
126
|
+
end
|
127
|
+
logger.warn("msg3")
|
128
|
+
end
|
129
|
+
logger.warn("msg4")
|
130
|
+
end
|
131
|
+
|
132
|
+
def test_logger_io
|
133
|
+
logger = flexmock
|
134
|
+
io = Logger::LoggerIO.new(logger, :uncommon_level)
|
135
|
+
|
136
|
+
logger.should_receive(:uncommon_level).with("msg0").once.ordered
|
137
|
+
logger.should_receive(:uncommon_level).with("msg1 msg2").once.ordered
|
138
|
+
io.puts "msg0"
|
139
|
+
io.print "msg1"
|
140
|
+
io.puts " msg2"
|
141
|
+
end
|
142
|
+
|
143
|
+
|
144
|
+
module HierarchyTest
|
145
|
+
def self.logger; "root_logger" end
|
146
|
+
class HierarchyTest
|
147
|
+
extend Logger::Hierarchy
|
148
|
+
extend Logger::Forward
|
149
|
+
end
|
150
|
+
|
151
|
+
module A
|
152
|
+
extend Logger::Hierarchy
|
153
|
+
extend Logger::Forward
|
154
|
+
|
155
|
+
class B
|
156
|
+
extend Logger::Hierarchy
|
157
|
+
include Logger::Hierarchy
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
module HierarchyTestForSubclass
|
163
|
+
def self.logger; "other_logger" end
|
164
|
+
class HierarchyTest < HierarchyTest::HierarchyTest
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
module NotALoggingModule
|
169
|
+
class HierarchyTest < HierarchyTest::HierarchyTest
|
170
|
+
end
|
171
|
+
class NoLogger
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def test_hierarchy_can_resolve_parent_logger_with_identical_name
|
176
|
+
assert_equal "root_logger", HierarchyTest::HierarchyTest.logger
|
177
|
+
end
|
178
|
+
def test_hierarchy_can_resolve_parent_logger_in_subclasses_where_the_subclass_parent_module_is_not_providing_a_logger
|
179
|
+
assert_equal "root_logger", NotALoggingModule::HierarchyTest.logger
|
180
|
+
end
|
181
|
+
def test_hierarchy_resolves_the_parent_module_first_even_in_subclasses
|
182
|
+
assert_equal "other_logger", HierarchyTestForSubclass::HierarchyTest.logger
|
183
|
+
end
|
184
|
+
def test_hierarchy_raises_if_no_parent_logger_can_be_found
|
185
|
+
assert_raises(Logger::Hierarchy::NoParentLogger) { NotALoggingModule::NoLogger.extend Logger::Hierarchy }
|
186
|
+
end
|
187
|
+
|
188
|
+
module RootModule
|
189
|
+
end
|
190
|
+
def test_hierarchy_raises_if_hierarchy_is_called_on_a_root_module
|
191
|
+
assert_raises(Logger::Hierarchy::NoParentLogger) { RootModule.extend Logger::Hierarchy }
|
192
|
+
end
|
193
|
+
|
194
|
+
def test_instance_resolves_to_class_logger
|
195
|
+
klass = Class.new(HierarchyTest::HierarchyTest)
|
196
|
+
klass.send(:include, Logger::Hierarchy)
|
197
|
+
obj = klass.new
|
198
|
+
assert_equal "root_logger", obj.logger
|
199
|
+
end
|
200
|
+
def test_instance_resolves_to_own_logger_if_set
|
201
|
+
a_logger = HierarchyTest::A.make_own_logger
|
202
|
+
assert_same a_logger, HierarchyTest::A::B.logger
|
203
|
+
end
|
55
204
|
end
|
data/test/test_misc.rb
CHANGED
data/test/test_models.rb
ADDED
@@ -0,0 +1,212 @@
|
|
1
|
+
require 'test/test_config'
|
2
|
+
|
3
|
+
require 'flexmock/test_unit'
|
4
|
+
require 'set'
|
5
|
+
require 'enumerator'
|
6
|
+
require 'utilrb/module'
|
7
|
+
|
8
|
+
class TC_Models < Test::Unit::TestCase
|
9
|
+
def test_inherited_enumerable_module
|
10
|
+
m = Module.new do
|
11
|
+
inherited_enumerable(:signature, :signatures) { Array.new }
|
12
|
+
end
|
13
|
+
k = Class.new do
|
14
|
+
include m
|
15
|
+
inherited_enumerable(:child_attribute) { Array.new }
|
16
|
+
end
|
17
|
+
|
18
|
+
# Add another attribute *after* k has been defined
|
19
|
+
m.class_eval do
|
20
|
+
inherited_enumerable(:mapped, :map, :map => true) { Hash.new }
|
21
|
+
end
|
22
|
+
check_inherited_enumerable(m, k)
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_inherited_enumerable_class
|
26
|
+
a = Class.new do
|
27
|
+
inherited_enumerable(:signature, :signatures) { Array.new }
|
28
|
+
inherited_enumerable(:mapped, :map, :map => true) { Hash.new }
|
29
|
+
end
|
30
|
+
b = Class.new(a) do
|
31
|
+
include Module.new # include an empty module between a and b to check that the module
|
32
|
+
# is skipped transparently
|
33
|
+
inherited_enumerable(:child_attribute) { Array.new }
|
34
|
+
end
|
35
|
+
check_inherited_enumerable(a, b)
|
36
|
+
|
37
|
+
# Test for singleton class support
|
38
|
+
object = b.new
|
39
|
+
assert(object.singleton_class.respond_to?(:signatures))
|
40
|
+
object.singleton_class.signatures << :in_singleton
|
41
|
+
assert_equal([:in_singleton], object.singleton_class.signatures)
|
42
|
+
end
|
43
|
+
|
44
|
+
def check_inherited_enumerable(base, derived)
|
45
|
+
assert(base.respond_to?(:each_signature))
|
46
|
+
assert(base.respond_to?(:signatures))
|
47
|
+
assert(!base.respond_to?(:has_signature?))
|
48
|
+
assert(!base.respond_to?(:find_signatures))
|
49
|
+
|
50
|
+
assert(base.respond_to?(:each_mapped))
|
51
|
+
assert(base.respond_to?(:map))
|
52
|
+
assert(base.respond_to?(:has_mapped?))
|
53
|
+
|
54
|
+
base.signatures << :in_base
|
55
|
+
base.map[:base] = 10
|
56
|
+
base.map[:overriden] = 20
|
57
|
+
assert_equal([:in_base], base.enum_for(:each_signature).to_a)
|
58
|
+
assert_equal([10].to_set, base.enum_for(:each_mapped, :base, false).to_set)
|
59
|
+
|
60
|
+
assert(!base.respond_to?(:child_attribute))
|
61
|
+
assert(!base.respond_to?(:each_child_attribute))
|
62
|
+
assert(derived.respond_to?(:child_attribute))
|
63
|
+
assert(derived.respond_to?(:each_child_attribute))
|
64
|
+
|
65
|
+
derived.signatures << :in_derived
|
66
|
+
|
67
|
+
derived.map[:overriden] = 15
|
68
|
+
derived.map[:derived] = 25
|
69
|
+
|
70
|
+
assert_equal([:in_derived, :in_base], derived.enum_for(:each_signature).to_a)
|
71
|
+
assert_equal([20, 15].to_set, derived.enum_for(:each_mapped, :overriden, false).to_set)
|
72
|
+
assert_equal([15].to_set, derived.enum_for(:each_mapped, :overriden, true).to_set)
|
73
|
+
assert_equal([25].to_set, derived.enum_for(:each_mapped, :derived).to_set)
|
74
|
+
assert_equal([[:base, 10], [:overriden, 20], [:overriden, 15], [:derived, 25]].to_set, derived.enum_for(:each_mapped, nil, false).to_set)
|
75
|
+
assert_equal([[:base, 10], [:overriden, 15], [:derived, 25]].to_set, derived.enum_for(:each_mapped, nil, true).to_set)
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_inherited_enumerable_non_mapping_promote
|
79
|
+
a = Class.new do
|
80
|
+
def self.promote_value(v)
|
81
|
+
v
|
82
|
+
end
|
83
|
+
inherited_enumerable(:value, :values) { Array.new }
|
84
|
+
end
|
85
|
+
b = flexmock(Class.new(a), 'b')
|
86
|
+
c = flexmock(Class.new(b), 'c')
|
87
|
+
d = flexmock(Class.new(c), 'd')
|
88
|
+
|
89
|
+
c.should_receive(:promote_value).with(10).and_return("10_b_c").once.ordered
|
90
|
+
d.should_receive(:promote_value).with("10_b_c").and_return(12).once.ordered
|
91
|
+
c.should_receive(:promote_value).with(11).and_return("11_b_c").once.ordered
|
92
|
+
d.should_receive(:promote_value).with("11_b_c").and_return(13).once.ordered
|
93
|
+
b.should_receive(:promote_value).with(0).and_return("0_b_c").once.ordered
|
94
|
+
c.should_receive(:promote_value).with("0_b_c").and_return("0_c_d").once.ordered
|
95
|
+
d.should_receive(:promote_value).with("0_c_d").and_return(2).once.ordered
|
96
|
+
b.should_receive(:promote_value).with(1).and_return("1_b_c").once.ordered
|
97
|
+
c.should_receive(:promote_value).with("1_b_c").and_return("1_c_d").once.ordered
|
98
|
+
d.should_receive(:promote_value).with("1_c_d").and_return(3).once.ordered
|
99
|
+
|
100
|
+
a.values << 0 << 1
|
101
|
+
b.values << 10 << 11
|
102
|
+
# Do NOT add anything at the level of C. Its promote_value method should
|
103
|
+
# still be called, though
|
104
|
+
d.values << 100 << 110
|
105
|
+
assert_equal [0, 1], a.each_value.to_a
|
106
|
+
assert_equal [100, 110, 12, 13, 2, 3], d.each_value.to_a
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_inherited_enumerable_mapping_promote
|
110
|
+
a = Class.new do
|
111
|
+
def self.promote_value(key, v)
|
112
|
+
end
|
113
|
+
def self.name; 'A' end
|
114
|
+
inherited_enumerable(:value, :values, :map => true) { Hash.new }
|
115
|
+
end
|
116
|
+
b = Class.new(a)
|
117
|
+
c = Class.new(b)
|
118
|
+
d = Class.new(c)
|
119
|
+
|
120
|
+
flexmock(c).should_receive(:promote_value).with('b', 2).and_return("b2_b_c").once.ordered
|
121
|
+
flexmock(d).should_receive(:promote_value).with('b', "b2_b_c").and_return(15).once.ordered
|
122
|
+
|
123
|
+
flexmock(c).should_receive(:promote_value).with('c', 3).and_return("c3_b_c").once.ordered
|
124
|
+
flexmock(d).should_receive(:promote_value).with('c', "c3_b_c").and_return(16).once.ordered
|
125
|
+
|
126
|
+
flexmock(b).should_receive(:promote_value).with('a', 0).and_return("a0_a_b").once.ordered
|
127
|
+
flexmock(c).should_receive(:promote_value).with('a', "a0_a_b").and_return("a0_b_c").once.ordered
|
128
|
+
flexmock(d).should_receive(:promote_value).with('a', "a0_b_c").and_return(10).once.ordered
|
129
|
+
|
130
|
+
a.values.merge!('a' => 0, 'b' => 1)
|
131
|
+
b.values.merge!('b' => 2, 'c' => 3, 'd' => 4)
|
132
|
+
d.values.merge!('d' => 5, 'e' => 6)
|
133
|
+
assert_equal [['d', 5], ['e', 6], ['b', 15], ['c', 16], ['a', 10]], d.each_value.to_a
|
134
|
+
end
|
135
|
+
|
136
|
+
def test_inherited_enumerable_mapping_promote_non_uniq
|
137
|
+
a = Class.new do
|
138
|
+
def self.promote_value(key, v)
|
139
|
+
end
|
140
|
+
inherited_enumerable(:value, :values, :map => true) { Hash.new }
|
141
|
+
end
|
142
|
+
b = flexmock(Class.new(a), 'b')
|
143
|
+
c = flexmock(Class.new(b), 'c')
|
144
|
+
d = flexmock(Class.new(c), 'd')
|
145
|
+
|
146
|
+
c.should_receive(:promote_value).with('b', 2).and_return("b2_b_c").once.ordered
|
147
|
+
d.should_receive(:promote_value).with('b', "b2_b_c").and_return(12).once.ordered
|
148
|
+
|
149
|
+
c.should_receive(:promote_value).with('c', 3).and_return("c3_b_c").once.ordered
|
150
|
+
d.should_receive(:promote_value).with('c', "c3_b_c").and_return(13).once.ordered
|
151
|
+
|
152
|
+
c.should_receive(:promote_value).with('d', 4).and_return("d4_b_c").once.ordered
|
153
|
+
d.should_receive(:promote_value).with('d', "d4_b_c").and_return(14).once.ordered
|
154
|
+
|
155
|
+
b.should_receive(:promote_value).with('a', 0).and_return("a0_a_b").once.ordered
|
156
|
+
c.should_receive(:promote_value).with('a', "a0_a_b").and_return("a0_b_c").once.ordered
|
157
|
+
d.should_receive(:promote_value).with('a', "a0_b_c").and_return(10).once.ordered
|
158
|
+
|
159
|
+
b.should_receive(:promote_value).with('b', 1).and_return("b1_a_b").once.ordered
|
160
|
+
c.should_receive(:promote_value).with('b', "b1_a_b").and_return("b1_b_c").once.ordered
|
161
|
+
d.should_receive(:promote_value).with('b', "b1_b_c").and_return(11).once.ordered
|
162
|
+
|
163
|
+
a.values.merge!('a' => 0, 'b' => 1)
|
164
|
+
b.values.merge!('b' => 2, 'c' => 3, 'd' => 4)
|
165
|
+
d.values.merge!('d' => 5, 'e' => 6)
|
166
|
+
assert_equal [['d', 5], ['e', 6], ['b', 12], ['c', 13], ['d', 14], ['a', 10], ['b', 11]], d.each_value(nil, false).to_a
|
167
|
+
end
|
168
|
+
|
169
|
+
def test_inherited_enumerable_mapping_promote_with_key_uniq
|
170
|
+
a = Class.new do
|
171
|
+
def self.promote_value(key, v)
|
172
|
+
end
|
173
|
+
inherited_enumerable(:value, :values, :map => true) { Hash.new }
|
174
|
+
end
|
175
|
+
b = flexmock(Class.new(a), 'b')
|
176
|
+
c = flexmock(Class.new(b), 'c')
|
177
|
+
d = flexmock(Class.new(c), 'd')
|
178
|
+
|
179
|
+
c.should_receive(:promote_value).with('b', 2).and_return("b2_b_c").once.ordered
|
180
|
+
d.should_receive(:promote_value).with('b', "b2_b_c").and_return(12).once.ordered
|
181
|
+
|
182
|
+
a.values.merge!('a' => 0, 'b' => 1)
|
183
|
+
b.values.merge!('b' => 2, 'c' => 3, 'd' => 4)
|
184
|
+
d.values.merge!('d' => 5, 'e' => 6)
|
185
|
+
assert_equal [12], d.each_value('b', true).to_a
|
186
|
+
end
|
187
|
+
|
188
|
+
def test_inherited_enumerable_mapping_promote_with_key_non_uniq
|
189
|
+
a = Class.new do
|
190
|
+
def self.promote_value(key, v)
|
191
|
+
end
|
192
|
+
inherited_enumerable(:value, :values, :map => true) { Hash.new }
|
193
|
+
end
|
194
|
+
b = flexmock(Class.new(a), 'b')
|
195
|
+
c = flexmock(Class.new(b), 'c')
|
196
|
+
d = flexmock(Class.new(c), 'd')
|
197
|
+
|
198
|
+
c.should_receive(:promote_value).with('b', 2).and_return("b2_b_c").once.ordered
|
199
|
+
d.should_receive(:promote_value).with('b', "b2_b_c").and_return(12).once.ordered
|
200
|
+
|
201
|
+
b.should_receive(:promote_value).with('b', 1).and_return("b1_a_b").once.ordered
|
202
|
+
c.should_receive(:promote_value).with('b', "b1_a_b").and_return("b1_b_c").once.ordered
|
203
|
+
d.should_receive(:promote_value).with('b', "b1_b_c").and_return(11).once.ordered
|
204
|
+
|
205
|
+
a.values.merge!('a' => 0, 'b' => 1)
|
206
|
+
b.values.merge!('b' => 2, 'c' => 3, 'd' => 4)
|
207
|
+
d.values.merge!('d' => 5, 'e' => 6)
|
208
|
+
assert_equal [12, 11], d.each_value('b', false).to_a
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
|