# frozen_string_literal: true

RSpec.describe TTY::Reader, "#read_keypress" do
  let(:input)  { StringIO.new }
  let(:out)    { StringIO.new }
  let(:env)    { { "TTY_TEST" => true } }

  it "reads single key press" do
    reader = described_class.new(input: input, output: out, env: env)
    input << "\e[Aaaaaaa\n"
    input.rewind

    answer = reader.read_keypress

    expect(answer).to eq("\e[A")
  end

  it "reads multibyte key press" do
    reader = described_class.new(input: input, output: out, env: env)
    input << "ㄱ"
    input.rewind

    answer = reader.read_keypress

    expect(answer).to eq("ㄱ")
  end

  context "when Ctrl+C pressed" do
    it "defaults to raising InputInterrupt" do
      reader = described_class.new(input: input, output: out, env: env)
      input << "\x03"
      input.rewind

      expect {
        reader.read_keypress
      }.to raise_error(TTY::Reader::InputInterrupt)
    end

    it "sends interrupt signal when :signal option is chosen" do
      reader = described_class.new(
        input: input,
        output: out,
        interrupt: :signal,
        env: env)
      input << "\x03"
      input.rewind

      allow(Process).to receive(:pid).and_return(666)
      allow(Process).to receive(:kill)
      expect(Process).to receive(:kill).with("SIGINT", 666)

      reader.read_keypress
    end

    it "exits with 130 code when :exit option is chosen" do
      reader = described_class.new(
        input: input,
        output: out,
        interrupt: :exit,
        env: env)
      input << "\x03"
      input.rewind

      expect {
        reader.read_keypress
      }.to raise_error(SystemExit)
    end

    it "evaluates custom handler when proc object is provided" do
      handler = proc { raise ArgumentError }
      reader = described_class.new(
        input: input,
        output: out,
        interrupt: handler,
        env: env)
      input << "\x03"
      input.rewind

      expect {
       reader.read_keypress
      }.to raise_error(ArgumentError)
    end

    it "skips handler when handler is nil" do
      reader = described_class.new(
        input: input,
        output: out,
        interrupt: :noop,
        env: env)
      input << "\x03"
      input.rewind

      expect(reader.read_keypress).to eq("\x03")
    end
  end
end
