# frozen_string_literal: true

RSpec.describe SemverDialects::Boundary do
  def cut_for_version(version_string)
    case version_string
    when 'inf'
      SemverDialects::AboveAll.new
    when '-inf'
      SemverDialects::BelowAll.new
    else
      described_class.new(SemverDialects::SemanticVersion.new(version_string))
    end
  end

  describe '#to_s' do
    subject { described_class.new(version).to_s }

    let(:version) { double('version', to_s: version_string) }
    let(:version_string) { '1.2.3-alpha.1' }

    it 'delegates to version' do
      is_expected.to eq(version_string)
    end
  end

  describe 'version cuts' do
    it 'should correctly identify initial versions' do
      vc0 = cut_for_version('0.0.0')
      expect(vc0.is_initial_version?).to eq(true)

      vc1 = cut_for_version('0')
      expect(vc1.is_initial_version?).to eq(true)

      vc2 = cut_for_version('1.2.3')
      expect(vc2.is_initial_version?).to eq(false)

      vc3 = cut_for_version('0.rc1')
      expect(vc3.is_initial_version?).to eq(true)
    end
  end

  describe '#<=>' do
    using RSpec::Parameterized::TableSyntax

    subject { boundary.<=>(other_boundary) }
    let(:boundary) { cut_for_version(a) }
    let(:other_boundary) { cut_for_version(b) }

    # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands
    where(:a, :b, :result) do
      '3' | '2' | 1
      '2.3.1' | '2.3.2' | -1
      '2.4.0-alpha' | '2.4.0-beta' | -1
      '3.0.0a1' | '3.0.0RC4' | -1
      '1.3.0dev0' | '1.3.0b3' | -1
      '1.2-alpha-6' | '1.2-beta-2' | -1
      '2.1' | '2.2' | -1
      '2.3.x' | '2.3.7' | 0
      '4.2' | '4.2.0.RELEASE' | 0
      '1' | '1' | 0
      'inf' | 'inf' | 0
      'inf' | '-inf' | 1
      'inf' | '1.0.0' | 1
      '-inf' | '-inf' | 0
      '-inf' | '1.0.0' | -1
    end
    # rubocop:enable Lint/BinaryOperatorWithIdenticalOperands

    with_them do
      it { is_expected.to eq(result) }

      it 'gives opposite result when arguments are swapped' do
        expect(other_boundary.<=>(boundary)).to eq(-result)
      end
    end
  end
end
