libis-workflow-mongoid 2.0.2 → 2.0.3

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.
@@ -0,0 +1,92 @@
1
+ require "map_with_indifferent_access/normalization/deep_normalizer"
2
+
3
+ module MapWithIndifferentAccess
4
+ module Normalization
5
+ class << self
6
+ # Deeply normalizes `Hash`-like and `Array`-like hash entry
7
+ # values and array items, preserving all of the existing key
8
+ # values (`String`, `Symbol`, or otherwise) from the inner
9
+ # collections.
10
+ #
11
+ # @see DeepNormalizer#call
12
+ def deeply_normalize(obj)
13
+ deep_basic_normalizer.call( obj )
14
+ end
15
+
16
+ # Deeply coerces keys to `Symbol` type.
17
+ #
18
+ # @see DeepNormalizer#call
19
+ def deeply_symbolize_keys(obj)
20
+ deep_key_symbolizer.call( obj )
21
+ end
22
+
23
+ # Deeply coerces keys to `String` type.
24
+ #
25
+ # @see DeepNormalizer#call
26
+ def deeply_stringify_keys(obj)
27
+ deep_key_stringifier.call( obj )
28
+ end
29
+
30
+ private
31
+
32
+ def deep_basic_normalizer
33
+ @deep_basic_normalizer ||= DeepNormalizer.new( NullKeyStrategy )
34
+ end
35
+
36
+ def deep_key_symbolizer
37
+ @deep_key_symbolizer ||= DeepNormalizer.new( SymbolizationKeyStrategy )
38
+ end
39
+
40
+ def deep_key_stringifier
41
+ @deep_key_stringifier ||= DeepNormalizer.new( StringificationKeyStrategy )
42
+ end
43
+ end
44
+
45
+ module KeyStrategy
46
+ def self.needs_coercion?(key)
47
+ raise NotImplementedError, "Including-module responsibility"
48
+ end
49
+
50
+ def self.coerce(key)
51
+ raise NotImplementedError, "Including-module responsibility"
52
+ end
53
+ end
54
+
55
+ module NullKeyStrategy
56
+ extend Normalization::KeyStrategy
57
+
58
+ def self.needs_coercion?(key)
59
+ false
60
+ end
61
+
62
+ def self.coerce(key)
63
+ key
64
+ end
65
+ end
66
+
67
+ module SymbolizationKeyStrategy
68
+ extend Normalization::KeyStrategy
69
+
70
+ def self.needs_coercion?(key)
71
+ !( Symbol === key )
72
+ end
73
+
74
+ def self.coerce(key)
75
+ key.to_s.to_sym
76
+ end
77
+ end
78
+
79
+ module StringificationKeyStrategy
80
+ extend Normalization::KeyStrategy
81
+
82
+ def self.needs_coercion?(key)
83
+ !( String === key )
84
+ end
85
+
86
+ def self.coerce(key)
87
+ key.to_s
88
+ end
89
+ end
90
+
91
+ end
92
+ end
@@ -0,0 +1,104 @@
1
+ module MapWithIndifferentAccess
2
+ module Normalization
3
+
4
+ class DeepNormalizer
5
+ attr_reader :strategy
6
+
7
+ # Initializes a new DeepNormalizer with a given object that
8
+ # extends {KeyStrategy}.
9
+ def initialize(strategy)
10
+ @strategy = strategy
11
+ end
12
+
13
+ # Given an `Array`-like or `Hash`-like object, returns a
14
+ # similar object with keys coerced according to the
15
+ # target {DeepNormalizer}'s strategy.
16
+ # Given an object that is not `Array`-like or `Hash`-like,
17
+ # then the given object is returned.
18
+ #
19
+ # During this process, any hash entry values or array
20
+ # items that are instances of
21
+ # {Map} or {List} are replaced with `Hash` or `Array`
22
+ # deconstructions respectively. If a {Map} or {List} is
23
+ # given, then the same type of object is returned.
24
+ #
25
+ # If a `Hash` or an object that resonds to `#to_hash` and
26
+ # `#each_pair` is given, then a `Hash` is returned. The
27
+ # same applies to each `Hash`/{Map} entry value or
28
+ # `Array`/{List} item that is traversed.
29
+ #
30
+ # If an `Array` or an object that resonds to `#to_ary` is
31
+ # given, then an `Array` is returned. The same applies to
32
+ # each `Hash`/{Map} entry value or `Array`/{List} item that
33
+ # is traversed.
34
+ #
35
+ # If any keys, `Hash` entry values, or `Array` items are
36
+ # replaced, then a new object is returned that includes
37
+ # those replacements. Otherwise, the given object is
38
+ # returned. In either case, the contents of `obj` are not
39
+ # modified.
40
+ def call(obj)
41
+ if WrapsCollection === obj
42
+ coerced_inner_col = recursively_coerce( obj )
43
+ Values.externalize( coerced_inner_col )
44
+ else
45
+ recursively_coerce( obj )
46
+ end
47
+ end
48
+
49
+ private
50
+
51
+ def recursively_coerce(obj)
52
+ if ::Hash === obj
53
+ coerce_hash( obj )
54
+ elsif Map === obj
55
+ coerce_hash( obj.inner_map )
56
+ elsif ::Array === obj
57
+ coerce_array( obj )
58
+ elsif List === obj
59
+ coerce_array( obj.inner_array )
60
+ elsif obj.respond_to?(:to_hash) && obj.respond_to?(:each_pair)
61
+ coerce_hash( obj.to_hash )
62
+ elsif obj.respond_to?(:to_ary)
63
+ coerce_array( obj.to_ary )
64
+ else
65
+ obj
66
+ end
67
+ end
68
+
69
+ def coerce_hash(obj)
70
+ does_need_key_coercion = obj.each_key.any?{ |key|
71
+ strategy.needs_coercion?( key )
72
+ }
73
+ result = does_need_key_coercion ? {} : obj
74
+
75
+ obj.each_pair do |(key,value)|
76
+ key = strategy.coerce( key ) if strategy.needs_coercion?( key )
77
+ new_value = recursively_coerce( value )
78
+ if result.equal?( obj )
79
+ unless new_value.equal?( value )
80
+ result = obj.dup
81
+ result[ key ] = new_value
82
+ end
83
+ else
84
+ result[ key ] = new_value
85
+ end
86
+ end
87
+ result
88
+ end
89
+
90
+ def coerce_array( obj )
91
+ result = obj
92
+ obj.each_with_index do |item,i|
93
+ new_item = recursively_coerce(item)
94
+ unless new_item.equal?( item )
95
+ result = obj.dup if result.equal?( obj )
96
+ result[ i ] = new_item
97
+ end
98
+ end
99
+ result
100
+ end
101
+ end
102
+
103
+ end
104
+ end
@@ -0,0 +1,39 @@
1
+ module MapWithIndifferentAccess
2
+
3
+ module Values
4
+
5
+ class << self
6
+ # Converts `obj` to a {Map} or {List} if possible, otherwise
7
+ # returns `obj`.
8
+ #
9
+ # @return [Map, List, Object]
10
+ def externalize(obj)
11
+ (
12
+ Map.try_convert( obj ) ||
13
+ List.try_convert( obj ) ||
14
+ obj
15
+ )
16
+ end
17
+
18
+ alias >> externalize
19
+
20
+ # Converts `obj`, which might be a {Map} or {List} to a
21
+ # `Hash` or `Array` if possible. Returns `obj` if no
22
+ # conversion is possible.
23
+ #
24
+ # @return [Hash, Array, Object]
25
+ def internalize(obj)
26
+ (
27
+ Map.try_deconstruct( obj ) ||
28
+ List.try_deconstruct( obj ) ||
29
+ obj
30
+ )
31
+ end
32
+
33
+ alias << internalize
34
+ end
35
+
36
+ end
37
+
38
+ end
39
+
@@ -0,0 +1,3 @@
1
+ module MapWithIndifferentAccess
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,152 @@
1
+ require 'forwardable'
2
+
3
+ module MapWithIndifferentAccess
4
+
5
+ module WrapsCollection
6
+ extend Forwardable
7
+ include Enumerable
8
+
9
+ # The encapsulated collection object.
10
+ attr_reader :inner_collection
11
+
12
+ # @!method length
13
+ # The number of entries in the collection.
14
+ #
15
+ # @return [Fixnum]
16
+ # @see #size
17
+
18
+ # @!method size
19
+ # The number of entries in the collection.
20
+ #
21
+ # @return [Fixnum]
22
+ # @see #length
23
+
24
+ # @!method empty?
25
+ # Returns `true` if the collection contains no entries.
26
+ #
27
+ # Returns `false` if the collection contains 1 or more
28
+ # entries.
29
+ #
30
+ # @return [Boolean]
31
+
32
+ # @!method _frozen?
33
+ # Returns true when the target object (the wrapper) is
34
+ # frozen.
35
+ #
36
+ # There are some cases in which this returns `false` when
37
+ # {#frozen?} would return `true`.
38
+ #
39
+ # @return [Boolean]
40
+ # @see #frozen?
41
+
42
+ # Using `class_eval` to hide the aliasing from YARD, so it
43
+ # does not document this alias to the implementation
44
+ # inherited from `Object` as an alias to the subsequent
45
+ # override.
46
+ class_eval 'alias _frozen? frozen?', __FILE__, __LINE__
47
+
48
+ # @!method tainted?
49
+ # Reflects the tainted-ness of its #inner_collection.
50
+ # @return [Boolean]
51
+
52
+ # @!method untrusted?
53
+ # Reflects the untrusted-ness of its #inner_collection.
54
+ # @return [Boolean]
55
+
56
+ # @!method frozen?
57
+ # Reflects the frozen-ness of its {#inner_collection}.
58
+ #
59
+ # Returns `true` when the {#inner_collection} is frozen (
60
+ # and the target/wrapper might be frozen or not).
61
+ #
62
+ # Returns `false` when the {#inner_collection} is not
63
+ # frozen (and neither is the target/wrapper).
64
+ #
65
+ # When the {#inner_collection} is frozen, but the target
66
+ # object is not, then the target behaves as if frozen in
67
+ # most ways, but some of the restrictions that Ruby applies
68
+ # to truly frozen (such as preventing instance methods from
69
+ # being dynamically added to the object) do not apply.
70
+ #
71
+ # @return [Boolean]
72
+ # @see #_frozen?
73
+
74
+ # @!method hash
75
+ # Compute a hash-code for this collection wrapper. Two
76
+ # wrappers with the same type and the same
77
+ # {#inner_collection} content will have the same hash code
78
+ # (and will match using {#eql?}).
79
+ #
80
+ # @return [Fixnum]
81
+
82
+ def_delegators(
83
+ :inner_collection,
84
+ :length,
85
+ :size,
86
+ :empty?,
87
+ :tainted?,
88
+ :untrusted?,
89
+ :frozen?,
90
+ :hash,
91
+ )
92
+
93
+ # @!method taint
94
+ # Causes the target's #inner_collection to be tainted.
95
+
96
+ # @!method untaint
97
+ # Causes the target's #inner_collection to be untainted.
98
+
99
+ # @!method untrust
100
+ # Causes the target's #inner_collection to be untrusted.
101
+
102
+ # @!method trust
103
+ # Causes the target's {#inner_collection} to be trusted.
104
+
105
+ [:taint, :untaint, :untrust, :trust ].each do |method_name|
106
+ class_eval <<-EOS, __FILE__, __LINE__ + 1
107
+ def #{method_name}
108
+ inner_collection.#{method_name}
109
+ self
110
+ end
111
+ EOS
112
+ end
113
+
114
+ # Removes all entries from the target's {#inner_collection}.
115
+ def clear
116
+ inner_collection.clear
117
+ self
118
+ end
119
+
120
+ # Freezes both the target map and its {#inner_collection}
121
+ # object.
122
+ def freeze
123
+ super
124
+ inner_collection.freeze
125
+ self
126
+ end
127
+
128
+ # Returns `true` for another instance of the same class as
129
+ # the target where the target's {#inner_collection} is
130
+ # `#eql?` to the given object's {#inner_collection}. Returns
131
+ # `false` otherwise.
132
+ #
133
+ # @return [Boolean]
134
+ def eql?(other)
135
+ self.class == other.class &&
136
+ self.inner_collection.eql?( other.inner_collection )
137
+ end
138
+
139
+ private
140
+
141
+ def initialize_dup(orig)
142
+ super
143
+ @inner_collection = inner_collection.dup
144
+ end
145
+
146
+ def initialize_clone(orig)
147
+ super
148
+ @inner_collection = inner_collection.clone
149
+ end
150
+ end
151
+
152
+ end
@@ -27,7 +27,6 @@ Gem::Specification.new do |spec|
27
27
  spec.require_paths = ['lib']
