[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