aduki 0.0.11 → 0.1.0

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: 6ca8a03939e3f4904afebba8a335ca2f7e3fdcc5
4
- data.tar.gz: 70223137072e357aa6963fa97b3536fe14ffa93d
3
+ metadata.gz: 45420ab64b5875f1f53255ea0600451290e07f9a
4
+ data.tar.gz: 9a4a18aa6898f51506d3cd6161a1c3b3b7d5b628
5
5
  SHA512:
6
- metadata.gz: 7bde6768466c7cecde67f17caa5dfa0cd3c4b6956342e75affc73a4447335e6bbc4bf48dd72229456db8926bec4d900c49e297ad9a904088f082303ed8ebf1d5
7
- data.tar.gz: 93dab1a3ebcb754f76edc823caea987cdabee8f1d70f24567ca2d2d3c72f91b70ec9a64cf415805fc341d94094d12360761dc83633a5f7f69119a0da1c92063c
6
+ metadata.gz: 4ed7538d054f37e27516b18927a1285f1c827165b44738b47fe656990aa9605aa0a0d1a0dd422096c1554043f7c33e9a2d05129378186642da1ad15a683b5b97
7
+ data.tar.gz: dbab54e9a51a1e76377f0d9be20dce68240514d4573d365f35202054faaa98bb838e67b8fe85fcf281e62c40528eae52b63efc068657a08cb5c4d6e477706d6c
@@ -97,10 +97,15 @@ module Aduki
97
97
  end
98
98
 
99
99
  def self.apply_single_attribute klass, object, setter, value
100
- setter_method = "#{setter}=".to_sym
101
- return unless object.respond_to? setter_method
100
+ existing_value = object.send setter
101
+ if existing_value && value.is_a?(Hash)
102
+ Aduki.apply_attributes existing_value, value
103
+ else
104
+ setter_method = "#{setter}=".to_sym
105
+ return unless object.respond_to? setter_method
102
106
 
103
- object.send setter_method, to_value(klass, setter, value)
107
+ object.send setter_method, to_value(klass, setter, value)
108
+ end
104
109
  end
105
110
 
106
111
  def self.apply_attribute klass, object, setter, value
@@ -123,20 +128,41 @@ module Aduki
123
128
 
124
129
  module ClassMethods
125
130
  @@types = { }
131
+ @@initializers = { }
126
132
 
127
133
  def aduki types
128
134
  @@types[self] ||= { }
129
135
  @@types[self] = @@types[self].merge types
136
+ types.each do |attr, k|
137
+ attr = attr.to_sym
138
+ attr_reader attr unless method_defined? attr
139
+ attr_writer attr unless method_defined? :"#{attr}="
140
+ end
141
+ end
142
+
143
+ def aduki_initialize name, klass
144
+ aduki name => klass
145
+ initializer_name = :"aduki_initialize_#{name}"
146
+ define_method initializer_name do
147
+ send :"#{name}=", klass.new
148
+ end
149
+ @@initializers[self] ||= []
150
+ @@initializers[self] << initializer_name
130
151
  end
131
152
 
132
153
  def aduki_type_for_attribute_name name
133
154
  hsh = @@types[self]
134
155
  hsh ? hsh[name.to_sym] : nil
135
156
  end
157
+
158
+ def get_aduki_initializers
159
+ @@initializers[self] || []
160
+ end
136
161
  end
137
162
 
138
163
  module Initializer
139
164
  def initialize attrs={ }
165
+ self.class.get_aduki_initializers.each { |initializer| send initializer }
140
166
  Aduki.apply_attributes self, attrs
141
167
  end
142
168
 
@@ -1,3 +1,3 @@
1
1
  module Aduki
2
- VERSION = "0.0.11"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -2,11 +2,11 @@ require "aduki"
2
2
  require "spec_helper"
3
3
 
4
4
  describe Aduki::Initializer do
5
-
6
- it "should assign an integer attribute" do
5
+ it "should assign an integer attribute of an object nested in an array attribute" do
7
6
  props = {
8
7
  "name" => "Foo",
9
- "assemblies" => [{ "name" => "A0", "height" => "10" }, { "name" => "A1", "height" => "20" }, { "name" => "A2", "height" => "30" }, ]
8
+ "assemblies" => [{ "name" => "A0", "height" => "10" }, { "name" => "A1", "height" => "20" }, { "name" => "A2", "height" => "30" }, ],
9
+ "dimensions" => [{ x: 1, y: 2, z: 34.5}, { x: 17, y: 23, z: 34.5}, ]
10
10
  }
