From 8a39813708e58bb5cfe97dcef1ca272ff80d9f54 Mon Sep 17 00:00:00 2001 From: Kyrylo Silin Date: Mon, 26 Nov 2012 18:07:32 +0200 Subject: [PATCH] Fix subcommands A few things were missing. I had to add a new method and slightly adjust ClassCommand#slop method. Without these changes subcommands doesn't work properly. Add some unit tests for subcommands. Signed-off-by: Kyrylo Silin --- lib/pry/command.rb | 31 +++++++++++++++------ spec/command_spec.rb | 64 ++++++++++++++++++++++++++++++++------------ 2 files changed, 70 insertions(+), 25 deletions(-) diff --git a/lib/pry/command.rb b/lib/pry/command.rb index 5540eb0f..da5400df 100644 --- a/lib/pry/command.rb +++ b/lib/pry/command.rb @@ -552,7 +552,7 @@ class Pry self.get(key) || default.get(key) end - # Check for a default options presence. + # Check for default options presence. # # @param [String, Symbol] keys The list of keys to check. # @return [Boolean] Whether all of the +keys+ are present in the parsed @@ -561,6 +561,22 @@ class Pry default.present?(*keys) end + # Check for a command presence. + # + # @example + # opts.parse %w'install' + # opts.command?(:install) + # # => true + # opts.command?(:list) + # # => false + # + # @param [Symbol, String] name The name of the command to be checked + # @return [Boolean] `true` if the given +name+ is present in the parsed + # arguments + def command?(name) + __getobj__.present?(name) + end + # Convenience method for {#present?}. # # @example @@ -622,15 +638,14 @@ class Pry # Return an instance of Slop::Commands that can parse either subcommands # or the options that this command accepts. def slop - opts = proc do |opt| - opt.banner(unindent(self.class.banner)) - options(opt) - opt.on(:h, :help, "Show this message.") - end - Slop::Commands.new do |cmd| subcommands(cmd) - cmd.default { |opt| opts.call(opt) } + + cmd.default do |opt| + opt.banner(unindent(self.class.banner)) + options(opt) + opt.on(:h, :help, "Show this message.") + end end end diff --git a/spec/command_spec.rb b/spec/command_spec.rb index 1d874b82..57242141 100644 --- a/spec/command_spec.rb +++ b/spec/command_spec.rb @@ -301,23 +301,6 @@ describe "Pry::Command" do mock_command(cmd, %w(--four 4 four)) end - it 'should provide cmds and args as provided by slop' do - cmd = @set.create_command 'dichlorvos', 'Kill insects' do - def subcommands(cmd) - cmd.on :kill do - on :i, :insect, "An insect." - end - end - - def process - args.should == ["ant"] - opts[:kill][:insect].should == true - end - end - - mock_command(cmd, %w(kill --insect ant)) - end - it 'should allow overriding options after definition' do cmd = @set.create_command /number-(one|two)/, "Lieutenants of the Golgafrinchan Captain", :shellwords => false do @@ -327,6 +310,53 @@ describe "Pry::Command" do cmd.command_options[:shellwords].should == false cmd.command_options[:listing].should == 'number-one' end + + it "should create subcommands" do + cmd = @set.create_command 'mum', 'Your mum' do + def subcommands(cmd) + cmd.on :yell + end + + def process + opts.command?(:blahblah).should == false + opts.command?(:yell).should == true + end + end + + mock_command(cmd, ['yell']) + end + + it "should create subcommand options" do + cmd = @set.create_command 'mum', 'Your mum' do + def subcommands(cmd) + cmd.on :yell do |opt| + opt.on :p, :person + end + end + + def process + args.should == ['papa'] + opts[:yell][:person].should == true + opts[:yell].present? :person + end + end + + mock_command(cmd, %w|yell --person papa|) + end + + it "should accept top-level arguments" do + cmd = @set.create_command 'mum', 'Your mum' do + def subcommands(cmd) + cmd.on :yell + end + + def process + opts.arguments.should == ['papa', 'sonny', 'daughter'] + end + end + + mock_command(cmd, %w|yell papa sonny daughter|) + end end describe 'tokenize' do