virtus 1.0.0.rc1 → 1.0.0.rc2
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/.travis.yml +0 -1
- data/Changelog.md +1 -0
- data/Gemfile +0 -3
- data/lib/virtus/attribute/accessor.rb +8 -7
- data/lib/virtus/attribute/coercible.rb +6 -0
- data/lib/virtus/attribute/collection.rb +3 -3
- data/lib/virtus/attribute/embedded_value.rb +1 -20
- data/lib/virtus/attribute/hash.rb +16 -12
- data/lib/virtus/attribute/strict.rb +6 -0
- data/lib/virtus/version.rb +1 -1
- data/spec/unit/virtus/class_methods/finalize_spec.rb +6 -0
- data/virtus.gemspec +1 -1
- metadata +4 -4
data/.travis.yml
CHANGED
data/Changelog.md
CHANGED
@@ -15,6 +15,7 @@ This release no longer works with Ruby 1.8.7.
|
|
15
15
|
* [changed] A meaningful error will be raised if a reserved name is used as an attribute name (solnic)
|
16
16
|
* [changed] Default value can be set via private and protected methods now (solnic)
|
17
17
|
* [changed] New syntax for value objects (solnic)
|
18
|
+
* [changed] Default values are now set in the constructor for non-lazy attributes (solnic)
|
18
19
|
* [deprecated] `Virtus::Attribute.coerce` in favor of `Virtus.coerce` or a customized configured module (solnic)
|
19
20
|
* [deprecated] `include Virtus` in favor of `include Virtus.model` (for classes) or `Virtus.module` (for modules) (solnic)
|
20
21
|
* [deprecated] `include Virtus::ValueObject` in favor of `include Virtus.value_object` (solnic)
|
data/Gemfile
CHANGED
@@ -26,6 +26,14 @@ module Virtus
|
|
26
26
|
# @api private
|
27
27
|
attr_reader :instance_variable_name
|
28
28
|
|
29
|
+
# @api private
|
30
|
+
def self.extended(descendant)
|
31
|
+
super
|
32
|
+
name = descendant.options.fetch(:name).to_sym
|
33
|
+
descendant.instance_variable_set('@name', name)
|
34
|
+
descendant.instance_variable_set('@instance_variable_name', "@#{name}")
|
35
|
+
end
|
36
|
+
|
29
37
|
# Return value of the attribute
|
30
38
|
#
|
31
39
|
# @param [Object] instance
|
@@ -78,13 +86,6 @@ module Virtus
|
|
78
86
|
options[:writer] == :public
|
79
87
|
end
|
80
88
|
|
81
|
-
# @api private
|
82
|
-
def finalize
|
83
|
-
@name = options.fetch(:name).to_sym
|
84
|
-
@instance_variable_name = "@#{@name}"
|
85
|
-
super
|
86
|
-
end
|
87
|
-
|
88
89
|
end # Accessor
|
89
90
|
|
90
91
|
end # Attribute
|
@@ -1,8 +1,14 @@
|
|
1
1
|
module Virtus
|
2
2
|
class Attribute
|
3
3
|
|
4
|
+
# Attribute extension providing coercion when setting an attribute value
|
5
|
+
#
|
4
6
|
module Coercible
|
5
7
|
|
8
|
+
# Coerce value before setting
|
9
|
+
#
|
10
|
+
# @see Accessor#set
|
11
|
+
#
|
6
12
|
# @api public
|
7
13
|
def set(instance, value)
|
8
14
|
super(instance, coerce(value))
|
@@ -1,14 +1,14 @@
|
|
1
1
|
module Virtus
|
2
2
|
class Attribute
|
3
3
|
|
4
|
-
#
|
4
|
+
# Collection attribute handles enumerable-like types
|
5
5
|
#
|
6
6
|
# Handles coercing members to the designated member type.
|
7
7
|
#
|
8
|
-
# @abstract
|
9
8
|
class Collection < Attribute
|
10
|
-
default Proc.new { |_, attribute| attribute.
|
9
|
+
default Proc.new { |_, attribute| attribute.primitive.new }
|
11
10
|
|
11
|
+
# @api private
|
12
12
|
attr_reader :member_type
|
13
13
|
|
14
14
|
# FIXME: temporary hack, remove when Axiom::Type works with EV as member_type
|
@@ -1,26 +1,7 @@
|
|
1
1
|
module Virtus
|
2
2
|
class Attribute
|
3
3
|
|
4
|
-
# EmbeddedValue
|
5
|
-
#
|
6
|
-
# @example
|
7
|
-
#
|
8
|
-
# class Address
|
9
|
-
# include Virtus
|
10
|
-
#
|
11
|
-
# attribute :street, String
|
12
|
-
# attribute :zipcode, String
|
13
|
-
# attribute :city, String
|
14
|
-
# end
|
15
|
-
#
|
16
|
-
# class User
|
17
|
-
# include Virtus
|
18
|
-
#
|
19
|
-
# attribute :address, Address
|
20
|
-
# end
|
21
|
-
#
|
22
|
-
# user = User.new(:address => {
|
23
|
-
# :street => 'Street 1/2', :zipcode => '12345', :city => 'NYC' })
|
4
|
+
# EmbeddedValue handles virtus-like objects, OpenStruct and Struct
|
24
5
|
#
|
25
6
|
class EmbeddedValue < Attribute
|
26
7
|
TYPES = [Struct, OpenStruct, Virtus, Model::Constructor].freeze
|
@@ -1,25 +1,18 @@
|
|
1
1
|
module Virtus
|
2
2
|
class Attribute
|
3
3
|
|
4
|
-
# Hash
|
5
|
-
#
|
6
|
-
# @example
|
7
|
-
# class Post
|
8
|
-
# include Virtus
|
9
|
-
#
|
10
|
-
# attribute :meta, Hash
|
11
|
-
# end
|
12
|
-
#
|
13
|
-
# Post.new(:meta => { :tags => %w(foo bar) })
|
4
|
+
# Handles attributes with Hash type
|
14
5
|
#
|
15
6
|
class Hash < Attribute
|
16
7
|
primitive ::Hash
|
17
8
|
default primitive.new
|
18
9
|
|
19
|
-
|
20
|
-
attr_reader :value_type
|
10
|
+
# @api private
|
11
|
+
attr_reader :key_type, :value_type
|
21
12
|
|
22
13
|
# FIXME: remove this once axiom-types supports it
|
14
|
+
#
|
15
|
+
# @private
|
23
16
|
Type = Struct.new(:key_type, :value_type) do
|
24
17
|
def self.infer(type)
|
25
18
|
if axiom_type?(type)
|
@@ -33,14 +26,17 @@ module Virtus
|
|
33
26
|
end
|
34
27
|
end
|
35
28
|
|
29
|
+
# @api private
|
36
30
|
def self.pending?(primitive)
|
37
31
|
primitive.is_a?(String) || primitive.is_a?(Symbol)
|
38
32
|
end
|
39
33
|
|
34
|
+
# @api private
|
40
35
|
def self.axiom_type?(type)
|
41
36
|
type.is_a?(Class) && type < Axiom::Types::Type
|
42
37
|
end
|
43
38
|
|
39
|
+
# @api private
|
44
40
|
def self.determine_type(type)
|
45
41
|
return type if pending?(type)
|
46
42
|
|
@@ -51,6 +47,7 @@ module Virtus
|
|
51
47
|
end
|
52
48
|
end
|
53
49
|
|
50
|
+
# @api private
|
54
51
|
def self.infer_key_and_value_types(type)
|
55
52
|
return {} unless type.kind_of?(::Hash)
|
56
53
|
|
@@ -77,10 +74,12 @@ module Virtus
|
|
77
74
|
end
|
78
75
|
end
|
79
76
|
|
77
|
+
# @api private
|
80
78
|
def coercion_method
|
81
79
|
:to_hash
|
82
80
|
end
|
83
81
|
|
82
|
+
# @api private
|
84
83
|
def primitive
|
85
84
|
::Hash
|
86
85
|
end
|
@@ -97,6 +96,10 @@ module Virtus
|
|
97
96
|
options[:value_type] ||= Attribute.build(type.value_type)
|
98
97
|
end
|
99
98
|
|
99
|
+
# Coerce members
|
100
|
+
#
|
101
|
+
# @see [Attribute#coerce]
|
102
|
+
#
|
100
103
|
# @api public
|
101
104
|
def coerce(*)
|
102
105
|
coerced = super
|
@@ -122,5 +125,6 @@ module Virtus
|
|
122
125
|
end
|
123
126
|
|
124
127
|
end # class Hash
|
128
|
+
|
125
129
|
end # class Attribute
|
126
130
|
end # module Virtus
|
@@ -1,8 +1,14 @@
|
|
1
1
|
module Virtus
|
2
2
|
class Attribute
|
3
3
|
|
4
|
+
# Attribute extension which raises CoercionError when coercion failed
|
5
|
+
#
|
4
6
|
module Strict
|
5
7
|
|
8
|
+
# @see [Attribute#coerce]
|
9
|
+
#
|
10
|
+
# @raises [CoercionError] when coercer failed
|
11
|
+
#
|
6
12
|
# @api public
|
7
13
|
def coerce(*)
|
8
14
|
output = super
|
data/lib/virtus/version.rb
CHANGED
@@ -6,6 +6,7 @@ describe Virtus, '.finalize' do
|
|
6
6
|
class Person
|
7
7
|
include Virtus.model(:finalize => false)
|
8
8
|
|
9
|
+
attribute :name, String
|
9
10
|
attribute :articles, Array['Examples::Article']
|
10
11
|
attribute :address, :'Examples::Address'
|
11
12
|
end
|
@@ -39,6 +40,11 @@ describe Virtus, '.finalize' do
|
|
39
40
|
Virtus.finalize
|
40
41
|
end
|
41
42
|
|
43
|
+
it "sets attributes that don't require finalization" do
|
44
|
+
expect(Examples::Person.attribute_set[:name]).to be_instance_of(Virtus::Attribute)
|
45
|
+
expect(Examples::Person.attribute_set[:name].primitive).to be(String)
|
46
|
+
end
|
47
|
+
|
42
48
|
it 'it finalizes member type for a collection attribute' do
|
43
49
|
expect(Examples::Person.attribute_set[:address].primitive).to be(Examples::Address)
|
44
50
|
end
|
data/virtus.gemspec
CHANGED
@@ -20,5 +20,5 @@ Gem::Specification.new do |gem|
|
|
20
20
|
gem.add_dependency('descendants_tracker', '~> 0.0.1')
|
21
21
|
gem.add_dependency('equalizer', '~> 0.0.7')
|
22
22
|
gem.add_dependency('coercible', '~> 0.2')
|
23
|
-
gem.add_dependency('axiom-types', '~> 0.0.
|
23
|
+
gem.add_dependency('axiom-types', '~> 0.0.5')
|
24
24
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: virtus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.
|
4
|
+
version: 1.0.0.rc2
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-10-
|
12
|
+
date: 2013-10-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: descendants_tracker
|
@@ -66,7 +66,7 @@ dependencies:
|
|
66
66
|
requirements:
|
67
67
|
- - ~>
|
68
68
|
- !ruby/object:Gem::Version
|
69
|
-
version: 0.0.
|
69
|
+
version: 0.0.5
|
70
70
|
type: :runtime
|
71
71
|
prerelease: false
|
72
72
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -74,7 +74,7 @@ dependencies:
|
|
74
74
|
requirements:
|
75
75
|
- - ~>
|
76
76
|
- !ruby/object:Gem::Version
|
77
|
-
version: 0.0.
|
77
|
+
version: 0.0.5
|
78
78
|
description: Attributes on Steroids for Plain Old Ruby Objects
|
79
79
|
email:
|
80
80
|
- piotr.solnica@gmail.com
|