diff options
Diffstat (limited to 'spec/unit')
-rw-r--r-- | spec/unit/chef_fs/file_system/repository/base_file_spec.rb | 18 | ||||
-rw-r--r-- | spec/unit/decorator/lazy_array_spec.rb | 58 | ||||
-rw-r--r-- | spec/unit/decorator/lazy_spec.rb | 39 | ||||
-rw-r--r-- | spec/unit/decorator_spec.rb | 142 | ||||
-rw-r--r-- | spec/unit/provider/package/rubygems_spec.rb | 42 | ||||
-rw-r--r-- | spec/unit/provider/package_spec.rb | 13 |
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 |