mirror of
https://github.com/pry/pry.git
synced 2022-11-09 12:35:05 -05:00
Add Pry::Driver to handle the reading and looping
This commit is contained in:
parent
3dfac682c1
commit
eeb67684d0
11 changed files with 300 additions and 306 deletions
|
@ -229,6 +229,7 @@ rescue LoadError
|
|||
end
|
||||
|
||||
require 'pry/version'
|
||||
require 'pry/driver'
|
||||
require 'pry/rbx_method'
|
||||
require 'pry/rbx_path'
|
||||
require 'pry/code'
|
||||
|
|
197
lib/pry/driver.rb
Normal file
197
lib/pry/driver.rb
Normal file
|
@ -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 <Ctrl+C> 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
|
|
@ -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
|
||||
|
|
|
@ -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 <Ctrl+C> 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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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/
|
||||
|
|
|
@ -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/
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue