caruby-core 1.4.4 → 1.4.5

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 (37) hide show
  1. data/History.txt +2 -0
  2. data/README.md +0 -2
  3. data/lib/caruby/migration/migrator.rb +1 -1
  4. data/lib/caruby/version.rb +1 -1
  5. data/test/lib/caruby/csv/csv_mapper_test.rb +40 -0
  6. data/test/lib/caruby/csv/csvio_test.rb +69 -0
  7. data/test/lib/caruby/database/persistable_test.rb +92 -0
  8. data/test/lib/caruby/domain/domain_test.rb +126 -0
  9. data/test/lib/caruby/domain/inversible_test.rb +99 -0
  10. data/test/lib/caruby/domain/reference_visitor_test.rb +130 -0
  11. data/test/lib/caruby/import/java_test.rb +58 -0
  12. data/test/lib/caruby/util/cache_test.rb +23 -0
  13. data/test/lib/caruby/util/class_test.rb +61 -0
  14. data/test/lib/caruby/util/collection_test.rb +379 -0
  15. data/test/lib/caruby/util/command_test.rb +55 -0
  16. data/test/lib/caruby/util/controlled_value_test.rb +26 -0
  17. data/test/lib/caruby/util/domain_extent_test.rb +60 -0
  18. data/test/lib/caruby/util/file_separator_test.rb +30 -0
  19. data/test/lib/caruby/util/inflector_test.rb +12 -0
  20. data/test/lib/caruby/util/lazy_hash_test.rb +34 -0
  21. data/test/lib/caruby/util/merge_test.rb +83 -0
  22. data/test/lib/caruby/util/module_test.rb +29 -0
  23. data/test/lib/caruby/util/options_test.rb +59 -0
  24. data/test/lib/caruby/util/partial_order_test.rb +41 -0
  25. data/test/lib/caruby/util/person_test.rb +115 -0
  26. data/test/lib/caruby/util/pretty_print_test.rb +85 -0
  27. data/test/lib/caruby/util/properties_test.rb +50 -0
  28. data/test/lib/caruby/util/stopwatch_test.rb +18 -0
  29. data/test/lib/caruby/util/topological_sync_enumerator_test.rb +69 -0
  30. data/test/lib/caruby/util/transitive_closure_test.rb +59 -0
  31. data/test/lib/caruby/util/tree_test.rb +23 -0
  32. data/test/lib/caruby/util/trie_test.rb +14 -0
  33. data/test/lib/caruby/util/validation_test.rb +14 -0
  34. data/test/lib/caruby/util/version_test.rb +31 -0
  35. data/test/lib/caruby/util/visitor_test.rb +277 -0
  36. data/test/lib/caruby/util/weak_hash_test.rb +45 -0
  37. metadata +179 -161
