shell_test 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.rdoc +7 -0
 - data/MIT-LICENSE +19 -0
 - data/README.rdoc +146 -0
 - data/lib/shell_test/command_parser.rb +67 -0
 - data/lib/shell_test/file_methods.rb +208 -0
 - data/lib/shell_test/regexp_escape.rb +84 -0
 - data/lib/shell_test/shell_methods.rb +176 -0
 - data/lib/shell_test/unit/shim.rb +72 -0
 - data/lib/shell_test/unit.rb +40 -0
 - data/lib/shell_test/version.rb +3 -0
 - data/lib/shell_test.rb +8 -0
 - metadata +85 -0
 
    
        data/History.rdoc
    ADDED
    
    
    
        data/MIT-LICENSE
    ADDED
    
    | 
         @@ -0,0 +1,19 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            Copyright (c) 2011, Simon Chiang.
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Permission is hereby granted, free of charge, to any person obtaining a copy
         
     | 
| 
      
 4 
     | 
    
         
            +
            of this software and associated documentation files (the "Software"), to deal
         
     | 
| 
      
 5 
     | 
    
         
            +
            in the Software without restriction, including without limitation the rights
         
     | 
| 
      
 6 
     | 
    
         
            +
            to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
         
     | 
| 
      
 7 
     | 
    
         
            +
            copies of the Software, and to permit persons to whom the Software is
         
     | 
| 
      
 8 
     | 
    
         
            +
            furnished to do so, subject to the following conditions:
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            The above copyright notice and this permission notice shall be included in all
         
     | 
| 
      
 11 
     | 
    
         
            +
            copies or substantial portions of the Software.
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
         
     | 
| 
      
 14 
     | 
    
         
            +
            IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
         
     | 
| 
      
 15 
     | 
    
         
            +
            FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
         
     | 
| 
      
 16 
     | 
    
         
            +
            AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
         
     | 
| 
      
 17 
     | 
    
         
            +
            LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
         
     | 
| 
      
 18 
     | 
    
         
            +
            OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
         
     | 
| 
      
 19 
     | 
    
         
            +
            SOFTWARE.
         
     | 
    
        data/README.rdoc
    ADDED
    
    | 
         @@ -0,0 +1,146 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            = ShellTest
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Test modules for shell scripts.
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            == Description
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            Provides test modules to simplify testing of shell scripts.
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            ShellTest is not a testing framework. ShellTest integrates with Test::Unit and
         
     | 
| 
      
 10 
     | 
    
         
            +
            MiniTest out of the box, but it should be possible to include the test modules
         
     | 
| 
      
 11 
     | 
    
         
            +
            into other test frameworks.
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            == Usage
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            ShellTest builds on modules that provide specific functionality. The modules
         
     | 
| 
      
 16 
     | 
    
         
            +
            may be used independently, but by including ShellTest you get them all:
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
              require 'shell_test/unit'
         
     | 
| 
      
 19 
     | 
    
         
            +
              
         
     | 
| 
      
 20 
     | 
    
         
            +
              class ShellTestExample < Test::Unit::TestCase
         
     | 
| 
      
 21 
     | 
    
         
            +
                include ShellTest
         
     | 
| 
      
 22 
     | 
    
         
            +
              
         
     | 
| 
      
 23 
     | 
    
         
            +
                def test_a_script
         
     | 
| 
      
 24 
     | 
    
         
            +
                  script = prepare('script.sh') do |io|
         
     | 
| 
      
 25 
     | 
    
         
            +
                    io.puts "echo goodnight $1"
         
     | 
| 
      
 26 
     | 
    
         
            +
                  end
         
     | 
| 
      
 27 
     | 
    
         
            +
              
         
     | 
| 
      
 28 
     | 
    
         
            +
                  assert_script %{
         
     | 
| 
      
 29 
     | 
    
         
            +
                    $ sh '#{script}' moon
         
     | 
| 
      
 30 
     | 
    
         
            +
                    goodnight moon
         
     | 
| 
      
 31 
     | 
    
         
            +
                  }
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
            ==== {ShellMethods}[link:classes/ShellTest/ShellMethods.html]
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
            Provides the shell testing methods. These methods are designed to input a
         
     | 
| 
      
 38 
     | 
    
         
            +
            string that looks like terminal input/output. Commands are parsed out of the
         
     | 
| 
      
 39 
     | 
    
         
            +
            string, run, and then anything printed to stdout is compared to the expected
         
     | 
| 
      
 40 
     | 
    
         
            +
            output. In addition the exit status is checked for success (0).
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
            Special comments following the first line of a command can turn off
         
     | 
| 
      
 43 
     | 
    
         
            +
            output/status checking, or specify a different exit status to expect.
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
              require 'shell_test/unit'
         
     | 
| 
      
 46 
     | 
    
         
            +
              
         
     | 
| 
      
 47 
     | 
    
         
            +
              class ShellMethodsExample < Test::Unit::TestCase
         
     | 
| 
      
 48 
     | 
    
         
            +
                include ShellTest::ShellMethods
         
     | 
| 
      
 49 
     | 
    
         
            +
              
         
     | 
| 
      
 50 
     | 
    
         
            +
                def test_a_script_using_variables
         
     | 
| 
      
 51 
     | 
    
         
            +
                  with_env("THING" => "moon") do
         
     | 
| 
      
 52 
     | 
    
         
            +
                    assert_script %{
         
     | 
| 
      
 53 
     | 
    
         
            +
                      $ echo "goodnight $THING"
         
     | 
| 
      
 54 
     | 
    
         
            +
                      goodnight moon
         
     | 
| 
      
 55 
     | 
    
         
            +
                    }
         
     | 
| 
      
 56 
     | 
    
         
            +
                  end
         
     | 
| 
      
 57 
     | 
    
         
            +
                end
         
     | 
| 
      
 58 
     | 
    
         
            +
                
         
     | 
| 
      
 59 
     | 
    
         
            +
                def test_multiple_commands
         
     | 
| 
      
 60 
     | 
    
         
            +
                  assert_script %{
         
     | 
| 
      
 61 
     | 
    
         
            +
                    $ echo one
         
     | 
| 
      
 62 
     | 
    
         
            +
                    one
         
     | 
| 
      
 63 
     | 
    
         
            +
                    $ echo two
         
     | 
| 
      
 64 
     | 
    
         
            +
                    two
         
     | 
| 
      
 65 
     | 
    
         
            +
                  }
         
     | 
| 
      
 66 
     | 
    
         
            +
                end
         
     | 
| 
      
 67 
     | 
    
         
            +
              
         
     | 
| 
      
 68 
     | 
    
         
            +
                def test_multiline_commands
         
     | 
| 
      
 69 
     | 
    
         
            +
                  assert_script %{
         
     | 
| 
      
 70 
     | 
    
         
            +
                    $ for n in one two; do
         
     | 
| 
      
 71 
     | 
    
         
            +
                    >   echo $n
         
     | 
| 
      
 72 
     | 
    
         
            +
                    > done
         
     | 
| 
      
 73 
     | 
    
         
            +
                    one
         
     | 
| 
      
 74 
     | 
    
         
            +
                    two
         
     | 
| 
      
 75 
     | 
    
         
            +
                  }
         
     | 
| 
      
 76 
     | 
    
         
            +
                end
         
     | 
| 
      
 77 
     | 
    
         
            +
             
         
     | 
| 
      
 78 
     | 
    
         
            +
                def test_exit_statuses
         
     | 
| 
      
 79 
     | 
    
         
            +
                  assert_script %{
         
     | 
| 
      
 80 
     | 
    
         
            +
                    $ true  # [0]
         
     | 
| 
      
 81 
     | 
    
         
            +
                    $ false # [1]
         
     | 
| 
      
 82 
     | 
    
         
            +
                  }
         
     | 
| 
      
 83 
     | 
    
         
            +
                end
         
     | 
| 
      
 84 
     | 
    
         
            +
                
         
     | 
| 
      
 85 
     | 
    
         
            +
                def test_exit_status_and_not_ouptut
         
     | 
| 
      
 86 
     | 
    
         
            +
                  assert_script %{
         
     | 
| 
      
 87 
     | 
    
         
            +
                    $ date  # [0] ...
         
     | 
| 
      
 88 
     | 
    
         
            +
                  }
         
     | 
| 
      
 89 
     | 
    
         
            +
                end
         
     | 
