[DRE-commits] [ruby-airbrussh] 01/01: New upstream version 1.3.0

Samuel Henrique samueloph-guest at moszumanska.debian.org
Wed Nov 15 15:24:41 UTC 2017


This is an automated email from the git hooks/post-receive script.

samueloph-guest pushed a commit to annotated tag upstream/1.3.0
in repository ruby-airbrussh.

commit aa73c89c204091dda49496ec8aede6b9aebb1cd8
Author: Samuel Henrique <samueloph at gmail.com>
Date:   Wed Nov 15 13:19:35 2017 -0200

    New upstream version 1.3.0
---
 test/airbrussh/capistrano/tasks_test.rb     | 122 ++++++++
 test/airbrussh/capistrano_test.rb           |  29 ++
 test/airbrussh/colors_test.rb               |  26 ++
 test/airbrussh/command_formatter_test.rb    |  75 +++++
 test/airbrussh/configuration_test.rb        | 123 ++++++++
 test/airbrussh/console_formatter_test.rb    |  38 +++
 test/airbrussh/console_test.rb              | 134 ++++++++
 test/airbrussh/delegating_formatter_test.rb |  58 ++++
 test/airbrussh/formatter_test.rb            | 461 ++++++++++++++++++++++++++++
 test/airbrussh/log_file_formatter_test.rb   |  53 ++++
 test/airbrussh/rake/context_test.rb         |  76 +++++
 test/airbrussh/version_test.rb              |   7 +
 test/airbrussh_test.rb                      |  19 ++
 test/minitest_helper.rb                     |  10 +
 test/sshkit/formatter/airbrussh_test.rb     |  13 +
 test/support/coveralls.rb                   |  10 +
 test/support/minitest_reporters.rb          |   7 +
 test/support/mocha.rb                       |   4 +
 test/support/rake_task_definition.rb        |  12 +
 19 files changed, 1277 insertions(+)

