knife-essentials 0.9.2 → 0.9.3

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.
@@ -28,46 +28,59 @@ describe ChefFS::FileSystem::DataBagsDir do
28
28
  :client_key => 'key'
29
29
  }, 'everything')
30
30
  }
31
- let(:data_bags_dir) { root_dir.child('data_bags') }
32
- let(:should_list_data_bags) do
33
- @rest.should_receive(:get_rest).with('data').once.and_return(
34
- {
35
- "achild" => "http://opscode.com/achild",
36
- "bchild" => "http://opscode.com/bchild"
37
- })
38
- end
39
- before(:each) do
40
- @rest = double("rest")
41
- Chef::REST.stub(:new).with('url','username','key') { @rest }
42
- end
43
31
 
44
- it 'has / as parent' do
45
- data_bags_dir.parent.should == root_dir
46
- end
47
- it 'is a directory' do
48
- data_bags_dir.dir?.should be_true
49
- end
50
- it 'exists' do
51
- data_bags_dir.exists?.should be_true
52
- end
53
- it 'has name data_bags' do
54
- data_bags_dir.name.should == 'data_bags'
55
- end
56
- it 'has path /data_bags' do
57
- data_bags_dir.path.should == '/data_bags'
58
- end
59
- it 'has path_for_printing remote/data_bags' do
60
- data_bags_dir.path_for_printing.should == 'remote/data_bags'
32
+ let(:data_bags_dir) do
33
+ root_dir.child('data_bags').tap do |artifact|
34
+ artifact.stub(:chef_collection).and_return(chef_collection)
35
+ end
61
36
  end
62
- it 'has correct children' do
63
- should_list_data_bags
64
- data_bags_dir.children.map { |child| child.name }.should =~ %w(achild bchild)
37
+
38
+ let(:should_list_data_bags) { } # noop. Remove before committing
39
+
40
+ let(:chef_collection) do
41
+ {
42
+ "achild" => "http://opscode.com/achild",
43
+ "bchild" => "http://opscode.com/bchild"
44
+ }
65
45
  end
66
- it 'can have directories as children' do
67
- data_bags_dir.can_have_child?('blah', true).should be_true
46
+
47
+ let(:item_collection) do
48
+ {
49
+ "aitem" => "http://opscode.com/achild",
50
+ "bitem" => "http://opscode.com/bchild"
51
+ }
68
52
  end
69
- it 'cannot have files as children' do
70
- data_bags_dir.can_have_child?('blah', false).should be_false
53
+
54
+ context 'code contract' do
55
+
56
+ it 'has / as parent' do
57
+ data_bags_dir.parent.should == root_dir
58
+ end
59
+ it 'is a directory' do
60
+ data_bags_dir.dir?.should be_true
61
+ end
62
+ it 'exists' do
63
+ data_bags_dir.exists?.should be_true
64
+ end
65
+ it 'has name data_bags' do
66
+ data_bags_dir.name.should == 'data_bags'
67
+ end
68
+ it 'has path /data_bags' do
69
+ data_bags_dir.path.should == '/data_bags'
70
+ end
71
+ it 'has path_for_printing remote/data_bags' do
72
+ data_bags_dir.path_for_printing.should == 'remote/data_bags'
73
+ end
74
+ it 'has correct children' do
75
+ should_list_data_bags
76
+ data_bags_dir.children.map { |child| child.name }.should =~ %w(achild bchild)
77
+ end
78
+ it 'can have directories as children' do
79
+ data_bags_dir.can_have_child?('blah', true).should be_true
80
+ end
81
+ it 'cannot have files as children' do
82
+ data_bags_dir.can_have_child?('blah', false).should be_false
83
+ end
71
84
  end
72
85
 
73
86
  shared_examples_for 'a data bag item' do
@@ -90,11 +103,14 @@ describe ChefFS::FileSystem::DataBagsDir do
90
103
  it 'has correct path_for_printing' do
91
104
  data_bag_item.path_for_printing.should == "remote/data_bags/#{data_bag_dir_name}/#{data_bag_item_name}"
92
105
  end
106
+
93
107
  it 'reads correctly' do
94
- @rest.should_receive(:get_rest).with("data/#{data_bag_dir_name}/#{data_bag_item_short_name}").once.and_return({
95
- 'a' => 'b'
96
- })
97
- data_bag_item.read.should == '{
108
+ data_bag_item.should_receive(:raw_request).
109
+ with("data/#{data_bag_dir_name}/#{data_bag_item_short_name}").
110
+ once.and_return({'a' => 'b'}.to_json)
111
+
112
+ data_bag_item.read.should ==
113
+ '{
98
114
  "id": "aitem",
99
115
  "a": "b"
100
116
  }'
@@ -102,13 +118,8 @@ describe ChefFS::FileSystem::DataBagsDir do
102
118
  end
103
119
 
104
120
  shared_examples_for 'a data bag' do
105
- let(:should_list_data_bag_items) do
106
- @rest.should_receive(:get_rest).with("data/#{data_bag_dir_name}").once.and_return(
107
- {
108
- "aitem" => "http://opscode.com/achild",
109
- "bitem" => "http://opscode.com/bchild"
110
- })
111
- end
121
+ let(:should_list_data_bag_items) { data_bag_dir.should_receive(:chef_collection).once.and_return(item_collection) }
122
+
112
123
  it 'has /data as a parent' do
113
124
  data_bag_dir.parent.should == data_bags_dir
114
125
  end
@@ -174,7 +185,11 @@ describe ChefFS::FileSystem::DataBagsDir do
174
185
  nonexistent_child.dir?.should be_false
175
186
  end
176
187
  it 'read returns NotFoundError' do
177
- @rest.should_receive(:get_rest).with("data/#{data_bag_dir_name}/blah").once.and_raise(Net::HTTPServerException.new(nil,Net::HTTPResponse.new(nil,'404',nil)))
188
+ nonexistent_child.should_receive(:raw_request).
189
+ with("data/#{data_bag_dir_name}/blah").
190
+ once.
191
+ and_raise(Net::HTTPServerException.new(nil,Net::HTTPResponse.new(nil,'404',nil)))
192
+
178
193
  expect { nonexistent_child.read }.to raise_error(ChefFS::FileSystem::NotFoundError)
179
194
  end
180
195
  end
@@ -182,7 +197,6 @@ describe ChefFS::FileSystem::DataBagsDir do
182
197
 
183
198
  context 'achild from data_bags.children' do
