cheffish 0.8.1 → 0.8.2

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: 338276289ac7fab89d006bc453e20266560948b7
4
- data.tar.gz: 60ac99761729f96b46b5d12f38101fcf930008cc
3
+ metadata.gz: 7de0b0a59e8705c145dce86b294d9ec4ab0e43c4
4
+ data.tar.gz: 6239ca45f2db3ae775172f41666283c48ba78d39
5
5
  SHA512:
6
- metadata.gz: d2fbe1a958c572c4c885d8bea5c2453bbd0cfbb9cd0fbba63a15cf47eb7266b946f66a900549b1a9f6b45186f378a01312c573accdadfc84c520b5a288a99753
7
- data.tar.gz: 0676d6791b22f25d28ce7977b4e905e10bb8ab2cf44059af0b1cc6175ae6dcad98cebc73024dbb352829405a7237575f862559032105d13c4e95a0aa4270d7f7
6
+ metadata.gz: ac3f5b8b7a9f8d79846a9784225b1bc3babc07ec08c96d4c42ac61ee36ac65e8bb68ff36f0bb6f2d2ee6e9bbdd0441beb95f90b7b6db11e9e7b795b378d55bd1
7
+ data.tar.gz: 32907291f4a2ddfb3cdddaf69b44e4a5380eff0aeb0b7975a51fc450374f0747962f6eb19989e5c317fc1e1cf59395cd5e0bc6c840fe438fd8913a1f25831993
@@ -31,8 +31,8 @@ module Cheffish
31
31
  if new_resource.complete
32
32
  result = normalize(resource_to_json(new_resource))
33
33
  else
34
- # If resource is incomplete, use current json to fill any holes
35
- result = Chef::Mixin::DeepMerge.hash_only_merge(current_json, resource_to_json(new_resource))
34
+ # If the resource is incomplete, we use the current json to fill any holes
35
+ result = current_json.merge(resource_to_json(new_resource))
36
36
  end
37
37
  augment_new_json(result)
38
38
  end
@@ -131,7 +131,18 @@ module Cheffish
131
131
  modifiers.each do |path, value|
132
132
  path = [path] if !path.kind_of?(Array)
133
133
  path = path.map { |path_part| path_part.to_s }
134
- parent = path[0..-2].inject(json) { |hash, path_part| hash ? hash[path_part] : nil }
134
+ parent = 0.upto(path.size-2).inject(json) do |hash, index|
135
+ if hash.nil?
136
+ nil
137
+ elsif !hash.is_a?(Hash)
138
+ raise "Attempt to set #{path} to #{value} when #{path[0..index-1]} is not a hash"
139
+ else
140
+ hash[path[index]]
141
+ end
142
+ end
143
+ if !parent.nil? && !parent.is_a?(Hash)
144
+ raise "Attempt to set #{path} to #{value} when #{path[0..-2]} is not a hash"
145
+ end
135
146
  existing_value = parent ? parent[path[-1]] : nil
136
147
 
137
148
  if value.is_a?(Proc)
@@ -139,14 +150,11 @@ module Cheffish
139
150
  end
140
151
  if value == :delete
141
152
  parent.delete(path[-1]) if parent
142
- # TODO clean up parent chain if hash is completely emptied
143
153
  else
144
- if !parent
145
- # Create parent if necessary
146
- parent = path[0..-2].inject(json) do |hash, path_part|
147
- hash[path_part] = {} if !hash[path_part]
148
- hash[path_part]
149
- end
154
+ # Create parent if necessary, overwriting values
155
+ parent = path[0..-2].inject(json) do |hash, path_part|
156
+ hash[path_part] = {} if !hash[path_part]
157
+ hash[path_part]
150
158
  end
151
159
  parent[path[-1]] = value
152
160
  end
@@ -1,3 +1,3 @@
1
1
  module Cheffish
2
- VERSION = '0.8.1'
2
+ VERSION = '0.8.2'
3
3
  end
@@ -109,88 +109,676 @@ describe Chef::Resource::ChefNode do
109
109
  end
110
110
  end
111
111
 
