caruby-core 1.5.3 → 1.5.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -46,9 +46,11 @@ module CaRuby
46
46
  #
47
47
  # @return [Resource] self
48
48
  def add_defaults
49
- # apply owner defaults
50
- if owner and owner.identifier.nil? then
51
- owner.add_defaults
49
+ # If there is an owner, then delegate to the owner.
50
+ # Otherwise, add defaults to this object.
51
+ par = owner
52
+ if par and par.identifier.nil? then
53
+ par.add_defaults
52
54
  else
53
55
  logger.debug { "Adding defaults to #{qp} and its dependents..." }
54
56
  # apply the local and dependent defaults
@@ -625,14 +625,6 @@ module Hashable
625
625
  filter_on_value { |value| not value.nil? }
626
626
  end
627
627
 
628
- # Partitions this Hashable into two Hashables based on the given filter block
629
- #
630
- # @yield [key, value] the partition block
631
- # @return [(Hashable, Hashable)] the partitioned result
632
- def hash_partition(&block)
633
- [filter(&block), filter { |k, v| not yield(k, v) }]
634
- end
635
-
636
628
  # Returns the difference between this Hashable and the other Hashable in a Hash of the form:
637
629
  #
638
630
  # _key_ => [_mine_, _theirs_]
@@ -753,14 +745,14 @@ module Hashable
753
745
  def flatten
754
746
  Flattener.new(self).to_a
755
747
  end
756
-
748
+
757
749
  # @yield [key, value] hash splitter
758
- # @return [Hash] two hashes split by whether calling the block on the
750
+ # @return [(Hash, Hash)] two hashes split by whether calling the block on the
759
751
  # entry returns a non-nil, non-false value
760
752
  # @example
761
- # {:a => 1, :b => 2}.partition { |key, value| value < 2 } #=> [{:a => 1}, {:b => 2}]
762
- def partition(&block)
763
- super(&block).map { |pairs| pairs.to_assoc_hash }
753
+ # {:a => 1, :b => 2}.split { |key, value| value < 2 } #=> [{:a => 1}, {:b => 2}]
754
+ def split(&block)
755
+ partition(&block).map { |pairs| pairs.to_assoc_hash }
764
756
  end
765
757
 
766
758
  # Returns a new Hash that recursively copies this hash's values. Values of type hash are copied using copy_recursive.
@@ -1065,10 +1057,11 @@ class Array
1065
1057
  # element is associated with the second element. If there is less than two elements in the member,
1066
1058
  # the first element is associated with nil. An empty array is ignored.
1067
1059
  #
1068
- # Example:
1060
+ # @example
1069
1061
  # [[:a, 1], [:b, 2, 3], [:c], []].to_assoc_hash #=> { :a => 1, :b => [2,3], :c => nil }
1062
+ # @return [Hash] the first => rest hash
1070
1063
  def to_assoc_hash
1071
- hash = Hash.new
1064
+ hash = {}
1072
1065
  each do |item|
1073
1066
  raise ArgumentError.new("Array member must be an array: #{item.pp_s(:single_line)}") unless Array === item
1074
1067
  key = item.first
@@ -50,7 +50,7 @@ module CaRuby
50
50
  shift_age = Options.get(:shift_age, options, 4)
51
51
  shift_size = Options.get(:shift_size, options, 16 * 1048576)
52
52
  @logger = MultilineLogger.new(dev, shift_age, shift_size)
53
- @logger.level = Options.get(:debug, options, ENV['DEBUG']) ? Logger::DEBUG : Logger::INFO
53
+ @logger.level = Options.get(:debug, options, ENV['DEBUG'] == 'true') ? Logger::DEBUG : Logger::INFO
54
54
  @logger.info('============================================')
55
55
  @logger.info('Logging started.')
56
56
  @dev = dev
@@ -86,7 +86,7 @@ module CaRuby
86
86
  end
87
87
  # if the key is a merge property key, then perform a deep merge.
88
88
  # otherwise, do a shallow merge of the property value into this property hash.
89
- deep, shallow = properties.partition { |key, value| @merge_properties.include?(key) }
89
+ deep, shallow = properties.split { |key, value| @merge_properties.include?(key) }
90
90
  merge!(deep, :deep)
91
91
  merge!(shallow)
