Module: Tap::Test::ShellTest
- Defined in:
- lib/tap/test/shell_test.rb,
lib/tap/test/shell_test/class_methods.rb,
lib/tap/test/shell_test/regexp_escape.rb
Overview
A module for testing shell scripts.
require 'test/unit'
class ShellTestSample < Test::Unit::TestCase
include Tap::Test::ShellTest
# these are the default sh_test options used
# in tests like test_sh_command_alias
self. = {
:cmd_pattern => '% inspect_argv',
:cmd => 'ruby -e "puts ARGV.inspect"'
}
def test_echo
assert_equal "goodnight moon", sh("echo goodnight moon").strip
end
def test_echo_using_sh_test
sh_test %q{
echo goodnight moon
goodnight moon
}
end
def test_sh_command_alias
sh_test("% inspect_env") do |output|
assert output !~ /NEW_ENV_VAR/
end
sh_test("NEW_ENV_VAR=blue % inspect_env") do |output|
assert output =~ /NEW_ENV_VAR=blue/
end
end
end
Defined Under Namespace
Modules: ClassMethods Classes: RegexpEscape
Class Method Summary collapse
-
.included(base) ⇒ Object
:nodoc:.
Instance Method Summary collapse
- #assert_alike(a, b, msg = nil) ⇒ Object
- #assert_output_equal(a, b, msg = nil) ⇒ Object
-
#quiet? ⇒ Boolean
Returns true if the ENV variable ‘QUIET’ is true.
-
#set_env(env = {}, replace = false) ⇒ Object
Sets the specified ENV variables and returns the current env.
-
#setup ⇒ Object
Sets up the ShellTest module.
-
#sh(cmd, options = {}) ⇒ Object
Executes the command using IO.popen and returns the stdout content.
- #sh_match(cmd, *regexps) {|result| ... } ⇒ Object
-
#sh_test(cmd, options = {}) {|result| ... } ⇒ Object
Peforms a shell test.
-
#sh_test_options ⇒ Object
Returns a hash of the default sh_test options.
-
#verbose? ⇒ Boolean
Returns true if the ENV variable ‘VERBOSE’ is true.
-
#with_env(env = {}, replace = false) ⇒ Object
Sets the specified ENV variables for the duration of the block.
Class Method Details
.included(base) ⇒ Object
:nodoc:
44 45 46 47 |
# File 'lib/tap/test/shell_test.rb', line 44 def self.included(base) # :nodoc: super base.extend ShellTest::ClassMethods end |
Instance Method Details
#assert_alike(a, b, msg = nil) ⇒ Object
266 267 268 269 270 271 272 273 274 275 276 277 278 279 |
# File 'lib/tap/test/shell_test.rb', line 266 def assert_alike(a, b, msg=nil) if b =~ a assert true else flunk %Q{ #{msg} ================= expected output like ================== #{whitespace_escape(a)} ======================== but was ======================== #{whitespace_escape(b)} ========================================================= } end end |
#assert_output_equal(a, b, msg = nil) ⇒ Object
250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 |
# File 'lib/tap/test/shell_test.rb', line 250 def assert_output_equal(a, b, msg=nil) a = a[1..-1] if a[0] == ?\n if a == b assert true else flunk %Q{ #{msg} ==================== expected output ==================== #{whitespace_escape(a)} ======================== but was ======================== #{whitespace_escape(b)} ========================================================= } end end |
#quiet? ⇒ Boolean
Returns true if the ENV variable ‘QUIET’ is true. When quiet, ShellTest does not print any extra information to $stdout.
If ‘VERBOSE’ and ‘QUIET’ are both set, verbose wins.
67 68 69 70 71 72 |
# File 'lib/tap/test/shell_test.rb', line 67 def quiet? return false if verbose? quiet = ENV['QUIET'] quiet && quiet =~ /^true$/i ? true : false end |
#set_env(env = {}, replace = false) ⇒ Object
Sets the specified ENV variables and returns the current env. If replace is true, current ENV variables are replaced; otherwise the new env variables are simply added to the existing set.
77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/tap/test/shell_test.rb', line 77 def set_env(env={}, replace=false) current_env = {} ENV.each_pair do |key, value| current_env[key] = value end ENV.clear if replace env.each_pair do |key, value| ENV[key] = value end if env current_env end |
#setup ⇒ Object
Sets up the ShellTest module. Be sure to call super if you override setup in an including module.
51 52 53 54 |
# File 'lib/tap/test/shell_test.rb', line 51 def setup super @notify_method_name = true end |
#sh(cmd, options = {}) ⇒ Object
Executes the command using IO.popen and returns the stdout content.
Note
On Windows this method requires the win32-popen3 utility. If it is not available, it will have to be installed:
% gem install win32-open3
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/tap/test/shell_test.rb', line 117 def sh(cmd, ={}) if @notify_method_name && !quiet? @notify_method_name = false puts puts method_name end original_cmd = cmd if cmd_pattern = [:cmd_pattern] cmd = cmd.sub(cmd_pattern, [:cmd].to_s) end start = Time.now result = with_env([:env], [:replace_env]) do IO.popen(cmd) do |io| yield(io) if block_given? io.read end end finish = Time.now elapsed = "%.3f" % [finish-start] puts " (#{elapsed}s) #{verbose? ? cmd : original_cmd}" unless quiet? result end |
#sh_match(cmd, *regexps) {|result| ... } ⇒ Object
231 232 233 234 235 236 237 238 239 240 241 242 |
# File 'lib/tap/test/shell_test.rb', line 231 def sh_match(cmd, *regexps) = regexps.last.kind_of?(Hash) ? regexps.pop : {} = .merge() result = sh(cmd, ) regexps.each do |regexp| assert_match regexp, result, cmd end yield(result) if block_given? result end |
#sh_test(cmd, options = {}) {|result| ... } ⇒ Object
Peforms a shell test. Shell tests execute the command and yield the $stdout result to the block for validation. The command is executed through sh, ie using IO.popen.
Options provided to sh_test are merged with the sh_test_options set for the class.
Command Aliases
The options allow specification of a command pattern that gets replaced with a command alias. Only the first instance of the command pattern is replaced. In addition, shell tests allow the expected result to be specified inline with the command. Used together, these allow multiple tests of a complex command to be specified easily:
opts = {
:cmd_pattern => '% argv_inspect',
:cmd => 'ruby -e "puts ARGV.inspect"'
}
sh_test %Q{
% argv_inspect goodnight moon
["goodnight", "moon"]
}, opts
sh_test %Q{
% argv_inspect hello world
["hello", "world"]
}, opts
Indents
To improve the readability of tests, sh_test will lstrip each line in the expected output to the same degree as the command line. So for instance these all pass:
sh_test %Q{
% argv_inspect hello world
["hello", "world"]
}, opts
sh_test %Q{
% argv_inspect hello world
["hello", "world"]
}, opts
sh_test %Q{
% argv_inspect hello world
["hello", "world"]
}, opts
Turn off indent stripping by specifying :indent => false.
ENV variables
Options may specify a hash of env variables that will be set in the subprocess.
sh_test %Q{
ruby -e "puts ENV['SAMPLE']"
value
}, :env => {'SAMPLE' => 'value'}
Note it is better to specify env variables in this way rather than through the command trick ‘VAR=value cmd …’, as that syntax does not work on Windows. As a point of interest, see gist.github.com/107363 for a demonstration of ENV variables being inherited by subprocesses.
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 |
# File 'lib/tap/test/shell_test.rb', line 212 def sh_test(cmd, ={}) = .merge() if cmd =~ /\A\s*?\n?(\s*)(.*?\n)(.*)\z/m indent, cmd, expected = $1, $2, $3 cmd.strip! if indent.length > 0 && [:indents] expected.gsub!(/^\s{0,#{indent.length}}/, '') end end result = sh(cmd, ) assert_equal(expected, result, cmd) if expected yield(result) if block_given? result end |
#sh_test_options ⇒ Object
Returns a hash of the default sh_test options. See ShellTest::ClassMethods#sh_test_options.
246 247 248 |
# File 'lib/tap/test/shell_test.rb', line 246 def self.class. end |
#verbose? ⇒ Boolean
Returns true if the ENV variable ‘VERBOSE’ is true. When verbose, ShellTest prints the expanded commands of sh_test to $stdout.
58 59 60 61 |
# File 'lib/tap/test/shell_test.rb', line 58 def verbose? verbose = ENV['VERBOSE'] verbose && verbose =~ /^true$/i ? true : false end |
#with_env(env = {}, replace = false) ⇒ Object
Sets the specified ENV variables for the duration of the block. If replace is true, current ENV variables are replaced; otherwise the new env variables are simply added to the existing set.
Returns the block return.
97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/tap/test/shell_test.rb', line 97 def with_env(env={}, replace=false) current_env = nil begin current_env = set_env(env, replace) yield ensure if current_env set_env(current_env, true) end end end |