kartograph 0.0.2 → 0.0.4

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: d0486e484ee7a91e233645567afcf28f2ff25d6b
4
- data.tar.gz: 0b6232dbd15c7a27a90f89b00652abdc4912a789
3
+ metadata.gz: 8fd632485d17da22b0e4d02656914d1a150d4cbf
4
+ data.tar.gz: 33045537b5961949bd128b12b51d61266b9532fb
5
5
  SHA512:
6
- metadata.gz: 389d7c025aad932d0f22e2d5b3fa1d03d907bd5af1cb06d916549af5caadfc10c47ee975ef3a0d5c4c9de6ea093bfc039bf2b9dccd8e34345ca5a9f5a6c0d994
7
- data.tar.gz: aeff8daa983de66a69c76a7c73e995d91ce28b977c2749c7eba257ecda38294ba6d4653eb0f16c03f8bcac860003cd4b072dc44cecd1e25d1cb265d7a1f6092a
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: [:read]
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 )
@@ -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{Short Summary}
12
- spec.description = %q{Short Description}
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
 
@@ -8,7 +8,11 @@ module Kartograph
8
8
  def kartograph(&block)
9
9
  @kartograph_map ||= Map.new
10
10
 
11
- block.arity > 0 ? block.call(@kartograph_map) : @kartograph_map.instance_eval(&block)
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)
@@ -1,7 +1,10 @@
1
1
  module Kartograph
2
2
  class Map
3
3
  def property(*args, &block)
4
- properties << Property.new(*args, &block)
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
@@ -1,11 +1,18 @@
1
1
  module Kartograph
2
2
  class Property
3
- attr_reader :name, :options, :map
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)
@@ -16,5 +16,12 @@ module Kartograph
16
16
  property.scopes.include?(scope)
17
17
  end
18
18
  end
19
+
20
+ def ==(other)
21
+ each_with_index.inject(true) do |current_value, (property, index)|
22
+ break unless current_value
23
+ property == other[index]
24
+ end
25
+ end
19
26
  end
20
27
  end
@@ -1,3 +1,4 @@
1
1
  module Kartograph
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.4"
3
3
  end
4
+
@@ -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(instance_of(Kartograph::Map))
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(instance_of(Kartograph::Map))
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.2
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-07-31 00:00:00.000000000 Z
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: Short 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: Short 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