lazy_mapper 0.1.0 → 0.1.1

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
  SHA256:
3
- metadata.gz: '08c13aa83740c1719069305ba2be381b32c65ed59017fa251d16a2c5590dd945'
4
- data.tar.gz: 5f1febab53594a456df8b842972f8ea26015270fd3043853a991ab7b467eae9e
3
+ metadata.gz: cdd5ce6d6e5cfaffaac7c6e73fc0692d5b3657888d26bb12bd54eb9f1bf48799
4
+ data.tar.gz: e38a3b2f0c571627583feceb7ac3dc87e4c47f2170cbc815e16779e57c083e07
5
5
  SHA512:
6
- metadata.gz: d4c44f93957f6b04c7069b3f7991862f75d6539ab8b2ae70ebbbcdfbfe4080d59548b9a7b2364cc18dd0c16a1b4b223df6417fb039d57fd36718fd17aa36da17
7
- data.tar.gz: 05523ef4f8fc5d26a335c0b8be671d8e38e677ada3a350e6817cc1a13691b616ed6d8c0b7617c16735894bfe6e799117076dfd100abe15ab44c5798afa8aa2e3
6
+ metadata.gz: a9e5ae539bb7ca177712621f9f7416e636d4cf101cb311a8e0ab257dca496f7bd9d675936e982b61a94f3035bed6f38c833cd8f4cfe0fc406f0f5a30d1f2e3ff
7
+ data.tar.gz: 894084472c088c23256ed76b9e4c568d56e2a2d986104b50c28550358e65fea9ca89326323f26d58f703dbe0c3f7b7f51b73d9f006414e1821fdccce4fd2c91c
data/.gitignore CHANGED
@@ -7,3 +7,4 @@ log/
7
7
  tmp/
8
8
  .idea/
9
9
  Gemfile.lock
10
+ *.gem
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
- # LazyModel
1
+ # LazyMapper
2
2
 
