[DRE-commits] [pry] 04/08: Refresh patch: import upstream rspec

Youhei SASAKI uwabami-guest at moszumanska.debian.org
Tue Aug 12 11:11:08 UTC 2014


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

uwabami-guest pushed a commit to branch master
in repository pry.

commit 371700f1a1fa5b5ea92e25879d81344b6a8e10f9
Author: Youhei SASAKI <uwabami at gfd-dennou.org>
Date:   Tue Aug 12 19:53:16 2014 +0900

    Refresh patch: import upstream rspec
    
    Signed-off-by: Youhei SASAKI <uwabami at gfd-dennou.org>
---
 .../patches/0001-Import-upstream-rspec-files.patch | 12420 +++++++++++++++++++
 ...2-Modify-upstream-spec-for-Debian-Package.patch |    37 +
 debian/patches/fix_spelling.patch                  |    15 -
 debian/patches/series                              |     3 +-
 4 files changed, 12459 insertions(+), 16 deletions(-)

diff --git a/debian/patches/0001-Import-upstream-rspec-files.patch b/debian/patches/0001-Import-upstream-rspec-files.patch
new file mode 100644
index 0000000..9bb0737
--- /dev/null
+++ b/debian/patches/0001-Import-upstream-rspec-files.patch
@@ -0,0 +1,12420 @@
+From: Youhei SASAKI <uwabami at gfd-dennou.org>
+Date: Tue, 12 Aug 2014 19:36:30 +0900
+Subject: Import upstream rspec files
+
+Signed-off-by: Youhei SASAKI <uwabami at gfd-dennou.org>
+---
+ spec/Procfile                             |   3 +
+ spec/cli_spec.rb                          |  88 ++++
+ spec/code_object_spec.rb                  | 283 ++++++++++
+ spec/code_spec.rb                         | 256 +++++++++
+ spec/command_helpers_spec.rb              |  29 ++
+ spec/command_integration_spec.rb          | 564 ++++++++++++++++++++
+ spec/command_set_spec.rb                  | 676 ++++++++++++++++++++++++
+ spec/command_spec.rb                      | 819 +++++++++++++++++++++++++++++
+ spec/commands/amend_line_spec.rb          | 247 +++++++++
+ spec/commands/bang_spec.rb                |  24 +
+ spec/commands/cat/file_formatter_spec.rb  |  83 +++
+ spec/commands/cat_spec.rb                 | 164 ++++++
+ spec/commands/cd_spec.rb                  | 259 ++++++++++
+ spec/commands/disable_pry_spec.rb         |  25 +
+ spec/commands/edit_spec.rb                | 768 +++++++++++++++++++++++++++
+ spec/commands/exit_all_spec.rb            |  27 +
+ spec/commands/exit_program_spec.rb        |  19 +
+ spec/commands/exit_spec.rb                |  28 +
+ spec/commands/find_method_spec.rb         |  63 +++
+ spec/commands/gem_list_spec.rb            |  25 +
+ spec/commands/gist_spec.rb                |  32 ++
+ spec/commands/help_spec.rb                |  56 ++
+ spec/commands/hist_spec.rb                | 204 ++++++++
+ spec/commands/jump_to_spec.rb             |  15 +
+ spec/commands/ls_spec.rb                  | 246 +++++++++
+ spec/commands/play_spec.rb                | 182 +++++++
+ spec/commands/raise_up_spec.rb            |  56 ++
+ spec/commands/reload_code_spec.rb         |  21 +
+ spec/commands/save_file_spec.rb           | 177 +++++++
+ spec/commands/shell_command_spec.rb       |  63 +++
+ spec/commands/show_doc_spec.rb            | 573 +++++++++++++++++++++
+ spec/commands/show_input_spec.rb          |  17 +
+ spec/commands/show_source_spec.rb         | 829 ++++++++++++++++++++++++++++++
+ spec/commands/watch_expression_spec.rb    | 119 +++++
+ spec/commands/whereami_spec.rb            | 237 +++++++++
+ spec/completion_spec.rb                   | 214 ++++++++
+ spec/config_spec.rb                       | 189 +++++++
+ spec/control_d_handler_spec.rb            |  62 +++
+ spec/documentation_helper_spec.rb         |  68 +++
+ spec/editor_spec.rb                       |  68 +++
+ spec/exception_whitelist_spec.rb          |  21 +
+ spec/fixtures/candidate_helper1.rb        |  11 +
+ spec/fixtures/candidate_helper2.rb        |   8 +
+ spec/fixtures/cat_load_path               |   0
+ spec/fixtures/cat_load_path.rb            |   0
+ spec/fixtures/example.erb                 |   5 +
+ spec/fixtures/example_nesting.rb          |  33 ++
+ spec/fixtures/pry_history                 |   3 +
+ spec/fixtures/show_source_doc_examples.rb |  22 +
+ spec/fixtures/slinky.rb                   |   0
+ spec/fixtures/slinky/stinky.rb            |   0
+ spec/fixtures/testlinkrc                  |   1 +
+ spec/fixtures/testrc                      |   2 +
+ spec/fixtures/testrcbad                   |   2 +
+ spec/fixtures/whereami_helper.rb          |   6 +
+ spec/helper.rb                            |  34 ++
+ spec/helpers/table_spec.rb                | 105 ++++
+ spec/history_array_spec.rb                |  71 +++
+ spec/history_spec.rb                      | 154 ++++++
+ spec/hooks_spec.rb                        | 475 +++++++++++++++++
+ spec/indent_spec.rb                       | 301 +++++++++++
+ spec/method/patcher_spec.rb               |  34 ++
+ spec/method_spec.rb                       | 507 ++++++++++++++++++
+ spec/pager_spec.rb                        |  66 +++
+ spec/prompt_spec.rb                       |  61 +++
+ spec/pry_defaults_spec.rb                 | 428 +++++++++++++++
+ spec/pry_output_spec.rb                   | 117 +++++
+ spec/pry_repl_spec.rb                     | 102 ++++
+ spec/pry_spec.rb                          | 414 +++++++++++++++
+ spec/pryrc_spec.rb                        |  97 ++++
+ spec/regression/readline_spec.rb          |  39 ++
+ spec/run_command_spec.rb                  |  23 +
+ spec/spec_helpers/bacon.rb                |  86 ++++
+ spec/spec_helpers/mock_pry.rb             |  44 ++
+ spec/spec_helpers/repl_tester.rb          | 112 ++++
+ spec/sticky_locals_spec.rb                | 180 +++++++
+ spec/syntax_checking_spec.rb              |  81 +++
+ spec/wrapped_module_spec.rb               | 276 ++++++++++
+ 78 files changed, 11799 insertions(+)
+ create mode 100644 spec/Procfile
+ create mode 100644 spec/cli_spec.rb
+ create mode 100644 spec/code_object_spec.rb
+ create mode 100644 spec/code_spec.rb
+ create mode 100644 spec/command_helpers_spec.rb
+ create mode 100644 spec/command_integration_spec.rb
+ create mode 100644 spec/command_set_spec.rb
+ create mode 100644 spec/command_spec.rb
+ create mode 100644 spec/commands/amend_line_spec.rb
+ create mode 100644 spec/commands/bang_spec.rb
+ create mode 100644 spec/commands/cat/file_formatter_spec.rb
+ create mode 100644 spec/commands/cat_spec.rb
+ create mode 100644 spec/commands/cd_spec.rb
+ create mode 100644 spec/commands/disable_pry_spec.rb
+ create mode 100644 spec/commands/edit_spec.rb
+ create mode 100644 spec/commands/exit_all_spec.rb
+ create mode 100644 spec/commands/exit_program_spec.rb
+ create mode 100644 spec/commands/exit_spec.rb
+ create mode 100644 spec/commands/find_method_spec.rb
+ create mode 100644 spec/commands/gem_list_spec.rb
+ create mode 100644 spec/commands/gist_spec.rb
+ create mode 100644 spec/commands/help_spec.rb
+ create mode 100644 spec/commands/hist_spec.rb
+ create mode 100644 spec/commands/jump_to_spec.rb
+ create mode 100644 spec/commands/ls_spec.rb
+ create mode 100644 spec/commands/play_spec.rb
+ create mode 100644 spec/commands/raise_up_spec.rb
+ create mode 100644 spec/commands/reload_code_spec.rb
+ create mode 100644 spec/commands/save_file_spec.rb
+ create mode 100644 spec/commands/shell_command_spec.rb
+ create mode 100644 spec/commands/show_doc_spec.rb
+ create mode 100644 spec/commands/show_input_spec.rb
+ create mode 100644 spec/commands/show_source_spec.rb
+ create mode 100644 spec/commands/watch_expression_spec.rb
+ create mode 100644 spec/commands/whereami_spec.rb
+ create mode 100644 spec/completion_spec.rb
+ create mode 100644 spec/config_spec.rb
+ create mode 100644 spec/control_d_handler_spec.rb
+ create mode 100644 spec/documentation_helper_spec.rb
+ create mode 100644 spec/editor_spec.rb
+ create mode 100644 spec/exception_whitelist_spec.rb
+ create mode 100644 spec/fixtures/candidate_helper1.rb
+ create mode 100644 spec/fixtures/candidate_helper2.rb
+ create mode 100644 spec/fixtures/cat_load_path
+ create mode 100644 spec/fixtures/cat_load_path.rb
+ create mode 100644 spec/fixtures/example.erb
+ create mode 100644 spec/fixtures/example_nesting.rb
+ create mode 100644 spec/fixtures/pry_history
+ create mode 100644 spec/fixtures/show_source_doc_examples.rb
+ create mode 100644 spec/fixtures/slinky.rb
+ create mode 100644 spec/fixtures/slinky/stinky.rb
+ create mode 120000 spec/fixtures/testlinkrc
+ create mode 100644 spec/fixtures/testrc
+ create mode 100644 spec/fixtures/testrcbad
+ create mode 100644 spec/fixtures/whereami_helper.rb
+ create mode 100644 spec/helper.rb
+ create mode 100644 spec/helpers/table_spec.rb
+ create mode 100644 spec/history_array_spec.rb
+ create mode 100644 spec/history_spec.rb
+ create mode 100644 spec/hooks_spec.rb
+ create mode 100644 spec/indent_spec.rb
+ create mode 100644 spec/method/patcher_spec.rb
+ create mode 100644 spec/method_spec.rb
+ create mode 100644 spec/pager_spec.rb
+ create mode 100644 spec/prompt_spec.rb
+ create mode 100644 spec/pry_defaults_spec.rb
+ create mode 100644 spec/pry_output_spec.rb
+ create mode 100644 spec/pry_repl_spec.rb
+ create mode 100644 spec/pry_spec.rb
+ create mode 100644 spec/pryrc_spec.rb
+ create mode 100644 spec/regression/readline_spec.rb
+ create mode 100644 spec/run_command_spec.rb
+ create mode 100644 spec/spec_helpers/bacon.rb
+ create mode 100644 spec/spec_helpers/mock_pry.rb
+ create mode 100644 spec/spec_helpers/repl_tester.rb
+ create mode 100644 spec/sticky_locals_spec.rb
+ create mode 100644 spec/syntax_checking_spec.rb
+ create mode 100644 spec/wrapped_module_spec.rb
+
+diff --git a/spec/Procfile b/spec/Procfile
+new file mode 100644
+index 0000000..d0fec32
+--- /dev/null
++++ b/spec/Procfile
+@@ -0,0 +1,3 @@
++# Run this with:
++# gem install foreman && foreman start -f spec/Procfile
++pryhere: sh -c '(cd ..; rake pry)'
+diff --git a/spec/cli_spec.rb b/spec/cli_spec.rb
+new file mode 100644
+index 0000000..0f6f88c
+--- /dev/null
++++ b/spec/cli_spec.rb
+@@ -0,0 +1,88 @@
++require_relative 'helper'
++
++describe Pry::Hooks do
++  before do
++    Pry::CLI.reset
++  end
++
++  describe "parsing options" do
++    it 'should raise if no options defined' do
++      lambda { Pry::CLI.parse_options(["--nothing"]) }.should.raise Pry::CLI::NoOptionsError
++    end
++
++    it "should remove args from ARGV by default" do
++      ARGV << '-v'
++      Pry::CLI.add_options do
++        on :v, "Display the Pry version" do
++          # irrelevant
++        end
++      end.parse_options
++      ARGV.include?('-v').should == false
++    end
++  end
++
++  describe "adding options" do
++    it "should be able to add an option" do
++      run = false
++
++      Pry::CLI.add_options do
++        on :optiontest, "A test option" do
++          run = true
++        end
++      end.parse_options(["--optiontest"])
++
++      run.should == true
++    end
++
++    it "should be able to add multiple options" do
++      run = false
++      run2 = false
++
++      Pry::CLI.add_options do
++        on :optiontest, "A test option" do
++          run = true
++        end
++      end.add_options do
++        on :optiontest2, "Another test option" do
++          run2 = true
++        end
++      end.parse_options(["--optiontest", "--optiontest2"])
++
++      run.should.be.true
++      run2.should.be.true
++    end
++
++  end
++
++  describe "processing options" do
++    it "should be able to process an option" do
++      run = false
++
++      Pry::CLI.add_options do
++        on :optiontest, "A test option"
++      end.add_option_processor do |opts|
++        run = true if opts.present?(:optiontest)
++      end.parse_options(["--optiontest"])
++
++      run.should == true
++    end
++
++    it "should be able to  process multiple options" do
++      run = false
++      run2 = false
++
++      Pry::CLI.add_options do
++        on :optiontest, "A test option"
++        on :optiontest2, "Another test option"
++      end.add_option_processor do |opts|
++        run = true if opts.present?(:optiontest)
++      end.add_option_processor do |opts|
++        run2 = true if opts.present?(:optiontest2)
++      end.parse_options(["--optiontest", "--optiontest2"])
++
++      run.should == true
++      run2.should == true
++    end
++
++  end
++end
+diff --git a/spec/code_object_spec.rb b/spec/code_object_spec.rb
+new file mode 100644
+index 0000000..2184c98
+--- /dev/null
++++ b/spec/code_object_spec.rb
+@@ -0,0 +1,283 @@
++require_relative 'helper'
++
++describe Pry::CodeObject do
++  describe "basic lookups" do
++    before do
++      @obj = Object.new
++      def @obj.ziggy
++        "a flight of scarlet pigeons thunders round my thoughts"
++      end
++
++      class ClassyWassy
++        def piggy
++          binding
++        end
++      end
++
++      @p = Pry.new
++      @p.binding_stack = [binding]
++    end
++
++    after do
++      Object.remove_const(:ClassyWassy)
++    end
++
++    it 'should lookup methods' do
++      m = Pry::CodeObject.lookup("@obj.ziggy", @p)
++      m.is_a?(Pry::Method).should == true
++      m.name.to_sym.should == :ziggy
++    end
++
++    it 'should lookup modules' do
++      m = Pry::CodeObject.lookup("ClassyWassy", @p)
++      m.is_a?(Pry::WrappedModule).should == true
++      m.source.should =~ /piggy/
++    end
++
++    it 'should lookup procs' do
++      my_proc = proc { :hello }
++      @p.binding_stack = [binding]
++      m = Pry::CodeObject.lookup("my_proc", @p)
++      m.is_a?(Pry::Method).should == true
++      m.source.should =~ /hello/
++    end
++
++    describe 'commands lookup' do
++      before do
++        @p = Pry.new
++        @p.binding_stack = [binding]
++      end
++
++      it 'should return command class' do
++        @p.commands.command "jeremy-jones" do
++          "lobster"
++        end
++        m = Pry::CodeObject.lookup("jeremy-jones", @p)
++        (m <= Pry::Command).should == true
++        m.source.should =~ /lobster/
++      end
++
++      describe "class commands" do
++        before do
++          class LobsterLady < Pry::ClassCommand
++            match "lobster-lady"
++            description "nada."
++            def process
++              "lobster"
++            end
++          end
++        end
++
++        after do
++          Object.remove_const(:LobsterLady)
++        end
++
++        it 'should return Pry::ClassCommand class when looking up class command' do
++          Pry.config.commands.add_command(LobsterLady)
++          m = Pry::CodeObject.lookup("lobster-lady", @p)
++          (m <= Pry::ClassCommand).should == true
++          m.source.should =~ /class LobsterLady/
++          Pry.config.commands.delete("lobster-lady")
++        end
++
++        it 'should return Pry::WrappedModule when looking up command class directly (as a class, not as a command)' do
++          Pry.config.commands.add_command(LobsterLady)
++          m = Pry::CodeObject.lookup("LobsterLady", @p)
++          m.is_a?(Pry::WrappedModule).should == true
++          m.source.should =~ /class LobsterLady/
++          Pry.config.commands.delete("lobster-lady")
++        end
++      end
++
++      it 'looks up commands by :listing name as well' do
++        @p.commands.command /jeremy-.*/, "", :listing => "jeremy-baby" do
++          "lobster"
++        end
++        m = Pry::CodeObject.lookup("jeremy-baby", @p)
++        (m <= Pry::Command).should == true
++        m.source.should =~ /lobster/
++      end
++
++      it 'finds nothing when passing nil as the first argument' do
++        Pry::CodeObject.lookup(nil, @p).should == nil
++      end
++
++    end
++
++    it 'should lookup instance methods defined on classes accessed via local variable' do
++      o = Class.new do
++        def princess_bubblegum
++          "mathematic!"
++        end
++      end
++
++      @p.binding_stack = [binding]
++      m = Pry::CodeObject.lookup("o#princess_bubblegum", @p)
++      m.is_a?(Pry::Method).should == true
++      m.source.should =~ /mathematic!/
++    end
++
++    it 'should lookup class methods defined on classes accessed via local variable' do
++      o = Class.new do
++        def self.finn
++          "4 realzies"
++        end
++      end
++      @p.binding_stack = [binding]
++      m = Pry::CodeObject.lookup("o.finn", @p)
++      m.is_a?(Pry::Method).should == true
++      m.source.should =~ /4 realzies/
++    end
++
++    it 'should lookup the class of an object (when given a variable)' do
++      moddy = ClassyWassy.new
++      @p.binding_stack = [binding]
++      m = Pry::CodeObject.lookup("moddy", @p)
++      m.is_a?(Pry::WrappedModule).should == true
++      m.source.should =~ /piggy/
++    end
++
++    describe "inferring object from binding when lookup str is empty/nil" do
++      before do
++        @b1 = Pry.binding_for(ClassyWassy)
++        @b2 = Pry.binding_for(ClassyWassy.new)
++      end
++
++      describe "infer module objects" do
++        it 'should infer module object when binding self is a module' do
++          ["", nil].each do |v|
++            @p.binding_stack = [@b1]
++            m = Pry::CodeObject.lookup(v, @p)
++            m.is_a?(Pry::WrappedModule).should == true
++            m.name.should =~ /ClassyWassy/
++          end
++        end
++
++        it 'should infer module object when binding self is an instance' do
++          ["", nil].each do |v|
++            @p.binding_stack = [@b2]
++            m = Pry::CodeObject.lookup(v, @p)
++            m.is_a?(Pry::WrappedModule).should == true
++            m.name.should =~ /ClassyWassy/
++          end
++        end
++      end
++
++      describe "infer method objects" do
++        it 'should infer method object from binding when inside method context' do
++          b = ClassyWassy.new.piggy
++
++          ["", nil].each do |v|
++            @p.binding_stack = [b]
++            m = Pry::CodeObject.lookup(v, @p)
++            m.is_a?(Pry::Method).should == true
++            m.name.should =~ /piggy/
++          end
++        end
++      end
++    end
++  end
++
++  describe "lookups with :super" do
++    before do
++      class MyClassyWassy; end
++      class CuteSubclass < MyClassyWassy; end
++      @p = Pry.new
++      @p.binding_stack = [binding]
++    end
++
++    after do
++      Object.remove_const(:MyClassyWassy)
++      Object.remove_const(:CuteSubclass)
++    end
++
++    it 'should lookup original class with :super => 0' do
++      m = Pry::CodeObject.lookup("CuteSubclass", @p, :super => 0)
++      m.is_a?(Pry::WrappedModule).should == true
++      m.wrapped.should == CuteSubclass
++    end
++
++    it 'should lookup immediate super class with :super => 1' do
++      m = Pry::CodeObject.lookup("CuteSubclass", @p, :super => 1)
++      m.is_a?(Pry::WrappedModule).should == true
++      m.wrapped.should == MyClassyWassy
++    end
++
++    it 'should ignore :super parameter for commands' do
++      p = Pry.new
++      p.commands.command "jeremy-jones" do
++        "lobster"
++      end
++      p.binding_stack = [binding]
++      m = Pry::CodeObject.lookup("jeremy-jones", p, :super => 10)
++      m.source.should =~ /lobster/
++    end
++  end
++
++  describe "precedence" do
++    before do
++      class ClassyWassy
++        class Puff
++          def tiggy
++          end
++        end
++
++        def Puff
++        end
++
++        def piggy
++        end
++      end
++
++      Object.class_eval do
++        def ClassyWassy
++          :ducky
++        end
++      end
++
++      @p = Pry.new
++      @p.binding_stack = [binding]
++    end
++
++    after do
++      Object.remove_const(:ClassyWassy)
++      Object.remove_method(:ClassyWassy)
++    end
++
++    it 'should look up classes before methods (at top-level)' do
++      m = Pry::CodeObject.lookup("ClassyWassy", @p)
++      m.is_a?(Pry::WrappedModule).should == true
++      m.source.should =~ /piggy/
++    end
++
++    it 'should look up methods before classes when ending in () (at top-level)' do
++      m = Pry::CodeObject.lookup("ClassyWassy()", @p)
++      m.is_a?(Pry::Method).should == true
++      m.source.should =~ /ducky/
++    end
++
++    it 'should look up classes before methods when namespaced' do
++      m = Pry::CodeObject.lookup("ClassyWassy::Puff", @p)
++      m.is_a?(Pry::WrappedModule).should == true
++      m.source.should =~ /tiggy/
++    end
++
++    it 'should look up locals before methods' do
++      b = Pry.binding_for(ClassyWassy)
++      b.eval("piggy = Puff.new")
++      @p.binding_stack = [b]
++      o = Pry::CodeObject.lookup("piggy", @p)
++      o.is_a?(Pry::WrappedModule).should == true
++    end
++
++    # actually locals are never looked up (via co.default_lookup)  when they're classes, it
++    # just falls through to co.method_or_class
++    it 'should look up classes before locals' do
++      c = ClassyWassy
++      @p.binding_stack = [binding]
++      o = Pry::CodeObject.lookup("c", @p)
++      o.is_a?(Pry::WrappedModule).should == true
++      o.wrapped.should == ClassyWassy
++    end
++  end
++end
+diff --git a/spec/code_spec.rb b/spec/code_spec.rb
+new file mode 100644
+index 0000000..d9fad6d
+--- /dev/null
++++ b/spec/code_spec.rb
+@@ -0,0 +1,256 @@
++require_relative 'helper'
++
++describe Pry::Code do
++  describe '.from_file' do
++    should 'read lines from a file on disk' do
++      Pry::Code.from_file('lib/pry.rb').length.should > 0
++    end
++
++    should 'read lines from Pry\'s line buffer' do
++      pry_eval ':hay_guys'
++      Pry::Code.from_file('(pry)').grep(/:hay_guys/).length.should == 1
++    end
++
++    should 'default to unknown' do
++      temp_file('') do |f|
++        Pry::Code.from_file(f.path).code_type.should == :unknown
++      end
++    end
++
++    should 'check the extension' do
++      temp_file('.c') do |f|
++        Pry::Code.from_file(f.path).code_type.should == :c
++      end
++    end
++
++    should 'raise an error if the file doesn\'t exist' do
++      proc do
++        Pry::Code.from_file('/knalkjsdnalsd/alkjdlkq')
++      end.should.raise(MethodSource::SourceNotFoundError)
++    end
++
++    should 'check for files relative to origin pwd' do
++      Dir.chdir('spec') do |f|
++        Pry::Code.from_file('spec/' + File.basename(__FILE__)).code_type.should == :ruby
++      end
++    end
++
++    should 'check for Ruby files relative to origin pwd with `.rb` omitted' do
++      Dir.chdir('spec') do |f|
++        Pry::Code.from_file('spec/' + File.basename(__FILE__, '.*')).code_type.should == :ruby
++      end
++    end
++
++    should 'find files that are relative to the current working directory' do
++      Dir.chdir('spec') do |f|
++        Pry::Code.from_file(File.basename(__FILE__)).code_type.should == :ruby
++      end
++    end
++
++    describe 'find Ruby files relative to $LOAD_PATH' do
++      before do
++        $LOAD_PATH << 'spec/fixtures'
++      end
++
++      after do
++        $LOAD_PATH.delete 'spec/fixtures'
++      end
++
++      it 'finds files with `.rb` extension' do
++        Pry::Code.from_file('slinky.rb').code_type.should == :ruby
++      end
++
++      it 'finds files with `.rb` omitted' do
++        Pry::Code.from_file('slinky').code_type.should == :ruby
++      end
++
++      it 'finds files in a relative directory with `.rb` extension' do
++        Pry::Code.from_file('../helper.rb').code_type.should == :ruby
++      end
++
++      it 'finds files in a relative directory with `.rb` omitted' do
++        Pry::Code.from_file('../helper').code_type.should == :ruby
++      end
++
++      it "doesn't confuse files with the same name, but without an extension" do
++        Pry::Code.from_file('cat_load_path').code_type.should == :unknown
++      end
++
++      it "doesn't confuse files with the same name, but with an extension" do
++        Pry::Code.from_file('cat_load_path.rb').code_type.should == :ruby
++      end
++    end
++  end
++
++  describe '.from_method' do
++    should 'read lines from a method\'s definition' do
++      m = Pry::Method.from_obj(Pry, :load_history)
++      Pry::Code.from_method(m).length.should > 0
++    end
++  end
++
++  describe '#initialize' do
++    before do
++      @str = Pry::Helpers::CommandHelpers.unindent <<-CODE
++        def hay
++          :guys
++        end
++      CODE
++
++      @array = ['def hay', '  :guys', 'end']
++    end
++
++    should 'break a string into lines' do
++      Pry::Code.new(@str).length.should == 3
++    end
++
++    should 'accept an array' do
++      Pry::Code.new(@array).length.should == 3
++    end
++
++    it 'an array or string should produce an equivalent object' do
++      Pry::Code.new(@str).should == Pry::Code.new(@array)
++    end
++  end
++
++  describe 'filters and formatters' do
++    def raw(str)
++      Pry::Helpers::Text.strip_color(str)
++    end
++    before do
++      @code = Pry::Code(Pry::Helpers::CommandHelpers.unindent <<-STR)
++        class MyProgram
++          def self.main
++            puts 'Hello, world!'
++          end
++        end
++      STR
++    end
++
++    describe 'filters' do
++      describe '#between' do
++        should 'work with an inclusive range' do
++          @code = @code.between(1..3)
++          @code.length.should == 3
++          raw(@code).should =~ /\Aclass MyProgram/
++          raw(@code).should =~ /world!'\Z/
++        end
++
++        should 'default to an inclusive range' do
++          @code = @code.between(3, 5)
++          @code.length.should == 3
++        end
++
++        should 'work with an exclusive range' do
++          @code = @code.between(2...4)
++          @code.length.should == 2
++          raw(@code).should =~ /\A  def self/
++          raw(@code).should =~ /world!'\Z/
++        end
++
++        should 'use real line numbers for positive indices' do
++          @code = @code.after(3, 3)
++          @code = @code.between(4, 4)
++          @code.length.should == 1
++          raw(@code).should =~ /\A  end\Z/
++        end
++      end
++
++      describe '#before' do
++        should 'work' do
++          @code = @code.before(3, 1)
++          raw(@code).should =~ /\A  def self\.main\Z/
++        end
++      end
++
++      describe '#around' do
++        should 'work' do
++          @code = @code.around(3, 1)
++          @code.length.should == 3
++          raw(@code).should =~ /\A  def self/
++          raw(@code).should =~ /  end\Z/
++        end
++      end
++
++      describe '#after' do
++        should 'work' do
++          @code = @code.after(3, 1)
++          raw(@code).should =~ /\A  end\Z/
++        end
++      end
++
++      describe '#grep' do
++        should 'work' do
++          @code = @code.grep(/end/)
++          @code.length.should == 2
++        end
++      end
++    end
++
++    describe 'formatters' do
++      describe '#with_line_numbers' do
++        should 'show line numbers' do
++          @code = @code.with_line_numbers
++          @code.should =~ /1:/
++        end
++
++        should 'disable line numbers when falsy' do
++          @code = @code.with_line_numbers
++          @code = @code.with_line_numbers(false)
++          @code.should.not =~ /1:/
++        end
++      end
++
++      describe '#with_marker' do
++        should 'show a marker in the right place' do
++          @code = @code.with_marker(2)
++          raw(@code).should =~ /^ =>   def self/
++        end
++
++        should 'disable the marker when falsy' do
++          @code = @code.with_marker(2)
++          @code = @code.with_marker(false)
++          raw(@code).should =~ /^  def self/
++        end
++      end
++
++      describe '#with_indentation' do
++        should 'indent the text' do
++          @code = @code.with_indentation(2)
++          raw(@code).should =~ /^    def self/
++        end
++
++        should 'disable the indentation when falsy' do
++          @code = @code.with_indentation(2)
++          @code = @code.with_indentation(false)
++          raw(@code).should =~ /^  def self/
++        end
++      end
++    end
++
++    describe 'composition' do
++      describe 'grep and with_line_numbers' do
++        should 'work' do
++          @code = @code.grep(/end/).with_line_numbers
++          raw(@code).should =~ /\A4:   end/
++          raw(@code).should =~ /5: end\Z/
++        end
++      end
++
++      describe 'grep and before and with_line_numbers' do
++        should 'work' do
++          @code = @code.grep(/e/).before(5, 5).with_line_numbers
++          raw(@code).should =~ /\A2:   def self.main\n3:/
++          raw(@code).should =~ /4:   end\Z/
++        end
++      end
++
++      describe 'before and after' do
++        should 'work' do
++          @code = @code.before(4, 2).after(2)
++          raw(@code).should == "    puts 'Hello, world!'\n"
++        end
++      end
++    end
++  end
++end
+diff --git a/spec/command_helpers_spec.rb b/spec/command_helpers_spec.rb
+new file mode 100644
+index 0000000..2cbee84
+--- /dev/null
++++ b/spec/command_helpers_spec.rb
+@@ -0,0 +1,29 @@
++require_relative 'helper'
++
++describe Pry::Helpers::CommandHelpers do
++  before do
++    @helper = Pry::Helpers::CommandHelpers
++  end
++
++  describe "unindent" do
++    it "should remove the same prefix from all lines" do
++      @helper.unindent(" one\n two\n").should == "one\ntwo\n"
++    end
++
++    it "should not be phased by empty lines" do
++      @helper.unindent(" one\n\n two\n").should == "one\n\ntwo\n"
++    end
++
++    it "should only remove a common prefix" do
++      @helper.unindent("  one\n two\n").should == " one\ntwo\n"
++    end
++
++    it "should also remove tabs if present" do
++      @helper.unindent("\tone\n\ttwo\n").should == "one\ntwo\n"
++    end
++
++    it "should ignore lines starting with --" do
++      @helper.unindent(" one\n--\n two\n").should == "one\n--\ntwo\n"
++    end
++  end
++end
+diff --git a/spec/command_integration_spec.rb b/spec/command_integration_spec.rb
+new file mode 100644
+index 0000000..d8707fa
+--- /dev/null
++++ b/spec/command_integration_spec.rb
+@@ -0,0 +1,564 @@
++require_relative 'helper'
++
++
++describe "commands" do
++  before do
++    @str_output = StringIO.new
++    @o = Object.new
++
++    # Shortcuts. They save a lot of typing.
++    @bs1 = "Pad.bs1 = _pry_.binding_stack.dup"
++    @bs2 = "Pad.bs2 = _pry_.binding_stack.dup"
++    @bs3 = "Pad.bs3 = _pry_.binding_stack.dup"
++
++    @self  = "Pad.self = self"
++
++    @command_tester = Pry::CommandSet.new do
++      command "command1", "command 1 test" do
++        output.puts "command1"
++      end
++
++      command "command2", "command 2 test" do |arg|
++        output.puts arg
++      end
++    end
++
++    Pad.bong = "bong"
++  end
++
++  after do
++    Pad.clear
++    Pry.reset_defaults
++  end
++
++  describe "alias_command" do
++    it 'should make an aliasd command behave like its original' do
++      set = Pry::CommandSet.new do
++        command "test-command" do
++          output.puts "testing 1, 2, 3"
++        end
++        alias_command "test-alias", "test-command"
++      end
++
++      pry_tester(:commands => set).tap do |t|
++        t.eval('test-command').should == t.eval('test-alias')
++      end
++    end
++
++    it 'should pass on arguments to original' do
++      set = Pry::CommandSet.new do
++        command "test-command" do |*args|
++          output.puts "testing #{args.join(' ')}"
++        end
++        alias_command "test-alias", "test-command"
++      end
++
++      t = pry_tester(:commands => set)
++
++      t.process_command "test-alias hello baby duck"
++      t.last_output.should =~ /testing hello baby duck/
++    end
++
++    it 'should pass option arguments to original' do
++      set = Pry::CommandSet.new do
++        import Pry::Commands
++        alias_command "test-alias", "ls"
++      end
++
++      obj = Class.new { @x = 10 }
++      t = pry_tester(obj, :commands => set)
++
++      t.process_command "test-alias -i"
++      t.last_output.should =~ /@x/
++    end
++
++    it 'should pass option arguments to original with additional parameters' do
++      set = Pry::CommandSet.new do
++        import Pry::Commands
++        alias_command "test-alias", "ls -M"
++      end
++
++      obj = Class.new { @x = Class.new { define_method(:plymouth) {} } }
++      t = pry_tester(obj, :commands => set)
++      t.process_command "test-alias @x"
++      t.last_output.should =~ /plymouth/
++    end
++
++    it 'should be able to alias a regex command' do
++      set = Pry::CommandSet.new do
++        command /du.k/ do
++          output.puts "ducky"
++        end
++        alias_command "test-alias", "duck"
++      end
++
++      t = pry_tester(:commands => set)
++      t.process_command "test-alias"
++      t.last_output.should =~ /ducky/
++    end
++
++    it 'should be able to make the alias a regex' do
++      set = Pry::CommandSet.new do
++        command /du.k/ do
++          output.puts "ducky"
++        end
++        alias_command /test-ali.s/, "duck"
++      end
++
++      redirect_pry_io(InputTester.new("test-alias"), out1 = StringIO.new) do
++        Pry.start self, :commands => set
++      end
++
++      out1.string.should =~ /ducky/
++    end
++  end
++
++  describe "Pry::Command#run" do
++    it 'should allow running of commands with following whitespace' do
++      set = Pry::CommandSet.new do
++        import Pry::Commands
++        command "test-run" do
++          run "cd / "
++        end
++      end
++
++      redirect_pry_io(InputTester.new("cd 1/2/3/4/5/6", @bs1, "test-run",
++                                      @self, @bs2, "exit-all")) do
++        Pry.start(@o, :commands => set)
++      end
++
++      Pad.bs1.size.should == 7
++      Pad.self.should == @o
++      Pad.bs2.size.should == 1
++    end
++
++    it 'should allow running of cd command when contained in a single string' do
++      set = Pry::CommandSet.new do
++        import Pry::Commands
++        command "test-run" do
++          run "cd /"
++        end
++      end
++      redirect_pry_io(InputTester.new("cd 1/2/3/4/5/6", @bs1, "test-run",
++                                      @self, @bs2, "exit-all")) do
++        Pry.start(@o, :commands => set)
++      end
++
++      Pad.bs1.size.should == 7
++      Pad.self.should == @o
++      Pad.bs2.size.should == 1
++    end
++
++    it 'should allow running of cd command when split into array' do
++      set = Pry::CommandSet.new do
++        import Pry::Commands
++        command "test-run" do
++          run "cd", "/"
++        end
++      end
++      redirect_pry_io(InputTester.new("cd 1/2/3/4/5/6", @bs1, "test-run",
++                                      @self, @bs2, "exit-all")) do
++        Pry.start(@o, :commands => set)
++      end
++
++      Pad.bs1.size.should == 7
++      Pad.self.should == @o
++      Pad.bs2.size.should == 1
++    end
++
++    it 'should run a command from within a command' do
++      klass = Pry::CommandSet.new do
++        command "v" do
++          output.puts "v command"
++        end
++
++        command "run_v" do
++          run "v"
++        end
++      end
++
++      pry_tester(:commands => klass).eval('run_v').should =~ /v command/
++    end
++
++    it 'should run a regex command from within a command' do
++      klass = Pry::CommandSet.new do
++        command /v(.*)?/ do |arg|
++          output.puts "v #{arg}"
++        end
++
++        command "run_v" do
++          run "vbaby"
++        end
++      end
++
++      pry_tester(:commands => klass).eval('run_v').should =~ /v baby/
++    end
++
++    it 'should run a command from within a command with arguments' do
++      klass = Pry::CommandSet.new do
++        command /v(\w+)/ do |arg1, arg2|
++          output.puts "v #{arg1} #{arg2}"
++        end
++
++        command "run_v_explicit_parameter" do
++          run "vbaby", "param"
++        end
++
++        command "run_v_embedded_parameter" do
++          run "vbaby param"
++        end
++      end
++
++      ["run_v_explicit_parameter", "run_v_embedded_parameter"].each do |cmd|
++        pry_tester(:commands => klass).eval(cmd).should =~ /v baby param/
++      end
++    end
++  end
++
++  describe "Pry#run_command" do
++    it 'should run a command that modifies the passed in eval_string' do
++      p = Pry.new(:output => @str_output)
++      p.eval "def hello\npeter pan\n"
++      p.run_command "amend-line !"
++      p.eval_string.should =~ /def hello/
++      p.eval_string.should.not =~ /peter pan/
++    end
++
++    it 'should run a command in the context of a session' do
++      pry_tester(Object.new).tap do |t|
++        t.eval "@session_ivar = 10", "_pry_.run_command('ls')"
++        t.last_output.should =~ /@session_ivar/
++      end
++    end
++  end
++
++  it 'should interpolate ruby code into commands' do
++    set = Pry::CommandSet.new do
++      command "hello", "", :keep_retval => true do |arg|
++        arg
++      end
++    end
++
++    pry_tester(:commands => set).eval('hello #{Pad.bong}').should =~ /bong/
++  end
++
++  # bug fix for https://github.com/pry/pry/issues/170
++  it 'should not choke on complex string interpolation when checking if ruby code is a command' do
++    redirect_pry_io(InputTester.new('/#{Regexp.escape(File.expand_path("."))}/'), @str_output) do
++      pry
++    end
++
++    @str_output.string.should.not =~ /SyntaxError/
++  end
++
++  it 'should NOT interpolate ruby code into commands if :interpolate => false' do
++    set = Pry::CommandSet.new do
++      command "hello", "", :keep_retval => true, :interpolate => false do |arg|
++        arg
++      end
++    end
++
++    pry_tester(:commands => set).eval('hello #{Pad.bong}').
++      should =~ /Pad\.bong/
++  end
++
++  it 'should NOT try to interpolate pure ruby code (no commands) ' do
++    # These should raise RuntimeError instead of NameError
++    proc {
++      pry_eval 'raise \'#{aggy}\''
++    }.should.raise(RuntimeError)
++
++    proc {
++      pry_eval 'raise #{aggy}'
++    }.should.raise(RuntimeError)
++
++    pry_eval('format \'#{my_var}\'').should == "\#{my_var}"
++  end
++
++  it 'should create a command with a space in its name zzz' do
++    set = Pry::CommandSet.new do
++      command "hello baby", "" do
++        output.puts "hello baby command"
++      end
++    end
++
++    pry_tester(:commands => set).eval('hello baby').
++      should =~ /hello baby command/
++  end
++
++  it 'should create a command with a space in its name and pass an argument' do
++    set = Pry::CommandSet.new do
++      command "hello baby", "" do |arg|
++        output.puts "hello baby command #{arg}"
++      end
++    end
++
++    pry_tester(:commands => set).eval('hello baby john').
++      should =~ /hello baby command john/
++  end
++
++  it 'should create a regex command and be able to invoke it' do
++    set = Pry::CommandSet.new do
++      command /hello(.)/, "" do
++        c = captures.first
++        output.puts "hello#{c}"
++      end
++    end
++
++    pry_tester(:commands => set).eval('hello1').should =~ /hello1/
++  end
++
++  it 'should create a regex command and pass captures into the args list before regular arguments' do
++    set = Pry::CommandSet.new do
++      command /hello(.)/, "" do |c1, a1|
++        output.puts "hello #{c1} #{a1}"
++      end
++    end
++
++    pry_tester(:commands => set).eval('hello1 baby').should =~ /hello 1 baby/
++  end
++
++  it 'should create a regex command and interpolate the captures' do
++    set = Pry::CommandSet.new do
++      command /hello (.*)/, "" do |c1|
++        output.puts "hello #{c1}"
++      end
++    end
++
++    bong = "bong"
++    pry_tester(binding, :commands => set).eval('hello #{bong}').
++      should =~ /hello bong/
++  end
++
++  it 'should create a regex command and arg_string should be interpolated' do
++    set = Pry::CommandSet.new do
++      command /hello(\w+)/, "" do |c1, a1, a2, a3|
++        output.puts "hello #{c1} #{a1} #{a2} #{a3}"
++      end
++    end
++
++    bing = 'bing'
++    bong = 'bong'
++    bang = 'bang'
++
++    pry_tester(binding, :commands => set).
++      eval('hellojohn #{bing} #{bong} #{bang}').
++      should =~ /hello john bing bong bang/
++  end
++
++  it 'if a regex capture is missing it should be nil' do
++    set = Pry::CommandSet.new do
++      command /hello(.)?/, "" do |c1, a1|
++        output.puts "hello #{c1.inspect} #{a1}"
++      end
++    end
++
++    pry_tester(:commands => set).eval('hello baby').should =~ /hello nil baby/
++  end
++
++  it 'should create a command in a nested context and that command should be accessible from the parent' do
++    pry_tester(Object.new).eval(*(<<-RUBY.split("\n"))).should =~ /instance variables:\s+ at x/m
++      @x = nil
++      cd 7
++      _pry_.commands.instance_eval { command('bing') { |arg| run arg } }
++      cd ..
++      bing ls
++    RUBY
++  end
++
++  it 'should define a command that keeps its return value' do
++    klass = Pry::CommandSet.new do
++      command "hello", "", :keep_retval => true do
++        :kept_hello
++      end
++    end
++
++    t = pry_tester(:commands => klass)
++    t.eval("hello\n")
++    t.last_command_result.should == :kept_hello
++  end
++
++  it 'should define a command that does NOT keep its return value' do
++    klass = Pry::CommandSet.new do
++      command "hello", "", :keep_retval => false do
++        :kept_hello
++      end
++    end
++
++    t = pry_tester(:commands => klass)
++    t.eval("hello\n").should == ''
++    t.last_command_result.should == Pry::Command::VOID_VALUE
++  end
++
++  it 'should define a command that keeps its return value even when nil' do
++    klass = Pry::CommandSet.new do
++      command "hello", "", :keep_retval => true do
++        nil
++      end
++    end
++
++    t = pry_tester(:commands => klass)
++    t.eval("hello\n")
++    t.last_command_result.should == nil
++  end
++
++  it 'should define a command that keeps its return value but does not return when value is void' do
++    klass = Pry::CommandSet.new do
++      command "hello", "", :keep_retval => true do
++        void
++      end
++    end
++
++    pry_tester(:commands => klass).eval("hello\n").empty?.should == true
++  end
++
++  it 'a command (with :keep_retval => false) that replaces eval_string with a valid expression should not have the expression value suppressed' do
++    klass = Pry::CommandSet.new do
++      command "hello", "" do
++        eval_string.replace("6")
++      end
++    end
++
++    output = StringIO.new
++
++    redirect_pry_io(InputTester.new('def yo', 'hello'), output) do
++      Pry.start self, :commands => klass
++    end
++
++    output.string.should =~ /6/
++  end
++
++  it 'a command (with :keep_retval => true) that replaces eval_string with a valid expression should overwrite the eval_string with the return value' do
++    klass = Pry::CommandSet.new do
++      command "hello", "", :keep_retval => true do
++        eval_string.replace("6")
++        7
++      end
++    end
++
++    pry_tester(:commands => klass).eval("def yo\nhello\n").should == 7
++  end
++
++  it 'a command that return a value in a multi-line expression should clear the expression and return the value' do
++    klass = Pry::CommandSet.new do
++      command "hello", "", :keep_retval => true do
++        5
++      end
++    end
++
++    pry_tester(:commands => klass).eval("def yo\nhello\n").should == 5
++  end
++
++  it 'should set the commands default, and the default should be overridable' do
++    klass = Pry::CommandSet.new do
++      command "hello" do
++        output.puts "hello world"
++      end
++    end
++
++    other_klass = Pry::CommandSet.new do
++      command "goodbye", "" do
++        output.puts "goodbye world"
++      end
++    end
++
++    Pry.config.commands = klass
++    pry_tester.eval("hello").should == "hello world\n"
++    pry_tester(:commands => other_klass).eval("goodbye").should == "goodbye world\n"
++  end
++
++  it 'should inherit commands from Pry::Commands' do
++    klass = Pry::CommandSet.new Pry::Commands do
++      command "v" do
++      end
++    end
++
++    klass.to_hash.include?("nesting").should == true
++    klass.to_hash.include?("jump-to").should == true
++    klass.to_hash.include?("cd").should == true
++    klass.to_hash.include?("v").should == true
++  end
++
++  it 'should change description of a command using desc' do
++    klass = Pry::CommandSet.new do
++      import Pry::Commands
++    end
++    orig = klass["help"].description
++    klass.instance_eval do
++      desc "help", "blah"
++    end
++    commands = klass.to_hash
++    commands["help"].description.should.not == orig
++    commands["help"].description.should == "blah"
++  end
++
++  it 'should enable an inherited method to access opts and output and target, due to instance_exec' do
++    klass = Pry::CommandSet.new do
++      command "v" do
++        output.puts "#{target.eval('self')}"
++      end
++    end
++
++    child_klass = Pry::CommandSet.new klass do
++    end
++
++    mock_pry(Pry.binding_for('john'), "v", :print => proc {}, :commands => child_klass,
++                                           :output => @str_output)
++
++    @str_output.string.should == "john\n"
++  end
++
++  it 'should import commands from another command object' do
++    klass = Pry::CommandSet.new do
++      import_from Pry::Commands, "ls", "jump-to"
++    end
++
++    klass.to_hash.include?("ls").should == true
++    klass.to_hash.include?("jump-to").should == true
++  end
++
++  it 'should delete some inherited commands when using delete method' do
++    klass = Pry::CommandSet.new Pry::Commands do
++      command "v" do
++      end
++
++      delete "show-doc", "show-method"
++      delete "ls"
++    end
++
++    commands = klass.to_hash
++    commands.include?("nesting").should == true
++    commands.include?("jump-to").should == true
++    commands.include?("cd").should == true
++    commands.include?("v").should == true
++    commands.include?("show-doc").should == false
++    commands.include?("show-method").should == false
++    commands.include?("ls").should == false
++  end
++
++  it 'should override some inherited commands' do
++    klass = Pry::CommandSet.new Pry::Commands do
++      command "jump-to" do
++        output.puts "jump-to the music"
++      end
++
++      command "help" do
++        output.puts "help to the music"
++      end
++    end
++
++    t = pry_tester(:commands => klass)
++    t.eval('jump-to').should == "jump-to the music\n"
++    t.eval('help').should == "help to the music\n"
++  end
++
++  it 'should run a command with no parameter' do
++    pry_tester(:commands => @command_tester).eval('command1').
++      should == "command1\n"
++  end
++
++  it 'should run a command with one parameter' do
++    pry_tester(:commands => @command_tester).eval('command2 horsey').
++      should == "horsey\n"
++  end
++end
+diff --git a/spec/command_set_spec.rb b/spec/command_set_spec.rb
+new file mode 100644
+index 0000000..8e7eee3
+--- /dev/null
++++ b/spec/command_set_spec.rb
+@@ -0,0 +1,676 @@
++require_relative 'helper'
++
++describe Pry::CommandSet do
++  before do
++    @set = Pry::CommandSet.new do
++      import Pry::Commands
++    end
++
++    @ctx = {
++      :target => binding,
++      :command_set => @set,
++      :pry_instance => Pry.new(output: StringIO.new)
++    }
++  end
++
++  describe "[]=" do
++    it "removes a command from the command set" do
++      @set["help"].should.not == nil
++      @set["help"] = nil
++      @set["help"].should == nil
++      lambda { @set.run_command(TOPLEVEL_BINDING, "help") }.should.raise Pry::NoCommandError
++    end
++
++    it "replaces a command" do
++      old_help = @set["help"]
++      @set["help"] = @set["pry-version"]
++      @set["help"].should.not == old_help
++    end
++
++    it "rebinds the command with key" do
++      @set["help-1"] = @set["help"]
++      @set["help-1"].match.should == "help-1"
++    end
++
++    it "raises a TypeError when command is not a subclass of Pry::Command" do
++      lambda { @set["help"] = "hello" }.should.raise TypeError
++    end
++  end
++
++  it 'should call the block used for the command when it is called' do
++    run = false
++    @set.command 'foo' do
++      run = true
++    end
++
++    @set.run_command @ctx, 'foo'
++    run.should == true
++  end
++
++  it 'should pass arguments of the command to the block' do
++    @set.command 'foo' do |*args|
++      args.should == [1, 2, 3]
++    end
++
++    @set.run_command @ctx, 'foo', 1, 2, 3
++  end
++
++  it 'should use the first argument as context' do
++    ctx = @ctx
++
++    @set.command 'foo' do
++      self.context.should == ctx
++    end
++
++    @set.run_command @ctx, 'foo'
++  end
++
++  it 'should raise an error when calling an undefined command' do
++    @set.command('foo') {}
++    lambda {
++      @set.run_command @ctx, 'bar'
++    }.should.raise(Pry::NoCommandError)
++  end
++
++  it 'should be able to remove its own commands' do
++    @set.command('foo') {}
++    @set.delete 'foo'
++
++    lambda {
++      @set.run_command @ctx, 'foo'
++    }.should.raise(Pry::NoCommandError)
++  end
++
++  it 'should be able to remove its own commands, by listing name' do
++    @set.command(/^foo1/, 'desc', :listing => 'foo') {}
++    @set.delete 'foo'
++
++    lambda {
++      @set.run_command @ctx, /^foo1/
++    }.should.raise(Pry::NoCommandError)
++  end
++
++  it 'should be able to import some commands from other sets' do
++    run = false
++
++    other_set = Pry::CommandSet.new do
++      command('foo') { run = true }
++      command('bar') {}
++    end
++
++    @set.import_from(other_set, 'foo')
++
++    @set.run_command @ctx, 'foo'
++    run.should == true
++
++    lambda {
++      @set.run_command @ctx, 'bar'
++    }.should.raise(Pry::NoCommandError)
++  end
++
++  it 'should return command set after import' do
++    run = false
++
++    other_set = Pry::CommandSet.new do
++      command('foo') { run = true }
++      command('bar') {}
++    end
++
++    @set.import(other_set).should == @set
++  end
++
++  it 'should return command set after import_from' do
++    run = false
++
++    other_set = Pry::CommandSet.new do
++      command('foo') { run = true }
++      command('bar') {}
++    end
++
++    @set.import_from(other_set, 'foo').should == @set
++  end
++
++  it 'should be able to import some commands from other sets using listing name' do
++    run = false
++
++    other_set = Pry::CommandSet.new do
++      command(/^foo1/, 'desc', :listing => 'foo') { run = true }
++    end
++
++    @set.import_from(other_set, 'foo')
++
++    @set.run_command @ctx, /^foo1/
++    run.should == true
++  end
++
++  it 'should be able to import a whole set' do
++    run = []
++
++    other_set = Pry::CommandSet.new do
++      command('foo') { run << true }
++      command('bar') { run << true }
++    end
++
++    @set.import other_set
++
++    @set.run_command @ctx, 'foo'
++    @set.run_command @ctx, 'bar'
++    run.should == [true, true]
++  end
++
++  it 'should be able to import sets at creation' do
++    run = false
++    @set.command('foo') { run = true }
++
++    Pry::CommandSet.new(@set).run_command @ctx, 'foo'
++    run.should == true
++  end
++
++  it 'should set the descriptions of commands' do
++    @set.command('foo', 'some stuff') {}
++    @set['foo'].description.should == 'some stuff'
++  end
++
++  describe "aliases" do
++    it 'should be able to alias command' do
++      run = false
++      @set.command('foo', 'stuff') { run = true }
++
++      @set.alias_command 'bar', 'foo'
++      @set['bar'].match.should == 'bar'
++      @set['bar'].description.should == 'Alias for `foo`'
++
++      @set.run_command @ctx, 'bar'
++      run.should == true
++    end
++
++    it "should be able to alias command with command_prefix" do
++      run = false
++
++      begin
++        @set.command('owl', 'stuff') { run = true }
++        @set.alias_command 'owlet', 'owl'
++
++        Pry.config.command_prefix = '%'
++        @set['%owlet'].match.should == 'owlet'
++        @set['%owlet'].description.should == 'Alias for `owl`'
++
++        @set.run_command @ctx, 'owlet'
++        run.should == true
++      ensure
++        Pry.config.command_prefix = ''
++      end
++    end
++
++    it 'should inherit options from original command' do
++      run = false
++      @set.command('foo', 'stuff', :shellwords => true, :interpolate => false) { run = true }
++
++      @set.alias_command 'bar', 'foo'
++      @set['bar'].options[:shellwords].should == @set['foo'].options[:shellwords]
++      @set['bar'].options[:interpolate].should == @set['foo'].options[:interpolate]
++
++      # however some options should not be inherited
++      @set['bar'].options[:listing].should.not ==  @set['foo'].options[:listing]
++      @set['bar'].options[:listing].should == "bar"
++    end
++
++    it 'should be able to specify alias\'s description when aliasing' do
++      run = false
++      @set.command('foo', 'stuff') { run = true }
++
++      @set.alias_command 'bar', 'foo', :desc => "tobina"
++      @set['bar'].match.should == 'bar'
++      @set['bar'].description.should == "tobina"
++
++      @set.run_command @ctx, 'bar'
++      run.should == true
++    end
++
++    it "should be able to alias a command by its invocation line" do
++      run = false
++      @set.command(/^foo1/, 'stuff', :listing => 'foo') { run = true }
++
++      @set.alias_command 'bar', 'foo1'
++      @set['bar'].match.should == 'bar'
++      @set['bar'].description.should == 'Alias for `foo1`'
++
++      @set.run_command @ctx, 'bar'
++      run.should == true
++    end
++
++    it "should be able to specify options when creating alias" do
++      run = false
++      @set.command(/^foo1/, 'stuff', :listing => 'foo') { run = true }
++
++      @set.alias_command /^b.r/, 'foo1', :listing => "bar"
++      @set.to_hash[/^b.r/].options[:listing].should == "bar"
++    end
++
++    it "should set description to default if description parameter is nil" do
++      run = false
++      @set.command(/^foo1/, 'stuff', :listing => 'foo') { run = true }
++
++      @set.alias_command "bar", 'foo1'
++      @set["bar"].description.should == "Alias for `foo1`"
++    end
++  end
++
++  it 'should be able to change the descriptions of commands' do
++    @set.command('foo', 'bar') {}
++    @set.desc 'foo', 'baz'
++
++    @set['foo'].description.should == 'baz'
++  end
++
++  it 'should get the descriptions of commands' do
++    @set.command('foo', 'bar') {}
++    @set.desc('foo').should == 'bar'
++  end
++
++  it 'should get the descriptions of commands, by listing' do
++    @set.command(/^foo1/, 'bar', :listing => 'foo') {}
++    @set.desc('foo').should == 'bar'
++  end
++
++  it 'should return Pry::Command::VOID_VALUE for commands by default' do
++    @set.command('foo') { 3 }
++    @set.run_command(@ctx, 'foo').should == Pry::Command::VOID_VALUE
++  end
++
++  it 'should be able to keep return values' do
++    @set.command('foo', '', :keep_retval => true) { 3 }
++    @set.run_command(@ctx, 'foo').should == 3
++  end
++
++  it 'should be able to keep return values, even if return value is nil' do
++    @set.command('foo', '', :keep_retval => true) { nil }
++    @set.run_command(@ctx, 'foo').should == nil
++  end
++
++  it 'should be able to have its own helpers' do
++    @set.command('foo') do
++      should.respond_to :my_helper
++    end
++
++    @set.helpers do
++      def my_helper; end
++    end
++
++    @set.run_command(@ctx, 'foo')
++    Pry::Command.subclass('foo', '', {}, Module.new).new({:target => binding}).should.not.respond_to :my_helper
++  end
++
++  it 'should not recreate a new helper module when helpers is called' do
++    @set.command('foo') do
++      should.respond_to :my_helper
++      should.respond_to :my_other_helper
++    end
++
++    @set.helpers do
++      def my_helper; end
++    end
++
++    @set.helpers do
++      def my_other_helper; end
++    end
++
++    @set.run_command(@ctx, 'foo')
++  end
++
++  it 'should import helpers from imported sets' do
++    imported_set = Pry::CommandSet.new do
++      helpers do
++        def imported_helper_method; end
++      end
++    end
++
++    @set.import imported_set
++    @set.command('foo') { should.respond_to :imported_helper_method }
++    @set.run_command(@ctx, 'foo')
++  end
++
++  it 'should import helpers even if only some commands are imported' do
++    imported_set = Pry::CommandSet.new do
++      helpers do
++        def imported_helper_method; end
++      end
++
++      command('bar') {}
++    end
++
++    @set.import_from imported_set, 'bar'
++    @set.command('foo') { should.respond_to :imported_helper_method }
++    @set.run_command(@ctx, 'foo')
++  end
++
++  it 'should provide a :listing for a command that defaults to its name' do
++    @set.command 'foo', "" do;end
++    @set['foo'].options[:listing].should == 'foo'
++  end
++
++  it 'should provide a :listing for a command that differs from its name' do
++    @set.command 'foo', "", :listing => 'bar' do;end
++    @set['foo'].options[:listing].should == 'bar'
++  end
++
++  it "should provide a 'help' command" do
++    @ctx[:command_set] = @set
++    @ctx[:output] = StringIO.new
++
++    lambda {
++      @set.run_command(@ctx, 'help')
++    }.should.not.raise
++  end
++
++
++  describe "renaming a command" do
++    it 'should be able to rename and run a command' do
++      run = false
++      @set.command('foo') { run = true }
++      @set.rename_command('bar', 'foo')
++      @set.run_command(@ctx, 'bar')
++      run.should == true
++    end
++
++    it 'should accept listing name when renaming a command' do
++      run = false
++      @set.command('foo', "", :listing => 'love') { run = true }
++      @set.rename_command('bar', 'love')
++      @set.run_command(@ctx, 'bar')
++      run.should == true
++    end
++
++    it 'should raise exception trying to rename non-existent command' do
++      lambda { @set.rename_command('bar', 'foo') }.should.raise ArgumentError
++    end
++
++    it 'should make old command name inaccessible' do
++      @set.command('foo') { }
++      @set.rename_command('bar', 'foo')
++      lambda { @set.run_command(@ctx, 'foo') }.should.raise Pry::NoCommandError
++    end
++
++    it 'should be able to pass in options when renaming command' do
++      desc    = "hello"
++      listing = "bing"
++      @set.command('foo') { }
++      @set.rename_command('bar', 'foo', :description => desc, :listing => listing, :keep_retval => true)
++      @set['bar'].description.should           == desc
++      @set['bar'].options[:listing].should     == listing
++      @set['bar'].options[:keep_retval].should == true
++    end
++  end
++
++  describe "command decorators - before_command and after_command" do
++    describe "before_command" do
++      it 'should be called before the original command' do
++        foo = []
++        @set.command('foo') { foo << 1 }
++        @set.before_command('foo') { foo << 2 }
++        @set.run_command(@ctx, 'foo')
++
++        foo.should == [2, 1]
++      end
++
++      it 'should be called before the original command, using listing name' do
++        foo = []
++        @set.command(/^foo1/, '', :listing => 'foo') { foo << 1 }
++        @set.before_command('foo') { foo << 2 }
++        @set.run_command(@ctx, /^foo1/)
++
++        foo.should == [2, 1]
++      end
++
++      it 'should share the context with the original command' do
++        @ctx[:target] = "test target string".__binding__
++        before_val  = nil
++        orig_val    = nil
++        @set.command('foo') { orig_val = target }
++        @set.before_command('foo') { before_val = target }
++        @set.run_command(@ctx, 'foo')
++
++        before_val.should == @ctx[:target]
++        orig_val.should == @ctx[:target]
++      end
++
++      it 'should work when applied multiple times' do
++        foo = []
++        @set.command('foo') { foo << 1 }
++        @set.before_command('foo') { foo << 2 }
++        @set.before_command('foo') { foo << 3 }
++        @set.before_command('foo') { foo << 4 }
++        @set.run_command(@ctx, 'foo')
++
++        foo.should == [4, 3, 2, 1]
++      end
++
++    end
++
++    describe "after_command" do
++      it 'should be called after the original command' do
++        foo = []
++        @set.command('foo') { foo << 1 }
++        @set.after_command('foo') { foo << 2 }
++        @set.run_command(@ctx, 'foo')
++
++        foo.should == [1, 2]
++      end
++
++      it 'should be called after the original command, using listing name' do
++        foo = []
++        @set.command(/^foo1/, '', :listing => 'foo') { foo << 1 }
++        @set.after_command('foo') { foo << 2 }
++        @set.run_command(@ctx, /^foo1/)
++
++        foo.should == [1, 2]
++      end
++
++      it 'should share the context with the original command' do
++        @ctx[:target] = "test target string".__binding__
++        after_val   = nil
++        orig_val    = nil
++        @set.command('foo') { orig_val = target }
++        @set.after_command('foo') { after_val = target }
++        @set.run_command(@ctx, 'foo')
++
++        after_val.should == @ctx[:target]
++        orig_val.should == @ctx[:target]
++      end
++
++      it 'should determine the return value for the command' do
++        @set.command('foo', 'bar', :keep_retval => true) { 1 }
++        @set.after_command('foo') { 2 }
++        @set.run_command(@ctx, 'foo').should == 2
++      end
++
++      it 'should work when applied multiple times' do
++        foo = []
++        @set.command('foo') { foo << 1 }
++        @set.after_command('foo') { foo << 2 }
++        @set.after_command('foo') { foo << 3 }
++        @set.after_command('foo') { foo << 4 }
++        @set.run_command(@ctx, 'foo')
++
++        foo.should == [1, 2, 3, 4]
++      end
++    end
++
++    describe "before_command and after_command" do
++      it 'should work when combining both before_command and after_command' do
++        foo = []
++        @set.command('foo') { foo << 1 }
++        @set.after_command('foo') { foo << 2 }
++        @set.before_command('foo') { foo << 3 }
++        @set.run_command(@ctx, 'foo')
++
++        foo.should == [3, 1, 2]
++      end
++
++    end
++
++  end
++
++  describe 'find_command' do
++    it 'should find commands with the right string' do
++      cmd = @set.command('rincewind'){ }
++      @set.find_command('rincewind').should == cmd
++    end
++
++    it 'should not find commands with spaces before' do
++      cmd = @set.command('luggage'){ }
++      @set.find_command(' luggage').should == nil
++    end
++
++    it 'should find commands with arguments after' do
++      cmd = @set.command('vetinari'){ }
++      @set.find_command('vetinari --knock 3').should == cmd
++    end
++
++    it 'should find commands with names containing spaces' do
++      cmd = @set.command('nobby nobbs'){ }
++      @set.find_command('nobby nobbs --steal petty-cash').should == cmd
++    end
++
++    it 'should find command defined by regex' do
++      cmd = @set.command(/(capt|captain) vimes/i){ }
++      @set.find_command('Capt Vimes').should == cmd
++    end
++
++    it 'should find commands defined by regex with arguments' do
++      cmd = @set.command(/(cpl|corporal) Carrot/i){ }
++      @set.find_command('cpl carrot --write-home').should == cmd
++    end
++
++    it 'should not find commands by listing' do
++      cmd = @set.command(/werewol(f|ve)s?/, 'only once a month', :listing => "angua"){ }
++      @set.find_command('angua').should == nil
++    end
++
++    it 'should not find commands without command_prefix' do
++      begin
++        Pry.config.command_prefix = '%'
++        cmd = @set.command('detritus'){ }
++        @set.find_command('detritus').should == nil
++      ensure
++        Pry.config.command_prefix = ''
++      end
++    end
++
++    it "should find commands that don't use the prefix" do
++      begin
++        Pry.config.command_prefix = '%'
++        cmd = @set.command('colon', 'Sergeant Fred', :use_prefix => false){ }
++        @set.find_command('colon').should == cmd
++      ensure
++        Pry.config.command_prefix = ''
++      end
++    end
++
++    it "should find the command that has the longest match" do
++      cmd = @set.command(/\.(.*)/){ }
++      cmd2 = @set.command(/\.\|\|(.*)/){ }
++      @set.find_command('.||').should == cmd2
++    end
++
++    it "should find the command that has the longest name" do
++      cmd = @set.command(/\.(.*)/){ }
++      cmd2 = @set.command('.||'){ }
++      @set.find_command('.||').should == cmd2
++    end
++  end
++
++  describe '.valid_command?' do
++    it 'should be true for commands that can be found' do
++      cmd = @set.command('archchancellor')
++      @set.valid_command?('archchancellor of_the?(:University)').should == true
++    end
++
++    it 'should be false for commands that can\'' do
++      @set.valid_command?('def monkey(ape)').should == false
++    end
++
++    it 'should not cause argument interpolation' do
++      cmd = @set.command('hello')
++      lambda {
++        @set.valid_command?('hello #{raise "futz"}')
++      }.should.not.raise
++    end
++  end
++
++  describe '.process_line' do
++
++    it 'should return Result.new(false) if there is no matching command' do
++     result = @set.process_line('1 + 42')
++     result.command?.should == false
++     result.void_command?.should == false
++     result.retval.should == nil
++    end
++
++    it 'should return Result.new(true, VOID) if the command is not keep_retval' do
++      @set.create_command('mrs-cake') do
++        def process; 42; end
++      end
++
++      result = @set.process_line('mrs-cake')
++      result.command?.should == true
++      result.void_command?.should == true
++      result.retval.should == Pry::Command::VOID_VALUE
++    end
++
++    it 'should return Result.new(true, retval) if the command is keep_retval' do
++      @set.create_command('magrat', 'the maiden', :keep_retval => true) do
++        def process; 42; end
++      end
++
++      result = @set.process_line('magrat')
++      result.command?.should == true
++      result.void_command?.should == false
++      result.retval.should == 42
++    end
++
++    it 'should pass through context' do
++      ctx = {
++        :eval_string => "bloomers",
++        :pry_instance => Object.new,
++        :output => StringIO.new,
++        :target => binding
++      }
++      @set.create_command('agnes') do
++        define_method(:process) do
++          eval_string.should == ctx[:eval_string]
++          output.should == ctx[:output]
++          target.should == ctx[:target]
++          _pry_.should == ctx[:pry_instance]
++        end
++      end
++
++      @set.process_line('agnes', ctx)
++    end
++
++    it 'should add command_set to context' do
++      set = @set
++      @set.create_command(/nann+y ogg+/) do
++        define_method(:process) do
++          command_set.should == set
++        end
++      end
++
++      @set.process_line('nannnnnny oggggg')
++    end
++  end
++
++  if defined?(Bond)
++    describe '.complete' do
++      it "should list all command names" do
++        @set.create_command('susan'){ }
++        @set.complete('sus').should.include 'susan '
++      end
++
++      it "should delegate to commands" do
++        @set.create_command('susan'){ def complete(search); ['--foo']; end }
++        @set.complete('susan ').should == ['--foo']
++      end
++    end
++  end
++end
+diff --git a/spec/command_spec.rb b/spec/command_spec.rb
+new file mode 100644
+index 0000000..f493f14
+--- /dev/null
++++ b/spec/command_spec.rb
+@@ -0,0 +1,819 @@
++require_relative 'helper'
++
++describe "Pry::Command" do
++
++  before do
++    @set = Pry::CommandSet.new
++    @set.import Pry::Commands
++  end
++
++  describe 'call_safely' do
++
++    it 'should display a message if gems are missing' do
++      cmd = @set.create_command "ford-prefect", "From a planet near Beetlegeuse", :requires_gem => %w(ghijkl) do
++        #
++      end
++
++      mock_command(cmd, %w(hello world)).output.should =~ /install-command ford-prefect/
++    end
++
++    it 'should abort early if arguments are required' do
++      cmd = @set.create_command 'arthur-dent', "Doesn't understand Thursdays", :argument_required => true do
++        #
++      end
++
++      lambda {
++        mock_command(cmd, %w())
++      }.should.raise(Pry::CommandError)
++    end
++
++    it 'should return VOID without keep_retval' do
++      cmd = @set.create_command 'zaphod-beeblebrox', "Likes pan-Galactic Gargle Blasters" do
++        def process
++          3
++        end
++      end
++
++      mock_command(cmd).return.should == Pry::Command::VOID_VALUE
++    end
++
++    it 'should return the return value with keep_retval' do
++      cmd = @set.create_command 'tricia-mcmillian', "a.k.a Trillian", :keep_retval => true do
++        def process
++          5
++        end
++      end
++
++      mock_command(cmd).return.should == 5
++    end
++
++    it 'should call hooks in the right order' do
++      cmd = @set.create_command 'marvin', "Pained by the diodes in his left side" do
++        def process
++          output.puts 3 + args[0].to_i
++        end
++      end
++
++      @set.before_command 'marvin' do |i|
++        output.puts 2 + i.to_i
++      end
++      @set.before_command 'marvin' do |i|
++        output.puts 1 + i.to_i
++      end
++
++      @set.after_command 'marvin' do |i|
++        output.puts 4 + i.to_i
++      end
++
++      @set.after_command 'marvin' do |i|
++        output.puts 5 + i.to_i
++      end
++
++      mock_command(cmd, %w(2)).output.should == "3\n4\n5\n6\n7\n"
++    end
++
++    # TODO: This strikes me as rather silly...
++    it 'should return the value from the last hook with keep_retval' do
++      cmd = @set.create_command 'slartibartfast', "Designs Fjords", :keep_retval => true do
++        def process
++          22
++        end
++      end
++
++      @set.after_command 'slartibartfast' do
++        10
++      end
++
++      mock_command(cmd).return.should == 10
++    end
++  end
++
++  describe 'help' do
++    it 'should default to the description for blocky commands' do
++      @set.command 'oolon-colluphid', "Raving Atheist" do
++        #
++      end
++
++      mock_command(@set['help'], %w(oolon-colluphid), :command_set => @set).output.should =~ /Raving Atheist/
++    end
++
++    it 'should use slop to generate the help for classy commands' do
++      @set.create_command 'eddie', "The ship-board computer" do
++        def options(opt)
++          opt.banner "Over-cheerful, and makes a ticking noise."
++        end
++      end
++
++      mock_command(@set['help'], %w(eddie), :command_set => @set).output.should =~ /Over-cheerful/
++    end
++
++    it 'should provide --help for classy commands' do
++      cmd = @set.create_command 'agrajag', "Killed many times by Arthur" do
++        def options(opt)
++          opt.on :r, :retaliate, "Try to get Arthur back"
++        end
++      end
++
++      mock_command(cmd, %w(--help)).output.should =~ /--retaliate/
++    end
++
++    it 'should provide a -h for classy commands' do
++      cmd = @set.create_command 'zarniwoop', "On an intergalactic cruise, in his office." do
++        def options(opt)
++          opt.on :e, :escape, "Help zaphod escape the Total Perspective Vortex"
++        end
++      end
++
++      mock_command(cmd, %w(--help)).output.should =~ /Total Perspective Vortex/
++    end
++
++    it 'should use the banner provided' do
++      cmd = @set.create_command 'deep-thought', "The second-best computer ever" do
++        banner <<-BANNER
++          Who's merest operational parameters, I am not worthy to compute.
++        BANNER
++      end
++
++      mock_command(cmd, %w(--help)).output.should =~ /Who\'s merest/
++    end
++  end
++
++  describe 'context' do
++    context = {
++      :target => binding,
++      :output => StringIO.new,
++      :eval_string => "eval-string",
++      :command_set => @set,
++      :pry_instance => Pry.new
++    }
++
++    it 'should capture lots of stuff from the hash passed to new before setup' do
++      cmd = @set.create_command 'fenchurch', "Floats slightly off the ground" do
++        define_method(:setup) do
++          self.context.should == context
++          target.should == context[:target]
++          target_self.should == context[:target].eval('self')
++          output.should == context[:output]
++        end
++
++        define_method(:process) do
++          eval_string.should == "eval-string"
++          command_set.should == @set
++          _pry_.should == context[:pry_instance]
++        end
++      end
++
++      cmd.new(context).call
++    end
++  end
++
++  describe 'classy api' do
++
++    it 'should call setup, then subcommands, then options, then process' do
++      cmd = @set.create_command 'rooster', "Has a tasty towel" do
++        def setup
++          output.puts "setup"
++        end
++
++        def subcommands(cmd)
++          output.puts "subcommands"
++        end
++
++        def options(opt)
++          output.puts "options"
++        end
++
++        def process
++          output.puts "process"
++        end
++      end
++
++      mock_command(cmd).output.should == "setup\nsubcommands\noptions\nprocess\n"
++    end
++
++    it 'should raise a command error if process is not overridden' do
++      cmd = @set.create_command 'jeltz', "Commander of a Vogon constructor fleet" do
++        def proccces
++          #
++        end
++      end
++
++      lambda {
++        mock_command(cmd)
++      }.should.raise(Pry::CommandError)
++    end
++
++    it 'should work if neither options, nor setup is overridden' do
++      cmd = @set.create_command 'wowbagger', "Immortal, insulting.", :keep_retval => true do
++        def process
++          5
++        end
++      end
++
++      mock_command(cmd).return.should == 5
++    end
++
++    it 'should provide opts and args as provided by slop' do
++      cmd = @set.create_command 'lintilla', "One of 800,000,000 clones" do
++        def options(opt)
++          opt.on :f, :four, "A numeric four", :as => Integer, :optional_argument => true
++        end
++
++        def process
++          args.should == ['four']
++          opts[:f].should == 4
++        end
++      end
++
++      mock_command(cmd, %w(--four 4 four))
++    end
++
++    it 'should allow overriding options after definition' do
++      cmd = @set.create_command /number-(one|two)/, "Lieutenants of the Golgafrinchan Captain", :shellwords => false do
++
++        command_options :listing => 'number-one'
++      end
++
++      cmd.command_options[:shellwords].should == false
++      cmd.command_options[:listing].should == 'number-one'
++    end
++
++    it "should create subcommands" do
++      cmd = @set.create_command 'mum', 'Your mum' do
++        def subcommands(cmd)
++          cmd.command :yell
++        end
++
++        def process
++          opts.fetch_command(:blahblah).should == nil
++          opts.fetch_command(:yell).present?.should == true
++        end
++      end
++
++      mock_command(cmd, ['yell'])
++    end
++
++    it "should create subcommand options" do
++      cmd = @set.create_command 'mum', 'Your mum' do
++        def subcommands(cmd)
++          cmd.command :yell do
++            on :p, :person
++          end
++        end
++
++        def process
++          args.should == ['papa']
++          opts.fetch_command(:yell).present?.should == true
++          opts.fetch_command(:yell).person?.should == true
++        end
++      end
++
++      mock_command(cmd, %w|yell --person papa|)
++    end
++
++    it "should accept top-level arguments" do
++      cmd = @set.create_command 'mum', 'Your mum' do
++        def subcommands(cmd)
++          cmd.on :yell
++        end
++
++        def process
++          args.should == ['yell', 'papa', 'sonny', 'daughter']
++        end
++      end
++
++      mock_command(cmd, %w|yell papa sonny daughter|)
++    end
++
++    describe "explicit classes" do
++      before do
++        @x = Class.new(Pry::ClassCommand) do
++          options :baby => :pig
++          match /goat/
++          description "waaaninngggiiigygygygygy"
++        end
++      end
++
++      it 'subclasses should inherit options, match and description from superclass' do
++        k = Class.new(@x)
++        k.options.should == @x.options
++        k.match.should == @x.match
++        k.description.should == @x.description
++      end
++    end
++  end
++
++  describe 'tokenize' do
++    it 'should interpolate string with #{} in them' do
++      cmd = @set.command 'random-dent' do |*args|
++        args.should == ["3", "8"]
++      end
++
++      foo = 5
++
++      cmd.new(:target => binding).process_line 'random-dent #{1 + 2} #{3 + foo}'
++    end
++
++    it 'should not fail if interpolation is not needed and target is not set' do
++      cmd = @set.command 'the-book' do |*args|
++        args.should == ['--help']
++      end
++
++      cmd.new.process_line 'the-book --help'
++    end
++
++    it 'should not interpolate commands with :interpolate => false' do
++      cmd = @set.command 'thor', 'norse god', :interpolate => false do |*args|
++        args.should == ['%(#{foo})']
++      end
++
++      cmd.new.process_line 'thor %(#{foo})'
++    end
++
++    it 'should use shell-words to split strings' do
++      cmd = @set.command 'eccentrica' do |*args|
++        args.should == ['gallumbits', 'eroticon', '6']
++      end
++
++      cmd.new.process_line %(eccentrica "gallumbits" 'erot''icon' 6)
++    end
++
++    it 'should split on spaces if shellwords is not used' do
++      cmd = @set.command 'bugblatter-beast', 'would eat its grandmother', :shellwords => false do |*args|
++        args.should == ['"of', 'traal"']
++      end
++
++      cmd.new.process_line %(bugblatter-beast "of traal")
++    end
++
++    it 'should add captures to arguments for regex commands' do
++      cmd = @set.command /perfectly (normal)( beast)?/i do |*args|
++        args.should == ['Normal', ' Beast', '(honest!)']
++      end
++
++      cmd.new.process_line %(Perfectly Normal Beast (honest!))
++    end
++  end
++
++  describe 'process_line' do
++    it 'should check for command name collisions if configured' do
++      old = Pry.config.collision_warning
++      Pry.config.collision_warning = true
++
++      cmd = @set.command 'frankie' do
++
++      end
++
++      frankie = 'boyle'
++      output = StringIO.new
++      cmd.new(:target => binding, :output => output).process_line %(frankie mouse)
++
++      output.string.should =~ /command .* conflicts/
++
++      Pry.config.collision_warning = old
++    end
++
++    it 'should spot collision warnings on assignment if configured' do
++      old = Pry.config.collision_warning
++      Pry.config.collision_warning = true
++
++      cmd = @set.command 'frankie' do
++
++      end
++
++      output = StringIO.new
++      cmd.new(:target => binding, :output => output).process_line %(frankie = mouse)
++
++      output.string.should =~ /command .* conflicts/
++
++      Pry.config.collision_warning = old
++    end
++
++    it "should set the commands' arg_string and captures" do
++
++      cmd = @set.command /benj(ie|ei)/ do |*args|
++        self.arg_string.should == "mouse"
++        self.captures.should == ['ie']
++        args.should == ['ie', 'mouse']
++      end
++
++      cmd.new.process_line %(benjie mouse)
++    end
++
++    it "should raise an error if the line doesn't match the command" do
++      cmd = @set.command 'grunthos', 'the flatulent'
++
++      lambda {
++        cmd.new.process_line %(grumpos)
++      }.should.raise(Pry::CommandError)
++    end
++   end
++
++  describe "block parameters" do
++    before do
++      @context = Object.new
++      @set.command "walking-spanish", "down the hall", :takes_block => true do
++        PryTestHelpers.inject_var(:@x, command_block.call, target)
++      end
++      @set.import Pry::Commands
++
++      @t = pry_tester(@context, :commands => @set)
++    end
++
++    it 'should accept multiline blocks' do
++      @t.eval <<-EOS
++        walking-spanish | do
++          :jesus
++        end
++      EOS
++
++      @context.instance_variable_get(:@x).should == :jesus
++    end
++
++    it 'should accept normal parameters along with block' do
++      @set.block_command "walking-spanish",
++          "litella's been screeching for a blind pig.",
++          :takes_block => true do |x, y|
++        PryTestHelpers.inject_var(:@x, x, target)
++        PryTestHelpers.inject_var(:@y, y, target)
++        PryTestHelpers.inject_var(:@block_var, command_block.call, target)
++      end
++
++      @t.eval 'walking-spanish john carl| { :jesus }'
++
++      @context.instance_variable_get(:@x).should == "john"
++      @context.instance_variable_get(:@y).should == "carl"
++      @context.instance_variable_get(:@block_var).should == :jesus
++    end
++
++    describe "single line blocks" do
++      it 'should accept blocks with do ; end' do
++        @t.eval 'walking-spanish | do ; :jesus; end'
++        @context.instance_variable_get(:@x).should == :jesus
++      end
++
++      it 'should accept blocks with do; end' do
++        @t.eval 'walking-spanish | do; :jesus; end'
++        @context.instance_variable_get(:@x).should == :jesus
++      end
++
++      it 'should accept blocks with { }' do
++        @t.eval 'walking-spanish | { :jesus }'
++        @context.instance_variable_get(:@x).should == :jesus
++      end
++    end
++
++    describe "block-related content removed from arguments" do
++
++      describe "arg_string" do
++        it 'should remove block-related content from arg_string (with one normal arg)' do
++          @set.block_command "walking-spanish", "down the hall", :takes_block => true do |x, y|
++            PryTestHelpers.inject_var(:@arg_string, arg_string, target)
++            PryTestHelpers.inject_var(:@x, x, target)
++          end
++
++          @t.eval 'walking-spanish john| { :jesus }'
++
++          @context.instance_variable_get(:@arg_string).should == @context.instance_variable_get(:@x)
++        end
++
++        it 'should remove block-related content from arg_string (with no normal args)' do
++          @set.block_command "walking-spanish", "down the hall", :takes_block => true do
++            PryTestHelpers.inject_var(:@arg_string, arg_string, target)
++          end
++
++          @t.eval 'walking-spanish | { :jesus }'
++
++          @context.instance_variable_get(:@arg_string).should == ""
++        end
++
++        it 'should NOT remove block-related content from arg_string when :takes_block => false' do
++          block_string = "| { :jesus }"
++          @set.block_command "walking-spanish", "homemade special", :takes_block => false do
++            PryTestHelpers.inject_var(:@arg_string, arg_string, target)
++          end
++
++          @t.eval "walking-spanish #{block_string}"
++
++          @context.instance_variable_get(:@arg_string).should == block_string
++        end
++      end
++
++      describe "args" do
++        describe "block_command" do
++          it "should remove block-related content from arguments" do
++            @set.block_command "walking-spanish", "glass is full of sand", :takes_block => true do |x, y|
++              PryTestHelpers.inject_var(:@x, x, target)
++              PryTestHelpers.inject_var(:@y, y, target)
++            end
++
++            @t.eval 'walking-spanish | { :jesus }'
++
++            @context.instance_variable_get(:@x).should == nil
++            @context.instance_variable_get(:@y).should == nil
++          end
++
++          it "should NOT remove block-related content from arguments if :takes_block => false" do
++            @set.block_command "walking-spanish", "litella screeching for a blind pig", :takes_block => false do |x, y|
++              PryTestHelpers.inject_var(:@x, x, target)
++              PryTestHelpers.inject_var(:@y, y, target)
++            end
++
++            @t.eval 'walking-spanish | { :jesus }'
++
++            @context.instance_variable_get(:@x).should == "|"
++            @context.instance_variable_get(:@y).should == "{"
++          end
++        end
++
++        describe "create_command" do
++          it "should remove block-related content from arguments" do
++            @set.create_command "walking-spanish", "punk sanders carved one out of wood", :takes_block => true do
++              def process(x, y)
++                PryTestHelpers.inject_var(:@x, x, target)
++                PryTestHelpers.inject_var(:@y, y, target)
++              end
++            end
++
++            @t.eval 'walking-spanish | { :jesus }'
++
++            @context.instance_variable_get(:@x).should == nil
++            @context.instance_variable_get(:@y).should == nil
++          end
++
++          it "should NOT remove block-related content from arguments if :takes_block => false" do
++            @set.create_command "walking-spanish", "down the hall", :takes_block => false do
++              def process(x, y)
++                PryTestHelpers.inject_var(:@x, x, target)
++                PryTestHelpers.inject_var(:@y, y, target)
++              end
++            end
++
++            @t.eval 'walking-spanish | { :jesus }'
++
++            @context.instance_variable_get(:@x).should == "|"
++            @context.instance_variable_get(:@y).should == "{"
++          end
++        end
++      end
++    end
++
++    describe "blocks can take parameters" do
++      describe "{} style blocks" do
++        it 'should accept multiple parameters' do
++          @set.block_command "walking-spanish", "down the hall", :takes_block => true do
++            PryTestHelpers.inject_var(:@x, command_block.call(1, 2), target)
++          end
++
++          @t.eval 'walking-spanish | { |x, y| [x, y] }'
++
++          @context.instance_variable_get(:@x).should == [1, 2]
++        end
++      end
++
++      describe "do/end style blocks" do
++        it 'should accept multiple parameters' do
++          @set.create_command "walking-spanish", "litella", :takes_block => true do
++            def process
++              PryTestHelpers.inject_var(:@x, command_block.call(1, 2), target)
++            end
++          end
++
++          @t.eval <<-EOS
++            walking-spanish | do |x, y|
++              [x, y]
++            end
++          EOS
++
++          @context.instance_variable_get(:@x).should == [1, 2]
++        end
++      end
++    end
++
++    describe "closure behaviour" do
++      it 'should close over locals in the definition context' do
++        @t.eval 'var = :hello', 'walking-spanish | { var }'
++        @context.instance_variable_get(:@x).should == :hello
++      end
++    end
++
++    describe "exposing block parameter" do
++      describe "block_command" do
++        it "should expose block in command_block method" do
++          @set.block_command "walking-spanish", "glass full of sand", :takes_block => true do
++            PryTestHelpers.inject_var(:@x, command_block.call, target)
++          end
++
++          @t.eval 'walking-spanish | { :jesus }'
++
++          @context.instance_variable_get(:@x).should == :jesus
++        end
++      end
++
++      describe "create_command" do
++        it "should NOT expose &block in create_command's process method" do
++          @set.create_command "walking-spanish", "down the hall", :takes_block => true do
++            def process(&block)
++              block.call
++            end
++          end
++          @out = StringIO.new
++
++          proc {
++            @t.eval 'walking-spanish | { :jesus }'
++          }.should.raise(NoMethodError)
++        end
++
++        it "should expose block in command_block method" do
++          @set.create_command "walking-spanish", "homemade special", :takes_block => true do
++            def process
++              PryTestHelpers.inject_var(:@x, command_block.call, target)
++            end
++          end
++
++          @t.eval 'walking-spanish | { :jesus }'
++
++          @context.instance_variable_get(:@x).should == :jesus
++        end
++      end
++    end
++  end
++
++  describe "a command made with a custom sub-class" do
++
++    before do
++      class MyTestCommand < Pry::ClassCommand
++        match /my-*test/
++        description 'So just how many sound technicians does it take to' \
++          'change a lightbulb? 1? 2? 3? 1-2-3? Testing?'
++        options :shellwords => false, :listing => 'my-test'
++
++        def process
++          output.puts command_name * 2
++        end
++      end
++
++      Pry.config.commands.add_command MyTestCommand
++    end
++
++    after do
++      Pry.config.commands.delete 'my-test'
++    end
++
++    it "allows creation of custom subclasses of Pry::Command" do
++      pry_eval('my---test').should =~ /my-testmy-test/
++    end
++
++    it "shows the source of the process method" do
++      pry_eval('show-source my-test').should =~ /output.puts command_name/
++    end
++
++    describe "command options hash" do
++      it "is always present" do
++        options_hash = {
++          :requires_gem      => [],
++          :keep_retval       => false,
++          :argument_required => false,
++          :interpolate       => true,
++          :shellwords        => false,
++          :listing           => 'my-test',
++          :use_prefix        => true,
++          :takes_block       => false
++        }
++        MyTestCommand.options.should == options_hash
++      end
++
++      describe ":listing option" do
++        it "defaults to :match if not set explicitly" do
++          class HappyNewYear < Pry::ClassCommand
++            match 'happy-new-year'
++            description 'Happy New Year 2013'
++          end
++          Pry.config.commands.add_command HappyNewYear
++
++          HappyNewYear.options[:listing].should == 'happy-new-year'
++
++          Pry.config.commands.delete 'happy-new-year'
++        end
++
++        it "can be set explicitly" do
++          class MerryChristmas < Pry::ClassCommand
++            match 'merry-christmas'
++            description 'Merry Christmas!'
++            command_options :listing => 'happy-holidays'
++          end
++          Pry.config.commands.add_command MerryChristmas
++
++          MerryChristmas.options[:listing].should == 'happy-holidays'
++
++          Pry.config.commands.delete 'merry-christmas'
++        end
++
++        it "equals to :match option's inspect, if :match is Regexp" do
++          class CoolWinter < Pry::ClassCommand
++            match /.*winter/
++            description 'Is winter cool or cool?'
++          end
++          Pry.config.commands.add_command CoolWinter
++
++          CoolWinter.options[:listing].should == '/.*winter/'
++
++          Pry.config.commands.delete /.*winter/
++        end
++      end
++    end
++
++  end
++
++  describe "commands can save state" do
++    before do
++      @set = Pry::CommandSet.new do
++        create_command "litella", "desc" do
++          def process
++            state.my_state ||= 0
++            state.my_state += 1
++          end
++        end
++
++        create_command "sanders", "desc" do
++          def process
++            state.my_state = "wood"
++          end
++        end
++
++        create_command /[Hh]ello-world/, "desc" do
++          def process
++            state.my_state ||= 0
++            state.my_state += 2
++          end
++        end
++
++      end.import Pry::Commands
++
++      @t = pry_tester(:commands => @set)
++    end
++
++    it 'should save state for the command on the Pry#command_state hash' do
++      @t.eval 'litella'
++      @t.pry.command_state["litella"].my_state.should == 1
++    end
++
++    it 'should ensure state is maintained between multiple invocations of command' do
++      @t.eval 'litella'
++      @t.eval 'litella'
++      @t.pry.command_state["litella"].my_state.should == 2
++    end
++
++    it 'should ensure state with same name stored seperately for each command' do
++      @t.eval 'litella', 'sanders'
++
++      @t.pry.command_state["litella"].my_state.should == 1
++      @t.pry.command_state["sanders"].my_state.should =="wood"
++    end
++
++    it 'should ensure state is properly saved for regex commands' do
++      @t.eval 'hello-world', 'Hello-world'
++      @t.pry.command_state[/[Hh]ello-world/].my_state.should == 4
++    end
++  end
++
++  if defined?(Bond)
++    describe 'complete' do
++      it 'should return the arguments that are defined' do
++        @set.create_command "torrid" do
++          def options(opt)
++            opt.on :test
++            opt.on :lest
++            opt.on :pests
++          end
++        end
++
++        @set.complete('torrid ').should.include('--test ')
++      end
++    end
++  end
++
++  describe 'group' do
++    before do
++      @set.import(
++                  Pry::CommandSet.new do
++                    create_command("magic") { group("Not for a public use") }
++                  end
++                 )
++    end
++
++    it 'should be correct for default commands' do
++      @set["help"].group.should == "Help"
++    end
++
++    it 'should not change once it is initialized' do
++      @set["magic"].group("-==CD COMMAND==-")
++      @set["magic"].group.should == "Not for a public use"
++    end
++
++    it 'should not disappear after the call without parameters' do
++      @set["magic"].group
++      @set["magic"].group.should == "Not for a public use"
++    end
++  end
++end
+diff --git a/spec/commands/amend_line_spec.rb b/spec/commands/amend_line_spec.rb
+new file mode 100644
+index 0000000..7e16645
+--- /dev/null
++++ b/spec/commands/amend_line_spec.rb
+@@ -0,0 +1,247 @@
++require_relative '../helper'
++
++describe "amend-line" do
++  before do
++    @t = pry_tester
++  end
++
++  it 'should amend the last line of input when no line number specified' do
++    @t.push *unindent(<<-STR).split("\n")
++      def hello
++        puts :bing
++    STR
++
++    @t.process_command 'amend-line   puts :blah'
++
++    @t.eval_string.should == unindent(<<-STR)
++      def hello
++        puts :blah
++    STR
++  end
++
++  it 'should amend the specified line of input when line number given' do
++    @t.push *unindent(<<-STR).split("\n")
++      def hello
++        puts :bing
++        puts :bang
++    STR
++
++    @t.process_command 'amend-line 1 def goodbye'
++
++    @t.eval_string.should == unindent(<<-STR)
++      def goodbye
++        puts :bing
++        puts :bang
++    STR
++  end
++
++  it 'should amend the first line of input when 0 given as line number' do
++    @t.push *unindent(<<-STR).split("\n")
++      def hello
++        puts :bing
++        puts :bang
++    STR
++
++    @t.process_command 'amend-line 0 def goodbye'
++
++    @t.eval_string.should == unindent(<<-STR)
++      def goodbye
++        puts :bing
++        puts :bang
++    STR
++  end
++
++  it 'should amend a specified line when negative number given' do
++    @t.push *unindent(<<-STR).split("\n")
++      def hello
++        puts :bing
++        puts :bang
++    STR
++
++    @t.process_command 'amend-line -1   puts :bink'
++
++    @t.eval_string.should == unindent(<<-STR)
++      def hello
++        puts :bing
++        puts :bink
++    STR
++
++    @t.process_command 'amend-line -2   puts :bink'
++
++    @t.eval_string.should == unindent(<<-STR)
++      def hello
++        puts :bink
++        puts :bink
++    STR
++  end
++
++  it 'should amend a range of lines of input when negative numbers given' do
++    @t.push *unindent(<<-STR).split("\n")
++      def hello
++        puts :bing
++        puts :bang
++        puts :boat
++    STR
++
++    @t.process_command 'amend-line -3..-2   puts :bink'
++
++    @t.eval_string.should == unindent(<<-STR)
++      def hello
++        puts :bink
++        puts :boat
++    STR
++  end
++
++  it 'should correctly amend the specified line with interpolated text' do
++    @t.push *unindent(<<-STR).split("\n")
++      def hello
++        puts :bing
++        puts :bang
++    STR
++
++    @t.process_command 'amend-line   puts "#{goodbye}"'
++
++    @t.eval_string.should == unindent(<<-'STR')
++      def hello
++        puts :bing
++        puts "#{goodbye}"
++    STR
++  end
++
++  it 'should display error if nothing to amend' do
++    error = nil
++
++    begin
++      @t.process_command 'amend-line'
++    rescue Pry::CommandError => e
++      error = e
++    end
++
++    error.should.not.be.nil
++    error.message.should =~ /No input to amend/
++  end
++
++  it 'should correctly amend the specified range of lines' do
++    @t.push *unindent(<<-STR).split("\n")
++      def hello
++        puts :bing
++        puts :bang
++        puts :heart
++    STR
++
++    @t.process_command 'amend-line 2..3   puts :bong'
++
++    @t.eval_string.should == unindent(<<-STR)
++      def hello
++        puts :bong
++        puts :heart
++    STR
++  end
++
++  it 'should correctly delete a specific line using the ! for content' do
++    @t.push *unindent(<<-STR).split("\n")
++      def hello
++        puts :bing
++        puts :bang
++        puts :boast
++        puts :heart
++    STR
++
++    @t.process_command 'amend-line 3 !'
++
++    @t.eval_string.should == unindent(<<-STR)
++      def hello
++        puts :bing
++        puts :boast
++        puts :heart
++    STR
++  end
++
++  it 'should correctly delete a range of lines using the ! for content' do
++    @t.push *unindent(<<-STR).split("\n")
++      def hello
++        puts :bing
++        puts :bang
++        puts :boast
++        puts :heart
++    STR
++
++    @t.process_command 'amend-line 2..4 !'
++
++    @t.eval_string.should == unindent(<<-STR)
++      def hello
++        puts :heart
++    STR
++  end
++
++  it 'should correctly delete the previous line using the ! for content' do
++    @t.push *unindent(<<-STR).split("\n")
++      def hello
++        puts :bing
++        puts :bang
++        puts :boast
++        puts :heart
++    STR
++
++    @t.process_command 'amend-line !'
++
++    @t.eval_string.should == unindent(<<-STR)
++      def hello
++        puts :bing
++        puts :bang
++        puts :boast
++    STR
++  end
++
++  it 'should amend the specified range of lines, with numbers < 0 in range' do
++    @t.push *unindent(<<-STR).split("\n")
++      def hello
++        puts :bing
++        puts :bang
++        puts :boast
++        puts :heart
++    STR
++
++    @t.process_command 'amend-line 2..-2   puts :bong'
++
++    @t.eval_string.should == unindent(<<-STR)
++      def hello
++        puts :bong
++        puts :heart
++    STR
++  end
++
++  it 'should correctly insert a line before a specified line using >' do
++    @t.push *unindent(<<-STR).split("\n")
++      def hello
++        puts :bing
++        puts :bang
++    STR
++
++    @t.process_command 'amend-line 2 >  puts :inserted'
++
++    @t.eval_string.should == unindent(<<-STR)
++      def hello
++        puts :inserted
++        puts :bing
++        puts :bang
++    STR
++  end
++
++  it 'should ignore second value of range with > syntax' do
++    @t.push *unindent(<<-STR).split("\n")
++      def hello
++        puts :bing
++        puts :bang
++    STR
++
++    @t.process_command 'amend-line 2..21 >  puts :inserted'
++
++    @t.eval_string.should == unindent(<<-STR)
++      def hello
++        puts :inserted
++        puts :bing
++        puts :bang
++    STR
++  end
++end
+diff --git a/spec/commands/bang_spec.rb b/spec/commands/bang_spec.rb
+new file mode 100644
+index 0000000..3e8d2c0
+--- /dev/null
++++ b/spec/commands/bang_spec.rb
+@@ -0,0 +1,24 @@
++require_relative '../helper'
++
++describe "!" do
++  before do
++    @t = pry_tester
++  end
++
++  it 'should correctly clear the input buffer ' do
++    @t.push unindent(<<-STR)
++      def hello
++        puts :bing
++    STR
++
++    @t.process_command '!'
++    @t.last_output.should =~ /Input buffer cleared!/
++    @t.eval_string.should == ''
++  end
++
++  it 'should not clear the input buffer for negation' do
++    @t.push '! false'
++    @t.last_output.should =~ /true/
++    @t.eval_string.should == ''
++  end
++end
+diff --git a/spec/commands/cat/file_formatter_spec.rb b/spec/commands/cat/file_formatter_spec.rb
+new file mode 100644
+index 0000000..9d76475
+--- /dev/null
++++ b/spec/commands/cat/file_formatter_spec.rb
+@@ -0,0 +1,83 @@
++require_relative '../../helper'
++
++describe Pry::Command::Cat::FileFormatter do
++  describe "#file_and_line" do
++    before do
++      @p = Pry.new
++      @opt = Slop.new
++      Pry::Code.stubs(:from_file)
++    end
++
++    after do
++      Pry::Code.unstub(:from_file)
++    end
++
++    describe "windows filesystem" do
++      it "should parse '/'style absolute path without line_num" do
++        file_with_embedded_line = "C:/Ruby193/pry_instance.rb"
++        ff = Pry::Command::Cat::FileFormatter.new(file_with_embedded_line, @p, @opt)
++        file_name, line_num = ff.file_and_line
++        file_name.should == "C:/Ruby193/pry_instance.rb"
++        line_num.should == nil
++      end
++
++      it "should parse '/'style absolute path with line_num" do
++        file_with_embedded_line = "C:/Ruby193/pry_instance.rb:2"
++        ff = Pry::Command::Cat::FileFormatter.new(file_with_embedded_line, @p, @opt)
++        file_name, line_num = ff.file_and_line
++        file_name.should == "C:/Ruby193/pry_instance.rb"
++        line_num.should == 2
++      end
++
++      it "should parse '\\'style absolute path without line_num" do
++        file_with_embedded_line = "C:\\Ruby193\\pry_instance.rb"
++        ff = Pry::Command::Cat::FileFormatter.new(file_with_embedded_line, @p, @opt)
++        file_name, line_num = ff.file_and_line
++        file_name.should == "C:\\Ruby193\\pry_instance.rb"
++        line_num.should == nil
++      end
++
++      it "should parse '\\'style absolute path with line_num" do
++        file_with_embedded_line = "C:\\Ruby193\\pry_instance.rb:2"
++        ff = Pry::Command::Cat::FileFormatter.new(file_with_embedded_line, @p, @opt)
++        file_name, line_num = ff.file_and_line
++        file_name.should == "C:\\Ruby193\\pry_instance.rb"
++        line_num.should == 2
++      end      
++    end
++
++    describe "UNIX-like filesystem" do
++      it "should parse absolute path without line_num" do
++        file_with_embedded_line = "/Ruby193/pry_instance.rb"
++        ff = Pry::Command::Cat::FileFormatter.new(file_with_embedded_line, @p, @opt)
++        file_name, line_num = ff.file_and_line
++        file_name.should == "/Ruby193/pry_instance.rb"
++        line_num.should == nil
++      end
++
++      it "should parse absolute path with line_num" do
++        file_with_embedded_line = "/Ruby193/pry_instance.rb:2"
++        ff = Pry::Command::Cat::FileFormatter.new(file_with_embedded_line, @p, @opt)
++        file_name, line_num = ff.file_and_line
++        file_name.should == "/Ruby193/pry_instance.rb"
++        line_num.should == 2
++      end
++    end
++
++    it "should parse relative path without line_num" do
++      file_with_embedded_line = "pry_instance.rb"
++      ff = Pry::Command::Cat::FileFormatter.new(file_with_embedded_line, @p, @opt)
++      file_name, line_num = ff.file_and_line
++      file_name.should == "pry_instance.rb"
++      line_num.should == nil
++    end
++
++    it "should parse relative path with line_num" do
++      file_with_embedded_line = "pry_instance.rb:2"
++      ff = Pry::Command::Cat::FileFormatter.new(file_with_embedded_line, @p, @opt)
++      file_name, line_num = ff.file_and_line
++      file_name.should == "pry_instance.rb"
++      line_num.should == 2
++    end
++  end
++end
+diff --git a/spec/commands/cat_spec.rb b/spec/commands/cat_spec.rb
+new file mode 100644
+index 0000000..26b69b7
+--- /dev/null
++++ b/spec/commands/cat_spec.rb
+@@ -0,0 +1,164 @@
++require_relative '../helper'
++
++describe "cat" do
++  before do
++    @str_output = StringIO.new
++
++    @t = pry_tester do
++      def insert_nil_input
++        @pry.update_input_history(nil)
++      end
++
++      def last_exception=(e)
++        @pry.last_exception = e
++      end
++    end
++  end
++
++  describe "on receiving a file that does not exist" do
++    it 'should display an error message' do
++      proc {
++        @t.eval 'cat supercalifragilicious66'
++      }.should.raise(StandardError).message.should =~ /Cannot open/
++    end
++  end
++
++  describe "with --in" do
++    it 'should display the last few expressions with indices' do
++      @t.eval('10', '20', 'cat --in').should == unindent(<<-STR)
++        1:
++          10
++        2:
++          20
++      STR
++    end
++  end
++
++  describe "with --in 1" do
++    it 'should display the first expression with no index' do
++      @t.eval('10', '20', 'cat --in 1').should == "10\n"
++    end
++  end
++
++  describe "with --in -1" do
++    it 'should display the last expression with no index' do
++      @t.eval('10', '20', 'cat --in -1').should == "20\n"
++    end
++  end
++
++  describe "with --in 1..2" do
++    it 'should display the given range with indices, omitting nils' do
++      @t.eval '10'
++      @t.insert_nil_input # normally happens when a command is executed
++      @t.eval ':hello'
++
++      @t.eval('cat --in 1..3').should == unindent(<<-EOS)
++        1:
++          10
++        3:
++          :hello
++      EOS
++    end
++  end
++
++  # this doesnt work so well on rbx due to differences in backtrace
++  # so we currently skip rbx until we figure out a workaround
++  describe "with --ex" do
++    before do
++      @o = Object.new
++
++      # this is to test exception code (cat --ex)
++      def @o.broken_method
++        this method is broken
++      end
++    end
++
++    if !Pry::Helpers::BaseHelpers.rbx?
++      it 'cat --ex should display repl code that generated exception' do
++        @t.eval unindent(<<-EOS)
++          begin
++            this raises error
++          rescue => e
++            _pry_.last_exception = e
++          end
++        EOS
++        @t.eval('cat --ex').should =~ /\d+:(\s*) this raises error/
++      end
++
++      it 'cat --ex should correctly display code that generated exception' do
++        begin
++          @o.broken_method
++        rescue => e
++          @t.last_exception = e
++        end
++        @t.eval('cat --ex').should =~ /this method is broken/
++      end
++    end
++  end
++
++  describe "with --ex N" do
++    it 'should cat first level of backtrace when --ex used with no argument ' do
++      temp_file do |f|
++        f << "bt number 1"
++        f.flush
++        @t.last_exception = mock_exception("#{f.path}:1", 'x', 'x')
++        @t.eval('cat --ex').should =~ /bt number 1/
++      end
++    end
++
++    it 'should cat first level of backtrace when --ex 0 used ' do
++      temp_file do |f|
++        f << "bt number 1"
++        f.flush
++        @t.last_exception = mock_exception("#{f.path}:1", 'x', 'x')
++        @t.eval('cat --ex 0').should =~ /bt number 1/
++      end
++    end
++
++    it 'should cat second level of backtrace when --ex 1 used ' do
++      temp_file do |f|
++        f << "bt number 2"
++        f.flush
++        @t.last_exception = mock_exception('x', "#{f.path}:1", 'x')
++        @t.eval('cat --ex 1').should =~ /bt number 2/
++      end
++    end
++
++    it 'should cat third level of backtrace when --ex 2 used' do
++      temp_file do |f|
++        f << "bt number 3"
++        f.flush
++        @t.last_exception = mock_exception('x', 'x', "#{f.path}:1")
++        @t.eval('cat --ex 2').should =~ /bt number 3/
++      end
++    end
++
++    it 'should show error when backtrace level out of bounds' do
++      @t.last_exception = mock_exception('x', 'x', 'x')
++      proc {
++        @t.eval('cat --ex 3')
++      }.should.raise(Pry::CommandError).message.should =~ /out of bounds/
++    end
++
++    it 'each successive cat --ex should show the next level of backtrace, and going past the final level should return to the first' do
++      temp_files = []
++      3.times do |i|
++        temp_files << Tempfile.new(['pry', '.rb'])
++        temp_files.last << "bt number #{i}"
++        temp_files.last.flush
++      end
++
++      @t.last_exception = mock_exception(*temp_files.map { |f| "#{f.path}:1" })
++
++      3.times do |i|
++        @t.eval('cat --ex').should =~ /bt number #{i}/
++      end
++
++      @t.eval('cat --ex').should =~ /bt number 0/
++
++      temp_files.each do |file|
++        file.close(true)
++      end
++    end
++  end
++end
+diff --git a/spec/commands/cd_spec.rb b/spec/commands/cd_spec.rb
+new file mode 100644
+index 0000000..ddc3595
+--- /dev/null
++++ b/spec/commands/cd_spec.rb
+@@ -0,0 +1,259 @@
++require_relative '../helper'
++
++describe 'cd' do
++  before do
++    @o, @obj = Object.new, Object.new
++    @obj.instance_variable_set(:@x, 66)
++    @obj.instance_variable_set(:@y, 79)
++    @o.instance_variable_set(:@obj, @obj)
++
++    @t = pry_tester(@o) do
++      def assert_binding_stack(other)
++        binding_stack.map { |b| b.eval('self') }.should == other
++      end
++
++      def binding_stack
++        pry.binding_stack.dup
++      end
++
++      def command_state
++        pry.command_state["cd"]
++      end
++
++      def old_stack
++        pry.command_state['cd'].old_stack.dup
++      end
++    end
++  end
++
++  describe 'state' do
++    it 'should not to be set up in fresh instance' do
++      @t.command_state.should.be.nil
++    end
++  end
++
++  describe 'old stack toggling with `cd -`' do
++    describe 'in fresh pry instance' do
++      it 'should not toggle when there is no old stack' do
++        2.times do
++          @t.eval 'cd -'
++          @t.assert_binding_stack [@o]
++        end
++      end
++    end
++
++    describe 'when an error was raised' do
++      it 'should not toggle and should keep correct stacks' do
++        proc {
++          @t.eval 'cd %'
++        }.should.raise(Pry::CommandError)
++
++        @t.old_stack.should == []
++        @t.assert_binding_stack [@o]
++
++        @t.eval 'cd -'
++        @t.old_stack.should == []
++        @t.assert_binding_stack [@o]
++      end
++    end
++
++    describe 'when using simple cd syntax' do
++      it 'should toggle' do
++        @t.eval 'cd :mon_dogg', 'cd -'
++        @t.assert_binding_stack [@o]
++
++        @t.eval 'cd -'
++        @t.assert_binding_stack [@o, :mon_dogg]
++      end
++    end
++
++    describe "when using complex cd syntax" do
++      it 'should toggle with a complex path (simple case)' do
++        @t.eval 'cd 1/2/3', 'cd -'
++        @t.assert_binding_stack [@o]
++
++        @t.eval 'cd -'
++        @t.assert_binding_stack [@o, 1, 2, 3]
++      end
++
++      it 'should toggle with a complex path (more complex case)' do
++        @t.eval 'cd 1/2/3', 'cd ../4', 'cd -'
++        @t.assert_binding_stack [@o, 1, 2, 3]
++
++        @t.eval 'cd -'
++        @t.assert_binding_stack [@o, 1, 2, 4]
++      end
++    end
++
++    describe 'series of cd calls' do
++      it 'should toggle with fuzzy `cd -` calls' do
++        @t.eval 'cd :mon_dogg', 'cd -', 'cd 42', 'cd -'
++        @t.assert_binding_stack [@o]
++
++        @t.eval 'cd -'
++        @t.assert_binding_stack [@o, 42]
++      end
++    end
++
++    describe 'when using cd ..' do
++      it 'should toggle with a simple path' do
++        @t.eval 'cd :john_dogg', 'cd ..'
++        @t.assert_binding_stack [@o]
++
++        @t.eval 'cd -'
++        @t.assert_binding_stack [@o, :john_dogg]
++      end
++
++      it 'should toggle with a complex path' do
++        @t.eval 'cd 1/2/3/../4', 'cd -'
++        @t.assert_binding_stack [@o]
++
++        @t.eval 'cd -'
++        @t.assert_binding_stack [@o, 1, 2, 4]
++      end
++    end
++
++    describe 'when using cd ::' do
++      it 'should toggle' do
++        @t.eval 'cd ::', 'cd -'
++        @t.assert_binding_stack [@o]
++
++        @t.eval 'cd -'
++        @t.assert_binding_stack [@o, TOPLEVEL_BINDING.eval('self')]
++      end
++    end
++
++    describe 'when using cd /' do
++      it 'should toggle' do
++        @t.eval 'cd /', 'cd -'
++        @t.assert_binding_stack [@o]
++
++        @t.eval 'cd :john_dogg', 'cd /', 'cd -'
++        @t.assert_binding_stack [@o, :john_dogg]
++      end
++    end
++
++    describe 'when using ^D (Control-D) key press' do
++      it 'should keep correct old binding' do
++        @t.eval 'cd :john_dogg', 'cd :mon_dogg', 'cd :kyr_dogg',
++          'Pry::DEFAULT_CONTROL_D_HANDLER.call("", _pry_)'
++        @t.assert_binding_stack [@o, :john_dogg, :mon_dogg]
++
++        @t.eval 'cd -'
++        @t.assert_binding_stack [@o, :john_dogg, :mon_dogg, :kyr_dogg]
++
++        @t.eval 'cd -'
++        @t.assert_binding_stack [@o, :john_dogg, :mon_dogg]
++      end
++    end
++  end
++
++  it 'should cd into simple input' do
++    @t.eval 'cd :mon_ouie'
++    @t.eval('self').should == :mon_ouie
++  end
++
++  it 'should break out of session with cd ..' do
++    @t.eval 'cd :outer', 'cd :inner'
++    @t.eval('self').should == :inner
++
++    @t.eval 'cd ..'
++    @t.eval('self').should == :outer
++  end
++
++  it "should not leave the REPL session when given 'cd ..'" do
++    @t.eval 'cd ..'
++    @t.eval('self').should == @o
++  end
++
++  it 'should break out to outer-most session with cd /' do
++    @t.eval 'cd :inner'
++    @t.eval('self').should == :inner
++
++    @t.eval 'cd 5'
++    @t.eval('self').should == 5
++
++    @t.eval 'cd /'
++    @t.eval('self').should == @o
++  end
++
++  it 'should break out to outer-most session with just cd (no args)' do
++    @t.eval 'cd :inner'
++    @t.eval('self').should == :inner
++
++    @t.eval 'cd 5'
++    @t.eval('self').should == 5
++
++    @t.eval 'cd'
++    @t.eval('self').should == @o
++  end
++
++  it 'should cd into an object and its ivar using cd obj/@ivar syntax' do
++    @t.eval 'cd @obj/@x'
++    @t.assert_binding_stack [@o, @obj, 66]
++  end
++
++  it 'should cd into an object and its ivar using cd obj/@ivar/ syntax (note following /)' do
++    @t.eval 'cd @obj/@x/'
++    @t.assert_binding_stack [@o, @obj, 66]
++  end
++
++  it 'should cd into previous object and its local using cd ../local syntax' do
++    @t.eval 'cd @obj', 'local = :local', 'cd @x', 'cd ../local'
++    @t.assert_binding_stack [@o, @obj, :local]
++  end
++
++  it 'should cd into an object and its ivar and back again using cd obj/@ivar/.. syntax' do
++    @t.eval 'cd @obj/@x/..'
++    @t.assert_binding_stack [@o, @obj]
++  end
++
++  it 'should cd into an object and its ivar and back and then into another ivar using cd obj/@ivar/../@y syntax' do
++    @t.eval 'cd @obj/@x/../@y'
++    @t.assert_binding_stack [@o, @obj, 79]
++  end
++
++  it 'should cd back to top-level and then into another ivar using cd /@ivar/ syntax' do
++    @t.eval '@z = 20', 'cd @obj/@x/', 'cd /@z'
++    @t.assert_binding_stack [@o, 20]
++  end
++
++  it 'should start a session on TOPLEVEL_BINDING with cd ::' do
++    @t.eval 'cd ::'
++    @t.eval('self').should == TOPLEVEL_BINDING.eval('self')
++  end
++
++  it 'should cd into complex input (with spaces)' do
++    def @o.hello(x, y, z)
++      :mon_ouie
++    end
++
++    @t.eval 'cd hello 1, 2, 3'
++    @t.eval('self').should == :mon_ouie
++  end
++
++  it 'should not cd into complex input when it encounters an exception' do
++    proc {
++      @t.eval 'cd 1/2/swoop_a_doop/3'
++    }.should.raise(Pry::CommandError)
++
++    @t.assert_binding_stack [@o]
++  end
++
++  it 'can cd into an expression containing a string with slashes in it' do
++    @t.eval 'cd ["http://google.com"]'
++    @t.eval('self').should == ["http://google.com"]
++  end
++
++  it 'can cd into an expression with division in it' do
++    @t.eval 'cd (10/2)/even?'
++    @t.eval('self').should == false
++  end
++
++  # Regression test for ticket #516.
++  it 'should be able to cd into the Object BasicObject' do
++    proc {
++      @t.eval 'cd BasicObject.new'
++    }.should.not.raise
++  end
++end
+diff --git a/spec/commands/disable_pry_spec.rb b/spec/commands/disable_pry_spec.rb
+new file mode 100644
+index 0000000..534f063
+--- /dev/null
++++ b/spec/commands/disable_pry_spec.rb
+@@ -0,0 +1,25 @@
++require_relative '../helper'
++
++describe "disable-pry" do
++  before do
++    @t = pry_tester
++  end
++
++  after do
++    ENV.delete 'DISABLE_PRY'
++  end
++
++  it 'should quit the current session' do
++    lambda{
++      @t.process_command 'disable-pry'
++    }.should.throw(:breakout)
++  end
++
++  it "should set DISABLE_PRY" do
++    ENV['DISABLE_PRY'].should == nil
++    lambda{
++      @t.process_command 'disable-pry'
++    }.should.throw(:breakout)
++    ENV['DISABLE_PRY'].should == 'true'
++  end
++end
+diff --git a/spec/commands/edit_spec.rb b/spec/commands/edit_spec.rb
+new file mode 100644
+index 0000000..b3b43ae
+--- /dev/null
++++ b/spec/commands/edit_spec.rb
+@@ -0,0 +1,768 @@
++require 'pathname'
++require_relative '../helper'
++
++describe "edit" do
++  before do
++    @old_editor = Pry.config.editor
++    @file = @line = @contents = nil
++    Pry.config.editor = lambda do |file, line|
++      @file = file; @line = line; @contents = File.read(@file)
++      nil
++    end
++  end
++
++  after do
++    Pry.config.editor = @old_editor
++  end
++
++  describe "with FILE" do
++
++    before do
++      # OS-specific tempdir name. For GNU/Linux it's "tmp", for Windows it's
++      # something "Temp".
++      @tf_dir =
++        if Pry::Helpers::BaseHelpers.mri_19?
++          Pathname.new(Dir::Tmpname.tmpdir)
++        else
++          Pathname.new(Dir.tmpdir)
++        end
++
++      @tf_path = File.expand_path(File.join(@tf_dir.to_s, 'bar.rb'))
++      FileUtils.touch(@tf_path)
++    end
++
++    after do
++      FileUtils.rm(@tf_path) if File.exists?(@tf_path)
++    end
++
++    it "should not allow patching any known kind of file" do
++      ["file.rb", "file.c", "file.py", "file.yml", "file.gemspec",
++       "/tmp/file", "\\\\Temp\\\\file"].each do |file|
++        proc {
++          pry_eval "edit -p #{file}"
++        }.should.raise(NotImplementedError).
++          message.should =~ /Cannot yet patch false objects!/
++      end
++    end
++
++    it "should invoke Pry.config.editor with absolutified filenames" do
++      pry_eval 'edit lib/pry.rb'
++      @file.should == File.expand_path('lib/pry.rb')
++
++      pry_eval "edit #@tf_path"
++      @file.should == @tf_path
++    end
++
++    it "should guess the line number from a colon" do
++      pry_eval 'edit lib/pry.rb:10'
++      @line.should == 10
++    end
++
++    it "should use the line number from -l" do
++      pry_eval 'edit -l 10 lib/pry.rb'
++      @line.should == 10
++    end
++
++    it "should not delete the file!" do
++      pry_eval 'edit Rakefile'
++      File.exist?(@file).should == true
++    end
++
++    it "works with files that contain blanks in their names" do
++      tf_path = File.join(File.dirname(@tf_path), 'swoop and doop.rb')
++      FileUtils.touch(tf_path)
++      pry_eval "edit #{ tf_path }"
++      @file.should == tf_path
++      FileUtils.rm(tf_path)
++    end
++
++    if respond_to?(:require_relative, true)
++      it "should work with require relative" do
++        Pry.config.editor = lambda { |file, line|
++          File.open(file, 'w'){ |f| f << 'require_relative "baz.rb"' }
++          File.open(file.gsub('bar.rb', 'baz.rb'), 'w'){ |f| f << "Pad.required = true; FileUtils.rm(__FILE__)" }
++
++          if defined?(Rubinius::Compiler)
++            File.unlink Rubinius::Compiler.compiled_name file
++          end
++          nil
++        }
++        pry_eval "edit #@tf_path"
++        Pad.required.should == true
++      end
++    end
++
++    describe do
++      before do
++        Pad.counter = 0
++        Pry.config.editor = lambda { |file, line|
++          File.open(file, 'w') { |f| f << "Pad.counter = Pad.counter + 1" }
++          nil
++        }
++      end
++
++      it "should reload the file if it is a ruby file" do
++        temp_file do |tf|
++          counter = Pad.counter
++          path    = tf.path
++
++          pry_eval "edit #{path}"
++
++          Pad.counter.should == counter + 1
++        end
++      end
++
++      it "should not reload the file if it is not a ruby file" do
++        temp_file('.py') do |tf|
++          counter = Pad.counter
++          path    = tf.path
++
++          pry_eval "edit #{path}"
++
++          Pad.counter.should == counter
++        end
++      end
++
++      it "should not reload a ruby file if -n is given" do
++        temp_file do |tf|
++          counter = Pad.counter
++          path    = tf.path
++
++          Pad.counter.should == counter
++        end
++      end
++
++      it "should reload a non-ruby file if -r is given" do
++        temp_file('.pryrc') do |tf|
++          counter = Pad.counter
++          path    = tf.path
++
++          pry_eval "edit -r #{path}"
++
++          Pad.counter.should == counter + 1
++        end
++      end
++    end
++
++    describe do
++      before do
++        @reloading = nil
++        Pry.config.editor = lambda do |file, line, reloading|
++          @file = file; @line = line; @reloading = reloading
++          nil
++        end
++      end
++
++      it "should pass the editor a reloading arg" do
++        pry_eval 'edit lib/pry.rb'
++        @reloading.should == true
++        pry_eval 'edit -n lib/pry.rb'
++        @reloading.should == false
++      end
++    end
++  end
++
++  describe "with --ex" do
++    before do
++      @t = pry_tester do
++        def last_exception=(exception)
++          @pry.last_exception = exception
++        end
++        def last_exception; @pry.last_exception; end
++      end
++    end
++
++    describe "with a real file" do
++      before do
++        @tf = Tempfile.new(["pry", ".rb"])
++        @path = @tf.path
++        @tf << "1\n2\nraise RuntimeError"
++        @tf.flush
++
++        begin
++          load @path
++        rescue RuntimeError => e
++          @t.last_exception = e
++        end
++      end
++
++      after do
++        @tf.close(true)
++        File.unlink("#{@path}c") if File.exists?("#{@path}c") #rbx
++      end
++
++      it "should reload the file" do
++        Pry.config.editor = lambda {|file, line|
++          File.open(file, 'w'){|f| f << "FOO = 'BAR'" }
++          if defined?(Rubinius::Compiler)
++            File.unlink Rubinius::Compiler.compiled_name file
++          end
++          nil
++        }
++
++        defined?(FOO).should.be.nil
++
++        @t.eval 'edit --ex'
++
++        FOO.should == 'BAR'
++      end
++
++      # regression test (this used to edit the current method instead
++      # of the exception)
++      it 'edits the exception even when in a patched method context' do
++        source_location = nil
++        Pry.config.editor = lambda {|file, line|
++          source_location = [file, line]
++          nil
++        }
++
++        Pad.le = @t.last_exception
++        redirect_pry_io(InputTester.new("def broken_method", "binding.pry", "end",
++                                        "broken_method",
++                                        "_pry_.last_exception = Pad.le",
++                                        "edit --ex -n", "exit-all", "exit-all")) do
++          Object.new.pry
++        end
++
++        source_location.should == [@path, 3]
++        Pad.clear
++      end
++
++      it "should not reload the file if -n is passed" do
++        Pry.config.editor = lambda {|file, line|
++          File.open(file, 'w'){|f| f << "FOO2 = 'BAZ'" }
++          nil
++        }
++
++        defined?(FOO2).should.be.nil
++
++        @t.eval 'edit -n --ex'
++
++        defined?(FOO2).should.be.nil
++      end
++
++      describe "with --patch" do
++        # Original source code must be untouched.
++        it "should apply changes only in memory (monkey patching)" do
++          Pry.config.editor = lambda {|file, line|
++            File.open(file, 'w'){|f| f << "FOO3 = 'PIYO'" }
++            @patched_def = File.open(file, 'r').read
++            nil
++          }
++
++          defined?(FOO3).should.be.nil
++
++          @t.eval 'edit --ex --patch'
++
++          FOO3.should == 'PIYO'
++
++          @tf.rewind
++          @tf.read.should == "1\n2\nraise RuntimeError"
++          @patched_def.should == "FOO3 = 'PIYO'"
++        end
++      end
++    end
++
++    describe "with --ex NUM" do
++      before do
++        Pry.config.editor = proc do |file, line|
++          @__ex_file__ = file
++          @__ex_line__ = line
++          nil
++        end
++
++        @t.last_exception = mock_exception('a:1', 'b:2', 'c:3')
++      end
++
++      it 'should start on first level of backtrace with just --ex' do
++        @t.eval 'edit -n --ex'
++        @__ex_file__.should == "a"
++        @__ex_line__.should == 1
++      end
++
++      it 'should start editor on first level of backtrace with --ex 0' do
++        @t.eval 'edit -n --ex 0'
++        @__ex_file__.should == "a"
++        @__ex_line__.should == 1
++      end
++
++      it 'should start editor on second level of backtrace with --ex 1' do
++        @t.eval 'edit -n --ex 1'
++        @__ex_file__.should == "b"
++        @__ex_line__.should == 2
++      end
++
++      it 'should start editor on third level of backtrace with --ex 2' do
++        @t.eval 'edit -n --ex 2'
++        @__ex_file__.should == "c"
++        @__ex_line__.should == 3
++      end
++
++      it 'should display error message when backtrace level is invalid' do
++        proc {
++          @t.eval 'edit -n --ex 4'
++        }.should.raise(Pry::CommandError)
++      end
++    end
++  end
++
++  describe "without FILE" do
++    before do
++      @t = pry_tester
++    end
++
++    it "should edit the current expression if it's incomplete" do
++      @t.push 'def a'
++      @t.process_command 'edit'
++      @contents.should == "def a\n"
++    end
++
++    it "should edit the previous expression if the current is empty" do
++      @t.eval 'def a; 2; end', 'edit'
++      @contents.should == "def a; 2; end\n"
++    end
++
++    it "should use a blank file if -t is specified" do
++      @t.eval 'def a; 5; end', 'edit -t'
++      @contents.should == "\n"
++    end
++
++    it "should use a blank file if -t given, even during an expression" do
++      @t.push 'def a;'
++      @t.process_command 'edit -t'
++      @contents.should == "\n"
++    end
++
++    it "should position the cursor at the end of the expression" do
++      @t.eval "def a; 2;\nend"
++      @t.process_command 'edit'
++      @line.should == 2
++    end
++
++    it "should evaluate the expression" do
++      Pry.config.editor = lambda {|file, line|
++        File.open(file, 'w'){|f| f << "'FOO'\n" }
++        nil
++      }
++      @t.process_command 'edit'
++      @t.eval_string.should == "'FOO'\n"
++    end
++
++    it "should ignore -n for tempfiles" do
++      Pry.config.editor = lambda {|file, line|
++        File.open(file, 'w'){|f| f << "'FOO'\n" }
++        nil
++      }
++      @t.process_command "edit -n"
++      @t.eval_string.should == "'FOO'\n"
++    end
++
++    it "should not evaluate a file with -n" do
++      Pry.config.editor = lambda {|file, line|
++        File.open(file, 'w'){|f| f << "'FOO'\n" }
++        nil
++      }
++      begin
++        @t.process_command 'edit -n spec/fixtures/foo.rb'
++        File.read("spec/fixtures/foo.rb").should == "'FOO'\n"
++        @t.eval_string.should == ''
++      ensure
++        FileUtils.rm "spec/fixtures/foo.rb"
++      end
++    end
++  end
++
++  describe "with --in" do
++    it "should edit the nth line of _in_" do
++      pry_eval '10', '11', 'edit --in -2'
++      @contents.should == "10\n"
++    end
++
++    it "should edit the last line if no argument is given" do
++      pry_eval '10', '11', 'edit --in'
++      @contents.should == "11\n"
++    end
++
++    it "should edit a range of lines if a range is given" do
++      pry_eval "10", "11", "edit -i 1,2"
++      @contents.should == "10\n11\n"
++    end
++
++    it "should edit a multi-line expression as it occupies one line of _in_" do
++      pry_eval "class Fixnum\n  def invert; -self; end\nend", "edit -i 1"
++      @contents.should == "class Fixnum\n  def invert; -self; end\nend\n"
++    end
++
++    it "should not work with a filename" do
++      proc {
++        pry_eval 'edit ruby.rb -i'
++      }.should.raise(Pry::CommandError).
++        message.should =~ /Only one of --ex, --temp, --in, --method and FILE/
++    end
++
++    it "should not work with nonsense" do
++      proc {
++        pry_eval 'edit --in three'
++      }.should.raise(Pry::CommandError).
++        message.should =~ /Not a valid range: three/
++    end
++  end
++
++  describe "old edit-method tests now migrated to edit" do
++    describe "on a method defined in a file" do
++      before do
++        @tempfile = (Tempfile.new(['pry', '.rb']))
++        @tempfile.puts <<-EOS
++        module A
++          def a
++            :yup
++          end
++
++          def b
++            :kinda
++          end
++        end
++
++        class X
++          include A
++
++          def self.x
++            :double_yup
++          end
++
++          def x
++            :nope
++          end
++
++          def b
++            super
++          end
++          alias c b
++
++          def y?
++            :because
++          end
++
++          class B
++            G = :nawt
++
++            def foo
++              :possibly
++              G
++            end
++          end
++        end
++        EOS
++        @tempfile.flush
++        load @tempfile.path
++
++        @tempfile_path = @tempfile.path
++      end
++
++      after do
++        @tempfile.close(true)
++      end
++
++      describe 'without -p' do
++        before do
++          @file = @line = @contents = nil
++          Pry.config.editor = lambda do |file, line|
++            @file = file; @line = line
++            nil
++          end
++        end
++
++        it "should correctly find a class method" do
++          pry_eval 'edit X.x'
++
++          @file.should == @tempfile_path
++          @line.should == 14
++
++        end
++
++        it "should correctly find an instance method" do
++          pry_eval 'edit X#x'
++          @file.should == @tempfile_path
++          @line.should == 18
++        end
++
++        it "should correctly find a method on an instance" do
++          pry_eval 'x = X.new', 'edit x.x'
++          @file.should == @tempfile_path
++          @line.should == 18
++        end
++
++        it "should correctly find a method from a module" do
++          pry_eval 'edit X#a'
++          @file.should == @tempfile_path
++          @line.should == 2
++        end
++
++        it "should correctly find an aliased method" do
++          pry_eval 'edit X#c'
++          @file.should == @tempfile_path
++          @line.should == 22
++        end
++      end
++
++      describe 'with -p' do
++        before do
++          Pry.config.editor = lambda do |file, line|
++            lines = File.read(file).lines.to_a
++            lines[1] = ":maybe\n"
++            File.open(file, 'w') do |f|
++              f.write(lines.join)
++            end
++            @patched_def = String(lines[1]).chomp
++            nil
++          end
++        end
++
++        it "should successfully replace a class method" do
++          pry_eval 'edit -p X.x'
++
++          class << X
++            X.method(:x).owner.should == self
++          end
++          X.method(:x).receiver.should == X
++          X.x.should == :maybe
++        end
++
++        it "should successfully replace an instance method" do
++          pry_eval 'edit -p X#x'
++
++          X.instance_method(:x).owner.should == X
++          X.new.x.should == :maybe
++        end
++
++        it "should successfully replace a method on an instance" do
++          pry_eval 'instance = X.new', 'edit -p instance.x'
++
++          instance = X.new
++          instance.method(:x).owner.should == X
++          instance.x.should == :maybe
++        end
++
++        it "should successfully replace a method from a module" do
++          pry_eval 'edit -p X#a'
++
++          X.instance_method(:a).owner.should == A
++          X.new.a.should == :maybe
++        end
++
++        it "should successfully replace a method with a question mark" do
++          pry_eval 'edit -p X#y?'
++
++          X.instance_method(:y?).owner.should == X
++          X.new.y?.should == :maybe
++        end
++
++        it "should preserve module nesting" do
++          pry_eval 'edit -p X::B#foo'
++
++          X::B.instance_method(:foo).owner.should == X::B
++          X::B.new.foo.should == :nawt
++        end
++
++        describe "monkey-patching" do
++          before do
++            @edit = 'edit --patch ' # A shortcut.
++          end
++
++          # @param [Integer] lineno
++          # @return [String] the stripped line from the tempfile at +lineno+
++          def stripped_line_at(lineno)
++            @tempfile.rewind
++            @tempfile.lines.to_a[lineno].strip
++          end
++
++          # Applies the monkey patch for +method+ with help of evaluation of
++          # +eval_strs+. The idea is to capture the initial line number (before
++          # the monkey patch), because it gets overwritten by the line number from
++          # the monkey patch. And our goal is to check that the original
++          # definition hasn't changed.
++          # @param [UnboundMethod] method
++          # @param [Array<String>] eval_strs
++          # @return [Array<String] the lines with definitions of the same line
++          #   before monkey patching and after (normally, they should be equal)
++          def apply_monkey_patch(method, *eval_strs)
++            _, lineno = method.source_location
++            definition_before = stripped_line_at(lineno)
++
++            pry_eval(*eval_strs)
++
++            definition_after = stripped_line_at(lineno)
++
++            [definition_before, definition_after]
++          end
++
++          it "should work for a class method" do
++            def_before, def_after =
++              apply_monkey_patch(X.method(:x), "#@edit X.x")
++
++            def_before.should   == ':double_yup'
++            def_after.should    == ':double_yup'
++            @patched_def.should == ':maybe'
++          end
++
++          it "should work for an instance method" do
++            def_before, def_after =
++              apply_monkey_patch(X.instance_method(:x), "#@edit X#x")
++
++            def_before.should   == ':nope'
++            def_after.should    == ':nope'
++            @patched_def.should == ':maybe'
++          end
++
++          it "should work for a method on an instance" do
++            def_before, def_after =
++              apply_monkey_patch(X.instance_method(:x), 'instance = X.new', "#@edit instance.x")
++
++            def_before.should   == ':nope'
++            def_after.should    == ':nope'
++            @patched_def.should == ':maybe'
++          end
++
++          it "should work for a method from a module" do
++            def_before, def_after =
++              apply_monkey_patch(X.instance_method(:a), "#@edit X#a")
++
++            def_before.should   == ':yup'
++            def_after.should    == ':yup'
++            @patched_def.should == ':maybe'
++          end
++
++          it "should work for a method with a question mark" do
++            def_before, def_after =
++              apply_monkey_patch(X.instance_method(:y?), "#@edit X#y?")
++
++            def_before.should   == ':because'
++            def_after.should    == ':because'
++            @patched_def.should == ':maybe'
++          end
++
++          it "should work with nesting" do
++            def_before, def_after =
++              apply_monkey_patch(X::B.instance_method(:foo), "#@edit X::B#foo")
++
++            def_before.should   == ':possibly'
++            def_after.should    == ':possibly'
++            @patched_def.should == ':maybe'
++          end
++        end
++      end
++
++      describe 'on an aliased method' do
++        before do
++          Pry.config.editor = lambda do |file, line|
++            lines = File.read(file).lines.to_a
++            lines[1] = '"#{super}aa".to_sym' + "\n"
++            File.open(file, 'w') do |f|
++              f.write(lines.join)
++            end
++            nil
++          end
++        end
++
++        it "should change the alias, but not the original, without breaking super" do
++
++          $x = :bebe
++          pry_eval 'edit -p X#c'
++
++
++          Pry::Method.from_str("X#c").alias?.should == true
++
++          X.new.b.should == :kinda
++          X.new.c.should == :kindaaa
++          $x = nil
++        end
++      end
++
++      describe 'with three-arg editor' do
++        before do
++          @file = @line = @reloading = nil
++          Pry.config.editor = lambda do |file, line, reloading|
++            @file = file; @line = line; @reloading = reloading
++            nil
++          end
++        end
++
++        it "should pass the editor a reloading arg" do
++          pry_eval 'edit X.x'
++          @reloading.should == true
++          pry_eval 'edit -n X.x'
++          @reloading.should == false
++        end
++      end
++    end
++  end
++
++  describe "--method flag" do
++    before do
++      @t = pry_tester
++      class BinkyWink
++        eval %{
++          def tits_macgee
++            binding
++          end
++        }
++
++        def tots_macgee
++          :jeremy_jones
++          binding
++        end
++      end
++    end
++
++    after do
++      Object.remove_const(:BinkyWink)
++    end
++
++    it 'should edit method context' do
++      Pry.config.editor = lambda do |file, line|
++        [file, line].should == BinkyWink.instance_method(:tots_macgee).source_location
++        nil
++      end
++
++      t = pry_tester(BinkyWink.new.tots_macgee)
++      t.process_command "edit -m -n"
++    end
++
++    it 'errors when cannot find method context' do
++      Pry.config.editor = lambda do |file, line|
++        [file, line].should == BinkyWink.instance_method(:tits_macgee).source_location
++        nil
++      end
++
++      t = pry_tester(BinkyWink.new.tits_macgee)
++      lambda { t.process_command "edit -m -n" }.should.
++        raise(Pry::CommandError).message.should.match(/Cannot find a file for/)
++    end
++
++    it 'errors when a filename arg is passed with --method' do
++      lambda { @t.process_command "edit -m Pry#repl" }.should.
++        raise(Pry::CommandError).message.should.match(/Only one of/)
++    end
++  end
++
++  describe "pretty error messages" do
++    before do
++      @t = pry_tester
++      class TrinkyDink
++        eval %{
++          def claudia_linklater
++          end
++        }
++      end
++    end
++
++    after do
++      Object.remove_const(:TrinkyDink)
++    end
++
++    it 'should display a nice error message when cannot open a file' do
++      lambda { @t.process_command "edit TrinkyDink#claudia_linklater" }.should.
++        raise(Pry::CommandError).message.should.match(/Cannot find a file for/)
++    end
++  end
++end
+diff --git a/spec/commands/exit_all_spec.rb b/spec/commands/exit_all_spec.rb
+new file mode 100644
+index 0000000..7a771c9
+--- /dev/null
++++ b/spec/commands/exit_all_spec.rb
+@@ -0,0 +1,27 @@
++require_relative '../helper'
++
++describe "exit-all" do
++  before { @pry = Pry.new }
++
++  it "should break out of the repl and return nil" do
++    @pry.eval("exit-all").should.be.false
++    @pry.exit_value.should.be.nil
++  end
++
++  it "should break out of the repl wth a user specified value" do
++    @pry.eval("exit-all 'message'").should.be.false
++    @pry.exit_value.should == "message"
++  end
++
++  it "should break out of the repl even if multiple bindings still on stack" do
++    ["cd 1", "cd 2"].each { |line| @pry.eval(line).should.be.true }
++    @pry.eval("exit-all 'message'").should.be.false
++    @pry.exit_value.should == "message"
++  end
++
++  it "should have empty binding_stack after breaking out of the repl" do
++    ["cd 1", "cd 2"].each { |line| @pry.eval(line).should.be.true }
++    @pry.eval("exit-all").should.be.false
++    @pry.binding_stack.should.be.empty
++  end
++end
+diff --git a/spec/commands/exit_program_spec.rb b/spec/commands/exit_program_spec.rb
+new file mode 100644
+index 0000000..b80cc7e
+--- /dev/null
++++ b/spec/commands/exit_program_spec.rb
+@@ -0,0 +1,19 @@
++require_relative '../helper'
++
++describe "exit-program" do
++  it 'should raise SystemExit' do
++    proc {
++      pry_eval('exit-program')
++    }.should.raise SystemExit
++  end
++
++  it 'should exit the program with the provided value' do
++    begin
++      pry_eval 'exit-program 66'
++    rescue SystemExit => e
++      e.status.should == 66
++    else
++      raise "Failed to raise SystemExit"
++    end
++  end
++end
+diff --git a/spec/commands/exit_spec.rb b/spec/commands/exit_spec.rb
+new file mode 100644
+index 0000000..8cd7587
+--- /dev/null
++++ b/spec/commands/exit_spec.rb
+@@ -0,0 +1,28 @@
++require_relative '../helper'
++
++describe "exit" do
++  before { @pry = Pry.new(:target => :outer, :output => StringIO.new) }
++
++  it "should pop a binding" do
++    @pry.eval "cd :inner"
++    @pry.evaluate_ruby("self").should == :inner
++    @pry.eval "exit"
++    @pry.evaluate_ruby("self").should == :outer
++  end
++
++  it "should break out of the repl when binding_stack has only one binding" do
++    @pry.eval("exit").should.be.false
++    @pry.exit_value.should.be.nil
++  end
++
++  it "should break out of the repl and return user-given value" do
++    @pry.eval("exit :john").should.be.false
++    @pry.exit_value.should == :john
++  end
++
++  it "should break out of the repl even after an exception" do
++    @pry.eval "exit = 42"
++    @pry.output.string.should =~ /^SyntaxError/
++    @pry.eval("exit").should.be.false
++  end
++end
+diff --git a/spec/commands/find_method_spec.rb b/spec/commands/find_method_spec.rb
+new file mode 100644
+index 0000000..a00e8b9
+--- /dev/null
++++ b/spec/commands/find_method_spec.rb
+@@ -0,0 +1,63 @@
++require_relative '../helper'
++
++MyKlass = Class.new do
++  def hello
++    "timothy"
++  end
++  def goodbye
++    "jenny"
++  end
++  def tea_tim?
++    "timothy"
++  end
++  def tea_time?
++    "polly"
++  end
++end
++
++describe "find-method" do
++  describe "find matching methods by name regex (-n option)" do
++    it "should find a method by regex" do
++      pry_eval("find-method hell MyKlass").should =~
++        /MyKlass.*?hello/m
++    end
++
++    it "should NOT match a method that does not match the regex" do
++      pry_eval("find-method hell MyKlass").should.not =~
++        /MyKlass.*?goodbye/m
++    end
++  end
++
++  describe "find matching methods by content regex (-c option)" do
++    it "should find a method by regex" do
++      pry_eval("find-method -c timothy MyKlass").should =~
++        /MyKlass.*?hello/m
++    end
++
++    it "should NOT match a method that does not match the regex" do
++      pry_eval("find-method timothy MyKlass").should.not =~
++        /MyKlass.*?goodbye/m
++    end
++  end
++
++  it "should work with badly behaved constants" do
++    MyKlass::X = Object.new
++    def (MyKlass::X).hash
++      raise "mooo"
++    end
++
++    pry_eval("find-method -c timothy MyKlass").should =~
++      /MyKlass.*?hello/m
++  end
++
++  it "should escape regexes correctly" do
++    good = /tea_time\?/
++    bad  = /tea_tim\?/
++    pry_eval('find-method tea_time? MyKlass').should =~ good
++    pry_eval('find-method tea_time? MyKlass').should =~ good
++    pry_eval('find-method tea_time\? MyKlass').should.not =~ bad
++    pry_eval('find-method tea_time\? MyKlass').should =~ good
++  end
++end
++
++Object.remove_const(:MyKlass)
+diff --git a/spec/commands/gem_list_spec.rb b/spec/commands/gem_list_spec.rb
+new file mode 100644
+index 0000000..cef5c74
+--- /dev/null
++++ b/spec/commands/gem_list_spec.rb
+@@ -0,0 +1,25 @@
++require_relative '../helper'
++
++describe "gem-list" do
++  it 'should not raise when invoked' do
++    proc {
++      pry_eval(self, 'gem-list')
++    }.should.not.raise
++  end
++
++  it 'should work arglessly' do
++    list = pry_eval('gem-list')
++    list.should =~ /slop \(/
++    list.should =~ /bacon \(/
++  end
++
++  it 'should find arg' do
++    prylist = pry_eval('gem-list slop')
++    prylist.should =~ /slop \(/
++    prylist.should.not =~ /bacon/
++  end
++
++  it 'should return non-results as silence' do
++    pry_eval('gem-list aoeuoueouaou').should.empty?
++  end
++end
+diff --git a/spec/commands/gist_spec.rb b/spec/commands/gist_spec.rb
+new file mode 100644
+index 0000000..dc29ba7
+--- /dev/null
++++ b/spec/commands/gist_spec.rb
+@@ -0,0 +1,32 @@
++# These tests are out of date.
++# THey need to be updated for the new 'gist' API, but im too sleepy to
++# do that now.
++
++require_relative '../helper'
++
++describe 'gist' do
++  it 'has a dependency on the jist gem' do
++    Pry::Command::Gist.command_options[:requires_gem].should == "gist"
++  end
++
++  before do
++    Pad.gist_calls = {}
++  end
++
++  # In absence of normal mocking, just monkeysmash these with no undoing after.
++  module ::Gist
++    class << self
++      def login!; Pad.gist_calls[:login!] = true end
++      def gist(*args)
++        Pad.gist_calls[:gist_args] = args
++        {'html_url' => 'http://gist.blahblah'}
++      end
++      def copy(content); Pad.gist_calls[:copy_args] = content end
++    end
++  end
++
++  it 'nominally logs in' do
++    pry_eval 'gist --login'
++    Pad.gist_calls[:login!].should.not.be.nil
++  end
++end
+diff --git a/spec/commands/help_spec.rb b/spec/commands/help_spec.rb
+new file mode 100644
+index 0000000..d6876c9
+--- /dev/null
++++ b/spec/commands/help_spec.rb
+@@ -0,0 +1,56 @@
++require_relative '../helper'
++
++describe "help" do
++  before do
++    @oldset = Pry.config.commands
++    @set = Pry.config.commands = Pry::CommandSet.new do
++      import Pry::Commands
++    end
++  end
++
++  after do
++    Pry.config.commands = @oldset
++  end
++
++  it 'should display help for a specific command' do
++    pry_eval('help ls').should =~ /Usage: ls/
++  end
++
++  it 'should display help for a regex command with a "listing"' do
++    @set.command /bar(.*)/, "Test listing", :listing => "foo" do; end
++    pry_eval('help foo').should =~ /Test listing/
++  end
++
++  it 'should display help for a command with a spaces in its name' do
++    @set.command "cmd with spaces", "desc of a cmd with spaces" do; end
++    pry_eval('help "cmd with spaces"').should =~ /desc of a cmd with spaces/
++  end
++
++  it 'should display help for all commands with a description' do
++    @set.command /bar(.*)/, "Test listing", :listing => "foo" do; end
++    @set.command "b", "description for b", :listing => "foo" do; end
++    @set.command "c" do;end
++    @set.command "d", "" do;end
++
++    output = pry_eval('help')
++    output.should =~ /Test listing/
++    output.should =~ /Description for b/
++    output.should =~ /No description/
++  end
++
++  it "should sort the output of the 'help' command" do
++    @set.command 'faa', "Fooerizes" do; end
++    @set.command 'gaa', "Gooerizes" do; end
++    @set.command 'maa', "Mooerizes" do; end
++    @set.command 'baa', "Booerizes" do; end
++
++    doc = pry_eval('help')
++
++    order = [doc.index("baa"),
++             doc.index("faa"),
++             doc.index("gaa"),
++             doc.index("maa")]
++
++    order.should == order.sort
++  end
++end
+diff --git a/spec/commands/hist_spec.rb b/spec/commands/hist_spec.rb
+new file mode 100644
+index 0000000..3b444eb
+--- /dev/null
++++ b/spec/commands/hist_spec.rb
+@@ -0,0 +1,204 @@
++require_relative '../helper'
++
++describe "hist" do
++  before do
++    Pry.history.clear
++    @hist = Pry.history
++
++    @str_output = StringIO.new
++    @t = pry_tester :history => @hist do
++      # For looking at what hist pushes into the input stack. The implementation
++      # of this helper will definitely have to change at some point.
++      def next_input
++        @pry.input.string
++      end
++    end
++  end
++
++  it 'should replay history correctly (single item)' do
++    o = Object.new
++    @hist.push "@x = 10"
++    @hist.push "@y = 20"
++    @hist.push "@z = 30"
++
++    @t.push_binding o
++    @t.eval 'hist --replay -1'
++
++    o.instance_variable_get(:@z).should == 30
++  end
++
++  it 'should replay a range of history correctly (range of items)' do
++    o = Object.new
++    @hist.push "@x = 10"
++    @hist.push "@y = 20"
++
++    @t.push_binding o
++    @t.eval 'hist --replay 0..2'
++    @t.eval('[@x, @y]').should == [10, 20]
++  end
++
++  # this is to prevent a regression where input redirection is
++  # replaced by just appending to `eval_string`
++  it 'should replay a range of history correctly (range of commands)' do
++    o = Object.new
++    @hist.push "cd 1"
++    @hist.push "cd 2"
++
++    @t.eval("hist --replay 0..2")
++    stack = @t.eval("Pad.stack = _pry_.binding_stack.dup")
++    stack.map{ |b| b.eval("self") }.should == [TOPLEVEL_BINDING.eval("self"), 1, 2]
++  end
++
++  it 'should grep for correct lines in history' do
++    @hist.push "abby"
++    @hist.push "box"
++    @hist.push "button"
++    @hist.push "pepper"
++    @hist.push "orange"
++    @hist.push "grape"
++    @hist.push "def blah 1"
++    @hist.push "def boink 2"
++    @hist.push "place holder"
++
++    @t.eval('hist --grep o').should =~ /\d:.*?box\n\d:.*?button\n\d:.*?orange/
++
++    # test more than one word in a regex match (def blah)
++    @t.eval('hist --grep def blah').should =~ /def blah 1/
++
++    # test more than one word with leading white space in a regex match (def boink)
++    @t.eval('hist --grep      def boink').should =~ /def boink 2/
++  end
++
++  it 'should return last N lines in history with --tail switch' do
++    ("a".."z").each do |v|
++      @hist.push v
++    end
++
++    out = @t.eval 'hist --tail 3'
++    out.each_line.count.should == 3
++    out.should =~ /x\n\d+:.*y\n\d+:.*z/
++  end
++
++  it "should start from beginning if tail number is longer than history" do
++    @hist.push 'Hyacinth'
++    out = @t.eval 'hist --tail'
++    out.should =~ /Hyacinth/
++  end
++
++  it 'should apply --tail after --grep' do
++    @hist.push "print 1"
++    @hist.push "print 2"
++    @hist.push "puts  3"
++    @hist.push "print 4"
++    @hist.push "puts  5"
++
++    out = @t.eval 'hist --tail 2 --grep print'
++    out.each_line.count.should == 2
++    out.should =~ /\d:.*?print 2\n\d:.*?print 4/
++  end
++
++  it 'should apply --head after --grep' do
++    @hist.push "puts  1"
++    @hist.push "print 2"
++    @hist.push "puts  3"
++    @hist.push "print 4"
++    @hist.push "print 5"
++
++    out = @t.eval 'hist --head 2 --grep print'
++    out.each_line.count.should == 2
++    out.should =~ /\d:.*?print 2\n\d:.*?print 4/
++  end
++
++  # strangeness in this test is due to bug in Readline::HISTORY not
++  # always registering first line of input
++  it 'should return first N lines in history with --head switch' do
++    ("a".."z").each do |v|
++      @hist.push v
++    end
++
++    out = @t.eval 'hist --head 4'
++    out.each_line.count.should == 4
++    out.should =~ /a\n\d+:.*b\n\d+:.*c/
++  end
++
++  # strangeness in this test is due to bug in Readline::HISTORY not
++  # always registering first line of input
++  it 'should show lines between lines A and B with the --show switch' do
++    ("a".."z").each do |v|
++      @hist.push v
++    end
++
++    out = @t.eval 'hist --show 1..4'
++    out.each_line.count.should == 4
++    out.should =~ /b\n\d+:.*c\n\d+:.*d/
++  end
++
++  it "should store a call with `--replay` flag" do
++    @t.eval ":banzai"
++    @t.eval "hist --replay 1"
++    @t.eval("hist").should =~ /hist --replay 1/
++  end
++
++  it "should not contain lines produced by `--replay` flag" do
++    @t.eval ":banzai"
++    @t.eval ":geronimo"
++    @t.eval ":huzzah"
++    @t.eval("hist --replay 1..3")
++
++    output = @t.eval("hist")
++    output.should == "1: :banzai\n2: :geronimo\n3: :huzzah\n4: hist --replay 1..3\n"
++  end
++
++  it "should raise CommandError when index of `--replay` points out to another `hist --replay`" do
++    @t.eval ":banzai"
++    @t.eval "hist --replay 1"
++    lambda do
++      @t.eval "hist --replay 2"
++    end.should.raise(Pry::CommandError, /Replay index 4 points out to another replay call: `hist --replay 1`/)
++  end
++
++  it "should disallow execution of `--replay <i>` when CommandError raised" do
++    @t.eval "a = 0"
++    @t.eval "a += 1"
++    @t.eval "hist --replay 2"
++    lambda{
++      @t.eval "hist --replay 3"
++    }.should.raise(Pry::CommandError)
++    @t.eval("a").should == 2
++    @t.eval("hist").lines.to_a.size.should == 5
++  end
++
++  it "excludes Pry commands from the history with `-e` switch" do
++    @hist.push('a = 20')
++    @hist.push('ls')
++    pry_eval('hist -e').should == "1: a = 20\n"
++  end
++
++  describe "sessions" do
++    before do
++      @old_file = Pry.config.history.file
++      Pry.config.history.file = File.expand_path('spec/fixtures/pry_history')
++      @hist.load
++    end
++
++    after do
++      Pry.config.history.file = @old_file
++    end
++
++    it "displays history only for current session" do
++      @hist.push('hello')
++      @hist.push('world')
++
++      @t.eval('hist').should =~ /1:\shello\n2:\sworld/
++    end
++
++    it "displays all history (including the current sesion) with `--all` switch" do
++      @hist.push('goodbye')
++      @hist.push('world')
++
++      output = @t.eval('hist --all')
++      output.should =~ /1:\s:athos\n2:\s:porthos\n3:\s:aramis\n/
++      output.should =~ /4:\sgoodbye\n5:\sworld/
++    end
++  end
++end
+diff --git a/spec/commands/jump_to_spec.rb b/spec/commands/jump_to_spec.rb
+new file mode 100644
+index 0000000..d6958cf
+--- /dev/null
++++ b/spec/commands/jump_to_spec.rb
+@@ -0,0 +1,15 @@
++require_relative '../helper'
++
++describe "jump-to" do
++  it 'should jump to the proper binding index in the stack' do
++    pry_eval('cd 1', 'cd 2', 'jump-to 1', 'self').should == 1
++  end
++
++  it 'should print error when trying to jump to a non-existent binding index' do
++    pry_eval("cd 1", "cd 2", "jump-to 100").should =~ /Invalid nest level/
++  end
++
++  it 'should print error when trying to jump to the same binding index' do
++    pry_eval("cd 1", "cd 2", "jump-to 2").should =~ /Already/
++  end
++end
+diff --git a/spec/commands/ls_spec.rb b/spec/commands/ls_spec.rb
+new file mode 100644
+index 0000000..d03479c
+--- /dev/null
++++ b/spec/commands/ls_spec.rb
+@@ -0,0 +1,246 @@
++require_relative '../helper'
++
++describe "ls" do
++  describe "below ceiling" do
++    it "should stop before Object by default" do
++      pry_eval("cd Class.new{ def goo; end }.new", "ls").should.not =~ /Object/
++      pry_eval("cd Class.new{ def goo; end }", "ls -M").should.not =~ /Object/
++    end
++
++    it "should include object if -v is given" do
++      pry_eval("cd Class.new{ def goo; end }.new", "ls -m -v").should =~ /Object/
++      pry_eval("cd Class.new{ def goo; end }", "ls -vM").should =~ /Object/
++    end
++
++    it "should include super-classes by default" do
++      pry_eval(
++        "cd Class.new(Class.new{ def goo; end; public :goo }).new",
++        "ls").should =~ /goo/
++
++      pry_eval(
++        "cd Class.new(Class.new{ def goo; end; public :goo })",
++        "ls -M").should =~ /goo/
++    end
++
++    it "should not include super-classes when -q is given" do
++      pry_eval("cd Class.new(Class.new{ def goo; end }).new", "ls -q").should.not =~ /goo/
++      pry_eval("cd Class.new(Class.new{ def goo; end })", "ls -M -q").should.not =~ /goo/
++    end
++  end
++
++  describe "help" do
++    it 'should show help with -h' do
++      pry_eval("ls -h").should =~ /Usage: ls/
++    end
++  end
++
++  describe "BasicObject" do
++    it "should work on BasicObject" do
++      pry_eval("ls BasicObject.new").should =~ /BasicObject#methods:.*__send__/m
++    end
++
++    it "should work on subclasses of BasicObject" do
++      pry_eval(
++        "class LessBasic < BasicObject; def jaroussky; 5; end; end",
++        "ls LessBasic.new"
++      ).should =~ /LessBasic#methods:.*jaroussky/m
++    end
++  end
++
++  describe "immediates" do
++    it "should work on Fixnum" do
++      pry_eval("ls 5").should =~ /Fixnum#methods:.*modulo/m
++    end
++  end
++
++  describe "methods" do
++    it "should show public methods by default" do
++      output = pry_eval("ls Class.new{ def goo; end; public :goo }.new")
++      output.should =~ /methods: goo/
++    end
++
++    it "should not show protected/private by default" do
++      pry_eval("ls -M Class.new{ def goo; end; private :goo }").should.not =~ /goo/
++      pry_eval("ls Class.new{ def goo; end; protected :goo }.new").should.not =~ /goo/
++    end
++
++    it "should show public methods with -p" do
++      pry_eval("ls -p Class.new{ def goo; end }.new").should =~ /methods: goo/
++    end
++
++    it "should show protected/private methods with -p" do
++      pry_eval("ls -pM Class.new{ def goo; end; protected :goo }").should =~ /methods: goo/
++      pry_eval("ls -p Class.new{ def goo; end; private :goo }.new").should =~ /methods: goo/
++    end
++
++    it "should work for objects with an overridden method method" do
++      require 'net/http'
++      # This doesn't actually touch the network, promise!
++      pry_eval("ls Net::HTTP::Get.new('localhost')").should =~ /Net::HTTPGenericRequest#methods/
++    end
++
++    it "should work for objects which instance_variables returns array of symbol but there is no Symbol#downcase" do
++      test_case = "class Object; alias :fg :instance_variables; def instance_variables; fg.map(&:to_sym); end end;"
++      normalize = "class Object; def instance_variables; fg; end end;"
++
++      test = lambda do
++        begin
++          pry_eval(test_case, "class GeFromulate2; @flurb=1.3; end", "cd GeFromulate2", "ls")
++          pry_eval(normalize)
++        rescue
++          pry_eval(normalize)
++          raise
++        end
++      end
++
++      test.should.not.raise
++    end
++
++    it "should show error message when instance is given with -M option" do
++      error = lambda{ pry_eval("ls -M String.new") }.should.raise(Pry::CommandError)
++      error.message.should.match(/-M only makes sense with a Module or a Class/)
++    end
++
++
++    # see: https://travis-ci.org/pry/pry/jobs/5071918
++    unless Pry::Helpers::BaseHelpers.rbx?
++      it "should handle classes that (pathologically) define .ancestors" do
++        output = pry_eval("ls Class.new{ def self.ancestors; end; def hihi; end }")
++        output.should =~ /hihi/
++      end
++    end
++  end
++
++  describe 'with -l' do
++    it 'should find locals and sort by descending size' do
++      result = pry_eval("aa = 'asdf'; bb = 'xyz'", 'ls -l')
++      result.should.not =~ /=>/
++      result.should.not =~ /0x\d{5}/
++      result.should =~ /asdf.*xyz/m
++    end
++    it 'should not list pry noise' do
++      pry_eval('ls -l').should.not =~ /_(?:dir|file|ex|pry|out|in)_/
++    end
++  end
++
++  describe "when inside Modules" do
++    it "should still work" do
++      pry_eval(
++        "cd Module.new{ def foobie; end; public :foobie }",
++        "ls -M").should =~ /foobie/
++    end
++
++    it "should work for ivars" do
++      pry_eval(
++        "module StigmaT1sm; def foobie; @@gharble = 456; end; end",
++        "Object.new.tap{ |o| o.extend(StigmaT1sm) }.foobie",
++        "cd StigmaT1sm",
++        "ls -i").should =~ /@@gharble/
++    end
++
++    it "should include instance methods by default" do
++      output = pry_eval(
++        "ls Module.new{ def shinanagarns; 4; end; public :shinanagarns }")
++      output.should =~ /shinanagarns/
++    end
++
++    it "should behave normally when invoked on Module itself" do
++      pry_eval("ls Module").should.not =~ /Pry/
++    end
++  end
++
++  describe "constants" do
++    it "works on top-level" do
++      toplevel_consts = pry_eval('ls -c')
++      [/RUBY_PLATFORM/, /ARGF/, /STDOUT/].each do |const|
++        toplevel_consts.should =~ const
++      end
++    end
++
++    it "should show constants defined on the current module" do
++      pry_eval("class TempFoo1; BARGHL = 1; end", "ls TempFoo1").should =~ /BARGHL/
++    end
++
++    it "should not show constants defined on parent modules by default" do
++      pry_eval("class TempFoo2; LHGRAB = 1; end; class TempFoo3 < TempFoo2; BARGHL = 1; end", "ls TempFoo3").should.not =~ /LHGRAB/
++    end
++
++    it "should show constants defined on ancestors with -v" do
++      pry_eval("class TempFoo4; LHGRAB = 1; end; class TempFoo5 < TempFoo4; BARGHL = 1; end", "ls -v TempFoo5").should =~ /LHGRAB/
++    end
++
++    it "should not autoload constants!" do
++      autoload :McflurgleTheThird, "/tmp/this-file-d000esnat-exist.rb"
++      lambda{ pry_eval("ls -c") }.should.not.raise
++    end
++
++    it "should show constants for an object's class regardless of mixins" do
++      pry_eval(
++        "cd Pry.new",
++        "extend Module.new",
++        "ls -c"
++      ).should.match(/Method/)
++    end
++  end
++
++  describe "grep" do
++    it "should reduce the number of outputted things" do
++      pry_eval("ls -c Object").should =~ /ArgumentError/
++      pry_eval("ls -c Object --grep Run").should.not =~ /ArgumentError/
++    end
++
++    it "should still output matching things" do
++      pry_eval("ls -c Object --grep Run").should =~ /RuntimeError/
++    end
++  end
++
++  describe "when no arguments given" do
++    describe "when at the top-level" do
++      # rubinius has a bug that means local_variables of "main" aren't reported inside eval()
++      unless Pry::Helpers::BaseHelpers.rbx?
++        it "should show local variables" do
++          pry_eval("ls").should =~ /_pry_/
++          pry_eval("arbitrar = 1", "ls").should =~ /arbitrar/
++        end
++      end
++    end
++
++    describe "when in a class" do
++      it "should show constants" do
++        pry_eval("class GeFromulate1; FOOTIFICATE=1.3; end", "cd GeFromulate1", "ls").should =~ /FOOTIFICATE/
++      end
++
++      it "should show class variables" do
++        pry_eval("class GeFromulate2; @@flurb=1.3; end", "cd GeFromulate2", "ls").should =~ /@@flurb/
++      end
++
++      it "should show methods" do
++        pry_eval("class GeFromulate3; def self.mooflight; end ; end", "cd GeFromulate3", "ls").should =~ /mooflight/
++      end
++    end
++
++    describe "when in an object" do
++      it "should show methods" do
++        pry_eval("cd Class.new{ def self.fooerise; end; self }", "ls").should =~ /fooerise/
++      end
++
++      it "should show instance variables" do
++        pry_eval("cd Class.new", "@alphooent = 1", "ls").should =~ /@alphooent/
++      end
++    end
++  end
++
++  if Pry::Helpers::BaseHelpers.jruby?
++    describe 'on java objects' do
++      it 'should omit java-esque aliases by default' do
++        pry_eval('ls java.lang.Thread.current_thread').should =~ /\bthread_group\b/
++        pry_eval('ls java.lang.Thread.current_thread').should.not =~ /\bgetThreadGroup\b/
++      end
++
++      it 'should include java-esque aliases if requested' do
++        pry_eval('ls java.lang.Thread.current_thread -J').should =~ /\bthread_group\b/
++        pry_eval('ls java.lang.Thread.current_thread -J').should =~ /\bgetThreadGroup\b/
++      end
++    end
++  end
++end
+diff --git a/spec/commands/play_spec.rb b/spec/commands/play_spec.rb
+new file mode 100644
+index 0000000..ed75922
+--- /dev/null
++++ b/spec/commands/play_spec.rb
+@@ -0,0 +1,182 @@
++# This command needs a TONNE more tests for it, but i can't figure out
++# how to do them yet, and i really want to release. Sorry. Someone
++# come along and do a better job.
++
++require_relative '../helper'
++
++describe "play" do
++  before do
++    @o = Object.new
++    @t = pry_tester(@o)
++  end
++
++  describe "with an argument" do
++
++    # can't think of a f*cking way to test this!!
++    describe "implied file" do
++      # it 'should play from the file associated with the current binding' do
++      #   # require 'fixtures/play_helper'
++      # end
++
++
++      # describe "integer" do
++      #   it "should process one line from _pry_.last_file" do
++      #     @t.process_command 'play --lines 1', @eval_str
++      #     @eval_str.should =~ /bing = :bing\n/
++      #   end
++      # end
++
++      # describe "range" do
++      #   it "should process multiple lines at once from _pry_.last_file" do
++      #     @t.process_command 'play --lines 1..3', @eval_str
++      #     [/bing = :bing\n/, /bang = :bang\n/, /bong = :bong\n/].each { |str|
++      #       @eval_str.should =~ str
++      #     }
++      #   end
++    end
++  end
++
++  describe "playing a file" do
++    it 'should play a file' do
++      @t.process_command 'play spec/fixtures/whereami_helper.rb'
++      @t.eval_string.should == unindent(<<-STR)
++        class Cor
++          def a; end
++          def b; end
++          def c; end
++          def d; end
++        end
++      STR
++    end
++
++
++    it 'should output file contents with print option' do
++      @t.process_command 'play --print spec/fixtures/whereami_helper.rb'
++      @t.last_output.should == unindent(<<-STR)
++        1: class Cor
++        2:   def a; end
++        3:   def b; end
++        4:   def c; end
++        5:   def d; end
++        6: end
++      STR
++    end
++  end
++
++  describe "whatever" do
++    before do
++      def @o.test_method
++        :test_method_content
++      end
++    end
++
++    it 'should play documentation with the -d switch' do
++      # @v = 10
++      # @y = 20
++      def @o.test_method
++        :test_method_content
++      end
++
++      @t.process_command 'play -d test_method'
++      @t.eval_string.should == unindent(<<-STR)
++        @v = 10
++        @y = 20
++      STR
++    end
++
++    it 'should restrict -d switch with --lines' do
++      # @x = 0
++      # @v = 10
++      # @y = 20
++      # @z = 30
++      def @o.test_method
++        :test_method_content
++      end
++
++      @t.process_command 'play -d test_method --lines 2..3'
++      @t.eval_string.should == unindent(<<-STR)
++        @v = 10
++        @y = 20
++      STR
++    end
++
++    it 'has pretty error messages when -d cant find object' do
++      lambda { @t.process_command "play -d sdfsdf" }.should.raise(Pry::CommandError).message.should.match(/Cannot locate/)
++    end
++
++    it 'should play a method (a single line)' do
++      @t.process_command 'play test_method --lines 2'
++      @t.eval_string.should == ":test_method_content\n"
++    end
++
++    it 'should properly reindent lines' do
++      def @o.test_method
++        'hello world'
++      end
++
++      @t.process_command 'play test_method --lines 2'
++      @t.eval_string.should == "'hello world'\n"
++    end
++
++    it 'should APPEND to the input buffer when playing a method line, not replace it' do
++      @t.eval_string = unindent(<<-STR)
++        def another_test_method
++      STR
++
++      @t.process_command 'play test_method --lines 2'
++
++      @t.eval_string.should == unindent(<<-STR)
++        def another_test_method
++          :test_method_content
++      STR
++    end
++
++    it 'should play a method (multiple lines)' do
++      def @o.test_method
++        @var0 = 10
++        @var1 = 20
++        @var2 = 30
++        @var3 = 40
++      end
++
++      @t.process_command 'play test_method --lines 3..4'
++      @t.eval_string.should == unindent(<<-STR, 0)
++        @var1 = 20
++        @var2 = 30
++      STR
++    end
++
++    describe "play -i" do
++      it 'should play multi-ranged input expressions' do
++        a = b = c = d = e = 0
++        redirect_pry_io(InputTester.new('a += 1', 'b += 1',
++                                        'c += 1', 'd += 1', 'e += 1',
++                                        "play -i 1..3"), StringIO.new) do
++          binding.pry
++        end
++
++        [a, b, c].all? { |v| v.should == 2 }
++        d.should == 1
++      end
++    end
++
++    describe "play -e" do
++      it 'should run an expression from given line number' do
++        def @o.test_method
++          @s = [
++            1,2,3,
++            4,5,6
++          ]
++        end
++
++        @t.process_command 'play test_method -e 2'
++        @t.eval_string.should == unindent(<<-STR, 0)
++          @s = [
++            1,2,3,
++            4,5,6
++          ]
++        STR
++      end
++    end
++  end
++end
+diff --git a/spec/commands/raise_up_spec.rb b/spec/commands/raise_up_spec.rb
+new file mode 100644
+index 0000000..bc45164
+--- /dev/null
++++ b/spec/commands/raise_up_spec.rb
+@@ -0,0 +1,56 @@
++require_relative '../helper'
++
++describe "raise-up" do
++  before do
++    @self  = "Pad.self = self"
++    @inner = "Pad.inner = self"
++    @outer = "Pad.outer = self"
++  end
++
++  after do
++    Pad.clear
++  end
++
++  it "should raise the exception with raise-up" do
++    redirect_pry_io(InputTester.new("raise NoMethodError", "raise-up NoMethodError")) do
++      lambda { Object.new.pry }.should.raise NoMethodError
++    end
++  end
++
++  it "should raise an unamed exception with raise-up" do
++    redirect_pry_io(InputTester.new("raise 'stop'","raise-up 'noreally'")) do
++      lambda { Object.new.pry }.should.raise RuntimeError, "noreally"
++    end
++  end
++
++  it "should eat the exception at the last new pry instance on raise-up" do
++    redirect_pry_io(InputTester.new(":inner.pry", "raise NoMethodError", @inner,
++                                    "raise-up NoMethodError", @outer, "exit-all")) do
++      Pry.start(:outer)
++    end
++
++    Pad.inner.should == :inner
++    Pad.outer.should == :outer
++  end
++
++  it "should raise the most recently raised exception" do
++    lambda { mock_pry("raise NameError, 'homographery'","raise-up") }.should.raise NameError, 'homographery'
++  end
++
++  it "should allow you to cd up and (eventually) out" do
++    redirect_pry_io(InputTester.new("cd :inner", "raise NoMethodError", @inner,
++                                    "deep = :deep", "cd deep","Pad.deep = self",
++                                    "raise-up NoMethodError", "raise-up", @outer,
++                                    "raise-up", "exit-all")) do
++      lambda { Pry.start(:outer) }.should.raise NoMethodError
++    end
++
++    Pad.deep.should  == :deep
++    Pad.inner.should == :inner
++    Pad.outer.should == :outer
++  end
++
++  it "should jump immediately out of nested contexts with !" do
++    lambda { mock_pry("cd 1", "cd 2", "cd 3", "raise-up! 'fancy that...'") }.should.raise RuntimeError, 'fancy that...'
++  end
++end
+diff --git a/spec/commands/reload_code_spec.rb b/spec/commands/reload_code_spec.rb
+new file mode 100644
+index 0000000..f471e4b
+--- /dev/null
++++ b/spec/commands/reload_code_spec.rb
+@@ -0,0 +1,21 @@
++require_relative '../helper'
++
++describe "reload_code" do
++  describe "reload_current_file" do
++    it 'raises an error source code not found' do
++      proc do
++        eval <<-RUBY, TOPLEVEL_BINDING, 'does_not_exist.rb', 1
++          pry_eval(binding, "reload-code")
++        RUBY
++      end.should.raise(Pry::CommandError)
++    end
++
++    it 'raises an error when class not found' do
++      proc do
++        pry_eval(
++          "cd Class.new(Class.new{ def goo; end; public :goo })",
++          "reload-code")
++      end.should.raise(Pry::CommandError)
++    end
++  end
++end
+diff --git a/spec/commands/save_file_spec.rb b/spec/commands/save_file_spec.rb
+new file mode 100644
+index 0000000..5041e90
+--- /dev/null
++++ b/spec/commands/save_file_spec.rb
+@@ -0,0 +1,177 @@
++require_relative '../helper'
++
++describe "save-file" do
++  before do
++    @tf = Tempfile.new(["pry", ".py"])
++    @path = @tf.path
++    @t = pry_tester
++  end
++
++  after do
++    @tf.close(true)
++  end
++
++  describe "-f" do
++    it 'should save a file to a file' do
++      temp_file do |f|
++        path = f.path
++        f.puts ":cute_horse"
++        f.flush
++
++        @t.eval("save-file '#{path}' --to '#{@path}'")
++
++       
++        File.read(@path).should == File.read(path)
++      end
++    end
++  end
++
++  describe "-i" do
++    it 'should save input expressions to a file (single expression)' do
++      @t.eval ':horse_nostrils'
++      @t.eval "save-file -i 1 --to '#{@path}'"
++      File.read(@path).should == ":horse_nostrils\n"
++    end
++
++    it "should display a success message on save" do
++      @t.eval ':horse_nostrils'
++      @t.eval("save-file -i 1 --to '#{@path}'").should =~ /successfully saved/
++    end
++
++    it 'should save input expressions to a file (range)' do
++      @t.eval ':or_nostrils', ':sucking_up_all_the_oxygen', ':or_whatever'
++      @t.eval "save-file -i 1..2 --to '#{@path}'"
++      File.read(@path).should == ":or_nostrils\n:sucking_up_all_the_oxygen\n"
++    end
++
++    it 'should save multi-ranged input expressions' do
++      @t.eval ':or_nostrils', ':sucking_up_all_the_oxygen', ':or_whatever',
++      ':baby_ducks', ':cannot_escape'
++      @t.eval "save-file -i 1..2 -i 4..5 --to '#{@path}'"
++      File.read(@path).should == ":or_nostrils\n:sucking_up_all_the_oxygen\n:baby_ducks\n:cannot_escape\n"
++    end
++  end
++
++  describe "saving methods" do
++    before do
++      @o = Object.new
++      def @o.baby
++        :baby
++      end
++      def @o.bang
++        :bang
++      end
++
++      @t = pry_tester(@o)
++    end
++
++    describe "single method" do
++      it 'should save a method to a file' do
++        @t.eval "save-file --to '#{@path}' baby"
++        File.read(@path).should == Pry::Method.from_obj(@o, :baby).source
++      end
++
++      it "should display a success message on save" do
++        @t.eval("save-file --to '#{@path}' baby").should =~ /successfully saved/
++      end
++
++      it 'should save a method to a file truncated by --lines' do
++        @t.eval "save-file --to '#{@path}' baby --lines 2..4"
++
++        # must add 1 as first line of method is 1
++        File.read(@path).should ==
++          Pry::Method.from_obj(@o, :baby).source.lines.to_a[1..5].join
++      end
++    end
++
++    # TODO: do we want to reintroduce this spec??
++    #
++    # describe "multiple method" do
++    #   it 'should save multiple methods to a file' do
++    #     @t.eval "save-file #{@path} -m baby -m bang"
++
++    #     File.read(@path).should == Pry::Method.from_obj(@o, :baby).source +
++    #       Pry::Method.from_obj(@o, :bang).source
++    #   end
++
++    #   it 'should save multiple methods to a file trucated by --lines' do
++    #     @t.eval "save-file #{@path} -m baby -m bang --lines 2..-2"
++
++    #     # must add 1 as first line of method is 1
++    #     File.read(@path).should == (Pry::Method.from_obj(@o, :baby).source +
++    #       Pry::Method.from_obj(@o, :bang).source).lines.to_a[1..-2].join
++    #   end
++
++    #   it 'should save multiple methods to a file trucated by --lines 1 ' \
++    #      '(single parameter, not range)' do
++    #     @t.eval "save-file #{@path} -m baby -m bang --lines 1"
++
++    #     # must add 1 as first line of method is 1
++    #     File.read(@path).should == (Pry::Method.from_obj(@o, :baby).source +
++    #       Pry::Method.from_obj(@o, :bang).source).lines.to_a[0]
++    #   end
++    # end
++  end
++
++  describe "overwrite by default (no --append)" do
++    it 'should overwrite specified file with new input' do
++      @t.eval ':horse_nostrils'
++      @t.eval "save-file -i 1 --to '#{@path}'"
++
++      @t.eval ':sucking_up_all_the_oxygen'
++      @t.eval "save-file -i 2 --to '#{@path}'"
++
++      File.read(@path).should == ":sucking_up_all_the_oxygen\n"
++    end
++  end
++
++  describe "--append" do
++    it 'should append to end of specified file' do
++      @t.eval ':horse_nostrils'
++      @t.eval "save-file -i 1 --to '#{@path}'"
++
++      @t.eval ':sucking_up_all_the_oxygen'
++      @t.eval "save-file -i 2 --to '#{@path}' -a"
++
++      File.read(@path).should ==
++        ":horse_nostrils\n:sucking_up_all_the_oxygen\n"
++    end
++  end
++
++  describe "saving commands" do
++    it 'should save a command to a file' do
++      @t.eval "save-file --to '#{@path}' show-source"
++      cmd_source = Pry.config.commands["show-source"].source
++      File.read(@path).should == cmd_source
++    end
++  end
++
++  # TODO: reintroduce these specs at some point?
++  #
++  # describe "combined options" do
++  #   before do
++  #     @o = Object.new
++  #     def @o.baby
++  #       :baby
++  #     end
++
++  #     @t = pry_tester(@o)
++  #   end
++
++  #   it 'should save input cache and a method to a file (in that order)' do
++  #     @t.eval ":horse_nostrils"
++  #     @t.eval "save-file -i 1 -m baby #{@path}"
++
++  #     File.read(@path).should == ":horse_nostrils\n" +
++  #       Pry::Method.from_obj(@o, :baby).source
++  #   end
++
++  #   it 'should select a portion to save using --lines' do
++  #     @t.eval ":horse_nostrils"
++  #     @t.eval "save-file -i 1 -m baby #{@path} --lines 2..-2"
++
++  #     str = ":horse_nostrils\n" + Pry::Method.from_obj(@o, :baby).source
++  #     File.read(@path).should == str.lines.to_a[1..-2].join
++  #   end
++  # end
++end
+diff --git a/spec/commands/shell_command_spec.rb b/spec/commands/shell_command_spec.rb
+new file mode 100644
+index 0000000..422fc3e
+--- /dev/null
++++ b/spec/commands/shell_command_spec.rb
+@@ -0,0 +1,63 @@
++require_relative '../helper'
++
++describe "Command::ShellCommand" do
++  describe 'cd' do
++    before do
++      @o = Object.new
++
++      @t = pry_tester(@o) do
++        def command_state
++          pry.command_state[Pry::Command::ShellCommand.match]
++        end
++      end
++    end
++
++    describe ".cd" do
++      before do
++        Dir.stubs(:chdir)
++      end
++
++      it "saves the current working directory" do
++        Dir.stubs(:pwd).returns("initial_path")
++
++        @t.eval ".cd new_path"
++        @t.command_state.old_pwd.should == "initial_path"
++      end
++
++      describe "given a path" do
++        it "sends the path to File.expand_path" do
++          Dir.expects(:chdir).with(File.expand_path("new_path"))
++          @t.eval ".cd new_path"
++        end
++      end
++
++      describe "given an empty string" do
++        it "sends ~ to File.expand_path" do
++          Dir.expects(:chdir).with(File.expand_path("~"))
++          @t.eval ".cd "
++        end
++      end
++
++      describe "given a dash" do
++        describe "given no prior directory" do
++          it "raises the correct error" do
++            lambda { @t.eval ".cd -" }.should.raise(StandardError).
++              message.should == "No prior directory available"
++          end
++        end
++
++        describe "given a prior directory" do
++          it "sends the user's last pry working directory to File.expand_path" do
++            Dir.stubs(:pwd).returns("initial_path")
++
++            Dir.expects(:chdir).with(File.expand_path("new_path"))
++            @t.eval ".cd new_path"
++
++            Dir.expects(:chdir).with(File.expand_path("initial_path"))
++            @t.eval ".cd -"
++          end
++        end
++      end
++    end
++  end
++end
+diff --git a/spec/commands/show_doc_spec.rb b/spec/commands/show_doc_spec.rb
+new file mode 100644
+index 0000000..6d347b3
+--- /dev/null
++++ b/spec/commands/show_doc_spec.rb
+@@ -0,0 +1,573 @@
++require_relative '../helper'
++require "fixtures/show_source_doc_examples"
++
++describe "show-doc" do
++  before do
++    @o = Object.new
++
++    # sample doc
++    def @o.sample_method
++      :sample
++    end
++
++    def @o.no_docs;end
++
++  end
++
++  it 'should output a method\'s documentation' do
++    pry_eval(binding, "show-doc @o.sample_method").should =~ /sample doc/
++  end
++
++  it 'should raise exception when cannot find docs' do
++    lambda { pry_eval(binding, "show-doc @o.no_docs") }.should.raise(Pry::CommandError)
++  end
++
++  it 'should output a method\'s documentation with line numbers' do
++    pry_eval(binding, "show-doc @o.sample_method -l").should =~ /\d: sample doc/
++  end
++
++  it 'should output a method\'s documentation with line numbers (base one)' do
++    pry_eval(binding, "show-doc @o.sample_method -b").should =~ /1: sample doc/
++  end
++
++  it 'should output a method\'s documentation if inside method without needing to use method name' do
++    # sample comment
++    def @o.sample
++      pry_eval(binding, 'show-doc').should =~ /sample comment/
++    end
++    @o.sample
++  end
++
++  describe "finding find super method docs with help of `--super` switch" do
++    before do
++      class Daddy
++        # daddy initialize!
++        def initialize(*args); end
++      end
++
++      class Classy < Daddy
++        # classy initialize!
++        def initialize(*args); end
++      end
++
++      class Grungy < Classy
++        # grungy initialize??
++        def initialize(*args); end
++      end
++
++      @o = Grungy.new
++
++      # instancey initialize!
++      def @o.initialize; end
++    end
++
++    after do
++      Object.remove_const(:Grungy)
++      Object.remove_const(:Classy)
++      Object.remove_const(:Daddy)
++    end
++
++    it "finds super method docs" do
++      output = pry_eval(binding, 'show-doc --super @o.initialize')
++      output.should =~ /grungy initialize/
++    end
++
++    it "traverses ancestor chain and finds super method docs" do
++      output = pry_eval(binding, 'show-doc -ss @o.initialize')
++      output.should =~ /classy initialize/
++    end
++
++    it "traverses ancestor chain even higher and finds super method doc" do
++      output = pry_eval(binding, 'show-doc @o.initialize -sss')
++      output.should =~ /daddy initialize/
++    end
++
++    it "finds super method docs without explicit method argument" do
++      fatty = Grungy.new
++
++      # fatty initialize!
++      def fatty.initialize
++        pry_eval(binding, 'show-doc --super')
++      end
++
++      output = fatty.initialize
++      output.should =~ /grungy initialize/
++    end
++
++    it "finds super method docs without `--super` but with the `super` keyword" do
++      fatty = Grungy.new
++
++      fatty.extend Module.new {
++        def initialize
++          :nibble
++        end
++      }
++
++      # fatty initialize!
++      def fatty.initialize
++        pry_eval(binding, 'show-doc --super --super')
++      end
++
++      output = fatty.initialize
++      output.should =~ /grungy initialize/
++    end
++  end
++
++  describe "rdoc highlighting" do
++    it "should syntax highlight code in rdoc" do
++      c = Class.new{
++        # This can initialize your class:
++        #
++        #   a = c.new :foo
++        #
++        # @param foo
++        def initialize(foo); end
++      }
++
++      begin
++        t = pry_tester(binding)
++        t.eval("show-doc c#initialize").should =~ /c.new :foo/
++        Pry.config.color = true
++        # I don't want the test to rely on which colour codes are there, just to
++        # assert that "something" is being colourized.
++        t.eval("show-doc c#initialize").should.not =~ /c.new :foo/
++      ensure
++        Pry.config.color = false
++      end
++    end
++
++    it "should syntax highlight `code` in rdoc" do
++      c = Class.new{
++        # After initializing your class with `c.new(:foo)`, go have fun!
++        #
++        # @param foo
++        def initialize(foo); end
++      }
++
++      begin
++        t = pry_tester(binding)
++        t.eval("show-doc c#initialize").should =~ /c.new\(:foo\)/
++        Pry.config.color = true
++        # I don't want the test to rely on which colour codes are there, just to
++        # assert that "something" is being colourized.
++        t.eval("show-doc c#initialize").should.not =~ /c.new\(:foo\)/
++      ensure
++        Pry.config.color = false
++      end
++
++    end
++
++    it "should not syntax highlight `` inside code" do
++      c = Class.new{
++        # Convert aligned output (from many shell commands) into nested arrays:
++        #
++        #   a = decolumnize `ls -l $HOME`
++        #
++        # @param output
++        def decolumnize(output); end
++      }
++
++      begin
++        t = pry_tester(binding)
++        Pry.config.color = true
++        t.eval("show-doc c#decolumnize").should =~ /ls -l \$HOME/
++        t.eval("show-doc c#decolumnize").should.not =~ /`ls -l \$HOME`/
++      ensure
++        Pry.config.color = false
++      end
++    end
++  end
++
++  describe "on sourcable objects" do
++    it "should show documentation for object" do
++      # this is a documentation
++      hello = proc { puts 'hello world!' }
++      mock_pry(binding, "show-doc hello").should =~ /this is a documentation/
++    end
++  end
++
++  describe "on modules" do
++    before do
++      # god this is boring1
++      class ShowSourceTestClass
++        def alpha
++        end
++      end
++
++      # god this is boring2
++      module ShowSourceTestModule
++        def alpha
++        end
++      end
++
++      # god this is boring3
++      ShowSourceTestClassWeirdSyntax = Class.new do
++        def beta
++        end
++      end
++
++      # god this is boring4
++      ShowSourceTestModuleWeirdSyntax = Module.new do
++        def beta
++        end
++      end
++    end
++
++    after do
++      Object.remove_const :ShowSourceTestClass
++      Object.remove_const :ShowSourceTestClassWeirdSyntax
++      Object.remove_const :ShowSourceTestModule
++      Object.remove_const :ShowSourceTestModuleWeirdSyntax
++    end
++
++    describe "basic functionality, should show docs for top-level module definitions" do
++      it 'should show docs for a class' do
++        pry_eval("show-doc ShowSourceTestClass").should =~
++          /god this is boring1/
++      end
++
++      it 'should show docs for a module' do
++        pry_eval("show-doc ShowSourceTestModule").should =~
++          /god this is boring2/
++      end
++
++      it 'should show docs for a class when Const = Class.new syntax is used' do
++        pry_eval("show-doc ShowSourceTestClassWeirdSyntax").should =~
++          /god this is boring3/
++      end
++
++      it 'should show docs for a module when Const = Module.new syntax is used' do
++        pry_eval("show-doc ShowSourceTestModuleWeirdSyntax").should =~
++          /god this is boring4/
++      end
++    end
++
++    describe "in REPL" do
++      it 'should find class defined in repl' do
++        t = pry_tester
++        t.eval <<-RUBY
++          # hello tobina
++          class TobinaMyDog
++            def woof
++            end
++          end
++        RUBY
++        t.eval('show-doc TobinaMyDog').should =~ /hello tobina/
++        Object.remove_const :TobinaMyDog
++      end
++    end
++
++    it 'should lookup module name with respect to current context' do
++      constant_scope(:AlphaClass, :BetaClass) do
++        # top-level beta
++        class BetaClass
++          def alpha
++          end
++        end
++
++        class AlphaClass
++          # nested beta
++          class BetaClass
++            def beta
++            end
++          end
++        end
++
++        pry_eval(AlphaClass, "show-doc BetaClass").should =~ /nested beta/
++      end
++    end
++
++    it 'should look up nested modules' do
++      constant_scope(:AlphaClass) do
++        class AlphaClass
++          # nested beta
++          class BetaClass
++            def beta
++            end
++          end
++        end
++
++        pry_eval("show-doc AlphaClass::BetaClass").should =~
++          /nested beta/
++      end
++    end
++
++    describe "show-doc -a" do
++      it 'should show the docs for all monkeypatches defined in different files' do
++        # local monkeypatch
++        class TestClassForShowSource
++          def beta
++          end
++        end
++
++        result = pry_eval("show-doc TestClassForShowSource -a")
++        result.should =~ /used by/
++        result.should =~ /local monkeypatch/
++      end
++
++      describe "messages relating to -a" do
++        it "displays the original definition by default (not a doc of a monkeypatch)" do
++          class TestClassForCandidatesOrder
++            def beta
++            end
++          end
++
++          result = pry_eval("show-doc TestClassForCandidatesOrder")
++          result.should =~ /Number of monkeypatches: 2/
++          result.should =~ /The first definition/
++        end
++
++        it 'indicates all available monkeypatches can be shown with -a ' \
++          '(when -a not used and more than one candidate exists for class)' do
++          # Still reading boring tests, eh?
++          class TestClassForShowSource
++            def beta
++            end
++          end
++
++          result = pry_eval('show-doc TestClassForShowSource')
++          result.should =~ /available monkeypatches/
++        end
++
++        it 'shouldnt say anything about monkeypatches when only one candidate exists for selected class' do
++          # Do not remove me.
++          class Aarrrrrghh
++            def o;end
++          end
++
++          result = pry_eval('show-doc Aarrrrrghh')
++          result.should.not =~ /available monkeypatches/
++          Object.remove_const(:Aarrrrrghh)
++        end
++      end
++    end
++
++    describe "when no class/module arg is given" do
++      before do
++        module TestHost
++
++          # hello there froggy
++          module M
++            def d; end
++            def e; end
++          end
++        end
++      end
++
++      after do
++        Object.remove_const(:TestHost)
++      end
++
++      it 'should return doc for current module' do
++        pry_eval(TestHost::M, "show-doc").should =~ /hello there froggy/
++      end
++    end
++
++    # FIXME: THis is nto a good spec anyway, because i dont think it
++    # SHOULD skip!
++    describe "should skip over broken modules" do
++      before do
++        module TestHost
++          # hello
++          module M
++            binding.eval("def a; end", "dummy.rb", 1)
++            binding.eval("def b; end", "dummy.rb", 2)
++            binding.eval("def c; end", "dummy.rb", 3)
++          end
++
++          # goodbye
++          module M
++            def d; end
++            def e; end
++          end
++        end
++      end
++
++      after do
++        Object.remove_const(:TestHost)
++      end
++
++      it 'should return doc for first valid module' do
++        result = pry_eval("show-doc TestHost::M")
++        result.should =~ /goodbye/
++        result.should.not =~ /hello/
++      end
++    end
++  end
++
++  describe "on commands" do
++    # mostly copied & modified from test_help.rb
++    before do
++      @oldset = Pry.config.commands
++      @set = Pry.config.commands = Pry::CommandSet.new do
++        import Pry::Commands
++      end
++    end
++
++    after do
++      Pry.config.commands = @oldset
++    end
++
++    it 'should display help for a specific command' do
++      pry_eval('show-doc ls').should =~ /Usage: ls/
++    end
++
++    it 'should display help for a regex command with a "listing"' do
++      @set.command /bar(.*)/, "Test listing", :listing => "foo" do; end
++      pry_eval('show-doc foo').should =~ /Test listing/
++    end
++
++    it 'should display help for a command with a spaces in its name' do
++      @set.command "command with spaces", "description of a command with spaces" do; end
++      pry_eval('show-doc command with spaces').should =~ /description of a command with spaces/
++    end
++
++    describe "class commands" do
++      before do
++        # pretty pink pincers
++        class LobsterLady < Pry::ClassCommand
++          match "lobster-lady"
++          description "nada."
++          def process
++            "lobster"
++          end
++        end
++
++        Pry.config.commands.add_command(LobsterLady)
++      end
++
++      after do
++        Object.remove_const(:LobsterLady)
++      end
++
++      it 'should display "help" when looking up by command name' do
++        pry_eval('show-doc lobster-lady').should =~ /nada/
++        Pry.config.commands.delete("lobster-lady")
++      end
++
++      it 'should display actual preceding comment for a class command, when class is used (rather than command name) when looking up' do
++        pry_eval('show-doc LobsterLady').should =~ /pretty pink pincers/
++        Pry.config.commands.delete("lobster-lady")
++      end
++    end
++  end
++
++  describe "should set _file_ and _dir_" do
++    it 'should set _file_ and _dir_ to file containing method source' do
++      t = pry_tester
++      t.process_command "show-doc TestClassForShowSource#alpha"
++      t.pry.last_file.should =~ /show_source_doc_examples/
++      t.pry.last_dir.should =~ /fixtures/
++    end
++  end
++
++  unless Pry::Helpers::BaseHelpers.rbx?
++    describe "can't find class docs" do
++      describe "for classes" do
++        before do
++          module Jesus
++            class Brian; end
++
++            # doink-doc
++            class Jingle
++              def a; :doink; end
++            end
++
++            class Jangle < Jingle; end
++            class Bangle < Jangle; end
++          end
++        end
++
++        after do
++          Object.remove_const(:Jesus)
++        end
++
++        it 'shows superclass doc' do
++          t = pry_tester
++          t.process_command "show-doc Jesus::Jangle"
++          t.last_output.should =~ /doink-doc/
++        end
++
++        it 'errors when class has no superclass to show' do
++          t = pry_tester
++          lambda { t.process_command "show-doc Jesus::Brian" }.should.raise(Pry::CommandError).message.
++            should =~ /Couldn't locate/
++        end
++
++        it 'shows warning when reverting to superclass docs' do
++          t = pry_tester
++          t.process_command "show-doc Jesus::Jangle"
++          t.last_output.should =~ /Warning.*?Cannot find.*?Jesus::Jangle.*Showing.*Jesus::Jingle instead/
++        end
++
++        it 'shows nth level superclass docs (when no intermediary superclasses have code either)' do
++          t = pry_tester
++          t.process_command "show-doc Jesus::Bangle"
++          t.last_output.should =~ /doink-doc/
++        end
++
++        it 'shows correct warning when reverting to nth level superclass' do
++          t = pry_tester
++          t.process_command "show-doc Jesus::Bangle"
++          t.last_output.should =~ /Warning.*?Cannot find.*?Jesus::Bangle.*Showing.*Jesus::Jingle instead/
++        end
++      end
++
++      describe "for modules" do
++        before do
++          module Jesus
++
++            # alpha-doc
++            module Alpha
++              def alpha; :alpha; end
++            end
++
++            module Zeta; end
++
++            module Beta
++              include Alpha
++            end
++
++            module Gamma
++              include Beta
++            end
++          end
++        end
++
++        after do
++          Object.remove_const(:Jesus)
++        end
++
++        it 'shows included module doc' do
++          t = pry_tester
++          t.process_command "show-doc Jesus::Beta"
++          t.last_output.should =~ /alpha-doc/
++        end
++
++        it 'shows warning when reverting to included module doc' do
++          t = pry_tester
++          t.process_command "show-doc Jesus::Beta"
++          t.last_output.should =~ /Warning.*?Cannot find.*?Jesus::Beta.*Showing.*Jesus::Alpha instead/
++        end
++
++        it 'errors when module has no included module to show' do
++          t = pry_tester
++          lambda { t.process_command "show-source Jesus::Zeta" }.should.raise(Pry::CommandError).message.
++            should =~ /Couldn't locate/
++        end
++
++        it 'shows nth level included module doc (when no intermediary modules have code either)' do
++          t = pry_tester
++          t.process_command "show-doc Jesus::Gamma"
++          t.last_output.should =~ /alpha-doc/
++        end
++
++        it 'shows correct warning when reverting to nth level included module' do
++          t = pry_tester
++          t.process_command "show-source Jesus::Gamma"
++          t.last_output.should =~ /Warning.*?Cannot find.*?Jesus::Gamma.*Showing.*Jesus::Alpha instead/
++        end
++      end
++    end
++  end
++end
+diff --git a/spec/commands/show_input_spec.rb b/spec/commands/show_input_spec.rb
+new file mode 100644
+index 0000000..6b2856b
+--- /dev/null
++++ b/spec/commands/show_input_spec.rb
+@@ -0,0 +1,17 @@
++require_relative '../helper'
++
++describe "show-input" do
++  before do
++    @t = pry_tester
++  end
++
++  it 'should correctly show the current lines in the input buffer' do
++    @t.push *unindent(<<-STR).split("\n")
++      def hello
++        puts :bing
++    STR
++
++    @t.process_command 'show-input'
++    @t.last_output.should =~ /\A\d+: def hello\n\d+:   puts :bing/
++  end
++end
+diff --git a/spec/commands/show_source_spec.rb b/spec/commands/show_source_spec.rb
+new file mode 100644
+index 0000000..d624555
+--- /dev/null
++++ b/spec/commands/show_source_spec.rb
+@@ -0,0 +1,829 @@
++require_relative '../helper'
++require "fixtures/show_source_doc_examples"
++
++describe "show-source" do
++  before do
++    @o = Object.new
++    def @o.sample_method
++      :sample
++    end
++
++    Object.const_set(:Test, Module.new)
++  end
++
++  after do
++    Pad.clear
++  end
++
++  it "should output a method's source" do
++    pry_eval(binding, 'show-source @o.sample_method').should =~ /def @o.sample/
++  end
++
++  it "should output help" do
++    pry_eval('show-source -h').should =~ /Usage:\s+show-source/
++  end
++
++  it "should output a method's source with line numbers" do
++    pry_eval(binding, 'show-source -l @o.sample_method').should =~ /\d+: def @o.sample/
++  end
++
++  it "should output a method's source with line numbers starting at 1" do
++    pry_eval(binding, 'show-source -b @o.sample_method').should =~ /1: def @o.sample/
++  end
++
++  it "should output a method's source if inside method and no name given" do
++    def @o.sample
++      pry_eval(binding, 'show-source').should =~ /def @o.sample/
++    end
++    @o.sample
++  end
++
++  it "should output a method's source inside method using the -l switch" do
++    def @o.sample
++      pry_eval(binding, 'show-source -l').should =~ /def @o.sample/
++    end
++    @o.sample
++  end
++
++  it "should find methods even if there are spaces in the arguments" do
++    def @o.foo(*bars)
++      "Mr flibble"
++      self
++    end
++
++    out = pry_eval(binding, "show-source @o.foo('bar', 'baz bam').foo")
++    out.should =~ /Mr flibble/
++  end
++
++  it "should find methods even if the object overrides method method" do
++    c = Class.new{
++      def method;
++        98
++      end
++    }
++
++    pry_eval(binding, "show-source c.new.method").should =~ /98/
++  end
++
++  it "should not show the source when a non-extant method is requested" do
++    c = Class.new{ def method; 98; end }
++    mock_pry(binding, "show-source c#wrongmethod").should =~ /Couldn't locate/
++  end
++
++  it "should find instance_methods if the class overrides instance_method" do
++    c = Class.new{
++      def method;
++        98
++      end
++
++      def self.instance_method; 789; end
++    }
++
++    pry_eval(binding, "show-source c#method").should =~ /98/
++  end
++
++  it "should find instance methods with self#moo" do
++    c = Class.new{ def moo; "ve over!"; end }
++
++    pry_eval(binding, "cd c", "show-source self#moo").should =~ /ve over/
++  end
++
++  it "should not find instance methods with self.moo" do
++    c = Class.new{ def moo; "ve over!"; end }
++
++    proc {
++      pry_eval(binding, 'cd c', 'show-source self.moo')
++    }.should.raise(Pry::CommandError).message.should =~ /Couldn't locate/
++  end
++
++  it "should find normal methods with self.moo" do
++    c = Class.new{ def self.moo; "ve over!"; end }
++
++    pry_eval(binding, 'cd c', 'show-source self.moo').should =~ /ve over/
++  end
++
++  it "should not find normal methods with self#moo" do
++    c = Class.new{ def self.moo; "ve over!"; end }
++
++    proc {
++      pry_eval(binding, 'cd c', 'show-source self#moo')
++    }.should.raise(Pry::CommandError).message.should =~ /Couldn't locate/
++  end
++
++  it "should find normal methods (i.e non-instance methods) by default" do
++    c = Class.new{ def self.moo; "ve over!"; end }
++
++    pry_eval(binding, "cd c", "show-source moo").should =~ /ve over/
++  end
++
++  it "should find instance methods if no normal methods available" do
++    c = Class.new{ def moo; "ve over!"; end }
++
++    pry_eval(binding, "cd c", "show-source moo").should =~ /ve over/
++  end
++
++  describe "with -e option" do
++    before do
++      class FooBar
++        def bar
++          :bar
++        end
++      end
++    end
++
++    after do
++      Object.remove_const(:FooBar)
++    end
++
++    it "evaluates the argument as ruby and shows the source code for the returned value" do
++      ReplTester.start target: binding do
++        input 'show-source -e FooBar.new'
++        output /class FooBar/
++      end
++    end
++  end
++
++  it "should raise a CommandError when super method doesn't exist" do
++    def @o.foo(*bars); end
++
++    proc {
++      pry_eval(binding, "show-source --super @o.foo")
++    }.should.raise(Pry::CommandError).message.should =~ /No superclass found/
++  end
++
++  it "should output the source of a method defined inside Pry" do
++    out = pry_eval("def dyn_method\n:test\nend", 'show-source dyn_method')
++    out.should =~ /def dyn_method/
++    Object.remove_method :dyn_method
++  end
++
++  it 'should output source for an instance method defined inside pry' do
++    pry_tester.tap do |t|
++      t.eval "class Test::A\n  def yo\n  end\nend"
++      t.eval('show-source Test::A#yo').should =~ /def yo/
++    end
++  end
++
++  it 'should output source for a repl method defined using define_method' do
++    pry_tester.tap do |t|
++      t.eval "class Test::A\n  define_method(:yup) {}\nend"
++      t.eval('show-source Test::A#yup').should =~ /define_method\(:yup\)/
++    end
++  end
++
++  it "should output the source of a command defined inside Pry" do
++    command_definition = %{
++      Pry.config.commands.command "hubba-hubba" do
++        puts "that's what she said!"
++      end
++    }
++    out = pry_eval(command_definition, 'show-source hubba-hubba')
++    out.should =~ /what she said/
++    Pry.config.commands.delete "hubba-hubba"
++  end
++
++  describe "finding super methods with help of `--super` switch" do
++    before do
++      class Foo
++        def foo(*bars)
++          :super_wibble
++        end
++      end
++    end
++
++    after do
++      Object.remove_const(:Foo)
++    end
++
++    it "finds super methods with explicit method argument" do
++
++      o = Foo.new
++      def o.foo(*bars)
++        :wibble
++      end
++
++      pry_eval(binding, "show-source --super o.foo").should =~ /:super_wibble/
++    end
++
++    it "finds super methods without explicit method argument" do
++      o = Foo.new
++      def o.foo(*bars)
++        :wibble
++        pry_eval(binding, 'show-source --super')
++      end
++
++      o.foo.should =~ /:super_wibble/
++    end
++
++    it "finds super methods with multiple --super " do
++      o = Foo.new
++
++      o.extend Module.new {
++        def foo
++          :nibble
++        end
++      }
++
++      def o.foo(*bars)
++        :wibble
++        pry_eval(binding, 'show-source --super --super')
++      end
++
++      o.foo.should =~ /:super_wibble/
++    end
++  end
++
++  describe "on sourcable objects" do
++    it "should output source defined inside pry" do
++      pry_tester.tap do |t|
++        t.eval "hello = proc { puts 'hello world!' }"
++        t.eval("show-source hello").should =~ /proc \{ puts/
++      end
++    end
++
++    it "should output source for procs/lambdas stored in variables" do
++      hello = proc { puts 'hello world!' }
++      pry_eval(binding, 'show-source hello').should =~ /proc \{ puts/
++    end
++
++    it "should output source for procs/lambdas stored in constants" do
++      HELLO = proc { puts 'hello world!' }
++      pry_eval(binding, "show-source HELLO").should =~ /proc \{ puts/
++      Object.remove_const(:HELLO)
++    end
++
++    it "should output source for method objects" do
++      def @o.hi; puts 'hi world'; end
++      meth = @o.method(:hi)
++      pry_eval(binding, "show-source meth").should =~ /puts 'hi world'/
++    end
++
++    describe "on variables that shadow methods" do
++      before do
++        @t = pry_tester.eval unindent(<<-EOS)
++          class ::TestHost
++            def hello
++              hello = proc { ' smile ' }
++              pry_tester(binding)
++            end
++          end
++          ::TestHost.new.hello
++          EOS
++        end
++
++        after do
++          Object.remove_const(:TestHost)
++        end
++
++        it "source of variable should take precedence over method that is being shadowed" do
++          source = @t.eval('show-source hello')
++          source.should.not =~ /def hello/
++          source.should =~ /proc \{ ' smile ' \}/
++        end
++
++        it "source of method being shadowed should take precedence over variable
++          if given self.meth_name syntax" do
++          @t.eval('show-source self.hello').should =~ /def hello/
++        end
++      end
++    end
++
++    describe "on variable or constant" do
++      before do
++        class TestHost
++          def hello
++            "hi there"
++          end
++        end
++      end
++
++      after do
++        Object.remove_const(:TestHost)
++      end
++
++      it "should output source of its class if variable doesn't respond to source_location" do
++        test_host = TestHost.new
++        pry_eval(binding, 'show-source test_host').
++          should =~ /class TestHost\n.*def hello/
++      end
++
++      it "should output source of its class if constant doesn't respond to source_location" do
++        TEST_HOST = TestHost.new
++        pry_eval(binding, 'show-source TEST_HOST').
++          should =~ /class TestHost\n.*def hello/
++        Object.remove_const(:TEST_HOST)
++      end
++    end
++
++    describe "on modules" do
++      before do
++        class ShowSourceTestSuperClass
++          def alpha
++          end
++        end
++
++        class ShowSourceTestClass<ShowSourceTestSuperClass
++          def alpha
++          end
++        end
++
++        module ShowSourceTestSuperModule
++          def alpha
++          end
++        end
++
++        module ShowSourceTestModule
++          include ShowSourceTestSuperModule
++          def alpha
++          end
++        end
++
++        ShowSourceTestClassWeirdSyntax = Class.new do
++          def beta
++          end
++        end
++
++        ShowSourceTestModuleWeirdSyntax = Module.new do
++          def beta
++          end
++        end
++      end
++
++      after do
++        Object.remove_const :ShowSourceTestSuperClass
++        Object.remove_const :ShowSourceTestClass
++        Object.remove_const :ShowSourceTestClassWeirdSyntax
++        Object.remove_const :ShowSourceTestSuperModule
++        Object.remove_const :ShowSourceTestModule
++        Object.remove_const :ShowSourceTestModuleWeirdSyntax
++      end
++
++      describe "basic functionality, should find top-level module definitions" do
++        it 'should show source for a class' do
++          pry_eval('show-source ShowSourceTestClass').
++            should =~ /class ShowSourceTestClass.*?def alpha/m
++        end
++
++        it 'should show source for a super class' do
++          pry_eval('show-source -s ShowSourceTestClass').
++            should =~ /class ShowSourceTestSuperClass.*?def alpha/m
++        end
++
++        it 'should show source for a module' do
++          pry_eval('show-source ShowSourceTestModule').
++            should =~ /module ShowSourceTestModule/
++        end
++
++        it 'should show source for an ancestor module' do
++          pry_eval('show-source -s ShowSourceTestModule').
++            should =~ /module ShowSourceTestSuperModule/
++        end
++
++        it 'should show source for a class when Const = Class.new syntax is used' do
++          pry_eval('show-source ShowSourceTestClassWeirdSyntax').
++            should =~ /ShowSourceTestClassWeirdSyntax = Class.new/
++        end
++
++        it 'should show source for a super class when Const = Class.new syntax is used' do
++          pry_eval('show-source -s ShowSourceTestClassWeirdSyntax').
++            should =~ /class Object/
++        end
++
++        it 'should show source for a module when Const = Module.new syntax is used' do
++          pry_eval('show-source ShowSourceTestModuleWeirdSyntax').
++            should =~ /ShowSourceTestModuleWeirdSyntax = Module.new/
++        end
++      end
++
++      before do
++        pry_eval unindent(<<-EOS)
++        class Dog
++          def woof
++          end
++        end
++
++        class TobinaMyDog < Dog
++          def woof
++          end
++        end
++        EOS
++      end
++
++      after do
++        Object.remove_const :Dog
++        Object.remove_const :TobinaMyDog
++      end
++
++      describe "in REPL" do
++        it 'should find class defined in repl' do
++          pry_eval('show-source TobinaMyDog').should =~ /class TobinaMyDog/
++        end
++
++        it 'should find superclass defined in repl' do
++          pry_eval('show-source -s TobinaMyDog').should =~ /class Dog/
++        end
++      end
++
++      it 'should lookup module name with respect to current context' do
++
++        constant_scope(:AlphaClass, :BetaClass) do
++          class BetaClass
++            def alpha
++            end
++          end
++
++          class AlphaClass
++            class BetaClass
++              def beta
++              end
++            end
++          end
++
++          pry_eval(AlphaClass, 'show-source BetaClass').should =~ /def beta/
++        end
++      end
++
++      it 'should lookup nested modules' do
++        constant_scope(:AlphaClass) do
++          class AlphaClass
++            class BetaClass
++              def beta
++              end
++            end
++          end
++
++          pry_eval('show-source AlphaClass::BetaClass').should =~ /class Beta/
++        end
++      end
++
++      # note that pry assumes a class is only monkey-patched at most
++      # ONCE per file, so will not find multiple monkeypatches in the
++      # SAME file.
++      describe "show-source -a" do
++        it 'should show the source for all monkeypatches defined in different files' do
++          class TestClassForShowSource
++            def beta
++            end
++          end
++
++          result = pry_eval('show-source TestClassForShowSource -a')
++          result.should =~ /def alpha/
++          result.should =~ /def beta/
++        end
++
++        it 'should show the source for a class_eval-based monkeypatch' do
++          TestClassForShowSourceClassEval.class_eval do
++            def class_eval_method
++            end
++          end
++
++          result = pry_eval('show-source TestClassForShowSourceClassEval -a')
++          result.should =~ /def class_eval_method/
++        end
++
++        it 'should ignore -a when object is not a module' do
++          TestClassForShowSourceClassEval.class_eval do
++            def class_eval_method
++              :bing
++            end
++          end
++
++          result = pry_eval('show-source TestClassForShowSourceClassEval#class_eval_method -a')
++          result.should =~ /bing/
++        end
++
++        it 'should show the source for an instance_eval-based monkeypatch' do
++          TestClassForShowSourceInstanceEval.instance_eval do
++            def instance_eval_method
++            end
++          end
++
++          result = pry_eval('show-source TestClassForShowSourceInstanceEval -a')
++          result.should =~ /def instance_eval_method/
++        end
++
++        describe "messages relating to -a" do
++          it 'indicates all available monkeypatches can be shown with -a when (when -a not used and more than one candidate exists for class)' do
++            class TestClassForShowSource
++              def beta
++              end
++            end
++
++            result = pry_eval('show-source TestClassForShowSource')
++            result.should =~ /available monkeypatches/
++          end
++
++          it 'shouldnt say anything about monkeypatches when only one candidate exists for selected class' do
++            class Aarrrrrghh
++              def o;end
++            end
++
++            result = pry_eval('show-source Aarrrrrghh')
++            result.should.not =~ /available monkeypatches/
++            Object.remove_const(:Aarrrrrghh)
++          end
++        end
++      end
++
++      describe "when show-source is invoked without a method or class argument" do
++        before do
++          module TestHost
++            class M
++              def alpha; end
++              def beta; end
++            end
++
++            module C
++            end
++
++            module D
++              def self.invoked_in_method
++                pry_eval(binding, 'show-source')
++              end
++            end
++          end
++        end
++
++        after do
++          Object.remove_const(:TestHost)
++        end
++
++        describe "inside a module" do
++          it 'should display module source by default' do
++            out = pry_eval(TestHost::M, 'show-source')
++            out.should =~ /class M/
++            out.should =~ /def alpha/
++            out.should =~ /def beta/
++          end
++
++          it 'should be unable to find module source if no methods defined' do
++            proc {
++              pry_eval(TestHost::C, 'show-source')
++            }.should.raise(Pry::CommandError).
++              message.should =~ /Couldn't locate/
++          end
++
++          it 'should display method code (rather than class) if Pry started inside method binding' do
++            out = TestHost::D.invoked_in_method
++            out.should =~ /invoked_in_method/
++            out.should.not =~ /module D/
++          end
++
++          it 'should display class source when inside instance' do
++            out = pry_eval(TestHost::M.new, 'show-source')
++            out.should =~ /class M/
++            out.should =~ /def alpha/
++            out.should =~ /def beta/
++          end
++
++          it 'should allow options to be passed' do
++            out = pry_eval(TestHost::M, 'show-source -b')
++            out.should =~ /\d:\s*class M/
++            out.should =~ /\d:\s*def alpha/
++            out.should =~ /\d:\s*def beta/
++          end
++
++          describe "should skip over broken modules" do
++            before do
++              module BabyDuck
++
++                module Muesli
++                  binding.eval("def a; end", "dummy.rb", 1)
++                  binding.eval("def b; end", "dummy.rb", 2)
++                  binding.eval("def c; end", "dummy.rb", 3)
++                end
++
++                module Muesli
++                  def d; end
++                  def e; end
++                end
++              end
++            end
++
++            after do
++              Object.remove_const(:BabyDuck)
++            end
++
++            it 'should return source for first valid module' do
++              out = pry_eval('show-source BabyDuck::Muesli')
++              out.should =~ /def d; end/
++              out.should.not =~ /def a; end/
++            end
++          end
++        end
++      end
++    end
++
++    describe "on commands" do
++      before do
++        @oldset = Pry.config.commands
++        @set = Pry.config.commands = Pry::CommandSet.new do
++          import Pry::Commands
++        end
++      end
++
++      after do
++        Pry.config.commands = @oldset
++      end
++
++      describe "block commands" do
++        it 'should show source for an ordinary command' do
++          @set.command "foo", :body_of_foo do; end
++
++          pry_eval('show-source foo').should =~ /:body_of_foo/
++        end
++
++        it "should output source of commands using special characters" do
++          @set.command "!%$", "I gots the yellow fever" do; end
++
++          pry_eval('show-source !%$').should =~ /yellow fever/
++        end
++
++        it 'should show source for a command with spaces in its name' do
++          @set.command "foo bar", :body_of_foo_bar do; end
++
++          pry_eval('show-source foo bar').should =~ /:body_of_foo_bar/
++        end
++
++        it 'should show source for a command by listing name' do
++          @set.command /foo(.*)/, :body_of_foo_bar_regex, :listing => "bar" do; end
++
++          pry_eval('show-source bar').should =~ /:body_of_foo_bar_regex/
++        end
++      end
++
++      describe "create_command commands" do
++        it 'should show source for a command' do
++          @set.create_command "foo", "babble" do
++            def process() :body_of_foo end
++          end
++          pry_eval('show-source foo').should =~ /:body_of_foo/
++        end
++
++        it 'should show source for a command defined inside pry' do
++          pry_eval %{
++          _pry_.commands.create_command "foo", "babble" do
++            def process() :body_of_foo end
++          end
++        }
++        pry_eval('show-source foo').should =~ /:body_of_foo/
++      end
++    end
++
++    describe "real class-based commands" do
++      before do
++        class ::TemporaryCommand < Pry::ClassCommand
++          match 'temp-command'
++          def process() :body_of_temp end
++        end
++
++        Pry.config.commands.add_command(::TemporaryCommand)
++      end
++
++      after do
++        Object.remove_const(:TemporaryCommand)
++      end
++
++      it 'should show source for a command' do
++        pry_eval('show-source temp-command').should =~ /:body_of_temp/
++      end
++
++      it 'should show source for a command defined inside pry' do
++        pry_eval %{
++          class ::TemporaryCommandInPry < Pry::ClassCommand
++            match 'temp-command-in-pry'
++            def process() :body_of_temp end
++          end
++        }
++        Pry.config.commands.add_command(::TemporaryCommandInPry)
++        pry_eval('show-source temp-command-in-pry').should =~ /:body_of_temp/
++        Object.remove_const(:TemporaryCommandInPry)
++      end
++    end
++  end
++
++  describe "should set _file_ and _dir_" do
++    it 'should set _file_ and _dir_ to file containing method source' do
++      t = pry_tester
++      t.process_command "show-source TestClassForShowSource#alpha"
++      t.pry.last_file.should =~ /show_source_doc_examples/
++      t.pry.last_dir.should =~ /fixtures/
++    end
++  end
++
++  unless Pry::Helpers::BaseHelpers.rbx?
++    describe "can't find class/module code" do
++      describe "for classes" do
++        before do
++          module Jesus
++            module Pig
++              def lillybing; :lillybing; end
++            end
++
++            class Brian; end
++            class Jingle
++              def a; :doink; end
++            end
++
++            class Jangle < Jingle; include Pig; end
++            class Bangle < Jangle; end
++          end
++        end
++
++        after do
++          Object.remove_const(:Jesus)
++        end
++
++        it 'shows superclass code' do
++          t = pry_tester
++          t.process_command "show-source Jesus::Jangle"
++          t.last_output.should =~ /doink/
++        end
++
++        it 'ignores included modules' do
++          t = pry_tester
++          t.process_command "show-source Jesus::Jangle"
++          t.last_output.should.not =~ /lillybing/
++        end
++
++        it 'errors when class has no superclass to show' do
++          t = pry_tester
++          lambda { t.process_command "show-source Jesus::Brian" }.should.raise(Pry::CommandError).message.
++            should =~ /Couldn't locate/
++        end
++
++        it 'shows warning when reverting to superclass code' do
++          t = pry_tester
++          t.process_command "show-source Jesus::Jangle"
++          t.last_output.should =~ /Warning.*?Cannot find.*?Jesus::Jangle.*Showing.*Jesus::Jingle instead/
++        end
++
++        it 'shows nth level superclass code (when no intermediary superclasses have code either)' do
++          t = pry_tester
++          t.process_command "show-source Jesus::Bangle"
++          t.last_output.should =~ /doink/
++        end
++
++        it 'shows correct warning when reverting to nth level superclass' do
++          t = pry_tester
++          t.process_command "show-source Jesus::Bangle"
++          t.last_output.should =~ /Warning.*?Cannot find.*?Jesus::Bangle.*Showing.*Jesus::Jingle instead/
++        end
++      end
++
++      describe "for modules" do
++        before do
++          module Jesus
++            module Alpha
++              def alpha; :alpha; end
++            end
++
++            module Zeta; end
++
++            module Beta
++              include Alpha
++            end
++
++            module Gamma
++              include Beta
++            end
++          end
++        end
++
++        after do
++          Object.remove_const(:Jesus)
++        end
++
++        it 'shows included module code' do
++          t = pry_tester
++          t.process_command "show-source Jesus::Beta"
++          t.last_output.should =~ /alpha/
++        end
++
++        it 'shows warning when reverting to included module code' do
++          t = pry_tester
++          t.process_command "show-source Jesus::Beta"
++          t.last_output.should =~ /Warning.*?Cannot find.*?Jesus::Beta.*Showing.*Jesus::Alpha instead/
++        end
++
++        it 'errors when module has no included module to show' do
++          t = pry_tester
++          lambda { t.process_command "show-source Jesus::Zeta" }.should.raise(Pry::CommandError).message.
++            should =~ /Couldn't locate/
++        end
++
++        it 'shows nth level included module code (when no intermediary modules have code either)' do
++          t = pry_tester
++          t.process_command "show-source Jesus::Gamma"
++          t.last_output.should =~ /alpha/
++        end
++
++        it 'shows correct warning when reverting to nth level included module' do
++          t = pry_tester
++          t.process_command "show-source Jesus::Gamma"
++          t.last_output.should =~ /Warning.*?Cannot find.*?Jesus::Gamma.*Showing.*Jesus::Alpha instead/
++        end
++      end
++    end
++  end
++end
+diff --git a/spec/commands/watch_expression_spec.rb b/spec/commands/watch_expression_spec.rb
+new file mode 100644
+index 0000000..765c040
+--- /dev/null
++++ b/spec/commands/watch_expression_spec.rb
+@@ -0,0 +1,119 @@
++require_relative '../helper'
++
++describe "watch expression" do
++
++  # Custom eval that will:
++  # 1) Create an instance of pry that can use for multiple calls
++  # 2) Exercise the after_eval hook
++  # 3) Return the output
++  def eval(expr)
++    output = @tester.eval expr
++    @tester.pry.hooks.exec_hook :after_eval, nil, @tester.pry
++    output
++  end
++
++  before do
++    @tester = pry_tester
++    @tester.pry.hooks.clear :after_eval
++    eval "watch --delete"
++  end
++
++  it "registers the after_eval hook" do
++    eval 'watch 1+1'
++    @tester.pry.hooks.hook_exists?(:after_eval, :watch_expression).should == true
++  end
++
++  it "prints no watched expressions" do
++    eval('watch').should =~ /No watched expressions/
++  end
++
++  it "watches an expression" do
++    eval "watch 1+1"
++    eval('watch').should =~ /=> 2/
++  end
++
++  it "watches a local variable" do
++    eval 'foo = :bar'
++    eval 'watch foo'
++    eval('watch').should =~ /=> :bar/
++  end
++
++  it "prints when an expression changes" do
++    ReplTester.start do
++      input 'a = 1'
++      output '=> 1'
++
++      input 'watch a'
++      output "Watching a\nwatch: a => 1"
++
++      input "a = 2"
++      output "watch: a => 2\n=> 2"
++    end
++  end
++
++  it "prints when an expression is mutated" do
++    ReplTester.start do
++      input 'a = "one"'
++      output '=> "one"'
++
++      input 'watch a'
++      output %(Watching a\nwatch: a => "one")
++
++      input "a.sub! 'o', 'p'"
++      output %(watch: a => "pne"\n=> "pne")
++    end
++  end
++
++  it "doesn't print when an expresison remains the same" do
++    ReplTester.start do
++      input 'a = 1'
++      output '=> 1'
++
++      input 'watch a'
++      output "Watching a\nwatch: a => 1"
++
++      input "a = 1"
++      output "=> 1"
++    end
++  end
++
++  it "continues to work if you start a second pry instance" do
++    ReplTester.start do
++      input 'a = 1'
++      output '=> 1'
++
++      input 'watch a'
++      output "Watching a\nwatch: a => 1"
++
++      input "a = 2"
++      output "watch: a => 2\n=> 2"
++    end
++
++    ReplTester.start do
++      input 'b = 1'
++      output '=> 1'
++
++      input 'watch b'
++      output "Watching b\nwatch: b => 1"
++
++      input "b = 2"
++      output "watch: b => 2\n=> 2"
++    end
++  end
++
++  describe "deleting expressions" do
++    before do
++      eval 'watch :keeper'
++      eval 'watch :delete'
++      eval 'watch -d 2'
++    end
++
++    it "keeps keeper" do
++      eval('watch').should =~ /keeper/
++    end
++
++    it "deletes delete" do
++      eval('watch').should.not =~ /delete/
++    end
++  end
++end
+diff --git a/spec/commands/whereami_spec.rb b/spec/commands/whereami_spec.rb
+new file mode 100644
+index 0000000..f19f49d
+--- /dev/null
++++ b/spec/commands/whereami_spec.rb
+@@ -0,0 +1,237 @@
++require_relative '../helper'
++
++describe "whereami" do
++  it 'should work with methods that have been undefined' do
++    class Cor
++      def blimey!
++        Cor.send :undef_method, :blimey!
++        Pad.binding = binding
++      end
++    end
++
++    Cor.new.blimey!
++
++    # using [.] so the regex doesn't match itself
++    pry_eval(Pad.binding, 'whereami').should =~ /self[.]blimey!/
++
++    Object.remove_const(:Cor)
++  end
++
++  it 'should work in objects with no method methods' do
++    class Cor
++      def blimey!
++        pry_eval(binding, 'whereami').should =~ /Cor[#]blimey!/
++      end
++
++      def method; "moo"; end
++    end
++    Cor.new.blimey!
++    Object.remove_const(:Cor)
++  end
++
++  it 'should properly set _file_, _line_ and _dir_' do
++    class Cor
++      def blimey!
++        pry_eval(binding, 'whereami', '_file_').
++          should == File.expand_path(__FILE__)
++      end
++    end
++
++    Cor.new.blimey!
++    Object.remove_const(:Cor)
++  end
++
++  it 'should work in BasicObjects' do
++    cor = Class.new(BasicObject) do
++      def blimey!
++        ::Kernel.binding # omnom
++      end
++    end.new.blimey!
++
++    pry_eval(cor, 'whereami').should =~ /::Kernel.binding [#] omnom/
++  end
++
++  it 'should show description and correct code when __LINE__ and __FILE__ are outside @method.source_location' do
++    class Cor
++      def blimey!
++        eval <<-END, binding, "spec/fixtures/example.erb", 1
++          pry_eval(binding, 'whereami')
++        END
++      end
++    end
++
++    Cor.instance_method(:blimey!).source.should =~ /pry_eval/
++    Cor.new.blimey!.should =~ /Cor#blimey!.*Look at me/m
++    Object.remove_const(:Cor)
++  end
++
++  it 'should show description and correct code when @method.source_location would raise an error' do
++    class Cor
++      eval <<-END, binding, "spec/fixtures/example.erb", 1
++        def blimey!
++          pry_eval(binding, 'whereami')
++        end
++        END
++      end
++
++      lambda{
++        Cor.instance_method(:blimey!).source
++      }.should.raise(MethodSource::SourceNotFoundError)
++
++      Cor.new.blimey!.should =~ /Cor#blimey!.*Look at me/m
++      Object.remove_const(:Cor)
++    end
++
++    # Now that we use stagger_output (paging output) we no longer get
++    # the "From: " line, as we output everything in one go (not separate output.puts)
++    # and so the user just gets a single `Error: Cannot open
++    # "not.found.file.erb" for reading.`
++    # which is good enough IMO. Unfortunately we can't test for it
++    # though, as we don't hook stdout.
++    #
++    # it 'should display a description and error if reading the file goes wrong' do
++    #   class Cor
++    #     def blimey!
++    #       eval <<-END, binding, "not.found.file.erb", 7
++    #         Pad.tester = pry_tester(binding)
++    #         Pad.tester.eval('whereami')
++    #       END
++    #     end
++    #   end
++
++    #   proc { Cor.new.blimey! }.should.raise(MethodSource::SourceNotFoundError)
++
++    #   Pad.tester.last_output.should =~
++    #     /From: not.found.file.erb @ line 7 Cor#blimey!:/
++    #   Object.remove_const(:Cor)
++    # end
++
++    it 'should show code window (not just method source) if parameter passed to whereami' do
++      class Cor
++        def blimey!
++          pry_eval(binding, 'whereami 3').should =~ /class Cor/
++        end
++      end
++      Cor.new.blimey!
++      Object.remove_const(:Cor)
++    end
++
++    it 'should show entire method when -m option used' do
++      old_size, Pry.config.default_window_size = Pry.config.default_window_size, 1
++      old_cutoff, Pry::Command::Whereami.method_size_cutoff = Pry::Command::Whereami.method_size_cutoff, 1
++      class Cor
++        def blimey!
++          1
++          2
++          pry_eval(binding, 'whereami -m').should =~ /def blimey/
++        end
++      end
++      Pry::Command::Whereami.method_size_cutoff, Pry.config.default_window_size = old_cutoff, old_size
++      Cor.new.blimey!
++      Object.remove_const(:Cor)
++    end
++
++    it 'should show entire file when -f option used' do
++      class Cor
++        def blimey!
++          1
++          2
++          pry_eval(binding, 'whereami -f').should =~ /show entire file when -f option used/
++        end
++      end
++      Cor.new.blimey!
++      Object.remove_const(:Cor)
++    end
++
++    describe "-c" do
++      it 'should show class when -c option used, and locate correct candidate' do
++        require 'fixtures/whereami_helper'
++        class Cor
++          def blimey!
++            1
++            2
++            out = pry_eval(binding, 'whereami -c')
++            out.should =~ /class Cor/
++            out.should =~ /blimey/
++          end
++        end
++        Cor.new.blimey!
++        Object.remove_const(:Cor)
++      end
++
++      it 'should show class when -c option used, and locate correct superclass' do
++        class Cor
++          def blimey!
++            1
++            2
++            out = pry_eval(binding, 'whereami -c')
++            out.should =~ /class Cor/
++            out.should =~ /blimey/
++          end
++        end
++
++        class Horse < Cor
++          def pig;end
++        end
++
++        Horse.new.blimey!
++        Object.remove_const(:Cor)
++        Object.remove_const(:Horse)
++      end
++
++      # https://github.com/rubinius/rubinius/pull/2247
++      unless Pry::Helpers::BaseHelpers.rbx?
++        it 'should show class when -c option used, and binding is outside a method' do
++          class Cor
++            def blimey;end
++
++            out = pry_eval(binding, 'whereami -c')
++            out.should =~ /class Cor/
++            out.should =~ /blimey/
++          end
++          Object.remove_const(:Cor)
++        end
++      end
++    end
++
++  it 'should not show line numbers or marker when -n switch is used' do
++    class Cor
++      def blimey!
++        out = pry_eval(binding, 'whereami -n')
++        out.should =~ /^\s*def/
++        out.should.not =~ /\=\>/
++      end
++    end
++    Cor.new.blimey!
++    Object.remove_const(:Cor)
++  end
++
++  it 'should use Pry.config.default_window_size for window size when outside a method context' do
++    old_size, Pry.config.default_window_size = Pry.config.default_window_size, 1
++    :litella
++    :pig
++    out = pry_eval(binding, 'whereami')
++    :punk
++    :sanders
++
++    out.should.not =~ /:litella/
++    out.should =~ /:pig/
++    out.should =~ /:punk/
++    out.should.not =~ /:sanders/
++
++    Pry.config.default_window_size = old_size
++  end
++
++  it "should work at the top level" do
++    pry_eval(Pry.toplevel_binding, 'whereami').should =~
++      /At the top level/
++  end
++
++  it "should work inside a class" do
++    pry_eval(Pry, 'whereami').should =~ /Inside Pry/
++  end
++
++  it "should work inside an object" do
++    pry_eval(Object.new, 'whereami').should =~ /Inside #<Object/
++  end
++end
+diff --git a/spec/completion_spec.rb b/spec/completion_spec.rb
+new file mode 100644
+index 0000000..1207f25
+--- /dev/null
++++ b/spec/completion_spec.rb
+@@ -0,0 +1,214 @@
++require_relative 'helper'
++require "readline" unless defined?(Readline)
++require "pry/input_completer"
++
++def completer_test(bind, pry=nil, assert_flag=true)
++  test = proc {|symbol|
++    Pry::InputCompleter.new(pry || Readline, pry).call(symbol[0..-2], :target => Pry.binding_for(bind)).include?(symbol).should  == assert_flag}
++  return proc {|*symbols| symbols.each(&test) }
++end
++
++
++describe Pry::InputCompleter do
++  before do
++    # The AMQP gem has some classes like this:
++    #  pry(main)> AMQP::Protocol::Test::ContentOk.name
++    #  => :content_ok
++    module SymbolyName
++      def self.name; :symboly_name; end
++    end
++
++    @before_completer = Pry.config.completer
++    Pry.config.completer = Pry::InputCompleter
++  end
++
++  after do
++    Pry.config.completer = @before_completer
++    Object.remove_const :SymbolyName
++  end
++
++  # another jruby hack :((
++  if !Pry::Helpers::BaseHelpers.jruby?
++    it "should not crash if there's a Module that has a symbolic name." do
++      lambda{ Pry::InputCompleter.new(Readline).call "a.to_s.", :target => Pry.binding_for(Object.new) }.should.not.raise Exception
++    end
++  end
++
++  it 'should take parenthesis and other characters into account for symbols' do
++    lambda { Pry::InputCompleter.new(Readline).call(":class)", :target => Pry.binding_for(Object.new)) }.should.not.raise(RegexpError)
++  end
++
++  it 'should complete instance variables' do
++    object = Class.new.new
++
++    # set variables in appropriate scope
++    object.instance_variable_set(:'@name', 'Pry')
++    object.class.send(:class_variable_set, :'@@number', 10)
++
++    # check to see if variables are in scope
++    object.instance_variables.
++      map { |v| v.to_sym }.
++      include?(:'@name').should == true
++
++    object.class.class_variables.
++      map { |v| v.to_sym }.
++      include?(:'@@number').should == true
++
++    # Complete instance variables.
++    b = Pry.binding_for(object)
++    completer_test(b).call('@name', '@name.downcase')
++
++    # Complete class variables.
++    b = Pry.binding_for(object.class)
++    completer_test(b).call('@@number', '@@number.class')
++
++  end
++
++
++  it 'should complete for stdlib symbols' do
++
++    o = Object.new
++    # Regexp
++    completer_test(o).call('/foo/.extend')
++
++    # Array
++    completer_test(o).call('[1].push')
++
++    # Hash
++    completer_test(o).call('{"a" => "b"}.keys')
++
++    # Proc
++    completer_test(o).call('{2}.call')
++
++    # Symbol
++    completer_test(o).call(':symbol.to_s')
++
++    # Absolute Constant
++    completer_test(o).call('::IndexError')
++  end
++
++  it 'should complete for target symbols' do
++    o = Object.new
++
++    # Constant
++    module Mod
++      Con = 'Constant'
++      module Mod2
++      end
++    end
++
++    completer_test(Mod).call('Con')
++
++    # Constants or Class Methods
++    completer_test(o).call('Mod::Con')
++
++    # Symbol
++    foo = :symbol
++    completer_test(o).call(':symbol')
++
++    # Variables
++    class << o
++      attr_accessor :foo
++    end
++    o.foo = 'bar'
++    completer_test(binding).call('o.foo')
++
++    # trailing slash
++    Pry::InputCompleter.new(Readline).call('Mod2/', :target => Pry.binding_for(Mod)).include?('Mod2/').should   == true
++  end
++
++  it 'should complete for arbitrary scopes' do
++    module Bar
++      @barvar = :bar
++    end
++
++    module Baz
++      @bar = Bar
++      @bazvar = :baz
++      Con = :constant
++    end
++
++    pry = Pry.new(:target => Baz)
++    pry.push_binding(Bar)
++
++    b = Pry.binding_for(Bar)
++    completer_test(b, pry).call("../@bazvar")
++    completer_test(b, pry).call('/Con')
++  end
++
++  it 'should complete for stdlib symbols' do
++
++    o = Object.new
++    # Regexp
++    completer_test(o).call('/foo/.extend')
++
++    # Array
++    completer_test(o).call('[1].push')
++
++    # Hash
++    completer_test(o).call('{"a" => "b"}.keys')
++
++    # Proc
++    completer_test(o).call('{2}.call')
++
++    # Symbol
++    completer_test(o).call(':symbol.to_s')
++
++    # Absolute Constant
++    completer_test(o).call('::IndexError')
++  end
++
++  it 'should complete for target symbols' do
++    o = Object.new
++
++    # Constant
++    module Mod
++      Con = 'Constant'
++      module Mod2
++      end
++    end
++
++    completer_test(Mod).call('Con')
++
++    # Constants or Class Methods
++    completer_test(o).call('Mod::Con')
++
++    # Symbol
++    foo = :symbol
++    completer_test(o).call(':symbol')
++
++    # Variables
++    class << o
++      attr_accessor :foo
++    end
++    o.foo = 'bar'
++    completer_test(binding).call('o.foo')
++
++    # trailing slash
++    Pry::InputCompleter.new(Readline).call('Mod2/', :target => Pry.binding_for(Mod)).include?('Mod2/').should   == true
++  end
++
++  it 'should complete for arbitrary scopes' do
++    module Bar
++      @barvar = :bar
++    end
++
++    module Baz
++      @bar = Bar
++      @bazvar = :baz
++      Con = :constant
++    end
++
++    pry = Pry.new(:target => Baz)
++    pry.push_binding(Bar)
++
++    b = Pry.binding_for(Bar)
++    completer_test(b, pry).call("../@bazvar")
++    completer_test(b, pry).call('/Con')
++  end
++
++  it 'should not return nil in its output' do
++    pry = Pry.new
++    Pry::InputCompleter.new(Readline, pry).call("pry.", :target => binding).should.not.include nil
++  end
++end
+diff --git a/spec/config_spec.rb b/spec/config_spec.rb
+new file mode 100644
+index 0000000..228f30d
+--- /dev/null
++++ b/spec/config_spec.rb
+@@ -0,0 +1,189 @@
++require_relative 'helper'
++describe Pry::Config do
++  describe "reserved keys" do
++    it "raises an ArgumentError on assignment of a reserved key" do
++      local = Pry::Config.new
++      Pry::Config::RESERVED_KEYS.each do |key|
++        should.raise(ArgumentError) { local[key] = 1 }
++      end
++    end
++  end
++
++  describe "traversal to parent" do
++    it "traverses back to the parent when a local key is not found" do
++      local = Pry::Config.new Pry::Config.from_hash(foo: 1)
++      local.foo.should == 1
++    end
++
++    it "stores a local key and prevents traversal to the parent" do
++      local = Pry::Config.new Pry::Config.from_hash(foo: 1)
++      local.foo = 2
++      local.foo.should == 2
++    end
++
++    it "traverses through a chain of parents" do
++      root = Pry::Config.from_hash({foo: 21})
++      local1 = Pry::Config.new(root)
++      local2 = Pry::Config.new(local1)
++      local3 = Pry::Config.new(local2)
++      local3.foo.should == 21
++    end
++  end
++
++  describe ".from_hash" do
++    it "returns an object without a default" do
++      local = Pry::Config.from_hash({})
++      local.default.should == nil
++    end
++
++    it "returns an object with a default" do
++      default = Pry::Config.new(nil)
++      local = Pry::Config.from_hash({}, default)
++      local.default.should == local
++    end
++  end
++
++
++  describe "#respond_to_missing?" do
++    before do
++      @config = Pry::Config.new(nil)
++    end
++
++    it "returns a Method object for a dynamic key" do
++      @config["key"] = 1
++      method_obj = @config.method(:key)
++      method_obj.name.should == :key
++      method_obj.call.should == 1
++    end
++  end
++
++  describe "#respond_to?" do
++    before do
++      @config = Pry::Config.new(nil)
++    end
++
++    it "returns true for a local key" do
++      @config.zzfoo = 1
++      @config.respond_to?(:zzfoo).should == true
++    end
++
++    it "returns false for an unknown key" do
++      @config.respond_to?(:blahblah).should == false
++    end
++  end
++
++  describe "#default" do
++    it "returns nil" do
++      local = Pry::Config.new(nil)
++      local.default.should == nil
++    end
++
++    it "returns the default" do
++      default = Pry::Config.new(nil)
++      local = Pry::Config.new(default)
++      local.default.should == default
++    end
++  end
++
++  describe "#keys" do
++    it "returns an array of local keys" do
++      root = Pry::Config.from_hash({zoo: "boo"}, nil)
++      local = Pry::Config.from_hash({foo: "bar"}, root)
++      local.keys.should == ["foo"]
++    end
++  end
++
++  describe "#==" do
++    it "compares equality through the underlying lookup table" do
++      local1 = Pry::Config.new(nil)
++      local2 = Pry::Config.new(nil)
++      local1.foo = "hi"
++      local2.foo = "hi"
++      local1.should == local2
++    end
++
++    it "compares equality against an object who does not implement #to_hash" do
++      local1 = Pry::Config.new(nil)
++      local1.should.not == Object.new
++    end
++  end
++
++  describe "#forget" do
++    it "forgets a local key" do
++      local = Pry::Config.new Pry::Config.from_hash(foo: 1)
++      local.foo = 2
++      local.foo.should == 2
++      local.forget(:foo)
++      local.foo.should == 1
++    end
++  end
++
++  describe "#to_hash" do
++    it "provides a copy of local key & value pairs as a Hash" do
++      local = Pry::Config.new Pry::Config.from_hash(bar: true)
++      local.foo = "21"
++      local.to_hash.should == { "foo" => "21" }
++    end
++
++    it "returns a duplicate of the lookup table" do
++      local = Pry::Config.new(nil)
++      local.to_hash.merge!("foo" => 42)
++      local.foo.should.not == 42
++    end
++  end
++
++  describe "#merge!" do
++    before do
++      @config = Pry::Config.new(nil)
++    end
++
++    it "merges an object who returns a Hash through #to_hash" do
++      obj = Class.new { def to_hash() {epoch: 1} end }.new
++      @config.merge!(obj)
++      @config.epoch.should == 1
++    end
++
++    it "merges an object who returns a Hash through #to_h" do
++      obj = Class.new { def to_h() {epoch: 2} end }.new
++      @config.merge!(obj)
++      @config.epoch.should == 2
++    end
++
++    it "merges a Hash" do
++      @config.merge!(epoch: 420)
++      @config.epoch.should == 420
++    end
++
++    it "raises a TypeError for objects who can't become a Hash" do
++      should.raise(TypeError) { @config.merge!(Object.new) }
++    end
++  end
++
++  describe "#clear" do
++    before do
++      @local = Pry::Config.new(nil)
++    end
++
++    it "returns true" do
++      @local.clear.should == true
++    end
++
++    it "clears local assignments" do
++      @local.foo = 1
++      @local.clear
++      @local.to_hash.should == {}
++    end
++
++    it "is aliased as #refresh" do
++      @local.method(:clear).should == @local.method(:refresh)
++    end
++  end
++
++  describe "#[]=" do
++    it "stores keys as strings" do
++      local = Pry::Config.from_hash({})
++      local[:zoo] = "hello"
++      local.to_hash.should == { "zoo" => "hello" }
++    end
++  end
++end
+diff --git a/spec/control_d_handler_spec.rb b/spec/control_d_handler_spec.rb
+new file mode 100644
+index 0000000..1c83776
+--- /dev/null
++++ b/spec/control_d_handler_spec.rb
+@@ -0,0 +1,62 @@
++require_relative 'helper'
++
++describe Pry::DEFAULT_CONTROL_D_HANDLER do
++
++  describe "control-d press" do
++
++    before do
++      # Simulates a ^D press.
++      @control_d = "Pry::DEFAULT_CONTROL_D_HANDLER.call('', _pry_)"
++    end
++
++    describe "in an expression" do
++      it "should clear out passed string" do
++        str = 'hello world'
++        Pry::DEFAULT_CONTROL_D_HANDLER.call(str, nil)
++        str.should == ''
++      end
++    end
++
++    describe 'at top-level session' do
++      it 'should break out of a REPL loop' do
++        instance = Pry.new
++        instance.binding_stack.should.not.be.empty
++        instance.eval(nil).should.be.false
++        instance.binding_stack.should.be.empty
++      end
++    end
++
++    describe 'in a nested session' do
++      it 'should pop last binding from the binding stack' do
++        t = pry_tester
++        t.eval "cd Object.new"
++        t.eval("_pry_.binding_stack.size").should == 2
++        t.eval("_pry_.eval(nil)").should.be.true
++        t.eval("_pry_.binding_stack.size").should == 1
++      end
++
++      it "breaks out of the parent session" do
++        ReplTester.start do
++          input  'Pry::REPL.new(_pry_, :target => 10).start'
++          output ''
++          prompt(/10.*> $/)
++
++          input  'self'
++          output '=> 10'
++
++          input  nil # Ctrl-D
++          output ''
++
++          input  'self'
++          output '=> main'
++
++          input  nil # Ctrl-D
++          output '=> nil' # Exit value of nested REPL.
++          assert_exited
++        end
++      end
++    end
++
++  end
++
++end
+diff --git a/spec/documentation_helper_spec.rb b/spec/documentation_helper_spec.rb
+new file mode 100644
+index 0000000..8cab716
+--- /dev/null
++++ b/spec/documentation_helper_spec.rb
+@@ -0,0 +1,68 @@
++require_relative 'helper'
++
++describe Pry::Helpers::DocumentationHelpers do
++  before do
++    @helper = Pry::Helpers::DocumentationHelpers
++  end
++
++  describe "get_comment_content" do
++    it "should strip off the hash and unindent" do
++      @helper.get_comment_content(" # hello\n # world\n").should == "hello\nworld\n"
++    end
++
++    it "should strip out leading lines of hashes" do
++      @helper.get_comment_content("###############\n#hello\n#world\n").should == "hello\nworld\n"
++    end
++
++    it "should remove shebangs" do
++      @helper.get_comment_content("#!/usr/bin/env ruby\n# This is a program\n").should == "This is a program\n"
++    end
++
++    it "should unindent past separators" do
++      @helper.get_comment_content(" # Copyright Me <me at cirw.in>\n #--\n # So there.\n").should == "Copyright Me <me at cirw.in>\n--\nSo there.\n"
++    end
++  end
++
++  describe "process_rdoc" do
++    before do
++      Pry.config.color = true
++    end
++
++    after do
++      Pry.config.color = false
++    end
++
++    it "should syntax highlight indented code" do
++      @helper.process_rdoc("  4 + 4\n").should.not == "  4 + 4\n"
++    end
++
++    it "should highlight words surrounded by +s" do
++      @helper.process_rdoc("the +parameter+").should =~ /the \e.*parameter\e.*/
++    end
++
++    it "should syntax highlight things in backticks" do
++      @helper.process_rdoc("for `Example`").should =~ /for `\e.*Example\e.*`/
++    end
++
++    it "should emphasise em tags" do
++      @helper.process_rdoc("for <em>science</em>").should == "for \e[1mscience\e[0m"
++    end
++
++    it "should emphasise italic tags" do
++      @helper.process_rdoc("for <i>science</i>").should == "for \e[1mscience\e[0m"
++    end
++
++    it "should syntax highlight code in <code>" do
++      @helper.process_rdoc("for <code>Example</code>").should =~ /for \e.*Example\e.*/
++    end
++
++    it "should not double-highlight backticks inside indented code" do
++      @helper.process_rdoc("  `echo 5`").should =~ /echo 5/
++    end
++
++    it "should not remove ++" do
++      @helper.process_rdoc("--\n  comment in a bubble\n++").should =~ /\+\+/
++    end
++  end
++
++end
+diff --git a/spec/editor_spec.rb b/spec/editor_spec.rb
+new file mode 100644
+index 0000000..a26722a
+--- /dev/null
++++ b/spec/editor_spec.rb
+@@ -0,0 +1,68 @@
++require 'pathname'
++require_relative 'helper'
++
++describe Pry::Editor do
++  class Pry::Editor
++    public :build_editor_invocation_string
++  end
++
++  before do
++    # OS-specific tempdir name. For GNU/Linux it's "tmp", for Windows it's
++    # something "Temp".
++    @tf_dir =
++      if Pry::Helpers::BaseHelpers.mri_19?
++        Pathname.new(Dir::Tmpname.tmpdir)
++      else
++        Pathname.new(Dir.tmpdir)
++      end
++
++    @tf_path = File.join(@tf_dir.to_s, 'hello world.rb')
++
++    @editor = Pry::Editor.new(Pry.new)
++  end
++
++  unless Pry::Helpers::BaseHelpers.windows?
++    describe "build_editor_invocation_string" do
++      it 'should shell-escape files' do
++        invocation_str = @editor.build_editor_invocation_string(@tf_path, 5, true)
++        invocation_str.should =~ /#@tf_dir.+hello\\ world\.rb/
++      end
++    end
++  end
++
++  describe "build_editor_invocation_string on windows" do
++    before do
++      class Pry::Editor
++        def windows?; true; end
++      end
++    end
++
++    after do
++      class Pry::Editor
++        undef windows?
++      end
++    end
++
++    it "should replace / by \\" do
++      invocation_str = @editor.build_editor_invocation_string(@tf_path, 5, true)
++      invocation_str.should =~ %r(\\#{@tf_dir.basename}\\)
++    end
++
++    it "should not shell-escape files" do
++      invocation_str = @editor.build_editor_invocation_string(@tf_path, 5, true)
++      invocation_str.should =~ /hello world\.rb/
++    end
++  end
++
++  describe 'invoke_editor with a proc' do
++    it 'should not shell-escape files' do
++      editor = Pry::Editor.new(Pry.new(editor: proc{ |file, line, blocking|
++        @file = file
++        nil
++      }))
++
++      editor.invoke_editor(@tf_path, 10, true)
++      @file.should == @tf_path
++    end
++  end
++end
+diff --git a/spec/exception_whitelist_spec.rb b/spec/exception_whitelist_spec.rb
+new file mode 100644
+index 0000000..414abbb
+--- /dev/null
++++ b/spec/exception_whitelist_spec.rb
+@@ -0,0 +1,21 @@
++require_relative 'helper'
++
++describe "Pry.config.exception_whitelist" do
++  before do
++    @str_output = StringIO.new
++  end
++
++  it 'should rescue all exceptions NOT specified on whitelist' do
++    Pry.config.exception_whitelist.include?(NameError).should == false
++    lambda { Pry.start(self, :input => StringIO.new("raise NameError\nexit"), :output => @str_output) }.should.not.raise NameError
++  end
++
++  it 'should NOT rescue exceptions specified on whitelist' do
++    old_whitelist = Pry.config.exception_whitelist
++    Pry.config.exception_whitelist = [NameError]
++    lambda { Pry.start(self, :input => StringIO.new("raise NameError"), :output => @str_output) }.should.raise NameError
++    Pry.config.exception_whitelist = old_whitelist
++  end
++end
++
++
+diff --git a/spec/fixtures/candidate_helper1.rb b/spec/fixtures/candidate_helper1.rb
+new file mode 100644
+index 0000000..46056a5
+--- /dev/null
++++ b/spec/fixtures/candidate_helper1.rb
+@@ -0,0 +1,11 @@
++# rank 0
++class CandidateTest
++  def test1
++  end
++
++  def test2
++  end
++
++  def test3
++  end
++end
+diff --git a/spec/fixtures/candidate_helper2.rb b/spec/fixtures/candidate_helper2.rb
+new file mode 100644
+index 0000000..ebc22a9
+--- /dev/null
++++ b/spec/fixtures/candidate_helper2.rb
+@@ -0,0 +1,8 @@
++# rank 1
++class CandidateTest
++  def test4
++  end
++
++  def test5
++  end
++end
+diff --git a/spec/fixtures/cat_load_path b/spec/fixtures/cat_load_path
+new file mode 100644
+index 0000000..e69de29
+diff --git a/spec/fixtures/cat_load_path.rb b/spec/fixtures/cat_load_path.rb
+new file mode 100644
+index 0000000..e69de29
+diff --git a/spec/fixtures/example.erb b/spec/fixtures/example.erb
+new file mode 100644
+index 0000000..43c2efd
+--- /dev/null
++++ b/spec/fixtures/example.erb
+@@ -0,0 +1,5 @@
++<html>
++
++  Look at me, testing my erb!
++
++</html>
+diff --git a/spec/fixtures/example_nesting.rb b/spec/fixtures/example_nesting.rb
+new file mode 100644
+index 0000000..06c9050
+--- /dev/null
++++ b/spec/fixtures/example_nesting.rb
+@@ -0,0 +1,33 @@
++                                    # []
++class A                             # ["class A"]
++  def a; end                        # ["class A"]
++  class B; def b; end; end          # ["class A", "class B"]
++end                                 # []
++                                    # []
++class << A                          # ["class << A"]
++  class B                           # ["class << A", "class B"]
++    def c; end                      # ["class << A", "class B"]
++  end                               # ["class << A"]
++                                    # ["class << A"]
++  module F::B                       # ["class << A", "module F::B"]
++    def foo; end                    # ["class << A", "module F::B"]
++  end                               # ["class << A"]
++end                                 # []
++                                    # []
++module (:symbol.class)::Exciting    #
++  def foo; end                      #
++  class B                           #
++    def goo; end                    #
++  end                               #
++end                                 # []
++                                    # []
++module C                            # ["module C"]
++  class D                           # ["module C", "class D"]
++    def guh; foo.end; end           # ["module C", "class D"]
++  end                               # ["module C"]
++  def bar; :end; end                # ["module C"]
++  class << new.bar; end             # ["module C"]
++  class << new.bar; def f; end; end #
++                                    # ["module C"]
++  class << self; def mug; end; end  # ["module C", "class << self"]
++end                                 # []
+diff --git a/spec/fixtures/pry_history b/spec/fixtures/pry_history
+new file mode 100644
+index 0000000..6eb63d9
+--- /dev/null
++++ b/spec/fixtures/pry_history
+@@ -0,0 +1,3 @@
++:athos
++:porthos
++:aramis
+diff --git a/spec/fixtures/show_source_doc_examples.rb b/spec/fixtures/show_source_doc_examples.rb
+new file mode 100644
+index 0000000..90efc43
+--- /dev/null
++++ b/spec/fixtures/show_source_doc_examples.rb
+@@ -0,0 +1,22 @@
++# used by show_source_spec.rb and show_doc_spec.rb
++class TestClassForShowSource
++  #doc
++  def alpha
++  end
++end
++
++class TestClassForShowSourceClassEval
++  def alpha
++  end
++end
++
++class TestClassForShowSourceInstanceEval
++  def alpha
++  end
++end
++
++# The first definition (find the second one in show_doc_spec.rb).
++class TestClassForCandidatesOrder
++  def alpha
++  end
++end
+diff --git a/spec/fixtures/slinky.rb b/spec/fixtures/slinky.rb
+new file mode 100644
+index 0000000..e69de29
+diff --git a/spec/fixtures/slinky/stinky.rb b/spec/fixtures/slinky/stinky.rb
+new file mode 100644
+index 0000000..e69de29
+diff --git a/spec/fixtures/testlinkrc b/spec/fixtures/testlinkrc
+new file mode 120000
+index 0000000..a307d52
+--- /dev/null
++++ b/spec/fixtures/testlinkrc
+@@ -0,0 +1 @@
++testrc
+\ No newline at end of file
+diff --git a/spec/fixtures/testrc b/spec/fixtures/testrc
+new file mode 100644
+index 0000000..c1045c0
+--- /dev/null
++++ b/spec/fixtures/testrc
+@@ -0,0 +1,2 @@
++TEST_RC = [] if !Object.const_defined?(:TEST_RC)
++TEST_RC << 0
+diff --git a/spec/fixtures/testrcbad b/spec/fixtures/testrcbad
+new file mode 100644
+index 0000000..fad9f73
+--- /dev/null
++++ b/spec/fixtures/testrcbad
+@@ -0,0 +1,2 @@
++TEST_BEFORE_RAISE = 1
++raise "messin with ya"
+diff --git a/spec/fixtures/whereami_helper.rb b/spec/fixtures/whereami_helper.rb
+new file mode 100644
+index 0000000..661e932
+--- /dev/null
++++ b/spec/fixtures/whereami_helper.rb
+@@ -0,0 +1,6 @@
++class Cor
++  def a; end
++  def b; end
++  def c; end
++  def d; end
++end
+diff --git a/spec/helper.rb b/spec/helper.rb
+new file mode 100644
+index 0000000..b579d8c
+--- /dev/null
++++ b/spec/helper.rb
+@@ -0,0 +1,34 @@
++require 'bundler/setup'
++require 'pry/test/helper'
++Bundler.require :default, :test
++require_relative 'spec_helpers/bacon'
++require_relative 'spec_helpers/mock_pry'
++require_relative 'spec_helpers/repl_tester'
++
++if ENV["COVERAGE"]
++  require "simplecov"
++  SimpleCov.start
++end
++
++class Module
++  public :remove_const
++  public :remove_method
++end
++
++# turn warnings off (esp for Pry::Hooks which will generate warnings
++# in tests)
++$VERBOSE = nil
++
++Pad = Class.new do
++  include Pry::Config::Behavior
++end.new(nil)
++
++# to help with tracking down bugs that cause an infinite loop in the test suite
++if ENV["SET_TRACE_FUNC"]
++  require 'set_trace' if Pry::Helpers::BaseHelpers.rbx?
++  set_trace_func proc { |event, file, line, id, binding, classname|
++     STDERR.printf "%8s %s:%-2d %10s %8s\n", event, file, line, id, classname
++  }
++end
++
++puts "Ruby v#{RUBY_VERSION} (#{defined?(RUBY_ENGINE) ? RUBY_ENGINE : "ruby"}), Pry v#{Pry::VERSION}, method_source v#{MethodSource::VERSION}, CodeRay v#{CodeRay::VERSION}, Slop v#{Slop::VERSION}"
+diff --git a/spec/helpers/table_spec.rb b/spec/helpers/table_spec.rb
+new file mode 100644
+index 0000000..5b8dbc9
+--- /dev/null
++++ b/spec/helpers/table_spec.rb
+@@ -0,0 +1,105 @@
++require_relative '../helper'
++
++describe 'Formatting Table' do
++  it 'knows about colorized fitting' do
++    t = Pry::Helpers::Table.new %w(hihi), :column_count => 1
++    t.fits_on_line?(4).should == true
++    t.items = []
++    t.fits_on_line?(4).should == true
++
++    t.items = %w(hi hi)
++    t.fits_on_line?(4).should == true
++    t.column_count = 2
++    t.fits_on_line?(4).should == false
++
++    t.items = %w(
++      a   ccc
++      bb  dddd
++    ).sort
++    t.fits_on_line?(8).should == true
++    t.fits_on_line?(7).should == false
++  end
++
++  describe 'formatting - should order downward and wrap to columns' do
++    FAKE_COLUMNS = 62
++    def try_round_trip(expected)
++      things = expected.split(/\s+/).sort
++      actual = Pry::Helpers.tablify(things, FAKE_COLUMNS).to_s.strip
++      [expected, actual].each{|e| e.gsub! /\s+$/, ''}
++      if actual != expected
++        bar = '-'*25
++        puts \
++          bar+'expected'+bar,
++          expected,
++          bar+'actual'+bar,
++          actual
++      end
++      actual.should == expected
++    end
++
++    it 'should handle a tiny case' do
++      try_round_trip(<<-eot)
++asdf  asfddd  fdass
++      eot
++    end
++
++    it 'should handle the basic case' do
++      try_round_trip(<<-eot)
++aadd            ddasffssdad  sdsaadaasd      ssfasaafssd
++adassdfffaasds  f            sdsfasddasfds   ssssdaa
++assfsafsfsds    fsasa        ssdsssafsdasdf
++      eot
++    end
++
++    it 'should handle... another basic case' do
++      try_round_trip(<<-EOT)
++aaad            dasaasffaasf    fdasfdfss       safdfdddsasd
++aaadfasassdfff  ddadadassasdf   fddsasadfssdss  sasf
++aaddaafaf       dddasaaaaaa     fdsasad         sddsa
++aas             dfsddffdddsdfd  ff              sddsfsaa
++adasadfaaffds   dsfafdsfdfssda  ffadsfafsaafa   ss
++asddaadaaadfdd  dssdss          ffssfsfafaadss  ssas
++asdsdaa         faadf           fsddfff         ssdfssff
++asfadsssaaad    fasfaafdssd     s
++      EOT
++    end
++
++    it 'should handle colors' do
++      try_round_trip(<<-EOT)
++\e[31maaaaaaaaaa\e[0m                      \e[31mccccccccccccccccccccccccccccc\e[0m
++\e[31mbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\e[0m  \e[31mddddddddddddd\e[0m
++      EOT
++    end
++
++    it 'should handle empty input' do
++      try_round_trip('')
++    end
++
++    it 'should handle one-token input' do
++      try_round_trip('asdf')
++    end
++  end
++
++  describe 'line length is smaller than the length of the longest word' do
++    before do
++      element = 'swizzle'
++      @elem_len = element.length
++      @out = [element, 'crime', 'fun']
++    end
++
++    it 'should not raise error' do
++      should.not.raise(FloatDomainError) {
++        Pry::Helpers.tablify(@out, @elem_len - 1)
++      }
++    end
++
++    it 'should format output as one column' do
++      table = Pry::Helpers.tablify(@out, @elem_len - 1).to_s
++      table.should == "swizzle\ncrime  \nfun    "
++    end
++  end
++
++  describe 'decide between one-line or indented output' do
++    Pry::Helpers.tablify_or_one_line('head', %w(ing)).should == 'head:  ing'
++  end
++end
+diff --git a/spec/history_array_spec.rb b/spec/history_array_spec.rb
+new file mode 100644
+index 0000000..3f392bb
+--- /dev/null
++++ b/spec/history_array_spec.rb
+@@ -0,0 +1,71 @@
++require_relative 'helper'
++
++describe Pry::HistoryArray do
++  before do
++    @array = Pry::HistoryArray.new 10
++    @populated = @array.dup << 1 << 2 << 3 << 4
++  end
++
++  it 'should have a maximum size specifed at creation time' do
++    @array.max_size.should == 10
++  end
++
++  it 'should be able to be added objects to' do
++    @populated.size.should == 4
++    @populated.to_a.should == [1, 2, 3, 4]
++  end
++
++  it 'should be able to access single elements' do
++    @populated[2].should == 3
++  end
++
++  it 'should be able to access negative indices' do
++    @populated[-1].should == 4
++  end
++
++  it 'should be able to access ranges' do
++    @populated[1..2].should == [2, 3]
++  end
++
++  it 'should be able to access ranges starting from a negative index' do
++    @populated[-2..3].should == [3, 4]
++  end
++
++  it 'should be able to access ranges ending at a negative index' do
++    @populated[2..-1].should == [3, 4]
++  end
++
++  it 'should be able to access ranges using only negative indices' do
++    @populated[-2..-1].should == [3, 4]
++  end
++
++  it 'should be able to use range where end is excluded' do
++    @populated[-2...-1].should == [3]
++  end
++
++  it 'should be able to access slices using a size' do
++    @populated[-3, 2].should == [2, 3]
++  end
++
++  it 'should remove older entries' do
++    11.times { |n| @array << n }
++
++    @array[0].should  == nil
++    @array[1].should  == 1
++    @array[10].should == 10
++  end
++
++  it 'should not be larger than specified maximum size' do
++    12.times { |n| @array << n }
++    @array.entries.compact.size.should == 10
++  end
++
++  it 'should pop!' do
++    @populated.pop!
++    @populated.to_a.should == [1, 2, 3]
++  end
++
++  it 'should return an indexed hash' do
++    @populated.to_h[0].should == @populated[0]
++  end
++end
+diff --git a/spec/history_spec.rb b/spec/history_spec.rb
+new file mode 100644
+index 0000000..0a7c66d
+--- /dev/null
++++ b/spec/history_spec.rb
+@@ -0,0 +1,154 @@
++require_relative 'helper'
++require 'tempfile'
++
++describe Pry do
++  before do
++    Pry.history.clear
++
++    @saved_history = "1\n2\n3\n"
++
++    Pry.history.loader = proc do |&blk|
++      @saved_history.lines.each { |l| blk.call(l) }
++    end
++
++    Pry.load_history
++  end
++
++  after do
++    Pry.history.clear
++    Pry.history.restore_default_behavior
++    Pry.history.instance_variable_set(:@original_lines, 0)
++  end
++
++  describe '#push' do
++    it "should not record duplicated lines" do
++      Pry.history << '3'
++      Pry.history << '_ += 1'
++      Pry.history << '_ += 1'
++      Pry.history.to_a.grep('_ += 1').count.should == 1
++    end
++
++    it "should not record empty lines" do
++      c = Pry.history.to_a.count
++      Pry.history << ''
++      Pry.history.to_a.count.should == c
++    end
++  end
++
++  describe "#clear" do
++    before do
++      @old_file = Pry.config.history.file
++      @hist_file_path = File.expand_path('spec/fixtures/pry_history')
++      Pry.config.history.file = @hist_file_path
++      Pry.history.clear
++      Pry.history.restore_default_behavior
++      Pry.load_history
++    end
++
++    after do
++      Pry.config.history.file = @old_file
++    end
++
++    it "clears this session's history" do
++      Pry.history.to_a.size.should > 0
++      Pry.history.clear
++      Pry.history.to_a.size.should == 0
++    end
++
++    it "doesn't affect the contents of the history file" do
++      Pry.history.to_a.size.should == 3
++      Pry.history.clear
++
++      File.open(@hist_file_path, 'r') { |fh|
++        file = fh.to_a
++
++        file.length.should == 3
++        file.any? { |a| a =~ /athos/ }.should == true
++      }
++    end
++  end
++
++  describe "#history_line_count" do
++    it "counts entries in history" do
++      Pry.history.clear
++      saved_history = "olgierd\ngustlik\njanek\ngrzes\ntomek\n"
++      Pry.history.loader = proc do |&blk|
++        saved_history.lines.each { |l| blk.call(l) }
++      end
++      Pry.load_history
++
++      Pry.history.history_line_count.should == 5
++    end
++  end
++
++  describe "#restore_default_behavior" do
++    it "restores loader" do
++      Pry.history.loader = proc {}
++      Pry.history.restore_default_behavior
++      Pry.history.loader.class.should == Method
++      Pry.history.loader.name.to_sym.should == :read_from_file
++    end
++
++    it "restores saver" do
++      Pry.history.saver = proc {}
++      Pry.history.restore_default_behavior
++      Pry.history.saver.class.should == Method
++      Pry.history.saver.name.to_sym.should == :save_to_file
++    end
++
++    it "restores pusher" do
++      Pry.history.pusher = proc {}
++      Pry.history.restore_default_behavior
++      Pry.history.pusher.class.should == Method
++      Pry.history.pusher.name.to_sym.should == :push_to_readline
++    end
++
++    it "restores clearer" do
++      Pry.history.clearer = proc {}
++      Pry.history.restore_default_behavior
++      Pry.history.clearer.class.should == Method
++      Pry.history.clearer.name.to_sym.should == :clear_readline
++    end
++  end
++
++  describe "#session_line_count" do
++    it "returns the number of lines in history from just this session" do
++      Pry.history << 'you?'
++      Pry.history << 'you are so precious'
++      Pry.history.session_line_count.should == 2
++    end
++  end
++
++  describe ".load_history" do
++    it "should read the contents of the file" do
++      Pry.history.to_a[-2..-1].should == %w(2 3)
++    end
++  end
++
++  describe "saving to a file" do
++    before do
++      @histfile = Tempfile.new(["pryhistory", "txt"])
++      @history = Pry::History.new(:file_path => @histfile.path)
++      Pry.config.history.should_save = true
++      @history.pusher = proc{ }
++    end
++
++    after do
++      @histfile.close(true)
++      Pry.config.history.should_save = false
++    end
++
++    it "should save lines to a file as they are written" do
++      @history.push "5"
++      File.read(@histfile.path).should == "5\n"
++    end
++
++    it "should interleave lines from many places" do
++      @history.push "5"
++      File.open(@histfile.path, 'a'){ |f| f.puts "6" }
++      @history.push "7"
++
++      File.read(@histfile.path).should == "5\n6\n7\n"
++    end
++  end
++end
+diff --git a/spec/hooks_spec.rb b/spec/hooks_spec.rb
+new file mode 100644
+index 0000000..ba28ce6
+--- /dev/null
++++ b/spec/hooks_spec.rb
+@@ -0,0 +1,475 @@
++require_relative 'helper'
++
++describe Pry::Hooks do
++  before do
++    @hooks = Pry::Hooks.new
++  end
++
++  describe "adding a new hook" do
++    it 'should not execute hook while adding it' do
++      run = false
++      @hooks.add_hook(:test_hook, :my_name) { run = true }
++      run.should == false
++    end
++
++    it 'should not allow adding of a hook with a duplicate name' do
++      @hooks.add_hook(:test_hook, :my_name) {}
++
++      lambda { @hooks.add_hook(:test_hook, :my_name) {} }.should.raise ArgumentError
++    end
++
++    it 'should create a new hook with a block' do
++      @hooks.add_hook(:test_hook, :my_name) { }
++      @hooks.hook_count(:test_hook).should == 1
++    end
++
++    it 'should create a new hook with a callable' do
++      @hooks.add_hook(:test_hook, :my_name, proc { })
++      @hooks.hook_count(:test_hook).should == 1
++    end
++
++    it 'should use block if given both block and callable' do
++      run = false
++      foo = false
++      @hooks.add_hook(:test_hook, :my_name, proc { foo = true }) { run = true }
++      @hooks.hook_count(:test_hook).should == 1
++      @hooks.exec_hook(:test_hook)
++      run.should == true
++      foo.should == false
++    end
++
++    it 'should raise if not given a block or any other object' do
++      lambda { @hooks.add_hook(:test_hook, :my_name) }.should.raise ArgumentError
++    end
++
++    it 'should create multiple hooks for an event' do
++      @hooks.add_hook(:test_hook, :my_name) {}
++      @hooks.add_hook(:test_hook, :my_name2) {}
++      @hooks.hook_count(:test_hook).should == 2
++    end
++
++    it 'should return a count of 0 for an empty hook' do
++      @hooks.hook_count(:test_hook).should == 0
++    end
++  end
++
++  describe "Pry::Hooks#merge" do
++    describe "merge!" do
++      it 'should merge in the Pry::Hooks' do
++        h1 = Pry::Hooks.new.add_hook(:test_hook, :testing) {}
++        h2 = Pry::Hooks.new
++
++        h2.merge!(h1)
++        h2.get_hook(:test_hook, :testing).should == h1.get_hook(:test_hook, :testing)
++      end
++
++      it 'should not share merged elements with original' do
++        h1 = Pry::Hooks.new.add_hook(:test_hook, :testing) {}
++        h2 = Pry::Hooks.new
++
++        h2.merge!(h1)
++        h2.add_hook(:test_hook, :testing2) {}
++        h2.get_hook(:test_hook, :testing2).should.not == h1.get_hook(:test_hook, :testing2)
++      end
++
++      it 'should NOT overwrite hooks belonging to shared event in receiver' do
++        h1 = Pry::Hooks.new.add_hook(:test_hook, :testing) {}
++        callable = proc {}
++        h2 = Pry::Hooks.new.add_hook(:test_hook, :testing2, callable)
++
++        h2.merge!(h1)
++        h2.get_hook(:test_hook, :testing2).should == callable
++      end
++
++      it 'should overwrite identical hook in receiver' do
++        callable1 = proc { :one }
++        h1 = Pry::Hooks.new.add_hook(:test_hook, :testing, callable1)
++        callable2 = proc { :two }
++        h2 = Pry::Hooks.new.add_hook(:test_hook, :testing, callable2)
++
++        h2.merge!(h1)
++        h2.get_hook(:test_hook, :testing).should == callable1
++        h2.hook_count(:test_hook).should == 1
++      end
++
++      it 'should preserve hook order' do
++        name = ""
++        h1 = Pry::Hooks.new
++        h1.add_hook(:test_hook, :testing3) { name << "h" }
++        h1.add_hook(:test_hook, :testing4) { name << "n" }
++
++        h2 = Pry::Hooks.new
++        h2.add_hook(:test_hook, :testing1) { name << "j" }
++        h2.add_hook(:test_hook, :testing2) { name << "o" }
++
++        h2.merge!(h1)
++        h2.exec_hook(:test_hook)
++
++        name.should == "john"
++      end
++
++      describe "merge" do
++        it 'should return a fresh, independent instance' do
++          h1 = Pry::Hooks.new.add_hook(:test_hook, :testing) {}
++          h2 = Pry::Hooks.new
++
++          h3 = h2.merge(h1)
++          h3.should.not == h1
++          h3.should.not == h2
++        end
++
++        it 'should contain hooks from original instance' do
++          h1 = Pry::Hooks.new.add_hook(:test_hook, :testing) {}
++          h2 = Pry::Hooks.new.add_hook(:test_hook2, :testing) {}
++
++          h3 = h2.merge(h1)
++          h3.get_hook(:test_hook, :testing).should == h1.get_hook(:test_hook, :testing)
++          h3.get_hook(:test_hook2, :testing).should == h2.get_hook(:test_hook2, :testing)
++        end
++
++        it 'should not affect original instances when new hooks are added' do
++          h1 = Pry::Hooks.new.add_hook(:test_hook, :testing) {}
++          h2 = Pry::Hooks.new.add_hook(:test_hook2, :testing) {}
++
++          h3 = h2.merge(h1)
++          h3.add_hook(:test_hook3, :testing) {}
++
++          h1.get_hook(:test_hook3, :testing).should == nil
++          h2.get_hook(:test_hook3, :testing).should == nil
++        end
++      end
++
++    end
++  end
++
++  describe "dupping a Pry::Hooks instance" do
++    it 'should share hooks with original' do
++      @hooks.add_hook(:test_hook, :testing) do
++        :none_such
++      end
++
++      hooks_dup = @hooks.dup
++      hooks_dup.get_hook(:test_hook, :testing).should == @hooks.get_hook(:test_hook, :testing)
++    end
++
++    it 'adding a new event to dupped instance should not affect original' do
++      @hooks.add_hook(:test_hook, :testing) { :none_such }
++      hooks_dup = @hooks.dup
++
++      hooks_dup.add_hook(:other_test_hook, :testing) { :okay_man }
++
++      hooks_dup.get_hook(:other_test_hook, :testing).should.not == @hooks.get_hook(:other_test_hook, :testing)
++    end
++
++    it 'adding a new hook to dupped instance should not affect original' do
++      @hooks.add_hook(:test_hook, :testing) { :none_such }
++      hooks_dup = @hooks.dup
++
++      hooks_dup.add_hook(:test_hook, :testing2) { :okay_man }
++
++      hooks_dup.get_hook(:test_hook, :testing2).should.not == @hooks.get_hook(:test_hook, :testing2)
++    end
++
++  end
++
++  describe "getting hooks" do
++    describe "get_hook" do
++      it 'should return the correct requested hook' do
++        run = false
++        fun = false
++        @hooks.add_hook(:test_hook, :my_name) { run = true }
++        @hooks.add_hook(:test_hook, :my_name2) { fun = true }
++        @hooks.get_hook(:test_hook, :my_name).call
++        run.should == true
++        fun.should == false
++      end
++
++      it 'should return nil if hook does not exist' do
++        @hooks.get_hook(:test_hook, :my_name).should == nil
++      end
++    end
++
++    describe "get_hooks" do
++      it 'should return a hash of hook names/hook functions for an event' do
++        hook1 = proc { 1 }
++        hook2 = proc { 2 }
++        @hooks.add_hook(:test_hook, :my_name1, hook1)
++        @hooks.add_hook(:test_hook, :my_name2, hook2)
++        hash = @hooks.get_hooks(:test_hook)
++        hash.size.should == 2
++        hash[:my_name1].should == hook1
++        hash[:my_name2].should == hook2
++      end
++
++      it 'should return an empty hash if no hooks defined' do
++        @hooks.get_hooks(:test_hook).should == {}
++      end
++    end
++  end
++
++  describe "clearing all hooks for an event" do
++    it 'should clear all hooks' do
++      @hooks.add_hook(:test_hook, :my_name) { }
++      @hooks.add_hook(:test_hook, :my_name2) { }
++      @hooks.add_hook(:test_hook, :my_name3) { }
++      @hooks.clear(:test_hook)
++      @hooks.hook_count(:test_hook).should == 0
++    end
++  end
++
++  describe "deleting a hook" do
++    it 'should successfully delete a hook' do
++      @hooks.add_hook(:test_hook, :my_name) {}
++      @hooks.delete_hook(:test_hook, :my_name)
++      @hooks.hook_count(:test_hook).should == 0
++    end
++
++    it 'should return the deleted hook' do
++      run = false
++      @hooks.add_hook(:test_hook, :my_name) { run = true }
++      @hooks.delete_hook(:test_hook, :my_name).call
++      run.should == true
++    end
++
++    it 'should return nil if hook does not exist' do
++      @hooks.delete_hook(:test_hook, :my_name).should == nil
++    end
++  end
++
++  describe "executing a hook" do
++    it 'should execute block hook' do
++      run = false
++      @hooks.add_hook(:test_hook, :my_name) { run = true }
++      @hooks.exec_hook(:test_hook)
++      run.should == true
++    end
++
++    it 'should execute proc hook' do
++      run = false
++      @hooks.add_hook(:test_hook, :my_name, proc { run = true })
++      @hooks.exec_hook(:test_hook)
++      run.should == true
++    end
++
++    it 'should execute a general callable hook' do
++      callable = Object.new.tap do |obj|
++        obj.instance_variable_set(:@test_var, nil)
++        class << obj
++          attr_accessor :test_var
++          def call() @test_var = true; end
++        end
++      end
++
++      @hooks.add_hook(:test_hook, :my_name, callable)
++      @hooks.exec_hook(:test_hook)
++      callable.test_var.should == true
++    end
++
++    it 'should execute all hooks for an event if more than one is defined' do
++      x = nil
++      y = nil
++      @hooks.add_hook(:test_hook, :my_name1) { y = true }
++      @hooks.add_hook(:test_hook, :my_name2) { x = true }
++      @hooks.exec_hook(:test_hook)
++      x.should == true
++      y.should == true
++    end
++
++    it 'should execute hooks in order' do
++      array = []
++      @hooks.add_hook(:test_hook, :my_name1) { array << 1 }
++      @hooks.add_hook(:test_hook, :my_name2) { array << 2 }
++      @hooks.add_hook(:test_hook, :my_name3) { array << 3 }
++      @hooks.exec_hook(:test_hook)
++      array.should == [1, 2, 3]
++    end
++
++    it 'return value of exec_hook should be that of last executed hook' do
++      @hooks.add_hook(:test_hook, :my_name1) { 1 }
++      @hooks.add_hook(:test_hook, :my_name2) { 2 }
++      @hooks.add_hook(:test_hook, :my_name3) { 3 }
++      @hooks.exec_hook(:test_hook).should == 3
++    end
++
++    it 'should add exceptions to the errors array' do
++      @hooks.add_hook(:test_hook, :foo1) { raise 'one' }
++      @hooks.add_hook(:test_hook, :foo2) { raise 'two' }
++      @hooks.add_hook(:test_hook, :foo3) { raise 'three' }
++      @hooks.exec_hook(:test_hook)
++      @hooks.errors.map(&:message).should == ['one', 'two', 'three']
++    end
++
++    it 'should return the last exception raised as the return value' do
++      @hooks.add_hook(:test_hook, :foo1) { raise 'one' }
++      @hooks.add_hook(:test_hook, :foo2) { raise 'two' }
++      @hooks.add_hook(:test_hook, :foo3) { raise 'three' }
++      @hooks.exec_hook(:test_hook).should == @hooks.errors.last
++    end
++  end
++
++  describe "integration tests" do
++    describe "when_started hook" do
++      it 'should yield options to the hook' do
++        options = nil
++        Pry.config.hooks.add_hook(:when_started, :test_hook) { |target, opt, _| options = opt }
++
++        redirect_pry_io(StringIO.new("exit"), out=StringIO.new) do
++          Pry.start binding, :hello => :baby
++        end
++
++        options[:hello].should == :baby
++
++        Pry.config.hooks.delete_hook(:when_started, :test_hook)
++      end
++
++      describe "target" do
++
++        it 'should yield the target, as a binding ' do
++          b = nil
++          Pry.config.hooks.add_hook(:when_started, :test_hook) { |target, opt, _| b = target }
++
++          redirect_pry_io(StringIO.new("exit"), out=StringIO.new) do
++            Pry.start 5, :hello => :baby
++          end
++
++          b.is_a?(Binding).should == true
++          Pry.config.hooks.delete_hook(:when_started, :test_hook)
++        end
++
++        it 'should yield the target to the hook' do
++          b = nil
++          Pry.config.hooks.add_hook(:when_started, :test_hook) { |target, opt, _| b = target }
++
++          redirect_pry_io(StringIO.new("exit"), out=StringIO.new) do
++            Pry.start 5, :hello => :baby
++          end
++
++          b.eval('self').should == 5
++          Pry.config.hooks.delete_hook(:when_started, :test_hook)
++        end
++      end
++
++      it 'should allow overriding of target (and binding_stack)' do
++        options = nil
++        o = Object.new
++        class << o; attr_accessor :value; end
++
++        Pry.config.hooks.add_hook(:when_started, :test_hook) { |target, opt, _pry_| _pry_.binding_stack = [Pry.binding_for(o)] }
++
++        redirect_pry_io(InputTester.new("@value = true","exit-all")) do
++          Pry.start binding, :hello => :baby
++        end
++
++        o.value.should == true
++        Pry.config.hooks.delete_hook(:when_started, :test_hook)
++      end
++
++    end
++
++    describe "after_session hook" do
++      it 'should always run, even if uncaught exception bubbles out of repl' do
++        o = OpenStruct.new
++        o.great_escape = Class.new(StandardError)
++
++        old_ew = Pry.config.exception_whitelist
++        Pry.config.exception_whitelist << o.great_escape
++
++        array = [1, 2, 3, 4, 5]
++
++        begin
++          redirect_pry_io(StringIO.new("raise great_escape"), out=StringIO.new) do
++            Pry.start o, :hooks => Pry::Hooks.new.add_hook(:after_session, :cleanup) { array = nil }
++          end
++        rescue => ex
++          exception = ex
++        end
++
++        # ensure that an exception really was raised and it broke out
++        # of the repl
++        exception.is_a?(o.great_escape).should == true
++
++        # check that after_session hook ran
++        array.should == nil
++
++        # cleanup after test
++        Pry.config.exception_whitelist = old_ew
++      end
++
++      describe "before_eval hook" do
++        describe "modifying input code" do
++          it 'should replace input code with code determined by hook' do
++            hooks = Pry::Hooks.new.add_hook(:before_eval, :quirk) { |code, pry| code.replace(":little_duck") }
++            redirect_pry_io(InputTester.new(":jemima", "exit-all"), out = StringIO.new) do
++              Pry.start(self, :hooks => hooks)
++            end
++            out.string.should =~ /little_duck/
++            out.string.should.not =~ /jemima/
++          end
++
++          it 'should not interfere with command processing when replacing input code' do
++            commands = Pry::CommandSet.new do
++              import_from Pry::Commands, "exit-all"
++
++              command "how-do-you-like-your-blue-eyed-boy-now-mister-death" do
++                output.puts "in hours of bitterness i imagine balls of sapphire, of metal"
++              end
++            end
++
++            hooks = Pry::Hooks.new.add_hook(:before_eval, :quirk) { |code, pry| code.replace(":little_duck") }
++            redirect_pry_io(InputTester.new("how-do-you-like-your-blue-eyed-boy-now-mister-death", "exit-all"), out = StringIO.new) do
++              Pry.start(self, :hooks => hooks, :commands => commands)
++            end
++            out.string.should =~ /in hours of bitterness i imagine balls of sapphire, of metal/
++            out.string.should.not =~ /little_duck/
++          end
++        end
++
++      end
++
++      describe "exceptions" do
++        before do
++          Pry.config.hooks.add_hook(:after_eval, :baddums){ raise "Baddums" }
++          Pry.config.hooks.add_hook(:after_eval, :simbads){ raise "Simbads" }
++        end
++
++        after do
++          Pry.config.hooks.delete_hook(:after_eval, :baddums)
++          Pry.config.hooks.delete_hook(:after_eval, :simbads)
++        end
++        it "should not raise exceptions" do
++          lambda{
++            mock_pry("1", "2", "3")
++          }.should.not.raise
++        end
++
++        it "should print out a notice for each exception raised" do
++          mock_pry("1").should =~ /after_eval hook failed: RuntimeError: Baddums\n.*after_eval hook failed: RuntimeError: Simbads/m
++        end
++      end
++    end
++  end
++
++  describe "anonymous hooks" do
++    it 'should allow adding of hook without a name' do
++      @hooks.add_hook(:test_hook, nil) {}
++      @hooks.hook_count(:test_hook).should == 1
++    end
++
++    it 'should only allow one anonymous hook to exist' do
++      @hooks.add_hook(:test_hook, nil) {  }
++      @hooks.add_hook(:test_hook, nil) {  }
++      @hooks.hook_count(:test_hook).should == 1
++    end
++
++    it 'should execute most recently added anonymous hook' do
++      x = nil
++      y = nil
++      @hooks.add_hook(:test_hook, nil) { y = 1 }
++      @hooks.add_hook(:test_hook, nil) { x = 2 }
++      @hooks.exec_hook(:test_hook)
++      y.should == nil
++      x.should == 2
++    end
++  end
++
++end
+diff --git a/spec/indent_spec.rb b/spec/indent_spec.rb
+new file mode 100644
+index 0000000..6be0270
+--- /dev/null
++++ b/spec/indent_spec.rb
+@@ -0,0 +1,301 @@
++require_relative 'helper'
++
++# Please keep in mind that any hash signs ("#") in the heredoc strings are
++# placed on purpose. Without these editors might remove the whitespace on empty
++# lines.
++describe Pry::Indent do
++  before do
++    @indent = Pry::Indent.new
++  end
++
++  it 'should indent an array' do
++    input  = "array = [\n10,\n15\n]"
++    output = "array = [\n  10,\n  15\n]"
++
++    @indent.indent(input).should == output
++  end
++
++  it 'should indent a hash' do
++    input  = "hash = {\n:name => 'Ruby'\n}"
++    output = "hash = {\n  :name => 'Ruby'\n}"
++
++    @indent.indent(input).should == output
++  end
++
++  it 'should indent a function' do
++    input  = "def\nreturn 10\nend"
++    output = "def\n  return 10\nend"
++
++    @indent.indent(input).should == output
++  end
++
++  it 'should indent a module and class' do
++    input        = "module Foo\n# Hello world\nend"
++    output       = "module Foo\n  # Hello world\nend"
++    input_class  = "class Foo\n# Hello world\nend"
++    output_class = "class Foo\n  # Hello world\nend"
++
++    @indent.indent(input).should       == output
++    @indent.indent(input_class).should == output_class
++  end
++
++  it 'should indent separate lines' do
++    @indent.indent('def foo').should   == 'def foo'
++    @indent.indent('return 10').should == '  return 10'
++    @indent.indent('end').should       == 'end'
++  end
++
++  it 'should not indent single line statements' do
++    input = <<TXT.strip
++def hello; end
++puts "Hello"
++TXT
++
++    @indent.indent(input).should == input
++  end
++
++  it 'should handle multiple open and closing tokens on a line' do
++    input = <<TXT.strip
++[10, 15].each do |num|
++puts num
++end
++TXT
++
++    output = <<TXT.strip
++[10, 15].each do |num|
++  puts num
++end
++TXT
++
++    @indent.indent(input).should == output
++  end
++
++  it 'should properly indent nested code' do
++    input = <<TXT.strip
++module A
++module B
++class C
++attr_accessor :test
++# keep
++def number
++return 10
++end
++end
++end
++end
++TXT
++
++    output = <<TXT.strip
++module A
++  module B
++    class C
++      attr_accessor :test
++      # keep
++      def number
++        return 10
++      end
++    end
++  end
++end
++TXT
++
++    @indent.indent(input).should == output
++  end
++
++  it 'should indent statements such as if, else, etc' do
++    input = <<TXT.strip
++if a == 10
++#
++elsif a == 15
++#
++else
++#
++end
++#
++while true
++#
++end
++#
++for num in [10, 15, 20]
++#
++end
++#
++for num in [10, 15, 20] do
++#
++end
++TXT
++
++    output = <<TXT.strip
++if a == 10
++  #
++elsif a == 15
++  #
++else
++  #
++end
++#
++while true
++  #
++end
++#
++for num in [10, 15, 20]
++  #
++end
++#
++for num in [10, 15, 20] do
++  #
++end
++TXT
++
++    @indent.indent(input).should == output
++  end
++
++  it "should correctly handle while <foo> do" do
++    input = "while 5 do\n5\nend"
++    @indent.indent(input).should == "while 5 do\n  5\nend"
++  end
++
++  it "should ident case statements" do
++    input = <<TXT.strip
++case foo
++when 1
++2
++when 2
++if 3
++4
++end
++when 5
++#
++else
++#
++end
++TXT
++
++ output = <<TXT.strip
++case foo
++when 1
++  2
++when 2
++  if 3
++    4
++  end
++when 5
++  #
++else
++  #
++end
++TXT
++
++    @indent.indent(input).should == output
++  end
++
++  it "should indent correctly with nesting" do
++    @indent.indent("[[\n[]]\n]").should == "[[\n  []]\n]"
++    @indent.reset.indent("[[\n[]]\n]").should == "[[\n  []]\n]"
++    @indent.reset.indent("[[{\n[] =>\n[]}]\n]").should == "[[{\n      [] =>\n  []}]\n]"
++  end
++
++  it "should not indent single-line ifs" do
++    @indent.indent("foo if bar\n#").should == "foo if bar\n#"
++    @indent.reset.indent("foo() if bar\n#").should == "foo() if bar\n#"
++    @indent.reset.indent("foo 'hi' if bar\n#").should == "foo 'hi' if bar\n#"
++    @indent.reset.indent("foo 1 while bar\n#").should == "foo 1 while bar\n#"
++    @indent.reset.indent("super if true\n#").should == "super if true\n#"
++    @indent.reset.indent("true if false\n#").should == "true if false\n#"
++    @indent.reset.indent("String if false\n#").should == "String if false\n#"
++  end
++
++  it "should indent cunningly disguised ifs" do
++    @indent.indent("{1 => if bar\n#").should == "{1 => if bar\n    #"
++    @indent.reset.indent("foo(if bar\n#").should == "foo(if bar\n    #"
++    @indent.reset.indent("bar(baz, if bar\n#").should == "bar(baz, if bar\n    #"
++    @indent.reset.indent("[if bar\n#").should == "[if bar\n    #"
++    @indent.reset.indent("true; while bar\n#").should == "true; while bar\n  #"
++  end
++
++  it "should differentiate single/multi-line unless" do
++    @indent.indent("foo unless bar\nunless foo\nbar\nend").should == "foo unless bar\nunless foo\n  bar\nend"
++  end
++
++  it "should not indent single/multi-line until" do
++    @indent.indent("%w{baz} until bar\nuntil foo\nbar\nend").should == "%w{baz} until bar\nuntil foo\n  bar\nend"
++  end
++
++  it "should indent begin rescue end" do
++    input = <<INPUT.strip
++begin
++doo :something => :wrong
++rescue => e
++doit :right
++end
++INPUT
++    output = <<OUTPUT.strip
++begin
++  doo :something => :wrong
++rescue => e
++  doit :right
++end
++OUTPUT
++
++    @indent.indent(input).should == output
++  end
++
++  it "should not indent inside strings" do
++    @indent.indent(%(def a\n"foo\nbar"\n  end)).should == %(def a\n  "foo\nbar"\nend)
++    @indent.indent(%(def a\nputs %w(foo\nbar), 'foo\nbar'\n  end)).should == %(def a\n  puts %w(foo\nbar), 'foo\nbar'\nend)
++  end
++
++  it "should not indent inside HEREDOCs" do
++    @indent.indent(%(def a\nputs <<FOO\n bar\nFOO\nbaz\nend)).should == %(def a\n  puts <<FOO\n bar\nFOO\n  baz\nend)
++    @indent.indent(%(def a\nputs <<-'^^'\n bar\n\t^^\nbaz\nend)).should == %(def a\n  puts <<-'^^'\n bar\n\t^^\n  baz\nend)
++  end
++
++  it "should not indent nested HEREDOCs" do
++    input = <<INPUT.strip
++def a
++puts <<FOO, <<-BAR, "baz", <<-':p'
++foo
++FOO
++bar
++BAR
++tongue
++:p
++puts :p
++end
++INPUT
++
++    output = <<OUTPUT.strip
++def a
++  puts <<FOO, <<-BAR, "baz", <<-':p'
++foo
++FOO
++bar
++BAR
++tongue
++:p
++  puts :p
++end
++OUTPUT
++
++    @indent.indent(input).should == output
++  end
++
++  describe "nesting" do
++      test = File.read("spec/fixtures/example_nesting.rb")
++
++      test.lines.each_with_index do |line, i|
++        result = line.split("#").last.strip
++        if result == ""
++          it "should fail to parse nesting on line #{i + 1} of example_nesting.rb" do
++            lambda {
++              Pry::Indent.nesting_at(test, i + 1)
++            }.should.raise(Pry::Indent::UnparseableNestingError)
++          end
++        else
++          it "should parse nesting on line #{i + 1} of example_nesting.rb" do
++            Pry::Indent.nesting_at(test, i + 1).should == eval(result)
++          end
++        end
++      end
++    end
++end
+diff --git a/spec/method/patcher_spec.rb b/spec/method/patcher_spec.rb
+new file mode 100644
+index 0000000..95b5f3e
+--- /dev/null
++++ b/spec/method/patcher_spec.rb
+@@ -0,0 +1,34 @@
++require_relative '../helper'
++
++describe Pry::Method::Patcher do
++
++  before do
++    @x = Object.new
++    def @x.test; :before; end
++    @method = Pry::Method(@x.method(:test))
++  end
++
++  it "should change the behaviour of the method" do
++    @x.test.should == :before
++    @method.redefine "def @x.test; :after; end\n"
++    @x.test.should == :after
++  end
++
++  it "should return a new method with new source" do
++    @method.source.strip.should == "def @x.test; :before; end"
++    @method.redefine("def @x.test; :after; end\n").
++      source.strip.should == "def @x.test; :after; end"
++  end
++
++  it "should change the source of new Pry::Method objects" do
++    @method.redefine "def @x.test; :after; end\n"
++    Pry::Method(@x.method(:test)).source.strip.should == "def @x.test; :after; end"
++  end
++
++  it "should preserve visibility" do
++    class << @x; private :test; end
++    @method.visibility.should == :private
++    @method.redefine "def @x.test; :after; end\n"
++    Pry::Method(@x.method(:test)).visibility.should == :private
++  end
++end
+diff --git a/spec/method_spec.rb b/spec/method_spec.rb
+new file mode 100644
+index 0000000..b667267
+--- /dev/null
++++ b/spec/method_spec.rb
+@@ -0,0 +1,507 @@
++require_relative 'helper'
++require 'set'
++
++describe Pry::Method do
++  it "should use String names for compatibility" do
++    klass = Class.new { def hello; end }
++    Pry::Method.new(klass.instance_method(:hello)).name.should == "hello"
++  end
++
++  describe ".from_str" do
++    it 'should look up instance methods if no methods available and no options provided' do
++      klass = Class.new { def hello; end }
++      meth = Pry::Method.from_str(:hello, Pry.binding_for(klass))
++      meth.should == klass.instance_method(:hello)
++    end
++
++    it 'should look up methods if no instance methods available and no options provided' do
++      klass = Class.new { def self.hello; end }
++      meth = Pry::Method.from_str(:hello, Pry.binding_for(klass))
++      meth.should == klass.method(:hello)
++    end
++
++    it 'should look up instance methods first even if methods available and no options provided' do
++      klass = Class.new { def hello; end; def self.hello; end  }
++      meth = Pry::Method.from_str(:hello, Pry.binding_for(klass))
++      meth.should == klass.instance_method(:hello)
++    end
++
++    it 'should look up instance methods if "instance-methods"  option provided' do
++      klass = Class.new { def hello; end; def self.hello; end  }
++      meth = Pry::Method.from_str(:hello, Pry.binding_for(klass), {"instance-methods" => true})
++      meth.should == klass.instance_method(:hello)
++    end
++
++    it 'should look up methods if :methods  option provided' do
++      klass = Class.new { def hello; end; def self.hello; end  }
++      meth = Pry::Method.from_str(:hello, Pry.binding_for(klass), {:methods => true})
++      meth.should == klass.method(:hello)
++    end
++
++    it 'should look up instance methods using the Class#method syntax' do
++      klass = Class.new { def hello; end; def self.hello; end  }
++      meth = Pry::Method.from_str("klass#hello", Pry.binding_for(binding))
++      meth.should == klass.instance_method(:hello)
++    end
++
++    it 'should look up methods using the object.method syntax' do
++      klass = Class.new { def hello; end; def self.hello; end  }
++      meth = Pry::Method.from_str("klass.hello", Pry.binding_for(binding))
++      meth.should == klass.method(:hello)
++    end
++
++    it 'should NOT look up instance methods using the Class#method syntax if no instance methods defined' do
++      klass = Class.new { def self.hello; end  }
++      meth = Pry::Method.from_str("klass#hello", Pry.binding_for(binding))
++      meth.should == nil
++    end
++
++    it 'should NOT look up methods using the object.method syntax if no methods defined' do
++      klass = Class.new { def hello; end  }
++      meth = Pry::Method.from_str("klass.hello", Pry.binding_for(binding))
++      meth.should == nil
++    end
++
++    it 'should look up methods using klass.new.method syntax' do
++      klass = Class.new { def hello; :hello; end }
++      meth = Pry::Method.from_str("klass.new.hello", Pry.binding_for(binding))
++      meth.name.should == "hello"
++    end
++
++    it 'should take care of corner cases like mongo[] e.g Foo::Bar.new[]- issue 998' do
++      klass = Class.new { def []; :hello; end }
++      meth = Pry::Method.from_str("klass.new[]", Pry.binding_for(binding))
++      meth.name.should == "[]"
++    end
++
++    it 'should take care of cases like $ mongo[] - issue 998' do
++      f = Class.new { def []; :hello; end }.new
++      meth = Pry::Method.from_str("f[]", Pry.binding_for(binding))
++      meth.name.should == "[]"
++    end
++
++    it 'should look up instance methods using klass.meth#method syntax' do
++      klass = Class.new { def self.meth; Class.new; end }
++      meth = Pry::Method.from_str("klass.meth#initialize", Pry.binding_for(binding))
++      meth.name.should == "initialize"
++    end
++
++    it 'should look up methods using instance::bar syntax' do
++      klass = Class.new{ def self.meth; Class.new; end }
++      meth = Pry::Method.from_str("klass::meth", Pry.binding_for(binding))
++      meth.name.should == "meth"
++    end
++
++    it 'should not raise an exception if receiver does not exist' do
++      lambda { Pry::Method.from_str("random_klass.meth", Pry.binding_for(binding)) }.should.not.raise
++    end
++  end
++
++  describe '.from_binding' do
++    it 'should be able to pick a method out of a binding' do
++      Pry::Method.from_binding(Class.new{ def self.foo; binding; end }.foo).name.should == "foo"
++    end
++
++    it 'should NOT find a method from the toplevel binding' do
++      Pry::Method.from_binding(TOPLEVEL_BINDING).should == nil
++    end
++
++    it "should find methods that have been undef'd" do
++      c = Class.new do
++        def self.bar
++          class << self; undef bar; end
++          binding
++        end
++      end
++
++      m = Pry::Method.from_binding(c.bar)
++      m.name.should == "bar"
++    end
++
++    # Our source_location trick doesn't work, due to https://github.com/rubinius/rubinius/issues/953
++    unless Pry::Helpers::BaseHelpers.rbx?
++       it 'should find the super method correctly' do
++        a = Class.new{ def gag33; binding; end; def self.line; __LINE__; end }
++        b = Class.new(a){ def gag33; super; end }
++
++        g = b.new.gag33
++        m = Pry::Method.from_binding(g)
++
++        m.owner.should == a
++        m.source_line.should == a.line
++        m.name.should == "gag33"
++      end
++    end
++
++    it 'should find the right method if a super method exists' do
++      a = Class.new{ def gag; binding; end; }
++      b = Class.new(a){ def gag; super; binding; end; def self.line; __LINE__; end }
++
++      m = Pry::Method.from_binding(b.new.gag)
++
++      m.owner.should == b
++      m.source_line.should == b.line
++      m.name.should == "gag"
++    end
++
++    # Temporarily disabled to work around rubinius/rubinius#2871.
++    unless Pry::Helpers::BaseHelpers.rbx?
++      it "should find the right method from a BasicObject" do
++        a = Class.new(BasicObject) { def gag; ::Kernel.binding; end; def self.line; __LINE__; end }
++
++        m = Pry::Method.from_binding(a.new.gag)
++        m.owner.should == a
++        m.source_file.should == __FILE__
++        m.source_line.should == a.line
++      end
++    end
++
++    it 'should find the right method even if it was renamed and replaced' do
++      o = Object.new
++      class << o
++        def borscht
++          "nips"
++          binding
++        end
++        alias paella borscht
++        def borscht() paella end
++      end
++
++      m = Pry::Method.from_binding(o.borscht)
++      m.source.should == Pry::Method(o.method(:paella)).source
++    end
++  end
++
++  describe 'super' do
++    it 'should be able to find the super method on a bound method' do
++      a = Class.new{ def rar; 4; end }
++      b = Class.new(a){ def rar; super; end }
++
++      obj = b.new
++
++      zuper = Pry::Method(obj.method(:rar)).super
++      zuper.owner.should == a
++      zuper.receiver.should == obj
++    end
++
++    it 'should be able to find the super method of an unbound method' do
++      a = Class.new{ def rar; 4; end }
++      b = Class.new(a){ def rar; super; end }
++
++      zuper = Pry::Method(b.instance_method(:rar)).super
++      zuper.owner.should == a
++    end
++
++    it 'should return nil if no super method exists' do
++      a = Class.new{ def rar; super; end }
++
++      Pry::Method(a.instance_method(:rar)).super.should == nil
++    end
++
++    it 'should be able to find super methods defined on modules' do
++      m = Module.new{ def rar; 4; end }
++      a = Class.new{ def rar; super; end; include m }
++
++      zuper = Pry::Method(a.new.method(:rar)).super
++      zuper.owner.should == m
++    end
++
++    it 'should be able to find super methods defined on super-classes when there are modules in the way' do
++      a = Class.new{ def rar; 4; end }
++      m = Module.new{ def mooo; 4; end }
++      b = Class.new(a){ def rar; super; end; include m }
++
++      zuper = Pry::Method(b.new.method(:rar)).super
++      zuper.owner.should == a
++    end
++
++    it 'should be able to jump up multiple levels of bound method, even through modules' do
++      a = Class.new{ def rar; 4; end }
++      m = Module.new{ def rar; 4; end }
++      b = Class.new(a){ def rar; super; end; include m }
++
++      zuper = Pry::Method(b.new.method(:rar)).super
++      zuper.owner.should == m
++      zuper.super.owner.should == a
++    end
++  end
++
++  describe 'all_from_class' do
++    def should_find_method(name)
++      Pry::Method.all_from_class(@class).map(&:name).should.include(name)
++    end
++
++    it 'should be able to find public instance methods defined in a class' do
++      @class = Class.new{ def meth; 1; end }
++      should_find_method('meth')
++    end
++
++    it 'should be able to find private and protected instance methods defined in a class' do
++      @class = Class.new { protected; def prot; 1; end; private; def priv; 1; end }
++      should_find_method('priv')
++      should_find_method('prot')
++    end
++
++    it 'should find methods all the way up to Kernel' do
++      @class = Class.new
++      should_find_method('exit!')
++    end
++
++    it 'should be able to find instance methods defined in a super-class' do
++      @class = Class.new(Class.new{ def meth; 1; end }) {}
++      should_find_method('meth')
++    end
++
++    it 'should be able to find instance methods defined in modules included into this class' do
++      @class = Class.new{ include Module.new{ def meth; 1; end; } }
++      should_find_method('meth')
++    end
++
++    it 'should be able to find instance methods defined in modules included into super-classes' do
++      @class = Class.new(Class.new{ include Module.new{ def meth; 1; end; } })
++      should_find_method('meth')
++    end
++
++    it 'should attribute overridden methods to the sub-class' do
++      @class = Class.new(Class.new{ include Module.new{ def meth; 1; end; } }) { def meth; 2; end }
++      Pry::Method.all_from_class(@class).detect{ |x| x.name == 'meth' }.owner.should == @class
++    end
++
++    it 'should be able to find methods defined on a singleton class' do
++      @class = (class << Object.new; def meth; 1; end; self; end)
++      should_find_method('meth')
++    end
++
++    it 'should be able to find methods on super-classes when given a singleton class' do
++      @class = (class << Class.new{ def meth; 1; end}.new; self; end)
++      should_find_method('meth')
++    end
++  end
++
++  describe 'all_from_obj' do
++    describe 'on normal objects' do
++      def should_find_method(name)
++        Pry::Method.all_from_obj(@obj).map(&:name).should.include(name)
++      end
++
++      it "should find methods defined in the object's class" do
++        @obj = Class.new{ def meth; 1; end }.new
++        should_find_method('meth')
++      end
++
++      it "should find methods defined in modules included into the object's class" do
++        @obj = Class.new{ include Module.new{ def meth; 1; end } }.new
++        should_find_method('meth')
++      end
++
++      it "should find methods defined in the object's singleton class" do
++        @obj = Object.new
++        class << @obj; def meth; 1; end; end
++        should_find_method('meth')
++      end
++
++      it "should find methods in modules included into the object's singleton class" do
++        @obj = Object.new
++        @obj.extend Module.new{ def meth; 1; end }
++        should_find_method('meth')
++      end
++
++      it "should find methods all the way up to Kernel" do
++        @obj = Object.new
++        should_find_method('exit!')
++      end
++
++      it "should not find methods defined on the classes singleton class" do
++        @obj = Class.new{ class << self; def meth; 1; end; end }.new
++        Pry::Method.all_from_obj(@obj).map(&:name).should.not.include('meth')
++      end
++
++      it "should work in the face of an overridden send" do
++        @obj = Class.new{ def meth; 1; end; def send; raise EOFError; end }.new
++        should_find_method('meth')
++      end
++    end
++
++    describe 'on classes' do
++      def should_find_method(name)
++        Pry::Method.all_from_obj(@class).map(&:name).should.include(name)
++      end
++
++      it "should find methods defined in the class' singleton class" do
++        @class = Class.new{ class << self; def meth; 1; end; end }
++        should_find_method('meth')
++      end
++
++      it "should find methods defined on modules extended into the class" do
++        @class = Class.new{ extend Module.new{ def meth; 1; end; } }
++        should_find_method('meth')
++      end
++
++      it "should find methods defined on the singleton class of super-classes" do
++        @class = Class.new(Class.new{ class << self; def meth; 1; end; end })
++        should_find_method('meth')
++      end
++
++      it "should not find methods defined within the class" do
++        @class = Class.new{ def meth; 1; end }
++        Pry::Method.all_from_obj(@obj).map(&:name).should.not.include('meth')
++      end
++
++      it "should find methods defined on Class" do
++        @class = Class.new
++        should_find_method('allocate')
++      end
++
++      it "should find methods defined on Kernel" do
++        @class = Class.new
++        should_find_method('exit!')
++      end
++
++      it "should attribute overridden methods to the sub-class' singleton class" do
++        @class = Class.new(Class.new{ class << self; def meth; 1; end; end }) { class << self; def meth; 1; end; end }
++        Pry::Method.all_from_obj(@class).detect{ |x| x.name == 'meth' }.owner.should == (class << @class; self; end)
++      end
++
++      it "should attrbute overridden methods to the class not the module" do
++        @class = Class.new { class << self; def meth; 1; end; end; extend Module.new{ def meth; 1; end; } }
++        Pry::Method.all_from_obj(@class).detect{ |x| x.name == 'meth' }.owner.should == (class << @class; self; end)
++      end
++
++      it "should attribute overridden methods to the relevant singleton class in preference to Class" do
++        @class = Class.new { class << self; def allocate; 1; end; end }
++        Pry::Method.all_from_obj(@class).detect{ |x| x.name == 'allocate' }.owner.should == (class << @class; self; end)
++      end
++    end
++
++    describe 'method resolution order' do
++      module LS
++        class Top; end
++
++        class Next < Top; end
++
++        module M; end
++        module N; include M; end
++        module O; include M; end
++        module P; end
++
++        class Low < Next; include N; include P; end
++        class Lower < Low; extend N; end
++        class Bottom < Lower; extend O; end
++      end
++
++      def singleton_class(obj); class << obj; self; end; end
++
++      it "should look at a class and then its superclass" do
++        Pry::Method.instance_resolution_order(LS::Next).should == [LS::Next] + Pry::Method.instance_resolution_order(LS::Top)
++      end
++
++      it "should include the included modules between a class and its superclass" do
++        Pry::Method.instance_resolution_order(LS::Low).should == [LS::Low, LS::P, LS::N, LS::M] + Pry::Method.instance_resolution_order(LS::Next)
++      end
++
++      it "should not include modules extended into the class" do
++        Pry::Method.instance_resolution_order(LS::Bottom).should == [LS::Bottom] + Pry::Method.instance_resolution_order(LS::Lower)
++      end
++
++      it "should include included modules for Modules" do
++        Pry::Method.instance_resolution_order(LS::O).should == [LS::O, LS::M]
++      end
++
++      it "should include the singleton class of objects" do
++        obj = LS::Low.new
++        Pry::Method.resolution_order(obj).should == [singleton_class(obj)] + Pry::Method.instance_resolution_order(LS::Low)
++      end
++
++      it "should not include singleton classes of numbers" do
++        Pry::Method.resolution_order(4).should == Pry::Method.instance_resolution_order(Fixnum)
++      end
++
++      it "should include singleton classes for classes" do
++        Pry::Method.resolution_order(LS::Low).should == [singleton_class(LS::Low)] + Pry::Method.resolution_order(LS::Next)
++      end
++
++      it "should include modules included into singleton classes" do
++        Pry::Method.resolution_order(LS::Lower).should == [singleton_class(LS::Lower), LS::N, LS::M] + Pry::Method.resolution_order(LS::Low)
++      end
++
++      it "should include modules at most once" do
++        Pry::Method.resolution_order(LS::Bottom).count(LS::M).should == 1
++      end
++
++      it "should include modules at the point which they would be reached" do
++        Pry::Method.resolution_order(LS::Bottom).should == [singleton_class(LS::Bottom), LS::O] + (Pry::Method.resolution_order(LS::Lower))
++      end
++
++      it "should include the Pry::Method.instance_resolution_order of Class after the singleton classes" do
++        Pry::Method.resolution_order(LS::Top).should ==
++          [singleton_class(LS::Top), singleton_class(Object), singleton_class(BasicObject),
++           *Pry::Method.instance_resolution_order(Class)]
++      end
++    end
++  end
++
++  describe 'method_name_from_first_line' do
++    it 'should work in all simple cases' do
++      meth = Pry::Method.new(nil)
++      meth.send(:method_name_from_first_line, "def x").should == "x"
++      meth.send(:method_name_from_first_line, "def self.x").should == "x"
++      meth.send(:method_name_from_first_line, "def ClassName.x").should == "x"
++      meth.send(:method_name_from_first_line, "def obj_name.x").should == "x"
++    end
++  end
++
++  describe 'method aliases' do
++    before do
++      @class = Class.new {
++        def eat
++        end
++
++        alias fress eat
++        alias_method :omnomnom, :fress
++
++        def eruct
++        end
++      }
++    end
++
++    it 'should be able to find method aliases' do
++      meth = Pry::Method(@class.new.method(:eat))
++      aliases = Set.new(meth.aliases)
++
++      aliases.should == Set.new(["fress", "omnomnom"])
++    end
++
++    it 'should return an empty Array if cannot find aliases' do
++      meth = Pry::Method(@class.new.method(:eruct))
++      meth.aliases.should.be.empty
++    end
++
++    it 'should not include the own name in the list of aliases' do
++      meth = Pry::Method(@class.new.method(:eat))
++      meth.aliases.should.not.include "eat"
++    end
++
++    it 'should find aliases for top-level methods' do
++      # top-level methods get added as private instance methods on Object
++      class Object
++        private
++        def my_top_level_method ; end
++        alias my_other_top_level_method my_top_level_method
++      end
++
++      meth = Pry::Method.new(method(:my_top_level_method))
++      meth.aliases.should.include 'my_other_top_level_method'
++
++      class Object
++        remove_method :my_top_level_method
++      end
++    end
++
++    it 'should be able to find aliases for methods implemented in C' do
++      meth = Pry::Method(Hash.new.method(:key?))
++      aliases = Set.new(meth.aliases)
++
++      aliases.should == Set.new(["include?", "member?", "has_key?"])
++    end
++  end
++end
+diff --git a/spec/pager_spec.rb b/spec/pager_spec.rb
+new file mode 100644
+index 0000000..5e64b2c
+--- /dev/null
++++ b/spec/pager_spec.rb
+@@ -0,0 +1,66 @@
++require_relative "helper"
++describe "Pry::Pager" do
++  describe "PageTracker" do
++    before do
++      @pt = Pry::Pager::PageTracker.new(10, 10)
++    end
++
++    def record_short_line
++      @pt.record "012345678\n"
++    end
++
++    def record_long_line
++      @pt.record "0123456789012\n"
++    end
++
++    def record_multiline
++      @pt.record "0123456789012\n01\n"
++    end
++
++    def record_string_without_newline
++      @pt.record "0123456789"
++    end
++
++    def record_string_with_color_codes
++      @pt.record(CodeRay.scan("0123456789", :ruby).term + "\n")
++    end
++
++    it "records short lines that don't add up to a page" do
++      9.times { record_short_line }
++      @pt.page?.should.be.false
++    end
++
++    it "records short lines that do add up to a page" do
++      10.times { record_short_line }
++      @pt.page?.should.be.true
++    end
++
++    it "treats a long line as taking up more than one row" do
++      4.times { record_long_line }
++      @pt.page?.should.be.false
++      record_long_line
++      @pt.page?.should.be.true
++    end
++
++    it "records a string with an embedded newline" do
++      3.times { record_multiline }
++      @pt.page?.should.be.false
++      record_short_line
++      @pt.page?.should.be.true
++    end
++
++    it "doesn't count a line until it ends" do
++      12.times { record_string_without_newline }
++      @pt.page?.should.be.false
++      record_short_line
++      @pt.page?.should.be.true
++    end
++
++    it "doesn't count ansi color codes towards length" do
++      9.times { record_string_with_color_codes }
++      @pt.page?.should.be.false
++      record_string_with_color_codes
++      @pt.page?.should.be.true
++    end
++  end
++end
+diff --git a/spec/prompt_spec.rb b/spec/prompt_spec.rb
+new file mode 100644
+index 0000000..ddda435
+--- /dev/null
++++ b/spec/prompt_spec.rb
+@@ -0,0 +1,61 @@
++require_relative 'helper'
++
++describe "Prompts" do
++  describe "one-parameter prompt proc" do
++    it 'should get full config object' do
++      config = nil
++      redirect_pry_io(InputTester.new("exit-all")) do
++        Pry.start(self, :prompt => proc { |v| config = v })
++      end
++      config.is_a?(Pry::Config).should == true
++    end
++
++    it 'should get full config object, when using a proc array' do
++      config1 = nil
++      redirect_pry_io(InputTester.new("exit-all")) do
++        Pry.start(self, :prompt => [proc { |v| config1 = v }, proc { |v| config2 = v }])
++      end
++      config1.is_a?(Pry::Config).should == true
++    end
++
++    it 'should receive correct data in the config object' do
++      config = nil
++      redirect_pry_io(InputTester.new("def hello", "exit-all")) do
++        Pry.start(self, :prompt => proc { |v| config = v })
++      end
++
++      config.eval_string.should =~ /def hello/
++      config.nesting_level.should == 0
++      config.expr_number.should == 1
++      config.cont.should == true
++      config._pry_.is_a?(Pry).should == true
++      config.object.should == self
++    end
++  end
++
++  describe "BACKWARDS COMPATIBILITY: 3 parameter prompt proc" do
++    it 'should get 3 parameters' do
++      o = n = p = nil
++      redirect_pry_io(InputTester.new("exit-all")) do
++        Pry.start(:test, :prompt => proc { |obj, nesting, _pry_|
++                    o, n, p = obj, nesting, _pry_ })
++      end
++      o.should == :test
++      n.should == 0
++      p.is_a?(Pry).should == true
++    end
++
++    it 'should get 3 parameters, when using proc array' do
++      o1 = n1 = p1 = nil
++      redirect_pry_io(InputTester.new("exit-all")) do
++        Pry.start(:test, :prompt => [proc { |obj, nesting, _pry_|
++                                       o1, n1, p1 = obj, nesting, _pry_ },
++                                     proc { |obj, nesting, _pry_|
++                                       o2, n2, p2 = obj, nesting, _pry_ }])
++      end
++      o1.should == :test
++      n1.should == 0
++      p1.is_a?(Pry).should == true
++    end
++  end
++end
+diff --git a/spec/pry_defaults_spec.rb b/spec/pry_defaults_spec.rb
+new file mode 100644
+index 0000000..404094d
+--- /dev/null
++++ b/spec/pry_defaults_spec.rb
+@@ -0,0 +1,428 @@
++require_relative 'helper'
++
++version = 1
++
++describe "test Pry defaults" do
++  before do
++    @str_output = StringIO.new
++  end
++
++  after do
++    Pry.reset_defaults
++    Pry.config.color = false
++  end
++
++  describe "input" do
++    after do
++      Pry.reset_defaults
++      Pry.config.color = false
++    end
++
++    it 'should set the input default, and the default should be overridable' do
++      Pry.config.input = InputTester.new("5")
++      Pry.config.output = @str_output
++      Object.new.pry
++      @str_output.string.should =~ /5/
++
++      Pry.config.output = @str_output
++      Object.new.pry :input => InputTester.new("6")
++      @str_output.string.should =~ /6/
++    end
++
++    it 'should pass in the prompt if readline arity is 1' do
++      Pry.prompt = proc { "A" }
++
++      arity_one_input = Class.new do
++        attr_accessor :prompt
++        def readline(prompt)
++          @prompt = prompt
++          "exit-all"
++        end
++      end.new
++
++      Pry.start(self, :input => arity_one_input, :output => StringIO.new)
++      arity_one_input.prompt.should == Pry.prompt.call
++    end
++
++    it 'should not pass in the prompt if the arity is 0' do
++      Pry.prompt = proc { "A" }
++
++      arity_zero_input = Class.new do
++        def readline
++          "exit-all"
++        end
++      end.new
++
++      lambda { Pry.start(self, :input => arity_zero_input, :output => StringIO.new) }.should.not.raise Exception
++    end
++
++    it 'should not pass in the prompt if the arity is -1' do
++      Pry.prompt = proc { "A" }
++
++      arity_multi_input = Class.new do
++        attr_accessor :prompt
++
++        def readline(*args)
++          @prompt = args.first
++          "exit-all"
++        end
++      end.new
++
++      Pry.start(self, :input => arity_multi_input, :output => StringIO.new)
++      arity_multi_input.prompt.should == nil
++    end
++
++  end
++
++  it 'should set the output default, and the default should be overridable' do
++    Pry.config.output = @str_output
++
++    Pry.config.input  = InputTester.new("5")
++    Object.new.pry
++    @str_output.string.should =~ /5/
++
++    Pry.config.input  = InputTester.new("6")
++    Object.new.pry
++    @str_output.string.should =~ /5\n.*6/
++
++    Pry.config.input  = InputTester.new("7")
++    @str_output = StringIO.new
++    Object.new.pry :output => @str_output
++    @str_output.string.should.not =~ /5\n.*6/
++    @str_output.string.should =~ /7/
++  end
++
++  it "should set the print default, and the default should be overridable" do
++    new_print = proc { |out, value| out.puts "=> LOL" }
++    Pry.config.print =  new_print
++
++    Pry.new.print.should == Pry.config.print
++    Object.new.pry :input => InputTester.new("\"test\""), :output => @str_output
++    @str_output.string.should == "=> LOL\n"
++
++    @str_output = StringIO.new
++    Object.new.pry :input => InputTester.new("\"test\""), :output => @str_output,
++                   :print => proc { |out, value| out.puts value.reverse }
++    @str_output.string.should == "tset\n"
++
++    Pry.new.print.should == Pry.config.print
++    @str_output = StringIO.new
++    Object.new.pry :input => InputTester.new("\"test\""), :output => @str_output
++    @str_output.string.should == "=> LOL\n"
++  end
++
++  describe "pry return values" do
++    it 'should return nil' do
++      Pry.start(self, :input => StringIO.new("exit-all"), :output => StringIO.new).should == nil
++    end
++
++    it 'should return the parameter given to exit-all' do
++      Pry.start(self, :input => StringIO.new("exit-all 10"), :output => StringIO.new).should == 10
++    end
++
++    it 'should return the parameter (multi word string) given to exit-all' do
++      Pry.start(self, :input => StringIO.new("exit-all \"john mair\""), :output => StringIO.new).should == "john mair"
++    end
++
++    it 'should return the parameter (function call) given to exit-all' do
++      Pry.start(self, :input => StringIO.new("exit-all 'abc'.reverse"), :output => StringIO.new).should == 'cba'
++    end
++
++    it 'should return the parameter (self) given to exit-all' do
++      Pry.start("carl", :input => StringIO.new("exit-all self"), :output => StringIO.new).should == "carl"
++    end
++  end
++
++  describe "prompts" do
++    before do
++      Pry.config.output = StringIO.new
++    end
++
++    def get_prompts(pry)
++      a = pry.select_prompt
++      pry.eval "["
++      b = pry.select_prompt
++      pry.eval "]"
++      [a, b]
++    end
++
++    it 'should set the prompt default, and the default should be overridable (single prompt)' do
++      Pry.prompt = proc { "test prompt> " }
++      new_prompt = proc { "A" }
++
++      pry = Pry.new
++      pry.prompt.should == Pry.prompt
++      get_prompts(pry).should == ["test prompt> ",  "test prompt> "]
++
++
++      pry = Pry.new(:prompt => new_prompt)
++      pry.prompt.should == new_prompt
++      get_prompts(pry).should == ["A",  "A"]
++
++      pry = Pry.new
++      pry.prompt.should == Pry.prompt
++      get_prompts(pry).should == ["test prompt> ",  "test prompt> "]
++    end
++
++    it 'should set the prompt default, and the default should be overridable (multi prompt)' do
++      Pry.prompt = [proc { "test prompt> " }, proc { "test prompt* " }]
++      new_prompt = [proc { "A" }, proc { "B" }]
++
++      pry = Pry.new
++      pry.prompt.should == Pry.prompt
++      get_prompts(pry).should == ["test prompt> ",  "test prompt* "]
++
++
++      pry = Pry.new(:prompt => new_prompt)
++      pry.prompt.should == new_prompt
++      get_prompts(pry).should == ["A",  "B"]
++
++      pry = Pry.new
++      pry.prompt.should == Pry.prompt
++      get_prompts(pry).should == ["test prompt> ",  "test prompt* "]
++    end
++
++    describe 'storing and restoring the prompt' do
++      before do
++        make = lambda do |name,i|
++          prompt = [ proc { "#{i}>" } , proc { "#{i+1}>" } ]
++          (class << prompt; self; end).send(:define_method, :inspect) { "<Prompt-#{name}>" }
++          prompt
++        end
++        @a , @b , @c = make[:a,0] , make[:b,1] , make[:c,2]
++        @pry = Pry.new :prompt => @a
++      end
++      it 'should have a prompt stack' do
++        @pry.push_prompt @b
++        @pry.push_prompt @c
++        @pry.prompt.should == @c
++        @pry.pop_prompt
++        @pry.prompt.should == @b
++        @pry.pop_prompt
++        @pry.prompt.should == @a
++      end
++
++      it 'should restore overridden prompts when returning from file-mode' do
++        pry = Pry.new(:prompt => [ proc { 'P>' } ] * 2)
++        pry.select_prompt.should == "P>"
++        pry.process_command('shell-mode')
++        pry.select_prompt.should =~ /\Apry .* \$ \z/
++        pry.process_command('shell-mode')
++        pry.select_prompt.should == "P>"
++      end
++
++      it '#pop_prompt should return the popped prompt' do
++        @pry.push_prompt @b
++        @pry.push_prompt @c
++        @pry.pop_prompt.should == @c
++        @pry.pop_prompt.should == @b
++      end
++
++      it 'should not pop the last prompt' do
++        @pry.push_prompt @b
++        @pry.pop_prompt.should == @b
++        @pry.pop_prompt.should == @a
++        @pry.pop_prompt.should == @a
++        @pry.prompt.should == @a
++      end
++
++      describe '#prompt= should replace the current prompt with the new prompt' do
++        it 'when only one prompt on the stack' do
++          @pry.prompt = @b
++          @pry.prompt.should == @b
++          @pry.pop_prompt.should == @b
++          @pry.pop_prompt.should == @b
++        end
++        it 'when several prompts on the stack' do
++          @pry.push_prompt @b
++          @pry.prompt = @c
++          @pry.pop_prompt.should == @c
++          @pry.pop_prompt.should == @a
++        end
++      end
++    end
++  end
++
++  describe "view_clip used for displaying an object in a truncated format" do
++    DEFAULT_OPTIONS =  {
++      max_length: 60
++    }
++    MAX_LENGTH = DEFAULT_OPTIONS[:max_length]
++
++    describe "given an object with an #inspect string" do
++      it "returns the #<> format of the object (never use inspect)" do
++        o = Object.new
++        def o.inspect; "a" * MAX_LENGTH; end
++
++        Pry.view_clip(o, DEFAULT_OPTIONS).should =~ /#<Object/
++      end
++    end
++
++    describe "given the 'main' object" do
++      it "returns the #to_s of main (special case)" do
++        o = TOPLEVEL_BINDING.eval('self')
++        Pry.view_clip(o, DEFAULT_OPTIONS).should == o.to_s
++      end
++    end
++
++    describe "the list of prompt safe objects" do
++      [1, 2.0, -5, "hello", :test].each do |o|
++        it "returns the #inspect of the special-cased immediate object: #{o}" do
++          Pry.view_clip(o, DEFAULT_OPTIONS).should == o.inspect
++        end
++      end
++
++      it "returns #<> format of the special-cased immediate object if #inspect is longer than maximum" do
++        o = "o" * (MAX_LENGTH + 1)
++        Pry.view_clip(o, DEFAULT_OPTIONS).should =~ /#<String/
++      end
++
++      it "returns the #inspect of the custom prompt safe objects" do
++        Barbie = Class.new { def inspect; "life is plastic, it's fantastic" end }
++        Pry.config.prompt_safe_objects << Barbie
++        output = Pry.view_clip(Barbie.new, DEFAULT_OPTIONS)
++        output.should == "life is plastic, it's fantastic"
++      end
++    end
++
++    describe "given an object with an #inspect string as long as the maximum specified" do
++      it "returns the #<> format of the object (never use inspect)" do
++        o = Object.new
++        def o.inspect; "a" * DEFAULT_OPTIONS; end
++
++        Pry.view_clip(o, DEFAULT_OPTIONS).should =~ /#<Object/
++      end
++    end
++
++    describe "given a regular object with an #inspect string longer than the maximum specified" do
++
++      describe "when the object is a regular one" do
++        it "returns a string of the #<class name:object idish> format" do
++          o = Object.new
++          def o.inspect; "a" * (DEFAULT_OPTIONS + 1); end
++
++          Pry.view_clip(o, DEFAULT_OPTIONS).should =~ /#<Object/
++        end
++      end
++
++      describe "when the object is a Class or a Module" do
++        describe "without a name (usually a c = Class.new)" do
++          it "returns a string of the #<class name:object idish> format" do
++            c, m = Class.new, Module.new
++
++            Pry.view_clip(c, DEFAULT_OPTIONS).should =~ /#<Class/
++            Pry.view_clip(m, DEFAULT_OPTIONS).should =~ /#<Module/
++          end
++        end
++
++        describe "with a #name longer than the maximum specified" do
++          it "returns a string of the #<class name:object idish> format" do
++            c, m = Class.new, Module.new
++
++
++            def c.name; "a" * (MAX_LENGTH + 1); end
++            def m.name; "a" * (MAX_LENGTH + 1); end
++
++            Pry.view_clip(c, DEFAULT_OPTIONS).should =~ /#<Class/
++            Pry.view_clip(m, DEFAULT_OPTIONS).should =~ /#<Module/
++          end
++        end
++
++        describe "with a #name shorter than or equal to the maximum specified" do
++          it "returns a string of the #<class name:object idish> format" do
++            c, m = Class.new, Module.new
++
++            def c.name; "a" * MAX_LENGTH; end
++            def m.name; "a" * MAX_LENGTH; end
++
++            Pry.view_clip(c, DEFAULT_OPTIONS).should == c.name
++            Pry.view_clip(m, DEFAULT_OPTIONS).should == m.name
++          end
++        end
++
++      end
++
++    end
++
++  end
++
++  describe 'quiet' do
++    it 'should show whereami by default' do
++      Pry.start(binding, :input => InputTester.new("1", "exit-all"),
++              :output => @str_output,
++              :hooks => Pry::DEFAULT_HOOKS)
++
++      @str_output.string.should =~ /[w]hereami by default/
++    end
++
++    it 'should hide whereami if quiet is set' do
++      Pry.new(:input => InputTester.new("exit-all"),
++              :output => @str_output,
++              :quiet => true,
++              :hooks => Pry::DEFAULT_HOOKS)
++
++      @str_output.string.should == ""
++    end
++  end
++
++  describe 'toplevel_binding' do
++    it 'should be devoid of local variables' do
++      pry_eval(Pry.toplevel_binding, "ls -l").should.not =~ /version/
++    end
++
++    it 'should have self the same as TOPLEVEL_BINDING' do
++      Pry.toplevel_binding.eval('self').should.equal? TOPLEVEL_BINDING.eval('self')
++    end
++
++    # https://github.com/rubinius/rubinius/issues/1779
++    unless Pry::Helpers::BaseHelpers.rbx?
++      it 'should define private methods on Object' do
++        TOPLEVEL_BINDING.eval 'def gooey_fooey; end'
++        method(:gooey_fooey).owner.should == Object
++        Pry::Method(method(:gooey_fooey)).visibility.should == :private
++      end
++    end
++  end
++
++  it 'should set the hooks default, and the default should be overridable' do
++    Pry.config.input = InputTester.new("exit-all")
++    Pry.config.hooks = Pry::Hooks.new.
++      add_hook(:before_session, :my_name) { |out,_,_|  out.puts "HELLO" }.
++      add_hook(:after_session, :my_name) { |out,_,_| out.puts "BYE" }
++
++    Object.new.pry :output => @str_output
++    @str_output.string.should =~ /HELLO/
++    @str_output.string.should =~ /BYE/
++
++    Pry.config.input.rewind
++
++    @str_output = StringIO.new
++    Object.new.pry :output => @str_output,
++                   :hooks => Pry::Hooks.new.
++                   add_hook( :before_session, :my_name) { |out,_,_| out.puts "MORNING" }.
++                   add_hook(:after_session, :my_name) { |out,_,_| out.puts "EVENING" }
++
++    @str_output.string.should =~ /MORNING/
++    @str_output.string.should =~ /EVENING/
++
++    # try below with just defining one hook
++    Pry.config.input.rewind
++    @str_output = StringIO.new
++    Object.new.pry :output => @str_output,
++                   :hooks => Pry::Hooks.new.
++                   add_hook(:before_session, :my_name) { |out,_,_| out.puts "OPEN" }
++
++    @str_output.string.should =~ /OPEN/
++
++    Pry.config.input.rewind
++    @str_output = StringIO.new
++    Object.new.pry :output => @str_output,
++                   :hooks => Pry::Hooks.new.
++                   add_hook(:after_session, :my_name) { |out,_,_| out.puts "CLOSE" }
++
++    @str_output.string.should =~ /CLOSE/
++
++    Pry.reset_defaults
++    Pry.config.color = false
++  end
++end
+diff --git a/spec/pry_output_spec.rb b/spec/pry_output_spec.rb
+new file mode 100644
+index 0000000..dc59400
+--- /dev/null
++++ b/spec/pry_output_spec.rb
+@@ -0,0 +1,117 @@
++require_relative 'helper'
++
++describe Pry do
++  describe "output failsafe" do
++    after do
++      Pry.config.print = Pry::DEFAULT_PRINT
++    end
++
++    it "should catch serialization exceptions" do
++      Pry.config.print = lambda { |*a| raise "catch-22" }
++
++      lambda {
++        mock_pry("1")
++      }.should.not.raise
++    end
++
++    it "should display serialization exceptions" do
++      Pry.config.print = lambda { |*a| raise "catch-22" }
++
++      mock_pry("1").should =~ /\(pry\) output error: #<RuntimeError: catch-22>/
++    end
++
++    it "should catch errors serializing exceptions" do
++      Pry.config.print = lambda do |*a|
++        raise Exception.new("catch-22").tap{ |e| class << e; def inspect; raise e; end; end }
++      end
++
++      mock_pry("1").should =~ /\(pry\) output error: failed to show result/
++    end
++  end
++
++  describe "DEFAULT_PRINT" do
++    it "should output the right thing" do
++      mock_pry("[1]").should =~ /^=> \[1\]/
++    end
++
++    it "should include the =>" do
++      pry = Pry.new
++      accumulator = StringIO.new
++      pry.config.output = accumulator
++      pry.config.print.call(accumulator, [1], pry)
++      accumulator.string.should == "=> \[1\]\n"
++    end
++
++    it "should not be phased by un-inspectable things" do
++      mock_pry("class NastyClass; undef pretty_inspect; end", "NastyClass.new").should =~ /#<.*NastyClass:0x.*?>/
++    end
++
++    it "doesn't leak colour for object literals" do
++      mock_pry("Object.new").should =~ /=> #<Object:0x[a-z0-9]+>\n/
++    end
++  end
++
++  describe "output_prefix" do
++    it "should be able to change output_prefix" do
++      pry = Pry.new
++      accumulator = StringIO.new
++      pry.config.output = accumulator
++      pry.config.output_prefix = "-> "
++      pry.config.print.call(accumulator, [1], pry)
++      accumulator.string.should == "-> \[1\]\n"
++    end
++  end
++
++  describe "color" do
++    before do
++      Pry.config.color = true
++    end
++
++    after do
++      Pry.config.color = false
++    end
++
++    it "should colorize strings as though they were ruby" do
++      pry = Pry.new
++      accumulator = StringIO.new
++      colorized   = CodeRay.scan("[1]", :ruby).term
++      pry.config.output = accumulator
++      pry.config.print.call(accumulator, [1], pry)
++      accumulator.string.should == "=> #{colorized}\n"
++    end
++
++    it "should not colorize strings that already include color" do
++      pry = Pry.new
++      f = Object.new
++      def f.inspect
++        "\e[1;31mFoo\e[0m"
++      end
++      accumulator = StringIO.new
++      pry.config.output = accumulator
++      pry.config.print.call(accumulator, f, pry)
++      # We add an extra \e[0m to prevent color leak
++      accumulator.string.should == "=> \e[1;31mFoo\e[0m\e[0m\n"
++    end
++  end
++
++  describe "output suppression" do
++    before do
++      @t = pry_tester
++    end
++    it "should normally output the result" do
++      mock_pry("1 + 2").should == "=> 3\n"
++    end
++
++    it "should not output anything if the input ends with a semicolon" do
++      mock_pry("1 + 2;").should == ""
++    end
++
++    it "should output something if the input ends with a comment" do
++      mock_pry("1 + 2 # basic addition").should == "=> 3\n"
++    end
++
++    it "should not output something if the input is only a comment" do
++      mock_pry("# basic addition").should == ""
++    end
++  end
++end
+diff --git a/spec/pry_repl_spec.rb b/spec/pry_repl_spec.rb
+new file mode 100644
+index 0000000..43c77ec
+--- /dev/null
++++ b/spec/pry_repl_spec.rb
+@@ -0,0 +1,102 @@
++require_relative 'helper'
++
++describe "The whole thing" do
++  it "should let you run commands in the middle of multiline expressions" do
++    ReplTester.start do
++      input  'def a'
++      input  '!'
++      output /^Input buffer cleared/
++
++      input  '5'
++      output '=> 5'
++    end
++  end
++
++  it "should rescue exceptions" do
++    ReplTester.start do
++      input  'raise "lorum"'
++      output /^RuntimeError: lorum/
++
++      if defined?(java)
++        input  'raise java.lang.Exception.new("foo")'
++        output /Exception: foo/
++
++        input  'raise java.io.IOException.new("bar")'
++        output /IOException: bar/
++      end
++    end
++  end
++
++  describe "eval_string and binding_stack" do
++    it "shouldn't break if we start a nested REPL" do
++      ReplTester.start do
++        input  'Pry::REPL.new(_pry_, :target => 10).start'
++        output ''
++        prompt /10.*> $/
++
++        input  'self'
++        output '=> 10'
++
++        input  nil # Ctrl-D
++        output ''
++
++        input  'self'
++        output '=> main'
++      end
++    end
++
++    it "shouldn't break if we start a nested instance" do
++      ReplTester.start do
++        input  'Pry.start(10, _pry_.config)'
++        output ''
++        prompt /10.*> $/
++
++        input  'self'
++        output '=> 10'
++
++        input  nil # Ctrl-D
++        output '=> nil' # return value of Pry session
++
++        input  'self'
++        output '=> main'
++      end
++    end
++
++    it "shouldn't break if we pop bindings in Ruby" do
++      ReplTester.start do
++        input  'cd 10'
++        output ''
++        prompt /10.*> $/
++
++        input  '_pry_.binding_stack.pop'
++        output /^=> #<Binding/
++        prompt /main.*> $/
++
++        input  '_pry_.binding_stack.pop'
++        output /^=> #<Binding/
++        assert_exited
++      end
++    end
++
++    it "should immediately evaluate eval_string after cmd if complete" do
++      set = Pry::CommandSet.new do
++        import Pry::Commands
++
++        command 'hello!' do
++          eval_string.replace('"hello"')
++        end
++      end
++
++      ReplTester.start(:commands => set) do
++        input  'def x'
++        output ''
++        prompt /\*   $/
++
++        input  'hello!'
++        output '=> "hello"'
++        prompt /> $/
++      end
++    end
++  end
++
++end
+diff --git a/spec/pry_spec.rb b/spec/pry_spec.rb
+new file mode 100644
+index 0000000..ca5a3f9
+--- /dev/null
++++ b/spec/pry_spec.rb
+@@ -0,0 +1,414 @@
++require_relative 'helper'
++
++describe Pry do
++  before do
++    @str_output = StringIO.new
++  end
++
++  describe "Exotic object support" do
++    # regression test for exotic object support
++    it "Should not error when return value is a BasicObject instance" do
++      ReplTester.start do
++        input('BasicObject.new').should =~ /^=> #<BasicObject:/
++      end
++    end
++  end
++
++  describe 'DISABLE_PRY' do
++    before do
++      ENV['DISABLE_PRY'] = 'true'
++    end
++
++    after do
++      ENV.delete 'DISABLE_PRY'
++    end
++
++    it 'should not binding.pry' do
++      binding.pry.should == nil
++    end
++
++    it 'should not Pry.start' do
++      Pry.start.should == nil
++    end
++  end
++
++  describe "Pry.critical_section" do
++    it "should prevent Pry being called" do
++      output = StringIO.new
++      Pry.config.output = output
++      Pry.critical_section do
++        Pry.start
++      end
++      output.string.should =~ /Pry started inside Pry/
++    end
++  end
++
++  describe "Pry.binding_for" do
++
++    # regression test for burg's bug (see git history)
++    it "Should not error when object doesn't have a valid == method" do
++      o = Object.new
++      def o.==(other)
++        raise
++      end
++
++      lambda { Pry.binding_for(o) }.should.not.raise Exception
++    end
++
++    it "should not leak local variables" do
++      [Object.new, Array, 3].each do |obj|
++        Pry.binding_for(obj).eval("local_variables").should.be.empty
++      end
++    end
++
++    it "should work on frozen objects" do
++      a = "hello".freeze
++      Pry.binding_for(a).eval("self").should.equal? a
++    end
++  end
++
++  describe "#last_exception=" do
++    before do
++      @pry = Pry.new binding: binding
++      @e = mock_exception "foo.rb:1"
++    end
++
++    it "returns an instance of Pry::LastException" do
++      @pry.last_exception = @e
++      @pry.last_exception.wrapped_exception.should == @e
++    end
++
++    it "returns a frozen exception" do
++      @pry.last_exception = @e.freeze
++      @pry.last_exception.should.be.frozen?
++    end
++
++    it "returns an object who mirrors itself as the wrapped exception" do
++      @pry.last_exception = @e.freeze
++      @pry.last_exception.should.be.instance_of?(StandardError)
++    end
++  end
++
++  describe "open a Pry session on an object" do
++    describe "rep" do
++      before do
++        class Hello
++        end
++      end
++
++      after do
++        Object.send(:remove_const, :Hello)
++      end
++
++      # bug fix for https://github.com/banister/pry/issues/93
++      it 'should not leak pry constants into Object namespace' do
++        lambda{
++          pry_eval(Object.new, "Command")
++        }.should.raise(NameError)
++      end
++
++      it 'should be able to operate inside the BasicObject class' do
++        pry_eval(BasicObject, ":foo", "Pad.obj = _")
++        Pad.obj.should == :foo
++      end
++
++      it 'should set an ivar on an object' do
++        o = Object.new
++        pry_eval(o, "@x = 10")
++        o.instance_variable_get(:@x).should == 10
++      end
++
++      it 'should display error if Pry instance runs out of input' do
++        redirect_pry_io(StringIO.new, @str_output) do
++          Pry.start
++        end
++        @str_output.string.should =~ /Error: Pry ran out of things to read/
++      end
++
++      it 'should make self evaluate to the receiver of the rep session' do
++        o = :john
++        pry_eval(o, "self").should == o
++      end
++
++      it 'should define a nested class under Hello and not on top-level or Pry' do
++        mock_pry(Pry.binding_for(Hello), "class Nested", "end")
++        Hello.const_defined?(:Nested).should == true
++      end
++
++      it 'should suppress output if input ends in a ";" and is an Exception object (single line)' do
++        mock_pry("Exception.new;").should == ""
++      end
++
++      it 'should suppress output if input ends in a ";" (single line)' do
++        mock_pry("x = 5;").should == ""
++      end
++
++      it 'should be able to evaluate exceptions normally' do
++        was_called = false
++        mock_pry("RuntimeError.new", :exception_handler => proc{ was_called = true })
++        was_called.should == false
++      end
++
++      it 'should notice when exceptions are raised' do
++        was_called = false
++        mock_pry("raise RuntimeError", :exception_handler => proc{ was_called = true })
++        was_called.should == true
++      end
++
++      it 'should not try to catch intended exceptions' do
++        lambda { mock_pry("raise SystemExit") }.should.raise SystemExit
++        # SIGTERM
++        lambda { mock_pry("raise SignalException.new(15)") }.should.raise SignalException
++      end
++
++      describe "multi-line input" do
++        it "works" do
++          mock_pry('x = ', '1 + 4').should =~ /5/
++        end
++
++        it 'should suppress output if input ends in a ";" (multi-line)' do
++          mock_pry('def self.blah', ':test', 'end;').should == ''
++        end
++
++        describe "newline stripping from an empty string" do
++          it "with double quotes" do
++            mock_pry('"', '"').should =~ %r|"\\n"|
++            mock_pry('"', "\n", "\n", "\n", '"').should =~ %r|"\\n\\n\\n\\n"|
++          end
++
++          it "with single quotes" do
++            mock_pry("'", "'").should =~ %r|"\\n"|
++            mock_pry("'", "\n", "\n", "\n", "'").should =~ %r|"\\n\\n\\n\\n"|
++          end
++
++          it "with fancy delimiters" do
++            mock_pry('%(', ')').should =~ %r|"\\n"|
++            mock_pry('%|', "\n", "\n", '|').should =~ %r|"\\n\\n\\n"|
++            mock_pry('%q[', "\n", "\n", ']').should =~ %r|"\\n\\n\\n"|
++          end
++        end
++
++        describe "newline stripping from an empty regexp" do
++          it "with regular regexp delimiters" do
++            mock_pry('/', '/').should =~ %r{/\n/}
++          end
++
++          it "with fancy delimiters" do
++            mock_pry('%r{', "\n", "\n", '}').should =~ %r{/\n\n\n/}
++            mock_pry('%r<', "\n", '>').should =~ %r{/\n\n/}
++          end
++        end
++
++        describe "newline from an empty heredoc" do
++          it "works" do
++            mock_pry('<<HERE', 'HERE').should =~ %r|""|
++            mock_pry("<<'HERE'", "\n", 'HERE').should =~ %r|"\\n"|
++            mock_pry("<<-'HERE'", "\n", "\n", 'HERE').should =~ %r|"\\n\\n"|
++          end
++        end
++      end
++    end
++
++    describe "repl" do
++      describe "basic functionality" do
++        it 'should set an ivar on an object and exit the repl' do
++          input_strings = ["@x = 10", "exit-all"]
++          input = InputTester.new(*input_strings)
++
++          o = Object.new
++
++          pry_tester = Pry.start(o, :input => input, :output => StringIO.new)
++
++          o.instance_variable_get(:@x).should == 10
++        end
++      end
++
++      describe "complete_expression?" do
++        it "should not mutate the input!" do
++          clean = "puts <<-FOO\nhi\nFOO\n"
++          a = clean.dup
++          Pry::Code.complete_expression?(a)
++          a.should == clean
++        end
++      end
++
++      describe "history arrays" do
++        it 'sets _ to the last result' do
++          t = pry_tester
++          t.eval ":foo"
++          t.eval("_").should == :foo
++          t.eval "42"
++          t.eval("_").should == 42
++        end
++
++        it 'sets out to an array with the result' do
++          t = pry_tester
++          t.eval ":foo"
++          t.eval "42"
++          res = t.eval "_out_"
++
++          res.should.be.kind_of Pry::HistoryArray
++          res[1..2].should == [:foo, 42]
++        end
++
++        it 'sets _in_ to an array with the entered lines' do
++          t = pry_tester
++          t.eval ":foo"
++          t.eval "42"
++          res = t.eval "_in_"
++
++          res.should.be.kind_of Pry::HistoryArray
++          res[1..2].should == [":foo\n", "42\n"]
++        end
++
++        it 'uses 100 as the size of _in_ and _out_' do
++          pry_tester.eval("[_in_.max_size, _out_.max_size]").should == [100, 100]
++        end
++
++        it 'can change the size of the history arrays' do
++          pry_tester(:memory_size => 1000).eval("[_out_, _in_].map(&:max_size)").should == [1000, 1000]
++        end
++
++        it 'store exceptions' do
++          mock_pry("foo!", "Pad.in = _in_[-1]; Pad.out = _out_[-1]")
++
++          Pad.in.should == "foo!\n"
++          Pad.out.should.be.kind_of NoMethodError
++        end
++      end
++
++      describe "last_result" do
++        it "should be set to the most recent value" do
++          pry_eval("2", "_ + 82").should == 84
++        end
++
++        # This test needs mock_pry because the command retvals work by
++        # replacing the eval_string, so _ won't be modified without Pry doing
++        # a REPL loop.
++        it "should be set to the result of a command with :keep_retval" do
++          Pry::Commands.block_command '++', '', :keep_retval => true do |a|
++            a.to_i + 1
++          end
++
++          mock_pry('++ 86', '++ #{_}').should =~ /88/
++        end
++
++        it "should be preserved over an empty line" do
++          pry_eval("2 + 2", " ", "\t",  " ", "_ + 92").should == 96
++        end
++
++        it "should be preserved when evalling a  command without :keep_retval" do
++          pry_eval("2 + 2", "ls -l", "_ + 96").should == 100
++        end
++      end
++
++      describe "nesting" do
++        after do
++          Pry.reset_defaults
++          Pry.config.color = false
++        end
++
++        it 'should nest properly' do
++          Pry.config.input = InputTester.new("cd 1", "cd 2", "cd 3", "\"nest:\#\{(_pry_.binding_stack.size - 1)\}\"", "exit-all")
++
++          Pry.config.output = @str_output
++
++          o = Object.new
++
++          pry_tester = o.pry
++          @str_output.string.should =~ /nest:3/
++        end
++      end
++
++      describe "defining methods" do
++        it 'should define a method on the singleton class of an object when performing "def meth;end" inside the object' do
++          [Object.new, {}, []].each do |val|
++            pry_eval(val, 'def hello; end')
++            val.methods(false).map(&:to_sym).include?(:hello).should == true
++          end
++        end
++
++        it 'should define an instance method on the module when performing "def meth;end" inside the module' do
++          hello = Module.new
++          pry_eval(hello, "def hello; end")
++          hello.instance_methods(false).map(&:to_sym).include?(:hello).should == true
++        end
++
++        it 'should define an instance method on the class when performing "def meth;end" inside the class' do
++          hello = Class.new
++          pry_eval(hello, "def hello; end")
++          hello.instance_methods(false).map(&:to_sym).include?(:hello).should == true
++        end
++
++        it 'should define a method on the class of an object when performing "def meth;end" inside an immediate value or Numeric' do
++          [:test, 0, true, false, nil,
++              (0.0 unless Pry::Helpers::BaseHelpers.jruby?)].each do |val|
++            pry_eval(val, "def hello; end");
++            val.class.instance_methods(false).map(&:to_sym).include?(:hello).should == true
++          end
++        end
++      end
++
++      describe "Object#pry" do
++
++        after do
++          Pry.reset_defaults
++          Pry.config.color = false
++        end
++
++        it "should start a pry session on the receiver (first form)" do
++          Pry.config.input = InputTester.new("self", "exit-all")
++
++          str_output = StringIO.new
++          Pry.config.output = str_output
++
++          20.pry
++
++          str_output.string.should =~ /20/
++        end
++
++        it "should start a pry session on the receiver (second form)" do
++          Pry.config.input = InputTester.new("self", "exit-all")
++
++          str_output = StringIO.new
++          Pry.config.output = str_output
++
++          pry 20
++
++          str_output.string.should =~ /20/
++        end
++
++        it "should raise if more than two arguments are passed to Object#pry" do
++          lambda { pry(20, :quiet, :input => Readline) }.should.raise ArgumentError
++        end
++      end
++
++      describe "Pry.binding_for" do
++        it 'should return TOPLEVEL_BINDING if parameter self is main' do
++          _main_ = lambda { TOPLEVEL_BINDING.eval('self') }
++          Pry.binding_for(_main_.call).is_a?(Binding).should == true
++          Pry.binding_for(_main_.call).should == TOPLEVEL_BINDING
++          Pry.binding_for(_main_.call).should == Pry.binding_for(_main_.call)
++        end
++      end
++    end
++  end
++
++  describe 'setting custom options' do
++    it 'should not raise for unrecognized options' do
++      should.not.raise?(NoMethodError) {
++        instance = Pry.new(:custom_option => 'custom value')
++      }
++    end
++  end
++
++  describe "a fresh instance" do
++    it "should use `caller` as its backtrace" do
++      location  = "#{__FILE__}:#{__LINE__ + 1}"[1..-1] # omit leading .
++      backtrace = Pry.new.backtrace
++
++      backtrace.should.not.be.nil
++      backtrace.any? { |l| l.include?(location) }.should.be.true
++    end
++  end
++end
+diff --git a/spec/pryrc_spec.rb b/spec/pryrc_spec.rb
+new file mode 100644
+index 0000000..ade0473
+--- /dev/null
++++ b/spec/pryrc_spec.rb
+@@ -0,0 +1,97 @@
++require_relative 'helper'
++
++describe Pry do
++  describe 'loading rc files' do
++    before do
++      Pry::HOME_RC_FILE.replace "spec/fixtures/testrc"
++      Pry::LOCAL_RC_FILE.replace "spec/fixtures/testrc/../testrc"
++      Pry.instance_variable_set(:@initial_session, true)
++      Pry.config.should_load_rc = true
++      Pry.config.should_load_local_rc = true
++    end
++
++    after do
++      Pry::HOME_RC_FILE.replace "~/.pryrc"
++      Pry::LOCAL_RC_FILE.replace "./.pryrc"
++      Pry.config.should_load_rc = false
++      Object.remove_const(:TEST_RC) if defined?(TEST_RC)
++    end
++
++    it "should never run the rc file twice" do
++      Pry.start(self, :input => StringIO.new("exit-all\n"), :output => StringIO.new)
++      TEST_RC.should == [0]
++
++      Pry.start(self, :input => StringIO.new("exit-all\n"), :output => StringIO.new)
++      TEST_RC.should == [0]
++    end
++
++    # Resolving symlinks doesn't work on jruby 1.9 [jruby issue #538]
++    unless Pry::Helpers::BaseHelpers.jruby_19?
++      it "should not load the rc file twice if it's symlinked differently" do
++        Pry::HOME_RC_FILE.replace "spec/fixtures/testrc"
++        Pry::LOCAL_RC_FILE.replace "spec/fixtures/testlinkrc"
++
++        Pry.start(self, :input => StringIO.new("exit-all\n"), :output => StringIO.new)
++
++        TEST_RC.should == [0]
++      end
++    end
++
++    it "should not load the pryrc if it cannot expand ENV[HOME]" do
++      old_home = ENV['HOME']
++      ENV['HOME'] = nil
++      Pry.config.should_load_rc = true
++      lambda { Pry.start(self, :input => StringIO.new("exit-all\n"), :output => StringIO.new) }.should.not.raise
++
++      ENV['HOME'] = old_home
++    end
++
++    it "should not run the rc file at all if Pry.config.should_load_rc is false" do
++      Pry.config.should_load_rc = false
++      Pry.config.should_load_local_rc = false
++      Pry.start(self, :input => StringIO.new("exit-all\n"), :output => StringIO.new)
++      Object.const_defined?(:TEST_RC).should == false
++    end
++
++    describe "that raise exceptions" do
++      before do
++        Pry::HOME_RC_FILE = "spec/fixtures/testrcbad"
++        Pry.config.should_load_local_rc = false
++
++        putsed = nil
++
++        # YUCK! horrible hack to get round the fact that output is not configured
++        # at the point this message is printed.
++        (class << Pry; self; end).send(:define_method, :puts) { |str|
++          putsed = str
++        }
++
++        @doing_it = lambda{
++          Pry.start(self, :input => StringIO.new("Object::TEST_AFTER_RAISE=1\nexit-all\n"), :output => StringIO.new)
++          putsed
++        }
++      end
++
++      after do
++        Object.remove_const(:TEST_BEFORE_RAISE)
++        Object.remove_const(:TEST_AFTER_RAISE)
++        (class << Pry; undef_method :puts; end)
++      end
++
++      it "should not raise exceptions" do
++        @doing_it.should.not.raise
++      end
++
++      it "should continue to run pry" do
++        @doing_it[]
++        Object.const_defined?(:TEST_BEFORE_RAISE).should == true
++        Object.const_defined?(:TEST_AFTER_RAISE).should == true
++      end
++
++      it "should output an error" do
++        @doing_it.call.split("\n").first.should =~
++          %r{Error loading .*spec/fixtures/testrcbad: messin with ya}
++      end
++    end
++  end
++end
+diff --git a/spec/regression/readline_spec.rb b/spec/regression/readline_spec.rb
+new file mode 100644
+index 0000000..65427db
+--- /dev/null
++++ b/spec/regression/readline_spec.rb
+@@ -0,0 +1,39 @@
++# These specs ensure that Pry doesn't require readline until the first time a
++# REPL is started.
++
++require "helper"
++require "shellwords"
++
++describe "Readline" do
++  before do
++    @ruby    = RbConfig.ruby.shellescape
++    @pry_dir = File.expand_path(File.join(__FILE__, '../../../lib')).shellescape
++  end
++
++  it "is not loaded on requiring 'pry'" do
++    code = <<-RUBY
++      require "pry"
++      p defined?(Readline)
++    RUBY
++    `#@ruby -I #@pry_dir -e '#{code}'`.should == "nil\n"
++  end
++
++  it "is loaded on invoking 'pry'" do
++    code = <<-RUBY
++      require "pry"
++      Pry.start self, input: StringIO.new("exit-all"), output: StringIO.new
++      puts defined?(Readline)
++    RUBY
++    `#@ruby -I #@pry_dir -e '#{code}'`.end_with?("constant\n").should == true
++  end
++
++  it "is not loaded on invoking 'pry' if Pry.input is set" do
++    code = <<-RUBY
++      require "pry"
++      Pry.input = StringIO.new("exit-all")
++      Pry.start self, output: StringIO.new
++      p defined?(Readline)
++    RUBY
++    `#@ruby -I #@pry_dir -e '#{code}'`.end_with?("nil\n").should == true
++  end
++end
+diff --git a/spec/run_command_spec.rb b/spec/run_command_spec.rb
+new file mode 100644
+index 0000000..787ffd0
+--- /dev/null
++++ b/spec/run_command_spec.rb
+@@ -0,0 +1,23 @@
++require_relative 'helper'
++
++describe "Pry.run_command" do
++  before do
++    o = Object.new
++    def o.drum
++      "roken is dodelijk"
++    end
++    @context = Pry.binding_for(o)
++  end
++
++  it 'performs a simple ls' do
++    @context.eval("hokey_pokey = 10")
++    Pry.run_command "ls", :context => @context, :output => out = StringIO.new
++    out.string.should =~ /hokey_pokey/
++  end
++
++  # This is a regression test as 0.9.11 broke this behaviour
++  it 'can perform a show-source' do
++    Pry.run_command "show-source drum", :context => @context, :output => out = StringIO.new
++    out.string.should =~ /roken is dodelijk/
++  end
++end
+diff --git a/spec/spec_helpers/bacon.rb b/spec/spec_helpers/bacon.rb
+new file mode 100644
+index 0000000..2a7721a
+--- /dev/null
++++ b/spec/spec_helpers/bacon.rb
+@@ -0,0 +1,86 @@
++# Colorize output (based on greeneggs (c) 2009 Michael Fleet)
++# TODO: Make own gem (assigned to rking)
++module Bacon
++  class Context
++    include PryTestHelpers
++  end
++
++  COLORS    = {'F' => 31, 'E' => 35, 'M' => 33, '.' => 32}
++  USE_COLOR = !(ENV['NO_PRY_COLORED_BACON'] == 'true') && Pry::Helpers::BaseHelpers.use_ansi_codes?
++
++  module TestUnitOutput
++    def handle_requirement(description)
++      error = yield
++
++      if error.empty?
++        print colorize_string('.')
++      else
++        print colorize_string(error[0..0])
++      end
++    end
++
++    def handle_summary
++      puts
++      puts ErrorLog if Backtraces
++
++      out = "%d tests, %d assertions, %d failures, %d errors" %
++        Counter.values_at(:specifications, :requirements, :failed, :errors)
++
++      if Counter.values_at(:failed, :errors).inject(:+) > 0
++        puts colorize_string(out, 'F')
++      else
++        puts colorize_string(out, '.')
++      end
++    end
++
++    def colorize_string(text, color = nil)
++      if USE_COLOR
++        "\e[#{ COLORS[color || text] }m#{ text }\e[0m"
++      else
++        text
++      end
++    end
++  end
++end
++
++# Reset top-level binding at the beginning of each test case.
++module Bacon
++  class Context
++    def it_with_reset_binding(description, &block)
++      Pry.toplevel_binding = nil
++      it_without_reset_binding(description, &block)
++    end
++    alias it_without_reset_binding it
++    alias it it_with_reset_binding
++  end
++end
++
++# Support mocha
++# mocha-on-bacon (c) Copyright (C) 2011, Eloy Durán <eloy.de.enige at gmail.com>
++module Bacon
++  module MochaRequirementsCounter
++    def self.increment
++      Counter[:requirements] += 1
++    end
++  end
++
++  class Context
++    include Mocha::API
++
++    def it_with_mocha(description, &block)
++      it_without_mocha(description) do
++        begin
++          mocha_setup
++          block.call
++          mocha_verify(MochaRequirementsCounter)
++        rescue Mocha::ExpectationError => e
++          raise Error.new(:failed, e.message)
++        ensure
++          mocha_teardown
++        end
++      end
++    end
++    alias it_without_mocha it
++    alias it it_with_mocha
++  end
++end
+diff --git a/spec/spec_helpers/mock_pry.rb b/spec/spec_helpers/mock_pry.rb
+new file mode 100644
+index 0000000..c724611
+--- /dev/null
++++ b/spec/spec_helpers/mock_pry.rb
+@@ -0,0 +1,44 @@
++def mock_pry(*args)
++  args.flatten!
++  binding = args.first.is_a?(Binding) ? args.shift : binding()
++  options = args.last.is_a?(Hash) ? args.pop : {}
++
++  input = InputTester.new(*args)
++  output = StringIO.new
++
++  redirect_pry_io(input, output) do
++    binding.pry(options)
++  end
++
++  output.string
++end
++
++# Set I/O streams. Out defaults to an anonymous StringIO.
++def redirect_pry_io(new_in, new_out = StringIO.new)
++  old_in = Pry.config.input
++  old_out = Pry.config.output
++
++  Pry.config.input = new_in
++  Pry.config.output = new_out
++  begin
++    yield
++  ensure
++    Pry.config.input = old_in
++    Pry.config.output = old_out
++  end
++end
++
++class InputTester
++  def initialize(*actions)
++    @orig_actions = actions.dup
++    @actions = actions
++  end
++
++  def readline(*)
++    @actions.shift
++  end
++
++  def rewind
++    @actions = @orig_actions.dup
++  end
++end
+diff --git a/spec/spec_helpers/repl_tester.rb b/spec/spec_helpers/repl_tester.rb
+new file mode 100644
+index 0000000..51457e1
+--- /dev/null
++++ b/spec/spec_helpers/repl_tester.rb
+@@ -0,0 +1,112 @@
++# This is for super-high-level integration testing.
++
++require 'thread'
++require 'delegate'
++
++class ReplTester
++  class Input
++    def initialize(tester_mailbox)
++      @tester_mailbox = tester_mailbox
++    end
++
++    def readline(prompt)
++      @tester_mailbox.push prompt
++      mailbox.pop
++    end
++
++    def mailbox
++      Thread.current[:mailbox]
++    end
++  end
++
++  class Output < SimpleDelegator
++    def clear
++      __setobj__(StringIO.new)
++    end
++  end
++
++  def self.start(options = {}, &block)
++    Thread.current[:mailbox] = Queue.new
++    instance = nil
++    input    = Input.new(Thread.current[:mailbox])
++    output   = Output.new(StringIO.new)
++
++    redirect_pry_io input, output do
++      instance = new(options)
++      instance.instance_eval(&block)
++      instance.ensure_exit
++    end
++  ensure
++    if instance && instance.thread && instance.thread.alive?
++      instance.thread.kill
++    end
++  end
++
++  attr_accessor :thread, :mailbox, :last_prompt
++
++  def initialize(options = {})
++    @pry     = Pry.new(options)
++    @repl    = Pry::REPL.new(@pry)
++    @mailbox = Thread.current[:mailbox]
++
++    @thread  = Thread.new do
++      begin
++        Thread.current[:mailbox] = Queue.new
++        @repl.start
++      ensure
++        Thread.current[:session_ended] = true
++        mailbox.push nil
++      end
++    end
++
++    wait # wait until the instance reaches its first readline
++  end
++
++  # Accept a line of input, as if entered by a user.
++  def input(input)
++    reset_output
++    repl_mailbox.push input
++    wait
++    @pry.output.string
++  end
++
++  # Assert that the current prompt matches the given string or regex.
++  def prompt(match)
++    match.should === last_prompt
++  end
++
++  # Assert that the most recent output (since the last time input was called)
++  # matches the given string or regex.
++  def output(match)
++    match.should === @pry.output.string.chomp
++  end
++
++  # Assert that the Pry session ended naturally after the last input.
++  def assert_exited
++    @should_exit_naturally = true
++  end
++
++  # @private
++  def ensure_exit
++    if @should_exit_naturally
++      @thread[:session_ended].should.be.true
++    else
++      input "exit-all"
++      raise "REPL didn't die" unless @thread[:session_ended]
++    end
++  end
++
++  private
++
++  def reset_output
++    @pry.output.clear
++  end
++
++  def repl_mailbox
++    @thread[:mailbox]
++  end
++
++  def wait
++    @last_prompt = mailbox.pop
++  end
++end
+diff --git a/spec/sticky_locals_spec.rb b/spec/sticky_locals_spec.rb
+new file mode 100644
+index 0000000..7caf931
+--- /dev/null
++++ b/spec/sticky_locals_spec.rb
+@@ -0,0 +1,180 @@
++require_relative 'helper'
++
++describe "Sticky locals (_file_ and friends)" do
++  it 'locals should all exist upon initialization' do
++    proc {
++      pry_eval '_file_', '_dir_', '_ex_', '_pry_', '_'
++    }.should.not.raise(NameError)
++  end
++
++  it 'locals should still exist after cd-ing into a new context' do
++    proc {
++      pry_eval 'cd 0', '_file_', '_dir_', '_ex_', '_pry_', '_'
++    }.should.not.raise(NameError)
++  end
++
++  it 'locals should keep value after cd-ing (_pry_)' do
++    pry_tester.tap do |t|
++      pry = t.eval '_pry_'
++      t.eval 'cd 0'
++      t.eval('_pry_').should == pry
++    end
++  end
++
++  describe '_ex_' do
++    it 'returns the last exception without wrapping it in a LastException' do
++      ReplTester.start do
++        input  'raise "halp"'
++
++        input  '_ex_.message == "halp"'
++        output '=> true'
++
++        input  'Kernel.instance_method(:class).bind(_ex_).call'
++        output '=> RuntimeError'
++      end
++    end
++
++    it 'keeps its value after cd-ing' do
++      ReplTester.start do
++        input  'error blah'
++        input  '$x = _ex_'
++        input  'cd 0'
++
++        input  '_ex_ == $x'
++        output '=> true'
++      end
++    end
++  end
++
++  it 'locals should keep value after cd-ing (_file_ and _dir_)' do
++    Pry.config.commands.command "file-and-dir-test" do
++      set_file_and_dir_locals("/blah/ostrich.rb")
++    end
++
++    pry_eval('file-and-dir-test', 'cd 0', '_file_').
++      should =~ /\/blah\/ostrich\.rb/
++
++    pry_eval('file-and-dir-test', 'cd 0', '_dir_').
++      should =~ /\/blah/
++
++    Pry.config.commands.delete "file-and-dir-test"
++  end
++
++  it 'locals should return last result (_)' do
++    pry_tester.tap do |t|
++      lam = t.eval 'lambda { |foo| }'
++      t.eval('_').should == lam
++    end
++  end
++
++  it 'locals should return second last result (__)' do
++    pry_tester.tap do |t|
++      lam = t.eval 'lambda { |foo| }'
++      t.eval 'num = 1'
++      t.eval('__').should == lam
++    end
++  end
++
++  describe "User defined sticky locals" do
++    describe "setting as Pry.config option" do
++      it 'should define a new sticky local for the session (normal value)' do
++        Pry.config.extra_sticky_locals[:test_local] = :john
++        o = Object.new
++        redirect_pry_io(InputTester.new("@value = test_local",
++                                        "exit-all")) do
++          Pry.start(o)
++        end
++        o.instance_variable_get(:@value).should == :john
++        Pry.config.extra_sticky_locals = {}
++      end
++
++      it 'should define a new sticky local for the session (proc)' do
++        Pry.config.extra_sticky_locals[:test_local] = proc { :john }
++
++        o = Object.new
++        redirect_pry_io(InputTester.new("@value = test_local",
++                                        "exit-all")) do
++          Pry.start(o)
++        end
++
++        o.instance_variable_get(:@value).should == :john
++        Pry.config.extra_sticky_locals = {}
++      end
++
++    end
++
++    describe "passing in as hash option when creating pry instance" do
++      it 'should define a new sticky local for the session (normal value)' do
++        o = Object.new
++        redirect_pry_io(InputTester.new("@value = test_local",
++                                        "exit-all")) do
++          Pry.start(o, :extra_sticky_locals => { :test_local => :john } )
++        end
++
++        o.instance_variable_get(:@value).should == :john
++      end
++
++      it 'should define multiple sticky locals' do
++        o = Object.new
++        redirect_pry_io(InputTester.new("@value1 = test_local1",
++                                        "@value2 = test_local2",
++                                        "exit-all")) do
++          Pry.start(o, :extra_sticky_locals => { :test_local1 => :john ,
++                      :test_local2 => :carl} )
++        end
++
++        o.instance_variable_get(:@value1).should == :john
++        o.instance_variable_get(:@value2).should == :carl
++      end
++
++
++      it 'should define a new sticky local for the session (as Proc)' do
++        o = Object.new
++        redirect_pry_io(InputTester.new("@value = test_local",
++                                        "exit-all")) do
++          Pry.start(o, :extra_sticky_locals => { :test_local => proc { :john }} )
++        end
++
++        o.instance_variable_get(:@value).should == :john
++      end
++    end
++
++    describe "hash option value should override config value" do
++      it 'should define a new sticky local for the session (normal value)' do
++        Pry.config.extra_sticky_locals[:test_local] = :john
++
++        o = Object.new
++        redirect_pry_io(InputTester.new("@value = test_local",
++                                        "exit-all")) do
++          Pry.start(o, :extra_sticky_locals => { :test_local => :carl })
++        end
++
++        o.instance_variable_get(:@value).should == :carl
++        Pry.config.extra_sticky_locals = {}
++      end
++    end
++
++    it 'should create a new sticky local' do
++      t = pry_tester
++      t.eval "_pry_.add_sticky_local(:test_local){ :test_value }"
++      t.eval("test_local").should == :test_value
++    end
++
++    it 'should still exist after cd-ing into new binding' do
++      t = pry_tester
++      t.eval "_pry_.add_sticky_local(:test_local){ :test_value }"
++      t.eval "cd Object.new"
++      t.eval("test_local").should == :test_value
++    end
++
++    it 'should provide different values for successive block invocations' do
++      pry = Pry.new
++      pry.push_binding binding
++      pry.add_sticky_local(:test_local) { rand }
++      value1 = pry.evaluate_ruby 'test_local'
++      value2 = pry.evaluate_ruby 'test_local'
++      value1.should.not == value2
++    end
++  end
++
++end
+diff --git a/spec/syntax_checking_spec.rb b/spec/syntax_checking_spec.rb
+new file mode 100644
+index 0000000..cd2700f
+--- /dev/null
++++ b/spec/syntax_checking_spec.rb
+@@ -0,0 +1,81 @@
++require_relative 'helper'
++
++describe Pry do
++  before do
++    @str_output = StringIO.new
++  end
++
++  [
++    ["p = '", "'"],
++    ["def", "a", "(); end"],
++    ["p = <<FOO", "lots", "and", "lots of", "foo", "FOO"],
++    ["[", ":lets,", "'list',", "[/nested/", "], things ]"],
++    ["abc =~ /hello", "/"],
++    ["issue = %W/", "343/"],
++    ["pouts(<<HI, 'foo", "bar", "HI", "baz')"],
++  ].each do |foo|
++    it "should not raise an error on broken lines: #{foo.join("\\n")}" do
++      redirect_pry_io(InputTester.new(*foo), @str_output) do
++        Pry.start
++      end
++
++      @str_output.string.should.not =~ /SyntaxError/
++    end
++  end
++
++  [
++    ["end"],
++    ["puts )("],
++    ["1 1"],
++    ["puts :"]
++  ] + (Pry::Helpers::BaseHelpers.rbx? ? [] : [
++    ["def", "method(1"], # in this case the syntax error is "expecting ')'".
++    ["o = Object.new.tap{ def o.render;","'MEH'", "}"] # in this case the syntax error is "expecting keyword_end".
++  ]).compact.each do |foo|
++    it "should raise an error on invalid syntax like #{foo.inspect}" do
++      redirect_pry_io(InputTester.new(*foo), @str_output) do
++        Pry.start
++      end
++
++      @str_output.string.should =~ /SyntaxError/
++    end
++  end
++
++  it "should not intefere with syntax errors explicitly raised" do
++    redirect_pry_io(InputTester.new(%q{raise SyntaxError, "unexpected $end"}), @str_output) do
++      Pry.start
++    end
++
++    @str_output.string.should =~ /SyntaxError/
++  end
++
++  it "should allow trailing , to continue the line" do
++    pry = Pry.new
++    Pry::Code.complete_expression?("puts 1, 2,").should == false
++  end
++
++  it "should complete an expression that contains a line ending with a ," do
++    pry = Pry.new
++    Pry::Code.complete_expression?("puts 1, 2,\n3").should == true
++  end
++
++  it "should not suppress the error output if the line ends in ;" do
++    mock_pry("raise RuntimeError, 'foo';").should =~ /RuntimeError/
++  end
++
++  it "should not clobber _ex_ on a SyntaxError in the repl" do
++    mock_pry("raise RuntimeError, 'foo'", "puts foo)", "_ex_.is_a?(RuntimeError)").should =~ /^RuntimeError.*\nSyntaxError.*\n=> true/m
++  end
++
++  it "should allow whitespace delimeted strings" do
++    mock_pry('"%s" %% foo ').should =~ /"foo"/
++  end
++
++  it "should allow newline delimeted strings" do
++    mock_pry('"%s" %%','foo').should =~ /"foo"/
++  end
++
++  it "should allow whitespace delimeted strings ending on the first char of a line" do
++    mock_pry('"%s" %% ', ' #done!').should =~ /"\\n"/
++  end
++end
+diff --git a/spec/wrapped_module_spec.rb b/spec/wrapped_module_spec.rb
+new file mode 100644
+index 0000000..d3d32d0
+--- /dev/null
++++ b/spec/wrapped_module_spec.rb
+@@ -0,0 +1,276 @@
++require_relative 'helper'
++
++describe Pry::WrappedModule do
++
++  describe "#initialize" do
++    it "should raise an exception when a non-module is passed" do
++      lambda{ Pry::WrappedModule.new(nil) }.should.raise ArgumentError
++    end
++  end
++
++  describe "candidates" do
++    before do
++      class Host
++        %w(spec/fixtures/candidate_helper1.rb
++           spec/fixtures/candidate_helper2.rb).each do |file|
++          binding.eval File.read(file), file, 1
++        end
++
++        # rank 2
++        class CandidateTest
++          def test6
++          end
++        end
++
++        class PitifullyBlank
++          DEFAULT_TEST = CandidateTest
++        end
++
++        FOREVER_ALONE_LINE = __LINE__ + 1
++        class ForeverAlone
++          class DoublyNested
++            # nested docs
++            class TriplyNested
++              def nested_method
++              end
++            end
++          end
++        end
++      end
++    end
++
++    describe "number_of_candidates" do
++      it 'should return the correct number of candidates' do
++        Pry::WrappedModule(Host::CandidateTest).number_of_candidates.should == 3
++      end
++
++      it 'should return 0 candidates for a class with no nested modules or methods' do
++        Pry::WrappedModule(Host::PitifullyBlank).number_of_candidates.should == 0
++      end
++
++      it 'should return 1 candidate for a class with a nested module with methods' do
++        Pry::WrappedModule(Host::ForeverAlone).number_of_candidates.should == 1
++      end
++    end
++
++    describe "ordering of candidates" do
++      it 'should return class with largest number of methods as primary candidate' do
++        Pry::WrappedModule(Host::CandidateTest).candidate(0).file.should =~ /helper1/
++      end
++
++      it 'should return class with second largest number of methods as second ranked candidate' do
++        Pry::WrappedModule(Host::CandidateTest).candidate(1).file.should =~ /helper2/
++      end
++
++      it 'should return class with third largest number of methods as third ranked candidate' do
++        Pry::WrappedModule(Host::CandidateTest).candidate(2).file.should =~ /#{__FILE__}/
++      end
++
++      it 'should raise when trying to access non-existent candidate' do
++        lambda { Pry::WrappedModule(Host::CandidateTest).candidate(3) }.should.raise Pry::CommandError
++      end
++    end
++
++    describe "source_location" do
++      it 'should return primary candidates source_location by default' do
++        wm = Pry::WrappedModule(Host::CandidateTest)
++        wm.source_location.should == wm.candidate(0).source_location
++      end
++
++      it 'should return the location of the outer module if an inner module has methods' do
++        wm = Pry::WrappedModule(Host::ForeverAlone)
++        File.expand_path(wm.source_location.first).should == File.expand_path(__FILE__)
++        wm.source_location.last.should == Host::FOREVER_ALONE_LINE
++      end
++
++      it 'should return nil if no source_location can be found' do
++        Pry::WrappedModule(Host::PitifullyBlank).source_location.should == nil
++      end
++    end
++
++    describe "source" do
++      it 'should return primary candidates source by default' do
++        wm = Pry::WrappedModule(Host::CandidateTest)
++        wm.source.should == wm.candidate(0).source
++      end
++
++      it 'should return source for highest ranked candidate' do
++        Pry::WrappedModule(Host::CandidateTest).candidate(0).source.should =~ /test1/
++      end
++
++      it 'should return source for second ranked candidate' do
++        Pry::WrappedModule(Host::CandidateTest).candidate(1).source.should =~ /test4/
++      end
++
++      it 'should return source for third ranked candidate' do
++        Pry::WrappedModule(Host::CandidateTest).candidate(2).source.should =~ /test6/
++      end
++
++      it 'should return source for deeply nested class' do
++        Pry::WrappedModule(Host::ForeverAlone::DoublyNested::TriplyNested).source.should =~ /nested_method/
++        Pry::WrappedModule(Host::ForeverAlone::DoublyNested::TriplyNested).source.lines.count.should == 4
++      end
++    end
++
++    describe "doc" do
++      it 'should return primary candidates doc by default' do
++        wm = Pry::WrappedModule(Host::CandidateTest)
++        wm.doc.should == wm.candidate(0).doc
++      end
++
++      it 'should return doc for highest ranked candidate' do
++        Pry::WrappedModule(Host::CandidateTest).candidate(0).doc.should =~ /rank 0/
++      end
++
++      it 'should return doc for second ranked candidate' do
++        Pry::WrappedModule(Host::CandidateTest).candidate(1).doc.should =~ /rank 1/
++      end
++
++      it 'should return doc for third ranked candidate' do
++        Pry::WrappedModule(Host::CandidateTest).candidate(2).doc.should =~ /rank 2/
++      end
++
++      it 'should return docs for deeply nested class' do
++        Pry::WrappedModule(Host::ForeverAlone::DoublyNested::TriplyNested).doc.should =~ /nested docs/
++      end
++    end
++
++    after do
++      Object.remove_const(:Host)
++    end
++  end
++
++  describe ".method_prefix" do
++    before do
++      Foo = Class.new
++      @foo = Foo.new
++    end
++
++    after do
++      Object.remove_const(:Foo)
++    end
++
++    it "should return Foo# for normal classes" do
++      Pry::WrappedModule.new(Foo).method_prefix.should == "Foo#"
++    end
++
++    it "should return Bar# for modules" do
++      Pry::WrappedModule.new(Kernel).method_prefix.should == "Kernel#"
++    end
++
++    it "should return Foo. for singleton classes of classes" do
++      Pry::WrappedModule.new(class << Foo; self; end).method_prefix.should == "Foo."
++    end
++
++    describe "of singleton classes of objects" do
++      Pry::WrappedModule.new(class << @foo; self; end).method_prefix.should == "self."
++    end
++
++    describe "of anonymous classes should not be empty" do
++      Pry::WrappedModule.new(Class.new).method_prefix.should =~ /#<Class:.*>#/
++    end
++
++    describe "of singleton classes of anonymous classes should not be empty" do
++      Pry::WrappedModule.new(class << Class.new; self; end).method_prefix.should =~ /#<Class:.*>./
++    end
++  end
++
++  describe ".singleton_class?" do
++    it "should be true for singleton classes" do
++      Pry::WrappedModule.new(class << ""; self; end).singleton_class?.should == true
++    end
++
++    it "should be false for normal classes" do
++      Pry::WrappedModule.new(Class.new).singleton_class?.should == false
++    end
++
++    it "should be false for modules" do
++      Pry::WrappedModule.new(Module.new).singleton_class?.should == false
++    end
++  end
++
++  describe ".singleton_instance" do
++    it "should raise an exception when called on a non-singleton-class" do
++      lambda{ Pry::WrappedModule.new(Class).singleton_instance }.should.raise ArgumentError
++    end
++
++    it "should return the attached object" do
++      Pry::WrappedModule.new(class << "hi"; self; end).singleton_instance.should == "hi"
++      Pry::WrappedModule.new(class << Object; self; end).singleton_instance.should.equal?(Object)
++    end
++  end
++
++  describe ".super" do
++    describe "receiver is a class" do
++      before do
++        @a = Class.new
++        @m = Module.new
++        @b = Class.new(@a)
++        @b.send(:include, @m)
++        @c = Class.new(@b)
++      end
++
++      it 'should return superclass for a wrapped class'  do
++        Pry::WrappedModule(@c).super.wrapped.should == @b
++      end
++
++      it 'should return nth superclass for a wrapped class'  do
++        d = Class.new(@c)
++        Pry::WrappedModule(d).super(2).wrapped.should == @b
++      end
++
++      it 'should ignore modules when retrieving nth superclass'  do
++        Pry::WrappedModule(@c).super(2).wrapped.should == @a
++      end
++
++      it 'should return nil when no nth superclass exists' do
++        Pry::WrappedModule(@c).super(10).should == nil
++      end
++
++      it 'should return self when .super(0) is used' do
++        c = Pry::WrappedModule(@c)
++        c.super(0).should == c
++      end
++    end
++
++    describe "receiver is a module" do
++      before do
++        @m1 = Module.new
++        @m2 = Module.new.tap { |v| v.send(:include, @m1) }
++        @m3 = Module.new.tap { |v| v.send(:include, @m2) }
++      end
++
++      it 'should not ignore modules when retrieving supers' do
++        Pry::WrappedModule(@m3).super.wrapped.should == @m2
++      end
++
++      it 'should retrieve nth super' do
++        Pry::WrappedModule(@m3).super(2).wrapped.should == @m1
++      end
++
++      it 'should return self when .super(0) is used' do
++        m = Pry::WrappedModule(@m1)
++        m.super(0).should == m
++      end
++    end
++  end
++
++  describe ".from_str" do
++    it 'should lookup a constant' do
++      m = Pry::WrappedModule.from_str("Host::CandidateTest", binding)
++      m.wrapped.should == Host::CandidateTest
++    end
++
++    it 'should lookup a local' do
++      local = Host::CandidateTest
++      m = Pry::WrappedModule.from_str("local", binding)
++      m.wrapped.should == Host::CandidateTest
++    end
++
++    it 'should lookup an ivar' do
++      @ivar = Host::CandidateTest
++      m = Pry::WrappedModule.from_str("@ivar", binding)
++      m.wrapped.should == Host::CandidateTest
++    end
++  end
++end
diff --git a/debian/patches/0002-Modify-upstream-spec-for-Debian-Package.patch b/debian/patches/0002-Modify-upstream-spec-for-Debian-Package.patch
new file mode 100644
index 0000000..3851efb
--- /dev/null
+++ b/debian/patches/0002-Modify-upstream-spec-for-Debian-Package.patch
@@ -0,0 +1,37 @@
+From: Youhei SASAKI <uwabami at gfd-dennou.org>
+Date: Tue, 12 Aug 2014 19:50:15 +0900
+Subject: Modify upstream spec for Debian Package
+
+Signed-off-by: Youhei SASAKI <uwabami at gfd-dennou.org>
+---
+ Rakefile       | 0
+ spec/helper.rb | 9 +++------
+ 2 files changed, 3 insertions(+), 6 deletions(-)
+ create mode 100644 Rakefile
+
+diff --git a/Rakefile b/Rakefile
+new file mode 100644
+index 0000000..e69de29
+diff --git a/spec/helper.rb b/spec/helper.rb
+index b579d8c..da296cf 100644
+--- a/spec/helper.rb
++++ b/spec/helper.rb
+@@ -1,15 +1,12 @@
+ require 'bundler/setup'
+ require 'pry/test/helper'
+-Bundler.require :default, :test
++require 'ostruct'
++require 'bacon'
++require 'mocha/api'
+ require_relative 'spec_helpers/bacon'
+ require_relative 'spec_helpers/mock_pry'
+ require_relative 'spec_helpers/repl_tester'
+ 
+-if ENV["COVERAGE"]
+-  require "simplecov"
+-  SimpleCov.start
+-end
+-
+ class Module
+   public :remove_const
+   public :remove_method
diff --git a/debian/patches/fix_spelling.patch b/debian/patches/fix_spelling.patch
deleted file mode 100644
index 258fd58..0000000
--- a/debian/patches/fix_spelling.patch
+++ /dev/null
@@ -1,15 +0,0 @@
-Description: fix spelling, not forwarded, upstream will remove manpages
-Author: Jonas Genannt <jonas.genannt at capi2name.de>
-Forwarded: not-needed
-
---- a/man/pry.1
-+++ b/man/pry.1
-@@ -43,7 +43,7 @@
- .
- .TP
- \fB\-\-no\-plugins\fR
--Supress loading of plugins\.
-+Suppress loading of plugins\.
- .
- .TP
- \fB\-\-installed\-plugins\fR
diff --git a/debian/patches/series b/debian/patches/series
index 1201281..c135c64 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1 +1,2 @@
-# fix_spelling.patch
+0001-Import-upstream-rspec-files.patch
+0002-Modify-upstream-spec-for-Debian-Package.patch

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



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