caruby-core 1.5.5 → 2.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (126) hide show
  1. data/Gemfile +9 -0
  2. data/History.md +5 -1
  3. data/lib/caruby.rb +3 -5
  4. data/lib/caruby/caruby-src.tar.gz +0 -0
  5. data/lib/caruby/database.rb +53 -69
  6. data/lib/caruby/database/application_service.rb +25 -0
  7. data/lib/caruby/database/cache.rb +60 -0
  8. data/lib/caruby/database/fetched_matcher.rb +52 -38
  9. data/lib/caruby/database/lazy_loader.rb +4 -4
  10. data/lib/caruby/database/operation.rb +34 -0
  11. data/lib/caruby/database/persistable.rb +171 -86
  12. data/lib/caruby/database/persistence_service.rb +32 -34
  13. data/lib/caruby/database/persistifier.rb +100 -43
  14. data/lib/caruby/database/reader.rb +107 -85
  15. data/lib/caruby/database/reader_template_builder.rb +60 -0
  16. data/lib/caruby/database/saved_matcher.rb +3 -3
  17. data/lib/caruby/database/sql_executor.rb +88 -17
  18. data/lib/caruby/database/writer.rb +213 -177
  19. data/lib/caruby/database/writer_template_builder.rb +334 -0
  20. data/lib/caruby/{util → helpers}/controlled_value.rb +0 -0
  21. data/lib/caruby/{util → helpers}/coordinate.rb +4 -4
  22. data/lib/caruby/{util → helpers}/person.rb +3 -3
  23. data/lib/caruby/{util → helpers}/properties.rb +7 -9
  24. data/lib/caruby/{util → helpers}/roman.rb +2 -2
  25. data/lib/caruby/{util → helpers}/version.rb +1 -1
  26. data/lib/caruby/json/deserializer.rb +2 -2
  27. data/lib/caruby/json/serializer.rb +49 -7
  28. data/lib/caruby/metadata.rb +30 -0
  29. data/lib/caruby/metadata/java_property.rb +21 -0
  30. data/lib/caruby/metadata/propertied.rb +191 -0
  31. data/lib/caruby/metadata/property.rb +22 -0
  32. data/lib/caruby/metadata/property_characteristics.rb +201 -0
  33. data/lib/caruby/migration/migratable.rb +11 -182
  34. data/lib/caruby/rdbi/driver/jdbc.rb +446 -0
  35. data/lib/caruby/resource.rb +20 -823
  36. data/lib/caruby/version.rb +1 -1
  37. data/test/lib/caruby/database/cache_test.rb +54 -0
  38. data/test/lib/caruby/{util → helpers}/controlled_value_test.rb +3 -5
  39. data/test/lib/caruby/{util → helpers}/person_test.rb +4 -6
  40. data/test/lib/caruby/helpers/properties_test.rb +34 -0
  41. data/test/lib/caruby/{util → helpers}/roman_test.rb +2 -3
  42. data/test/lib/caruby/{util → helpers}/version_test.rb +2 -3
  43. data/test/lib/helper.rb +7 -0
  44. metadata +161 -214
  45. data/lib/caruby/cli/application.rb +0 -36
  46. data/lib/caruby/cli/command.rb +0 -202
  47. data/lib/caruby/csv/csv_mapper.rb +0 -159
  48. data/lib/caruby/csv/csvio.rb +0 -203
  49. data/lib/caruby/database/search_template_builder.rb +0 -56
  50. data/lib/caruby/database/store_template_builder.rb +0 -278
  51. data/lib/caruby/domain.rb +0 -193
  52. data/lib/caruby/domain/attribute.rb +0 -584
  53. data/lib/caruby/domain/attributes.rb +0 -628
  54. data/lib/caruby/domain/dependency.rb +0 -225
  55. data/lib/caruby/domain/id_alias.rb +0 -22
  56. data/lib/caruby/domain/importer.rb +0 -183
  57. data/lib/caruby/domain/introspection.rb +0 -176
  58. data/lib/caruby/domain/inverse.rb +0 -172
  59. data/lib/caruby/domain/inversible.rb +0 -90
  60. data/lib/caruby/domain/java_attribute.rb +0 -173
  61. data/lib/caruby/domain/merge.rb +0 -185
  62. data/lib/caruby/domain/metadata.rb +0 -142
  63. data/lib/caruby/domain/mixin.rb +0 -35
  64. data/lib/caruby/domain/properties.rb +0 -95
  65. data/lib/caruby/domain/reference_visitor.rb +0 -428
  66. data/lib/caruby/domain/uniquify.rb +0 -50
  67. data/lib/caruby/import/java.rb +0 -387
  68. data/lib/caruby/migration/migrator.rb +0 -918
  69. data/lib/caruby/migration/resource_module.rb +0 -9
  70. data/lib/caruby/migration/uniquify.rb +0 -17
  71. data/lib/caruby/util/attribute_path.rb +0 -44
  72. data/lib/caruby/util/cache.rb +0 -56
  73. data/lib/caruby/util/class.rb +0 -149
  74. data/lib/caruby/util/collection.rb +0 -1152
  75. data/lib/caruby/util/domain_extent.rb +0 -46
  76. data/lib/caruby/util/file_separator.rb +0 -65
  77. data/lib/caruby/util/inflector.rb +0 -27
  78. data/lib/caruby/util/log.rb +0 -95
  79. data/lib/caruby/util/math.rb +0 -12
  80. data/lib/caruby/util/merge.rb +0 -59
  81. data/lib/caruby/util/module.rb +0 -18
  82. data/lib/caruby/util/options.rb +0 -97
  83. data/lib/caruby/util/partial_order.rb +0 -35
  84. data/lib/caruby/util/pretty_print.rb +0 -204
  85. data/lib/caruby/util/stopwatch.rb +0 -74
  86. data/lib/caruby/util/topological_sync_enumerator.rb +0 -62
  87. data/lib/caruby/util/transitive_closure.rb +0 -55
  88. data/lib/caruby/util/tree.rb +0 -48
  89. data/lib/caruby/util/trie.rb +0 -37
  90. data/lib/caruby/util/uniquifier.rb +0 -30
  91. data/lib/caruby/util/validation.rb +0 -20
  92. data/lib/caruby/util/visitor.rb +0 -365
  93. data/lib/caruby/util/weak_hash.rb +0 -36
  94. data/test/lib/caruby/csv/csv_mapper_test.rb +0 -40
  95. data/test/lib/caruby/csv/csvio_test.rb +0 -69
  96. data/test/lib/caruby/database/persistable_test.rb +0 -92
  97. data/test/lib/caruby/domain/domain_test.rb +0 -112
  98. data/test/lib/caruby/domain/inversible_test.rb +0 -99
  99. data/test/lib/caruby/domain/reference_visitor_test.rb +0 -130
  100. data/test/lib/caruby/import/java_test.rb +0 -80
  101. data/test/lib/caruby/import/mixed_case_test.rb +0 -14
  102. data/test/lib/caruby/migration/test_case.rb +0 -102
  103. data/test/lib/caruby/test_case.rb +0 -230
  104. data/test/lib/caruby/util/cache_test.rb +0 -23
  105. data/test/lib/caruby/util/class_test.rb +0 -61
  106. data/test/lib/caruby/util/collection_test.rb +0 -398
  107. data/test/lib/caruby/util/command_test.rb +0 -55
  108. data/test/lib/caruby/util/domain_extent_test.rb +0 -60
  109. data/test/lib/caruby/util/file_separator_test.rb +0 -30
  110. data/test/lib/caruby/util/inflector_test.rb +0 -12
  111. data/test/lib/caruby/util/lazy_hash_test.rb +0 -34
  112. data/test/lib/caruby/util/merge_test.rb +0 -83
  113. data/test/lib/caruby/util/module_test.rb +0 -25
  114. data/test/lib/caruby/util/options_test.rb +0 -59
  115. data/test/lib/caruby/util/partial_order_test.rb +0 -42
  116. data/test/lib/caruby/util/pretty_print_test.rb +0 -85
  117. data/test/lib/caruby/util/properties_test.rb +0 -50
  118. data/test/lib/caruby/util/stopwatch_test.rb +0 -18
  119. data/test/lib/caruby/util/topological_sync_enumerator_test.rb +0 -69
  120. data/test/lib/caruby/util/transitive_closure_test.rb +0 -67
  121. data/test/lib/caruby/util/tree_test.rb +0 -23
  122. data/test/lib/caruby/util/trie_test.rb +0 -14
  123. data/test/lib/caruby/util/visitor_test.rb +0 -278
  124. data/test/lib/caruby/util/weak_hash_test.rb +0 -45
  125. data/test/lib/examples/clinical_trials/migration/migration_test.rb +0 -58
  126. data/test/lib/examples/clinical_trials/migration/test_case.rb +0 -38
