1
0
Fork 0
mirror of https://github.com/pry/pry.git synced 2022-11-09 12:35:05 -05:00

Rearrange command tests to match command file layout

This commit is contained in:
Ryan Fitzgerald 2012-09-15 14:50:15 -07:00
parent 6d147a637d
commit 735e057e1e
29 changed files with 1761 additions and 1751 deletions

View file

@ -36,6 +36,8 @@ guard 'bacon' do
# Example of mapping a lib file to one or more test files
watch('lib/pry/indent.rb') { 'test/test_indent.rb' }
watch(%r{^lib/pry/commands/([^.]+)\.rb}) { |m| "test/test_commands/test_#{m[1]}.rb" }
# If no such mapping exists, just run all of them
watch(%r{^lib/}) { :all }

View file

@ -0,0 +1,248 @@
require '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
eval_str = unindent(<<-STR)
def hello
puts :bing
STR
@t.process_command 'amend-line puts :blah', eval_str
eval_str.should == unindent(<<-STR)
def hello
puts :blah
STR
end
it 'should amend the specified line of input when line number given' do
eval_str = unindent(<<-STR)
def hello
puts :bing
puts :bang
STR
@t.process_command 'amend-line 1 def goodbye', eval_str
eval_str.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
eval_str = unindent(<<-STR)
def hello
puts :bing
puts :bang
STR
@t.process_command 'amend-line 0 def goodbye', eval_str
eval_str.should == unindent(<<-STR)
def goodbye
puts :bing
puts :bang
STR
end
it 'should amend a specified line when negative number given' do
eval_str = unindent(<<-STR)
def hello
puts :bing
puts :bang
STR
@t.process_command 'amend-line -1 puts :bink', eval_str
eval_str.should == unindent(<<-STR)
def hello
puts :bing
puts :bink
STR
@t.process_command 'amend-line -2 puts :bink', eval_str
eval_str.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
eval_str = unindent(<<-STR)
def hello
puts :bing
puts :bang
puts :boat
STR
@t.process_command 'amend-line -3..-2 puts :bink', eval_str
eval_str.should == unindent(<<-STR)
def hello
puts :bink
puts :boat
STR
end
it 'should correctly amend the specified line with interpolated text' do
eval_str = unindent(<<-STR)
def hello
puts :bing
puts :bang
STR
@t.process_command 'amend-line puts "#{goodbye}"', eval_str
eval_str.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
eval_str = unindent(<<-STR)
def hello
puts :bing
puts :bang
puts :heart
STR
@t.process_command 'amend-line 2..3 puts :bong', eval_str
eval_str.should == unindent(<<-STR)
def hello
puts :bong
puts :heart
STR
end
it 'should correctly delete a specific line using the ! for content' do
eval_str = unindent(<<-STR)
def hello
puts :bing
puts :bang
puts :boast
puts :heart
STR
@t.process_command 'amend-line 3 !', eval_str
eval_str.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
eval_str = unindent(<<-STR)
def hello
puts :bing
puts :bang
puts :boast
puts :heart
STR
@t.process_command 'amend-line 2..4 !', eval_str
eval_str.should == unindent(<<-STR)
def hello
puts :heart
STR
end
it 'should correctly delete the previous line using the ! for content' do
eval_str = unindent(<<-STR)
def hello
puts :bing
puts :bang
puts :boast
puts :heart
STR
@t.process_command 'amend-line !', eval_str
eval_str.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
eval_str = unindent(<<-STR)
def hello
puts :bing
puts :bang
puts :boast
puts :heart
STR
@t.process_command 'amend-line 2..-2 puts :bong', eval_str
eval_str.should == unindent(<<-STR)
def hello
puts :bong
puts :heart
STR
end
it 'should correctly insert a line before a specified line using >' do
eval_str = unindent(<<-STR)
def hello
puts :bing
puts :bang
STR
@t.process_command 'amend-line 2 > puts :inserted', eval_str
eval_str.should == unindent(<<-STR)
def hello
puts :inserted
puts :bing
puts :bang
STR
end
it 'should ignore second value of range with > syntax' do
eval_str = unindent(<<-STR)
def hello
puts :bing
puts :bang
STR
@t.process_command 'amend-line 2..21 > puts :inserted', eval_str
eval_str.should == unindent(<<-STR)
def hello
puts :inserted
puts :bing
puts :bang
STR
end
end

View file

@ -0,0 +1,19 @@
require 'helper'
describe "!" do
before do
@t = pry_tester
end
it 'should correctly clear the input buffer ' do
eval_str = unindent(<<-STR)
def hello
puts :bing
STR
@t.process_command '!', eval_str
@t.last_output.should =~ /Input buffer cleared!/
eval_str.should == ''
end
end

View file

@ -0,0 +1,155 @@
require '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
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
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

View file

@ -1,6 +1,6 @@
require 'helper'
describe 'Pry::DefaultCommands::Cd' do
describe 'cd' do
before do
@o, @obj = Object.new, Object.new
@obj.instance_variable_set(:@x, 66)

View file

@ -0,0 +1,299 @@
require 'helper'
describe "edit" do
before do
@old_editor = Pry.config.editor
@file = nil; @line = nil; @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
it "should invoke Pry.config.editor with absolutified filenames" do
pry_eval 'edit lib/pry.rb'
@file.should == File.expand_path('lib/pry.rb')
FileUtils.touch '/tmp/bar.rb'
pry_eval 'edit /tmp/bar.rb'
@file.should == '/tmp/bar.rb'
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
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
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'" }
nil
}
defined?(FOO).should.be.nil
@t.eval 'edit --ex'
FOO.should == 'BAR'
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
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
eval_str = 'def a'
@t.process_command 'edit', eval_str
@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
eval_str = 'def a;'
@t.process_command 'edit -t', eval_str
@contents.should == "\n"
end
it "should position the cursor at the end of the expression" do
eval_str = "def a; 2;\nend"
@t.process_command 'edit', eval_str
@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
}
eval_str = ''
@t.process_command 'edit', eval_str
eval_str.should == "'FOO'\n"
end
it "should not evaluate the expression with -n" do
Pry.config.editor = lambda {|file, line|
File.open(file, 'w'){|f| f << "'FOO'\n" }
nil
}
eval_str = ''
@t.process_command 'edit -n', eval_str
eval_str.should == ''
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 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
end

View file

@ -0,0 +1,210 @@
require 'helper'
describe "edit-method" 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
:maybe
G
end
end
end
EOS
@tempfile.flush
load @tempfile.path
end
after do
@tempfile.close(true)
end
describe 'without -p' do
before do
@old_editor = Pry.config.editor
@file, @line, @contents = nil, nil, nil
Pry.config.editor = lambda do |file, line|
@file = file; @line = line
nil
end
end
after do
Pry.config.editor = @old_editor
end
it "should correctly find a class method" do
pry_eval 'edit-method X.x'
@file.should == @tempfile.path
@line.should == 14
end
it "should correctly find an instance method" do
pry_eval 'edit-method 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-method x.x'
@file.should == @tempfile.path
@line.should == 18
end
it "should correctly find a method from a module" do
pry_eval 'edit-method X#a'
@file.should == @tempfile.path
@line.should == 2
end
it "should correctly find an aliased method" do
pry_eval 'edit-method X#c'
@file.should == @tempfile.path
@line.should == 22
end
end
describe 'with -p' do
before do
@old_editor = Pry.config.editor
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
nil
end
end
after do
Pry.config.editor = @old_editor
end
it "should successfully replace a class method" do
pry_eval 'edit-method -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-method -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-method -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-method -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-method -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-method -p X::B#foo'
X::B.instance_method(:foo).owner.should == X::B
X::B.new.foo.should == :nawt
end
end
describe 'on an aliased method' do
before do
@old_editor = Pry.config.editor
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
after do
Pry.config.editor = @old_editor
end
it "should change the alias, but not the original, without breaking super" do
pry_eval 'edit-method -p X#c'
Pry::Method.from_str("X#c").alias?.should == true
X.new.b.should == :kinda
X.new.c.should == :kindaaa
end
end
describe 'with three-arg editor' do
before do
@old_editor = Pry.config.editor
@file, @line, @reloading = nil, nil, nil
Pry.config.editor = lambda do |file, line, reloading|
@file = file; @line = line; @reloading = reloading
nil
end
end
after do
Pry.config.editor = @old_editor
end
it "should pass the editor a reloading arg" do
pry_eval 'edit-method X.x'
@reloading.should == true
pry_eval 'edit-method -n X.x'
@reloading.should == false
end
end
end
end

View file

@ -0,0 +1,34 @@
require 'helper'
describe "exit" do
it 'should pop a binding with exit' do
pry_tester(:outer).simulate_repl do |t|
t.eval 'cd :inner'
t.eval('self').should == :inner
t.eval 'exit'
t.eval('self').should == :outer
t.eval 'exit-all'
end
end
it 'should break out of the repl loop of Pry instance when binding_stack has only one binding with exit' do
pry_tester(0).simulate_repl do |t|
t.eval 'exit'
end.should == nil
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_tester(0).simulate_repl do |t|
t.eval 'exit :john'
end.should == :john
end
it 'should break out the repl loop of Pry instance even after an exception in user-given value' do
pry_tester(0).simulate_repl do |t|
proc {
t.eval 'exit = 42'
}.should.raise(SyntaxError)
t.eval 'exit'
end.should == nil
end
end

View file

@ -0,0 +1,34 @@
require 'helper'
describe "exit-all" do
it 'should break out of the repl loop of Pry instance and return nil' do
pry_tester(0).simulate_repl do |t|
t.eval 'exit-all'
end.should == nil
end
it 'should break out of the repl loop of Pry instance wth a user specified value' do
pry_tester(0).simulate_repl do |t|
t.eval "exit-all 'message'"
end.should == 'message'
end
it 'should break of the repl loop even if multiple bindings still on stack' do
pry_tester(0).simulate_repl do |t|
t.eval 'cd 1', 'cd 2', "exit-all 'message'"
end.should == 'message'
end
it 'binding_stack should be empty after breaking out of the repl loop' do
t = pry_tester(0) do
def binding_stack
@pry.binding_stack
end
end
t.simulate_repl do |t|
t.eval 'cd 1', 'cd 2', 'exit-all'
end
t.binding_stack.empty?.should == true
end
end

View file

@ -0,0 +1,19 @@
require '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

View file

@ -0,0 +1,26 @@
require 'helper'
describe "gem-list" do
# fixing bug for 1.8 compat
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

View file

@ -1,6 +1,6 @@
require 'helper'
describe "'help' command" do
describe "help" do
before do
@oldset = Pry.config.commands
@set = Pry.config.commands = Pry::CommandSet.new do

View file

@ -0,0 +1,181 @@
require 'helper'
describe "hist" do
before do
Pry.history.clear
@hist = Pry.history
@str_output = StringIO.new
@t = pry_tester 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 display the correct history' do
@hist.push "hello"
@hist.push "world"
@t.eval('hist').should =~ /hello\n.*world/
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.context = o
@t.eval 'hist --replay -1'
@t.next_input.should == "@z = 30\n"
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.context = o
@t.eval 'hist --replay 0..2'
@t.next_input.should == "@x = 10\n@y = 20\n"
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"
redirect_pry_io(InputTester.new("hist --replay 0..2", "Pad.stack = _pry_.binding_stack.dup", "exit-all")) do
o.pry
end
o = Pad.stack[-2..-1].map { |v| v.eval('self') }
o.should == [1, 2]
Pad.clear
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 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
redirect_pry_io(InputTester.new(":banzai", "hist --replay 1",
"hist", "exit-all"), @str_output) do
Pry.start
end
@str_output.string.should =~ /hist --replay 1/
end
it "should not contain lines produced by `--replay` flag" do
redirect_pry_io(InputTester.new(":banzai", ":geronimo", ":huzzah",
"hist --replay 1..3", "hist",
"exit-all"), @str_output) do
Pry.start
end
@str_output.string.each_line.to_a.reject { |line| line.start_with?("=>") }.size.should == 4
@str_output.string.each_line.to_a.last.should =~ /hist --replay 1\.\.3/
@str_output.string.each_line.to_a[-2].should =~ /:huzzah/
end
it "should raise CommandError when index of `--replay` points out to another `hist --replay`" do
redirect_pry_io(InputTester.new(":banzai", "hist --replay 1",
"hist --replay 2", "exit-all"), @str_output) do
Pry.start
end
@str_output.string.should =~ /Replay index 2 points out to another replay call: `hist --replay 1`/
end
it "should disallow execution of `--replay <i>` when CommandError raised" do
redirect_pry_io(InputTester.new("a = 0", "a += 1", "hist --replay 2",
"hist --replay 3", "'a is ' + a.to_s",
"hist", "exit-all"), @str_output) do
Pry.start
end
@str_output.string.each_line.to_a.reject { |line| line !~ /\A\d/ }.size.should == 5
@str_output.string.should =~ /a is 2/
end
end

View file

@ -0,0 +1,15 @@
require '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

View file

@ -0,0 +1,113 @@
require 'helper'
describe "play" do
before do
@t = pry_tester
end
it 'should play a string variable (with no args)' do
eval_str = ''
@t.eval 'x = "\"hello\""'
@t.process_command 'play x', eval_str
eval_str.should == '"hello"'
end
it 'should play a string variable (with no args) using --lines to select what to play' do
eval_str = ''
@t.eval 'x = "\"hello\"\n\"goodbye\"\n\"love\""'
@t.process_command 'play x --lines 1', eval_str
eval_str.should == "\"hello\"\n"
end
it 'should play documentation with the -d switch' do
eval_str = ''
o = Object.new
# @v = 10
# @y = 20
def o.test_method
:test_method_content
end
pry_tester(o).process_command 'play -d test_method', eval_str
eval_str.should == unindent(<<-STR)
@v = 10
@y = 20
STR
end
it 'should restrict -d switch with --lines' do
eval_str = ''
o = Object.new
# @x = 0
# @v = 10
# @y = 20
# @z = 30
def o.test_method
:test_method_content
end
pry_tester(o).process_command 'play -d test_method --lines 2..3', eval_str
eval_str.should == unindent(<<-STR)
@v = 10
@y = 20
STR
end
it 'should play a method with the -m switch (a single line)' do
eval_str = ''
o = Object.new
def o.test_method
:test_method_content
end
pry_tester(o).process_command 'play -m test_method --lines 2', eval_str
eval_str.should == " :test_method_content\n"
end
it 'should APPEND to the input buffer when playing a line with play -m, not replace it' do
eval_str = unindent(<<-STR)
def another_test_method
STR
o = Object.new
def o.test_method
:test_method_content
end
pry_tester(o).process_command 'play -m test_method --lines 2', eval_str
eval_str.should == unindent(<<-STR)
def another_test_method
:test_method_content
STR
end
it 'should play a method with the -m switch (multiple line)' do
eval_str = ''
o = Object.new
def o.test_method
@var0 = 10
@var1 = 20
@var2 = 30
@var3 = 40
end
pry_tester(o).process_command 'play -m test_method --lines 3..4', eval_str
eval_str.should == unindent(<<-STR, 2)
@var1 = 20
@var2 = 30
STR
end
end

View file

@ -0,0 +1,56 @@
require '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 { 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'")) 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
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

View file

@ -0,0 +1,157 @@
require '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 -f #{path} #{@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 #{@path}"
File.read(@path).should == ":horse_nostrils\n"
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 #{@path}"
File.read(@path).should == ":or_nostrils\n:sucking_up_all_the_oxygen\n"
end
end
describe "-m" 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 #{@path} -m baby"
File.read(@path).should == Pry::Method.from_obj(@o, :baby).source
end
it 'should save a method to a file truncated by --lines' do
@t.eval "save-file #{@path} -m 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
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 #{@path}"
@t.eval ':sucking_up_all_the_oxygen'
@t.eval "save-file -i 2 #{@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 #{@path}"
@t.eval ':sucking_up_all_the_oxygen'
@t.eval "save-file -i 2 #{@path} -a"
File.read(@path).should ==
":horse_nostrils\n:sucking_up_all_the_oxygen\n"
end
end
describe "-c" do
it 'should save a command to a file' do
@t.eval "save-file #{@path} -k show-method"
cmd = Pry::Method.new(Pry.commands.find_command("show-method").block)
File.read(@path).should == Pry::Code.from_method(cmd).to_s
end
end
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

View file