| 
      
 90 
     | 
    
         
            +
                
         
     | 
| 
      
 91 
     | 
    
         
            +
                def test_output_with_inline_regexps
         
     | 
| 
      
 92 
     | 
    
         
            +
                  assert_script_match %{
         
     | 
| 
      
 93 
     | 
    
         
            +
                    $ cal
         
     | 
| 
      
 94 
     | 
    
         
            +
                    :...:
         
     | 
| 
      
 95 
     | 
    
         
            +
                    Su Mo Tu We Th Fr Sa
         
     | 
| 
      
 96 
     | 
    
         
            +
                    :...:
         
     | 
| 
      
 97 
     | 
    
         
            +
                  }
         
     | 
| 
      
 98 
     | 
    
         
            +
                end
         
     | 
| 
      
 99 
     | 
    
         
            +
              end
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
            ==== {FileMethods}[link:classes/ShellTest/FileMethods.html]
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
            Sets up a temporary, test-specific directory for working with files. This
         
     | 
| 
      
 104 
     | 
    
         
            +
            approach is better in most cases than using Tempfile because you can flag the
         
     | 
| 
      
 105 
     | 
    
         
            +
            directory to be saved on a failure (using ENV['KEEP_OUTPUTS']='true').
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
            By default the directory is guessed based off of the test file and test
         
     | 
| 
      
 108 
     | 
    
         
            +
            method. If this example were located in the 'test/file_methods_example.rb'
         
     | 
| 
      
 109 
     | 
    
         
            +
            file, then the directory for the test case would be
         
     | 
| 
      
 110 
     | 
    
         
            +
            'test/file_methods_example/test_preparation_of_a_test_specific_file'.
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
              require 'shell_test/unit'
         
     | 
| 
      
 113 
     | 
    
         
            +
              
         
     | 
| 
      
 114 
     | 
    
         
            +
              class FileMethodsExample < Test::Unit::TestCase
         
     | 
| 
      
 115 
     | 
    
         
            +
                include ShellTest::FileMethods
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
                def test_preparation_of_a_test_specific_file
         
     | 
| 
      
 118 
     | 
    
         
            +
                  path = prepare('dir/file.txt') {|io| io << 'content' }
         
     | 
| 
      
 119 
     | 
    
         
            +
                  assert_equal "content", File.read(path)
         
     | 
| 
      
 120 
     | 
    
         
            +
                end
         
     | 
| 
      
 121 
     | 
    
         
            +
              end
         
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
      
 123 
     | 
    
         
            +
            == Installation
         
     | 
| 
      
 124 
     | 
    
         
            +
             
     | 
