aduki 0.0.11 → 0.1.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.
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