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,110 +1,106 @@
1
1
  require 'spec_helper'
2
2
 
3
- module Berkshelf
4
- describe CookbookStore do
5
- subject { CookbookStore.new(tmp_path.join("cbstore_rspec")) }
3
+ describe Berkshelf::CookbookStore do
4
+ describe '#initialize' do
5
+ it 'creates the storage_path' do
6
+ storage_path = tmp_path.join('random_storage')
7
+ Berkshelf::CookbookStore.new(storage_path)
6
8
 
7
- describe "#initialize" do
8
- it "creates the storage_path" do
9
- storage_path = tmp_path.join("random_storage")
10
- subject.class.new(storage_path)
11
-
12
- storage_path.should exist
13
- end
9
+ expect(storage_path).to exist
14
10
  end
11
+ end
15
12
 
16
- describe "#cookbook_path" do
17
- let(:cookbook_name) { "nginx" }
18
- let(:cookbook_version) { "0.101.2" }
19
13
 
20
- before(:each) do
21
- @cb_path = subject.cookbook_path(cookbook_name, cookbook_version)
22
- end
23
14
 
24
- it "returns an instance of Pathname" do
25
- @cb_path.should be_a(Pathname)
26
- end
15
+ subject { Berkshelf::CookbookStore.new(tmp_path.join("cbstore_rspec")) }
27
16
 
28
- it "returns a Cookbook Version's filepath within the storage path" do
29
- @cb_path.dirname.should eql(subject.storage_path)
30
- end
17
+ describe '#cookbook_path' do
18
+ let(:cookbook_name) { 'nginx' }
19
+ let(:cookbook_version) { '0.101.2' }
20
+ let(:path) { subject.cookbook_path(cookbook_name, cookbook_version) }
31
21
 
32
- it "returns a basename containing the cookbook name and version separated by a dash" do
33
- @cb_path.basename.to_s.should eql("#{cookbook_name}-#{cookbook_version}")
34
- end
22
+ it 'returns an instance of Pathname' do
23
+ expect(path).to be_a(Pathname)
35
24
  end
36
25
 
37
- describe "#satisfy" do
38
- let(:name) { "nginx" }
39
- let(:version) { "0.101.4" }
40
- let(:constraint) { Solve::Constraint.new("~> 0.101.2") }
41
- let(:cached_cb) { double('cached-cb', name: name, version: Solve::Version.new(version)) }
42
- let(:cached_two) { double('cached-two', name: "mysql", version: Solve::Version.new("1.2.6")) }
26
+ it 'returns a the filepath within the storage path' do
27
+ expect(path.dirname).to eq(subject.storage_path)
28
+ end
43
29
 
44
- before(:each) do
45
- subject.stub(:cookbooks).and_return([cached_cb, cached_two])
46
- end
30
+ it 'returns a basename containing the cookbook name and version separated by a dash' do
31
+ expect(path.basename.to_s).to eq("#{cookbook_name}-#{cookbook_version}")
32
+ end
33
+ end
47
34
 
48
- it "gets and returns the the CachedCookbook best matching the name and constraint" do
49
- subject.should_receive(:cookbook).with(name, version).and_return(cached_cb)
35
+ describe '#satisfy' do
36
+ let(:name) { 'nginx' }
37
+ let(:version) { '0.101.4' }
38
+ let(:constraint) { Solve::Constraint.new('~> 0.101.2') }
39
+ let(:cached_one) { double('cached-one', name: name, version: Solve::Version.new(version)) }
40
+ let(:cached_two) { double('cached-two', name: 'mysql', version: Solve::Version.new('1.2.6')) }
50
41
 
51
- subject.satisfy(name, constraint).should eql(cached_cb)
52
- end
42
+ before { subject.stub(:cookbooks).and_return([cached_one, cached_two]) }
43
+
44
+ it 'gets and returns the the CachedCookbook best matching the name and constraint' do
45
+ subject.should_receive(:cookbook).with(name, version).and_return(cached_one)
46
+ result = subject.satisfy(name, constraint)
53
47
 
54
- context "when there are no cookbooks in the cookbook store" do
55
- before(:each) { subject.stub(:cookbooks).and_return([]) }
48
+ expect(result).to eq(cached_one)
49
+ end
50
+
51
+ context 'when there are no cookbooks in the cookbook store' do
52
+ before { subject.stub(:cookbooks).and_return([]) }
56
53
 
