berkshelf 1.4.6 → 2.0.0.beta

Sign up to get free protection for your applications and to get access to all the features.
Files changed (96) hide show
  1. data/.gitignore +1 -0
  2. data/CHANGELOG.md +1 -5
  3. data/CONTRIBUTING.md +3 -1
  4. data/Gemfile +11 -1
  5. data/README.md +16 -0
  6. data/Thorfile +3 -1
  7. data/berkshelf.gemspec +26 -38
  8. data/features/apply_command.feature +32 -0
  9. data/features/configure_command.feature +31 -0
  10. data/features/contingent_command.feature +5 -5
  11. data/features/default_locations.feature +2 -2
  12. data/features/groups_install.feature +19 -20
  13. data/features/info_command.feature +13 -13
  14. data/features/install_command.feature +86 -83
  15. data/features/json_formatter.feature +60 -23
  16. data/features/list_command.feature +5 -11
  17. data/features/lockfile.feature +286 -6
  18. data/features/open_command.feature +8 -4
  19. data/features/outdated_command.feature +8 -15
  20. data/features/package_command.feature +39 -0
  21. data/features/show_command.feature +8 -9
  22. data/features/step_definitions/chef_server_steps.rb +20 -2
  23. data/features/step_definitions/cli_steps.rb +10 -2
  24. data/features/step_definitions/configure_cli_steps.rb +7 -0
  25. data/features/step_definitions/filesystem_steps.rb +19 -14
  26. data/features/step_definitions/json_steps.rb +22 -5
  27. data/features/step_definitions/utility_steps.rb +13 -1
  28. data/features/support/env.rb +10 -23
  29. data/features/update_command.feature +105 -24
  30. data/features/upload_command.feature +0 -14
  31. data/features/vendor_install.feature +3 -3
  32. data/generator_files/Vagrantfile.erb +11 -11
  33. data/lib/berkshelf.rb +6 -5
  34. data/lib/berkshelf/berksfile.rb +267 -99
  35. data/lib/berkshelf/cli.rb +70 -34
  36. data/lib/berkshelf/cli_commands/test_command.rb +11 -0
  37. data/lib/berkshelf/community_rest.rb +1 -1
  38. data/lib/berkshelf/config.rb +19 -2
  39. data/lib/berkshelf/cookbook_source.rb +41 -12
  40. data/lib/berkshelf/cookbook_store.rb +8 -4
  41. data/lib/berkshelf/errors.rb +61 -29
  42. data/lib/berkshelf/formatters.rb +13 -19
  43. data/lib/berkshelf/formatters/human_readable.rb +8 -0
  44. data/lib/berkshelf/formatters/json.rb +12 -1
  45. data/lib/berkshelf/formatters/null.rb +23 -0
  46. data/lib/berkshelf/init_generator.rb +22 -11
  47. data/lib/berkshelf/location.rb +8 -10
  48. data/lib/berkshelf/locations/chef_api_location.rb +4 -5
  49. data/lib/berkshelf/locations/git_location.rb +14 -12
  50. data/lib/berkshelf/locations/path_location.rb +16 -1
  51. data/lib/berkshelf/locations/site_location.rb +1 -3
  52. data/lib/berkshelf/lockfile.rb +230 -33
  53. data/lib/berkshelf/resolver.rb +2 -1
  54. data/lib/berkshelf/ui.rb +4 -8
  55. data/lib/berkshelf/version.rb +1 -1
  56. data/lib/thor/monkies/shell.rb +2 -5
  57. data/spec/fixtures/cassettes/Berkshelf_Resolver/{ClassMethods/_initialize → _initialize}/adds_the_dependencies_of_the_source_as_sources.yml +0 -0
  58. data/spec/fixtures/cookbooks/example_cookbook/.gitignore +2 -0
  59. data/spec/fixtures/cookbooks/example_cookbook/.kitchen.yml +26 -0
  60. data/spec/fixtures/cookbooks/example_cookbook/Berksfile.lock +5 -0
  61. data/spec/fixtures/lockfiles/default.lock +11 -0
  62. data/spec/{config/knife.rb → knife.rb.sample} +2 -2
  63. data/spec/spec_helper.rb +15 -3
  64. data/spec/support/chef_api.rb +19 -5
  65. data/spec/support/chef_server.rb +4 -3
  66. data/spec/support/knife.rb +18 -0
  67. data/spec/unit/berkshelf/berksfile_spec.rb +332 -235
  68. data/spec/unit/berkshelf/cached_cookbook_spec.rb +40 -42
  69. data/spec/unit/berkshelf/chef/cookbook/chefignore_spec.rb +11 -15
  70. data/spec/unit/berkshelf/community_rest_spec.rb +16 -14
  71. data/spec/unit/berkshelf/config_spec.rb +36 -20
  72. data/spec/unit/berkshelf/cookbook_generator_spec.rb +6 -10
  73. data/spec/unit/berkshelf/cookbook_source_spec.rb +244 -183
  74. data/spec/unit/berkshelf/cookbook_store_spec.rb +72 -76
  75. data/spec/unit/berkshelf/core_ext/file_utils_spec.rb +2 -2
  76. data/spec/unit/berkshelf/downloader_spec.rb +137 -157
  77. data/spec/unit/berkshelf/errors_spec.rb +1 -1
  78. data/spec/unit/berkshelf/formatters/null_spec.rb +17 -0
  79. data/spec/unit/berkshelf/formatters_spec.rb +83 -90
  80. data/spec/unit/berkshelf/git_spec.rb +219 -207
  81. data/spec/unit/berkshelf/init_generator_spec.rb +73 -73
  82. data/spec/unit/berkshelf/location_spec.rb +143 -162
  83. data/spec/unit/berkshelf/locations/chef_api_location_spec.rb +94 -89
  84. data/spec/unit/berkshelf/locations/git_location_spec.rb +75 -59
  85. data/spec/unit/berkshelf/locations/path_location_spec.rb +46 -30
  86. data/spec/unit/berkshelf/locations/site_location_spec.rb +4 -4
  87. data/spec/unit/berkshelf/lockfile_spec.rb +185 -1
  88. data/spec/unit/berkshelf/logger_spec.rb +6 -24
  89. data/spec/unit/berkshelf/mixin/logging_spec.rb +6 -8
  90. data/spec/unit/berkshelf/resolver_spec.rb +36 -38
  91. data/spec/unit/berkshelf/ui_spec.rb +9 -10
  92. data/spec/unit/berkshelf_spec.rb +41 -40
  93. data/spec/unit/chef/config_spec.rb +9 -11
  94. metadata +55 -203
  95. data/spec/config/berkshelf.pem +0 -27
  96. data/spec/config/validator.pem +0 -27
