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
data/History.txt CHANGED
@@ -18,6 +18,8 @@
18
18
 
19
19
  * Merge nondomain collection value properly.
20
20
 
21
+ === 1.4.5 / 2011-02-26
21
22
 
23
+ * Fix default option
22
24
 
23
25
 
data/README.md CHANGED
@@ -6,8 +6,6 @@ caRuby: Simplifying caBIG(TM)
6
6
  **Author**: OHSU Knight Cancer Institute
7
7
  **Copyright**: 2010, 2011
8
8
  **License**: MIT License
9
- **Latest Version**: 1.4.1
10
- **Release Date**: February 25th 2011
11
9
 
12
10
  Synopsis
13
11
  --------
@@ -129,7 +129,7 @@ module CaRuby
129
129
  # create the class => path => header hash
130
130
  fld_map = load_field_map(@fld_map_file)
131
131
  # create the class => path => default value hash
132
- @def_hash = @def_file ? load_defaults(@def_file) : {}
132
+ @def_hash = @def_file ? load_defaults(@def_file) : LazyHash.new { Hash.new }
133
133
  # create the class => paths hash
134
134
  @cls_paths_hash = create_class_paths_hash(fld_map, @def_hash)
135
135
  # create the path => class => header hash
@@ -1,3 +1,3 @@
1
1
  module CaRuby
2
- VERSION = "1.4.4"
2
+ VERSION = "1.4.5"
3
3
  end
