cheffish 0.8.1 → 0.8.2

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