2011-06-02 11:26:49 -04:00
|
|
|
require 'helper'
|
|
|
|
|
|
|
|
describe "Pry::DefaultCommands::Context" do
|
2011-08-25 05:41:43 -04:00
|
|
|
describe "exit-all" do
|
2011-11-05 02:22:21 -04:00
|
|
|
it 'should break out of the repl loop of Pry instance and return nil' do
|
2011-08-25 05:41:43 -04:00
|
|
|
redirect_pry_io(InputTester.new("exit-all"), StringIO.new) do
|
2011-11-05 02:22:21 -04:00
|
|
|
Pry.new.repl(0).should == nil
|
2011-08-21 22:57:59 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'should break out of the repl loop of Pry instance wth a user specified value' do
|
2011-08-25 05:41:43 -04:00
|
|
|
redirect_pry_io(InputTester.new("exit-all 'message'"), StringIO.new) do
|
2011-08-21 22:57:59 -04:00
|
|
|
Pry.new.repl(0).should == 'message'
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-08-25 05:41:43 -04:00
|
|
|
it 'should break of the repl loop even if multiple bindings still on stack' do
|
2011-08-21 22:57:59 -04:00
|
|
|
ins = nil
|
2011-08-25 05:41:43 -04:00
|
|
|
redirect_pry_io(InputTester.new("cd 1", "cd 2", "exit-all 'message'"), StringIO.new) do
|
2011-08-21 22:57:59 -04:00
|
|
|
ins = Pry.new.tap { |v| v.repl(0).should == 'message' }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'binding_stack should be empty after breaking out of the repl loop' do
|
|
|
|
ins = nil
|
2011-08-25 05:41:43 -04:00
|
|
|
redirect_pry_io(InputTester.new("cd 1", "cd 2", "exit-all"), StringIO.new) do
|
2011-08-21 22:57:59 -04:00
|
|
|
ins = Pry.new.tap { |v| v.repl(0) }
|
|
|
|
end
|
|
|
|
|
|
|
|
ins.binding_stack.empty?.should == true
|
|
|
|
end
|
2011-08-22 05:17:52 -04:00
|
|
|
end
|
|
|
|
|
2011-12-03 23:21:02 -05:00
|
|
|
describe "whereami" do
|
|
|
|
it 'should work with methods that have been undefined' do
|
|
|
|
class Cor
|
|
|
|
def blimey!
|
|
|
|
Cor.send :undef_method, :blimey!
|
|
|
|
# using [.] so the regex doesn't match itself
|
|
|
|
mock_pry(binding, 'whereami').should =~ /self[.]blimey!/
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
Cor.new.blimey!
|
|
|
|
Object.remove_const(:Cor)
|
|
|
|
end
|
2012-03-08 01:20:23 -05:00
|
|
|
|
|
|
|
it 'should work in objects with no method methods' do
|
|
|
|
class Cor
|
|
|
|
def blimey!
|
|
|
|
mock_pry(binding, 'whereami').should =~ /Cor[#]blimey!/
|
|
|
|
end
|
|
|
|
|
|
|
|
def method; "moo"; end
|
|
|
|
end
|
|
|
|
Cor.new.blimey!
|
|
|
|
Object.remove_const(:Cor)
|
|
|
|
end
|
2011-12-03 23:21:02 -05:00
|
|
|
end
|
|
|
|
|
2011-08-25 05:41:43 -04:00
|
|
|
describe "exit" do
|
|
|
|
it 'should pop a binding with exit' do
|
|
|
|
b = Pry.binding_for(:outer)
|
|
|
|
b.eval("x = :inner")
|
|
|
|
|
|
|
|
redirect_pry_io(InputTester.new("cd x", "$inner = self;", "exit", "$outer = self", "exit-all"), StringIO.new) do
|
|
|
|
b.pry
|
|
|
|
end
|
|
|
|
$inner.should == :inner
|
|
|
|
$outer.should == :outer
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'should break out of the repl loop of Pry instance when binding_stack has only one binding with exit' do
|
2011-11-05 02:22:21 -04:00
|
|
|
Pry.start(0, :input => StringIO.new("exit")).should == nil
|
2011-08-25 05:41:43 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'should break out of the repl loop of Pry instance when binding_stack has only one binding with exit, and return user-given value' do
|
|
|
|
Pry.start(0, :input => StringIO.new("exit :john")).should == :john
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-08-22 05:17:52 -04:00
|
|
|
describe "jump-to" do
|
|
|
|
it 'should jump to the proper binding index in the stack' do
|
|
|
|
outp = StringIO.new
|
2011-08-25 05:41:43 -04:00
|
|
|
redirect_pry_io(InputTester.new("cd 1", "cd 2", "jump-to 1", "$blah = self", "exit-all"), outp) do
|
2011-08-22 05:17:52 -04:00
|
|
|
Pry.start(0)
|
|
|
|
end
|
2011-08-21 22:57:59 -04:00
|
|
|
|
2011-08-22 05:17:52 -04:00
|
|
|
$blah.should == 1
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'should print error when trying to jump to a non-existent binding index' do
|
|
|
|
outp = StringIO.new
|
2011-08-25 05:41:43 -04:00
|
|
|
redirect_pry_io(InputTester.new("cd 1", "cd 2", "jump-to 100", "exit-all"), outp) do
|
2011-08-22 05:17:52 -04:00
|
|
|
Pry.start(0)
|
|
|
|
end
|
|
|
|
|
|
|
|
outp.string.should =~ /Invalid nest level/
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'should print error when trying to jump to the same binding index' do
|
|
|
|
outp = StringIO.new
|
2011-08-25 05:41:43 -04:00
|
|
|
redirect_pry_io(InputTester.new("cd 1", "cd 2", "jump-to 2", "exit-all"), outp) do
|
2011-08-22 05:17:52 -04:00
|
|
|
Pry.new.repl(0)
|
|
|
|
end
|
|
|
|
|
|
|
|
outp.string.should =~ /Already/
|
|
|
|
end
|
2011-08-21 22:57:59 -04:00
|
|
|
end
|
|
|
|
|
2011-08-25 05:41:43 -04:00
|
|
|
describe "exit-program" do
|
2011-08-21 22:57:59 -04:00
|
|
|
it 'should raise SystemExit' do
|
2011-08-25 05:41:43 -04:00
|
|
|
redirect_pry_io(InputTester.new("exit-program"), StringIO.new) do
|
2011-08-21 22:57:59 -04:00
|
|
|
lambda { Pry.new.repl(0).should == 0 }.should.raise SystemExit
|
|
|
|
end
|
|
|
|
end
|
2011-08-29 11:22:10 -04:00
|
|
|
|
|
|
|
it 'should exit the program with the provided value' do
|
|
|
|
redirect_pry_io(InputTester.new("exit-program 66"), StringIO.new) do
|
|
|
|
begin
|
|
|
|
Pry.new.repl(0)
|
|
|
|
rescue SystemExit => e
|
|
|
|
e.status.should == 66
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2011-08-21 22:57:59 -04:00
|
|
|
end
|
|
|
|
|
2011-06-02 11:26:49 -04:00
|
|
|
describe "cd" do
|
|
|
|
after do
|
|
|
|
$obj = nil
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'should cd into simple input' do
|
|
|
|
b = Pry.binding_for(Object.new)
|
|
|
|
b.eval("x = :mon_ouie")
|
|
|
|
|
|
|
|
redirect_pry_io(InputTester.new("cd x", "$obj = self", "exit-all"), StringIO.new) do
|
|
|
|
b.pry
|
|
|
|
end
|
|
|
|
|
|
|
|
$obj.should == :mon_ouie
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'should break out of session with cd ..' do
|
|
|
|
b = Pry.binding_for(:outer)
|
|
|
|
b.eval("x = :inner")
|
|
|
|
|
|
|
|
redirect_pry_io(InputTester.new("cd x", "$inner = self;", "cd ..", "$outer = self", "exit-all"), StringIO.new) do
|
|
|
|
b.pry
|
|
|
|
end
|
|
|
|
$inner.should == :inner
|
|
|
|
$outer.should == :outer
|
|
|
|
end
|
|
|
|
|
2012-01-03 23:45:24 -05:00
|
|
|
it "should not leave the REPL session when given 'cd ..'" do
|
|
|
|
b = Pry.binding_for(Object.new)
|
|
|
|
input = InputTester.new "cd ..", "$obj = self", "exit-all"
|
|
|
|
|
|
|
|
redirect_pry_io(input, StringIO.new) do
|
|
|
|
b.pry
|
|
|
|
end
|
|
|
|
|
|
|
|
$obj.should == b.eval("self")
|
2011-08-21 22:57:59 -04:00
|
|
|
end
|
|
|
|
|
2011-06-02 11:26:49 -04:00
|
|
|
it 'should break out to outer-most session with cd /' do
|
|
|
|
b = Pry.binding_for(:outer)
|
|
|
|
b.eval("x = :inner")
|
|
|
|
|
|
|
|
redirect_pry_io(InputTester.new("cd x", "$inner = self;", "cd 5", "$five = self", "cd /", "$outer = self", "exit-all"), StringIO.new) do
|
|
|
|
b.pry
|
|
|
|
end
|
|
|
|
$inner.should == :inner
|
|
|
|
$five.should == 5
|
|
|
|
$outer.should == :outer
|
|
|
|
end
|
|
|
|
|
2011-09-03 06:37:46 -04:00
|
|
|
it 'should break out to outer-most session with just cd (no args)' do
|
|
|
|
b = Pry.binding_for(:outer)
|
|
|
|
b.eval("x = :inner")
|
|
|
|
|
|
|
|
redirect_pry_io(InputTester.new("cd x", "$inner = self;", "cd 5", "$five = self", "cd", "$outer = self", "exit-all"), StringIO.new) do
|
|
|
|
b.pry
|
|
|
|
end
|
|
|
|
$inner.should == :inner
|
|
|
|
$five.should == 5
|
|
|
|
$outer.should == :outer
|
|
|
|
end
|
|
|
|
|
2011-09-05 12:12:53 -04:00
|
|
|
it 'should cd into an object and its ivar using cd obj/@ivar syntax' do
|
|
|
|
$obj = Object.new
|
|
|
|
$obj.instance_variable_set(:@x, 66)
|
|
|
|
|
|
|
|
redirect_pry_io(InputTester.new("cd $obj/@x", "$result = _pry_.binding_stack.dup", "exit-all"), StringIO.new) do
|
|
|
|
Pry.start
|
|
|
|
end
|
|
|
|
$result.size.should == 3
|
|
|
|
$result[1].eval('self').should == $obj
|
|
|
|
$result[2].eval('self').should == 66
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'should cd into an object and its ivar using cd obj/@ivar/ syntax (note following /)' do
|
|
|
|
$obj = Object.new
|
|
|
|
$obj.instance_variable_set(:@x, 66)
|
|
|
|
|
|
|
|
redirect_pry_io(InputTester.new("cd $obj/@x/", "$result = _pry_.binding_stack.dup", "exit-all"), StringIO.new) do
|
|
|
|
Pry.start
|
|
|
|
end
|
|
|
|
$result.size.should == 3
|
|
|
|
$result[1].eval('self').should == $obj
|
|
|
|
$result[2].eval('self').should == 66
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'should cd into previous object and its local using cd ../local syntax' do
|
|
|
|
$obj = Object.new
|
|
|
|
$obj.instance_variable_set(:@x, 66)
|
|
|
|
|
|
|
|
redirect_pry_io(InputTester.new("cd $obj", "local = :local", "cd @x", "cd ../local", "$result = _pry_.binding_stack.dup", "exit-all"), StringIO.new) do
|
|
|
|
Pry.start
|
|
|
|
end
|
|
|
|
$result.size.should == 3
|
|
|
|
$result[1].eval('self').should == $obj
|
|
|
|
$result[2].eval('self').should == :local
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'should cd into an object and its ivar and back again using cd obj/@ivar/.. syntax' do
|
|
|
|
$obj = Object.new
|
|
|
|
$obj.instance_variable_set(:@x, 66)
|
|
|
|
|
|
|
|
redirect_pry_io(InputTester.new("cd $obj/@x/..", "$result = _pry_.binding_stack.dup", "exit-all"), StringIO.new) do
|
|
|
|
Pry.start
|
|
|
|
end
|
|
|
|
$result.size.should == 2
|
|
|
|
$result[1].eval('self').should == $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
|
|
|
|
$obj = Object.new
|
|
|
|
$obj.instance_variable_set(:@x, 66)
|
|
|
|
$obj.instance_variable_set(:@y, 79)
|
|
|
|
|
|
|
|
redirect_pry_io(InputTester.new("cd $obj/@x/../@y", "$result = _pry_.binding_stack.dup", "exit-all"), StringIO.new) do
|
|
|
|
Pry.start
|
|
|
|
end
|
|
|
|
$result.size.should == 3
|
|
|
|
$result[1].eval('self').should == $obj
|
|
|
|
$result[2].eval('self').should == 79
|
|
|
|
end
|
2011-06-02 11:26:49 -04:00
|
|
|
|
2011-09-05 12:12:53 -04:00
|
|
|
it 'should cd back to top-level and then into another ivar using cd /@ivar/ syntax' do
|
|
|
|
$obj = Object.new
|
|
|
|
$obj.instance_variable_set(:@x, 66)
|
|
|
|
TOPLEVEL_BINDING.eval('@z = 20')
|
|
|
|
|
|
|
|
redirect_pry_io(InputTester.new("cd $obj/@x/", "cd /@z", "$result = _pry_.binding_stack.dup", "exit-all"), StringIO.new) do
|
|
|
|
Pry.start
|
|
|
|
end
|
|
|
|
$result.size.should == 2
|
|
|
|
$result[1].eval('self').should == 20
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'should start a session on TOPLEVEL_BINDING with cd ::' do
|
2011-06-02 11:26:49 -04:00
|
|
|
redirect_pry_io(InputTester.new("cd ::", "$obj = self", "exit-all"), StringIO.new) do
|
|
|
|
5.pry
|
|
|
|
end
|
|
|
|
$obj.should == TOPLEVEL_BINDING.eval('self')
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'should cd into complex input (with spaces)' do
|
|
|
|
o = Object.new
|
|
|
|
def o.hello(x, y, z)
|
|
|
|
:mon_ouie
|
|
|
|
end
|
|
|
|
|
|
|
|
redirect_pry_io(InputTester.new("cd hello 1, 2, 3", "$obj = self", "exit-all"), StringIO.new) do
|
|
|
|
o.pry
|
|
|
|
end
|
|
|
|
$obj.should == :mon_ouie
|
|
|
|
end
|
|
|
|
end
|
2012-03-08 00:54:19 -05:00
|
|
|
|
|
|
|
describe "raise-up" do
|
|
|
|
it "should raise the exception with raise-up" do
|
|
|
|
redirect_pry_io(InputTester.new("raise NoMethodError", "raise-up NoMethodError"),StringIO.new) do
|
|
|
|
lambda { Pry.new.repl(0) }.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'"),StringIO.new) do
|
|
|
|
lambda { Pry.new.repl(0) }.should.raise RuntimeError, "noreally"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it "should eat the exception at the last new pry instance on raise-up" do
|
|
|
|
b = Pry.binding_for(:outer)
|
|
|
|
b.eval("x = :inner")
|
|
|
|
|
|
|
|
redirect_pry_io(InputTester.new("x.pry", "raise NoMethodError",
|
|
|
|
"$inner = self", "raise-up NoMethodError", "$outer = self", "exit-all"),StringIO.new) do
|
|
|
|
b.pry
|
|
|
|
end
|
|
|
|
$inner.should == :inner
|
|
|
|
$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
|
|
|
|
$deep = $inner = $outer = nil
|
|
|
|
b = Pry.binding_for(:outer)
|
|
|
|
b.eval("x = :inner")
|
|
|
|
redirect_pry_io(InputTester.new("cd x", "raise NoMethodError","$inner = self",
|
|
|
|
"deep = :deep", "cd deep","$deep = self","raise-up NoMethodError", "raise-up", "$outer = self", "raise-up", "exit-all"),StringIO.new) do
|
|
|
|
lambda { b.pry }.should.raise NoMethodError
|
|
|
|
end
|
|
|
|
$deep.should == :deep
|
|
|
|
$inner.should == :inner
|
|
|
|
$outer.should == :outer
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "raise-up!" do
|
|
|
|
it "should jump immediately out of nested context's" do
|
|
|
|
lambda { mock_pry("cd 1", "cd 2", "cd 3", "raise-up! 'fancy that...'") }.should.raise RuntimeError, 'fancy that...'
|
|
|
|
end
|
|
|
|
end
|
2011-06-02 11:26:49 -04:00
|
|
|
end
|