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.
- data/History.txt +2 -0
- data/README.md +0 -2
- data/lib/caruby/migration/migrator.rb +1 -1
- data/lib/caruby/version.rb +1 -1
- data/test/lib/caruby/csv/csv_mapper_test.rb +40 -0
- data/test/lib/caruby/csv/csvio_test.rb +69 -0
- data/test/lib/caruby/database/persistable_test.rb +92 -0
- data/test/lib/caruby/domain/domain_test.rb +126 -0
- data/test/lib/caruby/domain/inversible_test.rb +99 -0
- data/test/lib/caruby/domain/reference_visitor_test.rb +130 -0
- data/test/lib/caruby/import/java_test.rb +58 -0
- data/test/lib/caruby/util/cache_test.rb +23 -0
- data/test/lib/caruby/util/class_test.rb +61 -0
- data/test/lib/caruby/util/collection_test.rb +379 -0
- data/test/lib/caruby/util/command_test.rb +55 -0
- data/test/lib/caruby/util/controlled_value_test.rb +26 -0
- data/test/lib/caruby/util/domain_extent_test.rb +60 -0
- data/test/lib/caruby/util/file_separator_test.rb +30 -0
- data/test/lib/caruby/util/inflector_test.rb +12 -0
- data/test/lib/caruby/util/lazy_hash_test.rb +34 -0
- data/test/lib/caruby/util/merge_test.rb +83 -0
- data/test/lib/caruby/util/module_test.rb +29 -0
- data/test/lib/caruby/util/options_test.rb +59 -0
- data/test/lib/caruby/util/partial_order_test.rb +41 -0
- data/test/lib/caruby/util/person_test.rb +115 -0
- data/test/lib/caruby/util/pretty_print_test.rb +85 -0
- data/test/lib/caruby/util/properties_test.rb +50 -0
- data/test/lib/caruby/util/stopwatch_test.rb +18 -0
- data/test/lib/caruby/util/topological_sync_enumerator_test.rb +69 -0
- data/test/lib/caruby/util/transitive_closure_test.rb +59 -0
- data/test/lib/caruby/util/tree_test.rb +23 -0
- data/test/lib/caruby/util/trie_test.rb +14 -0
- data/test/lib/caruby/util/validation_test.rb +14 -0
- data/test/lib/caruby/util/version_test.rb +31 -0
- data/test/lib/caruby/util/visitor_test.rb +277 -0
- data/test/lib/caruby/util/weak_hash_test.rb +45 -0
- metadata +179 -161
data/History.txt
CHANGED
data/README.md
CHANGED
@@ -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
|
data/lib/caruby/version.rb
CHANGED
@@ -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
|