require 'helper'

class BoringVendorProvidedCLI < Thor
  desc "boring", "do boring stuff"
  def boring
    puts "bored. <yawn>"
  end
end

class ExcitingPluginCLI < Thor
  desc "hooray", "say hooray!"
  def hooray
    puts "hooray!"
  end

  desc "fireworks", "exciting fireworks!"
  def fireworks
    puts "kaboom!"
  end
end

class SuperSecretPlugin < Thor
  default_command :squirrel

  desc "squirrel", "All of secret squirrel's secrets"
  def squirrel
    puts "I love nuts"
  end
end

class GroupPlugin < Thor::Group
  desc "part one"
  def part_one
    puts "part one"
  end

  desc "part two"
  def part_two
    puts "part two"
  end
end

class ClassOptionGroupPlugin < Thor::Group
  class_option :who,
    :type => :string,
    :aliases => "-w",
    :default => "zebra"
end

class CompatibleWith19Plugin < ClassOptionGroupPlugin
  desc "animal"
  def animal
    p options[:who]
  end
end

class PluginWithDefault < Thor
  desc "say MSG", "print MSG"
  def say(msg)
    puts msg
  end

  default_command :say
end

class PluginWithDefaultMultipleArguments < Thor
  desc "say MSG [MSG]", "print multiple messages"
  def say(*args)
    puts args
  end

  default_command :say
end

class PluginWithDefaultcommandAndDeclaredArgument < Thor
  desc "say MSG [MSG]", "print multiple messages"
  argument :msg
  def say
    puts msg
  end

  default_command :say
end

BoringVendorProvidedCLI.register(
  ExcitingPluginCLI,
  "exciting",
  "do exciting things",
  "Various non-boring actions")

BoringVendorProvidedCLI.register(
  SuperSecretPlugin,
  "secret",
  "secret stuff",
  "Nothing to see here. Move along.",
  :hide => true)

BoringVendorProvidedCLI.register(
  GroupPlugin,
  'groupwork',
  "Do a bunch of things in a row",
  "purple monkey dishwasher")

BoringVendorProvidedCLI.register(
  CompatibleWith19Plugin,
  'zoo',
  "zoo [-w animal]",
  "Shows a provided animal or just zebra")

BoringVendorProvidedCLI.register(
  PluginWithDefault,
  'say',
  'say message',
  'subcommands ftw')

BoringVendorProvidedCLI.register(
  PluginWithDefaultMultipleArguments,
  'say_multiple',
  'say message',
  'subcommands ftw')

BoringVendorProvidedCLI.register(
  PluginWithDefaultcommandAndDeclaredArgument,
  'say_argument',
  'say message',
  'subcommands ftw')

describe ".register-ing a Thor subclass" do
  it "registers the plugin as a subcommand" do
    fireworks_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[exciting fireworks]) }
    expect(fireworks_output).to eq("kaboom!\n")
  end

  it "includes the plugin's usage in the help" do
    help_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[help]) }
    expect(help_output).to include('do exciting things')
  end

  it "invokes the default command correctly" do
    output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[say hello]) }
    expect(output).to include("hello")
  end

  it "invokes the default command correctly with multiple args" do
    output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[say_multiple hello adam]) }
    expect(output).to include("hello")
    expect(output).to include("adam")
  end

  it "invokes the default command correctly with a declared argument" do
    output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[say_argument hello]) }
    expect(output).to include("hello")
  end

  context "when $thor_runner is false" do
    it "includes the plugin's subcommand name in subcommand's help" do
      begin
        $thor_runner = false
        help_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[exciting]) }
        expect(help_output).to include('thor exciting_plugin_c_l_i fireworks')
      ensure
        $thor_runner = true
      end
    end
  end

  context "when hidden" do
    it "omits the hidden plugin's usage from the help" do
      help_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[help]) }
      expect(help_output).not_to include('secret stuff')
    end

    it "registers the plugin as a subcommand" do
      secret_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[secret squirrel]) }
      expect(secret_output).to eq("I love nuts\n")
    end
  end
end

describe ".register-ing a Thor::Group subclass" do
  it "registers the group as a single command" do
    group_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[groupwork]) }
    expect(group_output).to eq("part one\npart two\n")
  end
end

describe "1.8 and 1.9 syntax compatibility" do
  it "is compatible with both 1.8 and 1.9 syntax w/o command options" do
    group_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[zoo]) }
    expect(group_output).to match(/zebra/)
  end

  it "is compatible with both 1.8 and 1.9 syntax w/command options" do
    group_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[zoo -w lion]) }
    expect(group_output).to match(/lion/)
  end
end
