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 +4 -4
- data/.travis.yml +1 -0
- data/CHANGELOG.md +9 -0
- data/lib/praxis-blueprints.rb +1 -1
- data/lib/praxis-blueprints/blueprint.rb +2 -1
- data/lib/praxis-blueprints/collection_view.rb +31 -0
- data/lib/praxis-blueprints/version.rb +1 -1
- data/lib/praxis-blueprints/view.rb +2 -2
- data/spec/praxis-blueprints/blueprint_spec.rb +25 -50
- data/spec/praxis-blueprints/collection_view_spec.rb +59 -0
- data/spec/praxis-blueprints/view_spec.rb +4 -54
- metadata +4 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 54c80c09733228cb18f5fdc35ae05054bd0727a4
|
4
|
+
data.tar.gz: 90eba917e0f3d2651d840333fe5d81b94a13428b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5f307971333a02b445884d4e3a514b4a20c4bca46fa9fe38aed65e7fec34b717f0a02afbd520ef0ac3d601a396b7554f6af73cfe1a7cc23bb56ef76b0b2ba814
|
7
|
+
data.tar.gz: 1d375284f3af2b1d32ea79b06c0677b3588696d377840297ebfa71a473f79286bbed6ce7d5a4ef85b3c92988f1b4062df108be8cff48b5141aebf8f3d605d5f3
|
data/.travis.yml
CHANGED
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!
|
data/lib/praxis-blueprints.rb
CHANGED
@@ -231,7 +231,8 @@ module Praxis
|
|
231
231
|
if @block
|
232
232
|
self.define_attribute!
|
233
233
|
self.define_readers!
|
234
|
-
|
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
|
@@ -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
|
-
|
297
|
-
|
298
|
-
|
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
|
-
|
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
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
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
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
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
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
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
|
-
|
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
|
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
|
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
|