184
199
  let(:data_bag_dir) do
185
- should_list_data_bags
186
200
  data_bags_dir.children.select { |child| child.name == 'achild' }.first
187
201
  end
188
202
  let(:data_bag_dir_name) { 'achild' }
@@ -16,9 +16,9 @@ describe 'knife deps' do
16
16
  when_the_repository 'has a role with a default run_list' do
17
17
  file 'roles/starring.json', { 'run_list' => %w(role[minor] recipe[quiche] recipe[soup::chicken]) }
18
18
  file 'roles/minor.json', {}
19
- file 'cookbooks/quiche/metadata.rb', ''
19
+ file 'cookbooks/quiche/metadata.rb', 'name "quiche"'
20
20
  file 'cookbooks/quiche/recipes/default.rb', ''
21
- file 'cookbooks/soup/metadata.rb', ''
21
+ file 'cookbooks/soup/metadata.rb', 'name "soup"'
22
22
  file 'cookbooks/soup/recipes/chicken.rb', ''
23
23
  it 'knife deps reports all dependencies' do
24
24
  knife('deps /roles/starring.json').should_succeed <<EOM
@@ -33,9 +33,9 @@ EOM
33
33
  when_the_repository 'has a role with an env_run_list' do
34
34
  file 'roles/starring.json', { 'env_run_lists' => { 'desert' => %w(role[minor] recipe[quiche] recipe[soup::chicken]) } }
35
35
  file 'roles/minor.json', {}
36
- file 'cookbooks/quiche/metadata.rb', ''
36
+ file 'cookbooks/quiche/metadata.rb', 'name "quiche"'
37
37
  file 'cookbooks/quiche/recipes/default.rb', ''
38
- file 'cookbooks/soup/metadata.rb', ''
38
+ file 'cookbooks/soup/metadata.rb', 'name "soup"'
39
39
  file 'cookbooks/soup/recipes/chicken.rb', ''
40
40
  it 'knife deps reports all dependencies' do
41
41
  knife('deps /roles/starring.json').should_succeed <<EOM
@@ -62,9 +62,9 @@ EOM
62
62
  end
63
63
  when_the_repository 'has a node with roles and recipes in its run_list' do
64
64
  file 'roles/minor.json', {}
65
- file 'cookbooks/quiche/metadata.rb', ''
65
+ file 'cookbooks/quiche/metadata.rb', 'name "quiche"'
66
66
  file 'cookbooks/quiche/recipes/default.rb', ''
67
- file 'cookbooks/soup/metadata.rb', ''
67
+ file 'cookbooks/soup/metadata.rb', 'name "soup"'
68
68
  file 'cookbooks/soup/recipes/chicken.rb', ''
69
69
  file 'nodes/mort.json', { 'run_list' => %w(role[minor] recipe[quiche] recipe[soup::chicken]) }
70
70
  it 'knife deps reports just the node' do
@@ -77,15 +77,15 @@ EOM
77
77
  end
78
78
  end
79
79
  when_the_repository 'has a cookbook with no dependencies' do
80
- file 'cookbooks/quiche/metadata.rb', ''
80
+ file 'cookbooks/quiche/metadata.rb', 'name "quiche"'
81
81
  file 'cookbooks/quiche/recipes/default.rb', ''
82
82
  it 'knife deps reports just the cookbook' do
83
83
  knife('deps /cookbooks/quiche').should_succeed "/cookbooks/quiche\n"
84
84
  end
85
85
  end
86
86
  when_the_repository 'has a cookbook with dependencies' do
87
- file 'cookbooks/kettle/metadata.rb', ''
88
- file 'cookbooks/quiche/metadata.rb', 'depends "kettle"'
87
+ file 'cookbooks/kettle/metadata.rb', 'name "kettle"'
88
+ file 'cookbooks/quiche/metadata.rb', "name 'quiche'\ndepends 'kettle'\n"
89
89
  file 'cookbooks/quiche/recipes/default.rb', ''
90
90
  it 'knife deps reports just the cookbook' do
91
91
  knife('deps /cookbooks/quiche').should_succeed "/cookbooks/kettle\n/cookbooks/quiche\n"
@@ -106,9 +106,9 @@ EOM
106
106
  when_the_repository 'has a deep dependency tree' do
107
107
  file 'roles/starring.json', { 'run_list' => %w(role[minor] recipe[quiche] recipe[soup::chicken]) }
108
108
  file 'roles/minor.json', {}
109
- file 'cookbooks/quiche/metadata.rb', ''
109
+ file 'cookbooks/quiche/metadata.rb', 'name "quiche"'
110
110
  file 'cookbooks/quiche/recipes/default.rb', ''
111
- file 'cookbooks/soup/metadata.rb', ''
111
+ file 'cookbooks/soup/metadata.rb', 'name "soup"'
112
112
  file 'cookbooks/soup/recipes/chicken.rb', ''
113
113
  file 'environments/desert.json', {}
114
114
  file 'nodes/mort.json', { 'chef_environment' => 'desert', 'run_list' => [ 'role[starring]' ] }
@@ -171,10 +171,10 @@ EOM
171
171
 
172
172
  context 'circular dependencies' do
173
173
  when_the_repository 'has cookbooks with circular dependencies' do
174
- file 'cookbooks/foo/metadata.rb', 'depends "bar"'
175
- file 'cookbooks/bar/metadata.rb', 'depends "baz"'
176
- file 'cookbooks/baz/metadata.rb', 'depends "foo"'
177
- file 'cookbooks/self/metadata.rb', 'depends "self"'
174
+ file 'cookbooks/foo/metadata.rb', "name 'foo'\ndepends 'bar'\n"
175
+ file 'cookbooks/bar/metadata.rb', "name 'bar'\ndepends 'baz'\n"
176
+ file 'cookbooks/baz/metadata.rb', "name 'baz'\ndepends 'foo'\n"
177
+ file 'cookbooks/self/metadata.rb', "name 'self'\ndepends 'self'\n"
178
178
  it 'knife deps prints each once' do
179
179
  knife('deps /cookbooks/foo /cookbooks/self').should_succeed <<EOM
180
180
  /cookbooks/baz
@@ -312,7 +312,7 @@ EOM
312
312
  end
313
313
  end
314
314
  when_the_repository 'has a cookbook' do
315
- file 'cookbooks/blah/metadata.rb', ''
315
+ file 'cookbooks/blah/metadata.rb', 'name "blah"'
316
316
  it 'knife deps on a cookbook file shows no dependencies' do