| 
      
 125 
     | 
    
         
            +
            ShellTest is available as a gem[http://rubygems.org/gems/shell_test].
         
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
      
 127 
     | 
    
         
            +
              $ gem install shell_test
         
     | 
| 
      
 128 
     | 
    
         
            +
             
     | 
| 
      
 129 
     | 
    
         
            +
            == Development
         
     | 
| 
      
 130 
     | 
    
         
            +
             
     | 
| 
      
 131 
     | 
    
         
            +
            To get started, checkout the code from GitHub[http://github.com/thinkerbot/shell_test] and run:
         
     | 
| 
      
 132 
     | 
    
         
            +
             
     | 
| 
      
 133 
     | 
    
         
            +
              git clone https://thinkerbot@github.com/thinkerbot/shell_test.git
         
     | 
| 
      
 134 
     | 
    
         
            +
              cd shell_test
         
     | 
| 
      
 135 
     | 
    
         
            +
              rake test
         
     | 
| 
      
 136 
     | 
    
         
            +
             
     | 
| 
      
 137 
     | 
    
         
            +
            To test against multiple platforms I suggest using rvm.  In that case:
         
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
      
 139 
     | 
    
         
            +
              rvm rake test
         
     | 
| 
      
 140 
     | 
    
         
            +
             
     | 
| 
      
 141 
     | 
    
         
            +
            Please report any issues {here}[http://github.com/thinkerbot/shell_test/issues].
         
     | 
| 
      
 142 
     | 
    
         
            +
             
     | 
| 
      
 143 
     | 
    
         
            +
            == Info
         
     | 
| 
      
 144 
     | 
    
         
            +
             
     | 
| 
      
 145 
     | 
    
         
            +
            Developer:: {Simon Chiang}[http://thinkerbot.posterous.com]
         
     | 
| 
      
 146 
     | 
    
         
            +
            License:: {MIT-Style}[link:files/MIT-LICENSE.html]
         
     | 
| 
         @@ -0,0 +1,67 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module ShellTest
         
     | 
| 
      
 2 
     | 
    
         
            +
              class CommandParser
         
     | 
| 
      
 3 
     | 
    
         
            +
                attr_reader :ps1
         
     | 
| 
      
 4 
     | 
    
         
            +
                attr_reader :ps2
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                def initialize(options={})
         
     | 
| 
      
 7 
     | 
    
         
            +
                  options = {
         
     | 
| 
      
 8 
     | 
    
         
            +
                    :ps1 => '$ ',
         
     | 
| 
      
 9 
     | 
    
         
            +
                    :ps2 => '> '
         
     | 
| 
      
 10 
     | 
    
         
            +
                  }.merge(options)
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                  @ps1 = options[:ps1]
         
     | 
| 
      
 13 
     | 
    
         
            +
                  @ps2 = options[:ps2]
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                def parse_cmd(cmd)
         
     | 
| 
      
 17 
     | 
    
         
            +
                  cmd =~ /.*?#\s*(?:\[(\d+)\])?\s*(\.{3})?/
         
     | 
| 
      
 18 
     | 
    
         
            +
                  exit_status = $1 ? $1.to_i : 0
         
     | 
| 
      
 19 
     | 
    
         
            +
                  output = $2 ? nil : ""
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                  [cmd, output, exit_status]
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                def parse(script)
         
     | 
| 
      
 25 
     | 
    
         
            +
                  commands = []
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                  command, output, exit_status = nil, "", 0
         
     | 
| 
      
 28 
     | 
    
         
            +
                  script.each_line do |line|
         
     | 
| 
      
 29 
     | 
    
         
            +
                    case
         
     | 
| 
      
 30 
     | 
    
         
            +
                    when line.index(ps1) == 0
         
     | 
| 
      
 31 
     | 
    
         
            +
                      if command
         
     | 
| 
      
 32 
     | 
    
         
            +
                        commands << [command, output, exit_status]
         
     | 
| 
      
 33 
     | 
    
         
            +
                      end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                      command, output, exit_status = parse_cmd lchomp(ps1, line)
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                    when command.nil?
         
     | 
| 
      
 38 
     | 
    
         
            +
                      unless line.strip.empty?
         
     | 
| 
      
 39 
     | 
    
         
            +
                        command, output, exit_status = parse_cmd(line)
         
     | 
| 
      
 40 
     | 
    
         
            +
                      end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                    when line.index(ps2) == 0
         
     | 
| 
      
 43 
     | 
    
         
            +
                      command << lchomp(ps2, line)
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                    when output.nil?
         
     | 
| 
      
 46 
     | 
    
         
            +
                      output = line
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                    else
         
     | 
| 
      
 49 
     | 
    
         
            +
                      output << line
         
     | 
| 
      
 50 
     | 
    
         
            +
                    end
         
     | 
| 
      
 51 
     | 
    
         
            +
                  end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                  if command
         
     | 
| 
      
 54 
     | 
    
         
            +
                    commands << [command, output, exit_status]
         
     | 
| 
      
 55 
     | 
    
         
            +
                  end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                  commands
         
     | 
| 
      
 58 
     | 
    
         
            +
                end
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                private
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                def lchomp(prefix, line) # :nodoc:
         
     | 
| 
      
 63 
     | 
    
         
            +
                  length = prefix.length
         
     | 
| 
      
 64 
     | 
    
         
            +
                  line[length, line.length - length]
         
     | 
| 
      
 65 
     | 
    
         
            +
                end
         
     | 
| 
      
 66 
     | 
    
         
            +
              end
         
     | 
| 
      
 67 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,208 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'fileutils'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module ShellTest
         
     | 
| 
      
 4 
     | 
    
         
            +
              module FileMethods
         
     | 
| 
      
 5 
     | 
    
         
            +
                module ClassMethods
         
     | 
| 
      
 6 
     | 
    
         
            +
                  attr_accessor :class_dir
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                  attr_reader :cleanup_method_registry
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                  def cleanup_methods
         
     | 
| 
      
 11 
     | 
    
         
            +
                    @cleanup_methods ||= begin
         
     | 
| 
      
 12 
     | 
    
         
            +
                      cleanup_methods = {}
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                      ancestors.reverse.each do |ancestor|
         
     | 
| 
      
 15 
     | 
    
         
            +
                        next unless ancestor.kind_of?(ClassMethods)
         
     | 
| 
      
 16 
     | 
    
         
            +
                        ancestor.cleanup_method_registry.each_pair do |key, value|
         
     | 
| 
      
 17 
     | 
    
         
            +
                          if value.nil?
         
     | 
| 
      
 18 
     | 
    
         
            +
                            cleanup_methods.delete(key)
         
     | 
| 
      
 19 
     | 
    
         
            +
                          else
         
     | 
| 
      
 20 
     | 
    
         
            +
                            cleanup_methods[key] = value
         
     | 
| 
      
 21 
     | 
    
         
            +
                          end
         
     | 
| 
      
 22 
     | 
    
         
            +
                        end
         
     | 
| 
      
 23 
     | 
    
         
            +
                      end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                      cleanup_methods
         
     | 
| 
      
 26 
     | 
    
         
            +
                    end
         
     | 
| 
      
 27 
     | 
    
         
            +
                  end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                  def reset_cleanup_methods
         
     | 
| 
      
 30 
     | 
    
         
            +
                    @cleanup_methods = nil
         
     | 
| 
      
 31 
     | 
    
         
            +
                  end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                  protected
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                  def self.initialize(base)
         
     | 
| 
      
 36 
     | 
    
         
            +
                    # Infers the test directory from the calling file.
         
     | 
| 
      
 37 
     | 
    
         
            +
                    #   'some_class_test.rb' => 'some_class_test'
         
     | 
| 
      
 38 
     | 
    
         
            +
                    call_line = caller.find {|value| value !~ /`(includ|inherit|extend)ed'$/ }
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                    if call_line
         
     | 
| 
      
 41 
     | 
    
         
            +
                      calling_file   = call_line.gsub(/:\d+(:in .*)?$/, "")
         
     | 
| 
      
 42 
     | 
    
         
            +
                      base.class_dir = calling_file.chomp(File.extname(calling_file))
         
     | 
| 
      
 43 
     | 
    
         
            +
                    else
         
     | 
| 
      
 44 
     | 
    
         
            +
                      unless Dir.respond_to?(:tmpdir)
         
     | 
| 
      
 45 
     | 
    
         
            +
                        require 'tmpdir'
         
     | 
| 
      
 46 
     | 
    
         
            +
                      end
         
     | 
| 
      
 47 
     | 
    
         
            +
                      base.class_dir = Dir.tmpdir
         
     | 
| 
      
 48 
     | 
    
         
            +
                    end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                    base.reset_cleanup_methods
         
     | 
| 
      
 51 
     | 
    
         
            +
                    unless base.instance_variable_defined?(:@cleanup_method_registry)
         
     | 
| 
      
 52 
     | 
    
         
            +
                      base.instance_variable_set(:@cleanup_method_registry, {})
         
     | 
| 
      
 53 
     | 
    
         
            +
                    end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                    unless base.instance_variable_defined?(:@cleanup_paths)
         
     | 
| 
      
 56 
     | 
    
         
            +
                      base.instance_variable_set(:@cleanup_paths, ['.'])
         
     | 
| 
      
 57 
     | 
    
         
            +
                    end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                    unless base.instance_variable_defined?(:@cleanup)
         
     | 
| 
      
 60 
     | 
    
         
            +
                      base.instance_variable_set(:@cleanup, true)
         
     | 
| 
      
 61 
     | 
    
         
            +
                    end
         
     | 
| 
      
 62 
     | 
    
         
            +
                  end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                  def inherited(base) # :nodoc:
         
     | 
| 
      
 65 
     | 
    
         
            +
                    ClassMethods.initialize(base)
         
     | 
| 
      
 66 
     | 
    
         
            +
                    super
         
     | 
| 
      
 67 
     | 
    
         
            +
                  end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                  def define_method_cleanup(method_name, dirs)
         
     | 
| 
      
 70 
     | 
    
         
            +
                    reset_cleanup_methods
         
     | 
| 
      
 71 
     | 
    
         
            +
                    cleanup_method_registry[method_name.to_sym] = dirs
         
     | 
| 
      
 72 
     | 
    
         
            +
                  end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                  def remove_method_cleanup(method_name)
         
     | 
| 
      
 75 
     | 
    
         
            +
                    reset_cleanup_methods
         
     | 
| 
      
 76 
     | 
    
         
            +
                    cleanup_method_registry.delete(method_name.to_sym)
         
     | 
| 
      
 77 
     | 
    
         
            +
                  end
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                  def undef_method_cleanup(method_name)
         
     | 
| 
      
 80 
     | 
    
         
            +
                    reset_cleanup_methods
         
     | 
| 
      
 81 
     | 
    
         
            +
                    cleanup_method_registry[method_name.to_sym] = nil
         
     | 
| 
      
 82 
     | 
    
         
            +
                  end
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                  def cleanup_paths(*dirs)
         
     | 
| 
      
 85 
     | 
    
         
            +
                    @cleanup_paths = dirs
         
     | 
| 
      
 86 
     | 
    
         
            +
                  end
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
                  def cleanup(*method_names)
         
     | 
| 
      
 89 
     | 
    
         
            +
                    if method_names.empty?
         
     | 
| 
      
 90 
     | 
    
         
            +
                      @cleanup = true
         
     | 
| 
      
 91 
     | 
    
         
            +
                    else
         
     | 
| 
      
 92 
     | 
    
         
            +
                      method_names.each do |method_name|
         
     | 
| 
      
 93 
     | 
    
         
            +
                        define_method_cleanup method_name, @cleanup_paths
         
     | 
| 
      
 94 
     | 
    
         
            +
                      end
         
     | 
| 
      
 95 
     | 
    
         
            +
                    end
         
     | 
| 
      
 96 
     | 
    
         
            +
                  end
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
                  def no_cleanup(*method_names)
         
     | 
| 
      
 99 
     | 
    
         
            +
                    if method_names.empty?
         
     | 
| 
      
 100 
     | 
    
         
            +
                      @cleanup = false
         
     | 
| 
      
 101 
     | 
    
         
            +
                    else
         
     | 
| 
      
 102 
     | 
    
         
            +
                      method_names.each do |method_name|
         
     | 
| 
      
 103 
     | 
    
         
            +
                        undef_method_cleanup method_name
         
     | 
| 
      
 104 
     | 
    
         
            +
                      end
         
     | 
| 
      
 105 
     | 
    
         
            +
                    end
         
     | 
| 
      
 106 
     | 
    
         
            +
                  end
         
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
      
 108 
     | 
    
         
            +
                  def method_added(sym)
         
     | 
| 
      
 109 
     | 
    
         
            +
                    if @cleanup && !cleanup_method_registry.has_key?(sym.to_sym) && sym.to_s[0, 5] == "test_"
         
     | 
| 
      
 110 
     | 
    
         
            +
                      cleanup sym
         
     | 
| 
      
 111 
     | 
    
         
            +
                    end
         
     | 
| 
      
 112 
     | 
    
         
            +
                  end
         
     | 
| 
      
 113 
     | 
    
         
            +
                end
         
     | 
| 
      
 114 
     | 
    
         
            +
             
     | 
| 
      
 115 
     | 
    
         
            +
                module ModuleMethods
         
     | 
| 
      
 116 
     | 
    
         
            +
                  module_function
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
                  def included(base)
         
     | 
| 
      
 119 
     | 
    
         
            +
                    base.extend ClassMethods
         
     | 
| 
      
 120 
     | 
    
         
            +
                    base.extend ModuleMethods unless base.kind_of?(Class)
         
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
      
 122 
     | 
    
         
            +
                    ClassMethods.initialize(base)
         
     | 
| 
      
 123 
     | 
    
         
            +
                    super
         
     | 
| 
      
 124 
     | 
    
         
            +
                  end
         
     | 
| 
      
 125 
     | 
    
         
            +
                end
         
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
      
 127 
     | 
    
         
            +
                extend ModuleMethods
         
     | 
| 
      
 128 
     | 
    
         
            +
             
     | 
| 
      
 129 
     | 
    
         
            +
                def setup
         
     | 
| 
      
 130 
     | 
    
         
            +
                  super
         
     | 
| 
      
 131 
     | 
    
         
            +
                  cleanup
         
     | 
| 
      
 132 
     | 
    
         
            +
                end
         
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
                def teardown
         
     | 
| 
      
 135 
     | 
    
         
            +
                  Dir.chdir(user_dir)
         
     | 
| 
      
 136 
     | 
    
         
            +
             
     | 
| 
      
 137 
     | 
    
         
            +
                  unless ENV["KEEP_OUTPUTS"] == "true"
         
     | 
| 
      
 138 
     | 
    
         
            +
                    cleanup
         
     | 
| 
      
 139 
     | 
    
         
            +
             
     | 
| 
      
 140 
     | 
    
         
            +
                    dir = method_dir
         
     | 
| 
      
 141 
     | 
    
         
            +
                    while dir != class_dir
         
     | 
| 
      
 142 
     | 
    
         
            +
                      dir = File.dirname(dir)
         
     | 
| 
      
 143 
     | 
    
         
            +
                      Dir.rmdir(dir)
         
     | 
| 
      
 144 
     | 
    
         
            +
                    end rescue(SystemCallError)
         
     | 
| 
      
 145 
     | 
    
         
            +
                  end
         
     | 
| 
      
 146 
     | 
    
         
            +
             
     | 
| 
      
 147 
     | 
    
         
            +
                  super
         
     | 
| 
      
 148 
     | 
    
         
            +
                end
         
     | 
| 
      
 149 
     | 
    
         
            +
             
     | 
| 
      
 150 
     | 
    
         
            +
                def user_dir
         
     | 
| 
      
 151 
     | 
    
         
            +
                  @user_dir   ||= File.expand_path('.')
         
     | 
| 
      
 152 
     | 
    
         
            +
                end
         
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
      
 154 
     | 
    
         
            +
                def class_dir
         
     | 
| 
      
 155 
     | 
    
         
            +
                  @class_dir  ||= File.expand_path(self.class.class_dir, user_dir)
         
     | 
| 
      
 156 
     | 
    
         
            +
                end
         
     | 
| 
      
 157 
     | 
    
         
            +
             
     | 
| 
      
 158 
     | 
    
         
            +
                def method_dir
         
     | 
| 
      
 159 
     | 
    
         
            +
                  @method_dir ||= File.expand_path(method_name.to_s, class_dir)
         
     | 
| 
      
 160 
     | 
    
         
            +
                end
         
     | 
| 
      
 161 
     | 
    
         
            +
             
     | 
| 
      
 162 
     | 
    
         
            +
                def method_name
         
     | 
| 
      
 163 
     | 
    
         
            +
                  __name__
         
     | 
| 
      
 164 
     | 
    
         
            +
                end
         
     | 
| 
      
 165 
     | 
    
         
            +
             
     | 
| 
      
 166 
     | 
    
         
            +
                def cleanup_methods
         
     | 
| 
      
 167 
     | 
    
         
            +
                  self.class.cleanup_methods
         
     | 
| 
      
 168 
     | 
    
         
            +
                end
         
     | 
| 
      
 169 
     | 
    
         
            +
             
     | 
| 
      
 170 
     | 
    
         
            +
                def cleanup
         
     | 
| 
      
 171 
     | 
    
         
            +
                  if cleanup_paths = cleanup_methods[method_name.to_sym]
         
     | 
| 
      
 172 
     | 
    
         
            +
                    cleanup_paths.each {|relative_path| remove(relative_path) }
         
     | 
| 
      
 173 
     | 
    
         
            +
                  end
         
     | 
| 
      
 174 
     | 
    
         
            +
                end
         
     | 
| 
      
 175 
     | 
    
         
            +
             
     | 
| 
      
 176 
     | 
    
         
            +
                def path(relative_path)
         
     | 
| 
      
 177 
     | 
    
         
            +
                  path = File.expand_path(relative_path, method_dir)
         
     | 
| 
      
 178 
     | 
    
         
            +
             
     | 
| 
      
 179 
     | 
    
         
            +
                  unless path.index(method_dir) == 0
         
     | 
| 
      
 180 
     | 
    
         
            +
                    raise "does not make a path relative to method_dir: #{relative_path.inspect}"
         
     | 
| 
      
 181 
     | 
    
         
            +
                  end
         
     | 
| 
      
 182 
     | 
    
         
            +
             
     | 
| 
      
 183 
     | 
    
         
            +
                  path
         
     | 
| 
      
 184 
     | 
    
         
            +
                end
         
     | 
| 
      
 185 
     | 
    
         
            +
             
     | 
| 
      
 186 
     | 
    
         
            +
                def prepare(relative_path, content=nil, &block)
         
     | 
| 
      
 187 
     | 
    
         
            +
                  target = path(relative_path)
         
     | 
| 
      
 188 
     | 
    
         
            +
             
     | 
| 
      
 189 
     | 
    
         
            +
                  if File.exists?(target)
         
     | 
| 
      
 190 
     | 
    
         
            +
                    FileUtils.rm(target)
         
     | 
| 
      
 191 
     | 
    
         
            +
                  else
         
     | 
| 
      
 192 
     | 
    
         
            +
                    target_dir = File.dirname(target)
         
     | 
| 
      
 193 
     | 
    
         
            +
                    FileUtils.mkdir_p(target_dir) unless File.exists?(target_dir)
         
     | 
| 
      
 194 
     | 
    
         
            +
                  end
         
     | 
| 
      
 195 
     | 
    
         
            +
             
     | 
| 
      
 196 
     | 
    
         
            +
                  FileUtils.touch(target)
         
     | 
| 
      
 197 
     | 
    
         
            +
                  File.open(target, 'w') {|io| io << content } if content
         
     | 
| 
      
 198 
     | 
    
         
            +
                  File.open(target, 'a', &block) if block
         
     | 
| 
      
 199 
     | 
    
         
            +
             
     | 
| 
      
 200 
     | 
    
         
            +
                  target
         
     | 
| 
      
 201 
     | 
    
         
            +
                end
         
     | 
| 
      
 202 
     | 
    
         
            +
             
     | 
| 
      
 203 
     | 
    
         
            +
                def remove(relative_path)
         
     | 
| 
      
 204 
     | 
    
         
            +
                  full_path = path(relative_path)
         
     | 
| 
      
 205 
     | 
    
         
            +
                  FileUtils.rm_r(full_path) if File.exists?(full_path)
         
     | 
| 
      
 206 
     | 
    
         
            +
                end
         
     | 
| 
      
 207 
     | 
    
         
            +
              end
         
     | 
| 
      
 208 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,84 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module ShellTest
         
     | 
| 
      
 2 
     | 
    
         
            +
              # RegexpEscape is a subclass of regexp that escapes all but the text in a
         
     | 
| 
      
 3 
     | 
    
         
            +
              # special escape sequence.  This allows the creation of complex regexps
         
     | 
| 
      
 4 
     | 
    
         
            +
              # to match, for instance, console output.
         
     | 
| 
      
 5 
     | 
    
         
            +
              #
         
     | 
| 
      
 6 
     | 
    
         
            +
              # The RegexpEscape.escape (or equivalently the quote) method does the
         
     | 
| 
      
 7 
     | 
    
         
            +
              # work; all regexp-active characters are escaped except for characters
         
     | 
| 
      
 8 
     | 
    
         
            +
              # enclosed by ':.' and '.:' delimiters.
         
     | 
| 
      
 9 
     | 
    
         
            +
              #
         
     | 
| 
      
 10 
     | 
    
         
            +
              #   RegexpEscape.escape('reg[exp]+ chars. are(quoted)')       # => 'reg\[exp\]\+\ chars\.\ are\(quoted\)'
         
     | 
| 
      
 11 
     | 
    
         
            +
              #   RegexpEscape.escape('these are not: :.a(b*)c.:')          # => 'these\ are\ not:\ a(b*)c'
         
     | 
| 
      
 12 
     | 
    
         
            +
              #
         
     | 
| 
      
 13 
     | 
    
         
            +
              # In addition, all-period regexps are automatically upgraded to '.*?';
         
     | 
| 
      
 14 
     | 
    
         
            +
              # use the '.{n}' notation to specify n arbitrary characters.
         
     | 
| 
      
 15 
     | 
    
         
            +
              #
         
     | 
| 
      
 16 
     | 
    
         
            +
              #   RegexpEscape.escape('_:..:_:...:_:....:')        # => '_.*?_.*?_.*?'
         
     | 
| 
      
 17 
     | 
    
         
            +
              #   RegexpEscape.escape(':..{1}.:')                  # => '.{1}'
         
     | 
| 
      
 18 
     | 
    
         
            +
              #
         
     | 
| 
      
 19 
     | 
    
         
            +
              # RegexpEscape instances are initialized using the escaped input string
         
     | 
| 
      
 20 
     | 
    
         
            +
              # and return the original string upon to_s.
         
     | 
| 
      
 21 
     | 
    
         
            +
              #
         
     | 
| 
      
 22 
     | 
    
         
            +
              #   str = %q{
         
     | 
| 
      
 23 
     | 
    
         
            +
              #   a multiline
         
     | 
| 
      
 24 
     | 
    
         
            +
              #   :...:
         
     | 
| 
      
 25 
     | 
    
         
            +
              #   example}
         
     | 
| 
      
 26 
     | 
    
         
            +
              #   r = RegexpEscape.new(str)
         
     | 
| 
      
 27 
     | 
    
         
            +
              #
         
     | 
| 
      
 28 
     | 
    
         
            +
              #   r =~ %q{
         
     | 
| 
      
 29 
     | 
    
         
            +
              #   a multiline
         
     | 
| 
      
 30 
     | 
    
         
            +
              #   matching
         
     | 
| 
      
 31 
     | 
    
         
            +
              #   example}  # => true
         
     | 
| 
      
 32 
     | 
    
         
            +
              #
         
     | 
| 
      
 33 
     | 
    
         
            +
              #   r !~ %q{
         
     | 
| 
      
 34 
     | 
    
         
            +
              #   a failing multiline
         
     | 
| 
      
 35 
     | 
    
         
            +
              #   example}  # => true
         
     | 
| 
      
 36 
     | 
    
         
            +
              #
         
     | 
| 
      
 37 
     | 
    
         
            +
              #   r.to_s    # => str
         
     | 
| 
      
 38 
     | 
    
         
            +
              #
         
     | 
| 
      
 39 
     | 
    
         
            +
              class RegexpEscape < Regexp
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                # matches the escape sequence
         
     | 
| 
      
 42 
     | 
    
         
            +
                ESCAPE_SEQUENCE = /:\..*?\.:/
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                class << self
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                  # Escapes regexp-active characters in str, except for character
         
     | 
| 
      
 47 
     | 
    
         
            +
                  # delimited by ':.' and '.:'.  See the class description for
         
     | 
| 
      
 48 
     | 
    
         
            +
                  # details.
         
     | 
| 
      
 49 
     | 
    
         
            +
                  def escape(str)
         
     | 
| 
      
 50 
     | 
    
         
            +
                    substituents = []
         
     | 
| 
      
 51 
     | 
    
         
            +
                    str.scan(ESCAPE_SEQUENCE) do
         
     | 
| 
      
 52 
     | 
    
         
            +
                      regexp_str = $&[2...-2]
         
     | 
| 
      
 53 
     | 
    
         
            +
                      regexp_str = ".*?" if regexp_str =~ /^\.*$/
         
     | 
| 
      
 54 
     | 
    
         
            +
                      substituents << regexp_str
         
     | 
| 
      
 55 
     | 
    
         
            +
                    end
         
     | 
| 
      
 56 
     | 
    
         
            +
                    substituents << ""
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                    splits = str.split(ESCAPE_SEQUENCE).collect do |split|
         
     | 
| 
      
 59 
     | 
    
         
            +
                      super(split)
         
     | 
| 
      
 60 
     | 
    
         
            +
                    end
         
     | 
| 
      
 61 
     | 
    
         
            +
                    splits << "" if splits.empty?
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                    splits.zip(substituents).to_a.flatten.join
         
     | 
| 
      
 64 
     | 
    
         
            +
                  end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                  # Same as escape.
         
     | 
| 
      
 67 
     | 
    
         
            +
                  def quote(str)
         
     | 
| 
      
 68 
     | 
    
         
            +
                    escape(str)
         
     | 
| 
      
 69 
     | 
    
         
            +
                  end
         
     | 
| 
      
 70 
     | 
    
         
            +
                end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                # Generates a new RegexpEscape by escaping the str, using the same
         
     | 
| 
      
 73 
     | 
    
         
            +
                # options as Regexp.
         
     | 
| 
      
 74 
     | 
    
         
            +
                def initialize(str, *options)
         
     | 
| 
      
 75 
     | 
    
         
            +
                  super(RegexpEscape.escape(str), *options)
         
     | 
| 
      
 76 
     | 
    
         
            +
                  @original_str = str
         
     | 
| 
      
 77 
     | 
    
         
            +
                end
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                # Returns the original string for self
         
     | 
| 
      
 80 
     | 
    
         
            +
                def to_s
         
     | 
| 
      
 81 
     | 
    
         
            +
                  @original_str
         
     | 
| 
      
 82 
     | 
    
         
            +
                end
         
     | 
| 
      
 83 
     | 
    
         
            +
              end
         
     | 
| 
      
 84 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,176 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'shell_test/regexp_escape'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'shell_test/command_parser'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module ShellTest
         
     | 
| 
      
 5 
     | 
    
         
            +
              module ShellMethods
         
     | 
| 
      
 6 
     | 
    
         
            +
                def setup
         
     | 
| 
      
 7 
     | 
    
         
            +
                  super
         
     | 
| 
      
 8 
     | 
    
         
            +
                  @notify_method_name = true
         
     | 
| 
      
 9 
     | 
    
         
            +
                end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                # Parse a script into an array of [cmd, output, status] triplets.
         
     | 
| 
      
 12 
     | 
    
         
            +
                def parse_script(script, options={})
         
     | 
| 
      
 13 
     | 
    
         
            +
                  CommandParser.new(options).parse(script)
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                # Returns true if the ENV variable 'VERBOSE' is true.  When verbose,
         
     | 
| 
      
 17 
     | 
    
         
            +
                # ShellTest prints the expanded commands of sh_test to $stdout.
         
     | 
| 
      
 18 
     | 
    
         
            +
                def verbose?
         
     | 
| 
      
 19 
     | 
    
         
            +
                  verbose = ENV['VERBOSE']
         
     | 
| 
      
 20 
     | 
    
         
            +
                  verbose && verbose =~ /^true$/i ? true : false
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                # Sets the specified ENV variables and returns the *current* env.
         
     | 
| 
      
 24 
     | 
    
         
            +
                # If replace is true, current ENV variables are replaced; otherwise
         
     | 
| 
      
 25 
     | 
    
         
            +
                # the new env variables are simply added to the existing set.
         
     | 
| 
      
 26 
     | 
    
         
            +
                def set_env(env={}, replace=false)
         
     | 
| 
      
 27 
     | 
    
         
            +
                  current_env = {}
         
     | 
| 
      
 28 
     | 
    
         
            +
                  ENV.each_pair do |key, value|
         
     | 
| 
      
 29 
     | 
    
         
            +
                    current_env[key] = value
         
     | 
| 
      
 30 
     | 
    
         
            +
                  end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                  ENV.clear if replace
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                  env.each_pair do |key, value|
         
     | 
| 
      
 35 
     | 
    
         
            +
                    if value.nil?
         
     | 
| 
      
 36 
     | 
    
         
            +
                      ENV.delete(key)
         
     | 
| 
      
 37 
     | 
    
         
            +
                    else
         
     | 
| 
      
 38 
     | 
    
         
            +
                      ENV[key] = value
         
     | 
| 
      
 39 
     | 
    
         
            +
                    end
         
     | 
| 
      
 40 
     | 
    
         
            +
                  end if env
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                  current_env
         
     | 
| 
      
 43 
     | 
    
         
            +
                end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                # Sets the specified ENV variables for the duration of the block.
         
     | 
| 
      
 46 
     | 
    
         
            +
                # If replace is true, current ENV variables are replaced; otherwise
         
     | 
| 
      
 47 
     | 
    
         
            +
                # the new env variables are simply added to the existing set.
         
     | 
| 
      
 48 
     | 
    
         
            +
                #
         
     | 
| 
      
 49 
     | 
    
         
            +
                # Returns the block return.
         
     | 
| 
      
 50 
     | 
    
         
            +
                def with_env(env={}, replace=false)
         
     | 
| 
      
 51 
     | 
    
         
            +
                  current_env = nil
         
     | 
| 
      
 52 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 53 
     | 
    
         
            +
                    current_env = set_env(env, replace)
         
     | 
| 
      
 54 
     | 
    
         
            +
                    yield
         
     | 
| 
      
 55 
     | 
    
         
            +
                  ensure
         
     | 
| 
      
 56 
     | 
    
         
            +
                    if current_env
         
     | 
| 
      
 57 
     | 
    
         
            +
                      set_env(current_env, true)
         
     | 
| 
      
 58 
     | 
    
         
            +
                    end
         
     | 
| 
      
 59 
     | 
    
         
            +
                  end
         
     | 
| 
      
 60 
     | 
    
         
            +
                end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                def sh(cmd)
         
     | 
| 
      
 63 
     | 
    
         
            +
                  if @notify_method_name && verbose?
         
     | 
| 
      
 64 
     | 
    
         
            +
                    @notify_method_name = false
         
     | 
| 
      
 65 
     | 
    
         
            +
                    puts
         
     | 
| 
      
 66 
     | 
    
         
            +
                    puts method_name 
         
     | 
| 
      
 67 
     | 
    
         
            +
                  end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                  start  = Time.now
         
     | 
| 
      
 70 
     | 
    
         
            +
                  result = `#{cmd}`
         
     | 
| 
      
 71 
     | 
    
         
            +
                  finish = Time.now
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                  if verbose?
         
     | 
| 
      
 74 
     | 
    
         
            +
                    elapsed = "%.3f" % [finish-start]
         
     | 
| 
      
 75 
     | 
    
         
            +
                    puts "  (#{elapsed}s) #{cmd}"
         
     | 
| 
      
 76 
     | 
    
         
            +
                  end
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
                  result
         
     | 
| 
      
 79 
     | 
    
         
            +
                end
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                def assert_script(script, options={})
         
     | 
| 
      
 82 
     | 
    
         
            +
                  _assert_script outdent(script), options
         
     | 
| 
      
 83 
     | 
    
         
            +
                end
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
                def _assert_script(script, options={})
         
     | 
| 
      
 86 
     | 
    
         
            +
                  parse_script(script, options).each do |cmd, output, status|
         
     | 
| 
      
 87 
     | 
    
         
            +
                    result = sh(cmd)
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
                    _assert_output_equal(output, result, cmd) if output
         
     | 
| 
      
 90 
     | 
    
         
            +
                    assert_equal(status, $?.exitstatus, cmd)  if status
         
     | 
| 
      
 91 
     | 
    
         
            +
                  end
         
     | 
| 
      
 92 
     | 
    
         
            +
                end
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
                def assert_script_match(script, options={})
         
     | 
| 
      
 95 
     | 
    
         
            +
                  _assert_script_match outdent(script), options
         
     | 
| 
      
 96 
     | 
    
         
            +
                end
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
                def _assert_script_match(script, options={})
         
     | 
| 
      
 99 
     | 
    
         
            +
                  parse_script(script, options).each do |cmd, output, status|
         
     | 
| 
      
 100 
     | 
    
         
            +
                    result = sh(cmd)
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
                    _assert_alike(output, result, cmd)       if output
         
     | 
| 
      
 103 
     | 
    
         
            +
                    assert_equal(status, $?.exitstatus, cmd) if status
         
     | 
| 
      
 104 
     | 
    
         
            +
                  end
         
     | 
| 
      
 105 
     | 
    
         
            +
                end
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
                # Asserts whether or not the a and b strings are equal, with a more
         
     | 
| 
      
 108 
     | 
    
         
            +
                # readable output than assert_equal for large strings (especially large
         
     | 
| 
      
 109 
     | 
    
         
            +
                # strings with significant whitespace).
         
     | 
| 
      
 110 
     | 
    
         
            +
                def assert_output_equal(a, b, msg=nil)
         
     | 
| 
      
 111 
     | 
    
         
            +
                  _assert_output_equal outdent(a), b, msg
         
     | 
| 
      
 112 
     | 
    
         
            +
                end
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
                def _assert_output_equal(a, b, msg=nil)
         
     | 
| 
      
 115 
     | 
    
         
            +
                  if a == b
         
     | 
| 
      
 116 
     | 
    
         
            +
                    assert true
         
     | 
| 
      
 117 
     | 
    
         
            +
                  else
         
     | 
| 
      
 118 
     | 
    
         
            +
                    flunk %Q{
         
     | 
| 
      
 119 
     | 
    
         
            +
            #{msg}
         
     | 
| 
      
 120 
     | 
    
         
            +
            ==================== expected output ====================
         
     | 
| 
      
 121 
     | 
    
         
            +
            #{whitespace_escape(a)}
         
     | 
| 
      
 122 
     | 
    
         
            +
            ======================== but was ========================
         
     | 
| 
      
 123 
     | 
    
         
            +
            #{whitespace_escape(b)}
         
     | 
| 
      
 124 
     | 
    
         
            +
            =========================================================
         
     | 
| 
      
 125 
     | 
    
         
            +
            }
         
     | 
| 
      
 126 
     | 
    
         
            +
                  end
         
     | 
| 
      
 127 
     | 
    
         
            +
                end
         
     | 
| 
      
 128 
     | 
    
         
            +
             
     | 
| 
      
 129 
     | 
    
         
            +
                # Asserts whether or not b is like a (which should be a Regexp), and
         
     | 
| 
      
 130 
     | 
    
         
            +
                # provides a more readable output in the case of a failure as compared
         
     | 
| 
      
 131 
     | 
    
         
            +
                # with assert_match.
         
     | 
| 
      
 132 
     | 
    
         
            +
                #
         
     | 
| 
      
 133 
     | 
    
         
            +
                # If a is a string it is turned into a RegexpEscape.
         
     | 
| 
      
 134 
     | 
    
         
            +
                def assert_alike(a, b, msg=nil)
         
     | 
| 
      
 135 
     | 
    
         
            +
                  a = outdent(a) if a.kind_of?(String)
         
     | 
| 
      
 136 
     | 
    
         
            +
                  _assert_alike a, b, msg
         
     | 
| 
      
 137 
     | 
    
         
            +
                end
         
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
      
 139 
     | 
    
         
            +
                def _assert_alike(a, b, msg=nil)
         
     | 
| 
      
 140 
     | 
    
         
            +
                  if a.kind_of?(String)
         
     | 
| 
      
 141 
     | 
    
         
            +
                    a = RegexpEscape.new(a)
         
     | 
| 
      
 142 
     | 
    
         
            +
                  end
         
     | 
| 
      
 143 
     | 
    
         
            +
             
     | 
| 
      
 144 
     | 
    
         
            +
                  if b =~ a
         
     | 
| 
      
 145 
     | 
    
         
            +
                    assert true
         
     | 
| 
      
 146 
     | 
    
         
            +
                  else
         
     | 
| 
      
 147 
     | 
    
         
            +
                    flunk %Q{
         
     | 
| 
      
 148 
     | 
    
         
            +
            #{msg}
         
     | 
| 
      
 149 
     | 
    
         
            +
            ================= expected output like ==================
         
     | 
| 
      
 150 
     | 
    
         
            +
            #{whitespace_escape(a)}
         
     | 
| 
      
 151 
     | 
    
         
            +
            ======================== but was ========================
         
     | 
| 
      
 152 
     | 
    
         
            +
            #{whitespace_escape(b)}
         
     | 
| 
      
 153 
     | 
    
         
            +
            =========================================================
         
     | 
| 
      
 154 
     | 
    
         
            +
            }
         
     | 
| 
      
 155 
     | 
    
         
            +
                  end
         
     | 
| 
      
 156 
     | 
    
         
            +
                end
         
     | 
| 
      
 157 
     | 
    
         
            +
             
     | 
| 
      
 158 
     | 
    
         
            +
                # helper for stripping indentation off a string
         
     | 
| 
      
 159 
     | 
    
         
            +
                def outdent(str)
         
     | 
| 
      
 160 
     | 
    
         
            +
                  str =~ /\A(?:\s*?\n)( *)(.*)\z/m ? $2.gsub!(/^ {0,#{$1.length}}/, '') : str
         
     | 
| 
      
 161 
     | 
    
         
            +
                end
         
     | 
| 
      
 162 
     | 
    
         
            +
             
     | 
| 
      
 163 
     | 
    
         
            +
                # helper for formatting escaping whitespace into readable text
         
     | 
| 
      
 164 
     | 
    
         
            +
                def whitespace_escape(str)
         
     | 
| 
      
 165 
     | 
    
         
            +
                  str.to_s.gsub(/\s/) do |match|
         
     | 
| 
      
 166 
     | 
    
         
            +
                    case match
         
     | 
| 
      
 167 
     | 
    
         
            +
                    when "\n" then "\\n\n"
         
     | 
| 
      
 168 
     | 
    
         
            +
                    when "\t" then "\\t"
         
     | 
| 
      
 169 
     | 
    
         
            +
                    when "\r" then "\\r"
         
     | 
| 
      
 170 
     | 
    
         
            +
                    when "\f" then "\\f"
         
     | 
| 
      
 171 
     | 
    
         
            +
                    else match
         
     | 
| 
      
 172 
     | 
    
         
            +
                    end
         
     | 
| 
      
 173 
     | 
    
         
            +
                  end
         
     | 
| 
      
 174 
     | 
    
         
            +
                end
         
     | 
| 
      
 175 
     | 
    
         
            +
              end
         
     | 
| 
      
 176 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,72 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # :stopdoc:
         
     | 
| 
      
 2 
     | 
    
         
            +
            module ShellTest
         
     | 
| 
      
 3 
     | 
    
         
            +
              module Unit
         
     | 
| 
      
 4 
     | 
    
         
            +
                
         
     | 
| 
      
 5 
     | 
    
         
            +
                # An exception class to flag skips.
         
     | 
| 
      
 6 
     | 
    
         
            +
                class SkipException < StandardError
         
     | 
| 
      
 7 
     | 
    
         
            +
                end
         
     | 
| 
      
 8 
     | 
    
         
            +
                
         
     | 
| 
      
 9 
     | 
    
         
            +
                # Modifies how errors related to a SkipException are displayed.
         
     | 
| 
      
 10 
     | 
    
         
            +
                module SkipDisplay
         
     | 
| 
      
 11 
     | 
    
         
            +
                  # Display S rather than E in the progress.
         
     | 
| 
      
 12 
     | 
    
         
            +
                  def single_character_display
         
     | 
| 
      
 13 
     | 
    
         
            +
                    "S"
         
     | 
| 
      
 14 
     | 
    
         
            +
                  end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                  # Removes the exception class from the message.
         
     | 
| 
      
 17 
     | 
    
         
            +
                  def message
         
     | 
| 
      
 18 
     | 
    
         
            +
                    @exception.message
         
     | 
| 
      
 19 
     | 
    
         
            +
                  end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                  # Updates the output to look like a MiniTest skip error.
         
     | 
| 
      
 22 
     | 
    
         
            +
                  def long_display
         
     | 
| 
      
 23 
     | 
    
         
            +
                    backtrace = filter_backtrace(@exception.backtrace)
         
     | 
| 
      
 24 
     | 
    
         
            +
                    "Skipped:\n#@test_name [#{backtrace[0].sub(/:in `.*$/, "")}]:\n#{message}\n"
         
     | 
| 
      
 25 
     | 
    
         
            +
                  end
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
            end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
            require 'test/unit/testresult'
         
     | 
| 
      
 31 
     | 
    
         
            +
            class Test::Unit::TestResult
         
     | 
| 
      
 32 
     | 
    
         
            +
              # Returns an array of skips recorded for self.
         
     | 
| 
      
 33 
     | 
    
         
            +
              def skips
         
     | 
| 
      
 34 
     | 
    
         
            +
                @skips ||= []
         
     | 
| 
      
 35 
     | 
    
         
            +
              end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
              # Partition errors from a SkipException from other errors and records as
         
     | 
| 
      
 38 
     | 
    
         
            +
              # them as skips (the error is extended to display as a skip).
         
     | 
| 
      
 39 
     | 
    
         
            +
              def add_error(error)
         
     | 
| 
      
 40 
     | 
    
         
            +
                if error.exception.kind_of?(ShellTest::Unit::SkipException)
         
     | 
| 
      
 41 
     | 
    
         
            +
                  error.extend ShellTest::Unit::SkipDisplay
         
     | 
| 
      
 42 
     | 
    
         
            +
                  skips << error
         
     | 
| 
      
 43 
     | 
    
         
            +
                else
         
     | 
| 
      
 44 
     | 
    
         
            +
                  @errors << error
         
     | 
| 
      
 45 
     | 
    
         
            +
                end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                notify_listeners(FAULT, error)
         
     | 
| 
      
 48 
     | 
    
         
            +
                notify_listeners(CHANGED, self)
         
     | 
| 
      
 49 
     | 
    
         
            +
              end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
              alias shell_test_original_to_s to_s
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
              # Adds the skip count to the summary.
         
     | 
| 
      
 54 
     | 
    
         
            +
              def to_s
         
     | 
| 
      
 55 
     | 
    
         
            +
                "#{shell_test_original_to_s}, #{skips.length} skips"
         
     | 
| 
      
 56 
     | 
    
         
            +
              end
         
     | 
| 
      
 57 
     | 
    
         
            +
            end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
            require 'test/unit/testcase'
         
     | 
| 
      
 60 
     | 
    
         
            +
            class Test::Unit::TestCase
         
     | 
| 
      
 61 
     | 
    
         
            +
              # Alias method_name to __name__ such that FileMethods can redefine
         
     | 
| 
      
 62 
     | 
    
         
            +
              # method_name to call __name__ (circular I know, but necessary for
         
     | 
| 
      
 63 
     | 
    
         
            +
              # compatibility with MiniTest)
         
     | 
| 
      
 64 
     | 
    
         
            +
              alias __name__ method_name
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
              # Call to skip a test.
         
     | 
| 
      
 67 
     | 
    
         
            +
              def skip(msg = nil, bt = caller)
         
     | 
| 
      
 68 
     | 
    
         
            +
                msg ||= "Skipped, no message given"
         
     | 
| 
      
 69 
     | 
    
         
            +
                raise ShellTest::Unit::SkipException, msg, bt
         
     | 
| 
      
 70 
     | 
    
         
            +
              end
         
     | 
| 
      
 71 
     | 
    
         
            +
            end
         
     | 
| 
      
 72 
     | 
    
         
            +
            # :startdoc:
         
     | 
| 
         @@ -0,0 +1,40 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'test/unit'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'shell_test'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module ShellTest
         
     | 
| 
      
 5 
     | 
    
         
            +
              # ShellTest is designed to work with MiniTest, which is the standard testing
         
     | 
| 
      
 6 
     | 
    
         
            +
              # framework included in ruby 1.9.  Minor changes in the API break backward
         
     | 
| 
      
 7 
     | 
    
         
            +
              # compatibility with Test::Unit and/or add functionality expected by
         
     | 
| 
      
 8 
     | 
    
         
            +
              # ShellTest.
         
     | 
| 
      
 9 
     | 
    
         
            +
              #
         
     | 
| 
      
 10 
     | 
    
         
            +
              # Test::Unit can be patched by requiring the shim file before defining
         
     | 
| 
      
 11 
     | 
    
         
            +
              # specific TestCase subclasses.
         
     | 
| 
      
 12 
     | 
    
         
            +
              #
         
     | 
| 
      
 13 
     | 
    
         
            +
              #   require 'test/unit'
         
     | 
| 
      
 14 
     | 
    
         
            +
              #   unless Object.const_defined?(:MiniTest)
         
     | 
| 
      
 15 
     | 
    
         
            +
              #     require 'shell_test/unit/shim'
         
     | 
| 
      
 16 
     | 
    
         
            +
              #   end
         
     | 
| 
      
 17 
     | 
    
         
            +
              #
         
     | 
| 
      
 18 
     | 
    
         
            +
              # To let ShellTest do this for you:
         
     | 
| 
      
 19 
     | 
    
         
            +
              #
         
     | 
| 
      
 20 
     | 
    
         
            +
              #  require 'shell_test/unit'
         
     | 
| 
      
 21 
     | 
    
         
            +
              #
         
     | 
| 
      
 22 
     | 
    
         
            +
              # Note that the shim script has only been tested vs the Test::Unit that
         
     | 
| 
      
 23 
     | 
    
         
            +
              # comes with ruby 1.8.x.  A Test::Unit 2.0 gem exists; use with caution.
         
     | 
| 
      
 24 
     | 
    
         
            +
              #
         
     | 
| 
      
 25 
     | 
    
         
            +
              # ==== Patches
         
     | 
| 
      
 26 
     | 
    
         
            +
              #
         
     | 
| 
      
 27 
     | 
    
         
            +
              # The shim script adds two things to Test::Unit:
         
     | 
| 
      
 28 
     | 
    
         
            +
              #
         
     | 
| 
      
 29 
     | 
    
         
            +
              # 1) A __name__ method which returns the test method name (alias for
         
     | 
| 
      
 30 
     | 
    
         
            +
              # method_name)
         
     | 
| 
      
 31 
     | 
    
         
            +
              #
         
     | 
| 
      
 32 
     | 
    
         
            +
              # 2) A skip method which can be used to skip a test (use it like flunk)
         
     | 
| 
      
 33 
     | 
    
         
            +
              #
         
     | 
| 
      
 34 
     | 
    
         
            +
              module Unit
         
     | 
| 
      
 35 
     | 
    
         
            +
              end
         
     | 
| 
      
 36 
     | 
    
         
            +
            end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            unless Object.const_defined?(:MiniTest)
         
     | 
| 
      
 39 
     | 
    
         
            +
              require 'shell_test/unit/shim'
         
     | 
| 
      
 40 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/shell_test.rb
    ADDED
    
    
    
        metadata
    ADDED
    
    | 
         @@ -0,0 +1,85 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            --- !ruby/object:Gem::Specification 
         
     | 
| 
      
 2 
     | 
    
         
            +
            name: shell_test
         
     | 
| 
      
 3 
     | 
    
         
            +
            version: !ruby/object:Gem::Version 
         
     | 
| 
      
 4 
     | 
    
         
            +
              hash: 27
         
     | 
| 
      
 5 
     | 
    
         
            +
              prerelease: 
         
     | 
| 
      
 6 
     | 
    
         
            +
              segments: 
         
     | 
| 
      
 7 
     | 
    
         
            +
              - 0
         
     | 
| 
      
 8 
     | 
    
         
            +
              - 1
         
     | 
| 
      
 9 
     | 
    
         
            +
              - 0
         
     | 
| 
      
 10 
     | 
    
         
            +
              version: 0.1.0
         
     | 
| 
      
 11 
     | 
    
         
            +
            platform: ruby
         
     | 
| 
      
 12 
     | 
    
         
            +
            authors: 
         
     | 
| 
      
 13 
     | 
    
         
            +
            - Simon Chiang
         
     | 
| 
      
 14 
     | 
    
         
            +
            autorequire: 
         
     | 
| 
      
 15 
     | 
    
         
            +
            bindir: bin
         
     | 
| 
      
 16 
     | 
    
         
            +
            cert_chain: []
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            date: 2011-07-07 00:00:00 -06:00
         
     | 
| 
      
 19 
     | 
    
         
            +
            default_executable: 
         
     | 
| 
      
 20 
     | 
    
         
            +
            dependencies: []
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
            description: Provides test modules to simplify testing of shell scripts. ShellTest is not a testing framework. ShellTest integrates with Test::Unit and MiniTest out of the box, but it should be possible to include the test modules into other test frameworks.
         
     | 
| 
      
 23 
     | 
    
         
            +
            email: 
         
     | 
| 
      
 24 
     | 
    
         
            +
            - simon.a.chiang@gmail.com
         
     | 
| 
      
 25 
     | 
    
         
            +
            executables: []
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            extensions: []
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            extra_rdoc_files: 
         
     | 
| 
      
 30 
     | 
    
         
            +
            - History.rdoc
         
     | 
| 
      
 31 
     | 
    
         
            +
            - README.rdoc
         
     | 
| 
      
 32 
     | 
    
         
            +
            - MIT-LICENSE
         
     | 
| 
      
 33 
     | 
    
         
            +
            files: 
         
     | 
| 
      
 34 
     | 
    
         
            +
            - lib/shell_test.rb
         
     | 
| 
      
 35 
     | 
    
         
            +
            - lib/shell_test/command_parser.rb
         
     | 
| 
      
 36 
     | 
    
         
            +
            - lib/shell_test/file_methods.rb
         
     | 
| 
      
 37 
     | 
    
         
            +
            - lib/shell_test/regexp_escape.rb
         
     | 
| 
      
 38 
     | 
    
         
            +
            - lib/shell_test/shell_methods.rb
         
     | 
| 
      
 39 
     | 
    
         
            +
            - lib/shell_test/unit.rb
         
     | 
| 
      
 40 
     | 
    
         
            +
            - lib/shell_test/unit/shim.rb
         
     | 
| 
      
 41 
     | 
    
         
            +
            - lib/shell_test/version.rb
         
     | 
| 
      
 42 
     | 
    
         
            +
            - History.rdoc
         
     | 
| 
      
 43 
     | 
    
         
            +
            - README.rdoc
         
     | 
| 
      
 44 
     | 
    
         
            +
            - MIT-LICENSE
         
     | 
| 
      
 45 
     | 
    
         
            +
            has_rdoc: true
         
     | 
| 
      
 46 
     | 
    
         
            +
            homepage: ""
         
     | 
| 
      
 47 
     | 
    
         
            +
            licenses: []
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
            post_install_message: 
         
     | 
| 
      
 50 
     | 
    
         
            +
            rdoc_options: 
         
     | 
| 
      
 51 
     | 
    
         
            +
            - --main
         
     | 
| 
      
 52 
     | 
    
         
            +
            - README.rdoc
         
     | 
| 
      
 53 
     | 
    
         
            +
            - -S
         
     | 
| 
      
 54 
     | 
    
         
            +
            - -N
         
     | 
| 
      
 55 
     | 
    
         
            +
            - --title
         
     | 
| 
      
 56 
     | 
    
         
            +
            - ShellTest
         
     | 
| 
      
 57 
     | 
    
         
            +
            require_paths: 
         
     | 
| 
      
 58 
     | 
    
         
            +
            - lib
         
     | 
| 
      
 59 
     | 
    
         
            +
            required_ruby_version: !ruby/object:Gem::Requirement 
         
     | 
| 
      
 60 
     | 
    
         
            +
              none: false
         
     | 
| 
      
 61 
     | 
    
         
            +
              requirements: 
         
     | 
| 
      
 62 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 63 
     | 
    
         
            +
                - !ruby/object:Gem::Version 
         
     | 
| 
      
 64 
     | 
    
         
            +
                  hash: 3
         
     | 
| 
      
 65 
     | 
    
         
            +
                  segments: 
         
     | 
| 
      
 66 
     | 
    
         
            +
                  - 0
         
     | 
| 
      
 67 
     | 
    
         
            +
                  version: "0"
         
     | 
| 
      
 68 
     | 
    
         
            +
            required_rubygems_version: !ruby/object:Gem::Requirement 
         
     | 
| 
      
 69 
     | 
    
         
            +
              none: false
         
     | 
| 
      
 70 
     | 
    
         
            +
              requirements: 
         
     | 
| 
      
 71 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 72 
     | 
    
         
            +
                - !ruby/object:Gem::Version 
         
     | 
| 
      
 73 
     | 
    
         
            +
                  hash: 3
         
     | 
| 
      
 74 
     | 
    
         
            +
                  segments: 
         
     | 
| 
      
 75 
     | 
    
         
            +
                  - 0
         
     | 
| 
      
 76 
     | 
    
         
            +
                  version: "0"
         
     | 
| 
      
 77 
     | 
    
         
            +
            requirements: []
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
            rubyforge_project: shell_test
         
     | 
| 
      
 80 
     | 
    
         
            +
            rubygems_version: 1.6.2
         
     | 
| 
      
 81 
     | 
    
         
            +
            signing_key: 
         
     | 
| 
      
 82 
     | 
    
         
            +
            specification_version: 3
         
     | 
| 
      
 83 
     | 
    
         
            +
            summary: Test modules for shell scripts
         
     | 
| 
      
 84 
     | 
    
         
            +
            test_files: []
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     |