knife-essentials 0.9.2 → 0.9.3

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