Question

I am having trouble writing to standard input with Aruba. I have tried three approaches.

Approach 1:

Scenario: Write to stdin take 1
  Given a file named "infile" with:
    """
    Hello World!
    """
  When I run `cat < infile`
  Then the output should contain exactly:
    """
    Hello World!
    """

For this I get the following error:

  expected: "Hello World!"
       got: "Hello World!cat: <: No such file or directory\n" (using ==)
  Diff:
  @@ -1,2 +1,2 @@
  -Hello World!
  +Hello World!cat: <: No such file or directory
   (RSpec::Expectations::ExpectationNotMetError)
  features/cgi.feature:17:in `Then the output should contain exactly:'

Aruba is passing the '<' through literally whereas the shell would do some magic with pipes.

Approach 2:

Scenario: Write to stdin take 2
  When I run `cat` interactively
  And I type "Hello World!"
  Then the output should contain:
    """
    Hello World!
    """

I get the following error:

  process still alive after 3 seconds (ChildProcess::TimeoutError)
  features/cgi.feature:25:in `Then the output should contain:'

I don't know but I assume that cat is not receiving a EOF character and so cat remains open waiting for further input before writing. Is there any way to signal an end to input?

Approach 3:

Scenario: Write to stdin take 1
  Given a file named "infile" with:
    """
    Hello World!
    """
  When I run `sh -c "cat < infile"`
  Then the output should contain exactly:
    """
    Hello World!
    """

This approach works, but passing the input through a shell process does not appear to be the ideal solution.

I would have expected this was a fairly standard requirement but have not had any success getting it to work yet.

Any suggestions?

Thanks.

Was it helpful?

Solution

EDIT: I tried using the interactive mode to pipe in files however in real world usage I found it was significantly slower than using sh -c "process < infile", I'm not too sure why this is, it may be extra overhead in writing to stdin in Ruby @interactive.stdin.write(input) or it may be closing the pipe takes a little while @interactive.stdin.close(). I ended up using sh -c to get around the slow down. If cross-platform support was required then I expect that the slower runtime may be acceptable.

ORIGINAL POST:

I found a couple of ways to achieve this.

For take 1:

Scenario: Write to stdin take 1
  Given a file named "infile" with:
    """
    Hello World!
    """
 -When I run `cat < infile`
 +When I run `cat` interactively
 +And I pipe in the file "infile"
  Then the output should contain exactly:
    """
    Hello World!
    """

For scenario 1 I removed the attempt at pipe (<) and instead ran the process interactively. On the back end I wrote this step:

When /^I pipe in the file "(.*?)"$/ do |file|
  in_current_dir do
    File.open(file, 'r').each_line do |line|
      _write_interactive(line)
    end
  end
  @interactive.stdin.close()
end

The @interactive.stdin.close() should be moved to aruba/api.rb as a function there but the idea works. The call to _write_interactive should also arguably be a call to type(), but type() always adds a new line, which may not be what we want when piping in a file.

For take 2:

Scenario: Write to stdin take 2
  When I run `cat` interactively
  And I type "Hello World!"
 +Then I close the stdin stream
  And the output should contain:
    """
    Hello World!
    """

I added the close stdin stream, with the background step:

Then /^I close the stdin stream$/ do
  @interactive.stdin.close()
end

Once again this line should be made into a method in aruba/api.rb, but the code works.

OTHER TIPS

I pipe in the file has been implemented by Aruba, so you can now do this (related to Allan5's answer)

Scenario: Write to stdin
  Given a file named "infile" with:
    """
    Hello World!
    """
  When I run `cat` interactively
  And I pipe in the file "infile"
  Then the output should contain exactly:
    """
    Hello World!
    """
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top