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,70 +1,68 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Berkshelf::CachedCookbook do
4
- describe "ClassMethods" do
5
- subject { described_class }
4
+ describe '.from_store_path' do
5
+ let(:path) { fixtures_path.join('cookbooks', 'example_cookbook-0.5.0') }
6
+ let(:cached) { Berkshelf::CachedCookbook.from_path(path) }
6
7
 
7
- describe "#from_store_path" do
8
- before(:each) do
9
- @cached_cb = subject.from_store_path(fixtures_path.join("cookbooks", "example_cookbook-0.5.0"))
10
- end
11
-
12
- it "returns an instance of CachedCookbook" do
13
- @cached_cb.should be_a(described_class)
14
- end
8
+ it 'returns a CachedCookbook' do
9
+ expect(cached).to be_a(Berkshelf::CachedCookbook)
10
+ end
15
11
 
16
- it "sets a version number" do
17
- @cached_cb.version.should eql("0.5.0")
18
- end
12
+ it 'sets a version number' do
13
+ expect(cached.version).to eq('0.5.0')
14
+ end
19
15
 
20
- it "sets the metadata.name value to the cookbook_name" do
21
- @cached_cb.metadata.name.should eql("example_cookbook")
22
- end
16
+ it 'sets the metadata.name value to the cookbook_name' do
17
+ expect(cached.metadata.name).to eq('example_cookbook')
18
+ end
23
19
 
24
- context "given a path that does not contain a cookbook" do
25
- it "returns nil" do
26
- subject.from_store_path(tmp_path).should be_nil
27
- end
20
+ context 'given a path that does not contain a cookbook' do
21
+ it 'returns nil' do
22
+ expect(Berkshelf::CachedCookbook.from_store_path(tmp_path)).to be_nil
28
23
  end
24
+ end
29
25
 
30
- context "given a path that does not match the CachedCookbook dirname format" do
31
- it "returns nil" do
32
- subject.from_store_path(fixtures_path.join("cookbooks", "example_cookbook")).should be_nil
33
- end
26
+ context 'given a path that does not match the CachedCookbook dirname format' do
27
+ it 'returns nil' do
28
+ path = fixtures_path.join('cookbooks', 'example_cookbook')
29
+ expect(Berkshelf::CachedCookbook.from_store_path(path)).to be_nil
34
30
  end
35
31
  end
36
32
 
37
- describe "#checksum" do
38
- it "returns a checksum of the given filepath" do
39
- subject.checksum(fixtures_path.join("cookbooks", "example_cookbook-0.5.0", "README.md")).should eql("6e21094b7a920e374e7261f50e9c4eef")
33
+ describe '#checksum' do
34
+ it 'returns a checksum of the given filepath' do
35
+ path = fixtures_path.join('cookbooks', 'example_cookbook-0.5.0', 'README.md')
36
+ expect(Berkshelf::CachedCookbook.checksum(path)).to eq('6e21094b7a920e374e7261f50e9c4eef')
40
37
  end
41
38
 
42
- context "given path does not exist" do
43
- it "raises an Errno::ENOENT error" do
44
- lambda {
45
- subject.checksum(fixtures_path.join("notexisting.file"))
46
- }.should raise_error(Errno::ENOENT)
39
+ context 'given path does not exist' do
40
+ it 'raises an Errno::ENOENT error' do
41
+ expect {
42
+ Berkshelf::CachedCookbook.checksum(fixtures_path.join('notexisting.file'))
43
+ }.to raise_error(Errno::ENOENT)
47
44
  end
48
45
  end
49
46
  end
50
47
  end
51
48
 
52
- describe "#dependencies" do
53
- let(:dependencies) { { "mysql" => "= 1.2.0", "ntp" => ">= 0.0.0" } }
54
- let(:recommendations) { { "database" => ">= 0.0.0" } }
55
49
 
56
- let(:cb_path) do
57
- generate_cookbook(Berkshelf.cookbook_store.storage_path, "sparkle", "0.1.0", dependencies: dependencies, recommendations: recommendations)
50
+ describe '#dependencies' do
51
+ let(:dependencies) { { 'mysql' => '= 1.2.0', 'ntp' => '>= 0.0.0' } }
52
+ let(:recommendations) { { 'database' => '>= 0.0.0' } }
53
+
54
+ let(:path) do
55
+ generate_cookbook(Berkshelf.cookbook_store.storage_path, 'sparkle', '0.1.0', dependencies: dependencies, recommendations: recommendations)
58
56
  end
59
57
 
60
- subject { described_class.from_store_path(cb_path) }
58
+ subject { Berkshelf::CachedCookbook.from_store_path(path) }
61
59
 
62
- it "contains depends from the cookbook metadata" do
63
- subject.dependencies.should include(dependencies)
60
+ it 'contains depends from the cookbook metadata' do
61
+ expect(subject.dependencies).to include(dependencies)
64
62
  end
65
63
 
66
- it "contains recommendations from the cookbook metadata" do
67
- subject.dependencies.should include(recommendations)
64
+ it 'contains recommendations from the cookbook metadata' do
65
+ expect(subject.dependencies).to include(recommendations)
68
66
  end
