diff --git a/.document b/.document new file mode 100644 index 0000000..f175b1d --- /dev/null +++ b/.document @@ -0,0 +1,7 @@ +COPYING +ChangeLog +README.md +doc/ +lib/ +logs/ +misc/ diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..b18fd29 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: 'github-actions' + directory: '/' + schedule: + interval: 'weekly' diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index eaac9f6..98a7642 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -3,10 +3,21 @@ name: test on: [push, pull_request] jobs: - build: + ruby-versions: + runs-on: ubuntu-latest + outputs: + versions: ${{ steps.versions.outputs.value }} + steps: + - id: versions + run: | + versions=$(curl -s 'https://cache.ruby-lang.org/pub/misc/ci_versions/all.json' | jq -c '. + ["2.5"]') + echo "::set-output name=value::${versions}" + test: + needs: ruby-versions + name: build (${{ matrix.ruby }} / ${{ matrix.os }}) strategy: matrix: - ruby: [ '3.0', 2.7, 2.6, 2.5, head ] + ruby: ${{ fromJson(needs.ruby-versions.outputs.versions) }} os: [ ubuntu-latest, macos-latest ] runs-on: ${{ matrix.os }} steps: @@ -15,7 +26,7 @@ jobs: git config --global core.autocrlf false git config --global core.eol lf git config --global advice.detachedHead 0 - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up Ruby uses: ruby/setup-ruby@v1 with: @@ -35,7 +46,7 @@ jobs: RUNNING_OS: ${{matrix.os}} shell: bash - name: Upload package - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: path: pkg/*.gem name: ${{steps.build.outputs.pkg}} diff --git a/Rakefile b/Rakefile index 2262982..29d9a18 100644 --- a/Rakefile +++ b/Rakefile @@ -16,5 +16,5 @@ end task :default => :test task :rdoc do - sh("rdoc", "--op", "rdoc") + sh("rdoc", *Bundler::GemHelper.instance.gemspec.rdoc_options, ".") end diff --git a/doc/optparse/.document b/doc/optparse/.document new file mode 100644 index 0000000..96dfc77 --- /dev/null +++ b/doc/optparse/.document @@ -0,0 +1 @@ +*.rdoc diff --git a/doc/optparse/creates_option.rdoc b/doc/optparse/creates_option.rdoc index 131c877..ab672d5 100644 --- a/doc/optparse/creates_option.rdoc +++ b/doc/optparse/creates_option.rdoc @@ -1,7 +1,7 @@ Creates an option from the given parameters +params+. -See {Parameters for New Options}[./doc/optparse/option_params_rdoc.html]. +See {Parameters for New Options}[optparse/option_params.rdoc]. The block, if given, is the handler for the created option. When the option is encountered during command-line parsing, the block is called with the argument given for the option, if any. -See {Option Handlers}[./option_params_rdoc.html#label-Option+Handlers]. +See {Option Handlers}[optparse/option_params.rdoc#label-Option+Handlers]. diff --git a/doc/optparse/option_params.rdoc b/doc/optparse/option_params.rdoc index 3e6cb1b..ace2c42 100644 --- a/doc/optparse/option_params.rdoc +++ b/doc/optparse/option_params.rdoc @@ -410,7 +410,7 @@ from the default \String to an instance of another class. There are a number of built-in converters. You can also define custom converters. -See {Argument Converters}[./argument_converters_rdoc.html]. +See {Argument Converters}[./argument_converters.rdoc]. === Descriptions @@ -418,7 +418,7 @@ A description parameter is any string parameter that is not recognized as an {option name}[#label-Option+Names] or a {terminator}[#label-Terminators]; -in other words, it does not begin with a hypnen. +in other words, it does not begin with a hyphen. You may give any number of description parameters; each becomes a line in the text generated by option --help. @@ -453,7 +453,7 @@ when the option is encountered. The handler may be: ==== Handler Blocks -An option hadler may be a block. +An option handler may be a block. File +block.rb+ defines an option that has a handler block. diff --git a/doc/optparse/tutorial.rdoc b/doc/optparse/tutorial.rdoc index 1d7c52b..b950898 100644 --- a/doc/optparse/tutorial.rdoc +++ b/doc/optparse/tutorial.rdoc @@ -541,7 +541,7 @@ Executions: [#, Date] You can also define custom converters. -See {Argument Converters}[./argument_converters_rdoc.html] +See {Argument Converters}[./argument_converters.rdoc] for both built-in and custom converters. === Help @@ -657,7 +657,7 @@ Though you may never need to call it directly, here's the core method for defining an option: - \Method \OptionParser#make_switch accepts an array of parameters and a block. - See {Parameters for New Options}[./option_params_rdoc.html]. + See {Parameters for New Options}[optparse/option_params.rdoc]. This method is unlike others here in that it: - Accepts an array of parameters; others accept a sequence of parameter arguments. diff --git a/lib/optparse.rb b/lib/optparse.rb index 61dd87f..dc2b8a0 100644 --- a/lib/optparse.rb +++ b/lib/optparse.rb @@ -50,7 +50,7 @@ # # === New to \OptionParser? # -# See the {Tutorial}[./doc/optparse/tutorial_rdoc.html]. +# See the {Tutorial}[optparse/tutorial.rdoc]. # # === Introduction # @@ -420,12 +420,12 @@ # === Further documentation # # The above examples, along with the accompanying -# {Tutorial}[./doc/optparse/tutorial_rdoc.html], +# {Tutorial}[optparse/tutorial.rdoc], # should be enough to learn how to use this class. # If you have any questions, file a ticket at http://bugs.ruby-lang.org. # class OptionParser - OptionParser::Version = "0.2.0" + OptionParser::Version = "0.3.0" # :stopdoc: NoArgument = [NO_ARGUMENT = :NONE, nil].freeze @@ -674,6 +674,29 @@ def compsys(sdone, ldone) # :nodoc: end end + def pretty_print_contents(q) # :nodoc: + if @block + q.text ":" + @block.source_location.join(":") + ":" + first = false + else + first = true + end + [@short, @long].each do |list| + list.each do |opt| + if first + q.text ":" + first = false + end + q.breakable + q.text opt + end + end + end + + def pretty_print(q) # :nodoc: + q.object_group(self) {pretty_print_contents(q)} + end + # # Switch that takes no arguments. # @@ -693,6 +716,10 @@ def self.incompatible_argument_styles(*) def self.pattern Object end + + def pretty_head # :nodoc: + "NoArgument" + end end # @@ -710,6 +737,10 @@ def parse(arg, argv) end conv_arg(*parse_arg(arg, &method(:raise))) end + + def pretty_head # :nodoc: + "Required" + end end # @@ -727,18 +758,22 @@ def parse(arg, argv, &error) conv_arg(arg) end end + + def pretty_head # :nodoc: + "Optional" + end end # - # Switch that takes an argument, which does not begin with '-'. + # Switch that takes an argument, which does not begin with '-' or is '-'. # class PlacedArgument < self # - # Returns nil if argument is not present or begins with '-'. + # Returns nil if argument is not present or begins with '-' and is not '-'. # def parse(arg, argv, &error) - if !(val = arg) and (argv.empty? or /\A-/ =~ (val = argv[0])) + if !(val = arg) and (argv.empty? or /\A-./ =~ (val = argv[0])) return nil, block, nil end opt = (val = parse_arg(val, &error))[1] @@ -750,6 +785,10 @@ def parse(arg, argv, &error) end val end + + def pretty_head # :nodoc: + "Placed" + end end end @@ -781,6 +820,17 @@ def initialize @list = [] end + def pretty_print(q) # :nodoc: + q.group(1, "(", ")") do + @list.each do |sw| + next unless Switch === sw + q.group(1, "(" + sw.pretty_head, ")") do + sw.pretty_print_contents(q) + end + end + end + end + # # See OptionParser.accept. # @@ -1098,6 +1148,7 @@ def initialize(banner = nil, width = 32, indent = ' ' * 4) @summary_indent = indent @default_argv = ARGV @require_exact = false + @raise_unknown = true add_officious yield self if block_given? end @@ -1175,6 +1226,9 @@ def self.reject(*args, &blk) top.reject(*args, &blk) end # abbreviated long option as short option). attr_accessor :require_exact + # Whether to raise at unknown option. + attr_accessor :raise_unknown + # # Heading banner preceding summary. # @@ -1293,6 +1347,29 @@ def summarize(to = [], width = @summary_width, max = width - 1, indent = @summar def help; summarize("#{banner}".sub(/\n?\z/, "\n")) end alias to_s help + def pretty_print(q) # :nodoc: + q.object_group(self) do + first = true + if @stack.size > 2 + @stack.each_with_index do |s, i| + next if i < 2 + next if s.list.empty? + if first + first = false + q.text ":" + end + q.breakable + s.pretty_print(q) + end + end + end + end + + def inspect # :nodoc: + require 'pp' + pretty_print_inspect + end + # # Returns option summary list. # @@ -1429,7 +1506,7 @@ def make_switch(opts, block = nil) style = notwice(default_style.guess(arg = o), style, 'style') default_pattern, conv = search(:atype, Object) unless default_pattern else - desc.push(o) + desc.push(o) if o && !o.empty? end end @@ -1566,9 +1643,11 @@ def parse_in_order(argv = default_argv, setter = nil, &nonopt) # :nodoc: begin sw, = complete(:long, opt, true) if require_exact && !sw.long.include?(arg) + throw :terminate, arg unless raise_unknown raise InvalidOption, arg end rescue ParseError + throw :terminate, arg unless raise_unknown raise $!.set_option(arg, true) end begin @@ -1600,6 +1679,7 @@ def parse_in_order(argv = default_argv, setter = nil, &nonopt) # :nodoc: end end rescue ParseError + throw :terminate, arg unless raise_unknown raise $!.set_option(arg, true) end begin @@ -1830,10 +1910,13 @@ def candidate(word) # directory ~/.options, then the basename with '.options' suffix # under XDG and Haiku standard places. # - def load(filename = nil) + # The optional +into+ keyword argument works exactly like that accepted in + # method #parse. + # + def load(filename = nil, into: nil) unless filename basename = File.basename($0, '.*') - return true if load(File.expand_path(basename, '~/.options')) rescue nil + return true if load(File.expand_path(basename, '~/.options'), into: into) rescue nil basename << ".options" return [ # XDG @@ -1845,11 +1928,11 @@ def load(filename = nil) '~/config/settings', ].any? {|dir| next if !dir or dir.empty? - load(File.expand_path(basename, dir)) rescue nil + load(File.expand_path(basename, dir), into: into) rescue nil } end begin - parse(*IO.readlines(filename).each {|s| s.chomp!}) + parse(*File.readlines(filename, chomp: true), into: into) true rescue Errno::ENOENT, Errno::ENOTDIR false diff --git a/lib/optparse/ac.rb b/lib/optparse/ac.rb index 9d52010..0953725 100644 --- a/lib/optparse/ac.rb +++ b/lib/optparse/ac.rb @@ -1,5 +1,5 @@ # frozen_string_literal: false -require 'optparse' +require_relative '../optparse' class OptionParser::AC < OptionParser private diff --git a/lib/optparse/date.rb b/lib/optparse/date.rb index d6649c8..7bbf12b 100644 --- a/lib/optparse/date.rb +++ b/lib/optparse/date.rb @@ -1,5 +1,5 @@ # frozen_string_literal: false -require 'optparse' +require_relative '../optparse' require 'date' OptionParser.accept(DateTime) do |s,| diff --git a/lib/optparse/kwargs.rb b/lib/optparse/kwargs.rb index ccf20c6..992aca4 100644 --- a/lib/optparse/kwargs.rb +++ b/lib/optparse/kwargs.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true -require 'optparse' +require_relative '../optparse' class OptionParser # :call-seq: diff --git a/lib/optparse/shellwords.rb b/lib/optparse/shellwords.rb index bf31701..4feb199 100644 --- a/lib/optparse/shellwords.rb +++ b/lib/optparse/shellwords.rb @@ -2,6 +2,6 @@ # -*- ruby -*- require 'shellwords' -require 'optparse' +require_relative '../optparse' OptionParser.accept(Shellwords) {|s,| Shellwords.shellwords(s)} diff --git a/lib/optparse/time.rb b/lib/optparse/time.rb index ffc6ff0..0ce651f 100644 --- a/lib/optparse/time.rb +++ b/lib/optparse/time.rb @@ -1,5 +1,5 @@ # frozen_string_literal: false -require 'optparse' +require_relative '../optparse' require 'time' OptionParser.accept(Time) do |s,| diff --git a/lib/optparse/uri.rb b/lib/optparse/uri.rb index 51550cf..31d1059 100644 --- a/lib/optparse/uri.rb +++ b/lib/optparse/uri.rb @@ -1,7 +1,7 @@ # frozen_string_literal: false # -*- ruby -*- -require 'optparse' +require_relative '../optparse' require 'uri' OptionParser.accept(URI) {|s,| URI.parse(s) if s} diff --git a/optparse.gemspec b/optparse.gemspec index ae65966..a4287dd 100644 --- a/optparse.gemspec +++ b/optparse.gemspec @@ -23,6 +23,7 @@ Gem::Specification.new do |spec| spec.metadata["source_code_uri"] = spec.homepage spec.files = Dir["{doc,lib,misc}/**/*"] + %w[README.md ChangeLog COPYING] + spec.rdoc_options = ["--main=README.md", "--op=rdoc", "--page-dir=doc"] spec.bindir = "exe" spec.executables = [] spec.require_paths = ["lib"] diff --git a/test/lib/core_assertions.rb b/test/lib/core_assertions.rb index 4471525..bac3856 100644 --- a/test/lib/core_assertions.rb +++ b/test/lib/core_assertions.rb @@ -100,7 +100,7 @@ def syntax_check(code, fname, line) def assert_no_memory_leak(args, prepare, code, message=nil, limit: 2.0, rss: false, **opt) # TODO: consider choosing some appropriate limit for MJIT and stop skipping this once it does not randomly fail - pend 'assert_no_memory_leak may consider MJIT memory usage as leak' if defined?(RubyVM::JIT) && RubyVM::JIT.enabled? + pend 'assert_no_memory_leak may consider MJIT memory usage as leak' if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? require_relative 'memory_status' raise Test::Unit::PendedError, "unsupported platform" unless defined?(Memory::Status) diff --git a/test/optparse/test_acceptable.rb b/test/optparse/test_acceptable.rb index 12f7886..12f5322 100644 --- a/test/optparse/test_acceptable.rb +++ b/test/optparse/test_acceptable.rb @@ -1,7 +1,7 @@ # frozen_string_literal: false require_relative 'test_optparse' -class TestOptionParser::Acceptable < TestOptionParser +class TestOptionParserAcceptable < TestOptionParser def setup super diff --git a/test/optparse/test_autoconf.rb b/test/optparse/test_autoconf.rb index 45f2ba0..ec87744 100644 --- a/test/optparse/test_autoconf.rb +++ b/test/optparse/test_autoconf.rb @@ -2,9 +2,7 @@ require 'test/unit' require 'optparse/ac' -class TestOptionParser < Test::Unit::TestCase; end - -class TestOptionParser::AutoConf < Test::Unit::TestCase +class TestOptionParserAutoConf < Test::Unit::TestCase def setup @opt = OptionParser::AC.new @foo = @bar = self.class diff --git a/test/optparse/test_bash_completion.rb b/test/optparse/test_bash_completion.rb index 513e986..60c82f7 100644 --- a/test/optparse/test_bash_completion.rb +++ b/test/optparse/test_bash_completion.rb @@ -2,9 +2,7 @@ require 'test/unit' require 'optparse' -class TestOptionParser < Test::Unit::TestCase -end -class TestOptionParser::BashCompletion < Test::Unit::TestCase +class TestOptionParserBashCompletion < Test::Unit::TestCase def setup @opt = OptionParser.new @opt.define("-z", "zzz") {} diff --git a/test/optparse/test_cclass.rb b/test/optparse/test_cclass.rb index ac46f46..0ded61f 100644 --- a/test/optparse/test_cclass.rb +++ b/test/optparse/test_cclass.rb @@ -1,7 +1,7 @@ # frozen_string_literal: false require_relative 'test_optparse' -class TestOptionParser::CClass < TestOptionParser +class TestOptionParserCClass < TestOptionParser def test_no_argument flags = [] @opt.def_option("-[a-z]") {|x| flags << x} diff --git a/test/optparse/test_did_you_mean.rb b/test/optparse/test_did_you_mean.rb index 7630625..3c92392 100644 --- a/test/optparse/test_did_you_mean.rb +++ b/test/optparse/test_did_you_mean.rb @@ -6,17 +6,21 @@ return end -class TestOptionParser::DidYouMean < TestOptionParser +class TestOptionParserDidYouMean < TestOptionParser def setup super @opt.def_option("--foo", Integer) { |v| @foo = v } @opt.def_option("--bar", Integer) { |v| @bar = v } @opt.def_option("--baz", Integer) { |v| @baz = v } @formatter = ::DidYouMean.formatter - case @formatter - when ::DidYouMean::PlainFormatter + if ::DidYouMean.const_defined?(:Formatter) + ::DidYouMean.formatter = ::DidYouMean::Formatter else - ::DidYouMean.formatter = ::DidYouMean::PlainFormatter.new + case @formatter + when ::DidYouMean::PlainFormatter + else + ::DidYouMean.formatter = ::DidYouMean::PlainFormatter.new + end end end @@ -36,15 +40,7 @@ def test_plain end end - def test_verbose - require 'did_you_mean/formatters/verbose_formatter' - ::DidYouMean.formatter = ::DidYouMean::VerboseFormatter.new - assert_raise_with_message(OptionParser::InvalidOption, /invalid option: --baa\n\s+Did you mean\?\s+bar\s+baz\s*\Z/) do - @opt.permute!(%w"--baa") - end - end - - def test_ambiguos + def test_ambiguous assert_raise_with_message(OptionParser::AmbiguousOption, /ambiguous option: --ba\nDid you mean\?\s+bar\s+baz\Z/) do @opt.permute!(%w"--ba") end diff --git a/test/optparse/test_getopts.rb b/test/optparse/test_getopts.rb index 3711e6f..7d9160f 100644 --- a/test/optparse/test_getopts.rb +++ b/test/optparse/test_getopts.rb @@ -2,9 +2,7 @@ require 'test/unit' require 'optparse' -class TestOptionParser < Test::Unit::TestCase -end -class TestOptionParser::Getopts < Test::Unit::TestCase +class TestOptionParserGetopts < Test::Unit::TestCase def setup @opt = OptionParser.new end diff --git a/test/optparse/test_kwargs.rb b/test/optparse/test_kwargs.rb index 78d7e2e..2e826bf 100644 --- a/test/optparse/test_kwargs.rb +++ b/test/optparse/test_kwargs.rb @@ -3,9 +3,7 @@ require 'optparse' require 'optparse/kwargs' -class TestOptionParser < Test::Unit::TestCase -end -class TestOptionParser::KwArg < Test::Unit::TestCase +class TestOptionParserKwArg < Test::Unit::TestCase class K def initialize(host:, port: 8080) @host = host diff --git a/test/optparse/test_load.rb b/test/optparse/test_load.rb new file mode 100644 index 0000000..0ebe855 --- /dev/null +++ b/test/optparse/test_load.rb @@ -0,0 +1,141 @@ +# frozen_string_literal: false +require 'test/unit' +require 'optparse' +require 'tmpdir' + +class TestOptionParserLoad < Test::Unit::TestCase + def setup + @tmpdir = Dir.mktmpdir("optparse_test-") + @basename = File.basename($0, '.*') + @envs = %w[HOME XDG_CONFIG_HOME XDG_CONFIG_DIRS].each_with_object({}) do |v, h| + h[v] = ENV.delete(v) + end + end + + def teardown + ENV.update(@envs) + FileUtils.rm_rf(@tmpdir) + end + + def new_parser + @result = nil + OptionParser.new do |opt| + opt.on("--test=arg") {|v| @result = v} + end + end + + def assert_load(result) + assert new_parser.load + assert_equal(result, @result) + assert new_parser.load(into: into = {}) + assert_equal({test: result}, into) + end + + def setup_options(env, dir, suffix = nil) + optdir = File.join(@tmpdir, dir) + FileUtils.mkdir_p(optdir) + file = File.join(optdir, [@basename, suffix].join("")) + File.write(file, "--test=#{dir}") + ENV.update(env) + if block_given? + begin + yield dir, optdir + ensure + File.unlink(file) + Dir.rmdir(optdir) rescue nil + end + else + return dir, optdir + end + end + + def setup_options_home(&block) + setup_options({'HOME'=>@tmpdir}, ".options", &block) + end + + def setup_options_xdg_config_home(&block) + setup_options({'XDG_CONFIG_HOME'=>@tmpdir+"/xdg"}, "xdg", ".options", &block) + end + + def setup_options_home_config(&block) + setup_options({'HOME'=>@tmpdir}, ".config", ".options", &block) + end + + def setup_options_xdg_config_dirs(&block) + setup_options({'XDG_CONFIG_DIRS'=>@tmpdir+"/xdgconf"}, "xdgconf", ".options", &block) + end + + def setup_options_home_config_settings(&block) + setup_options({'HOME'=>@tmpdir}, "config/settings", ".options", &block) + end + + def test_load_home_options + result, = setup_options_home + assert_load(result) + + setup_options_xdg_config_home do + assert_load(result) + end + + setup_options_home_config do + assert_load(result) + end + + setup_options_xdg_config_dirs do + assert_load(result) + end + + setup_options_home_config_settings do + assert_load(result) + end + end + + def test_load_xdg_config_home + result, = setup_options_xdg_config_home + assert_load(result) + + setup_options_home_config do + assert_load(result) + end + + setup_options_xdg_config_dirs do + assert_load(result) + end + + setup_options_home_config_settings do + assert_load(result) + end + end + + def test_load_home_config + result, = setup_options_home_config + assert_load(result) + + setup_options_xdg_config_dirs do + assert_load(result) + end + + setup_options_home_config_settings do + assert_load(result) + end + end + + def test_load_xdg_config_dirs + result, = setup_options_xdg_config_dirs + assert_load(result) + + setup_options_home_config_settings do + assert_load(result) + end + end + + def test_load_home_config_settings + result, = setup_options_home_config_settings + assert_load(result) + end + + def test_load_nothing + assert !new_parser.load + assert_nil @result + end +end diff --git a/test/optparse/test_noarg.rb b/test/optparse/test_noarg.rb index 8f20519..a53399a 100644 --- a/test/optparse/test_noarg.rb +++ b/test/optparse/test_noarg.rb @@ -1,7 +1,7 @@ # frozen_string_literal: false require_relative 'test_optparse' -module TestOptionParser::NoArg +module TestOptionParserNoArg def setup super @opt.def_option "--with_underscore" do |x| @flag = x end @@ -9,7 +9,7 @@ def setup end class Def1 < TestOptionParser - include NoArg + include TestOptionParserNoArg def setup super @opt.def_option("-x") {|x| @flag = x} @@ -17,7 +17,7 @@ def setup end end class Def2 < TestOptionParser - include NoArg + include TestOptionParserNoArg def setup super @opt.def_option("-x", "--option") {|x| @flag = x} diff --git a/test/optparse/test_optarg.rb b/test/optparse/test_optarg.rb index 14584f7..81127a8 100644 --- a/test/optparse/test_optarg.rb +++ b/test/optparse/test_optarg.rb @@ -1,7 +1,7 @@ # frozen_string_literal: false require_relative 'test_optparse' -class TestOptionParser::OptArg < TestOptionParser +class TestOptionParserOptArg < TestOptionParser def setup super @opt.def_option("-x[VAL]") {|x| @flag = x} diff --git a/test/optparse/test_optparse.rb b/test/optparse/test_optparse.rb index 5f5ea18..5a0593d 100644 --- a/test/optparse/test_optparse.rb +++ b/test/optparse/test_optparse.rb @@ -98,6 +98,18 @@ def test_require_exact assert_raise(OptionParser::InvalidOption) {@opt.parse(%w(-z foo))} end + def test_raise_unknown + @opt.def_option('--my-foo [ARG]') {|arg| @foo = arg} + assert @opt.raise_unknown + + @opt.raise_unknown = false + assert_equal(%w[--my-bar], @opt.parse(%w[--my-foo --my-bar])) + assert_nil(@foo) + + assert_equal(%w[--my-bar], @opt.parse(%w[--my-foo x --my-bar])) + assert_equal("x", @foo) + end + def test_nonopt_pattern @opt.def_option(/^[^-]/) do |arg| assert(false, "Never gets called") diff --git a/test/optparse/test_placearg.rb b/test/optparse/test_placearg.rb index 8acfdb2..ed0e4d3 100644 --- a/test/optparse/test_placearg.rb +++ b/test/optparse/test_placearg.rb @@ -1,7 +1,7 @@ # frozen_string_literal: false require_relative 'test_optparse' -class TestOptionParser::PlaceArg < TestOptionParser +class TestOptionParserPlaceArg < TestOptionParser def setup super @opt.def_option("-x [VAL]") {|x| @flag = x} @@ -18,6 +18,8 @@ def setup def test_short assert_equal(%w"", no_error {@opt.parse!(%w"-x -n")}) assert_equal(nil, @flag) + assert_equal(%w"", no_error {@opt.parse!(%w"-x -")}) + assert_equal("-", @flag) @flag = false assert_equal(%w"", no_error {@opt.parse!(%w"-x foo")}) assert_equal("foo", @flag) @@ -30,6 +32,8 @@ def test_short def test_abbrev assert_equal(%w"", no_error {@opt.parse!(%w"-o -n")}) assert_equal(nil, @flag) + assert_equal(%w"", no_error {@opt.parse!(%w"-o -")}) + assert_equal("-", @flag) @flag = false assert_equal(%w"", no_error {@opt.parse!(%w"-o foo")}) assert_equal("foo", @flag) @@ -42,6 +46,8 @@ def test_abbrev def test_long assert_equal(%w"", no_error {@opt.parse!(%w"--opt -n")}) assert_equal(nil, @flag) + assert_equal(%w"", no_error {@opt.parse!(%w"--opt -")}) + assert_equal("-", @flag) assert_equal(%w"foo", no_error {@opt.parse!(%w"--opt= foo")}) assert_equal("", @flag) assert_equal(%w"", no_error {@opt.parse!(%w"--opt=foo")}) diff --git a/test/optparse/test_reqarg.rb b/test/optparse/test_reqarg.rb index b2e4755..d5686d1 100644 --- a/test/optparse/test_reqarg.rb +++ b/test/optparse/test_reqarg.rb @@ -1,7 +1,7 @@ # frozen_string_literal: false require_relative 'test_optparse' -module TestOptionParser::ReqArg +module TestOptionParserReqArg def setup super @opt.def_option "--with_underscore=VAL" do |x| @flag = x end @@ -9,7 +9,7 @@ def setup end class Def1 < TestOptionParser - include ReqArg + include TestOptionParserReqArg def setup super @opt.def_option("-xVAL") {|x| @flag = x} @@ -19,21 +19,21 @@ def setup end end class Def2 < TestOptionParser - include ReqArg + include TestOptionParserReqArg def setup super @opt.def_option("-x", "--option=VAL") {|x| @flag = x} end end class Def3 < TestOptionParser - include ReqArg + include TestOptionParserReqArg def setup super @opt.def_option("--option=VAL", "-x") {|x| @flag = x} end end class Def4 < TestOptionParser - include ReqArg + include TestOptionParserReqArg def setup super @opt.def_option("-xVAL", "--option=VAL") {|x| @flag = x} diff --git a/test/optparse/test_summary.rb b/test/optparse/test_summary.rb index 67b0567..b5dcb35 100644 --- a/test/optparse/test_summary.rb +++ b/test/optparse/test_summary.rb @@ -1,7 +1,7 @@ # frozen_string_literal: false require_relative 'test_optparse' -class TestOptionParser::SummaryTest < TestOptionParser +class TestOptionParserSummaryTest < TestOptionParser def test_short_clash r = nil o = OptionParser.new do |opts| @@ -55,4 +55,27 @@ def test_ver o.release = "rel" assert_equal "foo 0.1 (rel)", o.ver end + + # https://github.com/ruby/optparse/issues/37 + def test_very_long_without_short + o = OptionParser.new do |opts| + # This causes TypeError + opts.on('', '--long-long-option-param-without-short', "Error desc") { options[:long_long_option_param_without_short] = true } + opts.on('', '--long-option-param', "Long desc") { options[:long_option_param_without_short] = true } + opts.on('-a', '--long-long-option-param-with-short', "Normal description") { options[:long_long_option_param_with_short] = true } + + opts.on('', '--long-long-option-param-without-short-but-with-desc', 'Description of the long long param') { options[:long_long_option_param_without_short_but_with_desc] = true } + end + + s = o.summarize + + assert_match(/^\s*--long-long-option-param-without-short$/, s[0]) + assert_match(/^\s*Error desc$/, s[1]) + assert_match(/^\s*--long-option-param\s+Long desc$/, s[2]) + assert_match(/^\s*-a\s+Normal description$/, s[3]) + assert_match(/^\s*--long-long-option-param-with-short$/, s[4]) + + assert_match(/^\s*--long-long-option-param-without-short-but-with-desc$/, s[5]) + assert_match(/^\s*Description of the long long param$/, s[6]) + end end diff --git a/test/optparse/test_zsh_completion.rb b/test/optparse/test_zsh_completion.rb index c548d4a..76f0a73 100644 --- a/test/optparse/test_zsh_completion.rb +++ b/test/optparse/test_zsh_completion.rb @@ -2,9 +2,7 @@ require 'test/unit' require 'optparse' -class TestOptionParser < Test::Unit::TestCase -end -class TestOptionParser::ZshCompletion < Test::Unit::TestCase +class TestOptionParserZshCompletion < Test::Unit::TestCase def setup @opt = OptionParser.new @opt.define("-z", "zzz") {}