caruby-tissue 1.3.1 → 1.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. data/History.txt +4 -0
  2. data/README.md +6 -0
  3. data/lib/catissue/annotation/annotation_class.rb +1 -1
  4. data/lib/catissue/cli/migrate.rb +1 -0
  5. data/lib/catissue/domain/container.rb +13 -8
  6. data/lib/catissue/domain/specimen.rb +9 -3
  7. data/lib/catissue/domain/specimen_event_parameters.rb +1 -8
  8. data/lib/catissue/domain/specimen_requirement.rb +1 -1
  9. data/lib/catissue/domain/storage_container.rb +4 -3
  10. data/lib/catissue/domain/uniquify.rb +82 -0
  11. data/lib/catissue/migration/migrator.rb +15 -7
  12. data/lib/catissue/migration/uniquify.rb +2 -111
  13. data/lib/catissue/util/position.rb +14 -2
  14. data/lib/catissue/version.rb +1 -1
  15. data/test/fixtures/catissue/domain/conf/catissue_override.yaml +9 -0
  16. data/test/fixtures/catissue/extract/conf/scg_extract.yaml +3 -0
  17. data/test/fixtures/catissue/extract/conf/scg_fields.yaml +3 -0
  18. data/test/fixtures/catissue/extract/conf/spc_extract.yaml +3 -0
  19. data/test/fixtures/catissue/extract/conf/spc_fields.yaml +4 -0
  20. data/test/fixtures/lib/catissue/defaults_test_fixture.rb +202 -0
  21. data/test/lib/catissue/database/controlled_values_test.rb +47 -0
  22. data/test/lib/catissue/database/database_test.rb +28 -0
  23. data/test/lib/catissue/domain/address_test.rb +53 -0
  24. data/test/lib/catissue/domain/base_haemotology_pathology_test.rb +25 -0
  25. data/test/lib/catissue/domain/ca_tissue_test_defaults_test.rb +27 -0
  26. data/test/lib/catissue/domain/capacity_test.rb +12 -0
  27. data/test/lib/catissue/domain/collection_event_parameters_test.rb +24 -0
  28. data/test/lib/catissue/domain/collection_protocol_event_test.rb +25 -0
  29. data/test/lib/catissue/domain/collection_protocol_registration_test.rb +71 -0
  30. data/test/lib/catissue/domain/collection_protocol_test.rb +69 -0
  31. data/test/lib/catissue/domain/container_position_test.rb +29 -0
  32. data/test/lib/catissue/domain/department_test.rb +21 -0
  33. data/test/lib/catissue/domain/disposal_event_parameters_test.rb +16 -0
  34. data/test/lib/catissue/domain/location_test.rb +38 -0
  35. data/test/lib/catissue/domain/metadata_test.rb +62 -0
  36. data/test/lib/catissue/domain/participant_medical_identifier_test.rb +26 -0
  37. data/test/lib/catissue/domain/participant_test.rb +96 -0
  38. data/test/lib/catissue/domain/site_test.rb +30 -0
  39. data/test/lib/catissue/domain/specimen_array_test.rb +38 -0
  40. data/test/lib/catissue/domain/specimen_array_type_test.rb +27 -0
  41. data/test/lib/catissue/domain/specimen_characteristics_test.rb +15 -0
  42. data/test/lib/catissue/domain/specimen_collection_group_test.rb +216 -0
  43. data/test/lib/catissue/domain/specimen_event_parameters_test.rb +61 -0
  44. data/test/lib/catissue/domain/specimen_position_test.rb +62 -0
  45. data/test/lib/catissue/domain/specimen_requirement_test.rb +61 -0
  46. data/test/lib/catissue/domain/specimen_test.rb +272 -0
  47. data/test/lib/catissue/domain/storage_container_test.rb +150 -0
  48. data/test/lib/catissue/domain/storage_type_test.rb +70 -0
  49. data/test/lib/catissue/domain/transfer_event_parameters_test.rb +38 -0
  50. data/test/lib/catissue/domain/user_test.rb +50 -0
  51. data/test/lib/catissue/extract/delta_test.rb +25 -0
  52. data/test/lib/catissue/extract/extractor_test.rb +43 -0
  53. data/test/lib/catissue/import/importable_module_test.rb +14 -0
  54. data/test/lib/catissue/migration/test_case.rb +103 -0
  55. data/test/lib/catissue/test_case.rb +225 -0
  56. data/test/lib/examples/galena/domain/examples_test.rb +70 -0
  57. data/test/lib/examples/galena/migration/catissue.log +0 -0
  58. data/test/lib/examples/galena/migration/filter_test.rb +26 -0
  59. data/test/lib/examples/galena/migration/frozen_test.rb +28 -0
  60. data/test/lib/examples/galena/migration/general_test.rb +44 -0
  61. data/test/lib/examples/galena/migration/simple_test.rb +29 -0
  62. data/test/lib/examples/galena/migration/test_case.rb +52 -0
  63. data/test/lib/examples/galena/migration/uniquify.rb +93 -0
  64. metadata +223 -184