92
92
  end
@@ -1,5 +1,8 @@
1
1
  require 'caruby/util/collection'
2
2
 
3
+ # A TopologicalSyncEnumerator iterates over (target, source) pairs with the target matched
4
+ # to the source with a matcher block. Child targets are matched to child sources based on
5
+ # a topological order reference method. The iteration is performed in depth-first order.
3
6
  class TopologicalSyncEnumerator
4
7
  include Enumerable
5
8
 
@@ -14,7 +17,7 @@ class TopologicalSyncEnumerator
14
17
  @matcher = matcher || lambda { |tgt, srcs| srcs.first }
15
18
  end
16
19
 
17
- # Calls the given block on each matching target and source.
20
+ # Calls the given block on each matching target and source in depth-first order.
18
21
  #
19
22
  # @yield [target, source] the objects to synchronize
20
23
  # @return [Hash] the matching target => source hash
@@ -1,7 +1,18 @@
1
1
  require 'caruby/util/visitor'
2
2
 
3
3
  class Object
4
- # Returns the transitive closure over a method or block, e.g.:
4
+ # Returns the transitive closure over a method or block. This method returns an array partially ordered
5
+ # by the children method or block, i.e. each node occurs before all other nodes referenced directly or
6
+ # indirectly by the children.
7
+ #
8
+ # If a method symbol or name is provided, then that method is called. Otherwise, the block is called.
9
+ # In either case, the call is expected to return an object or Enumerable of objects which also respond
10
+ # to the method or block.
11
+ #
12
+ # @param [Symbol, nil] method the child reference, or nil if a block is given
13
+ # @yield [node] the parent node's children
14
+ # @yieldparam node the parent node
15
+ # @example
5
16
  # class Node
6
17
  # attr_reader :parent, :children
7
18
  # def initialize(name, parent=nil)
@@ -17,16 +28,15 @@ class Object
17
28
  # a = Node.new('a'); b = Node.new('b', a), c = Node.new('c', a); d = Node.new('d', c)
18
29
  # a.transitive_closure { |node| node.children }.to_a.join(", ") #=> a, b, c, d
19
30
  # a.transitive_closure(:children).to_a.join(", ") #=> a, b, c, d
20
- # This method returns an array partially ordered by the closure method, i.e.
21
- # each node occurs before all other nodes referenced directly or indirectly by the closure method.
22
- #
23
- # If a method symbol or name is provided, then that method is called. Otherwise, the block is called.
24
- # In either case, the call is expected to return an object or Enumerable of objects which also respond
25
- # to the method or block.
26
31
  def transitive_closure(method=nil)
27
32
  raise ArgumentError.new("Missing both a method argument and a block") if method.nil? and not block_given?
28
- return transitive_closure() { |node| node.send(method) } if method
29
- CaRuby::Visitor.new(:depth_first) { |node| yield node }.to_enum(self).to_a.reverse
33
+ # If there is a method argument, then the transitive closure is based on that method.
34
+ # Otherwise, visit the closure in reverse depth-first order.
35
+ if method then
36
+ transitive_closure() { |node| node.send(method) }
37
+ else
38
+ CaRuby::Visitor.new(:depth_first) { |node| yield node }.to_enum(self).to_a.reverse
39
+ end
30
40
  end
31
41
  end
32
42
 
@@ -1,3 +1,3 @@
1
1
  module CaRuby
2
- VERSION = "1.5.3"
2
+ VERSION = "1.5.4"
3
3
  end
@@ -60,7 +60,7 @@ class CollectionTest < Test::Unit::TestCase
60
60
 
61
61
  def test_detect_value
62
62
  assert_equal(4, [1, 2, 3].detect_value { |item| item * 2 if item > 1 }, "Detect value incorrect")
63
- assert_nil([1, 2, 3].detect_value { |item| iitem * 2 if item > 3 }, "Value incorrectly detected")
63
+ assert_nil([1, 2, 3].detect_value { |item| item * 2 if item > 3 }, "Value incorrectly detected")
64
64
  end
65
65
 
66
66
  def test_detect_with_value
@@ -202,10 +202,6 @@ class CollectionTest < Test::Unit::TestCase
202
202
  assert_equal([1, 2, 3], ev.sort, "Hash value enumerator does not reflect hash change")
