Skip to content

Commit

Permalink
[ARGV] No need for a separate parser file.
Browse files Browse the repository at this point in the history
And rename @subject in tests to what it is.
  • Loading branch information
alloy committed Nov 12, 2014
1 parent 00986e2 commit d464ead
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 141 deletions.
83 changes: 81 additions & 2 deletions lib/claide/argv.rb
@@ -1,7 +1,5 @@
# encoding: utf-8

require 'claide/argv/parser'

module CLAide
# This class is responsible for parsing the parameters specified by the user,
# accessing individual parameters, and keep state by removing handled
Expand Down Expand Up @@ -203,5 +201,86 @@ def delete_entry(requested_type, requested_key, default)
end
result.nil? ? default : result
end

module Parser
# @return [Array<Array<Symbol, String, Array>>] A list of tuples for each
# parameter, where the first entry is the `type` and the second
# entry the actual parsed parameter.
#
# @example
#
# list = parse(['tea', '--no-milk', '--sweetner=honey'])
# list # => [[:arg, "tea"],
# [:flag, ["milk", false]],
# [:option, ["sweetner", "honey"]]]
#
def self.parse(argv)
entries = []
copy = argv.map(&:to_s)
while argument = copy.shift
type = argument_type(argument)
parsed_argument = parse_argument(type, argument)
entries << [type, parsed_argument]
end
entries
end

# @return [Symbol] Returns the type of an argument. The types can be
# either: `:arg`, `:flag`, `:option`.
#
# @param [String] argument
# The argument to check.
#
def self.argument_type(argument)
if argument.start_with?('--')
if argument.include?('=')
:option
else
:flag
end
else
:arg
end
end

# @return [String, Array<String, String>] Returns the argument itself for
# normal arguments (like commands) and a tuple with the key and
# the value for options and flags.
#
# @param [Symbol] type
# The type of the argument.
#
# @param [String] argument
# The argument to check.
#
def self.parse_argument(type, argument)
case type
when :arg
return argument
when :flag
return parse_flag(argument)
when :option
return argument[2..-1].split('=', 2)
end
end

# @return [String, Array<String, String>] Returns the parameter
# describing a flag arguments.
#
# @param [String] argument
# The flag argument to check.
#
def self.parse_flag(argument)
if argument.start_with?('--no-')
key = argument[5..-1]
value = false
else
key = argument[2..-1]
value = true
end
[key, value]
end
end

end
end
83 changes: 0 additions & 83 deletions lib/claide/argv/parser.rb

This file was deleted.

38 changes: 0 additions & 38 deletions spec/argv/parser_spec.rb

This file was deleted.

69 changes: 51 additions & 18 deletions spec/argv_spec.rb
Expand Up @@ -7,7 +7,7 @@ module CLAide
describe 'in general' do
before do
parameters = %w(--flag --option=VALUE ARG1 ARG2 --no-other-flag)
@subject = ARGV.new(parameters)
@argv = ARGV.new(parameters)
end

it 'converts objects into strings while parsing' do
Expand All @@ -23,49 +23,82 @@ module CLAide
end

it 'returns the options as a hash' do
@subject.options.should == {
@argv.options.should == {
'flag' => true,
'other-flag' => false,
'option' => 'VALUE',
}
end

it 'returns the arguments' do
@subject.arguments.should == %w(ARG1 ARG2)
@argv.arguments.should == %w(ARG1 ARG2)
end

it 'returns a flag and deletes it' do
@subject.flag?('flag').should == true
@subject.flag?('other-flag').should == false
@subject.flag?('option').should.nil?
@subject.remainder.should == %w(--option=VALUE ARG1 ARG2)
@argv.flag?('flag').should == true
@argv.flag?('other-flag').should == false
@argv.flag?('option').should.nil?
@argv.remainder.should == %w(--option=VALUE ARG1 ARG2)
end

it 'returns a default value if a flag does not exist' do
@subject.flag?('option', true).should == true
@subject.flag?('option', false).should == false
@argv.flag?('option', true).should == true
@argv.flag?('option', false).should == false
end

it 'returns an option and deletes it' do
@subject.option('flag').should.nil?
@subject.option('other-flag').should.nil?
@subject.option('option').should == 'VALUE'
@subject.remainder.should == %w(--flag ARG1 ARG2 --no-other-flag)
@argv.option('flag').should.nil?
@argv.option('other-flag').should.nil?
@argv.option('option').should == 'VALUE'
@argv.remainder.should == %w(--flag ARG1 ARG2 --no-other-flag)
end

it 'returns a default value if an option does not exist' do
@subject.option('flag', 'value').should == 'value'
@argv.option('flag', 'value').should == 'value'
end

it 'returns the first argument and deletes it' do
@subject.shift_argument.should == 'ARG1'
@subject.remainder.should ==
@argv.shift_argument.should == 'ARG1'
@argv.remainder.should ==
%w(--flag --option=VALUE ARG2 --no-other-flag)
end

it 'returns and deletes all arguments' do
@subject.arguments!.should == %w(ARG1 ARG2)
@subject.remainder.should == %w(--flag --option=VALUE --no-other-flag)
@argv.arguments!.should == %w(ARG1 ARG2)
@argv.remainder.should == %w(--flag --option=VALUE --no-other-flag)
end
end
end

describe ARGV::Parser do
before do
@parser = ARGV::Parser
end

describe '::parse' do
it 'handles regular arguments' do
@parser.parse(%w(value)).should == [[:arg, 'value']]
end

it 'returns the parameter for a positive flag' do
@parser.parse(%w(--value)).should == [[:flag, ['value', true]]]
end

it 'returns the parameter for a negative flag' do
@parser.parse(%w(--no-value)).should == [[:flag, ['value', false]]]
end

it 'returns the parameter for an option' do
@parser.parse(%w(--key=value)).should == [[:option, %w(key value)]]
end

it 'returns the parameter for a combination of arguments' do
@parser.parse(%w(value --value --no-value --key=value)).should == [
[:arg, 'value'],
[:flag, ['value', true]],
[:flag, ['value', false]],
[:option, %w(key value)],
]
end
end
end
Expand Down

0 comments on commit d464ead

Please sign in to comment.