<commit_before>require 'shell_mock/call_verifier'
require 'shell_mock/stub_registry'

module ShellMock
  class CommandStub
    attr_reader :command, :output, :exitstatus, :env, :options, :side_effect

    def initialize(command)
      @command     = command
      @env         = {}
      @options     = {}
      @side_effect = proc {}
      @exitstatus  = 0

      @reader, @writer = IO.pipe
    end

    def with_env(env)
      @env = env

      self
    end

    def with_options(options)
      @options = options

      self
    end

    def and_output(output)
      @output = output

      self
    end

    def and_return(output)
      self.
        and_output(output).
        and_exit(0)
    end

    def and_exit(exitstatus)
      @exitstatus = exitstatus

      self
    end

    def calls
      @calls ||= 0

      marshaled_signatures.each do |marshaled_signature|
        @calls += 1
      end

      @calls
    end

    def called_with(env, command, options)
      writer.puts("called\n")
    end

    def to_oneliner
      "echo '#{output}' && exit #{exitstatus}"
    end

    private

    attr_reader :reader, :writer

    def marshaled_signatures
      messages = ""

      loop do
        begin
          messages += reader.read_nonblock(1)
        rescue IO::WaitReadable
          break
        end
      end

      messages.split("\n")
    end
  end
end<commit_msg>got rid of some of the extra lines in the spec output<commit_after>require 'shell_mock/call_verifier'
require 'shell_mock/stub_registry'

module ShellMock
  class CommandStub
    attr_reader :command, :output, :exitstatus, :env, :options, :side_effect

    def initialize(command)
      @command     = command
      @env         = {}
      @options     = {}
      @side_effect = proc {}
      @exitstatus  = 0
      @output      = nil

      @reader, @writer = IO.pipe
    end

    def with_env(env)
      @env = env

      self
    end

    def with_options(options)
      @options = options

      self
    end

    def and_output(output)
      @output = output

      self
    end

    def and_return(output)
      self.
        and_output(output).
        and_exit(0)
    end

    def and_exit(exitstatus)
      @exitstatus = exitstatus

      self
    end

    def calls
      @calls ||= 0

      marshaled_signatures.each do |marshaled_signature|
        @calls += 1
      end

      @calls
    end

    def called_with(env, command, options)
      writer.puts("called\n")
    end

    def to_oneliner
      if output
        "echo '#{output}' && exit #{exitstatus}"
      else
        "exit #{exitstatus}"
      end
    end

    private

    attr_reader :reader, :writer

    def marshaled_signatures
      messages = ""

      loop do
        begin
          messages += reader.read_nonblock(1)
        rescue IO::WaitReadable
          break
        end
      end

      messages.split("\n")
    end
  end
end
{'fraction_non_alphanumeric': 0.0843954529796762, 'fraction_numerical': 0.003444712366517396, 'mean_word_length': 1.8085106382978724, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '793133', 'n_tokens_mistral': 923, 'n_tokens_neox': 884, 'n_words': 228}