kartograph 0.0.2 → 0.0.4
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/README.md +31 -2
- data/kartograph.gemspec +3 -3
- data/lib/kartograph/dsl.rb +5 -1
- data/lib/kartograph/map.rb +26 -1
- data/lib/kartograph/property.rb +23 -2
- data/lib/kartograph/property_collection.rb +7 -0
- data/lib/kartograph/version.rb +2 -1
- data/spec/lib/kartograph/dsl_spec.rb +5 -1
- data/spec/lib/kartograph/map_spec.rb +49 -0
- data/spec/lib/kartograph/property_spec.rb +40 -1
- metadata +7 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8fd632485d17da22b0e4d02656914d1a150d4cbf
|
4
|
+
data.tar.gz: 33045537b5961949bd128b12b51d61266b9532fb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 86471a3fc7372a2bde1038c9aeb97310a6190e66e150f6c0c27528db369fcb27cfde4e19dbe9605f9fb44c2e7459f1f33c919b2afb8265a3aa1fa4392d430ab9
|
7
|
+
data.tar.gz: 9b5beb0e77705f6ce61b87a6755f17cb90342c0e56c36dfabe04c733520dadbdf4526da5057081db0ca3c61cbc6f52239f4b8970d103149e40950f0319e4d13e
|
data/README.md
CHANGED
@@ -29,8 +29,8 @@ class UserMapping
|
|
29
29
|
kartograph do
|
30
30
|
mapping User # The object we're mapping
|
31
31
|
|
32
|
-
property :name, scopes: [:create, :update]
|
33
|
-
property :id, scopes:
|
32
|
+
property :name, :email, scopes: [:create, :update]
|
33
|
+
property :id, scopes: :read
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
@@ -111,6 +111,35 @@ users = UserMapping.extract_collection(response.body, :read)
|
|
111
111
|
It will look for the root key before trying to deserialize the JSON response.
|
112
112
|
The advantage of this is it will only use the root key if there is a scope defined for it.
|
113
113
|
|
114
|
+
|
115
|
+
### Including other definitions within eachother
|
116
|
+
|
117
|
+
Sometimes you might have models that are nested within eachother on responses. Or you simply want to cleanup definitions by separating concerns. Kartograph lets you do this with includes.
|
118
|
+
|
119
|
+
```ruby
|
120
|
+
class UserMapping
|
121
|
+
include Kartograph::DSL
|
122
|
+
|
123
|
+
kartograph do
|
124
|
+
mapping User
|
125
|
+
property :id, scopes: [:read]
|
126
|
+
property :comments, plural: true, include: CommentMapping
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
class CommentMapping
|
131
|
+
include Kartograph::DSL
|
132
|
+
|
133
|
+
kartograph do
|
134
|
+
mapping Comment
|
135
|
+
property :id, scopes: [:read]
|
136
|
+
property :text, scopes: [:read]
|
137
|
+
end
|
138
|
+
end
|
139
|
+
```
|
140
|
+
|
141
|
+
Now when JSON includes comments for a user, it will know how to map the comments using the provided Kartograph definition.
|
142
|
+
|
114
143
|
## Contributing
|
115
144
|
|
116
145
|
1. Fork it ( https://github.com/[my-github-username]/kartograph/fork )
|
data/kartograph.gemspec
CHANGED
@@ -7,9 +7,9 @@ Gem::Specification.new do |spec|
|
|
7
7
|
spec.name = "kartograph"
|
8
8
|
spec.version = Kartograph::VERSION
|
9
9
|
spec.authors = ["Robert Ross"]
|
10
|
-
spec.email = ["rross@digitalocean.com"]
|
11
|
-
spec.summary = %q{
|
12
|
-
spec.description = %q{
|
10
|
+
spec.email = ["rross@digitalocean.com", "ivan@digitalocean.com"]
|
11
|
+
spec.summary = %q{Kartograph makes it easy to generate and convert JSON. It's intention is to be used for API clients.}
|
12
|
+
spec.description = %q{Kartograph makes it easy to generate and convert JSON. It's intention is to be used for API clients.}
|
13
13
|
spec.homepage = ""
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
data/lib/kartograph/dsl.rb
CHANGED
@@ -8,7 +8,11 @@ module Kartograph
|
|
8
8
|
def kartograph(&block)
|
9
9
|
@kartograph_map ||= Map.new
|
10
10
|
|
11
|
-
|
11
|
+
if block_given?
|
12
|
+
block.arity > 0 ? block.call(@kartograph_map) : @kartograph_map.instance_eval(&block)
|
13
|
+
end
|
14
|
+
|
15
|
+
@kartograph_map
|
12
16
|
end
|
13
17
|
|
14
18
|
def representation_for(scope, object, dumper = JSON)
|
data/lib/kartograph/map.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
module Kartograph
|
2
2
|
class Map
|
3
3
|
def property(*args, &block)
|
4
|
-
|
4
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
5
|
+
args.each do |prop|
|
6
|
+
properties << Property.new(prop, options, &block)
|
7
|
+
end
|
5
8
|
end
|
6
9
|
|
7
10
|
def properties
|
@@ -28,5 +31,27 @@ module Kartograph
|
|
28
31
|
root_key.send(type)
|
29
32
|
end
|
30
33
|
end
|
34
|
+
|
35
|
+
def dup
|
36
|
+
Kartograph::Map.new.tap do |map|
|
37
|
+
self.properties.each do |property|
|
38
|
+
map.properties << property.dup
|
39
|
+
end
|
40
|
+
|
41
|
+
map.mapping self.mapping
|
42
|
+
|
43
|
+
self.root_keys.each do |rk|
|
44
|
+
map.root_keys << rk
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def ==(other)
|
50
|
+
methods = %i(properties root_keys mapping)
|
51
|
+
methods.inject(true) do |current_value, method|
|
52
|
+
break unless current_value
|
53
|
+
send(method) == other.send(method)
|
54
|
+
end
|
55
|
+
end
|
31
56
|
end
|
32
57
|
end
|
data/lib/kartograph/property.rb
CHANGED
@@ -1,11 +1,18 @@
|
|
1
1
|
module Kartograph
|
2
2
|
class Property
|
3
|
-
attr_reader :name, :options
|
3
|
+
attr_reader :name, :options
|
4
|
+
attr_accessor :map
|
4
5
|
|
5
6
|
def initialize(name, options = {}, &block)
|
6
7
|
@name = name
|
7
8
|
@options = options
|
8
9
|
|
10
|
+
if mapped_class = options[:include]
|
11
|
+
# Perform a safe duplication into our properties map
|
12
|
+
# This allows the user to define more attributes on the map should they need to
|
13
|
+
@map = mapped_class.kartograph.dup
|
14
|
+
end
|
15
|
+
|
9
16
|
if block_given?
|
10
17
|
@map ||= Map.new
|
11
18
|
block.arity > 0 ? block.call(map) : map.instance_eval(&block)
|
@@ -18,18 +25,32 @@ module Kartograph
|
|
18
25
|
end
|
19
26
|
|
20
27
|
def value_from(object, scope = nil)
|
28
|
+
return if object.nil?
|
21
29
|
value = object.has_key?(name) ? object[name] : object[name.to_s]
|
22
30
|
map ? sculpt_value(value, scope) : value
|
23
31
|
end
|
24
32
|
|
25
33
|
def scopes
|
26
|
-
options[:scopes] || []
|
34
|
+
Array(options[:scopes] || [])
|
27
35
|
end
|
28
36
|
|
29
37
|
def plural?
|
30
38
|
!!options[:plural]
|
31
39
|
end
|
32
40
|
|
41
|
+
def dup
|
42
|
+
Property.new(name, options.dup).tap do |property|
|
43
|
+
property.map = map.dup if self.map
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def ==(other)
|
48
|
+
%i(name options map).inject(true) do |equals, method|
|
49
|
+
break unless equals
|
50
|
+
send(method) == other.send(method)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
33
54
|
private
|
34
55
|
|
35
56
|
def sculpt_value(value, scope)
|
data/lib/kartograph/version.rb
CHANGED
@@ -12,7 +12,11 @@ describe Kartograph::DSL do
|
|
12
12
|
subject(:mapping) { Class.new { include Kartograph::DSL } }
|
13
13
|
|
14
14
|
it 'yields a Kartograph::Map instance' do
|
15
|
-
expect {|b| mapping.kartograph(&b) }.to yield_with_args(
|
15
|
+
expect {|b| mapping.kartograph(&b) }.to yield_with_args(Kartograph::Map.new)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'returns the map instance' do
|
19
|
+
expect(mapping.kartograph).to be_kind_of(Kartograph::Map)
|
16
20
|
end
|
17
21
|
end
|
18
22
|
|
@@ -9,6 +9,21 @@ describe Kartograph::Map do
|
|
9
9
|
expect(map.properties.size).to be(1)
|
10
10
|
expect(map.properties.first).to be_kind_of(Kartograph::Property)
|
11
11
|
end
|
12
|
+
|
13
|
+
context 'defining multiple properties' do
|
14
|
+
it 'adds multiple properties at the same time for the scope' do
|
15
|
+
map.property :attribute1, :attribute2, scopes: [:read]
|
16
|
+
|
17
|
+
expect(map.properties.size).to be(2)
|
18
|
+
expect(map.properties).to all(be_kind_of(Kartograph::Property))
|
19
|
+
|
20
|
+
expect(map.properties[0].name).to eq(:attribute1)
|
21
|
+
expect(map.properties[0].scopes).to eq([:read])
|
22
|
+
|
23
|
+
expect(map.properties[1].name).to eq(:attribute2)
|
24
|
+
expect(map.properties[1].scopes).to eq([:read])
|
25
|
+
end
|
26
|
+
end
|
12
27
|
end
|
13
28
|
|
14
29
|
describe '#properties' do
|
@@ -43,4 +58,38 @@ describe Kartograph::Map do
|
|
43
58
|
expect(key).to eq('test')
|
44
59
|
end
|
45
60
|
end
|
61
|
+
|
62
|
+
describe '#dup' do
|
63
|
+
it 'performs a safe duplication of the map' do
|
64
|
+
mapped_class = Class.new
|
65
|
+
|
66
|
+
prop1 = map.property :name, scopes: [:read, :write]
|
67
|
+
prop2 = map.property :id, scopes: [:read]
|
68
|
+
map.mapping mapped_class
|
69
|
+
map.root_key singular: 'woot', plural: 'woots', scopes: [:read]
|
70
|
+
|
71
|
+
new_map = map.dup
|
72
|
+
|
73
|
+
expect(new_map.properties[0]).to_not be(prop1)
|
74
|
+
expect(new_map.properties[1]).to_not be(prop2)
|
75
|
+
|
76
|
+
expect(new_map.properties).to all(be_kind_of(Kartograph::Property))
|
77
|
+
expect(new_map.properties[0].name).to eq(:name)
|
78
|
+
expect(new_map.properties[1].name).to eq(:id)
|
79
|
+
|
80
|
+
expect(new_map.mapping).to eq(mapped_class)
|
81
|
+
expect(new_map.root_keys).to eq(map.root_keys)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe 'Equality' do
|
86
|
+
specify 'duplicated maps are equal to eachother' do
|
87
|
+
map1 = Kartograph::Map.new
|
88
|
+
map1.property :something, scopes: [:read]
|
89
|
+
|
90
|
+
map2 = map1.dup
|
91
|
+
|
92
|
+
expect(map1).to eq(map2)
|
93
|
+
end
|
94
|
+
end
|
46
95
|
end
|
@@ -13,7 +13,21 @@ describe Kartograph::Property do
|
|
13
13
|
|
14
14
|
context 'with a block' do
|
15
15
|
it 'yields a map instance for the property' do
|
16
|
-
expect {|b| Kartograph::Property.new(:hello, &b) }.to yield_with_args(
|
16
|
+
expect {|b| Kartograph::Property.new(:hello, &b) }.to yield_with_args(Kartograph::Map.new)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'with an include' do
|
21
|
+
it 'sets the map to the included mapped class' do
|
22
|
+
klass = Class.new do
|
23
|
+
include Kartograph::DSL
|
24
|
+
kartograph do
|
25
|
+
property :lol, scopes: [:read]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
property = Kartograph::Property.new(:id, scopes: [:read], include: klass)
|
30
|
+
expect(property.map).to eq(klass.kartograph)
|
17
31
|
end
|
18
32
|
end
|
19
33
|
end
|
@@ -28,6 +42,11 @@ describe Kartograph::Property do
|
|
28
42
|
property = Kartograph::Property.new(:name)
|
29
43
|
expect(property.scopes).to eq( [] )
|
30
44
|
end
|
45
|
+
|
46
|
+
it 'always casts to an array' do
|
47
|
+
property = Kartograph::Property.new(:name, scopes: :read)
|
48
|
+
expect(property.scopes).to eq [:read]
|
49
|
+
end
|
31
50
|
end
|
32
51
|
|
33
52
|
describe '#plural?' do
|
@@ -90,6 +109,14 @@ describe Kartograph::Property do
|
|
90
109
|
expect(property.value_from(hash)).to eq('world')
|
91
110
|
end
|
92
111
|
|
112
|
+
context 'for a nil object' do
|
113
|
+
it 'bails and does not try to retrieve' do
|
114
|
+
property = Kartograph::Property.new(:hello)
|
115
|
+
value = property.value_from(nil)
|
116
|
+
expect(value).to be_nil
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
93
120
|
context 'string and symbol agnostic' do
|
94
121
|
let(:hash) { { 'hello' => 'world' } }
|
95
122
|
|
@@ -152,4 +179,16 @@ describe Kartograph::Property do
|
|
152
179
|
end
|
153
180
|
end
|
154
181
|
end
|
182
|
+
|
183
|
+
describe '#dup' do
|
184
|
+
it 'copies the name, options, and map into another property' do
|
185
|
+
instance = Kartograph::Property.new(:id, scopes: [:read])
|
186
|
+
duped = instance.dup
|
187
|
+
|
188
|
+
expect(duped).to be_kind_of(Kartograph::Property)
|
189
|
+
expect(duped.name).to eq(:id)
|
190
|
+
expect(duped.options).to_not be(instance.options)
|
191
|
+
expect(duped.options).to eq(instance.options)
|
192
|
+
end
|
193
|
+
end
|
155
194
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kartograph
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Ross
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-08-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -66,9 +66,11 @@ dependencies:
|
|
66
66
|
- - '>='
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
-
description:
|
69
|
+
description: Kartograph makes it easy to generate and convert JSON. It's intention
|
70
|
+
is to be used for API clients.
|
70
71
|
email:
|
71
72
|
- rross@digitalocean.com
|
73
|
+
- ivan@digitalocean.com
|
72
74
|
executables: []
|
73
75
|
extensions: []
|
74
76
|
extra_rdoc_files: []
|
@@ -125,7 +127,8 @@ rubyforge_project:
|
|
125
127
|
rubygems_version: 2.2.2
|
126
128
|
signing_key:
|
127
129
|
specification_version: 4
|
128
|
-
summary:
|
130
|
+
summary: Kartograph makes it easy to generate and convert JSON. It's intention is
|
131
|
+
to be used for API clients.
|
129
132
|
test_files:
|
130
133
|
- spec/lib/kartograph/artist_spec.rb
|
131
134
|
- spec/lib/kartograph/dsl_spec.rb
|