112
- context 'has a node named "blah" with everything in it' do
113
- node 'blah', {
114
- 'chef_environment' => 'blah',
115
- 'run_list' => [ 'recipe[bjork]' ],
116
- 'normal' => { 'foo' => 'bar', 'tags' => [ 'a', 'b' ] },
117
- 'default' => { 'foo2' => 'bar2' },
118
- 'automatic' => { 'foo3' => 'bar3' },
119
- 'override' => { 'foo4' => 'bar4' }
120
- }
112
+ describe '#complete' do
113
+ context 'when the Chef server has a node named "blah" with everything in it' do
114
+ node 'blah', {
115
+ 'chef_environment' => 'blah',
116
+ 'run_list' => [ 'recipe[bjork]' ],
117
+ 'normal' => { 'foo' => 'bar', 'tags' => [ 'a', 'b' ] },
118
+ 'default' => { 'foo2' => 'bar2' },
119
+ 'automatic' => { 'foo3' => 'bar3' },
120
+ 'override' => { 'foo4' => 'bar4' }
121
+ }
122
+
123
+ it 'chef_node with no attributes modifies nothing' do
124
+ run_recipe do
125
+ chef_node 'blah'
126
+ end
127
+ expect(get('nodes/blah')).to include(
128
+ 'name' => 'blah',
129
+ 'chef_environment' => 'blah',
130
+ 'run_list' => [ 'recipe[bjork]' ],
131
+ 'normal' => { 'foo' => 'bar', 'tags' => [ 'a', 'b' ] },
132
+ 'default' => { 'foo2' => 'bar2' },
133
+ 'automatic' => { 'foo3' => 'bar3' },
134
+ 'override' => { 'foo4' => 'bar4' }
135
+ )
136
+ end
121
137
 
122
- context 'with chef_node "blah"' do
123
- with_converge do
124
- chef_node 'blah'
138
+ it 'chef_node with complete true removes everything except default, automatic and override' do
139
+ run_recipe do
140
+ chef_node 'blah' do
141
+ complete true
142
+ end
143
+ end
144
+ expect(get('nodes/blah')).to include(
145
+ 'name' => 'blah',
146
+ 'chef_environment' => '_default',
147
+ 'run_list' => [ ],
148
+ 'normal' => { 'tags' => [ 'a', 'b' ] },
149
+ 'default' => { 'foo2' => 'bar2' },
150
+ 'automatic' => { 'foo3' => 'bar3' },
151
+ 'override' => { 'foo4' => 'bar4' }
152
+ )
153
+ end
154
+
155
+ it 'chef_node with complete true sets the given attributes' do
156
+ run_recipe do
157
+ chef_node 'blah' do
158
+ chef_environment 'x'
159
+ run_list [ 'recipe[y]' ]
160
+ attributes 'a' => 'b'
161
+ tags 'c', 'd'
162
+ complete true
163
+ end
164
+ end
165
+ expect(get('nodes/blah')).to include(
166
+ 'name' => 'blah',
167
+ 'chef_environment' => 'x',
168
+ 'run_list' => [ 'recipe[y]' ],
169
+ 'normal' => { 'a' => 'b', 'tags' => [ 'c', 'd' ] },
170
+ 'default' => { 'foo2' => 'bar2' },
171
+ 'automatic' => { 'foo3' => 'bar3' },
172
+ 'override' => { 'foo4' => 'bar4' }
173
+ )
125
174
  end
126
175
 
127
- it 'nothing gets updated' do
128
- expect(chef_run).not_to have_updated 'chef_node[blah]', :create
176
+ it 'chef_node with complete true and partial attributes sets the given attributes' do
177
+ run_recipe do
178
+ chef_node 'blah' do
179
+ chef_environment 'x'
180
+ recipe 'y'
181
+ attribute 'a', 'b'
182
+ tags 'c', 'd'
183
+ complete true
184
+ end
185
+ end
186
+ expect(get('nodes/blah')).to include(
187
+ 'name' => 'blah',
188
+ 'chef_environment' => 'x',
189
+ 'run_list' => [ 'recipe[y]' ],
190
+ 'normal' => { 'a' => 'b', 'tags' => [ 'c', 'd' ] },
191
+ 'default' => { 'foo2' => 'bar2' },
192
+ 'automatic' => { 'foo3' => 'bar3' },
193
+ 'override' => { 'foo4' => 'bar4' }
194
+ )
129
195
  end