203
203
  end
204
204
 
205
- def test_hash_partition
206
- assert_equal([{:a => 1}, { :b => 2}], { :a => 1, :b => 2 }.partition { |key, value| value < 2 }, "Hash partition incorrect")
207
- end
208
-
209
205
  def test_hash_flatten
210
206
  assert_equal([:a, :b, :c, :d, :e, :f, :g], {:a => {:b => :c}, :d => :e, :f => [:g]}.flatten, "Hash flatten incorrect")
211
207
  end
@@ -231,7 +227,7 @@ class CollectionTest < Test::Unit::TestCase
231
227
  end
232
228
 
233
229
  def test_hash_partition
234
- assert_equal([{:a => 1, :c => 3}, {:b => 2}], {:a => 1, :b => 2, :c => 3}.hash_partition { |k, v| k == :a or v == 3 }, "Hash partition incorrect")
230
+ assert_equal([{:a => 1, :c => 3}, {:b => 2}], {:a => 1, :b => 2, :c => 3}.split { |k, v| k == :a or v == 3 }, "Hash partition incorrect")
235
231
  end
236
232
 
237
233
  def test_hash_filter_on_key
@@ -23,37 +23,45 @@ class TransitiveClosureTest < Test::Unit::TestCase
23
23
  alias :inspect :to_s
24
24
  end
25
25
 
26
+ # Verifies closure iteration for the following hierarchy:
27
+ # root -> a, e
28
+ # a -> b, c
29
+ # c -> d
30
+ # The expected iteration is +root+ preceding +a+ and +e+, +a+ preceding +b+ and +c+, +c+ preceding +d+.
26
31
  def test_hierarchy
27
32
  root= Node.new('root'); a = Node.new('a', root); b = Node.new('b', a); c = Node.new('c', a); d = Node.new('d', c); e = Node.new('e', root)
28
- expected = [root, a, b, c, d, e].to_set
29
- closure = root.transitive_closure(:children)
30
- assert_equal(expected, closure.to_set, "Hierarchy closure incorrect")
31
- closure.each_with_index { |node, index| closure[index..-1].each { |other| assert(!other.children.include?(node), "Order incorrect") } }
32
- closure.reject { |node| node.parent.nil? }.each_with_index { |node, index| assert(closure[0..index].detect { |other| other.children.include?(node) }, "Order incorrect") }
33
+ verify_closure([root, a, b, c, d, e], root.transitive_closure(:children))
33
34
  end
34
35
 
35
36
  def test_internal
36
37
  root= Node.new('root'); a = Node.new('a', root); b = Node.new('b', a); c = Node.new('c', a); d = Node.new('d', c); e = Node.new('e', root)
37
- expected = [a, b, c, d].to_set
38
- closure = a.transitive_closure(:children)
39
- assert_equal(expected, closure.to_set, "Hierarchy closure incorrect")
38
+ verify_closure([a, b, c, d], a.transitive_closure(:children))
40
39
  end
41
40
 
42
41
  def test_leaf
43
42
  leaf = Node.new(1)
44
- assert_equal([leaf], leaf.transitive_closure(:children), "Leaf closure incorrect")
43
+ verify_closure([leaf], leaf.transitive_closure(:children))
45
44
  end
46
45
 
47
46
  def test_collection
48
47
  a = Node.new('a'); b = Node.new('b'); c = Node.new('c', a); d = Node.new('d', b); e = Node.new('e', c)
49
- expected = [a, b, c, d, e].to_set
50
- closure = [a, b].transitive_closure(:children)
51
- assert_equal(expected, closure.to_set, "Hierarchy closure incorrect")
48
+ verify_closure([a, b, c, d, e], [a, b].transitive_closure(:children))
52
49
  end
53
50
 
54
51
  def test_cycle
55
52
  root= Node.new('root'); a = Node.new('a', root); b = Node.new('b', a); c = Node.new('c', a); c.children << root
56
53
  expected = [root, a, b, c].to_set