57
- it "returns nil" do
58
- subject.satisfy(name, constraint).should be_nil
59
- end
54
+ it 'returns nil' do
55
+ result = subject.satisfy(name, constraint)
56
+ expect(result).to be_nil
60
57
  end
58
+ end
61
59
 
62
- context "when there is no matching cookbook for the given name and constraint" do
63
- let(:version) { Solve::Version.new("1.0.0") }
64
- let(:constraint) { Solve::Constraint.new("= 0.1.0") }
60
+ context 'when there is no matching cookbook for the given name and constraint' do
61
+ let(:version) { Solve::Version.new('1.0.0') }
62
+ let(:constraint) { Solve::Constraint.new('= 0.1.0') }
65
63
 
66
- before(:each) do
67
- subject.stub(:cookbooks).and_return([ double('badcache', name: 'none', version: version) ])
68
- end
64
+ before { subject.stub(:cookbooks).and_return([ double('badcache', name: 'none', version: version) ]) }
69
65
 
70
- it "returns nil if there is no matching cookbook for the name and constraint" do
71
- subject.satisfy(name, constraint).should be_nil
72
- end
66
+ it 'returns nil if there is no matching cookbook for the name and constraint' do
67
+ result = subject.satisfy(name, constraint)
68
+ expect(result).to be_nil
73
69
  end
74
70
  end
71
+ end
75
72
 
76
- describe "#cookbook" do
77
- subject { CookbookStore.new(fixtures_path.join("cookbooks")) }
73
+ describe '#cookbook' do
74
+ subject { Berkshelf::CookbookStore.new(fixtures_path.join('cookbooks')) }
78
75
 
79
- it "returns a CachedCookbook if the specified cookbook version exists" do
80
- subject.cookbook("example_cookbook", "0.5.0").should be_a(CachedCookbook)
81
- end
76
+ it 'returns a CachedCookbook if the specified cookbook version exists' do
77
+ expect(subject.cookbook('example_cookbook', '0.5.0')).to be_a(Berkshelf::CachedCookbook)
78
+ end
82
79
 
83
- it "returns nil if the specified cookbook version does not exist" do
84
- subject.cookbook("doesnotexist", "0.1.0").should be_nil
85
- end
80
+ it 'returns nil if the specified cookbook version does not exist' do
81
+ expect(subject.cookbook('doesnotexist', '0.1.0')).to be_nil
86
82
  end
83
+ end
87
84
 
88
- describe "#cookbooks" do
89
- before(:each) do
90
- generate_cookbook(subject.storage_path, "nginx", "0.101.2")
91
- generate_cookbook(subject.storage_path, "mysql", "1.2.6")
92
- end
85
+ describe '#cookbooks' do
86
+ before do
87
+ generate_cookbook(subject.storage_path, 'nginx', '0.101.2')
88
+ generate_cookbook(subject.storage_path, 'mysql', '1.2.6')
89
+ end
93
90
 
94
- it "returns a list of CachedCookbooks" do
95
- subject.cookbooks.each do |cb|
96
- cb.should be_a(CachedCookbook)
97
- end
91
+ it 'returns a list of CachedCookbooks' do
92
+ subject.cookbooks.each do |cookbook|
93
+ expect(cookbook).to be_a(Berkshelf::CachedCookbook)
98
94
  end
95
+ end
99
96
 
100
- it "contains a CachedCookbook for every cookbook in the storage path" do
101
- subject.cookbooks.should have(2).items
102
- end
97
+ it 'contains a CachedCookbook for every cookbook in the storage path' do
98
+ expect(subject.cookbooks).to have(2).items
99
+ end
103
100
 
104
- context "given a value for the filter parameter" do
105
- it "returns only the CachedCookbooks whose name match the filter" do
106
- subject.cookbooks("mysql").should have(1).item
107
- end
101
+ context 'given a value for the filter parameter' do
102
+ it 'returns only the CachedCookbooks whose name match the filter' do
103
+ expect(subject.cookbooks('mysql')).to have(1).item
108
104
  end
109
105
  end
110
106
  end
@@ -1,12 +1,12 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe FileUtils do
4
- describe "#mv" do
4
+ describe '#mv' do
5
5
  let(:src) { double('src') }
6
6
  let(:dest) { double('dest') }
7
7
  let(:options) { double('options') }
8
8
 
9
- it "replaces mv with cp_r and rm_rf" do
9
+ it 'replaces mv with cp_r and rm_rf' do
10
10
  subject.stub(:windows?) { true }
11
11
  FileUtils.should_receive(:cp_r).with(src, dest, options)