130
196
  end
197
+ end
131
198
 
132
- context 'with chef_node "blah" and an updated normal attribute value' do
133
- with_converge do
134
- chef_node 'blah' do
135
- attributes 'foo' => 'fum'
199
+ describe '#attributes' do
200
+ context 'with a node with normal attributes a => b and c => { d => e }' do
201
+ node 'blah', {
202
+ 'normal' => {
203
+ 'a' => 'b',
204
+ 'c' => { 'd' => 'e' },
205
+ 'tags' => [ 'a', 'b' ]
206
+ },
207
+ 'automatic' => {
208
+ 'x' => 'y'
209
+ },
210
+ 'chef_environment' => 'desert'
211
+ }
212
+
213
+ it 'chef_node with attributes {} removes all normal attributes but leaves tags, automatic and environment alone' do
214
+ run_recipe do
215
+ chef_node 'blah' do
216
+ attributes({})
217
+ end
136
218
  end
219
+ expect(chef_run).to have_updated('chef_node[blah]', :create)
220
+ expect(get('nodes/blah')).to include(
221
+ 'normal' => { 'tags' => [ 'a', 'b' ] },
222
+ 'automatic' => { 'x' => 'y' },
223
+ 'chef_environment' => 'desert'
224
+ )
137
225
  end
138
226
 
139
- it 'new normal attribute is added' do
140
- expect(chef_run).to have_updated 'chef_node[blah]', :create
141
- node = get('nodes/blah')
142
- expect(node['normal']).to eq({ 'foo' => 'fum', 'tags' => [ 'a', 'b' ] })
227
+ it 'chef_node with attributes { c => d } replaces normal but not tags/automatic/environment' do
228
+ run_recipe do
229
+ chef_node 'blah' do
230
+ attributes 'c' => 'd'
231
+ end
232
+ end
233
+ expect(chef_run).to have_updated('chef_node[blah]', :create)
234
+ expect(get('nodes/blah')).to include(
235
+ 'normal' => { 'c' => 'd', 'tags' => [ 'a', 'b' ] },
236
+ 'automatic' => { 'x' => 'y' },
237
+ 'chef_environment' => 'desert'
238
+ )
143
239
  end
144
- end
145
240
 
146
- context 'with chef_node "blah" and a new normal attribute' do
147
- with_converge do
148
- chef_node 'blah' do
149
- attributes 'foe' => 'fum'
241
+ it 'chef_node with attributes { c => f => g, y => z } replaces normal but not tags/automatic/environment' do
242
+ run_recipe do
243
+ chef_node 'blah' do
244
+ attributes 'c' => { 'f' => 'g' }, 'y' => 'z'
245
+ end
150
246
  end
247
+ expect(chef_run).to have_updated('chef_node[blah]', :create)
248
+ expect(get('nodes/blah')).to include(
249
+ 'normal' => { 'c' => { 'f' => 'g' }, 'y' => 'z', 'tags' => [ 'a', 'b' ] },
250
+ 'automatic' => { 'x' => 'y' },
251
+ 'chef_environment' => 'desert'
252
+ )
151
253
  end
152
254
 
153
- it 'new normal attribute is added' do
154
- expect(chef_run).to have_updated 'chef_node[blah]', :create
155
- node = get('nodes/blah')
156
- expect(node['normal']).to eq({ 'foe' => 'fum', 'foo' => 'bar', 'tags' => [ 'a', 'b' ] })
255
+ it 'chef_node with attributes { tags => [ "x" ] } replaces normal and tags but not automatic/environment' do
256
+ run_recipe do
257
+ chef_node 'blah' do
258
+ attributes 'tags' => [ 'x' ]
259
+ end
260
+ end
261
+ expect(chef_run).to have_updated('chef_node[blah]', :create)
262
+ expect(get('nodes/blah')).to include(
263
+ 'normal' => { 'tags' => [ 'x' ] },
264
+ 'automatic' => { 'x' => 'y' },
265
+ 'chef_environment' => 'desert'
266
+ )
267
+ end
268
+
269
+ it 'chef_node with tags "x" and attributes { "tags" => [ "y" ] } sets tags to "x"' do
270
+ run_recipe do
271
+ chef_node 'blah' do
272
+ tags 'x'
273
+ attributes 'tags' => [ 'y' ]
274
+ end
275
+ end
276
+ expect(chef_run).to have_updated('chef_node[blah]', :create)
277
+ expect(get('nodes/blah')).to include(
278
+ 'normal' => {
279
+ 'tags' => [ 'x' ]
280
+ },
281
+ 'automatic' => { 'x' => 'y' },
282
+ 'chef_environment' => 'desert'
283
+ )
157
284
  end
