Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Some projects I've seen implement their command line tools as Command objects (for example: <a href="https://github.com/rubygems/rubygems/" rel="nofollow">Rubygems</a> and <a href="https://github.com/aef/linebreak/" rel="nofollow">my linebreak gem</a>). These objects are initialized with the ARGV simply have a call or execute method which then starts the whole process. This enables these projects to put their command line applications into a virtual environment. They could, for example hold the input and output stream objects in instance variables of the command object to make the application independant of using STDOUT/STDIN. And thus, making it possible to test the input/output of the command line application. In the same way I imagine, you could hold your current working directory in an instance variable to make your command line application independent of your real working directory. You could then create a temporary directory for each test and set this one as the working directory for your Command object.</p> <p>And now some code:</p> <pre><code>require 'pathname' class MyCommand attr_accessor :input, :output, :error, :working_dir def initialize(options = {}) @input = options[:input] ? options[:input] : STDIN @output = options[:output] ? options[:output] : STDOUT @error = options[:error] ? options[:error] : STDERR @working_dir = options[:working_dir] ? Pathname.new(options[:working_dir]) : Pathname.pwd end # Override the puts method to use the specified output stream def puts(output = nil) @output.puts(output) end def execute(arguments = ARGV) # Change to the given working directory Dir.chdir(working_dir) do # Analyze the arguments if arguments[0] == '--readfile' posts_dir = Pathname.new('posts') my_file = posts_dir + 'myfile' puts my_file.read end end end end # Start the command without mockups if the ruby script is called directly if __FILE__ == $PROGRAM_NAME MyCommand.new.execute end </code></pre> <p>Now in your test's setup and teardown methods you could do:</p> <pre><code>require 'pathname' require 'tmpdir' require 'stringio' def setup @working_dir = Pathname.new(Dir.mktmpdir('mycommand')) @output = StringIO.new @error = StringIO.new @command = MyCommand.new(:working_dir =&gt; @working_dir, :output =&gt; @output, :error =&gt; @error) end def test_some_stuff @command.execute(['--readfile']) # ... end def teardown @working_dir.rmtree end </code></pre> <p>(In the example I'm using Pathname, which is a really nice object oriented file system API from Ruby's standard library and StringIO, which is useful for for mocking STDOUT as it's an IO object which streams into a simple String)</p> <p>In the acutal test you could now use the @working_dir variable to test for existence or content of files:</p> <pre><code>path = @working_dir + 'posts' + 'myfile' path.exist? path.file? path.directory? path.read == "abc\n" </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload