caruby-core 1.4.4 → 1.4.5

Sign up to get free protection for your applications and to get access to all the features.
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