317
317
  knife('deps /cookbooks/blah/metadata.rb').should_succeed(
318
318
  "/cookbooks/blah/metadata.rb\n"
@@ -333,8 +333,8 @@ EOM
333
333
  when_the_chef_server 'has a role with a default run_list' do
334
334
  role 'starring', { 'run_list' => %w(role[minor] recipe[quiche] recipe[soup::chicken]) }
335
335
  role 'minor', {}
336
- cookbook 'quiche', '1.0.0', { 'metadata.rb' => '', 'recipes' => { 'default.rb' => '' } }
337
- cookbook 'soup', '1.0.0', { 'metadata.rb' => '', 'recipes' => { 'chicken.rb' => '' } }
336
+ cookbook 'quiche', '1.0.0', { 'metadata.rb' => "name 'quiche'\nversion '1.0.0'\n", 'recipes' => { 'default.rb' => '' } }
337
+ cookbook 'soup', '1.0.0', { 'metadata.rb' => "name 'soup'\nversion '1.0.0'\n", 'recipes' => { 'chicken.rb' => '' } }
338
338
  it 'knife deps reports all dependencies' do
339
339
  knife('deps --remote /roles/starring.json').should_succeed <<EOM
340
340
  /roles/minor.json
@@ -348,8 +348,8 @@ EOM
348
348
  when_the_chef_server 'has a role with an env_run_list' do
349
349
  role 'starring', { 'env_run_lists' => { 'desert' => %w(role[minor] recipe[quiche] recipe[soup::chicken]) } }
350
350
  role 'minor', {}
351
- cookbook 'quiche', '1.0.0', { 'metadata.rb' => '', 'recipes' => { 'default.rb' => '' } }
352
- cookbook 'soup', '1.0.0', { 'metadata.rb' => '', 'recipes' => { 'chicken.rb' => '' } }
351
+ cookbook 'quiche', '1.0.0', { 'metadata.rb' => "name 'quiche'\nversion '1.0.0'\n", 'recipes' => { 'default.rb' => '' } }
352
+ cookbook 'soup', '1.0.0', { 'metadata.rb' => "name 'soup'\nversion '1.0.0'\n", 'recipes' => { 'chicken.rb' => '' } }
353
353
  it 'knife deps reports all dependencies' do
354
354
  knife('deps --remote /roles/starring.json').should_succeed <<EOM
355
355
  /roles/minor.json
@@ -375,8 +375,8 @@ EOM
375
375
  end
376
376
  when_the_chef_server 'has a node with roles and recipes in its run_list' do
377
377
  role 'minor', {}
378
- cookbook 'quiche', '1.0.0', { 'metadata.rb' => '', 'recipes' => { 'default.rb' => '' } }
379
- cookbook 'soup', '1.0.0', { 'metadata.rb' => '', 'recipes' => { 'chicken.rb' => '' } }
378
+ cookbook 'quiche', '1.0.0', { 'metadata.rb' => "name 'quiche'\nversion '1.0.0'\n", 'recipes' => { 'default.rb' => '' } }
379
+ cookbook 'soup', '1.0.0', { 'metadata.rb' => "name 'soup'\nversion '1.0.0'\n", 'recipes' => { 'chicken.rb' => '' } }
380
380
  node 'mort', { 'run_list' => %w(role[minor] recipe[quiche] recipe[soup::chicken]) }
381
381
  it 'knife deps reports just the node' do
382
382
  knife('deps --remote --repo-mode=everything /nodes/mort.json').should_succeed <<EOM
@@ -388,14 +388,14 @@ EOM
388
388
  end
389
389
  end
390
390
  when_the_chef_server 'has a cookbook with no dependencies' do
391
- cookbook 'quiche', '1.0.0', { 'metadata.rb' => '', 'recipes' => { 'default.rb' => '' } }
391
+ cookbook 'quiche', '1.0.0', { 'metadata.rb' => "name 'quiche'\nversion '1.0.0'\n", 'recipes' => { 'default.rb' => '' } }
392
392
  it 'knife deps reports just the cookbook' do
393
393
  knife('deps --remote /cookbooks/quiche').should_succeed "/cookbooks/quiche\n"
394
394
  end
395
395
  end
396
396
  when_the_chef_server 'has a cookbook with dependencies' do
397
- cookbook 'kettle', '1.0.0', { 'metadata.rb' => '' }
398
- cookbook 'quiche', '1.0.0', { 'metadata.rb' => 'depends "kettle"', 'recipes' => { 'default.rb' => '' } }
397
+ cookbook 'kettle', '1.0.0', { 'metadata.rb' => "name 'kettle'\nversion '1.0.0'\n" }
398
+ cookbook 'quiche', '1.0.0', { 'metadata.rb' => "name 'quiche'\ndepends 'kettle'\n", 'recipes' => { 'default.rb' => '' } }
399
399
  it 'knife deps reports just the cookbook' do
400
400
  knife('deps --remote /cookbooks/quiche').should_succeed "/cookbooks/kettle\n/cookbooks/quiche\n"
401
401
  end
@@ -415,8 +415,8 @@ EOM
415
415
  when_the_chef_server 'has a deep dependency tree' do
416
416
  role 'starring', { 'run_list' => %w(role[minor] recipe[quiche] recipe[soup::chicken]) }
417
417
  role 'minor', {}
418
- cookbook 'quiche', '1.0.0', { 'metadata.rb' => '', 'recipes' => { 'default.rb' => '' } }
419
- cookbook 'soup', '1.0.0', { 'metadata.rb' => '', 'recipes' => { 'chicken.rb' => '' } }
418
+ cookbook 'quiche', '1.0.0', { 'metadata.rb' => "name 'quiche'\nversion '1.0.0'\n", 'recipes' => { 'default.rb' => '' } }
419
+ cookbook 'soup', '1.0.0', { 'metadata.rb' => "name 'soup'\nversion '1.0.0'\n", 'recipes' => { 'chicken.rb' => '' } }
420
420
  environment 'desert', {}
421
421
  node 'mort', { 'chef_environment' => 'desert', 'run_list' => [ 'role[starring]' ] }
422
422
  node 'bart', { 'run_list' => [ 'role[minor]' ] }
@@ -478,10 +478,10 @@ EOM
478
478
 
479
479
  context 'circular dependencies' do
480
480
  when_the_chef_server 'has cookbooks with circular dependencies' do
481
- cookbook 'foo', '1.0.0', { 'metadata.rb' => 'depends "bar"' }
482
- cookbook 'bar', '1.0.0', { 'metadata.rb' => 'depends "baz"' }
483
- cookbook 'baz', '1.0.0', { 'metadata.rb' => 'depends "foo"' }
484
- cookbook 'self', '1.0.0', { 'metadata.rb' => 'depends "self"' }
481
+ cookbook 'foo', '1.0.0', { 'metadata.rb' => "name 'foo'\ndepends 'bar'\n" }
482
+ cookbook 'bar', '1.0.0', { 'metadata.rb' => "name 'bar'\ndepends 'baz'\n" }
483
+ cookbook 'baz', '1.0.0', { 'metadata.rb' => "name 'baz'\ndepends 'foo'\n" }
484
+ cookbook 'self', '1.0.0', { 'metadata.rb' => "name 'self'\ndepends 'self'\n" }
485
485
  it 'knife deps prints each once' do
486
486
  knife('deps --remote /cookbooks/foo /cookbooks/self').should_succeed <<EOM
487
487
  /cookbooks/baz
@@ -615,7 +615,7 @@ EOM
615
615
  end
616
616
  end
617
617
  when_the_chef_server 'has a cookbook' do
618
- cookbook 'blah', '1.0.0', { 'metadata.rb' => '' }
618
+ cookbook 'blah', '1.0.0', { 'metadata.rb' => 'name "blah"' }
619
619
  it 'knife deps on a cookbook file shows no dependencies' do
620
620
  knife('deps --remote /cookbooks/blah/metadata.rb').should_succeed(
621
621
  "/cookbooks/blah/metadata.rb\n"
@@ -5,26 +5,27 @@ describe 'knife diff' do
5
5
  extend IntegrationSupport
6
6
  include KnifeSupport
7
7
 
8
- when_the_chef_server "has one of each thing" do
9
- client 'x', '{}'
10
- cookbook 'x', '1.0.0', { 'metadata.rb' => 'version "1.0.0"' }
11
- data_bag 'x', { 'y' => '{}' }
12
- environment 'x', '{}'
13
- node 'x', '{}'
14
- role 'x', '{}'
15
- user 'x', '{}'
16
-
17
- when_the_repository 'has only top-level directories' do
18
- directory 'clients'
19
- directory 'cookbooks'
20
- directory 'data_bags'
21
- directory 'environments'
22
- directory 'nodes'
23
- directory 'roles'
24
- directory 'users'
25
-
26
- it 'knife diff reports everything as deleted' do
27
- knife('diff --name-status /').should_succeed <<EOM
8
+ context 'without versioned cookbooks' do
9
+ when_the_chef_server "has one of each thing" do
10
+ client 'x', '{}'
11
+ cookbook 'x', '1.0.0', { 'metadata.rb' => 'version "1.0.0"' }
12
+ data_bag 'x', { 'y' => '{}' }
13
+ environment 'x', '{}'
14
+ node 'x', '{}'
15
+ role 'x', '{}'
16
+ user 'x', '{}'
17
+
18
+ when_the_repository 'has only top-level directories' do
19
+ directory 'clients'
20
+ directory 'cookbooks'
21
+ directory 'data_bags'
22
+ directory 'environments'
23
+ directory 'nodes'
24
+ directory 'roles'
25
+ directory 'users'
26
+
27
+ it 'knife diff reports everything as deleted' do
28
+ knife('diff --name-status /').should_succeed <<EOM
28
29
  D\t/cookbooks/x
29
30
  D\t/data_bags/x
30
31
  D\t/environments/_default.json
@@ -34,17 +35,17 @@ EOM
34
35
  end
35
36
  end
36
37
 
37
- when_the_repository 'has an identical copy of each thing' do
38
- file 'clients/x.json', <<EOM
38
+ when_the_repository 'has an identical copy of each thing' do
39
+ file 'clients/x.json', <<EOM
39
40
  {}
40
41
  EOM
41
- file 'cookbooks/x/metadata.rb', 'version "1.0.0"'
42
- file 'data_bags/x/y.json', <<EOM
42
+ file 'cookbooks/x/metadata.rb', 'version "1.0.0"'
43
+ file 'data_bags/x/y.json', <<EOM
43
44
  {
44
45
  "id": "y"
45
46
  }
46
47
  EOM
47
- file 'environments/_default.json', <<EOM
48
+ file 'environments/_default.json', <<EOM
48
49
  {
49
50
  "name": "_default",
50
51
  "description": "The default Chef environment",
@@ -58,7 +59,7 @@ EOM
58
59
  }
59
60
  }
60
61
  EOM
61
- file 'environments/x.json', <<EOM
62
+ file 'environments/x.json', <<EOM
62
63
  {
63
64
  "chef_type": "environment",
64
65
  "cookbook_versions": {
@@ -72,10 +73,10 @@ EOM
72
73
  }
73
74
  }
74
75
  EOM
75
- file 'nodes/x.json', <<EOM
76
+ file 'nodes/x.json', <<EOM
76
77
  {}
77
78
  EOM
78
- file 'roles/x.json', <<EOM
79
+ file 'roles/x.json', <<EOM
79
80
  {
80
81
  "chef_type": "role",
81
82
  "default_attributes": {
@@ -92,48 +93,48 @@ EOM
92
93
  ]
93
94
  }
94
95
  EOM
95
- file 'users/x.json', <<EOM
96
+ file 'users/x.json', <<EOM
96
97
  {}
97
98
  EOM
98
99
 
99
- it 'knife diff reports no differences' do
100
- knife('diff /').should_succeed ''
101
- end
100
+ it 'knife diff reports no differences' do
101
+ knife('diff /').should_succeed ''
102
+ end
102
103
 
103
- it 'knife diff /environments/nonexistent.json reports an error' do
104
- knife('diff /environments/nonexistent.json').should_fail "ERROR: /environments/nonexistent.json: No such file or directory on remote or local\n"
105
- end
104
+ it 'knife diff /environments/nonexistent.json reports an error' do
105
+ knife('diff /environments/nonexistent.json').should_fail "ERROR: /environments/nonexistent.json: No such file or directory on remote or local\n"
106
+ end
106
107
 
107
- it 'knife diff /environments/*.txt reports an error' do
108
- knife('diff /environments/*.txt').should_fail "ERROR: /environments/*.txt: No such file or directory on remote or local\n"
109
- end
108
+ it 'knife diff /environments/*.txt reports an error' do
109
+ knife('diff /environments/*.txt').should_fail "ERROR: /environments/*.txt: No such file or directory on remote or local\n"
110
+ end
110
111
 
111
- context 'except the role file' do
112
- file 'roles/x.json', <<EOM
112
+ context 'except the role file' do
113
+ file 'roles/x.json', <<EOM
113
114
  {
114
115
  "foo": "bar"
115
116
  }
116
117
  EOM
117
- it 'knife diff reports the role as different' do
118
- knife('diff --name-status /').should_succeed <<EOM
118
+ it 'knife diff reports the role as different' do
119
+ knife('diff --name-status /').should_succeed <<EOM
119
120
  M\t/roles/x.json
120
121
  EOM
122
+ end
121
123
  end
122
- end
123
124
 
124
- context 'as well as one extra copy of each thing' do
125
- file 'clients/y.json', {}
126
- file 'cookbooks/x/blah.rb', ''
127
- file 'cookbooks/y/metadata.rb', 'version "1.0.0"'
128
- file 'data_bags/x/z.json', {}
129
- file 'data_bags/y/zz.json', {}
130
- file 'environments/y.json', {}
131
- file 'nodes/y.json', {}
132
- file 'roles/y.json', {}
133
- file 'users/y.json', {}
134
-
135
- it 'knife diff reports the new files as added' do
136
- knife('diff --name-status /').should_succeed <<EOM
125
+ context 'as well as one extra copy of each thing' do
126
+ file 'clients/y.json', {}
127
+ file 'cookbooks/x/blah.rb', ''
128
+ file 'cookbooks/y/metadata.rb', 'version "1.0.0"'
129
+ file 'data_bags/x/z.json', {}
130
+ file 'data_bags/y/zz.json', {}
131
+ file 'environments/y.json', {}
132
+ file 'nodes/y.json', {}
133
+ file 'roles/y.json', {}
134
+ file 'users/y.json', {}
135
+
136
+ it 'knife diff reports the new files as added' do
137
+ knife('diff --name-status /').should_succeed <<EOM
137
138
  A\t/cookbooks/x/blah.rb
138
139
  A\t/cookbooks/y
139
140
  A\t/data_bags/x/z.json
@@ -141,160 +142,451 @@ A\t/data_bags/y
141
142
  A\t/environments/y.json
142
143
  A\t/roles/y.json
143
144
  EOM
144
- end
145
+ end
145
146
 
146
- context 'when cwd is the data_bags directory' do
147
- cwd 'data_bags'
148
- it 'knife diff reports different data bags' do
149
- knife('diff --name-status').should_succeed <<EOM
147
+ context 'when cwd is the data_bags directory' do
148
+ cwd 'data_bags'
149
+ it 'knife diff reports different data bags' do
150
+ knife('diff --name-status').should_succeed <<EOM
150
151
  A\tx/z.json
151
152
  A\ty
152
153
  EOM
153
- end
154
- it 'knife diff * reports different data bags' do
155
- knife('diff --name-status *').should_succeed <<EOM
154
+ end
155
+ it 'knife diff * reports different data bags' do
156
+ knife('diff --name-status *').should_succeed <<EOM
156
157
  A\tx/z.json
157
158
  A\ty
158
159
  EOM
160
+ end
159
161
  end
160
162
  end
161
163
  end
162
- end
163
164
 
164
- when_the_repository 'is empty' do
165
- it 'knife diff reports everything as deleted' do
166
- knife('diff --name-status /').should_succeed <<EOM
165
+ when_the_repository 'is empty' do
166
+ it 'knife diff reports everything as deleted' do
167
+ knife('diff --name-status /').should_succeed <<EOM
167
168
  D\t/cookbooks
168
169
  D\t/data_bags
169
170
  D\t/environments
170
171
  D\t/roles
171
172
  EOM
173
+ end
172
174
  end
173
175
  end
174
- end
175
176
 
176
- when_the_repository 'has a cookbook' do
177
- file 'cookbooks/x/metadata.rb', 'version "1.0.0"'
178
- file 'cookbooks/x/onlyin1.0.0.rb', ''
177
+ when_the_repository 'has a cookbook' do
178
+ file 'cookbooks/x/metadata.rb', 'version "1.0.0"'
179
+ file 'cookbooks/x/onlyin1.0.0.rb', ''
179
180
 
180
- when_the_chef_server 'has a later version for the cookbook' do
181
- cookbook 'x', '1.0.0', { 'metadata.rb' => 'version "1.0.0"', 'onlyin1.0.0.rb' => ''}
182
- cookbook 'x', '1.0.1', { 'metadata.rb' => 'version "1.0.1"', 'onlyin1.0.1.rb' => '' }
181
+ when_the_chef_server 'has a later version for the cookbook' do
182
+ cookbook 'x', '1.0.0', { 'metadata.rb' => 'version "1.0.0"', 'onlyin1.0.0.rb' => ''}
183
+ cookbook 'x', '1.0.1', { 'metadata.rb' => 'version "1.0.1"', 'onlyin1.0.1.rb' => '' }
183
184
 
184
- it 'knife diff /cookbooks/x shows differences' do
185
- knife('diff --name-status /cookbooks/x').should_succeed <<EOM
185
+ it 'knife diff /cookbooks/x shows differences' do
186
+ knife('diff --name-status /cookbooks/x').should_succeed <<EOM
186
187
  M\t/cookbooks/x/metadata.rb
187
188
  D\t/cookbooks/x/onlyin1.0.1.rb
188
189
  A\t/cookbooks/x/onlyin1.0.0.rb
189
190
  EOM
190
- end
191
+ end
191
192
 
192
- it 'knife diff --diff-filter=MAT does not show deleted files' do
193
- knife('diff --diff-filter=MAT --name-status /cookbooks/x').should_succeed <<EOM
193
+ it 'knife diff --diff-filter=MAT does not show deleted files' do
194
+ knife('diff --diff-filter=MAT --name-status /cookbooks/x').should_succeed <<EOM
194
195
  M\t/cookbooks/x/metadata.rb
195
196
  A\t/cookbooks/x/onlyin1.0.0.rb
196
197
  EOM
198
+ end
197
199
  end
198
- end
199
200
 
200
- when_the_chef_server 'has an earlier version for the cookbook' do
201
- cookbook 'x', '1.0.0', { 'metadata.rb' => 'version "1.0.0"', 'onlyin1.0.0.rb' => '' }
202
- cookbook 'x', '0.9.9', { 'metadata.rb' => 'version "0.9.9"', 'onlyin0.9.9.rb' => '' }
203
- it 'knife diff /cookbooks/x shows no differences' do
204
- knife('diff --name-status /cookbooks/x').should_succeed ''
201
+ when_the_chef_server 'has an earlier version for the cookbook' do
202
+ cookbook 'x', '1.0.0', { 'metadata.rb' => 'version "1.0.0"', 'onlyin1.0.0.rb' => '' }
203
+ cookbook 'x', '0.9.9', { 'metadata.rb' => 'version "0.9.9"', 'onlyin0.9.9.rb' => '' }
204
+ it 'knife diff /cookbooks/x shows no differences' do
205
+ knife('diff --name-status /cookbooks/x').should_succeed ''
206
+ end
205
207
  end
206
- end
207
208
 
208
- when_the_chef_server 'has a later version for the cookbook, and no current version' do
209
- cookbook 'x', '1.0.1', { 'metadata.rb' => 'version "1.0.1"', 'onlyin1.0.1.rb' => '' }
209
+ when_the_chef_server 'has a later version for the cookbook, and no current version' do
210
+ cookbook 'x', '1.0.1', { 'metadata.rb' => 'version "1.0.1"', 'onlyin1.0.1.rb' => '' }
210
211
 
211
- it 'knife diff /cookbooks/x shows the differences' do
212
- knife('diff --name-status /cookbooks/x').should_succeed <<EOM
212
+ it 'knife diff /cookbooks/x shows the differences' do
213
+ knife('diff --name-status /cookbooks/x').should_succeed <<EOM
213
214
  M\t/cookbooks/x/metadata.rb
214
215
  D\t/cookbooks/x/onlyin1.0.1.rb
215
216
  A\t/cookbooks/x/onlyin1.0.0.rb
216
217
  EOM
218
+ end
217
219
  end
218
- end
219
220
 
220
- when_the_chef_server 'has an earlier version for the cookbook, and no current version' do
221
- cookbook 'x', '0.9.9', { 'metadata.rb' => 'version "0.9.9"', 'onlyin0.9.9.rb' => '' }
221
+ when_the_chef_server 'has an earlier version for the cookbook, and no current version' do
222
+ cookbook 'x', '0.9.9', { 'metadata.rb' => 'version "0.9.9"', 'onlyin0.9.9.rb' => '' }
222
223
 
223
- it 'knife diff /cookbooks/x shows the differences' do
224
- knife('diff --name-status /cookbooks/x').should_succeed <<EOM
224
+ it 'knife diff /cookbooks/x shows the differences' do
225
+ knife('diff --name-status /cookbooks/x').should_succeed <<EOM
225
226
  M\t/cookbooks/x/metadata.rb
226
227
  D\t/cookbooks/x/onlyin0.9.9.rb
227
228
  A\t/cookbooks/x/onlyin1.0.0.rb
228
229
  EOM
230
+ end
229
231
  end
230
232
  end
231
- end
232
233
 
233
- context 'json diff tests' do
234
- when_the_repository 'has an empty environment file' do
235
- file 'environments/x.json', {}
236
- when_the_chef_server 'has an empty environment' do
237
- environment 'x', {}
238
- it 'knife diff returns no differences' do
239
- knife('diff /environments/x.json').should_succeed ''
234
+ context 'json diff tests' do
235
+ when_the_repository 'has an empty environment file' do
236
+ file 'environments/x.json', {}
237
+ when_the_chef_server 'has an empty environment' do
238
+ environment 'x', {}
239
+ it 'knife diff returns no differences' do
240
+ knife('diff /environments/x.json').should_succeed ''
241
+ end
240
242
  end
241
- end
242
- when_the_chef_server 'has an environment with a different value' do
243
- environment 'x', { 'description' => 'hi' }
244
- it 'knife diff reports the difference', :pending => (RUBY_VERSION < "1.9") do
245
- knife('diff /environments/x.json').should_succeed(/
243
+ when_the_chef_server 'has an environment with a different value' do
244
+ environment 'x', { 'description' => 'hi' }
245
+ it 'knife diff reports the difference', :pending => (RUBY_VERSION < "1.9") do
246
+ knife('diff /environments/x.json').should_succeed(/
246
247
  {
247
248
  - "name": "x",
248
249
  - "description": "hi"
249
250
  \+ "name": "x"
250
251
  }
251
252
  /)
253
+ end
254
+ end
255
+ end
256
+
257
+ when_the_repository 'has an environment file with a value in it' do
258
+ file 'environments/x.json', { 'description' => 'hi' }
259
+ when_the_chef_server 'has an environment with the same value' do
260
+ environment 'x', { 'description' => 'hi' }
261
+ it 'knife diff returns no differences' do
262
+ knife('diff /environments/x.json').should_succeed ''
263
+ end
264
+ end
265
+ when_the_chef_server 'has an environment with no value' do
266
+ environment 'x', {}
267
+ it 'knife diff reports the difference', :pending => (RUBY_VERSION < "1.9") do
268
+ knife('diff /environments/x.json').should_succeed(/
269
+ {
270
+ - "name": "x"
271
+ \+ "name": "x",
272
+ \+ "description": "hi"
273
+ }
274
+ /)
275
+ end
276
+ end
277
+ when_the_chef_server 'has an environment with a different value' do
278
+ environment 'x', { 'description' => 'lo' }
279
+ it 'knife diff reports the difference', :pending => (RUBY_VERSION < "1.9") do
280
+ knife('diff /environments/x.json').should_succeed(/
281
+ {
282
+ "name": "x",
283
+ - "description": "lo"
284
+ \+ "description": "hi"
285
+ }
286
+ /)
287
+ end
252
288
  end
253
289
  end
254
290
  end
255
291
 
256
- when_the_repository 'has an environment file with a value in it' do
257
- file 'environments/x.json', { 'description' => 'hi' }
258
- when_the_chef_server 'has an environment with the same value' do
259
- environment 'x', { 'description' => 'hi' }
260
- it 'knife diff returns no differences' do
261
- knife('diff /environments/x.json').should_succeed ''
292
+ when_the_chef_server 'has an environment' do
293
+ environment 'x', {}
294
+ when_the_repository 'has an environment with bad JSON' do
295
+ file 'environments/x.json', '{'
296
+ it 'knife diff reports an error and does a textual diff' do
297
+ knife('diff /environments/x.json').should_succeed(/- "name": "x"/, :stderr => "WARN: Parse error reading #{path_to('environments/x.json')} as JSON: A JSON text must at least contain two octets!\n")
262
298
  end
263
299
  end
264
- when_the_chef_server 'has an environment with no value' do
265
- environment 'x', {}
266
- it 'knife diff reports the difference', :pending => (RUBY_VERSION < "1.9") do
267
- knife('diff /environments/x.json').should_succeed(/
300
+ end
301
+ end # without versioned cookbooks
302
+
303
+ with_versioned_cookbooks do
304
+ when_the_chef_server "has one of each thing" do
305
+ client 'x', '{}'
306
+ cookbook 'x', '1.0.0', { 'metadata.rb' => 'version "1.0.0"' }
307
+ data_bag 'x', { 'y' => '{}' }
308
+ environment 'x', '{}'
309
+ node 'x', '{}'
310
+ role 'x', '{}'
311
+ user 'x', '{}'
312
+
313
+ when_the_repository 'has only top-level directories' do
314
+ directory 'clients'
315
+ directory 'cookbooks'
316
+ directory 'data_bags'
317
+ directory 'environments'
318
+ directory 'nodes'
319
+ directory 'roles'
320
+ directory 'users'
321
+
322
+ it 'knife diff reports everything as deleted' do
323
+ knife('diff --name-status /').should_succeed <<EOM
324
+ D\t/cookbooks/x-1.0.0
325
+ D\t/data_bags/x
326
+ D\t/environments/_default.json
327
+ D\t/environments/x.json
328
+ D\t/roles/x.json
329
+ EOM
330
+ end
331
+ end
332
+
333
+ when_the_repository 'has an identical copy of each thing' do
334
+ file 'clients/x.json', <<EOM
335
+ {}
336
+ EOM
337
+ file 'cookbooks/x-1.0.0/metadata.rb', 'version "1.0.0"'
338
+ file 'data_bags/x/y.json', <<EOM
339
+ {
340
+ "id": "y"
341
+ }
342
+ EOM
343
+ file 'environments/_default.json', <<EOM
344
+ {
345
+ "name": "_default",
346
+ "description": "The default Chef environment",
347
+ "cookbook_versions": {
348
+ },
349
+ "json_class": "Chef::Environment",
350
+ "chef_type": "environment",
351
+ "default_attributes": {
352
+ },
353
+ "override_attributes": {
354
+ }
355
+ }
356
+ EOM
357
+ file 'environments/x.json', <<EOM
358
+ {
359
+ "chef_type": "environment",
360
+ "cookbook_versions": {
361
+ },
362
+ "default_attributes": {
363
+ },
364
+ "description": "",
365
+ "json_class": "Chef::Environment",
366
+ "name": "x",
367
+ "override_attributes": {
368
+ }
369
+ }
370
+ EOM
371
+ file 'nodes/x.json', <<EOM
372
+ {}
373
+ EOM
374
+ file 'roles/x.json', <<EOM
375
+ {
376
+ "chef_type": "role",
377
+ "default_attributes": {
378
+ },
379
+ "description": "",
380
+ "env_run_lists": {
381
+ },
382
+ "json_class": "Chef::Role",
383
+ "name": "x",
384
+ "override_attributes": {
385
+ },
386
+ "run_list": [
387
+
388
+ ]
389
+ }
390
+ EOM
391
+ file 'users/x.json', <<EOM
392
+ {}
393
+ EOM
394
+
395
+ it 'knife diff reports no differences' do
396
+ knife('diff /').should_succeed ''
397
+ end
398
+
399
+ it 'knife diff /environments/nonexistent.json reports an error' do
400
+ knife('diff /environments/nonexistent.json').should_fail "ERROR: /environments/nonexistent.json: No such file or directory on remote or local\n"
401
+ end
402
+
403
+ it 'knife diff /environments/*.txt reports an error' do
404
+ knife('diff /environments/*.txt').should_fail "ERROR: /environments/*.txt: No such file or directory on remote or local\n"
405
+ end
406
+
407
+ context 'except the role file' do
408
+ file 'roles/x.json', <<EOM
409
+ {
410
+ "foo": "bar"
411
+ }
412
+ EOM
413
+ it 'knife diff reports the role as different' do
414
+ knife('diff --name-status /').should_succeed <<EOM
415
+ M\t/roles/x.json
416
+ EOM
417
+ end
418
+ end
419
+
420
+ context 'as well as one extra copy of each thing' do
421
+ file 'clients/y.json', {}
422
+ file 'cookbooks/x-1.0.0/blah.rb', ''
423
+ file 'cookbooks/x-2.0.0/metadata.rb', 'version "2.0.0"'
424
+ file 'cookbooks/y-1.0.0/metadata.rb', 'version "1.0.0"'
425
+ file 'data_bags/x/z.json', {}
426
+ file 'data_bags/y/zz.json', {}
427
+ file 'environments/y.json', {}
428
+ file 'nodes/y.json', {}
429
+ file 'roles/y.json', {}
430
+ file 'users/y.json', {}
431
+
432
+ it 'knife diff reports the new files as added' do
433
+ knife('diff --name-status /').should_succeed <<EOM
434
+ A\t/cookbooks/x-1.0.0/blah.rb
435
+ A\t/cookbooks/x-2.0.0
436
+ A\t/cookbooks/y-1.0.0
437
+ A\t/data_bags/x/z.json
438
+ A\t/data_bags/y
439
+ A\t/environments/y.json
440
+ A\t/roles/y.json
441
+ EOM
442
+ end
443
+
444
+ context 'when cwd is the data_bags directory' do
445
+ cwd 'data_bags'
446
+ it 'knife diff reports different data bags' do
447
+ knife('diff --name-status').should_succeed <<EOM
448
+ A\tx/z.json
449
+ A\ty
450
+ EOM
451
+ end
452
+ it 'knife diff * reports different data bags' do
453
+ knife('diff --name-status *').should_succeed <<EOM
454
+ A\tx/z.json
455
+ A\ty
456
+ EOM
457
+ end
458
+ end
459
+ end
460
+ end
461
+
462
+ when_the_repository 'is empty' do
463
+ it 'knife diff reports everything as deleted' do
464
+ knife('diff --name-status /').should_succeed <<EOM
465
+ D\t/cookbooks
466
+ D\t/data_bags
467
+ D\t/environments
468
+ D\t/roles
469
+ EOM
470
+ end
471
+ end
472
+ end
473
+
474
+ when_the_repository 'has a cookbook' do
475
+ file 'cookbooks/x-1.0.0/metadata.rb', 'version "1.0.0"'
476
+ file 'cookbooks/x-1.0.0/onlyin1.0.0.rb', ''
477
+
478
+ when_the_chef_server 'has a later version for the cookbook' do
479
+ cookbook 'x', '1.0.0', { 'metadata.rb' => 'version "1.0.0"', 'onlyin1.0.0.rb' => ''}
480
+ cookbook 'x', '1.0.1', { 'metadata.rb' => 'version "1.0.1"', 'onlyin1.0.1.rb' => '' }
481
+
482
+ it 'knife diff /cookbooks shows differences' do
483
+ knife('diff --name-status /cookbooks').should_succeed <<EOM
484
+ D\t/cookbooks/x-1.0.1
485
+ EOM
486
+ end
487
+
488
+ it 'knife diff --diff-filter=MAT does not show deleted files' do
489
+ knife('diff --diff-filter=MAT --name-status /cookbooks').should_succeed ''
490
+ end
491
+ end
492
+
493
+ when_the_chef_server 'has an earlier version for the cookbook' do
494
+ cookbook 'x', '1.0.0', { 'metadata.rb' => 'version "1.0.0"', 'onlyin1.0.0.rb' => '' }
495
+ cookbook 'x', '0.9.9', { 'metadata.rb' => 'version "0.9.9"', 'onlyin0.9.9.rb' => '' }
496
+ it 'knife diff /cookbooks shows the differences' do
497
+ knife('diff --name-status /cookbooks').should_succeed "D\t/cookbooks/x-0.9.9\n"
498
+ end
499
+ end
500
+
501
+ when_the_chef_server 'has a later version for the cookbook, and no current version' do
502
+ cookbook 'x', '1.0.1', { 'metadata.rb' => 'version "1.0.1"', 'onlyin1.0.1.rb' => '' }
503
+
504
+ it 'knife diff /cookbooks shows the differences' do
505
+ knife('diff --name-status /cookbooks').should_succeed <<EOM
506
+ D\t/cookbooks/x-1.0.1
507
+ A\t/cookbooks/x-1.0.0
508
+ EOM
509
+ end
510
+ end
511
+
512
+ when_the_chef_server 'has an earlier version for the cookbook, and no current version' do
513
+ cookbook 'x', '0.9.9', { 'metadata.rb' => 'version "0.9.9"', 'onlyin0.9.9.rb' => '' }
514
+
515
+ it 'knife diff /cookbooks shows the differences' do
516
+ knife('diff --name-status /cookbooks').should_succeed <<EOM
517
+ D\t/cookbooks/x-0.9.9
518
+ A\t/cookbooks/x-1.0.0
519
+ EOM
520
+ end
521
+ end
522
+ end
523
+
524
+ context 'json diff tests' do
525
+ when_the_repository 'has an empty environment file' do
526
+ file 'environments/x.json', {}
527
+ when_the_chef_server 'has an empty environment' do
528
+ environment 'x', {}
529
+ it 'knife diff returns no differences' do
530
+ knife('diff /environments/x.json').should_succeed ''
531
+ end
532
+ end
533
+ when_the_chef_server 'has an environment with a different value' do
534
+ environment 'x', { 'description' => 'hi' }
535
+ it 'knife diff reports the difference', :pending => (RUBY_VERSION < "1.9") do
536
+ knife('diff /environments/x.json').should_succeed(/
537
+ {
538
+ - "name": "x",
539
+ - "description": "hi"
540
+ \+ "name": "x"
541
+ }
542
+ /)
543
+ end
544
+ end
545
+ end
546
+
547
+ when_the_repository 'has an environment file with a value in it' do
548
+ file 'environments/x.json', { 'description' => 'hi' }
549
+ when_the_chef_server 'has an environment with the same value' do
550
+ environment 'x', { 'description' => 'hi' }
551
+ it 'knife diff returns no differences' do
552
+ knife('diff /environments/x.json').should_succeed ''
553
+ end
554
+ end
555
+ when_the_chef_server 'has an environment with no value' do
556
+ environment 'x', {}
557
+ it 'knife diff reports the difference', :pending => (RUBY_VERSION < "1.9") do
558
+ knife('diff /environments/x.json').should_succeed(/
268
559
  {
269
560
  - "name": "x"
270
561
  \+ "name": "x",
271
562
  \+ "description": "hi"
272
563
  }
273
564
  /)
565
+ end
274
566
  end
275
- end
276
- when_the_chef_server 'has an environment with a different value' do
277
- environment 'x', { 'description' => 'lo' }
278
- it 'knife diff reports the difference', :pending => (RUBY_VERSION < "1.9") do
279
- knife('diff /environments/x.json').should_succeed(/
567
+ when_the_chef_server 'has an environment with a different value' do
568
+ environment 'x', { 'description' => 'lo' }
569
+ it 'knife diff reports the difference', :pending => (RUBY_VERSION < "1.9") do
570
+ knife('diff /environments/x.json').should_succeed(/
280
571
  {
281
572
  "name": "x",
282
573
  - "description": "lo"
283
574
  \+ "description": "hi"
284
575
  }
285
576
  /)
577
+ end
286
578
  end
287
579
  end
288
580
  end
289
- end
290
-
291
- when_the_chef_server 'has an environment' do
292
- environment 'x', {}
293
- when_the_repository 'has an environment with bad JSON' do
294
- file 'environments/x.json', '{'
295
- it 'knife diff reports an error and does a textual diff' do
296
- knife('diff /environments/x.json').should_succeed(/- "name": "x"/, :stderr => "WARN: Parse error reading #{path_to('environments/x.json')} as JSON: A JSON text must at least contain two octets!\n")
581
+
582
+ when_the_chef_server 'has an environment' do
583
+ environment 'x', {}
584
+ when_the_repository 'has an environment with bad JSON' do
585
+ file 'environments/x.json', '{'
586
+ it 'knife diff reports an error and does a textual diff' do
587
+ knife('diff /environments/x.json').should_succeed(/- "name": "x"/, :stderr => "WARN: Parse error reading #{path_to('environments/x.json')} as JSON: A JSON text must at least contain two octets!\n")
588
+ end
297
589
  end
298
590
  end
299
- end
591
+ end # without versioned cookbooks
300
592
  end