@@ -1,192 +1,192 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Berkshelf::InitGenerator, vcr: { record: :new_episodes, serialize_with: :json } do
4
- subject { described_class }
5
-
6
4
  let(:target) { tmp_path.join("some_cookbook") }
7
5
  let(:resolver) { double('resolver') }
8
6
 
9
- context "with default options" do
10
- before(:each) do
7
+ context 'with default options' do
8
+ before do
11
9
  capture(:stdout) {
12
- subject.new([target]).invoke_all
10
+ Berkshelf::InitGenerator.new([target]).invoke_all
13
11
  }
14
12
  end
15
13
 
16
14
  specify do
17
- target.should have_structure {
18
- file ".gitignore"
19
- file "Berksfile"
20
- file "Gemfile" do
15
+ expect(target).to have_structure {
16
+ file '.gitignore'
17
+ file 'Berksfile'
18
+ file 'Gemfile' do
21
19
  contains "gem 'berkshelf'"
22
20
  end
23
- file "Vagrantfile" do
24
- contains "recipe[some_cookbook::default]"
21
+ file 'Vagrantfile' do
22
+ contains 'recipe[some_cookbook::default]'
25
23
  end
26
- no_file "chefignore"
24
+ no_file 'chefignore'
27
25
  }
28
26
  end
29
27
  end
30
28
 
31
- context "with a chefignore" do
29
+ context 'with a chefignore' do
32
30
  before(:each) do
33
31
  capture(:stdout) {
34
- subject.new([target], chefignore: true).invoke_all
32
+ Berkshelf::InitGenerator.new([target], chefignore: true).invoke_all
35
33
  }
36
34
  end
37
35
 
38
36
  specify do
39
- target.should have_structure {
40
- file "Berksfile"
41
- file "chefignore"
37
+ expect(target).to have_structure {
38
+ file 'Berksfile'
39
+ file 'chefignore'
42
40
  }
43
41
  end
44
42
  end
45
43
 
46
- context "with a metadata entry in the Berksfile" do
44
+ context 'with a metadata entry in the Berksfile' do
47
45
  before(:each) do
48
46
  Dir.mkdir target
49
- File.open(target.join("metadata.rb"), 'w+') do |f|
50
- f.write ""
47
+ File.open(target.join('metadata.rb'), 'w+') do |f|
48
+ f.write ''
51
49
  end
52
50
 
53
51
  capture(:stdout) {
54
- subject.new([target], metadata_entry: true).invoke_all
52
+ Berkshelf::InitGenerator.new([target], metadata_entry: true).invoke_all
55
53
  }
56
54
  end
57
55
 
58
56
  specify do
59
- target.should have_structure {
60
- file "Berksfile" do
61
- contains "metadata"
57
+ expect(target).to have_structure {
58
+ file 'Berksfile' do
59
+ contains 'metadata'
62
60
  end
63
61
  }
64
62
  end
65
63
  end
66
64
 
67
- context "with the foodcritic option true" do
65
+ context 'with the foodcritic option true' do
68
66
  before(:each) do
69
67
  capture(:stdout) {
70
- subject.new([target], foodcritic: true).invoke_all
68
+ Berkshelf::InitGenerator.new([target], foodcritic: true).invoke_all
71
69
  }
72
70
  end
73
71
 
74
72
  specify do
75
- target.should have_structure {
76
- file "Thorfile" do
73
+ expect(target).to have_structure {
74
+ file 'Thorfile' do
77
75
  contains "require 'thor/foodcritic'"
78
76
  end
79
- file "Gemfile" do
77
+ file 'Gemfile' do
80
78
  contains "gem 'thor-foodcritic'"
81
79
  end
82
80
  }
83
81
  end
84
82
  end
85
83
 
86
- context "with the scmversion option true" do
84
+ context 'with the scmversion option true' do
87
85
  before(:each) do
88
86
  capture(:stdout) {
89
- subject.new([target], scmversion: true).invoke_all
87
+ Berkshelf::InitGenerator.new([target], scmversion: true).invoke_all
90
88
  }
91
89
  end
92
90
 
93
91
  specify do
94
- target.should have_structure {
95
- file "Thorfile" do
92
+ expect(target).to have_structure {
93
+ file 'Thorfile' do
96
94
  contains "require 'thor/scmversion'"
97
95
  end
98
- file "Gemfile" do
96
+ file 'Gemfile' do
99
97
  contains "gem 'thor-scmversion'"
100
98
  end
101
99
  }
102
100
  end
103
101
  end
104
102
 
105
- context "with the bundler option true" do
103
+ context 'with the bundler option true' do
106
104
  before(:each) do
107
105
  capture(:stdout) {
108
- subject.new([target], no_bundler: true).invoke_all
106
+ Berkshelf::InitGenerator.new([target], no_bundler: true).invoke_all
109
107
  }
110
108
  end
111
109
 
112
110
  specify do
113
- target.should have_structure {
114
- no_file "Gemfile"
111
+ expect(target).to have_structure {
112
+ no_file 'Gemfile'
115
113
  }
116
114
  end
117
115
  end
118
116
 
119
- context "given a value for the cookbook_name option" do
120
- it "sets the value of cookbook_name attribute to the specified option" do
121
- generator = subject.new([target], cookbook_name: "nautilus")
117
+ context 'given a value for the cookbook_name option' do
118
+ it 'sets the value of cookbook_name attribute to the specified option' do
119
+ generator = Berkshelf::InitGenerator.new([target], cookbook_name: 'nautilus')
120
+ cookbook = generator.send(:cookbook_name)
122
121
 
123
- generator.send(:cookbook_name).should eql("nautilus")
122
+ expect(cookbook).to eq('nautilus')
124
123
  end
125
124
  end
126
125
 
127
- context "when no value for cookbook_name option is specified" do
128
- it "infers the name of the cookbook from the directory name" do
129
- generator = subject.new([target])
126
+ context 'when no value for cookbook_name option is specified' do
127
+ it 'infers the name of the cookbook from the directory name' do
128
+ generator = Berkshelf::InitGenerator.new([target])
129
+ cookbook = generator.send(:cookbook_name)
130
130
 
131
- generator.send(:cookbook_name).should eql("some_cookbook")
131
+ expect(cookbook).to eq('some_cookbook')
132
132
  end
133
133
  end
134
134
 
135
- context "when skipping git" do
135
+ context 'when skipping git' do
136
136
  before(:each) do
137
- generator = subject.new([target], skip_git: true)
137
+ generator = Berkshelf::InitGenerator.new([target], skip_git: true)
138
138
  capture(:stdout) { generator.invoke_all }
139
139
  end
140
140
 
141
- it "should not have a .git directory" do
142
- target.should_not have_structure {
143
- directory ".git"
141
+ it 'does not have a .git directory' do
142
+ expect(target).to_not have_structure {
143
+ directory '.git'
144
144
  }
145
145
  end
146
146
  end
147
147
 
148
- context "when skipping vagrant" do
148
+ context 'when skipping vagrant' do
149
149
  before(:each) do
150
150
  capture(:stdout) {
151
- subject.new([target], skip_vagrant: true).invoke_all
151
+ Berkshelf::InitGenerator.new([target], skip_vagrant: true).invoke_all
152
152
  }
153
153
  end
154
154
 
155
- it "should not have a Vagrantfile" do
156
- target.should have_structure {
157
- no_file "Vagrantfile"
155
+ it 'does not have a Vagrantfile' do
156
+ expect(target).to have_structure {
157
+ no_file 'Vagrantfile'
158
158
  }
159
159
  end
160
160
  end
161
161
 
162
- context "with the chef_minitest option true" do
162
+ context 'with the chef_minitest option true' do
163
163
  before(:each) do
164
164
  Berkshelf::Resolver.stub(:resolve) { resolver }
165
- pending "Runs fine with no mock for the HTTP call on the first pass, subsequent passes throw errors"
165
+ pending 'Runs fine with no mock for the HTTP call on the first pass, subsequent passes throw errors'
166
166
  capture(:stdout) {
167
- subject.new([target], chef_minitest: true).invoke_all
167
+ Berkshelf::InitGenerator.new([target], chef_minitest: true).invoke_all
168
168
  }
169
169
  end
170
170
 
171
171
  specify do
172
- target.should have_structure {
173
- file "Berksfile" do
174
- contains "cookbook \"minitest-handler\""
172
+ expect(target).to have_structure {
173
+ file 'Berksfile' do
174
+ contains "cookbook 'minitest-handler'"
175
175
  end
176
- file "Vagrantfile" do
177
- contains "\"recipe[minitest-handler::default]\""
176
+ file 'Vagrantfile' do
177
+ contains "'recipe[minitest-handler::default]'"
178
178
  end
179
- directory "files" do
180
- directory "default" do
181
- directory "tests" do
182
- directory "minitest" do
183
- file "default_test.rb" do
179
+ directory 'files' do
180
+ directory 'default' do
181
+ directory 'tests' do
182
+ directory 'minitest' do
183
+ file 'default_test.rb' do
184
184
  contains "describe 'some_cookbook::default' do"
185
- contains "include Helpers::Some_cookbook"
185
+ contains 'include Helpers::Some_cookbook'
186
186
  end
187
- directory "support" do
188
- file "helpers.rb" do
189
- contains "module Some_cookbook"
187
+ directory 'support' do
188
+ file 'helpers.rb' do
189
+ contains 'module Some_cookbook'
190
190
  end
191
191
  end
192
192
  end
@@ -1,208 +1,189 @@
1
1
  require 'spec_helper'
2
2
 
3
- module Berkshelf
4
- describe Location do
5
- describe "ClassMethods Module" do
6
- subject do
7
- Class.new do
8
- include Location
9
- end
10
- end
3
+ describe Berkshelf::Location do
4
+ # Since this is a module, we need to test the implementation via a class
5
+ let(:klass) { Class.new { include Berkshelf::Location } }
6
+
7
+ describe '.set_location_key' do
8
+ before do
9
+ @original = Berkshelf::CookbookSource.class_variable_get :@@location_keys
10
+ Berkshelf::CookbookSource.class_variable_set :@@location_keys, {}
11
+ end
11
12
 
12
- describe "::set_location_key" do
13
- before(:each) do
14
- @original = CookbookSource.class_variable_get :@@location_keys
15
- CookbookSource.class_variable_set :@@location_keys, {}
16
- end
13
+ after do
14
+ Berkshelf::CookbookSource.class_variable_set :@@location_keys, @original
15
+ end
17
16
 
18
- after(:each) do
19
- CookbookSource.class_variable_set :@@location_keys, @original
20
- end
17
+ it 'adds the given location key CookbookSource.location_keys' do
18
+ klass.set_location_key(:reset)
21
19
 
22
- it "adds the given location key with the includer's Class to CookbookSource.location_keys" do
23
- subject.set_location_key(:reset)
20
+ expect(Berkshelf::CookbookSource.location_keys).to have(1).item
21
+ expect(Berkshelf::CookbookSource.location_keys).to include(:reset)
22
+ expect(Berkshelf::CookbookSource.location_keys[:reset]).to eq(klass)
23
+ end
24
+ end
24
25
 
25
- CookbookSource.location_keys.should have(1).item
26
- CookbookSource.location_keys.should include(:reset)
27
- CookbookSource.location_keys[:reset].should eql(subject)
28
- end
29
- end
26
+ describe '.location_key' do
27
+ before do
28
+ @original = Berkshelf::CookbookSource.class_variable_get :@@location_keys
29
+ Berkshelf::CookbookSource.class_variable_set :@@location_keys, {}
30
+ end
30
31
 
31
- describe "::location_key" do
32
- before(:each) do
33
- @original = CookbookSource.class_variable_get :@@location_keys
34
- CookbookSource.class_variable_set :@@location_keys, {}
35
- end
32
+ after do
33
+ Berkshelf::CookbookSource.class_variable_set :@@location_keys, @original
34
+ end
36
35
 
37
- after(:each) do
38
- CookbookSource.class_variable_set :@@location_keys, @original
39
- end
36
+ it "returns the class' registered location key" do
37
+ klass.set_location_key(:reset)
38
+ expect(klass.location_key).to eq(:reset)
39
+ end
40
+ end
40
41
 
41
- it "returns the class' registered location key" do
42
- subject.set_location_key(:reset)
42
+ describe '.set_valid_options' do
43
+ before do
44
+ @original = Berkshelf::CookbookSource.class_variable_get :@@valid_options
45
+ Berkshelf::CookbookSource.class_variable_set :@@valid_options, []
46
+ end
43
47
 
44
- subject.location_key.should eql(:reset)
45
- end
46
- end
48
+ after do
49
+ Berkshelf::CookbookSource.class_variable_set :@@valid_options, @original
50
+ end
47
51
 
48
- describe "::set_valid_options" do
49
- before(:each) do
50
- @original = CookbookSource.class_variable_get :@@valid_options
51
- CookbookSource.class_variable_set :@@valid_options, []
52
- end
52
+ it 'adds the given symbol to the list of valid options on CookbookSource' do
53
+ klass.set_valid_options(:mundo)
53
54
 
54
- after(:each) do
55
- CookbookSource.class_variable_set :@@valid_options, @original
56
- end
55
+ expect(Berkshelf::CookbookSource.valid_options).to have(1).item
56
+ expect(Berkshelf::CookbookSource.valid_options).to include(:mundo)
57
+ end
57
58
 
58
- it "adds the given symbol to the list of valid options on CookbookSource" do
59
- subject.set_valid_options(:mundo)
59
+ it 'adds parameters to the list of valid options on the CookbookSource' do
60
+ klass.set_valid_options(:riot, :arenanet)
60
61
 
61
- CookbookSource.valid_options.should have(1).item
62
- CookbookSource.valid_options.should include(:mundo)
63
- end
62
+ expect(Berkshelf::CookbookSource.valid_options).to have(2).items
63
+ expect(Berkshelf::CookbookSource.valid_options).to include(:riot)
64
+ expect(Berkshelf::CookbookSource.valid_options).to include(:arenanet)
65
+ end
66
+ end
64
67
 
65
- it "adds parameters to the list of valid options on the CookbookSource" do
66
- subject.set_valid_options(:riot, :arenanet)
68
+ describe '.solve_for_constraint' do
69
+ let(:constraint) { '~> 0.101.2' }
70
+ let(:versions) do
71
+ {
72
+ '0.101.2' => 'http://cookbooks.opscode.com/api/v1/cookbooks/nginx/versions/0_101_2',
73
+ '0.101.0' => 'http://cookbooks.opscode.com/api/v1/cookbooks/nginx/versions/0_101_0',
74
+ '0.100.2' => 'http://cookbooks.opscode.com/api/v1/cookbooks/nginx/versions/0_100_2',
75
+ '0.100.0' => 'http://cookbooks.opscode.com/api/v1/cookbooks/nginx/versions/0_100_0'
76
+ }
77
+ end
67
78
 
68
- CookbookSource.valid_options.should have(2).items
69
- CookbookSource.valid_options.should include(:riot)
70
- CookbookSource.valid_options.should include(:arenanet)
71
- end
72
- end
79
+ it 'returns an array with a string containing the version of the solution at index 0' do
80
+ result = klass.solve_for_constraint(constraint, versions)
81
+ expect(result[0]).to eq('0.101.2')
82
+ end
73
83
 
74
- describe "::solve_for_constraint" do
75
- let(:constraint) { "~> 0.101.2" }
76
- let(:versions) do
77
- {
78
- "0.101.2" => "http://cookbooks.opscode.com/api/v1/cookbooks/nginx/versions/0_101_2",
79
- "0.101.0" => "http://cookbooks.opscode.com/api/v1/cookbooks/nginx/versions/0_101_0",
80
- "0.100.2" => "http://cookbooks.opscode.com/api/v1/cookbooks/nginx/versions/0_100_2",
81
- "0.100.0" => "http://cookbooks.opscode.com/api/v1/cookbooks/nginx/versions/0_100_0"
82
- }
83
- end
84
-
85
- it "returns an array with a string containing the version of the solution at index 0" do
86
- result = subject.solve_for_constraint(constraint, versions)
87
-
88
- result[0].should eql("0.101.2")
89
- end
90
-
91
- it "returns an array containing a URI at index 0" do
92
- result = subject.solve_for_constraint(constraint, versions)
93
-
94
- result[1].should match(URI.regexp)
95
- end
96
-
97
- it "should return the best match for the constraint and versions given" do
98
- subject.solve_for_constraint(constraint, versions)[0].to_s.should eql("0.101.2")
99
- end
100
-
101
- context "given a solution can not be found for constraint" do
102
- it "returns nil" do
103
- subject.solve_for_constraint(Solve::Constraint.new(">= 1.0"), versions).should be_nil
104
- end
105
- end
106
- end
84
+ it 'returns an array containing a URI at index 0' do
85
+ result = klass.solve_for_constraint(constraint, versions)
86
+ expect(result[1]).to match(URI.regexp)
107
87
  end
108
88
 
109
- describe "ModuleFunctions" do
110
- subject { Location }
89
+ it 'returns the best match for the constraint and versions given' do
90
+ expect(klass.solve_for_constraint(constraint, versions)[0].to_s).to eql('0.101.2')
91
+ end
111
92
 
112
- describe "::init" do
113
- let(:name) { "artifact" }
114
- let(:constraint) { double("constraint") }
93
+ context 'given a solution can not be found for constraint' do
94
+ it 'returns nil' do
95
+ result = klass.solve_for_constraint(Solve::Constraint.new('>= 1.0'), versions)
96
+ expect(result).to be_nil
97
+ end
98
+ end
99
+ end
115
100
 
116
- it "returns an instance of SiteLocation given a site: option key" do
117
- result = subject.init(name, constraint, site: "http://site/value")
101
+ describe ';init' do
102
+ let(:name) { 'artifact' }
103
+ let(:constraint) { double('constraint') }
118
104
 
119
- result.should be_a(SiteLocation)
120
- end
105
+ it 'returns an instance of SiteLocation given a site: option key' do
106
+ result = Berkshelf::Location.init(name, constraint, site: 'http://site/value')
107
+ expect(result).to be_a(Berkshelf::SiteLocation)
108
+ end
121
109
 
122
- it "returns an instance of PathLocation given a path: option key" do
123
- result = subject.init(name, constraint, path: "/Users/reset/code")
110
+ it 'returns an instance of PathLocation given a path: option key' do
111
+ result = Berkshelf::Location.init(name, constraint, path: '/Users/reset/code')
112
+ expect(result).to be_a(Berkshelf::PathLocation)
113
+ end
124
114
 
125
- result.should be_a(PathLocation)
126
- end
115
+ it 'returns an instance of GitLocation given a git: option key' do
116
+ result = Berkshelf::Location.init(name, constraint, git: 'git://github.com/something.git')
117
+ expect(result).to be_a(Berkshelf::GitLocation)
118
+ end
127
119
 
128
- it "returns an instance of GitLocation given a git: option key" do
129
- result = subject.init(name, constraint, git: "git://github.com/something.git")
120
+ it 'returns an instance of SiteLocation when no option key is given that matches a registered location_key' do
121
+ result = Berkshelf::Location.init(name, constraint)
122
+ expect(result).to be_a(Berkshelf::SiteLocation)
123
+ end
130
124
 
131
- result.should be_a(GitLocation)
132
- end
125
+ context 'given two location_keys' do
126
+ it 'raises an InternalError' do
127
+ expect {
128
+ Berkshelf::Location.init(name, constraint, git: :value, path: :value)
129
+ }.to raise_error(Berkshelf::InternalError)
130
+ end
131
+ end
132
+ end
133
133
 
134
- it "returns an instance of SiteLocation when no option key is given that matches a registered location_key" do
135
- result = subject.init(name, constraint)
136
134
 
137
- result.should be_a(SiteLocation)
138
- end
139
135
 
140
- context "given two location_keys" do
141
- it "raises an InternalError" do
142
- lambda {
143
- subject.init(name, constraint, git: :value, path: :value)
144
- }.should raise_error(InternalError)
145
- end
146
- end
147
- end
148
- end
136
+ let(:name) { 'nginx' }
137
+ let(:constraint) { double('constraint') }
149
138
 
150
- let(:name) { "nginx" }
151
- let(:constraint) { double('constraint') }
139
+ subject do
140
+ Class.new { include Berkshelf::Location }.new(name, constraint)
141
+ end
152
142
 
153
- subject do
154
- Class.new do
155
- include Location
156
- end.new(name, constraint)
143
+ describe 'downloaded?' do
144
+ it 'starts as false' do
145
+ expect(subject.downloaded?).to be_false
157
146
  end
147
+ end
158
148
 
159
- it "sets the downloaded? state to false" do
160
- subject.downloaded?.should be_false
149
+ describe '#download' do
150
+ it 'raises a AbstractFunction if not defined' do
151
+ expect {
152
+ subject.download(double('destination'))
153
+ }.to raise_error(Berkshelf::AbstractFunction)
161
154
  end
155
+ end
162
156
 
163
- describe "#download" do
164
- it "raises a AbstractFunction if not defined" do
165
- lambda {
166
- subject.download(double('destination'))
167
- }.should raise_error(AbstractFunction)
168
- end
169
- end
157
+ describe '#validate_cached' do
158
+ let(:cached) { double('cached-cb', cookbook_name: name, version: '0.1.0') }
170
159
 
171
- describe "#validate_cached" do
172
- let(:cached) { double('cached-cb', cookbook_name: name, version: "0.1.0") }
160
+ it 'raises a CookbookValidationFailure error if the version constraint does not satisfy the cached version' do
161
+ constraint.should_receive(:satisfies?).with(cached.version).and_return(false)
173
162
 
174
- it "raises a CookbookValidationFailure error if the version constraint does not satisfy the cached version" do
175
- constraint.should_receive(:satisfies?).with(cached.version).and_return(false)
163
+ expect {
164
+ subject.validate_cached(cached)
165
+ }.to raise_error(Berkshelf::CookbookValidationFailure)
166
+ end
176
167
 
177
- lambda {
178
- subject.validate_cached(cached)
179
- }.should raise_error(CookbookValidationFailure)
180
- end
168
+ it 'returns true if cached_cookbooks satisfies the version constraint' do
169
+ constraint.should_receive(:satisfies?).with(cached.version).and_return(true)
170
+ expect(subject.validate_cached(cached)).to be_true
171
+ end
181
172
 
182
- it "returns true if cached_cookbooks satisfies the version constraint" do
173
+ context "when the cached_cookbooks satisfies the version constraint" do
174
+ it "returns true if the name of the cached_cookbook matches the name of the location" do
183
175
  constraint.should_receive(:satisfies?).with(cached.version).and_return(true)
184
-
185
- subject.validate_cached(cached).should be_true
176
+ cached.stub(:name) { name }
177
+ expect(subject.validate_cached(cached)).to be_true
186
178
  end
187
179
 
188
- context "when the cached_cookbooks satisfies the version constraint" do
189
- it "returns true if the name of the cached_cookbook matches the name of the location" do
190
- constraint.should_receive(:satisfies?).with(cached.version).and_return(true)
191
- cached.stub(:name) { name }
192
-
193
- subject.validate_cached(cached).should be_true
194
- end
195
-
196
- it "raises an AmbiguousCookbookName error if the cached_cookbook's name does not match the location's" do
197
- pending "Implement when Opscode makes the 'name' a required attribute in Cookbook metadata"
198
-
199
- constraint.should_receive(:satisfies?).with(cached.version).and_return(true)
200
- cached.stub(:cookbook_name) { "artifact" }
180
+ it "warns about the MismatchedCookbookName if the cached_cookbook's name does not match the location's" do
181
+ constraint.should_receive(:satisfies?).with(cached.version).and_return(true)
182
+ cached.stub(:cookbook_name) { "artifact" }
183
+ msg = Berkshelf::MismatchedCookbookName.new(subject, cached).to_s
201
184
 
202
- lambda {
203
- subject.validate_cached(cached)
204
- }.should raise_error(AmbiguousCookbookName)
205
- end
185
+ Berkshelf.ui.should_receive(:warn).with(msg)
186
+ subject.validate_cached(cached)
206
187
  end
207
188
  end
208
189
  end