require "spec_helper"
require "stringio"

RSpec.describe Todo::Commands::Update do
  describe "#run" do
    let(:output) { StringIO.new }
    let(:error_output) { StringIO.new }
    let(:repository) { instance_double(Todo::FileRepository) }

    before do
      allow(repository).to receive(:list).and_return([])
    end

    context "when arguments are empty" do
      it "puts help message to error output" do
        update = described_class.new(arguments: [], state: :done, output: output, error_output: error_output)
        update.run(repository: repository)
      rescue SystemExit
        # ignore exit
      ensure
        expect(error_output.string).to eq(update.help_message)
      end

      it "exits with status code 1" do
        update = described_class.new(arguments: [], state: :done, output: output, error_output: error_output)
        expect {
          update.run(repository: repository)
        }.to raise_error(an_instance_of(SystemExit).and(having_attributes({status: 1})))
      end
    end

    ["-h", "--help"].each do |flag|
      context "when arguments include '#{flag}' flag" do
        it "puts help message to output" do
          update = described_class.new(arguments: [flag], state: :done, output: output, error_output: error_output)
          update.run(repository: repository)
          expect(output.string).to eq(update.help_message)
        end
      end
    end

    context "when arguments include IDs" do
      it "calls Todo::FileRepository#update" do
        expect(repository).to receive(:update).with(ids: [1], state: :done)
        update = described_class.new(arguments: ["1"], state: :done, output: output, error_output: error_output)
        update.run(repository: repository)
      end
    end
  end
end