57
- assert_equal(expected, a.transitive_closure(:children).to_set, "Cycle closure incorrect")
54
+ verify_closure([root, a, b, c], root.transitive_closure(:children))
55
+ end
56
+
57
+ def verify_closure(content, closure)
58
+ assert_equal(content.to_set, closure.to_set, "Hierarchy closure incorrect")
59
+ # Verify that no child succeeds the parent.
60
+ closure.each_with_index do |node, index|
61
+ par = node.parent
62
+ if content.include?(par) then
63
+ assert(closure.index(par) < index, "Child #{node} precedes parent #{par}")
64
+ end
65
+ end
58
66
  end
59
67
  end
@@ -0,0 +1,58 @@
1
+ require 'test/lib/caruby/migration/test_case'
2
+ require 'examples/clinical_trials/lib/clinical_trials'
3
+
4
+ module ClinicalTrials
5
+ # Tests the ClinicalTrials example migration.
6
+ class MigrationTest < Test::Unit::TestCase
7
+ include CaRuby::MigrationTestCase
8
+
9
+ def setup
10
+ super(FIXTURES)
11
+ end
12
+
13
+ # def test_subject
14
+ # verify_target(:subject, :target => ClinicalTrials::Subject, :mapping=> SUBJECT_MAPPING) do |sbj|
15
+ # assert_not_nil(sbj.ssn, "Missing SSN")
16
+ # end
17
+ # end
18
+ #
19
+ # def test_ssn_filter
20
+ # verify_target(:ssn_filter, :target => ClinicalTrials::Subject, :mapping=> SUBJECT_MAPPING, :shims => SSN_SHIMS) do |sbj|
21
+ # assert_not_nil(sbj.ssn, "Missing SSN")
22
+ # end
23
+ # end
24
+
25
+ def test_activity_filter
26
+ verify_target(:activity_filter, :target => ClinicalTrials::Study, :mapping=> STUDY_MAPPING, :defaults => STUDY_DEFAULTS, :filters => STUDY_FILTERS) do |std|
27
+ expected = std.name.split(' ').first
28
+ assert_equal(expected, std.activity_status, "Incorrect activity status")
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ # The migration input data directory.
35
+ FIXTURES = 'examples/clinical_trials/data'
36
+
37
+ # The migration input shim directory.
38
+ SHIMS = 'examples/clinical_trials/lib/clinical_trials/migration'
39
+
40
+ # The migration configuration directory.
41
+ CONFIGS = 'examples/clinical_trials/conf/migration'
42
+
43
+ # The subject input file.
44
+ SUBJECT_MAPPING = File.join(CONFIGS, "subject_fields.yaml")
45
+
46
+ # The study input file.
47
+ STUDY_MAPPING = File.join(CONFIGS, "study_fields.yaml")
48
+
49
+ # The study default values.
50
+ STUDY_DEFAULTS = File.join(CONFIGS, "study_defaults.yaml")
51
+
52
+ # The study default values.
53
+ STUDY_FILTERS = File.join(CONFIGS, "study_filters.yaml")
54
+
55
+ # The filter shims file.
56
+ SSN_SHIMS = File.join(SHIMS, "ssn_shim.rb")
57
+ end
58
+ end
@@ -0,0 +1,38 @@
1
+ require 'test/lib/caruby/migration/test_case'
2
+ require 'examples/clinical_trials/lib/clinical_trials'
3
+
4
+ # Tests the ClinicalTrials example migration.
5
+ module ClinicalTrials
6
+ module MigrationTestCase
7
+ include CaRuby::MigrationTestCase
8
+
9
+ def setup
10
+ super(FIXTURES)
11
+ end
12
+
13
+ # Adds the +:target+, +:mapping+ and +:shims+ to the options and delegates
14
+ # to the superclass.
15
+ #
16
+ # @see {CaTissue::MigrationTestCase#create_migrator}
17
+ def create_migrator(fixture, opts={})
18
+ opts[:mapping] ||= File.join(CONFIGS, "#{fixture}_fields.yaml")
19
+ shims = File.join(SHIMS, "#{fixture}_shims.rb")
20
+ if File.exists?(shims) then
21
+ sopt = opts[:shims] ||= []
22
+ sopt << shims
23
+ end
24
+ super
25
+ end
26
+
27
+ private
28
+
29
+ # The migration input data directory.
30
+ FIXTURES = 'examples/clinical_trials/data'
31
+
32
+ # The migration input shim directory.
33
+ SHIMS = 'examples/clinical_trials/lib/clinical_trials/migration'
34
+
35
+ # The migration configuration directory.
36
+ CONFIGS = 'examples/clinical_trials/conf/migration'
37
+ end
38
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: caruby-core
3
3
  version: !ruby/object:Gem::Version
