berkshelf 0.3.7 → 0.4.0.rc1

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.
Files changed (44) hide show
  1. data/.gitignore +2 -1
  2. data/README.md +8 -0
  3. data/Thorfile +2 -2
  4. data/berkshelf.gemspec +1 -1
  5. data/features/install.feature +102 -2
  6. data/features/lockfile.feature +1 -1
  7. data/features/step_definitions/chef_server_steps.rb +8 -0
  8. data/features/step_definitions/cli_steps.rb +1 -1
  9. data/features/step_definitions/filesystem_steps.rb +12 -0
  10. data/features/support/env.rb +8 -10
  11. data/features/update.feature +1 -1
  12. data/lib/berkshelf.rb +19 -1
  13. data/lib/berkshelf/berksfile.rb +18 -6
  14. data/lib/berkshelf/cli.rb +3 -8
  15. data/lib/berkshelf/cookbook_source.rb +108 -23
  16. data/lib/berkshelf/cookbook_source/chef_api_location.rb +256 -0
  17. data/lib/berkshelf/cookbook_source/git_location.rb +14 -2
  18. data/lib/berkshelf/cookbook_source/location.rb +119 -2
  19. data/lib/berkshelf/cookbook_source/path_location.rb +6 -1
  20. data/lib/berkshelf/cookbook_source/site_location.rb +36 -105
  21. data/lib/berkshelf/cookbook_store.rb +7 -12
  22. data/lib/berkshelf/dsl.rb +1 -1
  23. data/lib/berkshelf/errors.rb +2 -0
  24. data/lib/berkshelf/init_generator.rb +6 -6
  25. data/lib/berkshelf/resolver.rb +8 -34
  26. data/lib/berkshelf/uploader.rb +7 -7
  27. data/lib/berkshelf/version.rb +1 -1
  28. data/spec/fixtures/reset.pem +27 -0
  29. data/spec/knife.rb.sample +12 -0
  30. data/spec/spec_helper.rb +4 -1
  31. data/spec/support/chef_api.rb +32 -0
  32. data/spec/support/knife.rb +18 -0
  33. data/spec/unit/berkshelf/cookbook_source/chef_api_location_spec.rb +243 -0
  34. data/spec/unit/berkshelf/cookbook_source/git_location_spec.rb +2 -2
  35. data/spec/unit/berkshelf/cookbook_source/location_spec.rb +130 -2
  36. data/spec/unit/berkshelf/cookbook_source/path_location_spec.rb +2 -2
  37. data/spec/unit/berkshelf/cookbook_source/site_location_spec.rb +22 -105
  38. data/spec/unit/berkshelf/cookbook_source_spec.rb +140 -71
  39. data/spec/unit/berkshelf/cookbook_store_spec.rb +6 -6
  40. data/spec/unit/berkshelf/resolver_spec.rb +9 -30
  41. data/spec/unit/berkshelf/uploader_spec.rb +1 -10
  42. data/spec/unit/berkshelf_spec.rb +21 -1
  43. metadata +19 -15
  44. data/features/config.sample.yml +0 -3
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  module Berkshelf
4
4
  describe CookbookSource::GitLocation do
5
- let(:complacent_constraint) { double('comp-vconstraint', include?: true) }
5
+ let(:complacent_constraint) { double('comp-vconstraint', satisfies?: true) }
6
6
 
7
7
  describe "ClassMethods" do
8
8
  subject { CookbookSource::GitLocation }
@@ -72,7 +72,7 @@ module Berkshelf
72
72
  context "given the content at the Git repo does not satisfy the version constraint" do
73
73
  subject do
74
74
  CookbookSource::GitLocation.new("nginx",
75
- double('constraint', include?: false),
75
+ double('constraint', satisfies?: false),
76
76
  git: "git://github.com/opscode-cookbooks/nginx.git"
77
77
  )
78
78
  end
@@ -1,5 +1,133 @@
1
1
  module Berkshelf
2
2
  describe CookbookSource::Location do