69
67
  end
70
68
  end
@@ -1,23 +1,19 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Berkshelf::Chef::Cookbook::Chefignore do
4
- describe "ClassMethods" do
5
- subject { described_class }
4
+ describe '.find_relative_to' do
5
+ let(:path) { tmp_path.join('chefignore-test') }
6
+ before(:each) { FileUtils.mkdir_p(path) }
6
7
 
7
- describe "::find_relative_to" do
8
- let(:path) { tmp_path.join('chefignore-test') }
9
- before(:each) { FileUtils.mkdir_p(path) }
10
-
11
- it "finds a chefignore file in a 'cookbooks' directory relative to the given path" do
12
- FileUtils.touch(path.join('chefignore'))
13
- subject.find_relative_to(path)
14
- end
8
+ it "finds a chefignore file in a 'cookbooks' directory relative to the given path" do
9
+ FileUtils.touch(path.join('chefignore'))
10
+ Berkshelf::Chef::Cookbook::Chefignore.find_relative_to(path)
11
+ end
15
12
 
16
- it "finds a chefignore file relative to the given path" do
17
- FileUtils.mkdir_p(path.join('cookbooks'))
18
- FileUtils.touch(path.join('cookbooks', 'chefignore'))
19
- subject.find_relative_to(path)
20
- end
13
+ it 'finds a chefignore file relative to the given path' do
14
+ FileUtils.mkdir_p(path.join('cookbooks'))
15
+ FileUtils.touch(path.join('cookbooks', 'chefignore'))
16
+ Berkshelf::Chef::Cookbook::Chefignore.find_relative_to(path)
21
17
  end
22
18
  end
23
19
  end
