bound 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 19c4132942443826a69acf31323e7aa1383e4901
4
- data.tar.gz: a227951c47f6e073371f6134f16a193e7f349d49
3
+ metadata.gz: 407f1b12ba2b429451193286bed998eb48a47fcb
4
+ data.tar.gz: b97c11dcaa8c42fe8eda4291d9653a3722a14ceb
5
5
  SHA512:
6
- metadata.gz: 0d06853ef334dcb348d5765d7eb9b47695fd78cfa30a010e3baa5ba311ad61f7b4f6f7a488a4fcdb8b7c68241470bb0203c4ae71185efad1fffbbf19261ca580
7
- data.tar.gz: 2a3cabfd7c91b7c127406afe68ba7205421d6e41c6ae8c79bb4af6f65fef651a4386075010cf0011e9bb419160b845bd614c870db3196f65ff448b64b3c57941
6
+ metadata.gz: 93d70c496b9f16d3380620e56b48e7de691069cbd1d29c156184470b25db29dc096477cab62ed576c413c9a1874add6dcd8298a1bef8a153e7383696ebf60ca1
7
+ data.tar.gz: ffe2af419bf9692707cca7ef4442103dbc42666fa989a24bc02e6accc031cba31a20ade6027af97cc40be28b59e0bcb9f3f3a9c7cf7a7b7d459274ed7b66d6ed
@@ -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)
@@ -1,3 +1,3 @@
1
1
  class Bound
2
- VERSION = "0.0.5"
2
+ VERSION = "0.0.6"
3
3
  end
@@ -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
@@ -19,7 +19,19 @@ class HashObject
19
19
  if attributes.empty?
20
20
  Class.new
21
21
  else
22
- Struct.new(*attributes).new(*values)
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.5
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-21 00:00:00.000000000 Z
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