<commit_before>require 'spec_helper'
require 'cli'
require 'cli/client/errands_client'

describe Bosh::Cli::Command::Errand do
  subject(:command) { described_class.new }

  before { command.stub(director: director) }
  let(:director) { instance_double('Bosh::Cli::Client::Director') }

  describe 'run errand' do
    before { allow(Bosh::Cli::Client::ErrandsClient).to receive(:new).with(director).and_return(errands_client) }
    let(:errands_client) { instance_double('Bosh::Cli::Client::ErrandsClient') }

    context 'when user is logged in' do
      before { allow(command).to receive(:logged_in?).and_return(true) }

      context 'when deployment is selected' do
        before { allow(command).to receive(:deployment).and_return('/fake-manifest-path') }
        before { allow(command).to receive(:prepare_deployment_manifest).with(no_args).and_return('name' => 'fake-dep-name') }

        context 'when errand name is given' do
          def perform; command.run_errand('fake-errand-name'); end
          let(:errand_result) { Bosh::Cli::Client::ErrandsClient::ErrandResult.new(0, 'fake-stdout', 'fake-stderr') }

          it 'tells director to start running errand with given name on given instance' do
            expect(errands_client).to receive(:run_errand).
              with('fake-dep-name', 'fake-errand-name').
              and_return([:done, 'fake-task-id', errand_result])
            perform
          end

          context 'when errand director task finishes successfully' do
            before { allow(errands_client).to receive(:run_errand).and_return([:done, 'fake-task-id', errand_result]) }

            context 'when errand finished with 0 exit code' do
              let(:errand_result) { Bosh::Cli::Client::ErrandsClient::ErrandResult.new(0, 'fake-stdout', 'fake-stderr') }

              it 'exits with exit code 0' do
                perform
                expect(command.exit_code).to eq(0)
              end

              it 'does not raise an error' do
                perform
                expect_output(<<-TEXT)

                  [stdout]
                  fake-stdout

                  [stderr]
                  fake-stderr

                  Errand `fake-errand-name' completed successfully (exit code 0)
                TEXT
              end
            end

            context 'when errand finished with non-0 exit code' do
              let(:errand_result) { Bosh::Cli::Client::ErrandsClient::ErrandResult.new(123, 'fake-stdout', 'fake-stderr') }

              it 'raises an error and prints output' do
                expect {
                  perform
                }.to raise_error(
                  Bosh::Cli::CliError,
                  /Errand `fake-errand-name' completed with error \(exit code 123\)/,
                )

                expect_output(<<-TEXT)

                  [stdout]
                  fake-stdout

                  [stderr]
                  fake-stderr

                TEXT
              end
            end

            context 'when errand has stdout and stderr' do
              let(:errand_result) { Bosh::Cli::Client::ErrandsClient::ErrandResult.new(0, 'fake-stdout', 'fake-stderr') }

              it 'prints actual output for stdout and stderr' do
                perform
                expect_output(<<-TEXT)

                  [stdout]
                  fake-stdout

                  [stderr]
                  fake-stderr

                  Errand `fake-errand-name' completed successfully (exit code 0)
                TEXT
              end
            end

            context 'when errand has stdout and no stderr' do
              let(:errand_result) { Bosh::Cli::Client::ErrandsClient::ErrandResult.new(0, 'fake-stdout', '') }

              it 'prints None for both stderr and actual output for stdout' do
                perform
                expect_output(<<-TEXT)

                  [stdout]
                  fake-stdout

                  [stderr]
                  None

                  Errand `fake-errand-name' completed successfully (exit code 0)
                TEXT
              end
            end

            context 'when errand has stderr and no stdout' do
              let(:errand_result) { Bosh::Cli::Client::ErrandsClient::ErrandResult.new(0, '', 'fake-stderr') }

              it 'prints None for both stdout and actual output for stderr' do
                perform
                expect_output(<<-TEXT)

                  [stdout]
                  None

                  [stderr]
                  fake-stderr

                  Errand `fake-errand-name' completed successfully (exit code 0)
                TEXT
              end
            end

            context 'when errand has no stderr and no stdout' do
              let(:errand_result) { Bosh::Cli::Client::ErrandsClient::ErrandResult.new(0, '', '') }

              it 'prints None for both stdout and stderr' do
                perform
                expect_output(<<-TEXT)

                  [stdout]
                  None

                  [stderr]
                  None

                  Errand `fake-errand-name' completed successfully (exit code 0)
                TEXT
              end
            end
          end

          context 'when errand task does not finish successfully' do
            before { allow(errands_client).to receive(:run_errand).and_return([:error, 'fake-task-id', nil]) }

            it 'reports task information to the user' do
              perform
              expect_output(<<-TEXT)

                Errand `fake-errand-name' did not complete

                For a more detailed error report, run: bosh task fake-task-id --debug
              TEXT
            end

            it 'exits with exit code 1' do
              perform
              expect(command.exit_code).to eq(1)
            end
          end
        end
      end

      context 'when deployment is not selected' do
        before { allow(command).to receive(:deployment).and_return(nil) }

        it 'raises an CliError that says to choose a deployment' do
          expect {
            command.run_errand(nil)
          }.to raise_error(Bosh::Cli::CliError, /Please choose deployment first/)
        end
      end
    end

    it_requires_logged_in_user ->(command) { command.run_errand(nil) }
  end

  def expect_output(expected_output)
    actual = Bosh::Cli::Config.output.string
    indent = expected_output.scan(/^[ \t]*(?=\S)/).min.size || 0
    expect(actual).to eq(expected_output.gsub(/^[ \t]{#{indent}}/, ''))
  end
end
<commit_msg>fix cli errand spec to stub out target<commit_after>require 'spec_helper'
require 'cli'
require 'cli/client/errands_client'

describe Bosh::Cli::Command::Errand do
  subject(:command) { described_class.new }

  before { command.stub(director: director) }
  let(:director) { instance_double('Bosh::Cli::Client::Director') }

  describe 'run errand' do
    def perform; command.run_errand('fake-errand-name'); end

    before { allow(Bosh::Cli::Client::ErrandsClient).to receive(:new).with(director).and_return(errands_client) }
    let(:errands_client) { instance_double('Bosh::Cli::Client::ErrandsClient') }

    context 'when some director is targeted' do
      before { command.stub(target: 'fake-target') }

      context 'when user is logged in' do
        before { allow(command).to receive(:logged_in?).and_return(true) }

        context 'when deployment is selected' do
          before { allow(command).to receive(:deployment).and_return('/fake-manifest-path') }
          before { allow(command).to receive(:prepare_deployment_manifest).with(no_args).and_return('name' => 'fake-dep-name') }

          context 'when errand name is given' do
            let(:errand_result) { Bosh::Cli::Client::ErrandsClient::ErrandResult.new(0, 'fake-stdout', 'fake-stderr') }

            it 'tells director to start running errand with given name on given instance' do
              expect(errands_client).to receive(:run_errand).
                with('fake-dep-name', 'fake-errand-name').
                and_return([:done, 'fake-task-id', errand_result])
              perform
            end

            context 'when errand director task finishes successfully' do
              before { allow(errands_client).to receive(:run_errand).and_return([:done, 'fake-task-id', errand_result]) }

              context 'when errand finished with 0 exit code' do
                let(:errand_result) { Bosh::Cli::Client::ErrandsClient::ErrandResult.new(0, 'fake-stdout', 'fake-stderr') }

                it 'exits with exit code 0' do
                  perform
                  expect(command.exit_code).to eq(0)
                end

                it 'does not raise an error' do
                  perform
                  expect_output(<<-TEXT)

                    [stdout]
                    fake-stdout

                    [stderr]
                    fake-stderr

                    Errand `fake-errand-name' completed successfully (exit code 0)
                  TEXT
                end
              end

              context 'when errand finished with non-0 exit code' do
                let(:errand_result) { Bosh::Cli::Client::ErrandsClient::ErrandResult.new(123, 'fake-stdout', 'fake-stderr') }

                it 'raises an error and prints output' do
                  expect {
                    perform
                  }.to raise_error(
                    Bosh::Cli::CliError,
                    /Errand `fake-errand-name' completed with error \(exit code 123\)/,
                  )

                  expect_output(<<-TEXT)

                    [stdout]
                    fake-stdout

                    [stderr]
                    fake-stderr

                  TEXT
                end
              end

              context 'when errand has stdout and stderr' do
                let(:errand_result) { Bosh::Cli::Client::ErrandsClient::ErrandResult.new(0, 'fake-stdout', 'fake-stderr') }

                it 'prints actual output for stdout and stderr' do
                  perform
                  expect_output(<<-TEXT)

                    [stdout]
                    fake-stdout

                    [stderr]
                    fake-stderr

                    Errand `fake-errand-name' completed successfully (exit code 0)
                  TEXT
                end
              end

              context 'when errand has stdout and no stderr' do
                let(:errand_result) { Bosh::Cli::Client::ErrandsClient::ErrandResult.new(0, 'fake-stdout', '') }

                it 'prints None for both stderr and actual output for stdout' do
                  perform
                  expect_output(<<-TEXT)

                    [stdout]
                    fake-stdout

                    [stderr]
                    None

                    Errand `fake-errand-name' completed successfully (exit code 0)
                  TEXT
                end
              end

              context 'when errand has stderr and no stdout' do
                let(:errand_result) { Bosh::Cli::Client::ErrandsClient::ErrandResult.new(0, '', 'fake-stderr') }

                it 'prints None for both stdout and actual output for stderr' do
                  perform
                  expect_output(<<-TEXT)

                    [stdout]
                    None

                    [stderr]
                    fake-stderr

                    Errand `fake-errand-name' completed successfully (exit code 0)
                  TEXT
                end
              end

              context 'when errand has no stderr and no stdout' do
                let(:errand_result) { Bosh::Cli::Client::ErrandsClient::ErrandResult.new(0, '', '') }

                it 'prints None for both stdout and stderr' do
                  perform
                  expect_output(<<-TEXT)

                    [stdout]
                    None

                    [stderr]
                    None

                    Errand `fake-errand-name' completed successfully (exit code 0)
                  TEXT
                end
              end
            end

            context 'when errand task does not finish successfully' do
              before { allow(errands_client).to receive(:run_errand).and_return([:error, 'fake-task-id', nil]) }

              it 'reports task information to the user' do
                perform
                expect_output(<<-TEXT)

                  Errand `fake-errand-name' did not complete

                  For a more detailed error report, run: bosh task fake-task-id --debug
                TEXT
              end

              it 'exits with exit code 1' do
                perform
                expect(command.exit_code).to eq(1)
              end
            end
          end
        end

        context 'when deployment is not selected' do
          before { allow(command).to receive(:deployment).and_return(nil) }

          it 'raises an CliError that says to choose a deployment' do
            expect {
              command.run_errand(nil)
            }.to raise_error(Bosh::Cli::CliError, /Please choose deployment first/)
          end
        end
      end

      it_requires_logged_in_user ->(command) { command.run_errand(nil) }
    end

    context 'when nothing is targeted' do
      it 'fails with required target error' do
        command.stub(target: nil)
        expect { perform }.to raise_error(Bosh::Cli::CliError, 'Please choose target first')
      end
    end
  end

  def expect_output(expected_output)
    actual = Bosh::Cli::Config.output.string
    indent = expected_output.scan(/^[ \t]*(?=\S)/).min.size || 0
    expect(actual).to eq(expected_output.gsub(/^[ \t]{#{indent}}/, ''))
  end
end

{'fraction_non_alphanumeric': 0.0963846657452535, 'fraction_numerical': 0.003491670910016731, 'mean_word_length': 1.5774278215223096, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1203045', 'n_tokens_mistral': 3782, 'n_tokens_neox': 3455, 'n_words': 939}