28
28
 
29
29
  spec.add_runtime_dependency 'libis-workflow', '~> 2.0'
30
-
31
30
  spec.add_runtime_dependency 'mongoid', '~> 5.0'
32
31
 
33
32
  spec.add_development_dependency 'bundler', '~> 1.6'
@@ -12,7 +12,7 @@ class TestDirItem < TestItem
12
12
  end
13
13
 
14
14
  def name
15
- self.properties['name'] || super
15
+ self.properties[:name] || super
16
16
  end
17
17
 
18
18
  end
@@ -15,15 +15,15 @@ class TestFileItem < TestItem
15
15
  end
16
16
 
17
17
  def name
18
- self.properties['name'] || super
18
+ self.properties[:name] || super
19
19
  end
20
20
 
21
21
  def filesize
22
- properties['size']
22
+ properties[:size]
23
23
  end
24
24
 
25
25
  def fixity_check(checksum)
26
- properties['checksum'] == checksum
26
+ properties[:checksum] == checksum
27
27
  end
28
28
 
29
29
  end
@@ -6,7 +6,7 @@ class CamelizeName < ::Libis::Workflow::Task
6
6
 
7
7
  def process(item)
8
8
  return unless (item.is_a?(TestFileItem) || item.is_a?(TestDirItem))
9
- item.properties['name'] = item.name.camelize
9
+ item.properties[:name] = item.name.camelize
10
10
  item.save!
11
11
  end
12
12
 
@@ -190,8 +190,8 @@ STR
190
190
  item = run.items.first
191
191
  expect(item.nil?).to eq false
192
192
  expect(item.is_a? TestDirItem).to eq true
193
- expect(item.properties['name']).to eq 'Items'
194
- expect(item.properties['ingest_failed']).to eq false
193
+ expect(item.properties[:name]).to eq 'Items'
194
+ expect(item.properties[:ingest_failed]).to eq false
195
195
  end
196
196
 
197
197
  it 'move item in relation' do