From e8b54c9a2303f9e7389ae85202739a63ccac5336 Mon Sep 17 00:00:00 2001 From: John Mair Date: Thu, 25 Aug 2011 21:41:43 +1200 Subject: [PATCH] reverted behaviour of exit and friends back to 1.9.3 behaviour (to prevent surprising users) also updated tests to reflect this --- lib/pry/default_commands/context.rb | 41 +++++++++++++------- test/test_default_commands/test_context.rb | 45 ++++++++++++++++------ test/test_pry.rb | 42 ++++++++++---------- 3 files changed, 81 insertions(+), 47 deletions(-) diff --git a/lib/pry/default_commands/context.rb b/lib/pry/default_commands/context.rb index d54a3927..59a4eb7b 100644 --- a/lib/pry/default_commands/context.rb +++ b/lib/pry/default_commands/context.rb @@ -44,8 +44,6 @@ class Pry end command "nesting", "Show nesting information." do - nesting = opts[:nesting] - output.puts "Nesting status:" output.puts "--" _pry_.binding_stack.each_with_index do |obj, level| @@ -57,7 +55,7 @@ class Pry end end - command "jump-to", "Jump to a Pry session further up the stack, exiting all sessions below." do |break_level| + command "jump-to", "Jump to a binding further up the stack, popping all bindings below." do |break_level| break_level = break_level.to_i nesting_level = _pry_.binding_stack.size - 1 @@ -73,8 +71,7 @@ class Pry end end - command "quit", "End the current Pry session. Accepts optional return value. Aliases: exit-all, !!@" do - + command "exit-all", "End the current Pry session (popping all bindings) and returning to caller. Accepts optional return value. Aliases: !!@" do # clear the binding stack _pry_.binding_stack.clear @@ -82,19 +79,35 @@ class Pry throw(:breakout, target.eval(arg_string)) end - alias_command "!!@", "quit", "" - alias_command "exit-all", "quit", "" - alias_command "!!@", "exit-all", "" - command "exit", "End the current program. Aliases: exit-program, quit-program, !!!" do - Pry.save_history if Pry.config.history.should_save - exit + command "exit", "Pop the current binding and return to the one immediately prior. Note this does NOT exit the program. Aliases: quit", :keep_retval => true do + if _pry_.binding_stack.one? + # when breaking out of top-level then behave like `exit-all` + _pry_.binding_stack.clear + throw(:breakout, target.eval(arg_string)) + else + # otherwise just pop a binding + popped_object = _pry_.binding_stack.pop.eval('self') + + # return a user-specified value if given + if !arg_string.empty? + target.eval(arg_string) + else + popped_object + end + end end - alias_command "exit-program", "exit", "" - alias_command "quit-program", "exit", "" - alias_command "!!!", "exit", "" + alias_command "quit", "exit", "" + + command "exit-program", "End the current program. Aliases: quit-program, !!!" do + Pry.save_history if Pry.config.history.should_save + Kernel.exit + end + + alias_command "quit-program", "exit-program", "" + alias_command "!!!", "exit-program", "" command "!pry", "Start a Pry session on current self; this even works mid-expression." do target.pry diff --git a/test/test_default_commands/test_context.rb b/test/test_default_commands/test_context.rb index 9c7a68c9..01949628 100644 --- a/test/test_default_commands/test_context.rb +++ b/test/test_default_commands/test_context.rb @@ -1,29 +1,29 @@ require 'helper' describe "Pry::DefaultCommands::Context" do - describe "quit" do + describe "exit-all" do it 'should break out of the repl loop of Pry instance (returning target of session)' do - redirect_pry_io(InputTester.new("quit"), StringIO.new) do + redirect_pry_io(InputTester.new("exit-all"), StringIO.new) do Pry.new.repl(0).should == 0 end end it 'should break out of the repl loop of Pry instance wth a user specified value' do - redirect_pry_io(InputTester.new("quit 'message'"), StringIO.new) do + redirect_pry_io(InputTester.new("exit-all 'message'"), StringIO.new) do Pry.new.repl(0).should == 'message' end end - it 'should quit break of the repl loop even if multiple bindings still on stack' do + it 'should break of the repl loop even if multiple bindings still on stack' do ins = nil - redirect_pry_io(InputTester.new("cd 1", "cd 2", "quit 'message'"), StringIO.new) do + redirect_pry_io(InputTester.new("cd 1", "cd 2", "exit-all 'message'"), StringIO.new) do 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 - redirect_pry_io(InputTester.new("cd 1", "cd 2", "quit"), StringIO.new) do + redirect_pry_io(InputTester.new("cd 1", "cd 2", "exit-all"), StringIO.new) do ins = Pry.new.tap { |v| v.repl(0) } end @@ -31,10 +31,31 @@ describe "Pry::DefaultCommands::Context" do end end + 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 + Pry.start(0, :input => StringIO.new("exit")).should == 0 + 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 + describe "jump-to" do it 'should jump to the proper binding index in the stack' do outp = StringIO.new - redirect_pry_io(InputTester.new("cd 1", "cd 2", "jump-to 1", "$blah = self", "quit"), outp) do + redirect_pry_io(InputTester.new("cd 1", "cd 2", "jump-to 1", "$blah = self", "exit-all"), outp) do Pry.start(0) end @@ -43,7 +64,7 @@ describe "Pry::DefaultCommands::Context" do it 'should print error when trying to jump to a non-existent binding index' do outp = StringIO.new - redirect_pry_io(InputTester.new("cd 1", "cd 2", "jump-to 100", "quit"), outp) do + redirect_pry_io(InputTester.new("cd 1", "cd 2", "jump-to 100", "exit-all"), outp) do Pry.start(0) end @@ -52,7 +73,7 @@ describe "Pry::DefaultCommands::Context" do it 'should print error when trying to jump to the same binding index' do outp = StringIO.new - redirect_pry_io(InputTester.new("cd 1", "cd 2", "jump-to 2", "quit"), outp) do + redirect_pry_io(InputTester.new("cd 1", "cd 2", "jump-to 2", "exit-all"), outp) do Pry.new.repl(0) end @@ -60,9 +81,9 @@ describe "Pry::DefaultCommands::Context" do end end - describe "exit" do + describe "exit-program" do it 'should raise SystemExit' do - redirect_pry_io(InputTester.new("exit"), StringIO.new) do + redirect_pry_io(InputTester.new("exit-program"), StringIO.new) do lambda { Pry.new.repl(0).should == 0 }.should.raise SystemExit end end @@ -95,7 +116,7 @@ describe "Pry::DefaultCommands::Context" do $outer.should == :outer end - it 'should break out of the repl loop of Pry instance when binding_stack has only one binding' do + it 'should break out of the repl loop of Pry instance when binding_stack has only one binding with cd ..' do # redirect_pry_io(InputTester.new("ls"), StringIO.new) do # o = Pry.new.tap { |v| v.repl(0) } # end diff --git a/test/test_pry.rb b/test/test_pry.rb index 6ac18908..4098cd67 100644 --- a/test/test_pry.rb +++ b/test/test_pry.rb @@ -175,7 +175,7 @@ describe Pry do describe "repl" do describe "basic functionality" do it 'should set an ivar on an object and exit the repl' do - input_strings = ["@x = 10", "quit"] + input_strings = ["@x = 10", "exit-all"] input = InputTester.new(*input_strings) o = Object.new @@ -262,10 +262,10 @@ describe Pry do Pry.config.should_load_rc = true Pry::RC_FILES << File.expand_path("../testrc", __FILE__) - Pry.start(self, :input => StringIO.new("quit\n"), :output => Pry::NullOutput) + Pry.start(self, :input => StringIO.new("exit-all\n"), :output => Pry::NullOutput) TEST_RC.should == [0] - Pry.start(self, :input => StringIO.new("quit\n"), :output => Pry::NullOutput) + Pry.start(self, :input => StringIO.new("exit-all\n"), :output => Pry::NullOutput) TEST_RC.should == [0] Object.remove_const(:TEST_RC) @@ -273,13 +273,13 @@ describe Pry do 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.start(self, :input => StringIO.new("quit\n"), :output => Pry::NullOutput) + Pry.start(self, :input => StringIO.new("exit-all\n"), :output => Pry::NullOutput) Object.const_defined?(:TEST_RC).should == false end it "should not load the rc file if #repl method invoked" do Pry.config.should_load_rc = true - Pry.new(:input => StringIO.new("quit\n"), :output => Pry::NullOutput).repl(self) + Pry.new(:input => StringIO.new("exit-all\n"), :output => Pry::NullOutput).repl(self) Object.const_defined?(:TEST_RC).should == false Pry.config.should_load_rc = false end @@ -377,7 +377,7 @@ describe Pry do end it "should start a pry session on the receiver (first form)" do - Pry.input = InputTester.new("self", "quit") + Pry.input = InputTester.new("self", "exit-all") str_output = StringIO.new Pry.output = str_output @@ -388,7 +388,7 @@ describe Pry do end it "should start a pry session on the receiver (second form)" do - Pry.input = InputTester.new("self", "quit") + Pry.input = InputTester.new("self", "exit-all") str_output = StringIO.new Pry.output = str_output @@ -446,7 +446,7 @@ describe Pry do attr_accessor :prompt def readline(prompt) @prompt = prompt - "quit" + "exit-all" end end.new @@ -459,7 +459,7 @@ describe Pry do arity_zero_input = Class.new do def readline - "quit" + "exit-all" end end.new @@ -474,7 +474,7 @@ describe Pry do def readline(*args) @prompt = args.first - "quit" + "exit-all" end end.new @@ -673,7 +673,7 @@ describe Pry do it 'should create a command in a nested context and that command should be accessible from the parent' do redirect_pry_io(StringIO.new, StringIO.new) do - str_input = StringIO.new("@x=nil\ncd 7\n_pry_.commands.instance_eval {\ncommand('bing') { |arg| run arg }\n}\ncd ..\nbing ls\nquit") + str_input = StringIO.new("@x=nil\ncd 7\n_pry_.commands.instance_eval {\ncommand('bing') { |arg| run arg }\n}\ncd ..\nbing ls\nexit-all") str_output = StringIO.new Pry.input = str_input obj = Object.new @@ -926,23 +926,23 @@ describe Pry do describe "pry return values" do it 'should return the target object' do - Pry.start(self, :input => StringIO.new("quit"), :output => Pry::NullOutput).should == self + Pry.start(self, :input => StringIO.new("exit-all"), :output => Pry::NullOutput).should == self end - it 'should return the parameter given to quit' do - Pry.start(self, :input => StringIO.new("quit 10"), :output => Pry::NullOutput).should == 10 + it 'should return the parameter given to exit-all' do + Pry.start(self, :input => StringIO.new("exit-all 10"), :output => Pry::NullOutput).should == 10 end - it 'should return the parameter (multi word string) given to quit' do - Pry.start(self, :input => StringIO.new("quit \"john mair\""), :output => Pry::NullOutput).should == "john mair" + it 'should return the parameter (multi word string) given to exit-all' do + Pry.start(self, :input => StringIO.new("exit-all \"john mair\""), :output => Pry::NullOutput).should == "john mair" end - it 'should return the parameter (function call) given to quit' do - Pry.start(self, :input => StringIO.new("quit 'abc'.reverse"), :output => Pry::NullOutput).should == 'cba' + it 'should return the parameter (function call) given to exit-all' do + Pry.start(self, :input => StringIO.new("exit-all 'abc'.reverse"), :output => Pry::NullOutput).should == 'cba' end - it 'should return the parameter (self) given to quit' do - Pry.start("carl", :input => StringIO.new("quit self"), :output => Pry::NullOutput).should == "carl" + it 'should return the parameter (self) given to exit-all' do + Pry.start("carl", :input => StringIO.new("exit-all self"), :output => Pry::NullOutput).should == "carl" end end @@ -1048,7 +1048,7 @@ describe Pry do end it 'should set the hooks default, and the default should be overridable' do - Pry.input = InputTester.new("quit") + Pry.input = InputTester.new("exit-all") Pry.hooks = { :before_session => proc { |out,_| out.puts "HELLO" }, :after_session => proc { |out,_| out.puts "BYE" }