From 772032f18a174d2cd5982800ebc0682eb569d0e1 Mon Sep 17 00:00:00 2001 From: Claudia Date: Sun, 30 Aug 2020 22:29:46 +0200 Subject: [PATCH] Add failing tests for `popen_write` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When using `popen_write`, the expectation is to return the standard output of the child process. This expectation is evident in how `safe_popen_write` is written: ``` def self.safe_popen_write(*args, **options, &block) output = popen_write(*args, **options, &block) return output if $CHILD_STATUS.success? raise ErrorDuringExecution.new(args, status: $CHILD_STATUS, output: [[:stdout, output]]) end ``` However, no code has been written to actually *obtain* that output from the child process. The side effects of that are described in issue #8244. [1] [1]: https://github.com/Homebrew/brew/issues/8244 The newly-added tests reveal that `popen_write` only returns the number 4 instead of the expected standard output. For example, given a file `foo` with the content `Foo\n`, one test calls `popen_write` with `cat foo -` and an input of `Bar`. The expected output would be `Foo\nBar\n` but the actual output is the number 4 (which is what Ruby’s `IO#write` method returns). --- Library/Homebrew/test/utils/popen_spec.rb | 42 +++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/test/utils/popen_spec.rb b/Library/Homebrew/test/utils/popen_spec.rb index c3f6027cf7..dcce91d8b4 100644 --- a/Library/Homebrew/test/utils/popen_spec.rb +++ b/Library/Homebrew/test/utils/popen_spec.rb @@ -26,11 +26,49 @@ describe Utils do end describe "::popen_write" do - it "with supports writing to a command's standard input" do + let(:foo) { mktmpdir/"foo" } + + before { foo.write "Foo\n" } + + it "supports writing to a command's standard input" do subject.popen_write("grep", "-q", "success") do |pipe| - pipe.write("success\n") + pipe.write "success\n" end expect($CHILD_STATUS).to be_a_success end + + it "returns the command's standard output before writing" do + child_stdout = subject.popen_write("cat", foo, "-") do |pipe| + pipe.write "Bar\n" + end + expect($CHILD_STATUS).to be_a_success + expect(child_stdout).to eq <<~EOS + Foo + Bar + EOS + end + + it "returns the command's standard output after writing" do + child_stdout = subject.popen_write("cat", "-", foo) do |pipe| + pipe.write "Bar\n" + end + expect($CHILD_STATUS).to be_a_success + expect(child_stdout).to eq <<~EOS + Bar + Foo + EOS + end + + it "supports interleaved writing between two reads" do + child_stdout = subject.popen_write("cat", foo, "-", foo) do |pipe| + pipe.write "Bar\n" + end + expect($CHILD_STATUS).to be_a_success + expect(child_stdout).to eq <<~EOS + Foo + Bar + Foo + EOS + end end end