From 7859c5bbb07cb30183309376248f1e45998cb7db Mon Sep 17 00:00:00 2001 From: RuhmUndAnsehen <97001540+RuhmUndAnsehen@users.noreply.github.com> Date: Sat, 1 Nov 2025 21:17:59 +0100 Subject: [PATCH] Don't mess with global constants directly. --- lib/getoptlong.rb | 47 ++++++++++++++++++++++------------------- test/test_getoptlong.rb | 22 +++++++++---------- 2 files changed, 36 insertions(+), 33 deletions(-) diff --git a/lib/getoptlong.rb b/lib/getoptlong.rb index d681a42..aaac5cd 100644 --- a/lib/getoptlong.rb +++ b/lib/getoptlong.rb @@ -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]. @@ -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 @@ -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]; @@ -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 @@ -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 @@ -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 # @@ -756,8 +759,8 @@ 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") @@ -765,8 +768,8 @@ def get 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 @@ -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}") @@ -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 diff --git a/test/test_getoptlong.rb b/test/test_getoptlong.rb index 0cd370b..ee4c8fd 100644 --- a/test/test_getoptlong.rb +++ b/test/test_getoptlong.rb @@ -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