11
11
 
12
12
  machine = Machine.new props
@@ -21,5 +21,13 @@ describe Aduki::Initializer do
21
21
 
22
22
  expect(machine.assemblies[2].name).to eq "A2"
23
23
  expect(machine.assemblies[2].height).to eq 30
24
+
25
+ expect(machine.dimensions[0][:x]).to eq 1
26
+ expect(machine.dimensions[0][:y]).to eq 2
27
+ expect(machine.dimensions[0][:z]).to eq 34.5
28
+
29
+ expect(machine.dimensions[1][:x]).to eq 17
30
+ expect(machine.dimensions[1][:y]).to eq 23
31
+ expect(machine.dimensions[1][:z]).to eq 34.5
24
32
  end
25
33
  end
@@ -3,88 +3,90 @@ require "spec_helper"
3
3
 
4
4
  describe Aduki::Initializer do
5
5
 
6
+ PROPS = {
7
+ "name" => "Willy",
8
+ "email" => "willy@wonka.softify.com",
9
+ "item" => "HXB5H",
10
+ "thing" => "0",
11
+ "gadget.name" => "My Big Gadget",
12
+ "gadget.price" => "21",
13
+ "gadget.supplier" => "Apple, Inc.",
14
+ "machines[0].name" => "The First Machine",
15
+ "machines[0].weight" => "88",
16
+ "machines[0].speed" => "142",
17
+ "machines[0].builder.name" => "The First Machine Builder",
18
+ "machines[0].builder.email" => "wibble@bump",
19
+ "machines[0].builder.phone" => "4099",
20
+ "machines[0].builder.office" => "2nd floor room 12",
21
+ "machines[0].assemblies[0].name" => "first machine, first assembly", # the array index orders items without respecting the exact position
22
+ "machines[0].assemblies[1].name" => "first machine, second assembly",
23
+ "machines[0].assemblies[2].name" => "first machine, third assembly",
24
+ "machines[0].assemblies[0].colour" => "red",
25
+ "machines[0].assemblies[1].colour" => "green",
26
+ "machines[0].assemblies[2].colour" => "blue",
27
+ "machines[0].assemblies[0].size" => "pretty large",
28
+ "machines[0].assemblies[1].size" => "sort of medium",
29
+ "machines[0].assemblies[2].size" => "miniscule",
30
+ "machines[0].dimensions[0]" => "2346.56",
31
+ "machines[0].dimensions[1]" => "6456.64",
32
+ "machines[0].dimensions[2]" => "3859.39",
33
+ "machines[0].dimensions[3]" => "2365.68",
34
+ "machines[0].team.lead" => "Shakespeare", # there is no class definition for #team, so Aduki will apply a hash with properties #lead, #code, #design
35
+ "machines[0].team.code" => "Chaucer",
36
+ "machines[0].team.design" => "Jobs",
37
+ "machines[0].helpers.jim.name" => "Jim Appleby",
38
+ "machines[0].helpers.jim.email" => "Jim.Appleby@example.com",
39
+ "machines[0].helpers.jim.phone" => "123 456 789",
40
+ "machines[0].helpers.jim.office" => "Elephant & Castle",
41
+ "machines[0].helpers.ben.name" => "Ben Barnes",
42
+ "machines[0].helpers.ben.email" => "Ben.Barnes@example.com",
43
+ "machines[0].helpers.ben.phone" => "123 456 790",
44
+ "machines[0].helpers.ben.office" => "Cockney",
45
+ "machines[0].helpers.pat.name" => "Patrick O'Brien",
46
+ "machines[0].helpers.pat.email" => "Patrick.O.Brien@example.com",
47
+ "machines[0].helpers.pat.phone" => "123 456 791",
48
+ "machines[0].helpers.pat.office" => "Hammersmith",
49
+ "machines[1].name" => "The Second Machine",
50
+ "machines[1].weight" => "34",
51
+ "machines[1].speed" => "289",
52
+ "machines[1].builder.name" => "The Second Machine Builder",
53
+ "machines[1].builder.email" => "waggie@bump",
54
+ "machines[1].builder.phone" => "4101",
55
+ "machines[1].builder.office" => "3rd floor room 23",
56
+ "machines[1].assemblies[98].name" => "second machine, first assembly", # the array index orders items but the position is not respected
57
+ "machines[1].assemblies[98].colour" => "purple",
58
+ "machines[1].assemblies[98].size" => "pretty small",
59
+ "machines[1].assemblies[1].name" => "second machine, second assembly",
60
+ "machines[1].assemblies[1].colour" => "turquoise",
61
+ "machines[1].assemblies[1].size" => "large-ish",
62
+ "machines[1].assemblies[99].name" => "second machine, third assembly",
63
+ "machines[1].assemblies[99].colour" => "magenta",
64
+ "machines[1].assemblies[99].size" => "gigantic",
65
+ "machines[1].dimensions[20]" => "1985.85",
66
+ "machines[1].dimensions[30]" => "7234.92",
67
+ "machines[1].dimensions[40]" => "9725.52",
68
+ "machines[1].dimensions[50]" => "3579.79",
69
+ "machines[1].team.lead" => "Joyce",
70
+ "machines[1].team.code" => "O'Brien",
71
+ "machines[1].team.design" => "Moore",
72
+ "machines[1].team.muffins" => "MacNamara",
73
+ "contraptions[0].x" => "19",
74
+ "contraptions[0].y" => "0.003",
75
+ "contraptions[1].x" => "12",
76
+ "contraptions[1].y" => "0.0012",
77
+ "contraptions[2].x" => "24",
78
+ "contraptions[2].y" => "0.00063",
79
+ "contraptions[3].x" => "16",
80
+ "contraptions[3].y" => "0.00091",
81
+ "countries[0]" => "France",
82
+ "countries[1]" => "Sweden",
83
+ "countries[2]" => "Germany",
84
+ "countries[3]" => "Ireland",
85
+ "countries[4]" => "Spain",
86
+ }
87
+
6
88
  it "should set a bunch of properties from a hash of property paths" do
