summaryrefslogtreecommitdiff
path: root/spec/unit
diff options
context:
space:
mode:
Diffstat (limited to 'spec/unit')
-rw-r--r--spec/unit/chef_fs/file_system/repository/base_file_spec.rb18
-rw-r--r--spec/unit/decorator/lazy_array_spec.rb58
-rw-r--r--spec/unit/decorator/lazy_spec.rb39
-rw-r--r--spec/unit/decorator_spec.rb142
-rw-r--r--spec/unit/provider/package/rubygems_spec.rb42
-rw-r--r--spec/unit/provider/package_spec.rb13
6 files changed, 293 insertions, 19 deletions
diff --git a/spec/unit/chef_fs/file_system/repository/base_file_spec.rb b/spec/unit/chef_fs/file_system/repository/base_file_spec.rb
index bb0c267368..625ef32dca 100644
--- a/spec/unit/chef_fs/file_system/repository/base_file_spec.rb
+++ b/spec/unit/chef_fs/file_system/repository/base_file_spec.rb
@@ -47,7 +47,7 @@ describe Chef::ChefFS::FileSystem::Repository::BaseFile do
end
context "#is_json_file?" do
- it "returns false when the file is not json" do
+ it "returns false when the file is not json", pending: "We assume that everything is ruby or JSON" do
file = described_class.new("test_file.dpkg", parent)
expect(file.is_json_file?).to be_falsey
end
@@ -63,11 +63,16 @@ describe Chef::ChefFS::FileSystem::Repository::BaseFile do
expect(file.name_valid?).to be_falsey
end
- it "rejects non json files" do
+ it "rejects non json files", pending: "We assume that everything is ruby or JSON" do
file = described_class.new("test_file.dpkg", parent)
expect(file.name_valid?).to be_falsey
end
+ it "allows ruby files" do
+ file = described_class.new("test_file.rb", parent)
+ expect(file.name_valid?).to be_truthy
+ end
+
it "allows correctly named files" do
expect(file.name_valid?).to be_truthy
end
@@ -105,14 +110,7 @@ describe Chef::ChefFS::FileSystem::Repository::BaseFile do
context "#write" do
context "minimises a json object" do
- it "not if pretty json is off" do
- expect(file).to_not receive(:minimize)
- file.write(content)
- end
-
- it "not if it's not a json file" do
- file = described_class.new("test_file.dpkg", parent)
- file.write_pretty_json = true
+ it "unless pretty json is off" do
expect(file).to_not receive(:minimize)
file.write(content)
end
diff --git a/spec/unit/decorator/lazy_array_spec.rb b/spec/unit/decorator/lazy_array_spec.rb
new file mode 100644
index 0000000000..0c5c2eeee0
--- /dev/null
+++ b/spec/unit/decorator/lazy_array_spec.rb
@@ -0,0 +1,58 @@
+#
+# Author:: Lamont Granquist (<lamont@chef.io>)
+# Copyright:: Copyright 2015-2016, Chef Software Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require "spec_helper"
+
+describe Chef::Decorator::LazyArray do
+ def foo
+ @foo ||= 1
+ end
+
+ def bar
+ @bar ||= 2
+ end
+
+ let(:decorator) do
+ Chef::Decorator::LazyArray.new { [ foo, bar ] }
+ end
+
+ it "behaves like an array" do
+ expect(decorator[0]).to eql(1)
+ expect(decorator[1]).to eql(2)
+ end
+
+ it "accessing the array elements is lazy" do
+ expect(decorator[0].class).to eql(Chef::Decorator::Lazy)
+ expect(decorator[1].class).to eql(Chef::Decorator::Lazy)
+ expect(@foo).to be nil
+ expect(@bar).to be nil
+ end
+
+ it "calling a method on the array element runs the proc (and both elements are autovivified)" do
+ expect(decorator[0].nil?).to be false
+ expect(@foo).to equal(1)
+ expect(@bar).to equal(2)
+ end
+
+ it "if we loop over the elements and do nothing then its not lazy" do
+ # we don't know how many elements there are unless we evaluate the proc
+ decorator.each { |i| }
+ expect(@foo).to equal(1)
+ expect(@bar).to equal(2)
+ end
+end
diff --git a/spec/unit/decorator/lazy_spec.rb b/spec/unit/decorator/lazy_spec.rb
new file mode 100644
index 0000000000..4ea8301b63
--- /dev/null
+++ b/spec/unit/decorator/lazy_spec.rb
@@ -0,0 +1,39 @@
+#
+# Author:: Lamont Granquist (<lamont@chef.io>)
+# Copyright:: Copyright 2015-2016, Chef Software Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require "spec_helper"
+
+describe Chef::Decorator::Lazy do
+ let(:decorator) do
+ @a = 0
+ Chef::Decorator::Lazy.new { @a = @a + 1 }
+ end
+
+ it "decorates an object" do
+ expect(decorator.even?).to be false
+ end
+
+ it "the proc runs and does work" do
+ expect(decorator).to eql(1)
+ end
+
+ it "creating the decorator does not cause the proc to run" do
+ decorator
+ expect(@a).to eql(0)
+ end
+end
diff --git a/spec/unit/decorator_spec.rb b/spec/unit/decorator_spec.rb
new file mode 100644
index 0000000000..6d73db2cc4
--- /dev/null
+++ b/spec/unit/decorator_spec.rb
@@ -0,0 +1,142 @@
+#
+# Author:: Lamont Granquist (<lamont@chef.io>)
+# Copyright:: Copyright 2015-2016, Chef Software Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require "spec_helper"
+
+def impersonates_a(klass)
+ it "#is_a?(#{klass}) is true" do
+ expect(decorator.is_a?(klass)).to be true
+ end
+
+ it "#is_a?(Chef::Decorator) is true" do
+ expect(decorator.is_a?(Chef::Decorator)).to be true
+ end
+
+ it "#kind_of?(#{klass}) is true" do
+ expect(decorator.kind_of?(klass)).to be true
+ end
+
+ it "#kind_of?(Chef::Decorator) is true" do
+ expect(decorator.kind_of?(Chef::Decorator)).to be true
+ end
+
+ it "#instance_of?(#{klass}) is false" do
+ expect(decorator.instance_of?(klass)).to be false
+ end
+
+ it "#instance_of?(Chef::Decorator) is true" do
+ expect(decorator.instance_of?(Chef::Decorator)).to be true
+ end
+
+ it "#class is Chef::Decorator" do
+ expect(decorator.class).to eql(Chef::Decorator)
+ end
+end
+
+describe Chef::Decorator do
+ let(:obj) {}
+ let(:decorator) { Chef::Decorator.new(obj) }
+
+ context "when the obj is a string" do
+ let(:obj) { "STRING" }
+
+ impersonates_a(String)
+
+ it "#nil? is false" do
+ expect(decorator.nil?).to be false
+ end
+
+ it "!! is true" do
+ expect(!!decorator).to be true
+ end
+
+ it "dup returns a decorator" do
+ expect(decorator.dup.class).to be Chef::Decorator
+ end
+
+ it "dup dup's the underlying thing" do
+ expect(decorator.dup.__getobj__).not_to equal(decorator.__getobj__)
+ end
+ end
+
+ context "when the obj is a nil" do
+ let(:obj) { nil }
+
+ it "#nil? is true" do
+ expect(decorator.nil?).to be true
+ end
+
+ it "!! is false" do
+ expect(!!decorator).to be false
+ end
+
+ impersonates_a(NilClass)
+ end
+
+ context "when the obj is an empty Hash" do
+ let(:obj) { {} }
+
+ impersonates_a(Hash)
+
+ it "formats it correctly through ffi-yajl and not the JSON gem" do
+ # this relies on a quirk of pretty formatting whitespace between yajl and ruby's JSON
+ expect(FFI_Yajl::Encoder.encode(decorator, pretty: true)).to eql("{\n\n}\n")
+ end
+ end
+
+ context "whent he obj is a Hash with elements" do
+ let(:obj) { { foo: "bar", baz: "qux" } }
+
+ impersonates_a(Hash)
+
+ it "dup is shallow on the Hash" do
+ expect(decorator.dup[:baz]).to equal(decorator[:baz])
+ end
+
+ it "deep mutating the dup'd hash mutates the origin" do
+ decorator.dup[:baz] << "qux"
+ expect(decorator[:baz]).to eql("quxqux")
+ end
+ end
+
+ context "memoizing methods" do
+ let(:obj) { {} }
+
+ it "calls method_missing only once" do
+ expect(decorator).to receive(:method_missing).once.and_call_original
+ expect(decorator.keys).to eql([])
+ expect(decorator.keys).to eql([])
+ end
+
+ it "switching a Hash to an Array responds to keys then does not" do
+ expect(decorator.respond_to?(:keys)).to be true
+ expect(decorator.keys).to eql([])
+ decorator.__setobj__([])
+ expect(decorator.respond_to?(:keys)).to be false
+ expect { decorator.keys }.to raise_error(NoMethodError)
+ end
+
+ it "memoization of methods happens on the instances, not the classes" do
+ decorator2 = Chef::Decorator.new([])
+ expect(decorator.respond_to?(:keys)).to be true
+ expect(decorator.keys).to eql([])
+ expect(decorator2.respond_to?(:keys)).to be false
+ expect { decorator2.keys }.to raise_error(NoMethodError)
+ end
+ end
+end
diff --git a/spec/unit/provider/package/rubygems_spec.rb b/spec/unit/provider/package/rubygems_spec.rb
index 6e77e7c112..f87c261ec0 100644
--- a/spec/unit/provider/package/rubygems_spec.rb
+++ b/spec/unit/provider/package/rubygems_spec.rb
@@ -496,12 +496,36 @@ describe Chef::Provider::Package::Rubygems do
provider.load_current_resource
end
- it "does not query for available versions when the current version is the target version" do
- expect(provider.candidate_version).to be_nil
+ context "when the current version is the target version" do
+ it "does not query for available versions" do
+ # NOTE: odd use case -- we've equality pinned a version, but are calling :upgrade
+ expect(provider.gem_env).not_to receive(:candidate_version_from_remote)
+ expect(provider.gem_env).not_to receive(:install)
+ provider.run_action(:upgrade)
+ expect(new_resource).not_to be_updated_by_last_action
+ end
end
- context "when the current version is not the target version" do
- let(:target_version) { "9000.0.2" }
+ context "when the current version satisfies the target version requirement" do
+ let(:target_version) { ">= 0" }
+
+ it "does not query for available versions on install" do
+ expect(provider.gem_env).not_to receive(:candidate_version_from_remote)
+ expect(provider.gem_env).not_to receive(:install)
+ provider.run_action(:install)
+ expect(new_resource).not_to be_updated_by_last_action
+ end
+
+ it "queries for available versions on upgrade" do
+ expect(provider.gem_env).to receive(:candidate_version_from_remote).
+ and_return(Gem::Version.new("9000.0.2"))
+ expect(provider.gem_env).to receive(:install)
+ provider.run_action(:upgrade)
+ expect(new_resource).to be_updated_by_last_action
+ end
+ end
+
+ context "when the requested source is a remote server" do
let(:source) { "http://mygems.example.com" }
it "determines the candidate version by querying the remote gem servers" do
@@ -669,6 +693,11 @@ describe Chef::Provider::Package::Rubygems do
expect(provider.gem_env).not_to receive(:install)
provider.run_action(:install)
end
+
+ it "performs the upgrade" do
+ expect(provider.gem_env).to receive(:install)
+ provider.run_action(:upgrade)
+ end
end
context "if the fuzzy operator is used" do
@@ -679,6 +708,11 @@ describe Chef::Provider::Package::Rubygems do
expect(provider.gem_env).not_to receive(:install)
provider.run_action(:install)
end
+
+ it "it upgrades an existing gem" do
+ expect(provider.gem_env).to receive(:install)
+ provider.run_action(:upgrade)
+ end
end
end
end
diff --git a/spec/unit/provider/package_spec.rb b/spec/unit/provider/package_spec.rb
index 393b5f6853..2ef58db9f3 100644
--- a/spec/unit/provider/package_spec.rb
+++ b/spec/unit/provider/package_spec.rb
@@ -576,8 +576,11 @@ describe "Chef::Provider::Package - Multi" do
let(:new_resource) { Chef::Resource::Package.new(%w{emacs vi}) }
let(:current_resource) { Chef::Resource::Package.new(%w{emacs vi}) }
let(:candidate_version) { [ "1.0", "6.2" ] }
+ class MyPackageProvider < Chef::Provider::Package
+ use_multipackage_api
+ end
let(:provider) do
- provider = Chef::Provider::Package.new(new_resource, run_context)
+ provider = MyPackageProvider.new(new_resource, run_context)
provider.current_resource = current_resource
provider.candidate_version = candidate_version
provider
@@ -741,7 +744,7 @@ describe "Chef::Provider::Package - Multi" do
it "should remove the packages if all are installed" do
expect(provider).to be_removing_package
- expect(provider).to receive(:remove_package).with(%w{emacs vi}, nil)
+ expect(provider).to receive(:remove_package).with(%w{emacs vi}, [nil])
provider.run_action(:remove)
expect(new_resource).to be_updated
expect(new_resource).to be_updated_by_last_action
@@ -750,7 +753,7 @@ describe "Chef::Provider::Package - Multi" do
it "should remove the packages if some are installed" do
current_resource.version ["1.0", nil]
expect(provider).to be_removing_package
- expect(provider).to receive(:remove_package).with(%w{emacs vi}, nil)
+ expect(provider).to receive(:remove_package).with(%w{emacs vi}, [nil])
provider.run_action(:remove)
expect(new_resource).to be_updated
expect(new_resource).to be_updated_by_last_action
@@ -797,7 +800,7 @@ describe "Chef::Provider::Package - Multi" do
it "should purge the packages if all are installed" do
expect(provider).to be_removing_package
- expect(provider).to receive(:purge_package).with(%w{emacs vi}, nil)
+ expect(provider).to receive(:purge_package).with(%w{emacs vi}, [nil])
provider.run_action(:purge)
expect(new_resource).to be_updated
expect(new_resource).to be_updated_by_last_action
@@ -806,7 +809,7 @@ describe "Chef::Provider::Package - Multi" do
it "should purge the packages if some are installed" do
current_resource.version ["1.0", nil]
expect(provider).to be_removing_package
- expect(provider).to receive(:purge_package).with(%w{emacs vi}, nil)
+ expect(provider).to receive(:purge_package).with(%w{emacs vi}, [nil])
provider.run_action(:purge)
expect(new_resource).to be_updated
expect(new_resource).to be_updated_by_last_action