diff --git a/test/airbrussh/capistrano/tasks_test.rb b/test/airbrussh/capistrano/tasks_test.rb
new file mode 100644
index 0000000..3afdd43
--- /dev/null
+++ b/test/airbrussh/capistrano/tasks_test.rb
@@ -0,0 +1,122 @@
+require "minitest_helper"
+require "airbrussh/capistrano/tasks"
+require "airbrussh/configuration"
+require "ostruct"
+require "stringio"
+require "tempfile"
+
+class Airbrussh::Capistrano::TasksTest < Minitest::Test
+  DSL = Struct.new(:formatter) do
+    def set(*)
+    end
+
+    # The Tasks object needs to reach into the backend provided by `env` in
+    # order to obtain the current Formatter, so here we build the complex mock
+    # needed for that.
+    def env
+      OpenStruct.new(
+        :backend => OpenStruct.new(
+          :config => OpenStruct.new(
+            :output => formatter
+          )
+        )
+      )
+    end
+
+    private
+
+    def namespace(*)
+    end
+
+    def task(*)
+    end
+  end
+
+  def setup
+    @config = Airbrussh::Configuration.new
+    @dsl = DSL.new(Airbrussh::Formatter.new(StringIO.new, @config))
+    @stderr = StringIO.new
+    @tasks = Airbrussh::Capistrano::Tasks.new(@dsl, @stderr, @config)
+  end
+
+  def test_no_warning_is_printed_when_proper_dsl_is_present
+    assert_empty(stderr)
+  end
+
+  def test_prints_warning_if_dsl_is_missing
+    bad_dsl = Object.new
+    Airbrussh::Capistrano::Tasks.new(bad_dsl, @stderr, @config)
+    assert_match(/WARNING.*must be loaded by Capistrano/, stderr)
+  end
+
+  def test_configures_for_capistrano
+    assert_equal("log/capistrano.log", @config.log_file)
+    assert(@config.monkey_patch_rake)
+    assert_equal(:auto, @config.color)
+    assert_equal(:auto, @config.truncate)
+    assert_equal(:auto, @config.banner)
+    refute(@config.command_output)
+  end
+
+  def test_sets_airbrussh_formatter_on_load_defaults
+    @dsl.expects(:set).with(:format, :airbrussh)
+    @tasks.load_defaults
+    assert(defined?(SSHKit::Formatter::Airbrussh))
+  end
+
+  def test_prints_last_20_logfile_lines_on_deploy_failure
+    with_log_file do |log_file|
+      log_file.write((11..31).map { |i| "line #{i}\n" }.join)
+      log_file.close
+
+      @tasks.deploy_failed
+
+      assert_match("DEPLOY FAILED", stderr)
+      refute_match("line 11", stderr)
+      (12..31).each { |i| assert_match("line #{i}", stderr) }
+    end
+  end
+
+  def test_does_not_truncate_log_file_lines
+    @config.truncate = 80
+
+    with_log_file do |log_file|
+      long_line = "a" * 100
+      log_file.puts(long_line)
+      log_file.close
+
+      @tasks.deploy_failed
+
+      assert_match(long_line, stderr)
+    end
+  end
+
+  def test_does_not_print_anything_on_deploy_failure_if_nil_logfile
+    @config.log_file = nil
+    @tasks.deploy_failed
+    assert_empty(stderr)
+  end
+
+  def test_does_not_print_anything_on_deploy_failure_if_airbrussh_is_not_used
+    pretty_dsl = DSL.new(SSHKit::Formatter::Pretty.new(StringIO.new))
+    tasks = Airbrussh::Capistrano::Tasks.new(pretty_dsl, @stderr, @config)
+    tasks.deploy_failed
+    assert_empty(stderr)
+  end
+
+  private
+
+  def stderr
+    @stderr.string
+  end
+
+  def with_log_file
+    log_file = Tempfile.new("airbrussh-test-")
+    begin
+      @config.log_file = log_file.path
+      yield(log_file)
+    ensure
+      log_file.unlink
+    end
+  end
+end
diff --git a/test/airbrussh/capistrano_test.rb b/test/airbrussh/capistrano_test.rb
new file mode 100644
index 0000000..3101d61
--- /dev/null
+++ b/test/airbrussh/capistrano_test.rb
@@ -0,0 +1,29 @@
+require "minitest_helper"
+
+class Airbrussh::CapistranoTest < Minitest::Test
+  def setup
+    # Mute the warning that is normally printed to $stderr when
+    # airbrussh/capistrano is required outside a capistrano runtime.
+    $stderr.stubs(:write)
+    require "airbrussh/capistrano"
+  end
+
+  def teardown
+    Airbrussh::Rake::Context.current_task_name = nil
+  end
+
+  def test_defines_tasks
+    assert_instance_of(Rake::Task, Rake.application["load:defaults"])
+    assert_instance_of(Rake::Task, Rake.application["deploy:failed"])
+  end
+
+  def test_load_defaults_rake_task_delegates_to_tasks_instance
+    Airbrussh::Capistrano::Tasks.any_instance.expects(:load_defaults)
+    Rake.application["load:defaults"].execute
+  end
+
+  def test_deploy_failed_rake_task_delegates_to_tasks_instance
+    Airbrussh::Capistrano::Tasks.any_instance.expects(:deploy_failed)
+    Rake.application["deploy:failed"].execute
+  end
+end
diff --git a/test/airbrussh/colors_test.rb b/test/airbrussh/colors_test.rb
new file mode 100644
index 0000000..f1b5782
--- /dev/null
+++ b/test/airbrussh/colors_test.rb
@@ -0,0 +1,26 @@
+require "minitest_helper"
+require "airbrussh/colors"
+
+class Airbrussh::ColorsTest < Minitest::Test
+  include Airbrussh::Colors
+
+  def test_red
+    assert_equal("\e[0;31;49mhello\e[0m", red("hello"))
+  end
+
+  def test_green
+    assert_equal("\e[0;32;49mhello\e[0m", green("hello"))
+  end
+
+  def test_yellow
+    assert_equal("\e[0;33;49mhello\e[0m", yellow("hello"))
+  end
+
+  def test_blue
+    assert_equal("\e[0;34;49mhello\e[0m", blue("hello"))
+  end
+
+  def test_gray
+    assert_equal("\e[0;90;49mhello\e[0m", gray("hello"))
+  end
+end
diff --git a/test/airbrussh/command_formatter_test.rb b/test/airbrussh/command_formatter_test.rb
new file mode 100644
index 0000000..2f2c628
--- /dev/null
+++ b/test/airbrussh/command_formatter_test.rb
@@ -0,0 +1,75 @@
+# encoding: UTF-8
+require "minitest_helper"
+require "ostruct"
+require "airbrussh/command_formatter"
+
+class Airbrussh::CommandFormatterTest < Minitest::Test
+  def setup
+    @sshkit_command = OpenStruct.new(
+      :host => host("deployer", "12.34.56.78"),
+      :options => { :user => "override" },
+      :runtime => 1.23456,
+      :failure? => false
+    )
+    @sshkit_command.define_singleton_method(:to_s) do
+      "/usr/bin/env echo hello"
+    end
+    @command = Airbrussh::CommandFormatter.new(@sshkit_command, 0)
+  end
+
+  def test_format_output
+    assert_equal("01 hello", @command.format_output("hello\n"))
+  end
+
+  def test_start_message
+    assert_equal("01 \e[0;33;49mecho hello\e[0m", @command.start_message)
+  end
+
+  def test_exit_message_success
+    assert_equal(
+      "\e[0;32;49m✔ 01 deployer at 12.34.56.78\e[0m 1.235s",
+      @command.exit_message
+    )
+  end
+
+  def test_exit_message_failure
+    @command.stub(:failure?, true) do
+      assert_equal(
+        "\e[0;31;49m✘ 01 deployer at 12.34.56.78\e[0m "\
+        "1.235s",
+        @command.exit_message
+      )
+    end
+  end
+
+  def test_uses_ssh_options_if_host_user_is_absent
+    @sshkit_command.host = host(nil, "12.34.56.78", :user => "sshuser")
+    assert_equal(
+      "\e[0;32;49m✔ 01 sshuser at 12.34.56.78\e[0m 1.235s",
+      @command.exit_message
+    )
+  end
+
+  def test_shows_hostname_only_if_no_user
+    @sshkit_command.host = host(nil, "12.34.56.78")
+    assert_equal(
+      "\e[0;32;49m✔ 01 12.34.56.78\e[0m 1.235s",
+      @command.exit_message
+    )
+  end
+
+  def test_handles_nil_position_gracefully
+    command = Airbrussh::CommandFormatter.new(@sshkit_command, nil)
+    assert_equal("01 hello", command.format_output("hello\n"))
+  end
+
+  private
+
+  def host(user, hostname, ssh_options={})
+    SSHKit::Host.new(
+      :user => user,
+      :hostname => hostname,
+      :ssh_options => ssh_options
+    )
+  end
+end
diff --git a/test/airbrussh/configuration_test.rb b/test/airbrussh/configuration_test.rb
new file mode 100644
index 0000000..2f42820
--- /dev/null
+++ b/test/airbrussh/configuration_test.rb
@@ -0,0 +1,123 @@
+require "minitest_helper"
+require "airbrussh/console_formatter"
+require "airbrussh/log_file_formatter"
+require "tempfile"
+
+class Airbrussh::ConfigurationTest < Minitest::Test
+  def setup
+    @config = Airbrussh::Configuration.new
+  end
+
+  def test_defaults
+    assert_nil(@config.log_file)
+    assert_equal(:auto, @config.color)
+    assert_equal(:auto, @config.truncate)
+    assert_equal(:auto, @config.banner)
+    assert_nil(@config.task_prefix)
+    refute(@config.monkey_patch_rake)
+    refute(@config.command_output)
+  end
+
+  def test_apply_options
+    @config.apply_options(
+      :log_file => "test",
+      :color => true,
+      :truncate => false,
+      :banner => "hi",
+      :monkey_patch_rake => true,
+      :command_output => true
+    )
+
+    assert_equal("test", @config.log_file)
+    assert_equal(true, @config.color)
+    assert_equal(false, @config.truncate)
+    assert_equal("hi", @config.banner)
+    assert(@config.monkey_patch_rake)
+    assert(@config.command_output)
+  end
+
+  def test_apply_options_warns_on_stderr_of_bad_key
+    _out, err = capture_io { @config.apply_options(:bad => "test") }
+    assert_match(/unrecognized/i, err)
+    assert_match(/bad/, err)
+  end
+
+  def test_auto_banner_message_without_log
+    @config.log_file = nil
+    @config.banner = :auto
+    assert_equal("Using airbrussh format.", @config.banner_message)
+  end
+
+  def test_auto_banner_message_with_log
+    @config.log_file = "log/test.log"
+    @config.banner = :auto
+    assert_equal(
+      "Using airbrussh format.\n"\
+      "Verbose output is being written to \e[0;34;49mlog/test.log\e[0m.",
+      @config.banner_message
+    )
+  end
+
+  def test_nil_or_false_banner_message
+    @config.banner = nil
+    assert_nil(@config.banner_message)
+    @config.banner = false
+    assert_nil(@config.banner_message)
+  end
+
+  def test_custom_banner_message
+    @config.banner = "Hello!"
+    assert_equal("Hello!", @config.banner_message)
+  end
+
+  def test_formatters_without_log_file
+    io = StringIO.new
+    formatters = @config.formatters(io)
+    assert_equal(1, formatters.length)
+    assert_instance_of(Airbrussh::ConsoleFormatter, formatters.first)
+    assert_equal(io, formatters.first.original_output)
+    assert_equal(@config, formatters.first.config)
+  end
+
+  def test_formatters_with_log_file
+    @config.log_file = Tempfile.new("airbrussh-test").path
+    io = StringIO.new
+    formatters = @config.formatters(io)
+    assert_equal(2, formatters.length)
+    assert_instance_of(Airbrussh::LogFileFormatter, formatters.first)
+    assert_instance_of(Airbrussh::ConsoleFormatter, formatters.last)
+    assert_equal(@config.log_file, formatters.first.path)
+    assert_equal(io, formatters.last.original_output)
+    assert_equal(@config, formatters.last.config)
+  end
+
+  def test_effects_of_command_output_true
+    @config.command_output = true
+    assert(@config.show_command_output?(:stdout))
+    assert(@config.show_command_output?(:stderr))
+  end
+
+  def test_effects_of_command_output_false
+    @config.command_output = false
+    refute(@config.show_command_output?(:stdout))
+    refute(@config.show_command_output?(:stderr))
+  end
+
+  def test_effects_of_command_output_stdout
+    @config.command_output = :stdout
+    assert(@config.show_command_output?(:stdout))
+    refute(@config.show_command_output?(:stderr))
+  end
+
+  def test_effects_of_command_output_stderr
+    @config.command_output = :stderr
+    refute(@config.show_command_output?(:stdout))
+    assert(@config.show_command_output?(:stderr))
+  end
+
+  def test_effects_of_command_output_stdout_stderr
+    @config.command_output = [:stdout, :stderr]
+    assert(@config.show_command_output?(:stdout))
+    assert(@config.show_command_output?(:stderr))
+  end
+end
diff --git a/test/airbrussh/console_formatter_test.rb b/test/airbrussh/console_formatter_test.rb
new file mode 100644
index 0000000..14d5319
--- /dev/null
+++ b/test/airbrussh/console_formatter_test.rb
@@ -0,0 +1,38 @@
+require "minitest_helper"
+require "stringio"
+require "airbrussh/configuration"
+require "airbrussh/console_formatter"
+
+# ConsoleFormatter is currently tested via a comprehensive acceptance-style
+# test in Airbrussh::FormatterTest. Hence the lack of unit tests here, which
+# would be redundant.
+class Airbrussh::ConsoleFormatterTest < Minitest::Test
+  def setup
+    @config = Airbrussh::Configuration.new
+    @config.banner = false
+    @config.command_output = true
+    @output = StringIO.new
+    @formatter = Airbrussh::ConsoleFormatter.new(@output, @config)
+  end
+
+  # Make sure that command data containing two lines is formatted as two
+  # indented lines.
+  def test_log_command_data_with_multiline_string
+    command = stub(:verbosity => SSHKit::Logger::INFO, :to_s => "greet")
+    data = "hello\nworld\n"
+    @formatter.log_command_start(command)
+    @formatter.log_command_data(command, :stdout, data)
+    assert_equal(
+      "      01 greet\n"\
+      "      01 hello\n"\
+      "      01 world\n",
+      output
+    )
+  end
+
+  private
+
+  def output
+    @output.string
+  end
+end
diff --git a/test/airbrussh/console_test.rb b/test/airbrussh/console_test.rb
new file mode 100644
index 0000000..1ffb256
--- /dev/null
+++ b/test/airbrussh/console_test.rb
@@ -0,0 +1,134 @@
+# encoding: UTF-8
+
+require "minitest_helper"
+require "stringio"
+require "airbrussh/configuration"
+require "airbrussh/console"
+
+class Airbrussh::ConsoleTest < Minitest::Test
+  def setup
+    @output = StringIO.new
+  end
+
+  def test_color_is_allowed_for_tty
+    console = configured_console(:tty => true) do |config|
+      config.color = :auto
+    end
+    console.print_line("The \e[0;32;49mgreen\e[0m text")
+    assert_equal("The \e[0;32;49mgreen\e[0m text\n", output)
+  end
+
+  def test_color_is_can_be_forced
+    console = configured_console(:tty => false) do |config|
+      config.color = true
+    end
+    console.print_line("The \e[0;32;49mgreen\e[0m text")
+    assert_equal("The \e[0;32;49mgreen\e[0m text\n", output)
+  end
+
+  def test_color_is_can_be_forced_via_env
+    console = configured_console(:tty => false) do |config|
+      config.color = :auto
+    end
+    ENV.stubs(:[]).with("SSHKIT_COLOR").returns("1")
+    console.print_line("The \e[0;32;49mgreen\e[0m text")
+    assert_equal("The \e[0;32;49mgreen\e[0m text\n", output)
+  end
+
+  def test_color_is_stripped_for_non_tty
+    console = configured_console(:tty => false) do |config|
+      config.color = :auto
+    end
+    console.print_line("The \e[0;32;49mgreen\e[0m text")
+    assert_equal("The green text\n", output)
+  end
+
+  def test_color_can_be_disabled_for_tty
+    console = configured_console(:tty => true) do |config|
+      config.color = false
+    end
+    console.print_line("The \e[0;32;49mgreen\e[0m text")
+    assert_equal("The green text\n", output)
+  end
+
+  def test_truncates_to_winsize
+    console = configured_console(:tty => true) do |config|
+      config.color = false
+      config.truncate = :auto
+    end
+    IO.stubs(:console => stub(:winsize => [100, 20]))
+    console.print_line("The quick brown fox jumps over the lazy dog.")
+    assert_equal("The quick brown fox…\n", output)
+  end
+
+  def test_ignores_ascii_color_codes_when_determing_truncation_amount
+    console = configured_console(:tty => true) do |config|
+      config.color = true
+      config.truncate = :auto
+    end
+    IO.stubs(:console => stub(:winsize => [100, 20]))
+    twenty_chars_plus_color = "\e[0;31;49m#{'a' * 20}\e[0m"
+    console.print_line(twenty_chars_plus_color)
+    assert_equal("#{twenty_chars_plus_color}\n", output)
+  end
+
+  def test_truncates_to_explicit_width
+    console = configured_console(:tty => true) do |config|
+      config.color = false
+      config.truncate = 25
+    end
+    console.print_line("The quick brown fox jumps over the lazy dog.")
+    assert_equal("The quick brown fox jump…\n", output)
+  end
+
+  def test_truncation_can_be_disabled
+    console = configured_console(:tty => true) do |config|
+      config.truncate = false
+    end
+    IO.expects(:console).never
+    console.print_line("The quick brown fox jumps over the lazy dog.")
+    assert_equal("The quick brown fox jumps over the lazy dog.\n", output)
+  end
+
+  # SSHKit sometimes returns raw ASCII-8BIT data that cannot be converted to
+  # UTF-8, which could frustrate the truncation logic. Make sure that Console
+  # recovers gracefully in this scenario.
+  def test_truncates_improperly_encoded_ascii_string
+    console = configured_console(:tty => true) do |config|
+      config.color = false
+      config.truncate = 10
+    end
+
+    console.print_line(ascii_8bit("The ‘quick’ brown fox"))
+
+    # Note that the left-apostrophe character is actually 3 bytes as raw
+    # ASCII-8BIT, which accounts for the short truncated value.
+    assert_equal(ascii_8bit("The ‘...\n"), ascii_8bit(output))
+  end
+
+  def test_doesnt_truncates_to_zero_width
+    console = configured_console(:tty => true) do |config|
+      config.color = false
+      config.truncate = 0
+    end
+    console.print_line("The quick brown fox jumps over the lazy dog.")
+    assert_equal("The quick brown fox jumps over the lazy dog.\n", output)
+  end
+
+  private
+
+  def ascii_8bit(string)
+    string.force_encoding("ASCII-8BIT")
+  end
+
+  def output
+    @output.string
+  end
+
+  def configured_console(opts={})
+    config = Airbrussh::Configuration.new
+    yield(config) if block_given?
+    @output.stubs(:tty? => opts.fetch(:tty, false))
+    Airbrussh::Console.new(@output, config)
+  end
+end
diff --git a/test/airbrussh/delegating_formatter_test.rb b/test/airbrussh/delegating_formatter_test.rb
new file mode 100644
index 0000000..18c12a7
--- /dev/null
+++ b/test/airbrussh/delegating_formatter_test.rb
@@ -0,0 +1,58 @@
+require "minitest_helper"
+require "airbrussh/delegating_formatter"
+
+class Airbrussh::DelegatingFormatterTest < Minitest::Test
+  def setup
+    @fmt_1 = stub
+    @fmt_2 = stub
+    @delegating = Airbrussh::DelegatingFormatter.new([@fmt_1, @fmt_2])
+  end
+
+  def test_forwards_logger_methods
+    %w(fatal error warn info debug log).each do |method|
+      @fmt_1.expects(method).with("string").returns(6)
+      @fmt_2.expects(method).with("string").returns(6)
+      result = @delegating.public_send(method, "string")
+      assert_equal(6, result)
+    end
+  end
+
+  def test_forwards_start_and_exit_methods
+    %w(log_command_start log_command_exit).each do |method|
+      @fmt_1.expects(method).with(:command).returns(nil)
+      @fmt_2.expects(method).with(:command).returns(nil)
+      result = @delegating.public_send(method, :command)
+      assert_nil(result)
+    end
+  end
+
+  def test_forwards_log_command_data
+    @fmt_1.expects(:log_command_data).with(:command, :stdout, "a").returns(nil)
+    @fmt_2.expects(:log_command_data).with(:command, :stdout, "a").returns(nil)
+    result = @delegating.log_command_data(:command, :stdout, "a")
+    assert_nil(result)
+  end
+
+  def test_forwards_io_methods_to_multiple_formatters
+    # All formatters get duped commands except for the last one. This is
+    # because in SSHKit versions up to and including 1.7.1, the formatters
+    # clear the command output, so each must be given it's own copy.
+    command = stub(:dup => "I've been duped!")
+    %w(<< write).each do |method|
+      @fmt_1.expects(method).with("I've been duped!").returns(16)
+      @fmt_2.expects(method).with(command).returns(10)
+      result = @delegating.public_send(method, command)
+      assert_equal(10, result)
+    end
+  end
+
+  def test_forwards_io_methods_to_a_single_formatter
+    command = stub(:dup => "I've been duped!")
+    %w(<< write).each do |method|
+      delegating = Airbrussh::DelegatingFormatter.new([@fmt_1])
+      @fmt_1.expects(method).with(command).returns(10)
+      result = delegating.public_send(method, command)
+      assert_equal(10, result)
+    end
+  end
+end
diff --git a/test/airbrussh/formatter_test.rb b/test/airbrussh/formatter_test.rb
new file mode 100644
index 0000000..26fb9e2
--- /dev/null
+++ b/test/airbrussh/formatter_test.rb
@@ -0,0 +1,461 @@
+# encoding: utf-8
+require "minitest_helper"
+require "bundler"
+require "etc"
+
+# rubocop:disable Metrics/LineLength
+
+class Airbrussh::FormatterTest < Minitest::Test
+  include RakeTaskDefinition
+
+  def setup
+    @output = StringIO.new
+    @log_file = StringIO.new
+    # sshkit > 1.6.1 && <= 1.7.1 uses Etc.getpwuid.name for local user lookup
+    # which causes a NoMethodError on Windows, so we need to stub it here.
+    Etc.stubs(:getpwuid => stub(:name => "stubbed_user")) unless sshkit_after?("1.7.1")
+    @user = SSHKit::Host.new(:local).username # nil on sshkit < 1.7.0
+    @user_at_localhost = [@user, "localhost"].compact.join("@")
+  end
+
+  def teardown
+    Airbrussh::Rake::Context.current_task_name = nil
+    SSHKit.reset_configuration!
+  end
+
+  def configure
+    airbrussh_config = Airbrussh::Configuration.new
+    airbrussh_config.log_file = @log_file
+
+    # Replace command map so it doesn't prefix every cmd with /usr/bin/env
+    sshkit_config = SSHKit.config
+    sshkit_config.command_map = Hash.new { |h, cmd| h[cmd] = cmd.to_s }
+
+    yield(airbrussh_config, sshkit_config)
+
+    sshkit_config.output = formatter_class.new(@output, airbrussh_config)
+  end
+
+  def test_can_be_configured_with_options_hash
+    formatter = Airbrussh::Formatter.new(@output, :banner => "success!")
+    config = formatter.formatters.last.config
+    assert_equal("success!", config.banner)
+  end
+
+  def test_formats_execute_with_color
+    configure do |airbrussh_config, sshkit_config|
+      sshkit_config.output_verbosity = ::Logger::DEBUG
+      airbrussh_config.command_output = true
+      airbrussh_config.color = true
+    end
+
+    on_local do
+      execute(:echo, "foo")
+    end
+
+    assert_output_lines(
+      "      01 \e[0;33;49mecho foo\e[0m\n",
+      "      01 foo\n",
+      /    \e\[0;32;49m✔ 01 #{@user_at_localhost}\e\[0m \d.\d+s\n/
+    )
+
+    assert_log_file_lines(
+      command_running("echo foo"),
+      command_started_debug("echo foo"),
+      command_std_stream(:stdout, "foo"),
+      command_success
+    )
+  end
+
+  def test_formats_execute_without_color
+    configure do |airbrussh_config|
+      airbrussh_config.command_output = true
+    end
+
+    on_local do
+      execute(:echo, "foo")
+    end
+
+    assert_output_lines(
+      "      01 echo foo\n",
+      "      01 foo\n",
+      /    ✔ 01 #{@user_at_localhost} \d.\d+s\n/
+    )
+
+    assert_log_file_lines(
+      command_running("echo foo"), command_success
+    )
+  end
+
+  def test_formats_without_command_output
+    configure do |airbrussh_config|
+      airbrussh_config.command_output = false
+    end
+
+    on_local do
+      execute(:ls, "-l")
+    end
+
+    assert_output_lines(
+      "      01 ls -l\n",
+      /    ✔ 01 #{@user_at_localhost} \d.\d+s\n/
+    )
+  end
+
+  def test_formats_failing_execute_with_color
+    configure do |airbrussh_config, sshkit_config|
+      sshkit_config.output_verbosity = ::Logger::DEBUG
+      airbrussh_config.command_output = true
+      airbrussh_config.color = true
+    end
+
+    error = nil
+    on_local do
+      begin
+        execute(:echo, "hi")
+        execute(:ls, "_file_does_not_exist")
+        # rubocop:disable Lint/HandleExceptions
+      rescue SSHKit::Command::Failed => error
+        # rubocop:enable Lint/HandleExceptions
+      end
+    end
+
+    refute_nil error
+
+    expected_output = [
+      "      01 \e[0;33;49mecho hi\e[0m\n",
+      "      01 hi\n",
+      /    \e\[0;32;49m✔ 01 #{@user_at_localhost}\e\[0m \d.\d+s\n/,
+      "      02 \e[0;33;49mls _file_does_not_exist\e[0m\n"
+    ]
+
+    error_message = /.*_file_does_not_exist.*No such file or directory/
+
+    # Don't know why this log line doesn't show up in SSHKit 1.6.1
+    expected_output << /      02 #{error_message}\n/ if sshkit_after?("1.6.1")
+
+    assert_output_lines(*expected_output)
+
+    expected_log_output = [
+      command_running("echo hi"),
+      command_started_debug("echo hi"),
+      command_std_stream(:stdout, "hi"),
+      command_success,
+
+      command_running("ls _file_does_not_exist"),
+      command_started_debug("ls _file_does_not_exist")
+    ]
+
+    if sshkit_after?("1.6.1")
+      expected_log_output << command_std_stream(:stderr, error_message)
+      expected_log_output << "\e[0m" if color_output?
+    end
+
+    assert_log_file_lines(*expected_log_output)
+  end
+
+  def test_formats_capture_with_color
+    configure do |airbrussh_config|
+      airbrussh_config.command_output = true
+      airbrussh_config.color = true
+    end
+
+    on_local do
+      capture(:ls, "-1", "airbrussh.gemspec", :verbosity => SSHKit::Logger::INFO)
+    end
+
+    assert_output_lines(
+      "      01 \e[0;33;49mls -1 airbrussh.gemspec\e[0m\n",
+      "      01 airbrussh.gemspec\n",
+      /    \e\[0;32;49m✔ 01 #{@user_at_localhost}\e\[0m \d.\d+s\n/
+    )
+
+    assert_log_file_lines(
+      command_running("ls -1 airbrussh.gemspec"), command_success
+    )
+  end
+
+  def test_formats_capture_without_color
+    configure do |airbrussh_config|
+      airbrussh_config.command_output = true
+    end
+
+    on_local do
+      capture(:ls, "-1", "airbrussh.gemspec", :verbosity => SSHKit::Logger::INFO)
+    end
+
+    assert_output_lines(
+      "      01 ls -1 airbrussh.gemspec\n",
+      "      01 airbrussh.gemspec\n",
+      /    ✔ 01 #{@user_at_localhost} \d.\d+s\n/
+    )
+
+    assert_log_file_lines(
+      command_running("ls -1 airbrussh.gemspec"), command_success
+    )
+  end
+
+  def test_does_not_output_test_commands
+    configure do |airbrussh_config, sshkit_config|
+      airbrussh_config.command_output = true
+      sshkit_config.output_verbosity = Logger::DEBUG
+    end
+
+    on_local do
+      test("echo hi")
+    end
+
+    assert_output_lines
+
+    assert_log_file_lines(
+      command_running("echo hi", "DEBUG"),
+      command_started_debug("echo hi"),
+      command_std_stream(:stdout, "hi"),
+      command_success("DEBUG")
+    )
+  end
+
+  def test_handles_rake_tasks
+    configure do |airbrussh_config|
+      airbrussh_config.monkey_patch_rake = true
+      airbrussh_config.command_output = true
+    end
+
+    on_local("special_rake_task") do
+      execute(:echo, "command 1")
+      info("Starting command 2")
+      execute(:echo, "command 2")
+    end
+    on_local("special_rake_task_2") do
+      error("New task starting")
+    end
+    on_local("special_rake_task_3") do
+      execute(:echo, "command 3")
+      execute(:echo, "command 4")
+      warn("All done")
+    end
+
+    assert_output_lines(
+      "00:00 special_rake_task\n",
+      "      01 echo command 1\n",
+      "      01 command 1\n",
+      /    ✔ 01 #{@user_at_localhost} \d.\d+s\n/,
+      "      Starting command 2\n",
+      "      02 echo command 2\n",
+      "      02 command 2\n",
+      /    ✔ 02 #{@user_at_localhost} \d.\d+s\n/,
+      "00:00 special_rake_task_2\n",
+      "      ERROR New task starting\n",
+      "00:00 special_rake_task_3\n",
+      "      01 echo command 3\n",
+      "      01 command 3\n",
+      /    ✔ 01 #{@user_at_localhost} \d.\d+s\n/,
+      "      02 echo command 4\n",
+      "      02 command 4\n",
+      /    ✔ 02 #{@user_at_localhost} \d.\d+s\n/,
+      "      WARN  All done\n"
+    )
+
+    assert_log_file_lines(
+      command_running("echo command 1"), command_success,
+      /#{blue('INFO')} Starting command 2\n/,
+      command_running("echo command 2"), command_success,
+      /#{red('ERROR')} New task starting\n/,
+      command_running("echo command 3"), command_success,
+      command_running("echo command 4"), command_success,
+      /#{yellow('WARN')} All done\n/
+    )
+  end
+
+  def test_log_message_levels
+    configure do |airbrussh_config, sshkit_config|
+      airbrussh_config.color = true
+      sshkit_config.output_verbosity = Logger::DEBUG
+    end
+
+    on_local do
+      %w(log fatal error warn info debug).each do |level|
+        send(level, "Test")
+      end
+    end
+
+    assert_output_lines(
+      "      Test\n",
+      "      \e[0;31;49mFATAL\e[0m Test\n",
+      "      \e[0;31;49mERROR\e[0m Test\n",
+      "      \e[0;33;49mWARN\e[0m  Test\n",
+      "      Test\n"
+    )
+
+    assert_log_file_lines(
+      /#{blue('INFO')} Test\n/,
+      /#{red('FATAL')} Test\n/,
+      /#{red('ERROR')} Test\n/,
+      /#{yellow('WARN')} Test\n/,
+      /#{blue('INFO')} Test\n/,
+      /#{black('DEBUG')} Test\n/
+    )
+  end
+
+  def test_interleaved_debug_and_info_commands
+    configure do |airbrussh_config|
+      airbrussh_config.monkey_patch_rake = true
+      airbrussh_config.command_output = true
+    end
+
+    on_local("interleaving_test") do
+      test("echo hi")
+      # test methods are logged at debug level by default
+      execute(:echo, "command 1")
+      test("echo hello")
+      debug("Debug line should not be output")
+      info("Info line should be output")
+      execute(:echo, "command 2")
+      execute(:echo, "command 3", :verbosity => :debug)
+      execute(:echo, "command 4")
+    end
+
+    assert_output_lines(
+      "00:00 interleaving_test\n",
+      "      01 echo command 1\n",
+      "      01 command 1\n",
+      /    ✔ 01 #{@user_at_localhost} \d.\d+s\n/,
+      "      Info line should be output\n",
+      "      02 echo command 2\n",
+      "      02 command 2\n",
+      /    ✔ 02 #{@user_at_localhost} \d.\d+s\n/,
+      "      03 echo command 4\n",
+      "      03 command 4\n",
+      /    ✔ 03 #{@user_at_localhost} \d.\d+s\n/
+    )
+  end
+
+  def test_task_prefix
+    configure do |airbrussh_config|
+      airbrussh_config.monkey_patch_rake = true
+      airbrussh_config.task_prefix = "--- "
+    end
+
+    on_local("task_prefix_test") do
+      execute(:echo, "command 1")
+      execute(:echo, "command 2")
+    end
+
+    assert_output_lines(
+      "--- 00:00 task_prefix_test\n",
+      "      01 echo command 1\n",
+      /    ✔ 01 #{@user_at_localhost} \d.\d+s\n/,
+      "      02 echo command 2\n",
+      /    ✔ 02 #{@user_at_localhost} \d.\d+s\n/
+    )
+  end
+
+  private
+
+  def on_local(task_name=nil, &block)
+    define_and_execute_rake_task(task_name) do
+      local_backend = SSHKit::Backend::Local.new(&block)
+      local_backend.run
+    end
+  end
+
+  def assert_output_lines(*expected_output)
+    expected_output = [
+      "Using airbrussh format.\n",
+      /Verbose output is being written to .*\n/
+    ] + expected_output
+    assert_string_io_lines(expected_output, @output)
+  end
+
+  def assert_string_io_lines(expected_output, string_io)
+    lines = string_io.string.lines.to_a
+    assert_equal expected_output.size, lines.size, lines.map(&:inspect).join(",\n")
+    lines.each.with_index do |line, i|
+      assert_case_equal(expected_output[i], line)
+    end
+  end
+
+  def assert_log_file_lines(*command_lines)
+    preamble_lines = [
+      /#{blue('INFO')} ---------------------------------------------------------------------------\n/,
+      /#{blue('INFO')} START [\d\-]+ [\d\:]+ [\+\-]\d+ cap\n/,
+      /#{blue('INFO')} ---------------------------------------------------------------------------\n/
+    ]
+
+    assert_string_io_lines(preamble_lines + command_lines, @log_file)
+  end
+
+  def command_running(command, level="INFO")
+    level_tag_color = level == "INFO" ? :blue : :black
+    /#{send(level_tag_color, level)} \[#{green('\w+')}\] Running #{bold_yellow(command.to_s)} #{@user ? "as #{blue(@user)}@" : "on "}#{blue('localhost')}\n/
+  end
+
+  def command_started_debug(command)
+    /#{black('DEBUG')} \[#{green('\w+')}\] Command: #{blue(command)}/
+  end
+
+  def command_std_stream(stream, output)
+    # Note ansii character end code is omitted due to newline
+    # This is probably a bug in SSHKit
+    color = stream == :stdout ? :green : :red
+    formatted_output = send(color, "\\t#{output}\\n").chomp('\\e\\[0m')
+    /#{black('DEBUG')} \[#{green('\w+')}\] #{formatted_output}/
+  end
+
+  def command_success(level="INFO")
+    level_tag_color = level == "INFO" ? :blue : :black
+    /#{send(level_tag_color, level)} \[#{green('\w+')}\] Finished in \d.\d+ seconds with exit status 0 \(#{bold_green("successful")}\).\n/
+  end
+
+  def command_failed(exit_status)
+    /#{black('DEBUG')} \[#{green('\w+')}\] Finished in \d.\d+ seconds with exit status #{exit_status} \(#{bold_red("failed")}\)/
+  end
+
+  {
+    :black => "0;30;49",
+    :red => "0;31;49",
+    :green => "0;32;49",
+    :yellow => "0;33;49",
+    :blue => "0;34;49",
+    :bold_red => "1;31;49",
+    :bold_green => "1;32;49",
+    :bold_yellow => "1;33;49"
+  }.each do |color, code|
+    define_method(color) do |string|
+      if color_output?
+        "\\e\\[#{code}m#{string}\\e\\[0m"
+      else
+        string
+      end
+    end
+  end
+
+  # Whether or not SSHKit emits color depends on the test environment. SSHKit
+  # versions up to 1.7.1 added colors to the log file, but only if
+  # `$stdout.tty?` is true. Later versions never output color to the log file.
+  def color_output?
+    $stdout.tty? && !(sshkit_after?("1.7.1") || sshkit_master?)
+  end
+
+  def sshkit_after?(version)
+    Gem.loaded_specs["sshkit"].version > Gem::Version.new(version)
+  end
+
+  def sshkit_master?
+    gem_source = Gem.loaded_specs["sshkit"].source
+    gem_source.is_a?(Bundler::Source::Git) && gem_source.branch == "master"
+  end
+
+  def formatter_class
+    Airbrussh::Formatter
+  end
+
+  module Minitest::Assertions
+    # rubocop:disable Style/CaseEquality
+    def assert_case_equal(matcher, obj, msg=nil)
+      message = message(msg) { "Expected #{mu_pp matcher} to === #{mu_pp obj}" }
+      assert matcher === obj, message
+    end
+    # rubocop:enable Style/CaseEquality
+  end
+end
diff --git a/test/airbrussh/log_file_formatter_test.rb b/test/airbrussh/log_file_formatter_test.rb
new file mode 100644
index 0000000..996187b
--- /dev/null
+++ b/test/airbrussh/log_file_formatter_test.rb
@@ -0,0 +1,53 @@
+require "minitest_helper"
+require "airbrussh/log_file_formatter"
+require "fileutils"
+require "tempfile"
+
+class Airbrussh::LogFileFormatterTest < Minitest::Test
+  def setup
+    @file = Tempfile.new("airbrussh-test-")
+    @file.puts("Existing data")
+    @file.close
+    @formatter = Airbrussh::LogFileFormatter.new(@file.path)
+  end
+
+  def teardown
+    @file.unlink
+    @output = nil
+  end
+
+  def test_appends_to_existing_file
+    assert_match("Existing data", output)
+  end
+
+  def test_writes_delimiter
+    assert_match("----------", output)
+    assert_match("START", output)
+  end
+
+  def test_writes_through_via_pretty_formatter
+    @formatter << SSHKit::LogMessage.new(SSHKit::Logger::INFO, "hello")
+    assert_match(/INFO.*hello/, output)
+  end
+
+  def test_creates_log_directory_and_file
+    with_tempdir do |dir|
+      log_file = File.join(dir, "log", "capistrano.log")
+      Airbrussh::LogFileFormatter.new(log_file)
+      assert(File.exist?(log_file))
+    end
+  end
+
+  private
+
+  def output
+    @output ||= IO.read(@file.path)
+  end
+
+  def with_tempdir
+    dir = Dir.mktmpdir("airbrussh-test-")
+    yield(dir)
+  ensure
+    FileUtils.rm_rf(dir)
+  end
+end
diff --git a/test/airbrussh/rake/context_test.rb b/test/airbrussh/rake/context_test.rb
new file mode 100644
index 0000000..d30d793
--- /dev/null
+++ b/test/airbrussh/rake/context_test.rb
@@ -0,0 +1,76 @@
+require "minitest_helper"
+require "airbrussh/rake/context"
+
+class Airbrussh::Rake::ContextTest < Minitest::Test
+  include RakeTaskDefinition
+
+  def setup
+    @config = Airbrussh::Configuration.new
+  end
+
+  def teardown
+    Airbrussh::Rake::Context.current_task_name = nil
+  end
+
+  def test_current_task_name_is_nil_when_disabled
+    @config.monkey_patch_rake = false
+    context = Airbrussh::Rake::Context.new(@config)
+    define_and_execute_rake_task("one") do
+      assert_nil(context.current_task_name)
+    end
+  end
+
+  def test_current_task_name
+    @config.monkey_patch_rake = true
+    context = Airbrussh::Rake::Context.new(@config)
+
+    assert_nil(context.current_task_name)
+
+    define_and_execute_rake_task("one") do
+      assert_equal("one", context.current_task_name)
+    end
+
+    define_and_execute_rake_task("two") do
+      assert_equal("two", context.current_task_name)
+    end
+  end
+
+  def test_register_new_command_is_true_for_first_execution_per_rake_task
+    @config.monkey_patch_rake = true
+    context = Airbrussh::Rake::Context.new(@config)
+    define_and_execute_rake_task("one") do
+      assert context.register_new_command(:command_one)
+      refute context.register_new_command(:command_one)
+      assert context.register_new_command(:command_two)
+      refute context.register_new_command(:command_two)
+    end
+
+    define_and_execute_rake_task("two") do
+      assert context.register_new_command(:command_one)
+      refute context.register_new_command(:command_one)
+      assert context.register_new_command(:command_two)
+      refute context.register_new_command(:command_two)
+    end
+  end
+
+  def test_position
+    @config.monkey_patch_rake = true
+    context = Airbrussh::Rake::Context.new(@config)
+
+    define_and_execute_rake_task("one") do
+      context.register_new_command(:command_one)
+      context.register_new_command(:command_two)
+
+      assert_equal(0, context.position(:command_one))
+      assert_equal(1, context.position(:command_two))
+    end
+
+    define_and_execute_rake_task("two") do
+      context.register_new_command(:command_three)
+      context.register_new_command(:command_four)
+
+      assert_equal(0, context.position(:command_three))
+      assert_equal(1, context.position(:command_four))
+    end
+  end
+end
diff --git a/test/airbrussh/version_test.rb b/test/airbrussh/version_test.rb
new file mode 100644
index 0000000..907381a
--- /dev/null
+++ b/test/airbrussh/version_test.rb
@@ -0,0 +1,7 @@
+require "minitest_helper"
+
+class Airbrussh::VersionTest < Minitest::Test
+  def test_that_it_has_a_version_number
+    refute_nil ::Airbrussh::VERSION
+  end
+end
diff --git a/test/airbrussh_test.rb b/test/airbrussh_test.rb
new file mode 100644
index 0000000..f997473
--- /dev/null
+++ b/test/airbrussh_test.rb
@@ -0,0 +1,19 @@
+require "minitest_helper"
+
+class AirbrusshTest < Minitest::Test
+  def test_configure_yields_config_object
+    config = Airbrussh.configuration
+    assert_equal(config, Airbrussh.configure { |c| c })
+  end
+
+  def test_configuration_returns_passed_config
+    config = Airbrussh::Configuration.new
+    assert_equal(config, Airbrussh.configuration(config))
+  end
+
+  def test_configuration_applies_options
+    config = Airbrussh.configuration(:banner => "test_success")
+    assert_equal("test_success", config.banner)
+    assert_equal("test_success", Airbrussh.configuration.banner)
+  end
+end
diff --git a/test/minitest_helper.rb b/test/minitest_helper.rb
new file mode 100644
index 0000000..bd61679
--- /dev/null
+++ b/test/minitest_helper.rb
@@ -0,0 +1,10 @@
+$LOAD_PATH.unshift(File.expand_path("../../lib", __FILE__))
+
+# Coveralls has to be loaded first
+require_relative("./support/coveralls")
+
+# Load everything else from test/support
+Dir[File.expand_path("../support/**/*.rb", __FILE__)].each { |rb| require(rb) }
+
+require "airbrussh"
+require "minitest/autorun"
diff --git a/test/sshkit/formatter/airbrussh_test.rb b/test/sshkit/formatter/airbrussh_test.rb
new file mode 100644
index 0000000..4d0bd76
--- /dev/null
+++ b/test/sshkit/formatter/airbrussh_test.rb
@@ -0,0 +1,13 @@
+require "minitest_helper"
+require "sshkit/formatter/airbrussh"
+require_relative "../../airbrussh/formatter_test.rb"
+
+# SSHKit::Formatter::Airbrussh should behave identically to
+# Airbrussh::Formatter, so just reuse the Airbrussh::FormatterTest.
+class SSHKit::Formatter::AirbrusshTest < Airbrussh::FormatterTest
+  private
+
+  def formatter_class
+    SSHKit::Formatter::Airbrussh
+  end
+end
diff --git a/test/support/coveralls.rb b/test/support/coveralls.rb
new file mode 100644
index 0000000..e68ff70
--- /dev/null
+++ b/test/support/coveralls.rb
@@ -0,0 +1,10 @@
+if ENV["TRAVIS"]
+  require "simplecov"
+  require "coveralls"
+
+  SimpleCov.formatter = Coveralls::SimpleCov::Formatter
+  SimpleCov.start do
+    # No need to report coverage metrics for the test code
+    add_filter "test"
+  end
+end
diff --git a/test/support/minitest_reporters.rb b/test/support/minitest_reporters.rb
new file mode 100644
index 0000000..8343855
--- /dev/null
+++ b/test/support/minitest_reporters.rb
@@ -0,0 +1,7 @@
+require "minitest/reporters"
+
+Minitest::Reporters.use!(
+  Minitest::Reporters::ProgressReporter.new,
+  ENV,
+  Minitest.backtrace_filter
+)
diff --git a/test/support/mocha.rb b/test/support/mocha.rb
new file mode 100644
index 0000000..415abec
--- /dev/null
+++ b/test/support/mocha.rb
@@ -0,0 +1,4 @@
+require "mocha/mini_test"
+
+Mocha::Configuration.warn_when(:stubbing_non_existent_method)
+Mocha::Configuration.warn_when(:stubbing_non_public_method)
diff --git a/test/support/rake_task_definition.rb b/test/support/rake_task_definition.rb
new file mode 100644
index 0000000..92bbb68
--- /dev/null
+++ b/test/support/rake_task_definition.rb
@@ -0,0 +1,12 @@
+module RakeTaskDefinition
+  def define_and_execute_rake_task(task_name, &block)
+    task_name ||= RakeTaskDefinition.unique_task_name(name)
+    Rake::Task[task_name].clear if Rake::Task.task_defined?(task_name)
+    Rake::Task.define_task(task_name, &block).execute
+  end
+
+  def self.unique_task_name(test_name)
+    @task_index ||= 0
+    "#{test_name}_#{@task_index += 1}"
+  end
+end

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ruby-extras/ruby-airbrussh.git



More information about the Pkg-ruby-extras-commits mailing list