berkshelf 3.0.0.beta7 → 3.0.0.beta8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +4 -1
  4. data/CONTRIBUTING.md +1 -1
  5. data/Gemfile +0 -1
  6. data/Guardfile +0 -8
  7. data/README.md +33 -13
  8. data/berkshelf.gemspec +3 -3
  9. data/features/commands/install.feature +16 -88
  10. data/features/commands/search.feature +15 -0
  11. data/features/commands/shelf/show.feature +2 -2
  12. data/features/commands/shelf/uninstall.feature +1 -1
  13. data/features/commands/show.feature +3 -3
  14. data/features/commands/update.feature +29 -1
  15. data/features/commands/upload.feature +172 -7
  16. data/features/commands/vendor.feature +32 -0
  17. data/features/json_formatter.feature +26 -24
  18. data/features/lifecycle.feature +285 -0
  19. data/features/lockfile.feature +9 -7
  20. data/features/step_definitions/chef_server_steps.rb +1 -0
  21. data/features/step_definitions/cli_steps.rb +2 -2
  22. data/features/step_definitions/filesystem_steps.rb +2 -4
  23. data/gem_graph.png +0 -0
  24. data/generator_files/chefignore +0 -2
  25. data/lib/berkshelf.rb +39 -14
  26. data/lib/berkshelf/berksfile.rb +161 -113
  27. data/lib/berkshelf/cached_cookbook.rb +2 -2
  28. data/lib/berkshelf/cli.rb +15 -3
  29. data/lib/berkshelf/commands/shelf.rb +3 -7
  30. data/lib/berkshelf/community_rest.rb +9 -9
  31. data/lib/berkshelf/config.rb +3 -3
  32. data/lib/berkshelf/cookbook_generator.rb +0 -8
  33. data/lib/berkshelf/cookbook_store.rb +1 -2
  34. data/lib/berkshelf/dependency.rb +25 -138
  35. data/lib/berkshelf/downloader.rb +41 -7
  36. data/lib/berkshelf/errors.rb +113 -214
  37. data/lib/berkshelf/formatters/base.rb +42 -0
  38. data/lib/berkshelf/formatters/human.rb +145 -0
  39. data/lib/berkshelf/formatters/json.rb +149 -133
  40. data/lib/berkshelf/formatters/null.rb +8 -18
  41. data/lib/berkshelf/init_generator.rb +1 -1
  42. data/lib/berkshelf/installer.rb +115 -104
  43. data/lib/berkshelf/location.rb +22 -121
  44. data/lib/berkshelf/locations/base.rb +75 -0
  45. data/lib/berkshelf/locations/git.rb +196 -0
  46. data/lib/berkshelf/locations/github.rb +8 -0
  47. data/lib/berkshelf/locations/path.rb +78 -0
  48. data/lib/berkshelf/lockfile.rb +452 -290
  49. data/lib/berkshelf/logger.rb +9 -3
  50. data/lib/berkshelf/mixin/logging.rb +4 -9
  51. data/lib/berkshelf/resolver.rb +12 -12
  52. data/lib/berkshelf/source.rb +13 -1
  53. data/lib/berkshelf/version.rb +1 -1
  54. data/spec/fixtures/cookbooks/example_cookbook-0.5.0/metadata.rb +3 -7
  55. data/spec/fixtures/cookbooks/example_cookbook/metadata.rb +3 -6
  56. data/spec/spec_helper.rb +5 -6
  57. data/spec/support/matchers/file_system_matchers.rb +4 -0
  58. data/spec/support/shared_examples/formatter.rb +11 -0
  59. data/spec/unit/berkshelf/berksfile_spec.rb +25 -28
  60. data/spec/unit/berkshelf/cli_spec.rb +19 -11
  61. data/spec/unit/berkshelf/dependency_spec.rb +4 -164
  62. data/spec/unit/berkshelf/formatters/base_spec.rb +35 -0
  63. data/spec/unit/berkshelf/formatters/human_spec.rb +7 -0
  64. data/spec/unit/berkshelf/formatters/json_spec.rb +7 -0
  65. data/spec/unit/berkshelf/formatters/null_spec.rb +7 -11
  66. data/spec/unit/berkshelf/location_spec.rb +16 -144
  67. data/spec/unit/berkshelf/locations/base_spec.rb +80 -0
  68. data/spec/unit/berkshelf/locations/git_spec.rb +249 -0
  69. data/spec/unit/berkshelf/locations/path_spec.rb +107 -0
  70. data/spec/unit/berkshelf/lockfile_parser_spec.rb +3 -3
  71. data/spec/unit/berkshelf/lockfile_spec.rb +55 -11
  72. data/spec/unit/berkshelf/logger_spec.rb +2 -2
  73. data/spec/unit/berkshelf/mixin/logging_spec.rb +5 -9
  74. data/spec/unit/berkshelf/source_spec.rb +32 -13
  75. data/spec/unit/berkshelf_spec.rb +6 -9
  76. metadata +33 -33
  77. data/.ruby-version +0 -1
  78. data/berkshelf-complete.sh +0 -75
  79. data/lib/berkshelf/formatters.rb +0 -110
  80. data/lib/berkshelf/formatters/human_readable.rb +0 -142
  81. data/lib/berkshelf/git.rb +0 -204
  82. data/lib/berkshelf/locations/git_location.rb +0 -135
  83. data/lib/berkshelf/locations/github_location.rb +0 -55
  84. data/lib/berkshelf/locations/mercurial_location.rb +0 -114
  85. data/lib/berkshelf/locations/path_location.rb +0 -88
  86. data/lib/berkshelf/mercurial.rb +0 -146
  87. data/lib/berkshelf/mixin.rb +0 -7
  88. data/spec/support/mercurial.rb +0 -123
  89. data/spec/unit/berkshelf/formatters_spec.rb +0 -114
  90. data/spec/unit/berkshelf/git_spec.rb +0 -312
  91. data/spec/unit/berkshelf/locations/git_location_spec.rb +0 -126
  92. data/spec/unit/berkshelf/locations/mercurial_location_spec.rb +0 -131
  93. data/spec/unit/berkshelf/locations/path_location_spec.rb +0 -25
  94. data/spec/unit/berkshelf/mercurial_spec.rb +0 -172
