virtus 1.0.0.rc2 → 1.0.0
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/config/flay.yml +1 -1
- data/lib/virtus.rb +1 -0
- data/lib/virtus/attribute.rb +1 -4
- data/lib/virtus/attribute/coercer.rb +9 -15
- data/lib/virtus/attribute/embedded_value.rb +4 -16
- data/lib/virtus/coercer.rb +40 -0
- data/lib/virtus/version.rb +1 -1
- data/spec/unit/virtus/attribute/embedded_value/coerce_spec.rb +21 -1
- metadata +6 -5
data/config/flay.yml
CHANGED
data/lib/virtus.rb
CHANGED
data/lib/virtus/attribute.rb
CHANGED
@@ -67,10 +67,7 @@ module Virtus
|
|
67
67
|
|
68
68
|
# @api private
|
69
69
|
def self.build_coercer(type, options = {})
|
70
|
-
Coercer.new(
|
71
|
-
options.fetch(:configured_coercer) { Virtus.coercer },
|
72
|
-
type.coercion_method
|
73
|
-
)
|
70
|
+
Coercer.new(type, options.fetch(:configured_coercer) { Virtus.coercer })
|
74
71
|
end
|
75
72
|
|
76
73
|
# @api private
|
@@ -4,8 +4,10 @@ module Virtus
|
|
4
4
|
# Coercer accessor wrapper
|
5
5
|
#
|
6
6
|
# @api private
|
7
|
-
class Coercer
|
8
|
-
|
7
|
+
class Coercer < Virtus::Coercer
|
8
|
+
|
9
|
+
# @api private
|
10
|
+
attr_reader :method, :coercers
|
9
11
|
|
10
12
|
# Initialize a new coercer object
|
11
13
|
#
|
@@ -15,9 +17,10 @@ module Virtus
|
|
15
17
|
# @return [undefined]
|
16
18
|
#
|
17
19
|
# @api private
|
18
|
-
def initialize(
|
20
|
+
def initialize(type, coercers)
|
21
|
+
super(type)
|
22
|
+
@method = type.coercion_method
|
19
23
|
@coercers = coercers
|
20
|
-
@method = method
|
21
24
|
end
|
22
25
|
|
23
26
|
# Coerce given value
|
@@ -26,23 +29,14 @@ module Virtus
|
|
26
29
|
#
|
27
30
|
# @api private
|
28
31
|
def call(value)
|
29
|
-
|
32
|
+
coercers[value.class].public_send(method, value)
|
30
33
|
rescue ::Coercible::UnsupportedCoercion
|
31
34
|
value
|
32
35
|
end
|
33
36
|
|
34
37
|
# @api public
|
35
38
|
def success?(primitive, value)
|
36
|
-
|
37
|
-
end
|
38
|
-
|
39
|
-
# Return coercer object for the given type
|
40
|
-
#
|
41
|
-
# @return [Object]
|
42
|
-
#
|
43
|
-
# @api private
|
44
|
-
def [](type)
|
45
|
-
@coercers[type]
|
39
|
+
coercers[primitive].coerced?(value)
|
46
40
|
end
|
47
41
|
|
48
42
|
end # class Coercer
|
@@ -6,23 +6,11 @@ module Virtus
|
|
6
6
|
class EmbeddedValue < Attribute
|
7
7
|
TYPES = [Struct, OpenStruct, Virtus, Model::Constructor].freeze
|
8
8
|
|
9
|
-
# Abstract EV coercer class
|
10
|
-
#
|
11
|
-
# @private
|
12
|
-
class Coercer
|
13
|
-
attr_reader :primitive
|
14
|
-
|
15
|
-
def initialize(primitive)
|
16
|
-
@primitive = primitive
|
17
|
-
end
|
18
|
-
|
19
|
-
end # Coercer
|
20
|
-
|
21
9
|
# Builds Struct-like instance with attributes passed to the constructor as
|
22
10
|
# a list of args rather than a hash
|
23
11
|
#
|
24
12
|
# @private
|
25
|
-
class FromStruct < Coercer
|
13
|
+
class FromStruct < Virtus::Coercer
|
26
14
|
|
27
15
|
# @api public
|
28
16
|
def call(input)
|
@@ -39,7 +27,7 @@ module Virtus
|
|
39
27
|
# as a hash
|
40
28
|
#
|
41
29
|
# @private
|
42
|
-
class FromOpenStruct < Coercer
|
30
|
+
class FromOpenStruct < Virtus::Coercer
|
43
31
|
|
44
32
|
# @api public
|
45
33
|
def call(input)
|
@@ -67,9 +55,9 @@ module Virtus
|
|
67
55
|
primitive = type.primitive
|
68
56
|
|
69
57
|
if primitive < Virtus || primitive < Model::Constructor || primitive <= OpenStruct
|
70
|
-
FromOpenStruct.new(
|
58
|
+
FromOpenStruct.new(type)
|
71
59
|
elsif primitive < Struct
|
72
|
-
FromStruct.new(
|
60
|
+
FromStruct.new(type)
|
73
61
|
end
|
74
62
|
end
|
75
63
|
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Virtus
|
2
|
+
|
3
|
+
# Abstract coercer class
|
4
|
+
#
|
5
|
+
class Coercer
|
6
|
+
|
7
|
+
# @api private
|
8
|
+
attr_reader :primitive, :type
|
9
|
+
|
10
|
+
# @api private
|
11
|
+
def initialize(type)
|
12
|
+
@type = type
|
13
|
+
@primitive = type.primitive
|
14
|
+
end
|
15
|
+
|
16
|
+
# Coerce input value into expected primitive type
|
17
|
+
#
|
18
|
+
# @param [Object] input
|
19
|
+
#
|
20
|
+
# @return [Object] coerced input
|
21
|
+
#
|
22
|
+
# @api public
|
23
|
+
def call(input)
|
24
|
+
NotImplementedError.new("#{self.class}#call must be implemented")
|
25
|
+
end
|
26
|
+
|
27
|
+
# Return if the input value was successfuly coerced
|
28
|
+
#
|
29
|
+
# @param [Object] input
|
30
|
+
#
|
31
|
+
# @return [Object] coerced input
|
32
|
+
#
|
33
|
+
# @api public
|
34
|
+
def success?(primitive, input)
|
35
|
+
input.kind_of?(primitive)
|
36
|
+
end
|
37
|
+
|
38
|
+
end # Coercer
|
39
|
+
|
40
|
+
end # Virtus
|
data/lib/virtus/version.rb
CHANGED
@@ -3,7 +3,8 @@ require 'spec_helper'
|
|
3
3
|
describe Virtus::Attribute::EmbeddedValue, '#coerce' do
|
4
4
|
subject { object.coerce(input) }
|
5
5
|
|
6
|
-
let(:object)
|
6
|
+
let(:object) { described_class.build(model, options) }
|
7
|
+
let(:options) { {} }
|
7
8
|
|
8
9
|
context 'when primitive is OpenStruct' do
|
9
10
|
let(:model) { OpenStruct }
|
@@ -54,4 +55,23 @@ describe Virtus::Attribute::EmbeddedValue, '#coerce' do
|
|
54
55
|
it { should be(input) }
|
55
56
|
end
|
56
57
|
end
|
58
|
+
|
59
|
+
context 'when :strict mode is enabled' do
|
60
|
+
let(:model) { Struct.new(:name) }
|
61
|
+
let(:options) { { :strict => true } }
|
62
|
+
|
63
|
+
context 'when input is coercible' do
|
64
|
+
let(:input) { ['Piotr'] }
|
65
|
+
|
66
|
+
it { should eql(model.new('Piotr')) }
|
67
|
+
end
|
68
|
+
|
69
|
+
context 'when input is not coercible' do
|
70
|
+
let(:input) { nil }
|
71
|
+
|
72
|
+
it 'raises error' do
|
73
|
+
expect { subject }.to raise_error(Virtus::CoercionError)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
57
77
|
end
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: virtus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0
|
5
|
-
prerelease:
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Piotr Solnica
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-10-
|
12
|
+
date: 2013-10-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: descendants_tracker
|
@@ -126,6 +126,7 @@ files:
|
|
126
126
|
- lib/virtus/builder/hook_context.rb
|
127
127
|
- lib/virtus/class_inclusions.rb
|
128
128
|
- lib/virtus/class_methods.rb
|
129
|
+
- lib/virtus/coercer.rb
|
129
130
|
- lib/virtus/configuration.rb
|
130
131
|
- lib/virtus/const_missing_extensions.rb
|
131
132
|
- lib/virtus/extensions.rb
|
@@ -218,9 +219,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
218
219
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
219
220
|
none: false
|
220
221
|
requirements:
|
221
|
-
- - ! '
|
222
|
+
- - ! '>='
|
222
223
|
- !ruby/object:Gem::Version
|
223
|
-
version:
|
224
|
+
version: '0'
|
224
225
|
requirements: []
|
225
226
|
rubyforge_project:
|
226
227
|
rubygems_version: 1.8.23
|