praxis-blueprints 3.2 → 3.3
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 +5 -3
- data/CHANGELOG.md +6 -0
- data/Gemfile +1 -0
- data/Guardfile +13 -7
- data/Rakefile +4 -3
- data/lib/praxis-blueprints.rb +2 -1
- data/lib/praxis-blueprints/blueprint.rb +68 -89
- data/lib/praxis-blueprints/collection_view.rb +8 -11
- data/lib/praxis-blueprints/config_hash.rb +15 -12
- data/lib/praxis-blueprints/field_expander.rb +46 -52
- data/lib/praxis-blueprints/finalizable.rb +4 -8
- data/lib/praxis-blueprints/renderer.rb +29 -27
- data/lib/praxis-blueprints/version.rb +2 -1
- data/lib/praxis-blueprints/view.rb +23 -28
- data/praxis-blueprints.gemspec +35 -25
- data/spec/praxis-blueprints/blueprint_spec.rb +33 -57
- data/spec/praxis-blueprints/collection_view_spec.rb +6 -10
- data/spec/praxis-blueprints/config_hash_spec.rb +64 -0
- data/spec/praxis-blueprints/field_expander_spec.rb +30 -38
- data/spec/praxis-blueprints/renderer_spec.rb +57 -50
- data/spec/praxis-blueprints/view_spec.rb +8 -12
- data/spec/spec_helper.rb +11 -14
- data/spec/support/spec_blueprints.rb +6 -14
- metadata +44 -8
data/praxis-blueprints.gemspec
CHANGED
@@ -1,39 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
lib = File.expand_path('../lib', __FILE__)
|
2
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
4
|
require 'praxis-blueprints/version'
|
4
5
|
|
5
6
|
Gem::Specification.new do |spec|
|
6
|
-
spec.name =
|
7
|
+
spec.name = 'praxis-blueprints'
|
7
8
|
spec.version = Praxis::BLUEPRINTS_VERSION
|
8
|
-
spec.authors = [
|
9
|
-
spec.summary =
|
10
|
-
spec.description =
|
11
|
-
|
12
|
-
|
9
|
+
spec.authors = ['Josep M. Blanquer', 'Dane Jensen']
|
10
|
+
spec.summary = 'Attributes, views, rendering and example generation for common Blueprint Structures.'
|
11
|
+
spec.description = <<-EOF
|
12
|
+
Praxis Blueprints is a library that allows for defining a reusable class
|
13
|
+
structures that has a set of typed attributes and a set of views with which
|
14
|
+
to render them. Instantiations of Blueprints resemble ruby Structs which
|
15
|
+
respond to methods of the attribute names. Rendering is format-agnostic in
|
16
|
+
that it results in a structured hash instead of an encoded string.
|
17
|
+
Blueprints can automatically generate object structures that follow the
|
18
|
+
attribute definitions.
|
19
|
+
EOF
|
20
|
+
spec.email = ['blanquer@gmail.com', 'dane.jensen@gmail.com']
|
13
21
|
|
14
|
-
spec.homepage =
|
15
|
-
spec.license =
|
16
|
-
spec.required_ruby_version =
|
22
|
+
spec.homepage = 'https://github.com/rightscale/praxis-blueprints'
|
23
|
+
spec.license = 'MIT'
|
24
|
+
spec.required_ruby_version = '>=2.1'
|
17
25
|
|
18
26
|
spec.files = `git ls-files -z`.split("\x0")
|
19
27
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
20
|
-
spec.require_paths = [
|
28
|
+
spec.require_paths = ['lib']
|
21
29
|
|
22
|
-
spec.add_runtime_dependency(
|
23
|
-
spec.add_runtime_dependency(
|
24
|
-
spec.add_runtime_dependency(
|
30
|
+
spec.add_runtime_dependency('randexp', ['~> 0'])
|
31
|
+
spec.add_runtime_dependency('attributor', ['>= 5.1'])
|
32
|
+
spec.add_runtime_dependency('activesupport', ['>= 3'])
|
25
33
|
|
26
|
-
spec.add_development_dependency
|
27
|
-
spec.add_development_dependency
|
34
|
+
spec.add_development_dependency 'bundler', '~> 1.6'
|
35
|
+
spec.add_development_dependency 'rake', '~> 0'
|
28
36
|
|
29
|
-
spec.add_development_dependency(
|
30
|
-
spec.add_development_dependency(
|
31
|
-
spec.add_development_dependency(
|
32
|
-
spec.add_development_dependency(
|
33
|
-
spec.add_development_dependency(
|
34
|
-
spec.add_development_dependency(
|
35
|
-
spec.add_development_dependency(
|
36
|
-
spec.add_development_dependency(
|
37
|
-
spec.add_development_dependency(
|
38
|
-
spec.add_development_dependency(
|
37
|
+
spec.add_development_dependency('redcarpet', ['< 3.0'])
|
38
|
+
spec.add_development_dependency('yard', ['~> 0.8.7'])
|
39
|
+
spec.add_development_dependency('guard', ['~> 2'])
|
40
|
+
spec.add_development_dependency('guard-rspec', ['>= 0'])
|
41
|
+
spec.add_development_dependency('rspec', ['< 2.99'])
|
42
|
+
spec.add_development_dependency('pry', ['~> 0'])
|
43
|
+
spec.add_development_dependency('pry-byebug', ['~> 1'])
|
44
|
+
spec.add_development_dependency('pry-stack_explorer', ['~> 0'])
|
45
|
+
spec.add_development_dependency('fuubar', ['~> 1'])
|
46
|
+
spec.add_development_dependency('coveralls')
|
47
|
+
spec.add_development_dependency 'rubocop'
|
48
|
+
spec.add_development_dependency 'guard-rubocop'
|
39
49
|
end
|
@@ -1,10 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
3
|
|
3
4
|
describe Praxis::Blueprint do
|
4
|
-
|
5
5
|
subject(:blueprint_class) { Person }
|
6
6
|
|
7
|
-
its(:family){ should eq('hash') }
|
7
|
+
its(:family) { should eq('hash') }
|
8
8
|
|
9
9
|
context 'deterministic examples' do
|
10
10
|
it 'works' do
|
@@ -52,7 +52,6 @@ describe Praxis::Blueprint do
|
|
52
52
|
its(:finalized?) { should be(true) }
|
53
53
|
end
|
54
54
|
|
55
|
-
|
56
55
|
context '.finalize on that subclass' do
|
57
56
|
before do
|
58
57
|
blueprint_class.should_receive(:_finalize!).and_call_original
|
@@ -60,9 +59,7 @@ describe Praxis::Blueprint do
|
|
60
59
|
end
|
61
60
|
|
62
61
|
its(:finalized?) { should be(true) }
|
63
|
-
|
64
62
|
end
|
65
|
-
|
66
63
|
end
|
67
64
|
|
68
65
|
context 'creating a base abstract Blueprint class without attributes' do
|
@@ -76,7 +73,6 @@ describe Praxis::Blueprint do
|
|
76
73
|
blueprint_class.finalize!
|
77
74
|
blueprint_class.finalized?.should be(true)
|
78
75
|
end
|
79
|
-
|
80
76
|
end
|
81
77
|
|
82
78
|
it 'has an inner Struct class for the attributes' do
|
@@ -88,7 +84,6 @@ describe Praxis::Blueprint do
|
|
88
84
|
it 'sorta has view objects' do
|
89
85
|
blueprint_class.views.should have_key(:default)
|
90
86
|
end
|
91
|
-
|
92
87
|
end
|
93
88
|
|
94
89
|
context 'an instance' do
|
@@ -113,24 +108,22 @@ describe Praxis::Blueprint do
|
|
113
108
|
end
|
114
109
|
end
|
115
110
|
|
116
|
-
|
117
111
|
context 'from Blueprint.example' do
|
118
112
|
subject(:blueprint_instance) { blueprint_class.example }
|
119
113
|
it_behaves_like 'a blueprint instance'
|
120
114
|
end
|
121
115
|
|
122
116
|
context 'wrapping an object' do
|
123
|
-
|
124
117
|
let(:data) do
|
125
118
|
{
|
126
119
|
name: 'Bob',
|
127
120
|
full_name: FullName.example,
|
128
121
|
address: Address.example,
|
129
|
-
email:
|
122
|
+
email: 'bob@example.com',
|
130
123
|
aliases: [],
|
131
124
|
prior_addresses: [],
|
132
|
-
parents: { father: Randgen.first_name, mother: Randgen.first_name},
|
133
|
-
href:
|
125
|
+
parents: { father: Randgen.first_name, mother: Randgen.first_name },
|
126
|
+
href: 'www.example.com',
|
134
127
|
alive: true
|
135
128
|
}
|
136
129
|
end
|
@@ -139,7 +132,6 @@ describe Praxis::Blueprint do
|
|
139
132
|
|
140
133
|
subject(:blueprint_instance) { blueprint_class.new(resource) }
|
141
134
|
|
142
|
-
|
143
135
|
it_behaves_like 'a blueprint instance'
|
144
136
|
|
145
137
|
context 'creating additional blueprint instances from that object' do
|
@@ -148,7 +140,7 @@ describe Praxis::Blueprint do
|
|
148
140
|
context 'with caching enabled' do
|
149
141
|
around do |example|
|
150
142
|
Praxis::Blueprint.caching_enabled = true
|
151
|
-
Praxis::Blueprint.cache = Hash.new { |h,k| h[k] =
|
143
|
+
Praxis::Blueprint.cache = Hash.new { |h, k| h[k] = {} }
|
152
144
|
example.run
|
153
145
|
|
154
146
|
Praxis::Blueprint.caching_enabled = false
|
@@ -165,15 +157,12 @@ describe Praxis::Blueprint do
|
|
165
157
|
context 'with caching disabled' do
|
166
158
|
it { should_not be blueprint_instance }
|
167
159
|
end
|
168
|
-
|
169
160
|
end
|
170
|
-
|
171
161
|
end
|
172
|
-
|
173
162
|
end
|
174
163
|
|
175
164
|
context '.describe' do
|
176
|
-
let(:shallow
|
165
|
+
let(:shallow) { false }
|
177
166
|
let(:example_object) { nil }
|
178
167
|
|
179
168
|
before do
|
@@ -187,18 +176,17 @@ describe Praxis::Blueprint do
|
|
187
176
|
expect(blueprint_class.attribute.type).to receive(:describe).with(true, example: example_object).twice.and_call_original
|
188
177
|
end
|
189
178
|
|
190
|
-
subject(:output){ blueprint_class.describe }
|
179
|
+
subject(:output) { blueprint_class.describe }
|
191
180
|
|
192
|
-
its([:name]){ should eq(blueprint_class.name)}
|
193
|
-
its([:id]){ should eq(blueprint_class.id)}
|
194
|
-
its([:views]){ should be_kind_of(Hash)}
|
195
|
-
its(:keys){ should_not include(:anonymous) }
|
181
|
+
its([:name]) { should eq(blueprint_class.name) }
|
182
|
+
its([:id]) { should eq(blueprint_class.id) }
|
183
|
+
its([:views]) { should be_kind_of(Hash) }
|
184
|
+
its(:keys) { should_not include(:anonymous) }
|
196
185
|
it 'should contain the an entry for each view' do
|
197
186
|
subject[:views].keys.should include(:default, :current, :extended, :master)
|
198
187
|
end
|
199
188
|
end
|
200
189
|
|
201
|
-
|
202
190
|
context 'for shallow descriptions' do
|
203
191
|
let(:shallow) { true }
|
204
192
|
|
@@ -218,8 +206,8 @@ describe Praxis::Blueprint do
|
|
218
206
|
end
|
219
207
|
it 'reports their anonymous-ness' do
|
220
208
|
description = blueprint_class.describe(true)
|
221
|
-
expect(
|
222
|
-
expect(
|
209
|
+
expect(description).to have_key(:anonymous)
|
210
|
+
expect(description[:anonymous]).to be(true)
|
223
211
|
end
|
224
212
|
end
|
225
213
|
end
|
@@ -241,8 +229,10 @@ describe Praxis::Blueprint do
|
|
241
229
|
output[:attributes][:name][:example].should eq example.name
|
242
230
|
output[:attributes][:age][:example].should eq example.age
|
243
231
|
|
232
|
+
output[:attributes][:aliases].should have_key(:example)
|
233
|
+
output[:attributes][:aliases][:example].should eq example.aliases.dump
|
234
|
+
|
244
235
|
output[:attributes][:full_name].should_not have_key(:example)
|
245
|
-
output[:attributes][:aliases].should_not have_key(:example)
|
246
236
|
|
247
237
|
parents_attributes = output[:attributes][:parents][:type][:attributes]
|
248
238
|
parents_attributes[:father][:example].should eq example.parents.father
|
@@ -252,7 +242,7 @@ describe Praxis::Blueprint do
|
|
252
242
|
end
|
253
243
|
|
254
244
|
context '.validate' do
|
255
|
-
let(:hash) { {name: 'bob'} }
|
245
|
+
let(:hash) { { name: 'bob' } }
|
256
246
|
let(:person) { Person.load(hash) }
|
257
247
|
subject(:errors) { person.validate }
|
258
248
|
|
@@ -261,7 +251,7 @@ describe Praxis::Blueprint do
|
|
261
251
|
end
|
262
252
|
|
263
253
|
context 'with invalid sub-attribute' do
|
264
|
-
let(:hash) { {name: 'bob', address: {state:
|
254
|
+
let(:hash) { { name: 'bob', address: { state: 'ME' } } }
|
265
255
|
|
266
256
|
it { should have(1).item }
|
267
257
|
its(:first) { should =~ /Attribute \$.address.state/ }
|
@@ -269,9 +259,9 @@ describe Praxis::Blueprint do
|
|
269
259
|
|
270
260
|
context 'for objects of the wrong type' do
|
271
261
|
it 'raises an error' do
|
272
|
-
expect
|
262
|
+
expect do
|
273
263
|
Person.validate(Object.new)
|
274
|
-
|
264
|
+
end.to raise_error(ArgumentError, /Error validating .* as Person for an object of type Object/)
|
275
265
|
end
|
276
266
|
end
|
277
267
|
end
|
@@ -279,9 +269,9 @@ describe Praxis::Blueprint do
|
|
279
269
|
context '.load' do
|
280
270
|
let(:hash) do
|
281
271
|
{
|
282
|
-
:
|
283
|
-
:
|
284
|
-
:
|
272
|
+
name: 'Bob',
|
273
|
+
full_name: { first: 'Robert', last: 'Robertson' },
|
274
|
+
address: { street: 'main', state: 'OR' }
|
285
275
|
}
|
286
276
|
end
|
287
277
|
subject(:person) { Person.load(hash) }
|
@@ -298,19 +288,16 @@ describe Praxis::Blueprint do
|
|
298
288
|
it { should be_kind_of(FullName) }
|
299
289
|
end
|
300
290
|
end
|
301
|
-
|
302
291
|
end
|
303
292
|
|
304
|
-
|
305
293
|
context 'decorators' do
|
306
294
|
let(:name) { 'Soren II' }
|
307
295
|
|
308
296
|
let(:object) { Person.example.object }
|
309
297
|
subject(:person) { Person.new(object, decorators) }
|
310
298
|
|
311
|
-
|
312
299
|
context 'as a hash' do
|
313
|
-
let(:decorators) { {name: name} }
|
300
|
+
let(:decorators) { { name: name } }
|
314
301
|
it do
|
315
302
|
person.name.should eq('Soren II')
|
316
303
|
end
|
@@ -318,7 +305,7 @@ describe Praxis::Blueprint do
|
|
318
305
|
its(:name) { should be(name) }
|
319
306
|
|
320
307
|
context 'an additional instance with the equivalent hash' do
|
321
|
-
subject(:additional_person) { Person.new(object,
|
308
|
+
subject(:additional_person) { Person.new(object, name: name) }
|
322
309
|
it { should_not be person }
|
323
310
|
end
|
324
311
|
|
@@ -334,7 +321,7 @@ describe Praxis::Blueprint do
|
|
334
321
|
end
|
335
322
|
|
336
323
|
context 'as an object' do
|
337
|
-
let(:decorators) { double(
|
324
|
+
let(:decorators) { double('decorators', name: name) }
|
338
325
|
its(:name) { should be(name) }
|
339
326
|
|
340
327
|
context 'an additional instance with the same object' do
|
@@ -342,13 +329,10 @@ describe Praxis::Blueprint do
|
|
342
329
|
it { should_not be person }
|
343
330
|
end
|
344
331
|
end
|
345
|
-
|
346
332
|
end
|
347
333
|
|
348
|
-
|
349
334
|
context 'with a provided :reference option on attributes' do
|
350
335
|
context 'that does not match the value set on the class' do
|
351
|
-
|
352
336
|
subject(:mismatched_reference) do
|
353
337
|
Class.new(Praxis::Blueprint) do
|
354
338
|
self.reference = Class.new(Praxis::Blueprint)
|
@@ -357,15 +341,13 @@ describe Praxis::Blueprint do
|
|
357
341
|
end
|
358
342
|
|
359
343
|
it 'should raise an error' do
|
360
|
-
expect
|
344
|
+
expect do
|
361
345
|
mismatched_reference.attributes
|
362
|
-
|
346
|
+
end.to raise_error
|
363
347
|
end
|
364
|
-
|
365
348
|
end
|
366
349
|
end
|
367
350
|
|
368
|
-
|
369
351
|
context '.example' do
|
370
352
|
context 'with some attribute values provided' do
|
371
353
|
let(:name) { 'Sir Bobbert' }
|
@@ -377,7 +359,6 @@ describe Praxis::Blueprint do
|
|
377
359
|
context '.render' do
|
378
360
|
let(:person) { Person.example('1') }
|
379
361
|
it 'is an alias to dump' do
|
380
|
-
|
381
362
|
person.object.contents
|
382
363
|
rendered = Person.render(person, view: :default)
|
383
364
|
dumped = Person.dump(person, view: :default)
|
@@ -391,10 +372,7 @@ describe Praxis::Blueprint do
|
|
391
372
|
let(:render_opts) { {} }
|
392
373
|
subject(:output) { person.render(view: view_name, **render_opts) }
|
393
374
|
|
394
|
-
|
395
|
-
|
396
375
|
context 'with a sub-attribute that is a blueprint' do
|
397
|
-
|
398
376
|
it { should have_key(:name) }
|
399
377
|
it { should have_key(:address) }
|
400
378
|
it 'renders the sub-attribute correctly' do
|
@@ -403,14 +381,13 @@ describe Praxis::Blueprint do
|
|
403
381
|
end
|
404
382
|
|
405
383
|
it 'reports a dump error with the appropriate context' do
|
406
|
-
person.address.should_receive(:state).and_raise(
|
407
|
-
expect
|
384
|
+
person.address.should_receive(:state).and_raise('Kaboom')
|
385
|
+
expect do
|
408
386
|
person.render(view: view_name, context: ['special_root'])
|
409
|
-
|
387
|
+
end.to raise_error(/Error while dumping attribute state of type Address for context special_root.address. Reason: .*Kaboom/)
|
410
388
|
end
|
411
389
|
end
|
412
390
|
|
413
|
-
|
414
391
|
context 'with sub-attribute that is an Attributor::Model' do
|
415
392
|
it { should have_key(:full_name) }
|
416
393
|
it 'renders the model correctly' do
|
@@ -422,7 +399,7 @@ describe Praxis::Blueprint do
|
|
422
399
|
|
423
400
|
context 'using the `fields` option' do
|
424
401
|
context 'as a hash' do
|
425
|
-
subject(:output) { person.render(fields: {address: {state: true}}) }
|
402
|
+
subject(:output) { person.render(fields: { address: { state: true } }) }
|
426
403
|
it 'should only have the address rendered' do
|
427
404
|
output.keys.should eq [:address]
|
428
405
|
end
|
@@ -438,5 +415,4 @@ describe Praxis::Blueprint do
|
|
438
415
|
end
|
439
416
|
end
|
440
417
|
end
|
441
|
-
|
442
418
|
end
|
@@ -1,17 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require_relative '../spec_helper'
|
2
3
|
|
3
4
|
describe Praxis::CollectionView do
|
4
|
-
|
5
5
|
let(:root_context) { ['people'] }
|
6
6
|
|
7
7
|
let(:people) do
|
8
|
-
3
|
9
|
-
context = [
|
8
|
+
Array.new(3) do |i|
|
9
|
+
context = ['people', "at(#{i})"]
|
10
10
|
Person.example(context)
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
-
|
15
14
|
let(:contents_definition) do
|
16
15
|
proc do
|
17
16
|
attribute :name
|
@@ -28,16 +27,14 @@ describe Praxis::CollectionView do
|
|
28
27
|
end
|
29
28
|
|
30
29
|
context 'creating from a member view' do
|
31
|
-
|
32
30
|
it 'gets the proper contents' do
|
33
31
|
collection_view.contents.should eq member_view.contents
|
34
32
|
end
|
35
33
|
|
36
34
|
context 'lazy initializes its contents' do
|
37
|
-
|
38
35
|
it 'so it will not call contents until it is first needed' do
|
39
|
-
member_view.stub(:contents){ raise 'No!' }
|
40
|
-
expect{ collection_view.name }.to_not raise_error
|
36
|
+
member_view.stub(:contents) { raise 'No!' }
|
37
|
+
expect { collection_view.name }.to_not raise_error
|
41
38
|
end
|
42
39
|
it 'when contents is needed, it will clone it from the member_view' do
|
43
40
|
# Twice is because we're callong member_view.contents for the right side of the equality
|
@@ -61,7 +58,7 @@ describe Praxis::CollectionView do
|
|
61
58
|
subject(:output) { collection_view.render(people, context: root_context) }
|
62
59
|
|
63
60
|
it { should be_kind_of(Array) }
|
64
|
-
it { should eq people.collect {|person| member_view.render(person)} }
|
61
|
+
it { should eq people.collect { |person| member_view.render(person) } }
|
65
62
|
end
|
66
63
|
|
67
64
|
context '#example' do
|
@@ -82,5 +79,4 @@ describe Praxis::CollectionView do
|
|
82
79
|
its([:attributes]) { should eq(member_view.describe[:attributes]) }
|
83
80
|
its([:type]) { should eq(:collection) }
|
84
81
|
end
|
85
|
-
|
86
82
|
end
|
@@ -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
|