7
- props = {
8
- "name" => "Willy",
9
- "email" => "willy@wonka.softify.com",
10
- "item" => "HXB5H",
11
- "thing" => "0",
12
- "gadget.name" => "My Big Gadget",
13
- "gadget.price" => "21",
14
- "gadget.supplier" => "Apple, Inc.",
15
- "machines[0].name" => "The First Machine",
16
- "machines[0].weight" => "88",
17
- "machines[0].speed" => "142",
18
- "machines[0].builder.name" => "The First Machine Builder",
19
- "machines[0].builder.email" => "wibble@bump",
20
- "machines[0].builder.phone" => "4099",
21
- "machines[0].builder.office" => "2nd floor room 12",
22
- "machines[0].assemblies[0].name" => "first machine, first assembly", # the array index distinguishes items but does not order them
23
- "machines[0].assemblies[1].name" => "first machine, second assembly",
24
- "machines[0].assemblies[2].name" => "first machine, third assembly",
25
- "machines[0].assemblies[0].colour" => "red",
26
- "machines[0].assemblies[1].colour" => "green",
27
- "machines[0].assemblies[2].colour" => "blue",
28
- "machines[0].assemblies[0].size" => "pretty large",
29
- "machines[0].assemblies[1].size" => "sort of medium",
30
- "machines[0].assemblies[2].size" => "miniscule",
31
- "machines[0].dimensions[0]" => "2346.56",
32
- "machines[0].dimensions[1]" => "6456.64",
33
- "machines[0].dimensions[2]" => "3859.39",
34
- "machines[0].dimensions[3]" => "2365.68",
35
- "machines[0].team.lead" => "Shakespeare", # there is no class definition for #team, so Aduki will apply a hash with properties #lead, #code, #design
36
- "machines[0].team.code" => "Chaucer",
37
- "machines[0].team.design" => "Jobs",
38
- "machines[0].helpers.jim.name" => "Jim Appleby",
39
- "machines[0].helpers.jim.email" => "Jim.Appleby@example.com",
40
- "machines[0].helpers.jim.phone" => "123 456 789",
41
- "machines[0].helpers.jim.office" => "Elephant & Castle",
42
- "machines[0].helpers.ben.name" => "Ben Barnes",
43
- "machines[0].helpers.ben.email" => "Ben.Barnes@example.com",
44
- "machines[0].helpers.ben.phone" => "123 456 790",
45
- "machines[0].helpers.ben.office" => "Cockney",
46
- "machines[0].helpers.pat.name" => "Patrick O'Brien",
47
- "machines[0].helpers.pat.email" => "Patrick.O.Brien@example.com",
48
- "machines[0].helpers.pat.phone" => "123 456 791",
49
- "machines[0].helpers.pat.office" => "Hammersmith",
50
- "machines[1].name" => "The Second Machine",
51
- "machines[1].weight" => "34",
52
- "machines[1].speed" => "289",
53
- "machines[1].builder.name" => "The Second Machine Builder",
54
- "machines[1].builder.email" => "waggie@bump",
55
- "machines[1].builder.phone" => "4101",
56
- "machines[1].builder.office" => "3rd floor room 23",
57
- "machines[1].assemblies[98].name" => "second machine, first assembly", # the array index orders items but the position is not respected
58
- "machines[1].assemblies[98].colour" => "purple",
59
- "machines[1].assemblies[98].size" => "pretty small",
60
- "machines[1].assemblies[1].name" => "second machine, second assembly",
61
- "machines[1].assemblies[1].colour" => "turquoise",
62
- "machines[1].assemblies[1].size" => "large-ish",
63
- "machines[1].assemblies[99].name" => "second machine, third assembly",
64
- "machines[1].assemblies[99].colour" => "magenta",
65
- "machines[1].assemblies[99].size" => "gigantic",
66
- "machines[1].dimensions[20]" => "1985.85",
67
- "machines[1].dimensions[30]" => "7234.92",
68
- "machines[1].dimensions[40]" => "9725.52",
69
- "machines[1].dimensions[50]" => "3579.79",
70
- "machines[1].team.lead" => "Joyce",
71
- "machines[1].team.code" => "O'Brien",
72
- "machines[1].team.design" => "Moore",
73
- "machines[1].team.muffins" => "MacNamara",
74
- "contraptions[0].x" => "19",
75
- "contraptions[0].y" => "0.003",
76
- "contraptions[1].x" => "12",
77
- "contraptions[1].y" => "0.0012",
78
- "contraptions[2].x" => "24",
79
- "contraptions[2].y" => "0.00063",
80
- "contraptions[3].x" => "16",
81
- "contraptions[3].y" => "0.00091",
82
- "countries[0]" => "France",
83
- "countries[1]" => "Sweden",
84
- "countries[2]" => "Germany",
85
- "countries[3]" => "Ireland",
86
- "countries[4]" => "Spain",
87
- }
89
+ props = PROPS
88
90
 