4
- hash: 5
4
+ hash: 11
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
8
  - 5
9
- - 3
10
- version: 1.5.3
9
+ - 4
10
+ version: 1.5.4
11
11
  platform: ruby
12
12
  authors:
13
13
  - OHSU
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-07-08 00:00:00 -07:00
18
+ date: 2011-09-22 00:00:00 -07:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -121,6 +121,8 @@ files:
121
121
  - lib/caruby/domain/uniquify.rb
122
122
  - lib/caruby/domain.rb
123
123
  - lib/caruby/import/java.rb
124
+ - lib/caruby/json/deserializer.rb
125
+ - lib/caruby/json/serializer.rb
124
126
  - lib/caruby/migration/migratable.rb
125
127
  - lib/caruby/migration/migrator.rb
126
128
  - lib/caruby/migration/resource_module.rb
@@ -191,8 +193,8 @@ files:
191
193
  - test/lib/caruby/util/version_test.rb
192
194
  - test/lib/caruby/util/visitor_test.rb
193
195
  - test/lib/caruby/util/weak_hash_test.rb
194
- - test/lib/examples/galena/clinical_trials/migration/participant_test.rb
195
- - test/lib/examples/galena/clinical_trials/migration/test_case.rb
196
+ - test/lib/examples/clinical_trials/migration/migration_test.rb
197
+ - test/lib/examples/clinical_trials/migration/test_case.rb
196
198
  - History.md
197
199
  - LEGAL
198
200
  - LICENSE
@@ -1,28 +0,0 @@
1
- require File.join(File.dirname(__FILE__), 'test_case')
2
-
3
- # Tests the ClinicalTrials example migration.
4
- module Galena
5
- module ClinicalTrials
6
- class ParticipantMigrationTest < Test::Unit::TestCase
7
- include MigrationTestCase
8
-
9
- def test_target
10
- verify_target(:participant, :target => ClinicalTrials::Participant) do |pnt|
11
- assert_not_nil(pnt.ssn, "Missing SSN")
12
- end
13
- end
14
-
15
- def test_filter
16
- verify_target(:participant, :target => ClinicalTrials::Participant, :input => FILTER_DATA, :shims => [FILTER_SHIMS]) do |pnt|
17
- assert_not_nil(pnt.ssn, "Missing SSN")
18
- end
19
- end
20
-
21
- private
22
-
23
- FILTER_DATA = 'examples/galena/data/filter.csv'
24
-
25
- FILTER_SHIMS = 'examples/galena/lib/galena/migration/filter_shims.rb'
26
- end
27
- end
28
- end
@@ -1,40 +0,0 @@
1
- $:.unshift 'examples/clinical_trials/lib'
2
-
3
- require 'test/lib/caruby/migration/test_case'
4
- require 'clinical_trials'
5
-
6
- # Tests the ClinicalTrials example migration.
7
- module Galena
8
- module ClinicalTrials
9
- module MigrationTestCase
10
- include CaRuby::MigrationTestCase
11
-
12
- # The migration input data directory.
13
- FIXTURES = 'examples/galena/data'
14
-
15
- # The migration input data directory.
16
- SHIMS = 'examples/galena/lib/galena/clinical_trials/migration'
17
-
18
- # The migration configuration directory.
19
- CONFIGS = 'examples/galena/conf/migration'
20
-
21
- def setup
22
- super(FIXTURES)
23
- end
24
-
25
- # Adds the +:target+, +:mapping+ and +:shims+ to the options and delegates
26
- # to the superclass.
27
- #
28
- # @see {CaTissue::MigrationTestCase#create_migrator}
29
- def create_migrator(fixture, opts={})
30
- opts[:mapping] ||= File.join(CONFIGS, "#{fixture}_fields.yaml")
31
- shims = File.join(SHIMS, "#{fixture}_shims.rb")
32
- if File.exists?(shims) then
33
- sopt = opts[:shims] ||= []
34
- sopt << shims
35
- end
36
- super
37
- end
38
- end
39
- end
40
- end