@@ -1,12 +1,18 @@
1
1
  module Berkshelf
2
- Logger = Ridley.logger
3
-
4
- Logger.class.class_eval do
2
+ class Logger < Ridley::Logging::Logger
5
3
  alias_method :fatal, :error
6
4
 
7
5
  def deprecate(message)
8
6
  trace = caller.join("\n\t")
9
7
  warn "DEPRECATION WARNING: #{message}\n\t#{trace}"
10
8
  end
9
+
10
+ # Log an exception and its backtrace to FATAL
11
+ #
12
+ # @param [Exception] ex
13
+ def exception(ex)
14
+ log.fatal("#{ex.class}: #{ex}")
15
+ log.fatal(ex.backtrace.join("\n")) unless ex.backtrace.nil?
16
+ end
11
17
  end
12
18
  end
@@ -1,17 +1,12 @@
1
1
  module Berkshelf
2
2
  module Mixin
3
3
  module Logging
4
- def log
5
- Berkshelf::Logger
6
- end
4
+ attr_writer :logger
7
5
 
8
- # Log an exception and its backtrace to FATAL
9
- #
10
- # @param [Exception] ex
11
- def log_exception(ex)
12
- log.fatal("#{ex.class}: #{ex}")
13
- log.fatal(ex.backtrace.join("\n")) unless ex.backtrace.nil?
6
+ def logger
7
+ @logger ||= Berkshelf::Logger.new(STDOUT)
14
8
  end
9
+ alias_method :log, :logger
15
10
  end
16
11
  end
17
12
  end
@@ -4,18 +4,18 @@ module Berkshelf
4
4
 
5
5
  extend Forwardable
6
6
 
7
- # @return [Berkshelf::Berksfile]
7
+ # @return [Berksfile]
8
8
  attr_reader :berksfile
9
9
 
10
10
  # @return [Resolver::Graph]
