require_relative '../lib/switch'

describe Switch do
  describe '.out' do
    it 'returns the total value sent to that output by default' do
      text = 'this is what you get'
      expect(Switch.out { print text }).to eq text
    end

    it 'can switch the standard output with an argument set as a StringIO' do
      text            = 'this is what you get'
      switched_output = Switch.out(true) { print text }
      expect(switched_output.class).to eq StringIO
      switched_output.rewind
      expect(switched_output.read).to eq text
    end
  end

  describe '.in' do
    it 'switches out standard input with an argument' do
      switched_in = 'this is what you get'
      closure     = nil
      Switch.in(switched_in) {closure = gets}
      expect(closure).to eq switched_in
    end

    it 'returns the rest of the original input object as a string after whatever was read from it' do
      after_switched_in = "this is what you don't"
      switched_in       = "this is what you get\n#{after_switched_in}"
      closure           = nil
      expect(Switch.in(switched_in) {closure = gets}).to eq after_switched_in
    end
  end

  describe '.up' do
    it 'combines both .in and .out' do
      text              = 'this is what you get'
      after_switched_in = "this is what you don't"
      switched_in       = "this is what you get\n#{after_switched_in}"
      closure           = nil
      value = Switch.up(stdin: switched_in) do 
        print text
        closure = gets
      end
      
      expect(value[:out]).to   eq text
      expect(closure.chomp).to eq text
      expect(value[:in]).to    eq after_switched_in
    end
  end
end
