# frozen_string_literal: true

require 'spec_helper'
require 'git/commands/stash/show'

RSpec.describe Git::Commands::Stash::Show do
  let(:execution_context) { execution_context_double }
  let(:command) { described_class.new(execution_context) }

  let(:numstat_output) do
    <<~OUTPUT
      5\t2\tlib/foo.rb
      3\t1\tlib/bar.rb
       2 files changed, 8 insertions(+), 3 deletions(-)
    OUTPUT
  end

  describe '#call' do
    context 'with no arguments (latest stash)' do
      it 'runs git stash show with no output-mode flags by default' do
        expected_result = command_result(numstat_output)
        expect_command_capturing('stash', 'show')
          .and_return(expected_result)

        result = command.call

        expect(result).to eq(expected_result)
      end
    end

    context 'with output mode options' do
      it 'includes --patch when patch: true' do
        expect_command_capturing('stash', 'show', '--patch')
          .and_return(command_result(''))

        command.call(patch: true)
      end

      it 'includes --numstat when numstat: true' do
        expect_command_capturing('stash', 'show', '--numstat')
          .and_return(command_result(numstat_output))

        command.call(numstat: true)
      end

      it 'includes --raw when raw: true' do
        expect_command_capturing('stash', 'show', '--raw')
          .and_return(command_result(''))

        command.call(raw: true)
      end

      it 'includes --shortstat when shortstat: true' do
        expect_command_capturing('stash', 'show', '--shortstat')
          .and_return(command_result(''))

        command.call(shortstat: true)
      end

      it 'combines multiple output mode flags in DSL order' do
        expect_command_capturing('stash', 'show', '--patch', '--numstat', '--shortstat')
          .and_return(command_result(numstat_output))

        command.call(patch: true, numstat: true, shortstat: true)
      end
    end

    context 'with :unified option' do
      it 'adds --unified=<n> for context lines' do
        expect_command_capturing('stash', 'show', '--unified=5')
          .and_return(command_result(''))

        command.call(unified: 5)
      end

      it 'accepts :U alias' do
        expect_command_capturing('stash', 'show', '--unified=3')
          .and_return(command_result(''))

        command.call(U: 3)
      end
    end

    context 'with specific stash reference' do
      it 'passes stash reference to command' do
        expect_command_capturing('stash', 'show', '--numstat', '--shortstat', 'stash@{2}')
          .and_return(command_result(numstat_output))

        command.call('stash@{2}', numstat: true, shortstat: true)
      end
    end

    context 'with :include_untracked option' do
      it 'adds --include-untracked flag when true' do
        expect_command_capturing('stash', 'show', '--numstat', '--shortstat', '--include-untracked')
          .and_return(command_result(numstat_output))

        command.call(numstat: true, shortstat: true, include_untracked: true)
      end

      it 'adds --no-include-untracked flag when :no_include_untracked is true' do
        expect_command_capturing('stash', 'show', '--numstat', '--shortstat', '--no-include-untracked')
          .and_return(command_result(numstat_output))

        command.call(numstat: true, shortstat: true, no_include_untracked: true)
      end

      it 'accepts :u alias' do
        expect_command_capturing('stash', 'show', '--numstat', '--shortstat', '--include-untracked')
          .and_return(command_result(numstat_output))

        command.call(numstat: true, shortstat: true, u: true)
      end
    end

    context 'with :only_untracked option' do
      it 'adds --only-untracked flag' do
        expect_command_capturing('stash', 'show', '--numstat', '--shortstat', '--only-untracked')
          .and_return(command_result(numstat_output))

        command.call(numstat: true, shortstat: true, only_untracked: true)
      end
    end

    context 'with :inter_hunk_context option' do
      it 'adds --inter-hunk-context=<n>' do
        expect_command_capturing('stash', 'show', '--inter-hunk-context=2')
          .and_return(command_result(''))

        command.call(inter_hunk_context: 2)
      end
    end

    context 'with :dirstat option' do
      it 'adds --dirstat flag when true' do
        expect_command_capturing('stash', 'show', '--numstat', '--shortstat', '--dirstat')
          .and_return(command_result(numstat_output))

        command.call(numstat: true, shortstat: true, dirstat: true)
      end

      it 'passes dirstat options when string' do
        expect_command_capturing('stash', 'show', '--numstat', '--shortstat',
                                 '--dirstat=lines,cumulative')
          .and_return(command_result(numstat_output))

        command.call(numstat: true, shortstat: true, dirstat: 'lines,cumulative')
      end
    end
  end
end