11
11
  attr_reader :graph
12
12
 
13
- # @return [Array<Berkshelf::Dependency>]
13
+ # @return [Array<Dependency>]
14
14
  # an array of dependencies that must be satisfied
15
15
  attr_reader :demands
16
16
 
17
- # @param [Berkshelf::Berksfile] berksfile
18
- # @param [Array<Berkshelf::Dependency>, Berkshelf::Dependency] demands
17
+ # @param [Berksfile] berksfile
18
+ # @param [Array<Dependency>, Dependency] demands
19
19
  # a dependency, or array of dependencies, which must be satisfied
20
20
  def initialize(berksfile, demands = [])
21
21
  @berksfile = berksfile
@@ -27,12 +27,12 @@ module Berkshelf
27
27
 
28
28
  # Add the given dependency to the collection of demands
29
29
  #
30
- # @param [Berkshelf::Dependency] demand
30
+ # @param [Dependency] demand
31
31
  # add a dependency that must be satisfied to the graph
32
32
  #
33
33
  # @raise [DuplicateDemand]
34
34
  #
35
- # @return [Array<Berkshelf::Dependency>]
35
+ # @return [Array<Dependency>]
36
36
  def add_demand(demand)
37
37
  if has_demand?(demand)
38
38
  raise DuplicateDemand, "A demand named '#{demand.name}' is already present."
@@ -44,7 +44,7 @@ module Berkshelf
44
44
  # Add dependencies of a locally cached cookbook which will take precedence over anything
45
45
  # found in the universe.
46
46
  #
47
- # @param [Berkshelf::CachedCookbook] cookbook
47
+ # @param [CachedCookbook] cookbook
48
48
  #
49
49
  # @return [Hash]
50
50
  def add_explicit_dependencies(cookbook)
@@ -63,7 +63,7 @@ module Berkshelf
63
63
  # Finds a solution for the currently added dependencies and their dependencies and
64
64
  # returns an array of CachedCookbooks.
65
65
  #
66
- # @raise [Berkshelf::NoSolutionError] when a solution could not be found for the given demands
66
+ # @raise [NoSolutionError] when a solution could not be found for the given demands
67
67
  #
68
68
  # @return [Array<Array<String, String, Dependency>>]
69
69
  def resolve
@@ -77,15 +77,15 @@ module Berkshelf
77
77
  dependency
78
78
  end
79
79
  rescue Solve::Errors::NoSolutionError
80
- raise Berkshelf::NoSolutionError.new(demands)
80
+ raise NoSolutionError.new(demands)
81
81
  end
82
82
 
83
83
  # Retrieve the given demand from the resolver
84
84
  #
85
- # @param [Berkshelf::Dependency, #to_s] demand
85
+ # @param [Dependency, #to_s] demand
86
86
  # name of the dependency to return
87
87
  #
88
- # @return [Berkshelf::Dependency]
88
+ # @return [Dependency]
89
89
  def [](demand)
90
90
  name = demand.respond_to?(:name) ? demand.name : demand.to_s
91
91
  demands.find { |demand| demand.name == name }
@@ -94,7 +94,7 @@ module Berkshelf
94
94
 
95
95
  # Check if the given demand has been added to the resolver
96
96
  #
97
- # @param [Berkshelf::Dependency, #to_s] demand
97
+ # @param [Dependency, #to_s] demand
98
98
  # the demand or the name of the demand to check for
99
99
  def has_demand?(demand)
100
100
  !get_demand(demand).nil?
@@ -44,13 +44,25 @@ module Berkshelf
44
44
  universe.find { |cookbook| cookbook.name == name && cookbook.version == version }
45
45
  end
46
46
 
47
+ # The list of remote cookbooks that match the given query.
48
+ #
49
+ # @param [String] name
50
+ #
51
+ # @return [Array<APIClient::RemoteCookbook]
52
+ def search(name)
53
+ universe
54
+ .select { |cookbook| cookbook.name =~ Regexp.new(name) }
55
+ .group_by(&:name)
56
+ .collect { |name, versions| versions.max_by(&:version) }
57
+ end
58
+
47
59
  # Determine if this source is a "default" source, as defined in the
