berkshelf-api 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.ruby-version +1 -0
- data/.travis.yml +17 -0
- data/CONTRIBUTING.md +33 -0
- data/Gemfile +40 -0
- data/Guardfile +20 -0
- data/LICENSE +201 -0
- data/README.md +37 -0
- data/Thorfile +39 -0
- data/berkshelf-api.gemspec +35 -0
- data/bin/berks-api +5 -0
- data/lib/berkshelf-api.rb +1 -0
- data/lib/berkshelf/api.rb +25 -0
- data/lib/berkshelf/api/application.rb +114 -0
- data/lib/berkshelf/api/cache_builder.rb +60 -0
- data/lib/berkshelf/api/cache_builder/worker.rb +116 -0
- data/lib/berkshelf/api/cache_builder/worker/chef_server.rb +46 -0
- data/lib/berkshelf/api/cache_builder/worker/opscode.rb +59 -0
- data/lib/berkshelf/api/cache_manager.rb +96 -0
- data/lib/berkshelf/api/config.rb +23 -0
- data/lib/berkshelf/api/cucumber.rb +11 -0
- data/lib/berkshelf/api/dependency_cache.rb +123 -0
- data/lib/berkshelf/api/endpoint.rb +17 -0
- data/lib/berkshelf/api/endpoint/v1.rb +19 -0
- data/lib/berkshelf/api/errors.rb +8 -0
- data/lib/berkshelf/api/generic_server.rb +50 -0
- data/lib/berkshelf/api/logging.rb +37 -0
- data/lib/berkshelf/api/mixin.rb +7 -0
- data/lib/berkshelf/api/mixin/services.rb +48 -0
- data/lib/berkshelf/api/rack_app.rb +5 -0
- data/lib/berkshelf/api/remote_cookbook.rb +3 -0
- data/lib/berkshelf/api/rest_gateway.rb +62 -0
- data/lib/berkshelf/api/rspec.rb +20 -0
- data/lib/berkshelf/api/rspec/server.rb +29 -0
- data/lib/berkshelf/api/site_connector.rb +7 -0
- data/lib/berkshelf/api/site_connector/opscode.rb +162 -0
- data/lib/berkshelf/api/srv_ctl.rb +63 -0
- data/lib/berkshelf/api/version.rb +5 -0
- data/spec/fixtures/reset.pem +27 -0
- data/spec/spec_helper.rb +53 -0
- data/spec/support/actor_mocking.rb +7 -0
- data/spec/support/chef_server.rb +73 -0
- data/spec/unit/berkshelf/api/application_spec.rb +24 -0
- data/spec/unit/berkshelf/api/cache_builder/worker/chef_server_spec.rb +59 -0
- data/spec/unit/berkshelf/api/cache_builder/worker/opscode_spec.rb +41 -0
- data/spec/unit/berkshelf/api/cache_builder/worker_spec.rb +80 -0
- data/spec/unit/berkshelf/api/cache_builder_spec.rb +37 -0
- data/spec/unit/berkshelf/api/cache_manager_spec.rb +123 -0
- data/spec/unit/berkshelf/api/config_spec.rb +24 -0
- data/spec/unit/berkshelf/api/dependency_cache_spec.rb +109 -0
- data/spec/unit/berkshelf/api/endpoint/v1_spec.rb +18 -0
- data/spec/unit/berkshelf/api/logging_spec.rb +28 -0
- data/spec/unit/berkshelf/api/mixin/services_spec.rb +68 -0
- data/spec/unit/berkshelf/api/rack_app_spec.rb +6 -0
- data/spec/unit/berkshelf/api/rest_gateway_spec.rb +26 -0
- data/spec/unit/berkshelf/api/site_connector/opscode_spec.rb +85 -0
- data/spec/unit/berkshelf/api/srv_ctl_spec.rb +56 -0
- metadata +293 -0
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Berkshelf::API::CacheBuilder::Worker::ChefServer do
|
4
|
+
describe "ClassMethods" do
|
5
|
+
subject { described_class }
|
6
|
+
its(:worker_type) { should eql("chef_server") }
|
7
|
+
end
|
8
|
+
|
9
|
+
subject do
|
10
|
+
described_class.new(url: "http://localhost:8889", client_name: "reset",
|
11
|
+
client_key: fixtures_path.join("reset.pem"))
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "#cookbooks" do
|
15
|
+
before do
|
16
|
+
chef_cookbook("ruby", "1.0.0")
|
17
|
+
chef_cookbook("ruby", "2.0.0")
|
18
|
+
chef_cookbook("elixir", "3.0.0")
|
19
|
+
chef_cookbook("elixir", "3.0.1")
|
20
|
+
end
|
21
|
+
|
22
|
+
it "returns an array containing an item for each cookbook on the server" do
|
23
|
+
expect(subject.cookbooks).to have(4).items
|
24
|
+
end
|
25
|
+
|
26
|
+
it "returns an array of RemoteCookbooks" do
|
27
|
+
subject.cookbooks.each do |cookbook|
|
28
|
+
expect(cookbook).to be_a(Berkshelf::API::RemoteCookbook)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
it "each RemoteCookbook is tagged with a location_type matching the worker_type of the builder" do
|
33
|
+
subject.cookbooks.each do |cookbook|
|
34
|
+
expect(cookbook.location_type).to eql(described_class.worker_type)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "#build" do
|
40
|
+
before do
|
41
|
+
Berkshelf::API::CacheManager.start
|
42
|
+
chef_cookbook("ruby", "1.0.0")
|
43
|
+
chef_cookbook("ruby", "2.0.0")
|
44
|
+
chef_cookbook("elixir", "3.0.0")
|
45
|
+
chef_cookbook("elixir", "3.0.1")
|
46
|
+
end
|
47
|
+
|
48
|
+
let(:cache) { Berkshelf::API::CacheManager.instance.cache }
|
49
|
+
|
50
|
+
it "adds each item to the cache" do
|
51
|
+
subject.build
|
52
|
+
expect(cache).to have_cookbook("ruby", "1.0.0")
|
53
|
+
expect(cache).to have_cookbook("ruby", "2.0.0")
|
54
|
+
expect(cache).to have_cookbook("elixir", "3.0.0")
|
55
|
+
expect(cache).to have_cookbook("elixir", "3.0.1")
|
56
|
+
expect(cache.cookbooks).to have(4).items
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Berkshelf::API::CacheBuilder::Worker::Opscode do
|
4
|
+
describe "ClassMethods" do
|
5
|
+
subject { described_class }
|
6
|
+
its(:worker_type) { should eql("opscode") }
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:cookbooks) { ["chicken", "tuna"] }
|
10
|
+
let(:chicken_versions) { ["1.0", "2.0"] }
|
11
|
+
let(:tuna_versions) { ["3.0.0", "3.0.1"] }
|
12
|
+
let(:connection) do
|
13
|
+
connection = double('connection')
|
14
|
+
connection.stub(:cookbooks).and_return(cookbooks)
|
15
|
+
connection
|
16
|
+
end
|
17
|
+
|
18
|
+
subject do
|
19
|
+
Berkshelf::API::CacheManager.start
|
20
|
+
described_class.new
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "#cookbooks" do
|
24
|
+
let(:location_type) { described_class.worker_type }
|
25
|
+
let(:location_path) { Berkshelf::API::SiteConnector::Opscode::V1_API}
|
26
|
+
|
27
|
+
it "returns an array of RemoteCookbooks described by the server" do
|
28
|
+
expected_value = [
|
29
|
+
Berkshelf::API::RemoteCookbook.new("chicken", "1.0", location_type, location_path),
|
30
|
+
Berkshelf::API::RemoteCookbook.new("chicken", "2.0", location_type, location_path),
|
31
|
+
Berkshelf::API::RemoteCookbook.new("tuna", "3.0.0", location_type, location_path),
|
32
|
+
Berkshelf::API::RemoteCookbook.new("tuna", "3.0.1", location_type, location_path)
|
33
|
+
]
|
34
|
+
|
35
|
+
connection.should_receive(:future).with(:versions, "chicken").and_return(double(value: chicken_versions))
|
36
|
+
connection.should_receive(:future).with(:versions, "tuna").and_return(double(value: tuna_versions))
|
37
|
+
subject.should_receive(:connection).at_least(1).times.and_return(connection)
|
38
|
+
expect(subject.cookbooks).to eql(expected_value)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Berkshelf::API::CacheBuilder::Worker do
|
4
|
+
describe "ClassMethods" do
|
5
|
+
describe "::[]" do
|
6
|
+
it "returns the class of the registered worker" do
|
7
|
+
expect(described_class["opscode"]).to eql(Berkshelf::API::CacheBuilder::Worker::Opscode)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "::register" do
|
12
|
+
it "adds the item to the Hash of types" do
|
13
|
+
worker = double('new-worker')
|
14
|
+
described_class.register("rspec-2", worker)
|
15
|
+
expect(described_class.types["rspec-2"]).to eql(worker)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "::types" do
|
20
|
+
subject { described_class.types }
|
21
|
+
|
22
|
+
it "returns a Hash" do
|
23
|
+
expect(subject).to be_a(Hash)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe Berkshelf::API::CacheBuilder::Worker::Base do
|
30
|
+
describe "ClassMethods" do
|
31
|
+
describe "::worker_type" do
|
32
|
+
let(:klass) { Class.new(described_class) }
|
33
|
+
|
34
|
+
it "registers the worker type and class to Worker.types" do
|
35
|
+
klass.worker_type("rspec")
|
36
|
+
expect(Berkshelf::API::CacheBuilder::Worker.types).to include("rspec")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
let(:cache_manager) { double(:diff => :chicken) }
|
42
|
+
subject { described_class.new }
|
43
|
+
|
44
|
+
describe "#diff" do
|
45
|
+
it "should delegate to the cache_manager to calculate the diff" do
|
46
|
+
subject.should_receive(:cache_manager).and_return(cache_manager)
|
47
|
+
subject.should_receive(:cookbooks).and_return(:cookbooks)
|
48
|
+
|
49
|
+
expect(subject.diff).to eql(:chicken)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should memoize the diff to prevent recalculating" do
|
53
|
+
subject.should_receive(:cache_manager).exactly(1).times.and_return(cache_manager)
|
54
|
+
subject.should_receive(:cookbooks).and_return(:cookbooks)
|
55
|
+
|
56
|
+
subject.diff
|
57
|
+
subject.diff
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "#clear_diff" do
|
62
|
+
it "should set the diff to nil" do
|
63
|
+
subject.should_receive(:cache_manager).and_return(cache_manager)
|
64
|
+
subject.should_receive(:cookbooks).and_return(:cookbooks)
|
65
|
+
|
66
|
+
subject.diff
|
67
|
+
expect(subject.instance_variable_get(:@diff)).to eql(:chicken)
|
68
|
+
subject.send(:clear_diff)
|
69
|
+
expect(subject.instance_variable_get(:@diff)).to eql(nil)
|
70
|
+
end
|
71
|
+
|
72
|
+
it "memoizes the diff to prevent recalculating" do
|
73
|
+
subject.should_receive(:cache_manager).exactly(1).times.and_return(cache_manager)
|
74
|
+
subject.should_receive(:cookbooks).and_return(:cookbooks)
|
75
|
+
|
76
|
+
subject.diff
|
77
|
+
subject.diff
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Berkshelf::API::CacheBuilder do
|
4
|
+
let(:instance) { described_class.new }
|
5
|
+
|
6
|
+
describe "#build" do
|
7
|
+
subject(:build) { instance.build }
|
8
|
+
let(:workers) { [ double('worker') ] }
|
9
|
+
let(:future) { double('future', value: nil) }
|
10
|
+
|
11
|
+
before { instance.stub(workers: workers) }
|
12
|
+
|
13
|
+
it "sends a #build message to each worker" do
|
14
|
+
workers.each { |worker| worker.should_receive(:future).with(:build).and_return(future) }
|
15
|
+
build
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "#workers" do
|
20
|
+
subject(:workers) { instance.workers }
|
21
|
+
|
22
|
+
it "returns an array of workers" do
|
23
|
+
expect(workers).to be_a(Array)
|
24
|
+
workers.each do |worker|
|
25
|
+
expect(worker).to be_a(described_class::Worker::Base)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
it "has one worker started by default" do
|
30
|
+
expect(workers).to have(1).item
|
31
|
+
end
|
32
|
+
|
33
|
+
it "has an opscode worker started by default" do
|
34
|
+
expect(workers.first).to be_a(described_class::Worker::Opscode)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Berkshelf::API::CacheManager do
|
4
|
+
describe "ClassMethods" do
|
5
|
+
describe "::new" do
|
6
|
+
subject { described_class.new }
|
7
|
+
its(:cache) { should be_empty }
|
8
|
+
|
9
|
+
context "when a save file exists" do
|
10
|
+
before do
|
11
|
+
@tempfile = Tempfile.new('berkshelf-api-rspec')
|
12
|
+
described_class.stub(:cache_file) { @tempfile.path }
|
13
|
+
end
|
14
|
+
after { @tempfile.close(true) }
|
15
|
+
|
16
|
+
it "loads the saved cache" do
|
17
|
+
described_class.any_instance.should_receive(:load_save)
|
18
|
+
subject
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context "when a save file does not exist" do
|
23
|
+
before { described_class.stub(cache_file: tmp_path.join('does_not_exist').to_s) }
|
24
|
+
|
25
|
+
it "skips loading of the saved cache" do
|
26
|
+
described_class.any_instance.should_not_receive(:load_save)
|
27
|
+
subject
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "::start" do
|
33
|
+
it "starts and registers a cache manager it with the application" do
|
34
|
+
described_class.start
|
35
|
+
|
36
|
+
expect(Berkshelf::API::Application[:cache_manager]).to be_a(described_class)
|
37
|
+
expect(Berkshelf::API::Application[:cache_manager]).to be_alive
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
subject { described_class.new }
|
43
|
+
|
44
|
+
describe "#add" do
|
45
|
+
pending
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "#load_save" do
|
49
|
+
pending
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "#remove" do
|
53
|
+
pending
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "#clear" do
|
57
|
+
it "returns an empty Hash" do
|
58
|
+
result = subject.clear
|
59
|
+
expect(result).to be_a(Hash)
|
60
|
+
expect(result).to be_empty
|
61
|
+
end
|
62
|
+
|
63
|
+
it "empties the cache" do
|
64
|
+
subject.clear
|
65
|
+
expect(subject.cache).to be_empty
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "#diff" do
|
70
|
+
let(:cookbook_one) { Berkshelf::API::RemoteCookbook.new("ruby", "1.2.3", "opscode") }
|
71
|
+
let(:cookbook_two) { Berkshelf::API::RemoteCookbook.new("elixir", "2.0.0", "opscode") }
|
72
|
+
let(:comparison) { Array.new }
|
73
|
+
|
74
|
+
before do
|
75
|
+
subject.add(cookbook_one, double(dependencies: nil, platforms: nil))
|
76
|
+
subject.add(cookbook_two, double(dependencies: nil, platforms: nil))
|
77
|
+
|
78
|
+
@created, @deleted = @diff = subject.diff(comparison)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "returns two items" do
|
82
|
+
expect(@diff).to have(2).items
|
83
|
+
end
|
84
|
+
|
85
|
+
context "when there are created and deleted cookbooks" do
|
86
|
+
let(:new_cookbook) { Berkshelf::API::RemoteCookbook.new("ruby", "3.0.0", "opscode") }
|
87
|
+
let(:comparison) { [ cookbook_one, new_cookbook ] }
|
88
|
+
|
89
|
+
it "should return created and deleted cookbooks" do
|
90
|
+
expect(@created).to eql([new_cookbook])
|
91
|
+
expect(@deleted).to eql([cookbook_two])
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
context "when there are only created cookbooks" do
|
96
|
+
let(:new_cookbook) { Berkshelf::API::RemoteCookbook.new("ruby", "3.0.0", "opscode") }
|
97
|
+
let(:comparison) { [ cookbook_one, cookbook_two, new_cookbook ] }
|
98
|
+
|
99
|
+
it "should return only created cookbooks" do
|
100
|
+
expect(@created).to eql([new_cookbook])
|
101
|
+
expect(@deleted).to be_empty
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
context "when there are only deleted cookbooks" do
|
106
|
+
let(:comparison) { [ cookbook_one ] }
|
107
|
+
|
108
|
+
it "should return only deleted cookbooks" do
|
109
|
+
expect(@created).to be_empty
|
110
|
+
expect(@deleted).to eql([cookbook_two])
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
context "when there are no differences" do
|
115
|
+
let(:comparison) { [ cookbook_one, cookbook_two ] }
|
116
|
+
|
117
|
+
it "should return empty arrays" do
|
118
|
+
expect(@created).to be_empty
|
119
|
+
expect(@deleted).to be_empty
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Berkshelf::API::Config do
|
4
|
+
describe "ClassMethods" do
|
5
|
+
describe "::default_path" do
|
6
|
+
it "returns a String" do
|
7
|
+
expect(described_class.default_path).to be_a(String)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "default config" do
|
13
|
+
subject { described_class.new }
|
14
|
+
|
15
|
+
it "has a endpoint configured" do
|
16
|
+
expect(subject.endpoints).to have(1).item
|
17
|
+
end
|
18
|
+
|
19
|
+
it "has the Opscode community site as an endpoint" do
|
20
|
+
expect(subject.endpoints.first.type).to eql("opscode")
|
21
|
+
expect(subject.endpoints.first.options[:url]).to eql("http://cookbooks.opscode.com/api/v1")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Berkshelf::API::DependencyCache do
|
4
|
+
describe "ClassMethods" do
|
5
|
+
describe "::from_file" do
|
6
|
+
let(:filepath) { @tempfile.path }
|
7
|
+
before { @tempfile = Tempfile.new('berkshelf-api-rspec') }
|
8
|
+
after { @tempfile.close(true) }
|
9
|
+
|
10
|
+
subject { described_class.from_file(filepath) }
|
11
|
+
|
12
|
+
context "when the file contains valid json" do
|
13
|
+
before do
|
14
|
+
@tempfile.write(JSON.generate({brooke: "winsor"}))
|
15
|
+
@tempfile.flush
|
16
|
+
end
|
17
|
+
|
18
|
+
it "returns an instance of DependencyCache" do
|
19
|
+
expect(subject).to be_a(described_class)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "when the filepath does not exist" do
|
24
|
+
let(:filepath) { nil }
|
25
|
+
|
26
|
+
it "raises a SaveNotFoundError" do
|
27
|
+
expect { subject }.to raise_error(Berkshelf::API::SaveNotFoundError)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "when the file does not contain valid JSON" do
|
32
|
+
let(:filepath) { @tempfile.path }
|
33
|
+
before do
|
34
|
+
@tempfile.write("asdfasdfasdf")
|
35
|
+
@tempfile.flush
|
36
|
+
end
|
37
|
+
|
38
|
+
it "raises an InvalidSaveError" do
|
39
|
+
expect { subject }.to raise_error(Berkshelf::API::InvalidSaveError)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
let(:chicken) do
|
46
|
+
{ "1.0" =>
|
47
|
+
{
|
48
|
+
dependencies: { "tuna" => "= 3.0.0" },
|
49
|
+
platforms: { "centos" => ">= 0.0.0" }
|
50
|
+
}
|
51
|
+
}
|
52
|
+
end
|
53
|
+
let(:tuna) do
|
54
|
+
{ "3.0.0" =>
|
55
|
+
{
|
56
|
+
dependencies: { },
|
57
|
+
platforms: { "centos" => ">= 0.0.0" }
|
58
|
+
}
|
59
|
+
}
|
60
|
+
end
|
61
|
+
let(:contents) do
|
62
|
+
{
|
63
|
+
"chicken" => chicken,
|
64
|
+
"tuna" => tuna,
|
65
|
+
}
|
66
|
+
end
|
67
|
+
|
68
|
+
subject { described_class.new(contents) }
|
69
|
+
|
70
|
+
describe "#cookbooks" do
|
71
|
+
it "should return a list of RemoteCookbooks" do
|
72
|
+
expected_value = [
|
73
|
+
Berkshelf::API::RemoteCookbook.new("chicken", "1.0"),
|
74
|
+
Berkshelf::API::RemoteCookbook.new("tuna", "3.0.0")
|
75
|
+
]
|
76
|
+
|
77
|
+
expect(subject.cookbooks).to eql(expected_value)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "#add" do
|
82
|
+
let(:cookbook) { Berkshelf::API::RemoteCookbook.new("ruby", "1.2.3", "opscode") }
|
83
|
+
before { subject.clear }
|
84
|
+
|
85
|
+
it "adds items to the cache" do
|
86
|
+
subject.add(cookbook, double(platforms: nil, dependencies: nil))
|
87
|
+
expect(subject.to_hash).to have(1).item
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe "#save" do
|
92
|
+
let(:path) { tmp_path.join('cerch.json') }
|
93
|
+
|
94
|
+
it "saves the contents of the cache as json to the given path" do
|
95
|
+
subject.save(path)
|
96
|
+
expect(File.exist?(path)).to be_true
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe "#clear" do
|
101
|
+
let(:cookbook) { Berkshelf::API::RemoteCookbook.new("ruby", "1.2.3", "opscode") }
|
102
|
+
before { subject.add(cookbook, double(platforms: nil, dependencies: nil)) }
|
103
|
+
|
104
|
+
it "empties items added to the cache" do
|
105
|
+
subject.clear
|
106
|
+
expect(subject).to be_empty
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|