89
91
  model = Model.new props
90
92
 
@@ -95,6 +97,8 @@ describe Aduki::Initializer do
95
97
  model.gadget.name.should == "My Big Gadget"
96
98
  model.gadget.price.should == "21"
97
99
  model.gadget.supplier.should == "Apple, Inc."
100
+ model.gadget.speaker.should be_a Speaker
101
+ model.gadget.speaker.ohms.should == nil
98
102
  model.machines[0].name.should == "The First Machine"
99
103
  model.machines[0].weight.should == "88"
100
104
  model.machines[0].speed.should == "142"
@@ -167,20 +171,20 @@ describe Aduki::Initializer do
167
171
  model.countries[4].should == "Spain"
168
172
 
169
173
  sensibly_indexed_props = props.merge({
170
- "machines[1].assemblies[0].name" => "second machine, second assembly",
171
- "machines[1].assemblies[0].colour" => "turquoise",
172
- "machines[1].assemblies[0].size" => "large-ish",
173
- "machines[1].assemblies[1].name" => "second machine, first assembly",
174
- "machines[1].assemblies[1].colour" => "purple",
175
- "machines[1].assemblies[1].size" => "pretty small",
176
- "machines[1].assemblies[2].name" => "second machine, third assembly",
177
- "machines[1].assemblies[2].colour" => "magenta",
178
- "machines[1].assemblies[2].size" => "gigantic",
179
- "machines[1].dimensions[0]" => "1985.85",
180
- "machines[1].dimensions[1]" => "7234.92",
181
- "machines[1].dimensions[2]" => "9725.52",
182
- "machines[1].dimensions[3]" => "3579.79",
183
- })
174
+ "machines[1].assemblies[0].name" => "second machine, second assembly",
175
+ "machines[1].assemblies[0].colour" => "turquoise",
176
+ "machines[1].assemblies[0].size" => "large-ish",
177
+ "machines[1].assemblies[1].name" => "second machine, first assembly",
178
+ "machines[1].assemblies[1].colour" => "purple",
179
+ "machines[1].assemblies[1].size" => "pretty small",
180
+ "machines[1].assemblies[2].name" => "second machine, third assembly",
181
+ "machines[1].assemblies[2].colour" => "magenta",
182
+ "machines[1].assemblies[2].size" => "gigantic",
183
+ "machines[1].dimensions[0]" => "1985.85",
184
+ "machines[1].dimensions[1]" => "7234.92",
185
+ "machines[1].dimensions[2]" => "9725.52",
186
+ "machines[1].dimensions[3]" => "3579.79",
187
+ })
184
188
 