48
60
  # {Berksfile}.
49
61
  #
50
62
  # @return [true, false]
51
63
  # true if this a default source, false otherwise
52
64
  def default?
53
- uri == Berksfile::DEFAULT_API_URL
65
+ @default_ ||= @uri.host == URI.parse(Berksfile::DEFAULT_API_URL).host
54
66
  end
55
67
 
56
68
  # @param [String] name
@@ -1,3 +1,3 @@
1
1
  module Berkshelf
2
- VERSION = "3.0.0.beta7"
2
+ VERSION = '3.0.0.beta8'
3
3
  end
@@ -1,7 +1,3 @@
1
- name "example_cookbook"
2
- maintainer "Josiah Kiehl"
3
- maintainer_email "jkiehl@riotgames.com"
4
- license "DO WHAT YOU WANT CAUSE A PIRATE IS FREE"
5
- description "Installs/Configures example_cookbook"
6
- long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
7
- version "0.5.0"
1
+ name 'example_cookbook'
2
+ maintainer 'Berkshelf Core'
3
+ version '0.5.0'
@@ -1,6 +1,3 @@
1
- maintainer "Josiah Kiehl"
2
- maintainer_email "jkiehl@riotgames.com"
3
- license "DO WHAT YOU WANT CAUSE A PIRATE IS FREE"
4
- description "Installs/Configures example_cookbook"
5
- long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
6
- version "0.5.0"
1
+ name 'example_cookbook'
2
+ maintainer 'Berkshelf Core'
3
+ version '0.5.0'
data/spec/spec_helper.rb CHANGED
@@ -28,16 +28,15 @@ Spork.prefork do
28
28
  config.filter_run focus: true
29
29
  config.run_all_when_everything_filtered = true
30
30
 
31
- config.before(:suite) do
32
- WebMock.disable_net_connect!(allow_localhost: true, net_http_connect_on_start: true)
33
- Berkshelf::RSpec::ChefServer.start
34
- Berkshelf::API::RSpec::Server.start unless windows?
31
+ config.before(:each) do
35
32
  Berkshelf.set_format(:null)
36
33
  Berkshelf.ui.mute!
37
34
  end
38
35
 
39
- config.after(:suite) do
40
- Berkshelf.ui.unmute!
36
+ config.before(:suite) do
37
+ WebMock.disable_net_connect!(allow_localhost: true, net_http_connect_on_start: true)
38
+ Berkshelf::RSpec::ChefServer.start
39
+ Berkshelf::API::RSpec::Server.start unless windows?
41
40
  end
42
41
 
43
42
  config.before(:all) do
@@ -115,6 +115,10 @@ module Berkshelf
115
115
  end
116
116
  end
117
117
 
118
+ def description
119
+ "have structure"
120
+ end
121
+
118
122
  def matches?(root)
119
123
  @failure = catch :failure do
120
124
  super
@@ -0,0 +1,11 @@
1
+ module Berkshelf
2
+ shared_examples 'a formatter object' do
3
+ BaseFormatter.instance_methods(false).each do |name|
4
+ next if name == :cleanup_hook
5
+
6
+ it "implements ##{name}" do
7
+ expect(subject.method(name).owner).to eq(described_class)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -320,6 +320,14 @@ describe Berkshelf::Berksfile do
320
320
  end
321
321
 
322
322
  describe '#upload' do
323
+ let(:graph) { double(locks: []) }
324
+ let(:lockfile) { double(present?: true, trusted?: true, graph: graph) }
325
+
326
+ before do
327
+ Berkshelf.stub(:config).and_return(berkshelf_config)
328
+ subject.stub(:lockfile).and_return(lockfile)
329
+ end
330
+
323
331
  let(:options) { Hash.new }
324
332
  let(:chef_config) do
325
333
  double('chef-config',
@@ -343,15 +351,9 @@ describe Berkshelf::Berksfile do
343
351
  }
344
352
  }
345
353
  end
346
- let(:installed_cookbooks) { Array.new }
347
354
 
