berkshelf 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +20 -0
- data/.rbenv-version +1 -0
- data/Gemfile +3 -0
- data/Guardfile +23 -0
- data/LICENSE +22 -0
- data/README.rdoc +102 -0
- data/Thorfile +47 -0
- data/berkshelf.gemspec +39 -0
- data/features/config.sample.yml +3 -0
- data/features/init_command.feature +40 -0
- data/features/install.feature +55 -0
- data/features/lockfile.feature +22 -0
- data/features/step_definitions/chef_server_steps.rb +13 -0
- data/features/step_definitions/cli_steps.rb +56 -0
- data/features/step_definitions/filesystem_steps.rb +79 -0
- data/features/support/env.rb +55 -0
- data/features/update.feature +23 -0
- data/features/upload_command.feature +43 -0
- data/features/without.feature +25 -0
- data/lib/berkshelf.rb +90 -0
- data/lib/berkshelf/berksfile.rb +170 -0
- data/lib/berkshelf/cached_cookbook.rb +253 -0
- data/lib/berkshelf/cookbook_source.rb +139 -0
- data/lib/berkshelf/cookbook_source/git_location.rb +54 -0
- data/lib/berkshelf/cookbook_source/path_location.rb +27 -0
- data/lib/berkshelf/cookbook_source/site_location.rb +206 -0
- data/lib/berkshelf/cookbook_store.rb +77 -0
- data/lib/berkshelf/core_ext.rb +3 -0
- data/lib/berkshelf/core_ext/file.rb +14 -0
- data/lib/berkshelf/core_ext/kernel.rb +33 -0
- data/lib/berkshelf/core_ext/pathname.rb +24 -0
- data/lib/berkshelf/downloader.rb +92 -0
- data/lib/berkshelf/dsl.rb +39 -0
- data/lib/berkshelf/errors.rb +20 -0
- data/lib/berkshelf/generator_files/Berksfile.erb +3 -0
- data/lib/berkshelf/generator_files/chefignore +44 -0
- data/lib/berkshelf/git.rb +70 -0
- data/lib/berkshelf/init_generator.rb +38 -0
- data/lib/berkshelf/lockfile.rb +42 -0
- data/lib/berkshelf/resolver.rb +176 -0
- data/lib/berkshelf/tx_result.rb +12 -0
- data/lib/berkshelf/tx_result_set.rb +37 -0
- data/lib/berkshelf/uploader.rb +153 -0
- data/lib/berkshelf/version.rb +3 -0
- data/lib/chef/knife/berks_init.rb +29 -0
- data/lib/chef/knife/berks_install.rb +27 -0
- data/lib/chef/knife/berks_update.rb +23 -0
- data/lib/chef/knife/berks_upload.rb +39 -0
- data/spec/fixtures/Berksfile +3 -0
- data/spec/fixtures/cookbooks/example_cookbook-0.5.0/README.md +12 -0
- data/spec/fixtures/cookbooks/example_cookbook-0.5.0/metadata.rb +6 -0
- data/spec/fixtures/cookbooks/example_cookbook-0.5.0/recipes/default.rb +8 -0
- data/spec/fixtures/cookbooks/example_cookbook/README.md +12 -0
- data/spec/fixtures/cookbooks/example_cookbook/metadata.rb +6 -0
- data/spec/fixtures/cookbooks/example_cookbook/recipes/default.rb +8 -0
- data/spec/fixtures/cookbooks/invalid_ruby_files-1.0.0/recipes/default.rb +1 -0
- data/spec/fixtures/cookbooks/invalid_template_files-1.0.0/templates/default/broken.erb +1 -0
- data/spec/fixtures/cookbooks/nginx-0.100.5/README.md +77 -0
- data/spec/fixtures/cookbooks/nginx-0.100.5/attributes/default.rb +65 -0
- data/spec/fixtures/cookbooks/nginx-0.100.5/definitions/nginx_site.rb +35 -0
- data/spec/fixtures/cookbooks/nginx-0.100.5/files/default/mime.types +73 -0
- data/spec/fixtures/cookbooks/nginx-0.100.5/files/ubuntu/mime.types +73 -0
- data/spec/fixtures/cookbooks/nginx-0.100.5/libraries/nginxlib.rb +1 -0
- data/spec/fixtures/cookbooks/nginx-0.100.5/metadata.rb +91 -0
- data/spec/fixtures/cookbooks/nginx-0.100.5/providers/defprovider.rb +1 -0
- data/spec/fixtures/cookbooks/nginx-0.100.5/recipes/default.rb +59 -0
- data/spec/fixtures/cookbooks/nginx-0.100.5/resources/defresource.rb +1 -0
- data/spec/fixtures/cookbooks/nginx-0.100.5/templates/default/nginx.pill.erb +15 -0
- data/spec/fixtures/cookbooks/nginx-0.100.5/templates/default/plugins/nginx.rb.erb +66 -0
- data/spec/fixtures/lockfile_spec/with_lock/Berksfile +1 -0
- data/spec/fixtures/lockfile_spec/without_lock/Berksfile.lock +5 -0
- data/spec/spec_helper.rb +92 -0
- data/spec/support/chef_api.rb +27 -0
- data/spec/support/matchers/file_system_matchers.rb +115 -0
- data/spec/support/matchers/filepath_matchers.rb +19 -0
- data/spec/unit/berkshelf/cached_cookbook_spec.rb +420 -0
- data/spec/unit/berkshelf/cookbook_source/git_location_spec.rb +59 -0
- data/spec/unit/berkshelf/cookbook_source/path_location_spec.rb +34 -0
- data/spec/unit/berkshelf/cookbook_source/site_location_spec.rb +166 -0
- data/spec/unit/berkshelf/cookbook_source_spec.rb +194 -0
- data/spec/unit/berkshelf/cookbook_store_spec.rb +71 -0
- data/spec/unit/berkshelf/cookbookfile_spec.rb +160 -0
- data/spec/unit/berkshelf/downloader_spec.rb +82 -0
- data/spec/unit/berkshelf/dsl_spec.rb +42 -0
- data/spec/unit/berkshelf/git_spec.rb +63 -0
- data/spec/unit/berkshelf/init_generator_spec.rb +52 -0
- data/spec/unit/berkshelf/lockfile_spec.rb +25 -0
- data/spec/unit/berkshelf/resolver_spec.rb +126 -0
- data/spec/unit/berkshelf/tx_result_set_spec.rb +77 -0
- data/spec/unit/berkshelf/tx_result_spec.rb +21 -0
- data/spec/unit/berkshelf/uploader_spec.rb +71 -0
- data/spec/unit/berkshelf_spec.rb +29 -0
- metadata +411 -0
@@ -0,0 +1 @@
|
|
1
|
+
cookbook 'nginx', '= 0.101.0'
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
require 'spork'
|
4
|
+
require 'vcr'
|
5
|
+
|
6
|
+
Spork.prefork do
|
7
|
+
require 'rspec'
|
8
|
+
require 'simplecov'
|
9
|
+
require 'pp'
|
10
|
+
require 'json_spec'
|
11
|
+
require 'webmock/rspec'
|
12
|
+
|
13
|
+
APP_ROOT = File.expand_path('../../', __FILE__)
|
14
|
+
|
15
|
+
Dir[File.join(APP_ROOT, "spec/support/**/*.rb")].each {|f| require f}
|
16
|
+
|
17
|
+
VCR.configure do |c|
|
18
|
+
c.cassette_library_dir = File.join(File.dirname(__FILE__), 'fixtures', 'vcr_cassettes')
|
19
|
+
c.hook_into :webmock
|
20
|
+
end
|
21
|
+
|
22
|
+
RSpec.configure do |config|
|
23
|
+
config.include Berkshelf::RSpec::FileSystemMatchers
|
24
|
+
config.include JsonSpec::Helpers
|
25
|
+
|
26
|
+
config.mock_with :rspec
|
27
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
28
|
+
config.filter_run :focus => true
|
29
|
+
config.run_all_when_everything_filtered = true
|
30
|
+
|
31
|
+
config.around do |example|
|
32
|
+
# Dynamically create cassettes based on the name of the example
|
33
|
+
# being run. This creates a new cassette for every test.
|
34
|
+
cur = example.metadata
|
35
|
+
identifiers = [example.metadata[:description_args]]
|
36
|
+
while cur = cur[:example_group] do
|
37
|
+
identifiers << cur[:description_args]
|
38
|
+
end
|
39
|
+
|
40
|
+
VCR.use_cassette(identifiers.reverse.join(' ')) do
|
41
|
+
example.run
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
config.before(:each) do
|
46
|
+
clean_tmp_path
|
47
|
+
Berkshelf.cookbook_store = Berkshelf::CookbookStore.new(tmp_path.join("downloader_tmp"))
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
SimpleCov.start do
|
52
|
+
add_filter 'spec/'
|
53
|
+
end
|
54
|
+
|
55
|
+
def capture(stream)
|
56
|
+
begin
|
57
|
+
stream = stream.to_s
|
58
|
+
eval "$#{stream} = StringIO.new"
|
59
|
+
yield
|
60
|
+
result = eval("$#{stream}").string
|
61
|
+
ensure
|
62
|
+
eval("$#{stream} = #{stream.upcase}")
|
63
|
+
end
|
64
|
+
|
65
|
+
result
|
66
|
+
end
|
67
|
+
|
68
|
+
def example_cookbook_from_path
|
69
|
+
@example_cookbook_from_path ||= Berkshelf::Cookbook.new('example_cookbook', path: File.join(File.dirname(__FILE__), 'fixtures', 'cookbooks'))
|
70
|
+
end
|
71
|
+
|
72
|
+
def app_root_path
|
73
|
+
Pathname.new(APP_ROOT)
|
74
|
+
end
|
75
|
+
|
76
|
+
def tmp_path
|
77
|
+
app_root_path.join('spec/tmp')
|
78
|
+
end
|
79
|
+
|
80
|
+
def fixtures_path
|
81
|
+
app_root_path.join('spec/fixtures')
|
82
|
+
end
|
83
|
+
|
84
|
+
def clean_tmp_path
|
85
|
+
FileUtils.rm_rf(tmp_path)
|
86
|
+
FileUtils.mkdir_p(tmp_path)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
Spork.each_run do
|
91
|
+
require 'berkshelf'
|
92
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'chef/rest'
|
2
|
+
require 'chef/cookbook_version'
|
3
|
+
|
4
|
+
module Berkshelf
|
5
|
+
module RSpec
|
6
|
+
module ChefAPI
|
7
|
+
def purge_cookbook(name, version)
|
8
|
+
rest.delete_rest("cookbooks/#{name}/#{version}?purge=true")
|
9
|
+
rescue Net::HTTPServerException => e
|
10
|
+
raise unless e.to_s =~ /^404/
|
11
|
+
end
|
12
|
+
|
13
|
+
def server_has_cookbook?(name, version)
|
14
|
+
rest.get_rest("cookbooks/#{name}/#{version}")
|
15
|
+
true
|
16
|
+
rescue Net::HTTPServerException => e
|
17
|
+
false
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def rest
|
23
|
+
quietly { Chef::REST.new(Chef::Config[:chef_server_url]) }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
# Taken from (https://github.com/carlhuda/beard)
|
2
|
+
# Permission granted by Yehuda Katz (Jan 4th, 2012)
|
3
|
+
module Berkshelf
|
4
|
+
module RSpec
|
5
|
+
module FileSystemMatchers
|
6
|
+
class File
|
7
|
+
def initialize(name, &block)
|
8
|
+
@contents = []
|
9
|
+
@name = name
|
10
|
+
|
11
|
+
if block_given?
|
12
|
+
instance_eval(&block)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def contains(text)
|
17
|
+
@contents << text
|
18
|
+
end
|
19
|
+
|
20
|
+
def matches?(root)
|
21
|
+
unless root.join(@name).exist?
|
22
|
+
throw :failure, root.join(@name)
|
23
|
+
end
|
24
|
+
|
25
|
+
contents = ::File.read(root.join(@name))
|
26
|
+
|
27
|
+
@contents.each do |string|
|
28
|
+
unless contents.include?(string)
|
29
|
+
throw :failure, [root.join(@name), string, contents]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class Directory
|
36
|
+
attr_reader :tree
|
37
|
+
|
38
|
+
def initialize(root = nil, &block)
|
39
|
+
@tree = {}
|
40
|
+
@negative_tree = []
|
41
|
+
@root = root
|
42
|
+
instance_eval(&block) if block_given?
|
43
|
+
end
|
44
|
+
|
45
|
+
def directory(name, &block)
|
46
|
+
@tree[name] = block_given? && Directory.new(location(name), &block)
|
47
|
+
end
|
48
|
+
|
49
|
+
def file(name, &block)
|
50
|
+
@tree[name] = File.new(location(name), &block)
|
51
|
+
end
|
52
|
+
|
53
|
+
def no_file(name)
|
54
|
+
@negative_tree << name
|
55
|
+
end
|
56
|
+
|
57
|
+
def location(name)
|
58
|
+
[@root, name].compact.join("/")
|
59
|
+
end
|
60
|
+
|
61
|
+
def matches?(root)
|
62
|
+
@tree.each do |file, value|
|
63
|
+
unless value
|
64
|
+
unless root.join(location(file)).exist?
|
65
|
+
throw :failure, "#{root}/#{location(file)}"
|
66
|
+
end
|
67
|
+
else
|
68
|
+
value.matches?(root)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
@negative_tree.each do |file|
|
73
|
+
if root.join(location(file)).exist?
|
74
|
+
throw :failure, [:not, "unexpected #{root}/#{location(file)}"]
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
nil
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
class Root < Directory
|
83
|
+
def failure_message
|
84
|
+
if @failure.is_a?(Array) && @failure[0] == :not
|
85
|
+
"Structure should not have had #{@failure[1]}, but it did"
|
86
|
+
elsif @failure.is_a?(Array)
|
87
|
+
"Structure should have #{@failure[0]} with #{@failure[1]}. It had:\n#{@failure[2]}"
|
88
|
+
else
|
89
|
+
"Structure should have #{@failure}, but it didn't"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def negative_failure_message
|
94
|
+
if @failure.is_a?(Array) && @failure[0] == :not
|
95
|
+
"Structure had #{@failure}, but it shouldn't have"
|
96
|
+
else
|
97
|
+
"Structure had #{@failure}, but it shouldn't have"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def matches?(root)
|
102
|
+
@failure = catch :failure do
|
103
|
+
super
|
104
|
+
end
|
105
|
+
|
106
|
+
!@failure
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def have_structure(&block)
|
111
|
+
Root.new(&block)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
3
|
+
RSpec::Matchers.define :be_relative_path do
|
4
|
+
match do |given|
|
5
|
+
if given.nil?
|
6
|
+
false
|
7
|
+
else
|
8
|
+
Pathname.new(given).relative?
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
failure_message_for_should do |given|
|
13
|
+
"Expected '#{given}' to be a relative path but got an absolute path."
|
14
|
+
end
|
15
|
+
|
16
|
+
failure_message_for_should_not do |given|
|
17
|
+
"Expected '#{given}' to not be a relative path but got an absolute path."
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,420 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Berkshelf
|
4
|
+
describe CachedCookbook do
|
5
|
+
describe "ClassMethods" do
|
6
|
+
subject { CachedCookbook }
|
7
|
+
|
8
|
+
describe "#from_path" do
|
9
|
+
before(:each) do
|
10
|
+
@cached_cb = subject.from_path(fixtures_path.join("cookbooks", "example_cookbook-0.5.0"))
|
11
|
+
end
|
12
|
+
|
13
|
+
it "returns an instance of CachedCookbook" do
|
14
|
+
@cached_cb.should be_a(CachedCookbook)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "sets a version number" do
|
18
|
+
@cached_cb.version.should eql("0.5.0")
|
19
|
+
end
|
20
|
+
|
21
|
+
context "given a path that does not contain a cookbook" do
|
22
|
+
it "returns nil" do
|
23
|
+
subject.from_path(tmp_path).should be_nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context "given a path that does not match the CachedCookbook dirname format" do
|
28
|
+
it "returns nil" do
|
29
|
+
subject.from_path(fixtures_path.join("cookbooks", "example_cookbook")).should be_nil
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "#checksum" do
|
35
|
+
it "returns a checksum of the given filepath" do
|
36
|
+
subject.checksum(fixtures_path.join("cookbooks", "example_cookbook-0.5.0", "README.md")).should eql("6e21094b7a920e374e7261f50e9c4eef")
|
37
|
+
end
|
38
|
+
|
39
|
+
context "given path does not exist" do
|
40
|
+
it "raises an Errno::ENOENT error" do
|
41
|
+
lambda {
|
42
|
+
subject.checksum(fixtures_path.join("notexisting.file"))
|
43
|
+
}.should raise_error(Errno::ENOENT)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
let(:cb_path) { fixtures_path.join("cookbooks", "nginx-0.100.5") }
|
50
|
+
subject { CachedCookbook.from_path(cb_path) }
|
51
|
+
|
52
|
+
describe "#checksums" do
|
53
|
+
it "returns a Hash containing an entry for all matching cookbook files on disk" do
|
54
|
+
subject.checksums.should have(11).items
|
55
|
+
end
|
56
|
+
|
57
|
+
it "has a checksum for each key" do
|
58
|
+
subject.checksums.should have_key("fb1f925dcd5fc4ebf682c4442a21c619")
|
59
|
+
end
|
60
|
+
|
61
|
+
it "has a filepath for each value" do
|
62
|
+
subject.checksums.should have_value(cb_path.join("recipes/default.rb").to_s)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "#manifest" do
|
67
|
+
it "returns a Mash with a key for each cookbook file category" do
|
68
|
+
[
|
69
|
+
:recipes,
|
70
|
+
:definitions,
|
71
|
+
:libraries,
|
72
|
+
:attributes,
|
73
|
+
:files,
|
74
|
+
:templates,
|
75
|
+
:resources,
|
76
|
+
:providers,
|
77
|
+
:root_files
|
78
|
+
].each do |category|
|
79
|
+
subject.manifest.should have_key(category)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe "#validate!" do
|
85
|
+
it "returns true if the cookbook of the given name and version is valid" do
|
86
|
+
@cb = CachedCookbook.from_path(fixtures_path.join("cookbooks", "example_cookbook-0.5.0"))
|
87
|
+
|
88
|
+
@cb.validate!.should be_true
|
89
|
+
end
|
90
|
+
|
91
|
+
it "raises CookbookSyntaxError if the cookbook contains invalid ruby files" do
|
92
|
+
@cb = CachedCookbook.from_path(fixtures_path.join("cookbooks", "invalid_ruby_files-1.0.0"))
|
93
|
+
|
94
|
+
lambda {
|
95
|
+
@cb.validate!
|
96
|
+
}.should raise_error(CookbookSyntaxError)
|
97
|
+
end
|
98
|
+
|
99
|
+
it "raises CookbookSyntaxError if the cookbook contains invalid template files" do
|
100
|
+
@cb = CachedCookbook.from_path(fixtures_path.join("cookbooks", "invalid_template_files-1.0.0"))
|
101
|
+
|
102
|
+
lambda {
|
103
|
+
@cb.validate!
|
104
|
+
}.should raise_error(CookbookSyntaxError)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe "#file_metadata" do
|
109
|
+
let(:file) { subject.path.join("files", "default", "mime.types") }
|
110
|
+
|
111
|
+
before(:each) { @metadata = subject.file_metadata(:file, file) }
|
112
|
+
|
113
|
+
it "has a 'path' key whose value is a relative path from the CachedCookbook's path" do
|
114
|
+
@metadata.should have_key(:path)
|
115
|
+
@metadata[:path].should be_relative_path
|
116
|
+
@metadata[:path].should eql("files/default/mime.types")
|
117
|
+
end
|
118
|
+
|
119
|
+
it "has a 'name' key whose value is the basename of the target file" do
|
120
|
+
@metadata.should have_key(:name)
|
121
|
+
@metadata[:name].should eql("mime.types")
|
122
|
+
end
|
123
|
+
|
124
|
+
it "has a 'checksum' key whose value is the checksum of the target file" do
|
125
|
+
@metadata.should have_key(:checksum)
|
126
|
+
@metadata[:checksum].should eql("06e7eca1d6cb608e2e74fd1f8e059f34")
|
127
|
+
end
|
128
|
+
|
129
|
+
it "has a 'specificity' key" do
|
130
|
+
@metadata.should have_key(:specificity)
|
131
|
+
end
|
132
|
+
|
133
|
+
context "given a 'template' or 'file' berksfile type" do
|
134
|
+
let(:file) { subject.path.join("files", "ubuntu", "mime.types") }
|
135
|
+
before(:each) { @metadata = subject.file_metadata(:files, file) }
|
136
|
+
|
137
|
+
it "has a 'specificity' key whose value represents the specificity found in filepath" do
|
138
|
+
@metadata[:specificity].should eql("ubuntu")
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
context "given any berksfile type that is not a 'template' or 'file'" do
|
143
|
+
let(:file) { subject.path.join("README.md") }
|
144
|
+
before(:each) { @metadata = subject.file_metadata(:root, file) }
|
145
|
+
|
146
|
+
it "has a 'specificity' key whose value is 'default'" do
|
147
|
+
@metadata[:specificity].should eql("default")
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
describe "#to_hash" do
|
153
|
+
before(:each) do
|
154
|
+
@hash = subject.to_hash
|
155
|
+
end
|
156
|
+
|
157
|
+
let(:cookbook_name) { subject.cookbook_name }
|
158
|
+
let(:cookbook_version) { subject.version }
|
159
|
+
|
160
|
+
it "has a 'recipes' key with a value of an Array Hashes" do
|
161
|
+
@hash.should have_key('recipes')
|
162
|
+
@hash['recipes'].should be_a(Array)
|
163
|
+
@hash['recipes'].each do |item|
|
164
|
+
item.should be_a(Hash)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
it "has a 'name' key value pair in a Hash of the 'recipes' Array of Hashes" do
|
169
|
+
@hash['recipes'].first.should have_key('name')
|
170
|
+
end
|
171
|
+
|
172
|
+
it "has a 'path' key value pair in a Hash of the 'recipes' Array of Hashes" do
|
173
|
+
@hash['recipes'].first.should have_key('path')
|
174
|
+
end
|
175
|
+
|
176
|
+
it "has a 'checksum' key value pair in a Hash of the 'recipes' Array of Hashes" do
|
177
|
+
@hash['recipes'].first.should have_key('checksum')
|
178
|
+
end
|
179
|
+
|
180
|
+
it "has a 'specificity' key value pair in a Hash of the 'recipes' Array of Hashes" do
|
181
|
+
@hash['recipes'].first.should have_key('specificity')
|
182
|
+
end
|
183
|
+
|
184
|
+
it "has a 'definitions' key with a value of an Array Hashes" do
|
185
|
+
@hash.should have_key('definitions')
|
186
|
+
@hash['definitions'].should be_a(Array)
|
187
|
+
@hash['definitions'].each do |item|
|
188
|
+
item.should be_a(Hash)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
it "has a 'name' key value pair in a Hash of the 'definitions' Array of Hashes" do
|
193
|
+
@hash['definitions'].first.should have_key('name')
|
194
|
+
end
|
195
|
+
|
196
|
+
it "has a 'path' key value pair in a Hash of the 'definitions' Array of Hashes" do
|
197
|
+
@hash['definitions'].first.should have_key('path')
|
198
|
+
end
|
199
|
+
|
200
|
+
it "has a 'checksum' key value pair in a Hash of the 'definitions' Array of Hashes" do
|
201
|
+
@hash['definitions'].first.should have_key('checksum')
|
202
|
+
end
|
203
|
+
|
204
|
+
it "has a 'specificity' key value pair in a Hash of the 'definitions' Array of Hashes" do
|
205
|
+
@hash['definitions'].first.should have_key('specificity')
|
206
|
+
end
|
207
|
+
|
208
|
+
it "has a 'libraries' key with a value of an Array Hashes" do
|
209
|
+
@hash.should have_key('libraries')
|
210
|
+
@hash['libraries'].should be_a(Array)
|
211
|
+
@hash['libraries'].each do |item|
|
212
|
+
item.should be_a(Hash)
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
it "has a 'name' key value pair in a Hash of the 'libraries' Array of Hashes" do
|
217
|
+
@hash['libraries'].first.should have_key('name')
|
218
|
+
end
|
219
|
+
|
220
|
+
it "has a 'path' key value pair in a Hash of the 'libraries' Array of Hashes" do
|
221
|
+
@hash['libraries'].first.should have_key('path')
|
222
|
+
end
|
223
|
+
|
224
|
+
it "has a 'checksum' key value pair in a Hash of the 'libraries' Array of Hashes" do
|
225
|
+
@hash['libraries'].first.should have_key('checksum')
|
226
|
+
end
|
227
|
+
|
228
|
+
it "has a 'specificity' key value pair in a Hash of the 'libraries' Array of Hashes" do
|
229
|
+
@hash['libraries'].first.should have_key('specificity')
|
230
|
+
end
|
231
|
+
|
232
|
+
it "has a 'attributes' key with a value of an Array Hashes" do
|
233
|
+
@hash.should have_key('attributes')
|
234
|
+
@hash['attributes'].should be_a(Array)
|
235
|
+
@hash['attributes'].each do |item|
|
236
|
+
item.should be_a(Hash)
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
it "has a 'name' key value pair in a Hash of the 'attributes' Array of Hashes" do
|
241
|
+
@hash['attributes'].first.should have_key('name')
|
242
|
+
end
|
243
|
+
|
244
|
+
it "has a 'path' key value pair in a Hash of the 'attributes' Array of Hashes" do
|
245
|
+
@hash['attributes'].first.should have_key('path')
|
246
|
+
end
|
247
|
+
|
248
|
+
it "has a 'checksum' key value pair in a Hash of the 'attributes' Array of Hashes" do
|
249
|
+
@hash['attributes'].first.should have_key('checksum')
|
250
|
+
end
|
251
|
+
|
252
|
+
it "has a 'specificity' key value pair in a Hash of the 'attributes' Array of Hashes" do
|
253
|
+
@hash['attributes'].first.should have_key('specificity')
|
254
|
+
end
|
255
|
+
|
256
|
+
it "has a 'files' key with a value of an Array Hashes" do
|
257
|
+
@hash.should have_key('files')
|
258
|
+
@hash['files'].should be_a(Array)
|
259
|
+
@hash['files'].each do |item|
|
260
|
+
item.should be_a(Hash)
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
it "has a 'name' key value pair in a Hash of the 'files' Array of Hashes" do
|
265
|
+
@hash['files'].first.should have_key('name')
|
266
|
+
end
|
267
|
+
|
268
|
+
it "has a 'path' key value pair in a Hash of the 'files' Array of Hashes" do
|
269
|
+
@hash['files'].first.should have_key('path')
|
270
|
+
end
|
271
|
+
|
272
|
+
it "has a 'checksum' key value pair in a Hash of the 'files' Array of Hashes" do
|
273
|
+
@hash['files'].first.should have_key('checksum')
|
274
|
+
end
|
275
|
+
|
276
|
+
it "has a 'specificity' key value pair in a Hash of the 'files' Array of Hashes" do
|
277
|
+
@hash['files'].first.should have_key('specificity')
|
278
|
+
end
|
279
|
+
|
280
|
+
it "has a 'templates' key with a value of an Array Hashes" do
|
281
|
+
@hash.should have_key('templates')
|
282
|
+
@hash['templates'].should be_a(Array)
|
283
|
+
@hash['templates'].each do |item|
|
284
|
+
item.should be_a(Hash)
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
it "has a 'name' key value pair in a Hash of the 'templates' Array of Hashes" do
|
289
|
+
@hash['templates'].first.should have_key('name')
|
290
|
+
end
|
291
|
+
|
292
|
+
it "has a 'path' key value pair in a Hash of the 'templates' Array of Hashes" do
|
293
|
+
@hash['templates'].first.should have_key('path')
|
294
|
+
end
|
295
|
+
|
296
|
+
it "has a 'checksum' key value pair in a Hash of the 'templates' Array of Hashes" do
|
297
|
+
@hash['templates'].first.should have_key('checksum')
|
298
|
+
end
|
299
|
+
|
300
|
+
it "has a 'specificity' key value pair in a Hash of the 'templates' Array of Hashes" do
|
301
|
+
@hash['templates'].first.should have_key('specificity')
|
302
|
+
end
|
303
|
+
|
304
|
+
it "has a 'resources' key with a value of an Array Hashes" do
|
305
|
+
@hash.should have_key('resources')
|
306
|
+
@hash['resources'].should be_a(Array)
|
307
|
+
@hash['resources'].each do |item|
|
308
|
+
item.should be_a(Hash)
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
it "has a 'name' key value pair in a Hash of the 'resources' Array of Hashes" do
|
313
|
+
@hash['resources'].first.should have_key('name')
|
314
|
+
end
|
315
|
+
|
316
|
+
it "has a 'path' key value pair in a Hash of the 'resources' Array of Hashes" do
|
317
|
+
@hash['resources'].first.should have_key('path')
|
318
|
+
end
|
319
|
+
|
320
|
+
it "has a 'checksum' key value pair in a Hash of the 'resources' Array of Hashes" do
|
321
|
+
@hash['resources'].first.should have_key('checksum')
|
322
|
+
end
|
323
|
+
|
324
|
+
it "has a 'specificity' key value pair in a Hash of the 'resources' Array of Hashes" do
|
325
|
+
@hash['resources'].first.should have_key('specificity')
|
326
|
+
end
|
327
|
+
|
328
|
+
it "has a 'providers' key with a value of an Array Hashes" do
|
329
|
+
@hash.should have_key('providers')
|
330
|
+
@hash['providers'].should be_a(Array)
|
331
|
+
@hash['providers'].each do |item|
|
332
|
+
item.should be_a(Hash)
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
it "has a 'name' key value pair in a Hash of the 'providers' Array of Hashes" do
|
337
|
+
@hash['providers'].first.should have_key('name')
|
338
|
+
end
|
339
|
+
|
340
|
+
it "has a 'path' key value pair in a Hash of the 'providers' Array of Hashes" do
|
341
|
+
@hash['providers'].first.should have_key('path')
|
342
|
+
end
|
343
|
+
|
344
|
+
it "has a 'checksum' key value pair in a Hash of the 'providers' Array of Hashes" do
|
345
|
+
@hash['providers'].first.should have_key('checksum')
|
346
|
+
end
|
347
|
+
|
348
|
+
it "has a 'specificity' key value pair in a Hash of the 'providers' Array of Hashes" do
|
349
|
+
@hash['providers'].first.should have_key('specificity')
|
350
|
+
end
|
351
|
+
|
352
|
+
it "has a 'root_files' key with a value of an Array Hashes" do
|
353
|
+
@hash.should have_key('root_files')
|
354
|
+
@hash['root_files'].should be_a(Array)
|
355
|
+
@hash['root_files'].each do |item|
|
356
|
+
item.should be_a(Hash)
|
357
|
+
end
|
358
|
+
end
|
359
|
+
|
360
|
+
it "has a 'name' key value pair in a Hash of the 'root_files' Array of Hashes" do
|
361
|
+
@hash['root_files'].first.should have_key('name')
|
362
|
+
end
|
363
|
+
|
364
|
+
it "has a 'path' key value pair in a Hash of the 'root_files' Array of Hashes" do
|
365
|
+
@hash['root_files'].first.should have_key('path')
|
366
|
+
end
|
367
|
+
|
368
|
+
it "has a 'checksum' key value pair in a Hash of the 'root_files' Array of Hashes" do
|
369
|
+
@hash['root_files'].first.should have_key('checksum')
|
370
|
+
end
|
371
|
+
|
372
|
+
it "has a 'specificity' key value pair in a Hash of the 'root_files' Array of Hashes" do
|
373
|
+
@hash['root_files'].first.should have_key('specificity')
|
374
|
+
end
|
375
|
+
|
376
|
+
it "has a 'cookbook_name' key with a String value" do
|
377
|
+
@hash.should have_key('cookbook_name')
|
378
|
+
@hash['cookbook_name'].should be_a(String)
|
379
|
+
end
|
380
|
+
|
381
|
+
it "has a 'metadata' key with a Cookbook::Metadata value" do
|
382
|
+
@hash.should have_key('metadata')
|
383
|
+
@hash['metadata'].should be_a(Chef::Cookbook::Metadata)
|
384
|
+
end
|
385
|
+
|
386
|
+
it "has a 'version' key with a String value" do
|
387
|
+
@hash.should have_key('version')
|
388
|
+
@hash['version'].should be_a(String)
|
389
|
+
end
|
390
|
+
|
391
|
+
it "has a 'name' key with a String value" do
|
392
|
+
@hash.should have_key('name')
|
393
|
+
@hash['name'].should be_a(String)
|
394
|
+
end
|
395
|
+
|
396
|
+
it "has a value containing the cookbook name and version separated by a dash for 'name'" do
|
397
|
+
name, version = @hash['name'].split('-')
|
398
|
+
|
399
|
+
name.should eql(cookbook_name)
|
400
|
+
version.should eql(cookbook_version)
|
401
|
+
end
|
402
|
+
|
403
|
+
it "has a 'chef_type' key with 'cookbook_version' as the value" do
|
404
|
+
@hash.should have_key('chef_type')
|
405
|
+
@hash['chef_type'].should eql("cookbook_version")
|
406
|
+
end
|
407
|
+
end
|
408
|
+
|
409
|
+
describe "#to_json" do
|
410
|
+
before(:each) do
|
411
|
+
@json = subject.to_json
|
412
|
+
end
|
413
|
+
|
414
|
+
it "has a 'json_class' key with 'Chef::CookbookVersion' as the value" do
|
415
|
+
@json.should have_json_path('json_class')
|
416
|
+
parse_json(@json)['json_class'].should eql("Chef::CookbookVersion")
|
417
|
+
end
|
418
|
+
end
|
419
|
+
end
|
420
|
+
end
|