185
189
  silly_keys = [ "machines[1].assemblies[98].name",
186
190
  "machines[1].assemblies[98].colour",
@@ -197,4 +201,19 @@ describe Aduki::Initializer do
197
201
 
198
202
  Aduki.to_aduki(model).should == sensibly_indexed_props
199
203
  end
204
+
205
+ it "should initialize attributes of pre-initialized nested objects" do
206
+ props = {
207
+ "name" => "Brackish Water",
208
+ "gadget.name" => "The Loud Gadget",
209
+ "gadget.speaker.ohms" => "29"
210
+ }
211
+
212
+ model = Model.new props
213
+
214
+ model.name.should == "Brackish Water"
215
+ model.gadget.name.should == "The Loud Gadget"
216
+ model.gadget.speaker.should be_a Speaker
217
+ model.gadget.speaker.ohms.should == "29"
218
+ end
200
219
  end
@@ -0,0 +1,34 @@
1
+ require "aduki"
2
+ require "spec_helper"
3
+
4
+ describe Aduki::Initializer do
5
+ it "should initialize attributes of pre-initialized nested objects" do
6
+ props = {
7
+ "name" => "Brackish Water",
8
+ "gadget.name" => "The Loud Gadget",
9
+ "gadget.speaker.ohms" => "29"
10
+ }
11
+
12
+ model = Model.new props
13
+
14
+ expect(model.name). to eq "Brackish Water"
15
+ expect(model.gadget.name). to eq "The Loud Gadget"
16
+ expect(model.gadget.price). to eq nil
17
+ expect(model.gadget.speaker.ohms). to eq "29"
18
+ expect(model.gadget.speaker.diameter).to eq nil
19
+
20
+ more_props = {
21
+ "name" => "Smelly Brackish Water",
22
+ "gadget.price" => "42",
23
+ "gadget.speaker.diameter" => "large"
24
+ }
25
+
26
+ Aduki.apply_attributes model, more_props
27
+
28
+ expect(model.name). to eq "Smelly Brackish Water"
29
+ expect(model.gadget.name). to eq "The Loud Gadget"
30
+ expect(model.gadget.price). to eq "42"
31
+ expect(model.gadget.speaker.ohms). to eq "29"
32
+ expect(model.gadget.speaker.diameter).to eq "large"
33
+ end
34
+ end
@@ -27,7 +27,8 @@ end
27
27
 
28
28
  class Assembly
29
29
  include Aduki::Initializer
30
- attr_accessor :name, :colour, :size, :height, :weight
30
+ attr_writer :weight
31
+ attr_accessor :name, :colour, :size, :height
31
32
  aduki :height => Integer, :weight => Float
32
33
  end
33
34
 
@@ -37,15 +38,22 @@ class MachineBuilder
37
38
  aduki :city => City
38
39
  end
39
40
 
41
+ class Speaker
42
+ include Aduki::Initializer
43
+ attr_accessor :ohms, :diameter
44
+ end
45
+
40
46
  class Gadget
41
47
  include Aduki::Initializer
42
48
  attr_accessor :name, :price, :supplier
49
+ aduki_initialize :speaker, Speaker
43
50
  end
44
51
 
45
52
  class Machine
46
53
  include Aduki::Initializer
47
- attr_accessor :name, :weight, :speed, :builder, :team
48
- attr_accessor :assemblies, :dimensions, :helpers
54
+ attr_reader :builder
55
+ attr_accessor :name, :weight, :speed, :team
56
+ attr_accessor :dimensions
49
57
  aduki :assemblies => Assembly, :builder => MachineBuilder
50
58
  aduki :helpers => { :key => MachineBuilder }
51
59
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aduki
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.11
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Conan Dalton
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-27 00:00:00.000000000 Z
11
+ date: 2015-04-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -57,6 +57,7 @@ files:
57
57
  - spec/array_attribute_spec.rb
58
58
  - spec/custom_builder_spec.rb
59
59
  - spec/initializer_spec.rb
60
+ - spec/merge_attributes_spec.rb
60
61
  - spec/model.rb
61
62
  - spec/nil_initializer_spec.rb
62
63
  - spec/number_attribute_spec.rb
@@ -91,6 +92,7 @@ test_files:
91
92
  - spec/array_attribute_spec.rb
92
93
  - spec/custom_builder_spec.rb
93
94
  - spec/initializer_spec.rb
95
+ - spec/merge_attributes_spec.rb
94
96
  - spec/model.rb
95
97
  - spec/nil_initializer_spec.rb
96
98
  - spec/number_attribute_spec.rb