From eeb67684d05c1f2cfb85661f6929c0d6f43e2cdd Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Thu, 20 Dec 2012 01:28:04 -0800 Subject: [PATCH] Add Pry::Driver to handle the reading and looping --- lib/pry.rb | 1 + lib/pry/driver.rb | 197 +++++++++++++++++++++++++++++++ lib/pry/pry_class.rb | 5 +- lib/pry/pry_instance.rb | 171 ++------------------------- spec/command_integration_spec.rb | 35 ++---- spec/commands/raise_up_spec.rb | 4 +- spec/control_d_handler_spec.rb | 29 ++--- spec/input_stack_spec.rb | 32 +++-- spec/pry_defaults_spec.rb | 44 ++++--- spec/pry_spec.rb | 63 ++++------ spec/sticky_locals_spec.rb | 25 ++-- 11 files changed, 300 insertions(+), 306 deletions(-) create mode 100644 lib/pry/driver.rb diff --git a/lib/pry.rb b/lib/pry.rb index 54a26b1f..6cc70050 100644 --- a/lib/pry.rb +++ b/lib/pry.rb @@ -229,6 +229,7 @@ rescue LoadError end require 'pry/version' +require 'pry/driver' require 'pry/rbx_method' require 'pry/rbx_path' require 'pry/code' diff --git a/lib/pry/driver.rb b/lib/pry/driver.rb new file mode 100644 index 00000000..563cf5c7 --- /dev/null +++ b/lib/pry/driver.rb @@ -0,0 +1,197 @@ +require 'forwardable' +class Pry + class Driver + extend Forwardable + attr_accessor :pry + + def_delegators :pry, :input, :output, :input_stack + + def self.start(options) + new(options).repl + end + + def initialize(options) + @pry = Pry.new(options) + @indent = Pry::Indent.new + end + + def repl + repl_prologue + + # FIXME: move these catchers back into Pry#accept_line + break_data = nil + exception = catch(:raise_up) do + break_data = catch(:breakout) do + repl_body + end + exception = false + end + + raise exception if exception + + break_data + ensure + repl_epilogue + end + + private + + def repl_prologue + pry.exec_hook :before_session, pry.output, pry.current_binding, pry + + # Clear the line before starting Pry. This fixes the issue discussed here: + # https://github.com/pry/pry/issues/566 + if Pry.config.auto_indent + Kernel.print Pry::Helpers::BaseHelpers.windows_ansi? ? "\e[0F" : "\e[0G" + end + + end + + def repl_body + loop do + case val = retrieve_line + when :control_c + output.puts "" + pry.reset_line + when :end_of_file + output.puts "" if output.tty? + pry.accept_eof + else + pry.accept_line val + end + end + end + + # Clean-up after the repl session. + def repl_epilogue + pry.exec_hook :after_session, pry.output, pry.current_binding, pry + + Pry.save_history if Pry.config.history.should_save + end + + # Read and process a line of input -- check for ^D, determine which prompt to + # use, rewrite the indentation if `Pry.config.auto_indent` is enabled, and, + # if the line is a command, process it and alter the @eval_string accordingly. + # + # @return [String] The line received. + def retrieve_line + @indent.reset if pry.eval_string.empty? + + current_prompt = pry.select_prompt + completion_proc = Pry.config.completer.build_completion_proc(pry.current_binding, pry, + pry.instance_eval(&pry.custom_completions)) + + safe_completion_proc = proc{ |*a| Pry.critical_section{ completion_proc.call(*a) } } + + indentation = Pry.config.auto_indent ? @indent.current_prefix : '' + + begin + val = readline("#{current_prompt}#{indentation}", safe_completion_proc) + + # Handle like Bash, empty the current input buffer but do not quit. + # This is only for ruby-1.9; other versions of ruby do not let you send Interrupt + # from within Readline. + rescue Interrupt + return :control_c + end + + # invoke handler if we receive EOF character (^D) + return :end_of_file unless val + + if Pry.config.auto_indent && !input.is_a?(StringIO) + original_val = "#{indentation}#{val}" + indented_val = @indent.indent(val) + + if output.tty? && Pry::Helpers::BaseHelpers.use_ansi_codes? && Pry.config.correct_indent + output.print @indent.correct_indentation(current_prompt, indented_val, original_val.length - indented_val.length) + output.flush + end + else + indented_val = val + end + + Pry.history << indented_val if interactive? + + indented_val + end + + # Is the user typing into this pry instance directly? + # @return [Boolean] + def interactive? + !input.is_a?(StringIO) + end + + # Manage switching of input objects on encountering EOFErrors + def handle_read_errors + should_retry = true + exception_count = 0 + begin + yield + rescue EOFError + if input_stack.empty? + pry.input = Pry.config.input + if !should_retry + output.puts "Error: Pry ran out of things to read from! Attempting to break out of REPL." + throw(:breakout) + end + should_retry = false + else + pry.input = input_stack.pop + end + + retry + + # Interrupts are handled in r() because they need to tweak @eval_string + # TODO: Refactor this baby. + rescue Interrupt + raise + + # If we get a random error when trying to read a line we don't want to automatically + # retry, as the user will see a lot of error messages scroll past and be unable to do + # anything about it. + rescue RescuableException => e + puts "Error: #{e.message}" + output.puts e.backtrace + exception_count += 1 + if exception_count < 5 + retry + end + puts "FATAL: Pry failed to get user input using `#{input}`." + puts "To fix this you may be able to pass input and output file descriptors to pry directly. e.g." + puts " Pry.config.input = STDIN" + puts " Pry.config.output = STDOUT" + puts " binding.pry" + throw(:breakout) + end + end + + # Returns the next line of input to be used by the pry instance. + # This method should not need to be invoked directly. + # @param [String] current_prompt The prompt to use for input. + # @return [String] The next line of input. + def readline(current_prompt="> ", completion_proc=nil) + handle_read_errors do + if defined? Coolline and input.is_a? Coolline + input.completion_proc = proc do |cool| + completions = completion_proc.call cool.completed_word + completions.compact + end + elsif input.respond_to? :completion_proc= + input.completion_proc = completion_proc + end + + if input == Readline + input.readline(current_prompt, false) # false since we'll add it manually + elsif defined? Coolline and input.is_a? Coolline + input.readline(current_prompt) + else + if input.method(:readline).arity == 1 + input.readline(current_prompt) + else + input.readline + end + end + end + end + end +end diff --git a/lib/pry/pry_class.rb b/lib/pry/pry_class.rb index 58e9e1a5..7f473b8f 100644 --- a/lib/pry/pry_class.rb +++ b/lib/pry/pry_class.rb @@ -148,8 +148,11 @@ class Pry end end + driver = options[:driver] || Pry::Driver + # Enter the matrix - new(options).repl + driver.new(options).repl + rescue Pry::TooSafeException puts "ERROR: Pry cannot work with $SAFE > 0" raise diff --git a/lib/pry/pry_instance.rb b/lib/pry/pry_instance.rb index 6b3275a9..ab2f54cd 100644 --- a/lib/pry/pry_instance.rb +++ b/lib/pry/pry_instance.rb @@ -231,48 +231,18 @@ class Pry Pry.save_history if Pry.config.history.should_save end - # Start a read-eval-print-loop in the current context. - def repl - repl_prologue - - break_data = nil - exception = catch(:raise_up) do - break_data = catch(:breakout) do - r - end - exception = false - end - - raise exception if exception - - break_data - ensure - repl_epilogue + def reset_line + @eval_string = "" end - def r - loop do - throw(:breakout) if current_binding.nil? - @suppress_output = false - inject_sticky_locals! - - case val = retrieve_line - when :control_c - output.puts "" - @eval_string = "" - when :end_of_file - output.puts "" if output.tty? - Pry.config.control_d_handler.call(@eval_string, self) - else - ensure_correct_encoding!(val) - accept_line(val) - end - - exec_hook :after_read, @eval_string, self - end + def accept_eof + Pry.config.control_d_handler.call(@eval_string, self) end def accept_line(line) + @suppress_output = false + inject_sticky_locals! + ensure_correct_encoding!(line) begin if !process_command_safely(line.lstrip) @eval_string << "#{line.chomp}\n" unless line.empty? @@ -287,6 +257,10 @@ class Pry return end + # This hook is supposed to be executed after each line of ruby code + # has been read (regardless of whether eval_string is yet a complete expression) + exec_hook :after_read, eval_string, self + begin complete_expr = Pry::Code.complete_expression?(@eval_string) rescue SyntaxError => e @@ -312,6 +286,8 @@ class Pry show_result(result) end end + + throw(:breakout) if current_binding.nil? end def evaluate_ruby(code) @@ -360,52 +336,6 @@ class Pry end private :ensure_correct_encoding! - # Read and process a line of input -- check for ^D, determine which prompt to - # use, rewrite the indentation if `Pry.config.auto_indent` is enabled, and, - # if the line is a command, process it and alter the @eval_string accordingly. - # - # @return [String] The line received. - def retrieve_line - @indent.reset if @eval_string.empty? - - current_prompt = select_prompt - completion_proc = Pry.config.completer.build_completion_proc(current_binding, self, - instance_eval(&custom_completions)) - - safe_completion_proc = proc{ |*a| Pry.critical_section{ completion_proc.call(*a) } } - - indentation = Pry.config.auto_indent ? @indent.current_prefix : '' - - begin - val = readline("#{current_prompt}#{indentation}", safe_completion_proc) - - # Handle like Bash, empty the current input buffer but do not quit. - # This is only for ruby-1.9; other versions of ruby do not let you send Interrupt - # from within Readline. - rescue Interrupt - return :control_c - end - - # invoke handler if we receive EOF character (^D) - return :end_of_file unless val - - if Pry.config.auto_indent && !input.is_a?(StringIO) - original_val = "#{indentation}#{val}" - indented_val = @indent.indent(val) - - if output.tty? && Pry::Helpers::BaseHelpers.use_ansi_codes? && Pry.config.correct_indent - output.print @indent.correct_indentation(current_prompt, indented_val, original_val.length - indented_val.length) - output.flush - end - else - indented_val = val - end - - Pry.history << indented_val if interactive? - - indented_val - end - # Is the user typing into this pry instance directly? # @return [Boolean] def interactive? @@ -543,81 +473,6 @@ class Pry @last_result_is_exception end - # Manage switching of input objects on encountering EOFErrors - def handle_read_errors - should_retry = true - exception_count = 0 - begin - yield - rescue EOFError - if input_stack.empty? - self.input = Pry.config.input - if !should_retry - output.puts "Error: Pry ran out of things to read from! Attempting to break out of REPL." - throw(:breakout) - end - should_retry = false - else - self.input = input_stack.pop - end - - retry - - # Interrupts are handled in r() because they need to tweak @eval_string - # TODO: Refactor this baby. - rescue Interrupt - raise - - # If we get a random error when trying to read a line we don't want to automatically - # retry, as the user will see a lot of error messages scroll past and be unable to do - # anything about it. - rescue RescuableException => e - puts "Error: #{e.message}" - output.puts e.backtrace - exception_count += 1 - if exception_count < 5 - retry - end - puts "FATAL: Pry failed to get user input using `#{input}`." - puts "To fix this you may be able to pass input and output file descriptors to pry directly. e.g." - puts " Pry.config.input = STDIN" - puts " Pry.config.output = STDOUT" - puts " binding.pry" - throw(:breakout) - end - end - private :handle_read_errors - - # Returns the next line of input to be used by the pry instance. - # This method should not need to be invoked directly. - # @param [String] current_prompt The prompt to use for input. - # @return [String] The next line of input. - def readline(current_prompt="> ", completion_proc=nil) - handle_read_errors do - - if defined? Coolline and input.is_a? Coolline - input.completion_proc = proc do |cool| - completions = completion_proc.call cool.completed_word - completions.compact - end - elsif input.respond_to? :completion_proc= - input.completion_proc = completion_proc - end - - if input == Readline - input.readline(current_prompt, false) # false since we'll add it manually - elsif defined? Coolline and input.is_a? Coolline - input.readline(current_prompt) - else - if input.method(:readline).arity == 1 - input.readline(current_prompt) - else - input.readline - end - end - end - end - # Whether the print proc should be invoked. # Currently only invoked if the output is not suppressed. # @return [Boolean] Whether the print proc should be invoked. diff --git a/spec/command_integration_spec.rb b/spec/command_integration_spec.rb index 452fad0c..8a4167c9 100644 --- a/spec/command_integration_spec.rb +++ b/spec/command_integration_spec.rb @@ -28,6 +28,7 @@ describe "commands" do after do Pad.clear + Pry.reset_defaults end describe "alias_command" do @@ -356,11 +357,7 @@ describe "commands" do end it 'should create a command in a nested context and that command should be accessible from the parent' do - redirect_pry_io(StringIO.new("@x=nil\ncd 7\n_pry_.commands.instance_eval {\ncommand('bing') { |arg| run arg }\n}\ncd ..\nbing ls\nexit-all"), @str_output) do - Pry.new(:target => 0).repl - end - - pry_tester(0).eval(*(<<-RUBY.split("\n"))).should =~ /instance variables:\s+@x/m + pry_tester(Object.new).eval(*(<<-RUBY.split("\n"))).should =~ /instance variables:\s+@x/m @x = nil cd 7 _pry_.commands.instance_eval { command('bing') { |arg| run arg } } @@ -459,21 +456,15 @@ describe "commands" do end end - Pry.commands = klass - - Pry.new(:input => InputTester.new("hello"), :output => @str_output).repl - @str_output.string.should =~ /hello world/ - other_klass = Pry::CommandSet.new do command "goodbye", "" do output.puts "goodbye world" end end - @str_output = StringIO.new - - Pry.new(:input => InputTester.new("goodbye"), :output => @str_output, :commands => other_klass).repl - @str_output.string.should =~ /goodbye world/ + Pry.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 @@ -554,19 +545,9 @@ describe "commands" do end end - # suppress evaluation output - Pry.print = proc {} - - Pry.new(:input => InputTester.new("jump-to"), :output => @str_output, :commands => klass).repl - @str_output.string.rstrip.should == "jump-to the music" - - @str_output = StringIO.new - Pry.new(:input => InputTester.new("help"), :output => @str_output, :commands => klass).repl - @str_output.string.should == "help to the music\n" - - - Pry.reset_defaults - Pry.color = false + 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 diff --git a/spec/commands/raise_up_spec.rb b/spec/commands/raise_up_spec.rb index dcabdbb3..ad162062 100644 --- a/spec/commands/raise_up_spec.rb +++ b/spec/commands/raise_up_spec.rb @@ -13,13 +13,13 @@ describe "raise-up" do it "should raise the exception with raise-up" do redirect_pry_io(InputTester.new("raise NoMethodError", "raise-up NoMethodError")) do - lambda { Pry.new(:target => 0).repl }.should.raise NoMethodError + 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 { Pry.new(:target => 0).repl }.should.raise RuntimeError, "noreally" + lambda { Object.new.pry }.should.raise RuntimeError, "noreally" end end diff --git a/spec/control_d_handler_spec.rb b/spec/control_d_handler_spec.rb index 51a38d6d..cf0f779d 100644 --- a/spec/control_d_handler_spec.rb +++ b/spec/control_d_handler_spec.rb @@ -17,28 +17,25 @@ describe Pry::DEFAULT_CONTROL_D_HANDLER do describe 'at top-level session' do it 'should break out of a REPL loop' do - instance = nil - redirect_pry_io(InputTester.new(@control_d)) do - instance = Pry.new - instance.repl - end - + instance = Pry.new + instance.binding_stack.should.not.be.empty + called = false + catch(:breakout) { + instance.accept_eof + called = true + } + called.should == 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 - base = OpenStruct.new - base.obj = OpenStruct.new - - redirect_pry_io(InputTester.new("cd obj", "self.stack_size = _pry_.binding_stack.size", - @control_d, "self.stack_size = _pry_.binding_stack.size", "exit-all")) do - Pry.start(base) - end - - base.obj.stack_size.should == 2 - base.stack_size.should == 1 + t = pry_tester + t.eval "cd Object.new" + t.eval("_pry_.binding_stack.size").should == 2 + t.eval("_pry_.accept_eof") + t.eval("_pry_.binding_stack.size").should == 1 end end end diff --git a/spec/input_stack_spec.rb b/spec/input_stack_spec.rb index 0ec6efba..297ccae7 100644 --- a/spec/input_stack_spec.rb +++ b/spec/input_stack_spec.rb @@ -17,13 +17,12 @@ describe "Pry#input_stack" do Pry.config.input_stack = [] end - it 'should read from all input objects on stack and exit session (usingn repl)' do + it 'should read from all input objects on stack and exit session' do stack = [b = StringIO.new(":cloister\nexit\n"), c = StringIO.new(":baron\n")] - instance = Pry.new(:input => StringIO.new(":alex\n"), - :output => @str_output, - :input_stack => stack) + Object.new.pry :input => StringIO.new(":alex\n"), + :output => @str_output, + :input_stack => stack - instance.repl @str_output.string.should =~ /:alex/ @str_output.string.should =~ /:baron/ @str_output.string.should =~ /:cloister/ @@ -31,28 +30,25 @@ describe "Pry#input_stack" do it 'input objects should be popped off stack as they are used up' do stack = [StringIO.new(":cloister\n"), StringIO.new(":baron\n")] - instance = Pry.new(:input => StringIO.new(":alex\n"), - :output => @str_output, - :input_stack => stack) - - instance.push_binding binding + driver = Pry::Driver.new :input => StringIO.new(":alex\n"), + :output => @str_output, + :input_stack => stack stack.size.should == 2 - instance.retrieve_line.should == ":alex\n" + driver.send(:retrieve_line).should == ":alex\n" stack.size.should == 2 - instance.retrieve_line.should == ":baron\n" + driver.send(:retrieve_line).should == ":baron\n" stack.size.should == 1 - instance.retrieve_line.should == ":cloister\n" + driver.send(:retrieve_line).should == ":cloister\n" stack.size.should == 0 end it 'should revert to Pry.config.input when it runs out of input objects in input_stack' do redirect_pry_io(StringIO.new(":rimbaud\nexit\n"), StringIO.new) do stack = [StringIO.new(":cloister\n"), StringIO.new(":baron\n")] - instance = Pry.new(:input => StringIO.new(":alex\n"), - :output => @str_output, - :input_stack => stack) + Object.new.pry :input => StringIO.new(":alex\n"), + :output => @str_output, + :input_stack => stack - instance.repl @str_output.string.should =~ /:alex/ @str_output.string.should =~ /:baron/ @str_output.string.should =~ /:cloister/ @@ -63,7 +59,7 @@ describe "Pry#input_stack" do it 'should display error and throw(:breakout) if at end of input after using up input_stack objects' do catch(:breakout) do redirect_pry_io(StringIO.new(":rimbaud\n"), @str_output) do - Pry.new(:input_stack => [StringIO.new(":a\n"), StringIO.new(":b\n")]).repl + Object.new.pry :input_stack => [StringIO.new(":a\n"), StringIO.new(":b\n")] end end @str_output.string.should =~ /Error: Pry ran out of things to read/ diff --git a/spec/pry_defaults_spec.rb b/spec/pry_defaults_spec.rb index 56c19ec8..0f01ebf8 100644 --- a/spec/pry_defaults_spec.rb +++ b/spec/pry_defaults_spec.rb @@ -21,10 +21,11 @@ describe "test Pry defaults" do it 'should set the input default, and the default should be overridable' do Pry.input = InputTester.new("5") Pry.output = @str_output - Pry.new.repl + Object.new.pry @str_output.string.should =~ /5/ - Pry.new(:input => InputTester.new("6")).repl + Pry.output = @str_output + Object.new.pry :input => InputTester.new("6") @str_output.string.should =~ /6/ end @@ -77,16 +78,16 @@ describe "test Pry defaults" do Pry.output = @str_output Pry.input = InputTester.new("5") - Pry.new.repl + Object.new.pry @str_output.string.should =~ /5/ Pry.input = InputTester.new("6") - Pry.new.repl + Object.new.pry @str_output.string.should =~ /5\n.*6/ Pry.input = InputTester.new("7") @str_output = StringIO.new - Pry.new(:output => @str_output).repl + Object.new.pry :output => @str_output @str_output.string.should.not =~ /5\n.*6/ @str_output.string.should =~ /7/ end @@ -96,17 +97,17 @@ describe "test Pry defaults" do Pry.print = new_print Pry.new.print.should == Pry.print - Pry.new(:input => InputTester.new("\"test\""), :output => @str_output).repl + Object.new.pry :input => InputTester.new("\"test\""), :output => @str_output @str_output.string.should == "=> LOL\n" @str_output = StringIO.new - Pry.new(:input => InputTester.new("\"test\""), :output => @str_output, - :print => proc { |out, value| out.puts value.reverse }).repl + 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.print @str_output = StringIO.new - Pry.new(:input => InputTester.new("\"test\""), :output => @str_output).repl + Object.new.pry :input => InputTester.new("\"test\""), :output => @str_output @str_output.string.should == "=> LOL\n" end @@ -381,18 +382,17 @@ describe "test Pry defaults" do add_hook(:before_session, :my_name) { |out,_,_| out.puts "HELLO" }. add_hook(:after_session, :my_name) { |out,_,_| out.puts "BYE" } - Pry.new(:output => @str_output).repl + Object.new.pry :output => @str_output @str_output.string.should =~ /HELLO/ @str_output.string.should =~ /BYE/ Pry.input.rewind @str_output = StringIO.new - Pry.new(: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" } - ).repl + 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/ @@ -400,19 +400,17 @@ describe "test Pry defaults" do # try below with just defining one hook Pry.input.rewind @str_output = StringIO.new - Pry.new(:output => @str_output, - :hooks => Pry::Hooks.new. - add_hook(:before_session, :my_name) { |out,_,_| out.puts "OPEN" } - ).repl + 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.input.rewind @str_output = StringIO.new - Pry.new(:output => @str_output, - :hooks => Pry::Hooks.new. - add_hook(:after_session, :my_name) { |out,_,_| out.puts "CLOSE" } - ).repl + 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/ diff --git a/spec/pry_spec.rb b/spec/pry_spec.rb index 0c008130..c1965c08 100644 --- a/spec/pry_spec.rb +++ b/spec/pry_spec.rb @@ -101,7 +101,7 @@ describe Pry do it 'should display error if Pry instance runs out of input' do redirect_pry_io(StringIO.new, @str_output) do - Pry.new.repl + Pry.start end @str_output.string.should =~ /Error: Pry ran out of things to read/ end @@ -176,50 +176,39 @@ describe Pry do describe "history arrays" do it 'sets _ to the last result' do - res = [] - input = InputTester.new *[":foo", "self << _", "42", "self << _"] - Pry.new(:input => input, :output => StringIO.new, :target => res).repl - - res.should == [:foo, 42] + 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 - res = {} - input = InputTester.new *[":foo", "42", "self[:res] = _out_"] - Pry.new(:input => input, :output => StringIO.new, :target => res).repl + t = pry_tester + t.eval ":foo" + t.eval "42" + res = t.eval "_out_" - res[:res].should.be.kind_of Pry::HistoryArray - res[:res][1..2].should == [:foo, 42] + 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 - res = {} - input = InputTester.new *[":foo", "42", "self[:res] = _in_"] - Pry.new(:input => input, :output => StringIO.new, :target => res).repl + t = pry_tester + t.eval ":foo" + t.eval "42" + res = t.eval "_in_" - res[:res].should.be.kind_of Pry::HistoryArray - res[:res][1..2].should == [":foo\n", "42\n"] + 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 - res = [] - input = InputTester.new *["self << _out_.max_size << _in_.max_size"] - Pry.new(:input => input, :output => StringIO.new, :target => res).repl - - res.should == [100, 100] + pry_tester.eval("[_in_.max_size, _out_.max_size]").should == [100, 100] end it 'can change the size of the history arrays' do - res = [] - input = InputTester.new *["self << _out_.max_size << _in_.max_size"] - Pry.new( - :input => input, - :output => StringIO.new, - :memory_size => 1000, - :target => res - ).repl - - res.should == [1000, 1000] + pry_tester(:memory_size => 1000).eval("[_out_, _in_].map(&:max_size)").should == [1000, 1000] end it 'store exceptions' do @@ -296,18 +285,6 @@ describe Pry do 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("exit-all\n"), - :output => StringIO.new - ).repl - - Object.const_defined?(:TEST_RC).should == false - Pry.config.should_load_rc = false - end - describe "that raise exceptions" do before do Pry::HOME_RC_FILE = "spec/fixtures/testrcbad" diff --git a/spec/sticky_locals_spec.rb b/spec/sticky_locals_spec.rb index 0ba5af8e..bda34ffa 100644 --- a/spec/sticky_locals_spec.rb +++ b/spec/sticky_locals_spec.rb @@ -122,27 +122,16 @@ describe "Sticky locals (_file_ and friends)" do end it 'should create a new sticky local' do - o = Object.new - pry = Pry.new(:target => o) - pry.add_sticky_local(:test_local) { :test_value } - pry.input = InputTester.new("@value = test_local", "exit-all") - pry.output = StringIO.new - pry.repl - - o.instance_variable_get(:@value).should == :test_value + 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 - o = Object.new - o2 = Object.new - o.instance_variable_set(:@o2, o2) - pry = Pry.new(:target => o) - pry.add_sticky_local(:test_local) { :test_value } - pry.input = InputTester.new("cd @o2\n", "@value = test_local", "exit-all") - pry.output = StringIO.new - pry.repl - - o2.instance_variable_get(:@value).should == :test_value + 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