attrio 0.4.1 → 0.5.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/.travis.yml +0 -1
- data/README.md +17 -0
- data/lib/attrio.rb +5 -4
- data/lib/attrio/attribute.rb +2 -2
- data/lib/attrio/attributes_parser.rb +2 -2
- data/lib/attrio/builders/writer_builder.rb +3 -3
- data/lib/attrio/types/array.rb +48 -0
- data/lib/attrio/types/boolean.rb +1 -1
- data/lib/attrio/version.rb +3 -3
- data/spec/unit/types/array_spec.rb +60 -0
- data/spec/unit/types/boolean_spec.rb +15 -15
- data/spec/unit/types/date_spec.rb +2 -2
- metadata +50 -17
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -300,6 +300,23 @@ class Klass
|
|
300
300
|
end
|
301
301
|
```
|
302
302
|
|
303
|
+
**Array**
|
304
|
+
|
305
|
+
Arrays are designed to automatically handle collections of objects (that also can be typecasted)
|
306
|
+
|
307
|
+
If value that should be typecasted responds to `split`, then this method is called with default (or overriden) attributes, else `Array` is wrapped on value. You can easily handle types and options of collection elements.
|
308
|
+
|
309
|
+
```ruby
|
310
|
+
class Klass
|
311
|
+
include Attrio
|
312
|
+
|
313
|
+
define_attributes do
|
314
|
+
attr :array_attribute, Array
|
315
|
+
attr :custom_array_attribute, Array, :split => ', ', :element => { :type => Date, :options => { :format => '%m/%d/%y' } }
|
316
|
+
end
|
317
|
+
end
|
318
|
+
```
|
319
|
+
|
303
320
|
## Inspect
|
304
321
|
Attrio adds its own `#inspect` method when included to the class. This overridden method prints object attributes in easy to read manner. To disable this feature pass `:inspect => false` to `define_arguments` block.
|
305
322
|
|
data/lib/attrio.rb
CHANGED
@@ -23,8 +23,8 @@ module Attrio
|
|
23
23
|
module ClassMethods
|
24
24
|
def define_attributes(options = {}, &block)
|
25
25
|
options[:as] ||= :attributes
|
26
|
-
|
27
|
-
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
26
|
+
|
27
|
+
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
28
28
|
@#{options[:as]} ||= {}
|
29
29
|
|
30
30
|
class << self
|
@@ -33,10 +33,10 @@ module Attrio
|
|
33
33
|
return @#{options[:as]} if attributes.empty?
|
34
34
|
|
35
35
|
attributes = @#{options[:as]}.keys & attributes
|
36
|
-
@#{options[:as]}.select{ |k,v| attributes.include?(k) }
|
36
|
+
@#{options[:as]}.select{ |k,v| attributes.include?(k) }
|
37
37
|
end
|
38
38
|
|
39
|
-
def inherited(subclass)
|
39
|
+
def inherited(subclass)
|
40
40
|
subclass.instance_variable_set("@#{options[:as]}", instance_variable_get("@#{options[:as]}").dup)
|
41
41
|
end
|
42
42
|
end
|
@@ -67,6 +67,7 @@ module Attrio
|
|
67
67
|
end
|
68
68
|
|
69
69
|
module Types
|
70
|
+
autoload :Array, 'attrio/types/array'
|
70
71
|
autoload :Base, 'attrio/types/base'
|
71
72
|
autoload :Boolean, 'attrio/types/boolean'
|
72
73
|
autoload :Date, 'attrio/types/date'
|
data/lib/attrio/attribute.rb
CHANGED
@@ -32,7 +32,7 @@ module Attrio
|
|
32
32
|
if !defined?(@default_value)
|
33
33
|
@default_value = Attrio::DefaultValue.new(self.name, self.options[:default])
|
34
34
|
end
|
35
|
-
@default_value
|
35
|
+
@default_value
|
36
36
|
end
|
37
37
|
|
38
38
|
def define_writer(klass)
|
@@ -64,7 +64,7 @@ module Attrio
|
|
64
64
|
end
|
65
65
|
|
66
66
|
def accessor_visibility_from_options(accessor)
|
67
|
-
return self.options[accessor] if self.options[accessor].present? && [:public, :protected, :private].include?(self.options[accessor])
|
67
|
+
return self.options[accessor] if self.options[accessor].present? && [:public, :protected, :private].include?(self.options[accessor])
|
68
68
|
(self.options[accessor].is_a?(Hash) && self.options[accessor][:visibility]) || self.options["#{accessor.to_s}_visibility".to_sym]
|
69
69
|
end
|
70
70
|
end
|
@@ -31,7 +31,7 @@ module Attrio
|
|
31
31
|
|
32
32
|
string = constant.to_s
|
33
33
|
string = string.camelize if (string =~ /\w_\w/ || string.chars.first.downcase == string.chars.first)
|
34
|
-
|
34
|
+
|
35
35
|
begin
|
36
36
|
if Attrio::Types.const_defined?(string)
|
37
37
|
return Attrio::Types.const_get(string)
|
@@ -66,6 +66,6 @@ module Attrio
|
|
66
66
|
|
67
67
|
def add_attribute(name, attribute)
|
68
68
|
@klass.send(self.as)[name.to_sym] = attribute
|
69
|
-
end
|
69
|
+
end
|
70
70
|
end
|
71
71
|
end
|
@@ -16,10 +16,10 @@ module Attrio
|
|
16
16
|
else
|
17
17
|
klass.send :attr_writer, options[:method_name].chop
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
klass.send options[:method_visibility], options[:method_name]
|
21
|
-
end
|
22
|
-
end
|
21
|
+
end
|
22
|
+
end
|
23
23
|
|
24
24
|
def self.define_typecasting_method(klass, type, options)
|
25
25
|
klass.send :define_method, options[:method_name] do |value|
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Attrio
|
4
|
+
module Types
|
5
|
+
class Array < Base
|
6
|
+
def self.typecast(value, options = {})
|
7
|
+
begin
|
8
|
+
array = value.respond_to?(:split) ? value.split(options[:split]) : Attrio::Helpers.to_a(value)
|
9
|
+
|
10
|
+
if options[:element].present?
|
11
|
+
type = Attrio::AttributesParser.cast_type(self.element_type(options[:element]))
|
12
|
+
options = self.element_options(options[:element])
|
13
|
+
|
14
|
+
array.map! do |item|
|
15
|
+
if type.respond_to?(:typecast) && type.respond_to?(:typecasted?)
|
16
|
+
type.typecasted?(item) ? item : type.typecast(*[item, options])
|
17
|
+
else
|
18
|
+
type == Hash && item.is_a?(Hash) ? value : type.new(item)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
array
|
24
|
+
rescue ArgumentError => e
|
25
|
+
nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.typecasted?(value)
|
30
|
+
value.is_a? ::Array
|
31
|
+
end
|
32
|
+
|
33
|
+
protected
|
34
|
+
|
35
|
+
def self.element_type(element)
|
36
|
+
element[:type]
|
37
|
+
rescue
|
38
|
+
element
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.element_options(element)
|
42
|
+
element[:options]
|
43
|
+
rescue
|
44
|
+
{}
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/attrio/types/boolean.rb
CHANGED
data/lib/attrio/version.rb
CHANGED
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Attrio::Types::Array do
|
4
|
+
context 'standard casting conventions' do
|
5
|
+
let(:model) do
|
6
|
+
Class.new do
|
7
|
+
include Attrio
|
8
|
+
|
9
|
+
define_attributes do
|
10
|
+
attr :array_attribute, Array
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:object){ model.new }
|
16
|
+
|
17
|
+
context 'with not typecasted assignment' do
|
18
|
+
it 'should cast space separated string' do
|
19
|
+
object.array_attribute = 'first second third'
|
20
|
+
object.array_attribute.should be_instance_of(Array)
|
21
|
+
object.array_attribute.should == %w(first second third)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'with typecasted assignment' do
|
26
|
+
it 'should assign <Array>' do
|
27
|
+
array = %w(first second third)
|
28
|
+
|
29
|
+
object.array_attribute = array
|
30
|
+
object.array_attribute.should be_instance_of(Array)
|
31
|
+
object.array_attribute.should be_equal(array)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'overriden split and element type' do
|
37
|
+
let(:model) do
|
38
|
+
Class.new do
|
39
|
+
include Attrio
|
40
|
+
|
41
|
+
define_attributes do
|
42
|
+
attr :array_attribute, Array, :split => ', ', :element => { :type => Date, :options => { :format => '%m/%d/%y' } }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
let(:object){ model.new }
|
48
|
+
|
49
|
+
context 'with not typecasted assignment' do
|
50
|
+
it 'should cast space separated string' do
|
51
|
+
dates = [Date.today, (Date.today + 1), (Date.today + 2)]
|
52
|
+
string = dates.map{ |date| date.strftime('%m/%d/%y') }.join(', ')
|
53
|
+
|
54
|
+
object.array_attribute = string
|
55
|
+
object.array_attribute.should be_instance_of(Array)
|
56
|
+
object.array_attribute.should == dates
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -14,55 +14,55 @@ describe Attrio::Types::Boolean do
|
|
14
14
|
|
15
15
|
let(:object){ model.new }
|
16
16
|
|
17
|
-
context 'not typecasted assignment' do
|
18
|
-
it 'should cast "true"' do
|
17
|
+
context 'with not typecasted assignment' do
|
18
|
+
it 'should cast "true"' do
|
19
19
|
object.boolean_attribute = 'true'
|
20
20
|
object.boolean_attribute?.should be_true
|
21
21
|
end
|
22
22
|
|
23
|
-
it 'should cast "1"' do
|
23
|
+
it 'should cast "1"' do
|
24
24
|
object.boolean_attribute = '1'
|
25
25
|
object.boolean_attribute?.should be_true
|
26
26
|
end
|
27
27
|
|
28
|
-
it 'should cast 1' do
|
28
|
+
it 'should cast 1' do
|
29
29
|
object.boolean_attribute = 1
|
30
30
|
object.boolean_attribute?.should be_true
|
31
31
|
end
|
32
32
|
|
33
|
-
it 'should cast "yes"' do
|
33
|
+
it 'should cast "yes"' do
|
34
34
|
object.boolean_attribute = 'yes'
|
35
35
|
object.boolean_attribute?.should be_true
|
36
36
|
end
|
37
37
|
|
38
|
-
it 'should cast "false"' do
|
38
|
+
it 'should cast "false"' do
|
39
39
|
object.boolean_attribute = 'false'
|
40
40
|
object.boolean_attribute?.should be_false
|
41
41
|
end
|
42
42
|
|
43
|
-
it 'should cast "0"' do
|
43
|
+
it 'should cast "0"' do
|
44
44
|
object.boolean_attribute = '0'
|
45
45
|
object.boolean_attribute?.should be_false
|
46
46
|
end
|
47
47
|
|
48
|
-
it 'should cast 0' do
|
48
|
+
it 'should cast 0' do
|
49
49
|
object.boolean_attribute = 0
|
50
50
|
object.boolean_attribute?.should be_false
|
51
51
|
end
|
52
52
|
|
53
|
-
it 'should cast "no"' do
|
53
|
+
it 'should cast "no"' do
|
54
54
|
object.boolean_attribute = 'no'
|
55
55
|
object.boolean_attribute?.should be_false
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
|
-
context 'typecasted assignment' do
|
60
|
-
it 'should assign <TrueClass> and do not typecast' do
|
59
|
+
context 'with typecasted assignment' do
|
60
|
+
it 'should assign <TrueClass> and do not typecast' do
|
61
61
|
object.boolean_attribute = true
|
62
62
|
object.boolean_attribute?.should be_true
|
63
63
|
end
|
64
64
|
|
65
|
-
it 'should assign <FalseClass> and do not typecast' do
|
65
|
+
it 'should assign <FalseClass> and do not typecast' do
|
66
66
|
object.boolean_attribute = false
|
67
67
|
object.boolean_attribute?.should be_false
|
68
68
|
end
|
@@ -82,12 +82,12 @@ describe Attrio::Types::Boolean do
|
|
82
82
|
|
83
83
|
let(:object){ model.new }
|
84
84
|
|
85
|
-
it 'should cast "yeah" as TrueClass' do
|
85
|
+
it 'should cast "yeah" as TrueClass' do
|
86
86
|
object.boolean_attribute = 'yeah'
|
87
87
|
object.boolean_attribute?.should be_true
|
88
88
|
end
|
89
89
|
|
90
|
-
it 'should cast anything else as FalseClass' do
|
90
|
+
it 'should cast anything else as FalseClass' do
|
91
91
|
object.boolean_attribute = 'yes'
|
92
92
|
object.boolean_attribute?.should be_false
|
93
93
|
|
@@ -97,5 +97,5 @@ describe Attrio::Types::Boolean do
|
|
97
97
|
object.boolean_attribute = 0
|
98
98
|
object.boolean_attribute?.should be_false
|
99
99
|
end
|
100
|
-
end
|
100
|
+
end
|
101
101
|
end
|
@@ -13,7 +13,7 @@ describe Attrio::Types::Date do
|
|
13
13
|
end
|
14
14
|
|
15
15
|
let(:object){ model.new }
|
16
|
-
|
16
|
+
|
17
17
|
context 'with not typecasted assignment' do
|
18
18
|
it 'should cast <String>' do
|
19
19
|
today = Date.today
|
@@ -47,7 +47,7 @@ describe Attrio::Types::Date do
|
|
47
47
|
end
|
48
48
|
|
49
49
|
let(:object){ model.new }
|
50
|
-
|
50
|
+
|
51
51
|
context 'with not typecasted assignment' do
|
52
52
|
it 'should cast <String> of appropriate format' do
|
53
53
|
today = Date.today
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: attrio
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,11 +10,11 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-
|
13
|
+
date: 2013-07-26 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rspec
|
17
|
-
requirement:
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
18
|
none: false
|
19
19
|
requirements:
|
20
20
|
- - ! '>='
|
@@ -22,10 +22,15 @@ dependencies:
|
|
22
22
|
version: '0'
|
23
23
|
type: :development
|
24
24
|
prerelease: false
|
25
|
-
version_requirements:
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ! '>='
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: '0'
|
26
31
|
- !ruby/object:Gem::Dependency
|
27
32
|
name: webmock
|
28
|
-
requirement:
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
29
34
|
none: false
|
30
35
|
requirements:
|
31
36
|
- - ~>
|
@@ -33,10 +38,15 @@ dependencies:
|
|
33
38
|
version: 1.9.0
|
34
39
|
type: :development
|
35
40
|
prerelease: false
|
36
|
-
version_requirements:
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ~>
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 1.9.0
|
37
47
|
- !ruby/object:Gem::Dependency
|
38
48
|
name: simplecov
|
39
|
-
requirement:
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
40
50
|
none: false
|
41
51
|
requirements:
|
42
52
|
- - ! '>='
|
@@ -44,10 +54,15 @@ dependencies:
|
|
44
54
|
version: '0'
|
45
55
|
type: :development
|
46
56
|
prerelease: false
|
47
|
-
version_requirements:
|
57
|
+
version_requirements: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ! '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
48
63
|
- !ruby/object:Gem::Dependency
|
49
64
|
name: coveralls
|
50
|
-
requirement:
|
65
|
+
requirement: !ruby/object:Gem::Requirement
|
51
66
|
none: false
|
52
67
|
requirements:
|
53
68
|
- - ! '>='
|
@@ -55,10 +70,15 @@ dependencies:
|
|
55
70
|
version: '0'
|
56
71
|
type: :development
|
57
72
|
prerelease: false
|
58
|
-
version_requirements:
|
73
|
+
version_requirements: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ! '>='
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
59
79
|
- !ruby/object:Gem::Dependency
|
60
80
|
name: rake
|
61
|
-
requirement:
|
81
|
+
requirement: !ruby/object:Gem::Requirement
|
62
82
|
none: false
|
63
83
|
requirements:
|
64
84
|
- - ! '>='
|
@@ -66,10 +86,15 @@ dependencies:
|
|
66
86
|
version: '0'
|
67
87
|
type: :development
|
68
88
|
prerelease: false
|
69
|
-
version_requirements:
|
89
|
+
version_requirements: !ruby/object:Gem::Requirement
|
90
|
+
none: false
|
91
|
+
requirements:
|
92
|
+
- - ! '>='
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
70
95
|
- !ruby/object:Gem::Dependency
|
71
96
|
name: bundler
|
72
|
-
requirement:
|
97
|
+
requirement: !ruby/object:Gem::Requirement
|
73
98
|
none: false
|
74
99
|
requirements:
|
75
100
|
- - ! '>='
|
@@ -77,7 +102,12 @@ dependencies:
|
|
77
102
|
version: '0'
|
78
103
|
type: :development
|
79
104
|
prerelease: false
|
80
|
-
version_requirements:
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
107
|
+
requirements:
|
108
|
+
- - ! '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
81
111
|
description:
|
82
112
|
email: hello@jetrockets.ru
|
83
113
|
executables: []
|
@@ -109,6 +139,7 @@ files:
|
|
109
139
|
- lib/attrio/initialize.rb
|
110
140
|
- lib/attrio/inspect.rb
|
111
141
|
- lib/attrio/reset.rb
|
142
|
+
- lib/attrio/types/array.rb
|
112
143
|
- lib/attrio/types/base.rb
|
113
144
|
- lib/attrio/types/boolean.rb
|
114
145
|
- lib/attrio/types/date.rb
|
@@ -130,6 +161,7 @@ files:
|
|
130
161
|
- spec/unit/inspect_spec.rb
|
131
162
|
- spec/unit/reset_spec.rb
|
132
163
|
- spec/unit/type_spec.rb
|
164
|
+
- spec/unit/types/array_spec.rb
|
133
165
|
- spec/unit/types/boolean_spec.rb
|
134
166
|
- spec/unit/types/date_spec.rb
|
135
167
|
- spec/unit/types/date_time_spec.rb
|
@@ -151,7 +183,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
151
183
|
version: '0'
|
152
184
|
segments:
|
153
185
|
- 0
|
154
|
-
hash:
|
186
|
+
hash: -10874694009707771
|
155
187
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
156
188
|
none: false
|
157
189
|
requirements:
|
@@ -160,10 +192,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
160
192
|
version: '0'
|
161
193
|
segments:
|
162
194
|
- 0
|
163
|
-
hash:
|
195
|
+
hash: -10874694009707771
|
164
196
|
requirements: []
|
165
197
|
rubyforge_project:
|
166
|
-
rubygems_version: 1.8.
|
198
|
+
rubygems_version: 1.8.24
|
167
199
|
signing_key:
|
168
200
|
specification_version: 3
|
169
201
|
summary: Attributes for plain old Ruby objects. No dependencies, only simplicity and
|
@@ -181,6 +213,7 @@ test_files:
|
|
181
213
|
- spec/unit/inspect_spec.rb
|
182
214
|
- spec/unit/reset_spec.rb
|
183
215
|
- spec/unit/type_spec.rb
|
216
|
+
- spec/unit/types/array_spec.rb
|
184
217
|
- spec/unit/types/boolean_spec.rb
|
185
218
|
- spec/unit/types/date_spec.rb
|
186
219
|
- spec/unit/types/date_time_spec.rb
|