# frozen_string_literal: true

RSpec.describe Algebra::Utils::Squish do
  describe 'instance' do
    subject(:instance) { described_class.new }

    it { is_expected.to respond_to(:[]) }
  end

  describe '#[]' do
    subject(:brackets) { instance[obj] }

    let(:instance) { described_class.new }

    describe 'result' do
      subject(:result) { brackets }

      context 'when argument is a string' do
        let(:obj) { 'a string' }

        it { is_expected.to be_a(String) }

        context 'when there are whitespaces in the string' do
          let(:obj) { "abc\ndef\tghi\vjkl\rmno prs" }

          it 'has spaces instead of them' do
            expect(result).to be == obj.gsub(/\s/, ' ')
          end
        end

        context 'when there are chains of whitespaces in the string' do
          let(:obj) { "abc\n def\t\nghi\v\tjkl\r\vmno \nprs" }

          it 'has no extra spaces' do
            expect(result).to be == obj.gsub(/\s+/, ' ')
          end
        end

        context 'when there are leading whitespaces in the string' do
          let(:obj) { "\n\r\t\v \n\rabc\n def\t\nghi\v\tjkl\r\vmno \nprs\r\v" }

          it 'has no leading whitespaces' do
            expect(result).to be == obj.gsub(/\s+/, ' ').strip
          end
        end

        context 'when the string is frozen' do
          let(:obj) { -'abc' }

          it 'is other string' do
            expect(result.object_id).not_to be == obj.object_id
          end
        end

        context 'when the string is not frozen' do
          let(:obj) { +'abc' }

          it 'is other string' do
            expect(result.object_id).not_to be == obj.object_id
          end
        end
      end

      context 'when argument is not a string' do
        let(:obj) { :'not   a    string' }

        it { is_expected.to be_a(String) }

        it 'is squished string representation' do
          expect(result).to be == obj.to_s.squeeze
        end
      end
    end
  end
end
