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

added some integration tests for class based commands && renamed Pry::CommandContext:Command#block to #callable

This commit is contained in:
John Mair 2011-12-30 00:07:49 +13:00
parent 1cbe7d4c9c
commit f52626e169
6 changed files with 160 additions and 74 deletions

View file

@ -161,17 +161,19 @@ class Pry
# Execute a Pry command.
# This method should not need to be invoked directly.
# @param [Binding] target The target of the Pry session.
# @param [String] command The name of the command to be run.
# @param [Pry::CommandSet::Command] command The command object.
# @param [Hash] options The options to set on the Commands object.
# @param [Array] args The command arguments.
# @return [Object] The value returned by the command
def execute_command(target, command, options, *args)
ret = nil
if command.block.is_a?(Proc)
if command.callable.is_a?(Proc)
context = CommandContext.new
else
context = command.block
# in the case of non-procs the callable *is* the context
context = command.callable
end
# set some useful methods to be used by the action blocks
@ -187,19 +189,19 @@ class Pry
end
def setup_context(target, command, context, options)
context.opts = options
context.target = target
context.target_self = target.eval('self')
context.output = output
context.captures = options[:captures]
context.eval_string = options[:eval_string]
context.arg_string = options[:arg_string]
context.opts = options
context.target = target
context.target_self = target.eval('self')
context.output = output
context.captures = options[:captures]
context.eval_string = options[:eval_string]
context.arg_string = options[:arg_string]
context.command_set = commands
context.command_name = command.options[:listing]
context._pry_ = @pry_instance
context._pry_ = @pry_instance
context.command_processor = self
context.command_processor = self
end
end
end

View file

@ -8,17 +8,19 @@ class Pry
# This class is used to create sets of commands. Commands can be imported from
# different sets, aliased, removed, etc.
class CommandSet
class Command < Struct.new(:name, :description, :options, :block)
class Command < Struct.new(:name, :description, :options, :callable)
def call(context, *args)
if stub_block = options[:stub_info]
context.instance_eval(&stub_block)
else
if block.is_a?(Proc)
ret = context.instance_exec(*correct_arg_arity(block.arity, args), &block)
if callable.is_a?(Proc)
ret = context.instance_exec(*correct_arg_arity(callable.arity, args), &callable)
else
ret = block.call(*correct_arg_arity(block.method(:call).arity, args))
# in the case of non-procs the callable *is* the context
ret = callable.call(*correct_arg_arity(callable.method(:call).arity, args))
end
if options[:keep_retval]
@ -157,13 +159,18 @@ class Pry
# end
def before_command(name, &block)
cmd = find_command_by_name_or_listing(name)
prev_block = cmd.block
prev_callable = cmd.callable
wrapper_block = proc do |*args|
instance_exec(*args, &block)
instance_exec(*args, &prev_block)
if prev_callable.is_a?(Proc)
instance_exec(*args, &prev_callable)
else
prev_callable.call(*args)
end
end
cmd.block = wrapper_block
cmd.callable = wrapper_block
end
# Execute a block of code after a command is invoked. The block also
@ -177,13 +184,18 @@ class Pry
# end
def after_command(name, &block)
cmd = find_command_by_name_or_listing(name)
prev_block = cmd.block
prev_callable = cmd.callable
wrapper_block = proc do |*args|
instance_exec(*args, &prev_block)
if prev_callable.is_a?(Proc)
instance_exec(*args, &prev_callable)
else
prev_callable.call(*args)
end
instance_exec(*args, &block)
end
cmd.block = wrapper_block
cmd.callable = wrapper_block
end
def each &block
@ -279,6 +291,8 @@ class Pry
# @raise [NoCommandError] If the command is not defined in this set
def run_command(context, command_name, *args)
command = commands[command_name]
context.extend helper_module
if command.nil?

View file

@ -69,7 +69,7 @@ class Pry
end
if find_command(command_name)
block = Pry::Method.new(find_command(command_name).block)
block = Pry::Method.new(find_command(command_name).callable)
next unless block.source
set_file_and_dir_locals(block.source_file)

View file

@ -0,0 +1,61 @@
require 'helper'
# integration tests
describe "integration tests for class-based commands" do
before do
@set = Pry::CommandSet.new
end
it 'should invoke a class-based command from the REPL' do
c = Class.new(Pry::CommandContext) do
def call
output.puts "yippee!"
end
end
@set.command 'foo', "desc", :definition => c.new
@set.import_from Pry::Commands, "exit-all"
redirect_pry_io(InputTester.new("foo", "exit-all"), out =StringIO.new) do
Pry.start binding, :commands => @set
end
out.string.should =~ /yippee!/
end
it 'should return specified value with :keep_retval => true' do
c = Class.new(Pry::CommandContext) do
def call
:i_enjoyed_the_song_new_flame_by_simply_red_as_a_child_wandering_around_supermarkets
end
end
@set.command 'foo', "desc", :keep_retval => true, :definition => c.new
@set.import_from Pry::Commands, "exit-all"
redirect_pry_io(InputTester.new("foo", "exit-all"), out =StringIO.new) do
Pry.start binding, :commands => @set
end
out.string.should =~ /i_enjoyed_the_song_new_flame_by_simply_red_as_a_child_wandering_around_supermarkets/
end
it 'should NOT return specified value with :keep_retval => false' do
c = Class.new(Pry::CommandContext) do
def call
:i_enjoyed_the_song_new_flame_by_simply_red_as_a_child_wandering_around_supermarkets
end
end
@set.command 'foo', "desc", :keep_retval => false, :definition => c.new
@set.import_from Pry::Commands, "exit-all"
redirect_pry_io(InputTester.new("foo", "exit-all"), out =StringIO.new) do
Pry.start binding, :commands => @set
end
out.string.should !~ /i_enjoyed_the_song_new_flame_by_simply_red_as_a_child_wandering_around_supermarkets/
end
end

View file

@ -376,7 +376,7 @@ describe Pry::CommandSet do
it 'should share the context with the original command' do
@ctx.target = "test target string"
after_val = nil
after_val = nil
orig_val = nil
@set.command('foo') { orig_val = target }
@set.after_command('foo') { after_val = target }
@ -429,7 +429,7 @@ describe Pry::CommandSet do
@set.command 'foo', "desc", :definition => c.new
ctx = @set.commands['foo'].block
ctx = @set.commands['foo'].callable
@set.run_command ctx, 'foo', 1, 2, 3
end
@ -444,7 +444,7 @@ describe Pry::CommandSet do
@set.command 'foo', "desc", :definition => c.new
ctx = @set.commands['foo'].block
ctx = @set.commands['foo'].callable
@set.run_command ctx, 'foo', 1
end
@ -458,7 +458,7 @@ describe Pry::CommandSet do
@set.command 'foo', "desc", :definition => c.new
ctx = @set.commands['foo'].block
ctx = @set.commands['foo'].callable
@set.run_command ctx, 'foo', 1, 2, 3, 4
end
@ -471,7 +471,7 @@ describe Pry::CommandSet do
@set.command 'foo', "desc", :definition => c.new
ctx = @set.commands['foo'].block
ctx = @set.commands['foo'].callable
@set.run_command(ctx, 'foo').should == Pry::CommandContext::VOID_VALUE
end
@ -484,7 +484,7 @@ describe Pry::CommandSet do
@set.command 'foo', "desc", :keep_retval => true, :definition => c.new
ctx = @set.commands['foo'].block
ctx = @set.commands['foo'].callable
@set.run_command(ctx, 'foo').should == :i_have_a_dog_called_tobina
end
@ -503,7 +503,7 @@ describe Pry::CommandSet do
end
end
ctx = @set.commands['foo'].block
ctx = @set.commands['foo'].callable
@set.run_command ctx, 'foo'
end
@ -518,7 +518,7 @@ describe Pry::CommandSet do
@set.command 'foo', "desc", :definition => c.new
ctx = @set.commands['foo'].block
ctx = @set.commands['foo'].callable
@set.run_command ctx, 'foo'
@set.run_command ctx, 'foo'
ctx.state.should == 2
@ -535,7 +535,7 @@ describe Pry::CommandSet do
@set.command 'foo', "desc", :definition => c.new
ctx = @set.commands['foo'].block
ctx = @set.commands['foo'].callable
@set.before_command('foo') { foo << 2 }
@set.run_command(ctx, 'foo')
@ -543,5 +543,24 @@ describe Pry::CommandSet do
end
end
describe "after_command" do
it 'should be called before the original command' do
foo = []
c = Class.new(Pry::CommandContext) do
define_method(:call) do
foo << 1
end
end
@set.command 'foo', "desc", :definition => c.new
ctx = @set.commands['foo'].callable
@set.after_command('foo') { foo << 2 }
@set.run_command(ctx, 'foo')
foo.should == [1, 2]
end
end
end
end

View file

@ -2,16 +2,6 @@ require 'helper'
describe Pry do
# if RUBY_PLATFORM !~ /mingw/ && RUBY_PLATFORM !~ /mswin/ && RUBY_PLATFORM != 'java'
# describe 'warning emissions' do
# it 'should emit no warnings' do
# Open4.popen4 'ruby -I lib -rubygems -r"pry" -W -e "exit"' do |pid, stdin, stdout, stderr|
# stderr.read.empty?.should == true
# end
# end
# end
# end
if RUBY_VERSION =~ /1.9/
describe "Exotic object support" do
# regression test for exotic object support
@ -792,7 +782,7 @@ describe Pry do
str_output = StringIO.new
Pry.new(:input => StringIO.new("hello\n"), :output => str_output, :commands => klass).rep
str_output.string.should =~ /nil/
str_output.string.should =~ /=>/
str_output.string.should =~ /=>/
end
it 'should define a command that keeps its return value but does not return when value is void' do
@ -806,7 +796,7 @@ describe Pry do
str_output.string.empty?.should == true
end
it 'a command (with :keep_retval => false) that replaces eval_string with a valid expression should not have the expression value suppressed' do
it 'a command (with :keep_retval => false) that replaces eval_string with a valid expression should not have the expression value suppressed' do
klass = Pry::CommandSet.new do
command "hello", "" do
eval_string.replace("6")
@ -818,45 +808,45 @@ describe Pry do
end
it 'a command (with :keep_retval => true) that replaces eval_string with a valid expression should overwrite the eval_string with the return value' do
klass = Pry::CommandSet.new do
command "hello", "", :keep_retval => true do
it 'a command (with :keep_retval => true) that replaces eval_string with a valid expression should overwrite the eval_string with the return value' do
klass = Pry::CommandSet.new do
command "hello", "", :keep_retval => true do
eval_string.replace("6")
7
end
end
end
str_output = StringIO.new
Pry.new(:input => StringIO.new("def yo\nhello\n"), :output => str_output, :commands => klass).rep
str_output = StringIO.new
Pry.new(:input => StringIO.new("def yo\nhello\n"), :output => str_output, :commands => klass).rep
str_output.string.should =~ /7/
str_output.string.should.not =~ /6/
end
it 'a command that return a value in a multi-line expression should clear the expression and return the value' do
klass = Pry::CommandSet.new do
command "hello", "", :keep_retval => true do
5
end
end
str_output = StringIO.new
Pry.new(:input => StringIO.new("def yo\nhello\n"), :output => str_output, :commands => klass).rep
str_output.string.should =~ /5/
end
it 'should set the commands default, and the default should be overridable' do
klass = Pry::CommandSet.new do
command "hello" do
output.puts "hello world"
it 'a command that return a value in a multi-line expression should clear the expression and return the value' do
klass = Pry::CommandSet.new do
command "hello", "", :keep_retval => true do
5
end
end
str_output = StringIO.new
Pry.new(:input => StringIO.new("def yo\nhello\n"), :output => str_output, :commands => klass).rep
str_output.string.should =~ /5/
end
Pry.commands = klass
str_output = StringIO.new
Pry.new(:input => InputTester.new("hello"), :output => str_output).rep
str_output.string.should =~ /hello world/
it 'should set the commands default, and the default should be overridable' do
klass = Pry::CommandSet.new do
command "hello" do
output.puts "hello world"
end
end
other_klass = Pry::CommandSet.new do
Pry.commands = klass
str_output = StringIO.new
Pry.new(:input => InputTester.new("hello"), :output => str_output).rep
str_output.string.should =~ /hello world/
other_klass = Pry::CommandSet.new do
command "goodbye", "" do
output.puts "goodbye world"
end
@ -896,7 +886,7 @@ describe Pry do
klass = Pry::CommandSet.new do
alias_command "help2", "help"
end
klass.commands["help2"].block.should == klass.commands["help"].block
klass.commands["help2"].callable.should == klass.commands["help"].callable
end
it 'should change description of a command using desc' do
@ -1312,7 +1302,7 @@ describe Pry do
str_output = StringIO.new
Pry.new(:output => str_output,
:hooks => Pry::Hooks.new.
add_hook(:before_session, :my_name) { |out,_,_| out.puts "OPEN" }
add_hook(:before_session, :my_name) { |out,_,_| out.puts "OPEN" }
).repl
str_output.string.should =~ /OPEN/
@ -1321,7 +1311,7 @@ describe Pry do
str_output = StringIO.new
Pry.new(:output => str_output,
:hooks => Pry::Hooks.new.
add_hook(:after_session, :my_name) { |out,_,_| out.puts "CLOSE" }
add_hook(:after_session, :my_name) { |out,_,_| out.puts "CLOSE" }
).repl
str_output.string.should =~ /CLOSE/