158
285
  end
286
+ end
159
287
 
160
- context 'with chef_node "blah" with complete true' do
161
- with_converge do
162
- chef_node 'blah' do
163
- complete true
288
+ describe '#attribute' do
289
+ context 'with a node with normal attributes a => b and c => { d => e }' do
290
+ node 'blah', {
291
+ 'normal' => {
292
+ 'a' => 'b',
293
+ 'c' => { 'd' => 'e' },
294
+ 'tags' => [ 'a', 'b' ]
295
+ },
296
+ 'automatic' => {
297
+ 'x' => 'y'
298
+ },
299
+ 'chef_environment' => 'desert'
300
+ }
301
+
302
+ context 'basic scenarios' do
303
+ it 'chef_node with no attributes, leaves it alone' do
304
+ run_recipe do
305
+ chef_node 'blah'
306
+ end
307
+ expect(chef_run).not_to have_updated('chef_node[blah]', :create)
308
+ expect(get('nodes/blah')).to include(
309
+ 'normal' => {
310
+ 'a' => 'b',
311
+ 'c' => { 'd' => 'e' },
312
+ 'tags' => [ 'a', 'b' ]
313
+ },
314
+ 'automatic' => { 'x' => 'y' },
315
+ 'chef_environment' => 'desert'
316
+ )
317
+ end
318
+
319
+ it 'chef_node with attribute d, e adds the attribute' do
320
+ run_recipe do
321
+ chef_node 'blah' do
322
+ attribute 'd', 'e'
323
+ end
324
+ end
325
+ expect(chef_run).to have_updated('chef_node[blah]', :create)
326
+ expect(get('nodes/blah')).to include(
327
+ 'normal' => {
328
+ 'a' => 'b',
329
+ 'c' => { 'd' => 'e' },
330
+ 'd' => 'e',
331
+ 'tags' => [ 'a', 'b' ]
332
+ },
333
+ 'automatic' => { 'x' => 'y' },
334
+ 'chef_environment' => 'desert'
335
+ )
336
+ end
337
+
338
+ it 'chef_node with attribute tags, [ "x" ] replaces tags' do
339
+ run_recipe do
340
+ chef_node 'blah' do
341
+ attribute 'tags', [ 'x' ]
342
+ end
343
+ end
344
+ expect(chef_run).to have_updated('chef_node[blah]', :create)
345
+ expect(get('nodes/blah')).to include(
346
+ 'normal' => {
347
+ 'a' => 'b',
348
+ 'c' => { 'd' => 'e' },
349
+ 'tags' => [ 'x' ]
350
+ },
351
+ 'automatic' => { 'x' => 'y' },
352
+ 'chef_environment' => 'desert'
353
+ )
354
+ end
355
+
356
+ it 'chef_node with attribute c, x replaces the attribute' do
357
+ run_recipe do
358
+ chef_node 'blah' do
359
+ attribute 'c', 'x'
360
+ end
361
+ end
362
+ expect(chef_run).to have_updated('chef_node[blah]', :create)
363
+ expect(get('nodes/blah')).to include(
364
+ 'normal' => {
365
+ 'a' => 'b',
366
+ 'c' => 'x',
367
+ 'tags' => [ 'a', 'b' ]
368
+ },
369
+ 'automatic' => { 'x' => 'y' },
370
+ 'chef_environment' => 'desert'
371
+ )
372
+ end
373
+
374
+ it 'chef_node with attribute c, { d => x } replaces the attribute' do
375
+ run_recipe do
376
+ chef_node 'blah' do
377
+ attribute 'c', { 'd' => 'x' }
378
+ end
379
+ end
380
+ expect(chef_run).to have_updated('chef_node[blah]', :create)
381
+ expect(get('nodes/blah')).to include(
382
+ 'normal' => {
383
+ 'a' => 'b',
384
+ 'c' => { 'd' => 'x' },
385
+ 'tags' => [ 'a', 'b' ]
386
+ },
387
+ 'automatic' => { 'x' => 'y' },
388
+ 'chef_environment' => 'desert'
389
+ )
390
+ end
391
+
392
+ it 'chef_node with attribute [ c, d ], x replaces the attribute' do
393
+ run_recipe do
394
+ chef_node 'blah' do
395
+ attribute [ 'c', 'd' ], 'x'
396
+ end
397
+ end
398
+ expect(chef_run).to have_updated('chef_node[blah]', :create)
399
+ expect(get('nodes/blah')).to include(
400
+ 'normal' => {
401
+ 'a' => 'b',
402
+ 'c' => { 'd' => 'x' },
403
+ 'tags' => [ 'a', 'b' ]
404
+ },
405
+ 'automatic' => { 'x' => 'y' },
406
+ 'chef_environment' => 'desert'
407
+ )
408
+ end
409
+
410
+ it 'chef_node with attribute [ a, b ], x raises an error' do
411
+ expect do
412
+ run_recipe do
413
+ chef_node 'blah' do
414
+ attribute [ 'a', 'b' ], 'x'
415
+ end
416
+ end
417
+ end.to raise_error /Attempt to set \["a", "b"\] to x when \["a"\] is not a hash/
418
+ end
419
+
420
+ it 'chef_node with attribute [ a, b, c ], x raises an error' do
421
+ expect do
422
+ run_recipe do
423
+ chef_node 'blah' do
424
+ attribute [ 'a', 'b', 'c' ], 'x'
425
+ end
426
+ end
427
+ end.to raise_error /Attempt to set \["a", "b", "c"\] to x when \["a"\] is not a hash/
428
+ end
429
+
430
+ it 'chef_node with attribute [ x, y ], z adds a new attribute' do
431
+ run_recipe do
432
+ chef_node 'blah' do
433
+ attribute [ 'x', 'y' ], 'z'
434
+ end
435
+ end
436
+ expect(chef_run).to have_updated('chef_node[blah]', :create)
437
+ expect(get('nodes/blah')).to include(
438
+ 'normal' => {
439
+ 'a' => 'b',
440
+ 'c' => { 'd' => 'e' },
441
+ 'x' => { 'y' => 'z' },
442
+ 'tags' => [ 'a', 'b' ]
443
+ },
444
+ 'automatic' => { 'x' => 'y' },
445
+ 'chef_environment' => 'desert'
446
+ )
164
447
  end
165
448
  end
166
449
 
167
- it 'default, automatic and override attributes are left alone' do
168
- expect(chef_run).to have_updated 'chef_node[blah]', :create
169
- node = get('nodes/blah')
170
- expect(node['chef_environment']).to eq('_default')
171
- expect(node['run_list']).to eq([])
172
- expect(node['normal']).to eq({ 'tags' => [ 'a', 'b' ] })
173
- expect(node['default']).to eq({ 'foo2' => 'bar2' })
174
- expect(node['automatic']).to eq({ 'foo3' => 'bar3' })
175
- expect(node['override']).to eq({ 'foo4' => 'bar4' })
450
+ context 'delete' do
451
+ it 'chef_node with attribute a, :delete deletes the attribute' do
452
+ run_recipe do
453
+ chef_node 'blah' do
454
+ attribute 'a', :delete
455
+ end
456
+ end
457
+ expect(chef_run).to have_updated('chef_node[blah]', :create)
458
+ expect(get('nodes/blah')).to include(
459
+ 'normal' => {
460
+ 'c' => { 'd' => 'e' },
461
+ 'tags' => [ 'a', 'b' ]
462
+ },
463
+ 'automatic' => { 'x' => 'y' },
464
+ 'chef_environment' => 'desert'
465
+ )
466
+ end
467
+
468
+ it 'chef_node with attribute c, :delete deletes the attribute' do
469
+ run_recipe do
470
+ chef_node 'blah' do
471
+ attribute 'c', :delete
472
+ end
473
+ end
474
+ expect(chef_run).to have_updated('chef_node[blah]', :create)
475
+ expect(get('nodes/blah')).to include(
476
+ 'normal' => {
477
+ 'a' => 'b',
478
+ 'tags' => [ 'a', 'b' ]
479
+ },
480
+ 'automatic' => { 'x' => 'y' },
481
+ 'chef_environment' => 'desert'
482
+ )
483
+ end
484
+
485
+ it 'chef_node with attribute [ c, d ], :delete deletes the attribute' do
486
+ run_recipe do
487
+ chef_node 'blah' do
488
+ attribute [ 'c', 'd' ], :delete
489
+ end
490
+ end
491
+ expect(chef_run).to have_updated('chef_node[blah]', :create)
492
+ expect(get('nodes/blah')).to include(
493
+ 'normal' => {
494
+ 'a' => 'b',
495
+ 'c' => {},
496
+ 'tags' => [ 'a', 'b' ]
497
+ },
498
+ 'automatic' => { 'x' => 'y' },
499
+ 'chef_environment' => 'desert'
500
+ )
501
+ end
502
+
503
+ it 'chef_node with attribute xyz, :delete does nothing' do
504
+ run_recipe do
505
+ chef_node 'blah' do
506
+ attribute 'xyz', :delete
507
+ end
508
+ end
509
+ expect(chef_run).not_to have_updated('chef_node[blah]', :create)
510
+ expect(get('nodes/blah')).to include(
511
+ 'normal' => {
512
+ 'a' => 'b',
513
+ 'c' => { 'd' => 'e' },
514
+ 'tags' => [ 'a', 'b' ]
515
+ },
516
+ 'automatic' => { 'x' => 'y' },
517
+ 'chef_environment' => 'desert'
518
+ )
519
+ end
520
+
521
+ it 'chef_node with attribute [ c, x ], :delete does nothing' do
522
+ run_recipe do
523
+ chef_node 'blah' do
524
+ attribute [ 'c', 'x' ], :delete
525
+ end
526
+ end
527
+ expect(chef_run).not_to have_updated('chef_node[blah]', :create)
528
+ expect(get('nodes/blah')).to include(
529
+ 'normal' => {
530
+ 'a' => 'b',
531
+ 'c' => { 'd' => 'e' },
532
+ 'tags' => [ 'a', 'b' ]
533
+ },
534
+ 'automatic' => { 'x' => 'y' },
535
+ 'chef_environment' => 'desert'
536
+ )
537
+ end
176
538
  end
177
- end
178
539
 
179
- context 'with chef_node "blah", complete true and a new normal attribute' do
180
- with_converge do
181
- chef_node 'blah' do
182
- attributes 'foe' => 'fum'
183
- complete true
540
+ context 'types' do
541
+ it 'chef_node with attribute a, true sets a to true' do
542
+ run_recipe do
543
+ chef_node 'blah' do
544
+ attribute 'a', true
545
+ end
546
+ end
547
+ expect(get('nodes/blah')).to include(
548
+ 'normal' => {
549
+ 'a' => true,
550
+ 'c' => { 'd' => 'e' },
551
+ 'tags' => [ 'a', 'b' ]
552
+ },
553
+ 'automatic' => { 'x' => 'y' },
554
+ 'chef_environment' => 'desert'
555
+ )
556
+ end
557
+
558
+ it 'chef_node with attribute a, 1 sets a to 1' do
559
+ run_recipe do
560
+ chef_node 'blah' do
561
+ attribute 'a', 1
562
+ end
563
+ end
564
+ expect(get('nodes/blah')).to include(
565
+ 'normal' => {
566
+ 'a' => 1,
567
+ 'c' => { 'd' => 'e' },
568
+ 'tags' => [ 'a', 'b' ]
569
+ },
570
+ 'automatic' => { 'x' => 'y' },
571
+ 'chef_environment' => 'desert'
572
+ )
573
+ end
574
+
575
+ it 'chef_node with attribute a, "1" sets a to "1"' do
576
+ run_recipe do
577
+ chef_node 'blah' do
578
+ attribute 'a', "1"
579
+ end
580
+ end
581
+ expect(get('nodes/blah')).to include(
582
+ 'normal' => {
583
+ 'a' => "1",
584
+ 'c' => { 'd' => 'e' },
585
+ 'tags' => [ 'a', 'b' ]
586
+ },
587
+ 'automatic' => { 'x' => 'y' },
588
+ 'chef_environment' => 'desert'
589
+ )
590
+ end
591
+
592
+ it 'chef_node with attribute a, "" sets a to ""' do
593
+ run_recipe do
594
+ chef_node 'blah' do
595
+ attribute 'a', ""
596
+ end
597
+ end
598
+ expect(get('nodes/blah')).to include(
599
+ 'normal' => {
600
+ 'a' => "",
601
+ 'c' => { 'd' => 'e' },
602
+ 'tags' => [ 'a', 'b' ]
603
+ },
604
+ 'automatic' => { 'x' => 'y' },
605
+ 'chef_environment' => 'desert'
606
+ )
607
+ end
608
+
609
+ it 'chef_node with attribute a, nil sets a to nil' do
610
+ run_recipe do
611
+ chef_node 'blah' do
612
+ attribute 'a', nil
613
+ end
614
+ end
615
+ expect(get('nodes/blah')).to include(
616
+ 'normal' => {
617
+ 'a' => nil,
618
+ 'c' => { 'd' => 'e' },
619
+ 'tags' => [ 'a', 'b' ]
620
+ },
621
+ 'automatic' => { 'x' => 'y' },
622
+ 'chef_environment' => 'desert'
623
+ )
184
624
  end
