berkshelf 0.4.0.rc4 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/Guardfile +6 -3
- data/features/default_locations.feature +122 -0
- data/features/install.feature +20 -4
- data/features/lockfile.feature +1 -6
- data/features/update.feature +2 -3
- data/generator_files/Berksfile.erb +2 -0
- data/generator_files/gitignore.erb +6 -0
- data/lib/berkshelf.rb +6 -10
- data/lib/berkshelf/berksfile.rb +203 -14
- data/lib/berkshelf/cached_cookbook.rb +5 -1
- data/lib/berkshelf/cli.rb +4 -0
- data/lib/berkshelf/cookbook_source.rb +49 -91
- data/lib/berkshelf/cookbook_store.rb +2 -0
- data/lib/berkshelf/downloader.rb +71 -51
- data/lib/berkshelf/errors.rb +7 -3
- data/lib/berkshelf/formatters.rb +6 -6
- data/lib/berkshelf/location.rb +171 -0
- data/lib/berkshelf/locations/chef_api_location.rb +252 -0
- data/lib/berkshelf/locations/git_location.rb +76 -0
- data/lib/berkshelf/locations/path_location.rb +38 -0
- data/lib/berkshelf/locations/site_location.rb +150 -0
- data/lib/berkshelf/lockfile.rb +2 -2
- data/lib/berkshelf/resolver.rb +12 -15
- data/lib/berkshelf/uploader.rb +2 -9
- data/lib/berkshelf/version.rb +1 -1
- data/spec/fixtures/lockfile_spec/without_lock/.gitkeep +0 -0
- data/spec/support/chef_api.rb +7 -1
- data/spec/unit/berkshelf/berksfile_spec.rb +157 -12
- data/spec/unit/berkshelf/cached_cookbook_spec.rb +19 -0
- data/spec/unit/berkshelf/cookbook_generator_spec.rb +1 -0
- data/spec/unit/berkshelf/cookbook_source_spec.rb +25 -35
- data/spec/unit/berkshelf/cookbook_store_spec.rb +3 -3
- data/spec/unit/berkshelf/downloader_spec.rb +171 -43
- data/spec/unit/berkshelf/formatters_spec.rb +13 -16
- data/spec/unit/berkshelf/{cookbook_source/location_spec.rb → location_spec.rb} +10 -10
- data/spec/unit/berkshelf/{cookbook_source → locations}/chef_api_location_spec.rb +4 -4
- data/spec/unit/berkshelf/{cookbook_source → locations}/git_location_spec.rb +8 -8
- data/spec/unit/berkshelf/{cookbook_source → locations}/path_location_spec.rb +5 -5
- data/spec/unit/berkshelf/{cookbook_source → locations}/site_location_spec.rb +17 -3
- data/spec/unit/berkshelf/lockfile_spec.rb +26 -17
- data/spec/unit/berkshelf/resolver_spec.rb +6 -5
- data/spec/unit/berkshelf/uploader_spec.rb +6 -4
- metadata +27 -31
- data/lib/berkshelf/cookbook_source/chef_api_location.rb +0 -256
- data/lib/berkshelf/cookbook_source/git_location.rb +0 -78
- data/lib/berkshelf/cookbook_source/location.rb +0 -167
- data/lib/berkshelf/cookbook_source/path_location.rb +0 -40
- data/lib/berkshelf/cookbook_source/site_location.rb +0 -149
- data/lib/berkshelf/dsl.rb +0 -45
- data/lib/berkshelf/tx_result.rb +0 -12
- data/lib/berkshelf/tx_result_set.rb +0 -37
- data/spec/fixtures/lockfile_spec/without_lock/Berksfile.lock +0 -5
- data/spec/unit/berkshelf/dsl_spec.rb +0 -42
- data/spec/unit/berkshelf/tx_result_set_spec.rb +0 -77
- data/spec/unit/berkshelf/tx_result_spec.rb +0 -21
data/lib/berkshelf/lockfile.rb
CHANGED
@@ -28,9 +28,9 @@ module Berkshelf
|
|
28
28
|
def get_source_definition(source)
|
29
29
|
definition = "cookbook '#{source.name}'"
|
30
30
|
|
31
|
-
if source.location.is_a?(
|
31
|
+
if source.location.is_a?(GitLocation)
|
32
32
|
definition += ", :git => '#{source.location.uri}', :ref => '#{source.location.branch || 'HEAD'}'"
|
33
|
-
elsif source.location.is_a?(
|
33
|
+
elsif source.location.is_a?(PathLocation)
|
34
34
|
definition += ", :path => '#{source.location.path}'"
|
35
35
|
else
|
36
36
|
definition += ", :locked_version => '#{source.locked_version}'"
|
data/lib/berkshelf/resolver.rb
CHANGED
@@ -6,8 +6,10 @@ module Berkshelf
|
|
6
6
|
attr_reader :graph
|
7
7
|
|
8
8
|
# @param [Downloader] downloader
|
9
|
-
# @param [
|
10
|
-
|
9
|
+
# @param [Hash] options
|
10
|
+
#
|
11
|
+
# @option options [Array<CookbookSource>, CookbookSource] sources
|
12
|
+
def initialize(downloader, options = {})
|
11
13
|
@downloader = downloader
|
12
14
|
@graph = Solve::Graph.new
|
13
15
|
@sources = Hash.new
|
@@ -16,11 +18,11 @@ module Berkshelf
|
|
16
18
|
# not, then one of the dependencies of a source that is added
|
17
19
|
# may take precedence over an explicitly set source that appears
|
18
20
|
# later in the iterator.
|
19
|
-
Array(sources).each do |source|
|
21
|
+
Array(options[:sources]).each do |source|
|
20
22
|
add_source(source, false)
|
21
23
|
end
|
22
24
|
|
23
|
-
Array(sources).each do |source|
|
25
|
+
Array(options[:sources]).each do |source|
|
24
26
|
add_source_dependencies(source)
|
25
27
|
end
|
26
28
|
end
|
@@ -41,7 +43,7 @@ module Berkshelf
|
|
41
43
|
raise DuplicateSourceDefined, "A source named '#{source.name}' is already present."
|
42
44
|
end
|
43
45
|
|
44
|
-
|
46
|
+
@sources[source.name] = source
|
45
47
|
use_source(source) || install_source(source)
|
46
48
|
|
47
49
|
graph.artifacts(source.name, source.cached_cookbook.version)
|
@@ -66,7 +68,7 @@ module Berkshelf
|
|
66
68
|
source.cached_cookbook.dependencies.each do |name, constraint|
|
67
69
|
next if has_source?(name)
|
68
70
|
|
69
|
-
add_source(CookbookSource.new(name, constraint))
|
71
|
+
add_source(CookbookSource.new(name, constraint: constraint))
|
70
72
|
end
|
71
73
|
end
|
72
74
|
|
@@ -116,17 +118,12 @@ module Berkshelf
|
|
116
118
|
|
117
119
|
attr_reader :downloader
|
118
120
|
|
119
|
-
# @param [CookbookSource] source
|
120
|
-
def set_source(source)
|
121
|
-
@sources[source.name] = source
|
122
|
-
end
|
123
|
-
|
124
121
|
# @param [Berkshelf::CookbookSource] source
|
125
122
|
#
|
126
123
|
# @return [Boolean]
|
127
124
|
def install_source(source)
|
128
|
-
downloader.download
|
129
|
-
Berkshelf.formatter.install source.name,
|
125
|
+
cached_cookbook, location = downloader.download(source)
|
126
|
+
Berkshelf.formatter.install source.name, cached_cookbook.version, location
|
130
127
|
end
|
131
128
|
|
132
129
|
# Use the given source to create a constraint solution if the source has been downloaded or can
|
@@ -148,7 +145,7 @@ module Berkshelf
|
|
148
145
|
cached = source.cached_cookbook
|
149
146
|
source.location.validate_cached(cached)
|
150
147
|
else
|
151
|
-
if source.location.is_a?(
|
148
|
+
if source.location.is_a?(GitLocation)
|
152
149
|
return false
|
153
150
|
end
|
154
151
|
|
@@ -158,7 +155,7 @@ module Berkshelf
|
|
158
155
|
get_source(source).cached_cookbook = cached
|
159
156
|
end
|
160
157
|
|
161
|
-
path = source.location.is_a?(
|
158
|
+
path = source.location.is_a?(PathLocation) ? "#{source.location}" : nil
|
162
159
|
Berkshelf.formatter.use cached.cookbook_name, cached.version, path
|
163
160
|
|
164
161
|
true
|
data/lib/berkshelf/uploader.rb
CHANGED
@@ -41,15 +41,8 @@ module Berkshelf
|
|
41
41
|
# Freeze the uploaded Cookbook on the Chef Server so that it cannot be
|
42
42
|
# overwritten
|
43
43
|
#
|
44
|
-
# @return [
|
44
|
+
# @return [Boolean]
|
45
45
|
def upload(cookbook, options = {})
|
46
|
-
upload!(cookbook, options)
|
47
|
-
rescue BerkshelfError => e
|
48
|
-
TXResult.new(:error, e.message)
|
49
|
-
end
|
50
|
-
|
51
|
-
# @see #upload
|
52
|
-
def upload!(cookbook, options = {})
|
53
46
|
cookbook.validate!
|
54
47
|
|
55
48
|
checksums = cookbook.checksums.dup
|
@@ -58,7 +51,7 @@ module Berkshelf
|
|
58
51
|
commit_sandbox(new_sandbox)
|
59
52
|
save_cookbook(cookbook, options)
|
60
53
|
|
61
|
-
|
54
|
+
true
|
62
55
|
end
|
63
56
|
|
64
57
|
private
|
data/lib/berkshelf/version.rb
CHANGED
File without changes
|
data/spec/support/chef_api.rb
CHANGED
@@ -14,7 +14,7 @@ module Berkshelf
|
|
14
14
|
|
15
15
|
def upload_cookbook(path)
|
16
16
|
cached = CachedCookbook.from_store_path(path)
|
17
|
-
uploader.upload
|
17
|
+
uploader.upload(cached)
|
18
18
|
end
|
19
19
|
|
20
20
|
# Remove all versions of all cookbooks from the Chef Server defined in your
|
@@ -83,6 +83,12 @@ EOF
|
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
86
|
+
if options[:recommendations]
|
87
|
+
options[:recommendations].each do |name, constraint|
|
88
|
+
metadata << "recommends '#{name}', '#{constraint}'\n"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
86
92
|
File.write(cookbook_path.join("metadata.rb"), metadata)
|
87
93
|
cookbook_path
|
88
94
|
end
|
@@ -62,20 +62,125 @@ EOF
|
|
62
62
|
let(:source_one) { double('source_one', name: "nginx") }
|
63
63
|
let(:source_two) { double('source_two', name: "mysql") }
|
64
64
|
|
65
|
-
subject
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
65
|
+
subject { Berksfile.new(tmp_path.join("Berksfile")) }
|
66
|
+
|
67
|
+
describe "#cookbook" do
|
68
|
+
let(:name) { "artifact" }
|
69
|
+
let(:constraint) { double('constraint') }
|
70
|
+
let(:default_options) { { group: [] } }
|
71
|
+
|
72
|
+
it "sends the add_source message with the name, constraint, and options to the instance of the includer" do
|
73
|
+
subject.should_receive(:add_source).with(name, constraint, default_options)
|
74
|
+
|
75
|
+
subject.cookbook name, constraint, default_options
|
76
|
+
end
|
77
|
+
|
78
|
+
it "merges the default options into specified options" do
|
79
|
+
subject.should_receive(:add_source).with(name, constraint, path: "/Users/reset", group: [])
|
80
|
+
|
81
|
+
subject.cookbook name, constraint, path: "/Users/reset"
|
82
|
+
end
|
83
|
+
|
84
|
+
it "converts a single specified group option into an array of groups" do
|
85
|
+
subject.should_receive(:add_source).with(name, constraint, group: [:production])
|
86
|
+
|
87
|
+
subject.cookbook name, constraint, group: :production
|
88
|
+
end
|
89
|
+
|
90
|
+
context "when no constraint specified" do
|
91
|
+
it "sends the add_source message with a nil value for constraint" do
|
92
|
+
subject.should_receive(:add_source).with(name, nil, default_options)
|
93
|
+
|
94
|
+
subject.cookbook name, default_options
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context "when no options specified" do
|
99
|
+
it "sends the add_source message with an empty Hash for the value of options" do
|
100
|
+
subject.should_receive(:add_source).with(name, constraint, default_options)
|
101
|
+
|
102
|
+
subject.cookbook name, constraint
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe '#group' do
|
108
|
+
let(:name) { "artifact" }
|
109
|
+
let(:group) { "production" }
|
110
|
+
|
111
|
+
it "sends the add_source message with an array of groups determined by the parameter passed to the group block" do
|
112
|
+
subject.should_receive(:add_source).with(name, nil, group: [group])
|
113
|
+
|
114
|
+
subject.group group do
|
115
|
+
subject.cookbook name
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe "#metadata" do
|
121
|
+
let(:cb_path) { fixtures_path.join('cookbooks/example_cookbook') }
|
122
|
+
subject { Berksfile.new(cb_path.join("Berksfile")) }
|
123
|
+
|
124
|
+
before(:each) { Dir.chdir(cb_path) }
|
125
|
+
|
126
|
+
it "sends the add_source message with an explicit version constraint and the path to the cookbook" do
|
127
|
+
subject.should_receive(:add_source).with("example_cookbook", "= 0.5.0", path: cb_path.to_s)
|
128
|
+
|
129
|
+
subject.metadata
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
describe "#site" do
|
134
|
+
let(:uri) { "http://opscode/v1" }
|
135
|
+
|
136
|
+
it "sends the add_location to the instance of the implementing class with a SiteLocation" do
|
137
|
+
subject.should_receive(:add_location).with(:site, uri)
|
138
|
+
|
139
|
+
subject.site(uri)
|
140
|
+
end
|
141
|
+
|
142
|
+
context "given the symbol :opscode" do
|
143
|
+
it "sends an add_location message with the default Opscode Community API as the first parameter" do
|
144
|
+
subject.should_receive(:add_location).with(:site, :opscode)
|
145
|
+
|
146
|
+
subject.site(:opscode)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
describe "#chef_api" do
|
152
|
+
let(:uri) { "http://chef:8080/" }
|
153
|
+
|
154
|
+
it "sends and add_location message with the type :chef_api and the given URI" do
|
155
|
+
subject.should_receive(:add_location).with(:chef_api, uri, {})
|
156
|
+
|
157
|
+
subject.chef_api(uri)
|
158
|
+
end
|
159
|
+
|
160
|
+
it "also sends any options passed" do
|
161
|
+
options = { node_name: "reset", client_key: "/Users/reset/.chef/reset.pem" }
|
162
|
+
subject.should_receive(:add_location).with(:chef_api, uri, options)
|
163
|
+
|
164
|
+
subject.chef_api(uri, options)
|
165
|
+
end
|
166
|
+
|
167
|
+
context "given the symbol :knife" do
|
168
|
+
it "sends an add_location message with the the type :chef_api and the URI :knife" do
|
169
|
+
subject.should_receive(:add_location).with(:chef_api, :knife, {})
|
170
|
+
|
171
|
+
subject.chef_api(:knife)
|
172
|
+
end
|
173
|
+
end
|
70
174
|
end
|
71
175
|
|
72
176
|
describe "#sources" do
|
73
177
|
it "returns all CookbookSources added to the instance of Berksfile" do
|
74
|
-
|
178
|
+
subject.add_source(source_one.name)
|
179
|
+
subject.add_source(source_two.name)
|
75
180
|
|
76
|
-
|
77
|
-
|
78
|
-
|
181
|
+
subject.sources.should have(2).items
|
182
|
+
subject.should have_source(source_one.name)
|
183
|
+
subject.should have_source(source_two.name)
|
79
184
|
end
|
80
185
|
|
81
186
|
context "given the option :exclude" do
|
@@ -89,6 +194,7 @@ EOF
|
|
89
194
|
|
90
195
|
describe "#groups" do
|
91
196
|
before(:each) do
|
197
|
+
subject.stub(:sources) { [source_one, source_two] }
|
92
198
|
source_one.stub(:groups) { [:nautilus, :skarner] }
|
93
199
|
source_two.stub(:groups) { [:nautilus, :riven] }
|
94
200
|
end
|
@@ -101,9 +207,8 @@ EOF
|
|
101
207
|
end
|
102
208
|
|
103
209
|
it "returns an Array of CookbookSources who are members of the group for value" do
|
104
|
-
subject.groups[:nautilus].should
|
105
|
-
subject.groups[:
|
106
|
-
subject.groups[:riven].should_not include(source_one)
|
210
|
+
subject.groups[:nautilus].should have(2).items
|
211
|
+
subject.groups[:riven].should have(1).item
|
107
212
|
end
|
108
213
|
end
|
109
214
|
|
@@ -205,5 +310,45 @@ EOF
|
|
205
310
|
subject.load(content).should be_a(Berksfile)
|
206
311
|
end
|
207
312
|
end
|
313
|
+
|
314
|
+
describe "#add_source" do
|
315
|
+
let(:name) { "cookbook_one" }
|
316
|
+
let(:constraint) { "= 1.2.0" }
|
317
|
+
let(:location) { { site: "http://site" } }
|
318
|
+
|
319
|
+
before(:each) do
|
320
|
+
subject.add_source(name, constraint, location)
|
321
|
+
end
|
322
|
+
|
323
|
+
it "adds new cookbook source to the list of sources" do
|
324
|
+
subject.sources.should have(1).source
|
325
|
+
end
|
326
|
+
|
327
|
+
it "adds a cookbook source with a 'name' of the given name" do
|
328
|
+
subject.sources.first.name.should eql(name)
|
329
|
+
end
|
330
|
+
|
331
|
+
it "adds a cookbook source with a 'version_constraint' of the given constraint" do
|
332
|
+
subject.sources.first.version_constraint.to_s.should eql(constraint)
|
333
|
+
end
|
334
|
+
|
335
|
+
it "raises DuplicateSourceDefined if multiple sources of the same name are found" do
|
336
|
+
lambda {
|
337
|
+
subject.add_source(name)
|
338
|
+
}.should raise_error(DuplicateSourceDefined)
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
describe "#add_location" do
|
343
|
+
let(:type) { :site }
|
344
|
+
let(:value) { double('value') }
|
345
|
+
let(:options) { double('options') }
|
346
|
+
|
347
|
+
it "delegates 'add_location' to the downloader" do
|
348
|
+
subject.downloader.should_receive(:add_location).with(type, value, options)
|
349
|
+
|
350
|
+
subject.add_location(type, value, options)
|
351
|
+
end
|
352
|
+
end
|
208
353
|
end
|
209
354
|
end
|
@@ -460,5 +460,24 @@ module Berkshelf
|
|
460
460
|
parse_json(@json)['json_class'].should eql("Chef::CookbookVersion")
|
461
461
|
end
|
462
462
|
end
|
463
|
+
|
464
|
+
describe "#dependencies" do
|
465
|
+
let(:dependencies) { { "mysql" => "= 1.2.0", "ntp" => ">= 0.0.0" } }
|
466
|
+
let(:recommendations) { { "database" => ">= 0.0.0" } }
|
467
|
+
|
468
|
+
let(:cb_path) do
|
469
|
+
generate_cookbook(Berkshelf.cookbook_store.to_s, "sparkle", "0.1.0", dependencies: dependencies, recommendations: recommendations)
|
470
|
+
end
|
471
|
+
|
472
|
+
subject { CachedCookbook.from_store_path(cb_path) }
|
473
|
+
|
474
|
+
it "contains depends from the cookbook metadata" do
|
475
|
+
subject.dependencies.should include(dependencies)
|
476
|
+
end
|
477
|
+
|
478
|
+
it "contains recommendations from the cookbook metadata" do
|
479
|
+
subject.dependencies.should include(recommendations)
|
480
|
+
end
|
481
|
+
end
|
463
482
|
end
|
464
483
|
end
|
@@ -11,8 +11,8 @@ module Berkshelf
|
|
11
11
|
context "given no location key (i.e. :git, :path, :site)" do
|
12
12
|
let(:source) { subject.new(cookbook_name) }
|
13
13
|
|
14
|
-
it "
|
15
|
-
source.location.
|
14
|
+
it "sets a nil value for location" do
|
15
|
+
source.location.should be_nil
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
@@ -25,7 +25,7 @@ module Berkshelf
|
|
25
25
|
end
|
26
26
|
|
27
27
|
context "given a value for constraint" do
|
28
|
-
let(:source) { subject.new(cookbook_name, "~> 1.0.84") }
|
28
|
+
let(:source) { subject.new(cookbook_name, constraint: "~> 1.0.84") }
|
29
29
|
|
30
30
|
it "returns a Solve::Constraint for the given version for version_constraint" do
|
31
31
|
source.version_constraint.to_s.should eql("~> 1.0.84")
|
@@ -37,7 +37,7 @@ module Berkshelf
|
|
37
37
|
let(:source) { subject.new(cookbook_name, git: url) }
|
38
38
|
|
39
39
|
it "initializes a GitLocation for location" do
|
40
|
-
source.location.should be_a(
|
40
|
+
source.location.should be_a(GitLocation)
|
41
41
|
end
|
42
42
|
|
43
43
|
it "points to the given Git URL" do
|
@@ -50,7 +50,7 @@ module Berkshelf
|
|
50
50
|
let(:path) { fixtures_path.join("cookbooks", "example_cookbook").to_s }
|
51
51
|
|
52
52
|
it "initializes a PathLocation for location" do
|
53
|
-
subject.new(cookbook_name, path: path).location.should be_a(
|
53
|
+
subject.new(cookbook_name, path: path).location.should be_a(PathLocation)
|
54
54
|
end
|
55
55
|
|
56
56
|
it "points to the specified path" do
|
@@ -141,7 +141,7 @@ module Berkshelf
|
|
141
141
|
let(:source) { subject.new(cookbook_name, site: url) }
|
142
142
|
|
143
143
|
it "initializes a SiteLocation for location" do
|
144
|
-
source.location.should be_a(
|
144
|
+
source.location.should be_a(SiteLocation)
|
145
145
|
end
|
146
146
|
|
147
147
|
it "points to the specified URI" do
|
@@ -211,43 +211,33 @@ module Berkshelf
|
|
211
211
|
end
|
212
212
|
end
|
213
213
|
|
214
|
-
describe "#
|
215
|
-
|
216
|
-
|
217
|
-
subject.download(tmp_path)
|
218
|
-
|
219
|
-
subject.cached_cookbook.should be_a(Berkshelf::CachedCookbook)
|
220
|
-
end
|
221
|
-
|
222
|
-
it "returns an array containing the symbol :ok and the local_path" do
|
223
|
-
result = subject.download(tmp_path)
|
214
|
+
describe "#downloaded?" do
|
215
|
+
it "returns true if self.cached_cookbook is not nil" do
|
216
|
+
subject.stub(:cached_cookbook) { double('cb') }
|
224
217
|
|
225
|
-
|
226
|
-
result[0].should eql(:ok)
|
227
|
-
result[1].should eql(subject.cached_cookbook)
|
228
|
-
end
|
218
|
+
subject.downloaded?.should be_true
|
229
219
|
end
|
230
220
|
|
231
|
-
|
232
|
-
|
233
|
-
subject { CookbookSource.new(bad_cb_name) }
|
234
|
-
|
235
|
-
it "returns an array containing the symbol :error and the error message" do
|
236
|
-
result = subject.download(tmp_path)
|
221
|
+
it "returns false if self.cached_cookbook is nil" do
|
222
|
+
subject.stub(:cached_cookbook) { nil }
|
237
223
|
|
238
|
-
|
239
|
-
result[0].should eql(:error)
|
240
|
-
result[1].should eql("Cookbook '#{bad_cb_name}' not found at site: 'http://cookbooks.opscode.com/api/v1/cookbooks'")
|
241
|
-
end
|
224
|
+
subject.downloaded?.should be_false
|
242
225
|
end
|
243
226
|
end
|
244
227
|
|
245
|
-
describe "#
|
246
|
-
|
228
|
+
describe "#to_s" do
|
229
|
+
it "contains the name, constraint, and groups" do
|
230
|
+
source = CookbookSource.new("artifact", constraint: "= 0.10.0")
|
231
|
+
|
232
|
+
source.to_s.should eql("artifact (= 0.10.0) groups: [:default]")
|
233
|
+
end
|
247
234
|
|
248
|
-
|
249
|
-
|
250
|
-
|
235
|
+
context "given a CookbookSource with an explicit location" do
|
236
|
+
it "contains the name, constraint, groups, and location" do
|
237
|
+
source = CookbookSource.new("artifact", constraint: "= 0.10.0", site: "http://cookbooks.opscode.com/api/v1/cookbooks")
|
238
|
+
|
239
|
+
source.to_s.should eql("artifact (= 0.10.0) groups: [:default] location: site: 'http://cookbooks.opscode.com/api/v1/cookbooks'")
|
240
|
+
end
|
251
241
|
end
|
252
242
|
end
|
253
243
|
end
|