caruby-core 1.4.7 → 1.4.9
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.
- data/History.txt +11 -0
- data/README.md +1 -1
- data/lib/caruby/cli/command.rb +27 -3
- data/lib/caruby/csv/csv_mapper.rb +2 -0
- data/lib/caruby/csv/csvio.rb +187 -169
- data/lib/caruby/database.rb +33 -16
- data/lib/caruby/database/lazy_loader.rb +23 -23
- data/lib/caruby/database/persistable.rb +32 -18
- data/lib/caruby/database/persistence_service.rb +20 -7
- data/lib/caruby/database/reader.rb +22 -21
- data/lib/caruby/database/search_template_builder.rb +7 -9
- data/lib/caruby/database/sql_executor.rb +52 -27
- data/lib/caruby/database/store_template_builder.rb +18 -13
- data/lib/caruby/database/writer.rb +107 -44
- data/lib/caruby/domain/attribute_metadata.rb +35 -25
- data/lib/caruby/domain/java_attribute_metadata.rb +43 -20
- data/lib/caruby/domain/merge.rb +9 -5
- data/lib/caruby/domain/reference_visitor.rb +4 -3
- data/lib/caruby/domain/resource_attributes.rb +52 -12
- data/lib/caruby/domain/resource_dependency.rb +129 -42
- data/lib/caruby/domain/resource_introspection.rb +1 -1
- data/lib/caruby/domain/resource_inverse.rb +20 -3
- data/lib/caruby/domain/resource_metadata.rb +20 -4
- data/lib/caruby/domain/resource_module.rb +190 -124
- data/lib/caruby/import/java.rb +39 -19
- data/lib/caruby/migration/migratable.rb +31 -6
- data/lib/caruby/migration/migrator.rb +126 -40
- data/lib/caruby/migration/uniquify.rb +0 -1
- data/lib/caruby/resource.rb +28 -5
- data/lib/caruby/util/attribute_path.rb +0 -2
- data/lib/caruby/util/class.rb +8 -5
- data/lib/caruby/util/collection.rb +5 -3
- data/lib/caruby/util/domain_extent.rb +0 -3
- data/lib/caruby/util/options.rb +10 -9
- data/lib/caruby/util/person.rb +41 -12
- data/lib/caruby/util/pretty_print.rb +1 -1
- data/lib/caruby/util/validation.rb +0 -28
- data/lib/caruby/version.rb +1 -1
- data/test/lib/caruby/import/java_test.rb +26 -9
- data/test/lib/caruby/migration/test_case.rb +103 -0
- data/test/lib/caruby/test_case.rb +231 -0
- data/test/lib/caruby/util/class_test.rb +2 -2
- data/test/lib/caruby/util/visitor_test.rb +3 -2
- data/test/lib/examples/galena/clinical_trials/migration/participant_test.rb +28 -0
- data/test/lib/examples/galena/clinical_trials/migration/test_case.rb +40 -0
- metadata +195 -170
- data/lib/caruby/domain/attribute_initializer.rb +0 -16
- data/test/lib/caruby/util/validation_test.rb +0 -14
data/lib/caruby/resource.rb
CHANGED
@@ -17,7 +17,7 @@ module CaRuby
|
|
17
17
|
# This module defines essential common domain methods that enable the jRuby-Java API bridge.
|
18
18
|
# Classes which include Domain must implement the +metadata+ Domain::Metadata accessor method.
|
19
19
|
module Resource
|
20
|
-
include Mergeable, Migratable, Persistable, Inversible
|
20
|
+
include Mergeable, Migratable, Persistable, Inversible
|
21
21
|
|
22
22
|
# JRuby alert - Bug #5090 - JRuby 1.5 object_id no longer reserved, results in String value.
|
23
23
|
# See http://jira.codehaus.org/browse/JRUBY-5090.
|
@@ -25,6 +25,7 @@ module CaRuby
|
|
25
25
|
#
|
26
26
|
# @return [Integer] the object id
|
27
27
|
def proxy_object_id
|
28
|
+
# make a hash code on demand
|
28
29
|
@_hc ||= (Object.new.object_id * 31) + 17
|
29
30
|
end
|
30
31
|
|
@@ -54,8 +55,13 @@ module CaRuby
|
|
54
55
|
end
|
55
56
|
self
|
56
57
|
end
|
58
|
+
|
59
|
+
# Sets the default attribute values for this auto-generated domain object.
|
60
|
+
def add_defaults_autogenerated
|
61
|
+
add_defaults_recursive
|
62
|
+
end
|
57
63
|
|
58
|
-
# Validates this domain object and its #{ResourceAttributes.
|
64
|
+
# Validates this domain object and its #{ResourceAttributes.unproxied_save_template_attributes}
|
59
65
|
# for completeness prior to a database create operation.
|
60
66
|
# An object without an identifer is valid if it contains a non-nil value for each mandatory property.
|
61
67
|
# Objects which have an identifier or have already been validated are skipped.
|
@@ -69,7 +75,7 @@ module CaRuby
|
|
69
75
|
validate_local
|
70
76
|
@validated = true
|
71
77
|
end
|
72
|
-
self.class.
|
78
|
+
self.class.unproxied_save_template_attributes.each do |attr|
|
73
79
|
send(attr).enumerate { |dep| dep.validate }
|
74
80
|
end
|
75
81
|
self
|
@@ -167,6 +173,12 @@ module CaRuby
|
|
167
173
|
def owner
|
168
174
|
self.class.owner_attributes.detect_value { |attr| send(attr) }
|
169
175
|
end
|
176
|
+
|
177
|
+
# @return [Symbol, nil] the attribute for which there is an owner reference,
|
178
|
+
# or nil if this domain object does not reference an owner
|
179
|
+
def effective_owner_attribute
|
180
|
+
self.class.owner_attributes.detect { |attr| send(attr) }
|
181
|
+
end
|
170
182
|
|
171
183
|
# Sets this dependent's owner attribute to the given domain object.
|
172
184
|
#
|
@@ -430,7 +442,7 @@ module CaRuby
|
|
430
442
|
# @yieldparam [Resource] owner the domain object to print
|
431
443
|
# @return [String] the domain object content
|
432
444
|
def dump(&selector)
|
433
|
-
|
445
|
+
do_without_lazy_loader { DetailPrinter.new(self, &selector).pp_s }
|
434
446
|
end
|
435
447
|
|
436
448
|
# Prints this domain object in the format:
|
@@ -708,7 +720,18 @@ module CaRuby
|
|
708
720
|
attr_md = self.class.attribute_metadata(attribute)
|
709
721
|
attr_md.property_descriptor.property_type if JavaAttributeMetadata === attr_md
|
710
722
|
end
|
711
|
-
|
723
|
+
|
724
|
+
# Executes the given block with the database lazy loader disabled, if any.
|
725
|
+
#
|
726
|
+
# @yield the block to execute
|
727
|
+
def do_without_lazy_loader(&block)
|
728
|
+
if database then
|
729
|
+
database.lazy_loader.disable(&block)
|
730
|
+
else
|
731
|
+
yield
|
732
|
+
end
|
733
|
+
end
|
734
|
+
|
712
735
|
# Returns the source => target hash of matches for the given attr_md newval sources and
|
713
736
|
# oldval targets. If the matcher block is given, then that block is called on the sources
|
714
737
|
# and targets. Otherwise, {Resource.match_all} is called.
|
@@ -2,8 +2,6 @@ require 'caruby/util/validation'
|
|
2
2
|
|
3
3
|
# An AttributePath encapsulates an array of attributes that can be evaluated on a source object.
|
4
4
|
class AttributePath < Array
|
5
|
-
include Validation
|
6
|
-
|
7
5
|
# Creates an AttributePath from the path Array, String or Symbol. A path string is a period-delimited sequence
|
8
6
|
# of attributes, e.g. +person.name+.
|
9
7
|
def initialize(path)
|
data/lib/caruby/util/class.rb
CHANGED
@@ -13,21 +13,21 @@ class Class
|
|
13
13
|
alias :succ :superclass
|
14
14
|
|
15
15
|
private
|
16
|
-
|
16
|
+
|
17
17
|
# Creates an alias for each accessor method of the given attribute.
|
18
18
|
#
|
19
19
|
# @example
|
20
20
|
# class Person
|
21
21
|
# attr_reader :social_security_number
|
22
22
|
# attr_accessor :postal_code
|
23
|
-
#
|
24
|
-
#
|
23
|
+
# alias_attribute(:ssn, :social_security_number)
|
24
|
+
# alias_attribute(:zip_code, :postal_code)
|
25
25
|
# end
|
26
26
|
# Person.method_defined?(:ssn) #=> true
|
27
27
|
# Person.method_defined?(:ssn=) #=> false
|
28
28
|
# Person.method_defined?(:zip_code) #=> true
|
29
29
|
# Person.method_defined?(:zip_code=) #=> true
|
30
|
-
def
|
30
|
+
def alias_attribute(aliaz, attribute)
|
31
31
|
alias_method(aliaz, attribute) if method_defined?(attribute)
|
32
32
|
writer = "#{attribute}=".to_sym
|
33
33
|
alias_method("#{aliaz}=".to_sym, writer) if method_defined?(writer)
|
@@ -117,7 +117,10 @@ class Class
|
|
117
117
|
# The block creates a proc which implements the new method body.
|
118
118
|
#
|
119
119
|
# @example
|
120
|
-
# redefine_method(:ssn) { |
|
120
|
+
# redefine_method(:ssn) { |omth| lambda { send(omth).delete('-').to_i } }
|
121
|
+
# @param [Symbol] method the method to redefine
|
122
|
+
# @yield [old_method] the redefinition Proc
|
123
|
+
# @yieldparam old_method [Symbol] the method being redefined
|
121
124
|
# @return [Symbol] an alias to the old method implementation
|
122
125
|
def redefine_method(method)
|
123
126
|
# make a new alias id method__base for the existing method.
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'set'
|
2
2
|
require 'delegate'
|
3
3
|
require 'enumerator'
|
4
|
-
require 'generator'
|
5
4
|
require 'caruby/util/class'
|
6
5
|
require 'caruby/util/validation'
|
7
6
|
require 'caruby/util/options'
|
@@ -229,10 +228,12 @@ module Enumerable
|
|
229
228
|
# @yield [item] the transformer on the enumerated items
|
230
229
|
# @yieldparam item an enumerated item
|
231
230
|
# @return [Enumerable] an enumeration on the transformed values
|
232
|
-
def
|
231
|
+
def transform(&mapper)
|
233
232
|
Transformer.new(self, &mapper)
|
234
233
|
end
|
235
234
|
|
235
|
+
alias :wrap :transform
|
236
|
+
|
236
237
|
def join(other)
|
237
238
|
Joiner.new(self, other)
|
238
239
|
end
|
@@ -276,7 +277,7 @@ module Enumerable
|
|
276
277
|
# @param item the item to add
|
277
278
|
# @return [Filter] self
|
278
279
|
def <<(item)
|
279
|
-
@base <<
|
280
|
+
@base << item
|
280
281
|
self
|
281
282
|
end
|
282
283
|
|
@@ -794,6 +795,7 @@ module Hashable
|
|
794
795
|
include Hashable
|
795
796
|
|
796
797
|
def initialize(*hashes)
|
798
|
+
if hashes.include?(nil) then raise ArgumentError.new("MultiHash is missing a component hash.") end
|
797
799
|
@hashes = hashes
|
798
800
|
end
|
799
801
|
|
@@ -7,8 +7,6 @@ require 'caruby/util/validation'
|
|
7
7
|
# @example
|
8
8
|
# DomainExtent.new { |klass, key| key.to_s + klass.name }.get(String, 'a') #=> aString
|
9
9
|
class DomainExtent < LazyHash
|
10
|
-
include Validation
|
11
|
-
|
12
10
|
# Creates a new DomainExtent. The block passed to the constructor
|
13
11
|
# is a factory to create an object on demand, with arguments
|
14
12
|
# the target class and the target key. The default block is empty.
|
@@ -24,7 +22,6 @@ class DomainExtent < LazyHash
|
|
24
22
|
# The factory accepts a single argument, the instance key, e.g.
|
25
23
|
# set_factory(MyClass) { |key| MyClass.new(key) }
|
26
24
|
def set_factory(klass, &factory)
|
27
|
-
validate_type(klass => Class)
|
28
25
|
# the current instances, if any
|
29
26
|
instances = fetch(klass) if has_key?(klass)
|
30
27
|
# make the key => instance class extent map
|
data/lib/caruby/util/options.rb
CHANGED
@@ -30,15 +30,16 @@ class Options
|
|
30
30
|
def self.get(option, options, default=nil, &block)
|
31
31
|
return default(default, &block) if options.nil?
|
32
32
|
case options
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
33
|
+
when Hash then
|
34
|
+
value = options[option]
|
35
|
+
if String === value then value.strip! end
|
36
|
+
value.nil_or_empty? ? default(default, &block) : value
|
37
|
+
when Enumerable then
|
38
|
+
options.include?(option) ? true : default(default, &block)
|
39
|
+
when Symbol then
|
40
|
+
option == options ? true : default(default, &block)
|
41
|
+
else
|
42
|
+
raise ArgumentError.new("Options argument type is not supported; expected Hash or Symbol, found: #{options.class}")
|
42
43
|
end
|
43
44
|
end
|
44
45
|
|
data/lib/caruby/util/person.rb
CHANGED
@@ -4,12 +4,29 @@ require 'caruby/util/validation'
|
|
4
4
|
module CaRuby
|
5
5
|
module Person
|
6
6
|
class Name
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
# @return [String] the salutation, e.g. 'Mr.'
|
8
|
+
attr_accessor :salutation
|
9
|
+
|
10
|
+
# @return [String] the trailing name qualifier, e.g. 'III'
|
11
|
+
attr_accessor :qualifier
|
12
|
+
|
13
|
+
# @return [String] the trailing name credentials, e.g. 'MD'
|
14
|
+
attr_accessor :credentials
|
15
|
+
|
16
|
+
# @return [String] the first name
|
17
|
+
attr_reader :first
|
18
|
+
|
19
|
+
# @return [String] the middle name
|
20
|
+
attr_reader :middle
|
21
|
+
|
22
|
+
# @return [String] the ;ast name
|
23
|
+
attr_reader :last
|
11
24
|
|
12
25
|
# Creates a new Name with the required last and optional first and middle components.
|
26
|
+
#
|
27
|
+
# @param [String] last the required last name
|
28
|
+
# @param [String, nil] first the optional first name
|
29
|
+
# @param [String, nil] middle the optional middle name
|
13
30
|
def initialize(last, first=nil, middle=nil)
|
14
31
|
# replace empty with nil
|
15
32
|
@first = first unless first == ''
|
@@ -17,7 +34,8 @@ module CaRuby
|
|
17
34
|
@middle = middle unless middle == ''
|
18
35
|
end
|
19
36
|
|
20
|
-
#
|
37
|
+
# @return [(String, String, String)] this Name as an array consisting of the first,
|
38
|
+
# middle and last fields
|
21
39
|
#
|
22
40
|
# @example
|
23
41
|
# Person.parse("Abe Lincoln").to_a #=> ["Abe", nil, "Lincoln"]
|
@@ -25,14 +43,14 @@ module CaRuby
|
|
25
43
|
[@first, @middle, @last]
|
26
44
|
end
|
27
45
|
|
28
|
-
#
|
46
|
+
# @return [String] this Name in the format [Salutation] First [Middle] Last[, Credentials]
|
29
47
|
def to_s
|
30
48
|
name_s = [salutation, first, middle, last, qualifier].reject { |part| part.nil? }.join(' ')
|
31
49
|
name_s << ', ' << credentials if credentials
|
32
50
|
name_s
|
33
51
|
end
|
34
52
|
|
35
|
-
#
|
53
|
+
# @return [Boolean] whether this Person's first, middle and last name components equal the other Person's
|
36
54
|
def ==(other)
|
37
55
|
self.class == other.class and first == other.first and middle == other.middle and last == other.last
|
38
56
|
end
|
@@ -44,12 +62,15 @@ module CaRuby
|
|
44
62
|
# * [salutation] [first [middle]] last [qualifier] [, credentials]
|
45
63
|
# where _salutation_ ends in a period.
|
46
64
|
#
|
47
|
-
#
|
65
|
+
# Example input:
|
48
66
|
# * Longfellow, Henry Wadsworth
|
49
67
|
# * Longfellow, Henry Gallifant Wadsworth
|
50
68
|
# * Henry Longfellow
|
51
69
|
# * Longfellow
|
52
70
|
# * Mr. Henry Wadsworth Longfellow III, MD, Ph.D.
|
71
|
+
#
|
72
|
+
# @param [String] name_s the name to parse
|
73
|
+
# @return [Name] the parsed Name
|
53
74
|
def self.parse(name_s)
|
54
75
|
return if name_s.blank?
|
55
76
|
# the name component variables
|
@@ -94,8 +115,8 @@ module CaRuby
|
|
94
115
|
name
|
95
116
|
end
|
96
117
|
|
97
|
-
#
|
98
|
-
# or if there is a middle name but no first name
|
118
|
+
# @raise [ValidationError] if there is neither a first nor a last name
|
119
|
+
# or if there is a middle name but no first name
|
99
120
|
def validate
|
100
121
|
if last.nil? and first.nil? then
|
101
122
|
raise ValidationError.new("Name is missing both the first and last fields")
|
@@ -105,12 +126,20 @@ module CaRuby
|
|
105
126
|
end
|
106
127
|
end
|
107
128
|
|
108
|
-
#
|
129
|
+
# @param [String] s a name fragment
|
130
|
+
# @return [Boolean] whether the fragment ends in a period
|
109
131
|
def self.salutation?(s)
|
110
132
|
s =~ /\.$/
|
111
133
|
end
|
112
134
|
|
113
|
-
# Returns whether
|
135
|
+
# Returns whether the given name fragment is a recognized qualifier. The following
|
136
|
+
# qualifiers are recognized:
|
137
|
+
# * +Jr+ with optional period
|
138
|
+
# * +Sr+ with optional period
|
139
|
+
# * +I+, +II+ or +III+
|
140
|
+
#
|
141
|
+
# @param [String] s a name fragment
|
142
|
+
# @return [Boolean] whether s is a recognized qualifier
|
114
143
|
def self.qualifier?(s)
|
115
144
|
s and (s =~ /[J|S]r[.]?/ or s =~ /\AI+\Z/)
|
116
145
|
end
|
@@ -18,31 +18,3 @@ class Object
|
|
18
18
|
nil? or (respond_to?(:empty?) and empty?)
|
19
19
|
end
|
20
20
|
end
|
21
|
-
|
22
|
-
module Validation
|
23
|
-
# A Validator is a procedure which responds to the +validate(value)+ method.
|
24
|
-
class Validator < Proc
|
25
|
-
alias :validate :call
|
26
|
-
end
|
27
|
-
|
28
|
-
# Validates that each key value in the value_type_assns value => type hash is an instance of the associated class.
|
29
|
-
#
|
30
|
-
# Raises ValidationError if the value is missing.
|
31
|
-
# Raises TypeError if the value is not the specified type.
|
32
|
-
def validate_type(value_type_assns)
|
33
|
-
TYPE_VALIDATOR.validate(value_type_assns)
|
34
|
-
end
|
35
|
-
|
36
|
-
private
|
37
|
-
|
38
|
-
def self.create_type_validator
|
39
|
-
Validator.new do |value_type_assns|
|
40
|
-
value_type_assns.each do |value, type|
|
41
|
-
raise ArgumentError.new("Missing #{type.name} argument") if value.nil?
|
42
|
-
raise TypeError.new("Unsupported argument type; expected: #{type.name} found: #{value.class.name}") unless type === value
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
TYPE_VALIDATOR = create_type_validator
|
48
|
-
end
|
data/lib/caruby/version.rb
CHANGED
@@ -6,18 +6,26 @@ require 'caruby'
|
|
6
6
|
|
7
7
|
class JavaTest < Test::Unit::TestCase
|
8
8
|
def test_ruby_to_java_date_conversion
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
assert(CaRuby::Resource.value_equal?(ruby_date, actual), 'Ruby->Java->Ruby date conversion not idempotent')
|
9
|
+
rdt = DateTime.now
|
10
|
+
jdt = Java::JavaUtil::Date.from_ruby_date(rdt)
|
11
|
+
assert(CaRuby::Resource.value_equal?(rdt, jdt.to_ruby_date), 'Ruby->Java->Ruby date conversion not idempotent')
|
13
12
|
end
|
14
13
|
|
15
14
|
def test_java_to_ruby_date_conversion
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
15
|
+
cal = Java::JavaUtil::Calendar.instance
|
16
|
+
verify_java_to_ruby_date_conversion(cal.time)
|
17
|
+
# roll back to a a different DST setting
|
18
|
+
if cal.timeZone.useDaylightTime then
|
19
|
+
verify_java_to_ruby_date_conversion(flip_DST(cal))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def flip_DST(cal)
|
24
|
+
isdt = cal.timeZone.inDaylightTime(cal.time)
|
25
|
+
11.times do
|
26
|
+
cal.roll(Java::JavaUtil::Calendar::MONTH, false)
|
27
|
+
return cal.time if cal.timeZone.inDaylightTime(cal.time) != isdt
|
28
|
+
end
|
21
29
|
end
|
22
30
|
|
23
31
|
def test_to_ruby
|
@@ -55,4 +63,13 @@ class JavaTest < Test::Unit::TestCase
|
|
55
63
|
assert(set.include?(2), "HashSet merge not updated")
|
56
64
|
assert_same(set, set.clear, "HashSet clear result incorrect")
|
57
65
|
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def verify_java_to_ruby_date_conversion(jdate)
|
70
|
+
rdt = jdate.to_ruby_date
|
71
|
+
actual = Java::JavaUtil::Date.from_ruby_date(rdt)
|
72
|
+
assert_equal(jdate.to_s, actual.to_s, 'Java->Ruby->Java date conversion not idempotent')
|
73
|
+
assert_equal(jdate.to_ruby_date, rdt, 'Java->Ruby date reconversion not equal')
|
74
|
+
end
|
58
75
|
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
LOG_FILE = 'test/results/log/migration.log'
|
2
|
+
|
3
|
+
require File.join(File.dirname(__FILE__), '..', 'test_case')
|
4
|
+
require 'caruby/domain/uniquify'
|
5
|
+
require 'caruby/migration/migrator'
|
6
|
+
|
7
|
+
module CaRuby
|
8
|
+
module MigrationTestCase
|
9
|
+
include CaRuby::TestCase
|
10
|
+
|
11
|
+
#@param [String] fixtures the fixtures directory
|
12
|
+
def setup(fixtures, database=nil)
|
13
|
+
super(database)
|
14
|
+
@fixtures = fixtures
|
15
|
+
# Clear the uniquifier for this migration.
|
16
|
+
CaRuby::ResourceUniquifier.instance.clear
|
17
|
+
end
|
18
|
+
|
19
|
+
## MIGRATION TEST UTILITY METHODS ##
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
# Runs a migrator on the given input fixture and options.
|
24
|
+
#
|
25
|
+
# @param (see #create_migrator)
|
26
|
+
# @option (see #create_migrator)
|
27
|
+
def migrate_to_database(fixture, opts={}, &verifier)
|
28
|
+
mgtr = create_migrator(fixture, opts)
|
29
|
+
logger.debug { "Migration test migrating #{fixture} fixture..." }
|
30
|
+
mgtr.migrate_to_database(&verifier)
|
31
|
+
logger.debug { "Migration test migrated #{fixture} fixture." }
|
32
|
+
end
|
33
|
+
|
34
|
+
# Creates a new Migrator for the given fixture with the given options.
|
35
|
+
# If a factory block is provided, then that factory is called to make a new
|
36
|
+
# Migrator instance. Otherwise, {CaTissue::Migrator#initialize} makes the instance.
|
37
|
+
#
|
38
|
+
# If there is no :input option, then the migration input is set to the
|
39
|
+
# _fixture_.+csv+ file in the {#initialize} fixtures directory.
|
40
|
+
#
|
41
|
+
# @param [Symbol] fixture the migration test fixture
|
42
|
+
# @param [{Symbol => Object}] opts (see CaTissue::Migrator#initialize)
|
43
|
+
# @option (see CaTissue::Migrator#initialize)
|
44
|
+
# @return [CaTissue::Migrator]
|
45
|
+
# @yield [opts] the optional Migrator factory
|
46
|
+
def create_migrator(fixture, opts={}, &factory)
|
47
|
+
opts[:quiet] = true
|
48
|
+
opts[:input] ||= File.join(@fixtures, fixture.to_s + '.csv')
|
49
|
+
block_given? ? yield(opts) : CaRuby::Migrator.new(opts)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Verifies that the given test fixture is successfully migrated.
|
53
|
+
# Each migrated target object is validated using {CaTissue::TestCase#verify_saved}.
|
54
|
+
# In addition, if a verifier block is given to this method, then that block is
|
55
|
+
# called on the target migration object, or nil if no target was migrated.
|
56
|
+
# Supported options are described in {CaTissue::Migrator#migrate}.
|
57
|
+
#
|
58
|
+
# @param (see #verify_target)
|
59
|
+
# @option (see #verify_target)
|
60
|
+
# @yield (see #verify_target)
|
61
|
+
# @yieldparam (see #verify_target)
|
62
|
+
def verify_save(fixture, opts={})
|
63
|
+
logger.debug { "Migrating the #{fixture} test fixture..." }
|
64
|
+
opts[:unique] = true unless opts.has_key?(:unique)
|
65
|
+
migrate_to_database(fixture, opts) do |tgt|
|
66
|
+
verify_saved(tgt)
|
67
|
+
yield tgt if block_given?
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# Verifies the given fixture migration.
|
72
|
+
# Each migrated target object is validated using {#validate_target}.
|
73
|
+
# The target is migrated but not stored.
|
74
|
+
#
|
75
|
+
# @param [Symbol] fixture the test fixture to verify
|
76
|
+
# @param [<Symbol>] opts the migration options
|
77
|
+
# @option (see CaTissue::Migrator#migrate)
|
78
|
+
# @yield [target] verifies the given target
|
79
|
+
# @yieldparam [Resource] target the domain object to verify
|
80
|
+
def verify_target(fixture, opts={}, &verifier)
|
81
|
+
opts[:unique] ||= false
|
82
|
+
create_migrator(fixture, opts).migrate { |tgt| validate_target(tgt, &verifier) }
|
83
|
+
end
|
84
|
+
|
85
|
+
# Validates that the given target was successfully migrated.
|
86
|
+
# If a target was migrated, then this method calls {CaTissue::TestCase#verify_defaults}
|
87
|
+
# to confirm that the target can be stored.
|
88
|
+
# In addition, if a block is given to this method then the block is called on the
|
89
|
+
# (possibly nil) migration target.
|
90
|
+
#
|
91
|
+
# @param [Resource] target the domain object to verify
|
92
|
+
# @yield (see #verify_target)
|
93
|
+
# @yieldparam (see #verify_target)
|
94
|
+
def validate_target(target)
|
95
|
+
assert_not_nil(target, "Missing target")
|
96
|
+
logger.debug { "Validating migration target #{target}..." }
|
97
|
+
verify_defaults(target) if target
|
98
|
+
yield target if block_given?
|
99
|
+
logger.debug { "Validated migration target #{target}." }
|
100
|
+
target
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|