bound 0.0.5 → 0.0.6
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.
- checksums.yaml +4 -4
- data/lib/bound.rb +37 -2
- data/lib/bound/version.rb +1 -1
- data/spec/bound_spec.rb +53 -0
- data/spec/hash_object_spec.rb +25 -0
- data/spec/spec_helper.rb +13 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 407f1b12ba2b429451193286bed998eb48a47fcb
|
4
|
+
data.tar.gz: b97c11dcaa8c42fe8eda4291d9653a3722a14ceb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 93d70c496b9f16d3380620e56b48e7de691069cbd1d29c156184470b25db29dc096477cab62ed576c413c9a1874add6dcd8298a1bef8a153e7383696ebf60ca1
|
7
|
+
data.tar.gz: ffe2af419bf9692707cca7ef4442103dbc42666fa989a24bc02e6accc031cba31a20ade6027af97cc40be28b59e0bcb9f3f3a9c7cf7a7b7d459274ed7b66d6ed
|
data/lib/bound.rb
CHANGED
@@ -15,13 +15,14 @@ class Bound
|
|
15
15
|
|
16
16
|
class BoundClass
|
17
17
|
class << self
|
18
|
-
attr_accessor :attributes, :optionals
|
18
|
+
attr_accessor :attributes, :optionals, :nested
|
19
19
|
|
20
20
|
def set_attributes(*attributes)
|
21
21
|
self.attributes = attributes
|
22
22
|
attr_accessor *attributes
|
23
23
|
|
24
|
-
self.optionals
|
24
|
+
self.optionals = []
|
25
|
+
self.nested = []
|
25
26
|
end
|
26
27
|
|
27
28
|
def optional(*optionals)
|
@@ -31,6 +32,24 @@ class Bound
|
|
31
32
|
self
|
32
33
|
end
|
33
34
|
|
35
|
+
def nested(nested_attributes)
|
36
|
+
attributes = nested_attributes.keys
|
37
|
+
self.nested = attributes
|
38
|
+
self.attributes += attributes
|
39
|
+
attr_reader *attributes
|
40
|
+
|
41
|
+
attributes.each do |attribute|
|
42
|
+
define_method :"#{attribute}=" do |initial_values|
|
43
|
+
nested_target = nested_attributes[attribute]
|
44
|
+
value = extract_values_for_nested_attribute(nested_target, initial_values)
|
45
|
+
|
46
|
+
instance_variable_set :"@#{attribute}", value
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
self
|
51
|
+
end
|
52
|
+
|
34
53
|
alias :build :new
|
35
54
|
end
|
36
55
|
|
@@ -57,6 +76,22 @@ class Bound
|
|
57
76
|
|
58
77
|
private
|
59
78
|
|
79
|
+
def build_nested_value(bound_class, init)
|
80
|
+
bound_class.new(init)
|
81
|
+
end
|
82
|
+
|
83
|
+
def extract_values_for_nested_attribute(nested_target, initial_values)
|
84
|
+
if nested_target.kind_of? Array
|
85
|
+
raise ArgumentError.new("Expected #{initial_values.inspect} to be an array") unless initial_values.kind_of? Array
|
86
|
+
|
87
|
+
initial_values.map do |initial_value|
|
88
|
+
build_nested_value(nested_target.first, initial_value)
|
89
|
+
end
|
90
|
+
else
|
91
|
+
build_nested_value(nested_target, initial_values)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
60
95
|
def validate!
|
61
96
|
self.class.attributes.each do |attribute|
|
62
97
|
raise ArgumentError.new("Missing attribute: #{attribute}") unless @hash.key?(attribute)
|
data/lib/bound/version.rb
CHANGED
data/spec/bound_spec.rb
CHANGED
@@ -113,4 +113,57 @@ describe Bound do
|
|
113
113
|
UserWithoutAttributes.build
|
114
114
|
end
|
115
115
|
end
|
116
|
+
|
117
|
+
describe 'nested attribute' do
|
118
|
+
Company = Bound.new(:name).nested(:address => Bound.new(:street))
|
119
|
+
EmployedUser = Bound.new(:uid).nested(:company => Company)
|
120
|
+
let(:hash) { {:uid => '1', :company => {:name => 'featurepoly', :address => {:street => 'Germany'}}} }
|
121
|
+
|
122
|
+
it 'works with nested attributes' do
|
123
|
+
[hash, object].each do |subject|
|
124
|
+
user = EmployedUser.build(subject)
|
125
|
+
|
126
|
+
assert_equal hash[:uid], user.uid
|
127
|
+
assert_equal hash[:company][:name], user.company.name
|
128
|
+
assert_equal hash[:company][:address][:street], user.company.address.street
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
describe 'array of nested attribute' do
|
134
|
+
Post = Bound.new(:title)
|
135
|
+
BloggingUser = Bound.new(:name).nested(:posts => [Post])
|
136
|
+
let(:hash) do
|
137
|
+
{
|
138
|
+
:name => 'Steve',
|
139
|
+
:posts => [
|
140
|
+
{:title => 'It is christmas'},
|
141
|
+
{:title => 'NOT'}
|
142
|
+
]
|
143
|
+
}
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'works with array of nested attributes' do
|
147
|
+
[hash, object].each do |subject|
|
148
|
+
user = BloggingUser.build(subject)
|
149
|
+
|
150
|
+
assert_equal hash[:name], user.name
|
151
|
+
assert_equal hash[:posts][0][:title], user.posts[0].title
|
152
|
+
assert_equal hash[:posts][1][:title], user.posts[1].title
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
it 'fails if posts is no array' do
|
157
|
+
hash[:posts] = {:title => 'broken'}
|
158
|
+
|
159
|
+
[hash, object].each do |subject|
|
160
|
+
exception = assert_raises ArgumentError do
|
161
|
+
BloggingUser.build(subject)
|
162
|
+
end
|
163
|
+
|
164
|
+
assert_match(/array/i, exception.message)
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
168
|
+
end
|
116
169
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# Test support object
|
4
|
+
describe HashObject do
|
5
|
+
|
6
|
+
subject { HashObject.new(hash) }
|
7
|
+
let(:hash) do
|
8
|
+
{
|
9
|
+
:name => 'Steve',
|
10
|
+
:address => {:street => 'Mainstreet'},
|
11
|
+
:posts => [
|
12
|
+
{:title => 'It is christmas'},
|
13
|
+
{:title => 'NOT'}
|
14
|
+
]
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'maps an intergalactic hash' do
|
19
|
+
assert_equal hash[:name], subject.name
|
20
|
+
assert_equal hash[:address][:street], subject.address.street
|
21
|
+
assert_equal hash[:posts].size, subject.posts.size
|
22
|
+
assert_equal hash[:posts][0][:title], subject.posts[0].title
|
23
|
+
assert_equal hash[:posts][1][:title], subject.posts[1].title
|
24
|
+
end
|
25
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -19,7 +19,19 @@ class HashObject
|
|
19
19
|
if attributes.empty?
|
20
20
|
Class.new
|
21
21
|
else
|
22
|
-
|
22
|
+
mapped_values = values.map { |v| map_value(v) }
|
23
|
+
Struct.new(*attributes).new(*mapped_values)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.map_value(value)
|
28
|
+
case value
|
29
|
+
when Hash
|
30
|
+
HashObject.new(value)
|
31
|
+
when Array
|
32
|
+
value.map { |v| map_value(v) }
|
33
|
+
else
|
34
|
+
value
|
23
35
|
end
|
24
36
|
end
|
25
37
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bound
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jakob Holderbaum
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-09-
|
12
|
+
date: 2013-09-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -70,6 +70,7 @@ files:
|
|
70
70
|
- lib/bound.rb
|
71
71
|
- lib/bound/version.rb
|
72
72
|
- spec/bound_spec.rb
|
73
|
+
- spec/hash_object_spec.rb
|
73
74
|
- spec/spec_helper.rb
|
74
75
|
homepage: ''
|
75
76
|
licenses:
|
@@ -97,4 +98,5 @@ specification_version: 4
|
|
97
98
|
summary: Implements a nice helper for fast boundary definitions
|
98
99
|
test_files:
|
99
100
|
- spec/bound_spec.rb
|
101
|
+
- spec/hash_object_spec.rb
|
100
102
|
- spec/spec_helper.rb
|