virtus 0.0.2 → 0.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.
- data/.gitignore +3 -0
- data/.rvmrc +1 -1
- data/Gemfile +20 -1
- data/History.txt +21 -0
- data/README.markdown +2 -2
- data/Rakefile +1 -2
- data/VERSION +1 -1
- data/config/flay.yml +3 -0
- data/config/flog.yml +2 -0
- data/config/roodi.yml +18 -0
- data/config/site.reek +91 -0
- data/config/yardstick.yml +2 -0
- data/lib/virtus.rb +51 -45
- data/lib/virtus/attribute.rb +301 -0
- data/lib/virtus/attribute/array.rb +17 -0
- data/lib/virtus/attribute/boolean.rb +60 -0
- data/lib/virtus/attribute/date.rb +35 -0
- data/lib/virtus/attribute/date_time.rb +34 -0
- data/lib/virtus/attribute/decimal.rb +24 -0
- data/lib/virtus/attribute/float.rb +33 -0
- data/lib/virtus/attribute/hash.rb +18 -0
- data/lib/virtus/attribute/integer.rb +30 -0
- data/lib/virtus/{attributes → attribute}/numeric.rb +2 -3
- data/lib/virtus/{attributes → attribute}/object.rb +2 -1
- data/lib/virtus/attribute/string.rb +31 -0
- data/lib/virtus/attribute/time.rb +34 -0
- data/lib/virtus/class_methods.rb +25 -8
- data/lib/virtus/instance_methods.rb +48 -9
- data/lib/virtus/support/chainable.rb +4 -6
- data/lib/virtus/typecast/boolean.rb +27 -0
- data/lib/virtus/typecast/numeric.rb +82 -0
- data/lib/virtus/typecast/time.rb +162 -0
- data/spec/integration/virtus/attributes/attribute/typecast_spec.rb +4 -4
- data/spec/integration/virtus/class_methods/attribute_spec.rb +1 -1
- data/spec/integration/virtus/class_methods/attributes_spec.rb +3 -2
- data/spec/integration/virtus/class_methods/const_missing_spec.rb +2 -2
- data/spec/rcov.opts +6 -0
- data/spec/spec_helper.rb +0 -9
- data/spec/unit/shared/attribute.rb +8 -8
- data/spec/unit/virtus/{attributes → attribute}/array_spec.rb +1 -1
- data/spec/unit/virtus/attribute/attribute_spec.rb +12 -0
- data/spec/unit/virtus/{attributes → attribute}/boolean_spec.rb +4 -4
- data/spec/unit/virtus/{attributes → attribute}/date_spec.rb +13 -7
- data/spec/unit/virtus/{attributes → attribute}/date_time_spec.rb +31 -10
- data/spec/unit/virtus/{attributes → attribute}/decimal_spec.rb +18 -18
- data/spec/unit/virtus/{attributes → attribute}/float_spec.rb +18 -18
- data/spec/unit/virtus/{attributes → attribute}/hash_spec.rb +1 -1
- data/spec/unit/virtus/{attributes → attribute}/integer_spec.rb +18 -18
- data/spec/unit/virtus/attribute/numeric/class_methods/descendants_spec.rb +15 -0
- data/spec/unit/virtus/attribute/object/class_methods/descendants_spec.rb +16 -0
- data/spec/unit/virtus/{attributes → attribute}/string_spec.rb +2 -2
- data/spec/unit/virtus/{attributes → attribute}/time_spec.rb +19 -9
- data/spec/unit/virtus/class_methods/new_spec.rb +7 -7
- data/spec/unit/virtus/determine_type_spec.rb +4 -4
- data/spec/unit/virtus/instance_methods/attribute_get_spec.rb +1 -1
- data/spec/unit/virtus/instance_methods/attribute_set_spec.rb +2 -2
- data/spec/unit/virtus/instance_methods/attributes_spec.rb +2 -2
- data/tasks/metrics/ci.rake +7 -0
- data/tasks/metrics/flay.rake +41 -0
- data/tasks/metrics/flog.rake +43 -0
- data/tasks/metrics/heckle.rake +261 -0
- data/tasks/metrics/metric_fu.rake +29 -0
- data/tasks/metrics/reek.rake +9 -0
- data/tasks/metrics/roodi.rake +15 -0
- data/tasks/metrics/yardstick.rake +23 -0
- data/tasks/spec.rake +26 -0
- data/tasks/yard.rake +9 -0
- data/virtus.gemspec +48 -33
- metadata +51 -41
- data/lib/virtus/attributes/array.rb +0 -8
- data/lib/virtus/attributes/attribute.rb +0 -214
- data/lib/virtus/attributes/boolean.rb +0 -39
- data/lib/virtus/attributes/date.rb +0 -44
- data/lib/virtus/attributes/date_time.rb +0 -43
- data/lib/virtus/attributes/decimal.rb +0 -24
- data/lib/virtus/attributes/float.rb +0 -20
- data/lib/virtus/attributes/hash.rb +0 -8
- data/lib/virtus/attributes/integer.rb +0 -20
- data/lib/virtus/attributes/string.rb +0 -11
- data/lib/virtus/attributes/time.rb +0 -45
- data/lib/virtus/attributes/typecast/numeric.rb +0 -32
- data/lib/virtus/attributes/typecast/time.rb +0 -27
- data/spec/unit/virtus/attributes/attribute_spec.rb +0 -13
- data/spec/unit/virtus/attributes/numeric/class_methods/descendants_spec.rb +0 -15
- data/spec/unit/virtus/attributes/object/class_methods/descendants_spec.rb +0 -16
@@ -1,39 +0,0 @@
|
|
1
|
-
module Virtus
|
2
|
-
module Attributes
|
3
|
-
class Boolean < Object
|
4
|
-
primitive TrueClass
|
5
|
-
|
6
|
-
TRUE_VALUES = [ 1, '1', 't', 'T', 'true', 'TRUE' ].freeze
|
7
|
-
FALSE_VALUES = [ 0, '0', 'f', 'F', 'false', 'FALSE' ].freeze
|
8
|
-
BOOLEAN_MAP = Hash[
|
9
|
-
TRUE_VALUES.product([ true ]) + FALSE_VALUES.product([ false ]) ].freeze
|
10
|
-
|
11
|
-
def primitive?(value)
|
12
|
-
value == true || value == false
|
13
|
-
end
|
14
|
-
|
15
|
-
def typecast_to_primitive(value, model = nil)
|
16
|
-
BOOLEAN_MAP.fetch(value, value)
|
17
|
-
end
|
18
|
-
|
19
|
-
private
|
20
|
-
|
21
|
-
# Creates standard and boolean attribute reader methods.
|
22
|
-
#
|
23
|
-
# @api private
|
24
|
-
def _create_reader
|
25
|
-
super
|
26
|
-
|
27
|
-
model.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
28
|
-
chainable(:attribute) do
|
29
|
-
#{reader_visibility}
|
30
|
-
|
31
|
-
def #{name}?
|
32
|
-
#{name}
|
33
|
-
end
|
34
|
-
end
|
35
|
-
RUBY
|
36
|
-
end
|
37
|
-
end # Boolean
|
38
|
-
end # Attributes
|
39
|
-
end # Virtus
|
@@ -1,44 +0,0 @@
|
|
1
|
-
module Virtus
|
2
|
-
module Attributes
|
3
|
-
class Date < Object
|
4
|
-
include Typecast::Time
|
5
|
-
|
6
|
-
primitive ::Date
|
7
|
-
|
8
|
-
# Typecasts an arbitrary value to a Date
|
9
|
-
# Handles both Hashes and Date instances.
|
10
|
-
#
|
11
|
-
# @param [Hash, #to_mash, #to_s] value
|
12
|
-
# value to be typecast
|
13
|
-
#
|
14
|
-
# @return [Date]
|
15
|
-
# Date constructed from value
|
16
|
-
#
|
17
|
-
# @api private
|
18
|
-
def typecast_to_primitive(value)
|
19
|
-
if value.respond_to?(:to_date)
|
20
|
-
value.to_date
|
21
|
-
elsif value.is_a?(::Hash)
|
22
|
-
typecast_hash_to_date(value)
|
23
|
-
else
|
24
|
-
::Date.parse(value.to_s)
|
25
|
-
end
|
26
|
-
rescue ArgumentError
|
27
|
-
value
|
28
|
-
end
|
29
|
-
|
30
|
-
# Creates a Date instance from a Hash with keys :year, :month, :day
|
31
|
-
#
|
32
|
-
# @param [Hash, #to_mash] value
|
33
|
-
# value to be typecast
|
34
|
-
#
|
35
|
-
# @return [Date]
|
36
|
-
# Date constructed from hash
|
37
|
-
#
|
38
|
-
# @api private
|
39
|
-
def typecast_hash_to_date(value)
|
40
|
-
::Date.new(*extract_time(value)[0, 3])
|
41
|
-
end
|
42
|
-
end # Date
|
43
|
-
end # Attributes
|
44
|
-
end # Virtus
|
@@ -1,43 +0,0 @@
|
|
1
|
-
module Virtus
|
2
|
-
module Attributes
|
3
|
-
class DateTime < Object
|
4
|
-
primitive ::DateTime
|
5
|
-
|
6
|
-
include Typecast::Time
|
7
|
-
|
8
|
-
# Typecasts an arbitrary value to a DateTime.
|
9
|
-
# Handles both Hashes and DateTime instances.
|
10
|
-
#
|
11
|
-
# @param [Hash, #to_mash, #to_s] value
|
12
|
-
# value to be typecast
|
13
|
-
#
|
14
|
-
# @return [DateTime]
|
15
|
-
# DateTime constructed from value
|
16
|
-
#
|
17
|
-
# @api private
|
18
|
-
def typecast_to_primitive(value, model = nil)
|
19
|
-
if value.is_a?(::Hash)
|
20
|
-
typecast_hash_to_datetime(value)
|
21
|
-
else
|
22
|
-
::DateTime.parse(value.to_s)
|
23
|
-
end
|
24
|
-
rescue ArgumentError
|
25
|
-
value
|
26
|
-
end
|
27
|
-
|
28
|
-
# Creates a DateTime instance from a Hash with keys :year, :month, :day,
|
29
|
-
# :hour, :min, :sec
|
30
|
-
#
|
31
|
-
# @param [Hash, #to_mash] value
|
32
|
-
# value to be typecast
|
33
|
-
#
|
34
|
-
# @return [DateTime]
|
35
|
-
# DateTime constructed from hash
|
36
|
-
#
|
37
|
-
# @api private
|
38
|
-
def typecast_hash_to_datetime(value)
|
39
|
-
::DateTime.new(*extract_time(value))
|
40
|
-
end
|
41
|
-
end # DateTime
|
42
|
-
end # Attributes
|
43
|
-
end # Virtus
|
@@ -1,24 +0,0 @@
|
|
1
|
-
module Virtus
|
2
|
-
module Attributes
|
3
|
-
class Decimal < Numeric
|
4
|
-
primitive ::BigDecimal
|
5
|
-
|
6
|
-
# Typecast a value to a BigDecimal
|
7
|
-
#
|
8
|
-
# @param [#to_str, #to_d, Integer] value
|
9
|
-
# value to typecast
|
10
|
-
#
|
11
|
-
# @return [BigDecimal]
|
12
|
-
# BigDecimal constructed from value
|
13
|
-
#
|
14
|
-
# @api private
|
15
|
-
def typecast_to_primitive(value, model = nil)
|
16
|
-
if value.kind_of?(::Integer)
|
17
|
-
value.to_s.to_d
|
18
|
-
else
|
19
|
-
typecast_to_numeric(value, :to_d)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end # Decimal
|
23
|
-
end # Attributes
|
24
|
-
end # Virtus
|
@@ -1,20 +0,0 @@
|
|
1
|
-
module Virtus
|
2
|
-
module Attributes
|
3
|
-
class Float < Numeric
|
4
|
-
primitive ::Float
|
5
|
-
|
6
|
-
# Typecast a value to a Float
|
7
|
-
#
|
8
|
-
# @param [#to_str, #to_f] value
|
9
|
-
# value to typecast
|
10
|
-
#
|
11
|
-
# @return [Float]
|
12
|
-
# Float constructed from value
|
13
|
-
#
|
14
|
-
# @api private
|
15
|
-
def typecast_to_primitive(value, model = nil)
|
16
|
-
typecast_to_numeric(value, :to_f)
|
17
|
-
end
|
18
|
-
end # Float
|
19
|
-
end # Attributes
|
20
|
-
end # Virtus
|
@@ -1,20 +0,0 @@
|
|
1
|
-
module Virtus
|
2
|
-
module Attributes
|
3
|
-
class Integer < Numeric
|
4
|
-
primitive ::Integer
|
5
|
-
|
6
|
-
# Typecast a value to an Integer
|
7
|
-
#
|
8
|
-
# @param [#to_str, #to_i] value
|
9
|
-
# value to typecast
|
10
|
-
#
|
11
|
-
# @return [Integer]
|
12
|
-
# Integer constructed from value
|
13
|
-
#
|
14
|
-
# @api private
|
15
|
-
def typecast_to_primitive(value, model = nil)
|
16
|
-
typecast_to_numeric(value, :to_i)
|
17
|
-
end
|
18
|
-
end # Integer
|
19
|
-
end # Attributes
|
20
|
-
end # Virtus
|
@@ -1,45 +0,0 @@
|
|
1
|
-
module Virtus
|
2
|
-
module Attributes
|
3
|
-
class Time < Object
|
4
|
-
include Typecast::Time
|
5
|
-
|
6
|
-
primitive ::Time
|
7
|
-
|
8
|
-
# Typecasts an arbitrary value to a Time
|
9
|
-
# Handles both Hashes and Time instances.
|
10
|
-
#
|
11
|
-
# @param [Hash, #to_mash, #to_s] value
|
12
|
-
# value to be typecast
|
13
|
-
#
|
14
|
-
# @return [Time]
|
15
|
-
# Time constructed from value
|
16
|
-
#
|
17
|
-
# @api private
|
18
|
-
def typecast_to_primitive(value, model = nil)
|
19
|
-
if value.respond_to?(:to_time)
|
20
|
-
value.to_time
|
21
|
-
elsif value.is_a?(::Hash)
|
22
|
-
typecast_hash_to_time(value)
|
23
|
-
else
|
24
|
-
::Time.parse(value.to_s)
|
25
|
-
end
|
26
|
-
rescue ArgumentError
|
27
|
-
value
|
28
|
-
end
|
29
|
-
|
30
|
-
# Creates a Time instance from a Hash with keys :year, :month, :day,
|
31
|
-
# :hour, :min, :sec
|
32
|
-
#
|
33
|
-
# @param [Hash, #to_mash] value
|
34
|
-
# value to be typecast
|
35
|
-
#
|
36
|
-
# @return [Time]
|
37
|
-
# Time constructed from hash
|
38
|
-
#
|
39
|
-
# @api private
|
40
|
-
def typecast_hash_to_time(value)
|
41
|
-
::Time.local(*extract_time(value))
|
42
|
-
end
|
43
|
-
end # Time
|
44
|
-
end # Attributes
|
45
|
-
end # Virtus
|
@@ -1,32 +0,0 @@
|
|
1
|
-
module Virtus
|
2
|
-
module Attributes
|
3
|
-
module Typecast
|
4
|
-
module Numeric
|
5
|
-
# Match numeric string
|
6
|
-
#
|
7
|
-
# @param [#to_str, Numeric] value
|
8
|
-
# value to typecast
|
9
|
-
# @param [Symbol] method
|
10
|
-
# method to typecast with
|
11
|
-
#
|
12
|
-
# @return [Numeric]
|
13
|
-
# number if matched, value if no match
|
14
|
-
#
|
15
|
-
# @api private
|
16
|
-
def typecast_to_numeric(value, method)
|
17
|
-
if value.respond_to?(:to_str)
|
18
|
-
if value.to_str =~ /\A(-?(?:0|[1-9]\d*)(?:\.\d+)?|(?:\.\d+))\z/
|
19
|
-
$1.send(method)
|
20
|
-
else
|
21
|
-
value
|
22
|
-
end
|
23
|
-
elsif value.respond_to?(method)
|
24
|
-
value.send(method)
|
25
|
-
else
|
26
|
-
value
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end # Numeric
|
30
|
-
end # Typecast
|
31
|
-
end # Attributes
|
32
|
-
end # Virtus
|
@@ -1,27 +0,0 @@
|
|
1
|
-
module Virtus
|
2
|
-
module Attributes
|
3
|
-
module Typecast
|
4
|
-
module Time
|
5
|
-
include Numeric
|
6
|
-
|
7
|
-
# Extracts the given args from the hash. If a value does not exist, it
|
8
|
-
# uses the value of Time.now.
|
9
|
-
#
|
10
|
-
# @param [Hash, #to_mash] value
|
11
|
-
# value to extract time args from
|
12
|
-
#
|
13
|
-
# @return [Array]
|
14
|
-
# Extracted values
|
15
|
-
#
|
16
|
-
# @api private
|
17
|
-
def extract_time(value)
|
18
|
-
now = ::Time.now
|
19
|
-
|
20
|
-
[ :year, :month, :day, :hour, :min, :sec ].map do |segment|
|
21
|
-
typecast_to_numeric(value.fetch(segment, now.send(segment)), :to_i)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end # Time
|
25
|
-
end # Typecast
|
26
|
-
end # Attributes
|
27
|
-
end # Virtus
|
@@ -1,13 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Virtus::Attributes::Attribute do
|
4
|
-
describe '#typecast_to_primitive' do
|
5
|
-
let(:model) { Class.new { include Virtus } }
|
6
|
-
let(:attribute) { Virtus::Attributes::Attribute.new(:name, model) }
|
7
|
-
let(:value) { 'value' }
|
8
|
-
|
9
|
-
it "returns original value" do
|
10
|
-
attribute.typecast_to_primitive(value, model).should == value
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
@@ -1,15 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Virtus::Attributes::Numeric, '.descendants' do
|
4
|
-
subject { described_class.descendants }
|
5
|
-
|
6
|
-
let(:known_descendants) do
|
7
|
-
[ Virtus::Attributes::Decimal,
|
8
|
-
Virtus::Attributes::Float,
|
9
|
-
Virtus::Attributes::Integer ]
|
10
|
-
end
|
11
|
-
|
12
|
-
it "should return all known attribute classes" do
|
13
|
-
subject.should == known_descendants
|
14
|
-
end
|
15
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Virtus::Attributes::Object, '.descendants' do
|
4
|
-
subject { described_class.descendants }
|
5
|
-
|
6
|
-
let(:known_descendants) do
|
7
|
-
[ Virtus::Attributes::Array, Virtus::Attributes::Boolean,
|
8
|
-
Virtus::Attributes::Date, Virtus::Attributes::DateTime,
|
9
|
-
Virtus::Attributes::Numeric, Virtus::Attributes::Hash,
|
10
|
-
Virtus::Attributes::String, Virtus::Attributes::Time ]
|
11
|
-
end
|
12
|
-
|
13
|
-
it "should return all known attribute classes" do
|
14
|
-
subject.should == known_descendants
|
15
|
-
end
|
16
|
-
end
|