libis-workflow-mongoid 2.0.2 → 2.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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