@@ -1,50 +0,0 @@
1
- $:.unshift('lib')
2
-
3
- require "test/unit"
4
- require 'caruby/util/properties'
5
- require 'caruby/util/log'
6
-
7
- class PropertiesTest < Test::Unit::TestCase
8
- LOG_FILE = File.join('test', 'results', 'log', 'caruby.log')
9
- FIXTURES_DIR = File.join('test', 'fixtures', 'caruby', 'util', 'properties')
10
- INPUT_FILE = File.join(FIXTURES_DIR, 'properties.yaml')
11
- MERGE_FILE = File.join(FIXTURES_DIR, 'merge_properties.yaml')
12
- MERGE_PROPERTIES = ['short', 'nested']
13
-
14
- def setup
15
- CaRuby::Log.instance.open(LOG_FILE, :debug => true)
16
- @properties = CaRuby::Properties.new(INPUT_FILE, :merge => MERGE_PROPERTIES)
17
- end
18
-
19
- def test_short_name
20
- assert_equal('short', @properties['short'], 'Short property incorrect')
21
- end
22
-
23
- def test_dotted_name
24
- assert_equal('dot', @properties['dot.property'], 'Dotted property incorrect')
25
- end
26
-
27
- def test_symbol
28
- assert_equal('short', @properties[:short], 'Symbol key lookup incorrect')
29
- end
30
-
31
- def test_nested
32
- assert_not_nil(@properties['nested'], 'Nested property not found')
33
- assert_equal('A', @properties['nested']['a'], 'Nested property value incorrect')
34
- assert_equal('B', @properties['nested']['b'], 'Nested property value incorrect')
35
- assert_not_nil(@properties['nested']['deep'], 'Nested deep property not found')
36
- assert_equal('U', @properties['nested']['deep']['u'], 'Nested deep property value incorrect')
37
- end
38
-
39
- def test_merge
40
- @properties.load_properties_file(MERGE_FILE)
41
- assert_equal('long', @properties['short'], 'Merge property value not overridden')
42
- assert_equal('dash', @properties['dot.property'], 'Non-merge property value not overridden')
43
- assert_not_nil(@properties['nested'], 'Nested property override incorrect')
44
- assert_equal('X', @properties['nested']['a'], 'Nested property value not overridden')
45
- assert_equal('B', @properties['nested']['b'], 'Nested property value not retained')
46
- assert_equal('C', @properties['nested']['c'], 'Nested property value not added')
47
- assert_equal('U', @properties['nested']['deep']['u'], 'Nested deep property value not retained')
48
- assert_equal('V', @properties['nested']['deep']['v'], 'Nested deep property value not added')
49
- end
50
- end
@@ -1,18 +0,0 @@
1
- $:.unshift 'lib'
2
-
3
- require 'caruby/util/stopwatch'
4
- require "test/unit"
5
-
6
- class StopwatchTest < Test::Unit::TestCase
7
-
8
- def setup
9
- @timer = Stopwatch.new
10
- end
11
-
12
- def test_run
13
- t1 = @timer.run { 1000000.times { " " * 100 } }
14
- t2 = @timer.run { 1000000.times { " " * 100 } }
15
- assert_equal(t1.elapsed + t2.elapsed, @timer.elapsed, "Elapsed time incorrectly accumulated")
16
- assert_equal(t1.cpu + t2.cpu, @timer.cpu, "CPU time incorrectly accumulated")
17
- end
18
- end
@@ -1,69 +0,0 @@
1
- $:.unshift 'lib'
2
-
3
- require "test/unit"
4
- require 'caruby/util/topological_sync_enumerator'
5
-
6
- class TopologicalSyncEnumeratorTest < Test::Unit::TestCase
7
- class Node
8
- attr_reader :value, :parent
9
-
10
- def initialize(value, parent=nil)
11
- super()
12
- @value = value
13
- @parent = parent
14
- end
15
-
16
- def to_s
17
- value.to_s
18
- end
19
-
20
- alias :inspect :to_s
21
- end
22
-
23
- def test_simple
24
- a = Node.new(:a)
25
- b = Node.new(:b)
26
- c = Node.new(:c, a)
27
- d = Node.new(:d, b)
28
- enum = TopologicalSyncEnumerator.new([a, c], [b, d], :parent)
29
- assert_equal([[a, b], [c, d]], enum.to_a, "Enumeration incorrect")
30
- end
31
-
32
- def test_many
33
- a = Node.new(:a)
34
- b = Node.new(:b)
35
- c1 = Node.new(:c1, a)
36
- c2 = Node.new(:c2, a)
37
- d1 = Node.new(:d1, b)
38
- d2 = Node.new(:d2, b)
39
- enum = TopologicalSyncEnumerator.new([a, c1, c2], [b, d1, d2], :parent)
40
- assert_equal([[a, b], [c1, d1], [c2, d2]], enum.to_a, "Enumeration incorrect")
41
- end
42
-
43
- def test_matcher
44
- a = Node.new(:a)
45
- b = Node.new(:b)
46
- c1 = Node.new(:c1, a)
47
- c2 = Node.new(:c2, a)
48
- d1 = Node.new(:d1, b)
49
- d2 = Node.new(:d2, b)
50
- enum = TopologicalSyncEnumerator.new([a, c1, c2], [b, d1, d2], :parent) { |t, srcs| srcs.last }
51
- assert_equal([[a, b], [c1, d2], [c2, d1]], enum.to_a, "Enumeration incorrect")
52
- end
53
-
54
- def test_excess_target
55
- a = Node.new(:a)
56
- b = Node.new(:b)
57
- c = Node.new(:c, a)
58
- enum = TopologicalSyncEnumerator.new([a, c], [b], :parent)
59
- assert_equal([[a, b]], enum.to_a, "Enumeration incorrect")
60
- end
61
-
62
- def test_excess_source
63
- a = Node.new(:a)
64
- b = Node.new(:b)
65
- d = Node.new(:d, b)
66
- enum = TopologicalSyncEnumerator.new([a], [b, d], :parent)
67
- assert_equal([[a, b]], enum.to_a, "Enumeration incorrect")
68
- end
69
- end
@@ -1,67 +0,0 @@
1
- $:.unshift 'lib'
2
-
3
- require "test/unit"
4
- require 'caruby/util/collection'
5
- require 'caruby/util/transitive_closure'
6
-
7
- class TransitiveClosureTest < Test::Unit::TestCase
8
- class Node
9
- attr_reader :parent, :children, :value
10
-
11
- def initialize(value, parent=nil)
12
- super()
13
- @value = value
14
- @parent = parent
15
- @children = []
16
- parent.children << self if parent
17
- end
18
-
19
- def to_s
20
- value.to_s
21
- end
22
-
23
- alias :inspect :to_s
24
- end
25
-
26
- # Verifies closure iteration for the following hierarchy:
27
- # root -> a, e
28
- # a -> b, c
29
- # c -> d
30
- # The expected iteration is +root+ preceding +a+ and +e+, +a+ preceding +b+ and +c+, +c+ preceding +d+.
31
- def test_hierarchy
32
- root= Node.new('root'); a = Node.new('a', root); b = Node.new('b', a); c = Node.new('c', a); d = Node.new('d', c); e = Node.new('e', root)
33
- verify_closure([root, a, b, c, d, e], root.transitive_closure(:children))
34
- end
35
-
36
- def test_internal
37
- root= Node.new('root'); a = Node.new('a', root); b = Node.new('b', a); c = Node.new('c', a); d = Node.new('d', c); e = Node.new('e', root)
38
- verify_closure([a, b, c, d], a.transitive_closure(:children))
39
- end
40
-
41
- def test_leaf
42
- leaf = Node.new(1)
43
- verify_closure([leaf], leaf.transitive_closure(:children))
44
- end
45
-
46
- def test_collection
47
- a = Node.new('a'); b = Node.new('b'); c = Node.new('c', a); d = Node.new('d', b); e = Node.new('e', c)
48
- verify_closure([a, b, c, d, e], [a, b].transitive_closure(:children))
49
- end
50
-
51
- def test_cycle
52
- root= Node.new('root'); a = Node.new('a', root); b = Node.new('b', a); c = Node.new('c', a); c.children << root
53
- expected = [root, a, b, c].to_set
54
- verify_closure([root, a, b, c], root.transitive_closure(:children))
55
- end
56
-
57
- def verify_closure(content, closure)
58
- assert_equal(content.to_set, closure.to_set, "Hierarchy closure incorrect")
59
- # Verify that no child succeeds the parent.
60
- closure.each_with_index do |node, index|
61
- par = node.parent
62
- if content.include?(par) then
63
- assert(closure.index(par) < index, "Child #{node} precedes parent #{par}")
64
- end
65
- end
66
- end
67
- end
@@ -1,23 +0,0 @@
1
- $:.unshift 'lib'
2
-
3
- require "test/unit"
4
- require 'caruby/util/tree'
5
-
6
- class TreeTest < Test::Unit::TestCase
7
- def test_tree
8
- a = Tree.new(:a)
9
- assert_equal(a.root, :a, "Tree root incorrect")
10
- a << :b
11
- b = a[:b]
12
- assert_not_nil(b, "Subtree not found")
13
- assert_equal(b, a.children.first, "Subtree child not found")
14
- assert_equal(:b, b.root, "Subtree root incorrect")
15
- assert_nil(a[:b, :c], "Subtree at non-existing path incorrect")
16
- b << :c
17
- assert_equal(b[:c], a[:b, :c], "Subtree at path incorrect")
18
- end
19
-
20
- def test_fill
21
- assert_equal(Tree.new(:a).fill(:b, :c).root, :c, "Fill result incorrect")
22
- end
23
- end
@@ -1,14 +0,0 @@
1
- $:.unshift 'lib'
2
-
3
- require "test/unit"
4
- require 'caruby/util/trie'
5
-
6
- class TrieTest < Test::Unit::TestCase
7
- def test_trie
8
- trie = Trie.new
9
- assert_nil(trie[:a], "Non-existing node value incorrect")
10
- trie[:a, :b] = 1
11
- assert_nil(trie[:a], "Existing unvalued node value incorrect")
12
- assert_equal(1, trie[:a, :b], "Trie value incorrect")
13
- end
14
- end
@@ -1,278 +0,0 @@
1
- $:.unshift 'lib'
2
-
3
- # JRuby SyncEnumerator moved from generator to REXML in JRuby 1.5
4
- require 'rexml/document'
5
- require "test/unit"
6
- require 'caruby/util/collection'
7
- require 'caruby/util/visitor'
8
-
9
- class Node
10
- attr_reader :parent, :children, :friends
11
-
12
- attr_accessor :value
13
-
14
- def initialize(value, parent=nil)
15
- @value = value
16
- @children = []
17
- @friends = []
18
- @parent = parent
19
- @parent.children << self if @parent
20
- end
21
-
22
- def <=>(other)
23
- value <=> other.value if other
24
- end
25
-
26
- def to_s
27
- "#{self.class.name}@#{hash}{value => #{value}}"
28
- end
29
-
30
- alias :inspect :to_s
31
- end
32
-
33
- class VistorTest < Test::Unit::TestCase
34
- def test_visit
35
- parent = Node.new(1)
36
- child = Node.new(2, parent)
37
- multiplier = 1
38
- result = CaRuby::Visitor.new { |node| node.children }.visit(parent) { |node| node.value *= (multiplier *= 2) }
39
- assert_equal(2, parent.value, "Visit parent value incorrect")
40
- assert_equal(8, child.value, "Visit child value incorrect")
41
- assert_equal(2, result, "Visit result incorrect")
42
- end
43
-
44
- def test_cycle
45
- parent = Node.new(1)
46
- child = Node.new(2, parent)
47
- child.children << parent
48
- multiplier = 2
49
- CaRuby::Visitor.new { |node| node.children }.visit(parent) { |node| node.value *= multiplier }
50
- assert_equal(2, parent.value, "Cycle parent value incorrect")
51
- assert_equal(4, child.value, "Cycle child value incorrect")
52
- end
53
-
54
- def test_depth_first
55
- parent = Node.new(1)
56
- child = Node.new(2, parent)
57
- multiplier = 1
58
- CaRuby::Visitor.new(:depth_first) { |node| node.children }.visit(parent) { |node| node.value *= (multiplier *= 2) }
59
- assert_equal(4, parent.value, "Depth-first parent value incorrect")
60
- assert_equal(4, child.value, "Depth-first child value incorrect")
61
- end
62
-
63
- def test_return
64
- parent = Node.new(1)
65
- child = Node.new(2, parent)
66
- result = increment(parent, 2)
67
- assert_nil(result, "Pre-emptive return incorrect")
68
- assert_equal(2, parent.value, "Pre-emptive return parent value incorrect")
69
- assert_equal(2, child.value, "Pre-emptive return child value incorrect")
70
- end
71
-
72
- def test_visited_detection
73
- parent = Node.new(1)
74
- child = Node.new(2, parent)
75
- c2 = Node.new(3, parent)
76
- c2.children << child
77
- result = CaRuby::Visitor.new { |node| node.children }.visit(parent) { |node| node.value += 1 }
78
- assert_equal(3, child.value, "Child visited twice")
79
- end
80
-
81
- def test_root_cycle
82
- parent = Node.new(1)
83
- c1 = Node.new(2, parent)
84
- c2 = Node.new(3, parent)
85
- c2.children << parent
86
- gc11 = Node.new(4, c1)
87
- gc12 = Node.new(5, c1)
88
- gc12.children << c1
89
- gc121 = Node.new(6, gc12)
90
- gc121.children << parent
91
- visitor = CaRuby::Visitor.new { |node| node.children }
92
- result = visitor.visit(parent)
93
- assert_equal([[2, 5, 2], [1, 2, 5, 6, 1], [1, 3, 1]], visitor.cycles.map { |cycle| cycle.map { |node| node.value } }, "Root cycles incorrect")
94
- end
95
-
96
- def increment(parent, limit)
97
- CaRuby::Visitor.new { |node| node.children }.visit(parent) { |node| node.value < limit ? node.value += 1 : return }
98
- end
99
-
100
- def test_collection
101
- p1 = Node.new(1)
102
- child = Node.new(2, p1)
103
- p2 = Node.new(3)
104
- p2.children << child
105
- result = CaRuby::Visitor.new { |pair| REXML::SyncEnumerator.new(pair.first.children, pair.last.children).to_a }.to_enum([p1, p2]).map { |pair| [pair.first.value, pair.last.value] }
106
- assert_equal([[1, 3], [2, 2]], result.to_a, "Collection visit result incorrect")
107
- end
108
-
109
- def node_value(node)
110
- node.value if node
111
- end
112
-
113
- def test_enumeration
114
- parent = Node.new(1)
115
- c1 = Node.new(2, parent)
116
- c2 = Node.new(3, parent)
117
- result = CaRuby::Visitor.new { |node| node.children }.to_enum(parent).map { |node| node.value }
118
- assert_equal([1, 2, 3], result, "Enumeration result incorrect")
119
- end
120
-
121
- def test_exclude_cycles
122
- parent = Node.new(1)
123
- c1 = Node.new(2, parent)
124
- gc11 = Node.new(3, c1)
125
- gc11.children << c1
126
- c2 = Node.new(4, parent)
127
- gc21 = Node.new(5, c2)
128
- gc21.children << parent
129
- result = CaRuby::Visitor.new(:prune_cycle) { |node| node.children }.to_enum(parent).map { |node| node.value }
130
- assert_equal([1, 2, 3], result, "Exclude result incorrect")
131
- end
132
-
133
- def test_missing_block
134
- parent = Node.new(1)
135
- c1 = Node.new(2, parent)
136
- c2 = Node.new(3, parent)
137
- visitor = CaRuby::Visitor.new { |node| node.children }
138
- visitor.visit(parent)
139
- assert_equal([parent, c1, c2], visitor.visited.values.sort, "Missing visit operator result incorrect")
140
- end
141
-
142
- def test_filter
143
- parent = Node.new(1)
144
- c1 = Node.new(2, parent)
145
- c2 = Node.new(3, parent)
146
- gc1 = Node.new(4, c1)
147
- gc2 = Node.new(5, c1)
148
- visitor = CaRuby::Visitor.new { |node| node.children }.filter { |parent, children| children.first if parent.value < 4 }
149
- result = visitor.to_enum(parent).map { |node| node.value }
150
- assert_equal([1, 2, 4], result, "Filter result incorrect")
151
- end
152
-
153
- def test_sync_without_block
154
- p1 = Node.new(1)
155
- c11 = Node.new(2, p1)
156
- c12 = Node.new(3, p1)
157
- gc111 = Node.new(4, c11)
158
- gc121 = Node.new(5, c12)
159
- p2 = Node.new(6)
160
- c21 = Node.new(7, p2)
161
- c22 = Node.new(8, p2)
162
- gc211 = Node.new(9, c21)
163
- visitor = CaRuby::Visitor.new { |node| node.children }.sync
164
- result = visitor.to_enum(p1, p2).map { |pair| pair.map { |node| node.value unless node.nil? } }
165
- assert_equal([[1, 6], [2, 7], [4, 9], [3, 8], [5, nil]], result, "Sync without block result incorrect")
166
- end
167
-
168
- def test_sync_with_matcher
169
- p1 = Node.new(1)
170
- c11 = Node.new(2, p1)
171
- c12 = Node.new(3, p1)
172
- gc111 = Node.new(4, c11)
173
- gc121 = Node.new(5, c12)
174
- p2 = Node.new(1)
175
- c21 = Node.new(2, p2)
176
- c22 = Node.new(3, p2)
177
- gc211 = Node.new(5, c21)
178
- visitor = CaRuby::Visitor.new { |node| node.children }
179
- synced = visitor.sync { |nodes, others| nodes.to_compact_hash { |n| others.detect { |o| n.value == o.value } } }
180
- result = synced.to_enum(p1, p2).map { |pair| pair.map { |node| node.value if node } }
181
- assert_equal([[1, 1], [2, 2], [4, nil], [3, 3], [5, nil]], result, "Sync with block result incorrect")
182
- end
183
-
184
- def test_sync_noncollection
185
- p1 = Node.new(1)
186
- child = Node.new(2, p1)
187
- p2 = Node.new(3)
188
- p2.children << child
189
- visitor = CaRuby::Visitor.new { |node| node.children.first }.sync
190
- value_hash = {}
191
- result = visitor.visit(p1, p2) { |first, last| value_hash[node_value(first)] = node_value(last) }
192
- assert_equal({1 => 3, 2 => 2}, value_hash, "Sync with non-collection children result incorrect")
193
- result = visitor.to_enum(p1, p2).map { |first, last| [node_value(first), node_value(last)] }
194
- assert_equal([[1, 3], [2, 2]], result.to_a, "Sync with non-collection children result incorrect")
195
- end
196
-
197
- def test_sync_missing
198
- p1 = Node.new(1)
199
- p2 = Node.new(2)
200
- c1 = Node.new(3, p1)
201
- c2 = Node.new(4, p2)
202
- gcren = Node.new(5, c2)
203
- visitor = CaRuby::Visitor.new { |node| node.children.first }.sync
204
- result = visitor.to_enum(p1, p2).map { |pair| [node_value(pair.first), node_value(pair.last)] }
205
- assert_equal([[1, 2], [3, 4]], result.to_a, "Sync with missing children result incorrect")
206
- end
207
-
208
- def test_missing_node
209
- parent = Node.new(1)
210
- child = Node.new(2, parent)
211
- multiplier = 2
212
- CaRuby::Visitor.new { |node| node.children unless node == child }.visit(parent) { |node| node.value *= multiplier }
213
- assert_equal(2, parent.value, "Missing node parent value incorrect")
214
- assert_equal(4, child.value, "Missing node child value incorrect")
215
- end
216
-
217
- def test_noncollection_traversal
218
- parent = Node.new(1)
219
- child = Node.new(2, parent)
220
- multiplier = 2
221
- CaRuby::Visitor.new { |node| node.parent }.visit(child) { |node| node.value *= multiplier }
222
- assert_equal(2, parent.value, "Non-collection parent value incorrect")
223
- assert_equal(4, child.value, "Non-collection child value incorrect")
224
- end
225
-
226
- def test_parent
227
- parent = Node.new(1)
228
- c1 = Node.new(2, parent)
229
- c2 = Node.new(3, parent)
230
- gc = Node.new(4, c1)
231
- visitor = CaRuby::Visitor.new { |node| node.children }
232
- visitor.visit(parent) { |node| node.value = visitor.parent.nil? ? 0 : visitor.parent.value + 1 }
233
- assert_equal(0, parent.value, "Parent value incorrect")
234
- assert_equal(1, c1.value, "Child value incorrect")
235
- assert_equal(1, c2.value, "Child value incorrect")
236
- assert_equal(2, gc.value, "gc value incorrect")
237
- end
238
-
239
- def test_parent_depth_first
240
- # An interesting variant: the parent node value is not reset until after the children are visited
241
- parent = Node.new(1)
242
- c1 = Node.new(2, parent)
243
- c2 = Node.new(3, parent)
244
- gc = Node.new(4, c1)
245
- visitor = CaRuby::Visitor.new(:depth_first) { |node| node.children }
246
- visitor.visit(parent) { |node| node.value = visitor.parent.nil? ? 0 : visitor.parent.value + 1 }
247
- assert_equal(0, parent.value, "Parent value incorrect")
248
- assert_equal(2, c1.value, "Child value incorrect")
249
- assert_equal(2, c2.value, "Child value incorrect")
250
- assert_equal(3, gc.value, "gc value incorrect")
251
- end
252
-
253
- def test_visited
254
- parent = Node.new(1)
255
- c1 = Node.new(nil, parent)
256
- c2 = Node.new(nil, parent)
257
- gc = Node.new(nil, c1)
258
- visitor = CaRuby::Visitor.new { |node| node.children }
259
- visitor.visit(parent) { |node| node.value ||= visitor.visited[node.parent] + 1 }
260
- assert_equal(1, parent.value, "Parent value incorrect")
261
- assert_equal(2, c1.value, "Child value incorrect")
262
- assert_equal(2, c2.value, "Child value incorrect")
263
- assert_equal(3, gc.value, "gc value incorrect")
264
- end
265
-
266
- def test_visited_result
267
- parent = Node.new(1)
268
- c1 = Node.new(2, parent)
269
- c2 = Node.new(3, parent)
270
- gc = Node.new(4, c1)
271
- visitor = CaRuby::Visitor.new { |node| node.children }
272
- visitor.visit(parent) { |node| node.value + 1 }
273
- assert_equal(2, visitor.visited[parent], "Parent visited value incorrect")
274
- assert_equal(3, visitor.visited[c1], "Child visited value incorrect")
275
- assert_equal(4, visitor.visited[c2], "Child visited value incorrect")
276
- assert_equal(5, visitor.visited[gc], "gc visited value incorrect")
277
- end
278
- end