12
12
  FileUtils.should_receive(:rm_rf).with(src)
@@ -1,210 +1,190 @@
1
1
  require 'spec_helper'
2
2
 
3
- module Berkshelf
4
- describe Downloader do
5
- describe "ClassMethods" do
6
- subject { Downloader }
7
-
8
- describe "::initialize" do
9
- context "when no value for locations is given" do
10
- it "sets the @locations instance variable to a blank array" do
11
- downloader = subject.new(double('store'))
12
-
13
- downloader.instance_variable_get(:@locations).should be_a(Array)
14
- downloader.instance_variable_get(:@locations).should have(0).items
15
- end
16
- end
17
-
18
- context "when an explicit value of locations is given" do
19
- let(:locations) do
20
- [
21
- {
22
- type: :chef_api,
23
- value: double('capi'),
24
- options: double('capi_opts')
25
- },
26
- {
27
- type: :chef_api,
28
- value: double('capi2'),
29
- options: double('capi_opts2')
30
- }
31
- ]
32
- end
33
-
34
- it "sets the @locations instance variable to the given locations" do
35
- downloader = subject.new(double('store'), locations: locations)
36
-
37
- downloader.instance_variable_get(:@locations).should eql(locations)
38
- end
39
- end
3
+ describe Berkshelf::Downloader do
4
+ let(:locations) do
5
+ [
6
+ {
7
+ type: :chef_api,
8
+ value: double('capi'),
9
+ options: double('capi_opts')
10
+ },
11
+ {
12
+ type: :chef_api,
13
+ value: double('capi2'),
14
+ options: double('capi_opts2')
15
+ }
16
+ ]
17
+ end
18
+
19
+ describe '.initialize' do
20
+ context 'when no value for locations is given' do
21
+ it 'sets the @locations instance variable to a blank array' do
22
+ downloader = Berkshelf::Downloader.new(double('store'))
23
+ locations = downloader.instance_variable_get(:@locations)
24
+
25
+ expect(locations).to be_a(Array)
26
+ expect(locations).to be_empty
40
27
  end
41
28
  end
42
29
 
43
- subject { Downloader.new(CookbookStore.new(tmp_path)) }
30
+ context 'when an explicit value of locations is given' do
31
+ it 'sets the @locations instance variable to the given locations' do
32
+ downloader = Berkshelf::Downloader.new(double('store'), locations: locations)
33
+ expect(downloader.instance_variable_get(:@locations)).to eq(locations)
34
+ end
35
+ end
36
+ end
44
37
 
45
- describe "#download" do
46
- let(:source) { double('source', name: "artifact", version_constraint: "= 0.10.0") }
47
- let(:location) { double('location') }
48
- let(:cached_cookbook) { double('cached') }
49
38
 
50
- context "when the source has a location" do
51
- before(:each) do
52
- source.stub(:location).and_return(location)
53
- location.should_receive(:download).with(subject.storage_path).and_return(cached_cookbook)
54
- source.should_receive(:cached_cookbook=).with(cached_cookbook)
55
- end
56
39
 
57
- it "sends 'download' to the source's location and sets the source's cached_cookbook to the result" do
58
- subject.download(source).should be_true
59
- end
40
+ let!(:cookbook_store) { Berkshelf::CookbookStore.new(tmp_path) }
41
+ subject { Berkshelf::Downloader.new(cookbook_store) }
60
42
 
61
- it "returns an Array containing the cached_cookbook and location used to download" do
62
- result = subject.download(source)
43
+ describe '#download' do
44
+ let(:source) { double('source', name: 'artifact', version_constraint: '= 0.10.0') }
45
+ let(:location) { double('location') }
46
+ let(:cached_cookbook) { double('cached') }
63
47
 
64
- result.should be_a(Array)
65
- result[0].should eql(cached_cookbook)
66
- result[1].should eql(location)
67
- end
48
+ context 'when the source has a location' do
49
+ before do
50
+ source.stub(:location).and_return(location)
51
+ location.should_receive(:download).with(subject.storage_path).and_return(cached_cookbook)
52
+ source.should_receive(:cached_cookbook=).with(cached_cookbook)
68
53
  end
69
54
 
70
- context "when the source does not have a location" do
71
- before(:each) do
72
- source.stub(:location).and_return(nil)
73
- subject.stub(:locations).and_return([{type: :chef_api, value: :config, options: Hash.new}])
74
- end
55
+ it "sends :download to the source's location and sets the source's cached_cookbook to the result" do
56
+ expect(subject.download(source)).to be_true
57
+ end
75
58
 
76
- it "sends the 'download' message to the default location" do
77
- Location.should_receive(:init).with(source.name, source.version_constraint, chef_api: :config).and_return(location)
78
- location.should_receive(:download).with(subject.storage_path).and_return(cached_cookbook)
79
- source.should_receive(:cached_cookbook=).with(cached_cookbook)
59
+ it 'returns an Array containing the cached_cookbook and location used to download' do
60
+ result = subject.download(source)
80
61
 
81
- subject.download(source)
82
- end
62
+ expect(result).to be_a(Array)
63
+ expect(result[0]).to eq(cached_cookbook)
64
+ expect(result[1]).to eq(location)
83
65
  end
84
66
  end
85
67
 
86
- describe "#locations" do
87
- let(:type) { :site }
88
- let(:value) { double('value') }
89
- let(:options) { double('options') }
68
+ context 'when the source does not have a location' do
69
+ before do
70
+ source.stub(:location).and_return(nil)
71
+ subject.stub(:locations).and_return([{ type: :chef_api, value: :config, options: {} }])
72
+ end
90
73
 
91
- it "returns an array of Hashes representing locations" do
92
- subject.add_location(type, value, options)
74
+ it 'sends the :download message to the default location' do
75
+ Berkshelf::Location.should_receive(:init).with(source.name, source.version_constraint, chef_api: :config).and_return(location)
76
+ location.should_receive(:download).with(subject.storage_path).and_return(cached_cookbook)
77
+ source.should_receive(:cached_cookbook=).with(cached_cookbook)
93
78
 
94
- subject.locations.each { |l| l.should be_a(Hash) }
79
+ subject.download(source)
95
80
  end
81
+ end
82
+ end
83
+
84
+ describe '#locations' do
85
+ let(:type) { :site }
86
+ let(:value) { double('value') }
87
+ let(:options) { double('options') }
96
88
 
97
- context "when no locations are explicitly added" do
98
- subject { Downloader.new(double('store')) }
89
+ it 'returns an array of Hashes representing locations' do
90
+ subject.add_location(type, value, options)
99
91
 
100
- it "returns an array of default locations" do
101
- subject.locations.should eql(Downloader::DEFAULT_LOCATIONS)
102
- end
92
+ subject.locations.each do |location|
93
+ expect(location).to be_a(Hash)
103
94
  end
95
+ end
104
96
 
105
- context "when locations are explicitly added" do
106
- let(:locations) do
107
- [
108
- {
109
- type: :chef_api,
110
- value: double('capi'),
111
- options: double('capi_opts')
112
- },
113
- {
114
- type: :chef_api,
115
- value: double('capi2'),
116
- options: double('capi_opts2')
117
- }
118
- ]
119
- end
120
-
121
- subject { Downloader.new(double('store'), locations: locations) }
122
-
123
- it "contains only the locations passed to the initializer" do
124
- subject.locations.should eql(locations)
125
- end
126
-
127
- it "does not include the array of default locations" do
128
- subject.locations.should_not include(Downloader::DEFAULT_LOCATIONS)
129
- end
97
+ context 'when no locations are explicitly added' do
98
+ subject { Berkshelf::Downloader.new(double('store')) }
99
+
100
+ it 'returns an array of default locations' do
101
+ expect(subject.locations).to eq(Berkshelf::Downloader::DEFAULT_LOCATIONS)
130
102
  end
131
103
  end
132
104
 
133
- describe "#add_location" do
134
- let(:type) { :site }
135
- let(:value) { double('value') }
136
- let(:options) { double('options') }
105
+ context 'when locations are explicitly added' do
106
+ subject { Berkshelf::Downloader.new(double('store'), locations: locations) }
137
107
 
138
- it "adds a hash to the end of the array of locations" do
139
- subject.add_location(type, value, options)
108
+ it 'contains only the locations passed to the initializer' do
109
+ expect(subject.locations).to eq(locations)
110
+ end
140
111
 
141
- subject.locations.should have(1).item
112
+ it 'does not include the array of default locations' do
113
+ expect(subject.locations).to_not include(Berkshelf::Downloader::DEFAULT_LOCATIONS)
142
114
  end
115
+ end
116
+ end
143
117
 
144
- it "adds a hash with a type, value, and options key" do
145
- subject.add_location(type, value, options)
118
+ describe '#add_location' do
119
+ let(:type) { :site }
120
+ let(:value) { double('value') }
121
+ let(:options) { double('options') }
146
122
 