@@ -19,50 +19,52 @@ describe Berkshelf::CommunityREST, vcr: { record: :new_episodes, serialize_with:
19
19
  Zlib::GzipReader.should_receive(:new).with(file)
20
20
  Archive::Tar::Minitar.should_receive(:unpack).with(gzip_reader, destination)
21
21
 
22
- expect(described_class.unpack(target, destination)).to eq(destination)
22
+ expect(Berkshelf::CommunityREST.unpack(target, destination)).to eq(destination)
23
23
  end
24
24
  end
25
25
 
26
26
  describe '.uri_escape_version' do
27
27
  it 'returns a string' do
28
- expect(described_class.uri_escape_version(nil)).to be_a(String)
28
+ expect(Berkshelf::CommunityREST.uri_escape_version(nil)).to be_a(String)
29
29
  end
30
30
 
31
31
  it 'converts a version to it\'s underscored version' do
32
- expect(described_class.uri_escape_version('1.1.2')).to eq('1_1_2')
32
+ expect(Berkshelf::CommunityREST.uri_escape_version('1.1.2')).to eq('1_1_2')
33
33
  end
34
34
 
35
35
  it 'works when the version has more than three points' do
36
- expect(described_class.uri_escape_version('1.1.1.2')).to eq('1_1_1_2')
36
+ expect(Berkshelf::CommunityREST.uri_escape_version('1.1.1.2')).to eq('1_1_1_2')
37
37
  end
38
38
 
39
39
  it 'works when the version has less than three points' do
40
- expect(described_class.uri_escape_version('1.2')).to eq('1_2')
40
+ expect(Berkshelf::CommunityREST.uri_escape_version('1.2')).to eq('1_2')
41
41
  end
42
42
  end
43
43
 
44
44
  describe '.version_from_uri' do
45
45
  it 'returns a string' do
46
- expect(described_class.version_from_uri(nil)).to be_a(String)
46
+ expect(Berkshelf::CommunityREST.version_from_uri(nil)).to be_a(String)
47
47
  end
48
48
 
49
49
  it 'extracts the version from the URL' do
50
- expect(described_class.version_from_uri('/api/v1/cookbooks/nginx/versions/1_1_2')).to eq('1.1.2')
50
+ expect(Berkshelf::CommunityREST.version_from_uri('/api/v1/cookbooks/nginx/versions/1_1_2')).to eq('1.1.2')
51
51
  end
52
52
 
53
53
  it 'works when the version has more than three points' do
54
- expect(described_class.version_from_uri('/api/v1/cookbooks/nginx/versions/1_1_1_2')).to eq('1.1.1.2')
54
+ expect(Berkshelf::CommunityREST.version_from_uri('/api/v1/cookbooks/nginx/versions/1_1_1_2')).to eq('1.1.1.2')
55
55
  end
56
56
 
57
57
  it 'works when the version has less than three points' do
58
- expect(described_class.version_from_uri('/api/v1/cookbooks/nginx/versions/1_2')).to eq('1.2')
58
+ expect(Berkshelf::CommunityREST.version_from_uri('/api/v1/cookbooks/nginx/versions/1_2')).to eq('1.2')
59
59
  end
60
60
  end
61
61
 
62
- let(:api_uri) { described_class::V1_API }
62
+
63
+
64
+ let(:api_uri) { Berkshelf::CommunityREST::V1_API }
63
65
 
64
66
  subject do
65
- described_class.new(api_uri)
67
+ Berkshelf::CommunityREST.new(api_uri)
66
68
  end
67
69
 
68
70
  describe '#download' do
@@ -112,7 +114,7 @@ describe Berkshelf::CommunityREST, vcr: { record: :new_episodes, serialize_with:
112
114
 
113
115
  describe '#latest_version' do
114
116
  it 'returns the version number of the latest version of the cookbook' do
115
- subject.latest_version('nginx').should eql('1.4.0')
117
+ expect(subject.latest_version('nginx')).to eq('1.4.0')
116
118
  end
117
119
 
118
120
  it 'raises a CookbookNotFound error on a 404 response' do
@@ -132,7 +134,7 @@ describe Berkshelf::CommunityREST, vcr: { record: :new_episodes, serialize_with:
132
134
 
133
135
  describe '#versions' do
134
136
  it 'returns an array containing an item for each version' do
135
- subject.versions('nginx').should have(24).versions
137
+ expect(subject.versions('nginx')).to have(24).versions
136
138
  end
137
139
 
138
140
  it 'raises a CookbookNotFound error on a 404 response' do
@@ -152,7 +154,7 @@ describe Berkshelf::CommunityREST, vcr: { record: :new_episodes, serialize_with:
152
154
 
153
155
  describe '#satisfy' do
154
156
  it 'returns the version number of the best solution' do
155
- subject.satisfy('nginx', '= 1.1.0').should eql('1.1.0')
157
+ expect(subject.satisfy('nginx', '= 1.1.0')).to eq('1.1.0')
156
158
  end
157
159
  end
158
160
 
@@ -1,38 +1,54 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Berkshelf::Config do
4
- let(:klass) { described_class }
4
+ describe '.file' do
5
+ context 'when the file does not exist' do
6
+ before { File.stub(:exists?).and_return(false) }
5
7
 
6
- describe "ClassMethods" do
7
- subject { klass }
8
-
9
- describe "::file" do
10
- subject { klass.file }
8
+ it 'is nil' do
9
+ expect(Berkshelf::Config.file).to be_nil
10
+ end
11
+ end
12
+ end
11
13
 
12
- context "when the file does not exist" do
13
- before :each do
14
- File.stub exists?: false
15
- end
14
+ describe '.instance' do
15
+ it 'should be a Berkshelf::Config' do
16
+ expect(Berkshelf::Config.instance).to be_an_instance_of(Berkshelf::Config)
17
+ end
18
+ end
16
19
 
17
- it { should be_nil }
18
- end
20
+ describe '.path' do
21
+ it 'is a string' do
22
+ expect(Berkshelf::Config.path).to be_a(String)
19
23
  end
20
24
 
21
- describe "::instance" do
22
- subject { klass.instance }
25
+ before do
26
+ File.stub(:exists?).and_return(false)
27
+ end
23
28
 
24
- it { should be_a klass }
29
+ after do
30
+ Berkshelf::Config.instance_variable_set(:@path, nil)
25
31
  end
26
32
 
27
- describe "::path" do
28
- subject { klass.path }
33
+ Berkshelf::Config::LOCATIONS.each do |location|
34
+ context "with '#{location}' as the config file" do
35
+ let(:path) { File.expand_path(location) }
36
+ before { File.stub(:exists?).with(path).and_return(true) }
29
37
 
30
- it { should be_a String }
38
+ it "returns '#{location}' as the path" do
39
+ expect(Berkshelf::Config.path).to eq(path)
40
+ end
41
+ end
42
+ end
31
43
 
32
- it "points to a location within ENV['BERKSHELF_PATH']" do
44
+ context "when ENV['BERKSHELF_PATH'] is used" do
45
+ before do
33
46
  ENV.stub(:[]).with('BERKSHELF_PATH').and_return('/tmp')
47
+ File.stub(:exists?).with('/tmp').and_return(true)
48
+ end
34
49
 
35
- subject.should eql("/tmp/config.json")
50
+ it "points to a location within it" do
51
+ expect(Berkshelf::Config.path).to eq('/tmp/config.json')
36
52
  end
37
53
  end
38
54
  end
@@ -1,14 +1,12 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Berkshelf::CookbookGenerator do
4
- subject { described_class }
5
-
6
- let(:name) { "sparkle_motion" }
4
+ let(:name) { 'sparkle_motion' }
7
5
  let(:target) { tmp_path.join(name) }
8
6
 
9
- context "with default options" do
7
+ context 'with default options' do
10
8
  before do
11
- capture(:stdout) { subject.new([target, name]).invoke_all }
9
+ capture(:stdout) { Berkshelf::CookbookGenerator.new([target, name]).invoke_all }
12
10
  end
13
11
 
14
12
  specify do
@@ -59,18 +57,16 @@ describe Berkshelf::CookbookGenerator do
59
57
 
60
58
  context "given a 'maintainer_email' option" do
61
59
  before do
62
- @email = "jamie@vialstudios.com"
63
60
  capture(:stdout) {
64
- described_class.new([target, name], maintainer_email: @email).invoke_all
61
+ Berkshelf::CookbookGenerator.new([target, name], maintainer_email: 'jamie@vialstudios.com').invoke_all
65
62
  }
66
63
  end
67
64
 
68
65
  it "generates a metadata.rb with the 'maintainer_email' value set" do
69
- email = @email
70
-
66
+ email = email
71
67
  expect(target).to have_structure {
72
68
  file 'metadata.rb' do
73
- contains "maintainer_email \"#{email}\""
69
+ contains 'maintainer_email "jamie@vialstudios.com"'
74
70
  end
75
71
  }
76
72
  end
@@ -1,287 +1,348 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Berkshelf::CookbookSource do
4
- let(:cookbook_name) { "nginx" }
5
- let(:berksfile) { double('berksfile', filepath: fixtures_path.join("Berksfile").to_s) }
4
+ let(:cookbook_name) { 'nginx' }
5
+ let(:berksfile) { double('berksfile', filepath: fixtures_path.join('Berksfile').to_s) }
6
6
 
7
- describe "ClassMethods" do
8
- subject { Berkshelf::CookbookSource }
7
+ describe '.initialize' do
8
+ let(:source) { Berkshelf::CookbookSource.new(berksfile, cookbook_name) }
9
9
 
10
- describe "::initialize" do
11
- context "given no location key (i.e. :git, :path, :site)" do
12
- let(:source) { subject.new(berksfile, cookbook_name) }
13
-
14
- it "sets a nil valie for location" do
15
- source.location.should be_nil
16
- end
10
+ context 'given no location key (i.e. :git, :path, :site)' do
11
+ it 'sets a nil valie for location' do
12
+ expect(source.location).to be_nil
17
13
  end
14
+ end
18
15
 
19
- context 'given no value for :locked_version' do
20
- let(:source) { subject.new(berksfile, cookbook_name) }
21
-
22
- it 'returns a wildcard match for any version' do
23
- expect(source.version_constraint.to_s).to eq('>= 0.0.0')
24
- end
16
+ context 'given no value for :locked_version' do
17
+ it 'returns a wildcard match for any version' do
18
+ expect(source.locked_version).to be_nil
25
19
  end
20
+ end
26
21
 
27
- context 'given a value for :locked_version' do
28
- let(:source) { subject.new(berksfile, cookbook_name, locked_version: '1.2.3') }
29
-
30
- it 'returns the locked_version as the constraint' do
31
- expect(source.version_constraint.to_s).to eq('= 1.2.3')
32
- end
22
+ context 'given no value for :constraint' do
23
+ it 'returns a wildcard match for any version' do
24
+ expect(source.version_constraint.to_s).to eq('>= 0.0.0')
33
25
  end
26
+ end
34
27
 
35
- context 'given no value for :constraint' do
36
- let(:source) { subject.new(berksfile, cookbook_name) }
28
+ context 'given a value for :constraint' do
29
+ let(:source) { Berkshelf::CookbookSource.new(berksfile, cookbook_name, constraint: '~> 1.0.84') }
37
30
 
38
- it 'returns a wildcard match for any version' do
39
- expect(source.version_constraint.to_s).to eq('>= 0.0.0')
40
- end
31
+ it 'returns a Solve::Constraint for the given version for version_constraint' do
32
+ expect(source.version_constraint.to_s).to eq('~> 1.0.84')
41
33
  end
34
+ end
42
35
 
43
- context 'given a value for :constraint' do
44
- let(:source) { subject.new(berksfile, cookbook_name, constraint: '~> 1.0.84') }
36
+ context 'given a location key :git' do
37
+ let(:url) { 'git://url_to_git' }
38
+ let(:source) { Berkshelf::CookbookSource.new(berksfile, cookbook_name, git: url) }
45
39
 
46
- it 'returns a Solve::Constraint for the given version for version_constraint' do
47
- expect(source.version_constraint.to_s).to eq('~> 1.0.84')
48
- end
40
+ it 'initializes a GitLocation for location' do
41
+ expect(source.location).to be_a(Berkshelf::GitLocation)
49
42
  end
50
43
 
51
- context 'given a value for :locked_version and :constraint' do
52
- let(:source) { subject.new(berksfile, cookbook_name, constraint: '~> 1.0.84', locked_version: '1.2.3') }
53
-
54
- it 'uses the :locked_version' do
55
- expect(source.version_constraint.to_s).to eq('= 1.2.3')
56
- end
44
+ it 'points to the given Git URL' do
45
+ expect(source.location.uri).to eq(url)
57
46
  end
47
+ end
58
48
 
59
- context "given a location key :git" do
60
- let(:url) { "git://url_to_git" }
61
- let(:source) { subject.new(berksfile, cookbook_name, git: url) }
49
+ context 'given a location key :path' do
50
+ context 'given a value for path that contains a cookbook' do
51
+ let(:path) { fixtures_path.join('cookbooks', 'example_cookbook').to_s }
52
+ let(:location) { Berkshelf::CookbookSource.new(berksfile, cookbook_name, path: path).location }
62
53
 
63
- it "initializes a GitLocation for location" do
64
- source.location.should be_a(Berkshelf::GitLocation)
54
+ it 'initializes a PathLocation for location' do
55
+ expect(location).to be_a(Berkshelf::PathLocation)
65
56
  end
66
57
 
67
- it "points to the given Git URL" do
68
- source.location.uri.should eql(url)
58
+ it 'points to the specified path' do
59
+ expect(location.path).to eq(path)
69
60
  end
70
61
  end
71
62
 
72
- context "given a location key :path" do
73
- context "given a value for path that contains a cookbook" do
74
- let(:path) { fixtures_path.join("cookbooks", "example_cookbook").to_s }
75
-
76
- it "initializes a PathLocation for location" do
77
- subject.new(berksfile, cookbook_name, path: path).location.should be_a(Berkshelf::PathLocation)
78
- end
63
+ context 'given a value for path that does not contain a cookbook' do
64
+ let(:path) { '/does/not/exist' }
79
65
 
80
- it "points to the specified path" do
81
- subject.new(berksfile, cookbook_name, path: path).location.path.should eql(path)
82
- end
66
+ it 'raises Berkshelf::CookbookNotFound' do
67
+ expect {
68
+ Berkshelf::CookbookSource.new(berksfile, cookbook_name, path: path)
69
+ }.to raise_error(Berkshelf::CookbookNotFound)
83
70
  end
71
+ end
84
72
 
85
- context "given a value for path that does not contain a cookbook" do
86
- let(:path) { "/does/not/exist" }
87
-
88
- it "raises Berkshelf::CookbookNotFound" do
89
- lambda {
90
- subject.new(berksfile, cookbook_name, path: path)
91
- }.should raise_error(Berkshelf::CookbookNotFound)
92
- end
73
+ context 'given an invalid option' do
74
+ it 'raises BerkshelfError with a friendly message' do
75
+ expect {
76
+ Berkshelf::CookbookSource.new(berksfile, cookbook_name, invalid_opt: 'thisisnotvalid')
77
+ }.to raise_error(Berkshelf::BerkshelfError, "Invalid options for Cookbook Source: 'invalid_opt'.")
93
78
  end
94
79
 
95
- context "given an invalid option" do
96
- it "raises BerkshelfError with a friendly message" do
97
- lambda {
98
- subject.new(berksfile, cookbook_name, invalid_opt: "thisisnotvalid")
99
- }.should raise_error(Berkshelf::BerkshelfError, "Invalid options for Cookbook Source: 'invalid_opt'.")
100
- end
101
-
102
- it "raises BerkshelfError with a messaging containing all of the invalid options" do
103
- lambda {
104
- subject.new(berksfile, cookbook_name, invalid_one: "one", invalid_two: "two")
105
- }.should raise_error(Berkshelf::BerkshelfError, "Invalid options for Cookbook Source: 'invalid_one', 'invalid_two'.")
106
- end
80
+ it 'raises BerkshelfError with a messaging containing all of the invalid options' do
81
+ expect {
82
+ Berkshelf::CookbookSource.new(berksfile, cookbook_name, invalid_one: 'one', invalid_two: 'two')
83
+ }.to raise_error(Berkshelf::BerkshelfError, "Invalid options for Cookbook Source: 'invalid_one', 'invalid_two'.")
107
84
  end
85
+ end
86
+ end
87
+ end
108
88
 
109
- describe "::add_valid_option" do
110
- before(:each) do
111
- @original = subject.class_variable_get :@@valid_options
112
- subject.class_variable_set :@@valid_options, []
113
- end
89
+ describe '.add_valid_option' do
90
+ before do
91
+ @original = Berkshelf::CookbookSource.class_variable_get :@@valid_options
92
+ Berkshelf::CookbookSource.class_variable_set :@@valid_options, []
93
+ end
114
94
 
115
- after(:each) do
116
- subject.class_variable_set :@@valid_options, @original
117
- end
95
+ after do
96
+ Berkshelf::CookbookSource.class_variable_set :@@valid_options, @original
97
+ end
118
98
 
119
- it "adds an option to the list of valid options" do
120
- subject.add_valid_option(:one)
99
+ it 'adds an option to the list of valid options' do
100
+ Berkshelf::CookbookSource.add_valid_option(:one)
121
101
 
122
- subject.valid_options.should have(1).item
123
- subject.valid_options.should include(:one)
124
- end
102
+ expect(Berkshelf::CookbookSource.valid_options).to have(1).item
103
+ expect(Berkshelf::CookbookSource.valid_options).to include(:one)
104
+ end
125
105
 
126
- it "does not add duplicate options to the list of valid options" do
127
- subject.add_valid_option(:one)
128
- subject.add_valid_option(:one)
106
+ it 'does not add duplicate options to the list of valid options' do
107
+ Berkshelf::CookbookSource.add_valid_option(:one)
108
+ Berkshelf::CookbookSource.add_valid_option(:one)
129
109
 
130
- subject.valid_options.should have(1).item
131
- subject.valid_options.should include(:one)
132
- end
133
- end
110
+ expect(Berkshelf::CookbookSource.valid_options).to have(1).item
111
+ end
112
+ end
134
113
 
135
- describe "::add_location_key" do
136
- before(:each) do
137
- @original = subject.class_variable_get :@@location_keys
138
- subject.class_variable_set :@@location_keys, {}
139
- end
114
+ describe '.add_location_key' do
115
+ before do
116
+ @original = Berkshelf::CookbookSource.class_variable_get :@@location_keys
117
+ Berkshelf::CookbookSource.class_variable_set :@@location_keys, {}
118
+ end
140
119
 
141
- after(:each) do
142
- subject.class_variable_set :@@location_keys, @original
143
- end
120
+ after do
121
+ Berkshelf::CookbookSource.class_variable_set :@@location_keys, @original
122
+ end
144
123
 
145
- it "adds a location key and the associated class to the list of valid locations" do
146
- subject.add_location_key(:git, subject.class)
124
+ it 'adds a location key and the associated class to the list of valid locations' do
125
+ Berkshelf::CookbookSource.add_location_key(:git, Berkshelf::CookbookSource)
147
126
 
148
- subject.location_keys.should have(1).item
149
- subject.location_keys.should include(:git)
150
- subject.location_keys[:git].should eql(subject.class)
151
- end
127
+ expect(Berkshelf::CookbookSource.location_keys).to have(1).item
128
+ expect(Berkshelf::CookbookSource.location_keys).to include(:git)
129
+ expect(Berkshelf::CookbookSource.location_keys[:git]).to eq(Berkshelf::CookbookSource)
130
+ end
152
131
 
153
- it "does not add duplicate location keys to the list of location keys" do
154
- subject.add_location_key(:git, subject.class)
155
- subject.add_location_key(:git, subject.class)
132
+ it 'does not add duplicate location keys to the list of location keys' do
133
+ Berkshelf::CookbookSource.add_location_key(:git, Berkshelf::CookbookSource)
134
+ Berkshelf::CookbookSource.add_location_key(:git, Berkshelf::CookbookSource)
156
135
 
157
- subject.location_keys.should have(1).item
158
- subject.location_keys.should include(:git)
159
- end
160
- end
161
- end
136
+ expect(Berkshelf::CookbookSource.location_keys).to have(1).item
137
+ expect(Berkshelf::CookbookSource.location_keys).to include(:git)
138
+ end
162
139
 
163
- context "given a location key :site" do
164
- let(:url) { "http://path_to_api/v1" }
165
- let(:source) { subject.new(berksfile, cookbook_name, site: url) }
140
+ context 'given a location key :site' do
141
+ let(:url) { 'http://path_to_api/v1' }
142
+ let(:source) { Berkshelf::CookbookSource.new(berksfile, cookbook_name, site: url) }
166
143
 
167
- it "initializes a SiteLocation for location" do
168
- source.location.should be_a(Berkshelf::SiteLocation)
169
- end
144
+ before do
145
+ Berkshelf::CookbookSource.add_location_key(:site, Berkshelf::SiteLocation)
146
+ end
170
147
 
171
- it "points to the specified URI" do
172
- source.location.api_uri.to_s.should eql(url)
173
- end
148
+ it 'initializes a SiteLocation for location' do
149
+ expect(source.location).to be_a(Berkshelf::SiteLocation)
174
150
  end
175
151
 
176
- context "given multiple location options" do
177
- it "raises with an Berkshelf::BerkshelfError" do
178
- lambda {
179
- subject.new(berksfile, cookbook_name, site: "something", git: "something")
180
- }.should raise_error(Berkshelf::BerkshelfError)
181
- end
152
+ it 'points to the specified URI' do
153
+ expect(source.location.api_uri.to_s).to eq(url)
182
154
  end
155
+ end
183
156
 
184
- context "given a group option containing a single group" do
185
- let(:group) { :production }
186
- let(:source) { subject.new(berksfile, cookbook_name, group: group) }
157
+ context 'given multiple location options' do
158
+ it 'raises with an Berkshelf::BerkshelfError' do
159
+ expect {
160
+ Berkshelf::CookbookSource.new(berksfile, cookbook_name, site: 'something', git: 'something')
161
+ }.to raise_error(Berkshelf::BerkshelfError)
162
+ end
163
+ end
187
164
 
188
- it "assigns the single group to the groups attribute" do
189
- source.groups.should include(group)
190
- end
165
+ context 'given a group option containing a single group' do
166
+ let(:group) { :production }
167
+ let(:source) { Berkshelf::CookbookSource.new(berksfile, cookbook_name, group: group) }
168
+
169
+ it 'assigns the single group to the groups attribute' do
170
+ expect(source.groups).to include(group)
191
171
  end
172
+ end
192
173
 
193
- context "given a group option containing an array of groups" do
194
- let(:groups) { [ :development, :test ] }
195
- let(:source) { subject.new(berksfile, cookbook_name, group: groups) }
174
+ context 'given a group option containing an array of groups' do
175
+ let(:groups) { [ :development, :test ] }
176
+ let(:source) { Berkshelf::CookbookSource.new(berksfile, cookbook_name, group: groups) }
196
177
 
197
- it "assigns all the groups to the group attribute" do
198
- source.groups.should eql(groups)
199
- end
178
+ it 'assigns all the groups to the group attribute' do
179
+ expect(source.groups).to eq(groups)
200
180
  end
181
+ end
201
182
 
202
- context "given no group option" do
203
- let(:source) { subject.new(berksfile, cookbook_name) }
183
+ context 'given no group option' do
184
+ let(:source) { Berkshelf::CookbookSource.new(berksfile, cookbook_name) }
204
185
 
205
- it "should have the default group assigned" do
206
- source.groups.should include(:default)
207
- end
186
+ it 'has the default group assigned' do
187
+ expect(source.groups).to include(:default)
208
188
  end
209
189
  end
210
190
  end
211
191
 
192
+
193
+
212
194
  subject { Berkshelf::CookbookSource.new(berksfile, cookbook_name) }
213
195
 
214
196
  describe '#add_group' do
215
- it "should store strings as symbols" do
216
- subject.add_group "foo"
217
- subject.groups.should =~ [:default, :foo]
197
+ it 'stores strings as symbols' do
198
+ subject.add_group 'foo'
199
+ expect(subject.groups).to eq([:default, :foo])
218
200
  end
219
201
 
220
- it "should not store duplicate groups" do
221
- subject.add_group "bar"
222
- subject.add_group "bar"
202
+ it 'does not store duplicate groups' do
203
+ subject.add_group 'bar'
204
+ subject.add_group 'bar'
223
205
  subject.add_group :bar
224
- subject.groups.should =~ [:default, :bar]
206
+ expect(subject.groups).to eq([:default, :bar])
225
207
  end
226
208
 
227
- it "should add multiple groups" do
228
- subject.add_group "baz", "quux"
229
- subject.groups.should =~ [:default, :baz, :quux]
209
+ it 'adds multiple groups' do
210
+ subject.add_group 'baz', 'quux'
211
+ expect(subject.groups).to eq([:default, :baz, :quux])
230
212
  end
231
213
 
232
- it "should handle multiple groups as an array" do
233
- subject.add_group ["baz", "quux"]
234
- subject.groups.should =~ [:default, :baz, :quux]
214
+ it 'handles multiple groups as an array' do
215
+ subject.add_group ['baz', 'quux']
216
+ expect(subject.groups).to eq([:default, :baz, :quux])
235
217
  end
236
218
  end
237
219
 
238
- describe "#cached_and_location" do
220
+ describe '#cached_and_location' do
239
221
  let(:options) { Hash.new }
240
222
 
241
223
  before do
242
224
  Berkshelf::CachedCookbook.stub(:from_path).and_return(double('cached_cookbook'))
243
225
  end
244
226
 
245
- context "when given a value for :path" do
227
+ context 'when given a value for :path' do
246
228
  before do
247
- berksfile.stub(filepath: "/rspec/Berksfile")
248
- options[:path] = "cookbooks/whatever"
229
+ berksfile.stub(filepath: '/rspec/Berksfile')
230
+ options[:path] = 'cookbooks/whatever'
249
231
  end
250
232
 
251
- it "returns a PathLocation with a path relative to the Berksfile's filepath" do
233
+ it 'returns a PathLocation with a path relative to the Berksfile.filepath' do
252
234
  _, location = subject.cached_and_location(options)
253
235
 
254
- location.path.should eql("/rspec/cookbooks/whatever")
236
+ expect(location.path).to eq('/rspec/cookbooks/whatever')
255
237
  end
256
238
  end
257
239
  end
258
240
 
259
- describe "#downloaded?" do
260
- it "returns true if self.cached_cookbook is not nil" do
241
+ describe '#downloaded?' do
242
+ it 'returns true if self.cached_cookbook is not nil' do
261
243
  subject.stub(:cached_cookbook) { double('cb') }
262
-
263
- subject.downloaded?.should be_true
244
+ expect(subject.downloaded?).to be_true
264
245
  end
265
246
 
266
- it "returns false if self.cached_cookbook is nil" do
247
+ it 'returns false if self.cached_cookbook is nil' do
267
248
  subject.stub(:cached_cookbook) { nil }
249
+ expect(subject.downloaded?).to be_false
250
+ end
251
+ end
252
+
253
+ describe '#to_hash' do
254
+ let(:hash) { subject.to_hash }
255
+
256
+ it 'does not include default values' do
257
+ [:constraint, :locked_version, :site, :git, :ref, :path].each do |key|
258
+ expect(hash).to_not have_key(key)
259
+ end
260
+ end
261
+
262
+ it 'includes the constraint' do
263
+ subject.version_constraint = '~> 1.0.0'
264
+
265
+ expect(hash).to have_key(:constraint)
266
+ expect(hash[:constraint]).to eq('~> 1.0.0')
267
+ end
268
268
 
269
- subject.downloaded?.should be_false
269
+ it 'includes the locked version' do
270
+ subject.cached_cookbook = double('cached', version: '1.2.3')
271
+
272
+ expect(hash).to have_key(:locked_version)
273
+ expect(hash[:locked_version]).to eq('1.2.3')
274
+ end
275
+
276
+ it 'does not include the site if it is the default' do
277
+ location = double('site', api_uri: Berkshelf::CommunityREST::V1_API)
278
+ location.stub(:kind_of?).with(Berkshelf::SiteLocation).and_return(true)
279
+ location.stub(:kind_of?).with(Berkshelf::GitLocation).and_return(false)
280
+ subject.stub(:location).and_return(location)
281
+
282
+ expect(hash).to_not have_key(:site)
283
+ end
284
+
285
+ it 'includes the site' do
286
+ location = double('site', api_uri: 'www.example.com')
287
+ location.stub(:kind_of?).with(Berkshelf::SiteLocation).and_return(true)
288
+ location.stub(:kind_of?).with(Berkshelf::GitLocation).and_return(false)
289
+ subject.stub(:location).and_return(location)
290
+
291
+ expect(hash).to have_key(:site)
292
+ expect(hash[:site]).to eq('www.example.com')
293
+ end
294
+
295
+ it 'includes the git url and ref' do
296
+ location = double('git', uri: 'git://github.com/foo/bar.git', ref: 'abcd1234')
297
+ location.stub(:kind_of?).with(Berkshelf::SiteLocation).and_return(false)
298
+ location.stub(:kind_of?).with(Berkshelf::GitLocation).and_return(true)
299
+ subject.stub(:location).and_return(location)
300
+
301
+ expect(hash).to have_key(:git)
302
+ expect(hash[:git]).to eq('git://github.com/foo/bar.git')
303
+ expect(hash).to have_key(:ref)
304
+ expect(hash[:ref]).to eq('abcd1234')
305
+ end
306
+
307
+ it 'includes a relative path' do
308
+ subject.instance_variable_set(:@options, { path: '~/Development/foo' })
309
+
310
+ expect(hash).to have_key(:path)
311
+ expect(hash[:path]).to eq('~/Development/foo')
270
312
  end
271
313
  end
272
314
 
273
- describe "#to_s" do
274
- it "contains the name, constraint, and groups" do
275
- source = Berkshelf::CookbookSource.new(berksfile, "artifact", constraint: "= 0.10.0")
315
+ describe '#to_s' do
316
+ it 'contains the name, constraint, and groups' do
317
+ source = Berkshelf::CookbookSource.new(berksfile, 'artifact', constraint: '= 0.10.0')
318
+ expect(source.to_s).to eq('#<Berkshelf::CookbookSource: artifact (= 0.10.0)>')
319
+ end
320
+
321
+ context 'given a CookbookSource with an explicit location' do
322
+ it 'contains the name, constraint, groups, and location' do
323
+ source = Berkshelf::CookbookSource.new(berksfile, 'artifact', constraint: '= 0.10.0', site: 'http://cookbooks.opscode.com/api/v1/cookbooks')
324
+ expect(source.to_s).to eq('#<Berkshelf::CookbookSource: artifact (= 0.10.0)>')
325
+ end
326
+ end
327
+ end
276
328
 
277
- source.to_s.should eql("artifact (= 0.10.0) groups: [:default]")
329
+ describe '#inspect' do
330
+ it 'contains the name, constraint, and groups' do
331
+ source = Berkshelf::CookbookSource.new(berksfile, 'artifact', constraint: '= 0.10.0')
332
+ expect(source.inspect).to eq('#<Berkshelf::CookbookSource: artifact (= 0.10.0), locked_version: nil, groups: [:default], location: default>')
278
333
  end
279
334
 
280
- context "given a CookbookSource with an explicit location" do
281
- it "contains the name, constraint, groups, and location" do
282
- source = Berkshelf::CookbookSource.new(berksfile, "artifact", constraint: "= 0.10.0", site: "http://cookbooks.opscode.com/api/v1/cookbooks")
335
+ context 'given a CookbookSource with an explicit location' do
336
+ it 'contains the name, constraint, groups, and location' do
337
+ source = Berkshelf::CookbookSource.new(berksfile, 'artifact', constraint: '= 0.10.0', site: 'http://cookbooks.opscode.com/api/v1/cookbooks')
338
+ expect(source.inspect).to eq("#<Berkshelf::CookbookSource: artifact (= 0.10.0), locked_version: nil, groups: [:default], location: site: 'http://cookbooks.opscode.com/api/v1/cookbooks'>")
339
+ end
340
+ end
283
341
 
284
- source.to_s.should eql("artifact (= 0.10.0) groups: [:default] location: site: 'http://cookbooks.opscode.com/api/v1/cookbooks'")
342
+ context 'given an explicitly locked version' do
343
+ it 'includes the locked_version' do
344
+ source = Berkshelf::CookbookSource.new(berksfile, 'artifact', constraint: '= 0.10.0', site: 'http://cookbooks.opscode.com/api/v1/cookbooks', locked_version: '1.2.3')
345
+ expect(source.inspect).to eq("#<Berkshelf::CookbookSource: artifact (= 0.10.0), locked_version: 1.2.3, groups: [:default], location: site: 'http://cookbooks.opscode.com/api/v1/cookbooks'>")
285
346
  end
286
347
  end
287
348
  end