praxis-blueprints 1.0.1 → 1.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: f5352b37878c8f506236cce34e6d90b9bc079329
4
- data.tar.gz: 6d02549269a82673793858e741f847c9519ea401
3
+ metadata.gz: 54c80c09733228cb18f5fdc35ae05054bd0727a4
4
+ data.tar.gz: 90eba917e0f3d2651d840333fe5d81b94a13428b
5
5
  SHA512:
6
- metadata.gz: 585e2c0318453b71e023ad11cc427e657ce4c09320ce78e1081790267c6b2289a635ccdc853a9c30dcc1f9aec78bbdd0b27616e551ab26ba373f1a9451ba5745
7
- data.tar.gz: 036eaaf49beda62497ec5cb3a34cf115224ce856741a9f8bd1fa8e9db0ac66f2b5e5ee80d741b04765da87a58ec9d32ec10bde392b50322f142853f112e8e450
6
+ metadata.gz: 5f307971333a02b445884d4e3a514b4a20c4bca46fa9fe38aed65e7fec34b717f0a02afbd520ef0ac3d601a396b7554f6af73cfe1a7cc23bb56ef76b0b2ba814
7
+ data.tar.gz: 1d375284f3af2b1d32ea79b06c0677b3588696d377840297ebfa71a473f79286bbed6ce7d5a4ef85b3c92988f1b4062df108be8cff48b5141aebf8f3d605d5f3
data/.travis.yml CHANGED
@@ -1,4 +1,5 @@
1
1
  language: ruby
2
+ cache: bundler
2
3
  rvm:
3
4
  - "2.1.2"
4
5
  script: bundle exec rspec spec
data/CHANGELOG.md CHANGED
@@ -1,10 +1,19 @@
1
1
  # praxis-blueprints changelog
2
2
 
3
+ ## next
4
+
5
+ * next thing here
6
+
7
+ ## 1.1.0
8
+
9
+ * Added CollectionView, a special type of view that renders an array of objects with another view.
10
+
3
11
 
4
12
  ## 1.0.1
5
13
 
6
14
  * Relaxed ActiveSupport version dependency (from 4 to >=3)
7
15
 
16
+
8
17
  ## 1.0
9
18
 
10
19
  Initial release!
@@ -11,4 +11,4 @@ require 'praxis-blueprints/config_hash'
11
11
 
12
12
  require 'praxis-blueprints/blueprint'
13
13
  require 'praxis-blueprints/view'
14
-
14
+ require 'praxis-blueprints/collection_view'
@@ -231,7 +231,8 @@ module Praxis
231
231
  if @block
232
232
  self.define_attribute!
233
233
  self.define_readers!
234
- self.generate_master_view!
234
+ # Don't blindly override a master view if the MediaType wants to define it on its own
235
+ self.generate_master_view! unless self.view(:master)
235
236
  end
236
237
  super
237
238
  end
@@ -0,0 +1,31 @@
1
+ module Praxis
2
+
3
+ class CollectionView
4
+ attr_reader :name, :schema, :using
5
+
6
+ def initialize(name, schema, using)
7
+ @name = name
8
+ @schema = schema
9
+ @using = using
10
+ end
11
+
12
+ def dump(collection, context: Attributor::DEFAULT_ROOT_CONTEXT,**opts)
13
+ collection.collect.with_index do |object, i|
14
+ subcontext = context + ["at(#{i})"]
15
+ using.dump(object, context: subcontext, **opts)
16
+ end
17
+ end
18
+
19
+ def example(context=Attributor::DEFAULT_ROOT_CONTEXT)
20
+ collection = self.schema.example(context)
21
+ opts = {}
22
+ opts[:context] = context if context
23
+ self.dump(collection, opts)
24
+ end
25
+
26
+ def describe
27
+ using.describe.merge(type: :collection)
28
+ end
29
+
30
+ end
31
+ end
@@ -1,3 +1,3 @@
1
1
  module Praxis
2
- BLUEPRINTS_VERSION = "1.0.1"
2
+ BLUEPRINTS_VERSION = "1.1.0"
3
3
  end
@@ -34,7 +34,7 @@ module Praxis
34
34
  next if value.nil?
35
35
 
36
36
  # FIXME: this is such an ugly way to do this. Need attributor#67.
37
- if dumpable.kind_of?(View)
37
+ if dumpable.kind_of?(View) || dumpable.kind_of?(CollectionView)
38
38
  new_context = context + [name]
39
39
  hash[name] = dumpable.dump(value, context: new_context ,**(dumpable_opts||{}))
40
40
  else
@@ -86,7 +86,7 @@ module Praxis
86
86
  view_attributes[k] = inner_desc