3
- Wraps a JSON object and lazily maps its attributes to rich domain objects using either a set of default mappers (for Ruby's built-in types), or custom mappers specified by the client.
3
+ Wraps a Hash and lazily maps its attributes to rich domain objects using either a set of default mappers (for Ruby's built-in types), or custom mappers specified by the client.
4
4
 
5
5
  The mapped values are memoized.
6
6
 
data/lazy_mapper.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = 'lazy_mapper'
3
- spec.version = '0.1.0'
3
+ spec.version = '0.1.1'
4
4
  spec.summary = "A lazy object mapper"
5
5
  spec.description = "Wraps primitive data in a semantically rich model"
6
6
  spec.authors = ["Adam Lett"]
data/lib/lazy_mapper.rb CHANGED
@@ -122,29 +122,35 @@ class LazyMapper
122
122
 
123
123
  # = ::one
124
124
  #
125
- # Defines an attribute
125
+ # Defines an attribute and creates a reader and a writer for it.
126
+ # The writer verifies the type of it's supplied value.
126
127
  #
127
128
  # == Arguments
128
129
  #
129
- # +name+ - The name of the attribue
130
+ # +name+ - The name of the attribue
130
131
  #
131
- # +type+ - The type of the attribute. If the wrapped value is already of
132
- # that type, the mapper is bypassed.
132
+ # +type+ - The type of the attribute. If the wrapped value is already of
133
+ # that type, the mapper is bypassed.
134
+ # If the type is allowed be one of several, use an Array to
135
+ # to specify which ones
133
136
  #
134
- # +from:+ - Specifies the name of the wrapped value in the JSON object.
135
- # Defaults to camelCased version of +name+.
137
+ # +from:+ - Specifies the name of the wrapped value in the JSON object.
138
+ # Defaults to camelCased version of +name+.
136
139
  #
137
- # +map:+ - Specifies a custom mapper to apply to the wrapped value. Must be
138
- # a Callable. If unspecified, it defaults to the default mapper for the
139
- # specified +type+ or simply the identity mapper if no default mapper exists.
140
+ # +map:+ - Specifies a custom mapper to apply to the wrapped value. Must be
141
+ # a Callable. If unspecified, it defaults to the default mapper for the
142
+ # specified +type+ or simply the identity mapper if no default mapper exists.
140
143
  #
141
- # +default:+ - The default value to use, if the wrapped value is not present
144
+ # +default:+ - The default value to use, if the wrapped value is not present
142
145
  # in the wrapped JSON object.
143
146
  #
147
+ # +allow_nil:+ - If true, allows the mapped value to be nil. Defaults to true.
148
+ #
144
149
  # == Example
145
150
  #
146
151
  # class Foo < LazyMapper
147
152
  # one :boss, Person, from: "supervisor", map: ->(p) { Person.new(p) }
153
+ # one :weapon, [BladedWeapon, Firearm], default: Sixshooter.new
148
154
  # # ...
149
155
  # end
150
156
  #
@@ -259,6 +265,9 @@ class LazyMapper
259
265
  end
260
266
 
261
267
  def inspect
268
+ @__under_inspection__ ||= 0
269
+ return "<#{ self.class.name } ... >" if @__under_inspection__ > 0
270
+ @__under_inspection__ += 1
262
271
  attributes = self.class.attributes
263
272
  if self.class.superclass.respond_to? :attributes
264
273
  attributes = self.class.superclass.attributes.merge attributes
@@ -268,6 +277,9 @@ class LazyMapper
268
277
  memo[name] = value unless value.nil?
269
278
  }
270
279
  "<#{ self.class.name } #{ present_attributes.map {|k,v| k.to_s + ': ' + v.inspect }.join(', ') } >"
280
+ res = "<#{ self.class.name } #{ present_attributes.map {|k,v| k.to_s + ': ' + v.inspect }.join(', ') } >"
281
+ @__under_inspection__ -= 1
282
+ res
271
283
  end
272
284
 
273
285
  protected
@@ -281,10 +293,10 @@ class LazyMapper
281
293
  # to the corresponding name in the unmapped
282
294
  # JSON object.
283
295
  #
284
- # Defaults to #camelize
296
+ # Defaults to CAMELIZE
285
297
  #
286
298
  def self.map_name(name)
287
- camelize(name)
299
+ CAMELIZE[name]
288
300
  end
289
301
 
290
302
  private
@@ -332,10 +344,5 @@ class LazyMapper
332
344
  end
333
345
 
334
346
  SNAKE_CASE_PATTERN = /(_[a-z])/
335
-
336
- # "foo_bar_baz" -> "fooBarBaz"
337
- # "foo_bar?" -> "fooBar"
338
- def self.camelize(name)
339
- name.to_s.gsub(SNAKE_CASE_PATTERN) { |x| x[1].upcase }.gsub('?', '')
340
- end
347
+ CAMELIZE = -> name { name.to_s.gsub(SNAKE_CASE_PATTERN) { |x| x[1].upcase }.gsub('?', '') }
341
348
  end
@@ -5,7 +5,7 @@ require 'lazy_mapper'
5
5
 
6
6
  describe LazyMapper do
7
7
 
8
- describe '.from_json' do
8
+ describe 'when constructed with .from_json' do
9
9
 
10
10
  subject(:instance) { klass.from_json json }
11
11
 
@@ -74,6 +74,36 @@ describe LazyMapper do
74
74
  expect(mapper).to have_received(:map).exactly(1).times.with('42')
75
75
  end
76
76
  end
77
+
78
+ context 'when the model has circular references' do
79
+
80
+ subject(:instance) { foo }
81
+
82
+ let(:foo) { klass_foo.from_json 'bar' => 'bar' }
83
+ let(:bar) { klass_bar.from_json 'foo' => 'foo' }
84
+ let(:foo_builder) { proc { foo } }
85
+ let(:bar_builder) { proc { bar } }
86
+
87
+ let(:klass_foo) {
88
+ b = bar_builder
89
+ Class.new LazyMapper do
90
+ one :bar, Object, map: b
91
+ end
92
+ }
93
+
94
+ let(:klass_bar) {
95
+ b = foo_builder
96
+ Class.new LazyMapper do
97
+ one :foo, Object, map: b
98
+ end
99
+ }
100
+
101
+ it 'avoids infinit recursion, when inspected' do
102
+ stub_const('Bar', klass_bar)
103
+ stub_const('Foo', klass_foo)
104
+ expect(foo.inspect).to eq('<Foo bar: <Bar foo: <Foo ... > > >')
105
+ end
106
+ end
77
107
  end
78
108
 
79
109
  describe 'the :from option' do
@@ -167,7 +197,7 @@ describe LazyMapper do
167
197
  end
168
198
  end
169
199
 
170
- context 'construction' do
200
+ context 'when constructed with .new' do
171
201
 
172
202
  subject(:instance) { klass.new values }
173
203
  let(:values) { {} }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lazy_mapper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Lett
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-08-21 00:00:00.000000000 Z
11
+ date: 2018-09-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport