Fix `whereami` inside erb files.

This commit is contained in:
Conrad Irwin 2012-06-03 20:09:00 -07:00
parent 2fd8ca8d01
commit e189538570
4 changed files with 87 additions and 33 deletions

View File

@ -18,48 +18,37 @@ class Pry
def setup
@method = Pry::Method.from_binding(target)
@file = target.eval('__FILE__')
@line = target.eval('__LINE__')
end
def code
if show_method?
Pry::Code.from_method(@method)
else
Pry::Code.from_file(@file).around(@line, 5)
end
end
def location
"#{@file} @ line #{show_method? ? @method.source_line : @line} #{@method && @method.name_with_owner}"
end
def process
if show_method?
file = @method.source_file
start = @method.source_range.begin
finish = @method.source_range.end
marker = target.eval("__LINE__")
else
file = target.eval("__FILE__")
start = target.eval("__LINE__")
finish = (args.first && args.first.to_i) || 5
marker = start
end
set_file_and_dir_locals(@file)
if invalid_file?(file)
raise Pry::CommandError,
"Cannot find local context. Did you use binding.pry?"
end
# TODO: refactor.
if show_method?
code = Pry::Code.from_file(file).between(start, finish)
else
code = Pry::Code.from_file(file).around(start, finish)
end
desc = (@method && @method.name_with_owner) || ""
if !code.empty?
set_file_and_dir_locals(file)
output.puts "\n#{text.bold('From:')} #{file} @ line #{start} #{desc}:\n\n"
output.puts code.with_line_numbers.with_marker(marker)
output.puts
end
output.puts "\n#{text.bold('From:')} #{location}:\n\n"
output.puts code.with_line_numbers.with_marker(@line)
output.puts
end
private
def show_method?
args.empty? && @method && !@method.instance_of?(Pry::Method::Disowned) && @method.source_range.count < 20
args.empty? && @method && @method.source? && @method.source_range.count < 20 &&
# These checks are needed in case of an eval with a binding and file/line
# numbers set to outside the function. As in rails' use of ERB.
@method.source_file == @file && @method.source_range.include?(@line)
end
def invalid_file?(file)

View File

@ -268,6 +268,14 @@ class Pry
end
end
# Can we get the source code for this method?
# @return [Boolean]
def source?
!!source
rescue MethodSource::SourceNotFoundError
false
end
# @return [String, nil] The documentation for the method, or `nil` if it's
# unavailable.
# @raise [CommandError] Raises when the method was defined in the REPL.
@ -516,6 +524,12 @@ class Pry
true
end
# Can we get the source for this method?
# @return [Boolean] false
def source?
false
end
# Get the hypothesized owner of the method.
#
# @return [Object]

View File

@ -0,0 +1,5 @@
<html>
Look at me, testing my erb!
</html>

View File

@ -68,6 +68,52 @@ describe "Pry::DefaultCommands::Context" do
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
mock_pry(binding, 'whereami')
END
end
end
Cor.instance_method(:blimey!).source.should =~ /mock_pry/
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!
mock_pry(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
mock_pry(binding, 'whereami')
END
end
end
Cor.new.blimey!.should =~ /From: not.found.file.erb @ line 7 Cor#blimey!:\n\nError: Cannot open "not.found.file.erb" for reading./m
Object.remove_const(:Cor)
end
end
describe "exit" do