utilrb 1.6.6 → 2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. data/Manifest.txt +10 -9
  2. data/README.rd +23 -0
  3. data/Rakefile +40 -37
  4. data/ext/utilrb/extconf.rb +36 -0
  5. data/ext/{proc.cc → utilrb/proc.c} +7 -6
  6. data/ext/utilrb/ruby_allocator.hh +76 -0
  7. data/ext/{ruby_internals-1.8.h → utilrb/ruby_internals-1.8.h} +0 -0
  8. data/ext/{ruby_internals-1.9.h → utilrb/ruby_internals-1.9.h} +0 -0
  9. data/ext/{swap.cc → utilrb/swap.cc} +0 -0
  10. data/ext/utilrb/utilrb.cc +79 -0
  11. data/ext/{value_set.cc → utilrb/value_set.cc} +5 -5
  12. data/ext/{weakref.cc → utilrb/weakref.cc} +0 -0
  13. data/lib/utilrb/common.rb +7 -2
  14. data/lib/utilrb/doc/rake.rb +46 -15
  15. data/lib/utilrb/kernel/load_dsl_file.rb +2 -2
  16. data/lib/utilrb/kernel/options.rb +6 -0
  17. data/lib/utilrb/logger/forward.rb +7 -0
  18. data/lib/utilrb/logger/hierarchy.rb +100 -42
  19. data/lib/utilrb/logger/indent.rb +38 -3
  20. data/lib/utilrb/logger/log_pp.rb +1 -1
  21. data/lib/utilrb/logger/root.rb +27 -12
  22. data/lib/utilrb/module/inherited_enumerable.rb +2 -196
  23. data/lib/utilrb/objectstats.rb +4 -1
  24. data/lib/utilrb/pkgconfig.rb +42 -6
  25. data/lib/utilrb/rake_common.rb +12 -0
  26. data/lib/utilrb/ruby_object_graph.rb +195 -46
  27. data/lib/utilrb/yard.rb +89 -89
  28. data/test/test_array.rb +1 -1
  29. data/test/test_dir.rb +1 -1
  30. data/test/test_enumerable.rb +7 -1
  31. data/test/test_event_loop.rb +407 -0
  32. data/test/test_exception.rb +1 -1
  33. data/test/test_gc.rb +1 -1
  34. data/test/test_hash.rb +57 -1
  35. data/test/test_kernel.rb +52 -21
  36. data/test/test_logger.rb +150 -1
  37. data/test/test_misc.rb +1 -1
  38. data/test/test_models.rb +212 -0
  39. data/test/test_module.rb +41 -71
  40. data/test/test_object.rb +1 -1
  41. data/test/test_objectstats.rb +1 -1
  42. data/test/test_pkgconfig.rb +7 -5
  43. data/test/test_proc.rb +1 -1
  44. data/test/test_set.rb +1 -1
  45. data/test/test_thread_pool.rb +409 -0
  46. data/test/test_time.rb +6 -6
  47. data/test/test_unbound_method.rb +1 -1
  48. metadata +157 -131
  49. data/README.txt +0 -45
  50. data/ext/extconf.rb +0 -29
  51. data/ext/utilrb_ext.cc +0 -144
@@ -1,4 +1,4 @@
1
- require 'test_config'
1
+ require 'test/test_config'
2
2
  require 'utilrb/exception'
3
3
  require 'flexmock'
4
4
 
data/test/test_gc.rb CHANGED
@@ -1,4 +1,4 @@
1
- require 'test_config'
1
+ require 'test/test_config'
2
2
 
3
3
  require 'utilrb/gc'
4
4
  require 'enumerator'
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/options'
6
- require 'utilrb/kernel/arity'
7
- require 'utilrb/kernel/swap'
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:160"
224
- assert e.backtrace.first =~ /#{expected}/, "wrong backtrace when checking constant resolution: #{e.backtrace[0]}, expected #{expected}"
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:168"
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
@@ -1,4 +1,4 @@
1
- require 'test_config'
1
+ require 'test/test_config'
2
2
 
3
3
  class TC_Misc < Test::Unit::TestCase
4
4
  def test_super_idiom
@@ -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
+