147
- subject.locations.last.should have_key(:type)
148
- subject.locations.last.should have_key(:value)
149
- subject.locations.last.should have_key(:options)
150
- end
123
+ it 'adds a hash to the end of the array of locations' do
124
+ subject.add_location(type, value, options)
125
+ expect(subject.locations).to have(1).item
126
+ end
151
127
 
152
- it "sets the value of the given 'value' to the value of the key 'value'" do
153
- subject.add_location(type, value, options)
128
+ it 'adds a hash with a type, value, and options key' do
129
+ subject.add_location(type, value, options)
130
+ location = subject.locations.last
154
131
 
155
- subject.locations.last[:value].should eql(value)
132
+ [:type, :value, :options].each do |key|
133
+ expect(location).to have_key(key)
156
134
  end
135
+ end
157
136
 
158
- it "sets the value of the given 'type' to the value of the key 'type'" do
159
- subject.add_location(type, value, options)
137
+ it 'sets the value of the given :value to the value of the key :value' do
138
+ subject.add_location(type, value, options)
139
+ expect(subject.locations.last[:value]).to eq(value)
140
+ end
160
141
 
161
- subject.locations.last[:type].should eql(type)
162
- end
142
+ it 'sets the value of the given :type to the value of the key :type' do
143
+ subject.add_location(type, value, options)
144
+ expect(subject.locations.last[:type]).to eq(type)
145
+ end
163
146
 
164
- it "sets the value of the given 'options' to the value of the key 'options'" do
165
- subject.add_location(type, value, options)
147
+ it 'sets the value of the given :options to the value of the key :options' do
148
+ subject.add_location(type, value, options)
149
+ expect(subject.locations.last[:options]).to eq(options)
150
+ end
166
151
 
167
- subject.locations.last[:options].should eql(options)
168
- end
152
+ it 'raises a DuplicateLocationDefined error if a location of the given type and value was already added' do
153
+ subject.add_location(type, value, options)
169
154
 
170
- it "raises a DuplicateLocationDefined error if a location of the given type and value was already added" do
155
+ expect {
171
156
  subject.add_location(type, value, options)
157
+ }.to raise_error(Berkshelf::DuplicateLocationDefined)
158
+ end
172
159
 
173
- lambda {
174
- subject.add_location(type, value, options)
175
- }.should raise_error(DuplicateLocationDefined)
176
- end
177
-
178
- context "adding multiple locations" do
179
- let(:type_2) { :site }
180
- let(:value_2) { double('value_2') }
181
- let(:options_2) { double('options_2') }
160
+ context 'adding multiple locations' do
161
+ let(:type_2) { :site }
162
+ let(:value_2) { double('value_2') }
163
+ let(:options_2) { double('options_2') }
182
164
 
183
- it "adds locations in the order they are added" do
184
- subject.add_location(type, value, options)
185
- subject.add_location(type_2, value_2, options_2)
165
+ it 'adds locations in the order they are added' do
166
+ subject.add_location(type, value, options)
167
+ subject.add_location(type_2, value_2, options_2)
186
168
 
187
- subject.locations.should have(2).items
169
+ expect(subject.locations).to have(2).items
188
170
 
189
- subject.locations[0][:value].should eql(value)
190
- subject.locations[1][:value].should eql(value_2)
191
- end
171
+ expect(subject.locations[0][:value]).to eql(value)
172
+ expect(subject.locations[1][:value]).to eql(value_2)
192
173
  end
193
174
  end
175
+ end
194
176
 
195
- describe "#has_location?" do
196
- let(:type) { :site }
197
- let(:value) { double('value') }
198
-
199
- it "returns true if a source of the given type and value was already added" do
200
- subject.add_location(type, value)
177
+ describe '#has_location?' do
178
+ let(:type) { :site }
179
+ let(:value) { double('value') }
201
180
 
202
- subject.has_location?(type, value).should be_true
203
- end
181
+ it 'returns true if a source of the given type and value was already added' do
182
+ subject.add_location(type, value)
183
+ expect(subject.has_location?(type, value)).to be_true
184
+ end
204
185
 
205
- it "returns false if a source of the given type and value was not added" do
206
- subject.has_location?(type, value).should be_false
207
- end
186
+ it 'returns false if a source of the given type and value was not added' do
187
+ expect(subject.has_location?(type, value)).to be_false
208
188
  end
209
189
  end
210
190
  end