Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 25 additions & 22 deletions lib/getoptlong.rb
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,8 @@ class NeedlessArgument < Error; end
class MissingArgument < Error; end
class InvalidOption < Error; end

attr_accessor :argv, :env

#
# Returns a new \GetoptLong object based on the given +arguments+.
# See {Options}[#class-GetoptLong-label-Options].
Expand All @@ -409,11 +411,11 @@ class InvalidOption < Error; end
# - Any option name or alias is not a string.
# - Any option type is invalid.
#
def initialize(*arguments)
def initialize(*arguments, argv: ARGV, env: ENV)
#
# Current ordering.
#
if ENV.include?('POSIXLY_CORRECT')
if env.include?('POSIXLY_CORRECT')
@ordering = REQUIRE_ORDER
else
@ordering = PERMUTE
Expand Down Expand Up @@ -467,6 +469,9 @@ def initialize(*arguments)
if 0 < arguments.length
set_options(*arguments)
end

self.argv = argv
self.env = env
end

# Sets the ordering; see {Ordering}[#class-GetoptLong-label-Ordering];
Expand Down Expand Up @@ -502,7 +507,7 @@ def ordering=(ordering)
if !ORDERINGS.include?(ordering)
raise ArgumentError, "invalid ordering `#{ordering}'"
end
if ordering == PERMUTE && ENV.include?('POSIXLY_CORRECT')
if ordering == PERMUTE && env.include?('POSIXLY_CORRECT')
@ordering = REQUIRE_ORDER
else
@ordering = ordering
Expand Down Expand Up @@ -614,9 +619,7 @@ def terminate
raise RuntimeError, "an error has occurred" if @error != nil

@status = STATUS_TERMINATED
@non_option_arguments.reverse_each do |argument|
ARGV.unshift(argument)
end
argv.unshift(*@non_option_arguments)

@canonical_names = nil
@argument_flags = nil
Expand Down Expand Up @@ -690,26 +693,26 @@ def get
#
if 0 < @rest_singles.length
argument = '-' + @rest_singles
elsif (ARGV.length == 0)
elsif argv.empty?
terminate
return nil
elsif @ordering == PERMUTE
while 0 < ARGV.length && ARGV[0] !~ /\A-./
@non_option_arguments.push(ARGV.shift)
while !(argv.empty? || /\A-./.match?(argv.first))
@non_option_arguments.push(argv.shift)
end
if ARGV.length == 0
if argv.empty?
terminate
return nil
end
argument = ARGV.shift
argument = argv.shift
elsif @ordering == REQUIRE_ORDER
if (ARGV[0] !~ /\A-./)
unless /\A-./.match?(argv.first)
terminate
return nil
end
argument = ARGV.shift
argument = argv.shift
else
argument = ARGV.shift
argument = argv.shift
end

#
Expand Down Expand Up @@ -756,17 +759,17 @@ def get
if @argument_flags[option_name] == REQUIRED_ARGUMENT
if argument =~ /=(.*)/m
option_argument = $1
elsif 0 < ARGV.length
option_argument = ARGV.shift
elsif !argv.empty?
option_argument = argv.shift
else
set_error(MissingArgument,
"option `#{argument}' requires an argument")
end
elsif @argument_flags[option_name] == OPTIONAL_ARGUMENT
if argument =~ /=(.*)/m
option_argument = $1
elsif 0 < ARGV.length && ARGV[0] !~ /\A-./
option_argument = ARGV.shift
elsif !(argv.empty? || /\A-./.match?(argv.first))
option_argument = argv.shift
else
option_argument = ''
end
Expand All @@ -792,8 +795,8 @@ def get
if 0 < @rest_singles.length
option_argument = @rest_singles
@rest_singles = ''
elsif 0 < ARGV.length
option_argument = ARGV.shift
elsif !argv.empty?
option_argument = argv.shift
else
# 1003.2 specifies the format of this message.
set_error(MissingArgument, "option requires an argument -- #{ch}")
Expand All @@ -802,8 +805,8 @@ def get
if 0 < @rest_singles.length
option_argument = @rest_singles
@rest_singles = ''
elsif 0 < ARGV.length && ARGV[0] !~ /\A-./
option_argument = ARGV.shift
elsif !(argv.empty? || /\A-./.match?(argv.first))
option_argument = argv.shift
else
option_argument = ''
end
Expand Down
22 changes: 11 additions & 11 deletions test/test_getoptlong.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,27 @@

class TestGetoptLong < Test::Unit::TestCase

def verify(test_argv, expected_remaining_argv, expected_options)
# Save ARGV and replace it with a test ARGV.
argv_saved = ARGV.dup
ARGV.replace(test_argv)
# Define options.
opts = GetoptLong.new(
def getoptlong_new(argv)
GetoptLong.new(
['--xxx', '-x', '--aaa', '-a', GetoptLong::REQUIRED_ARGUMENT],
['--yyy', '-y', '--bbb', '-b', GetoptLong::OPTIONAL_ARGUMENT],
['--zzz', '-z', '--ccc', '-c', GetoptLong::NO_ARGUMENT]
['--zzz', '-z', '--ccc', '-c', GetoptLong::NO_ARGUMENT],
argv:
)
end

def verify(test_argv, expected_remaining_argv, expected_options)
# Define options.
opts = getoptlong_new(test_argv)
opts.quiet = true
# Gather options.
actual_options = []
opts.each do |opt, arg|
actual_options << "#{opt}: #{arg}"
end
# Save remaining test ARGV and restore original ARGV.
actual_remaining_argv = ARGV.dup
ARGV.replace(argv_saved)

# Assert.
assert_equal(expected_remaining_argv, actual_remaining_argv, 'ARGV')
assert_equal(expected_remaining_argv, test_argv, 'ARGV')
assert_equal(expected_options, actual_options, 'Options')
end

Expand Down
Loading