348
355
  let(:upload) { subject.upload(options) }
349
356
 
350
- before do
351
- Berkshelf.stub(:config).and_return(berkshelf_config)
352
- subject.should_receive(:install).and_return(installed_cookbooks)
353
- end
354
-
355
357
  context 'when there is no value for :chef_server_url' do
356
358
  before { chef_config.stub(chef_server_url: nil) }
357
359
  let(:message) { 'Missing required attribute in your Berkshelf configuration: chef.server_url' }
@@ -443,39 +445,34 @@ describe Berkshelf::Berksfile do
443
445
  end
444
446
 
445
447
  context 'when validate is passed' do
448
+ let(:mysql_dependency) { double(name: 'mysql', metadata?: false, dependencies: []) }
449
+ let(:mysql_cookbook) { double(cookbook_name: 'mysql', path: 'path') }
450
+
446
451
  let(:options) do
447
452
  {
448
- force: false,
449
- freeze: true,
453
+ force: false,
454
+ freeze: true,
450
455
  validate: false,
451
- name: "cookbook"
456
+ name: mysql_cookbook.cookbook_name
452
457
  }
453
458
  end
454
459
  let(:ridley_options) do
455
- default_ridley_options.merge(
456
- { server_url: 'http://configured-chef-server/'})
460
+ default_ridley_options.merge({ server_url: 'http://configured-chef-server/'})
457
461
  end
458
- let(:cookbook) { double('cookbook', cookbook_name: 'cookbook', path: 'path', version: '1.0.0') }
459
- let(:installed_cookbooks) { [ cookbook ] }
460
- let(:cookbook_resource) { double('cookbook') }
461
462
  let(:conn) { double('conn') }
462
463
 
463
- it 'uses the passed in :validate' do
464
- Ridley.should_receive(:open).with(ridley_options).and_yield(conn)
465
- conn.should_receive(:cookbook).and_return(cookbook_resource)
466
- cookbook_resource.should_receive(:upload).with('path', options )
467
- upload
464
+ before do
465
+ subject.stub(:dependencies).and_return([mysql_dependency])
466
+ graph.stub(:find).with(mysql_dependency).and_return(mysql_dependency)
467
+ lockfile.stub(:retrieve).with(mysql_dependency).and_return(mysql_cookbook)
468
468
  end
469
- end
470
- end
471
-
472
- describe "#remove_dependency" do
473
- let(:dependency) { "nginx" }
474
- before { subject.add_dependency(dependency) }
475
469
 
476
- it "removes a dependencies from the list" do
477
- subject.remove_dependency(dependency)
478
- expect(subject.dependencies).to have(0).items
470
+ it 'uses the passed in :validate' do
471
+ expect(Ridley).to receive(:open).and_yield(conn)
472
+ expect(conn).to receive(:cookbook).and_return(mysql_cookbook)
473
+ expect(mysql_cookbook).to receive(:upload).with('path', options)
474
+ subject.upload('mysql', options)
475
+ end
479
476
  end
480
477
  end
481
478
 
@@ -1,17 +1,25 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Berkshelf::Cli do
4
- let(:subject) { described_class.new }
5
- let(:berksfile) { double('Berksfile') }
6
- let(:cookbooks) { ['mysql'] }
3
+ module Berkshelf
4
+ describe Cli do
5
+ let(:subject) { described_class.new }
6
+ let(:berksfile) { double('Berksfile') }
7
+ let(:cookbooks) { ['mysql'] }
7
8
 
8
- describe '#upload' do
9
- it 'calls to upload with params if passed in cli' do
10
- Berkshelf::Berksfile.should_receive(:from_file).and_return(berksfile)
11
- berksfile.should_receive(:upload).with(include(skip_syntax_check: true, freeze: false, cookbooks: cookbooks))
12
- subject.options[:skip_syntax_check] = true
13
- subject.options[:no_freeze] = true
14
- subject.upload('mysql')
9
+ before do
10
+ Berksfile.stub(:from_options).and_return(berksfile)
11
+ end
12
+
13
+ describe '#upload' do
14
+ it 'calls to upload with params if passed in cli' do
15
+ expect(berksfile).to receive(:upload).with(cookbooks,
16
+ include(skip_syntax_check: true, freeze: false)
17
+ )
18
+
19
+ subject.options[:skip_syntax_check] = true
20
+ subject.options[:no_freeze] = true
21
+ subject.upload('mysql')
22
+ end
15
23
  end