@@ -0,0 +1,40 @@
1
+ $:.unshift 'lib'
2
+ $:.unshift 'examples/clinical_trials/lib'
3
+
4
+ require 'set'
5
+ require "test/unit"
6
+ require 'caruby/csv/csv_mapper'
7
+
8
+ require 'caruby/util/log' and
9
+ CaRuby::Log.instance.open('test/results/log/csv.log', :shift_age => 10, :shift_size => 1048576, :debug => true)
10
+
11
+ require 'clinical_trials'
12
+
13
+ class CsvMapperTest < Test::Unit::TestCase
14
+ FIXTURES = File.join('test', 'fixtures', 'caruby', 'csv')
15
+
16
+ CONFIG_DIR = File.join(FIXTURES, 'config')
17
+
18
+ DATA_DIR = File.join(FIXTURES, 'data')
19
+
20
+ def test_read_mapper
21
+ config = File.join(CONFIG_DIR, 'study_fields.yaml')
22
+ csv = File.join(DATA_DIR, 'study.csv')
23
+ mapper = CaRuby::CsvMapper.new(config, ClinicalTrials::StudyEvent, csv)
24
+ assert_equal([ClinicalTrials::StudyEvent], mapper.classes, "Classes incorrect")
25
+ map = {[:calendar_event_point]=>:event_point, [:identifier]=>:id, [:study, :activity_status]=>:status, [:study, :name]=>:study}
26
+ paths = map.keys.to_set
27
+ path_md_sym_hash = mapper.paths(ClinicalTrials::StudyEvent).to_compact_hash { |path| path.map { |attr_md| attr_md.to_sym } }
28
+ assert_equal(paths, path_md_sym_hash.values.to_set, "Paths incorrect")
29
+ path_md_hdr_hash = mapper.paths.to_compact_hash { |path| mapper.header(path) }
30
+ actual = path_md_sym_hash.invert.join(path_md_hdr_hash).to_hash
31
+ assert_equal(map, actual, "Header map incorrect")
32
+ end
33
+
34
+ def test_write_mapper
35
+ config = File.join(CONFIG_DIR, 'study_fields.yaml')
36
+ csv = File.join(DATA_DIR, 'dummy.csv')
37
+ headers = ['Id', 'Study', 'Status', 'Event Point']
38
+ mapper = CaRuby::CsvMapper.new(config, ClinicalTrials::StudyEvent, csv, :mode => 'w', :headers => headers)
39
+ end
40
+ end
@@ -0,0 +1,69 @@
1
+ $:.unshift 'lib'
2
+
3
+ require "test/unit"
4
+ require 'ftools'
5
+ require 'date'
6
+ require 'caruby/csv/csvio'
7
+ require 'caruby/util/log'
8
+ require 'caruby/util/file_separator'
9
+
10
+ class CsvIOTest < Test::Unit::TestCase
11
+ FIXTURES_DIR = File.join('test', 'fixtures', 'caruby', 'csv', 'data')
12
+ OUTPUT_DIR = File.join('test', 'results', 'caruby', 'csv')
13
+ LOG_FILE = File.join('test', 'results', 'log', 'csv.log')
14
+
15
+ def setup
16
+ CaRuby::Log.instance.open(LOG_FILE, :debug => true)
17
+ File.makedirs(OUTPUT_DIR)
18
+ end
19
+
20
+ def test_read
21
+ loader = CsvIO.new(File.join(FIXTURES_DIR, 'variety.csv'))
22
+ loader.each do |row|
23
+ assert_not_nil(row[:id], "Missing id")
24
+ assert_not_nil(row[:string_field], "Missing string_field")
25
+ assert_not_nil(row[:integer], "Missing integer method")
26
+ assert(Integer === row[:integer], "Incorrect integer field value type")
27
+ assert_not_nil(row[:float], "Missing float method")
28
+ assert(Float === row[:float], "Incorrect float field value type")
29
+ assert_not_nil(row[:date], "Missing date method")
30
+ assert_equal(Date, row[:date].class, "Incorrect date field value type")
31
+ end
32
+ end
33
+
34
+ def test_empty
35
+ loader = CsvIO.new(File.join(FIXTURES_DIR, 'empty.csv'))
36
+ row = loader.shift
37
+ assert_nil(row[:one], "Missing value not nil")
38
+ assert_nil(row[:two], "Missing value not nil")
39
+ end
40
+
41
+ def test_accessor
42
+ loader = CsvIO.new(File.join(FIXTURES_DIR, 'variety.csv'))
43
+ assert_equal(:id, loader.accessor('Id'), "Accessor incorrect")
44
+ assert_equal(:string_field, loader.accessor('String Field'), "Accessor incorrect")
45
+ end
46
+
47
+ def test_write
48
+ input = File.join(FIXTURES_DIR, 'variety.csv')
49
+ output = File.join(OUTPUT_DIR, 'variety.csv')
50
+ headers = records = nil
51
+ # Read the input file content.
52
+ File.open(input) do |file|
53
+ headers = file.readline.chomp.split(/,\s*/)
54
+ records = file.map { |line| line.chomp.split(/,\s*/) }
55
+ end
56
+ # Write the output file.
57
+ CsvIO.open(output, :mode => 'w', :headers => headers) do |csvio|
58
+ records.each { |rec| csvio << rec }
59
+ end
60
+ # Compare the output to the input.
61
+ File.open(output) do |file|
62
+ assert_equal(headers, file.readline.chomp.split(/,\s*/), "Headers don't match")
63
+ file.each_with_index do |line, i|
64
+ rec = line.chomp.split(/,\s*/)
65
+ assert_equal(records[i], rec, "Line #{i.succ} doesn't match")
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,92 @@
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
+
11
+ class PersistableTest < Test::Unit::TestCase
12
+
13
+ def setup
14
+ @coord = ClinicalTrials::User.new(:login => 'study.coordinator@test.org')
15
+ address = ClinicalTrials::Address.new(:street => '555 Elm St', :city => 'Burlington', :state => 'VT', :zip_code => '55555')
16
+ @pnt = ClinicalTrials::Participant.new(:name => 'Test Participant')
17
+ @study = ClinicalTrials::Study.new(:name => 'Test Study')
18
+ @evt = ClinicalTrials::StudyEvent.new(:calendar_event_point => 1.0)
19
+ @consent = ClinicalTrials::Consent.new(:statement => 'Test statement')
20
+ @loader = lambda { |obj, attr| load(obj, attr) }
21
+ @@counter = 0
22
+ @study.identifier = @@counter += 1
23
+ @study.add_lazy_loader(@loader)
24
+ @references = {
25
+ @study => {:coordinator => @coord, :enrollment => [@pnt], :study_events => [@evt], :consents => [@consent]},
26
+ @pnt => {:address => address}
27
+ }
28
+ end
29
+
30
+ def test_independent_reference
31
+ assert_not_nil(@study.coordinator, "Independent reference not loaded")
32
+ assert_not_nil(@study.coordinator.identifier, "Independent reference loaded but identifier not set")
33
+ end
34
+
35
+ def test_dependent_reference
36
+ assert_not_nil(@study.events.first, "Dependent events reference not loaded")
37
+ assert_not_nil(@study.events.first.identifier, "Dependent events reference loaded but identifier not set")
38
+ end
39
+
40
+ def test_unidirectional_dependent
41
+ assert_nil(@study.consents.first, "Unidirectional dependent consents reference incorrectly loaded")
42
+ # explicitly set the consents loader
43
+ @study.remove_lazy_loader
44
+ @study.add_lazy_loader(@loader)
45
+ # verify the load merge
46
+ assert_not_nil(@study.consents.first, "Dependent consents reference not loaded")
47
+ assert_not_nil(@study.consents.first.identifier, "Dependent consents reference loaded but identifier not set")
48
+ end
49
+
50
+ def test_unidirectional_dependent_merge
51
+ # explicitly set the consents loader
52
+ @study.remove_lazy_loader
53
+ @study.add_lazy_loader(@loader)
54
+ # verify the load merge
55
+ assert_equal(1, @study.consents.size, "Unambiguous dependent consent not merged")
56
+ assert_not_nil(@study.consents.first.identifier, "Dependent consents reference loaded but identifier not set")
57
+ end
58
+
59
+ def test_unidirectional_dependent_ambiguous_merge
60
+ # add the consent
61
+ @study.consents << @consent
62
+ # make an ambiguous "persistent" consent
63
+ @references[@study][:consents] << @consent.copy
64
+ # explicitly set the consents loader
65
+ @study.remove_lazy_loader
66
+ @study.add_lazy_loader(@loader)
67
+ # verify the load merge
68
+ assert_equal(3, @study.consents.size, "Ambiguous dependent consent not added")
69
+ assert_nil(@consent.identifier, "Consent identifier incorrectly merged from ambiguous dependent consent")
70
+ end
71
+
72
+ # Verifies that the loader is disabled when an attribute is set.
73
+ def test_setter_disable
74
+ @study.coordinator = @coord
75
+ assert_nil(@study.coordinator.identifier, "Independent reference loaded after set")
76
+ end
77
+
78
+ private
79
+
80
+ def load(obj, attribute)
81
+ value = @references[obj][attribute]
82
+ raise ArgumentError.new("Value not found for #{attribute}: #{obj}") if value.nil?
83
+ duplicate_with_id(value)
84
+ end
85
+
86
+ def duplicate_with_id(obj)
87
+ return obj.map { |item| duplicate_with_id(item) } if Enumerable === obj
88
+ copy = obj.copy(obj.class.nondomain_attributes)
89
+ copy.identifier ||= @@counter += 1
90
+ copy
91
+ end
92
+ end
@@ -0,0 +1,126 @@
1
+ $:.unshift 'lib'
2
+ $:.unshift 'examples/clinical_trials/lib'
3
+
4
+ require 'test/unit'
5
+
6
+ # open the logger
7
+ require 'caruby/util/log'
8
+ CaRuby::Log.instance.open('test/results/log/clinical_trials.log', :shift_age => 10, :shift_size => 1048576, :debug => true)
9
+
10
+ require 'clinical_trials'
11
+
12
+ # CaRuby::Resource test cases.
13
+ class DomainTest < Test::Unit::TestCase
14
+ def setup
15
+ super
16
+ @crd = 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 => @crd, :enrollment => [@pnt])
20
+ @evt = ClinicalTrials::StudyEvent.new(:study => @study, :calendar_event_point => 1.0)
21
+ end
22
+
23
+ def test_alias
24
+ assert(ClinicalTrials::Study.method_defined?(:events), "Study alias not recognized: events")
25
+ assert_equal(@pnt.address.zip_code, @pnt.address.postal_code, 'zip_code not aliased to postal_code')
26
+ assert_equal(:zip_code, @pnt.address.class.standard_attribute(:postal_code), 'postal_code does not map to a standard attribute symbol')
27
+ end
28
+
29
+ def test_redefine
30
+ @pnt.address.zip_code = 55555
31
+ assert_equal('55555', @pnt.address.zip_code, "Address zip_code not redefined to support a numeric value")
32
+ end
33
+
34
+ def test_merge_attributes
35
+ assert_same(@study.enrollment.first, @pnt, "Merge incorrect")
36
+ end
37
+
38
+ def test_merge_unambiguous_dependent_collection_attribute
39
+ @study.enrollment.clear
40
+ assert_same(@study.enrollment, @study.merge_attribute(:enrollment, [@pnt]), "Merge collection attribute result incorrect")
41
+ assert_not_nil(@study.enrollment.first, "Merge collection attribute didn't add source item")
42
+ assert_same(@study.enrollment.first, @pnt, "Merge collection attribute incorrect")
43
+ end
44
+
45
+ def test_merge_ambiguous_dependent_collection_attribute
46
+ @study.enrollment.clear
47
+ assert_same(@study.enrollment, @study.merge_attribute(:enrollment, [@pnt]), "Merge collection attribute result incorrect")
48
+ assert_not_nil(@study.enrollment.first, "Merge collection attribute didn't add source item")
49
+ assert_same(@study.enrollment.first, @pnt, "Merge collection attribute incorrect")
50
+ end
51
+
52
+ def test_owner_inverse_setter
53
+ assert_equal([@evt], @study.events.to_a, 'Event not added to owner events')
54
+ # add another event
55
+ # note: calendar_event_point must be unique within the study or it won't be added to the study events set
56
+ @evt.calendar_event_point = 1.0
57
+ ClinicalTrials::StudyEvent.new(:study => @study, :calendar_event_point => 2.0)
58
+ assert_equal(2, @study.events.to_a.size, 'Second event not added to owner events')
59
+ end
60
+
61
+ def test_study_defaults
62
+ assert_nil(@study.activity_status, 'Activity status is already set')
63
+ @study.add_defaults
64
+ assert_equal('Active', @study.activity_status, 'Activity status is not set to default')
65
+ end
66
+
67
+ def test_event_defaults
68
+ @evt.calendar_event_point = nil
69
+ @evt.add_defaults
70
+ assert_equal(1.0, @evt.calendar_event_point, 'Event calendar_event_point is not set to default')
71
+ end
72
+
73
+ # Tests whether add_defaults method propagates to dependents.
74
+ def test_participant_defaults
75
+ assert_nil(@pnt.address.country, 'Participant address country is already set')
76
+ @pnt.add_defaults
77
+ assert_equal('US', @pnt.address.country, 'Participant address country is not set to default')
78
+ end
79
+
80
+ def test_dependents
81
+ assert_equal([@evt], @study.dependents.to_a, "Study dependents incorrect")
82
+ assert(@evt.dependent?, "Event not dependent")
83
+ end
84
+
85
+ def test_searchable_attributes
86
+ assert_equal([:name], @study.searchable_attributes.to_a, "Study finder attributes without identifier incorrect")
87
+ end
88
+
89
+ def test_event_key
90
+ @evt.calendar_event_point = 1.0
91
+ assert_equal([@study, 1.0], @evt.key, "Event key incorrect")
92
+ end
93
+
94
+ # def test_address_key
95
+ # assert_nil(@pnt.address.key, "Address key incorrect")
96
+ # end
97
+
98
+ def test_set_collection_attribute
99
+ consent = ClinicalTrials::Consent.new(:statement => 'Test Statement 1')
100
+ consents = @study.consents << consent
101
+ other_consent = ClinicalTrials::Consent.new(:statement => 'Test Statement 2')
102
+ @study.set_attribute(:consents, [other_consent])
103
+ assert_equal([other_consent], @study.consents.to_a, "Consents not set")
104
+ assert_same(consents, @study.consents)
105
+ end
106
+
107
+ def test_value_hash
108
+ assert_equal({:study => @study}, @evt.value_hash([:identifier, :study]), "Event value hash incorrect")
109
+ end
110
+
111
+ def test_reference_closure
112
+ assert_equal([@study, @evt], @study.reference_hierarchy { |ref| ref.class.dependent_attributes }.to_a, "Reference closure with block incorrect")
113
+ end
114
+
115
+ def test_visit_path
116
+ visited = []
117
+ @study.visit_path([:enrollment, :address]) { |ref| visited << ref }
118
+ assert_equal([@study, @pnt, @pnt.address], visited, "Path visitor incorrect")
119
+ end
120
+
121
+ def test_visit_dependents
122
+ visited = []
123
+ @study.visit_dependents { |ref| visited << ref }
124
+ assert_equal([@study, @evt], visited, "Dependents visitor incorrect")
125
+ end
126
+ end
@@ -0,0 +1,99 @@
1
+ $:.unshift 'lib'
2
+
3
+ require 'caruby'
4
+ require "test/unit"
5
+
6
+ class InversibleTest < Test::Unit::TestCase
7
+ module Domain
8
+ extend CaRuby::ResourceModule
9
+ end
10
+
11
+ module Resource
12
+ include CaRuby::Resource
13
+ attr_accessor :identifier
14
+ end
15
+
16
+ class Person; end
17
+
18
+ class Account
19
+ include Resource
20
+ Domain.add_class(self)
21
+
22
+ attr_accessor :person
23
+ add_attribute(:person, Person)
24
+ end
25
+
26
+ class Person
27
+ include Resource
28
+ Domain.add_class(self)
29
+
30
+ attr_accessor :spouse
31
+ add_attribute(:spouse, Person)
32
+
33
+ set_attribute_inverse(:spouse, :spouse)
34
+
35
+ attr_accessor :account
36
+ add_attribute(:account, Account)
37
+
38
+ set_attribute_inverse(:account, :person)
39
+ end
40
+
41
+ class Child; end
42
+
43
+ class Parent
44
+ include Resource
45
+ Domain.add_class(self)
46
+
47
+ attr_accessor :children
48
+ add_attribute(:children, Child, :collection)
49
+ end
50
+
51
+ class Child
52
+ include Resource
53
+ Domain.add_class(self)
54
+
55
+ attr_accessor :parent
56
+ add_attribute(:parent, Parent)
57
+
58
+ set_attribute_inverse(:parent, :children)
59
+ end
60
+
61
+ def test_1_1
62
+ p1 = Person.new
63
+ a1 = Account.new
64
+ p1.account = a1
65
+ assert_same(p1, a1.person, "1:1 inverse not set")
66
+ a2 = Account.new
67
+ p1.account = a2
68
+ assert_same(p1, a2.person, "1:1 inverse not set")
69
+ assert_nil(a1.person, "1:1 previous inverse not cleared")
70
+ p1.account = nil
71
+ assert_nil(a2.person, "1:1 previous inverse not cleared")
72
+ end
73
+
74
+ def test_1_1_same
75
+ p1 = Person.new
76
+ p2 = Person.new
77
+ p1.spouse = p2
78
+ assert_same(p1, p2.spouse, "1:1 inverse not set")
79
+ p3 = Person.new
80
+ p1.spouse = p3
81
+ assert_same(p3, p1.spouse, "1:1 inverse not set")
82
+ assert_nil(p2.spouse, "1:1 previous inverse not cleared")
83
+ p1.spouse = nil
84
+ assert_nil(p3.spouse, "1:1 previous inverse not cleared")
85
+ end
86
+
87
+ def test_1_m
88
+ p1 = Parent.new
89
+ c = Child.new
90
+ c.parent = p1
91
+ assert_same(c, p1.children.first, "1:M inverse not set")
92
+ p2 = Parent.new
93
+ c.parent = p2
94
+ assert_same(c, p2.children.first, "1:M inverse not set")
95
+ assert(p1.children.empty?, "1:M previous inverse not cleared")
96
+ c.parent = nil
97
+ assert(p2.children.empty?, "1:M previous inverse not cleared")
98
+ end
99
+ end