3
+ describe "ClassMethods Module" do
4
+ subject do
5
+ Class.new do
6
+ include CookbookSource::Location
7
+ end
8
+ end
9
+
10
+ describe "::location_key" do
11
+ before(:each) do
12
+ @original = CookbookSource.class_variable_get :@@location_keys
13
+ CookbookSource.class_variable_set :@@location_keys, {}
14
+ end
15
+
16
+ after(:each) do
17
+ CookbookSource.class_variable_set :@@location_keys, @original
18
+ end
19
+
20
+ it "adds the given location key with the includer's Class to CookbookSource.location_keys" do
21
+ subject.location_key(:reset)
22
+
23
+ CookbookSource.location_keys.should have(1).item
24
+ CookbookSource.location_keys.should include(:reset)
25
+ CookbookSource.location_keys[:reset].should eql(subject)
26
+ end
27
+ end
28
+
29
+ describe "::valid_options" do
30
+ before(:each) do
31
+ @original = CookbookSource.class_variable_get :@@valid_options
32
+ CookbookSource.class_variable_set :@@valid_options, []
33
+ end
34
+
35
+ after(:each) do
36
+ CookbookSource.class_variable_set :@@valid_options, @original
37
+ end
38
+
39
+ it "adds the given symbol to the list of valid options on CookbookSource" do
40
+ subject.valid_options(:mundo)
41
+
42
+ CookbookSource.valid_options.should have(1).item
43
+ CookbookSource.valid_options.should include(:mundo)
44
+ end
45
+
46
+ it "adds parameters to the list of valid options on the CookbookSource" do
47
+ subject.valid_options(:riot, :arenanet)
48
+
49
+ CookbookSource.valid_options.should have(2).items
50
+ CookbookSource.valid_options.should include(:riot)
51
+ CookbookSource.valid_options.should include(:arenanet)
52
+ end
53
+ end
54
+
55
+ describe "::solve_for_constraint" do
56
+ let(:constraint) { "~> 0.101.2" }
57
+ let(:versions) do
58
+ {
59
+ "0.101.2" => "http://cookbooks.opscode.com/api/v1/cookbooks/nginx/versions/0_101_2",
60
+ "0.101.0" => "http://cookbooks.opscode.com/api/v1/cookbooks/nginx/versions/0_101_0",
61
+ "0.100.2" => "http://cookbooks.opscode.com/api/v1/cookbooks/nginx/versions/0_100_2",
62
+ "0.100.0" => "http://cookbooks.opscode.com/api/v1/cookbooks/nginx/versions/0_100_0"
63
+ }
64
+ end
65
+
66
+ it "returns an array with a string containing the version of the solution at index 0" do
67
+ result = subject.solve_for_constraint(constraint, versions)
68
+
69
+ result[0].should eql("0.101.2")
70
+ end
71
+
72
+ it "returns an array containing a URI at index 0" do
73
+ result = subject.solve_for_constraint(constraint, versions)
74
+
75
+ result[1].should match(URI.regexp)
76
+ end
77
+
78
+ it "should return the best match for the constraint and versions given" do
79
+ subject.solve_for_constraint(constraint, versions)[0].to_s.should eql("0.101.2")
80
+ end
81
+
82
+ context "given a solution can not be found for constraint" do
83
+ it "returns nil" do
84
+ subject.solve_for_constraint(Solve::Constraint.new(">= 1.0"), versions).should be_nil
85
+ end
86
+ end
87
+ end
88
+ end
89
+
90
+ describe "ModuleFunctions" do
91
+ subject { CookbookSource::Location }
92
+
93
+ describe "::init" do
94
+ let(:name) { "artifact" }
95
+ let(:constraint) { double("constraint") }
96
+
97
+ it "returns an instance of SiteLocation given a site: option key" do
98
+ result = subject.init(name, constraint, site: "http://site/value")
99
+
100
+ result.should be_a(CookbookSource::SiteLocation)
101
+ end
102
+
103
+ it "returns an instance of PathLocation given a path: option key" do
104
+ result = subject.init(name, constraint, path: "/Users/reset/code")
105
+
106
+ result.should be_a(CookbookSource::PathLocation)
107
+ end
108
+
109
+ it "returns an instance of GitLocation given a git: option key" do
110
+ result = subject.init(name, constraint, git: "git://github.com/something.git")
111
+
112
+ result.should be_a(CookbookSource::GitLocation)
113
+ end
114
+
115
+ it "returns an instance of SiteLocation when no option key is given that matches a registered location_key" do
116
+ result = subject.init(name, constraint)
117
+
118
+ result.should be_a(CookbookSource::SiteLocation)
119
+ end
120
+
121
+ context "given two location_keys" do
122
+ it "raises an InternalError" do
123
+ lambda {
124
+ subject.init(name, constraint, git: :value, path: :value)
125
+ }.should raise_error(InternalError)
126
+ end
127
+ end
128
+ end
129
+ end
130
+
3
131
  let(:name) { "nginx" }
