[DRE-commits] [ruby-thor] 01/05: New upstream version 0.19.4
Lucas Nussbaum
lucas at moszumanska.debian.org
Sun Jul 2 09:06:58 UTC 2017
This is an automated email from the git hooks/post-receive script.
lucas pushed a commit to branch master
in repository ruby-thor.
commit 4c7b253c4c881eadbf1b86f03032792a960879ba
Author: Lucas Nussbaum <lucas at debian.org>
Date: Sun Jul 2 10:00:00 2017 +0200
New upstream version 0.19.4
---
CHANGELOG.md | 24 +
CONTRIBUTING.md | 15 +
README.md | 8 +-
Thorfile | 29 --
checksums.yaml.gz | Bin 270 -> 0 bytes
lib/thor.rb | 54 ++-
lib/thor/actions.rb | 43 +-
lib/thor/actions/create_file.rb | 2 +-
lib/thor/actions/create_link.rb | 2 +-
lib/thor/actions/directory.rb | 4 +-
lib/thor/actions/empty_directory.rb | 16 +-
lib/thor/actions/file_manipulation.rb | 35 +-
lib/thor/actions/inject_into_file.rb | 24 +-
lib/thor/base.rb | 60 +--
lib/thor/command.rb | 18 +-
lib/thor/core_ext/hash_with_indifferent_access.rb | 10 +-
lib/thor/core_ext/io_binary_read.rb | 12 +-
lib/thor/core_ext/ordered_hash.rb | 157 ++++---
lib/thor/error.rb | 6 +-
lib/thor/group.rb | 24 +-
lib/thor/invocation.rb | 9 +-
lib/thor/parser/argument.rb | 11 +-
lib/thor/parser/arguments.rb | 32 +-
lib/thor/parser/option.rb | 59 ++-
lib/thor/parser/options.rb | 12 +-
lib/thor/runner.rb | 50 +-
lib/thor/shell.rb | 2 +-
lib/thor/shell/basic.rb | 67 +--
lib/thor/shell/color.rb | 2 +-
lib/thor/shell/html.rb | 8 +-
lib/thor/util.rb | 15 +-
lib/thor/version.rb | 2 +-
metadata.yml | 240 ----------
spec/actions/create_file_spec.rb | 168 -------
spec/actions/create_link_spec.rb | 96 ----
spec/actions/directory_spec.rb | 169 -------
spec/actions/empty_directory_spec.rb | 129 ------
spec/actions/file_manipulation_spec.rb | 392 ----------------
spec/actions/inject_into_file_spec.rb | 135 ------
spec/actions_spec.rb | 331 --------------
spec/base_spec.rb | 298 ------------
spec/command_spec.rb | 79 ----
spec/core_ext/hash_with_indifferent_access_spec.rb | 48 --
spec/core_ext/ordered_hash_spec.rb | 115 -----
spec/exit_condition_spec.rb | 19 -
spec/fixtures/application.rb | 2 -
spec/fixtures/app{1}/README | 3 -
spec/fixtures/bundle/execute.rb | 6 -
spec/fixtures/bundle/main.thor | 1 -
spec/fixtures/command.thor | 10 -
spec/fixtures/doc/%file_name%.rb.tt | 1 -
spec/fixtures/doc/COMMENTER | 11 -
spec/fixtures/doc/README | 3 -
spec/fixtures/doc/block_helper.rb | 3 -
spec/fixtures/doc/config.rb | 1 -
spec/fixtures/doc/config.yaml.tt | 1 -
spec/fixtures/doc/excluding/%file_name%.rb.tt | 1 -
spec/fixtures/enum.thor | 10 -
spec/fixtures/group.thor | 128 ------
spec/fixtures/invoke.thor | 131 ------
spec/fixtures/path with spaces | 0
spec/fixtures/preserve/script.sh | 3 -
spec/fixtures/script.thor | 220 ---------
spec/fixtures/subcommand.thor | 17 -
spec/group_spec.rb | 222 ---------
spec/helper.rb | 80 ----
spec/invocation_spec.rb | 120 -----
spec/line_editor/basic_spec.rb | 28 --
spec/line_editor/readline_spec.rb | 69 ---
spec/line_editor_spec.rb | 43 --
spec/parser/argument_spec.rb | 53 ---
spec/parser/arguments_spec.rb | 66 ---
spec/parser/option_spec.rb | 210 ---------
spec/parser/options_spec.rb | 414 -----------------
spec/quality_spec.rb | 75 ---
spec/rake_compat_spec.rb | 72 ---
spec/register_spec.rb | 227 ---------
spec/runner_spec.rb | 246 ----------
spec/sandbox/application.rb | 2 -
spec/sandbox/app{1}/README | 3 -
spec/sandbox/bundle/execute.rb | 6 -
spec/sandbox/bundle/main.thor | 1 -
spec/sandbox/command.thor | 10 -
spec/sandbox/doc/%file_name%.rb.tt | 1 -
spec/sandbox/doc/COMMENTER | 11 -
spec/sandbox/doc/README | 3 -
spec/sandbox/doc/block_helper.rb | 3 -
spec/sandbox/doc/config.rb | 1 -
spec/sandbox/doc/config.yaml.tt | 1 -
spec/sandbox/doc/excluding/%file_name%.rb.tt | 1 -
spec/sandbox/enum.thor | 10 -
spec/sandbox/group.thor | 128 ------
spec/sandbox/invoke.thor | 131 ------
spec/sandbox/path with spaces | 0
spec/sandbox/preserve/script.sh | 3 -
spec/sandbox/script.thor | 220 ---------
spec/sandbox/subcommand.thor | 17 -
spec/shell/basic_spec.rb | 337 --------------
spec/shell/color_spec.rb | 119 -----
spec/shell/html_spec.rb | 31 --
spec/shell_spec.rb | 47 --
spec/subcommand_spec.rb | 48 --
spec/thor_spec.rb | 505 ---------------------
spec/util_spec.rb | 196 --------
thor.gemspec | 15 +-
105 files changed, 465 insertions(+), 6893 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 38687db..4b786ca 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,27 @@
+## 0.19.1, release 2014-03-24
+* Fix `say` non-String break regression
+
+## 0.19.0, release 2014-03-22
+* Add support for a default to #ask
+* Avoid @namespace not initialized warning
+* Avoid private attribute? warning
+* Fix initializing with unknown options
+* Loosen required_rubygems_version for compatibility with Ubuntu 10.04
+* Shell#ask: support a noecho option for stdin
+* Shell#ask: change API to be :echo => false
+* Display a message without a stack trace for ambiguous commands
+* Make say and say_status thread safe
+* Dependency for console io version check
+* Alias --help to help on subcommands
+* Use mime-types 1.x for Ruby 1.8.7 compatibility for Ruby 1.8 only
+* Accept .tt files as templates
+* Check if numeric value is in enum
+* Use Readline for user input
+* Fix dispatching of subcommands (concerning :help and *args)
+* Fix warnings when running specs with `$VERBOSE = true`
+* Make subcommand help more consistent
+* Make the current command chain accessible in command
+
## 0.18.1, release 2013-03-30
* Revert regressions found in 0.18.0
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..12f06e0
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,15 @@
+Pull Requests
+-------------
+Here are some reasons why a pull request may not be merged:
+
+1. It hasn’t been reviewed.
+2. It doesn’t include specs for new functionality.
+3. It doesn’t include documentation for new functionality.
+4. It changes behavior without changing the relevant documentation, comments, or specs.
+5. It changes behavior of an existing public API, breaking backward compatibility.
+6. It breaks the tests on a supported platform.
+7. It doesn’t merge cleanly (requiring Git rebasing and conflict resolution).
+
+If you would like to help in this process, you can start by evaluating open pull requests against the criteria above. For example, if a pull request does not include specs for new functionality, you can add a comment like: “If you would like this feature to be added to Thor, please add specs to ensure that it does not break in the future.” This will help move a pull request closer to being merged.
+
+Include this emoji in the top of your ticket to signal to us that you read this file: 🌈
diff --git a/README.md b/README.md
index 74d5144..a9a0ca1 100644
--- a/README.md
+++ b/README.md
@@ -21,7 +21,7 @@ utilities. It removes the pain of parsing command line options, writing
build tool. The syntax is Rake-like, so it should be familiar to most Rake
users.
-[rake]: https://github.com/jimweirich/rake
+[rake]: https://github.com/ruby/rake
Installation
------------
@@ -34,6 +34,12 @@ Please see the [wiki][] for basic usage and other documentation on using Thor. Y
[wiki]: https://github.com/erikhuda/thor/wiki
[homepage]: http://whatisthor.com/
+Contributing
+------------
+If you would like to help, please read the [CONTRIBUTING][] file for suggestions.
+
+[contributing]: CONTRIBUTING.md
+
License
-------
Released under the MIT License. See the [LICENSE][] file for further details.
diff --git a/Thorfile b/Thorfile
deleted file mode 100644
index 3b2df55..0000000
--- a/Thorfile
+++ /dev/null
@@ -1,29 +0,0 @@
-$LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
-
-require "bundler"
-require "thor/rake_compat"
-
-class Default < Thor
- include Thor::RakeCompat
- Bundler::GemHelper.install_tasks
-
- desc "build", "Build thor-#{Thor::VERSION}.gem into the pkg directory"
- def build
- Rake::Task["build"].execute
- end
-
- desc "install", "Build and install thor-#{Thor::VERSION}.gem into system gems"
- def install
- Rake::Task["install"].execute
- end
-
- desc "release", "Create tag v#{Thor::VERSION} and build and push thor-#{Thor::VERSION}.gem to Rubygems"
- def release
- Rake::Task["release"].execute
- end
-
- desc "spec", "Run RSpec code examples"
- def spec
- exec "rspec spec"
- end
-end
diff --git a/checksums.yaml.gz b/checksums.yaml.gz
deleted file mode 100644
index e2c25c7..0000000
Binary files a/checksums.yaml.gz and /dev/null differ
diff --git a/lib/thor.rb b/lib/thor.rb
index d687d3b..b510d28 100644
--- a/lib/thor.rb
+++ b/lib/thor.rb
@@ -1,7 +1,7 @@
require "set"
require "thor/base"
-class Thor # rubocop:disable ClassLength
+class Thor
class << self
# Allows for custom "Command" package naming.
#
@@ -9,7 +9,7 @@ class Thor # rubocop:disable ClassLength
# name<String>
# options<Hash>
#
- def package_name(name, options = {})
+ def package_name(name, _ = {})
@package_name = name.nil? || name == "" ? nil : name
end
@@ -57,7 +57,9 @@ class Thor # rubocop:disable ClassLength
command.usage = usage if usage
command.description = description if description
else
- @usage, @desc, @hide = usage, description, options[:hide] || false
+ @usage = usage
+ @desc = description
+ @hide = options[:hide] || false
end
end
@@ -156,6 +158,10 @@ class Thor # rubocop:disable ClassLength
end
alias_method :option, :method_option
+ def disable_class_options
+ @disable_class_options = true
+ end
+
# Prints help information for the given command.
#
# ==== Parameters
@@ -170,7 +176,7 @@ class Thor # rubocop:disable ClassLength
shell.say "Usage:"
shell.say " #{banner(command)}"
shell.say
- class_options_help(shell, nil => command.options.map { |_, o| o })
+ class_options_help(shell, nil => command.options.values)
if command.long_description
shell.say "Description:"
shell.print_wrapped(command.long_description, :indent => 2)
@@ -231,8 +237,9 @@ class Thor # rubocop:disable ClassLength
define_method(subcommand) do |*args|
args, opts = Thor::Arguments.split(args)
- args.unshift("help") if opts.include? "--help" or opts.include? "-h"
- invoke subcommand_class, args, opts, :invoked_via_subcommand => true, :class_options => options
+ invoke_args = [args, opts, {:invoked_via_subcommand => true, :class_options => options}]
+ invoke_args.unshift "help" if opts.delete("--help") || opts.delete("-h")
+ invoke subcommand_class, *invoke_args
end
end
alias_method :subtask, :subcommand
@@ -320,6 +327,7 @@ class Thor # rubocop:disable ClassLength
end
protected
+
def stop_on_unknown_option #:nodoc:
@stop_on_unknown_option ||= Set.new
end
@@ -345,12 +353,14 @@ class Thor # rubocop:disable ClassLength
opts.clear
end
else
- args, opts = given_args, nil
+ args = given_args
+ opts = nil
command = dynamic_command_class.new(meth)
end
opts = given_opts || opts || []
- config.merge!(:current_command => command, :command_options => command.options)
+ config[:current_command] = command
+ config[:command_options] = command.options
instance = new(args, opts, config)
yield instance if block_given?
@@ -380,17 +390,18 @@ class Thor # rubocop:disable ClassLength
@usage ||= nil
@desc ||= nil
@long_desc ||= nil
+ @disable_class_options ||= nil
if @usage && @desc
base_class = @hide ? Thor::HiddenCommand : Thor::Command
- commands[meth] = base_class.new(meth, @desc, @long_desc, @usage, method_options)
- @usage, @desc, @long_desc, @method_options, @hide = nil
+ commands[meth] = base_class.new(meth, @desc, @long_desc, @usage, method_options, @disable_class_options)
+ @usage, @desc, @long_desc, @method_options, @hide, @disable_class_options = nil
true
elsif all_commands[meth] || meth == "method_missing"
true
else
- puts "[WARNING] Attempted to create command #{meth.inspect} without usage or description. " <<
- "Call desc if you want this method to be available as command or declare it inside a " <<
+ puts "[WARNING] Attempted to create command #{meth.inspect} without usage or description. " \
+ "Call desc if you want this method to be available as command or declare it inside a " \
"no_commands{} block. Invoked from #{caller[1].inspect}."
false
end
@@ -405,11 +416,7 @@ class Thor # rubocop:disable ClassLength
# Retrieve the command name from given args.
def retrieve_command_name(args) #:nodoc:
meth = args.first.to_s unless args.empty?
- if meth && (map[meth] || meth !~ /^\-/)
- args.shift
- else
- nil
- end
+ args.shift if meth && (map[meth] || meth !~ /^\-/)
end
alias_method :retrieve_task_name, :retrieve_command_name
@@ -421,20 +428,20 @@ class Thor # rubocop:disable ClassLength
# +normalize_command_name+ also converts names like +animal-prison+
# into +animal_prison+.
def normalize_command_name(meth) #:nodoc:
- return default_command.to_s.gsub("-", "_") unless meth
+ return default_command.to_s.tr("-", "_") unless meth
possibilities = find_command_possibilities(meth)
- if possibilities.size > 1
- fail AmbiguousTaskError, "Ambiguous command #{meth} matches [#{possibilities.join(', ')}]"
- elsif possibilities.size < 1
- meth = meth || default_command
+ raise AmbiguousTaskError, "Ambiguous command #{meth} matches [#{possibilities.join(', ')}]" if possibilities.size > 1
+
+ if possibilities.empty?
+ meth ||= default_command
elsif map[meth]
meth = map[meth]
else
meth = possibilities.first
end
- meth.to_s.gsub("-", "_") # treat foo-bar as foo_bar
+ meth.to_s.tr("-", "_") # treat foo-bar as foo_bar
end
alias_method :normalize_task_name, :normalize_command_name
@@ -470,6 +477,7 @@ class Thor # rubocop:disable ClassLength
map HELP_MAPPINGS => :help
desc "help [COMMAND]", "Describe available commands or one specific command"
+ disable_class_options
def help(command = nil, subcommand = false)
if command
if self.class.subcommands.include? command
diff --git a/lib/thor/actions.rb b/lib/thor/actions.rb
index b08046b..0a6f55d 100644
--- a/lib/thor/actions.rb
+++ b/lib/thor/actions.rb
@@ -73,14 +73,15 @@ class Thor
#
def initialize(args = [], options = {}, config = {})
self.behavior = case config[:behavior].to_s
- when "force", "skip"
- _cleanup_options_and_set(options, config[:behavior])
- :invoke
- when "revoke"
- :revoke
- else
- :invoke
- end
+ when "force", "skip"
+ _cleanup_options_and_set(options, config[:behavior])
+ :invoke
+ when "revoke"
+ :revoke
+ else
+ :invoke
+ end
+
super
self.destination_root = config[:destination_root]
end
@@ -129,7 +130,7 @@ class Thor
# Receives a file or directory and search for it in the source paths.
#
- def find_in_source_paths(file) # rubocop:disable MethodLength
+ def find_in_source_paths(file)
possible_files = [file, file + TEMPLATE_EXTNAME]
relative_root = relative_to_original_destination_root(destination_root, false)
@@ -146,13 +147,13 @@ class Thor
message << "Please invoke #{self.class.name}.source_root(PATH) with the PATH containing your templates. "
end
- if source_paths.empty?
- message << "Currently you have no source paths."
- else
- message << "Your current source paths are: \n#{source_paths.join("\n")}"
- end
+ message << if source_paths.empty?
+ "Currently you have no source paths."
+ else
+ "Your current source paths are: \n#{source_paths.join("\n")}"
+ end
- fail Error, message
+ raise Error, message
end
# Do something in the root or on a provided subfolder. If a relative path
@@ -214,10 +215,10 @@ class Thor
say_status :apply, path, verbose
shell.padding += 1 if verbose
- if is_uri
- contents = open(path, "Accept" => "application/x-thor-template") { |io| io.read }
+ contents = if is_uri
+ open(path, "Accept" => "application/x-thor-template", &:read)
else
- contents = open(path) { |io| io.read }
+ open(path, &:read)
end
instance_eval(contents, path)
@@ -250,9 +251,7 @@ class Thor
say_status :run, desc, config.fetch(:verbose, true)
- unless options[:pretend]
- config[:capture] ? `#{command}` : system("#{command}")
- end
+ !options[:pretend] && config[:capture] ? `#{command}` : system(command.to_s)
end
# Executes a ruby script (taking into account WIN32 platform quirks).
@@ -308,7 +307,7 @@ class Thor
def _cleanup_options_and_set(options, key) #:nodoc:
case options
when Array
- %w[--force -f --skip -s].each { |i| options.delete(i) }
+ %w(--force -f --skip -s).each { |i| options.delete(i) }
options << "--#{key}"
when Hash
[:force, :skip, "force", "skip"].each { |i| options.delete(i) }
diff --git a/lib/thor/actions/create_file.rb b/lib/thor/actions/create_file.rb
index fcea392..483706d 100644
--- a/lib/thor/actions/create_file.rb
+++ b/lib/thor/actions/create_file.rb
@@ -84,7 +84,7 @@ class Thor
def force_or_skip_or_conflict(force, skip, &block)
if force
say_status :force, :yellow
- block.call unless pretend?
+ yield unless pretend?
elsif skip
say_status :skip, :yellow
else
diff --git a/lib/thor/actions/create_link.rb b/lib/thor/actions/create_link.rb
index db2c2a8..120fcfc 100644
--- a/lib/thor/actions/create_link.rb
+++ b/lib/thor/actions/create_link.rb
@@ -14,7 +14,7 @@ class Thor
#
# create_link "config/apache.conf", "/etc/apache.conf"
#
- def create_link(destination, *args, &block)
+ def create_link(destination, *args)
config = args.last.is_a?(Hash) ? args.pop : {}
source = args.first
action CreateLink.new(self, destination, source, config)
diff --git a/lib/thor/actions/directory.rb b/lib/thor/actions/directory.rb
index 9c44cfb..3e98f62 100644
--- a/lib/thor/actions/directory.rb
+++ b/lib/thor/actions/directory.rb
@@ -72,7 +72,7 @@ class Thor
protected
- def execute! # rubocop:disable MethodLength
+ def execute!
lookup = Util.escape_globs(source)
lookup = config[:recursive] ? File.join(lookup, "**") : lookup
lookup = file_level_lookup(lookup)
@@ -85,7 +85,7 @@ class Thor
case file_source
when /\.empty_directory$/
- dirname = File.dirname(file_destination).gsub(/\/\.$/, "")
+ dirname = File.dirname(file_destination).gsub(%r{/\.$}, "")
next if dirname == given_destination
base.empty_directory(dirname, config)
when /#{TEMPLATE_EXTNAME}$/
diff --git a/lib/thor/actions/empty_directory.rb b/lib/thor/actions/empty_directory.rb
index 281d8fb..2e544a1 100644
--- a/lib/thor/actions/empty_directory.rb
+++ b/lib/thor/actions/empty_directory.rb
@@ -32,7 +32,8 @@ class Thor
# config<Hash>:: give :verbose => false to not log the status.
#
def initialize(base, destination, config = {})
- @base, @config = base, {:verbose => true}.merge(config)
+ @base = base
+ @config = {:verbose => true}.merge(config)
self.destination = destination
end
@@ -80,11 +81,10 @@ class Thor
# given_destination #=> baz
#
def destination=(destination)
- if destination
- @given_destination = convert_encoded_instructions(destination.to_s)
- @destination = ::File.expand_path(@given_destination, base.destination_root)
- @relative_destination = base.relative_to_original_destination_root(@destination)
- end
+ return unless destination
+ @given_destination = convert_encoded_instructions(destination.to_s)
+ @destination = ::File.expand_path(@given_destination, base.destination_root)
+ @relative_destination = base.relative_to_original_destination_root(@destination)
end
# Filenames in the encoded form are converted. If you have a file:
@@ -113,7 +113,7 @@ class Thor
on_conflict_behavior(&block)
else
say_status :create, :green
- block.call unless pretend?
+ yield unless pretend?
end
destination
@@ -121,7 +121,7 @@ class Thor
# What to do when the destination file already exists.
#
- def on_conflict_behavior(&block)
+ def on_conflict_behavior
say_status :exist, :blue
end
diff --git a/lib/thor/actions/file_manipulation.rb b/lib/thor/actions/file_manipulation.rb
index 01f6d98..c4a93d5 100644
--- a/lib/thor/actions/file_manipulation.rb
+++ b/lib/thor/actions/file_manipulation.rb
@@ -26,7 +26,7 @@ class Thor
create_file destination, nil, config do
content = File.binread(source)
- content = block.call(content) if block
+ content = yield(content) if block
content
end
if config[:mode] == :preserve
@@ -49,7 +49,7 @@ class Thor
#
# link_file "doc/README"
#
- def link_file(source, *args, &block)
+ def link_file(source, *args)
config = args.last.is_a?(Hash) ? args.pop : {}
destination = args.first || source
source = File.expand_path(find_in_source_paths(source.to_s))
@@ -82,7 +82,7 @@ class Thor
render = open(source) { |input| input.binmode.read }
destination ||= if block_given?
- block.arity == 1 ? block.call(render) : block.call
+ block.arity == 1 ? yield(render) : yield
else
File.basename(source)
end
@@ -110,11 +110,11 @@ class Thor
destination = args.first || source.sub(/#{TEMPLATE_EXTNAME}$/, "")
source = File.expand_path(find_in_source_paths(source.to_s))
- context = instance_eval("binding")
+ context = config.delete(:context) || instance_eval("binding")
create_file destination, nil, config do
- content = ERB.new(::File.binread(source), nil, "-", "@output_buffer").result(context)
- content = block.call(content) if block
+ content = CapturableERB.new(::File.binread(source), nil, "-", "@output_buffer").result(context)
+ content = yield(content) if block
content
end
end
@@ -154,7 +154,7 @@ class Thor
#
def prepend_to_file(path, *args, &block)
config = args.last.is_a?(Hash) ? args.pop : {}
- config.merge!(:after => /\A/)
+ config[:after] = /\A/
insert_into_file(path, *(args << config), &block)
end
alias_method :prepend_file, :prepend_to_file
@@ -176,7 +176,7 @@ class Thor
#
def append_to_file(path, *args, &block)
config = args.last.is_a?(Hash) ? args.pop : {}
- config.merge!(:before => /\z/)
+ config[:before] = /\z/
insert_into_file(path, *(args << config), &block)
end
alias_method :append_file, :append_to_file
@@ -200,7 +200,7 @@ class Thor
#
def inject_into_class(path, klass, *args, &block)
config = args.last.is_a?(Hash) ? args.pop : {}
- config.merge!(:after => /class #{klass}\n|class #{klass} .*\n/)
+ config[:after] = /class #{klass}\n|class #{klass} .*\n/
insert_into_file(path, *(args << config), &block)
end
@@ -285,7 +285,7 @@ class Thor
#
def remove_file(path, config = {})
return unless behavior == :invoke
- path = File.expand_path(path, destination_root)
+ path = File.expand_path(path, destination_root)
say_status :remove, relative_to_original_destination_root(path), config.fetch(:verbose, true)
::FileUtils.rm_rf(path) if !options[:pretend] && File.exist?(path)
@@ -301,8 +301,8 @@ class Thor
@output_buffer.concat(string)
end
- def capture(*args, &block)
- with_output_buffer { block.call(*args) }
+ def capture(*args)
+ with_output_buffer { yield(*args) }
end
def with_output_buffer(buf = "") #:nodoc:
@@ -312,5 +312,16 @@ class Thor
ensure
self.output_buffer = old_buffer
end
+
+ # Thor::Actions#capture depends on what kind of buffer is used in ERB.
+ # Thus CapturableERB fixes ERB to use String buffer.
+ class CapturableERB < ERB
+ def set_eoutvar(compiler, eoutvar = "_erbout")
+ compiler.put_cmd = "#{eoutvar}.concat"
+ compiler.insert_cmd = "#{eoutvar}.concat"
+ compiler.pre_cmd = ["#{eoutvar} = ''"]
+ compiler.post_cmd = [eoutvar]
+ end
+ end
end
end
diff --git a/lib/thor/actions/inject_into_file.rb b/lib/thor/actions/inject_into_file.rb
index d617efb..20315ed 100644
--- a/lib/thor/actions/inject_into_file.rb
+++ b/lib/thor/actions/inject_into_file.rb
@@ -22,11 +22,8 @@ class Thor
# end
#
def insert_into_file(destination, *args, &block)
- if block_given?
- data, config = block, args.shift
- else
- data, config = args.shift, args.shift
- end
+ data = block_given? ? block : args.shift
+ config = args.shift
action InjectIntoFile.new(self, destination, data, config)
end
alias_method :inject_into_file, :insert_into_file
@@ -39,9 +36,9 @@ class Thor
@behavior, @flag = if @config.key?(:after)
[:after, @config.delete(:after)]
- else
- [:before, @config.delete(:before)]
- end
+ else
+ [:before, @config.delete(:before)]
+ end
@replacement = data.is_a?(Proc) ? data.call : data
@flag = Regexp.escape(@flag) unless @flag.is_a?(Regexp)
@@ -94,12 +91,11 @@ class Thor
# Adds the content to the file.
#
def replace!(regexp, string, force)
- unless base.options[:pretend]
- content = File.binread(destination)
- if force || !content.include?(replacement)
- content.gsub!(regexp, string)
- File.open(destination, "wb") { |file| file.write(content) }
- end
+ return if base.options[:pretend]
+ content = File.binread(destination)
+ if force || !content.include?(replacement)
+ content.gsub!(regexp, string)
+ File.open(destination, "wb") { |file| file.write(content) }
end
end
end
diff --git a/lib/thor/base.rb b/lib/thor/base.rb
index 4cfe514..6c04af0 100644
--- a/lib/thor/base.rb
+++ b/lib/thor/base.rb
@@ -14,11 +14,11 @@ class Thor
autoload :Group, "thor/group"
# Shortcuts for help.
- HELP_MAPPINGS = %w[-h -? --help -D]
+ HELP_MAPPINGS = %w(-h -? --help -D)
# Thor methods that should not be overwritten by the user.
- THOR_RESERVED_WORDS = %w[invoke shell options behavior root destination_root relative_root
- action add_file create_file in_root inside run run_ruby_script]
+ THOR_RESERVED_WORDS = %w(invoke shell options behavior root destination_root relative_root
+ action add_file create_file in_root inside run run_ruby_script)
TEMPLATE_EXTNAME = ".tt"
@@ -41,8 +41,8 @@ class Thor
#
# config<Hash>:: Configuration for this Thor class.
#
- def initialize(args = [], local_options = {}, config = {}) # rubocop:disable MethodLength
- parse_options = self.class.class_options
+ def initialize(args = [], local_options = {}, config = {})
+ parse_options = config[:current_command] && config[:current_command].disable_class_options ? {} : self.class.class_options
# The start method splits inbound arguments at the first argument
# that looks like an option (starts with - or --). It then calls
@@ -52,11 +52,13 @@ class Thor
command_options = config.delete(:command_options) # hook for start
parse_options = parse_options.merge(command_options) if command_options
if local_options.is_a?(Array)
- array_options, hash_options = local_options, {}
+ array_options = local_options
+ hash_options = {}
else
# Handle the case where the class was explicitly instantiated
# with pre-parsed options.
- array_options, hash_options = [], local_options
+ array_options = []
+ hash_options = local_options
end
# Let Thor::Options parse the options first, so it can remove
@@ -205,7 +207,7 @@ class Thor
# ==== Errors
# ArgumentError:: Raised if you supply a required argument after a non required one.
#
- def argument(name, options = {}) # rubocop:disable MethodLength
+ def argument(name, options = {})
is_thor_reserved_word?(name, :argument)
no_commands { attr_accessor name }
@@ -219,11 +221,13 @@ class Thor
remove_argument name
- arguments.each do |argument|
- next if argument.required?
- fail ArgumentError, "You cannot have #{name.to_s.inspect} as required argument after " <<
- "the non-required argument #{argument.human_name.inspect}."
- end if required
+ if required
+ arguments.each do |argument|
+ next if argument.required?
+ raise ArgumentError, "You cannot have #{name.to_s.inspect} as required argument after " \
+ "the non-required argument #{argument.human_name.inspect}."
+ end
+ end
options[:required] = required
@@ -343,7 +347,7 @@ class Thor
#
def all_commands
@all_commands ||= from_superclass(:all_commands, Thor::CoreExt::OrderedHash.new)
- @all_commands.merge(commands)
+ @all_commands.merge!(commands)
end
alias_method :all_tasks, :all_commands
@@ -467,11 +471,8 @@ class Thor
alias_method :public_task, :public_command
def handle_no_command_error(command, has_namespace = $thor_runner) #:nodoc:
- if has_namespace
- fail UndefinedCommandError, "Could not find command #{command.inspect} in #{namespace.inspect} namespace."
- else
- fail UndefinedCommandError, "Could not find command #{command.inspect}."
- end
+ raise UndefinedCommandError, "Could not find command #{command.inspect} in #{namespace.inspect} namespace." if has_namespace
+ raise UndefinedCommandError, "Could not find command #{command.inspect}."
end
alias_method :handle_no_task_error, :handle_no_command_error
@@ -480,7 +481,7 @@ class Thor
msg << "no arguments" if args.empty?
msg << "arguments " << args.inspect unless args.empty?
msg << "\nUsage: #{banner(command).inspect}"
- fail InvocationError, msg
+ raise InvocationError, msg
end
protected
@@ -513,14 +514,13 @@ class Thor
padding = options.map { |o| o.aliases.size }.max.to_i * 4
options.each do |option|
- unless option.hide
- item = [option.usage(padding)]
- item.push(option.description ? "# #{option.description}" : "")
+ next if option.hide
+ item = [option.usage(padding)]
+ item.push(option.description ? "# #{option.description}" : "")
- list << item
- list << ["", "# Default: #{option.default}"] if option.show_default?
- list << ["", "# Possible values: #{option.enum.join(', ')}"] if option.enum
- end
+ list << item
+ list << ["", "# Default: #{option.default}"] if option.show_default?
+ list << ["", "# Possible values: #{option.enum.join(', ')}"] if option.enum
end
shell.say(group_name ? "#{group_name} options:" : "Options:")
@@ -531,7 +531,7 @@ class Thor
# Raises an error if the word given is a Thor reserved word.
def is_thor_reserved_word?(word, type) #:nodoc:
return false unless THOR_RESERVED_WORDS.include?(word.to_s)
- fail "#{word.inspect} is a Thor reserved word and cannot be defined as #{type}"
+ raise "#{word.inspect} is a Thor reserved word and cannot be defined as #{type}"
end
# Build an option and adds it to the given scope.
@@ -566,7 +566,7 @@ class Thor
elsif command = all_commands[name.to_s] # rubocop:disable AssignmentInCondition
commands[name.to_s] = command.clone
else
- fail ArgumentError, "You supplied :for => #{name.inspect}, but the command #{name.inspect} could not be found."
+ raise ArgumentError, "You supplied :for => #{name.inspect}, but the command #{name.inspect} could not be found."
end
end
alias_method :find_and_refresh_task, :find_and_refresh_command
@@ -649,7 +649,7 @@ class Thor
# SIGNATURE: The hook invoked by start.
def dispatch(command, given_args, given_opts, config) #:nodoc:
- fail NotImplementedError
+ raise NotImplementedError
end
end
end
diff --git a/lib/thor/command.rb b/lib/thor/command.rb
index 71d1545..ceda591 100644
--- a/lib/thor/command.rb
+++ b/lib/thor/command.rb
@@ -1,9 +1,9 @@
class Thor
- class Command < Struct.new(:name, :description, :long_description, :usage, :options)
+ class Command < Struct.new(:name, :description, :long_description, :usage, :options, :disable_class_options)
FILE_REGEXP = /^#{Regexp.escape(File.dirname(__FILE__))}/
- def initialize(name, description, long_description, usage, options = nil)
- super(name.to_s, description, long_description, usage, options || {})
+ def initialize(name, description, long_description, usage, options = nil, disable_class_options = false)
+ super(name.to_s, description, long_description, usage, options || {}, disable_class_options)
end
def initialize_copy(other) #:nodoc:
@@ -33,7 +33,7 @@ class Thor
rescue ArgumentError => e
handle_argument_error?(instance, e, caller) ? instance.class.handle_argument_error(self, e, args, arity) : (raise e)
rescue NoMethodError => e
- handle_no_method_error?(instance, e, caller) ? instance.class.handle_no_command_error(name) : (fail e)
+ handle_no_method_error?(instance, e, caller) ? instance.class.handle_no_command_error(name) : (raise e)
end
# Returns the formatted usage by injecting given required arguments
@@ -50,7 +50,7 @@ class Thor
# Add usage with required arguments
formatted << if klass && !klass.arguments.empty?
usage.to_s.gsub(/^#{name}/) do |match|
- match << " " << klass.arguments.map { |a| a.usage }.compact.join(" ")
+ match << " " << klass.arguments.map(&:usage).compact.join(" ")
end
else
usage.to_s
@@ -88,7 +88,7 @@ class Thor
end
def sans_backtrace(backtrace, caller) #:nodoc:
- saned = backtrace.reject { |frame| frame =~ FILE_REGEXP || (frame =~ /\.java:/ && RUBY_PLATFORM =~ /java/) || (frame =~ /^kernel\// && RUBY_ENGINE =~ /rbx/) }
+ saned = backtrace.reject { |frame| frame =~ FILE_REGEXP || (frame =~ /\.java:/ && RUBY_PLATFORM =~ /java/) || (frame =~ %r{^kernel/} && RUBY_ENGINE =~ /rbx/) }
saned - caller
end
@@ -105,7 +105,7 @@ class Thor
error.message =~ /^undefined method `#{name}' for #{Regexp.escape(instance.to_s)}$/
end
end
- Task = Command # rubocop:disable ConstantName
+ Task = Command
# A command that is hidden in help messages but still invocable.
class HiddenCommand < Command
@@ -113,7 +113,7 @@ class Thor
true
end
end
- HiddenTask = HiddenCommand # rubocop:disable ConstantName
+ HiddenTask = HiddenCommand
# A dynamic command that handles method missing scenarios.
class DynamicCommand < Command
@@ -129,5 +129,5 @@ class Thor
end
end
end
- DynamicTask = DynamicCommand # rubocop:disable ConstantName
+ DynamicTask = DynamicCommand
end
diff --git a/lib/thor/core_ext/hash_with_indifferent_access.rb b/lib/thor/core_ext/hash_with_indifferent_access.rb
index 35dbf07..66f6241 100644
--- a/lib/thor/core_ext/hash_with_indifferent_access.rb
+++ b/lib/thor/core_ext/hash_with_indifferent_access.rb
@@ -28,6 +28,14 @@ class Thor
super(convert_key(key))
end
+ def fetch(key, *args)
+ super(convert_key(key), *args)
+ end
+
+ def key?(key)
+ super(convert_key(key))
+ end
+
def values_at(*indices)
indices.map { |key| self[convert_key(key)] }
end
@@ -60,7 +68,7 @@ class Thor
# options.shebang # => "/usr/lib/local/ruby"
# options.test_framework?(:rspec) # => options[:test_framework] == :rspec
#
- def method_missing(method, *args, &block)
+ def method_missing(method, *args)
method = method.to_s
if method =~ /^(\w+)\?$/
if args.empty?
diff --git a/lib/thor/core_ext/io_binary_read.rb b/lib/thor/core_ext/io_binary_read.rb
index 19f3c3d..0f6e2e0 100644
--- a/lib/thor/core_ext/io_binary_read.rb
+++ b/lib/thor/core_ext/io_binary_read.rb
@@ -1,10 +1,12 @@
class IO #:nodoc:
class << self
- def binread(file, *args)
- fail ArgumentError, "wrong number of arguments (#{1 + args.size} for 1..3)" unless args.size < 3
- File.open(file, "rb") do |f|
- f.read(*args)
+ unless method_defined? :binread
+ def binread(file, *args)
+ raise ArgumentError, "wrong number of arguments (#{1 + args.size} for 1..3)" unless args.size < 3
+ File.open(file, "rb") do |f|
+ f.read(*args)
+ end
end
- end unless method_defined? :binread
+ end
end
end
diff --git a/lib/thor/core_ext/ordered_hash.rb b/lib/thor/core_ext/ordered_hash.rb
index d3b2bc9..778772f 100644
--- a/lib/thor/core_ext/ordered_hash.rb
+++ b/lib/thor/core_ext/ordered_hash.rb
@@ -1,96 +1,127 @@
class Thor
- module CoreExt #:nodoc:
- if RUBY_VERSION >= "1.9"
- class OrderedHash < ::Hash
- end
- else
- # This class is based on the Ruby 1.9 ordered hashes.
- #
- # It keeps the semantics and most of the efficiency of normal hashes
- # while also keeping track of the order in which elements were set.
- #
- class OrderedHash #:nodoc:
- include Enumerable
-
- Node = Struct.new(:key, :value, :next, :prev)
-
- def initialize
- @hash = {}
+ module CoreExt
+ class OrderedHash < ::Hash
+ if RUBY_VERSION < "1.9"
+ def initialize(*args, &block)
+ super
+ @keys = []
end
- def [](key)
- @hash[key] && @hash[key].value
+ def initialize_copy(other)
+ super
+ # make a deep copy of keys
+ @keys = other.keys
end
def []=(key, value)
- if node = @hash[key] # rubocop:disable AssignmentInCondition
- node.value = value
- else
- node = Node.new(key, value)
-
- if !defined?(@first) || @first.nil?
- @first = @last = node
- else
- node.prev = @last
- @last.next = node
- @last = node
- end
- end
-
- @hash[key] = node
- value
+ @keys << key unless key?(key)
+ super
end
def delete(key)
- if node = @hash[key] # rubocop:disable AssignmentInCondition
- prev_node = node.prev
- next_node = node.next
+ if key? key
+ index = @keys.index(key)
+ @keys.delete_at index
+ end
+ super
+ end
- next_node.prev = prev_node if next_node
- prev_node.next = next_node if prev_node
+ def delete_if
+ super
+ sync_keys!
+ self
+ end
- @first = next_node if @first == node
- @last = prev_node if @last == node
+ alias_method :reject!, :delete_if
- value = node.value
- end
-
- @hash.delete(key)
- value
+ def reject(&block)
+ dup.reject!(&block)
end
def keys
- map { |k, v| k }
+ @keys.dup
end
def values
- map { |k, v| v }
+ @keys.map { |key| self[key] }
+ end
+
+ def to_hash
+ self
+ end
+
+ def to_a
+ @keys.map { |key| [key, self[key]] }
+ end
+
+ def each_key
+ return to_enum(:each_key) unless block_given?
+ @keys.each { |key| yield(key) }
+ self
+ end
+
+ def each_value
+ return to_enum(:each_value) unless block_given?
+ @keys.each { |key| yield(self[key]) }
+ self
end
def each
- return unless defined?(@first) && @first
- yield [@first.key, @first.value]
- node = @first
- yield [node.key, node.value] while node = node.next # rubocop:disable AssignmentInCondition
+ return to_enum(:each) unless block_given?
+ @keys.each { |key| yield([key, self[key]]) }
self
end
- def merge(other)
- hash = self.class.new
+ def each_pair
+ return to_enum(:each_pair) unless block_given?
+ @keys.each { |key| yield(key, self[key]) }
+ self
+ end
- each do |key, value|
- hash[key] = value
- end
+ alias_method :select, :find_all
+
+ def clear
+ super
+ @keys.clear
+ self
+ end
+
+ def shift
+ k = @keys.first
+ v = delete(k)
+ [k, v]
+ end
- other.each do |key, value|
- hash[key] = value
+ def merge!(other_hash)
+ if block_given?
+ other_hash.each { |k, v| self[k] = key?(k) ? yield(k, self[k], v) : v }
+ else
+ other_hash.each { |k, v| self[k] = v }
end
+ self
+ end
+
+ alias_method :update, :merge!
+
+ def merge(other_hash, &block)
+ dup.merge!(other_hash, &block)
+ end
- hash
+ # When replacing with another hash, the initial order of our keys must come from the other hash -ordered or not.
+ def replace(other)
+ super
+ @keys = other.keys
+ self
end
- def empty?
- @hash.empty?
+ def inspect
+ "#<#{self.class} #{super}>"
+ end
+
+ private
+
+ def sync_keys!
+ @keys.delete_if { |k| !key?(k) }
end
end
end
diff --git a/lib/thor/error.rb b/lib/thor/error.rb
index c53be49..9910bfb 100644
--- a/lib/thor/error.rb
+++ b/lib/thor/error.rb
@@ -3,7 +3,7 @@ class Thor
# errors have their backtrace suppressed and are nicely shown to the user.
#
# Errors that are caused by the developer, like declaring a method which
- # overwrites a thor keyword, it SHOULD NOT raise a Thor::Error. This way, we
+ # overwrites a thor keyword, SHOULD NOT raise a Thor::Error. This way, we
# ensure that developer errors are shown with full backtrace.
class Error < StandardError
end
@@ -11,11 +11,11 @@ class Thor
# Raised when a command was not found.
class UndefinedCommandError < Error
end
- UndefinedTaskError = UndefinedCommandError # rubocop:disable ConstantName
+ UndefinedTaskError = UndefinedCommandError
class AmbiguousCommandError < Error
end
- AmbiguousTaskError = AmbiguousCommandError # rubocop:disable ConstantName
+ AmbiguousTaskError = AmbiguousCommandError
# Raised when a command was found, but not invoked properly.
class InvocationError < Error
diff --git a/lib/thor/group.rb b/lib/thor/group.rb
index c4ee890..dd43547 100644
--- a/lib/thor/group.rb
+++ b/lib/thor/group.rb
@@ -4,7 +4,7 @@ require "thor/base"
# is that it invokes all commands at once. It also include some methods that allows
# invocations to be done at the class method, which are not available to Thor
# commands.
-class Thor::Group # rubocop:disable ClassLength
+class Thor::Group
class << self
# The description for this Thor::Group. If none is provided, but a source root
# exists, tries to find the USAGE one folder above it, otherwise searches
@@ -53,7 +53,7 @@ class Thor::Group # rubocop:disable ClassLength
# The namespace/class given will have its options showed on the help
# usage. Check invoke_from_option for more information.
#
- def invoke(*names, &block) # rubocop:disable MethodLength
+ def invoke(*names, &block)
options = names.last.is_a?(Hash) ? names.pop : {}
verbose = options.fetch(:verbose, true)
@@ -62,7 +62,7 @@ class Thor::Group # rubocop:disable ClassLength
invocation_blocks[name] = block if block_given?
class_eval <<-METHOD, __FILE__, __LINE__
- def _invoke_#{name.to_s.gsub(/\W/, "_")}
+ def _invoke_#{name.to_s.gsub(/\W/, '_')}
klass, command = self.class.prepare_for_invocation(nil, #{name.inspect})
if klass
@@ -107,21 +107,21 @@ class Thor::Group # rubocop:disable ClassLength
# invoked. The block receives two parameters, an instance of the current
# class and the klass to be invoked.
#
- def invoke_from_option(*names, &block) # rubocop:disable MethodLength
+ def invoke_from_option(*names, &block)
options = names.last.is_a?(Hash) ? names.pop : {}
verbose = options.fetch(:verbose, :white)
names.each do |name|
unless class_options.key?(name)
- fail ArgumentError, "You have to define the option #{name.inspect} " <<
- "before setting invoke_from_option."
+ raise ArgumentError, "You have to define the option #{name.inspect} " \
+ "before setting invoke_from_option."
end
invocations[name] = true
invocation_blocks[name] = block if block_given?
class_eval <<-METHOD, __FILE__, __LINE__
- def _invoke_from_option_#{name.to_s.gsub(/\W/, "_")}
+ def _invoke_from_option_#{name.to_s.gsub(/\W/, '_')}
return unless options[#{name.inspect}]
value = options[#{name.inspect}]
@@ -188,7 +188,7 @@ class Thor::Group # rubocop:disable ClassLength
group_options[human_name] ||= []
group_options[human_name] += klass.class_options.values.select do |class_option|
base_options[class_option.name.to_sym].nil? && class_option.group.nil? &&
- !group_options.values.flatten.any? { |i| i.name == class_option.name }
+ !group_options.values.flatten.any? { |i| i.name == class_option.name }
end
yield klass if block_given?
@@ -204,11 +204,11 @@ class Thor::Group # rubocop:disable ClassLength
end
alias_method :printable_tasks, :printable_commands
- def handle_argument_error(command, error, args, arity) #:nodoc:
+ def handle_argument_error(command, error, _args, arity) #:nodoc:
msg = "#{basename} #{command.name} takes #{arity} argument"
msg << "s" if arity > 1
msg << ", but it should not."
- fail error, msg
+ raise error, msg
end
protected
@@ -267,9 +267,9 @@ protected
if block
case block.arity
when 3
- block.call(self, klass, command)
+ yield(self, klass, command)
when 2
- block.call(self, klass)
+ yield(self, klass)
when 1
instance_exec(klass, &block)
end
diff --git a/lib/thor/invocation.rb b/lib/thor/invocation.rb
index 108c704..b111409 100644
--- a/lib/thor/invocation.rb
+++ b/lib/thor/invocation.rb
@@ -108,8 +108,8 @@ class Thor
command, args, opts, config = args
klass, command = _retrieve_class_and_command(name, command)
- fail "Missing Thor class for invoke #{name}" unless klass
- fail "Expected Thor class, got #{klass}" unless klass <= Thor::Base
+ raise "Missing Thor class for invoke #{name}" unless klass
+ raise "Expected Thor class, got #{klass}" unless klass <= Thor::Base
args, opts, config = _parse_initialization_options(args, opts, config)
klass.send(:dispatch, command, args, opts, config) do |instance|
@@ -150,10 +150,9 @@ class Thor
# use the given name and return self as class. Otherwise, call
# prepare_for_invocation in the current class.
def _retrieve_class_and_command(name, sent_command = nil) #:nodoc:
- case
- when name.nil?
+ if name.nil?
[self.class, nil]
- when self.class.all_commands[name.to_s]
+ elsif self.class.all_commands[name.to_s]
[self.class, name.to_s]
else
klass, command = self.class.prepare_for_invocation(nil, name)
diff --git a/lib/thor/parser/argument.rb b/lib/thor/parser/argument.rb
index 96f0eff..7b628ef 100644
--- a/lib/thor/parser/argument.rb
+++ b/lib/thor/parser/argument.rb
@@ -10,8 +10,8 @@ class Thor
type = options[:type]
- fail ArgumentError, "#{class_name} name can't be nil." if name.nil?
- fail ArgumentError, "Type :#{type} is not valid for #{class_name.downcase}s." if type && !valid_type?(type)
+ raise ArgumentError, "#{class_name} name can't be nil." if name.nil?
+ raise ArgumentError, "Type :#{type} is not valid for #{class_name.downcase}s." if type && !valid_type?(type)
@name = name.to_s
@description = options[:desc]
@@ -44,11 +44,8 @@ class Thor
protected
def validate!
- if required? && !default.nil?
- fail ArgumentError, "An argument cannot be required and have default value."
- elsif @enum && !@enum.is_a?(Array)
- fail ArgumentError, "An argument cannot have an enum other than an array."
- end
+ raise ArgumentError, "An argument cannot be required and have default value." if required? && !default.nil?
+ raise ArgumentError, "An argument cannot have an enum other than an array." if @enum && !@enum.is_a?(Array)
end
def valid_type?(type)
diff --git a/lib/thor/parser/arguments.rb b/lib/thor/parser/arguments.rb
index 8e9e973..522f1f8 100644
--- a/lib/thor/parser/arguments.rb
+++ b/lib/thor/parser/arguments.rb
@@ -1,6 +1,6 @@
class Thor
class Arguments #:nodoc: # rubocop:disable ClassLength
- NUMERIC = /(\d*\.\d+|\d+)/
+ NUMERIC = /[-+]?(\d*\.\d+|\d+)/
# Receives an array of args and returns two arrays, one with arguments
# and one with switches.
@@ -24,7 +24,8 @@ class Thor
# Takes an array of Thor::Argument objects.
#
def initialize(arguments = [])
- @assigns, @non_assigned_required = {}, []
+ @assigns = {}
+ @non_assigned_required = []
@switches = arguments
arguments.each do |argument|
@@ -49,7 +50,7 @@ class Thor
@assigns
end
- def remaining # rubocop:disable TrivialAccessors
+ def remaining
@pile
end
@@ -73,7 +74,7 @@ class Thor
end
def unshift(arg)
- if arg.kind_of?(Array)
+ if arg.is_a?(Array)
@pile = arg + @pile
else
@pile.unshift(arg)
@@ -99,6 +100,7 @@ class Thor
while current_is_value? && peek.include?(":")
key, value = shift.split(":", 2)
+ raise MalformattedArgumentError, "You can't specify '#{key}' more than once in option '#{name}'; got #{key}:#{hash[key]} and #{key}:#{value}" if hash.include? key
hash[key] = value
end
hash
@@ -128,13 +130,13 @@ class Thor
return shift if peek.is_a?(Numeric)
unless peek =~ NUMERIC && $& == peek
- fail MalformattedArgumentError, "Expected numeric value for '#{name}'; got #{peek.inspect}"
+ raise MalformattedArgumentError, "Expected numeric value for '#{name}'; got #{peek.inspect}"
end
value = $&.index(".") ? shift.to_f : shift.to_i
if @switches.is_a?(Hash) && switch = @switches[name]
if switch.enum && !switch.enum.include?(value)
- fail MalformattedArgumentError, "Expected '#{name}' to be one of #{switch.enum.join(', ')}; got #{value}"
+ raise MalformattedArgumentError, "Expected '#{name}' to be one of #{switch.enum.join(', ')}; got #{value}"
end
end
value
@@ -150,9 +152,9 @@ class Thor
nil
else
value = shift
- if @switches.is_a?(Hash) && switch = @switches[name] # rubocop:disable AssignmentInCondition
+ if @switches.is_a?(Hash) && switch = @switches[name]
if switch.enum && !switch.enum.include?(value)
- fail MalformattedArgumentError, "Expected '#{name}' to be one of #{switch.enum.join(', ')}; got #{value}"
+ raise MalformattedArgumentError, "Expected '#{name}' to be one of #{switch.enum.join(', ')}; got #{value}"
end
end
value
@@ -162,14 +164,12 @@ class Thor
# Raises an error if @non_assigned_required array is not empty.
#
def check_requirement!
- unless @non_assigned_required.empty?
- names = @non_assigned_required.map do |o|
- o.respond_to?(:switch_name) ? o.switch_name : o.human_name
- end.join("', '")
-
- class_name = self.class.name.split("::").last.downcase
- fail RequiredArgumentMissingError, "No value provided for required #{class_name} '#{names}'"
- end
+ return if @non_assigned_required.empty?
+ names = @non_assigned_required.map do |o|
+ o.respond_to?(:switch_name) ? o.switch_name : o.human_name
+ end.join("', '")
+ class_name = self.class.name.split("::").last.downcase
+ raise RequiredArgumentMissingError, "No value provided for required #{class_name} '#{names}'"
end
end
end
diff --git a/lib/thor/parser/option.rb b/lib/thor/parser/option.rb
index 9099a3d..fa9bcf9 100644
--- a/lib/thor/parser/option.rb
+++ b/lib/thor/parser/option.rb
@@ -40,31 +40,33 @@ class Thor
#
# By default all options are optional, unless :required is given.
#
- def self.parse(key, value) # rubocop:disable MethodLength
+ def self.parse(key, value)
if key.is_a?(Array)
name, *aliases = key
else
- name, aliases = key, []
+ name = key
+ aliases = []
end
name = name.to_s
default = value
type = case value
- when Symbol
- default = nil
- if VALID_TYPES.include?(value)
- value
- elsif required = (value == :required) # rubocop:disable AssignmentInCondition
- :string
- end
- when TrueClass, FalseClass
- :boolean
- when Numeric
- :numeric
- when Hash, Array, String
- value.class.name.downcase.to_sym
- end
+ when Symbol
+ default = nil
+ if VALID_TYPES.include?(value)
+ value
+ elsif required = (value == :required) # rubocop:disable AssignmentInCondition
+ :string
+ end
+ when TrueClass, FalseClass
+ :boolean
+ when Numeric
+ :numeric
+ when Hash, Array, String
+ value.class.name.downcase.to_sym
+ end
+
new(name.to_s, :required => required, :type => type, :default => default, :aliases => aliases)
end
@@ -86,7 +88,7 @@ class Thor
sample = "[#{sample}]" unless required?
if boolean?
- sample << ", [#{dasherize("no-" + human_name)}]" unless name == "force"
+ sample << ", [#{dasherize('no-' + human_name)}]" unless (name == "force") || name.start_with?("no-")
end
if aliases.empty?
@@ -107,7 +109,26 @@ class Thor
protected
def validate!
- fail ArgumentError, "An option cannot be boolean and required." if boolean? && required?
+ raise ArgumentError, "An option cannot be boolean and required." if boolean? && required?
+ validate_default_type!
+ end
+
+ def validate_default_type!
+ default_type = case @default
+ when nil
+ return
+ when TrueClass, FalseClass
+ required? ? :string : :boolean
+ when Numeric
+ :numeric
+ when Symbol
+ :string
+ when Hash, Array, String
+ @default.class.name.downcase.to_sym
+ end
+
+ # TODO: This should raise an ArgumentError in a future version of Thor
+ warn "Expected #{@type} default value for '#{switch_name}'; got #{@default.inspect} (#{default_type})" unless default_type == @type
end
def dasherized?
@@ -119,7 +140,7 @@ class Thor
end
def dasherize(str)
- (str.length > 1 ? "--" : "-") + str.gsub("_", "-")
+ (str.length > 1 ? "--" : "-") + str.tr("_", "-")
end
end
end
diff --git a/lib/thor/parser/options.rb b/lib/thor/parser/options.rb
index 6cfba11..188f416 100644
--- a/lib/thor/parser/options.rb
+++ b/lib/thor/parser/options.rb
@@ -14,7 +14,7 @@ class Thor
when true
"--#{key}"
when Array
- "--#{key} #{value.map { |v| v.inspect }.join(' ')}"
+ "--#{key} #{value.map(&:inspect).join(' ')}"
when Hash
"--#{key} #{value.map { |k, v| "#{k}:#{v}" }.join(' ')}"
when nil, false
@@ -40,7 +40,9 @@ class Thor
@non_assigned_required.delete(hash_options[key])
end
- @shorts, @switches, @extra = {}, {}, []
+ @shorts = {}
+ @switches = {}
+ @extra = []
options.each do |option|
@switches[option.switch_name] = option
@@ -52,7 +54,7 @@ class Thor
end
end
- def remaining # rubocop:disable TrivialAccessors
+ def remaining
@extra
end
@@ -119,7 +121,7 @@ class Thor
def check_unknown!
# an unknown option starts with - or -- and has no more --'s afterward.
unknown = @extra.select { |str| str =~ /^--?(?:(?!--).)*$/ }
- fail UnknownArgumentError, "Unknown switches '#{unknown.join(', ')}'" unless unknown.empty?
+ raise UnknownArgumentError, "Unknown switches '#{unknown.join(', ')}'" unless unknown.empty?
end
protected
@@ -207,7 +209,7 @@ class Thor
elsif option.lazy_default
return option.lazy_default
else
- fail MalformattedArgumentError, "No value provided for option '#{switch}'"
+ raise MalformattedArgumentError, "No value provided for option '#{switch}'"
end
end
diff --git a/lib/thor/runner.rb b/lib/thor/runner.rb
index 1d768a4..9f1aaaf 100644
--- a/lib/thor/runner.rb
+++ b/lib/thor/runner.rb
@@ -11,10 +11,18 @@ require "pathname"
class Thor::Runner < Thor #:nodoc: # rubocop:disable ClassLength
map "-T" => :list, "-i" => :install, "-u" => :update, "-v" => :version
+ def self.banner(command, all = false, subcommand = false)
+ "thor " + command.formatted_usage(self, all, subcommand)
+ end
+
+ def self.exit_on_failure?
+ true
+ end
+
# Override Thor#help so it can give information about any class and any method.
#
def help(meth = nil)
- if meth && !self.respond_to?(meth)
+ if meth && !respond_to?(meth)
initialize_thorfiles(meth)
klass, command = Thor::Util.find_class_and_command_by_namespace(meth)
self.class.handle_no_command_error(command, false) if klass.nil?
@@ -45,16 +53,18 @@ class Thor::Runner < Thor #:nodoc: # rubocop:disable ClassLength
# command in said directory.
begin
if File.directory?(File.expand_path(name))
- base, package = File.join(name, "main.thor"), :directory
- contents = open(base) { |input| input.read }
+ base = File.join(name, "main.thor")
+ package = :directory
+ contents = open(base, &:read)
else
- base, package = name, :file
- contents = open(name) { |input| input.read }
+ base = name
+ package = :file
+ contents = open(name, &:read)
end
rescue OpenURI::HTTPError
raise Error, "Error opening URI '#{name}'"
rescue Errno::ENOENT
- fail Error, "Error opening file '#{name}'"
+ raise Error, "Error opening file '#{name}'"
end
say "Your Thorfile contains:"
@@ -108,9 +118,9 @@ class Thor::Runner < Thor #:nodoc: # rubocop:disable ClassLength
desc "uninstall NAME", "Uninstall a named Thor module"
def uninstall(name)
- fail Error, "Can't find module '#{name}'" unless thor_yaml[name]
+ raise Error, "Can't find module '#{name}'" unless thor_yaml[name]
say "Uninstalling #{name}."
- FileUtils.rm_rf(File.join(thor_root, "#{thor_yaml[name][:filename]}"))
+ FileUtils.rm_rf(File.join(thor_root, (thor_yaml[name][:filename]).to_s))
thor_yaml.delete(name)
save_yaml(thor_yaml)
@@ -120,7 +130,7 @@ class Thor::Runner < Thor #:nodoc: # rubocop:disable ClassLength
desc "update NAME", "Update a Thor file from its original location"
def update(name)
- fail Error, "Can't find module '#{name}'" if !thor_yaml[name] || !thor_yaml[name][:location]
+ raise Error, "Can't find module '#{name}'" if !thor_yaml[name] || !thor_yaml[name][:location]
say "Updating '#{name}' from #{thor_yaml[name][:location]}"
@@ -138,9 +148,7 @@ class Thor::Runner < Thor #:nodoc: # rubocop:disable ClassLength
filename = install(thor_yaml[name][:location])
end
- unless filename == old_filename
- File.delete(File.join(thor_root, old_filename))
- end
+ File.delete(File.join(thor_root, old_filename)) unless filename == old_filename
end
desc "installed", "List the installed Thor modules and commands"
@@ -168,10 +176,6 @@ class Thor::Runner < Thor #:nodoc: # rubocop:disable ClassLength
private
- def self.banner(command, all = false, subcommand = false)
- "thor " + command.formatted_usage(self, all, subcommand)
- end
-
def thor_root
Thor::Util.thor_root
end
@@ -198,10 +202,6 @@ private
File.open(yaml_file, "w") { |f| f.puts yaml.to_yaml }
end
- def self.exit_on_failure?
- true
- end
-
# Load the Thorfiles. If relevant_to is supplied, looks for specific files
# in the thor_root instead of loading them all.
#
@@ -263,11 +263,11 @@ private
def thorfiles_relevant_to(meth)
lookup = [meth, meth.split(":")[0...-1].join(":")]
- files = thor_yaml.select do |k, v|
+ files = thor_yaml.select do |_, v|
v[:namespaces] && !(v[:namespaces] & lookup).empty?
end
- files.map { |k, v| File.join(thor_root, "#{v[:filename]}") }
+ files.map { |_, v| File.join(thor_root, (v[:filename]).to_s) }
end
# Display information about the given klasses. If with_module is given,
@@ -276,7 +276,7 @@ private
def display_klasses(with_modules = false, show_internal = false, klasses = Thor::Base.subclasses)
klasses -= [Thor, Thor::Runner, Thor::Group] unless show_internal
- fail Error, "No Thor commands available" if klasses.empty?
+ raise Error, "No Thor commands available" if klasses.empty?
show_modules if with_modules && !thor_yaml.empty?
list = Hash.new { |h, k| h[k] = [] }
@@ -306,8 +306,8 @@ private
alias_method :display_tasks, :display_commands
def show_modules #:nodoc:
- info = []
- labels = %w[Modules Namespaces]
+ info = []
+ labels = %w(Modules Namespaces)
info << labels
info << ["-" * labels[0].size, "-" * labels[1].size]
diff --git a/lib/thor/shell.rb b/lib/thor/shell.rb
index 707aac9..03eb7d1 100644
--- a/lib/thor/shell.rb
+++ b/lib/thor/shell.rb
@@ -9,7 +9,7 @@ class Thor
# it will use a colored log, otherwise it will use a basic one without color.
#
def shell
- @shell ||= if ENV["THOR_SHELL"] && ENV["THOR_SHELL"].size > 0
+ @shell ||= if ENV["THOR_SHELL"] && !ENV["THOR_SHELL"].empty?
Thor::Shell.const_get(ENV["THOR_SHELL"])
elsif RbConfig::CONFIG["host_os"] =~ /mswin|mingw/ && !ENV["ANSICON"]
Thor::Shell::Basic
diff --git a/lib/thor/shell/basic.rb b/lib/thor/shell/basic.rb
index 700b0eb..87d47f2 100644
--- a/lib/thor/shell/basic.rb
+++ b/lib/thor/shell/basic.rb
@@ -3,14 +3,17 @@ require "io/console" if RUBY_VERSION > "1.9.2"
class Thor
module Shell
- class Basic # rubocop:disable ClassLength
+ class Basic
attr_accessor :base
attr_reader :padding
# Initialize base, mute and padding to nil.
#
def initialize #:nodoc:
- @base, @mute, @padding, @always_force = nil, false, 0, false
+ @base = nil
+ @mute = false
+ @padding = 0
+ @always_force = false
end
# Mute everything that's inside given block
@@ -24,7 +27,7 @@ class Thor
# Check if base is muted
#
- def mute? # rubocop:disable TrivialAccessors
+ def mute?
@mute
end
@@ -34,6 +37,15 @@ class Thor
@padding = [0, value].max
end
+ # Sets the output padding while executing a block and resets it.
+ #
+ def indent(count = 1)
+ orig_padding = padding
+ self.padding = padding + count
+ yield
+ self.padding = orig_padding
+ end
+
# Asks something to the user and receives a response.
#
# If asked to limit the correct responses, you can pass in an
@@ -148,7 +160,9 @@ class Thor
def print_table(array, options = {}) # rubocop:disable MethodLength
return if array.empty?
- formats, indent, colwidth = [], options[:indent].to_i, options[:colwidth]
+ formats = []
+ indent = options[:indent].to_i
+ colwidth = options[:colwidth]
options[:truncate] = terminal_width if options[:truncate] == true
formats << "%-#{colwidth + 2}s" if colwidth
@@ -161,12 +175,12 @@ class Thor
start.upto(colcount - 1) do |index|
maxima = array.map { |row| row[index] ? row[index].to_s.size : 0 }.max
maximas << maxima
- if index == colcount - 1
- # Don't output 2 trailing spaces when printing the last column
- formats << "%-s"
- else
- formats << "%-#{maxima + 2}s"
- end
+ formats << if index == colcount - 1
+ # Don't output 2 trailing spaces when printing the last column
+ "%-s"
+ else
+ "%-#{maxima + 2}s"
+ end
end
formats[0] = formats[0].insert(0, " " * indent)
@@ -178,15 +192,15 @@ class Thor
row.each_with_index do |column, index|
maxima = maximas[index]
- if column.is_a?(Numeric)
+ f = if column.is_a?(Numeric)
if index == row.size - 1
# Don't output 2 trailing spaces when printing the last column
- f = "%#{maxima}s"
+ "%#{maxima}s"
else
- f = "%#{maxima}s "
+ "%#{maxima}s "
end
else
- f = formats[index]
+ formats[index]
end
sentence << f % column.to_s
end
@@ -211,7 +225,7 @@ class Thor
paras = message.split("\n\n")
paras.map! do |unwrapped|
- unwrapped.strip.gsub(/\n/, " ").squeeze(" ").gsub(/.{1,#{width}}(?:\s|\Z)/) { ($& + 5.chr).gsub(/\n\005/, "\n").gsub(/\005/, "\n") }
+ unwrapped.strip.tr("\n", " ").squeeze(" ").gsub(/.{1,#{width}}(?:\s|\Z)/) { ($& + 5.chr).gsub(/\n\005/, "\n").gsub(/\005/, "\n") }
end
paras.each do |para|
@@ -230,7 +244,7 @@ class Thor
# destination<String>:: the destination file to solve conflicts
# block<Proc>:: an optional block that returns the value to be used in diff
#
- def file_collision(destination) # rubocop:disable MethodLength
+ def file_collision(destination)
return true if @always_force
options = block_given? ? "[Ynaqdh]" : "[Ynaqh]"
@@ -249,7 +263,7 @@ class Thor
return @always_force = true
when is?(:quit)
say "Aborting..."
- fail SystemExit
+ raise SystemExit
when is?(:diff)
show_diff(destination, yield) if block_given?
say "Retrying..."
@@ -262,10 +276,10 @@ class Thor
# This code was copied from Rake, available under MIT-LICENSE
# Copyright (c) 2003, 2004 Jim Weirich
def terminal_width
- if ENV["THOR_COLUMNS"]
- result = ENV["THOR_COLUMNS"].to_i
+ result = if ENV["THOR_COLUMNS"]
+ ENV["THOR_COLUMNS"].to_i
else
- result = unix? ? dynamic_width : 80
+ unix? ? dynamic_width : 80
end
result < 10 ? 80 : result
rescue
@@ -284,7 +298,7 @@ class Thor
# Apply color to the given string with optional bold. Disabled in the
# Thor::Shell::Basic class.
#
- def set_color(string, *args) #:nodoc:
+ def set_color(string, *) #:nodoc:
string
end
@@ -353,11 +367,11 @@ class Thor
end
def dynamic_width_stty
- %x(stty size 2>/dev/null).split[1].to_i
+ `stty size 2>/dev/null`.split[1].to_i
end
def dynamic_width_tput
- %x(tput cols 2>/dev/null).to_i
+ `tput cols 2>/dev/null`.to_i
end
def unix?
@@ -370,7 +384,7 @@ class Thor
if chars.length <= width
chars.join
else
- ( chars[0, width - 3].join) + "..."
+ chars[0, width - 3].join + "..."
end
end
end
@@ -381,7 +395,8 @@ class Thor
end
else
def as_unicode
- old, $KCODE = $KCODE, "U"
+ old = $KCODE
+ $KCODE = "U"
yield
ensure
$KCODE = old
@@ -391,7 +406,7 @@ class Thor
def ask_simply(statement, color, options)
default = options[:default]
message = [statement, ("(#{default})" if default), nil].uniq.join(" ")
- message = prepare_message(message, color)
+ message = prepare_message(message, *color)
result = Thor::LineEditor.readline(message, options)
return unless result
diff --git a/lib/thor/shell/color.rb b/lib/thor/shell/color.rb
index 744a737..2a90d46 100644
--- a/lib/thor/shell/color.rb
+++ b/lib/thor/shell/color.rb
@@ -134,7 +134,7 @@ class Thor
# for diff.
#
def diff_lcs_loaded? #:nodoc:
- return true if defined?(Diff::LCS)
+ return true if defined?(Diff::LCS)
return @diff_lcs_loaded unless @diff_lcs_loaded.nil?
@diff_lcs_loaded = begin
diff --git a/lib/thor/shell/html.rb b/lib/thor/shell/html.rb
index 525f9a3..e393578 100644
--- a/lib/thor/shell/html.rb
+++ b/lib/thor/shell/html.rb
@@ -51,13 +51,13 @@ class Thor
def set_color(string, *colors)
if colors.all? { |color| color.is_a?(Symbol) || color.is_a?(String) }
html_colors = colors.map { |color| lookup_color(color) }
- "<span style=\"#{html_colors.join("; ")};\">#{string}</span>"
+ "<span style=\"#{html_colors.join('; ')};\">#{string}</span>"
else
color, bold = colors
html_color = self.class.const_get(color.to_s.upcase) if color.is_a?(Symbol)
styles = [html_color]
styles << BOLD if bold
- "<span style=\"#{styles.join("; ")};\">#{string}</span>"
+ "<span style=\"#{styles.join('; ')};\">#{string}</span>"
end
end
@@ -68,7 +68,7 @@ class Thor
#
# TODO: Implement #ask for Thor::Shell::HTML
def ask(statement, color = nil)
- fail NotImplementedError, "Implement #ask for Thor::Shell::HTML"
+ raise NotImplementedError, "Implement #ask for Thor::Shell::HTML"
end
protected
@@ -111,7 +111,7 @@ class Thor
# for diff.
#
def diff_lcs_loaded? #:nodoc:
- return true if defined?(Diff::LCS)
+ return true if defined?(Diff::LCS)
return @diff_lcs_loaded unless @diff_lcs_loaded.nil?
@diff_lcs_loaded = begin
diff --git a/lib/thor/util.rb b/lib/thor/util.rb
index f4ec83a..a48ed8e 100644
--- a/lib/thor/util.rb
+++ b/lib/thor/util.rb
@@ -64,7 +64,7 @@ class Thor
new_constants = Thor::Base.subclasses.dup
Thor::Base.subclasses.replace(old_constants)
- new_constants.map! { |c| c.namespace }
+ new_constants.map!(&:namespace)
new_constants.compact!
new_constants
end
@@ -72,7 +72,7 @@ class Thor
# Returns the thor classes declared inside the given class.
#
def thor_classes_in(klass)
- stringfied_constants = klass.constants.map { |c| c.to_s }
+ stringfied_constants = klass.constants.map(&:to_s)
Thor::Base.subclasses.select do |subclass|
next unless subclass.name
stringfied_constants.include?(subclass.name.gsub("#{klass.name}::", ""))
@@ -103,7 +103,7 @@ class Thor
#
def camel_case(str)
return str if str !~ /_/ && str =~ /[A-Z]+.*/
- str.split("_").map { |i| i.capitalize }.join
+ str.split("_").map(&:capitalize).join
end
# Receives a namespace and tries to retrieve a Thor or Thor::Group class
@@ -135,7 +135,8 @@ class Thor
klass = Thor::Util.find_by_namespace(pieces.join(":"))
end
unless klass # look for a Thor::Group with the right name
- klass, command = Thor::Util.find_by_namespace(namespace), nil
+ klass = Thor::Util.find_by_namespace(namespace)
+ command = nil
end
if !klass && fallback # try a command in the default namespace
command = namespace
@@ -163,7 +164,7 @@ class Thor
end
end
- def user_home # rubocop:disable MethodLength
+ def user_home
@@user_home ||= if ENV["HOME"]
ENV["HOME"]
elsif ENV["USERPROFILE"]
@@ -188,7 +189,7 @@ class Thor
# Returns the root where thor files are located, depending on the OS.
#
def thor_root
- File.join(user_home, ".thor").gsub(/\\/, "/")
+ File.join(user_home, ".thor").tr('\\', "/")
end
# Returns the files in the thor root. On Windows thor_root will be something
@@ -216,7 +217,7 @@ class Thor
# Return the path to the ruby interpreter taking into account multiple
# installations and windows extensions.
#
- def ruby_command # rubocop:disable MethodLength
+ def ruby_command
@ruby_command ||= begin
ruby_name = RbConfig::CONFIG["ruby_install_name"]
ruby = File.join(RbConfig::CONFIG["bindir"], ruby_name)
diff --git a/lib/thor/version.rb b/lib/thor/version.rb
index 1391ce4..e20f8c5 100644
--- a/lib/thor/version.rb
+++ b/lib/thor/version.rb
@@ -1,3 +1,3 @@
class Thor
- VERSION = "0.19.1"
+ VERSION = "0.19.4"
end
diff --git a/metadata.yml b/metadata.yml
deleted file mode 100644
index e48212a..0000000
--- a/metadata.yml
+++ /dev/null
@@ -1,240 +0,0 @@
---- !ruby/object:Gem::Specification
-name: thor
-version: !ruby/object:Gem::Version
- version: 0.19.1
-platform: ruby
-authors:
-- Yehuda Katz
-- José Valim
-autorequire:
-bindir: bin
-cert_chain: []
-date: 2014-03-24 00:00:00.000000000 Z
-dependencies:
-- !ruby/object:Gem::Dependency
- name: bundler
- requirement: !ruby/object:Gem::Requirement
- requirements:
- - - "~>"
- - !ruby/object:Gem::Version
- version: '1.0'
- type: :development
- prerelease: false
- version_requirements: !ruby/object:Gem::Requirement
- requirements:
- - - "~>"
- - !ruby/object:Gem::Version
- version: '1.0'
-description: Thor is a toolkit for building powerful command-line interfaces.
-email: ruby-thor at googlegroups.com
-executables:
-- thor
-extensions: []
-extra_rdoc_files: []
-files:
-- ".document"
-- CHANGELOG.md
-- LICENSE.md
-- README.md
-- Thorfile
-- bin/thor
-- lib/thor.rb
-- lib/thor/actions.rb
-- lib/thor/actions/create_file.rb
-- lib/thor/actions/create_link.rb
-- lib/thor/actions/directory.rb
-- lib/thor/actions/empty_directory.rb
-- lib/thor/actions/file_manipulation.rb
-- lib/thor/actions/inject_into_file.rb
-- lib/thor/base.rb
-- lib/thor/command.rb
-- lib/thor/core_ext/hash_with_indifferent_access.rb
-- lib/thor/core_ext/io_binary_read.rb
-- lib/thor/core_ext/ordered_hash.rb
-- lib/thor/error.rb
-- lib/thor/group.rb
-- lib/thor/invocation.rb
-- lib/thor/line_editor.rb
-- lib/thor/line_editor/basic.rb
-- lib/thor/line_editor/readline.rb
-- lib/thor/parser.rb
-- lib/thor/parser/argument.rb
-- lib/thor/parser/arguments.rb
-- lib/thor/parser/option.rb
-- lib/thor/parser/options.rb
-- lib/thor/rake_compat.rb
-- lib/thor/runner.rb
-- lib/thor/shell.rb
-- lib/thor/shell/basic.rb
-- lib/thor/shell/color.rb
-- lib/thor/shell/html.rb
-- lib/thor/util.rb
-- lib/thor/version.rb
-- spec/actions/create_file_spec.rb
-- spec/actions/create_link_spec.rb
-- spec/actions/directory_spec.rb
-- spec/actions/empty_directory_spec.rb
-- spec/actions/file_manipulation_spec.rb
-- spec/actions/inject_into_file_spec.rb
-- spec/actions_spec.rb
-- spec/base_spec.rb
-- spec/command_spec.rb
-- spec/core_ext/hash_with_indifferent_access_spec.rb
-- spec/core_ext/ordered_hash_spec.rb
-- spec/exit_condition_spec.rb
-- spec/fixtures/application.rb
-- spec/fixtures/app{1}/README
-- spec/fixtures/bundle/execute.rb
-- spec/fixtures/bundle/main.thor
-- spec/fixtures/command.thor
-- spec/fixtures/doc/%file_name%.rb.tt
-- spec/fixtures/doc/COMMENTER
-- spec/fixtures/doc/README
-- spec/fixtures/doc/block_helper.rb
-- spec/fixtures/doc/config.rb
-- spec/fixtures/doc/config.yaml.tt
-- spec/fixtures/doc/excluding/%file_name%.rb.tt
-- spec/fixtures/enum.thor
-- spec/fixtures/group.thor
-- spec/fixtures/invoke.thor
-- spec/fixtures/path with spaces
-- spec/fixtures/preserve/script.sh
-- spec/fixtures/script.thor
-- spec/fixtures/subcommand.thor
-- spec/group_spec.rb
-- spec/helper.rb
-- spec/invocation_spec.rb
-- spec/line_editor/basic_spec.rb
-- spec/line_editor/readline_spec.rb
-- spec/line_editor_spec.rb
-- spec/parser/argument_spec.rb
-- spec/parser/arguments_spec.rb
-- spec/parser/option_spec.rb
-- spec/parser/options_spec.rb
-- spec/quality_spec.rb
-- spec/rake_compat_spec.rb
-- spec/register_spec.rb
-- spec/runner_spec.rb
-- spec/sandbox/application.rb
-- spec/sandbox/app{1}/README
-- spec/sandbox/bundle/execute.rb
-- spec/sandbox/bundle/main.thor
-- spec/sandbox/command.thor
-- spec/sandbox/doc/%file_name%.rb.tt
-- spec/sandbox/doc/COMMENTER
-- spec/sandbox/doc/README
-- spec/sandbox/doc/block_helper.rb
-- spec/sandbox/doc/config.rb
-- spec/sandbox/doc/config.yaml.tt
-- spec/sandbox/doc/excluding/%file_name%.rb.tt
-- spec/sandbox/enum.thor
-- spec/sandbox/group.thor
-- spec/sandbox/invoke.thor
-- spec/sandbox/path with spaces
-- spec/sandbox/preserve/script.sh
-- spec/sandbox/script.thor
-- spec/sandbox/subcommand.thor
-- spec/shell/basic_spec.rb
-- spec/shell/color_spec.rb
-- spec/shell/html_spec.rb
-- spec/shell_spec.rb
-- spec/subcommand_spec.rb
-- spec/thor_spec.rb
-- spec/util_spec.rb
-- thor.gemspec
-homepage: http://whatisthor.com/
-licenses:
-- MIT
-metadata: {}
-post_install_message:
-rdoc_options: []
-require_paths:
-- lib
-required_ruby_version: !ruby/object:Gem::Requirement
- requirements:
- - - ">="
- - !ruby/object:Gem::Version
- version: '0'
-required_rubygems_version: !ruby/object:Gem::Requirement
- requirements:
- - - ">="
- - !ruby/object:Gem::Version
- version: 1.3.5
-requirements: []
-rubyforge_project:
-rubygems_version: 2.2.2
-signing_key:
-specification_version: 4
-summary: Thor is a toolkit for building powerful command-line interfaces.
-test_files:
-- spec/actions/create_file_spec.rb
-- spec/actions/create_link_spec.rb
-- spec/actions/directory_spec.rb
-- spec/actions/empty_directory_spec.rb
-- spec/actions/file_manipulation_spec.rb
-- spec/actions/inject_into_file_spec.rb
-- spec/actions_spec.rb
-- spec/base_spec.rb
-- spec/command_spec.rb
-- spec/core_ext/hash_with_indifferent_access_spec.rb
-- spec/core_ext/ordered_hash_spec.rb
-- spec/exit_condition_spec.rb
-- spec/fixtures/application.rb
-- spec/fixtures/app{1}/README
-- spec/fixtures/bundle/execute.rb
-- spec/fixtures/bundle/main.thor
-- spec/fixtures/command.thor
-- spec/fixtures/doc/%file_name%.rb.tt
-- spec/fixtures/doc/block_helper.rb
-- spec/fixtures/doc/COMMENTER
-- spec/fixtures/doc/config.rb
-- spec/fixtures/doc/config.yaml.tt
-- spec/fixtures/doc/excluding/%file_name%.rb.tt
-- spec/fixtures/doc/README
-- spec/fixtures/enum.thor
-- spec/fixtures/group.thor
-- spec/fixtures/invoke.thor
-- spec/fixtures/path with spaces
-- spec/fixtures/preserve/script.sh
-- spec/fixtures/script.thor
-- spec/fixtures/subcommand.thor
-- spec/group_spec.rb
-- spec/helper.rb
-- spec/invocation_spec.rb
-- spec/line_editor/basic_spec.rb
-- spec/line_editor/readline_spec.rb
-- spec/line_editor_spec.rb
-- spec/parser/argument_spec.rb
-- spec/parser/arguments_spec.rb
-- spec/parser/option_spec.rb
-- spec/parser/options_spec.rb
-- spec/quality_spec.rb
-- spec/rake_compat_spec.rb
-- spec/register_spec.rb
-- spec/runner_spec.rb
-- spec/sandbox/application.rb
-- spec/sandbox/app{1}/README
-- spec/sandbox/bundle/execute.rb
-- spec/sandbox/bundle/main.thor
-- spec/sandbox/command.thor
-- spec/sandbox/doc/%file_name%.rb.tt
-- spec/sandbox/doc/block_helper.rb
-- spec/sandbox/doc/COMMENTER
-- spec/sandbox/doc/config.rb
-- spec/sandbox/doc/config.yaml.tt
-- spec/sandbox/doc/excluding/%file_name%.rb.tt
-- spec/sandbox/doc/README
-- spec/sandbox/enum.thor
-- spec/sandbox/group.thor
-- spec/sandbox/invoke.thor
-- spec/sandbox/path with spaces
-- spec/sandbox/preserve/script.sh
-- spec/sandbox/script.thor
-- spec/sandbox/subcommand.thor
-- spec/shell/basic_spec.rb
-- spec/shell/color_spec.rb
-- spec/shell/html_spec.rb
-- spec/shell_spec.rb
-- spec/subcommand_spec.rb
-- spec/thor_spec.rb
-- spec/util_spec.rb
diff --git a/spec/actions/create_file_spec.rb b/spec/actions/create_file_spec.rb
deleted file mode 100644
index 4bf82c9..0000000
--- a/spec/actions/create_file_spec.rb
+++ /dev/null
@@ -1,168 +0,0 @@
-require "helper"
-require "thor/actions"
-
-describe Thor::Actions::CreateFile do
- before do
- @silence = false
- ::FileUtils.rm_rf(destination_root)
- end
-
- def create_file(destination = nil, config = {}, options = {})
- @base = MyCounter.new([1, 2], options, :destination_root => destination_root)
- allow(@base).to receive(:file_name).and_return("rdoc")
-
- @action = Thor::Actions::CreateFile.new(@base, destination, "CONFIGURATION", {:verbose => !@silence}.merge(config))
- end
-
- def invoke!
- capture(:stdout) { @action.invoke! }
- end
-
- def revoke!
- capture(:stdout) { @action.revoke! }
- end
-
- def silence!
- @silence = true
- end
-
- describe "#invoke!" do
- it "creates a file" do
- create_file("doc/config.rb")
- invoke!
- expect(File.exist?(File.join(destination_root, "doc/config.rb"))).to be true
- end
-
- it "does not create a file if pretending" do
- create_file("doc/config.rb", {}, :pretend => true)
- invoke!
- expect(File.exist?(File.join(destination_root, "doc/config.rb"))).to be false
- end
-
- it "shows created status to the user" do
- create_file("doc/config.rb")
- expect(invoke!).to eq(" create doc/config.rb\n")
- end
-
- it "does not show any information if log status is false" do
- silence!
- create_file("doc/config.rb")
- expect(invoke!).to be_empty
- end
-
- it "returns the given destination" do
- capture(:stdout) do
- expect(create_file("doc/config.rb").invoke!).to eq("doc/config.rb")
- end
- end
-
- it "converts encoded instructions" do
- create_file("doc/%file_name%.rb.tt")
- invoke!
- expect(File.exist?(File.join(destination_root, "doc/rdoc.rb.tt"))).to be true
- end
-
- describe "when file exists" do
- before do
- create_file("doc/config.rb")
- invoke!
- end
-
- describe "and is identical" do
- it "shows identical status" do
- create_file("doc/config.rb")
- invoke!
- expect(invoke!).to eq(" identical doc/config.rb\n")
- end
- end
-
- describe "and is not identical" do
- before do
- File.open(File.join(destination_root, "doc/config.rb"), "w") { |f| f.write("FOO = 3") }
- end
-
- it "shows forced status to the user if force is given" do
- expect(create_file("doc/config.rb", {}, :force => true)).not_to be_identical
- expect(invoke!).to eq(" force doc/config.rb\n")
- end
-
- it "shows skipped status to the user if skip is given" do
- expect(create_file("doc/config.rb", {}, :skip => true)).not_to be_identical
- expect(invoke!).to eq(" skip doc/config.rb\n")
- end
-
- it "shows forced status to the user if force is configured" do
- expect(create_file("doc/config.rb", :force => true)).not_to be_identical
- expect(invoke!).to eq(" force doc/config.rb\n")
- end
-
- it "shows skipped status to the user if skip is configured" do
- expect(create_file("doc/config.rb", :skip => true)).not_to be_identical
- expect(invoke!).to eq(" skip doc/config.rb\n")
- end
-
- it "shows conflict status to the user" do
- file = File.join(destination_root, "doc/config.rb")
- expect(create_file("doc/config.rb")).not_to be_identical
- expect(Thor::LineEditor).to receive(:readline).with("Overwrite #{file}? (enter \"h\" for help) [Ynaqdh] ", anything).and_return("s")
-
- content = invoke!
- expect(content).to match(/conflict doc\/config\.rb/)
- expect(content).to match(/skip doc\/config\.rb/)
- end
-
- it "creates the file if the file collision menu returns true" do
- create_file("doc/config.rb")
- expect(Thor::LineEditor).to receive(:readline).and_return("y")
- expect(invoke!).to match(/force doc\/config\.rb/)
- end
-
- it "skips the file if the file collision menu returns false" do
- create_file("doc/config.rb")
- expect(Thor::LineEditor).to receive(:readline).and_return("n")
- expect(invoke!).to match(/skip doc\/config\.rb/)
- end
-
- it "executes the block given to show file content" do
- create_file("doc/config.rb")
- expect(Thor::LineEditor).to receive(:readline).and_return("d", "n")
- expect(@base.shell).to receive(:system).with(/diff -u/)
- invoke!
- end
- end
- end
- end
-
- describe "#revoke!" do
- it "removes the destination file" do
- create_file("doc/config.rb")
- invoke!
- revoke!
- expect(File.exist?(@action.destination)).to be false
- end
-
- it "does not raise an error if the file does not exist" do
- create_file("doc/config.rb")
- revoke!
- expect(File.exist?(@action.destination)).to be false
- end
- end
-
- describe "#exists?" do
- it "returns true if the destination file exists" do
- create_file("doc/config.rb")
- expect(@action.exists?).to be false
- invoke!
- expect(@action.exists?).to be true
- end
- end
-
- describe "#identical?" do
- it "returns true if the destination file exists and is identical" do
- create_file("doc/config.rb")
- expect(@action.identical?).to be false
- invoke!
- expect(@action.identical?).to be true
- end
- end
-end
diff --git a/spec/actions/create_link_spec.rb b/spec/actions/create_link_spec.rb
deleted file mode 100644
index 7eaab7e..0000000
--- a/spec/actions/create_link_spec.rb
+++ /dev/null
@@ -1,96 +0,0 @@
-require "helper"
-require "thor/actions"
-require "tempfile"
-
-describe Thor::Actions::CreateLink do
- before do
- @silence = false
- @hardlink_to = File.join(Dir.tmpdir, "linkdest.rb")
- ::FileUtils.rm_rf(destination_root)
- ::FileUtils.rm_rf(@hardlink_to)
- end
-
- def create_link(destination = nil, config = {}, options = {})
- @base = MyCounter.new([1, 2], options, :destination_root => destination_root)
- allow(@base).to receive(:file_name).and_return("rdoc")
-
- @tempfile = Tempfile.new("config.rb")
-
- @action = Thor::Actions::CreateLink.new(@base, destination, @tempfile.path,
- {:verbose => !@silence}.merge(config))
- end
-
- def invoke!
- capture(:stdout) { @action.invoke! }
- end
-
- def revoke!
- capture(:stdout) { @action.revoke! }
- end
-
- def silence!
- @silence = true
- end
-
- describe "#invoke!" do
- it "creates a symbolic link for :symbolic => true" do
- create_link("doc/config.rb", :symbolic => true)
- invoke!
- destination_path = File.join(destination_root, "doc/config.rb")
- expect(File.exist?(destination_path)).to be true
- expect(File.symlink?(destination_path)).to be true
- end
-
- it "creates a hard link for :symbolic => false" do
- create_link(@hardlink_to, :symbolic => false)
- invoke!
- destination_path = @hardlink_to
- expect(File.exist?(destination_path)).to be true
- expect(File.symlink?(destination_path)).to be false
- end
-
- it "creates a symbolic link by default" do
- create_link("doc/config.rb")
- invoke!
- destination_path = File.join(destination_root, "doc/config.rb")
- expect(File.exist?(destination_path)).to be true
- expect(File.symlink?(destination_path)).to be true
- end
-
- it "does not create a link if pretending" do
- create_link("doc/config.rb", {}, :pretend => true)
- invoke!
- expect(File.exist?(File.join(destination_root, "doc/config.rb"))).to be false
- end
-
- it "shows created status to the user" do
- create_link("doc/config.rb")
- expect(invoke!).to eq(" create doc/config.rb\n")
- end
-
- it "does not show any information if log status is false" do
- silence!
- create_link("doc/config.rb")
- expect(invoke!).to be_empty
- end
- end
-
- describe "#identical?" do
- it "returns true if the destination link exists and is identical" do
- create_link("doc/config.rb")
- expect(@action.identical?).to be false
- invoke!
- expect(@action.identical?).to be true
- end
- end
-
- describe "#revoke!" do
- it "removes the symbolic link of non-existent destination" do
- create_link("doc/config.rb")
- invoke!
- File.delete(@tempfile.path)
- revoke!
- expect(File.symlink?(@action.destination)).to be false
- end
- end
-end
diff --git a/spec/actions/directory_spec.rb b/spec/actions/directory_spec.rb
deleted file mode 100644
index 23a1637..0000000
--- a/spec/actions/directory_spec.rb
+++ /dev/null
@@ -1,169 +0,0 @@
-require "helper"
-require "thor/actions"
-
-describe Thor::Actions::Directory do
- before do
- ::FileUtils.rm_rf(destination_root)
- allow(invoker).to receive(:file_name).and_return("rdoc")
- end
-
- def invoker
- @invoker ||= WhinyGenerator.new([1, 2], {}, :destination_root => destination_root)
- end
-
- def revoker
- @revoker ||= WhinyGenerator.new([1, 2], {}, :destination_root => destination_root, :behavior => :revoke)
- end
-
- def invoke!(*args, &block)
- capture(:stdout) { invoker.directory(*args, &block) }
- end
-
- def revoke!(*args, &block)
- capture(:stdout) { revoker.directory(*args, &block) }
- end
-
- def exists_and_identical?(source_path, destination_path)
- %w[config.rb README].each do |file|
- source = File.join(source_root, source_path, file)
- destination = File.join(destination_root, destination_path, file)
-
- expect(File.exist?(destination)).to be true
- expect(FileUtils.identical?(source, destination)).to be true
- end
- end
-
- describe "#invoke!" do
- it "raises an error if the source does not exist" do
- expect do
- invoke! "unknown"
- end.to raise_error(Thor::Error, /Could not find "unknown" in any of your source paths/)
- end
-
- it "does not create a directory in pretend mode" do
- invoke! "doc", "ghost", :pretend => true
- expect(File.exist?("ghost")).to be false
- end
-
- it "copies the whole directory recursively to the default destination" do
- invoke! "doc"
- exists_and_identical?("doc", "doc")
- end
-
- it "copies the whole directory recursively to the specified destination" do
- invoke! "doc", "docs"
- exists_and_identical?("doc", "docs")
- end
-
- it "copies only the first level files if recursive" do
- invoke! ".", "commands", :recursive => false
-
- file = File.join(destination_root, "commands", "group.thor")
- expect(File.exist?(file)).to be true
-
- file = File.join(destination_root, "commands", "doc")
- expect(File.exist?(file)).to be false
-
- file = File.join(destination_root, "commands", "doc", "README")
- expect(File.exist?(file)).to be false
- end
-
- it "ignores files within excluding/ directories when exclude_pattern is provided" do
- invoke! "doc", "docs", :exclude_pattern => /excluding\//
- file = File.join(destination_root, "docs", "excluding", "rdoc.rb")
- expect(File.exist?(file)).to be false
- end
-
- it "copies and evaluates files within excluding/ directory when no exclude_pattern is present" do
- invoke! "doc", "docs"
- file = File.join(destination_root, "docs", "excluding", "rdoc.rb")
- expect(File.exist?(file)).to be true
- expect(File.read(file)).to eq("BAR = BAR\n")
- end
-
- it "copies files from the source relative to the current path" do
- invoker.inside "doc" do
- invoke! "."
- end
- exists_and_identical?("doc", "doc")
- end
-
- it "copies and evaluates templates" do
- invoke! "doc", "docs"
- file = File.join(destination_root, "docs", "rdoc.rb")
- expect(File.exist?(file)).to be true
- expect(File.read(file)).to eq("FOO = FOO\n")
- end
-
- it "copies directories and preserves file mode" do
- invoke! "preserve", "preserved", :mode => :preserve
- original = File.join(source_root, "preserve", "script.sh")
- copy = File.join(destination_root, "preserved", "script.sh")
- expect(File.stat(original).mode).to eq(File.stat(copy).mode)
- end
-
- it "copies directories" do
- invoke! "doc", "docs"
- file = File.join(destination_root, "docs", "components")
- expect(File.exist?(file)).to be true
- expect(File.directory?(file)).to be true
- end
-
- it "does not copy .empty_directory files" do
- invoke! "doc", "docs"
- file = File.join(destination_root, "docs", "components", ".empty_directory")
- expect(File.exist?(file)).to be false
- end
-
- it "copies directories even if they are empty" do
- invoke! "doc/components", "docs/components"
- file = File.join(destination_root, "docs", "components")
- expect(File.exist?(file)).to be true
- end
-
- it "does not copy empty directories twice" do
- content = invoke!("doc/components", "docs/components")
- expect(content).not_to match(/exist/)
- end
-
- it "logs status" do
- content = invoke!("doc")
- expect(content).to match(/create doc\/README/)
- expect(content).to match(/create doc\/config\.rb/)
- expect(content).to match(/create doc\/rdoc\.rb/)
- expect(content).to match(/create doc\/components/)
- end
-
- it "yields a block" do
- checked = false
- invoke!("doc") do |content|
- checked ||= !!(content =~ /FOO/)
- end
- expect(checked).to be true
- end
-
- it "works with glob characters in the path" do
- content = invoke!("app{1}")
- expect(content).to match(/create app\{1\}\/README/)
- end
- end
-
- describe "#revoke!" do
- it "removes the destination file" do
- invoke! "doc"
- revoke! "doc"
-
- expect(File.exist?(File.join(destination_root, "doc", "README"))).to be false
- expect(File.exist?(File.join(destination_root, "doc", "config.rb"))).to be false
- expect(File.exist?(File.join(destination_root, "doc", "components"))).to be false
- end
-
- it "works with glob characters in the path" do
- invoke! "app{1}"
- expect(File.exist?(File.join(destination_root, "app{1}", "README"))).to be true
-
- revoke! "app{1}"
- expect(File.exist?(File.join(destination_root, "app{1}", "README"))).to be false
- end
- end
-end
diff --git a/spec/actions/empty_directory_spec.rb b/spec/actions/empty_directory_spec.rb
deleted file mode 100644
index 7304a24..0000000
--- a/spec/actions/empty_directory_spec.rb
+++ /dev/null
@@ -1,129 +0,0 @@
-require "helper"
-require "thor/actions"
-
-describe Thor::Actions::EmptyDirectory do
- before do
- ::FileUtils.rm_rf(destination_root)
- end
-
- def empty_directory(destination, options = {})
- @action = Thor::Actions::EmptyDirectory.new(base, destination)
- end
-
- def invoke!
- capture(:stdout) { @action.invoke! }
- end
-
- def revoke!
- capture(:stdout) { @action.revoke! }
- end
-
- def base
- @base ||= MyCounter.new([1, 2], {}, :destination_root => destination_root)
- end
-
- describe "#destination" do
- it "returns the full destination with the destination_root" do
- expect(empty_directory("doc").destination).to eq(File.join(destination_root, "doc"))
- end
-
- it "takes relative root into account" do
- base.inside("doc") do
- expect(empty_directory("contents").destination).to eq(File.join(destination_root, "doc", "contents"))
- end
- end
- end
-
- describe "#relative_destination" do
- it "returns the relative destination to the original destination root" do
- base.inside("doc") do
- expect(empty_directory("contents").relative_destination).to eq("doc/contents")
- end
- end
- end
-
- describe "#given_destination" do
- it "returns the destination supplied by the user" do
- base.inside("doc") do
- expect(empty_directory("contents").given_destination).to eq("contents")
- end
- end
- end
-
- describe "#invoke!" do
- it "copies the file to the specified destination" do
- empty_directory("doc")
- invoke!
- expect(File.exist?(File.join(destination_root, "doc"))).to be true
- end
-
- it "shows created status to the user" do
- empty_directory("doc")
- expect(invoke!).to eq(" create doc\n")
- end
-
- it "does not create a directory if pretending" do
- base.inside("foo", :pretend => true) do
- empty_directory("ghost")
- end
- expect(File.exist?(File.join(base.destination_root, "ghost"))).to be false
- end
-
- describe "when directory exists" do
- it "shows exist status" do
- empty_directory("doc")
- invoke!
- expect(invoke!).to eq(" exist doc\n")
- end
- end
- end
-
- describe "#revoke!" do
- it "removes the destination file" do
- empty_directory("doc")
- invoke!
- revoke!
- expect(File.exist?(@action.destination)).to be false
- end
- end
-
- describe "#exists?" do
- it "returns true if the destination file exists" do
- empty_directory("doc")
- expect(@action.exists?).to be false
- invoke!
- expect(@action.exists?).to be true
- end
- end
-
- context "protected methods" do
- describe "#convert_encoded_instructions" do
- before do
- empty_directory("test_dir")
- allow(@action.base).to receive(:file_name).and_return("expected")
- end
-
- it "accepts and executes a 'legal' %\w+% encoded instruction" do
- expect(@action.send(:convert_encoded_instructions, "%file_name%.txt")).to eq("expected.txt")
- end
-
- it "accepts and executes a private %\w+% encoded instruction" do
- @action.base.extend Module.new {
- def private_file_name
- "expected"
- end
- private :private_file_name
- }
- expect(@action.send(:convert_encoded_instructions, "%private_file_name%.txt")).to eq("expected.txt")
- end
-
- it "ignores an 'illegal' %\w+% encoded instruction" do
- expect(@action.send(:convert_encoded_instructions, "%some_name%.txt")).to eq("%some_name%.txt")
- end
-
- it "ignores incorrectly encoded instruction" do
- expect(@action.send(:convert_encoded_instructions, "%some.name%.txt")).to eq("%some.name%.txt")
- end
- end
- end
-end
diff --git a/spec/actions/file_manipulation_spec.rb b/spec/actions/file_manipulation_spec.rb
deleted file mode 100644
index 878b438..0000000
--- a/spec/actions/file_manipulation_spec.rb
+++ /dev/null
@@ -1,392 +0,0 @@
-require "helper"
-
-class Application; end
-
-describe Thor::Actions do
- def runner(options = {})
- @runner ||= MyCounter.new([1], options, :destination_root => destination_root)
- end
-
- def action(*args, &block)
- capture(:stdout) { runner.send(*args, &block) }
- end
-
- def exists_and_identical?(source, destination)
- destination = File.join(destination_root, destination)
- expect(File.exist?(destination)).to be true
-
- source = File.join(source_root, source)
- expect(FileUtils).to be_identical(source, destination)
- end
-
- def file
- File.join(destination_root, "foo")
- end
-
- before do
- ::FileUtils.rm_rf(destination_root)
- end
-
- describe "#chmod" do
- it "executes the command given" do
- expect(FileUtils).to receive(:chmod_R).with(0755, file) # rubocop:disable SymbolName
- action :chmod, "foo", 0755
- end
-
- it "does not execute the command if pretending" do
- expect(FileUtils).not_to receive(:chmod_R) # rubocop:disable SymbolName
- runner(:pretend => true)
- action :chmod, "foo", 0755
- end
-
- it "logs status" do
- expect(FileUtils).to receive(:chmod_R).with(0755, file) # rubocop:disable SymbolName
- expect(action(:chmod, "foo", 0755)).to eq(" chmod foo\n")
- end
-
- it "does not log status if required" do
- expect(FileUtils).to receive(:chmod_R).with(0755, file) # rubocop:disable SymbolName
- expect(action(:chmod, "foo", 0755, :verbose => false)).to be_empty
- end
- end
-
- describe "#copy_file" do
- it "copies file from source to default destination" do
- action :copy_file, "command.thor"
- exists_and_identical?("command.thor", "command.thor")
- end
-
- it "copies file from source to the specified destination" do
- action :copy_file, "command.thor", "foo.thor"
- exists_and_identical?("command.thor", "foo.thor")
- end
-
- it "copies file from the source relative to the current path" do
- runner.inside("doc") do
- action :copy_file, "README"
- end
- exists_and_identical?("doc/README", "doc/README")
- end
-
- it "copies file from source to default destination and preserves file mode" do
- action :copy_file, "preserve/script.sh", :mode => :preserve
- original = File.join(source_root, "preserve/script.sh")
- copy = File.join(destination_root, "preserve/script.sh")
- expect(File.stat(original).mode).to eq(File.stat(copy).mode)
- end
-
- it "logs status" do
- expect(action(:copy_file, "command.thor")).to eq(" create command.thor\n")
- end
-
- it "accepts a block to change output" do
- action :copy_file, "command.thor" do |content|
- "OMG" + content
- end
- expect(File.read(File.join(destination_root, "command.thor"))).to match(/^OMG/)
- end
- end
-
- describe "#link_file" do
- it "links file from source to default destination" do
- action :link_file, "command.thor"
- exists_and_identical?("command.thor", "command.thor")
- end
-
- it "links file from source to the specified destination" do
- action :link_file, "command.thor", "foo.thor"
- exists_and_identical?("command.thor", "foo.thor")
- end
-
- it "links file from the source relative to the current path" do
- runner.inside("doc") do
- action :link_file, "README"
- end
- exists_and_identical?("doc/README", "doc/README")
- end
-
- it "logs status" do
- expect(action(:link_file, "command.thor")).to eq(" create command.thor\n")
- end
- end
-
- describe "#get" do
- it "copies file from source to the specified destination" do
- action :get, "doc/README", "docs/README"
- exists_and_identical?("doc/README", "docs/README")
- end
-
- it "uses just the source basename as destination if none is specified" do
- action :get, "doc/README"
- exists_and_identical?("doc/README", "README")
- end
-
- it "allows the destination to be set as a block result" do
- action(:get, "doc/README") { |c| "docs/README" }
- exists_and_identical?("doc/README", "docs/README")
- end
-
- it "yields file content to a block" do
- action :get, "doc/README" do |content|
- expect(content).to eq("__start__\nREADME\n__end__\n")
- end
- end
-
- it "logs status" do
- expect(action(:get, "doc/README", "docs/README")).to eq(" create docs/README\n")
- end
-
- it "accepts http remote sources" do
- body = "__start__\nHTTPFILE\n__end__\n"
- FakeWeb.register_uri(:get, "http://example.com/file.txt", :body => body)
- action :get, "http://example.com/file.txt" do |content|
- expect(content).to eq(body)
- end
- FakeWeb.clean_registry
- end
-
- it "accepts https remote sources" do
- body = "__start__\nHTTPSFILE\n__end__\n"
- FakeWeb.register_uri(:get, "https://example.com/file.txt", :body => body)
- action :get, "https://example.com/file.txt" do |content|
- expect(content).to eq(body)
- end
- FakeWeb.clean_registry
- end
- end
-
- describe "#template" do
- it "allows using block helpers in the template" do
- action :template, "doc/block_helper.rb"
-
- file = File.join(destination_root, "doc/block_helper.rb")
- expect(File.read(file)).to eq("Hello world!")
- end
-
- it "evaluates the template given as source" do
- runner.instance_variable_set("@klass", "Config")
- action :template, "doc/config.rb"
-
- file = File.join(destination_root, "doc/config.rb")
- expect(File.read(file)).to eq("class Config; end\n")
- end
-
- it "copies the template to the specified destination" do
- runner.instance_variable_set("@klass", "Config")
- action :template, "doc/config.rb", "doc/configuration.rb"
- file = File.join(destination_root, "doc/configuration.rb")
- expect(File.exist?(file)).to be true
- end
-
- it "converts encoded instructions" do
- expect(runner).to receive(:file_name).and_return("rdoc")
- action :template, "doc/%file_name%.rb.tt"
- file = File.join(destination_root, "doc/rdoc.rb")
- expect(File.exist?(file)).to be true
- end
-
- it "accepts filename without .tt for template method" do
- expect(runner).to receive(:file_name).and_return("rdoc")
- action :template, "doc/%file_name%.rb"
- file = File.join(destination_root, "doc/rdoc.rb")
- expect(File.exist?(file)).to be true
- end
-
- it "logs status" do
- runner.instance_variable_set("@klass", "Config")
- expect(capture(:stdout) { runner.template("doc/config.rb") }).to eq(" create doc/config.rb\n")
- end
-
- it "accepts a block to change output" do
- runner.instance_variable_set("@klass", "Config")
- action :template, "doc/config.rb" do |content|
- "OMG" + content
- end
- expect(File.read(File.join(destination_root, "doc/config.rb"))).to match(/^OMG/)
- end
-
- it "guesses the destination name when given only a source" do
- action :template, "doc/config.yaml.tt"
-
- file = File.join(destination_root, "doc/config.yaml")
- expect(File.exist?(file)).to be true
- end
- end
-
- describe "when changing existent files" do
- before do
- ::FileUtils.cp_r(source_root, destination_root)
- end
-
- def file
- File.join(destination_root, "doc", "README")
- end
-
- describe "#remove_file" do
- it "removes the file given" do
- action :remove_file, "doc/README"
- expect(File.exist?(file)).to be false
- end
-
- it "removes directories too" do
- action :remove_dir, "doc"
- expect(File.exist?(File.join(destination_root, "doc"))).to be false
- end
-
- it "does not remove if pretending" do
- runner(:pretend => true)
- action :remove_file, "doc/README"
- expect(File.exist?(file)).to be true
- end
-
- it "logs status" do
- expect(action(:remove_file, "doc/README")).to eq(" remove doc/README\n")
- end
-
- it "does not log status if required" do
- expect(action(:remove_file, "doc/README", :verbose => false)).to be_empty
- end
- end
-
- describe "#gsub_file" do
- it "replaces the content in the file" do
- action :gsub_file, "doc/README", "__start__", "START"
- expect(File.binread(file)).to eq("START\nREADME\n__end__\n")
- end
-
- it "does not replace if pretending" do
- runner(:pretend => true)
- action :gsub_file, "doc/README", "__start__", "START"
- expect(File.binread(file)).to eq("__start__\nREADME\n__end__\n")
- end
-
- it "accepts a block" do
- action(:gsub_file, "doc/README", "__start__") { |match| match.gsub("__", "").upcase }
- expect(File.binread(file)).to eq("START\nREADME\n__end__\n")
- end
-
- it "logs status" do
- expect(action(:gsub_file, "doc/README", "__start__", "START")).to eq(" gsub doc/README\n")
- end
-
- it "does not log status if required" do
- expect(action(:gsub_file, file, "__", :verbose => false) { |match| match * 2 }).to be_empty
- end
- end
-
- describe "#append_to_file" do
- it "appends content to the file" do
- action :append_to_file, "doc/README", "END\n"
- expect(File.binread(file)).to eq("__start__\nREADME\n__end__\nEND\n")
- end
-
- it "accepts a block" do
- action(:append_to_file, "doc/README") { "END\n" }
- expect(File.binread(file)).to eq("__start__\nREADME\n__end__\nEND\n")
- end
-
- it "logs status" do
- expect(action(:append_to_file, "doc/README", "END")).to eq(" append doc/README\n")
- end
- end
-
- describe "#prepend_to_file" do
- it "prepends content to the file" do
- action :prepend_to_file, "doc/README", "START\n"
- expect(File.binread(file)).to eq("START\n__start__\nREADME\n__end__\n")
- end
-
- it "accepts a block" do
- action(:prepend_to_file, "doc/README") { "START\n" }
- expect(File.binread(file)).to eq("START\n__start__\nREADME\n__end__\n")
- end
-
- it "logs status" do
- expect(action(:prepend_to_file, "doc/README", "START")).to eq(" prepend doc/README\n")
- end
- end
-
- describe "#inject_into_class" do
- def file
- File.join(destination_root, "application.rb")
- end
-
- it "appends content to a class" do
- action :inject_into_class, "application.rb", Application, " filter_parameters :password\n"
- expect(File.binread(file)).to eq("class Application < Base\n filter_parameters :password\nend\n")
- end
-
- it "accepts a block" do
- action(:inject_into_class, "application.rb", Application) { " filter_parameters :password\n" }
- expect(File.binread(file)).to eq("class Application < Base\n filter_parameters :password\nend\n")
- end
-
- it "logs status" do
- expect(action(:inject_into_class, "application.rb", Application, " filter_parameters :password\n")).to eq(" insert application.rb\n")
- end
-
- it "does not append if class name does not match" do
- action :inject_into_class, "application.rb", "App", " filter_parameters :password\n"
- expect(File.binread(file)).to eq("class Application < Base\nend\n")
- end
- end
- end
-
- describe "when adjusting comments" do
- before do
- ::FileUtils.cp_r(source_root, destination_root)
- end
-
- def file
- File.join(destination_root, "doc", "COMMENTER")
- end
-
- unmodified_comments_file = /__start__\n # greenblue\n#\n# yellowblue\n#yellowred\n #greenred\norange\n purple\n ind#igo\n # ind#igo\n__end__/
-
- describe "#uncomment_lines" do
- it "uncomments all matching lines in the file" do
- action :uncomment_lines, "doc/COMMENTER", "green"
- expect(File.binread(file)).to match(/__start__\n greenblue\n#\n# yellowblue\n#yellowred\n greenred\norange\n purple\n ind#igo\n # ind#igo\n__end__/)
-
- action :uncomment_lines, "doc/COMMENTER", "red"
- expect(File.binread(file)).to match(/__start__\n greenblue\n#\n# yellowblue\nyellowred\n greenred\norange\n purple\n ind#igo\n # ind#igo\n__end__/)
- end
-
- it "correctly uncomments lines with hashes in them" do
- action :uncomment_lines, "doc/COMMENTER", "ind#igo"
- expect(File.binread(file)).to match(/__start__\n # greenblue\n#\n# yellowblue\n#yellowred\n #greenred\norange\n purple\n ind#igo\n ind#igo\n__end__/)
- end
-
- it "does not modify already uncommented lines in the file" do
- action :uncomment_lines, "doc/COMMENTER", "orange"
- action :uncomment_lines, "doc/COMMENTER", "purple"
- expect(File.binread(file)).to match(unmodified_comments_file)
- end
-
- it "does not uncomment the wrong line when uncommenting lines preceded by blank commented line" do
- action :uncomment_lines, "doc/COMMENTER", "yellow"
- expect(File.binread(file)).to match(/__start__\n # greenblue\n#\nyellowblue\nyellowred\n #greenred\norange\n purple\n ind#igo\n # ind#igo\n__end__/)
- end
- end
-
- describe "#comment_lines" do
- it "comments lines which are not commented" do
- action :comment_lines, "doc/COMMENTER", "orange"
- expect(File.binread(file)).to match(/__start__\n # greenblue\n#\n# yellowblue\n#yellowred\n #greenred\n# orange\n purple\n ind#igo\n # ind#igo\n__end__/)
-
- action :comment_lines, "doc/COMMENTER", "purple"
- expect(File.binread(file)).to match(/__start__\n # greenblue\n#\n# yellowblue\n#yellowred\n #greenred\n# orange\n # purple\n ind#igo\n # ind#igo\n__end__/)
- end
-
- it "correctly comments lines with hashes in them" do
- action :comment_lines, "doc/COMMENTER", "ind#igo"
- expect(File.binread(file)).to match(/__start__\n # greenblue\n#\n# yellowblue\n#yellowred\n #greenred\norange\n purple\n # ind#igo\n # ind#igo\n__end__/)
- end
-
- it "does not modify already commented lines" do
- action :comment_lines, "doc/COMMENTER", "green"
- expect(File.binread(file)).to match(unmodified_comments_file)
- end
- end
- end
-end
diff --git a/spec/actions/inject_into_file_spec.rb b/spec/actions/inject_into_file_spec.rb
deleted file mode 100644
index 05112a1..0000000
--- a/spec/actions/inject_into_file_spec.rb
+++ /dev/null
@@ -1,135 +0,0 @@
-require "helper"
-require "thor/actions"
-
-describe Thor::Actions::InjectIntoFile do
- before do
- ::FileUtils.rm_rf(destination_root)
- ::FileUtils.cp_r(source_root, destination_root)
- end
-
- def invoker(options = {})
- @invoker ||= MyCounter.new([1, 2], options, :destination_root => destination_root)
- end
-
- def revoker
- @revoker ||= MyCounter.new([1, 2], {}, :destination_root => destination_root, :behavior => :revoke)
- end
-
- def invoke!(*args, &block)
- capture(:stdout) { invoker.insert_into_file(*args, &block) }
- end
-
- def revoke!(*args, &block)
- capture(:stdout) { revoker.insert_into_file(*args, &block) }
- end
-
- def file
- File.join(destination_root, "doc/README")
- end
-
- describe "#invoke!" do
- it "changes the file adding content after the flag" do
- invoke! "doc/README", "\nmore content", :after => "__start__"
- expect(File.read(file)).to eq("__start__\nmore content\nREADME\n__end__\n")
- end
-
- it "changes the file adding content before the flag" do
- invoke! "doc/README", "more content\n", :before => "__end__"
- expect(File.read(file)).to eq("__start__\nREADME\nmore content\n__end__\n")
- end
-
- it "accepts data as a block" do
- invoke! "doc/README", :before => "__end__" do
- "more content\n"
- end
-
- expect(File.read(file)).to eq("__start__\nREADME\nmore content\n__end__\n")
- end
-
- it "logs status" do
- expect(invoke!("doc/README", "\nmore content", :after => "__start__")).to eq(" insert doc/README\n")
- end
-
- it "does not change the file if pretending" do
- invoker :pretend => true
- invoke! "doc/README", "\nmore content", :after => "__start__"
- expect(File.read(file)).to eq("__start__\nREADME\n__end__\n")
- end
-
- it "does not change the file if already includes content" do
- invoke! "doc/README", :before => "__end__" do
- "more content\n"
- end
-
- expect(File.read(file)).to eq("__start__\nREADME\nmore content\n__end__\n")
-
- invoke! "doc/README", :before => "__end__" do
- "more content\n"
- end
-
- expect(File.read(file)).to eq("__start__\nREADME\nmore content\n__end__\n")
- end
-
- it "does change the file if already includes content and :force is true" do
- invoke! "doc/README", :before => "__end__" do
- "more content\n"
- end
-
- expect(File.read(file)).to eq("__start__\nREADME\nmore content\n__end__\n")
-
- invoke! "doc/README", :before => "__end__", :force => true do
- "more content\n"
- end
-
- expect(File.read(file)).to eq("__start__\nREADME\nmore content\nmore content\n__end__\n")
- end
-
- end
-
- describe "#revoke!" do
- it "subtracts the destination file after injection" do
- invoke! "doc/README", "\nmore content", :after => "__start__"
- revoke! "doc/README", "\nmore content", :after => "__start__"
- expect(File.read(file)).to eq("__start__\nREADME\n__end__\n")
- end
-
- it "subtracts the destination file before injection" do
- invoke! "doc/README", "more content\n", :before => "__start__"
- revoke! "doc/README", "more content\n", :before => "__start__"
- expect(File.read(file)).to eq("__start__\nREADME\n__end__\n")
- end
-
- it "subtracts even with double after injection" do
- invoke! "doc/README", "\nmore content", :after => "__start__"
- invoke! "doc/README", "\nanother stuff", :after => "__start__"
- revoke! "doc/README", "\nmore content", :after => "__start__"
- expect(File.read(file)).to eq("__start__\nanother stuff\nREADME\n__end__\n")
- end
-
- it "subtracts even with double before injection" do
- invoke! "doc/README", "more content\n", :before => "__start__"
- invoke! "doc/README", "another stuff\n", :before => "__start__"
- revoke! "doc/README", "more content\n", :before => "__start__"
- expect(File.read(file)).to eq("another stuff\n__start__\nREADME\n__end__\n")
- end
-
- it "subtracts when prepending" do
- invoke! "doc/README", "more content\n", :after => /\A/
- invoke! "doc/README", "another stuff\n", :after => /\A/
- revoke! "doc/README", "more content\n", :after => /\A/
- expect(File.read(file)).to eq("another stuff\n__start__\nREADME\n__end__\n")
- end
-
- it "subtracts when appending" do
- invoke! "doc/README", "more content\n", :before => /\z/
- invoke! "doc/README", "another stuff\n", :before => /\z/
- revoke! "doc/README", "more content\n", :before => /\z/
- expect(File.read(file)).to eq("__start__\nREADME\n__end__\nanother stuff\n")
- end
-
- it "shows progress information to the user" do
- invoke!("doc/README", "\nmore content", :after => "__start__")
- expect(revoke!("doc/README", "\nmore content", :after => "__start__")).to eq(" subtract doc/README\n")
- end
- end
-end
diff --git a/spec/actions_spec.rb b/spec/actions_spec.rb
deleted file mode 100644
index e296780..0000000
--- a/spec/actions_spec.rb
+++ /dev/null
@@ -1,331 +0,0 @@
-require "helper"
-
-describe Thor::Actions do
- def runner(options = {})
- @runner ||= MyCounter.new([1], options, :destination_root => destination_root)
- end
-
- def action(*args, &block)
- capture(:stdout) { runner.send(*args, &block) }
- end
-
- def file
- File.join(destination_root, "foo")
- end
-
- describe "on include" do
- it "adds runtime options to the base class" do
- expect(MyCounter.class_options.keys).to include(:pretend)
- expect(MyCounter.class_options.keys).to include(:force)
- expect(MyCounter.class_options.keys).to include(:quiet)
- expect(MyCounter.class_options.keys).to include(:skip)
- end
- end
-
- describe "#initialize" do
- it "has default behavior invoke" do
- expect(runner.behavior).to eq(:invoke)
- end
-
- it "can have behavior revoke" do
- expect(MyCounter.new([1], {}, :behavior => :revoke).behavior).to eq(:revoke)
- end
-
- it "when behavior is set to force, overwrite options" do
- runner = MyCounter.new([1], {:force => false, :skip => true}, :behavior => :force)
- expect(runner.behavior).to eq(:invoke)
- expect(runner.options.force).to be true
- expect(runner.options.skip).not_to be true
- end
-
- it "when behavior is set to skip, overwrite options" do
- runner = MyCounter.new([1], %w[--force], :behavior => :skip)
- expect(runner.behavior).to eq(:invoke)
- expect(runner.options.force).not_to be true
- expect(runner.options.skip).to be true
- end
- end
-
- describe "accessors" do
- describe "#destination_root=" do
- it "gets the current directory and expands the path to set the root" do
- base = MyCounter.new([1])
- base.destination_root = "here"
- expect(base.destination_root).to eq(File.expand_path(File.join(File.dirname(__FILE__), "..", "here")))
- end
-
- it "does not use the current directory if one is given" do
- root = File.expand_path("/")
- base = MyCounter.new([1])
- base.destination_root = root
- expect(base.destination_root).to eq(root)
- end
-
- it "uses the current directory if none is given" do
- base = MyCounter.new([1])
- expect(base.destination_root).to eq(File.expand_path(File.join(File.dirname(__FILE__), "..")))
- end
- end
-
- describe "#relative_to_original_destination_root" do
- it "returns the path relative to the absolute root" do
- expect(runner.relative_to_original_destination_root(file)).to eq("foo")
- end
-
- it "does not remove dot if required" do
- expect(runner.relative_to_original_destination_root(file, false)).to eq("./foo")
- end
-
- it "always use the absolute root" do
- runner.inside("foo") do
- expect(runner.relative_to_original_destination_root(file)).to eq("foo")
- end
- end
-
- it "creates proper relative paths for absolute file location" do
- expect(runner.relative_to_original_destination_root("/test/file")).to eq("/test/file")
- end
-
- it "does not fail with files containing regexp characters" do
- runner = MyCounter.new([1], {}, :destination_root => File.join(destination_root, "fo[o-b]ar"))
- expect(runner.relative_to_original_destination_root("bar")).to eq("bar")
- end
-
- describe "#source_paths_for_search" do
- it "add source_root to source_paths_for_search" do
- expect(MyCounter.source_paths_for_search).to include(File.expand_path("fixtures", File.dirname(__FILE__)))
- end
-
- it "keeps only current source root in source paths" do
- expect(ClearCounter.source_paths_for_search).to include(File.expand_path("fixtures/bundle", File.dirname(__FILE__)))
- expect(ClearCounter.source_paths_for_search).not_to include(File.expand_path("fixtures", File.dirname(__FILE__)))
- end
-
- it "customized source paths should be before source roots" do
- expect(ClearCounter.source_paths_for_search[0]).to eq(File.expand_path("fixtures/doc", File.dirname(__FILE__)))
- expect(ClearCounter.source_paths_for_search[1]).to eq(File.expand_path("fixtures/bundle", File.dirname(__FILE__)))
- end
-
- it "keeps inherited source paths at the end" do
- expect(ClearCounter.source_paths_for_search.last).to eq(File.expand_path("fixtures/broken", File.dirname(__FILE__)))
- end
- end
- end
-
- describe "#find_in_source_paths" do
- it "raises an error if source path is empty" do
- expect do
- A.new.find_in_source_paths("foo")
- end.to raise_error(Thor::Error, /Currently you have no source paths/)
- end
-
- it "finds a template inside the source path" do
- expect(runner.find_in_source_paths("doc")).to eq(File.expand_path("doc", source_root))
- expect { runner.find_in_source_paths("README") }.to raise_error
-
- new_path = File.join(source_root, "doc")
- runner.instance_variable_set(:@source_paths, nil)
- runner.source_paths.unshift(new_path)
- expect(runner.find_in_source_paths("README")).to eq(File.expand_path("README", new_path))
- end
- end
- end
-
- describe "#inside" do
- it "executes the block inside the given folder" do
- runner.inside("foo") do
- expect(Dir.pwd).to eq(file)
- end
- end
-
- it "changes the base root" do
- runner.inside("foo") do
- expect(runner.destination_root).to eq(file)
- end
- end
-
- it "creates the directory if it does not exist" do
- runner.inside("foo") do
- expect(File.exist?(file)).to be true
- end
- end
-
- describe "when pretending" do
- it "no directories should be created" do
- runner.inside("bar", :pretend => true) {}
- expect(File.exist?("bar")).to be false
- end
- end
-
- describe "when verbose" do
- it "logs status" do
- expect(capture(:stdout) do
- runner.inside("foo", :verbose => true) {}
- end).to match(/inside foo/)
- end
-
- it "uses padding in next status" do
- expect(capture(:stdout) do
- runner.inside("foo", :verbose => true) do
- runner.say_status :cool, :padding
- end
- end).to match(/cool padding/)
- end
-
- it "removes padding after block" do
- expect(capture(:stdout) do
- runner.inside("foo", :verbose => true) {}
- runner.say_status :no, :padding
- end).to match(/no padding/)
- end
- end
- end
-
- describe "#in_root" do
- it "executes the block in the root folder" do
- runner.inside("foo") do
- runner.in_root { expect(Dir.pwd).to eq(destination_root) }
- end
- end
-
- it "changes the base root" do
- runner.inside("foo") do
- runner.in_root { expect(runner.destination_root).to eq(destination_root) }
- end
- end
-
- it "returns to the previous state" do
- runner.inside("foo") do
- runner.in_root {}
- expect(runner.destination_root).to eq(file)
- end
- end
- end
-
- describe "#apply" do
- before do
- @template = <<-TEMPLATE
- @foo = "FOO"
- say_status :cool, :padding
- TEMPLATE
- allow(@template).to receive(:read).and_return(@template)
-
- @file = "/"
- allow(runner).to receive(:open).and_return(@template)
- end
-
- it "accepts a URL as the path" do
- @file = "http://gist.github.com/103208.txt"
- expect(runner).to receive(:open).with(@file, "Accept" => "application/x-thor-template").and_return(@template)
- action(:apply, @file)
- end
-
- it "accepts a secure URL as the path" do
- @file = "https://gist.github.com/103208.txt"
- expect(runner).to receive(:open).with(@file, "Accept" => "application/x-thor-template").and_return(@template)
- action(:apply, @file)
- end
-
- it "accepts a local file path with spaces" do
- @file = File.expand_path("fixtures/path with spaces", File.dirname(__FILE__))
- expect(runner).to receive(:open).with(@file).and_return(@template)
- action(:apply, @file)
- end
-
- it "opens a file and executes its content in the instance binding" do
- action :apply, @file
- expect(runner.instance_variable_get("@foo")).to eq("FOO")
- end
-
- it "applies padding to the content inside the file" do
- expect(action(:apply, @file)).to match(/cool padding/)
- end
-
- it "logs its status" do
- expect(action(:apply, @file)).to match(/ apply #{@file}\n/)
- end
-
- it "does not log status" do
- content = action(:apply, @file, :verbose => false)
- expect(content).to match(/cool padding/)
- expect(content).not_to match(/apply http/)
- end
- end
-
- describe "#run" do
- before do
- expect(runner).to receive(:system).with("ls")
- end
-
- it "executes the command given" do
- action :run, "ls"
- end
-
- it "logs status" do
- expect(action(:run, "ls")).to eq(" run ls from \".\"\n")
- end
-
- it "does not log status if required" do
- expect(action(:run, "ls", :verbose => false)).to be_empty
- end
-
- it "accepts a color as status" do
- expect(runner.shell).to receive(:say_status).with(:run, 'ls from "."', :yellow)
- action :run, "ls", :verbose => :yellow
- end
- end
-
- describe "#run_ruby_script" do
- before do
- allow(Thor::Util).to receive(:ruby_command).and_return("/opt/jruby")
- expect(runner).to receive(:system).with("/opt/jruby script.rb")
- end
-
- it "executes the ruby script" do
- action :run_ruby_script, "script.rb"
- end
-
- it "logs status" do
- expect(action(:run_ruby_script, "script.rb")).to eq(" run jruby script.rb from \".\"\n")
- end
-
- it "does not log status if required" do
- expect(action(:run_ruby_script, "script.rb", :verbose => false)).to be_empty
- end
- end
-
- describe "#thor" do
- it "executes the thor command" do
- expect(runner).to receive(:system).with("thor list")
- action :thor, :list, :verbose => true
- end
-
- it "converts extra arguments to command arguments" do
- expect(runner).to receive(:system).with("thor list foo bar")
- action :thor, :list, "foo", "bar"
- end
-
- it "converts options hash to switches" do
- expect(runner).to receive(:system).with("thor list foo bar --foo")
- action :thor, :list, "foo", "bar", :foo => true
-
- expect(runner).to receive(:system).with("thor list --foo 1 2 3")
- action :thor, :list, :foo => [1, 2, 3]
- end
-
- it "logs status" do
- expect(runner).to receive(:system).with("thor list")
- expect(action(:thor, :list)).to eq(" run thor list from \".\"\n")
- end
-
- it "does not log status if required" do
- expect(runner).to receive(:system).with("thor list --foo 1 2 3")
- expect(action(:thor, :list, :foo => [1, 2, 3], :verbose => false)).to be_empty
- end
-
- it "captures the output when :capture is given" do
- expect(runner).to receive(:`).with("thor foo bar")
- action(:thor, "foo", "bar", :capture => true)
- end
- end
-end
diff --git a/spec/base_spec.rb b/spec/base_spec.rb
deleted file mode 100644
index fb6d6a9..0000000
--- a/spec/base_spec.rb
+++ /dev/null
@@ -1,298 +0,0 @@
-require "helper"
-require "thor/base"
-
-class Amazing
- desc "hello", "say hello"
- def hello
- puts "Hello"
- end
-end
-
-describe Thor::Base do
- describe "#initialize" do
- it "sets arguments array" do
- base = MyCounter.new [1, 2]
- expect(base.first).to eq(1)
- expect(base.second).to eq(2)
- end
-
- it "sets arguments default values" do
- base = MyCounter.new [1]
- expect(base.second).to eq(2)
- end
-
- it "sets options default values" do
- base = MyCounter.new [1, 2]
- expect(base.options[:third]).to eq(3)
- end
-
- it "allows options to be given as symbols or strings" do
- base = MyCounter.new [1, 2], :third => 4
- expect(base.options[:third]).to eq(4)
-
- base = MyCounter.new [1, 2], "third" => 4
- expect(base.options[:third]).to eq(4)
- end
-
- it "creates options with indifferent access" do
- base = MyCounter.new [1, 2], :third => 3
- expect(base.options["third"]).to eq(3)
- end
-
- it "creates options with magic predicates" do
- base = MyCounter.new [1, 2], :third => 3
- expect(base.options.third).to eq(3)
- end
- end
-
- describe "#no_commands" do
- it "avoids methods being added as commands" do
- expect(MyScript.commands.keys).to include("animal")
- expect(MyScript.commands.keys).not_to include("this_is_not_a_command")
- end
- end
-
- describe "#argument" do
- it "sets a value as required and creates an accessor for it" do
- expect(MyCounter.start(%w[1 2 --third 3])[0]).to eq(1)
- expect(Scripts::MyScript.start(%w[zoo my_special_param --param=normal_param])).to eq("my_special_param")
- end
-
- it "does not set a value in the options hash" do
- expect(BrokenCounter.start(%w[1 2 --third 3])[0]).to be nil
- end
- end
-
- describe "#arguments" do
- it "returns the arguments for the class" do
- expect(MyCounter.arguments.size).to be(2)
- end
- end
-
- describe ":aliases" do
- it "supports string aliases without a dash prefix" do
- expect(MyCounter.start(%w[1 2 -z 3])[4]).to eq(3)
- end
-
- it "supports symbol aliases" do
- expect(MyCounter.start(%w[1 2 -y 3])[5]).to eq(3)
- expect(MyCounter.start(%w[1 2 -r 3])[5]).to eq(3)
- end
- end
-
- describe "#class_option" do
- it "sets options class wise" do
- expect(MyCounter.start(%w[1 2 --third 3])[2]).to eq(3)
- end
-
- it "does not create an accessor for it" do
- expect(BrokenCounter.start(%w[1 2 --third 3])[3]).to be false
- end
- end
-
- describe "#class_options" do
- it "sets default options overwriting superclass definitions" do
- options = Scripts::MyScript.class_options
- expect(options[:force]).not_to be_required
- end
- end
-
- describe "#remove_argument" do
- it "removes previously defined arguments from class" do
- expect(ClearCounter.arguments).to be_empty
- end
-
- it "undefine accessors if required" do
- expect(ClearCounter.new).not_to respond_to(:first)
- expect(ClearCounter.new).not_to respond_to(:second)
- end
- end
-
- describe "#remove_class_option" do
- it "removes previous defined class option" do
- expect(ClearCounter.class_options[:third]).to be nil
- end
- end
-
- describe "#class_options_help" do
- before do
- @content = capture(:stdout) { MyCounter.help(Thor::Base.shell.new) }
- end
-
- it "shows option's description" do
- expect(@content).to match(/# The third argument/)
- end
-
- it "shows usage with banner content" do
- expect(@content).to match(/\[\-\-third=THREE\]/)
- end
-
- it "shows default values below descriptions" do
- expect(@content).to match(/# Default: 3/)
- end
-
- it "shows options in different groups" do
- expect(@content).to match(/Options\:/)
- expect(@content).to match(/Runtime options\:/)
- expect(@content).to match(/\-p, \[\-\-pretend\]/)
- end
-
- it "use padding in options that do not have aliases" do
- expect(@content).to match(/^ -t, \[--third/)
- expect(@content).to match(/^ \[--fourth/)
- end
-
- it "allows extra options to be given" do
- hash = {"Foo" => B.class_options.values}
-
- content = capture(:stdout) { MyCounter.send(:class_options_help, Thor::Base.shell.new, hash) }
- expect(content).to match(/Foo options\:/)
- expect(content).to match(/--last-name=LAST_NAME/)
- end
-
- it "displays choices for enums" do
- content = capture(:stdout) { Enum.help(Thor::Base.shell.new) }
- expect(content).to match(/Possible values\: apple, banana/)
- end
- end
-
- describe "#namespace" do
- it "returns the default class namespace" do
- expect(Scripts::MyScript.namespace).to eq("scripts:my_script")
- end
-
- it "sets a namespace to the class" do
- expect(Scripts::MyDefaults.namespace).to eq("default")
- end
- end
-
- describe "#group" do
- it "sets a group" do
- expect(MyScript.group).to eq("script")
- end
-
- it "inherits the group from parent" do
- expect(MyChildScript.group).to eq("script")
- end
-
- it "defaults to standard if no group is given" do
- expect(Amazing.group).to eq("standard")
- end
- end
-
- describe "#subclasses" do
- it "tracks its subclasses in an Array" do
- expect(Thor::Base.subclasses).to include(MyScript)
- expect(Thor::Base.subclasses).to include(MyChildScript)
- expect(Thor::Base.subclasses).to include(Scripts::MyScript)
- end
- end
-
- describe "#subclass_files" do
- it "returns tracked subclasses, grouped by the files they come from" do
- thorfile = File.join(File.dirname(__FILE__), "fixtures", "script.thor")
- expect(Thor::Base.subclass_files[File.expand_path(thorfile)]).to eq([
- MyScript, MyScript::AnotherScript, MyChildScript, Barn,
- PackageNameScript, Scripts::MyScript, Scripts::MyDefaults,
- Scripts::ChildDefault, Scripts::Arities
- ])
- end
-
- it "tracks a single subclass across multiple files" do
- thorfile = File.join(File.dirname(__FILE__), "fixtures", "command.thor")
- expect(Thor::Base.subclass_files[File.expand_path(thorfile)]).to include(Amazing)
- expect(Thor::Base.subclass_files[File.expand_path(__FILE__)]).to include(Amazing)
- end
- end
-
- describe "#commands" do
- it "returns a list with all commands defined in this class" do
- expect(MyChildScript.new).to respond_to("animal")
- expect(MyChildScript.commands.keys).to include("animal")
- end
-
- it "raises an error if a command with reserved word is defined" do
- expect do
- klass = Class.new(Thor::Group)
- klass.class_eval "def shell; end"
- end.to raise_error(RuntimeError, /"shell" is a Thor reserved word and cannot be defined as command/)
- end
- end
-
- describe "#all_commands" do
- it "returns a list with all commands defined in this class plus superclasses" do
- expect(MyChildScript.new).to respond_to("foo")
- expect(MyChildScript.all_commands.keys).to include("foo")
- end
- end
-
- describe "#remove_command" do
- it "removes the command from its commands hash" do
- expect(MyChildScript.commands.keys).not_to include("bar")
- expect(MyChildScript.commands.keys).not_to include("boom")
- end
-
- it "undefines the method if desired" do
- expect(MyChildScript.new).not_to respond_to("boom")
- end
- end
-
- describe "#from_superclass" do
- it "does not send a method to the superclass if the superclass does not respond to it" do
- expect(MyCounter.get_from_super).to eq(13)
- end
- end
-
- describe "#start" do
- it "raises an error instead of rescuing if THOR_DEBUG=1 is given" do
- begin
- ENV["THOR_DEBUG"] = "1"
-
- expect do
- MyScript.start %w[what --debug]
- end.to raise_error(Thor::UndefinedCommandError, 'Could not find command "what" in "my_script" namespace.')
- ensure
- ENV["THOR_DEBUG"] = nil
- end
- end
-
- it "raises an error instead of rescuing if :debug option is given" do
- expect do
- MyScript.start %w[what], :debug => true
- end.to raise_error(Thor::UndefinedCommandError, 'Could not find command "what" in "my_script" namespace.')
- end
-
- it "does not steal args" do
- args = %w[foo bar --force true]
- MyScript.start(args)
- expect(args).to eq(%w[foo bar --force true])
- end
-
- it "checks unknown options" do
- expect(capture(:stderr) do
- MyScript.start(%w[foo bar --force true --unknown baz])
- end.strip).to eq("Unknown switches '--unknown'")
- end
-
- it "checks unknown options except specified" do
- expect(capture(:stderr) do
- expect(MyScript.start(%w[with_optional NAME --omg --invalid])).to eq(["NAME", {}, %w[--omg --invalid]])
- end.strip).to be_empty
- end
- end
-
- describe "attr_*" do
- it "does not add attr_reader as a command" do
- expect(capture(:stderr) { MyScript.start(%w[another_attribute]) }).to match(/Could not find/)
- end
-
- it "does not add attr_writer as a command" do
- expect(capture(:stderr) { MyScript.start(%w[another_attribute= foo]) }).to match(/Could not find/)
- end
-
- it "does not add attr_accessor as a command" do
- expect(capture(:stderr) { MyScript.start(["some_attribute"]) }).to match(/Could not find/)
- expect(capture(:stderr) { MyScript.start(["some_attribute=", "foo"]) }).to match(/Could not find/)
- end
- end
-end
diff --git a/spec/command_spec.rb b/spec/command_spec.rb
deleted file mode 100644
index b09270d..0000000
--- a/spec/command_spec.rb
+++ /dev/null
@@ -1,79 +0,0 @@
-require "helper"
-
-describe Thor::Command do
- def command(options = {})
- options.each do |key, value|
- options[key] = Thor::Option.parse(key, value)
- end
-
- @command ||= Thor::Command.new(:can_has, "I can has cheezburger", "I can has cheezburger\nLots and lots of it", "can_has", options)
- end
-
- describe "#formatted_usage" do
- it "includes namespace within usage" do
- object = Struct.new(:namespace, :arguments).new("foo", [])
- expect(command(:bar => :required).formatted_usage(object)).to eq("foo:can_has --bar=BAR")
- end
-
- it "includes subcommand name within subcommand usage" do
- object = Struct.new(:namespace, :arguments).new("main:foo", [])
- expect(command(:bar => :required).formatted_usage(object, false, true)).to eq("foo can_has --bar=BAR")
- end
-
- it "removes default from namespace" do
- object = Struct.new(:namespace, :arguments).new("default:foo", [])
- expect(command(:bar => :required).formatted_usage(object)).to eq(":foo:can_has --bar=BAR")
- end
-
- it "injects arguments into usage" do
- options = {:required => true, :type => :string}
- object = Struct.new(:namespace, :arguments).new("foo", [Thor::Argument.new(:bar, options)])
- expect(command(:foo => :required).formatted_usage(object)).to eq("foo:can_has BAR --foo=FOO")
- end
- end
-
- describe "#dynamic" do
- it "creates a dynamic command with the given name" do
- expect(Thor::DynamicCommand.new("command").name).to eq("command")
- expect(Thor::DynamicCommand.new("command").description).to eq("A dynamically-generated command")
- expect(Thor::DynamicCommand.new("command").usage).to eq("command")
- expect(Thor::DynamicCommand.new("command").options).to eq({})
- end
-
- it "does not invoke an existing method" do
- dub = double
- expect(dub.class).to receive(:handle_no_command_error).with("to_s")
- Thor::DynamicCommand.new("to_s").run(dub)
- end
- end
-
- describe "#dup" do
- it "dup options hash" do
- command = Thor::Command.new("can_has", nil, nil, nil, :foo => true, :bar => :required)
- command.dup.options.delete(:foo)
- expect(command.options[:foo]).to be
- end
- end
-
- describe "#run" do
- it "runs a command by calling a method in the given instance" do
- dub = double
- expect(dub).to receive(:can_has).and_return { |*args| args }
- expect(command.run(dub, [1, 2, 3])).to eq([1, 2, 3])
- end
-
- it "raises an error if the method to be invoked is private" do
- klass = Class.new do
- def self.handle_no_command_error(name)
- name
- end
- def can_has
- "fail"
- end
- private :can_has
- end
-
- expect(command.run(klass.new)).to eq("can_has")
- end
- end
-end
diff --git a/spec/core_ext/hash_with_indifferent_access_spec.rb b/spec/core_ext/hash_with_indifferent_access_spec.rb
deleted file mode 100644
index ffeb05f..0000000
--- a/spec/core_ext/hash_with_indifferent_access_spec.rb
+++ /dev/null
@@ -1,48 +0,0 @@
-require "helper"
-require "thor/core_ext/hash_with_indifferent_access"
-
-describe Thor::CoreExt::HashWithIndifferentAccess do
- before do
- @hash = Thor::CoreExt::HashWithIndifferentAccess.new :foo => "bar", "baz" => "bee", :force => true
- end
-
- it "has values accessible by either strings or symbols" do
- expect(@hash["foo"]).to eq("bar")
- expect(@hash[:foo]).to eq("bar")
-
- expect(@hash.values_at(:foo, :baz)).to eq(%w[bar bee])
- expect(@hash.delete(:foo)).to eq("bar")
- end
-
- it "handles magic boolean predicates" do
- expect(@hash.force?).to be true
- expect(@hash.foo?).to be true
- expect(@hash.nothing?).to be false
- end
-
- it "handles magic comparisons" do
- expect(@hash.foo?("bar")).to be true
- expect(@hash.foo?("bee")).to be false
- end
-
- it "maps methods to keys" do
- expect(@hash.foo).to eq(@hash["foo"])
- end
-
- it "merges keys independent if they are symbols or strings" do
- @hash.merge!("force" => false, :baz => "boom")
- expect(@hash[:force]).to eq(false)
- expect(@hash["baz"]).to eq("boom")
- end
-
- it "creates a new hash by merging keys independent if they are symbols or strings" do
- other = @hash.merge("force" => false, :baz => "boom")
- expect(other[:force]).to eq(false)
- expect(other["baz"]).to eq("boom")
- end
-
- it "converts to a traditional hash" do
- expect(@hash.to_hash.class).to eq(Hash)
- expect(@hash).to eq("foo" => "bar", "baz" => "bee", "force" => true)
- end
-end
diff --git a/spec/core_ext/ordered_hash_spec.rb b/spec/core_ext/ordered_hash_spec.rb
deleted file mode 100644
index 8cc6143..0000000
--- a/spec/core_ext/ordered_hash_spec.rb
+++ /dev/null
@@ -1,115 +0,0 @@
-require "helper"
-require "thor/core_ext/ordered_hash"
-
-describe Thor::CoreExt::OrderedHash do
- before do
- @hash = Thor::CoreExt::OrderedHash.new
- end
-
- describe "without any items" do
- it "returns nil for an undefined key" do
- expect(@hash["foo"]).to be nil
- end
-
- it "doesn't iterate through any items" do
- @hash.each { fail }
- end
-
- it "has an empty key and values list" do
- expect(@hash.keys).to be_empty
- expect(@hash.values).to be_empty
- end
-
- it "must be empty" do
- expect(@hash).to be_empty
- end
- end
-
- describe "with several items" do
- before do
- @hash[:foo] = "Foo!"
- @hash[:bar] = "Bar!"
- @hash[:baz] = "Baz!"
- @hash[:bop] = "Bop!"
- @hash[:bat] = "Bat!"
- end
-
- it "returns nil for an undefined key" do
- expect(@hash[:boom]).to be nil
- end
-
- it "returns the value for each key" do
- expect(@hash[:foo]).to eq("Foo!")
- expect(@hash[:bar]).to eq("Bar!")
- expect(@hash[:baz]).to eq("Baz!")
- expect(@hash[:bop]).to eq("Bop!")
- expect(@hash[:bat]).to eq("Bat!")
- end
-
- it "iterates through the keys and values in order of assignment" do
- arr = []
- @hash.each do |key, value|
- arr << [key, value]
- end
- expect(arr).to eq([[:foo, "Foo!"], [:bar, "Bar!"], [:baz, "Baz!"],
- [:bop, "Bop!"], [:bat, "Bat!"]])
- end
-
- it "returns the keys in order of insertion" do
- expect(@hash.keys).to eq([:foo, :bar, :baz, :bop, :bat])
- end
-
- it "returns the values in order of insertion" do
- expect(@hash.values).to eq(["Foo!", "Bar!", "Baz!", "Bop!", "Bat!"])
- end
-
- it "does not move an overwritten node to the end of the ordering" do
- @hash[:baz] = "Bip!"
- expect(@hash.values).to eq(["Foo!", "Bar!", "Bip!", "Bop!", "Bat!"])
-
- @hash[:foo] = "Bip!"
- expect(@hash.values).to eq(["Bip!", "Bar!", "Bip!", "Bop!", "Bat!"])
-
- @hash[:bat] = "Bip!"
- expect(@hash.values).to eq(["Bip!", "Bar!", "Bip!", "Bop!", "Bip!"])
- end
-
- it "appends another ordered hash while preserving ordering" do
- other_hash = Thor::CoreExt::OrderedHash.new
- other_hash[1] = "one"
- other_hash[2] = "two"
- other_hash[3] = "three"
- expect(@hash.merge(other_hash).values).to eq(["Foo!", "Bar!", "Baz!", "Bop!", "Bat!", "one", "two", "three"])
- end
-
- it "overwrites hash keys with matching appended keys" do
- other_hash = Thor::CoreExt::OrderedHash.new
- other_hash[:bar] = "bar"
- expect(@hash.merge(other_hash)[:bar]).to eq("bar")
- expect(@hash[:bar]).to eq("Bar!")
- end
-
- it "converts to an array" do
- expect(@hash.to_a).to eq([[:foo, "Foo!"], [:bar, "Bar!"], [:baz, "Baz!"], [:bop, "Bop!"], [:bat, "Bat!"]])
- end
-
- it "must not be empty" do
- expect(@hash).not_to be_empty
- end
-
- it "deletes values from hash" do
- expect(@hash.delete(:baz)).to eq("Baz!")
- expect(@hash.values).to eq(["Foo!", "Bar!", "Bop!", "Bat!"])
-
- expect(@hash.delete(:foo)).to eq("Foo!")
- expect(@hash.values).to eq(["Bar!", "Bop!", "Bat!"])
-
- expect(@hash.delete(:bat)).to eq("Bat!")
- expect(@hash.values).to eq(["Bar!", "Bop!"])
- end
-
- it "returns nil if the value to be deleted can't be found" do
- expect(@hash.delete(:nothing)).to be nil
- end
- end
-end
diff --git a/spec/exit_condition_spec.rb b/spec/exit_condition_spec.rb
deleted file mode 100644
index 807b5af..0000000
--- a/spec/exit_condition_spec.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-require "helper"
-require "thor/base"
-
-describe "Exit conditions" do
- it "exits 0, not bubble up EPIPE, if EPIPE is raised" do
- epiped = false
-
- command = Class.new(Thor) do
- desc "my_action", "testing EPIPE"
- define_method :my_action do
- epiped = true
- fail Errno::EPIPE
- end
- end
-
- expect { command.start(["my_action"]) }.to raise_error(SystemExit)
- expect(epiped).to eq(true)
- end
-end
diff --git a/spec/fixtures/application.rb b/spec/fixtures/application.rb
deleted file mode 100644
index 50d2fae..0000000
--- a/spec/fixtures/application.rb
+++ /dev/null
@@ -1,2 +0,0 @@
-class Application < Base
-end
diff --git a/spec/fixtures/app{1}/README b/spec/fixtures/app{1}/README
deleted file mode 100644
index 16374df..0000000
--- a/spec/fixtures/app{1}/README
+++ /dev/null
@@ -1,3 +0,0 @@
-__start__
-README
-__end__
diff --git a/spec/fixtures/bundle/execute.rb b/spec/fixtures/bundle/execute.rb
deleted file mode 100644
index 0530d87..0000000
--- a/spec/fixtures/bundle/execute.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-class Execute < Thor
- desc "ls", "Execute ls"
- def ls
- system "ls"
- end
-end
diff --git a/spec/fixtures/bundle/main.thor b/spec/fixtures/bundle/main.thor
deleted file mode 100644
index 38bdfbc..0000000
--- a/spec/fixtures/bundle/main.thor
+++ /dev/null
@@ -1 +0,0 @@
-require File.join(File.dirname(__FILE__), 'execute')
diff --git a/spec/fixtures/command.thor b/spec/fixtures/command.thor
deleted file mode 100644
index 26a0268..0000000
--- a/spec/fixtures/command.thor
+++ /dev/null
@@ -1,10 +0,0 @@
-# module: random
-
-class Amazing < Thor
- desc "describe NAME", "say that someone is amazing"
- method_options :forcefully => :boolean
- def describe(name, opts)
- ret = "#{name} is amazing"
- puts opts["forcefully"] ? ret.upcase : ret
- end
-end
diff --git a/spec/fixtures/doc/%file_name%.rb.tt b/spec/fixtures/doc/%file_name%.rb.tt
deleted file mode 100644
index 4c4c6c0..0000000
--- a/spec/fixtures/doc/%file_name%.rb.tt
+++ /dev/null
@@ -1 +0,0 @@
-FOO = <%= "FOO" %>
diff --git a/spec/fixtures/doc/COMMENTER b/spec/fixtures/doc/COMMENTER
deleted file mode 100644
index 384cb3a..0000000
--- a/spec/fixtures/doc/COMMENTER
+++ /dev/null
@@ -1,11 +0,0 @@
-__start__
- # greenblue
-#
-# yellowblue
-#yellowred
- #greenred
-orange
- purple
- ind#igo
- # ind#igo
-__end__
diff --git a/spec/fixtures/doc/README b/spec/fixtures/doc/README
deleted file mode 100644
index 16374df..0000000
--- a/spec/fixtures/doc/README
+++ /dev/null
@@ -1,3 +0,0 @@
-__start__
-README
-__end__
diff --git a/spec/fixtures/doc/block_helper.rb b/spec/fixtures/doc/block_helper.rb
deleted file mode 100644
index df59211..0000000
--- a/spec/fixtures/doc/block_helper.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-<% world do -%>
-Hello
-<% end -%>
diff --git a/spec/fixtures/doc/config.rb b/spec/fixtures/doc/config.rb
deleted file mode 100644
index 6211739..0000000
--- a/spec/fixtures/doc/config.rb
+++ /dev/null
@@ -1 +0,0 @@
-class <%= @klass %>; end
diff --git a/spec/fixtures/doc/config.yaml.tt b/spec/fixtures/doc/config.yaml.tt
deleted file mode 100644
index e75615c..0000000
--- a/spec/fixtures/doc/config.yaml.tt
+++ /dev/null
@@ -1 +0,0 @@
---- Hi from yaml
diff --git a/spec/fixtures/doc/excluding/%file_name%.rb.tt b/spec/fixtures/doc/excluding/%file_name%.rb.tt
deleted file mode 100644
index 6296c46..0000000
--- a/spec/fixtures/doc/excluding/%file_name%.rb.tt
+++ /dev/null
@@ -1 +0,0 @@
-BAR = <%= "BAR" %>
diff --git a/spec/fixtures/enum.thor b/spec/fixtures/enum.thor
deleted file mode 100644
index b5a7ded..0000000
--- a/spec/fixtures/enum.thor
+++ /dev/null
@@ -1,10 +0,0 @@
-class Enum < Thor::Group
- include Thor::Actions
-
- desc "snack"
- class_option "fruit", :aliases => "-f", :type => :string, :enum => %w(apple banana)
- def snack
- puts options['fruit']
- end
-
-end
diff --git a/spec/fixtures/group.thor b/spec/fixtures/group.thor
deleted file mode 100644
index bc7e102..0000000
--- a/spec/fixtures/group.thor
+++ /dev/null
@@ -1,128 +0,0 @@
-class MyCounter < Thor::Group
- include Thor::Actions
- add_runtime_options!
-
- def self.get_from_super
- from_superclass(:get_from_super, 13)
- end
-
- source_root File.expand_path(File.dirname(__FILE__))
- source_paths << File.expand_path("broken", File.dirname(__FILE__))
-
- argument :first, :type => :numeric
- argument :second, :type => :numeric, :default => 2
-
- class_option :third, :type => :numeric, :desc => "The third argument", :default => 3,
- :banner => "THREE", :aliases => "-t"
- class_option :fourth, :type => :numeric, :desc => "The fourth argument"
- class_option :simple, :type => :numeric, :aliases => 'z'
- class_option :symbolic, :type => :numeric, :aliases => [:y, :r]
-
- desc <<-FOO
-Description:
- This generator runs three commands: one, two and three.
-FOO
-
- def one
- first
- end
-
- def two
- second
- end
-
- def three
- options[:third]
- end
-
- def four
- options[:fourth]
- end
-
- def five
- options[:simple]
- end
-
- def six
- options[:symbolic]
- end
-
- def self.inherited(base)
- super
- base.source_paths.unshift(File.expand_path(File.join(File.dirname(__FILE__), "doc")))
- end
-
- no_commands do
- def world(&block)
- result = capture(&block)
- concat(result.strip + " world!")
- end
- end
-end
-
-class ClearCounter < MyCounter
- remove_argument :first, :second, :undefine => true
- remove_class_option :third
-
- def self.source_root
- File.expand_path(File.join(File.dirname(__FILE__), "bundle"))
- end
-end
-
-class BrokenCounter < MyCounter
- namespace "app:broken:counter"
- class_option :fail, :type => :boolean, :default => false
-
- class << self
- undef_method :source_root
- end
-
- def one
- options[:first]
- end
-
- def four
- respond_to?(:fail)
- end
-
- def five
- options[:fail] ? this_method_does_not_exist : 5
- end
-end
-
-class WhinyGenerator < Thor::Group
- include Thor::Actions
-
- def self.source_root
- File.expand_path(File.dirname(__FILE__))
- end
-
- def wrong_arity(required)
- end
-end
-
-class CommandConflict < Thor::Group
- desc "A group with the same name as a default command"
- def group
- puts "group"
- end
-end
-
-class ParentGroup < Thor::Group
-private
- def foo
- "foo"
- end
-
- def baz(name = 'baz')
- name
- end
-end
-
-class ChildGroup < ParentGroup
- def bar
- "bar"
- end
-
- public_command :foo, :baz
-end
diff --git a/spec/fixtures/invoke.thor b/spec/fixtures/invoke.thor
deleted file mode 100644
index 0e76e98..0000000
--- a/spec/fixtures/invoke.thor
+++ /dev/null
@@ -1,131 +0,0 @@
-class A < Thor
- include Thor::Actions
-
- desc "one", "invoke one"
- def one
- p 1
- invoke :two
- invoke :three
- end
-
- desc "two", "invoke two"
- def two
- p 2
- invoke :three
- end
-
- desc "three", "invoke three"
- def three
- p 3
- end
-
- desc "four", "invoke four"
- def four
- p 4
- invoke "defined:five"
- end
-
- desc "five N", "check if number is equal 5"
- def five(number)
- number == 5
- end
-
- desc "invoker", "invoke a b command"
- def invoker(*args)
- invoke :b, :one, ["Jose"]
- end
-end
-
-class B < Thor
- class_option :last_name, :type => :string
-
- desc "one FIRST_NAME", "invoke one"
- def one(first_name)
- "#{options.last_name}, #{first_name}"
- end
-
- desc "two", "invoke two"
- def two
- options
- end
-
- desc "three", "invoke three"
- def three
- self
- end
-
- desc "four", "invoke four"
- option :defaulted_value, :type => :string, :default => 'default'
- def four
- options.defaulted_value
- end
-end
-
-class C < Thor::Group
- include Thor::Actions
-
- def one
- p 1
- end
-
- def two
- p 2
- end
-
- def three
- p 3
- end
-end
-
-class Defined < Thor::Group
- class_option :unused, :type => :boolean, :desc => "This option has no use"
-
- def one
- p 1
- invoke "a:two"
- invoke "a:three"
- invoke "a:four"
- invoke "defined:five"
- end
-
- def five
- p 5
- end
-
- def print_status
- say_status :finished, :counting
- end
-end
-
-class E < Thor::Group
- invoke Defined
-end
-
-class F < Thor::Group
- invoke "b:one" do |instance, klass, command|
- instance.invoke klass, command, [ "Jose" ], :last_name => "Valim"
- end
-end
-
-class G < Thor::Group
- class_option :invoked, :type => :string, :default => "defined"
- invoke_from_option :invoked
-end
-
-class H < Thor::Group
- class_option :defined, :type => :boolean, :default => true
- invoke_from_option :defined
-end
-
-class I < Thor
- desc "two", "Two"
- def two
- current_command_chain
- end
-end
-
-class J < Thor
- desc "i", "I"
- subcommand :one, I
-end
-
diff --git a/spec/fixtures/path with spaces b/spec/fixtures/path with spaces
deleted file mode 100644
index e69de29..0000000
diff --git a/spec/fixtures/preserve/script.sh b/spec/fixtures/preserve/script.sh
deleted file mode 100755
index c52d3c2..0000000
--- a/spec/fixtures/preserve/script.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-
-exit 0
diff --git a/spec/fixtures/script.thor b/spec/fixtures/script.thor
deleted file mode 100644
index 357b6e5..0000000
--- a/spec/fixtures/script.thor
+++ /dev/null
@@ -1,220 +0,0 @@
-class MyScript < Thor
- check_unknown_options! :except => :with_optional
-
- attr_accessor :some_attribute
- attr_writer :another_attribute
- attr_reader :another_attribute
-
- private
- attr_reader :private_attribute
-
- public
- group :script
- default_command :example_default_command
-
- map "-T" => :animal, ["-f", "--foo"] => :foo
-
- map "animal_prison" => "zoo"
-
- desc "zoo", "zoo around"
- def zoo
- true
- end
-
- desc "animal TYPE", "horse around"
-
- no_commands do
- def this_is_not_a_command
- end
- end
-
- def animal(type)
- [type]
- end
-
- map "hid" => "hidden"
-
- desc "hidden TYPE", "this is hidden", :hide => true
- def hidden(type)
- [type]
- end
-
- map "fu" => "zoo"
-
- desc "foo BAR", <<END
-do some fooing
- This is more info!
- Everyone likes more info!
-END
- method_option :force, :type => :boolean, :desc => "Force to do some fooing"
- def foo(bar)
- [bar, options]
- end
-
- desc "example_default_command", "example!"
- method_options :with => :string
- def example_default_command
- options.empty? ? "default command" : options
- end
-
- desc "call_myself_with_wrong_arity", "get the right error"
- def call_myself_with_wrong_arity
- call_myself_with_wrong_arity(4)
- end
-
- desc "call_unexistent_method", "Call unexistent method inside a command"
- def call_unexistent_method
- boom!
- end
-
- desc "long_description", "a" * 80
- long_desc <<-D
- This is a really really really long description.
- Here you go. So very long.
-
- It even has two paragraphs.
- D
- def long_description
- end
-
- desc "name-with-dashes", "Ensure normalization of command names"
- def name_with_dashes
- end
-
- method_options :all => :boolean
- method_option :lazy, :lazy_default => "yes"
- method_option :lazy_numeric, :type => :numeric, :lazy_default => 42
- method_option :lazy_array, :type => :array, :lazy_default => %w[eat at joes]
- method_option :lazy_hash, :type => :hash, :lazy_default => {'swedish' => 'meatballs'}
- desc "with_optional NAME", "invoke with optional name"
- def with_optional(name=nil, *args)
- [name, options, args]
- end
-
- class AnotherScript < Thor
- desc "baz", "do some bazing"
- def baz
- end
- end
-
- desc "send", "send as a command name"
- def send
- true
- end
-
- private
-
- def method_missing(meth, *args)
- if meth == :boom!
- super
- else
- [meth, args]
- end
- end
-
- desc "what", "what"
- def what
- end
-end
-
-class MyChildScript < MyScript
- remove_command :bar
-
- method_options :force => :boolean, :param => :numeric
- def initialize(*args)
- super
- end
-
- desc "zoo", "zoo around"
- method_options :param => :required
- def zoo
- options
- end
-
- desc "animal TYPE", "horse around"
- def animal(type)
- [type, options]
- end
- method_option :other, :type => :string, :default => "method default", :for => :animal
- desc "animal KIND", "fish around", :for => :animal
-
- desc "boom", "explodes everything"
- def boom
- end
-
- remove_command :boom, :undefine => true
-end
-
-class Barn < Thor
- desc "open [ITEM]", "open the barn door"
- def open(item = nil)
- if item == "shotgun"
- puts "That's going to leave a mark."
- else
- puts "Open sesame!"
- end
- end
-
- desc "paint [COLOR]", "paint the barn"
- method_option :coats, :type => :numeric, :default => 2, :desc => 'how many coats of paint'
- def paint(color='red')
- puts "#{options[:coats]} coats of #{color} paint"
- end
-end
-
-class PackageNameScript < Thor
- package_name "Baboon"
-end
-
-module Scripts
- class MyScript < MyChildScript
- argument :accessor, :type => :string
- class_options :force => :boolean
- method_option :new_option, :type => :string, :for => :example_default_command
-
- def zoo
- self.accessor
- end
- end
-
- class MyDefaults < Thor
- check_unknown_options!
-
- namespace :default
- desc "cow", "prints 'moo'"
- def cow
- puts "moo"
- end
-
- desc "command_conflict", "only gets called when prepended with a colon"
- def command_conflict
- puts "command"
- end
-
- desc "barn", "commands to manage the barn"
- subcommand "barn", Barn
- end
-
- class ChildDefault < Thor
- namespace "default:child"
- end
-
- class Arities < Thor
- desc "zero_args", "takes zero args"
- def zero_args
- end
-
- desc "one_arg ARG", "takes one arg"
- def one_arg(arg)
- end
-
- desc "two_args ARG1 ARG2", "takes two args"
- def two_args(arg1, arg2)
- end
-
- desc "optional_arg [ARG]", "takes an optional arg"
- def optional_arg(arg='default')
- end
- end
-end
-
diff --git a/spec/fixtures/subcommand.thor b/spec/fixtures/subcommand.thor
deleted file mode 100644
index 35d0b57..0000000
--- a/spec/fixtures/subcommand.thor
+++ /dev/null
@@ -1,17 +0,0 @@
-module TestSubcommands
-
- class Subcommand < Thor
- desc "print_opt", "My method"
- def print_opt
- print options["opt"]
- end
- end
-
- class Parent < Thor
- class_option "opt"
-
- desc "sub", "My subcommand"
- subcommand "sub", Subcommand
- end
-
-end
diff --git a/spec/group_spec.rb b/spec/group_spec.rb
deleted file mode 100644
index 823318f..0000000
--- a/spec/group_spec.rb
+++ /dev/null
@@ -1,222 +0,0 @@
-require "helper"
-
-describe Thor::Group do
- describe "command" do
- it "allows to use private methods from parent class as commands" do
- expect(ChildGroup.start).to eq(%w[bar foo baz])
- expect(ChildGroup.new.baz("bar")).to eq("bar")
- end
- end
-
- describe "#start" do
- it "invokes all the commands under the Thor group" do
- expect(MyCounter.start(%w[1 2 --third 3])).to eq([1, 2, 3, nil, nil, nil])
- end
-
- it "uses argument's default value" do
- expect(MyCounter.start(%w[1 --third 3])).to eq([1, 2, 3, nil, nil, nil])
- end
-
- it "invokes all the commands in the Thor group and its parents" do
- expect(BrokenCounter.start(%w[1 2 --third 3])).to eq([nil, 2, 3, false, 5, nil])
- end
-
- it "raises an error if a required argument is added after a non-required" do
- expect do
- MyCounter.argument(:foo, :type => :string)
- end.to raise_error(ArgumentError, 'You cannot have "foo" as required argument after the non-required argument "second".')
- end
-
- it "raises when an exception happens within the command call" do
- expect { BrokenCounter.start(%w[1 2 --fail]) }.to raise_error
- end
-
- it "raises an error when a Thor group command expects arguments" do
- expect { WhinyGenerator.start }.to raise_error(ArgumentError, /thor wrong_arity takes 1 argument, but it should not/)
- end
-
- it "invokes help message if any of the shortcuts are given" do
- expect(MyCounter).to receive(:help)
- MyCounter.start(%w[-h])
- end
- end
-
- describe "#desc" do
- it "sets the description for a given class" do
- expect(MyCounter.desc).to eq("Description:\n This generator runs three commands: one, two and three.\n")
- end
-
- it "can be inherited" do
- expect(BrokenCounter.desc).to eq("Description:\n This generator runs three commands: one, two and three.\n")
- end
-
- it "can be nil" do
- expect(WhinyGenerator.desc).to be nil
- end
- end
-
- describe "#help" do
- before do
- @content = capture(:stdout) { MyCounter.help(Thor::Base.shell.new) }
- end
-
- it "provides usage information" do
- expect(@content).to match(/my_counter N \[N\]/)
- end
-
- it "shows description" do
- expect(@content).to match(/Description:/)
- expect(@content).to match(/This generator runs three commands: one, two and three./)
- end
-
- it "shows options information" do
- expect(@content).to match(/Options/)
- expect(@content).to match(/\[\-\-third=THREE\]/)
- end
- end
-
- describe "#invoke" do
- before do
- @content = capture(:stdout) { E.start }
- end
-
- it "allows to invoke a class from the class binding" do
- expect(@content).to match(/1\n2\n3\n4\n5\n/)
- end
-
- it "shows invocation information to the user" do
- expect(@content).to match(/invoke Defined/)
- end
-
- it "uses padding on status generated by the invoked class" do
- expect(@content).to match(/finished counting/)
- end
-
- it "allows invocation to be configured with blocks" do
- capture(:stdout) do
- expect(F.start).to eq(["Valim, Jose"])
- end
- end
-
- it "shows invoked options on help" do
- content = capture(:stdout) { E.help(Thor::Base.shell.new) }
- expect(content).to match(/Defined options:/)
- expect(content).to match(/\[--unused\]/)
- expect(content).to match(/# This option has no use/)
- end
- end
-
- describe "#invoke_from_option" do
- describe "with default type" do
- before do
- @content = capture(:stdout) { G.start }
- end
-
- it "allows to invoke a class from the class binding by a default option" do
- expect(@content).to match(/1\n2\n3\n4\n5\n/)
- end
-
- it "does not invoke if the option is nil" do
- expect(capture(:stdout) { G.start(%w[--skip-invoked]) }).not_to match(/invoke/)
- end
-
- it "prints a message if invocation cannot be found" do
- content = capture(:stdout) { G.start(%w[--invoked unknown]) }
- expect(content).to match(/error unknown \[not found\]/)
- end
-
- it "allows to invoke a class from the class binding by the given option" do
- error = nil
- content = capture(:stdout) do
- error = capture(:stderr) do
- G.start(%w[--invoked e])
- end
- end
- expect(content).to match(/invoke e/)
- expect(error).to match(/ERROR: "thor two" was called with arguments/)
- end
-
- it "shows invocation information to the user" do
- expect(@content).to match(/invoke defined/)
- end
-
- it "uses padding on status generated by the invoked class" do
- expect(@content).to match(/finished counting/)
- end
-
- it "shows invoked options on help" do
- content = capture(:stdout) { G.help(Thor::Base.shell.new) }
- expect(content).to match(/defined options:/)
- expect(content).to match(/\[--unused\]/)
- expect(content).to match(/# This option has no use/)
- end
- end
-
- describe "with boolean type" do
- before do
- @content = capture(:stdout) { H.start }
- end
-
- it "allows to invoke a class from the class binding by a default option" do
- expect(@content).to match(/1\n2\n3\n4\n5\n/)
- end
-
- it "does not invoke if the option is false" do
- expect(capture(:stdout) { H.start(%w[--no-defined]) }).not_to match(/invoke/)
- end
-
- it "shows invocation information to the user" do
- expect(@content).to match(/invoke defined/)
- end
-
- it "uses padding on status generated by the invoked class" do
- expect(@content).to match(/finished counting/)
- end
-
- it "shows invoked options on help" do
- content = capture(:stdout) { H.help(Thor::Base.shell.new) }
- expect(content).to match(/defined options:/)
- expect(content).to match(/\[--unused\]/)
- expect(content).to match(/# This option has no use/)
- end
- end
- end
-
- describe "edge-cases" do
- it "can handle boolean options followed by arguments" do
- klass = Class.new(Thor::Group) do
- desc "say hi to name"
- argument :name, :type => :string
- class_option :loud, :type => :boolean
-
- def hi
- name.upcase! if options[:loud]
- "Hi #{name}"
- end
- end
-
- expect(klass.start(%w[jose])).to eq(["Hi jose"])
- expect(klass.start(%w[jose --loud])).to eq(["Hi JOSE"])
- expect(klass.start(%w[--loud jose])).to eq(["Hi JOSE"])
- end
-
- it "provides extra args as `args`" do
- klass = Class.new(Thor::Group) do
- desc "say hi to name"
- argument :name, :type => :string
- class_option :loud, :type => :boolean
-
- def hi
- name.upcase! if options[:loud]
- out = "Hi #{name}"
- out << ": " << args.join(", ") unless args.empty?
- out
- end
- end
-
- expect(klass.start(%w[jose])).to eq(["Hi jose"])
- expect(klass.start(%w[jose --loud])).to eq(["Hi JOSE"])
- expect(klass.start(%w[--loud jose])).to eq(["Hi JOSE"])
- end
- end
-end
diff --git a/spec/helper.rb b/spec/helper.rb
deleted file mode 100644
index fbdb4ce..0000000
--- a/spec/helper.rb
+++ /dev/null
@@ -1,80 +0,0 @@
-$TESTING = true
-
-require "simplecov"
-require "coveralls"
-
-SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
- SimpleCov::Formatter::HTMLFormatter,
- Coveralls::SimpleCov::Formatter
-]
-
-SimpleCov.start do
- add_filter "/spec/"
- minimum_coverage(92.21)
-end
-
-$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
-require "thor"
-require "thor/group"
-require "stringio"
-
-require "rdoc"
-require "rspec"
-require "diff/lcs" # You need diff/lcs installed to run specs (but not to run Thor).
-require "fakeweb" # You need fakeweb installed to run specs (but not to run Thor).
-
-# Set shell to basic
-$0 = "thor"
-$thor_runner = true
-ARGV.clear
-Thor::Base.shell = Thor::Shell::Basic
-
-# Load fixtures
-load File.join(File.dirname(__FILE__), "fixtures", "enum.thor")
-load File.join(File.dirname(__FILE__), "fixtures", "group.thor")
-load File.join(File.dirname(__FILE__), "fixtures", "invoke.thor")
-load File.join(File.dirname(__FILE__), "fixtures", "script.thor")
-load File.join(File.dirname(__FILE__), "fixtures", "subcommand.thor")
-load File.join(File.dirname(__FILE__), "fixtures", "command.thor")
-
-RSpec.configure do |config|
- config.before do
- ARGV.replace []
- end
-
- config.expect_with :rspec do |c|
- c.syntax = :expect
- end
-
- def capture(stream)
- begin
- stream = stream.to_s
- eval "$#{stream} = StringIO.new"
- yield
- result = eval("$#{stream}").string
- ensure
- eval("$#{stream} = #{stream.upcase}")
- end
-
- result
- end
-
- def source_root
- File.join(File.dirname(__FILE__), "fixtures")
- end
-
- def destination_root
- File.join(File.dirname(__FILE__), "sandbox")
- end
-
- # This code was adapted from Ruby on Rails, available under MIT-LICENSE
- # Copyright (c) 2004-2013 David Heinemeier Hansson
- def silence_warnings
- old_verbose, $VERBOSE = $VERBOSE, nil
- yield
- ensure
- $VERBOSE = old_verbose
- end
-
- alias silence capture
-end
diff --git a/spec/invocation_spec.rb b/spec/invocation_spec.rb
deleted file mode 100644
index 01160d2..0000000
--- a/spec/invocation_spec.rb
+++ /dev/null
@@ -1,120 +0,0 @@
-require "helper"
-require "thor/base"
-
-describe Thor::Invocation do
- describe "#invoke" do
- it "invokes a command inside another command" do
- expect(capture(:stdout) { A.new.invoke(:two) }).to eq("2\n3\n")
- end
-
- it "invokes a command just once" do
- expect(capture(:stdout) { A.new.invoke(:one) }).to eq("1\n2\n3\n")
- end
-
- it "invokes a command just once even if they belongs to different classes" do
- expect(capture(:stdout) { Defined.new.invoke(:one) }).to eq("1\n2\n3\n4\n5\n")
- end
-
- it "invokes a command with arguments" do
- expect(A.new.invoke(:five, [5])).to be true
- expect(A.new.invoke(:five, [7])).to be false
- end
-
- it "invokes the default command if none is given to a Thor class" do
- content = capture(:stdout) { A.new.invoke("b") }
- expect(content).to match(/Commands/)
- expect(content).to match(/LAST_NAME/)
- end
-
- it "accepts a class as argument without a command to invoke" do
- content = capture(:stdout) { A.new.invoke(B) }
- expect(content).to match(/Commands/)
- expect(content).to match(/LAST_NAME/)
- end
-
- it "accepts a class as argument with a command to invoke" do
- base = A.new([], :last_name => "Valim")
- expect(base.invoke(B, :one, %w[Jose])).to eq("Valim, Jose")
- end
-
- it "allows customized options to be given" do
- base = A.new([], :last_name => "Wrong")
- expect(base.invoke(B, :one, %w[Jose], :last_name => "Valim")).to eq("Valim, Jose")
- end
-
- it "reparses options in the new class" do
- expect(A.start(%w[invoker --last-name Valim])).to eq("Valim, Jose")
- end
-
- it "shares initialize options with invoked class" do
- expect(A.new([], :foo => :bar).invoke("b:two")).to eq("foo" => :bar)
- end
-
- it "uses default options from invoked class if no matching arguments are given" do
- expect(A.new([]).invoke("b:four")).to eq("default")
- end
-
- it "overrides default options if options are passed to the invoker" do
- expect(A.new([], :defaulted_value => "not default").invoke("b:four")).to eq("not default")
- end
-
- it "returns the command chain" do
- expect(I.new.invoke("two")).to eq([:two])
-
- if RUBY_VERSION < "1.9.3"
- result = J.start(["one", "two" ])
- expect(result).to include(:one)
- expect(result).to include(:two)
- else
- expect(J.start(["one", "two" ])).to eq([:one, :two])
- end
- end
-
- it "dump configuration values to be used in the invoked class" do
- base = A.new
- expect(base.invoke("b:three").shell).to eq(base.shell)
- end
-
- it "allow extra configuration values to be given" do
- base, shell = A.new, Thor::Base.shell.new
- expect(base.invoke("b:three", [], {}, :shell => shell).shell).to eq(shell)
- end
-
- it "invokes a Thor::Group and all of its commands" do
- expect(capture(:stdout) { A.new.invoke(:c) }).to eq("1\n2\n3\n")
- end
-
- it "does not invoke a Thor::Group twice" do
- base = A.new
- silence(:stdout) { base.invoke(:c) }
- expect(capture(:stdout) { base.invoke(:c) }).to be_empty
- end
-
- it "does not invoke any of Thor::Group commands twice" do
- base = A.new
- silence(:stdout) { base.invoke(:c) }
- expect(capture(:stdout) { base.invoke("c:one") }).to be_empty
- end
-
- it "raises Thor::UndefinedCommandError if the command can't be found" do
- expect do
- A.new.invoke("foo:bar")
- end.to raise_error(Thor::UndefinedCommandError)
- end
-
- it "raises Thor::UndefinedCommandError if the command can't be found even if all commands were already executed" do
- base = C.new
- silence(:stdout) { base.invoke_all }
-
- expect do
- base.invoke("foo:bar")
- end.to raise_error(Thor::UndefinedCommandError)
- end
-
- it "raises an error if a non Thor class is given" do
- expect do
- A.new.invoke(Object)
- end.to raise_error(RuntimeError, "Expected Thor class, got Object")
- end
- end
-end
diff --git a/spec/line_editor/basic_spec.rb b/spec/line_editor/basic_spec.rb
deleted file mode 100644
index 0aefe8c..0000000
--- a/spec/line_editor/basic_spec.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-require "helper"
-
-describe Thor::LineEditor::Basic do
- describe ".available?" do
- it "returns true" do
- expect(Thor::LineEditor::Basic).to be_available
- end
- end
-
- describe "#readline" do
- it "uses $stdin and $stdout to get input from the user" do
- expect($stdout).to receive(:print).with("Enter your name ")
- expect($stdin).to receive(:gets).and_return("George")
- expect($stdin).not_to receive(:noecho)
- editor = Thor::LineEditor::Basic.new("Enter your name ", {})
- expect(editor.readline).to eq("George")
- end
-
- it "disables echo when asked to" do
- expect($stdout).to receive(:print).with("Password: ")
- noecho_stdin = double("noecho_stdin")
- expect(noecho_stdin).to receive(:gets).and_return("secret")
- expect($stdin).to receive(:noecho).and_yield(noecho_stdin)
- editor = Thor::LineEditor::Basic.new("Password: ", :echo => false)
- expect(editor.readline).to eq("secret")
- end
- end
-end
diff --git a/spec/line_editor/readline_spec.rb b/spec/line_editor/readline_spec.rb
deleted file mode 100644
index dda489c..0000000
--- a/spec/line_editor/readline_spec.rb
+++ /dev/null
@@ -1,69 +0,0 @@
-require "helper"
-
-describe Thor::LineEditor::Readline do
- before do
- unless defined? ::Readline
- ::Readline = double("Readline")
- allow(::Readline).to receive(:completion_append_character=).with(nil)
- end
- end
-
- describe ".available?" do
- it "returns true when ::Readline exists" do
- allow(Object).to receive(:const_defined?).with(:Readline).and_return(true)
- expect(described_class).to be_available
- end
-
- it "returns false when ::Readline does not exist" do
- allow(Object).to receive(:const_defined?).with(:Readline).and_return(false)
- expect(described_class).not_to be_available
- end
- end
-
- describe "#readline" do
- it "invokes the readline library" do
- expect(::Readline).to receive(:readline).with("> ", true).and_return("foo")
- expect(::Readline).not_to receive(:completion_proc=)
- editor = Thor::LineEditor::Readline.new("> ", {})
- expect(editor.readline).to eq("foo")
- end
-
- it "supports the add_to_history option" do
- expect(::Readline).to receive(:readline).with("> ", false).and_return("foo")
- expect(::Readline).not_to receive(:completion_proc=)
- editor = Thor::LineEditor::Readline.new("> ", :add_to_history => false)
- expect(editor.readline).to eq("foo")
- end
-
- it "provides tab completion when given a limited_to option" do
- expect(::Readline).to receive(:readline)
- expect(::Readline).to receive(:completion_proc=) do |proc|
- expect(proc.call("")).to eq %w[Apples Chicken Chocolate]
- expect(proc.call("Ch")).to eq %w[Chicken Chocolate]
- expect(proc.call("Chi")).to eq ["Chicken"]
- end
-
- editor = Thor::LineEditor::Readline.new("Best food: ", :limited_to => %w[Apples Chicken Chocolate])
- editor.readline
- end
-
- it "provides path tab completion when given the path option" do
- expect(::Readline).to receive(:readline)
- expect(::Readline).to receive(:completion_proc=) do |proc|
- expect(proc.call("../line_ed").sort).to eq ["../line_editor/", "../line_editor_spec.rb"].sort
- end
-
- editor = Thor::LineEditor::Readline.new("Path to file: ", :path => true)
- Dir.chdir(File.dirname(__FILE__)) { editor.readline }
- end
-
- it "uses STDIN when asked not to echo input" do
- expect($stdout).to receive(:print).with("Password: ")
- noecho_stdin = double("noecho_stdin")
- expect(noecho_stdin).to receive(:gets).and_return("secret")
- expect($stdin).to receive(:noecho).and_yield(noecho_stdin)
- editor = Thor::LineEditor::Readline.new("Password: ", :echo => false)
- expect(editor.readline).to eq("secret")
- end
- end
-end
diff --git a/spec/line_editor_spec.rb b/spec/line_editor_spec.rb
deleted file mode 100644
index 575fd33..0000000
--- a/spec/line_editor_spec.rb
+++ /dev/null
@@ -1,43 +0,0 @@
-require "helper"
-
-describe Thor::LineEditor, "on a system with Readline support" do
- before do
- @original_readline = ::Readline if defined? ::Readline
- silence_warnings { ::Readline = double("Readline") }
- end
-
- after do
- silence_warnings { ::Readline = @original_readline }
- end
-
- describe ".readline" do
- it "uses the Readline line editor" do
- editor = double("Readline")
- expect(Thor::LineEditor::Readline).to receive(:new).with("Enter your name ", :default => "Brian").and_return(editor)
- expect(editor).to receive(:readline).and_return("George")
- expect(Thor::LineEditor.readline("Enter your name ", :default => "Brian")).to eq("George")
- end
- end
-end
-
-describe Thor::LineEditor, "on a system without Readline support" do
- before do
- if defined? ::Readline
- @original_readline = ::Readline
- Object.send(:remove_const, :Readline)
- end
- end
-
- after do
- silence_warnings { ::Readline = @original_readline }
- end
-
- describe ".readline" do
- it "uses the Basic line editor" do
- editor = double("Basic")
- expect(Thor::LineEditor::Basic).to receive(:new).with("Enter your name ", :default => "Brian").and_return(editor)
- expect(editor).to receive(:readline).and_return("George")
- expect(Thor::LineEditor.readline("Enter your name ", :default => "Brian")).to eq("George")
- end
- end
-end
diff --git a/spec/parser/argument_spec.rb b/spec/parser/argument_spec.rb
deleted file mode 100644
index 0b1c1cc..0000000
--- a/spec/parser/argument_spec.rb
+++ /dev/null
@@ -1,53 +0,0 @@
-require "helper"
-require "thor/parser"
-
-describe Thor::Argument do
-
- def argument(name, options = {})
- @argument ||= Thor::Argument.new(name, options)
- end
-
- describe "errors" do
- it "raises an error if name is not supplied" do
- expect do
- argument(nil)
- end.to raise_error(ArgumentError, "Argument name can't be nil.")
- end
-
- it "raises an error if type is unknown" do
- expect do
- argument(:command, :type => :unknown)
- end.to raise_error(ArgumentError, "Type :unknown is not valid for arguments.")
- end
-
- it "raises an error if argument is required and has default values" do
- expect do
- argument(:command, :type => :string, :default => "bar", :required => true)
- end.to raise_error(ArgumentError, "An argument cannot be required and have default value.")
- end
-
- it "raises an error if enum isn't an array" do
- expect do
- argument(:command, :type => :string, :enum => "bar")
- end.to raise_error(ArgumentError, "An argument cannot have an enum other than an array.")
- end
- end
-
- describe "#usage" do
- it "returns usage for string types" do
- expect(argument(:foo, :type => :string).usage).to eq("FOO")
- end
-
- it "returns usage for numeric types" do
- expect(argument(:foo, :type => :numeric).usage).to eq("N")
- end
-
- it "returns usage for array types" do
- expect(argument(:foo, :type => :array).usage).to eq("one two three")
- end
-
- it "returns usage for hash types" do
- expect(argument(:foo, :type => :hash).usage).to eq("key:value")
- end
- end
-end
diff --git a/spec/parser/arguments_spec.rb b/spec/parser/arguments_spec.rb
deleted file mode 100644
index bb77378..0000000
--- a/spec/parser/arguments_spec.rb
+++ /dev/null
@@ -1,66 +0,0 @@
-require "helper"
-require "thor/parser"
-
-describe Thor::Arguments do
- def create(opts = {})
- arguments = opts.map do |type, default|
- options = {:required => default.nil?, :type => type, :default => default}
- Thor::Argument.new(type.to_s, options)
- end
-
- arguments.sort! { |a, b| b.name <=> a.name }
- @opt = Thor::Arguments.new(arguments)
- end
-
- def parse(*args)
- @opt.parse(args)
- end
-
- describe "#parse" do
- it "parses arguments in the given order" do
- create :string => nil, :numeric => nil
- expect(parse("name", "13")["string"]).to eq("name")
- expect(parse("name", "13")["numeric"]).to eq(13)
- end
-
- it "accepts hashes" do
- create :string => nil, :hash => nil
- expect(parse("product", "title:string", "age:integer")["string"]).to eq("product")
- expect(parse("product", "title:string", "age:integer")["hash"]).to eq("title" => "string", "age" => "integer")
- expect(parse("product", "url:http://www.amazon.com/gp/product/123")["hash"]).to eq("url" => "http://www.amazon.com/gp/product/123")
- end
-
- it "accepts arrays" do
- create :string => nil, :array => nil
- expect(parse("product", "title", "age")["string"]).to eq("product")
- expect(parse("product", "title", "age")["array"]).to eq(%w[title age])
- end
-
- describe "with no inputs" do
- it "and no arguments returns an empty hash" do
- create
- expect(parse).to eq({})
- end
-
- it "and required arguments raises an error" do
- create :string => nil, :numeric => nil
- expect { parse }.to raise_error(Thor::RequiredArgumentMissingError, "No value provided for required arguments 'string', 'numeric'")
- end
-
- it "and default arguments returns default values" do
- create :string => "name", :numeric => 13
- expect(parse).to eq("string" => "name", "numeric" => 13)
- end
- end
-
- it "returns the input if it's already parsed" do
- create :string => nil, :hash => nil, :array => nil, :numeric => nil
- expect(parse("", 0, {}, [])).to eq("string" => "", "numeric" => 0, "hash" => {}, "array" => [])
- end
-
- it "returns the default value if none is provided" do
- create :string => "foo", :numeric => 3.0
- expect(parse("bar")).to eq("string" => "bar", "numeric" => 3.0)
- end
- end
-end
diff --git a/spec/parser/option_spec.rb b/spec/parser/option_spec.rb
deleted file mode 100644
index 29f5dc5..0000000
--- a/spec/parser/option_spec.rb
+++ /dev/null
@@ -1,210 +0,0 @@
-require "helper"
-require "thor/parser"
-
-describe Thor::Option do
- def parse(key, value)
- Thor::Option.parse(key, value)
- end
-
- def option(name, options = {})
- @option ||= Thor::Option.new(name, options)
- end
-
- describe "#parse" do
-
- describe "with value as a symbol" do
- describe "and symbol is a valid type" do
- it "has type equals to the symbol" do
- expect(parse(:foo, :string).type).to eq(:string)
- expect(parse(:foo, :numeric).type).to eq(:numeric)
- end
-
- it "has no default value" do
- expect(parse(:foo, :string).default).to be nil
- expect(parse(:foo, :numeric).default).to be nil
- end
- end
-
- describe "equals to :required" do
- it "has type equals to :string" do
- expect(parse(:foo, :required).type).to eq(:string)
- end
-
- it "has no default value" do
- expect(parse(:foo, :required).default).to be nil
- end
- end
-
- describe "and symbol is not a reserved key" do
- it "has type equal to :string" do
- expect(parse(:foo, :bar).type).to eq(:string)
- end
-
- it "has no default value" do
- expect(parse(:foo, :bar).default).to be nil
- end
- end
- end
-
- describe "with value as hash" do
- it "has default type :hash" do
- expect(parse(:foo, :a => :b).type).to eq(:hash)
- end
-
- it "has default value equal to the hash" do
- expect(parse(:foo, :a => :b).default).to eq(:a => :b)
- end
- end
-
- describe "with value as array" do
- it "has default type :array" do
- expect(parse(:foo, [:a, :b]).type).to eq(:array)
- end
-
- it "has default value equal to the array" do
- expect(parse(:foo, [:a, :b]).default).to eq([:a, :b])
- end
- end
-
- describe "with value as string" do
- it "has default type :string" do
- expect(parse(:foo, "bar").type).to eq(:string)
- end
-
- it "has default value equal to the string" do
- expect(parse(:foo, "bar").default).to eq("bar")
- end
- end
-
- describe "with value as numeric" do
- it "has default type :numeric" do
- expect(parse(:foo, 2.0).type).to eq(:numeric)
- end
-
- it "has default value equal to the numeric" do
- expect(parse(:foo, 2.0).default).to eq(2.0)
- end
- end
-
- describe "with value as boolean" do
- it "has default type :boolean" do
- expect(parse(:foo, true).type).to eq(:boolean)
- expect(parse(:foo, false).type).to eq(:boolean)
- end
-
- it "has default value equal to the boolean" do
- expect(parse(:foo, true).default).to eq(true)
- expect(parse(:foo, false).default).to eq(false)
- end
- end
-
- describe "with key as a symbol" do
- it "sets the name equal to the key" do
- expect(parse(:foo, true).name).to eq("foo")
- end
- end
-
- describe "with key as an array" do
- it "sets the first items in the array to the name" do
- expect(parse([:foo, :bar, :baz], true).name).to eq("foo")
- end
-
- it "sets all other items as aliases" do
- expect(parse([:foo, :bar, :baz], true).aliases).to eq([:bar, :baz])
- end
- end
- end
-
- it "returns the switch name" do
- expect(option("foo").switch_name).to eq("--foo")
- expect(option("--foo").switch_name).to eq("--foo")
- end
-
- it "returns the human name" do
- expect(option("foo").human_name).to eq("foo")
- expect(option("--foo").human_name).to eq("foo")
- end
-
- it "converts underscores to dashes" do
- expect(option("foo_bar").switch_name).to eq("--foo-bar")
- end
-
- it "can be required and have default values" do
- option = option("foo", :required => true, :type => :string, :default => "bar")
- expect(option.default).to eq("bar")
- expect(option).to be_required
- end
-
- it "boolean options cannot be required" do
- expect do
- option("foo", :required => true, :type => :boolean)
- end.to raise_error(ArgumentError, "An option cannot be boolean and required.")
- end
-
- it "allows type predicates" do
- expect(parse(:foo, :string)).to be_string
- expect(parse(:foo, :boolean)).to be_boolean
- expect(parse(:foo, :numeric)).to be_numeric
- end
-
- it "raises an error on method missing" do
- expect do
- parse(:foo, :string).unknown?
- end.to raise_error(NoMethodError)
- end
-
- describe "#usage" do
-
- it "returns usage for string types" do
- expect(parse(:foo, :string).usage).to eq("[--foo=FOO]")
- end
-
- it "returns usage for numeric types" do
- expect(parse(:foo, :numeric).usage).to eq("[--foo=N]")
- end
-
- it "returns usage for array types" do
- expect(parse(:foo, :array).usage).to eq("[--foo=one two three]")
- end
-
- it "returns usage for hash types" do
- expect(parse(:foo, :hash).usage).to eq("[--foo=key:value]")
- end
-
- it "returns usage for boolean types" do
- expect(parse(:foo, :boolean).usage).to eq("[--foo], [--no-foo]")
- end
-
- it "does not use padding when no aliases are given" do
- expect(parse(:foo, :boolean).usage).to eq("[--foo], [--no-foo]")
- end
-
- it "documents a negative option when boolean" do
- expect(parse(:foo, :boolean).usage).to include("[--no-foo]")
- end
-
- it "uses banner when supplied" do
- expect(option(:foo, :required => false, :type => :string, :banner => "BAR").usage).to eq("[--foo=BAR]")
- end
-
- it "checks when banner is an empty string" do
- expect(option(:foo, :required => false, :type => :string, :banner => "").usage).to eq("[--foo]")
- end
-
- describe "with required values" do
- it "does not show the usage between brackets" do
- expect(parse(:foo, :required).usage).to eq("--foo=FOO")
- end
- end
-
- describe "with aliases" do
- it "does not show the usage between brackets" do
- expect(parse([:foo, "-f", "-b"], :required).usage).to eq("-f, -b, --foo=FOO")
- end
-
- it "does not negate the aliases" do
- expect(parse([:foo, "-f", "-b"], :boolean).usage).to eq("-f, -b, [--foo], [--no-foo]")
- end
- end
- end
-end
diff --git a/spec/parser/options_spec.rb b/spec/parser/options_spec.rb
deleted file mode 100644
index 61a86de..0000000
--- a/spec/parser/options_spec.rb
+++ /dev/null
@@ -1,414 +0,0 @@
-require "helper"
-require "thor/parser"
-
-describe Thor::Options do
- def create(opts, defaults = {}, stop_on_unknown = false)
- opts.each do |key, value|
- opts[key] = Thor::Option.parse(key, value) unless value.is_a?(Thor::Option)
- end
-
- @opt = Thor::Options.new(opts, defaults, stop_on_unknown)
- end
-
- def parse(*args)
- @opt.parse(args.flatten)
- end
-
- def check_unknown!
- @opt.check_unknown!
- end
-
- def remaining
- @opt.remaining
- end
-
- describe "#to_switches" do
- it "turns true values into a flag" do
- expect(Thor::Options.to_switches(:color => true)).to eq("--color")
- end
-
- it "ignores nil" do
- expect(Thor::Options.to_switches(:color => nil)).to eq("")
- end
-
- it "ignores false" do
- expect(Thor::Options.to_switches(:color => false)).to eq("")
- end
-
- it "writes --name value for anything else" do
- expect(Thor::Options.to_switches(:format => "specdoc")).to eq('--format "specdoc"')
- end
-
- it "joins several values" do
- switches = Thor::Options.to_switches(:color => true, :foo => "bar").split(" ").sort
- expect(switches).to eq(%w["bar" --color --foo])
- end
-
- it "accepts arrays" do
- expect(Thor::Options.to_switches(:count => [1, 2, 3])).to eq("--count 1 2 3")
- end
-
- it "accepts hashes" do
- expect(Thor::Options.to_switches(:count => {:a => :b})).to eq("--count a:b")
- end
-
- it "accepts underscored options" do
- expect(Thor::Options.to_switches(:under_score_option => "foo bar")).to eq('--under_score_option "foo bar"')
- end
-
- end
-
- describe "#parse" do
- it "allows multiple aliases for a given switch" do
- create %w[--foo --bar --baz] => :string
- expect(parse("--foo", "12")["foo"]).to eq("12")
- expect(parse("--bar", "12")["foo"]).to eq("12")
- expect(parse("--baz", "12")["foo"]).to eq("12")
- end
-
- it "allows custom short names" do
- create "-f" => :string
- expect(parse("-f", "12")).to eq("f" => "12")
- end
-
- it "allows custom short-name aliases" do
- create %w[--bar -f] => :string
- expect(parse("-f", "12")).to eq("bar" => "12")
- end
-
- it "accepts conjoined short switches" do
- create %w[--foo -f] => true, %w[--bar -b] => true, %w[--app -a] => true
- opts = parse("-fba")
- expect(opts["foo"]).to be true
- expect(opts["bar"]).to be true
- expect(opts["app"]).to be true
- end
-
- it "accepts conjoined short switches with input" do
- create %w[--foo -f] => true, %w[--bar -b] => true, %w[--app -a] => :required
- opts = parse "-fba", "12"
- expect(opts["foo"]).to be true
- expect(opts["bar"]).to be true
- expect(opts["app"]).to eq("12")
- end
-
- it "returns the default value if none is provided" do
- create :foo => "baz", :bar => :required
- expect(parse("--bar", "boom")["foo"]).to eq("baz")
- end
-
- it "returns the default value from defaults hash to required arguments" do
- create Hash[:bar => :required], Hash[:bar => "baz"]
- expect(parse["bar"]).to eq("baz")
- end
-
- it "gives higher priority to defaults given in the hash" do
- create Hash[:bar => true], Hash[:bar => false]
- expect(parse["bar"]).to eq(false)
- end
-
- it "raises an error for unknown switches" do
- create :foo => "baz", :bar => :required
- parse("--bar", "baz", "--baz", "unknown")
- expect { check_unknown! }.to raise_error(Thor::UnknownArgumentError, "Unknown switches '--baz'")
- end
-
- it "skips leading non-switches" do
- create(:foo => "baz")
-
- expect(parse("asdf", "--foo", "bar")).to eq("foo" => "bar")
- end
-
- it "correctly recognizes things that look kind of like options, but aren't, as not options" do
- create(:foo => "baz")
- expect(parse("--asdf---asdf", "baz", "--foo", "--asdf---dsf--asdf")).to eq("foo" => "--asdf---dsf--asdf")
- check_unknown!
- end
-
- it "accepts underscores in commandline args hash for boolean" do
- create :foo_bar => :boolean
- expect(parse("--foo_bar")["foo_bar"]).to eq(true)
- expect(parse("--no_foo_bar")["foo_bar"]).to eq(false)
- end
-
- it "accepts underscores in commandline args hash for strings" do
- create :foo_bar => :string, :baz_foo => :string
- expect(parse("--foo_bar", "baz")["foo_bar"]).to eq("baz")
- expect(parse("--baz_foo", "foo bar")["baz_foo"]).to eq("foo bar")
- end
-
- it "interprets everything after -- as args instead of options" do
- create(:foo => :string, :bar => :required)
- expect(parse(%w[--bar abc moo -- --foo def -a])).to eq("bar" => "abc")
- expect(remaining).to eq(%w[moo --foo def -a])
- end
-
- it "ignores -- when looking for single option values" do
- create(:foo => :string, :bar => :required)
- expect(parse(%w[--bar -- --foo def -a])).to eq("bar" => "--foo")
- expect(remaining).to eq(%w[def -a])
- end
-
- it "ignores -- when looking for array option values" do
- create(:foo => :array)
- expect(parse(%w[--foo a b -- c d -e])).to eq("foo" => %w[a b c d -e])
- expect(remaining).to eq([])
- end
-
- it "ignores -- when looking for hash option values" do
- create(:foo => :hash)
- expect(parse(%w[--foo a:b -- c:d -e])).to eq("foo" => {"a" => "b", "c" => "d"})
- expect(remaining).to eq(%w[-e])
- end
-
- it "ignores trailing --" do
- create(:foo => :string)
- expect(parse(%w[--foo --])).to eq("foo" => nil)
- expect(remaining).to eq([])
- end
-
- describe "with no input" do
- it "and no switches returns an empty hash" do
- create({})
- expect(parse).to eq({})
- end
-
- it "and several switches returns an empty hash" do
- create "--foo" => :boolean, "--bar" => :string
- expect(parse).to eq({})
- end
-
- it "and a required switch raises an error" do
- create "--foo" => :required
- expect { parse }.to raise_error(Thor::RequiredArgumentMissingError, "No value provided for required options '--foo'")
- end
- end
-
- describe "with one required and one optional switch" do
- before do
- create "--foo" => :required, "--bar" => :boolean
- end
-
- it "raises an error if the required switch has no argument" do
- expect { parse("--foo") }.to raise_error(Thor::MalformattedArgumentError)
- end
-
- it "raises an error if the required switch isn't given" do
- expect { parse("--bar") }.to raise_error(Thor::RequiredArgumentMissingError)
- end
-
- it "raises an error if the required switch is set to nil" do
- expect { parse("--no-foo") }.to raise_error(Thor::RequiredArgumentMissingError)
- end
-
- it "does not raises an error if the required option has a default value" do
- options = {:required => true, :type => :string, :default => "baz"}
- create :foo => Thor::Option.new("foo", options), :bar => :boolean
- expect { parse("--bar") }.not_to raise_error
- end
- end
-
- context "when stop_on_unknown is true" do
- before do
- create({:foo => :string, :verbose => :boolean}, {}, true)
- end
-
- it "stops parsing on first non-option" do
- expect(parse(%w[foo --verbose])).to eq({})
- expect(remaining).to eq(%w[foo --verbose])
- end
-
- it "stops parsing on unknown option" do
- expect(parse(%w[--bar --verbose])).to eq({})
- expect(remaining).to eq(%w[--bar --verbose])
- end
-
- it "retains -- after it has stopped parsing" do
- expect(parse(%w[--bar -- whatever])).to eq({})
- expect(remaining).to eq(%w[--bar -- whatever])
- end
-
- it "still accepts options that are given before non-options" do
- expect(parse(%w[--verbose foo])).to eq("verbose" => true)
- expect(remaining).to eq(%w[foo])
- end
-
- it "still accepts options that require a value" do
- expect(parse(%w[--foo bar baz])).to eq("foo" => "bar")
- expect(remaining).to eq(%w[baz])
- end
-
- it "still interprets everything after -- as args instead of options" do
- expect(parse(%w[-- --verbose])).to eq({})
- expect(remaining).to eq(%w[--verbose])
- end
- end
-
- describe "with :string type" do
- before do
- create %w[--foo -f] => :required
- end
-
- it "accepts a switch <value> assignment" do
- expect(parse("--foo", "12")["foo"]).to eq("12")
- end
-
- it "accepts a switch=<value> assignment" do
- expect(parse("-f=12")["foo"]).to eq("12")
- expect(parse("--foo=12")["foo"]).to eq("12")
- expect(parse("--foo=bar=baz")["foo"]).to eq("bar=baz")
- end
-
- it "must accept underscores switch=value assignment" do
- create :foo_bar => :required
- expect(parse("--foo_bar=http://example.com/under_score/")["foo_bar"]).to eq("http://example.com/under_score/")
- end
-
- it "accepts a --no-switch format" do
- create "--foo" => "bar"
- expect(parse("--no-foo")["foo"]).to be nil
- end
-
- it "does not consume an argument for --no-switch format" do
- create "--cheese" => :string
- expect(parse("burger", "--no-cheese", "fries")["cheese"]).to be nil
- end
-
- it "accepts a --switch format on non required types" do
- create "--foo" => :string
- expect(parse("--foo")["foo"]).to eq("foo")
- end
-
- it "accepts a --switch format on non required types with default values" do
- create "--baz" => :string, "--foo" => "bar"
- expect(parse("--baz", "bang", "--foo")["foo"]).to eq("bar")
- end
-
- it "overwrites earlier values with later values" do
- expect(parse("--foo=bar", "--foo", "12")["foo"]).to eq("12")
- expect(parse("--foo", "12", "--foo", "13")["foo"]).to eq("13")
- end
-
- it "raises error when value isn't in enum" do
- enum = %w[apple banana]
- create :fruit => Thor::Option.new("fruit", :type => :string, :enum => enum)
- expect { parse("--fruit", "orange") }.to raise_error(Thor::MalformattedArgumentError,
- "Expected '--fruit' to be one of #{enum.join(', ')}; got orange")
- end
- end
-
- describe "with :boolean type" do
- before do
- create "--foo" => false
- end
-
- it "accepts --opt assignment" do
- expect(parse("--foo")["foo"]).to eq(true)
- expect(parse("--foo", "--bar")["foo"]).to eq(true)
- end
-
- it "uses the default value if no switch is given" do
- expect(parse("")["foo"]).to eq(false)
- end
-
- it "accepts --opt=value assignment" do
- expect(parse("--foo=true")["foo"]).to eq(true)
- expect(parse("--foo=false")["foo"]).to eq(false)
- end
-
- it "accepts --[no-]opt variant, setting false for value" do
- expect(parse("--no-foo")["foo"]).to eq(false)
- end
-
- it "accepts --[skip-]opt variant, setting false for value" do
- expect(parse("--skip-foo")["foo"]).to eq(false)
- end
-
- it "will prefer 'no-opt' variant over inverting 'opt' if explicitly set" do
- create "--no-foo" => true
- expect(parse("--no-foo")["no-foo"]).to eq(true)
- end
-
- it "will prefer 'skip-opt' variant over inverting 'opt' if explicitly set" do
- create "--skip-foo" => true
- expect(parse("--skip-foo")["skip-foo"]).to eq(true)
- end
-
- it "accepts inputs in the human name format" do
- create :foo_bar => :boolean
- expect(parse("--foo-bar")["foo_bar"]).to eq(true)
- expect(parse("--no-foo-bar")["foo_bar"]).to eq(false)
- expect(parse("--skip-foo-bar")["foo_bar"]).to eq(false)
- end
-
- it "doesn't eat the next part of the param" do
- create :foo => :boolean
- expect(parse("--foo", "bar")).to eq("foo" => true)
- expect(@opt.remaining).to eq(%w[bar])
- end
- end
-
- describe "with :hash type" do
- before do
- create "--attributes" => :hash
- end
-
- it "accepts a switch=<value> assignment" do
- expect(parse("--attributes=name:string", "age:integer")["attributes"]).to eq("name" => "string", "age" => "integer")
- end
-
- it "accepts a switch <value> assignment" do
- expect(parse("--attributes", "name:string", "age:integer")["attributes"]).to eq("name" => "string", "age" => "integer")
- end
-
- it "must not mix values with other switches" do
- expect(parse("--attributes", "name:string", "age:integer", "--baz", "cool")["attributes"]).to eq("name" => "string", "age" => "integer")
- end
- end
-
- describe "with :array type" do
- before do
- create "--attributes" => :array
- end
-
- it "accepts a switch=<value> assignment" do
- expect(parse("--attributes=a", "b", "c")["attributes"]).to eq(%w[a b c])
- end
-
- it "accepts a switch <value> assignment" do
- expect(parse("--attributes", "a", "b", "c")["attributes"]).to eq(%w[a b c])
- end
-
- it "must not mix values with other switches" do
- expect(parse("--attributes", "a", "b", "c", "--baz", "cool")["attributes"]).to eq(%w[a b c])
- end
- end
-
- describe "with :numeric type" do
- before do
- create "n" => :numeric, "m" => 5
- end
-
- it "accepts a -nXY assignment" do
- expect(parse("-n12")["n"]).to eq(12)
- end
-
- it "converts values to numeric types" do
- expect(parse("-n", "3", "-m", ".5")).to eq("n" => 3, "m" => 0.5)
- end
-
- it "raises error when value isn't numeric" do
- expect { parse("-n", "foo") }.to raise_error(Thor::MalformattedArgumentError,
- "Expected numeric value for '-n'; got \"foo\"")
- end
-
- it "raises error when value isn't in enum" do
- enum = [1, 2]
- create :limit => Thor::Option.new("limit", :type => :numeric, :enum => enum)
- expect { parse("--limit", "3") }.to raise_error(Thor::MalformattedArgumentError,
- "Expected '--limit' to be one of #{enum.join(', ')}; got 3")
- end
- end
-
- end
-end
diff --git a/spec/quality_spec.rb b/spec/quality_spec.rb
deleted file mode 100644
index 94f5100..0000000
--- a/spec/quality_spec.rb
+++ /dev/null
@@ -1,75 +0,0 @@
-if defined?(Encoding) && Encoding.default_external != "UTF-8"
- Encoding.default_external = "UTF-8"
-end
-
-describe "The library itself" do
- def check_for_spec_defs_with_single_quotes(filename)
- failing_lines = []
-
- File.readlines(filename).each_with_index do |line,number|
- failing_lines << number + 1 if line =~ /^ *(describe|it|context) {1}'{1}/
- end
-
- unless failing_lines.empty?
- "#{filename} uses inconsistent single quotes on lines #{failing_lines.join(', ')}"
- end
- end
-
- def check_for_tab_characters(filename)
- failing_lines = []
- File.readlines(filename).each_with_index do |line,number|
- failing_lines << number + 1 if line =~ /\t/
- end
-
- unless failing_lines.empty?
- "#{filename} has tab characters on lines #{failing_lines.join(', ')}"
- end
- end
-
- def check_for_extra_spaces(filename)
- failing_lines = []
- File.readlines(filename).each_with_index do |line,number|
- next if line =~ /^\s+#.*\s+\n$/
- failing_lines << number + 1 if line =~ /\s+\n$/
- end
-
- unless failing_lines.empty?
- "#{filename} has spaces on the EOL on lines #{failing_lines.join(', ')}"
- end
- end
-
- RSpec::Matchers.define :be_well_formed do
- failure_message_for_should do |actual|
- actual.join("\n")
- end
-
- match do |actual|
- actual.empty?
- end
- end
-
- it "has no malformed whitespace" do
- exempt = /\.gitmodules|\.marshal|fixtures|vendor|spec|ssl_certs|LICENSE/
- error_messages = []
- Dir.chdir(File.expand_path("../..", __FILE__)) do
- `git ls-files`.split("\n").each do |filename|
- next if filename =~ exempt
- error_messages << check_for_tab_characters(filename)
- error_messages << check_for_extra_spaces(filename)
- end
- end
- expect(error_messages.compact).to be_well_formed
- end
-
- it "uses double-quotes consistently in specs" do
- included = /spec/
- error_messages = []
- Dir.chdir(File.expand_path("../", __FILE__)) do
- `git ls-files`.split("\n").each do |filename|
- next unless filename =~ included
- error_messages << check_for_spec_defs_with_single_quotes(filename)
- end
- end
- expect(error_messages.compact).to be_well_formed
- end
-end
diff --git a/spec/rake_compat_spec.rb b/spec/rake_compat_spec.rb
deleted file mode 100644
index fac5c9c..0000000
--- a/spec/rake_compat_spec.rb
+++ /dev/null
@@ -1,72 +0,0 @@
-require "helper"
-require "thor/rake_compat"
-require "rake/tasklib"
-
-$main = self
-
-class RakeTask < Rake::TaskLib
- def initialize
- define
- end
-
- def define
- $main.instance_eval do
- desc "Say it's cool"
- task :cool do
- puts "COOL"
- end
-
- namespace :hiper_mega do
- task :super do
- puts "HIPER MEGA SUPER"
- end
- end
- end
- end
-end
-
-class ThorTask < Thor
- include Thor::RakeCompat
- RakeTask.new
-end
-
-describe Thor::RakeCompat do
- it "sets the rakefile application" do
- expect(%w[rake_compat_spec.rb Thorfile]).to include(Rake.application.rakefile)
- end
-
- it "adds rake tasks to thor classes too" do
- task = ThorTask.tasks["cool"]
- expect(task).to be
- end
-
- it "uses rake tasks descriptions on thor" do
- expect(ThorTask.tasks["cool"].description).to eq("Say it's cool")
- end
-
- it "gets usage from rake tasks name" do
- expect(ThorTask.tasks["cool"].usage).to eq("cool")
- end
-
- it "uses non namespaced name as description if non is available" do
- expect(ThorTask::HiperMega.tasks["super"].description).to eq("super")
- end
-
- it "converts namespaces to classes" do
- expect(ThorTask.const_get(:HiperMega)).to eq(ThorTask::HiperMega)
- end
-
- it "does not add tasks from higher namespaces in lowers namespaces" do
- expect(ThorTask.tasks["super"]).not_to be
- end
-
- it "invoking the thor task invokes the rake task" do
- expect(capture(:stdout) do
- ThorTask.start %w[cool]
- end).to eq("COOL\n")
-
- expect(capture(:stdout) do
- ThorTask::HiperMega.start %w[super]
- end).to eq("HIPER MEGA SUPER\n")
- end
-end
diff --git a/spec/register_spec.rb b/spec/register_spec.rb
deleted file mode 100644
index 2a08bae..0000000
--- a/spec/register_spec.rb
+++ /dev/null
@@ -1,227 +0,0 @@
-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
-
-class SubcommandWithDefault < Thor
- default_command :default
-
- desc "default", "default subcommand"
- def default
- puts "default"
- end
-
- desc "with_args", "subcommand with arguments"
- def with_args(*args)
- puts "received arguments: " + args.join(",")
- end
-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")
-
-BoringVendorProvidedCLI.register(SubcommandWithDefault,
- "subcommand", "subcommand", "Run subcommands")
-
-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
-
- context "with a default command," do
- 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
-
- it "displays the subcommand's help message" do
- output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[subcommand help]) }
- expect(output).to include("default subcommand")
- expect(output).to include("subcommand with argument")
- end
-
- it "invokes commands with their actual args" do
- output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[subcommand with_args actual_argument]) }
- expect(output.strip).to eql("received arguments: actual_argument")
- end
- 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
diff --git a/spec/runner_spec.rb b/spec/runner_spec.rb
deleted file mode 100644
index bf76885..0000000
--- a/spec/runner_spec.rb
+++ /dev/null
@@ -1,246 +0,0 @@
-require "helper"
-require "thor/runner"
-
-describe Thor::Runner do
- def when_no_thorfiles_exist
- old_dir = Dir.pwd
- Dir.chdir ".."
- delete = Thor::Base.subclasses.select { |e| e.namespace == "default" }
- delete.each { |e| Thor::Base.subclasses.delete e }
- yield
- Thor::Base.subclasses.concat delete
- Dir.chdir old_dir
- end
-
- describe "#help" do
- it "shows information about Thor::Runner itself" do
- expect(capture(:stdout) { Thor::Runner.start(%w[help]) }).to match(/List the available thor commands/)
- end
-
- it "shows information about a specific Thor::Runner command" do
- content = capture(:stdout) { Thor::Runner.start(%w[help list]) }
- expect(content).to match(/List the available thor commands/)
- expect(content).not_to match(/help \[COMMAND\]/)
- end
-
- it "shows information about a specific Thor class" do
- content = capture(:stdout) { Thor::Runner.start(%w[help my_script]) }
- expect(content).to match(/zoo\s+# zoo around/m)
- end
-
- it "shows information about a specific command from a specific Thor class" do
- content = capture(:stdout) { Thor::Runner.start(%w[help my_script:zoo]) }
- expect(content).to match(/zoo around/)
- expect(content).not_to match(/help \[COMMAND\]/)
- end
-
- it "shows information about a specific Thor group class" do
- content = capture(:stdout) { Thor::Runner.start(%w[help my_counter]) }
- expect(content).to match(/my_counter N/)
- end
-
- it "raises error if a class/command cannot be found" do
- content = capture(:stderr) { Thor::Runner.start(%w[help unknown]) }
- expect(content.strip).to eq('Could not find command "unknown" in "default" namespace.')
- end
-
- it "raises error if a class/command cannot be found for a setup without thorfiles" do
- when_no_thorfiles_exist do
- expect(Thor::Runner).to receive :exit
- content = capture(:stderr) { Thor::Runner.start(%w[help unknown]) }
- expect(content.strip).to eq('Could not find command "unknown".')
- end
- end
- end
-
- describe "#start" do
- it "invokes a command from Thor::Runner" do
- ARGV.replace %w[list]
- expect(capture(:stdout) { Thor::Runner.start }).to match(/my_counter N/)
- end
-
- it "invokes a command from a specific Thor class" do
- ARGV.replace %w[my_script:zoo]
- expect(Thor::Runner.start).to be true
- end
-
- it "invokes the default command from a specific Thor class if none is specified" do
- ARGV.replace %w[my_script]
- expect(Thor::Runner.start).to eq("default command")
- end
-
- it "forwards arguments to the invoked command" do
- ARGV.replace %w[my_script:animal horse]
- expect(Thor::Runner.start).to eq(%w[horse])
- end
-
- it "invokes commands through shortcuts" do
- ARGV.replace %w[my_script -T horse]
- expect(Thor::Runner.start).to eq(%w[horse])
- end
-
- it "invokes a Thor::Group" do
- ARGV.replace %w[my_counter 1 2 --third 3]
- expect(Thor::Runner.start).to eq([1, 2, 3, nil, nil, nil])
- end
-
- it "raises an error if class/command can't be found" do
- ARGV.replace %w[unknown]
- content = capture(:stderr) { Thor::Runner.start }
- expect(content.strip).to eq('Could not find command "unknown" in "default" namespace.')
- end
-
- it "raises an error if class/command can't be found in a setup without thorfiles" do
- when_no_thorfiles_exist do
- ARGV.replace %w[unknown]
- expect(Thor::Runner).to receive :exit
- content = capture(:stderr) { Thor::Runner.start }
- expect(content.strip).to eq('Could not find command "unknown".')
- end
- end
-
- it "does not swallow NoMethodErrors that occur inside the called method" do
- ARGV.replace %w[my_script:call_unexistent_method]
- expect { Thor::Runner.start }.to raise_error(NoMethodError)
- end
-
- it "does not swallow Thor::Group InvocationError" do
- ARGV.replace %w[whiny_generator]
- expect { Thor::Runner.start }.to raise_error(ArgumentError, /thor wrong_arity takes 1 argument, but it should not/)
- end
-
- it "does not swallow Thor InvocationError" do
- ARGV.replace %w[my_script:animal]
- content = capture(:stderr) { Thor::Runner.start }
- expect(content.strip).to eq(%Q(ERROR: "thor animal" was called with no arguments
-Usage: "thor my_script:animal TYPE"))
- end
- end
-
- describe "commands" do
- before do
- @location = "#{File.dirname(__FILE__)}/fixtures/command.thor"
- @original_yaml = {
- "random" => {
- :location => @location,
- :filename => "4a33b894ffce85d7b412fc1b36f88fe0",
- :namespaces => %w[amazing]
- }
- }
-
- root_file = File.join(Thor::Util.thor_root, "thor.yml")
-
- # Stub load and save to avoid thor.yaml from being overwritten
- allow(YAML).to receive(:load_file).and_return(@original_yaml)
- allow(File).to receive(:exist?).with(root_file).and_return(true)
- allow(File).to receive(:open).with(root_file, "w")
- end
-
- describe "list" do
- it "gives a list of the available commands" do
- ARGV.replace %w[list]
- content = capture(:stdout) { Thor::Runner.start }
- expect(content).to match(/amazing:describe NAME\s+# say that someone is amazing/m)
- end
-
- it "gives a list of the available Thor::Group classes" do
- ARGV.replace %w[list]
- expect(capture(:stdout) { Thor::Runner.start }).to match(/my_counter N/)
- end
-
- it "can filter a list of the available commands by --group" do
- ARGV.replace %w[list --group standard]
- expect(capture(:stdout) { Thor::Runner.start }).to match(/amazing:describe NAME/)
- ARGV.replace []
- expect(capture(:stdout) { Thor::Runner.start }).not_to match(/my_script:animal TYPE/)
- ARGV.replace %w[list --group script]
- expect(capture(:stdout) { Thor::Runner.start }).to match(/my_script:animal TYPE/)
- end
-
- it "can skip all filters to show all commands using --all" do
- ARGV.replace %w[list --all]
- content = capture(:stdout) { Thor::Runner.start }
- expect(content).to match(/amazing:describe NAME/)
- expect(content).to match(/my_script:animal TYPE/)
- end
-
- it "doesn't list superclass commands in the subclass" do
- ARGV.replace %w[list]
- expect(capture(:stdout) { Thor::Runner.start }).not_to match(/amazing:help/)
- end
-
- it "presents commands in the default namespace with an empty namespace" do
- ARGV.replace %w[list]
- expect(capture(:stdout) { Thor::Runner.start }).to match(/^thor :cow\s+# prints 'moo'/m)
- end
-
- it "runs commands with an empty namespace from the default namespace" do
- ARGV.replace %w[:command_conflict]
- expect(capture(:stdout) { Thor::Runner.start }).to eq("command\n")
- end
-
- it "runs groups even when there is a command with the same name" do
- ARGV.replace %w[command_conflict]
- expect(capture(:stdout) { Thor::Runner.start }).to eq("group\n")
- end
-
- it "runs commands with no colon in the default namespace" do
- ARGV.replace %w[cow]
- expect(capture(:stdout) { Thor::Runner.start }).to eq("moo\n")
- end
- end
-
- describe "uninstall" do
- before do
- path = File.join(Thor::Util.thor_root, @original_yaml["random"][:filename])
- expect(FileUtils).to receive(:rm_rf).with(path)
- end
-
- it "uninstalls existing thor modules" do
- silence(:stdout) { Thor::Runner.start(%w[uninstall random]) }
- end
- end
-
- describe "installed" do
- before do
- expect(Dir).to receive(:[]).and_return([])
- end
-
- it "displays the modules installed in a pretty way" do
- stdout = capture(:stdout) { Thor::Runner.start(%w[installed]) }
- expect(stdout).to match(/random\s*amazing/)
- expect(stdout).to match(/amazing:describe NAME\s+# say that someone is amazing/m)
- end
- end
-
- describe "install/update" do
- before do
- allow(FileUtils).to receive(:mkdir_p)
- allow(FileUtils).to receive(:touch)
- allow(Thor::LineEditor).to receive(:readline).and_return("Y")
-
- path = File.join(Thor::Util.thor_root, Digest::MD5.hexdigest(@location + "random"))
- expect(File).to receive(:open).with(path, "w")
- end
-
- it "updates existing thor files" do
- path = File.join(Thor::Util.thor_root, @original_yaml["random"][:filename])
- if File.directory? path
- expect(FileUtils).to receive(:rm_rf).with(path)
- else
- expect(File).to receive(:delete).with(path)
- end
- silence_warnings do
- silence(:stdout) { Thor::Runner.start(%w[update random]) }
- end
- end
-
- it "installs thor files" do
- ARGV.replace %W[install #{@location}]
- silence_warnings do
- silence(:stdout) { Thor::Runner.start }
- end
- end
- end
- end
-end
diff --git a/spec/sandbox/application.rb b/spec/sandbox/application.rb
deleted file mode 100644
index 50d2fae..0000000
--- a/spec/sandbox/application.rb
+++ /dev/null
@@ -1,2 +0,0 @@
-class Application < Base
-end
diff --git a/spec/sandbox/app{1}/README b/spec/sandbox/app{1}/README
deleted file mode 100644
index 16374df..0000000
--- a/spec/sandbox/app{1}/README
+++ /dev/null
@@ -1,3 +0,0 @@
-__start__
-README
-__end__
diff --git a/spec/sandbox/bundle/execute.rb b/spec/sandbox/bundle/execute.rb
deleted file mode 100644
index 0530d87..0000000
--- a/spec/sandbox/bundle/execute.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-class Execute < Thor
- desc "ls", "Execute ls"
- def ls
- system "ls"
- end
-end
diff --git a/spec/sandbox/bundle/main.thor b/spec/sandbox/bundle/main.thor
deleted file mode 100644
index 38bdfbc..0000000
--- a/spec/sandbox/bundle/main.thor
+++ /dev/null
@@ -1 +0,0 @@
-require File.join(File.dirname(__FILE__), 'execute')
diff --git a/spec/sandbox/command.thor b/spec/sandbox/command.thor
deleted file mode 100644
index 26a0268..0000000
--- a/spec/sandbox/command.thor
+++ /dev/null
@@ -1,10 +0,0 @@
-# module: random
-
-class Amazing < Thor
- desc "describe NAME", "say that someone is amazing"
- method_options :forcefully => :boolean
- def describe(name, opts)
- ret = "#{name} is amazing"
- puts opts["forcefully"] ? ret.upcase : ret
- end
-end
diff --git a/spec/sandbox/doc/%file_name%.rb.tt b/spec/sandbox/doc/%file_name%.rb.tt
deleted file mode 100644
index 4c4c6c0..0000000
--- a/spec/sandbox/doc/%file_name%.rb.tt
+++ /dev/null
@@ -1 +0,0 @@
-FOO = <%= "FOO" %>
diff --git a/spec/sandbox/doc/COMMENTER b/spec/sandbox/doc/COMMENTER
deleted file mode 100644
index 384cb3a..0000000
--- a/spec/sandbox/doc/COMMENTER
+++ /dev/null
@@ -1,11 +0,0 @@
-__start__
- # greenblue
-#
-# yellowblue
-#yellowred
- #greenred
-orange
- purple
- ind#igo
- # ind#igo
-__end__
diff --git a/spec/sandbox/doc/README b/spec/sandbox/doc/README
deleted file mode 100644
index 16374df..0000000
--- a/spec/sandbox/doc/README
+++ /dev/null
@@ -1,3 +0,0 @@
-__start__
-README
-__end__
diff --git a/spec/sandbox/doc/block_helper.rb b/spec/sandbox/doc/block_helper.rb
deleted file mode 100644
index df59211..0000000
--- a/spec/sandbox/doc/block_helper.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-<% world do -%>
-Hello
-<% end -%>
diff --git a/spec/sandbox/doc/config.rb b/spec/sandbox/doc/config.rb
deleted file mode 100644
index 6211739..0000000
--- a/spec/sandbox/doc/config.rb
+++ /dev/null
@@ -1 +0,0 @@
-class <%= @klass %>; end
diff --git a/spec/sandbox/doc/config.yaml.tt b/spec/sandbox/doc/config.yaml.tt
deleted file mode 100644
index e75615c..0000000
--- a/spec/sandbox/doc/config.yaml.tt
+++ /dev/null
@@ -1 +0,0 @@
---- Hi from yaml
diff --git a/spec/sandbox/doc/excluding/%file_name%.rb.tt b/spec/sandbox/doc/excluding/%file_name%.rb.tt
deleted file mode 100644
index 6296c46..0000000
--- a/spec/sandbox/doc/excluding/%file_name%.rb.tt
+++ /dev/null
@@ -1 +0,0 @@
-BAR = <%= "BAR" %>
diff --git a/spec/sandbox/enum.thor b/spec/sandbox/enum.thor
deleted file mode 100644
index b5a7ded..0000000
--- a/spec/sandbox/enum.thor
+++ /dev/null
@@ -1,10 +0,0 @@
-class Enum < Thor::Group
- include Thor::Actions
-
- desc "snack"
- class_option "fruit", :aliases => "-f", :type => :string, :enum => %w(apple banana)
- def snack
- puts options['fruit']
- end
-
-end
diff --git a/spec/sandbox/group.thor b/spec/sandbox/group.thor
deleted file mode 100644
index bc7e102..0000000
--- a/spec/sandbox/group.thor
+++ /dev/null
@@ -1,128 +0,0 @@
-class MyCounter < Thor::Group
- include Thor::Actions
- add_runtime_options!
-
- def self.get_from_super
- from_superclass(:get_from_super, 13)
- end
-
- source_root File.expand_path(File.dirname(__FILE__))
- source_paths << File.expand_path("broken", File.dirname(__FILE__))
-
- argument :first, :type => :numeric
- argument :second, :type => :numeric, :default => 2
-
- class_option :third, :type => :numeric, :desc => "The third argument", :default => 3,
- :banner => "THREE", :aliases => "-t"
- class_option :fourth, :type => :numeric, :desc => "The fourth argument"
- class_option :simple, :type => :numeric, :aliases => 'z'
- class_option :symbolic, :type => :numeric, :aliases => [:y, :r]
-
- desc <<-FOO
-Description:
- This generator runs three commands: one, two and three.
-FOO
-
- def one
- first
- end
-
- def two
- second
- end
-
- def three
- options[:third]
- end
-
- def four
- options[:fourth]
- end
-
- def five
- options[:simple]
- end
-
- def six
- options[:symbolic]
- end
-
- def self.inherited(base)
- super
- base.source_paths.unshift(File.expand_path(File.join(File.dirname(__FILE__), "doc")))
- end
-
- no_commands do
- def world(&block)
- result = capture(&block)
- concat(result.strip + " world!")
- end
- end
-end
-
-class ClearCounter < MyCounter
- remove_argument :first, :second, :undefine => true
- remove_class_option :third
-
- def self.source_root
- File.expand_path(File.join(File.dirname(__FILE__), "bundle"))
- end
-end
-
-class BrokenCounter < MyCounter
- namespace "app:broken:counter"
- class_option :fail, :type => :boolean, :default => false
-
- class << self
- undef_method :source_root
- end
-
- def one
- options[:first]
- end
-
- def four
- respond_to?(:fail)
- end
-
- def five
- options[:fail] ? this_method_does_not_exist : 5
- end
-end
-
-class WhinyGenerator < Thor::Group
- include Thor::Actions
-
- def self.source_root
- File.expand_path(File.dirname(__FILE__))
- end
-
- def wrong_arity(required)
- end
-end
-
-class CommandConflict < Thor::Group
- desc "A group with the same name as a default command"
- def group
- puts "group"
- end
-end
-
-class ParentGroup < Thor::Group
-private
- def foo
- "foo"
- end
-
- def baz(name = 'baz')
- name
- end
-end
-
-class ChildGroup < ParentGroup
- def bar
- "bar"
- end
-
- public_command :foo, :baz
-end
diff --git a/spec/sandbox/invoke.thor b/spec/sandbox/invoke.thor
deleted file mode 100644
index 0e76e98..0000000
--- a/spec/sandbox/invoke.thor
+++ /dev/null
@@ -1,131 +0,0 @@
-class A < Thor
- include Thor::Actions
-
- desc "one", "invoke one"
- def one
- p 1
- invoke :two
- invoke :three
- end
-
- desc "two", "invoke two"
- def two
- p 2
- invoke :three
- end
-
- desc "three", "invoke three"
- def three
- p 3
- end
-
- desc "four", "invoke four"
- def four
- p 4
- invoke "defined:five"
- end
-
- desc "five N", "check if number is equal 5"
- def five(number)
- number == 5
- end
-
- desc "invoker", "invoke a b command"
- def invoker(*args)
- invoke :b, :one, ["Jose"]
- end
-end
-
-class B < Thor
- class_option :last_name, :type => :string
-
- desc "one FIRST_NAME", "invoke one"
- def one(first_name)
- "#{options.last_name}, #{first_name}"
- end
-
- desc "two", "invoke two"
- def two
- options
- end
-
- desc "three", "invoke three"
- def three
- self
- end
-
- desc "four", "invoke four"
- option :defaulted_value, :type => :string, :default => 'default'
- def four
- options.defaulted_value
- end
-end
-
-class C < Thor::Group
- include Thor::Actions
-
- def one
- p 1
- end
-
- def two
- p 2
- end
-
- def three
- p 3
- end
-end
-
-class Defined < Thor::Group
- class_option :unused, :type => :boolean, :desc => "This option has no use"
-
- def one
- p 1
- invoke "a:two"
- invoke "a:three"
- invoke "a:four"
- invoke "defined:five"
- end
-
- def five
- p 5
- end
-
- def print_status
- say_status :finished, :counting
- end
-end
-
-class E < Thor::Group
- invoke Defined
-end
-
-class F < Thor::Group
- invoke "b:one" do |instance, klass, command|
- instance.invoke klass, command, [ "Jose" ], :last_name => "Valim"
- end
-end
-
-class G < Thor::Group
- class_option :invoked, :type => :string, :default => "defined"
- invoke_from_option :invoked
-end
-
-class H < Thor::Group
- class_option :defined, :type => :boolean, :default => true
- invoke_from_option :defined
-end
-
-class I < Thor
- desc "two", "Two"
- def two
- current_command_chain
- end
-end
-
-class J < Thor
- desc "i", "I"
- subcommand :one, I
-end
-
diff --git a/spec/sandbox/path with spaces b/spec/sandbox/path with spaces
deleted file mode 100644
index e69de29..0000000
diff --git a/spec/sandbox/preserve/script.sh b/spec/sandbox/preserve/script.sh
deleted file mode 100755
index c52d3c2..0000000
--- a/spec/sandbox/preserve/script.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-
-exit 0
diff --git a/spec/sandbox/script.thor b/spec/sandbox/script.thor
deleted file mode 100644
index 357b6e5..0000000
--- a/spec/sandbox/script.thor
+++ /dev/null
@@ -1,220 +0,0 @@
-class MyScript < Thor
- check_unknown_options! :except => :with_optional
-
- attr_accessor :some_attribute
- attr_writer :another_attribute
- attr_reader :another_attribute
-
- private
- attr_reader :private_attribute
-
- public
- group :script
- default_command :example_default_command
-
- map "-T" => :animal, ["-f", "--foo"] => :foo
-
- map "animal_prison" => "zoo"
-
- desc "zoo", "zoo around"
- def zoo
- true
- end
-
- desc "animal TYPE", "horse around"
-
- no_commands do
- def this_is_not_a_command
- end
- end
-
- def animal(type)
- [type]
- end
-
- map "hid" => "hidden"
-
- desc "hidden TYPE", "this is hidden", :hide => true
- def hidden(type)
- [type]
- end
-
- map "fu" => "zoo"
-
- desc "foo BAR", <<END
-do some fooing
- This is more info!
- Everyone likes more info!
-END
- method_option :force, :type => :boolean, :desc => "Force to do some fooing"
- def foo(bar)
- [bar, options]
- end
-
- desc "example_default_command", "example!"
- method_options :with => :string
- def example_default_command
- options.empty? ? "default command" : options
- end
-
- desc "call_myself_with_wrong_arity", "get the right error"
- def call_myself_with_wrong_arity
- call_myself_with_wrong_arity(4)
- end
-
- desc "call_unexistent_method", "Call unexistent method inside a command"
- def call_unexistent_method
- boom!
- end
-
- desc "long_description", "a" * 80
- long_desc <<-D
- This is a really really really long description.
- Here you go. So very long.
-
- It even has two paragraphs.
- D
- def long_description
- end
-
- desc "name-with-dashes", "Ensure normalization of command names"
- def name_with_dashes
- end
-
- method_options :all => :boolean
- method_option :lazy, :lazy_default => "yes"
- method_option :lazy_numeric, :type => :numeric, :lazy_default => 42
- method_option :lazy_array, :type => :array, :lazy_default => %w[eat at joes]
- method_option :lazy_hash, :type => :hash, :lazy_default => {'swedish' => 'meatballs'}
- desc "with_optional NAME", "invoke with optional name"
- def with_optional(name=nil, *args)
- [name, options, args]
- end
-
- class AnotherScript < Thor
- desc "baz", "do some bazing"
- def baz
- end
- end
-
- desc "send", "send as a command name"
- def send
- true
- end
-
- private
-
- def method_missing(meth, *args)
- if meth == :boom!
- super
- else
- [meth, args]
- end
- end
-
- desc "what", "what"
- def what
- end
-end
-
-class MyChildScript < MyScript
- remove_command :bar
-
- method_options :force => :boolean, :param => :numeric
- def initialize(*args)
- super
- end
-
- desc "zoo", "zoo around"
- method_options :param => :required
- def zoo
- options
- end
-
- desc "animal TYPE", "horse around"
- def animal(type)
- [type, options]
- end
- method_option :other, :type => :string, :default => "method default", :for => :animal
- desc "animal KIND", "fish around", :for => :animal
-
- desc "boom", "explodes everything"
- def boom
- end
-
- remove_command :boom, :undefine => true
-end
-
-class Barn < Thor
- desc "open [ITEM]", "open the barn door"
- def open(item = nil)
- if item == "shotgun"
- puts "That's going to leave a mark."
- else
- puts "Open sesame!"
- end
- end
-
- desc "paint [COLOR]", "paint the barn"
- method_option :coats, :type => :numeric, :default => 2, :desc => 'how many coats of paint'
- def paint(color='red')
- puts "#{options[:coats]} coats of #{color} paint"
- end
-end
-
-class PackageNameScript < Thor
- package_name "Baboon"
-end
-
-module Scripts
- class MyScript < MyChildScript
- argument :accessor, :type => :string
- class_options :force => :boolean
- method_option :new_option, :type => :string, :for => :example_default_command
-
- def zoo
- self.accessor
- end
- end
-
- class MyDefaults < Thor
- check_unknown_options!
-
- namespace :default
- desc "cow", "prints 'moo'"
- def cow
- puts "moo"
- end
-
- desc "command_conflict", "only gets called when prepended with a colon"
- def command_conflict
- puts "command"
- end
-
- desc "barn", "commands to manage the barn"
- subcommand "barn", Barn
- end
-
- class ChildDefault < Thor
- namespace "default:child"
- end
-
- class Arities < Thor
- desc "zero_args", "takes zero args"
- def zero_args
- end
-
- desc "one_arg ARG", "takes one arg"
- def one_arg(arg)
- end
-
- desc "two_args ARG1 ARG2", "takes two args"
- def two_args(arg1, arg2)
- end
-
- desc "optional_arg [ARG]", "takes an optional arg"
- def optional_arg(arg='default')
- end
- end
-end
-
diff --git a/spec/sandbox/subcommand.thor b/spec/sandbox/subcommand.thor
deleted file mode 100644
index 35d0b57..0000000
--- a/spec/sandbox/subcommand.thor
+++ /dev/null
@@ -1,17 +0,0 @@
-module TestSubcommands
-
- class Subcommand < Thor
- desc "print_opt", "My method"
- def print_opt
- print options["opt"]
- end
- end
-
- class Parent < Thor
- class_option "opt"
-
- desc "sub", "My subcommand"
- subcommand "sub", Subcommand
- end
-
-end
diff --git a/spec/shell/basic_spec.rb b/spec/shell/basic_spec.rb
deleted file mode 100644
index 417f371..0000000
--- a/spec/shell/basic_spec.rb
+++ /dev/null
@@ -1,337 +0,0 @@
-# coding: utf-8
-require "helper"
-
-describe Thor::Shell::Basic do
- def shell
- @shell ||= Thor::Shell::Basic.new
- end
-
- describe "#padding" do
- it "cannot be set to below zero" do
- shell.padding = 10
- expect(shell.padding).to eq(10)
-
- shell.padding = -1
- expect(shell.padding).to eq(0)
- end
- end
-
- describe "#ask" do
- it "prints a message to the user and gets the response" do
- expect(Thor::LineEditor).to receive(:readline).with("Should I overwrite it? ", {}).and_return("Sure")
- expect(shell.ask("Should I overwrite it?")).to eq("Sure")
- end
-
- it "prints a message to the user prefixed with the current padding" do
- expect(Thor::LineEditor).to receive(:readline).with(" Enter your name: ", {}).and_return("George")
- shell.padding = 2
- shell.ask("Enter your name:")
- end
-
- it "prints a message and returns nil if EOF is given as input" do
- expect(Thor::LineEditor).to receive(:readline).with(" ", {}).and_return(nil)
- expect(shell.ask("")).to eq(nil)
- end
-
- it "prints a message to the user and does not echo stdin if the echo option is set to false" do
- expect($stdout).to receive(:print).with('What\'s your password? ')
- expect($stdin).to receive(:noecho).and_return("mysecretpass")
- expect(shell.ask("What's your password?", :echo => false)).to eq("mysecretpass")
- end
-
- it "prints a message to the user with the available options and determines the correctness of the answer" do
- flavors = %w[strawberry chocolate vanilla]
- expect(Thor::LineEditor).to receive(:readline).with('What\'s your favorite Neopolitan flavor? [strawberry, chocolate, vanilla] ', :limited_to => flavors).and_return("chocolate")
- expect(shell.ask('What\'s your favorite Neopolitan flavor?', :limited_to => flavors)).to eq("chocolate")
- end
-
- it "prints a message to the user with the available options and reasks the question after an incorrect repsonse" do
- flavors = %w[strawberry chocolate vanilla]
- expect($stdout).to receive(:print).with("Your response must be one of: [strawberry, chocolate, vanilla]. Please try again.\n")
- expect(Thor::LineEditor).to receive(:readline).with('What\'s your favorite Neopolitan flavor? [strawberry, chocolate, vanilla] ', :limited_to => flavors).and_return("moose tracks", "chocolate")
- expect(shell.ask('What\'s your favorite Neopolitan flavor?', :limited_to => flavors)).to eq("chocolate")
- end
-
- it "prints a message to the user containing a default and sets the default if only enter is pressed" do
- expect(Thor::LineEditor).to receive(:readline).with('What\'s your favorite Neopolitan flavor? (vanilla) ', :default => "vanilla").and_return("")
- expect(shell.ask('What\'s your favorite Neopolitan flavor?', :default => "vanilla")).to eq("vanilla")
- end
-
- it "prints a message to the user with the available options and reasks the question after an incorrect repsonse and then returns the default" do
- flavors = %w[strawberry chocolate vanilla]
- expect($stdout).to receive(:print).with("Your response must be one of: [strawberry, chocolate, vanilla]. Please try again.\n")
- expect(Thor::LineEditor).to receive(:readline).with('What\'s your favorite Neopolitan flavor? [strawberry, chocolate, vanilla] (vanilla) ', :default => "vanilla", :limited_to => flavors).and_return("moose tracks", "")
- expect(shell.ask("What's your favorite Neopolitan flavor?", :default => "vanilla", :limited_to => flavors)).to eq("vanilla")
- end
- end
-
- describe "#yes?" do
- it "asks the user and returns true if the user replies yes" do
- expect(Thor::LineEditor).to receive(:readline).with("Should I overwrite it? ", :add_to_history => false).and_return("y")
- expect(shell.yes?("Should I overwrite it?")).to be_true
- end
-
- it "asks the user and returns false if the user replies no" do
- expect(Thor::LineEditor).to receive(:readline).with("Should I overwrite it? ", :add_to_history => false).and_return("n")
- expect(shell.yes?("Should I overwrite it?")).not_to be_true
- end
-
- it "asks the user and returns false if the user replies with an answer other than yes or no" do
- expect(Thor::LineEditor).to receive(:readline).with("Should I overwrite it? ", :add_to_history => false).and_return("foobar")
- expect(shell.yes?("Should I overwrite it?")).to be_false
- end
- end
-
- describe "#no?" do
- it "asks the user and returns true if the user replies no" do
- expect(Thor::LineEditor).to receive(:readline).with("Should I overwrite it? ", :add_to_history => false).and_return("n")
- expect(shell.no?("Should I overwrite it?")).to be_true
- end
-
- it "asks the user and returns false if the user replies yes" do
- expect(Thor::LineEditor).to receive(:readline).with("Should I overwrite it? ", :add_to_history => false).and_return("Yes")
- expect(shell.no?("Should I overwrite it?")).to be_false
- end
-
- it "asks the user and returns false if the user replies with an answer other than yes or no" do
- expect(Thor::LineEditor).to receive(:readline).with("Should I overwrite it? ", :add_to_history => false).and_return("foobar")
- expect(shell.no?("Should I overwrite it?")).to be_false
- end
- end
-
- describe "#say" do
- it "prints a message to the user" do
- expect($stdout).to receive(:print).with("Running...\n")
- shell.say("Running...")
- end
-
- it "prints a message to the user without new line if it ends with a whitespace" do
- expect($stdout).to receive(:print).with("Running... ")
- shell.say("Running... ")
- end
-
- it "does not use a new line with whitespace+newline embedded" do
- expect($stdout).to receive(:print).with("It's \nRunning...\n")
- shell.say("It's \nRunning...")
- end
-
- it "prints a message to the user without new line" do
- expect($stdout).to receive(:print).with("Running...")
- shell.say("Running...", nil, false)
- end
-
- it "coerces everything to a string before printing" do
- expect($stdout).to receive(:print).with("this_is_not_a_string\n")
- shell.say(:this_is_not_a_string, nil, true)
- end
- end
-
- describe "#say_status" do
- it "prints a message to the user with status" do
- expect($stdout).to receive(:print).with(" create ~/.thor/command.thor\n")
- shell.say_status(:create, "~/.thor/command.thor")
- end
-
- it "always uses new line" do
- expect($stdout).to receive(:print).with(" create \n")
- shell.say_status(:create, "")
- end
-
- it "does not print a message if base is muted" do
- expect(shell).to receive(:mute?).and_return(true)
- expect($stdout).not_to receive(:print)
-
- shell.mute do
- shell.say_status(:created, "~/.thor/command.thor")
- end
- end
-
- it "does not print a message if base is set to quiet" do
- base = MyCounter.new [1, 2]
- expect(base).to receive(:options).and_return(:quiet => true)
-
- expect($stdout).not_to receive(:print)
- shell.base = base
- shell.say_status(:created, "~/.thor/command.thor")
- end
-
- it "does not print a message if log status is set to false" do
- expect($stdout).not_to receive(:print)
- shell.say_status(:created, "~/.thor/command.thor", false)
- end
-
- it "uses padding to set message's left margin" do
- shell.padding = 2
- expect($stdout).to receive(:print).with(" create ~/.thor/command.thor\n")
- shell.say_status(:create, "~/.thor/command.thor")
- end
- end
-
- describe "#print_in_columns" do
- before do
- @array = [1_234_567_890]
- @array += ("a".."e").to_a
- end
-
- it "prints in columns" do
- content = capture(:stdout) { shell.print_in_columns(@array) }
- expect(content.rstrip).to eq("1234567890 a b c d e")
- end
- end
-
- describe "#print_table" do
- before do
- @table = []
- @table << ["abc", "#123", "first three"]
- @table << ["", "#0", "empty"]
- @table << ["xyz", "#786", "last three"]
- end
-
- it "prints a table" do
- content = capture(:stdout) { shell.print_table(@table) }
- expect(content).to eq(<<-TABLE)
-abc #123 first three
- #0 empty
-xyz #786 last three
-TABLE
- end
-
- it "prints a table with indentation" do
- content = capture(:stdout) { shell.print_table(@table, :indent => 2) }
- expect(content).to eq(<<-TABLE)
- abc #123 first three
- #0 empty
- xyz #786 last three
-TABLE
- end
-
- it "uses maximum terminal width" do
- @table << ["def", "#456", "Lançam foo bar"]
- @table << ["ghi", "#789", "بالله عليكم"]
- expect(shell).to receive(:terminal_width).and_return(20)
- content = capture(:stdout) { shell.print_table(@table, :indent => 2, :truncate => true) }
- expect(content).to eq(<<-TABLE)
- abc #123 firs...
- #0 empty
- xyz #786 last...
- def #456 Lanç...
- ghi #789 بالل...
-TABLE
- end
-
- it "honors the colwidth option" do
- content = capture(:stdout) { shell.print_table(@table, :colwidth => 10) }
- expect(content).to eq(<<-TABLE)
-abc #123 first three
- #0 empty
-xyz #786 last three
-TABLE
- end
-
- it "prints tables with implicit columns" do
- 2.times { @table.first.pop }
- content = capture(:stdout) { shell.print_table(@table) }
- expect(content).to eq(<<-TABLE)
-abc
- #0 empty
-xyz #786 last three
-TABLE
- end
-
- it "prints a table with small numbers and right-aligns them" do
- table = [
- ["Name", "Number", "Color"], # rubocop: disable WordArray
- ["Erik", 1, "green"]
- ]
- content = capture(:stdout) { shell.print_table(table) }
- expect(content).to eq(<<-TABLE)
-Name Number Color
-Erik 1 green
-TABLE
- end
-
- it "doesn't output extra spaces for right-aligned columns in the last column" do
- table = [
- ["Name", "Number"], # rubocop: disable WordArray
- ["Erik", 1]
- ]
- content = capture(:stdout) { shell.print_table(table) }
- expect(content).to eq(<<-TABLE)
-Name Number
-Erik 1
-TABLE
- end
-
- it "prints a table with big numbers" do
- table = [
- ["Name", "Number", "Color"], # rubocop: disable WordArray
- ["Erik", 1_234_567_890_123, "green"]
- ]
- content = capture(:stdout) { shell.print_table(table) }
- expect(content).to eq(<<-TABLE)
-Name Number Color
-Erik 1234567890123 green
-TABLE
- end
- end
-
- describe "#file_collision" do
- it "shows a menu with options" do
- expect(Thor::LineEditor).to receive(:readline).with('Overwrite foo? (enter "h" for help) [Ynaqh] ', :add_to_history => false).and_return("n")
- shell.file_collision("foo")
- end
-
- it "returns true if the user chooses default option" do
- expect(Thor::LineEditor).to receive(:readline).and_return("")
- expect(shell.file_collision("foo")).to be_true
- end
-
- it "returns false if the user chooses no" do
- expect(Thor::LineEditor).to receive(:readline).and_return("n")
- expect(shell.file_collision("foo")).to be_false
- end
-
- it "returns true if the user chooses yes" do
- expect(Thor::LineEditor).to receive(:readline).and_return("y")
- expect(shell.file_collision("foo")).to be_true
- end
-
- it "shows help usage if the user chooses help" do
- expect(Thor::LineEditor).to receive(:readline).and_return("h", "n")
- help = capture(:stdout) { shell.file_collision("foo") }
- expect(help).to match(/h \- help, show this help/)
- end
-
- it "quits if the user chooses quit" do
- expect($stdout).to receive(:print).with("Aborting...\n")
- expect(Thor::LineEditor).to receive(:readline).and_return("q")
-
- expect do
- shell.file_collision("foo")
- end.to raise_error(SystemExit)
- end
-
- it "always returns true if the user chooses always" do
- expect(Thor::LineEditor).to receive(:readline).with('Overwrite foo? (enter "h" for help) [Ynaqh] ', :add_to_history => false).and_return("a")
-
- expect(shell.file_collision("foo")).to be true
-
- expect($stdout).not_to receive(:print)
- expect(shell.file_collision("foo")).to be true
- end
-
- describe "when a block is given" do
- it "displays diff options to the user" do
- expect(Thor::LineEditor).to receive(:readline).with('Overwrite foo? (enter "h" for help) [Ynaqdh] ', :add_to_history => false).and_return("s")
- shell.file_collision("foo") {}
- end
-
- it "invokes the diff command" do
- expect(Thor::LineEditor).to receive(:readline).and_return("d")
- expect(Thor::LineEditor).to receive(:readline).and_return("n")
- expect(shell).to receive(:system).with(/diff -u/)
- capture(:stdout) { shell.file_collision("foo") {} }
- end
- end
- end
-end
diff --git a/spec/shell/color_spec.rb b/spec/shell/color_spec.rb
deleted file mode 100644
index 196e6b6..0000000
--- a/spec/shell/color_spec.rb
+++ /dev/null
@@ -1,119 +0,0 @@
-require "helper"
-
-describe Thor::Shell::Color do
- def shell
- @shell ||= Thor::Shell::Color.new
- end
-
- before do
- allow($stdout).to receive(:tty?).and_return(true)
- allow_any_instance_of(StringIO).to receive(:tty?).and_return(true)
- end
-
- describe "#ask" do
- it "sets the color if specified and tty?" do
- expect(Thor::LineEditor).to receive(:readline).with("\e[32mIs this green? \e[0m", anything).and_return("yes")
- shell.ask "Is this green?", :green
-
- expect(Thor::LineEditor).to receive(:readline).with("\e[32mIs this green? [Yes, No, Maybe] \e[0m", anything).and_return("Yes")
- shell.ask "Is this green?", :green, :limited_to => %w[Yes No Maybe]
- end
- end
-
- describe "#say" do
- it "set the color if specified and tty?" do
- out = capture(:stdout) do
- shell.say "Wow! Now we have colors!", :green
- end
-
- expect(out.chomp).to eq("\e[32mWow! Now we have colors!\e[0m")
- end
-
- it "does not set the color if output is not a tty" do
- out = capture(:stdout) do
- expect($stdout).to receive(:tty?).and_return(false)
- shell.say "Wow! Now we have colors!", :green
- end
-
- expect(out.chomp).to eq("Wow! Now we have colors!")
- end
-
- it "does not use a new line even with colors" do
- out = capture(:stdout) do
- shell.say "Wow! Now we have colors! ", :green
- end
-
- expect(out.chomp).to eq("\e[32mWow! Now we have colors! \e[0m")
- end
-
- it "handles an Array of colors" do
- out = capture(:stdout) do
- shell.say "Wow! Now we have colors *and* background colors", [:green, :on_red, :bold]
- end
-
- expect(out.chomp).to eq("\e[32m\e[41m\e[1mWow! Now we have colors *and* background colors\e[0m")
- end
- end
-
- describe "#say_status" do
- it "uses color to say status" do
- out = capture(:stdout) do
- shell.say_status :conflict, "README", :red
- end
-
- expect(out.chomp).to eq("\e[1m\e[31m conflict\e[0m README")
- end
- end
-
- describe "#set_color" do
- it "colors a string with a foreground color" do
- red = shell.set_color "hi!", :red
- expect(red).to eq("\e[31mhi!\e[0m")
- end
-
- it "colors a string with a background color" do
- on_red = shell.set_color "hi!", :white, :on_red
- expect(on_red).to eq("\e[37m\e[41mhi!\e[0m")
- end
-
- it "colors a string with a bold color" do
- bold = shell.set_color "hi!", :white, true
- expect(bold).to eq("\e[1m\e[37mhi!\e[0m")
-
- bold = shell.set_color "hi!", :white, :bold
- expect(bold).to eq("\e[37m\e[1mhi!\e[0m")
-
- bold = shell.set_color "hi!", :white, :on_red, :bold
- expect(bold).to eq("\e[37m\e[41m\e[1mhi!\e[0m")
- end
-
- it "does nothing when there are no colors" do
- colorless = shell.set_color "hi!", nil
- expect(colorless).to eq("hi!")
-
- colorless = shell.set_color "hi!"
- expect(colorless).to eq("hi!")
- end
-
- it "does nothing when the terminal does not support color" do
- allow($stdout).to receive(:tty?).and_return(false)
- colorless = shell.set_color "hi!", :white
- expect(colorless).to eq("hi!")
- end
- end
-
- describe "#file_collision" do
- describe "when a block is given" do
- it "invokes the diff command" do
- allow($stdout).to receive(:print)
- allow($stdout).to receive(:tty?).and_return(true)
- expect(Thor::LineEditor).to receive(:readline).and_return("d", "n")
-
- output = capture(:stdout) { shell.file_collision("spec/fixtures/doc/README") { "README\nEND\n" } }
- expect(output).to match(/\e\[31m\- __start__\e\[0m/)
- expect(output).to match(/^ README/)
- expect(output).to match(/\e\[32m\+ END\e\[0m/)
- end
- end
- end
-end
diff --git a/spec/shell/html_spec.rb b/spec/shell/html_spec.rb
deleted file mode 100644
index 1a6ef89..0000000
--- a/spec/shell/html_spec.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-require "helper"
-
-describe Thor::Shell::HTML do
- def shell
- @shell ||= Thor::Shell::HTML.new
- end
-
- describe "#say" do
- it "sets the color if specified" do
- out = capture(:stdout) { shell.say "Wow! Now we have colors!", :green }
- expect(out.chomp).to eq('<span style="color: green;">Wow! Now we have colors!</span>')
- end
-
- it "sets bold if specified" do
- out = capture(:stdout) { shell.say "Wow! Now we have colors *and* bold!", [:green, :bold] }
- expect(out.chomp).to eq('<span style="color: green; font-weight: bold;">Wow! Now we have colors *and* bold!</span>')
- end
-
- it "does not use a new line even with colors" do
- out = capture(:stdout) { shell.say "Wow! Now we have colors! ", :green }
- expect(out.chomp).to eq('<span style="color: green;">Wow! Now we have colors! </span>')
- end
- end
-
- describe "#say_status" do
- it "uses color to say status" do
- expect($stdout).to receive(:print).with("<span style=\"color: red; font-weight: bold;\"> conflict</span> README\n")
- shell.say_status :conflict, "README", :red
- end
- end
-end
diff --git a/spec/shell_spec.rb b/spec/shell_spec.rb
deleted file mode 100644
index 17e4d78..0000000
--- a/spec/shell_spec.rb
+++ /dev/null
@@ -1,47 +0,0 @@
-require "helper"
-
-describe Thor::Shell do
- def shell
- @shell ||= Thor::Base.shell.new
- end
-
- describe "#initialize" do
- it "sets shell value" do
- base = MyCounter.new [1, 2], {}, :shell => shell
- expect(base.shell).to eq(shell)
- end
-
- it "sets the base value on the shell if an accessor is available" do
- base = MyCounter.new [1, 2], {}, :shell => shell
- expect(shell.base).to eq(base)
- end
- end
-
- describe "#shell" do
- it "returns the shell in use" do
- expect(MyCounter.new([1, 2]).shell).to be_kind_of(Thor::Base.shell)
- end
-
- it "uses $THOR_SHELL" do
- class Thor::Shell::TestShell < Thor::Shell::Basic; end
-
- expect(Thor::Base.shell).to eq(shell.class)
- ENV["THOR_SHELL"] = "TestShell"
- Thor::Base.shell = nil
- expect(Thor::Base.shell).to eq(Thor::Shell::TestShell)
- ENV["THOR_SHELL"] = ""
- Thor::Base.shell = shell.class
- expect(Thor::Base.shell).to eq(shell.class)
- end
- end
-
- describe "with_padding" do
- it "uses padding for inside block outputs" do
- base = MyCounter.new([1, 2])
- base.with_padding do
- expect(capture(:stdout) { base.say_status :padding, "cool" }.strip).to eq("padding cool")
- end
- end
- end
-
-end
diff --git a/spec/subcommand_spec.rb b/spec/subcommand_spec.rb
deleted file mode 100644
index f189f21..0000000
--- a/spec/subcommand_spec.rb
+++ /dev/null
@@ -1,48 +0,0 @@
-require "helper"
-
-describe Thor do
-
- describe "#subcommand" do
-
- it "maps a given subcommand to another Thor subclass" do
- barn_help = capture(:stdout) { Scripts::MyDefaults.start(%w[barn]) }
- expect(barn_help).to include("barn help [COMMAND] # Describe subcommands or one specific subcommand")
- end
-
- it "passes commands to subcommand classes" do
- expect(capture(:stdout) { Scripts::MyDefaults.start(%w[barn open]) }.strip).to eq("Open sesame!")
- end
-
- it "passes arguments to subcommand classes" do
- expect(capture(:stdout) { Scripts::MyDefaults.start(%w[barn open shotgun]) }.strip).to eq("That's going to leave a mark.")
- end
-
- it "ignores unknown options (the subcommand class will handle them)" do
- expect(capture(:stdout) { Scripts::MyDefaults.start(%w[barn paint blue --coats 4]) }.strip).to eq("4 coats of blue paint")
- end
-
- it "passes parsed options to subcommands" do
- output = capture(:stdout) { TestSubcommands::Parent.start(%w[sub print_opt --opt output]) }
- expect(output).to eq("output")
- end
-
- it "accepts the help switch and calls the help command on the subcommand" do
- output = capture(:stdout) { TestSubcommands::Parent.start(%w[sub print_opt --help]) }
- sub_help = capture(:stdout) { TestSubcommands::Parent.start(%w[sub help print_opt]) }
- expect(output).to eq(sub_help)
- end
-
- it "accepts the help short switch and calls the help command on the subcommand" do
- output = capture(:stdout) { TestSubcommands::Parent.start(%w[sub print_opt -h]) }
- sub_help = capture(:stdout) { TestSubcommands::Parent.start(%w[sub help print_opt]) }
- expect(output).to eq(sub_help)
- end
-
- it "the help command on the subcommand and after it should result in the same output" do
- output = capture(:stdout) { TestSubcommands::Parent.start(%w[sub help])}
- sub_help = capture(:stdout) { TestSubcommands::Parent.start(%w[help sub])}
- expect(output).to eq(sub_help)
- end
- end
-
-end
diff --git a/spec/thor_spec.rb b/spec/thor_spec.rb
deleted file mode 100644
index 55450dc..0000000
--- a/spec/thor_spec.rb
+++ /dev/null
@@ -1,505 +0,0 @@
-require "helper"
-
-describe Thor do
- describe "#method_option" do
- it "sets options to the next method to be invoked" do
- args = %w[foo bar --force]
- _, options = MyScript.start(args)
- expect(options).to eq("force" => true)
- end
-
- describe ":lazy_default" do
- it "is absent when option is not specified" do
- _, options = MyScript.start(%w[with_optional])
- expect(options).to eq({})
- end
-
- it "sets a default that can be overridden for strings" do
- _, options = MyScript.start(%w[with_optional --lazy])
- expect(options).to eq("lazy" => "yes")
-
- _, options = MyScript.start(%w[with_optional --lazy yesyes!])
- expect(options).to eq("lazy" => "yesyes!")
- end
-
- it "sets a default that can be overridden for numerics" do
- _, options = MyScript.start(%w[with_optional --lazy-numeric])
- expect(options).to eq("lazy_numeric" => 42)
-
- _, options = MyScript.start(%w[with_optional --lazy-numeric 20000])
- expect(options).to eq("lazy_numeric" => 20_000)
- end
-
- it "sets a default that can be overridden for arrays" do
- _, options = MyScript.start(%w[with_optional --lazy-array])
- expect(options).to eq("lazy_array" => %w[eat at joes])
-
- _, options = MyScript.start(%w[with_optional --lazy-array hello there])
- expect(options).to eq("lazy_array" => %w[hello there])
- end
-
- it "sets a default that can be overridden for hashes" do
- _, options = MyScript.start(%w[with_optional --lazy-hash])
- expect(options).to eq("lazy_hash" => {"swedish" => "meatballs"})
-
- _, options = MyScript.start(%w[with_optional --lazy-hash polish:sausage])
- expect(options).to eq("lazy_hash" => {"polish" => "sausage"})
- end
- end
-
- describe "when :for is supplied" do
- it "updates an already defined command" do
- _, options = MyChildScript.start(%w[animal horse --other=fish])
- expect(options[:other]).to eq("fish")
- end
-
- describe "and the target is on the parent class" do
- it "updates an already defined command" do
- args = %w[example_default_command my_param --new-option=verified]
- options = Scripts::MyScript.start(args)
- expect(options[:new_option]).to eq("verified")
- end
-
- it "adds a command to the command list if the updated command is on the parent class" do
- expect(Scripts::MyScript.commands["example_default_command"]).to be
- end
-
- it "clones the parent command" do
- expect(Scripts::MyScript.commands["example_default_command"]).not_to eq(MyChildScript.commands["example_default_command"])
- end
- end
- end
- end
-
- describe "#default_command" do
- it "sets a default command" do
- expect(MyScript.default_command).to eq("example_default_command")
- end
-
- it "invokes the default command if no command is specified" do
- expect(MyScript.start([])).to eq("default command")
- end
-
- it "invokes the default command if no command is specified even if switches are given" do
- expect(MyScript.start(%w[--with option])).to eq("with" => "option")
- end
-
- it "inherits the default command from parent" do
- expect(MyChildScript.default_command).to eq("example_default_command")
- end
- end
-
- describe "#stop_on_unknown_option!" do
- my_script = Class.new(Thor) do
- class_option "verbose", :type => :boolean
- class_option "mode", :type => :string
-
- stop_on_unknown_option! :exec
-
- desc "exec", "Run a command"
- def exec(*args)
- [options, args]
- end
-
- desc "boring", "An ordinary command"
- def boring(*args)
- [options, args]
- end
- end
-
- it "passes remaining args to command when it encounters a non-option" do
- expect(my_script.start(%w[exec command --verbose])).to eq [{}, %w[command --verbose]]
- end
-
- it "passes remaining args to command when it encounters an unknown option" do
- expect(my_script.start(%w[exec --foo command --bar])).to eq [{}, %w[--foo command --bar]]
- end
-
- it "still accepts options that are given before non-options" do
- expect(my_script.start(%w[exec --verbose command --foo])).to eq [{"verbose" => true}, %w[command --foo]]
- end
-
- it "still accepts options that require a value" do
- expect(my_script.start(%w[exec --mode rashly command])).to eq [{"mode" => "rashly"}, %w[command]]
- end
-
- it "still passes everything after -- to command" do
- expect(my_script.start(%w[exec -- --verbose])).to eq [{}, %w[--verbose]]
- end
-
- it "does not affect ordinary commands" do
- expect(my_script.start(%w[boring command --verbose])).to eq [{"verbose" => true}, %w[command]]
- end
-
- context "when provided with multiple command names" do
- klass = Class.new(Thor) do
- stop_on_unknown_option! :foo, :bar
- end
- it "affects all specified commands" do
- expect(klass.stop_on_unknown_option?(double(:name => "foo"))).to be true
- expect(klass.stop_on_unknown_option?(double(:name => "bar"))).to be true
- expect(klass.stop_on_unknown_option?(double(:name => "baz"))).to be false
- end
- end
-
- context "when invoked several times" do
- klass = Class.new(Thor) do
- stop_on_unknown_option! :foo
- stop_on_unknown_option! :bar
- end
- it "affects all specified commands" do
- expect(klass.stop_on_unknown_option?(double(:name => "foo"))).to be true
- expect(klass.stop_on_unknown_option?(double(:name => "bar"))).to be true
- expect(klass.stop_on_unknown_option?(double(:name => "baz"))).to be false
- end
- end
-
- it "doesn't break new" do
- expect(my_script.new).to be_a(Thor)
- end
- end
-
- describe "#map" do
- it "calls the alias of a method if one is provided" do
- expect(MyScript.start(%w[-T fish])).to eq(%w[fish])
- end
-
- it "calls the alias of a method if several are provided via #map" do
- expect(MyScript.start(%w[-f fish])).to eq(["fish", {}])
- expect(MyScript.start(%w[--foo fish])).to eq(["fish", {}])
- end
-
- it "inherits all mappings from parent" do
- expect(MyChildScript.default_command).to eq("example_default_command")
- end
- end
-
- describe "#package_name" do
- it "provides a proper description for a command when the package_name is assigned" do
- content = capture(:stdout) { PackageNameScript.start(%w[help]) }
- expect(content).to match(/Baboon commands:/m)
- end
-
- # TODO: remove this, might be redundant, just wanted to prove full coverage
- it "provides a proper description for a command when the package_name is NOT assigned" do
- content = capture(:stdout) { MyScript.start(%w[help]) }
- expect(content).to match(/Commands:/m)
- end
- end
-
- describe "#desc" do
- it "provides description for a command" do
- content = capture(:stdout) { MyScript.start(%w[help]) }
- expect(content).to match(/thor my_script:zoo\s+# zoo around/m)
- end
-
- it "provides no namespace if $thor_runner is false" do
- begin
- $thor_runner = false
- content = capture(:stdout) { MyScript.start(%w[help]) }
- expect(content).to match(/thor zoo\s+# zoo around/m)
- ensure
- $thor_runner = true
- end
- end
-
- describe "when :for is supplied" do
- it "overwrites a previous defined command" do
- expect(capture(:stdout) { MyChildScript.start(%w[help]) }).to match(/animal KIND \s+# fish around/m)
- end
- end
-
- describe "when :hide is supplied" do
- it "does not show the command in help" do
- expect(capture(:stdout) { MyScript.start(%w[help]) }).not_to match(/this is hidden/m)
- end
-
- it "but the command is still invokable, does not show the command in help" do
- expect(MyScript.start(%w[hidden yesyes])).to eq(%w[yesyes])
- end
- end
- end
-
- describe "#method_options" do
- it "sets default options if called before an initializer" do
- options = MyChildScript.class_options
- expect(options[:force].type).to eq(:boolean)
- expect(options[:param].type).to eq(:numeric)
- end
-
- it "overwrites default options if called on the method scope" do
- args = %w[zoo --force --param feathers]
- options = MyChildScript.start(args)
- expect(options).to eq("force" => true, "param" => "feathers")
- end
-
- it "allows default options to be merged with method options" do
- args = %w[animal bird --force --param 1.0 --other tweets]
- arg, options = MyChildScript.start(args)
- expect(arg).to eq("bird")
- expect(options).to eq("force" => true, "param" => 1.0, "other" => "tweets")
- end
- end
-
- describe "#start" do
- it "calls a no-param method when no params are passed" do
- expect(MyScript.start(%w[zoo])).to eq(true)
- end
-
- it "calls a single-param method when a single param is passed" do
- expect(MyScript.start(%w[animal fish])).to eq(%w[fish])
- end
-
- it "does not set options in attributes" do
- expect(MyScript.start(%w[with_optional --all])).to eq([nil, {"all" => true}, []])
- end
-
- it "raises an error if the wrong number of params are provided" do
- arity_asserter = lambda do |args, msg|
- stderr = capture(:stderr) { Scripts::Arities.start(args) }
- expect(stderr.strip).to eq(msg)
- end
- arity_asserter.call %w[zero_args one], %Q(ERROR: "thor zero_args" was called with arguments ["one"]
-Usage: "thor scripts:arities:zero_args")
- arity_asserter.call %w[one_arg], %Q(ERROR: "thor one_arg" was called with no arguments
-Usage: "thor scripts:arities:one_arg ARG")
- arity_asserter.call %w[one_arg one two], %Q(ERROR: "thor one_arg" was called with arguments ["one", "two"]
-Usage: "thor scripts:arities:one_arg ARG")
- arity_asserter.call %w[one_arg one two], %Q(ERROR: "thor one_arg" was called with arguments ["one", "two"]
-Usage: "thor scripts:arities:one_arg ARG")
- arity_asserter.call %w[two_args one], %Q(ERROR: "thor two_args" was called with arguments ["one"]
-Usage: "thor scripts:arities:two_args ARG1 ARG2")
- arity_asserter.call %w[optional_arg one two], %Q(ERROR: "thor optional_arg" was called with arguments ["one", "two"]
-Usage: "thor scripts:arities:optional_arg [ARG]")
- end
-
- it "raises an error if the invoked command does not exist" do
- expect(capture(:stderr) { Amazing.start(%w[animal]) }.strip).to eq('Could not find command "animal" in "amazing" namespace.')
- end
-
- it "calls method_missing if an unknown method is passed in" do
- expect(MyScript.start(%w[unk hello])).to eq([:unk, %w[hello]])
- end
-
- it "does not call a private method no matter what" do
- expect(capture(:stderr) { MyScript.start(%w[what]) }.strip).to eq('Could not find command "what" in "my_script" namespace.')
- end
-
- it "uses command default options" do
- options = MyChildScript.start(%w[animal fish]).last
- expect(options).to eq("other" => "method default")
- end
-
- it "raises when an exception happens within the command call" do
- expect { MyScript.start(%w[call_myself_with_wrong_arity]) }.to raise_error(ArgumentError)
- end
-
- context "when the user enters an unambiguous substring of a command" do
- it "invokes a command" do
- expect(MyScript.start(%w[z])).to eq(MyScript.start(%w[zoo]))
- end
-
- it "invokes a command, even when there's an alias it resolves to the same command" do
- expect(MyScript.start(%w[hi arg])).to eq(MyScript.start(%w[hidden arg]))
- end
-
- it "invokes an alias" do
- expect(MyScript.start(%w[animal_pri])).to eq(MyScript.start(%w[zoo]))
- end
- end
-
- context "when the user enters an ambiguous substring of a command" do
- it "raises an exception and displays a message that explains the ambiguity" do
- shell = Thor::Base.shell.new
- expect(shell).to receive(:error).with("Ambiguous command call matches [call_myself_with_wrong_arity, call_unexistent_method]")
- MyScript.start(%w[call], :shell => shell)
- end
-
- it "raises an exception when there is an alias" do
- shell = Thor::Base.shell.new
- expect(shell).to receive(:error).with("Ambiguous command f matches [foo, fu]")
- MyScript.start(%w[f], :shell => shell)
- end
- end
-
- end
-
- describe "#help" do
- def shell
- @shell ||= Thor::Base.shell.new
- end
-
- describe "on general" do
- before do
- @content = capture(:stdout) { MyScript.help(shell) }
- end
-
- it "provides useful help info for the help method itself" do
- expect(@content).to match(/help \[COMMAND\]\s+# Describe available commands/)
- end
-
- it "provides useful help info for a method with params" do
- expect(@content).to match(/animal TYPE\s+# horse around/)
- end
-
- it "uses the maximum terminal size to show commands" do
- expect(@shell).to receive(:terminal_width).and_return(80)
- content = capture(:stdout) { MyScript.help(shell) }
- expect(content).to match(/aaa\.\.\.$/)
- end
-
- it "provides description for commands from classes in the same namespace" do
- expect(@content).to match(/baz\s+# do some bazing/)
- end
-
- it "shows superclass commands" do
- content = capture(:stdout) { MyChildScript.help(shell) }
- expect(content).to match(/foo BAR \s+# do some fooing/)
- end
-
- it "shows class options information" do
- content = capture(:stdout) { MyChildScript.help(shell) }
- expect(content).to match(/Options\:/)
- expect(content).to match(/\[\-\-param=N\]/)
- end
-
- it "injects class arguments into default usage" do
- content = capture(:stdout) { Scripts::MyScript.help(shell) }
- expect(content).to match(/zoo ACCESSOR \-\-param\=PARAM/)
- end
- end
-
- describe "for a specific command" do
- it "provides full help info when talking about a specific command" do
- expect(capture(:stdout) { MyScript.command_help(shell, "foo") }).to eq(<<-END)
-Usage:
- thor my_script:foo BAR
-
-Options:
- [--force] # Force to do some fooing
-
-do some fooing
- This is more info!
- Everyone likes more info!
-END
- end
-
- it "raises an error if the command can't be found" do
- expect do
- MyScript.command_help(shell, "unknown")
- end.to raise_error(Thor::UndefinedCommandError, 'Could not find command "unknown" in "my_script" namespace.')
- end
-
- it "normalizes names before claiming they don't exist" do
- expect(capture(:stdout) { MyScript.command_help(shell, "name-with-dashes") }).to match(/thor my_script:name-with-dashes/)
- end
-
- it "uses the long description if it exists" do
- expect(capture(:stdout) { MyScript.command_help(shell, "long_description") }).to eq(<<-HELP)
-Usage:
- thor my_script:long_description
-
-Description:
- This is a really really really long description. Here you go. So very long.
-
- It even has two paragraphs.
-HELP
- end
-
- it "doesn't assign the long description to the next command without one" do
- expect(capture(:stdout) do
- MyScript.command_help(shell, "name_with_dashes")
- end).not_to match(/so very long/i)
- end
- end
-
- describe "instance method" do
- it "calls the class method" do
- expect(capture(:stdout) { MyScript.start(%w[help]) }).to match(/Commands:/)
- end
-
- it "calls the class method" do
- expect(capture(:stdout) { MyScript.start(%w[help foo]) }).to match(/Usage:/)
- end
- end
- end
-
- describe "when creating commands" do
- it "prints a warning if a public method is created without description or usage" do
- expect(capture(:stdout) do
- klass = Class.new(Thor)
- klass.class_eval "def hello_from_thor; end"
- end).to match(/\[WARNING\] Attempted to create command "hello_from_thor" without usage or description/)
- end
-
- it "does not print if overwriting a previous command" do
- expect(capture(:stdout) do
- klass = Class.new(Thor)
- klass.class_eval "def help; end"
- end).to be_empty
- end
- end
-
- describe "edge-cases" do
- it "can handle boolean options followed by arguments" do
- klass = Class.new(Thor) do
- method_option :loud, :type => :boolean
- desc "hi NAME", "say hi to name"
- def hi(name)
- name.upcase! if options[:loud]
- "Hi #{name}"
- end
- end
-
- expect(klass.start(%w[hi jose])).to eq("Hi jose")
- expect(klass.start(%w[hi jose --loud])).to eq("Hi JOSE")
- expect(klass.start(%w[hi --loud jose])).to eq("Hi JOSE")
- end
-
- it "passes through unknown options" do
- klass = Class.new(Thor) do
- desc "unknown", "passing unknown options"
- def unknown(*args)
- args
- end
- end
-
- expect(klass.start(%w[unknown foo --bar baz bat --bam])).to eq(%w[foo --bar baz bat --bam])
- expect(klass.start(%w[unknown --bar baz])).to eq(%w[--bar baz])
- end
-
- it "does not pass through unknown options with strict args" do
- klass = Class.new(Thor) do
- strict_args_position!
-
- desc "unknown", "passing unknown options"
- def unknown(*args)
- args
- end
- end
-
- expect(klass.start(%w[unknown --bar baz])).to eq([])
- expect(klass.start(%w[unknown foo --bar baz])).to eq(%w[foo])
- end
-
- it "strict args works in the inheritance chain" do
- parent = Class.new(Thor) do
- strict_args_position!
- end
-
- klass = Class.new(parent) do
- desc "unknown", "passing unknown options"
- def unknown(*args)
- args
- end
- end
-
- expect(klass.start(%w[unknown --bar baz])).to eq([])
- expect(klass.start(%w[unknown foo --bar baz])).to eq(%w[foo])
- end
-
- it "send as a command name" do
- expect(MyScript.start(%w[send])).to eq(true)
- end
- end
-end
diff --git a/spec/util_spec.rb b/spec/util_spec.rb
deleted file mode 100644
index 9fe213c..0000000
--- a/spec/util_spec.rb
+++ /dev/null
@@ -1,196 +0,0 @@
-require "helper"
-
-module Thor::Util
- def self.clear_user_home!
- @@user_home = nil
- end
-end
-
-describe Thor::Util do
- describe "#find_by_namespace" do
- it "returns 'default' if no namespace is given" do
- expect(Thor::Util.find_by_namespace("")).to eq(Scripts::MyDefaults)
- end
-
- it "adds 'default' if namespace starts with :" do
- expect(Thor::Util.find_by_namespace(":child")).to eq(Scripts::ChildDefault)
- end
-
- it "returns nil if the namespace can't be found" do
- expect(Thor::Util.find_by_namespace("thor:core_ext:ordered_hash")).to be nil
- end
-
- it "returns a class if it matches the namespace" do
- expect(Thor::Util.find_by_namespace("app:broken:counter")).to eq(BrokenCounter)
- end
-
- it "matches classes default namespace" do
- expect(Thor::Util.find_by_namespace("scripts:my_script")).to eq(Scripts::MyScript)
- end
- end
-
- describe "#namespace_from_thor_class" do
- it "replaces constant nesting with command namespacing" do
- expect(Thor::Util.namespace_from_thor_class("Foo::Bar::Baz")).to eq("foo:bar:baz")
- end
-
- it "snake-cases component strings" do
- expect(Thor::Util.namespace_from_thor_class("FooBar::BarBaz::BazBoom")).to eq("foo_bar:bar_baz:baz_boom")
- end
-
- it "accepts class and module objects" do
- expect(Thor::Util.namespace_from_thor_class(Thor::CoreExt::OrderedHash)).to eq("thor:core_ext:ordered_hash")
- expect(Thor::Util.namespace_from_thor_class(Thor::Util)).to eq("thor:util")
- end
-
- it "removes Thor::Sandbox namespace" do
- expect(Thor::Util.namespace_from_thor_class("Thor::Sandbox::Package")).to eq("package")
- end
- end
-
- describe "#namespaces_in_content" do
- it "returns an array of names of constants defined in the string" do
- list = Thor::Util.namespaces_in_content("class Foo; class Bar < Thor; end; end; class Baz; class Bat; end; end")
- expect(list).to include("foo:bar")
- expect(list).not_to include("bar:bat")
- end
-
- it "doesn't put the newly-defined constants in the enclosing namespace" do
- Thor::Util.namespaces_in_content("class Blat; end")
- expect(defined?(Blat)).not_to be
- expect(defined?(Thor::Sandbox::Blat)).to be
- end
- end
-
- describe "#snake_case" do
- it "preserves no-cap strings" do
- expect(Thor::Util.snake_case("foo")).to eq("foo")
- expect(Thor::Util.snake_case("foo_bar")).to eq("foo_bar")
- end
-
- it "downcases all-caps strings" do
- expect(Thor::Util.snake_case("FOO")).to eq("foo")
- expect(Thor::Util.snake_case("FOO_BAR")).to eq("foo_bar")
- end
-
- it "downcases initial-cap strings" do
- expect(Thor::Util.snake_case("Foo")).to eq("foo")
- end
-
- it "replaces camel-casing with underscores" do
- expect(Thor::Util.snake_case("FooBarBaz")).to eq("foo_bar_baz")
- expect(Thor::Util.snake_case("Foo_BarBaz")).to eq("foo_bar_baz")
- end
-
- it "places underscores between multiple capitals" do
- expect(Thor::Util.snake_case("ABClass")).to eq("a_b_class")
- end
- end
-
- describe "#find_class_and_command_by_namespace" do
- it "returns a Thor::Group class if full namespace matches" do
- expect(Thor::Util.find_class_and_command_by_namespace("my_counter")).to eq([MyCounter, nil])
- end
-
- it "returns a Thor class if full namespace matches" do
- expect(Thor::Util.find_class_and_command_by_namespace("thor")).to eq([Thor, nil])
- end
-
- it "returns a Thor class and the command name" do
- expect(Thor::Util.find_class_and_command_by_namespace("thor:help")).to eq([Thor, "help"])
- end
-
- it "falls back in the namespace:command look up even if a full namespace does not match" do
- Thor.const_set(:Help, Module.new)
- expect(Thor::Util.find_class_and_command_by_namespace("thor:help")).to eq([Thor, "help"])
- Thor.send :remove_const, :Help
- end
-
- it "falls back on the default namespace class if nothing else matches" do
- expect(Thor::Util.find_class_and_command_by_namespace("test")).to eq([Scripts::MyDefaults, "test"])
- end
- end
-
- describe "#thor_classes_in" do
- it "returns thor classes inside the given class" do
- expect(Thor::Util.thor_classes_in(MyScript)).to eq([MyScript::AnotherScript])
- expect(Thor::Util.thor_classes_in(MyScript::AnotherScript)).to be_empty
- end
- end
-
- describe "#user_home" do
- before do
- allow(ENV).to receive(:[])
- Thor::Util.clear_user_home!
- end
-
- it "returns the user path if no variable is set on the environment" do
- expect(Thor::Util.user_home).to eq(File.expand_path("~"))
- end
-
- it "returns the *nix system path if file cannot be expanded and separator does not exist" do
- expect(File).to receive(:expand_path).with("~").and_raise(RuntimeError)
- previous_value = File::ALT_SEPARATOR
- capture(:stderr) { File.const_set(:ALT_SEPARATOR, false) } # rubocop:disable SymbolName
- expect(Thor::Util.user_home).to eq("/")
- capture(:stderr) { File.const_set(:ALT_SEPARATOR, previous_value) } # rubocop:disable SymbolName
- end
-
- it "returns the windows system path if file cannot be expanded and a separator exists" do
- expect(File).to receive(:expand_path).with("~").and_raise(RuntimeError)
- previous_value = File::ALT_SEPARATOR
- capture(:stderr) { File.const_set(:ALT_SEPARATOR, true) } # rubocop:disable SymbolName
- expect(Thor::Util.user_home).to eq("C:/")
- capture(:stderr) { File.const_set(:ALT_SEPARATOR, previous_value) } # rubocop:disable SymbolName
- end
-
- it "returns HOME/.thor if set" do
- allow(ENV).to receive(:[]).with("HOME").and_return("/home/user/")
- expect(Thor::Util.user_home).to eq("/home/user/")
- end
-
- it "returns path with HOMEDRIVE and HOMEPATH if set" do
- allow(ENV).to receive(:[]).with("HOMEDRIVE").and_return("D:/")
- allow(ENV).to receive(:[]).with("HOMEPATH").and_return("Documents and Settings/James")
- expect(Thor::Util.user_home).to eq("D:/Documents and Settings/James")
- end
-
- it "returns APPDATA/.thor if set" do
- allow(ENV).to receive(:[]).with("APPDATA").and_return("/home/user/")
- expect(Thor::Util.user_home).to eq("/home/user/")
- end
- end
-
- describe "#thor_root_glob" do
- before do
- allow(ENV).to receive(:[])
- Thor::Util.clear_user_home!
- end
-
- it "escapes globs in path" do
- allow(ENV).to receive(:[]).with("HOME").and_return("/home/user{1}/")
- expect(Dir).to receive(:[]).with('/home/user\\{1\\}/.thor/*').and_return([])
- expect(Thor::Util.thor_root_glob).to eq([])
- end
- end
-
- describe "#globs_for" do
- it "escapes globs in path" do
- expect(Thor::Util.globs_for("/home/apps{1}")).to eq([
- '/home/apps\\{1\\}/Thorfile',
- '/home/apps\\{1\\}/*.thor',
- '/home/apps\\{1\\}/tasks/*.thor',
- '/home/apps\\{1\\}/lib/tasks/*.thor'
- ])
- end
- end
-
- describe "#escape_globs" do
- it "escapes ? * { } [ ] glob characters" do
- expect(Thor::Util.escape_globs("apps?")).to eq('apps\\?')
- expect(Thor::Util.escape_globs("apps*")).to eq('apps\\*')
- expect(Thor::Util.escape_globs("apps {1}")).to eq('apps \\{1\\}')
- expect(Thor::Util.escape_globs("apps [1]")).to eq('apps \\[1\\]')
- end
- end
-end
diff --git a/thor.gemspec b/thor.gemspec
index 74fe55a..567e671 100644
--- a/thor.gemspec
+++ b/thor.gemspec
@@ -6,19 +6,16 @@ require "thor/version"
Gem::Specification.new do |spec|
spec.add_development_dependency "bundler", "~> 1.0"
spec.authors = ["Yehuda Katz", "José Valim"]
- spec.description = %q(Thor is a toolkit for building powerful command-line interfaces.)
+ spec.description = "Thor is a toolkit for building powerful command-line interfaces."
spec.email = "ruby-thor at googlegroups.com"
- spec.executables = %w[thor]
- spec.files = %w[.document CHANGELOG.md LICENSE.md README.md Thorfile thor.gemspec]
- spec.files += Dir.glob("bin/**/*")
- spec.files += Dir.glob("lib/**/*.rb")
- spec.files += Dir.glob("spec/**/*")
+ spec.executables = %w(thor)
+ spec.files = %w(.document thor.gemspec) + Dir["*.md", "bin/*", "lib/**/*.rb"]
spec.homepage = "http://whatisthor.com/"
- spec.licenses = %w[MIT]
+ spec.licenses = %w(MIT)
spec.name = "thor"
- spec.require_paths = %w[lib]
+ spec.require_paths = %w(lib)
+ spec.required_ruby_version = ">= 1.8.7"
spec.required_rubygems_version = ">= 1.3.5"
spec.summary = spec.description
- spec.test_files = Dir.glob("spec/**/*")
spec.version = Thor::VERSION
end
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ruby-extras/ruby-thor.git
More information about the Pkg-ruby-extras-commits
mailing list