@@ -0,0 +1,130 @@
1
+ $:.unshift 'lib'
2
+ $:.unshift 'examples/clinical_trials/lib'
3
+
4
+ require 'test/unit'
5
+
6
+ require 'caruby/util/log' and
7
+ CaRuby::Log.instance.open('test/results/log/clinical_trials.log', :shift_age => 10, :shift_size => 1048576, :debug => true)
8
+
9
+ require 'clinical_trials'
10
+ require 'caruby/domain/reference_visitor'
11
+
12
+ # CaRuby::ReferenceVisitor test cases.
13
+ class ReferenceVisitorTest < Test::Unit::TestCase
14
+ def setup
15
+ super
16
+ coordinator = ClinicalTrials::User.new(:login => 'study.coordinator@test.org')
17
+ address = ClinicalTrials::Address.new(:street => '555 Elm St', :city => 'Burlington', :state => 'VT', :zip_code => '55555')
18
+ @pnt = ClinicalTrials::Participant.new(:name => 'Test Participant', :address => address)
19
+ @study = ClinicalTrials::Study.new(:name => 'Test Study', :coordinator => coordinator, :enrollment => [@pnt])
20
+ @event = ClinicalTrials::StudyEvent.new(:study => @study, :calendar_event_point => 1.0)
21
+ end
22
+
23
+ def test_path_references
24
+ visitor = CaRuby::ReferencePathVisitorFactory.create(ClinicalTrials::Study, [:enrollment, :address])
25
+ assert_equal([@study, @pnt, @pnt.address], visitor.to_enum(@study).to_a, "Path references incorrect")
26
+ end
27
+
28
+ def test_cycles
29
+ # visit all references
30
+ visitor = CaRuby::ReferenceVisitor.new { |ref| ref.class.domain_attributes }
31
+ visitor.visit(@study)
32
+ assert_equal([[@study, @event, @study]], visitor.cycles, "Cycles incorrect")
33
+ end
34
+
35
+ def test_path_attributes
36
+ visitor = CaRuby::ReferencePathVisitorFactory.create(ClinicalTrials::Study, [:enrollment, :address])
37
+ assert_equal([nil, :enrollment, :address], visitor.to_enum(@study).map { visitor.attribute }, "Path attributes incorrect")
38
+ end
39
+
40
+ def test_to_enum
41
+ visitor = CaRuby::ReferencePathVisitorFactory.create(ClinicalTrials::Study, [:enrollment, :address])
42
+ assert_equal([@study, @pnt, @pnt.address], visitor.to_enum(@study).to_a, "Enumeration incorrect")
43
+ end
44
+
45
+ def test_id_match
46
+ # set the source ids
47
+ @study.identifier = 1
48
+ @event.identifier = 2
49
+ # make a match target
50
+ target = CaRuby::CopyVisitor.new { |ref| ref.class.dependent_attributes }.visit(@study)
51
+ # match the source to the target
52
+ matcher = CaRuby::MatchVisitor.new { |ref| ref.class.dependent_attributes }
53
+ matcher.visit(@study, target)
54
+ expected = {@study => target, @event => target.events.first}
55
+ # validate the match
56
+ assert_equal(expected, matcher.matches, "Match incorrect")
57
+ end
58
+
59
+ def test_copy
60
+ visitor = CaRuby::CopyVisitor.new { |ref| ref.class.dependent_attributes }
61
+ copy = visitor.visit(@study)
62
+ assert_not_nil(copy, "Study not copied")
63
+ assert_not_nil(visitor.visited[@study], "#{@study.qp} copy #{copy.qp} not captured in visited #{visitor.visited.qp}")
64
+ assert_same(copy, visitor.visited[@study], "#{@study.qp} visited value incorrect")
65
+ assert_not_same(copy, @study, "#{@study.qp} not copied into #{copy.qp} as new object")
66
+ assert_equal(@study.name, copy.name, "#{@study.qp} attribute not copied")
67
+ assert_nil(copy.coordinator, "#{@study.qp} coordinator incorrectly copied into #{copy.qp} as a dependent")
68
+ assert(!@study.events.empty?, "#{@study.qp} events cleared by copy")
69
+ assert(!copy.events.empty?, "#{@study.qp} events #{@study.events.qp} not copied into #{copy.qp}")
70
+ assert_equal(1, copy.events.size, "#{@study.qp} events copy #{copy.qp} size incorrect")
71
+ assert_not_same(copy.events.first, @study.events.first, "#{@study.qp} event #{@study.events.first} not copied into #{copy.qp} as new object")
72
+ assert_same(copy, copy.events.first.study, "Dependent owner attribute not set to copied owner #{copy.qp}")
73
+ end
74
+
75
+ def test_merge
76
+ # make a merge target
77
+ target = CaRuby::CopyVisitor.new { |ref| ref.class.dependent_attributes }.visit(@study)
78
+ # set the source ids
79
+ @study.identifier = 1
80
+ @event.identifier = 2
81
+
82
+ # merge into the copy
83
+ merger = CaRuby::MergeVisitor.new { |ref| ref.class.dependent_attributes }
84
+ merger.visit(@study, target)
85
+
86
+ # validate that the ids are copied
87
+ assert_equal(@study.identifier, target.identifier, "Merge didn't copy the study identifier")
88
+ assert_not_nil(target.events.first, "Merge didn't copy #{@study.qp} event #{@event.qp} to #{target.qp}")
89
+ assert_equal(target.events.first.identifier, @event.identifier, "Merge didn't copy #{@study.qp} event #{@event.qp} event identifier to #{target.qp}")
90
+ end
91
+
92
+ def test_copy_id_match
93
+ # set the study id
94
+ @study.identifier = 1
95
+ # mutate the references a la caCORE to form reference path @study -> @event -> s2,
96
+ # where @study.identifier == s2.identifier
97
+ s2 = @study.copy(:identifier)
98
+ @event.study = s2
99
+ s2.events.clear
100
+ @study.events << @event
101
+
102
+ # copy the mutated source
103
+ copier = CaRuby::CopyVisitor.new { |ref| ref.class.dependent_attributes }
104
+ copy = copier.visit(@study)
105
+
106
+ # validate the copy
107
+ assert_not_nil(copy.events.first, "Merge didn't copy event")
108
+ assert_same(copy, copy.events.first.study, "Merge didn't match on study id")
109
+ end
110
+
111
+ def test_copy_with_visit_block
112
+ visitor = CaRuby::CopyVisitor.new { |ref| ref.class.domain_attributes }
113
+ id = visitor.visit(@study) { |src, tgt| src.identifier }
114
+ assert_equal(@study.identifier, id, "Visit didn't return block result")
115
+ end
116
+
117
+ def test_copy_revisit_same_object
118
+ # make a new event in the study, resulting in two paths to the study
119
+ ClinicalTrials::StudyEvent.new(:study => @study, :calendar_event_point => 2.0)
120
+ # eliminate extraneous references
121
+ @study.coordinator = nil
122
+ @study.enrollment.clear
123
+ # visit all references, starting at an event, with traversal event -> study -> other event -> study
124
+ visitor = CaRuby::CopyVisitor.new { |ref| ref.class.domain_attributes }
125
+ visited = visitor.visit(@event)
126
+ studies = visitor.visited.select { |ref, copy| ClinicalTrials::Study === ref }
127
+ assert(!studies.empty?, "No study copied")
128
+ assert_equal(1, studies.size, "More than one study copied")
129
+ end
130
+ end
@@ -0,0 +1,58 @@
1
+ $:.unshift 'lib'
2
+ $:.unshift '../caruby/lib'
3
+
4
+ require "test/unit"
5
+ require 'caruby'
6
+
7
+ class JavaTest < Test::Unit::TestCase
8
+ def test_ruby_to_java_date_conversion
9
+ ruby_date = DateTime.now
10
+ java_date = Java::JavaUtil::Date.from_ruby_date(ruby_date)
11
+ actual = java_date.to_ruby_date
12
+ assert(CaRuby::Resource.value_equal?(ruby_date, actual), 'Ruby->Java->Ruby date conversion not idempotent')
13
+ end
14
+
15
+ def test_java_to_ruby_date_conversion
16
+ java_date = Java::JavaUtil::Calendar.instance.time
17
+ ruby_date = java_date.to_ruby_date
18
+ actual = Java::JavaUtil::Date.from_ruby_date(ruby_date)
19
+ assert_equal(java_date.to_s, actual.to_s, 'Java->Ruby->Java date conversion not idempotent')
20
+ assert_equal(java_date.to_ruby_date, ruby_date, 'Java->Ruby date reconversion not equal')
21
+ end
22
+
23
+ def test_to_ruby
24
+ assert_same(Java::JavaUtil::BitSet, Class.to_ruby(java.util.BitSet.java_class), "Java => Ruby class incorrect")
25
+ end
26
+
27
+ def test_list_delete_if
28
+ list = Java::JavaUtil::ArrayList.new << 1 << 2
29
+ assert_same(list, list.delete_if { |n| n == 2 })
30
+ assert_equal([1], list.to_a, "Java ArrayList delete_if incorrect")
31
+ end
32
+
33
+ def test_set_delete_if
34
+ list = Java::JavaUtil::HashSet.new << 1 << 2
35
+ assert_same(list, list.delete_if { |n| n == 2 })
36
+ assert_equal([1], list.to_a, "Java HashSet delete_if incorrect")
37
+ end
38
+
39
+ def test_list_clear
40
+ list = Java::JavaUtil::ArrayList.new
41
+ assert(list.empty?, "Cleared ArrayList not empty")
42
+ assert_same(list, list.clear, "ArrayList clear result incorrect")
43
+ end
44
+
45
+ def test_set_clear
46
+ set = Java::JavaUtil::HashSet.new
47
+ assert(set.empty?, "Cleared HashSet not empty")
48
+ assert_same(set, set.clear, "HashSet clear result incorrect")
49
+ end
50
+
51
+ def test_set_merge
52
+ set = Java::JavaUtil::HashSet.new << 1
53
+ other = Java::JavaUtil::HashSet.new << 2
54
+ assert_same(set, set.merge(other), "HashSet merge result incorrect")
55
+ assert(set.include?(2), "HashSet merge not updated")
56
+ assert_same(set, set.clear, "HashSet clear result incorrect")
57
+ end
58
+ end
@@ -0,0 +1,23 @@
1
+ $:.unshift 'lib'
2
+
3
+ require 'caruby/util/cache'
4
+ require "test/unit"
5
+
6
+ class CacheTest < Test::Unit::TestCase
7
+
8
+ def test_cache
9
+ cache = CaRuby::Cache.new { |n| n % 2 }
10
+ assert_nil(cache[1], "Value mistakenly cached")
11
+ cache.add(1)
12
+ assert_equal(1, cache[1], "Cached value not found")
13
+ assert_nil(cache[2], "Uncached value found")
14
+ assert_equal(1, cache[3], "Cached equivalent not found")
15
+ end
16
+
17
+ def test_cache_factory
18
+ cache = CaRuby::Cache.new(Proc.new { |n| n * 4 }) { |n| n % 2 }
19
+ assert_equal(4, cache[1], "Cached factory value not found")
20
+ assert_equal(8, cache[2], "Cached factory value found")
21
+ assert_equal(4, cache[3], "Cached factory equivalent not found")
22
+ end
23
+ end
@@ -0,0 +1,61 @@
1
+ $:.unshift 'lib'
2
+
3
+ require "test/unit"
4
+ require 'caruby/util/class'
5
+
6
+ class ClassTest < Test::Unit::TestCase
7
+ def ssn
8
+ '555-55-555'
9
+ end
10
+
11
+ def self.redefine_ssn
12
+ redefine_method(:ssn) { |old_method| lambda { send(old_method).delete('-').to_i } }
13
+ end
14
+
15
+ def test_redefine_method
16
+ self.class.redefine_ssn
17
+ assert_equal(55555555, ssn, "Method not redefined correctly")
18
+ end
19
+
20
+ def test_class_hierarchy
21
+ assert_equal([Array, Object], Array.class_hierarchy.to_a, "Class ancestors incorrect")
22
+ end
23
+
24
+ class Person
25
+ attr_reader :social_security_number
26
+ attr_accessor :postal_code
27
+ define_attribute_alias(:ssn, :social_security_number)
28
+ define_attribute_alias(:zip_code, :postal_code)
29
+ end
30
+
31
+ def test_attribute_alias
32
+ assert(Person.method_defined?(:ssn), "Reader alias not defined")
33
+ assert(!Person.method_defined?(:ssn=), "Writer alias incorrectly defined")
34
+ assert(Person.method_defined?(:zip_code), "Reader alias not defined")
35
+ assert(Person.method_defined?(:zip_code=), "Writer alias not defined")
36
+ end
37
+
38
+ class A; end
39
+ class B < A; end
40
+
41
+ def test_range
42
+ assert_equal([B, A, Object], (B..Object).to_a, "Class range incorrect")
43
+ end
44
+
45
+ class OneBased
46
+ attr_accessor :index
47
+ offset_attr_accessor :zero_based_index => :index
48
+ offset_attr_accessor({:two_based_index => :index}, 1)
49
+ end
50
+
51
+ def test_offset_attr_accessor
52
+ x = OneBased.new
53
+ x.index = 1
54
+ assert_equal(0, x.zero_based_index, "Offset reader incorrect")
55
+ x.zero_based_index = 1
56
+ assert_equal(2, x.index, "Offset writer incorrect")
57
+ assert_equal(3, x.two_based_index, "Offset reader incorrect")
58
+ x.two_based_index = 1
59
+ assert_equal(0, x.index, "Offset writer incorrect")
60
+ end
61
+ end
@@ -0,0 +1,379 @@
1
+ $:.unshift 'lib'
2
+
3
+ require "test/unit"
4
+ require 'caruby/util/collection'
5
+
6
+ class CollectionTest < Test::Unit::TestCase
7
+ def test_collection_classifier
8
+ assert([].collection?, "array is not a collecton")
9
+ assert(!nil.collection?, "nil is a collecton")
10
+ assert(!'a'.collection?, "String is a collecton")
11
+ end
12
+
13
+ def test_hashify
14
+ actual = [1, 2, 3].hashify { |key| key + 1 unless key == 2 }
15
+ expected = {1 => 2, 2 => nil, 3 => 4}
16
+ assert_equal(expected, actual, 'Hashify result incorrect')
17
+ end
18
+
19
+ def test_to_compact_hash
20
+ actual = [1, 2, 3].to_compact_hash { |key| key + 1 unless key == 2 }
21
+ expected = {1 => 2, 3 => 4}
22
+ assert_equal(expected, actual, 'Compact hash incorrect')
23
+ end
24
+
25
+ def test_lazy_hash
26
+ hash = LazyHash.new { |n| n * 2 }
27
+ assert_equal(2, hash[1], "Lazy hash value incorrect")
28
+ hash.merge!(2 => 3)
29
+ assert_equal({1 => 2, 2 => 3}, hash, "Lazy hash merge incorrect")
30
+ end
31
+
32
+ def test_array_operator_set_argument
33
+ array = [1, 2, 3]
34
+ set = [3, 4].to_set
35
+ assert_equal([3], array & set, "Array | Set result incorrect")
36
+ assert_equal([1, 2, 3, 4], array | set, "Array | Set result incorrect")
37
+ assert_equal([1, 2], array - set, "Array - Set result incorrect")
38
+ end
39
+
40
+ def test_empty_hash
41
+ assert_raises(NotImplementedError, "Assigment to empty hash succeeds") { Hash::EMPTY_HASH[:a] = 2 }
42
+ end
43
+
44
+ def test_set_first
45
+ assert_equal(1, [1, 2].to_set.first, "first of set incorrect")
46
+ assert_nil(Set.new.first, "first of empty set incorrect")
47
+ end
48
+
49
+ def test_assoc_values_single
50
+ expected = {:a => [1, 3], :b => [2, nil], :c => [nil, 4]}
51
+ actual = {:a => 1, :b => 2}.assoc_values({:a => 3, :c => 4})
52
+ assert_equal(expected, actual, "Association hash incorrect")
53
+ end
54
+
55
+ def test_assoc_values_multiple
56
+ expected = {:a => [1, 3, 4], :b => [2, nil, 5]}
57
+ actual = {:a => 1, :b => 2}.assoc_values({:a => 3}, { :a => 4, :b => 5 })
58
+ assert_equal(expected, actual, "Multiple association hash incorrect")
59
+ end
60
+
61
+ def test_detect_value
62
+ assert_equal(4, [1, 2, 3].detect_value { |item| item * 2 if item > 1 }, "Detect value incorrect")
63
+ assert_nil([1, 2, 3].detect_value { |item| iitem * 2 if item > 3 }, "Value incorrectly detected")
64
+ end
65
+
66
+ def test_detect_with_value
67
+ assert_equal([2, 1], [1, 2].detect_with_value { |item| item / 2 if item % 2 == 0 }, "Detect with value incorrect")
68
+ end
69
+
70
+ def test_array_filter
71
+ base = [1, 2, 3]
72
+ filter = base.filter { |n| n != 2 }
73
+ assert_equal([1, 3], filter.to_a, 'Filter incorrect')
74
+ base << 4
75
+ assert_equal([1, 3, 4], filter.to_a, 'Filter does not reflect operand modification')
76
+ filter << 5
77
+ assert_equal([1, 2, 3, 4, 5], base.to_a, 'Filter does not modify the base')
78
+ end
79
+
80
+ def test_array_filter_without_block
81
+ assert_equal([1, 3], [1, nil, 3, false].filter.to_a, 'Filter incorrect')
82
+ end
83
+
84
+ def test_set_filter_include
85
+ assert([1, 2, 3].to_set.filter { |n| n > 1 }.include?(2), 'Set filter include? incorrect')
86
+ assert(false == [1, 2, 3].to_set.filter { |n| n > 1 }.include?(1), 'Set filter include? incorrect')
87
+ end
88
+
89
+ def test_union
90
+ base = [1, 2]
91
+ sum = base.union([4])
92
+ assert_equal([1, 2, 4], sum.to_a, 'Enumerator union incorrect')
93
+ assert(sum.include?(2), "Enumerator union missing first array element")
94
+ assert(sum.include?(4), "Enumerator union missing second array element")
95
+ base << 3
96
+ assert_equal([1, 2, 3, 4], sum.to_a, 'Enumerator union does not reflect operand modification')
97
+ end
98
+
99
+ def test_intersection
100
+ base = [1, 2, 3, 4]
101
+ other = [3]
102
+ intersection = base.intersect(other)
103
+ assert_equal([3], intersection.to_a, 'Enumerator intersection incorrect')
104
+ other << 4 << 5
105
+ assert_equal([3, 4], intersection.to_a, 'Enumerator intersection does not reflect operand modification')
106
+ end
107
+
108
+ def test_difference
109
+ base = [1, 2, 3]
110
+ diff = base.difference([3])
111
+ assert_equal([1, 2], diff.to_a, 'Enumerator subtraction incorrect')
112
+ base << 4
113
+ assert_equal([1, 2, 4], diff.to_a, 'Enumerator subtraction does not reflect operand modification')
114
+ end
115
+
116
+ def test_wrap
117
+ assert_equal([2, 4, 6], [1, 2, 3].wrap { |n| n * 2 }.to_a, 'Wrap incorrect')
118
+ end
119
+
120
+ def test_enum_addition
121
+ a = [1, 2].filter { true }
122
+ b = [3, 4].filter { true }
123
+ ab = a + b
124
+ assert_equal([1, 2, 3, 4], ab.to_a, "Composite array incorrect")
125
+ a << 3
126
+ assert_equal([1, 2, 3, 3, 4], ab.to_a, "Addition does not reflect change to first enumerable")
127
+ b << 5
128
+ assert_equal([1, 2, 3, 3, 4, 5], ab.to_a, "Addition does not reflect change to second enumerable")
129
+ end
130
+
131
+ def test_hash_union
132
+ a = {:a => 1, :b => 2}
133
+ b = {:b => 3, :c => 4}
134
+ ab = a + b
135
+ assert_equal({:a => 1, :b => 2, :c => 4}, ab.keys.to_compact_hash { |key| ab[key] }, "Hash union incorrect")
136
+ assert_equal([1, 2, 4], ab.values.sort, "Hash union values incorrect")
137
+ a.delete(:b)
138
+ assert_equal({:a => 1, :b => 3, :c => 4}, ab.keys.to_compact_hash { |key| ab[key] }, "Hash union does not reflect underlying change")
139
+ end
140
+
141
+ def test_hash_compose
142
+ x = {:a => :c, :b => :d}
143
+ y = {:c => 1}
144
+ xy = x.compose(y)
145
+ assert_equal({:a => {:c => 1}}, xy.keys.to_compact_hash { |key| xy[key] }, "Composed hash incorrect")
146
+ y[:d] = 2
147
+ assert_equal({:a => {:c => 1}, :b => {:d => 2}}, xy.keys.to_compact_hash { |key| xy[key] }, "Composed hash does not reflect underlying change")
148
+ end
149
+
150
+ def test_hash_join
151
+ x = {:a => :c, :b => :d}
152
+ y = {:c => 1}
153
+ xy = x.join(y)
154
+ assert_equal({:a => 1}, xy.keys.to_compact_hash { |key| xy[key] }, "Joined hash incorrect")
155
+ y[:d] = 2
156
+ assert_equal({:a => 1, :b => 2}, xy.keys.to_compact_hash { |key| xy[key] }, "Joined hash does not reflect underlying change")
157
+ end
158
+
159
+ def test_hash_diff
160
+ x = {:a => 1, :b => 2, :c => 3}
161
+ y = {:b => 2, :c => 4, :d => 5}
162
+ assert_equal({:a => [1,nil], :c => [3,4], :d => [nil,5]}, x.diff(y), "Hash diff incorrect")
163
+ end
164
+
165
+ def test_to_assoc_hash
166
+ actual = [[:a, 1], [:b, 2, 3], [:c], []].to_assoc_hash
167
+ expected = {:a => 1, :b => [2,3], :c => nil}
168
+ assert_equal(expected, actual, 'Association hash incorrect')
169
+ end
170
+
171
+ def test_hashable_equal
172
+ assert_equal({:a => 1}, {:a => 1}.filter, "Hash equal incorrect")
173
+ end
174
+
175
+ def test_hash_enum_keys
176
+ assert_equal([1, 2], { 1 => :a, 2 => :b }.enum_keys.sort)
177
+ end
178
+
179
+ def test_hash_partition
180
+ assert_equal([{:a => 1}, { :b => 2}], { :a => 1, :b => 2 }.partition { |key, value| value < 2 }, "Hash partition incorrect")
181
+ end
182
+
183
+ def test_hash_enum_keys_with_value
184
+ assert_equal([:b, :c], {:a => 1, :b => 2, :c => 2}.enum_keys_with_value(2).to_a, "Hash filtered value keys incorrect")
185
+ end
186
+
187
+ def test_hash_enum_keys_with_value_block
188
+ assert_equal([:b, :c], {:a => 1, :b => 2, :c => 3}.enum_keys_with_value { |value| value > 1 }.to_a, "Hash filtered value block keys incorrect")
189
+ end
190
+
191
+ def test_hash_flatten
192
+ assert_equal([:a, :b, :c, :d, :e, :f, :g], {:a => {:b => :c}, :d => :e, :f => [:g]}.flatten, "Hash flatten incorrect")
193
+ end
194
+
195
+ def test_hash_first
196
+ assert_equal([:a, 1], {:a => 1, :b => 2}.first, "Hash first incorrect")
197
+ end
198
+
199
+ def test_hash_filter
200
+ assert_equal({:a => 1, :c => 3}, {:a => 1, :b => 2, :c => 3}.filter { |k, v| k != :b }, "Hash filter incorrect")
201
+ end
202
+
203
+ def test_hash_sort
204
+ assert_equal([['a', 1], ['b', 2]], {'a'=>1, 'b'=>2}.sort.to_a, "Hash sort incorrect")
205
+ end
206
+
207
+ def test_hash_sort_with_comparator
208
+ assert_equal([[:a, 1], [:b, 2]], {:a => 1, :b => 2}.sort { |k1, k2| k1.to_s <=> k2.to_s }, "Hash sort with comparator incorrect")
209
+ end
210
+
211
+ def test_hash_default_filter
212
+ assert_equal({:a => 1, :c => 3}, {:a => 1, :b => nil, :c => 3}.filter, "Hash default filter incorrect")
213
+ end
214
+
215
+ def test_hash_partition
216
+ assert_equal([{:a => 1, :c => 3}, {:b => 2}], {:a => 1, :b => 2, :c => 3}.hash_partition { |k, v| k == :a or v == 3 }, "Hash partition incorrect")
217
+ end
218
+
219
+ def test_hash_filter_on_key
220
+ filtered = {:a => 1, :b => 2, :c => 3}.filter_on_key { |k| k != :b }
221
+ assert_equal({:a => 1, :c => 3}, filtered.to_hash, "Hash on key filter incorrect")
222
+ assert_equal(1, filtered[:a], "Access on key filter inclusion incorrect")
223
+ assert_nil(filtered[:b], "Access on key filter exclusion incorrect")
224
+ end
225
+
226
+ def test_hash_filter_on_value
227
+ filtered = {:a => 1, :b => 2, :c => 3}.filter_on_value { |v| v != 2 }
228
+ assert_equal({:a => 1, :c => 3}, filtered.to_hash, "Hash on value filter incorrect")
229
+ end
230
+
231
+ def test_hash_compact
232
+ assert_equal({:a => 1, :c => 3}, {:a => 1, :b => nil, :c => 3}.compact.to_hash, "Compact hash incorrect")
233
+ end
234
+
235
+ def test_set_flatten
236
+ inner = Set.new << :a
237
+ actual = [inner, 'b'].flatten
238
+ expected = [:a, 'b']
239
+ assert_equal(expected, actual, 'Inner set not flattened')
240
+ end
241
+
242
+ def test_to_compact_hash
243
+ assert_equal({1 => 2, 2 => 3}, [1, 2].to_compact_hash { |item| item + 1 }, 'to_compact_hash result incorrect')
244
+ end
245
+
246
+ def test_to_compact_hash_with_index
247
+ assert_equal({:a => 1, :b => 2}, [:a, :b].to_compact_hash_with_index { |item, index| index + 1 }, 'to_compact_hash_with_index result incorrect')
248
+ end
249
+
250
+ def test_to_compact_hash_reject_missing
251
+ assert_equal({1 => 2, 2 => 3}, [1, 2, 3].to_compact_hash { |item| item + 1 unless item > 2 }, 'to_compact_hash maps a key with a nil value')
252
+ end
253
+
254
+ def test_series
255
+ actual = [1, 2, 3].to_series
256
+ assert_equal('1, 2 and 3', actual, 'Print string incorrect')
257
+ end
258
+
259
+ def test_empty_series
260
+ actual = [].to_series
261
+ assert_equal('', actual, 'Print string incorrect')
262
+ end
263
+
264
+ def test_singleton_series
265
+ actual = [1].to_series
266
+ assert_equal('1', actual, 'Print string incorrect')
267
+ end
268
+
269
+ def test_copy_recursive
270
+ hash = {1 => { 2 => 3 }, 4 => 5 }
271
+ copy = hash.copy_recursive
272
+ assert_equal(hash, copy, 'Copy not equal')
273
+ hash[1][2] = 6
274
+ assert_equal(3, copy[1][2], 'Copy reflects change to original')
275
+ hash[4] = 7
276
+ assert_equal(5, copy[4], 'Copy reflects change to original')
277
+ end
278
+
279
+ def test_case_insensitive_hash
280
+ hash = CaseInsensitiveHash.new
281
+ hash[:UP] = :down
282
+ assert_equal(:down, hash['up'], "Case-insensitive hash look-up incorrect")
283
+ end
284
+
285
+ def test_transformed_hash
286
+ hash = {:a => 1, :b => 2}
287
+ xfm = hash.transform { |value| value * 2 }
288
+ assert_equal(2, xfm[:a], 'Transformed hash accessor incorrect')
289
+ assert_equal([2, 4], xfm.values.sort, 'Transformed hash values incorrect')
290
+ assert(xfm.has_value?(4), 'Transformed hash value query incorrect')
291
+ assert(!xfm.has_value?(1), 'Transformed hash value query incorrect')
292
+ # base hash should be reflected in transformed hash
293
+ hash[:b] = 3; hash[:c] = 4
294
+ assert_equal(6, xfm[:b], 'Transformed hash does not reflect base hash change')
295
+ assert_equal(8, xfm[:c], 'Transformed hash does not reflect base hash change')
296
+ end
297
+
298
+ def test_key_transformer_hash
299
+ hash = KeyTransformerHash.new { |key| key % 2 }
300
+ hash[1] = :a
301
+ assert_equal(:a, hash[1], 'Key transformer hash entered value not found')
302
+ assert_nil(hash[2], 'Transformed hash unentered value found')
303
+ assert_equal(:a, hash[3], 'Key transformer hash equivalent value not found')
304
+ end
305
+
306
+ def test_hashinator
307
+ base = {:a => 1, :b => 2}.to_a
308
+ hash = Hashinator.new(base)
309
+ assert_equal(base.to_set, hash.to_set, "Hashinator enumeration invalid")
310
+ assert_equal(1, hash[:a], "Hashinator a value invalid")
311
+ assert_equal(2, hash[:b], "Hashinator b value invalid")
312
+ assert_nil(hash[:c], "Hashinator has association not in the base")
313
+ base.first[1] = 3
314
+ assert_equal(3, hash[:a], "Hashinator does not reflect change to underlying Enumerator")
315
+ assert_equal(base, hash.to_hash.to_a, "Hashable to_hash incorrect")
316
+ end
317
+
318
+ def test_collector
319
+ assert_equal([2, [3, 4]], Collector.on([1, [2, 3]]) { |n| n + 1 }, "Collector on nested array incorrect")
320
+ assert_nil(Collector.on(nil) { |n| n + 1 }, "Collector on nil incorrect")
321
+ assert_equal(2, Collector.on(1) { |n| n + 1 }, "Collector on non-collection incorrect")
322
+ end
323
+
324
+ def test_enumerate
325
+ counter = 0
326
+ nil.enumerate { |item| counter += item }
327
+ assert_equal(0, counter, "Enumerate on nil incorrect")
328
+ [1, 2, 3].enumerate { |item| counter += item }
329
+ assert_equal(6, counter, "Enumerate on array incorrect")
330
+ [1, [2, 3]].enumerate { |item| counter += 1 }
331
+ assert_equal(8, counter, "Enumerate on nested array incorrect")
332
+ 2.enumerate { |item| counter += item }
333
+ assert_equal(10, counter, "Enumerate on non-collection incorrect")
334
+ end
335
+
336
+ def test_to_enum
337
+ assert_equal([], nil.to_enum.to_a, "to_enum on nil incorrect")
338
+ assert_equal([1], 1.to_enum.to_a, "to_enum on non-collection incorrect")
339
+ array = [1, 2]
340
+ assert_same(array, array.to_enum, "to_enum on array incorrect")
341
+ s = 'a'
342
+ assert_same(s, s.to_enum, "to_enum on String incorrect")
343
+ end
344
+
345
+ def test_flattener
346
+ assert_equal([1, 2, 3], Flattener.new([1, [2, 3]]).to_a, "Flattener on nested array incorrect")
347
+ assert_equal([], Flattener.new(nil).to_a, "Flattener on nil incorrect")
348
+ assert_equal([1], Flattener.new(1).to_a, "Flattener on non-collection incorrect")
349
+ assert(Flattener.new(nil).all?, "Flattener all? on nil incorrect")
350
+ assert_equal([:b, :c, :e], {:a => {:b => :c}, :d => [:e]}.enum_values.flatten.to_a, "Enumerable flatten incorrect")
351
+ end
352
+
353
+ def test_hash_flattener
354
+ assert_equal([:a, :b, :c], {:a => {:b => :c}}.flatten.to_a, "Hash flatten incorrect")
355
+ assert_equal([:b, :c, :e], {:a => {:b => :c}, :d => [:e]}.enum_values.flatten.to_a, "Enumerable flatten incorrect")
356
+ end
357
+
358
+
359
+ def test_conditional_enumerator
360
+ assert_equal([1, 2], ConditionalEnumerator.new([1, 2, 3]) { |i| i < 3 }.to_a, "ConditionalEnumerator filter not applied")
361
+ end
362
+
363
+ def test_enumerable_size
364
+ assert_equal(2, {:a => 1, :b => 2}.enum_keys.size, "Enumerable size incorrect")
365
+ end
366
+
367
+ def test_set_merge
368
+ set = [1, 2].to_set
369
+ merged = set.merge!([3])
370
+ assert_equal([1, 2, 3].to_set, merged, "Merged set incorrect")
371
+ assert_same(set, merged, "Set merge! did not return same set")
372
+ end
373
+
374
+ def test_set_add_all
375
+ actual = [1, 2].add_all([3])
376
+ expected = [1, 2, 3]
377
+ assert_equal(expected, actual, 'Set content not added')
378
+ end
379
+ end