require "spec_helper"

require "fileutils"
require "aruba/matchers/path"

RSpec.describe "Path Matchers" do
  include_context "uses aruba API"

  def expand_path(*args)
    @aruba.expand_path(*args)
  end

  describe "to_be_an_absolute_path" do
    let(:name) { @file_name }
    let(:path) { @aruba.expand_path(name) }

    context "when is absolute path" do
      it { expect(path).to be_an_absolute_path }
    end

    context "when is relative path" do
      it { expect(name).not_to be_an_absolute_path }
    end
  end

  describe "to_be_an_existing_path" do
    context "when file" do
      context "exists" do
        before do
          Aruba.platform.write_file(@file_path, "")
        end

        it { expect(@file_name).to be_an_existing_path }
      end

      context "does not exist" do
        it { expect(@file_name).not_to be_an_existing_path }
      end
    end

    context "when directory" do
      let(:name) { "test.d" }
      let(:path) { @aruba.expand_path(name) }

      context "exists" do
        before do
          FileUtils.mkdir_p path
        end

        it { expect(name).to be_an_existing_path }
      end

      context "does not exist" do
        it { expect(name).not_to be_an_existing_path }
      end
    end
  end

  describe "to have_permissions" do
    let(:file_name) { @file_name }
    let(:file_path) { @file_path }

    let(:permissions) { "0644" }

    before do
      @aruba.set_environment_variable "HOME", File.expand_path(@aruba.aruba.current_directory)
      File.open(file_path, "w") { |f| f << "" }
      @aruba.chmod(permissions, file_name)
    end

    context "when file exists" do
      context "and should have the same permissions" do
        context "and permissions are given as string" do
          it { expect(file_name).to have_permissions permissions }
        end

        context "and permissions are given as octal number" do
          let(:permissions) { 0o644 }

          it { expect(file_name).to have_permissions permissions }
        end

        context "and path includes ~" do
          let(:string) { random_string }
          let(:file_name) { File.join("~", string) }
          let(:file_path) { File.join(@aruba.aruba.current_directory, string) }

          it { expect(file_name).to have_permissions permissions }
        end

        context "but the permissions are different" do
          let(:expected_permissions) { 0o666 }

          it do
            expect { expect(file_name).to have_permissions expected_permissions }
              .to raise_error RSpec::Expectations::ExpectationNotMetError
          end
        end
      end

      context "and should not have the same permissions" do
        context "and permissions are different" do
          let(:different_permissions) { 0o666 }

          it { expect(file_name).not_to have_permissions different_permissions }
        end

        context "but permissions are the same" do
          let(:different_permissions) { 0o644 }

          it do
            expect { expect(file_name).not_to have_permissions different_permissions }
              .to raise_error RSpec::Expectations::ExpectationNotMetError
          end
        end
      end
    end
  end
end