185
625
  end
186
626
 
187
- it 'normal foo attribute is replaced with new attribute' do
188
- expect(chef_run).to have_updated 'chef_node[blah]', :create
189
- node = get('nodes/blah')
190
- expect(node['normal']).to eq({ 'foe' => 'fum', 'tags' => [ 'a', 'b' ] })
627
+ context 'multiple attribute definitions' do
628
+ it 'chef_node with attribute a, x and c, y replaces both attributes' do
629
+ run_recipe do
630
+ chef_node 'blah' do
631
+ attribute 'a', 'x'
632
+ attribute 'c', 'y'
633
+ end
634
+ end
635
+ expect(get('nodes/blah')).to include(
636
+ 'normal' => {
637
+ 'a' => 'x',
638
+ 'c' => 'y',
639
+ 'tags' => [ 'a', 'b' ]
640
+ },
641
+ 'automatic' => { 'x' => 'y' },
642
+ 'chef_environment' => 'desert'
643
+ )
644
+ end
645
+
646
+ it 'chef_node with attribute m, x and n, y adds both attributes' do
647
+ run_recipe do
648
+ chef_node 'blah' do
649
+ attribute 'm', 'x'
650
+ attribute 'n', 'y'
651
+ end
652
+ end
653
+ expect(get('nodes/blah')).to include(
654
+ 'normal' => {
655
+ 'a' => 'b',
656
+ 'c' => { 'd' => 'e' },
657
+ 'm' => 'x',
658
+ 'n' => 'y',
659
+ 'tags' => [ 'a', 'b' ]
660
+ },
661
+ 'automatic' => { 'x' => 'y' },
662
+ 'chef_environment' => 'desert'
663
+ )
664
+ end
665
+
666
+ it 'chef_node with attribute [x, y], z and [x, yy], zz adds both attributes' do
667
+ run_recipe do
668
+ chef_node 'blah' do
669
+ attribute [ 'x', 'y' ], 'z'
670
+ attribute [ 'x', 'yy' ], 'zz'
671
+ end
672
+ end
673
+ expect(get('nodes/blah')).to include(
674
+ 'normal' => {
675
+ 'a' => 'b',
676
+ 'c' => { 'd' => 'e' },
677
+ 'x' => {
678
+ 'y' => 'z',
679
+ 'yy' => 'zz'
680
+ },
681
+ 'tags' => [ 'a', 'b' ]
682
+ },
683
+ 'automatic' => { 'x' => 'y' },
684
+ 'chef_environment' => 'desert'
685
+ )
686
+ end
687
+
688
+ describe 'precedence' do
689
+ it 'chef_node with attribute a, 1 and a, 2 sets a to 2' do
690
+ run_recipe do
691
+ chef_node 'blah' do
692
+ attribute 'a', 1
693
+ attribute 'a', 2
694
+ end
695
+ end
696
+ expect(get('nodes/blah')).to include(
697
+ 'normal' => {
698
+ 'a' => 2,
699
+ 'c' => { 'd' => 'e' },
700
+ 'tags' => [ 'a', 'b' ]
701
+ },
702
+ 'automatic' => { 'x' => 'y' },
703
+ 'chef_environment' => 'desert'
704
+ )
705
+ end
706
+
707
+ it 'chef_node with attribute [ x, y ], 1 and [ x, y ], 2 sets [ x, y ], 2' do
708
+ run_recipe do
709
+ chef_node 'blah' do
710
+ attribute [ 'x', 'y' ], 1
711
+ attribute [ 'x', 'y' ], 2
712
+ end
713
+ end
714
+ expect(get('nodes/blah')).to include(
715
+ 'normal' => {
716
+ 'a' => 'b',
717
+ 'c' => { 'd' => 'e' },
718
+ 'x' => { 'y' => 2 },
719
+ 'tags' => [ 'a', 'b' ]
720
+ },
721
+ 'automatic' => { 'x' => 'y' },
722
+ 'chef_environment' => 'desert'
723
+ )
724
+ end
725
+
726
+ it 'chef_node with attribute [ c, e ], { a => 1 }, [ c, e ], { b => 2 } sets b only' do
727
+ run_recipe do
728
+ chef_node 'blah' do
729
+ attribute [ 'c', 'e' ], { 'a' => 1 }
730
+ attribute [ 'c', 'e' ], { 'b' => 2 }
731
+ end
732
+ end
733
+ expect(get('nodes/blah')).to include(
734
+ 'normal' => {
735
+ 'a' => 'b',
736
+ 'c' => { 'd' => 'e', 'e' => { 'b' => 2 } },
737
+ 'tags' => [ 'a', 'b' ]
738
+ },
739
+ 'automatic' => { 'x' => 'y' },
740
+ 'chef_environment' => 'desert'
741
+ )
742
+ end
743
+
744
+ it 'chef_node with attribute [ c, e ], { a => 1 }, [ c, e, b ], 2 sets both' do
745
+ run_recipe do
746
+ chef_node 'blah' do
747
+ attribute [ 'c', 'e' ], { 'a' => 1 }
748
+ attribute [ 'c', 'e', 'b' ], 2
749
+ end
750
+ end
751
+ expect(get('nodes/blah')).to include(
752
+ 'normal' => {
753
+ 'a' => 'b',
754
+ 'c' => { 'd' => 'e', 'e' => { 'a' => 1, 'b' => 2 } },
755
+ 'tags' => [ 'a', 'b' ]
756
+ },
757
+ 'automatic' => { 'x' => 'y' },
758
+ 'chef_environment' => 'desert'
759
+ )
760
+ end
761
+
762
+ it 'chef_node with attribute [ c, e, b ], 2, [ c, e ], { a => 1 } sets a only' do
763
+ run_recipe do
764
+ chef_node 'blah' do
765
+ attribute [ 'c', 'e', 'b' ], 2
766
+ attribute [ 'c', 'e' ], { 'a' => 1 }
767
+ end
768
+ end
769
+ expect(get('nodes/blah')).to include(
770
+ 'normal' => {
771
+ 'a' => 'b',
772
+ 'c' => { 'd' => 'e', 'e' => { 'a' => 1 } },
773
+ 'tags' => [ 'a', 'b' ]
774
+ },
775
+ 'automatic' => { 'x' => 'y' },
776
+ 'chef_environment' => 'desert'
777
+ )
778
+ end
779
+ end
191
780
  end
192
781
  end
193
-
194
782
  end
195
783
  end
196
784
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cheffish
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.1
4
+ version: 0.8.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Keiser
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-08 00:00:00.000000000 Z
11
+ date: 2014-09-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: chef