praxis-blueprints 1.0.1 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|