summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLamont Granquist <lamont@scriptkiddie.org>2017-02-06 18:36:16 -0800
committerLamont Granquist <lamont@scriptkiddie.org>2017-02-07 11:27:09 -0800
commitac7cda9de8a41754226894336794b7972d33a1b8 (patch)
tree7a3e4da5307209eac6ec6c253a178d4a58b203fb
parentb7af0810fc7c8437585887dd3abf1b62dc773818 (diff)
downloadchef-ac7cda9de8a41754226894336794b7972d33a1b8.tar.gz
add unit tests for `which` behavior
Signed-off-by: Lamont Granquist <lamont@scriptkiddie.org>
-rw-r--r--lib/chef/mixin/which.rb7
-rw-r--r--spec/unit/mixin/which.rb106
2 files changed, 112 insertions, 1 deletions
diff --git a/lib/chef/mixin/which.rb b/lib/chef/mixin/which.rb
index a81aacd89b..faa46b9594 100644
--- a/lib/chef/mixin/which.rb
+++ b/lib/chef/mixin/which.rb
@@ -25,8 +25,8 @@ class Chef
def where(*cmds, extra_path: nil, &block)
# NOTE: unnecessarily duplicates function of path_sanity
extra_path ||= [ "/bin", "/usr/bin", "/sbin", "/usr/sbin" ]
+ paths = env_path.split(File::PATH_SEPARATOR) + extra_path
cmds.map do |cmd|
- paths = ENV["PATH"].split(File::PATH_SEPARATOR) + extra_path
paths.map do |path|
filename = Chef.path_to(File.join(path, cmd))
filename if valid_executable?(filename, &block)
@@ -36,6 +36,11 @@ class Chef
private
+ # for test stubbing
+ def env_path
+ ENV["PATH"]
+ end
+
def valid_executable?(filename, &block)
return false unless File.executable?(filename) && !File.directory?(filename)
block ? yield(filename) : true
diff --git a/spec/unit/mixin/which.rb b/spec/unit/mixin/which.rb
new file mode 100644
index 0000000000..50179a9b11
--- /dev/null
+++ b/spec/unit/mixin/which.rb
@@ -0,0 +1,106 @@
+#
+# Author:: Seth Chisamore (<schisamo@chef.io>)
+# Copyright:: Copyright 2011-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"
+
+class TestClass
+ include Chef::Mixin::Which
+end
+
+describe Chef::Mixin::Which do
+
+ let(:test) { TestClass.new }
+
+ def self.test_which(description, *args, finds: nil, others: nil, directory: false, &block)
+ it description do
+ # stub the ENV['PATH']
+ expect(test).to receive(:env_path).and_return(["/dir1", "/dir2" ].join(File::PATH_SEPARATOR))
+
+ # most files should not be found
+ allow(File).to receive(:executable?).and_return(false)
+ allow(File).to receive(:directory?).and_return(false)
+
+ # stub the expectation
+ expect(File).to receive(:executable?).with(finds).and_return(true) if finds
+
+ # if the file we find is a directory
+ expect(File).to receive(:directory?).with(finds).and_return(true) if finds && directory
+
+ # allow for stubbing other paths to exist that we should not find
+ if others
+ others.each do |other|
+ allow(File).to receive(:executable?).with(other).and_return(true)
+ end
+ end
+
+ # setup the actual expectation on the return value
+ if finds && !directory
+ expect(test.which(*args, &block)).to eql(finds)
+ else
+ expect(test.which(*args, &block)).to eql(false)
+ end
+ end
+ end
+
+ describe "#which" do
+ context "simple usage" do
+ test_which("returns false when it does not find anything", "foo1")
+
+ ["/dir1", "/dir2", "/bin", "/usr/bin", "/sbin", "/usr/sbin" ].each do |dir|
+ test_which("finds `foo1` in #{dir} when it is stubbed", "foo1", finds: "#{dir}/foo1")
+ end
+
+ test_which("does not find an executable directory", "foo1", finds: "/dir1/foo1", directory: true)
+ end
+
+ context "with an array of args" do
+ test_which("finds the first arg", "foo1", "foo2", finds: "/dir2/foo1")
+
+ test_which("finds the second arg", "foo1", "foo2", finds: "/dir2/foo2")
+
+ test_which("finds the first arg when there's both", "foo1", "foo2", finds: "/dir2/foo1", others: [ "/dir1/foo2" ])
+
+ test_which("and the directory order can be reversed", "foo1", "foo2", finds: "/dir1/foo1", others: [ "/dir2/foo2" ])
+
+ test_which("or be the same", "foo1", "foo2", finds: "/dir1/foo1", others: [ "/dir1/foo2" ])
+ end
+
+ context "with a block" do
+ test_which("doesnt find it if its false", "foo1", others: [ "/dir1/foo1" ]) do |f|
+ false
+ end
+
+ test_which("finds it if its true", "foo1", finds: "/dir1/foo1") do |f|
+ true
+ end
+
+ test_which("passes in the filename as the arg", "foo1", finds: "/dir1/foo1") do |f|
+ raise "bad arg to block" unless f == "/dir1/foo1"
+ true
+ end
+
+ test_which("arrays with blocks", "foo1", "foo2", finds: "/dir2/foo1", others: [ "/dir1/foo2" ]) do |f|
+ raise "bad arg to block" unless f == "/dir2/foo1" || f == "/dir1/foo2"
+ true
+ end
+ end
+ end
+
+ context "where" do
+ end
+end