struct Athena::Console::Spec::CommandTester

Overview

Allows testing the logic of an ACON::Command, without needing to create and run a binary.

Say we have the following command:

@[ACONA::AsCommand("add", description: "Sums two numbers, optionally making making the sum negative")]
class AddCommand < ACON::Command
  protected def configure : Nil
    self
      .argument("value1", :required, "The first value")
      .argument("value2", :required, "The second value")
      .option("negative", description: "If the sum should be made negative")
  end

  protected def execute(input : ACON::Input::Interface, output : ACON::Output::Interface) : ACON::Command::Status
    sum = input.argument("value1", Int32) + input.argument("value2", Int32)

    sum = -sum if input.option "negative", Bool

    output.puts "The sum of values is: #{sum}"

    ACON::Command::Status::SUCCESS
  end
end

We can use ACON::Spec::CommandTester to assert it is working as expected.

require "spec"
require "athena-spec"

describe AddCommand do
  describe "#execute" do
    it "without negative option" do
      tester = ACON::Spec::CommandTester.new AddCommand.new
      tester.execute value1: 10, value2: 7
      tester.display.should eq "The sum of the values is: 17\n"
    end

    it "with negative option" do
      tester = ACON::Spec::CommandTester.new AddCommand.new
      tester.execute value1: -10, value2: 5, "--negative": nil
      tester.display.should eq "The sum of the values is: 5\n"
    end
  end
end

Commands with User Input

A command that are asking ACON::Questions can also be tested:

@[ACONA::AsCommand("question")]
class QuestionCommand < ACON::Command
  protected def execute(input : ACON::Input::Interface, output : ACON::Output::Interface) : ACON::Command::Status
    helper = self.helper ACON::Helper::Question

    question = ACON::Question(String).new "What is your name?", "None"
    output.puts "Your name is: #{helper.ask input, output, question}"

    ACON::Command::Status::SUCCESS
  end
end
require "spec"
require "./src/spec"

describe QuestionCommand do
  describe "#execute" do
    it do
      command = QuestionCommand.new
      command.helper_set = ACON::Helper::HelperSet.new ACON::Helper::Question.new
      tester = ACON::Spec::CommandTester.new command
      tester.inputs "Jim"
      tester.execute
      tester.display.should eq "What is your name?Your name is: Jim\n"
    end
  end
end

Because we are not in the context of an ACON::Application, we need to manually set the ACON::Helper::HelperSet in order to make the command aware of ACON::Helper::Question. After that we can use the ACON::Spec::Tester#inputs method to set the inputs our test should use when prompted.

Multiple inputs can be provided if there are multiple questions being asked.

Included Modules

Defined in:

spec.cr

Constructors

Instance Method Summary

Instance methods inherited from module Athena::Console::Spec::Tester

assert_command_is_successful(message : String = "", *, file : String = __FILE__, line : Int32 = __LINE__) : Nil assert_command_is_successful, display(normalize : Bool = false) : String display, error_output(normalize : Bool = false) : String error_output, inputs(*args : String) : Nil inputs, inputs=(inputs : Array(String)) inputs=, output : ACON::Output::Interface output, output? : ACON::Output::Interface | Nil output?, status : ACON::Command::Status | Nil status

Constructor Detail

def self.new(command : ACON::Command) #

[View source]

Instance Method Detail

def execute(input : Hash(String, _) = Hash(String, String).new, *, decorated : Bool = false, interactive : Bool | Nil = nil, capture_stderr_separately : Bool = false, verbosity : ACON::Output::Verbosity | Nil = nil) : ACON::Command::Status #

Executes the command, with the provided input being passed to the command.

Custom values for decorated, interactive, and verbosity can also be provided and will be forwarded to their respective types. capture_stderr_separately makes it so output to STDERR is captured separately, in case you wanted to test error output. Otherwise both error and normal output are captured via ACON::Spec::Tester#display.


[View source]
def execute(decorated : Bool = false, interactive : Bool | Nil = nil, capture_stderr_separately : Bool = false, verbosity : ACON::Output::Verbosity | Nil = nil, **input : _) #

Executes the command, with the provided input being passed to the command.

Custom values for decorated, interactive, and verbosity can also be provided and will be forwarded to their respective types. capture_stderr_separately makes it so output to STDERR is captured separately, in case you wanted to test error output. Otherwise both error and normal output are captured via ACON::Spec::Tester#display.


[View source]

Returns the ACON::Input::Interface being used by the tester.


[View source]
def input? : ACON::Input::Interface | Nil #

Returns the ACON::Input::Interface being used by the tester.


[View source]
def status : ACON::Command::Status | Nil #

Returns the ACON::Command::Status of the command execution, or nil if it has not yet been executed.


[View source]