@@ -0,0 +1,9 @@
1
+ # Tests merging attribute properites.
2
+
3
+ secondary_key_attributes:
4
+ CollectionProtocol:
5
+ - title
6
+
7
+ required_attributes:
8
+ CollectionProtocol:
9
+ - sequenceNumber
@@ -0,0 +1,3 @@
1
+ fields: test/fixtures/catissue/extract/conf/scg_fields.yaml
2
+ output: test/results/catissue/extract/scg.csv
3
+ target: SpecimenCollectionGroup
@@ -0,0 +1,3 @@
1
+ MRN: registration.participant_identifier
2
+ SPN: surgical_pathology_number
3
+ Collection Date: collection_event_parameters.timestamp
@@ -0,0 +1,3 @@
1
+ fields: test/fixtures/catissue/extract/conf/spc_fields.yaml
2
+ output: test/results/catissue/extract/spc.csv
3
+ target: TissueSpecimen
@@ -0,0 +1,4 @@
1
+ MRN: specimen_collection_group.registration.participant_identifier
2
+ SPN: specimen_collection_group.surgical_pathology_number
3
+ Collection Date: specimen_collection_group.collection_event_parameters.timestamp
4
+ Quantity: initial_quantity
@@ -0,0 +1,202 @@
1
+ require 'singleton'
2
+ require 'caruby/util/uniquifier'
3
+ require 'catissue'
4
+
5
+ module CaTissueTest
6
+ # Error setting up the test fixture.
7
+ class TestError < RuntimeError; end
8
+
9
+ def self.defaults
10
+ Defaults.instance
11
+ end
12
+
13
+ # caTissue test default admin fixture.
14
+ class Defaults
15
+ include Singleton, Enumerable
16
+
17
+ attr_reader :tissue_bank, :protocol, :registration, :specimen,
18
+ :specimen_requirement, :specimen_collection_group, :box
19
+
20
+ def initialize
21
+ super
22
+ populate
23
+ end
24
+
25
+ # Retusns this fixture's domain objects.
26
+ def domain_objects
27
+ instance_variables.map { |iv| instance_eval iv }.select { |value| CaRuby::Resource === value }
28
+ end
29
+
30
+ # Adds default values to this fixture's domain objects.
31
+ def add_defaults
32
+ domain_objects.each { |obj| obj.add_defaults unless obj.equal?(specimen) }
33
+ # Add specimen default values last, since SCG add_specimens propagates the collection event
34
+ # necessary to set the default specimen label.
35
+ specimen.add_defaults
36
+ self
37
+ end
38
+
39
+ # Fetches the default instances from the database. Creates new objects if necesssary.
40
+ #
41
+ # Raises ValidationError if a domain object fails validation.
42
+ def validate
43
+ # identifiers are required for validation; these are removed following validation
44
+ objs_without_ids = domain_objects.select { |obj| obj.identifier.nil? }
45
+ objs_without_ids.each_with_index { |obj, index| obj.identifier = index + 1 }
46
+ domain_objects.each { |obj| obj.validate }
47
+ # restore null identifiers
48
+ objs_without_ids.each { |obj| obj.identifier = nil }
49
+ self
50
+ end
51
+
52
+ # Creates this fixture's {#domain_objects} in the database, if necessary.
53
+ def ensure_exists
54
+ domain_objects.each { |obj| obj.find(:create) unless obj.identifier or obj.class.dependent? }
55
+ end
56
+
57
+ # Repopulates the defaults and makes a unique collection_protocol short_title, participant MRN and
58
+ # specimen label.
59
+ #
60
+ # @return this fixture
61
+ def uniquify
62
+ populate
63
+ # make the CP and MRN unique; these values will ripple through the SCG, CPR, et al.
64
+ # to make them unique as well
65
+ @protocol.short_title = @protocol.short_title.uniquify
66
+ @registration.participant.medical_identifiers.each { |mid| mid.medical_record_number = Uniquifier.qualifier }
67
+ # unset the SCG name and specimen label so the default is set to a new unique value
68
+ @specimen_collection_group.name = @specimen.label = nil
69
+ self
70
+ end
71
+
72
+ private
73
+
74
+ # Adds data to this fixture.
75
+ #
76
+ # @return this fixture
77
+ def populate
78
+ logger.debug { "Populating the test fixture..." }
79
+ # the test institution
80
+ inst = CaTissue::Institution.new(:name => 'Test Institution')
81
+
82
+ # the standard test address
83
+ addr = CaTissue::Address.new
84
+ addr.city = 'Test City'
85
+ addr.state = 'Other'
86
+ addr.country = 'Niue'
87
+ addr.zipCode = '55555'
88
+ addr.street = '555 Test St'
89
+ addr.phoneNumber = '555-555-5555'
90
+
91
+ # the test department
92
+ dept = CaTissue::Department.new(:name => 'Test Department')
93
+
94
+ # the test cancer center
95
+ cc = CaTissue::CancerResearchGroup.new(:name => 'Test Cancer Center')
96
+
97
+ # the test tissue bank coordinator
98
+ coord = CaTissue::User.new
99
+ coord.loginName = coord.emailAddress = 'test_coordinator@example.edu'
100
+ coord.lastName = 'Coordinator'
101
+ coord.firstName = 'Test'
102
+ coord.address = addr.copy
103
+ coord.institution = inst
104
+ coord.department = dept
105
+ coord.cancer_research_group = cc
106
+ coord.add_defaults
107
+
108
+ # the test surgeon
109
+ surgeon = CaTissue::User.new
110
+ surgeon.loginName = surgeon.emailAddress = 'test_surgeon@example.edu'
111
+ surgeon.lastName = 'Scientist'
112
+ surgeon.firstName = 'Test'
113
+ surgeon.address = addr.copy
114
+ surgeon.institution = inst
115
+ surgeon.department = dept
116
+ surgeon.cancer_research_group = cc
117
+
118
+ # the test PI
119
+ pi = CaTissue::User.new
120
+ pi.loginName = pi.emailAddress = 'test_scientist@example.edu'
121
+ pi.lastName = 'Scientist'
122
+ pi.firstName = 'Test'
123
+ pi.address = addr.copy
124
+ pi.institution = inst
125
+ pi.department = dept
126
+ pi.cancer_research_group = cc
127
+
128
+ # the test hospital
129
+ hospital = CaTissue::Site.new(
130
+ :site_type => CaTissue::Site::SiteType::COLLECTION,
131
+ :name => 'Test Collection Site',
132
+ :address => addr.copy,
133
+ :coordinator => coord
134
+ )
135
+
136
+ # the test tissue bank
137
+ @tissue_bank = CaTissue::Site.new(
138
+ :site_type => CaTissue::Site::SiteType::REPOSITORY,
139
+ :name => 'Test Tissue Bank',
140
+ :address => addr.copy,
141
+ :coordinator => coord
142
+ )
143
+
144
+ # the test participant
145
+ pnt = CaTissue::Participant.new(:name => 'Test Participant')
146
+
147
+ # add the participant mrn
148
+ mrn = 555555
149
+ pnt.add_mrn(hospital, mrn)
150
+
151
+ # the test collection protocol
152
+ @protocol = CaTissue::CollectionProtocol.new(
153
+ :short_title => 'Test CP',
154
+ :principal_investigator => pi
155
+ )
156
+
157
+ # the test consent tier
158
+ ctier = CaTissue::ConsentTier.new(:statement => 'Test Consent Statement')
159
+ @protocol.consent_tiers << ctier
160
+
161
+ # the collection event template
162
+ cpe = CaTissue::CollectionProtocolEvent.new(:protocol => @protocol)
163
+
164
+ # the participant collection registration
165
+ @registration = @protocol.register(pnt)
166
+ # add a consent tier response
167
+ rsp = CaTissue::ConsentTierResponse.new(:consent_tier => ctier)
168
+ @registration.consent_tier_responses << rsp
169
+
170
+ # the specimen requirement template
171
+ @specimen_requirement = CaTissue::TissueSpecimenRequirement.new(
172
+ :collection_event => cpe,
173
+ :specimen_type => 'Frozen Tissue',
174
+ :specimen_characteristics => CaTissue::SpecimenCharacteristics.new,
175
+ :pathological_status => 'Malignant')
176
+
177
+ # the sole tissue specimen
178
+ @specimen = CaTissue::Specimen.create_specimen(:requirement => @specimen_requirement, :initial_quantity => 4.0)
179
+
180
+ # the SCG
181
+ @specimen_collection_group = @protocol.add_specimens(
182
+ @specimen,
183
+ :participant => pnt,
184
+ :collection_event => cpe,
185
+ :collection_site => hospital,
186
+ :receiver => coord)
187
+
188
+ # a storage container
189
+ frz_type = CaTissue::StorageType.new(:name => 'Test Freezer', :columns => 10, :rows => 1, :row_label => 'Rack')
190
+ rack_type = CaTissue::StorageType.new(:name => 'Test Rack', :columns => 10, :rows => 10)
191
+ box_type = CaTissue::StorageType.new(:name => 'Test Box', :columns => 10, :rows => 10)
192
+ frz_type << rack_type
193
+ rack_type << box_type
194
+ box_type << 'Tissue'
195
+ # a sample freezer box
196
+ @box = CaTissue::StorageContainer.new(:storage_type => box_type, :site => @tissue_bank)
197
+
198
+ logger.debug { "Test fixture populated." }
199
+ self
200
+ end
201
+ end
202
+ end
@@ -0,0 +1,47 @@
1
+ $:.unshift 'lib'
2
+ $:.unshift '../caruby/lib'
3
+
4
+ require "test/unit"
5
+ require 'caruby/util/log'
6
+ require 'caruby/util/uniquifier'
7
+ require 'catissue/database/controlled_values'
8
+
9
+ class ControlledValuesTest < Test::Unit::TestCase
10
+ LOG_FILE = 'test/results/catissue/log/catissue.log'
11
+
12
+ def setup
13
+ CaRuby::Log.instance.open(LOG_FILE, :debug => true)
14
+ end
15
+
16
+ # works but takes a long time
17
+ # def test_search_by_public_id
18
+ # tissue_sites = CaTissue::ControlledValues.instance.for_public_id(:tissue_site)
19
+ # assert_not_nil(tissue_sites, "Tissue site CVs not loaded")
20
+ # parent = tissue_sites.detect { |cv| cv.value == 'DIGESTIVE ORGANS' }
21
+ # assert_not_nil(parent, "DIGESTIVE ORGANS tissue site CVs not loaded")
22
+ # child = parent.children.detect { |cv| cv.value == 'ESOPHAGUS' }
23
+ # assert_not_nil(child, "DIGESTIVE ORGANS CV missing ESOPHAGUS child")
24
+ # gc = child.children.detect { |cv| cv.value == 'Esophagus, NOS' }
25
+ # assert_not_nil(gc, "ESOPHAGUS CV missing 'Esophagus, NOS' child")
26
+ # assert(!parent.children.include?(gc), "DIGESTIVE ORGANS CV children incorrectly includes ESOPHAGUS child")
27
+ # assert(parent.descendants.include?(gc), "DIGESTIVE ORGANS CV missing 'Esophagus, NOS' descendant")
28
+ # end
29
+
30
+ def test_find
31
+ assert_not_nil(CaTissue::ControlledValues.instance.find(:tissue_site, 'Esophagus, NOS'), "'Esophagus, NOS' CV not found")
32
+ end
33
+
34
+ def test_find_case_insensitive
35
+ assert_not_nil(CaTissue::ControlledValues.instance.find(:tissue_site, 'esophagus, NOS'), "Case-insensitive look-up inoperative")
36
+ end
37
+
38
+ def test_create_delete
39
+ cv = CaTissue::ControlledValue.new
40
+ cv.public_id = :tissue_site
41
+ cv.value = 'Test Tissue Site'.uniquify
42
+ assert_same(cv, CaTissue::ControlledValues.instance.create(cv), "CV not created")
43
+ assert_same(cv, CaTissue::ControlledValues.instance.find(cv.public_id, cv.value), "Created CV not found")
44
+ assert_nothing_raised("CV not deleted") { CaTissue::ControlledValues.instance.delete(cv) }
45
+ assert_nil(CaTissue::ControlledValues.instance.find(cv.public_id, cv.value), "Deleted CV found")
46
+ end
47
+ end
@@ -0,0 +1,28 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_case')
2
+
3
+ class CaTissueDatabaseTest < Test::Unit::TestCase
4
+ LOG_FILE = 'test/results/catissue/log/catissue.log'
5
+
6
+ def setup
7
+ CaRuby::Log.instance.open(LOG_FILE, :debug => true)
8
+ @database = CaTissue::Database.instance
9
+ end
10
+
11
+ def test_match_specimen
12
+ a = CaTissue::TissueSpecimen.new(:specimen_type => 'Fresh Tissue')
13
+ b = CaTissue::TissueSpecimen.new(:specimen_type => 'Fresh Tissue')
14
+ c1 = a.derive(:specimen_type => 'Fixed Tissue')
15
+ c2 = a.derive(:specimen_type => 'Fixed Tissue')
16
+ d = b.derive(:specimen_type => 'Fixed Tissue')
17
+ e1 = a.derive(:specimen_type => 'Frozen Tissue', :pathological_status => 'Normal')
18
+ e2 = a.derive(:specimen_type => 'Frozen Tissue', :pathological_status => 'Malignant')
19
+ f1 = b.derive(:specimen_type => 'Frozen Tissue', :pathological_status => 'Malignant')
20
+ f2 = b.derive(:specimen_type => 'Frozen Tissue', :pathological_status => 'Normal')
21
+ f3 = b.derive(:specimen_type => 'Frozen Tissue', :pathological_status => 'Normal')
22
+ actual = @database.instance_eval do
23
+ collect_matches([a, e1, c1, e2, c2], [f1, b, f2, d, f3])
24
+ end
25
+ expected = {a => b, c1 => d, e1 => f2, e2 => f1}
26
+ assert_equal(expected, actual, "Specimen match incorrect")
27
+ end
28
+ end
@@ -0,0 +1,53 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_case')
2
+ require 'caruby/util/uniquifier'
3
+
4
+ class AddressTest < Test::Unit::TestCase
5
+ include CaTissue::TestCase
6
+
7
+ def setup
8
+ super
9
+ # make the unique test address
10
+ @address = CaTissue::Address.new
11
+ @address.city = 'Test City'
12
+ @address.state = 'Other'
13
+ @address.country = 'US'
14
+ @address.zip_code = '55555'
15
+ @address.street = '555'.uniquify + ' Test St'
16
+ @address.phone_number = '555-555-5555'
17
+ end
18
+
19
+ # Tests the key method for a domain class without a secondary key.
20
+ def test_non_secondary_key
21
+ # make an address
22
+ @address = CaTissue::Address.new
23
+ @address.identifier = 1
24
+ expected = @address.identifier
25
+ assert_equal(expected, @address.key, 'Key incorrect')
26
+ end
27
+
28
+ def test_defaults
29
+ verify_defaults(@address)
30
+ end
31
+
32
+ def test_merge_identifier
33
+ from = CaTissue::User.new(:address => @address)
34
+ to = CaTissue::User.new(:address => @address.copy)
35
+ from.address.identifier = 555
36
+ to.merge_attributes(from)
37
+ assert_equal(555, to.address.identifier, "Address identifier not merged")
38
+ end
39
+
40
+ def test_save
41
+ database.create(@address)
42
+ assert_not_nil(@address.identifier, "Address not created")
43
+ @address.zip_code = '111111'
44
+ @address.phone_number = nil
45
+ database.update(@address)
46
+ template = @address.copy
47
+ template.zip_code = nil
48
+ fetched = database.query(template).first
49
+ assert_not_nil(fetched, "Address not found")
50
+ assert_equal('111111', fetched.zip_code, "Address zipcode not updated")
51
+ assert_nil(fetched.phone_number, "Address phone number not cleared by update")
52
+ end
53
+ end
@@ -0,0 +1,25 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_case')
2
+ require 'test/fixtures/lib/catissue/defaults_test_fixture'
3
+
4
+ class BaseHaematologyPathologyTest < Test::Unit::TestCase
5
+ include CaTissue::TestCase
6
+
7
+ def setup
8
+ super
9
+ @scg = defaults.specimen_collection_group
10
+ @annotation = CaTissue::PathologyScg::BaseHaematologyPathologyAnnotation.new(:specimen_collection_group => @scg)
11
+ @histology = CaTissue::PathologyScg::HistologicType.new(:base_pathology_annotation => @annotation, :histologic_type => 'Adenocarcinoma - NOS')
12
+ @finding = CaTissue::PathologyScg::AdditionalFinding.new(:base_pathology_annotation => @annotation, :pathologic_finding => 'Test finding')
13
+ @details = CaTissue::PathologyScg::Details.new(:additional_finding => @finding, :detail => 'Test detail')
14
+ end
15
+
16
+ def test_dependents
17
+ assert_equal([@histology], @annotation.histologic_type.to_a, "Annotation histologic types incorrect")
18
+ assert_equal([@finding], @annotation.additional_finding.to_a, "Annotation additional findings incorrect")
19
+ assert_equal([@details], @finding.details.to_a, "Finding details incorrect")
20
+ end
21
+
22
+ def test_save
23
+ verify_save(@annotation)
24
+ end
25
+ end
@@ -0,0 +1,27 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_case')
2
+ require 'test/fixtures/lib/catissue/defaults_test_fixture'
3
+
4
+ class CaTissueTestDefaultsTest < Test::Unit::TestCase
5
+ include CaTissue::TestCase
6
+
7
+ attr_reader :defaults
8
+
9
+ def setup
10
+ super
11
+ @defaults = CaTissueTest::Defaults.instance
12
+ end
13
+
14
+ def test_validation
15
+ assert_nothing_raised(ValidationError, "Defaults validation unsuccessful") { defaults.add_defaults.validate }
16
+ end
17
+
18
+ # Fetches the test data, creating new objects if necessary
19
+ def test_find
20
+ assert_nothing_raised(CaRuby::DatabaseError, "Defaults store unsuccessful") { defaults.each { |obj| database.find(obj) } }
21
+ end
22
+
23
+ # Store the test data
24
+ def test_save
25
+ defaults.each { |obj| verify_save(obj) }
26
+ end
27
+ end
@@ -0,0 +1,12 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_case')
2
+
3
+ class CapacityTest < Test::Unit::TestCase
4
+ include CaTissue::TestCase
5
+
6
+ # Verifies the :rows and :columns aliases.
7
+ def test_merge_attributes
8
+ cpc = CaTissue::Capacity.new(:columns => 5, :rows => 5)
9
+ assert_equal(5, cpc.one_dimension_capacity, "Rows incorrect")
10
+ assert_equal(5, cpc.two_dimension_capacity, "Columns incorrect")
11
+ end
12
+ end
@@ -0,0 +1,24 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_case')
2
+
3
+ class CollectionEventParametersTest < Test::Unit::TestCase
4
+ include CaTissue::TestCase
5
+
6
+ attr_reader :event_params
7
+
8
+ def setup
9
+ super
10
+ scg = CaTissue::SpecimenCollectionGroup.new
11
+ collector = CaTissue::User.new
12
+ @event_params = CaTissue::SpecimenEventParameters.create_parameters(:collection, scg, :user => collector)
13
+ end
14
+
15
+ def test_defaults
16
+ event_params.add_defaults
17
+ assert_not_nil(event_params.timestamp, 'Timestamp not set to default')
18
+ end
19
+
20
+ # Test updating an auto-created CollectionEventParameters
21
+ def test_create
22
+
23
+ end
24
+ end