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/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
|
+
|