caruby-core 1.5.3 → 1.5.4

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.
@@ -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