#! /usr/bin/ruby -s
require 'test/unit'

#$:.unshift(File.dirname(__FILE__)+'/lib')
$:.unshift($lib) if $lib
require 'optparse'

class TestOptionParser < Test::Unit::TestCase
  def setup
    @opt = OptionParser.new
    @flag = self.class		# cannot set by option
  end
  #  def no_error(&block)
  #    assert_nothing_raised(OptionParser::ParseError, &block)
  #  end
  alias no_error assert_nothing_raised

  def test_permute
    assert_equal(%w"", no_error {@opt.permute!(%w"")})
    assert_equal(self.class, @flag)
    assert_equal(%w"foo bar", no_error {@opt.permute!(%w"foo bar")})
    assert_equal(self.class, @flag)
    assert_equal(%w"- foo bar", no_error {@opt.permute!(%w"- foo bar")})
    assert_equal(self.class, @flag)
    assert_equal(%w"foo bar", no_error {@opt.permute!(%w"-- foo bar")})
    assert_equal(self.class, @flag)
    assert_equal(%w"foo - bar", no_error {@opt.permute!(%w"foo - bar")})
    assert_equal(self.class, @flag)
    assert_equal(%w"foo bar", no_error {@opt.permute!(%w"foo -- bar")})
    assert_equal(self.class, @flag)
    assert_equal(%w"foo --help bar", no_error {@opt.permute!(%w"foo -- --help bar")})
    assert_equal(self.class, @flag)
  end

  def test_order
    assert_equal(%w"", no_error {@opt.order!(%w"")})
    assert_equal(self.class, @flag)
    assert_equal(%w"foo bar", no_error {@opt.order!(%w"foo bar")})
    assert_equal(self.class, @flag)
    assert_equal(%w"- foo bar", no_error {@opt.order!(%w"- foo bar")})
    assert_equal(self.class, @flag)
    assert_equal(%w"foo bar", no_error {@opt.permute!(%w"-- foo bar")})
    assert_equal(self.class, @flag)
    assert_equal(%w"foo - bar", no_error {@opt.order!(%w"foo - bar")})
    assert_equal(self.class, @flag)
    assert_equal(%w"foo -- bar", no_error {@opt.order!(%w"foo -- bar")})
    assert_equal(self.class, @flag)
    assert_equal(%w"foo -- --help bar", no_error {@opt.order!(%w"foo -- --help bar")})
    assert_equal(self.class, @flag)
  end

  module NoArg
    class Def1 < TestOptionParser
      include NoArg
      def setup
	super
	@opt.def_option("-x") {|x| @flag = x}
	@opt.def_option("--option") {|x| @flag = x}
      end
    end
    class Def2 < TestOptionParser
      include NoArg
      def setup
	super
	@opt.def_option("-x", "--option") {|x| @flag = x}
      end
    end

    def test_short
      assert_raises(OptionParser::InvalidOption) {@opt.parse!(%w"-xq")}
      assert_equal(%w"", no_error {@opt.parse!(%w"-x")})
      assert_equal(true, @flag)
      @flag = nil
      assert_equal(%w"foo", no_error {@opt.parse!(%w"-x foo")})
      assert_equal(true, @flag)
    end

    def test_abbrev
      assert_raises(OptionParser::InvalidOption) {@opt.parse!(%w"-oq")}
      assert_equal(%w"", no_error {@opt.parse!(%w"-o")})
      assert_equal(true, @flag)
      @flag = nil
      no_error {@opt.parse!(%w"-O")}
      assert_equal(true, @flag)
      @flag = nil
      assert_equal(%w"foo", no_error {@opt.parse!(%w"-o foo")})
      assert_equal(true, @flag)
    end

    def test_long
      assert_raises(OptionParser::NeedlessArgument) {@opt.parse!(%w"--option=x")}
      assert_equal(%w"", no_error {@opt.parse!(%w"--opt")})
      assert_equal(true, @flag)
      @flag = nil
      assert_equal(%w"foo", no_error {@opt.parse!(%w"--opt foo")})
      assert_equal(true, @flag)
    end

    def test_ambiguous
      @opt.def_option("--open") {|x|}
      assert_raises(OptionParser::AmbiguousOption) {@opt.parse!(%w"--op")}
      assert_raises(OptionParser::AmbiguousOption) {@opt.parse!(%w"-o")}
      assert_equal(%w"", no_error {@opt.parse!(%w"--opt")})
      assert_equal(true, @flag)
    end
  end

  module ReqArg
    class Def1 < TestOptionParser
      include ReqArg
      def setup
	super
	@opt.def_option("-xVAL") {|x| @flag = x}
	@opt.def_option("--option=VAL") {|x| @flag = x}
      end
    end
    class Def2 < TestOptionParser
      include ReqArg
      def setup
	super
	@opt.def_option("-x", "--option=VAL") {|x| @flag = x}
      end
    end
    class Def3 < TestOptionParser
      include ReqArg
      def setup
	super
	@opt.def_option("--option=VAL", "-x") {|x| @flag = x}
      end
    end
    class Def4 < TestOptionParser
      include ReqArg
      def setup
	super
	@opt.def_option("-xVAL", "--option=VAL") {|x| @flag = x}
      end
    end

    def test_short
      assert_raises(OptionParser::MissingArgument) {@opt.parse!(%w"-x")}
      assert_equal(%w"", no_error {@opt.parse!(%w"-x foo")})
      assert_equal("foo", @flag)
      assert_equal(%w"", no_error {@opt.parse!(%w"-xbar")})
      assert_equal("bar", @flag)
      assert_equal(%w"", no_error {@opt.parse!(%w"-x=")})
      assert_equal("=", @flag)
    end

    def test_abbrev
      assert_raises(OptionParser::MissingArgument) {@opt.parse!(%w"-o")}
      assert_equal(%w"", no_error {@opt.parse!(%w"-o foo")})
      assert_equal("foo", @flag)
      assert_equal(%w"", no_error {@opt.parse!(%w"-obar")})
      assert_equal("bar", @flag)
      assert_equal(%w"", no_error {@opt.parse!(%w"-o=")})
      assert_equal("=", @flag)
    end

    def test_long
      assert_raises(OptionParser::MissingArgument) {@opt.parse!(%w"--opt")}
      assert_equal(%w"", no_error {@opt.parse!(%w"--opt foo")})
      assert_equal("foo", @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")})
      assert_equal("foo", @flag)
    end
  end

  class OptArg < TestOptionParser
    def setup
      super
      @opt.def_option("-x[VAL]") {|x| @flag = x}
      @opt.def_option("--option[=VAL]") {|x| @flag = x}
    end

    def test_short
      assert_equal(%w"", no_error {@opt.parse!(%w"-x")})
      assert_equal(nil, @flag)
      @flag = false
      assert_equal(%w"foo", no_error {@opt.parse!(%w"-x foo")})
      assert_equal(nil, @flag)
      assert_equal(%w"", no_error {@opt.parse!(%w"-xfoo")})
      assert_equal("foo", @flag)
      assert_equal(%w"", no_error {@opt.parse!(%w"-x=")})
      assert_equal("=", @flag)
    end

    def test_abbrev
      assert_equal(%w"", no_error {@opt.parse!(%w"-o")})
      assert_equal(nil, @flag)
      @flag = false
      assert_equal(%w"foo", no_error {@opt.parse!(%w"-o foo")})
      assert_equal(nil, @flag)
      assert_equal(%w"", no_error {@opt.parse!(%w"-ofoo")})
      assert_equal("foo", @flag)
      assert_equal(%w"", no_error {@opt.parse!(%w"-o=")})
      assert_equal("=", @flag)
    end

    def test_long
      assert_equal(%w"", no_error {@opt.parse!(%w"--opt")})
      assert_equal(nil, @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")})
      assert_equal("foo", @flag)
      assert_equal(%w"foo", no_error {@opt.parse!(%w"--opt foo")})
      assert_equal(nil, @flag)
    end
  end

  class PlaceArg < TestOptionParser
    def setup
      super
      @opt.def_option("-x [VAL]") {|x| @flag = x}
      @opt.def_option("--option [VAL]") {|x| @flag = x}
      @opt.def_option("-n") {}
    end

    def test_short
      assert_equal(%w"", no_error {@opt.parse!(%w"-x -n")})
      assert_equal(nil, @flag)
      @flag = false
      assert_equal(%w"", no_error {@opt.parse!(%w"-x foo")})
      assert_equal("foo", @flag)
      assert_equal(%w"", no_error {@opt.parse!(%w"-xbar")})
      assert_equal("bar", @flag)
      assert_equal(%w"", no_error {@opt.parse!(%w"-x=")})
      assert_equal("=", @flag)
    end

    def test_abbrev
      assert_equal(%w"", no_error {@opt.parse!(%w"-o -n")})
      assert_equal(nil, @flag)
      @flag = false
      assert_equal(%w"", no_error {@opt.parse!(%w"-o foo")})
      assert_equal("foo", @flag)
      assert_equal(%w"", no_error {@opt.parse!(%w"-obar")})
      assert_equal("bar", @flag)
      assert_equal(%w"", no_error {@opt.parse!(%w"-o=")})
      assert_equal("=", @flag)
    end

    def test_long
      assert_equal(%w"", no_error {@opt.parse!(%w"--opt -n")})
      assert_equal(nil, @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")})
      assert_equal("foo", @flag)
      assert_equal(%w"", no_error {@opt.parse!(%w"--opt bar")})
      assert_equal("bar", @flag)
    end
  end
end