16
24
  end
17
25
  end
@@ -57,29 +57,7 @@ describe Berkshelf::Dependency do
57
57
  end
58
58
 
59
59
  it 'points to the specified path' do
60
- expect(location.path).to eq(path)
61
- end
62
- end
63
-
64
- context 'given an invalid option' do
65
- it 'raises BerkshelfError with a friendly message' do
66
- expect {
67
- described_class.new(berksfile, cookbook_name, invalid_opt: 'thisisnotvalid')
68
- }.to raise_error(Berkshelf::BerkshelfError, "Invalid options for dependency: 'invalid_opt'.")
69
- end
70
-
71
- it 'raises BerkshelfError with a messaging containing all of the invalid options' do
72
- expect {
73
- described_class.new(berksfile, cookbook_name, invalid_one: 'one', invalid_two: 'two')
74
- }.to raise_error(Berkshelf::BerkshelfError, "Invalid options for dependency: 'invalid_one', 'invalid_two'.")
75
- end
76
- end
77
-
78
- context 'given multiple location options' do
79
- it 'raises with an Berkshelf::BerkshelfError' do
80
- expect {
81
- described_class.new(berksfile, cookbook_name, path: '/something', git: 'something')
82
- }.to raise_error(Berkshelf::BerkshelfError)
60
+ expect(location.options[:path]).to eq(path)
83
61
  end
84
62
  end
85
63
 
@@ -110,58 +88,6 @@ describe Berkshelf::Dependency do
110
88
  end
111
89
  end
112
90
  end
113
-
114
- describe "::add_valid_option" do
115
- before do
116
- @original = described_class.class_variable_get :@@valid_options
117
- described_class.class_variable_set :@@valid_options, []
118
- end
119
-
120
- after do
121
- described_class.class_variable_set :@@valid_options, @original
122
- end
123
-
124
- it 'adds an option to the list of valid options' do
125
- described_class.add_valid_option(:one)
126
-
127
- expect(described_class.valid_options).to have(1).item
128
- expect(described_class.valid_options).to include(:one)
129
- end
130
-
131
- it 'does not add duplicate options to the list of valid options' do
132
- described_class.add_valid_option(:one)
133
- described_class.add_valid_option(:one)
134
-
135
- expect(described_class.valid_options).to have(1).item
136
- end
137
- end
138
-
139
- describe "::add_location_key" do
140
- before do
141
- @original = described_class.class_variable_get :@@location_keys
142
- described_class.class_variable_set :@@location_keys, {}
143
- end
144
-
145
- after do
146
- described_class.class_variable_set :@@location_keys, @original
147
- end
148
-
149
- it 'adds a location key and the associated class to the list of valid locations' do
150
- described_class.add_location_key(:git, described_class)
151
-
152
- expect(described_class.location_keys).to have(1).item
153
- expect(described_class.location_keys).to include(:git)
154
- expect(described_class.location_keys[:git]).to eq(described_class)
155
- end
156
-
157
- it 'does not add duplicate location keys to the list of location keys' do
158
- described_class.add_location_key(:git, described_class)
159
- described_class.add_location_key(:git, described_class)
160
-
161
- expect(described_class.location_keys).to have(1).item
162
- expect(described_class.location_keys).to include(:git)
163
- end
164
- end
165
91
  end
166
92
 
167
93
  subject { described_class.new(berksfile, cookbook_name) }
@@ -193,101 +119,15 @@ describe Berkshelf::Dependency do
193
119
  describe "#cached_cookbook"
194
120
  describe "#download"
195
121
 
196
- describe '#downloaded?' do
122
+ describe '#installed?' do
197
123
  it 'returns true if self.cached_cookbook is not nil' do
198
124
  subject.stub(:cached_cookbook) { double('cb') }
199
- expect(subject.downloaded?).to be_true
125
+ expect(subject.installed?).to be_true
200
126
  end
201
127
 
202
128
  it 'returns false if self.cached_cookbook is nil' do
203
129
  subject.stub(:cached_cookbook) { nil }
204
- expect(subject.downloaded?).to be_false
205
- end
206
- end
207
-
208
- describe '#to_hash' do
209
- let(:hash) { subject.to_hash }
210
-
211
- it 'does not include default values' do
212
- [:constraint, :locked_version, :site, :git, :ref, :path].each do |key|
213
- expect(hash).to_not have_key(key)
214
- end
215
- end
216
-
217
- it 'includes the locked version' do
218
- subject.stub(locked_version: double('cached', to_s: '1.2.3'))
219
-
220
- expect(hash).to have_key(:locked_version)
221
- expect(hash[:locked_version]).to eq('1.2.3')
222
- end
223
-
224
- it 'includes the git url and ref' do
225
- location = double('git', uri: 'git://github.com/foo/bar.git', ref: 'abcd1234', rel: nil, download: nil)
226
- location.stub(:kind_of?).and_return(false)
227
- location.stub(:kind_of?).with(Berkshelf::GitLocation).and_return(true)
228
- subject.stub(:location).and_return(location)
229
-
230
- expect(hash).to have_key(:git)
231
- expect(hash[:git]).to eq('git://github.com/foo/bar.git')
232
- expect(hash).to have_key(:ref)
233
- expect(hash[:ref]).to eq('abcd1234')
234
- end
235
-
236
- it 'includes the git url and rel' do
237
- location = double('git', uri: 'git://github.com/foo/bar.git', ref: nil, rel: 'cookbooks/foo', download: nil)
238
- location.stub(:kind_of?).and_return(false)
239
- location.stub(:kind_of?).with(Berkshelf::GitLocation).and_return(true)
240
- subject.stub(:location).and_return(location)
241
-
242
- expect(hash).to have_key(:git)
243
- expect(hash[:git]).to eq('git://github.com/foo/bar.git')
244
- expect(hash).to have_key(:rel)
245
- expect(hash[:rel]).to eq('cookbooks/foo')
246
- end
247
-
248
- it 'includes a relative path' do
249
- location = double('path', relative_path: '../dev/foo')
250
- location.stub(:kind_of?).and_return(false)
251
- location.stub(:kind_of?).with(Berkshelf::PathLocation).and_return(true)
252
- subject.stub(:location).and_return(location)
253
-
254
- expect(hash).to have_key(:path)
255
- expect(hash[:path]).to eq('../dev/foo')
256
- end
257
- end
258
-
259
- describe "#scm_location?" do
260
- let(:options) { Hash.new }
261
- subject { described_class.new(berksfile, cookbook_name, options).scm_location? }
262
-
263
- context "when the location is a GitLocation" do
264
- let(:options) { { git: "git@github.com:berkshelf/berkshelf.git" } }
265
- it { should be_true }
266
- end
267
-
268
- context "when the location is a GithubLocation" do
269
- let(:options) { { github: "berkshelf/berkshelf" } }
270
- it { should be_true }
271
- end
272
-
273
- context "when the location is a PathLocation" do
274
- let(:options) { { path: fixtures_path.join('cookbooks', 'example_cookbook') } }
275
- it { should be_false }
276
- end
277
- end
278
-
279
- describe "#path_location?" do
280
- let(:options) { Hash.new }
281
- subject { described_class.new(berksfile, cookbook_name, options).path_location? }
282
-
283
- context "when the location is a PathLocation" do
284
- let(:options) { { path: fixtures_path.join("cookbooks", "example_cookbook") } }
285
- it { should be_true }
286
- end
287
-
288
- context "when the location is not a PathLocation" do
289
- let(:options) { { github: "berkshelf/berkshelf" } }
290
- it { should be_false }
130
+ expect(subject.installed?).to be_false
291
131
  end
292
132
  end
293
133
  end