@ -1,60 +1,58 @@
require 'helper'
if !mri18_and_no_real_source_location?
describe "Pry::DefaultCommands::Documentation" do
describe "show-doc" do
before do
@o = Object.new
describe "show-doc" do
before do
@o = Object.new
end
it 'should output a method\'s documentation' do
pry_eval("show-doc sample_method").should =~ /sample doc/
end
it 'should output a method\'s documentation with line numbers' do
pry_eval("show-doc sample_method -l").should =~ /\d: sample doc/
end
it 'should output a method\'s documentation with line numbers (base one)' do
pry_eval("show-doc 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
it 'should output a method\'s documentation' do
pry_eval("show-doc sample_method").should =~ /sample doc/
end
it "should be able to find super methods" do
c = Class.new{
# classy initialize!
def initialize(*args); end
}
it 'should output a method\'s documentation with line numbers' do
pry_eval("show-doc sample_method -l").should =~ /\d: sample doc/
end
d = Class.new(c){
# grungy initialize??
def initialize(*args, &block); end
}
it 'should output a method\'s documentation with line numbers (base one)' do
pry_eval("show-doc sample_method -b").should =~ /1: sample doc/
end
o = d.new
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
# instancey initialize!
def o.initialize; end
it "should be able to find super methods" do
c = Class.new{
# classy initialize!
def initialize(*args); end
}
t = pry_tester(binding)
d = Class.new(c){
# grungy initialize??
def initialize(*args, &block); end
}
t.eval("show-doc o.initialize").should =~ /instancey initialize/
t.eval("show-doc --super o.initialize").should =~ /grungy initialize/
t.eval("show-doc o.initialize -ss").should =~ /classy initialize/
o = d.new
# instancey initialize!
def o.initialize; end
t = pry_tester(binding)
t.eval("show-doc o.initialize").should =~ /instancey initialize/
t.eval("show-doc --super o.initialize").should =~ /grungy initialize/
t.eval("show-doc o.initialize -ss").should =~ /classy initialize/
begin
require 'pry-doc'
t.eval("show-doc --super o.initialize -ss").should ==
t.eval("show-doc Object#initialize")
rescue LoadError
end
begin
require 'pry-doc'
t.eval("show-doc --super o.initialize -ss").should ==
t.eval("show-doc Object#initialize")
rescue LoadError
end
end

View file

@ -0,0 +1,17 @@
require 'helper'
describe "show-input" do
before do
@t = pry_tester
end
it 'should correctly show the current lines in the input buffer' do
eval_str = unindent(<<-STR)
def hello
puts :bing
STR
@t.process_command 'show-input', eval_str
@t.last_output.should =~ /\A\d+: def hello\n\d+: puts :bing/
end
end

View file

@ -557,4 +557,3 @@ if !mri18_and_no_real_source_location?
end
end
end

View file

@ -0,0 +1,130 @@
require '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 show description and correct code when __LINE__ and __FILE__ are outside @method.source_location' do
class Cor
def blimey!
eval <<-END, binding, "test/test_commands/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, "test/test_commands/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
it 'should display a description and 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 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

View file

@ -1,287 +0,0 @@
require 'helper'
describe "Pry::DefaultCommands::Context" do
before do
@self = "Pad.self = self"
@inner = "Pad.inner = self"
@outer = "Pad.outer = self"
end
after do
Pad.clear
end
describe "exit-all" do
it 'should break out of the repl loop of Pry instance and return nil' do
pry_tester(0).simulate_repl do |t|
t.eval 'exit-all'
end.should == nil
end
it 'should break out of the repl loop of Pry instance wth a user specified value' do
pry_tester(0).simulate_repl do |t|
t.eval "exit-all 'message'"
end.should == 'message'
end
it 'should break of the repl loop even if multiple bindings still on stack' do
pry_tester(0).simulate_repl do |t|
t.eval 'cd 1', 'cd 2', "exit-all 'message'"
end.should == 'message'
end
it 'binding_stack should be empty after breaking out of the repl loop' do
t = pry_tester(0) do
def binding_stack
@pry.binding_stack
end
end
t.simulate_repl do |t|
t.eval 'cd 1', 'cd 2', 'exit-all'
end
t.binding_stack.empty?.should == true
end
end
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 show description and correct code when __LINE__ and __FILE__ are outside @method.source_location' do
class Cor
def blimey!
eval <<-END, binding, "test/test_default_commands/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, "test/test_default_commands/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
it 'should display a description and 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 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
describe "exit" do
it 'should pop a binding with exit' do
pry_tester(:outer).simulate_repl do |t|
t.eval 'cd :inner'
t.eval('self').should == :inner
t.eval 'exit'
t.eval('self').should == :outer
t.eval 'exit-all'
end
end
it 'should break out of the repl loop of Pry instance when binding_stack has only one binding with exit' do
pry_tester(0).simulate_repl do |t|
t.eval 'exit'
end.should == nil
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_tester(0).simulate_repl do |t|
t.eval 'exit :john'
end.should == :john
end
it 'should break out the repl loop of Pry instance even after an exception in user-given value' do
pry_tester(0).simulate_repl do |t|
proc {
t.eval 'exit = 42'
}.should.raise(SyntaxError)
t.eval 'exit'
end.should == nil
end
end
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
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
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.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'")) 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
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
end
describe "raise-up!" do
it "should jump immediately out of nested contexts" do
lambda { mock_pry("cd 1", "cd 2", "cd 3", "raise-up! 'fancy that...'") }.should.raise RuntimeError, 'fancy that...'
end
end
end

View file

@ -1,30 +0,0 @@
require 'helper'
describe "Pry::DefaultCommands::Gems" do
describe "gem-list" do
# fixing bug for 1.8 compat
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
end

View file

@ -1,563 +0,0 @@
require 'helper'
describe "Pry::DefaultCommands::Input" do
before do
@str_output = StringIO.new
@t = pry_tester
end
describe "amend-line" do
it 'should amend the last line of input when no line number specified' do
eval_str = unindent(<<-STR)
def hello
puts :bing
STR
@t.process_command 'amend-line puts :blah', eval_str
eval_str.should == unindent(<<-STR)
def hello
puts :blah
STR
end
it 'should amend the specified line of input when line number given' do
eval_str = unindent(<<-STR)
def hello
puts :bing
puts :bang
STR
@t.process_command 'amend-line 1 def goodbye', eval_str
eval_str.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
eval_str = unindent(<<-STR)
def hello
puts :bing
puts :bang
STR
@t.process_command 'amend-line 0 def goodbye', eval_str
eval_str.should == unindent(<<-STR)
def goodbye
puts :bing
puts :bang
STR
end
it 'should amend a specified line when negative number given' do
eval_str = unindent(<<-STR)
def hello
puts :bing
puts :bang
STR
@t.process_command 'amend-line -1 puts :bink', eval_str
eval_str.should == unindent(<<-STR)
def hello
puts :bing
puts :bink
STR
@t.process_command 'amend-line -2 puts :bink', eval_str
eval_str.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
eval_str = unindent(<<-STR)
def hello
puts :bing
puts :bang
puts :boat
STR
@t.process_command 'amend-line -3..-2 puts :bink', eval_str
eval_str.should == unindent(<<-STR)
def hello
puts :bink
puts :boat
STR
end
it 'should correctly amend the specified line with interpolated text' do
eval_str = unindent(<<-STR)
def hello
puts :bing
puts :bang
STR
@t.process_command 'amend-line puts "#{goodbye}"', eval_str
eval_str.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
eval_str = unindent(<<-STR)
def hello
puts :bing
puts :bang
puts :heart
STR
@t.process_command 'amend-line 2..3 puts :bong', eval_str
eval_str.should == unindent(<<-STR)
def hello
puts :bong
puts :heart
STR
end
it 'should correctly delete a specific line using the ! for content' do
eval_str = unindent(<<-STR)
def hello
puts :bing
puts :bang
puts :boast
puts :heart
STR
@t.process_command 'amend-line 3 !', eval_str
eval_str.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
eval_str = unindent(<<-STR)
def hello
puts :bing
puts :bang
puts :boast
puts :heart
STR
@t.process_command 'amend-line 2..4 !', eval_str
eval_str.should == unindent(<<-STR)
def hello
puts :heart
STR
end
it 'should correctly delete the previous line using the ! for content' do
eval_str = unindent(<<-STR)
def hello
puts :bing
puts :bang
puts :boast
puts :heart
STR
@t.process_command 'amend-line !', eval_str
eval_str.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
eval_str = unindent(<<-STR)
def hello
puts :bing
puts :bang
puts :boast
puts :heart
STR
@t.process_command 'amend-line 2..-2 puts :bong', eval_str
eval_str.should == unindent(<<-STR)
def hello
puts :bong
puts :heart
STR
end
it 'should correctly insert a line before a specified line using >' do
eval_str = unindent(<<-STR)
def hello
puts :bing
puts :bang
STR
@t.process_command 'amend-line 2 > puts :inserted', eval_str
eval_str.should == unindent(<<-STR)
def hello
puts :inserted
puts :bing
puts :bang
STR
end
it 'should ignore second value of range with > syntax' do
eval_str = unindent(<<-STR)
def hello
puts :bing
puts :bang
STR
@t.process_command 'amend-line 2..21 > puts :inserted', eval_str
eval_str.should == unindent(<<-STR)
def hello
puts :inserted
puts :bing
puts :bang
STR
end
end
describe "show-input" do
it 'should correctly show the current lines in the input buffer' do
eval_str = unindent(<<-STR)
def hello
puts :bing
STR
@t.process_command 'show-input', eval_str
@t.last_output.should =~ /\A\d+: def hello\n\d+: puts :bing/
end
end
describe "!" do
it 'should correctly clear the input buffer ' do
eval_str = unindent(<<-STR)
def hello
puts :bing
STR
@t.process_command '!', eval_str
@t.last_output.should =~ /Input buffer cleared!/
eval_str.should == ''
end
end
describe "play" do
it 'should play a string variable (with no args)' do
eval_str = ''
@t.eval 'x = "\"hello\""'
@t.process_command 'play x', eval_str
eval_str.should == '"hello"'
end
it 'should play a string variable (with no args) using --lines to select what to play' do
eval_str = ''
@t.eval 'x = "\"hello\"\n\"goodbye\"\n\"love\""'
@t.process_command 'play x --lines 1', eval_str
eval_str.should == "\"hello\"\n"
end
it 'should play documentation with the -d switch' do
eval_str = ''
o = Object.new
# @v = 10
# @y = 20
def o.test_method
:test_method_content
end
pry_tester(o).process_command 'play -d test_method', eval_str
eval_str.should == unindent(<<-STR)
@v = 10
@y = 20
STR
end
it 'should restrict -d switch with --lines' do
eval_str = ''
o = Object.new
# @x = 0
# @v = 10
# @y = 20
# @z = 30
def o.test_method
:test_method_content
end
pry_tester(o).process_command 'play -d test_method --lines 2..3', eval_str
eval_str.should == unindent(<<-STR)
@v = 10
@y = 20
STR
end
it 'should play a method with the -m switch (a single line)' do
eval_str = ''
o = Object.new
def o.test_method
:test_method_content
end
pry_tester(o).process_command 'play -m test_method --lines 2', eval_str
eval_str.should == " :test_method_content\n"
end
it 'should APPEND to the input buffer when playing a line with play -m, not replace it' do
eval_str = unindent(<<-STR)
def another_test_method
STR
o = Object.new
def o.test_method
:test_method_content
end
pry_tester(o).process_command 'play -m test_method --lines 2', eval_str
eval_str.should == unindent(<<-STR)
def another_test_method
:test_method_content
STR
end
it 'should play a method with the -m switch (multiple line)' do
eval_str = ''
o = Object.new
def o.test_method
@var0 = 10
@var1 = 20
@var2 = 30
@var3 = 40
end
pry_tester(o).process_command 'play -m test_method --lines 3..4', eval_str
eval_str.should == unindent(<<-STR, 2)
@var1 = 20
@var2 = 30
STR
end
end
describe "hist" do
before do
Pry.history.clear
@hist = Pry.history
@t = pry_tester 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 display the correct history' do
@hist.push "hello"
@hist.push "world"
@t.eval('hist').should =~ /hello\n.*world/
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.context = o
@t.eval 'hist --replay -1'
@t.next_input.should == "@z = 30\n"
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.context = o
@t.eval 'hist --replay 0..2'
@t.next_input.should == "@x = 10\n@y = 20\n"
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"
redirect_pry_io(InputTester.new("hist --replay 0..2", "Pad.stack = _pry_.binding_stack.dup", "exit-all")) do
o.pry
end
o = Pad.stack[-2..-1].map { |v| v.eval('self') }
o.should == [1, 2]
Pad.clear
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 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
redirect_pry_io(InputTester.new(":banzai", "hist --replay 1",
"hist", "exit-all"), @str_output) do
Pry.start
end
@str_output.string.should =~ /hist --replay 1/
end
it "should not contain lines produced by `--replay` flag" do
redirect_pry_io(InputTester.new(":banzai", ":geronimo", ":huzzah",
"hist --replay 1..3", "hist",
"exit-all"), @str_output) do
Pry.start
end
@str_output.string.each_line.to_a.reject { |line| line.start_with?("=>") }.size.should == 4
@str_output.string.each_line.to_a.last.should =~ /hist --replay 1\.\.3/
@str_output.string.each_line.to_a[-2].should =~ /:huzzah/
end
it "should raise CommandError when index of `--replay` points out to another `hist --replay`" do
redirect_pry_io(InputTester.new(":banzai", "hist --replay 1",
"hist --replay 2", "exit-all"), @str_output) do
Pry.start
end
@str_output.string.should =~ /Replay index 2 points out to another replay call: `hist --replay 1`/
end
it "should disallow execution of `--replay <i>` when CommandError raised" do
redirect_pry_io(InputTester.new("a = 0", "a += 1", "hist --replay 2",
"hist --replay 3", "'a is ' + a.to_s",
"hist", "exit-all"), @str_output) do
Pry.start
end
@str_output.string.each_line.to_a.reject { |line| line !~ /\A\d/ }.size.should == 5
@str_output.string.should =~ /a is 2/
end
end
end

View file

@ -1,510 +0,0 @@
require 'helper'
describe "Pry::DefaultCommands::Introspection" do
describe "edit" do
before do
@old_editor = Pry.config.editor
@file = nil; @line = nil; @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
it "should invoke Pry.config.editor with absolutified filenames" do
pry_eval 'edit lib/pry.rb'
@file.should == File.expand_path('lib/pry.rb')
FileUtils.touch '/tmp/bar.rb'
pry_eval 'edit /tmp/bar.rb'
@file.should == '/tmp/bar.rb'
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
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
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'" }
nil
}
defined?(FOO).should.be.nil
@t.eval 'edit --ex'
FOO.should == 'BAR'
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
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
eval_str = 'def a'
@t.process_command 'edit', eval_str
@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
eval_str = 'def a;'
@t.process_command 'edit -t', eval_str
@contents.should == "\n"
end
it "should position the cursor at the end of the expression" do
eval_str = "def a; 2;\nend"
@t.process_command 'edit', eval_str
@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
}
eval_str = ''
@t.process_command 'edit', eval_str
eval_str.should == "'FOO'\n"
end
it "should not evaluate the expression with -n" do
Pry.config.editor = lambda {|file, line|
File.open(file, 'w'){|f| f << "'FOO'\n" }
nil
}
eval_str = ''
@t.process_command 'edit -n', eval_str
eval_str.should == ''
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 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
end
describe "edit-method" 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
:maybe
G
end
end
end
EOS
@tempfile.flush
load @tempfile.path
end
after do
@tempfile.close(true)
end
describe 'without -p' do
before do
@old_editor = Pry.config.editor
@file, @line, @contents = nil, nil, nil
Pry.config.editor = lambda do |file, line|
@file = file; @line = line
nil
end
end
after do
Pry.config.editor = @old_editor
end
it "should correctly find a class method" do
pry_eval 'edit-method X.x'
@file.should == @tempfile.path
@line.should == 14
end
it "should correctly find an instance method" do
pry_eval 'edit-method 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-method x.x'
@file.should == @tempfile.path
@line.should == 18
end
it "should correctly find a method from a module" do
pry_eval 'edit-method X#a'
@file.should == @tempfile.path
@line.should == 2
end
it "should correctly find an aliased method" do
pry_eval 'edit-method X#c'
@file.should == @tempfile.path
@line.should == 22
end
end
describe 'with -p' do
before do
@old_editor = Pry.config.editor
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
nil
end
end
after do
Pry.config.editor = @old_editor
end
it "should successfully replace a class method" do
pry_eval 'edit-method -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-method -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-method -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-method -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-method -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-method -p X::B#foo'
X::B.instance_method(:foo).owner.should == X::B
X::B.new.foo.should == :nawt
end
end
describe 'on an aliased method' do
before do
@old_editor = Pry.config.editor
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
after do
Pry.config.editor = @old_editor
end
it "should change the alias, but not the original, without breaking super" do
pry_eval 'edit-method -p X#c'
Pry::Method.from_str("X#c").alias?.should == true
X.new.b.should == :kinda
X.new.c.should == :kindaaa
end
end
describe 'with three-arg editor' do
before do
@old_editor = Pry.config.editor
@file, @line, @reloading = nil, nil, nil
Pry.config.editor = lambda do |file, line, reloading|
@file = file; @line = line; @reloading = reloading
nil
end
end
after do
Pry.config.editor = @old_editor
end
it "should pass the editor a reloading arg" do
pry_eval 'edit-method X.x'
@reloading.should == true
pry_eval 'edit-method -n X.x'
@reloading.should == false
end
end
end
end
end

View file

@ -1,312 +0,0 @@
require 'helper'
describe "Pry::DefaultCommands::Shell" do
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 -f #{path} #{@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 #{@path}"
File.read(@path).should == ":horse_nostrils\n"
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 #{@path}"
File.read(@path).should == ":or_nostrils\n:sucking_up_all_the_oxygen\n"
end
end
describe "-m" 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 #{@path} -m baby"
File.read(@path).should == Pry::Method.from_obj(@o, :baby).source
end
it 'should save a method to a file truncated by --lines' do
@t.eval "save-file #{@path} -m 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
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 #{@path}"
@t.eval ':sucking_up_all_the_oxygen'
@t.eval "save-file -i 2 #{@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 #{@path}"
@t.eval ':sucking_up_all_the_oxygen'
@t.eval "save-file -i 2 #{@path} -a"
File.read(@path).should ==
":horse_nostrils\n:sucking_up_all_the_oxygen\n"
end
end
describe "-c" do
it 'should save a command to a file' do
@t.eval "save-file #{@path} -k show-method"
cmd = Pry::Method.new(Pry.commands.find_command("show-method").block)
File.read(@path).should == Pry::Code.from_method(cmd).to_s
end
end
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
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
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
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
end