Skip to content
This repository has been archived by the owner on Apr 27, 2018. It is now read-only.

Commit

Permalink
Actually implement, test and use the :remainder option
Browse files Browse the repository at this point in the history
  • Loading branch information
koraktor committed Jan 22, 2011
1 parent 37414c3 commit dbe0129
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 20 deletions.
2 changes: 1 addition & 1 deletion lib/rubikon/application/instance_methods.rb
Expand Up @@ -244,7 +244,7 @@ def help_command

app_help = lambda { |info| @__app__.instance_eval { help(info) } }

unless args.first.nil?
unless cmd.nil?
if commands.keys.include?(cmd)
puts commands[cmd].help
else
Expand Down
45 changes: 32 additions & 13 deletions lib/rubikon/has_arguments.rb
Expand Up @@ -19,10 +19,6 @@ module HasArguments

include Parameter

# @return [Array<String>] The arguments given to this parameter
attr_reader :args
alias_method :arguments, :args

# Creates a new parameter with arguments with the given name and an
# optional code block
#
Expand All @@ -44,9 +40,9 @@ module HasArguments
def initialize(app, name, *options, &block)
super(app, name, &block)

@arg_names = nil
@arg_names = []
@arg_values = nil
@args = []
@args = {}

@description = options.shift if options.first.is_a? String

Expand Down Expand Up @@ -80,7 +76,9 @@ def initialize(app, name, *options, &block)
end
arg.each do |arg_name, opt|
@arg_names << arg_name.to_sym
@min_arg_count += 1 unless opt.include? :optional
unless opt.include?(:optional) || opt.include?(:remainder)
@min_arg_count += 1
end
if opt.include? :remainder
@max_arg_count = -1
break
Expand Down Expand Up @@ -108,10 +106,21 @@ def initialize(app, name, *options, &block)
# @see #args
# @since 0.4.0
def [](arg)
arg = @arg_names.index(arg) if arg.is_a? Symbol
@args[arg]
end

# Returns the arguments given to this parameter. They are given as a Hash
# when there are named arguments or as an Array when there are no named
# arguments
#
# @return [Array<String>, Hash<Symbol, String>] The arguments given to this
# parameter
# @since 0.6.0
def args
@arg_names.empty? ? @args.values : @args
end
alias_method :arguments, :args

protected

# Adds an argument to this parameter. Arguments can be accessed inside the
Expand All @@ -126,10 +135,20 @@ def [](arg)
# @see #args
# @since 0.3.0
def <<(arg)
if args_full? && @args.size == @max_arg_count
raise ExtraArgumentError.new(@name)
raise ExtraArgumentError.new(@name) unless more_args?

if @arg_names.size > @args.size
name = @arg_names[@args.size]
if @max_arg_count == -1 && @arg_names.size == @args.size + 1
@args[name] = [arg]
else
@args[name] = arg
end
elsif !@arg_names.empty? && @max_arg_count == -1
@args[@arg_names.last] << arg
else
@args[@args.size] = arg
end
@args << arg
end

# Marks this parameter as active when it has been supplied by the user on
Expand Down Expand Up @@ -178,8 +197,8 @@ def check_args
# @user = name
# end
def method_missing(name, *args, &block)
if args.empty? && !block_given? && !@arg_names.nil? && @arg_names.include?(name)
@args[@arg_names.index(name)]
if args.empty? && !block_given? && !@arg_names.empty? && @arg_names.include?(name)
@args[name]
else
super
end
Expand Down
8 changes: 4 additions & 4 deletions samples/helloworld/hello_world.rb
Expand Up @@ -3,7 +3,7 @@
# This code is free software; you can redistribute it and/or modify it under
# the terms of the new BSD License.
#
# Copyright (c) 2010, Sebastian Staudt
# Copyright (c) 2010-2011, Sebastian Staudt

if ENV['RUBIKON_DEV']
require File.join(File.expand_path(File.dirname(__FILE__)), '..', '..', 'lib', 'rubikon')
Expand All @@ -17,14 +17,14 @@ class HelloWorld < Rubikon::Application::Base

# Greet the whole world per default
flag :more, 'Display more information while greeting'
option :names, -1, 'One or more names to greet'
option :name, 'A single name to greet', :who
option :names, 'One or more names to greet', :people => :remainder
default 'Simple hello world' do
debug 'Starting to greet the world...'
if given? :name
greet parameters[:name].who
greet who
elsif given? :names
names.args.each do |name|
names.people.each do |name|
greet name
end
else
Expand Down
28 changes: 26 additions & 2 deletions test/test_has_arguments.rb
Expand Up @@ -24,13 +24,13 @@ class TestHasArguments < Test::Unit::TestCase
should 'allow a Numeric as argument count' do
has_arg = HasArg.new 1
assert_equal 1..1, has_arg.arg_count
assert_nil has_arg.arg_names
assert_equal [], has_arg.arg_names
end

should 'allow a Range as argument count' do
has_arg = HasArg.new 1..3
assert_equal 1..3, has_arg.arg_count
assert_nil has_arg.arg_names
assert_equal [], has_arg.arg_names
end

should 'allow a Symbol Array as argument names' do
Expand Down Expand Up @@ -89,6 +89,30 @@ class TestHasArguments < Test::Unit::TestCase
end
end

should 'provide optional named arguments' do
has_arg = HasArg.new :required, :optional => :optional
has_arg << 'argument'
assert has_arg.args_full?
assert has_arg.more_args?
has_arg << 'argument'
assert !has_arg.more_args?
assert_equal 'argument', has_arg.required
assert_equal 'argument', has_arg.optional
end

should 'provide named arguments taking all remainding arguments' do
has_arg = HasArg.new :required, :remainder => :remainder
has_arg << 'argument'
assert has_arg.args_full?
assert has_arg.more_args?
has_arg << 'argument'
assert has_arg.more_args?
has_arg << 'argument'
assert has_arg.more_args?
assert_equal 'argument', has_arg.required
assert_equal %w{argument argument}, has_arg.remainder
end

should 'call its code block if it is activated' do
block_run = false
has_arg = HasArg.new nil do
Expand Down

0 comments on commit dbe0129

Please sign in to comment.