aduki 0.0.4 → 0.0.5
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/README.md +8 -0
- data/aduki.gemspec +1 -0
- data/lib/aduki.rb +51 -11
- data/lib/aduki/version.rb +1 -1
- data/spec/initializer_spec.rb +58 -0
- data/spec/spec_helper.rb +2 -1
- data/spec/to_aduki_spec.rb +115 -0
- metadata +20 -2
data/README.md
CHANGED
@@ -48,6 +48,7 @@ Here's an abbreviated version:
|
|
48
48
|
attr_accessor :name, :weight, :speed, :builder, :team
|
49
49
|
attr_accessor :assemblies, :dimensions
|
50
50
|
aduki :assemblies => Assembly, :builder => MachineBuilder
|
51
|
+
aduki :helpers => { :key => MachineBuilder }
|
51
52
|
end
|
52
53
|
|
53
54
|
class Model
|
@@ -71,6 +72,13 @@ This line instructs aduki to initialise the #gadget field with a Gadget object.
|
|
71
72
|
array with a Machine object. Aduki decides to create an object or an array of objects depending on the attributes-hash contents, rather than on any
|
72
73
|
metadata you may specify here.
|
73
74
|
|
75
|
+
|
76
|
+
The following line tells aduki to expect a hash for the #helpers attribute, and for each value in the hash is should construct a new MachineBuilder instance:
|
77
|
+
|
78
|
+
aduki :helpers => { :key => MachineBuilder }
|
79
|
+
|
80
|
+
|
81
|
+
|
74
82
|
## Contributing
|
75
83
|
|
76
84
|
1. Fork it
|
data/aduki.gemspec
CHANGED
@@ -17,6 +17,7 @@ Gem::Specification.new do |gem|
|
|
17
17
|
|
18
18
|
|
19
19
|
gem.add_development_dependency 'rspec', '~> 2.9'
|
20
|
+
gem.add_development_dependency 'rspec_numbering_formatter'
|
20
21
|
|
21
22
|
gem.files = `git ls-files`.split($/)
|
22
23
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
data/lib/aduki.rb
CHANGED
@@ -1,30 +1,71 @@
|
|
1
1
|
require "aduki/version"
|
2
2
|
|
3
3
|
module Aduki
|
4
|
+
def self.to_aduki obj, collector={ }, key="", join=""
|
5
|
+
case obj
|
6
|
+
when Hash
|
7
|
+
obj.keys.inject(collector) { |result, k|
|
8
|
+
v = obj[k]
|
9
|
+
to_aduki v, collector, "#{key}#{join}#{k}", "."
|
10
|
+
result
|
11
|
+
}
|
12
|
+
when Array
|
13
|
+
obj.each_with_index do |av, ix|
|
14
|
+
to_aduki av, collector, "#{key}[#{ix}]", "."
|
15
|
+
end
|
16
|
+
when String, Numeric, Symbol
|
17
|
+
collector[key] = obj
|
18
|
+
else
|
19
|
+
vv = obj.instance_variables
|
20
|
+
vv.each do |v|
|
21
|
+
accessor = v.to_s.gsub(/^@/, "").to_sym
|
22
|
+
if obj.respond_to?(accessor) && obj.respond_to?("#{accessor}=".to_sym)
|
23
|
+
to_aduki obj.send(accessor), collector, "#{key}#{join}#{accessor}", "."
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
collector
|
28
|
+
end
|
29
|
+
|
4
30
|
def self.to_value klass, setter, value
|
5
31
|
type = klass.aduki_type_for_attribute_name setter
|
6
|
-
|
32
|
+
if type.is_a? Hash
|
33
|
+
to_typed_hash type.values.first, value
|
34
|
+
else
|
35
|
+
type ? type.new(value) : value
|
36
|
+
end
|
7
37
|
end
|
8
38
|
|
9
|
-
def self.
|
10
|
-
setters =
|
11
|
-
|
39
|
+
def self.to_typed_hash klass, value
|
40
|
+
setters = split_attributes value
|
41
|
+
hsh = { }
|
42
|
+
setters.each { |k, v|
|
43
|
+
hsh[k] = klass.new(v)
|
44
|
+
}
|
45
|
+
hsh
|
46
|
+
end
|
12
47
|
|
48
|
+
def self.split_attributes attrs
|
49
|
+
setters = { }
|
13
50
|
attrs.each do |setter, value|
|
14
|
-
if setter.match
|
51
|
+
if setter.match(/\./)
|
15
52
|
first, rest = setter.split(/\./, 2)
|
16
53
|
setters[first] ||= { }
|
17
54
|
setters[first][rest] = value
|
18
|
-
elsif setter.match /\[\d+\]/
|
19
|
-
setters[setter] = value
|
20
55
|
else
|
21
|
-
|
56
|
+
setters[setter] = value
|
22
57
|
end
|
23
58
|
end
|
59
|
+
setters
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.apply_attributes object, attrs
|
63
|
+
setters = split_attributes attrs
|
64
|
+
klass = object.class
|
24
65
|
|
25
66
|
setters.each do |setter, value|
|
26
|
-
if setter.match
|
27
|
-
setter = setter.gsub
|
67
|
+
if setter.match(/\[\d+\]/)
|
68
|
+
setter = setter.gsub(/\[\d+\]/, '')
|
28
69
|
array = object.send setter.to_sym
|
29
70
|
if array == nil
|
30
71
|
array = []
|
@@ -32,7 +73,6 @@ module Aduki
|
|
32
73
|
end
|
33
74
|
array << to_value(klass, setter, value)
|
34
75
|
else
|
35
|
-
type = klass.aduki_type_for_attribute_name setter
|
36
76
|
object.send "#{setter}=", to_value(klass, setter, value)
|
37
77
|
end
|
38
78
|
end
|
data/lib/aduki/version.rb
CHANGED
data/spec/initializer_spec.rb
CHANGED
@@ -35,6 +35,18 @@ describe Aduki::Initializer do
|
|
35
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
36
|
"machines[0].team.code" => "Chaucer",
|
37
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",
|
38
50
|
"machines[1].name" => "The Second Machine",
|
39
51
|
"machines[1].weight" => "34",
|
40
52
|
"machines[1].speed" => "289",
|
@@ -104,6 +116,21 @@ describe Aduki::Initializer do
|
|
104
116
|
model.machines[0].dimensions[2].should == "3859.39"
|
105
117
|
model.machines[0].dimensions[3].should == "2365.68"
|
106
118
|
model.machines[0].team.should == { "lead" => "Shakespeare", "code" => "Chaucer", "design" => "Jobs"}
|
119
|
+
model.machines[0].helpers["jim"].should be_a MachineBuilder
|
120
|
+
model.machines[0].helpers["jim"].name.should == "Jim Appleby"
|
121
|
+
model.machines[0].helpers["jim"].email.should == "Jim.Appleby@example.com"
|
122
|
+
model.machines[0].helpers["jim"].phone.should == "123 456 789"
|
123
|
+
model.machines[0].helpers["jim"].office.should == "Elephant & Castle"
|
124
|
+
model.machines[0].helpers["ben"].should be_a MachineBuilder
|
125
|
+
model.machines[0].helpers["ben"].name.should == "Ben Barnes"
|
126
|
+
model.machines[0].helpers["ben"].email.should == "Ben.Barnes@example.com"
|
127
|
+
model.machines[0].helpers["ben"].phone.should == "123 456 790"
|
128
|
+
model.machines[0].helpers["ben"].office.should == "Cockney"
|
129
|
+
model.machines[0].helpers["pat"].should be_a MachineBuilder
|
130
|
+
model.machines[0].helpers["pat"].name.should == "Patrick O'Brien"
|
131
|
+
model.machines[0].helpers["pat"].email.should == "Patrick.O.Brien@example.com"
|
132
|
+
model.machines[0].helpers["pat"].phone.should == "123 456 791"
|
133
|
+
model.machines[0].helpers["pat"].office.should == "Hammersmith"
|
107
134
|
model.machines[1].name.should == "The Second Machine"
|
108
135
|
model.machines[1].weight.should == "34"
|
109
136
|
model.machines[1].speed.should == "289"
|
@@ -138,5 +165,36 @@ describe Aduki::Initializer do
|
|
138
165
|
model.countries[2].should == "Germany"
|
139
166
|
model.countries[3].should == "Ireland"
|
140
167
|
model.countries[4].should == "Spain"
|
168
|
+
|
169
|
+
sensibly_indexed_props = props.merge({
|
170
|
+
"machines[1].assemblies[0].name" => "second machine, first assembly", # the array index distinguishes items but does not order them
|
171
|
+
"machines[1].assemblies[0].colour" => "purple",
|
172
|
+
"machines[1].assemblies[0].size" => "pretty small",
|
173
|
+
"machines[1].assemblies[1].name" => "second machine, second assembly",
|
174
|
+
"machines[1].assemblies[1].colour" => "turquoise",
|
175
|
+
"machines[1].assemblies[1].size" => "large-ish",
|
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
|
+
})
|
184
|
+
|
185
|
+
silly_keys = [ "machines[1].assemblies[98].name",
|
186
|
+
"machines[1].assemblies[98].colour",
|
187
|
+
"machines[1].assemblies[98].size",
|
188
|
+
"machines[1].assemblies[99].name",
|
189
|
+
"machines[1].assemblies[99].colour",
|
190
|
+
"machines[1].assemblies[99].size",
|
191
|
+
"machines[1].dimensions[20]",
|
192
|
+
"machines[1].dimensions[30]",
|
193
|
+
"machines[1].dimensions[40]",
|
194
|
+
"machines[1].dimensions[50]"]
|
195
|
+
|
196
|
+
silly_keys.each { |k| sensibly_indexed_props.delete k }
|
197
|
+
|
198
|
+
Aduki.to_aduki(model).should == sensibly_indexed_props
|
141
199
|
end
|
142
200
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -28,8 +28,9 @@ end
|
|
28
28
|
class Machine
|
29
29
|
include Aduki::Initializer
|
30
30
|
attr_accessor :name, :weight, :speed, :builder, :team
|
31
|
-
attr_accessor :assemblies, :dimensions
|
31
|
+
attr_accessor :assemblies, :dimensions, :helpers
|
32
32
|
aduki :assemblies => Assembly, :builder => MachineBuilder
|
33
|
+
aduki :helpers => { :key => MachineBuilder }
|
33
34
|
end
|
34
35
|
|
35
36
|
class Model
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require "aduki"
|
2
|
+
require "spec_helper"
|
3
|
+
|
4
|
+
describe Aduki do
|
5
|
+
it "should return a plain hash structure" do
|
6
|
+
hsh = { "foo" => "bar" }
|
7
|
+
props = Aduki.to_aduki hsh
|
8
|
+
props.should == { "foo" => "bar" }
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should flatten nested keys" do
|
12
|
+
hsh = { "foo" => "bar", "bing" => { "boo" => "wogga", "tingle" => "wimp" } }
|
13
|
+
props = Aduki.to_aduki hsh
|
14
|
+
props.should == {
|
15
|
+
"foo" => "bar",
|
16
|
+
"bing.boo" => "wogga",
|
17
|
+
"bing.tingle" => "wimp"
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should flatten deeply nested keys" do
|
22
|
+
hsh = {
|
23
|
+
"foo" => "bar",
|
24
|
+
"bing" => {
|
25
|
+
"boo" => "wogga",
|
26
|
+
"tingle" => "wimp",
|
27
|
+
"harpoon" => {
|
28
|
+
"shonk" => "twaddle",
|
29
|
+
"scorn" => "shart"
|
30
|
+
}} }
|
31
|
+
props = Aduki.to_aduki hsh
|
32
|
+
props.should == {
|
33
|
+
"foo" => "bar",
|
34
|
+
"bing.boo" => "wogga",
|
35
|
+
"bing.tingle" => "wimp",
|
36
|
+
"bing.harpoon.shonk" => "twaddle",
|
37
|
+
"bing.harpoon.scorn" => "shart",
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should flatten array keys also " do
|
42
|
+
hsh = {
|
43
|
+
"foo" => "bar",
|
44
|
+
"bing" => {
|
45
|
+
"boo" => "wogga",
|
46
|
+
"tingle" => "wimp",
|
47
|
+
"harpoon" => ["shonk",
|
48
|
+
"twaddle",
|
49
|
+
"scorn",
|
50
|
+
"shart" ]
|
51
|
+
} }
|
52
|
+
props = Aduki.to_aduki hsh
|
53
|
+
props.should == {
|
54
|
+
"foo" => "bar",
|
55
|
+
"bing.boo" => "wogga",
|
56
|
+
"bing.tingle" => "wimp",
|
57
|
+
"bing.harpoon[0]" => "shonk",
|
58
|
+
"bing.harpoon[1]" => "twaddle",
|
59
|
+
"bing.harpoon[2]" => "scorn",
|
60
|
+
"bing.harpoon[3]" => "shart",
|
61
|
+
}
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should flatten nested arrays " do
|
65
|
+
hsh = {
|
66
|
+
"foo" => "bar",
|
67
|
+
"bing" => {
|
68
|
+
"boo" => "wogga",
|
69
|
+
"tingle" => "wimp",
|
70
|
+
"harpoon" => ["shonk",
|
71
|
+
"twaddle",
|
72
|
+
%w{alpha beta gamma},
|
73
|
+
{ wing: :tip, tail: :fin } ]
|
74
|
+
} }
|
75
|
+
props = Aduki.to_aduki hsh
|
76
|
+
props.should == {
|
77
|
+
"foo" => "bar",
|
78
|
+
"bing.boo" => "wogga",
|
79
|
+
"bing.tingle" => "wimp",
|
80
|
+
"bing.harpoon[0]" => "shonk",
|
81
|
+
"bing.harpoon[1]" => "twaddle",
|
82
|
+
"bing.harpoon[2][0]" => "alpha",
|
83
|
+
"bing.harpoon[2][1]" => "beta",
|
84
|
+
"bing.harpoon[2][2]" => "gamma",
|
85
|
+
"bing.harpoon[3].wing" => :tip,
|
86
|
+
"bing.harpoon[3].tail" => :fin,
|
87
|
+
}
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should flatten aduki objects " do
|
91
|
+
hsh = {
|
92
|
+
"foo" => "bar",
|
93
|
+
"bing" => {
|
94
|
+
"boo" => "wogga",
|
95
|
+
"tingle" => "wimp",
|
96
|
+
"harpoon" => ["shonk",
|
97
|
+
"twaddle",
|
98
|
+
%w{alpha beta gamma},
|
99
|
+
{ wing: :tip, tail: :fin } ]
|
100
|
+
} }
|
101
|
+
props = Aduki.to_aduki hsh
|
102
|
+
props.should == {
|
103
|
+
"foo" => "bar",
|
104
|
+
"bing.boo" => "wogga",
|
105
|
+
"bing.tingle" => "wimp",
|
106
|
+
"bing.harpoon[0]" => "shonk",
|
107
|
+
"bing.harpoon[1]" => "twaddle",
|
108
|
+
"bing.harpoon[2][0]" => "alpha",
|
109
|
+
"bing.harpoon[2][1]" => "beta",
|
110
|
+
"bing.harpoon[2][2]" => "gamma",
|
111
|
+
"bing.harpoon[3].wing" => :tip,
|
112
|
+
"bing.harpoon[3].tail" => :fin,
|
113
|
+
}
|
114
|
+
end
|
115
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aduki
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-12-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
@@ -27,6 +27,22 @@ dependencies:
|
|
27
27
|
- - ~>
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: '2.9'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rspec_numbering_formatter
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
30
46
|
description: recursive attribute setting for ruby objects
|
31
47
|
email:
|
32
48
|
- conan@conandalton.net
|
@@ -46,6 +62,7 @@ files:
|
|
46
62
|
- spec/initializer_spec.rb
|
47
63
|
- spec/model.rb
|
48
64
|
- spec/spec_helper.rb
|
65
|
+
- spec/to_aduki_spec.rb
|
49
66
|
homepage: https://github.com/conanite/aduki
|
50
67
|
licenses:
|
51
68
|
- MIT
|
@@ -75,3 +92,4 @@ test_files:
|
|
75
92
|
- spec/initializer_spec.rb
|
76
93
|
- spec/model.rb
|
77
94
|
- spec/spec_helper.rb
|
95
|
+
- spec/to_aduki_spec.rb
|