4
132
  let(:constraint) { double('constraint') }
5
133
 
@@ -25,7 +153,7 @@ module Berkshelf
25
153
  let(:cached) { double('cached-cb', version: "0.1.0") }
26
154
 
27
155
  it "raises a ConstraintNotSatisfied error if the version constraint does not satisfy the cached version" do
28
- constraint.should_receive(:include?).with(cached.version).and_return(false)
156
+ constraint.should_receive(:satisfies?).with(cached.version).and_return(false)
29
157
 
30
158
  lambda {
31
159
  subject.validate_cached(cached)
@@ -33,7 +161,7 @@ module Berkshelf
33
161
  end
34
162
 
35
163
  it "returns true if the version constraint satisfies the cached version" do
36
- constraint.should_receive(:include?).with(cached.version).and_return(true)
164
+ constraint.should_receive(:satisfies?).with(cached.version).and_return(true)
37
165
 
38
166
  subject.validate_cached(cached).should be_true
39
167
  end
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  module Berkshelf
4
4
  describe CookbookSource::PathLocation do
5
- let(:complacent_constraint) { double('comp-vconstraint', include?: true) }
5
+ let(:complacent_constraint) { double('comp-vconstraint', satisfies?: true) }
6
6
  let(:path) { fixtures_path.join("cookbooks", "example_cookbook").to_s }
7
7
  subject { CookbookSource::PathLocation.new("nginx", complacent_constraint, path: path) }
8
8
 
@@ -38,7 +38,7 @@ module Berkshelf
38
38
  end
39
39
 
40
40
  context "given the content at path does not satisfy the version constraint" do
41
- subject { CookbookSource::PathLocation.new("nginx", double('constraint', include?: false), path: path) }
41
+ subject { CookbookSource::PathLocation.new("nginx", double('constraint', satisfies?: false), path: path) }
42
42
 
43
43
  it "raises a ConstraintNotSatisfied error" do
44
44
  lambda {
@@ -2,47 +2,14 @@ require 'spec_helper'
2
2
 
3
3
  module Berkshelf
4
4
  describe CookbookSource::SiteLocation do
5
- describe "ClassMethods" do
6
- let(:constraint) { DepSelector::VersionConstraint.new("~> 0.101.2") }
7
- subject { CookbookSource::SiteLocation }
8
- let(:versions) do
9
- {
10
- DepSelector::Version.new("0.101.2") => "http://cookbooks.opscode.com/api/v1/cookbooks/nginx/versions/0_101_2",
11
- DepSelector::Version.new("0.101.0") => "http://cookbooks.opscode.com/api/v1/cookbooks/nginx/versions/0_101_0",
12
- DepSelector::Version.new("0.100.2") => "http://cookbooks.opscode.com/api/v1/cookbooks/nginx/versions/0_100_2",
13
- DepSelector::Version.new("0.100.0") => "http://cookbooks.opscode.com/api/v1/cookbooks/nginx/versions/0_100_0"
14
- }
15
- end
16
-
17
- describe "#solve_for_constraint" do
18
- it "returns an array containing a DepSelector::Version at index 0" do
19
- result = subject.solve_for_constraint(constraint, versions)
20
-
21
- result[0].should be_a(DepSelector::Version)
22
- end
23
-
24
- it "returns an array containing a URI at index 0" do
25
- result = subject.solve_for_constraint(constraint, versions)
26
-
27
- result[1].should match(URI.regexp)
28
- end
29
-
30
- it "should return the best match for the constraint and versions given" do
31
- subject.solve_for_constraint(constraint, versions)[0].to_s.should eql("0.101.2")
32
- end
33
-
34
- context "given a solution can not be found for constraint" do
35
- it "returns nil" do
36
- subject.solve_for_constraint(DepSelector::VersionConstraint.new(">= 1.0"), versions).should be_nil
37
- end
38
- end
39
- end
40
- end
41
-
42
- let(:complacent_constraint) { double('comp-vconstraint', include?: true) }
5
+ let(:complacent_constraint) { double('comp-vconstraint', satisfies?: true) }
43
6
  subject { CookbookSource::SiteLocation.new("nginx", complacent_constraint) }
44
7
 
45
8
  describe "#download" do
9
+ before(:each) do
10
+ subject.stub(:target_version).and_return(["0.101.2", "http://cookbooks.opscode.com/api/v1/cookbooks/nginx/versions/0_101_2"])
11
+ end
12
+
46
13
  it "returns a CachedCookbook" do
47
14
  result = subject.download(tmp_path)
48
15
  name = subject.name
@@ -58,7 +25,9 @@ module Berkshelf
58
25
  end
59
26
 
60
27
  context "given a wildcard '>= 0.0.0' version constraint is specified" do
61
- subject { CookbookSource::SiteLocation.new("nginx", DepSelector::VersionConstraint.new(">= 0.0.0")) }
28
+ before(:each) do
29
+ subject.stub(:latest_version).and_return(["0.101.2", "http://cookbooks.opscode.com/api/v1/cookbooks/nginx/versions/0_101_2"])
30
+ end
62
31
 
63
32
  it "downloads the latest version of the cookbook to the given destination" do
64
33
  subject.download(tmp_path)
@@ -73,36 +42,6 @@ module Berkshelf
73
42
  end
74
43
  end
75
44
 
76
- context "given an exact match version constraint" do
77
- subject { CookbookSource::SiteLocation.new("nginx", DepSelector::VersionConstraint.new("= 0.101.2")) }
78
-
79
- it "downloads the cookbook with the version matching the version_constraint to the given destination" do
80
- subject.download(tmp_path)
81
- name = subject.name
82
-
83
- tmp_path.should have_structure {
84
- directory "#{name}-0.101.2" do
85
- file "metadata.rb"
86
- end
87
- }
88
- end
89
- end
90
-
91
- context "given a more broad version constraint" do
92
- subject { CookbookSource::SiteLocation.new("nginx", DepSelector::VersionConstraint.new("~> 0.99.0")) }
93
-
94
- it "downloads the best matching cookbook version for the constraint to the given destination" do
95
- subject.download(tmp_path)
96
- name = subject.name
97
-
98
- tmp_path.should have_structure {
99
- directory "#{name}-0.99.2" do
100
- file "metadata.rb"
101
- end
102
- }
103
- end
104
- end
105
-
106
45
  context "given an explicit :site location key" do
107
46
  subject do
108
47
  CookbookSource::SiteLocation.new("nginx",
@@ -111,6 +50,10 @@ module Berkshelf
111
50
  )
112
51
  end
113
52
 
53
+ before(:each) do
54
+ subject.stub(:latest_version).and_return(["0.101.2", "http://cookbooks.opscode.com/api/v1/cookbooks/nginx/versions/0_101_2"])
55
+ end
56
+
114
57
  it "downloads the cookbook to the given destination" do
115
58
  subject.download(tmp_path)
116
59
  name = subject.name
@@ -125,11 +68,9 @@ module Berkshelf
125
68
  end
126
69
 
127
70
  context "given a cookbook that does not exist on the specified site" do
128
- subject do
129
- CookbookSource::SiteLocation.new("nowaythis_exists",
130
- complacent_constraint,
131
- site: "http://cookbooks.opscode.com/api/v1/cookbooks"
132
- )
71
+ before(:each) do
72
+ subject.stub(:versions).and_raise(CookbookNotFound)
73
+ subject.stub(:target_version).and_raise(CookbookNotFound)
133
74
  end
134
75
 
135
76
  it "raises a CookbookNotFound error" do
@@ -141,47 +82,23 @@ module Berkshelf
141
82
  end
142
83
 
143
84
  describe "#versions" do
144
- it "returns a hash containing versions for keys" do
145
- subject.versions.each do |key, val|
146
- key.should be_a(DepSelector::Version)
147
- end
148
- end
149
-
150
- it "returns a hash containing uris for values" do
151
- subject.versions.each do |key, val|
152
- val.should match(URI.regexp)
153
- end
154
- end
155
- end
156
-
157
- describe "#version" do
158
- it "returns an array containing a DepSelector::Version at index 0" do
159
- result = subject.version("0.101.2")
160
-
161
- result[0].should be_a(DepSelector::Version)
85
+ it "returns a hash containing a string containing the version number of each cookbook version as the keys" do
86
+ subject.versions.should have_key("0.101.2")
162
87
  end
163
88
 
164
- it "returns an array containing a URI at index 0" do
165
- result = subject.version("0.101.2")
166
-
167
- result[1].should match(URI.regexp)
168
- end
169
-
170
- it "returns a DepSelector::Version that matches the given version" do
171
- result = subject.version("0.101.2")
172
-
173
- result[0].to_s.should eql("0.101.2")
89
+ it "returns a hash containing a string containing the download URL for each cookbook version as the values" do
90
+ subject.versions["0.101.2"].should eql("http://cookbooks.opscode.com/api/v1/cookbooks/nginx/versions/0_101_2")
174
91
  end
175
92
  end
176
93
 
177
94
  describe "#latest_version" do
178
- it "returns an array containing a DepSelector::Version at index 0" do
95
+ it "returns an array containing a version string at index 0" do
179
96
  result = subject.latest_version
180
97
 
181
- result[0].should be_a(DepSelector::Version)
98
+ result[0].should match(/^(.+)\.(.+)\.(.+)$/)
182
99
  end
183
100
 
184
- it "returns an array containing a URI at index 0" do
101
+ it "returns an array containing a URI at index 1" do
185
102
  result = subject.latest_version
186
103
 
187
104
  result[1].should match(URI.regexp)
@@ -4,114 +4,183 @@ module Berkshelf
4
4
  describe CookbookSource do
5
5
  let(:cookbook_name) { "nginx" }
6
6
 
7
- describe "#initialize" do
7
+ describe "ClassMethods" do
8
8
  subject { CookbookSource }
9
9
 
10
- context "given no location key (i.e. :git, :path, :site)" do
11
- let(:source) { subject.new(cookbook_name) }
10
+ describe "::initialize" do
11
+ context "given no location key (i.e. :git, :path, :site)" do
12
+ let(:source) { subject.new(cookbook_name) }
12
13
 
13
- it "uses a default SiteLocation pointing to the opscode community api" do
14
- source.location.api_uri.should eql(subject::SiteLocation::OPSCODE_COMMUNITY_API)
14
+ it "uses a default SiteLocation pointing to the opscode community api" do
15
+ source.location.api_uri.should eql(subject::SiteLocation::OPSCODE_COMMUNITY_API)
16
+ end
15
17
  end
16
- end
17
18
 
18
- context "given no value for constraint" do
19
- let(:source) { subject.new(cookbook_name) }
19
+ context "given no value for constraint" do
20
+ let(:source) { subject.new(cookbook_name) }
20
21
 
21
- it "returns a wildcard match for any version" do
22
- source.version_constraint.to_s.should eql(">= 0.0.0")
22
+ it "returns a wildcard match for any version" do
23
+ source.version_constraint.to_s.should eql(">= 0.0.0")
24
+ end
23
25
  end
24
- end
25
26
 
26
- context "given a value for constraint" do
27
- let(:source) { subject.new(cookbook_name, "~> 1.0.84") }
27
+ context "given a value for constraint" do
28
+ let(:source) { subject.new(cookbook_name, "~> 1.0.84") }
28
29
 
29
- it "returns a DepSelector::VersionConstraint for the given version for version_constraint" do
30
- source.version_constraint.to_s.should eql("~> 1.0.84")
30
+ it "returns a Solve::Constraint for the given version for version_constraint" do
31
+ source.version_constraint.to_s.should eql("~> 1.0.84")
32
+ end
31
33
  end
32
- end
33
34
 
34
- context "given a location key :git" do
35
- let(:url) { "git://url_to_git" }
36
- let(:source) { subject.new(cookbook_name, :git => url) }
35
+ context "given a location key :git" do
36
+ let(:url) { "git://url_to_git" }
37
+ let(:source) { subject.new(cookbook_name, git: url) }
37
38
 
38
- it "initializes a GitLocation for location" do
39
- source.location.should be_a(subject::GitLocation)
40
- end
39
+ it "initializes a GitLocation for location" do
40
+ source.location.should be_a(subject::GitLocation)
41
+ end
41
42
 
42
- it "points to the given Git URL" do
43
- source.location.uri.should eql(url)
43
+ it "points to the given Git URL" do
44
+ source.location.uri.should eql(url)
45
+ end
44
46
  end
45
- end
46
47
 
47
- context "given a location key :path" do
48
- context "given a value for path that contains a cookbook" do
49
- let(:path) { fixtures_path.join("cookbooks", "example_cookbook").to_s }
48
+ context "given a location key :path" do
49
+ context "given a value for path that contains a cookbook" do
50
+ let(:path) { fixtures_path.join("cookbooks", "example_cookbook").to_s }
51
+
52
+ it "initializes a PathLocation for location" do
53
+ subject.new(cookbook_name, path: path).location.should be_a(subject::PathLocation)
54
+ end
50
55
 
51
- it "initializes a PathLocation for location" do
52
- subject.new(cookbook_name, path: path).location.should be_a(subject::PathLocation)
56
+ it "points to the specified path" do
57
+ subject.new(cookbook_name, path: path).location.path.should eql(path)
58
+ end
53
59
  end
54
60
 
55
- it "points to the specified path" do
56
- subject.new(cookbook_name, path: path).location.path.should eql(path)
61
+ context "given a value for path that does not contain a cookbook" do
62
+ let(:path) { "/does/not/exist" }
63
+
64
+ it "raises Berkshelf::CookbookNotFound" do
65
+ lambda {
66
+ subject.new(cookbook_name, path: path)
67
+ }.should raise_error(Berkshelf::CookbookNotFound)
68
+ end
57
69
  end
58
- end
59
70
 
60
- context "given a value for path that does not contain a cookbook" do
61
- let(:path) { "/does/not/exist" }
71
+ context "given an invalid option" do
72
+ it "raises BerkshelfError with a friendly message" do
73
+ lambda {
74
+ subject.new(cookbook_name, invalid_opt: "thisisnotvalid")
75
+ }.should raise_error(Berkshelf::BerkshelfError, "Invalid options for Cookbook Source: 'invalid_opt'.")
76
+ end
77
+
78
+ it "raises BerkshelfError with a messaging containing all of the invalid options" do
79
+ lambda {
80
+ subject.new(cookbook_name, invalid_one: "one", invalid_two: "two")
81
+ }.should raise_error(Berkshelf::BerkshelfError, "Invalid options for Cookbook Source: 'invalid_one', 'invalid_two'.")
82
+ end
83
+ end
62
84
 
63
- it "rasies Berkshelf::CookbookNotFound" do
64
- lambda {
65
- subject.new(cookbook_name, path: path)
66
- }.should raise_error(Berkshelf::CookbookNotFound)
85
+ describe "::add_valid_option" do
86
+ before(:each) do
87
+ @original = subject.class_variable_get :@@valid_options
88
+ subject.class_variable_set :@@valid_options, []
89
+ end
90
+
91
+ after(:each) do
92
+ subject.class_variable_set :@@valid_options, @original
93
+ end
94
+
95
+ it "adds an option to the list of valid options" do
96
+ subject.add_valid_option(:one)
97
+
98
+ subject.valid_options.should have(1).item
99
+ subject.valid_options.should include(:one)
100
+ end
101
+
102
+ it "does not add duplicate options to the list of valid options" do
103
+ subject.add_valid_option(:one)
104
+ subject.add_valid_option(:one)
105
+
106
+ subject.valid_options.should have(1).item
107
+ subject.valid_options.should include(:one)
108
+ end
109
+ end
110
+
111
+ describe "::add_location_key" do
112
+ before(:each) do
113
+ @original = subject.class_variable_get :@@location_keys
114
+ subject.class_variable_set :@@location_keys, {}
115
+ end
116
+
117
+ after(:each) do
118
+ subject.class_variable_set :@@location_keys, @original
119
+ end
120
+
121
+ it "adds a location key and the associated class to the list of valid locations" do
122
+ subject.add_location_key(:git, subject.class)
123
+
124
+ subject.location_keys.should have(1).item
125
+ subject.location_keys.should include(:git)
126
+ subject.location_keys[:git].should eql(subject.class)
127
+ end
128
+
129
+ it "does not add duplicate location keys to the list of location keys" do
130
+ subject.add_location_key(:git, subject.class)
131
+ subject.add_location_key(:git, subject.class)
132
+
133
+ subject.location_keys.should have(1).item
134
+ subject.location_keys.should include(:git)
135
+ end
67
136
  end
68
137
  end
69
- end
70
138
 
71
- context "given a location key :site" do
72
- let(:url) { "http://path_to_api/v1" }
73
- let(:source) { subject.new(cookbook_name, :site => url) }
139
+ context "given a location key :site" do
140
+ let(:url) { "http://path_to_api/v1" }
141
+ let(:source) { subject.new(cookbook_name, site: url) }
74
142
 
75
- it "initializes a SiteLocation for location" do
76
- source.location.should be_a(subject::SiteLocation)
77
- end
143
+ it "initializes a SiteLocation for location" do
144
+ source.location.should be_a(subject::SiteLocation)
145
+ end
78
146
 
79
- it "points to the specified URI" do
80
- source.location.api_uri.should eql(url)
147
+ it "points to the specified URI" do
148
+ source.location.api_uri.should eql(url)
149
+ end
81
150
  end
82
- end
83
151
 
84
- context "given multiple location options" do
85
- it "raises with an ArgumentError" do
86
- lambda {
87
- subject.new(cookbook_name, :site => "something", :git => "something")
88
- }.should raise_error(ArgumentError)
152
+ context "given multiple location options" do
153
+ it "raises with an Berkshelf::BerkshelfError" do
154
+ lambda {
155
+ subject.new(cookbook_name, site: "something", git: "something")
156
+ }.should raise_error(Berkshelf::BerkshelfError)
157
+ end
89
158
  end
90
- end
91
159
 
92
- context "given a group option containing a single group" do
93
- let(:group) { :production }
94
- let(:source) { subject.new(cookbook_name, :group => group) }
160
+ context "given a group option containing a single group" do
161
+ let(:group) { :production }
162
+ let(:source) { subject.new(cookbook_name, group: group) }
95
163
 
96
- it "assigns the single group to the groups attribute" do
97
- source.groups.should include(group)
164
+ it "assigns the single group to the groups attribute" do
165
+ source.groups.should include(group)
166
+ end
98
167
  end
99
- end
100
168
 
101
- context "given a group option containing an array of groups" do
102
- let(:groups) { [ :development, :test ] }
103
- let(:source) { subject.new(cookbook_name, :group => groups) }
169
+ context "given a group option containing an array of groups" do
170
+ let(:groups) { [ :development, :test ] }
171
+ let(:source) { subject.new(cookbook_name, group: groups) }
104
172
 
105
- it "assigns all the groups to the group attribute" do
106
- source.groups.should eql(groups)
173
+ it "assigns all the groups to the group attribute" do
174
+ source.groups.should eql(groups)
175
+ end
107
176
  end
108
- end
109
177
 
110
- context "given no group option" do
111
- let(:source) { subject.new(cookbook_name) }
178
+ context "given no group option" do
179
+ let(:source) { subject.new(cookbook_name) }
112
180
 
113
- it "should have the default group assigned" do
114
- source.groups.should include(:default)
181
+ it "should have the default group assigned" do
182
+ source.groups.should include(:default)
183
+ end
115
184
  end
116
185
  end
117
186
  end