87
87
  end
88
88
 
89
- { attributes: view_attributes }
89
+ { attributes: view_attributes, type: :standard }
90
90
  end
91
91
 
92
92
  end
@@ -4,7 +4,6 @@ describe Praxis::Blueprint do
4
4
 
5
5
  subject(:blueprint_class) { Person }
6
6
 
7
-
8
7
  context 'deterministic examples' do
9
8
  it 'works' do
10
9
  person_1 = Person.example('person 1')
@@ -293,61 +292,37 @@ describe Praxis::Blueprint do
293
292
  end
294
293
 
295
294
  context '#render' do
296
- let(:person) { Person.example }
297
- let(:view_name) { :default }
298
- subject(:output) { person.render(view_name) }
299
-
300
- context 'with a sub-attribute that is a blueprint' do
295
+ let(:person) { Person.example }
296
+ let(:view_name) { :default }
297
+ subject(:output) { person.render(view_name) }
301
298
 
302
- it { should have_key(:name) }
303
- it { should have_key(:address) }
304
- it 'renders the sub-attribute correctly' do
305
- output[:address].should have_key(:street)
306
- output[:address].should have_key(:state)
307
- end
299
+ context 'with a sub-attribute that is a blueprint' do
308
300
 
309
- it 'reports a dump error with the appropriate context' do
310
- person.address.should_receive(:state).and_raise("Kaboom")
311
- expect {
312
- person.render(view_name, context: ['special_root'])
313
- }.to raise_error(/Error while dumping attribute state of type Address for context special_root.address .*. Reason: .*Kaboom/)
314
- end
315
- end
316
-
317
-
318
- context 'with sub-attribute that is an Attributor::Model' do
319
- it { should have_key(:full_name) }
320
- it 'renders the model correctly' do
321
- output[:full_name].should be_kind_of(Hash)
322
- output[:full_name].should have_key(:first)
323
- output[:full_name].should have_key(:last)
324
- end
325
- end
326
-
327
-
328
- # context 'with circular references' do
329
- # let(:view_name) { :master }
301
+ it { should have_key(:name) }
302
+ it { should have_key(:address) }
303
+ it 'renders the sub-attribute correctly' do
304
+ output[:address].should have_key(:street)
305
+ output[:address].should have_key(:state)
306
+ end
330
307
 
331
- # # TODO: think about circular references without caching
332
- # around do |example|
333
- # Praxis::Blueprint.caching_enabled = true
334
- # example.run
335
- # Praxis::Blueprint.caching_enabled = false
336
- # end
308
+ it 'reports a dump error with the appropriate context' do
309
+ person.address.should_receive(:state).and_raise("Kaboom")
310
+ expect {
311
+ person.render(view_name, context: ['special_root'])
312
+ }.to raise_error(/Error while dumping attribute state of type Address for context special_root.address .*. Reason: .*Kaboom/)
313
+ end
314
+ end
337
315
 
338
- # it 'terminates' do
339
- # expect {
340
- # Person.example.render(:master)
341
- # }.to_not raise_error
342
- # end
343
316
 
344
- # it 'renders Praxis::Blueprint::CIRCULAR_REFERENCE_MARKER for circular references' do
345
- # person.address.resident.should be(person)
346
- # output[:address][:resident].should eq(Praxis::Blueprint::CIRCULAR_REFERENCE_MARKER)
347
- # end
317
+ context 'with sub-attribute that is an Attributor::Model' do
318
+ it { should have_key(:full_name) }
319
+ it 'renders the model correctly' do
320
+ output[:full_name].should be_kind_of(Hash)
321
+ output[:full_name].should have_key(:first)
322
+ output[:full_name].should have_key(:last)
323
+ end
324
+ end
348
325
 
349
- # end
350
-
351
326
  end
352
327
 
353
328
  end
