praxis-blueprints 3.0 → 3.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +35 -0
- data/.travis.yml +10 -5
- data/CHANGELOG.md +27 -0
- data/Gemfile +1 -0
- data/Guardfile +13 -7
- data/README.md +8 -3
- data/Rakefile +4 -3
- data/lib/praxis-blueprints.rb +2 -1
- data/lib/praxis-blueprints/blueprint.rb +96 -87
- data/lib/praxis-blueprints/collection_view.rb +15 -10
- data/lib/praxis-blueprints/config_hash.rb +15 -12
- data/lib/praxis-blueprints/field_expander.rb +60 -48
- data/lib/praxis-blueprints/finalizable.rb +4 -8
- data/lib/praxis-blueprints/renderer.rb +50 -19
- data/lib/praxis-blueprints/version.rb +2 -1
- data/lib/praxis-blueprints/view.rb +22 -29
- data/praxis-blueprints.gemspec +37 -24
- data/spec/praxis-blueprints/blueprint_spec.rb +84 -58
- data/spec/praxis-blueprints/collection_view_spec.rb +16 -7
- data/spec/praxis-blueprints/config_hash_spec.rb +64 -0
- data/spec/praxis-blueprints/field_expander_spec.rb +46 -38
- data/spec/praxis-blueprints/renderer_spec.rb +128 -40
- data/spec/praxis-blueprints/view_spec.rb +24 -10
- data/spec/spec_helper.rb +14 -14
- data/spec/support/spec_blueprints.rb +32 -8
- metadata +112 -35
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
3
|
+
|
4
|
+
describe Praxis::ConfigHash do
|
5
|
+
subject(:instance) { Praxis::ConfigHash.new(hash, &block) }
|
6
|
+
let(:hash) { { one: ['existing'], two: 'dos' } }
|
7
|
+
let(:block) do
|
8
|
+
proc { 'abc' }
|
9
|
+
end
|
10
|
+
|
11
|
+
context 'initialization' do
|
12
|
+
it 'saves the passed hash' do
|
13
|
+
expect(subject.hash).to be(hash)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context '.from' do
|
18
|
+
subject(:instance) { Praxis::ConfigHash.from(hash, &block) }
|
19
|
+
it 'returns an instance' do
|
20
|
+
expect(subject).to be_kind_of(Praxis::ConfigHash)
|
21
|
+
expect(subject.hash).to be(hash)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context '#to_hash' do
|
26
|
+
let(:block) do
|
27
|
+
proc { hash['i_was'] = 'here' }
|
28
|
+
end
|
29
|
+
it 'evaluates the block and returns the resulting hash' do
|
30
|
+
expect(subject.to_hash).to eq(subject.hash)
|
31
|
+
expect(subject.hash['i_was']).to eq('here')
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context '#method_missing' do
|
36
|
+
context 'when keys do not exist in the hash key' do
|
37
|
+
it 'sets a single value to the hash' do
|
38
|
+
subject.some_name 'someval'
|
39
|
+
expect(subject.hash[:some_name]).to eq('someval')
|
40
|
+
end
|
41
|
+
it 'sets a multiple values to the hash key' do
|
42
|
+
subject.some_name 'someval', 'other1', 'other2'
|
43
|
+
expect(subject.hash[:some_name]).to include('someval', 'other1', 'other2')
|
44
|
+
end
|
45
|
+
end
|
46
|
+
context 'when keys already exist in the hash key' do
|
47
|
+
it 'adds one value to the hash' do
|
48
|
+
subject.one'newval'
|
49
|
+
expect(subject.hash[:one]).to match_array(%w(existing newval))
|
50
|
+
end
|
51
|
+
it 'adds multiple values to the hash key' do
|
52
|
+
subject.one 'newval', 'other1', 'other2'
|
53
|
+
expect(subject.hash[:one]).to match_array(%w(existing newval other1 other2))
|
54
|
+
end
|
55
|
+
context 'when passing a value and a block' do
|
56
|
+
let(:my_block) { proc {} }
|
57
|
+
it 'adds the tuple to the hash key' do
|
58
|
+
subject.one 'val', &my_block
|
59
|
+
expect(subject.hash[:one]).to include(['val', my_block])
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'spec_helper'
|
2
3
|
|
3
4
|
describe Praxis::FieldExpander do
|
4
|
-
|
5
5
|
let(:field_expander) { Praxis::FieldExpander.new }
|
6
6
|
|
7
7
|
let(:view) do
|
@@ -21,96 +21,95 @@ describe Praxis::FieldExpander do
|
|
21
21
|
let(:full_expected) do
|
22
22
|
{
|
23
23
|
name: true,
|
24
|
-
full_name: {first: true, last: true},
|
25
|
-
parents: {mother: true, father: true},
|
24
|
+
full_name: { first: true, last: true },
|
25
|
+
parents: { mother: true, father: true },
|
26
26
|
address: {
|
27
27
|
state: true,
|
28
28
|
street: true,
|
29
29
|
resident: {
|
30
30
|
name: true,
|
31
|
-
full_name: {first: true, last: true},
|
32
|
-
address: {street:true, state:true},
|
33
|
-
prior_addresses: [{street:true, state:true}]
|
31
|
+
full_name: { first: true, last: true },
|
32
|
+
address: { street: true, state: true },
|
33
|
+
prior_addresses: [{ street: true, state: true }]
|
34
34
|
}
|
35
35
|
},
|
36
|
-
prior_addresses: [{state: true}],
|
36
|
+
prior_addresses: [{ state: true }],
|
37
37
|
tags: [true]
|
38
38
|
}
|
39
39
|
end
|
40
40
|
|
41
41
|
context 'expanding a view' do
|
42
42
|
it 'expands all fields on the view, subviews, and related attributes' do
|
43
|
-
field_expander.expand(view,true).should eq(full_expected)
|
43
|
+
field_expander.expand(view, true).should eq(full_expected)
|
44
44
|
end
|
45
45
|
|
46
46
|
it 'expands for a subset of the direct fields' do
|
47
|
-
field_expander.expand(view,name: true).should eq(
|
47
|
+
field_expander.expand(view, name: true).should eq(name: true)
|
48
48
|
end
|
49
49
|
|
50
50
|
it 'expands for a subview' do
|
51
|
-
field_expander.expand(view,parents: true).should eq(
|
51
|
+
field_expander.expand(view, parents: true).should eq(parents: { mother: true, father: true })
|
52
52
|
end
|
53
53
|
|
54
54
|
it 'expands for a related attribute' do
|
55
|
-
field_expander.expand(view,address: true).should eq(
|
55
|
+
field_expander.expand(view, address: true).should eq(address: full_expected[:address])
|
56
56
|
end
|
57
57
|
|
58
58
|
it 'expands for a subset of a related attribute' do
|
59
|
-
field_expander.expand(view,address: {resident: true}).should eq(
|
59
|
+
field_expander.expand(view, address: { resident: true }).should eq(address: { resident: full_expected[:address][:resident] })
|
60
60
|
end
|
61
61
|
|
62
62
|
it 'expands for a subset of a subview' do
|
63
|
-
field_expander.expand(view,parents: {mother: true}).should eq(
|
63
|
+
field_expander.expand(view, parents: { mother: true }).should eq(parents: { mother: true })
|
64
64
|
end
|
65
65
|
|
66
66
|
it 'ignores fields not defined in the view' do
|
67
|
-
field_expander.expand(view,name: true, age: true).should eq(
|
67
|
+
field_expander.expand(view, name: true, age: true).should eq(name: true)
|
68
68
|
end
|
69
69
|
|
70
70
|
it 'expands a specific subattribute of a struct' do
|
71
|
-
field_expander.expand(view,full_name: {first: true}).should eq(
|
71
|
+
field_expander.expand(view, full_name: { first: true }).should eq(full_name: { first: true })
|
72
72
|
end
|
73
73
|
|
74
74
|
it 'wraps expanded collections in arrays' do
|
75
|
-
field_expander.expand(view,prior_addresses: {state: true}).should eq(
|
75
|
+
field_expander.expand(view, prior_addresses: { state: true }).should eq(prior_addresses: [{ state: true }])
|
76
76
|
end
|
77
77
|
|
78
78
|
it 'wraps expanded collections in arrays' do
|
79
|
-
field_expander.expand(view, prior_addresses: true).should eq(
|
79
|
+
field_expander.expand(view, prior_addresses: true).should eq(prior_addresses: [{ state: true }])
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
83
83
|
it 'expands for an Attributor::Model' do
|
84
|
-
field_expander.expand(FullName).should eq(
|
84
|
+
field_expander.expand(FullName).should eq(first: true, last: true)
|
85
85
|
end
|
86
86
|
|
87
|
-
|
88
87
|
it 'expands for a Blueprint' do
|
89
|
-
field_expander.expand(Person, parents: true).should eq(
|
88
|
+
field_expander.expand(Person, parents: true).should eq(parents: { father: true, mother: true })
|
90
89
|
end
|
91
90
|
|
92
91
|
it 'expands for an Attributor::Collection of an Attrbutor::Model' do
|
93
|
-
expected = [{first: true, last: true}]
|
92
|
+
expected = [{ first: true, last: true }]
|
94
93
|
field_expander.expand(Attributor::Collection.of(FullName)).should eq expected
|
95
94
|
end
|
96
95
|
|
97
96
|
it 'expands for an Attributor::Collection of a Blueprint' do
|
98
|
-
expected = [{name: true, resident: {full_name: {first: true, last: true}}}]
|
97
|
+
expected = [{ name: true, resident: { full_name: { first: true, last: true } } }]
|
99
98
|
|
100
|
-
field_expander.expand(Attributor::Collection.of(Address), name: true, resident:{full_name: true}).should eq expected
|
99
|
+
field_expander.expand(Attributor::Collection.of(Address), name: true, resident: { full_name: true }).should eq expected
|
101
100
|
end
|
102
101
|
|
103
102
|
it 'also expands array-wrapped field hashes for collections' do
|
104
|
-
expected = [{name: true, resident: {full_name: {first: true, last: true}}}]
|
105
|
-
field_expander.expand(Attributor::Collection.of(Address), [name: true, resident:{full_name: true}]).should eq expected
|
103
|
+
expected = [{ name: true, resident: { full_name: { first: true, last: true } } }]
|
104
|
+
field_expander.expand(Attributor::Collection.of(Address), [name: true, resident: { full_name: true }]).should eq expected
|
106
105
|
end
|
107
106
|
|
108
107
|
it 'expands for an Attributor::Collection of a primitive type' do
|
109
|
-
|
108
|
+
field_expander.expand(Attributor::Collection.of(String)).should eq([true])
|
110
109
|
end
|
111
110
|
|
112
111
|
it 'expands for for a primitive type' do
|
113
|
-
|
112
|
+
field_expander.expand(String).should eq(true)
|
114
113
|
end
|
115
114
|
|
116
115
|
context 'expanding a two-dimensional collection' do
|
@@ -121,17 +120,31 @@ describe Praxis::FieldExpander do
|
|
121
120
|
it 'expands the fields with proper nesting' do
|
122
121
|
field_expander.expand(matrix_type).should eq([[first: true, last: true]])
|
123
122
|
end
|
124
|
-
|
125
123
|
end
|
126
124
|
|
127
125
|
context 'circular expansions' do
|
128
|
-
it '
|
129
|
-
|
126
|
+
it 'preserve field object identity for circular references' do
|
127
|
+
result = field_expander.expand(Address, true)
|
128
|
+
result.should be result[:resident][:address]
|
129
|
+
end
|
130
|
+
|
131
|
+
context 'with collections of Blueprints' do
|
132
|
+
it 'still preserves object identity' do
|
133
|
+
result = field_expander.expand(Person, prior_addresses: true)[:prior_addresses][0]
|
134
|
+
result.should be result[:resident][:prior_addresses][0]
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
context 'for views' do
|
139
|
+
it 'still preserves object identity' do
|
140
|
+
result = field_expander.expand(Person.views[:circular], true)
|
141
|
+
result[:address][:resident].should be result
|
142
|
+
end
|
130
143
|
end
|
131
144
|
end
|
132
145
|
|
133
146
|
it 'optimizes duplicate field expansions' do
|
134
|
-
expect(field_expander.expand(FullName,true)).to be(field_expander.expand(FullName,true))
|
147
|
+
expect(field_expander.expand(FullName, true)).to be(field_expander.expand(FullName, true))
|
135
148
|
end
|
136
149
|
|
137
150
|
context 'expanding hash attributes' do
|
@@ -155,15 +168,10 @@ describe Praxis::FieldExpander do
|
|
155
168
|
expected = {
|
156
169
|
name: true,
|
157
170
|
simple_hash: true,
|
158
|
-
keyed_hash: {foo: true, bar: true},
|
159
|
-
some_struct: {something: true}
|
171
|
+
keyed_hash: { foo: true, bar: true },
|
172
|
+
some_struct: { something: true }
|
160
173
|
}
|
161
174
|
field_expander.expand(type, true).should eq(expected)
|
162
175
|
end
|
163
|
-
|
164
|
-
|
165
|
-
|
166
176
|
end
|
167
|
-
|
168
|
-
|
169
177
|
end
|
@@ -1,33 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require_relative '../spec_helper'
|
2
3
|
|
3
4
|
describe Praxis::Renderer do
|
4
|
-
|
5
5
|
let(:address) { Address.example }
|
6
|
-
let(:prior_addresses) { 2
|
6
|
+
let(:prior_addresses) { Array.new(2) { Address.example } }
|
7
|
+
let(:alias_one) { FullName.example }
|
8
|
+
let(:alias_two) { FullName.example }
|
9
|
+
let(:aliases) { [alias_one, alias_two] }
|
10
|
+
let(:metadata_hash) { { something: 'here' } }
|
11
|
+
let(:metadata) { Attributor::Hash.load(metadata_hash) }
|
12
|
+
|
7
13
|
let(:person) do
|
8
|
-
|
14
|
+
Person.example(
|
9
15
|
address: address,
|
10
16
|
email: nil,
|
11
17
|
prior_addresses: prior_addresses,
|
12
18
|
alive: false,
|
13
|
-
work_address: nil
|
19
|
+
work_address: nil,
|
20
|
+
aliases: aliases,
|
21
|
+
metadata: metadata
|
14
22
|
)
|
15
23
|
end
|
16
24
|
|
17
|
-
|
18
25
|
let(:fields) do
|
19
26
|
{
|
20
|
-
name:true,
|
21
|
-
email:true,
|
22
|
-
full_name: {first:true, last:true},
|
27
|
+
name: true,
|
28
|
+
email: true,
|
29
|
+
full_name: { first: true, last: true },
|
23
30
|
address: {
|
24
|
-
state:true,
|
25
|
-
street:true,
|
26
|
-
resident: {name:true}
|
31
|
+
state: true,
|
32
|
+
street: true,
|
33
|
+
resident: { name: true }
|
27
34
|
},
|
28
|
-
prior_addresses: [{name: true}],
|
35
|
+
prior_addresses: [{ name: true }],
|
29
36
|
work_address: true,
|
30
|
-
alive: true
|
37
|
+
alive: true,
|
38
|
+
metadata: true,
|
39
|
+
aliases: [true]
|
31
40
|
}
|
32
41
|
end
|
33
42
|
|
@@ -36,31 +45,44 @@ describe Praxis::Renderer do
|
|
36
45
|
subject(:output) { renderer.render(person, fields) }
|
37
46
|
|
38
47
|
it 'renders existing attributes' do
|
39
|
-
output.keys.should match_array([:name, :full_name, :alive, :address, :prior_addresses])
|
48
|
+
output.keys.should match_array([:name, :full_name, :alive, :address, :prior_addresses, :metadata, :aliases])
|
40
49
|
|
41
50
|
output[:name].should eq person.name
|
42
|
-
output[:full_name].should eq(
|
51
|
+
output[:full_name].should eq(first: person.full_name.first, last: person.full_name.last)
|
43
52
|
output[:alive].should be false
|
44
53
|
|
45
|
-
output[:address].should eq(
|
46
|
-
|
47
|
-
|
48
|
-
resident: {name: person.address.resident.name}
|
49
|
-
})
|
54
|
+
output[:address].should eq(state: person.address.state,
|
55
|
+
street: person.address.street,
|
56
|
+
resident: { name: person.address.resident.name })
|
50
57
|
|
51
|
-
expected_prior_addresses = prior_addresses.collect { |addr| {name: addr.name} }
|
58
|
+
expected_prior_addresses = prior_addresses.collect { |addr| { name: addr.name } }
|
52
59
|
output[:prior_addresses].should match_array(expected_prior_addresses)
|
60
|
+
|
61
|
+
expected_aliases = aliases.collect(&:dump)
|
62
|
+
output[:aliases].should match_array(expected_aliases)
|
63
|
+
|
64
|
+
output[:metadata].should eq(metadata.dump)
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'calls dump for non-Blueprint, but still Dumpable instances' do
|
68
|
+
it 'when rendering them in full as array members' do
|
69
|
+
alias_one.should_receive(:dump).and_call_original
|
70
|
+
output[:aliases].first.should eq(first: alias_one.first, last: alias_one.last)
|
71
|
+
end
|
72
|
+
it 'when rendering them in full as leaf object' do
|
73
|
+
metadata.should_receive(:dump).and_call_original
|
74
|
+
output[:metadata].should eq(metadata_hash)
|
75
|
+
end
|
53
76
|
end
|
54
77
|
|
55
78
|
it 'does not render attributes with nil values' do
|
56
79
|
output.should_not have_key(:email)
|
57
80
|
end
|
58
81
|
|
59
|
-
|
60
82
|
it 'sends the correct ActiveSupport::Notification' do
|
61
83
|
fields = {
|
62
|
-
name:true,
|
63
|
-
email:true
|
84
|
+
name: true,
|
85
|
+
email: true
|
64
86
|
}
|
65
87
|
|
66
88
|
notification_payload = {
|
@@ -69,16 +91,16 @@ describe Praxis::Renderer do
|
|
69
91
|
fields: fields
|
70
92
|
}
|
71
93
|
|
72
|
-
ActiveSupport::Notifications.should_receive(:instrument)
|
73
|
-
|
74
|
-
|
94
|
+
ActiveSupport::Notifications.should_receive(:instrument)
|
95
|
+
.with('praxis.blueprint.render', notification_payload)
|
96
|
+
.and_call_original
|
75
97
|
|
76
98
|
renderer.render(person, fields)
|
77
|
-
|
78
|
-
|
99
|
+
end
|
79
100
|
|
80
101
|
context 'with include_nil: true' do
|
81
102
|
let(:renderer) { Praxis::Renderer.new(include_nil: true) }
|
103
|
+
let(:address) { nil }
|
82
104
|
|
83
105
|
it 'renders attributes with nil values' do
|
84
106
|
output.should have_key :email
|
@@ -87,44 +109,48 @@ describe Praxis::Renderer do
|
|
87
109
|
output.should have_key :work_address
|
88
110
|
output[:work_address].should be nil
|
89
111
|
end
|
112
|
+
|
113
|
+
it 'renders nil directly for nil subobjects' do
|
114
|
+
output.should have_key :address
|
115
|
+
output[:address].should be nil
|
116
|
+
end
|
90
117
|
end
|
91
118
|
|
92
119
|
context '#render_collection' do
|
93
|
-
let(:people) { 10
|
120
|
+
let(:people) { Array.new(10) { Person.example(address: address, email: nil) } }
|
94
121
|
subject(:output) { renderer.render_collection(people, fields) }
|
95
122
|
|
96
123
|
it { should have(10).items }
|
97
124
|
|
98
125
|
it 'renders the collection' do
|
99
|
-
output.first.should eq(renderer.render(people.first,fields))
|
126
|
+
output.first.should eq(renderer.render(people.first, fields))
|
100
127
|
end
|
101
|
-
|
102
128
|
end
|
103
129
|
|
104
130
|
context 'rendering a two-dimmensional collection' do
|
105
|
-
let(:names) { 9
|
131
|
+
let(:names) { Array.new(9) { |i| Address.example(i.to_s, name: i.to_s) } }
|
106
132
|
let(:matrix_type) do
|
107
133
|
Attributor::Collection.of(Attributor::Collection.of(Address))
|
108
134
|
end
|
109
135
|
|
110
|
-
let(:matrix) { matrix_type.load(names.each_slice(3).collect { |slice| slice })
|
136
|
+
let(:matrix) { matrix_type.load(names.each_slice(3).collect { |slice| slice }) }
|
111
137
|
|
112
|
-
let(:fields) { [[{name: true}]] }
|
138
|
+
let(:fields) { [[{ name: true }]] }
|
113
139
|
|
114
140
|
it 'renders with render_collection and per-element field spec' do
|
115
|
-
rendered = renderer.render_collection(matrix,fields.first)
|
116
|
-
rendered.flatten.collect {|r| r[:name] }.should eq((0..8).collect(&:to_s))
|
141
|
+
rendered = renderer.render_collection(matrix, fields.first)
|
142
|
+
rendered.flatten.collect { |r| r[:name] }.should eq((0..8).collect(&:to_s))
|
117
143
|
end
|
118
144
|
|
119
145
|
it 'renders with render and proper field spec' do
|
120
|
-
rendered =
|
121
|
-
rendered.flatten.collect {|r| r[:name] }.should eq((0..8).collect(&:to_s))
|
146
|
+
rendered = renderer.render(matrix, fields)
|
147
|
+
rendered.flatten.collect { |r| r[:name] }.should eq((0..8).collect(&:to_s))
|
122
148
|
end
|
123
149
|
end
|
124
150
|
|
125
151
|
context 'rendering stuff that breaks badly' do
|
126
152
|
it 'does not break badly' do
|
127
|
-
renderer.render(person, tags: [true])
|
153
|
+
renderer.render(person, {tags: [true]})
|
128
154
|
end
|
129
155
|
end
|
130
156
|
|
@@ -137,6 +163,68 @@ describe Praxis::Renderer do
|
|
137
163
|
render_2 = renderer.render(person, fields)
|
138
164
|
expect(render_1).to be(render_2)
|
139
165
|
end
|
166
|
+
end
|
167
|
+
|
168
|
+
context 'circular rendering' do
|
169
|
+
it do
|
170
|
+
field_expander = Praxis::FieldExpander.new
|
171
|
+
fields = field_expander.expand(Person, true)
|
172
|
+
|
173
|
+
person.object.address.object.resident = person
|
174
|
+
expect { renderer.render(person, fields) }.to raise_error(Praxis::Renderer::CircularRenderingError)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
context 'rendering hashes' do
|
179
|
+
let(:fields) do
|
180
|
+
{
|
181
|
+
id: true,
|
182
|
+
hash: true
|
183
|
+
}
|
184
|
+
end
|
185
|
+
|
186
|
+
let(:data) { { id: 10, hash: { foo: 'bar' } } }
|
187
|
+
let(:object) { SimpleHash.load(data) }
|
188
|
+
let(:renderer) { Praxis::Renderer.new }
|
189
|
+
|
190
|
+
subject(:output) { renderer.render(object, fields) }
|
191
|
+
|
192
|
+
its([:id]) { should eq data[:id] }
|
193
|
+
its([:hash]) { should eq data[:hash] }
|
194
|
+
its([:hash]) { should be_kind_of(Hash) }
|
195
|
+
end
|
196
|
+
|
197
|
+
context 'rendering collections of hashes' do
|
198
|
+
let(:fields) do
|
199
|
+
{
|
200
|
+
id: true,
|
201
|
+
hash_collection: [true]
|
202
|
+
}
|
203
|
+
end
|
204
|
+
|
205
|
+
let(:data) { { id: 10, hash_collection: [{ foo: 'bar' }] } }
|
206
|
+
let(:object) { SimpleHashCollection.load(data) }
|
207
|
+
let(:renderer) { Praxis::Renderer.new }
|
208
|
+
|
209
|
+
subject(:output) { renderer.render(object, fields) }
|
210
|
+
|
211
|
+
its([:id]) { should eq data[:id] }
|
212
|
+
its([:hash_collection]) { should eq data[:hash_collection] }
|
213
|
+
its([:hash_collection]) { should be_kind_of(Array) }
|
214
|
+
|
215
|
+
it 'renders the hashes' do
|
216
|
+
expect(output[:hash_collection].first).to be_kind_of(Hash)
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
context 'rendering a Blueprint with fields true' do
|
221
|
+
let(:fields) do
|
222
|
+
{
|
223
|
+
name: true,
|
224
|
+
address: true
|
225
|
+
}
|
226
|
+
end
|
140
227
|
|
228
|
+
its([:address]) { should eq person.address.dump }
|
141
229
|
end
|
142
230
|
end
|