virtus 0.4.0 → 0.4.1
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 +1 -0
- data/Changelog.md +9 -1
- data/Gemfile +1 -1
- data/Guardfile +0 -1
- data/README.md +0 -2
- data/Rakefile +0 -1
- data/config/flay.yml +1 -1
- data/config/flog.yml +1 -1
- data/config/site.reek +1 -1
- data/lib/virtus.rb +4 -2
- data/lib/virtus/attribute.rb +2 -2
- data/lib/virtus/attribute/boolean.rb +1 -1
- data/lib/virtus/attribute/default_value.rb +4 -14
- data/lib/virtus/attribute/default_value/from_callable.rb +5 -3
- data/lib/virtus/attribute/default_value/from_clonable.rb +4 -4
- data/lib/virtus/attribute/default_value/from_symbol.rb +4 -4
- data/lib/virtus/attribute/embedded_value.rb +0 -2
- data/lib/virtus/class_methods.rb +1 -1
- data/lib/virtus/coercion.rb +1 -1
- data/lib/virtus/coercion/numeric.rb +12 -12
- data/lib/virtus/coercion/object.rb +1 -1
- data/lib/virtus/support/equalizer.rb +129 -0
- data/lib/virtus/support/type_lookup.rb +2 -2
- data/lib/virtus/value_object.rb +0 -5
- data/lib/virtus/version.rb +1 -1
- data/spec/spec_helper.rb +0 -3
- data/spec/unit/virtus/attribute/default_spec.rb +0 -4
- data/spec/unit/virtus/attribute/default_value/call_spec.rb +21 -0
- data/spec/unit/virtus/attribute/default_value/class_methods/build_spec.rb +1 -3
- data/spec/unit/virtus/attribute/default_value/class_methods/new_spec.rb +1 -3
- data/spec/unit/virtus/attribute/default_value/from_callable/call_spec.rb +19 -0
- data/spec/unit/virtus/attribute/default_value/from_callable/class_methods/handle_spec.rb +1 -4
- data/spec/unit/virtus/attribute/default_value/from_clonable/call_spec.rb +20 -0
- data/spec/unit/virtus/attribute/default_value/from_clonable/class_methods/handle_spec.rb +1 -2
- data/spec/unit/virtus/attribute/default_value/from_symbol/{evaluate_spec.rb → call_spec.rb} +3 -4
- data/spec/unit/virtus/attribute/default_value/from_symbol/class_methods/handle_spec.rb +1 -4
- data/spec/unit/virtus/attribute/default_value/value_spec.rb +2 -3
- data/spec/unit/virtus/attributes_accessor/define_reader_method_spec.rb +0 -1
- data/spec/unit/virtus/attributes_accessor/define_writer_method_spec.rb +0 -1
- data/spec/unit/virtus/coercion/decimal/class_methods/to_decimal_spec.rb +0 -1
- data/spec/unit/virtus/coercion/float/class_methods/to_float_spec.rb +0 -1
- data/spec/unit/virtus/coercion/integer/class_methods/to_integer_spec.rb +0 -1
- data/spec/unit/virtus/coercion/numeric/class_methods/to_decimal_spec.rb +10 -0
- data/spec/unit/virtus/coercion/numeric/class_methods/to_float_spec.rb +10 -0
- data/spec/unit/virtus/coercion/numeric/class_methods/to_integer_spec.rb +10 -0
- data/spec/unit/virtus/coercion/numeric/class_methods/to_string_spec.rb +12 -0
- data/spec/unit/virtus/coercion/string/class_methods/to_symbol_spec.rb +0 -1
- data/spec/unit/virtus/coercion/time/class_methods/to_integer_spec.rb +0 -1
- data/spec/unit/virtus/coercion/time_coercions/to_date_spec.rb +33 -0
- data/spec/unit/virtus/coercion/time_coercions/to_datetime_spec.rb +33 -0
- data/spec/unit/virtus/coercion/time_coercions/to_string_spec.rb +18 -0
- data/spec/unit/virtus/coercion/time_coercions/to_time_spec.rb +33 -0
- data/spec/unit/virtus/equalizer/append_spec.rb +82 -0
- data/spec/unit/virtus/equalizer/class_method/new_spec.rb +111 -0
- data/spec/unit/virtus/equalizer/methods/eql_spec.rb +47 -0
- data/spec/unit/virtus/equalizer/methods/equal_value_spec.rb +57 -0
- data/spec/unit/virtus/type_lookup/class_methods/extended_spec.rb +0 -1
- data/spec/unit/virtus/value_object/class_methods/attribute_spec.rb +15 -8
- data/spec/unit/virtus/value_object/class_methods/equalizer_spec.rb +1 -1
- data/spec/unit/virtus/value_object/{with_spec.rb → instance_methods/with_spec.rb} +1 -1
- data/tasks/metrics/heckle.rake +2 -2
- data/virtus.gemspec +2 -1
- metadata +29 -23
- data/lib/virtus/value_object/equalizer.rb +0 -125
- data/spec/unit/virtus/attribute/default_value/attribute_spec.rb +0 -11
- data/spec/unit/virtus/attribute/default_value/evaluate_spec.rb +0 -22
- data/spec/unit/virtus/attribute/default_value/from_callable/evaluate_spec.rb +0 -21
- data/spec/unit/virtus/attribute/default_value/from_clonable/evaluate_spec.rb +0 -22
- data/spec/unit/virtus/value_object/equalizer/append_spec.rb +0 -61
data/.travis.yml
CHANGED
data/Changelog.md
CHANGED
@@ -1,10 +1,18 @@
|
|
1
|
+
# v0.4.1 2012-05-06
|
2
|
+
|
3
|
+
* [changed] backports gem is now a runtime dependency (solnic)
|
4
|
+
* [BREAKING CHANGE] Renamed Virtus::DefaultValue#evaluate => Virtus::DefaultValue#call (solnic)
|
5
|
+
* [BREAKING CHANGE] Renamed Virtus::ValueObject::Equalizer to Virtus::Equalizer (dkubb)
|
6
|
+
|
7
|
+
[Compare v0.4.0..v0.4.1](https://github.com/solnic/virtus/compare/v0.4.0...v0.4.1)
|
8
|
+
|
1
9
|
# v0.4.0 2012-03-22
|
2
10
|
|
3
11
|
* [improvement] Add a caching mechanism for type lookups (solnic)
|
4
12
|
* [fixed] Fix attributes mass-assignment when nil is passed (fgrehm)
|
5
13
|
* [changed] Replace usage of #to_hash with Hash.try_convert (dkubb)
|
6
14
|
|
7
|
-
[Compare v0.3.0..v0.4.0](https://github.com/solnic/virtus/compare/v0.3.0...
|
15
|
+
[Compare v0.3.0..v0.4.0](https://github.com/solnic/virtus/compare/v0.3.0...v0.4.0)
|
8
16
|
|
9
17
|
# v0.3.0 2012-02-25
|
10
18
|
|
data/Gemfile
CHANGED
data/Guardfile
CHANGED
data/README.md
CHANGED
data/Rakefile
CHANGED
data/config/flay.yml
CHANGED
data/config/flog.yml
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
---
|
2
|
-
threshold:
|
2
|
+
threshold: 22.2
|
data/config/site.reek
CHANGED
data/lib/virtus.rb
CHANGED
@@ -3,13 +3,15 @@ require 'date'
|
|
3
3
|
require 'time'
|
4
4
|
require 'bigdecimal'
|
5
5
|
require 'bigdecimal/util'
|
6
|
+
require 'ostruct'
|
7
|
+
require 'backports'
|
6
8
|
|
7
9
|
# Base module which adds Attribute API to your classes
|
8
10
|
module Virtus
|
9
11
|
|
10
12
|
# Provides args for const_get and const_defined? to make them behave
|
11
13
|
# consistently across different versions of ruby
|
12
|
-
EXTRA_CONST_ARGS = (RUBY_VERSION < '1.9'
|
14
|
+
EXTRA_CONST_ARGS = (RUBY_VERSION < '1.9' ? [] : [ false ]).freeze
|
13
15
|
|
14
16
|
# Represents an undefined parameter used by auto-generated option methods
|
15
17
|
Undefined = Object.new.freeze
|
@@ -34,6 +36,7 @@ end # module Virtus
|
|
34
36
|
require 'virtus/support/descendants_tracker'
|
35
37
|
require 'virtus/support/type_lookup'
|
36
38
|
require 'virtus/support/options'
|
39
|
+
require 'virtus/support/equalizer'
|
37
40
|
|
38
41
|
require 'virtus/attributes_accessor'
|
39
42
|
require 'virtus/class_methods'
|
@@ -83,4 +86,3 @@ require 'virtus/attribute/symbol'
|
|
83
86
|
require 'virtus/attribute/string'
|
84
87
|
require 'virtus/attribute/time'
|
85
88
|
require 'virtus/attribute/embedded_value'
|
86
|
-
|
data/lib/virtus/attribute.rb
CHANGED
@@ -127,7 +127,7 @@ module Virtus
|
|
127
127
|
@instance_variable_name = "@#{@name}".to_sym
|
128
128
|
@primitive = @options.fetch(:primitive)
|
129
129
|
@coercion_method = @options.fetch(:coercion_method)
|
130
|
-
@default = DefaultValue.build(
|
130
|
+
@default = DefaultValue.build(@options[:default])
|
131
131
|
initialize_visibility
|
132
132
|
end
|
133
133
|
|
@@ -160,7 +160,7 @@ module Virtus
|
|
160
160
|
if instance.instance_variable_defined?(@instance_variable_name)
|
161
161
|
get!(instance)
|
162
162
|
else
|
163
|
-
value = default.
|
163
|
+
value = default.call(instance, self)
|
164
164
|
set!(instance, value)
|
165
165
|
value
|
166
166
|
end
|
@@ -17,13 +17,6 @@ module Virtus
|
|
17
17
|
klass.new(*args)
|
18
18
|
end
|
19
19
|
|
20
|
-
# Returns the attribute associated with this default value instance
|
21
|
-
#
|
22
|
-
# @return [Virtus::Attribute::Object]
|
23
|
-
#
|
24
|
-
# @api private
|
25
|
-
attr_reader :attribute
|
26
|
-
|
27
20
|
# Returns the value instance
|
28
21
|
#
|
29
22
|
# @return [Object]
|
@@ -33,27 +26,24 @@ module Virtus
|
|
33
26
|
|
34
27
|
# Initializes an default value instance
|
35
28
|
#
|
36
|
-
# @param [Virtus::Attribute] attribute
|
37
29
|
# @param [Object] value
|
38
30
|
#
|
39
31
|
# @return [undefined]
|
40
32
|
#
|
41
33
|
# @api private
|
42
|
-
def initialize(
|
43
|
-
@
|
34
|
+
def initialize(value)
|
35
|
+
@value = value
|
44
36
|
end
|
45
37
|
|
46
38
|
# Evaluates the value
|
47
39
|
#
|
48
|
-
# @param [Object]
|
49
|
-
#
|
50
40
|
# @return [Object] evaluated value
|
51
41
|
#
|
52
42
|
# @api private
|
53
|
-
def
|
43
|
+
def call(*)
|
54
44
|
value
|
55
45
|
end
|
56
|
-
end # class DefaultValue
|
57
46
|
|
47
|
+
end # class DefaultValue
|
58
48
|
end # class Attribute
|
59
49
|
end # module Virtus
|
@@ -9,10 +9,12 @@ module Virtus
|
|
9
9
|
|
10
10
|
# Return if the class can handle the value
|
11
11
|
#
|
12
|
+
# @param [Object] value
|
13
|
+
#
|
12
14
|
# @return [Boolean]
|
13
15
|
#
|
14
16
|
# @api private
|
15
|
-
def self.handle?(
|
17
|
+
def self.handle?(value)
|
16
18
|
value.respond_to?(:call)
|
17
19
|
end
|
18
20
|
|
@@ -23,8 +25,8 @@ module Virtus
|
|
23
25
|
# @return [Object] evaluated value
|
24
26
|
#
|
25
27
|
# @api private
|
26
|
-
def
|
27
|
-
@value.call(
|
28
|
+
def call(*args)
|
29
|
+
@value.call(*args)
|
28
30
|
end
|
29
31
|
|
30
32
|
end # class FromCallable
|
@@ -11,10 +11,12 @@ module Virtus
|
|
11
11
|
|
12
12
|
# Return if the class can handle the value
|
13
13
|
#
|
14
|
+
# @param [Object] value
|
15
|
+
#
|
14
16
|
# @return [Boolean]
|
15
17
|
#
|
16
18
|
# @api private
|
17
|
-
def self.handle?(
|
19
|
+
def self.handle?(value)
|
18
20
|
case value
|
19
21
|
when *SINGLETON_CLASSES
|
20
22
|
false
|
@@ -25,12 +27,10 @@ module Virtus
|
|
25
27
|
|
26
28
|
# Evaluates the value via value#clone
|
27
29
|
#
|
28
|
-
# @param [Object]
|
29
|
-
#
|
30
30
|
# @return [Object] evaluated value
|
31
31
|
#
|
32
32
|
# @api private
|
33
|
-
def
|
33
|
+
def call(*)
|
34
34
|
@value.clone
|
35
35
|
end
|
36
36
|
|
@@ -9,10 +9,12 @@ module Virtus
|
|
9
9
|
|
10
10
|
# Return if the class can handle the value
|
11
11
|
#
|
12
|
+
# @param [Object] value
|
13
|
+
#
|
12
14
|
# @return [Boolean]
|
13
15
|
#
|
14
16
|
# @api private
|
15
|
-
def self.handle?(
|
17
|
+
def self.handle?(value)
|
16
18
|
value.is_a?(::Symbol)
|
17
19
|
end
|
18
20
|
|
@@ -20,12 +22,10 @@ module Virtus
|
|
20
22
|
#
|
21
23
|
# Symbol value is returned if the instance doesn't respond to value
|
22
24
|
#
|
23
|
-
# @param [Object]
|
24
|
-
#
|
25
25
|
# @return [Object] evaluated value
|
26
26
|
#
|
27
27
|
# @api private
|
28
|
-
def
|
28
|
+
def call(instance, *)
|
29
29
|
instance.respond_to?(@value) ? instance.public_send(@value) : @value
|
30
30
|
end
|
31
31
|
|
data/lib/virtus/class_methods.rb
CHANGED
data/lib/virtus/coercion.rb
CHANGED
@@ -8,9 +8,9 @@ module Virtus
|
|
8
8
|
# Coerce given value to String
|
9
9
|
#
|
10
10
|
# @example
|
11
|
-
# Virtus::Coercion::
|
11
|
+
# Virtus::Coercion::Numeric.to_string(Rational(2, 2)) # => "1.0"
|
12
12
|
#
|
13
|
-
# @param [
|
13
|
+
# @param [Numeric] value
|
14
14
|
#
|
15
15
|
# @return [String]
|
16
16
|
#
|
@@ -19,14 +19,14 @@ module Virtus
|
|
19
19
|
value.to_s
|
20
20
|
end
|
21
21
|
|
22
|
-
# Creates
|
22
|
+
# Creates an Integer instance from a numeric object
|
23
23
|
#
|
24
24
|
# @example
|
25
|
-
# Virtus::Coercion::
|
25
|
+
# Virtus::Coercion::Numeric.to_integer(Rational(2, 2)) # => 1
|
26
26
|
#
|
27
|
-
# @param [
|
27
|
+
# @param [Numeric] value
|
28
28
|
#
|
29
|
-
# @return [
|
29
|
+
# @return [Integer]
|
30
30
|
#
|
31
31
|
# @api public
|
32
32
|
def self.to_integer(value)
|
@@ -36,23 +36,23 @@ module Virtus
|
|
36
36
|
# Creates a Float instance from a numeric object
|
37
37
|
#
|
38
38
|
# @example
|
39
|
-
# Virtus::Coercion::
|
39
|
+
# Virtus::Coercion::Numeric.to_float(Rational(2, 2)) # => 1.0
|
40
40
|
#
|
41
|
-
# @param [
|
41
|
+
# @param [Numeric] value
|
42
42
|
#
|
43
|
-
# @return [
|
43
|
+
# @return [Float]
|
44
44
|
#
|
45
45
|
# @api public
|
46
46
|
def self.to_float(value)
|
47
47
|
value.to_f
|
48
48
|
end
|
49
49
|
|
50
|
-
# Coerce
|
50
|
+
# Coerce a BigDecimal instance from a numeric object
|
51
51
|
#
|
52
52
|
# @example
|
53
|
-
# Virtus::Coercion::
|
53
|
+
# Virtus::Coercion::Numeric.to_decimal(Rational(2, 2)) # => BigDecimal('1.0')
|
54
54
|
#
|
55
|
-
# @param [
|
55
|
+
# @param [Numeric] value
|
56
56
|
#
|
57
57
|
# @return [BigDecimal]
|
58
58
|
#
|
@@ -0,0 +1,129 @@
|
|
1
|
+
module Virtus
|
2
|
+
|
3
|
+
# Define equality, equivalence and inspection methods
|
4
|
+
class Equalizer < Module
|
5
|
+
|
6
|
+
# Initialize an Equalizer with the given keys
|
7
|
+
#
|
8
|
+
# Will use the keys with which it is initialized to define #cmp?,
|
9
|
+
# #hash, and #inspect
|
10
|
+
#
|
11
|
+
# @param [String] name
|
12
|
+
#
|
13
|
+
# @param [Array<Symbol>] keys
|
14
|
+
#
|
15
|
+
# @return [undefined]
|
16
|
+
#
|
17
|
+
# @api private
|
18
|
+
def initialize(name, keys = [])
|
19
|
+
@name = name.dup.freeze
|
20
|
+
@keys = keys.dup
|
21
|
+
define_methods
|
22
|
+
include_comparison_methods
|
23
|
+
end
|
24
|
+
|
25
|
+
# Append a key and compile the equality methods
|
26
|
+
#
|
27
|
+
# @return [Equalizer] self
|
28
|
+
#
|
29
|
+
# @api private
|
30
|
+
def <<(key)
|
31
|
+
@keys << key
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
# Define the equalizer methods based on #keys
|
38
|
+
#
|
39
|
+
# @return [undefined]
|
40
|
+
#
|
41
|
+
# @api private
|
42
|
+
def define_methods
|
43
|
+
define_cmp_method
|
44
|
+
define_hash_method
|
45
|
+
define_inspect_method
|
46
|
+
end
|
47
|
+
|
48
|
+
# Define an #cmp? method based on the instance's values identified by #keys
|
49
|
+
#
|
50
|
+
# @return [undefined]
|
51
|
+
#
|
52
|
+
# @api private
|
53
|
+
def define_cmp_method
|
54
|
+
keys = @keys
|
55
|
+
define_method(:cmp?) do |comparator, other|
|
56
|
+
keys.all? { |key| send(key).send(comparator, other.send(key)) }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Define a #hash method based on the instance's values identified by #keys
|
61
|
+
#
|
62
|
+
# @return [undefined]
|
63
|
+
#
|
64
|
+
# @api private
|
65
|
+
def define_hash_method
|
66
|
+
keys = @keys
|
67
|
+
define_method(:hash) do
|
68
|
+
keys.map { |key| send(key).hash }.reduce(self.class.hash, :^)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Define an inspect method that reports the values of the instance's keys
|
73
|
+
#
|
74
|
+
# @return [undefined]
|
75
|
+
#
|
76
|
+
# @api private
|
77
|
+
def define_inspect_method
|
78
|
+
name, keys = @name, @keys
|
79
|
+
define_method(:inspect) do
|
80
|
+
"#<#{name}#{keys.map { |key| " #{key}=#{send(key).inspect}" }.join}>"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# Include the #eql? and #== methods
|
85
|
+
#
|
86
|
+
# @return [undefined]
|
87
|
+
#
|
88
|
+
# @api private
|
89
|
+
def include_comparison_methods
|
90
|
+
module_eval { include Methods }
|
91
|
+
end
|
92
|
+
|
93
|
+
# The comparison methods
|
94
|
+
module Methods
|
95
|
+
|
96
|
+
# Compare the object with other object for equality
|
97
|
+
#
|
98
|
+
# @example
|
99
|
+
# object.eql?(other) # => true or false
|
100
|
+
#
|
101
|
+
# @param [Object] other
|
102
|
+
# the other object to compare with
|
103
|
+
#
|
104
|
+
# @return [Boolean]
|
105
|
+
#
|
106
|
+
# @api public
|
107
|
+
def eql?(other)
|
108
|
+
instance_of?(other.class) and cmp?(__method__, other)
|
109
|
+
end
|
110
|
+
|
111
|
+
# Compare the object with other object for equivalency
|
112
|
+
#
|
113
|
+
# @example
|
114
|
+
# object == other # => true or false
|
115
|
+
#
|
116
|
+
# @param [Object] other
|
117
|
+
# the other object to compare with
|
118
|
+
#
|
119
|
+
# @return [Boolean]
|
120
|
+
#
|
121
|
+
# @api public
|
122
|
+
def ==(other)
|
123
|
+
return false unless self.class <=> other.class
|
124
|
+
cmp?(__method__, other)
|
125
|
+
end
|
126
|
+
|
127
|
+
end # module Methods
|
128
|
+
end # class Equalizer
|
129
|
+
end # module Virtus
|