@@ -0,0 +1,59 @@
1
+ require_relative '../spec_helper'
2
+
3
+ describe Praxis::CollectionView do
4
+
5
+ let(:collection_schema) { double(:collection_schema) }
6
+
7
+ let(:people) { [Person.example('p-1'), Person.example('p-2')] }
8
+
9
+
10
+ let(:member_view) do
11
+ Praxis::View.new(:tiny, Person) do
12
+ attribute :name
13
+ attribute :address, view: :state
14
+ end
15
+ end
16
+
17
+ let(:collection_view) do
18
+ Praxis::CollectionView.new(:collection_view, collection_schema, member_view)
19
+ end
20
+
21
+ let(:root_context) { ['people'] }
22
+
23
+ context '#dump' do
24
+ before do
25
+ people.each_with_index do |person, i|
26
+ subcontext = root_context + ["at(#{i})"]
27
+ expect(member_view).to(
28
+ receive(:dump).
29
+ with(person, context: subcontext).
30
+ and_call_original)
31
+ end
32
+ end
33
+
34
+ subject(:output) { collection_view.dump(people, context: root_context) }
35
+
36
+ it { should be_kind_of(Array) }
37
+ end
38
+
39
+ context '#example' do
40
+ it 'generates an example from the schema and renders it' do
41
+ expect(collection_schema).to(
42
+ receive(:example).
43
+ with(root_context).
44
+ and_return(people)
45
+ )
46
+ expect(collection_view).to receive(:dump).and_call_original
47
+
48
+ collection_view.example(root_context)
49
+ end
50
+ end
51
+
52
+ context '#describe' do
53
+ subject(:description) { collection_view.describe }
54
+
55
+ its([:attributes]) { should eq(member_view.describe[:attributes]) }
56
+ its([:type]) { should eq(:collection) }
57
+ end
58
+
59
+ end
@@ -220,10 +220,9 @@ describe Praxis::View do
220
220
  end
221
221
 
222
222
  it { should eq expected_output }
223
-
224
-
225
223
  end
226
224
 
225
+
227
226
  context 'with a specified view' do
228
227
  let(:view) do
229
228
  Praxis::View.new(:default, Person) do
@@ -243,59 +242,12 @@ describe Praxis::View do
243
242
  end
244
243
 
245
244
  end
246
- # context 'with embedded related objects' do
247
- # context '#embed' do
248
- # let(:view) do
249
- # Praxis::View.new(:default, Person) do
250
- # attribute :name
251
- # embed :address
252
- # end
253
- # end
254
-
255
- # let(:expected_output) do
256
- # {
257
- # :name => person.name,
258
- # :address => {
259
- # :street => address.street,
260
- # :state => address.state
261
- # }}
262
- # end
263
-
264
-
265
- # before do
266
- # address.should_receive(:to_hash).with(:default).and_call_original
267
- # end
268
-
269
- # it { should == expected_output }
270
-
271
- # end
272
-
273
- # context '#embed_collection' do
274
- # let(:view) do
275
- # Praxis::View.new(:aka, Person) do
276
- # attribute :name
277
- # embed_collection :aliases
278
- # end
279
- # end
280
-
281
- # subject(:output) { view.to_hash(person) }
282
-
283
-
284
- # let(:expected_output) do
285
- # {
286
- # :name => person.name,
287
- # :aliases => person.aliases.collect { |a| a.to_hash(:default)}
288
- # }
289
- # end
290
-
291
- # it { should == expected_output }
292
- # end
293
- # end
245
+
294
246
 
295
247
  context '#describe' do
296
248
  subject(:description) { view.describe}
297
- its(:keys){ should == [:attributes] }
298
-
249
+ its(:keys){ should =~ [:attributes, :type] }
250
+ its([:type]) { should eq(:standard) }
299
251
  context 'returns attributes' do
300
252
  subject { description[:attributes] }
301
253
 
@@ -311,6 +263,4 @@ describe Praxis::View do
311
263
  end
312
264
  end
313
265
 
314
-
315
- #it 'has a spec for validating attribute names'
316
266
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: praxis-blueprints
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Josep M. Blanquer
@@ -228,12 +228,14 @@ files:
228
228
  - Rakefile
229
229
  - lib/praxis-blueprints.rb
230
230
  - lib/praxis-blueprints/blueprint.rb
231
+ - lib/praxis-blueprints/collection_view.rb
231
232
  - lib/praxis-blueprints/config_hash.rb
232
233
  - lib/praxis-blueprints/finalizable.rb
233
234
  - lib/praxis-blueprints/version.rb
234
235
  - lib/praxis-blueprints/view.rb
235
236
  - praxis-blueprints.gemspec
236
237
  - spec/praxis-blueprints/blueprint_spec.rb
238
+ - spec/praxis-blueprints/collection_view_spec.rb
237
239
  - spec/praxis-blueprints/view_spec.rb
238
240
  - spec/spec_helper.rb
239
241
  - spec/support/spec_blueprints.rb
@@ -264,6 +266,7 @@ summary: Attributes, views, rendering and example generation for common Blueprin
264
266
  Structures.
265
267
  test_files:
266
268
  - spec/praxis-blueprints/blueprint_spec.rb
269
+ - spec/praxis-blueprints/collection_view_spec.rb
267
270
  - spec/praxis-blueprints/view_spec.rb
268
271
  - spec/spec_helper.rb
269
272
  - spec/support/spec_blueprints.rb