home *** CD-ROM | disk | FTP | other *** search
/ PC World 2005 June / PCWorld_2005-06_cd.bin / software / vyzkuste / firewally / firewally.exe / framework-2.3.exe / test_optparse.py < prev    next >
Text File  |  2003-12-30  |  47KB  |  1,204 lines

  1. #!/usr/bin/python
  2.  
  3. #
  4. # Test suite for Optik.  Supplied by Johannes Gijsbers
  5. # (taradino@softhome.net) -- translated from the original Optik
  6. # test suite to this PyUnit-based version.
  7. #
  8. # $Id: test_optparse.py,v 1.2.8.1 2003/08/04 22:49:42 bwarsaw Exp $
  9. #
  10.  
  11. import sys
  12. import os
  13. import copy
  14. import unittest
  15.  
  16. from cStringIO import StringIO
  17. from pprint import pprint
  18. from test import test_support
  19.  
  20. from optparse import make_option, Option, IndentedHelpFormatter, \
  21.      TitledHelpFormatter, OptionParser, OptionContainer, OptionGroup, \
  22.      SUPPRESS_HELP, SUPPRESS_USAGE, OptionError, OptionConflictError, \
  23.      BadOptionError, OptionValueError
  24. from optparse import _match_abbrev
  25.  
  26. # Do the right thing with boolean values for all known Python versions.
  27. try:
  28.     True, False
  29. except NameError:
  30.     (True, False) = (1, 0)
  31.  
  32. class BaseTest(unittest.TestCase):
  33.     def assertParseOK(self, args, expected_opts, expected_positional_args):
  34.         """Assert the options are what we expected when parsing arguments.
  35.  
  36.         Otherwise, fail with a nicely formatted message.
  37.  
  38.         Keyword arguments:
  39.         args -- A list of arguments to parse with OptionParser.
  40.         expected_opts -- The options expected.
  41.         expected_positional_args -- The positional arguments expected.
  42.  
  43.         Returns the options and positional args for further testing.
  44.         """
  45.  
  46.         (options, positional_args) = self.parser.parse_args(args)
  47.         optdict = vars(options)
  48.  
  49.         self.assertEqual(optdict, expected_opts,
  50.                          """
  51. Options are %(optdict)s.
  52. Should be %(expected_opts)s.
  53. Args were %(args)s.""" % locals())
  54.  
  55.         self.assertEqual(positional_args, expected_positional_args,
  56.                          """
  57. Positional arguments are %(positional_args)s.
  58. Should be %(expected_positional_args)s.
  59. Args were %(args)s.""" % locals ())
  60.  
  61.         return (options, positional_args)
  62.  
  63.     def assertRaises(self, func, expected_exception, expected_output,
  64.                      get_output=None,
  65.                      funcargs=[], funckwargs={}):
  66.         """Assert the expected exception is raised when calling a function.
  67.  
  68.         Also check whether the right error message is given for a given error.
  69.  
  70.         Keyword arguments:
  71.         func -- The function to be called.
  72.         expected_exception -- The exception that should be raised.
  73.         expected_output -- The output we expect to see.
  74.         get_output -- The function to call to get the output.
  75.         funcargs -- The arguments `func` should be called with.
  76.         funckwargs -- The keyword arguments `func` should be called with.
  77.  
  78.         Returns the exception raised for further testing.
  79.         """
  80.         if get_output is None:
  81.             get_output = self.exception
  82.  
  83.         try:
  84.             out = func(*funcargs, **funckwargs)
  85.         except expected_exception, err:
  86.             output = get_output(err)
  87.  
  88.             self.failUnless(output.find(expected_output) != -1,
  89.                             """
  90. Message was:
  91. %(output)s
  92. Should contain:
  93. %(expected_output)s
  94. Function called:
  95. %(func)s
  96. With args/kwargs:
  97. %(funcargs)s/%(funckwargs)s""" % locals())
  98.  
  99.             return err
  100.         else:
  101.             self.fail("""
  102. No %(expected_exception)s raised.
  103. Function called:
  104. %(func)s
  105. With args/kwargs:
  106. %(funcargs)s/%(funckwargs)s""" % locals ())
  107.  
  108.     # -- Functions to be used as the get_output argument to assertRaises ------
  109.  
  110.     def exception(self, err):
  111.         return str(err)
  112.  
  113.     def redirected_stdout(self, err):
  114.         return sys.stdout.getvalue()
  115.  
  116.     # -- Assertions used in more than one class --------------------
  117.  
  118.     def assertParseFail(self, cmdline_args, expected_output):
  119.         """Assert the parser fails with the expected message."""
  120.         self.assertRaises(self.parser.parse_args, SystemExit, expected_output,
  121.                           funcargs=[cmdline_args])
  122.  
  123.     def assertStdoutEquals(self, cmdline_args, expected_output):
  124.         """Assert the parser prints the expected output on stdout."""
  125.         sys.stdout = StringIO()
  126.         self.assertRaises(self.parser.parse_args, SystemExit, expected_output,
  127.                           self.redirected_stdout, [cmdline_args])
  128.         sys.stdout = sys.__stdout__
  129.  
  130.     def assertTypeError(self, func, expected_output, *args):
  131.         """Assert a TypeError is raised when executing func."""
  132.         self.assertRaises(func, TypeError, expected_output, funcargs=args)
  133.  
  134. # -- Test make_option() aka Option -------------------------------------
  135.  
  136. # It's not necessary to test correct options here. All the tests in the
  137. # parser.parse_args() section deal with those, because they're needed
  138. # there. Duplication makes no sense to me.
  139.  
  140. class TestOptionChecks(BaseTest):
  141.     def setUp(self):
  142.         self.parser = OptionParser(usage=SUPPRESS_USAGE)
  143.  
  144.     def assertOptionError(self, expected_output, args=[], kwargs={}):
  145.         self.assertRaises(make_option, OptionError, expected_output,
  146.                           funcargs=args, funckwargs=kwargs)
  147.  
  148.     def test_opt_string_empty(self):
  149.         self.assertTypeError(make_option,
  150.                              "at least one option string must be supplied")
  151.  
  152.     def test_opt_string_too_short(self):
  153.         self.assertOptionError("invalid option string 'b': "
  154.                                "must be at least two characters long",
  155.                                ["b"])
  156.  
  157.     def test_opt_string_short_invalid(self):
  158.         self.assertOptionError("invalid short option string '--': must be "
  159.                                "of the form -x, (x any non-dash char)",
  160.                                ["--"])
  161.  
  162.     def test_opt_string_long_invalid(self):
  163.         self.assertOptionError("invalid long option string '---': "
  164.                                "must start with --, followed by non-dash",
  165.                                ["---"])
  166.  
  167.     def test_attr_invalid(self):
  168.         self.assertOptionError("invalid keyword arguments: foo, bar",
  169.                                ["-b"], {'foo': None, 'bar': None})
  170.  
  171.     def test_action_invalid(self):
  172.         self.assertOptionError("invalid action: 'foo'",
  173.                                ["-b"], {'action': 'foo'})
  174.  
  175.     def test_type_invalid(self):
  176.         self.assertOptionError("invalid option type: 'foo'",
  177.                                ["-b"], {'type': 'foo'})
  178.  
  179.     def test_no_type_for_action(self):
  180.         self.assertOptionError("must not supply a type for action 'count'",
  181.                                ["-b"], {'action': 'count', 'type': 'int'})
  182.  
  183.     def test_no_choices_list(self):
  184.         self.assertOptionError("must supply a list of "
  185.                                "choices for type 'choice'",
  186.                                ["-b", "--bad"], {'type': "choice"})
  187.  
  188.     def test_bad_choices_list(self):
  189.         typename = type('').__name__
  190.         self.assertOptionError("choices must be a list of "
  191.                                "strings ('%s' supplied)" % typename,
  192.                                ["-b", "--bad"],
  193.                                {'type': "choice", 'choices':"bad choices"})
  194.  
  195.     def test_no_choices_for_type(self):
  196.         self.assertOptionError("must not supply choices for type 'int'",
  197.                                ["-b"], {'type': 'int', 'choices':"bad"})
  198.  
  199.     def test_no_const_for_action(self):
  200.         self.assertOptionError("'const' must not be supplied for action "
  201.                                "'store'",
  202.                                ["-b"], {'action': 'store', 'const': 1})
  203.  
  204.     def test_no_nargs_for_action(self):
  205.         self.assertOptionError("'nargs' must not be supplied for action "
  206.                                "'count'",
  207.                                ["-b"], {'action': 'count', 'nargs': 2})
  208.  
  209.     def test_callback_not_callable(self):
  210.         self.assertOptionError("callback not callable: 'foo'",
  211.                                ["-b"], {'action': 'callback',
  212.                                         'callback': 'foo'})
  213.  
  214.     def dummy(self):
  215.         pass
  216.  
  217.     def test_callback_args_no_tuple(self):
  218.         self.assertOptionError("callback_args, if supplied, must be a tuple: "
  219.                                "not 'foo'",
  220.                                ["-b"], {'action': 'callback',
  221.                                         'callback': self.dummy,
  222.                                         'callback_args': 'foo'})
  223.  
  224.     def test_callback_kwargs_no_dict(self):
  225.         self.assertOptionError("callback_kwargs, if supplied, must be a dict: "
  226.                                "not 'foo'",
  227.                                ["-b"], {'action': 'callback',
  228.                                         'callback': self.dummy,
  229.                                         'callback_kwargs': 'foo'})
  230.  
  231.     def test_no_callback_for_action(self):
  232.         self.assertOptionError("callback supplied ('foo') for "
  233.                                "non-callback option",
  234.                                ["-b"], {'action': 'store',
  235.                                         'callback': 'foo'})
  236.  
  237.     def test_no_callback_args_for_action(self):
  238.         self.assertOptionError("callback_args supplied for non-callback "
  239.                                "option",
  240.                                ["-b"], {'action': 'store',
  241.                                         'callback_args': 'foo'})
  242.  
  243.     def test_no_callback_kwargs_for_action(self):
  244.         self.assertOptionError("callback_kwargs supplied for non-callback "
  245.                                "option",
  246.                                ["-b"], {'action': 'store',
  247.                                         'callback_kwargs': 'foo'})
  248.  
  249. class TestOptionParser(BaseTest):
  250.     def setUp(self):
  251.         self.parser = OptionParser()
  252.         self.parser.add_option("-v", "--verbose", "-n", "--noisy",
  253.                           action="store_true", dest="verbose")
  254.         self.parser.add_option("-q", "--quiet", "--silent",
  255.                           action="store_false", dest="verbose")
  256.  
  257.     def test_add_option_no_Option(self):
  258.         self.assertTypeError(self.parser.add_option,
  259.                              "not an Option instance: None", None)
  260.  
  261.     def test_add_option_invalid_arguments(self):
  262.         self.assertTypeError(self.parser.add_option,
  263.                              "invalid arguments", None, None)
  264.  
  265.     def test_get_option(self):
  266.         opt1 = self.parser.get_option("-v")
  267.         self.assert_(isinstance(opt1, Option))
  268.         self.assertEqual(opt1._short_opts, ["-v", "-n"])
  269.         self.assertEqual(opt1._long_opts, ["--verbose", "--noisy"])
  270.         self.assertEqual(opt1.action, "store_true")
  271.         self.assertEqual(opt1.dest, "verbose")
  272.  
  273.     def test_get_option_equals(self):
  274.         opt1 = self.parser.get_option("-v")
  275.         opt2 = self.parser.get_option("--verbose")
  276.         opt3 = self.parser.get_option("-n")
  277.         opt4 = self.parser.get_option("--noisy")
  278.         self.assert_(opt1 is opt2 is opt3 is opt4)
  279.  
  280.     def test_has_option(self):
  281.         self.assert_(self.parser.has_option("-v"))
  282.         self.assert_(self.parser.has_option("--verbose"))
  283.  
  284.     def assert_removed(self):
  285.         self.assert_(self.parser.get_option("-v") is None)
  286.         self.assert_(self.parser.get_option("--verbose") is None)
  287.         self.assert_(self.parser.get_option("-n") is None)
  288.         self.assert_(self.parser.get_option("--noisy") is None)
  289.  
  290.         self.failIf(self.parser.has_option("-v"))
  291.         self.failIf(self.parser.has_option("--verbose"))
  292.         self.failIf(self.parser.has_option("-n"))
  293.         self.failIf(self.parser.has_option("--noisy"))
  294.  
  295.         self.assert_(self.parser.has_option("-q"))
  296.         self.assert_(self.parser.has_option("--silent"))
  297.  
  298.     def test_remove_short_opt(self):
  299.         self.parser.remove_option("-n")
  300.         self.assert_removed()
  301.  
  302.     def test_remove_long_opt(self):
  303.         self.parser.remove_option("--verbose")
  304.         self.assert_removed()
  305.  
  306.     def test_remove_nonexistent(self):
  307.         self.assertRaises(self.parser.remove_option, ValueError,
  308.                           "no such option 'foo'", funcargs=['foo'])
  309.  
  310. # -- Test parser.parse_args() ------------------------------------------
  311.  
  312. class TestStandard(BaseTest):
  313.     def setUp(self):
  314.         options = [make_option("-a", type="string"),
  315.                    make_option("-b", "--boo", type="int", dest='boo'),
  316.                    make_option("--foo", action="append")]
  317.  
  318.         self.parser = OptionParser(usage=SUPPRESS_USAGE, option_list=options)
  319.  
  320.     def test_required_value(self):
  321.         self.assertParseFail(["-a"], "-a option requires a value")
  322.  
  323.     def test_invalid_integer(self):
  324.         self.assertParseFail(["-b", "5x"],
  325.                              "option -b: invalid integer value: '5x'")
  326.  
  327.     def test_no_such_option(self):
  328.         self.assertParseFail(["--boo13"], "no such option: --boo13")
  329.  
  330.     def test_long_invalid_integer(self):
  331.         self.assertParseFail(["--boo=x5"],
  332.                              "option --boo: invalid integer value: 'x5'")
  333.  
  334.     def test_empty(self):
  335.         self.assertParseOK([], {'a': None, 'boo': None, 'foo': None}, [])
  336.  
  337.     def test_shortopt_empty_longopt_append(self):
  338.         self.assertParseOK(["-a", "", "--foo=blah", "--foo="],
  339.                            {'a': "", 'boo': None, 'foo': ["blah", ""]},
  340.                            [])
  341.  
  342.     def test_long_option_append(self):
  343.         self.assertParseOK(["--foo", "bar", "--foo", "", "--foo=x"],
  344.                            {'a': None,
  345.                             'boo': None,
  346.                             'foo': ["bar", "", "x"]},
  347.                            [])
  348.  
  349.     def test_option_argument_joined(self):
  350.         self.assertParseOK(["-abc"],
  351.                            {'a': "bc", 'boo': None, 'foo': None},
  352.                            [])
  353.  
  354.     def test_option_argument_split(self):
  355.         self.assertParseOK(["-a", "34"],
  356.                            {'a': "34", 'boo': None, 'foo': None},
  357.                            [])
  358.  
  359.     def test_option_argument_joined_integer(self):
  360.         self.assertParseOK(["-b34"],
  361.                            {'a': None, 'boo': 34, 'foo': None},
  362.                            [])
  363.  
  364.     def test_option_argument_split_negative_integer(self):
  365.         self.assertParseOK(["-b", "-5"],
  366.                            {'a': None, 'boo': -5, 'foo': None},
  367.                            [])
  368.  
  369.     def test_long_option_argument_joined(self):
  370.         self.assertParseOK(["--boo=13"],
  371.                            {'a': None, 'boo': 13, 'foo': None},
  372.                            [])
  373.  
  374.     def test_long_option_argument_split(self):
  375.         self.assertParseOK(["--boo", "111"],
  376.                            {'a': None, 'boo': 111, 'foo': None},
  377.                            [])
  378.  
  379.     def test_long_option_short_option(self):
  380.         self.assertParseOK(["--foo=bar", "-axyz"],
  381.                            {'a': 'xyz', 'boo': None, 'foo': ["bar"]},
  382.                            [])
  383.  
  384.     def test_abbrev_long_option(self):
  385.         self.assertParseOK(["--f=bar", "-axyz"],
  386.                            {'a': 'xyz', 'boo': None, 'foo': ["bar"]},
  387.                            [])
  388.  
  389.     def test_defaults(self):
  390.         (options, args) = self.parser.parse_args([])
  391.         defaults = self.parser.get_default_values()
  392.         self.assertEqual(vars(defaults), vars(options))
  393.  
  394.     def test_ambiguous_option(self):
  395.         self.parser.add_option("--foz", action="store",
  396.                                type="string", dest="foo")
  397.         possibilities = ", ".join({"--foz": None, "--foo": None}.keys())
  398.         self.assertParseFail(["--f=bar"],
  399.                              "ambiguous option: --f (%s?)" % possibilities)
  400.  
  401.  
  402.     def test_short_and_long_option_split(self):
  403.         self.assertParseOK(["-a", "xyz", "--foo", "bar"],
  404.                            {'a': 'xyz', 'boo': None, 'foo': ["bar"]},
  405.                            []),
  406.  
  407.     def test_short_option_split_long_option_append(self):
  408.         self.assertParseOK(["--foo=bar", "-b", "123", "--foo", "baz"],
  409.                            {'a': None, 'boo': 123, 'foo': ["bar", "baz"]},
  410.                            [])
  411.  
  412.     def test_short_option_split_one_positional_arg(self):
  413.         self.assertParseOK(["-a", "foo", "bar"],
  414.                            {'a': "foo", 'boo': None, 'foo': None},
  415.                            ["bar"]),
  416.  
  417.     def test_short_option_consumes_separator(self):
  418.         self.assertParseOK(["-a", "--", "foo", "bar"],
  419.                            {'a': "--", 'boo': None, 'foo': None},
  420.                            ["foo", "bar"]),
  421.  
  422.     def test_short_option_joined_and_separator(self):
  423.         self.assertParseOK(["-ab", "--", "--foo", "bar"],
  424.                            {'a': "b", 'boo': None, 'foo': None},
  425.                            ["--foo", "bar"]),
  426.  
  427.     def test_invalid_option_becomes_positional_arg(self):
  428.         self.assertParseOK(["-ab", "-", "--foo", "bar"],
  429.                            {'a': "b", 'boo': None, 'foo': ["bar"]},
  430.                            ["-"])
  431.  
  432.     def test_no_append_versus_append(self):
  433.         self.assertParseOK(["-b3", "-b", "5", "--foo=bar", "--foo", "baz"],
  434.                            {'a': None, 'boo': 5, 'foo': ["bar", "baz"]},
  435.                            [])
  436.  
  437.     def test_option_consumes_optionlike_string(self):
  438.         self.assertParseOK(["-a", "-b3"],
  439.                            {'a': "-b3", 'boo': None, 'foo': None},
  440.                            [])
  441.  
  442. class TestBool(BaseTest):
  443.     def setUp(self):
  444.         options = [make_option("-v",
  445.                                "--verbose",
  446.                                action="store_true",
  447.                                dest="verbose",
  448.                                default=''),
  449.                    make_option("-q",
  450.                                "--quiet",
  451.                                action="store_false",
  452.                                dest="verbose")]
  453.         self.parser = OptionParser(option_list = options)
  454.  
  455.     def test_bool_default(self):
  456.         self.assertParseOK([],
  457.                            {'verbose': ''},
  458.                            [])
  459.  
  460.     def test_bool_false(self):
  461.         (options, args) = self.assertParseOK(["-q"],
  462.                                              {'verbose': 0},
  463.                                              [])
  464.         if hasattr(__builtins__, 'False'):
  465.             self.failUnless(options.verbose is False)
  466.  
  467.     def test_bool_true(self):
  468.         (options, args) = self.assertParseOK(["-v"],
  469.                                              {'verbose': 1},
  470.                                              [])
  471.         if hasattr(__builtins__, 'True'):
  472.             self.failUnless(options.verbose is True)
  473.  
  474.     def test_bool_flicker_on_and_off(self):
  475.         self.assertParseOK(["-qvq", "-q", "-v"],
  476.                            {'verbose': 1},
  477.                            [])
  478.  
  479. class TestChoice(BaseTest):
  480.     def setUp(self):
  481.         self.parser = OptionParser(usage=SUPPRESS_USAGE)
  482.         self.parser.add_option("-c", action="store", type="choice",
  483.                                dest="choice", choices=["one", "two", "three"])
  484.  
  485.     def test_valid_choice(self):
  486.         self.assertParseOK(["-c", "one", "xyz"],
  487.                            {'choice': 'one'},
  488.                            ["xyz"])
  489.  
  490.     def test_invalid_choice(self):
  491.         self.assertParseFail(["-c", "four", "abc"],
  492.                              "option -c: invalid choice: 'four' "
  493.                              "(choose from 'one', 'two', 'three')")
  494.  
  495.     def test_add_choice_option(self):
  496.         self.parser.add_option("-d", "--default",
  497.                                choices=["four", "five", "six"])
  498.         opt = self.parser.get_option("-d")
  499.         self.assertEqual(opt.type, "choice")
  500.         self.assertEqual(opt.action, "store")
  501.  
  502. class TestCount(BaseTest):
  503.     def setUp(self):
  504.         self.parser = OptionParser(usage=SUPPRESS_USAGE)
  505.         self.v_opt = make_option("-v", action="count", dest="verbose")
  506.         self.parser.add_option(self.v_opt)
  507.         self.parser.add_option("--verbose", type="int", dest="verbose")
  508.         self.parser.add_option("-q", "--quiet",
  509.                                action="store_const", dest="verbose", const=0)
  510.  
  511.     def test_empty(self):
  512.         self.assertParseOK([], {'verbose': None}, [])
  513.  
  514.     def test_count_one(self):
  515.         self.assertParseOK(["-v"], {'verbose': 1}, [])
  516.  
  517.     def test_count_three(self):
  518.         self.assertParseOK(["-vvv"], {'verbose': 3}, [])
  519.  
  520.     def test_count_three_apart(self):
  521.         self.assertParseOK(["-v", "-v", "-v"], {'verbose': 3}, [])
  522.  
  523.     def test_count_override_amount(self):
  524.         self.assertParseOK(["-vvv", "--verbose=2"], {'verbose': 2}, [])
  525.  
  526.     def test_count_override_quiet(self):
  527.         self.assertParseOK(["-vvv", "--verbose=2", "-q"], {'verbose': 0}, [])
  528.  
  529.     def test_count_overriding(self):
  530.         self.assertParseOK(["-vvv", "--verbose=2", "-q", "-v"],
  531.                            {'verbose': 1}, [])
  532.  
  533.     def test_count_interspersed_args(self):
  534.         self.assertParseOK(["--quiet", "3", "-v"],
  535.                            {'verbose': 1},
  536.                            ["3"])
  537.  
  538.     def test_count_no_interspersed_args(self):
  539.         self.parser.disable_interspersed_args()
  540.         self.assertParseOK(["--quiet", "3", "-v"],
  541.                            {'verbose': 0},
  542.                            ["3", "-v"])
  543.  
  544.     def test_count_no_such_option(self):
  545.         self.assertParseFail(["-q3", "-v"], "no such option: -3")
  546.  
  547.     def test_count_option_no_value(self):
  548.         self.assertParseFail(["--quiet=3", "-v"],
  549.                              "--quiet option does not take a value")
  550.  
  551.     def test_count_with_default(self):
  552.         self.parser.set_default('verbose', 0)
  553.         self.assertParseOK([], {'verbose':0}, [])
  554.  
  555.     def test_count_overriding_default(self):
  556.         self.parser.set_default('verbose', 0)
  557.         self.assertParseOK(["-vvv", "--verbose=2", "-q", "-v"],
  558.                            {'verbose': 1}, [])
  559.  
  560. class TestNArgs(BaseTest):
  561.     def setUp(self):
  562.         self.parser = OptionParser(usage=SUPPRESS_USAGE)
  563.         self.parser.add_option("-p", "--point",
  564.                                action="store", nargs=3, type="float", dest="point")
  565.  
  566.     def test_nargs_with_positional_args(self):
  567.         self.assertParseOK(["foo", "-p", "1", "2.5", "-4.3", "xyz"],
  568.                            {'point': (1.0, 2.5, -4.3)},
  569.                            ["foo", "xyz"])
  570.  
  571.     def test_nargs_long_opt(self):
  572.         self.assertParseOK(["--point", "-1", "2.5", "-0", "xyz"],
  573.                            {'point': (-1.0, 2.5, -0.0)},
  574.                            ["xyz"])
  575.  
  576.     def test_nargs_invalid_float_value(self):
  577.         self.assertParseFail(["-p", "1.0", "2x", "3.5"],
  578.                              "option -p: "
  579.                              "invalid floating-point value: '2x'")
  580.  
  581.     def test_nargs_required_values(self):
  582.         self.assertParseFail(["--point", "1.0", "3.5"],
  583.                              "--point option requires 3 values")
  584.  
  585. class TestNArgsAppend(BaseTest):
  586.     def setUp(self):
  587.         self.parser = OptionParser(usage=SUPPRESS_USAGE)
  588.         self.parser.add_option("-p", "--point", action="store", nargs=3,
  589.                                type="float", dest="point")
  590.         self.parser.add_option("-f", "--foo", action="append", nargs=2,
  591.                                type="int", dest="foo")
  592.  
  593.     def test_nargs_append(self):
  594.         self.assertParseOK(["-f", "4", "-3", "blah", "--foo", "1", "666"],
  595.                            {'point': None, 'foo': [(4, -3), (1, 666)]},
  596.                            ["blah"])
  597.  
  598.     def test_nargs_append_required_values(self):
  599.         self.assertParseFail(["-f4,3"],
  600.                              "-f option requires 2 values")
  601.  
  602.     def test_nargs_append_simple(self):
  603.         self.assertParseOK(["--foo=3", "4"],
  604.                            {'point': None, 'foo':[(3, 4)]},
  605.                            [])
  606.  
  607. class TestVersion(BaseTest):
  608.     def test_version(self):
  609.         oldargv = sys.argv[0]
  610.         sys.argv[0] = os.path.join(os.curdir, "foo", "bar")
  611.         self.parser = OptionParser(usage=SUPPRESS_USAGE, version="%prog 0.1")
  612.         self.assertStdoutEquals(["--version"], "bar 0.1\n")
  613.         sys.argv[0] = oldargv
  614.  
  615.     def test_no_version(self):
  616.         self.parser = OptionParser(usage=SUPPRESS_USAGE)
  617.         self.assertParseFail(["--version"],
  618.                              "no such option: --version")
  619.  
  620. # -- Test conflicting default values and parser.parse_args() -----------
  621.  
  622. class TestConflictingDefaults(BaseTest):
  623.     """Conflicting default values: the last one should win."""
  624.     def setUp(self):
  625.         self.parser = OptionParser(option_list=[
  626.             make_option("-v", action="store_true", dest="verbose", default=1)])
  627.  
  628.     def test_conflict_default(self):
  629.         self.parser.add_option("-q", action="store_false", dest="verbose",
  630.                                default=0)
  631.         self.assertParseOK([], {'verbose': 0}, [])
  632.  
  633.     def test_conflict_default_none(self):
  634.         self.parser.add_option("-q", action="store_false", dest="verbose",
  635.                                default=None)
  636.         self.assertParseOK([], {'verbose': None}, [])
  637.  
  638. class TestOptionGroup(BaseTest):
  639.     def setUp(self):
  640.         self.parser = OptionParser(usage=SUPPRESS_USAGE)
  641.  
  642.     def test_option_group_create_instance(self):
  643.         group = OptionGroup(self.parser, "Spam")
  644.         self.parser.add_option_group(group)
  645.         group.add_option("--spam", action="store_true",
  646.                          help="spam spam spam spam")
  647.         self.assertParseOK(["--spam"], {'spam': 1}, [])
  648.  
  649.     def test_add_group_no_group(self):
  650.         self.assertTypeError(self.parser.add_option_group,
  651.                              "not an OptionGroup instance: None", None)
  652.  
  653.     def test_add_group_invalid_arguments(self):
  654.         self.assertTypeError(self.parser.add_option_group,
  655.                              "invalid arguments", None, None)
  656.  
  657.     def test_add_group_wrong_parser(self):
  658.         group = OptionGroup(self.parser, "Spam")
  659.         group.parser = OptionParser()
  660.         self.assertRaises(self.parser.add_option_group, ValueError,
  661.                           "invalid OptionGroup (wrong parser)", funcargs=[group])
  662.  
  663.     def test_group_manipulate(self):
  664.         group = self.parser.add_option_group("Group 2",
  665.                                              description="Some more options")
  666.         group.set_title("Bacon")
  667.         group.add_option("--bacon", type="int")
  668.         self.assert_(self.parser.get_option_group("--bacon"), group)
  669.  
  670. # -- Test extending and parser.parse_args() ----------------------------
  671.  
  672. class TestExtendAddTypes(BaseTest):
  673.     def setUp(self):
  674.         self.parser = OptionParser(usage=SUPPRESS_USAGE,
  675.                                    option_class=self.MyOption)
  676.         self.parser.add_option("-a", None, type="string", dest="a")
  677.         self.parser.add_option("-f", "--file", type="file", dest="file")
  678.  
  679.     class MyOption (Option):
  680.         def check_file (option, opt, value):
  681.             if not os.path.exists(value):
  682.                 raise OptionValueError("%s: file does not exist" % value)
  683.             elif not os.path.isfile(value):
  684.                 raise OptionValueError("%s: not a regular file" % value)
  685.             return value
  686.  
  687.         TYPES = Option.TYPES + ("file",)
  688.         TYPE_CHECKER = copy.copy(Option.TYPE_CHECKER)
  689.         TYPE_CHECKER["file"] = check_file
  690.  
  691.     def test_extend_file(self):
  692.         open(test_support.TESTFN, "w").close()
  693.         self.assertParseOK(["--file", test_support.TESTFN, "-afoo"],
  694.                            {'file': test_support.TESTFN, 'a': 'foo'},
  695.                            [])
  696.  
  697.         os.unlink(test_support.TESTFN)
  698.  
  699.     def test_extend_file_nonexistent(self):
  700.         self.assertParseFail(["--file", test_support.TESTFN, "-afoo"],
  701.                              "%s: file does not exist" %
  702.                              test_support.TESTFN)
  703.  
  704.     def test_file_irregular(self):
  705.         os.mkdir(test_support.TESTFN)
  706.         self.assertParseFail(["--file", test_support.TESTFN, "-afoo"],
  707.                              "%s: not a regular file" %
  708.                              test_support.TESTFN)
  709.         os.rmdir(test_support.TESTFN)
  710.  
  711. class TestExtendAddActions(BaseTest):
  712.     def setUp(self):
  713.         options = [self.MyOption("-a", "--apple", action="extend",
  714.                                  type="string", dest="apple")]
  715.         self.parser = OptionParser(option_list=options)
  716.  
  717.     class MyOption (Option):
  718.         ACTIONS = Option.ACTIONS + ("extend",)
  719.         STORE_ACTIONS = Option.STORE_ACTIONS + ("extend",)
  720.         TYPED_ACTIONS = Option.TYPED_ACTIONS + ("extend",)
  721.  
  722.         def take_action (self, action, dest, opt, value, values, parser):
  723.             if action == "extend":
  724.                 lvalue = value.split(",")
  725.                 values.ensure_value(dest, []).extend(lvalue)
  726.             else:
  727.                 Option.take_action(self, action, dest, opt, parser, value,
  728.                                    values)
  729.  
  730.     def test_extend_add_action(self):
  731.         self.assertParseOK(["-afoo,bar", "--apple=blah"],
  732.                            {'apple': ["foo", "bar", "blah"]},
  733.                            [])
  734.  
  735.     def test_extend_add_action_normal(self):
  736.         self.assertParseOK(["-a", "foo", "-abar", "--apple=x,y"],
  737.                            {'apple': ["foo", "bar", "x", "y"]},
  738.                            [])
  739.  
  740. # -- Test callbacks and parser.parse_args() ----------------------------
  741.  
  742. class TestCallback(BaseTest):
  743.     def setUp(self):
  744.         options = [make_option("-x",
  745.                                None,
  746.                                action="callback",
  747.                                callback=self.process_opt),
  748.                    make_option("-f",
  749.                                "--file",
  750.                                action="callback",
  751.                                callback=self.process_opt,
  752.                                type="string",
  753.                                dest="filename")]
  754.         self.parser = OptionParser(option_list=options)
  755.  
  756.     def process_opt(self, option, opt, value, parser_):
  757.         if opt == "-x":
  758.             self.assertEqual(option._short_opts, ["-x"])
  759.             self.assertEqual(option._long_opts, [])
  760.             self.assert_(parser_ is self.parser)
  761.             self.assert_(value is None)
  762.             self.assertEqual(vars(parser_.values), {'filename': None})
  763.  
  764.             parser_.values.x = 42
  765.         elif opt == "--file":
  766.             self.assertEqual(option._short_opts, ["-f"])
  767.             self.assertEqual(option._long_opts, ["--file"])
  768.             self.assert_(parser_ is self.parser)
  769.             self.assertEqual(value, "foo")
  770.             self.assertEqual(vars(parser_.values), {'filename': None, 'x': 42})
  771.  
  772.             setattr(parser_.values, option.dest, value)
  773.         else:
  774.             self.fail("Unknown option %r in process_opt." % opt)
  775.  
  776.     def test_callback(self):
  777.         self.assertParseOK(["-x", "--file=foo"],
  778.                            {'filename': "foo", 'x': 42},
  779.                            [])
  780.  
  781. class TestCallBackExtraArgs(BaseTest):
  782.     def setUp(self):
  783.         options = [make_option("-p", "--point", action="callback",
  784.                                callback=self.process_tuple,
  785.                                callback_args=(3, int), type="string",
  786.                                dest="points", default=[])]
  787.         self.parser = OptionParser(option_list=options)
  788.  
  789.     def process_tuple (self, option, opt, value, parser_, len, type):
  790.         self.assertEqual(len, 3)
  791.         self.assert_(type is int)
  792.  
  793.         if opt == "-p":
  794.             self.assertEqual(value, "1,2,3")
  795.         elif opt == "--point":
  796.             self.assertEqual(value, "4,5,6")
  797.  
  798.         value = tuple(map(type, value.split(",")))
  799.         getattr(parser_.values, option.dest).append(value)
  800.  
  801.     def test_callback_extra_args(self):
  802.         self.assertParseOK(["-p1,2,3", "--point", "4,5,6"],
  803.                            {'points': [(1,2,3), (4,5,6)]},
  804.                            [])
  805.  
  806. class TestCallBackMeddleArgs(BaseTest):
  807.     def setUp(self):
  808.         options = [make_option(str(x), action="callback",
  809.                                callback=self.process_n, dest='things')
  810.                    for x in range(-1, -6, -1)]
  811.         self.parser = OptionParser(option_list=options)
  812.  
  813.     # Callback that meddles in rargs, largs
  814.     def process_n (self, option, opt, value, parser_):
  815.         # option is -3, -5, etc.
  816.         nargs = int(opt[1:])
  817.         rargs = parser_.rargs
  818.         if len(rargs) < nargs:
  819.             self.fail("Expected %d arguments for %s option." % (nargs, opt))
  820.         dest = parser_.values.ensure_value(option.dest, [])
  821.         dest.append(tuple(rargs[0:nargs]))
  822.         parser_.largs.append(nargs)
  823.         del rargs[0:nargs]
  824.  
  825.     def test_callback_meddle_args(self):
  826.         self.assertParseOK(["-1", "foo", "-3", "bar", "baz", "qux"],
  827.                            {'things': [("foo",), ("bar", "baz", "qux")]},
  828.                            [1, 3])
  829.  
  830.     def test_callback_meddle_args_separator(self):
  831.         self.assertParseOK(["-2", "foo", "--"],
  832.                            {'things': [('foo', '--')]},
  833.                            [2])
  834.  
  835. class TestCallBackManyArgs(BaseTest):
  836.     def setUp(self):
  837.         options = [make_option("-a", "--apple", action="callback", nargs=2,
  838.                                callback=self.process_many, type="string"),
  839.                    make_option("-b", "--bob", action="callback", nargs=3,
  840.                                callback=self.process_many, type="int")]
  841.         self.parser = OptionParser(option_list=options)
  842.  
  843.     def process_many (self, option, opt, value, parser_):
  844.         if opt == "-a":
  845.             self.assertEqual(value, ("foo", "bar"))
  846.         elif opt == "--apple":
  847.             self.assertEqual(value, ("ding", "dong"))
  848.         elif opt == "-b":
  849.             self.assertEqual(value, (1, 2, 3))
  850.         elif opt == "--bob":
  851.             self.assertEqual(value, (-666, 42, 0))
  852.  
  853.     def test_many_args(self):
  854.         self.assertParseOK(["-a", "foo", "bar", "--apple", "ding", "dong",
  855.                             "-b", "1", "2", "3", "--bob", "-666", "42",
  856.                             "0"],
  857.                            {},
  858.                            [])
  859.  
  860. class TestCallBackCheckAbbrev(BaseTest):
  861.     def setUp(self):
  862.         self.parser = OptionParser()
  863.         self.parser.add_option("--foo-bar", action="callback",
  864.                                callback=self.check_abbrev)
  865.  
  866.     def check_abbrev (self, option, opt, value, parser):
  867.         self.assertEqual(opt, "--foo-bar")
  868.  
  869.     def test_abbrev_callback_expansion(self):
  870.         self.assertParseOK(["--foo"], {}, [])
  871.  
  872. class TestCallBackVarArgs(BaseTest):
  873.     def setUp(self):
  874.         options = [make_option("-a", type="int", nargs=2, dest="a"),
  875.                    make_option("-b", action="store_true", dest="b"),
  876.                    make_option("-c", "--callback", action="callback",
  877.                                callback=self.variable_args, dest="c")]
  878.         self.parser = OptionParser(usage=SUPPRESS_USAGE, option_list=options)
  879.  
  880.     def variable_args (self, option, opt, value, parser):
  881.         self.assert_(value is None)
  882.         done = 0
  883.         value = []
  884.         rargs = parser.rargs
  885.         while rargs:
  886.             arg = rargs[0]
  887.             if ((arg[:2] == "--" and len(arg) > 2) or
  888.                 (arg[:1] == "-" and len(arg) > 1 and arg[1] != "-")):
  889.                 break
  890.             else:
  891.                 value.append(arg)
  892.                 del rargs[0]
  893.         setattr(parser.values, option.dest, value)
  894.  
  895.     def test_variable_args(self):
  896.         self.assertParseOK(["-a3", "-5", "--callback", "foo", "bar"],
  897.                            {'a': (3, -5), 'b': None, 'c': ["foo", "bar"]},
  898.                            [])
  899.  
  900.     def test_consume_separator_stop_at_option(self):
  901.         self.assertParseOK(["-c", "37", "--", "xxx", "-b", "hello"],
  902.                            {'a': None,
  903.                             'b': True,
  904.                             'c': ["37", "--", "xxx"]},
  905.                            ["hello"])
  906.  
  907.     def test_positional_arg_and_variable_args(self):
  908.         self.assertParseOK(["hello", "-c", "foo", "-", "bar"],
  909.                            {'a': None,
  910.                             'b': None,
  911.                             'c':["foo", "-", "bar"]},
  912.                            ["hello"])
  913.  
  914.     def test_stop_at_option(self):
  915.         self.assertParseOK(["-c", "foo", "-b"],
  916.                            {'a': None, 'b': True, 'c': ["foo"]},
  917.                            [])
  918.  
  919.     def test_stop_at_invalid_option(self):
  920.         self.assertParseFail(["-c", "3", "-5", "-a"], "no such option: -5")
  921.  
  922.  
  923. # -- Test conflict handling and parser.parse_args() --------------------
  924.  
  925. class ConflictBase(BaseTest):
  926.     def setUp(self):
  927.         options = [make_option("-v", "--verbose", action="count",
  928.                                dest="verbose", help="increment verbosity")]
  929.         self.parser = OptionParser(usage=SUPPRESS_USAGE, option_list=options)
  930.  
  931.     def show_version (self, option, opt, value, parser):
  932.         parser.values.show_version = 1
  933.  
  934. class TestConflict(ConflictBase):
  935.     """Use the default conflict resolution for Optik 1.2: error."""
  936.     def assert_conflict_error(self, func):
  937.         err = self.assertRaises(func, OptionConflictError,
  938.                                 "option -v/--version: conflicting option "
  939.                                 "string(s): -v",
  940.                                 funcargs=["-v", "--version"],
  941.                                 funckwargs={'action':"callback",
  942.                                             'callback':self.show_version,
  943.                                             'help':"show version"})
  944.  
  945.         self.assertEqual(err.msg, "conflicting option string(s): -v")
  946.         self.assertEqual(err.option_id, "-v/--version")
  947.  
  948.     def test_conflict_error(self):
  949.         self.assert_conflict_error(self.parser.add_option)
  950.  
  951.     def test_conflict_error_group(self):
  952.         group = OptionGroup(self.parser, "Group 1")
  953.         self.assert_conflict_error(group.add_option)
  954.  
  955.     def test_no_such_conflict_handler(self):
  956.         self.assertRaises(self.parser.set_conflict_handler, ValueError,
  957.                           "invalid conflict_resolution value 'foo'",
  958.                           funcargs=['foo'])
  959.  
  960.  
  961. class TestConflictIgnore(ConflictBase):
  962.     """Test the old (Optik <= 1.1 behaviour) -- arguably broken, but
  963.     still available so should be tested.
  964.     """
  965.  
  966.     def setUp(self):
  967.         ConflictBase.setUp(self)
  968.         self.parser.set_conflict_handler("ignore")
  969.         self.parser.add_option("-v", "--version", action="callback",
  970.                           callback=self.show_version, help="show version")
  971.  
  972.     def test_conflict_ignore(self):
  973.         v_opt = self.parser.get_option("-v")
  974.         verbose_opt = self.parser.get_option("--verbose")
  975.         version_opt = self.parser.get_option("--version")
  976.  
  977.         self.assert_(v_opt is version_opt)
  978.         self.assert_(v_opt is not verbose_opt)
  979.         self.assertEqual(v_opt._long_opts, ["--version"])
  980.         self.assertEqual(version_opt._short_opts, ["-v"])
  981.         self.assertEqual(verbose_opt._short_opts, ["-v"])
  982.  
  983.     def test_conflict_ignore_help(self):
  984.         self.assertStdoutEquals(["-h"], """\
  985. options:
  986.   -v, --verbose  increment verbosity
  987.   -h, --help     show this help message and exit
  988.   -v, --version  show version
  989. """)
  990.  
  991.     def test_conflict_ignore_short_opt(self):
  992.         self.assertParseOK(["-v"],
  993.                            {'show_version': 1, 'verbose': None},
  994.                            [])
  995.  
  996. class TestConflictResolve(ConflictBase):
  997.     def setUp(self):
  998.         ConflictBase.setUp(self)
  999.         self.parser.set_conflict_handler("resolve")
  1000.         self.parser.add_option("-v", "--version", action="callback",
  1001.                                callback=self.show_version, help="show version")
  1002.  
  1003.     def test_conflict_resolve(self):
  1004.         v_opt = self.parser.get_option("-v")
  1005.         verbose_opt = self.parser.get_option("--verbose")
  1006.         version_opt = self.parser.get_option("--version")
  1007.  
  1008.         self.assert_(v_opt is version_opt)
  1009.         self.assert_(v_opt is not verbose_opt)
  1010.         self.assertEqual(v_opt._long_opts, ["--version"])
  1011.         self.assertEqual(version_opt._short_opts, ["-v"])
  1012.         self.assertEqual(version_opt._long_opts, ["--version"])
  1013.         self.assertEqual(verbose_opt._short_opts, [])
  1014.         self.assertEqual(verbose_opt._long_opts, ["--verbose"])
  1015.  
  1016.     def test_conflict_resolve_help(self):
  1017.         self.assertStdoutEquals(["-h"], """\
  1018. options:
  1019.   --verbose      increment verbosity
  1020.   -h, --help     show this help message and exit
  1021.   -v, --version  show version
  1022. """)
  1023.  
  1024.     def test_conflict_resolve_short_opt(self):
  1025.         self.assertParseOK(["-v"],
  1026.                            {'verbose': None, 'show_version': 1},
  1027.                            [])
  1028.  
  1029.     def test_conflict_resolve_long_opt(self):
  1030.         self.assertParseOK(["--verbose"],
  1031.                            {'verbose': 1},
  1032.                            [])
  1033.  
  1034.     def test_conflict_resolve_long_opts(self):
  1035.         self.assertParseOK(["--verbose", "--version"],
  1036.                            {'verbose': 1, 'show_version': 1},
  1037.                            [])
  1038.  
  1039. class TestConflictOverride(BaseTest):
  1040.     def setUp(self):
  1041.         self.parser = OptionParser(usage=SUPPRESS_USAGE)
  1042.         self.parser.set_conflict_handler("resolve")
  1043.         self.parser.add_option("-n", "--dry-run",
  1044.                                action="store_true", dest="dry_run",
  1045.                                help="don't do anything")
  1046.         self.parser.add_option("--dry-run", "-n",
  1047.                                action="store_const", const=42, dest="dry_run",
  1048.                                help="dry run mode")
  1049.  
  1050.     def test_conflict_override_opts(self):
  1051.         opt = self.parser.get_option("--dry-run")
  1052.         self.assertEqual(opt._short_opts, ["-n"])
  1053.         self.assertEqual(opt._long_opts, ["--dry-run"])
  1054.  
  1055.     def test_conflict_override_help(self):
  1056.         self.assertStdoutEquals(["-h"], """\
  1057. options:
  1058.   -h, --help     show this help message and exit
  1059.   -n, --dry-run  dry run mode
  1060. """)
  1061.  
  1062.     def test_conflict_override_args(self):
  1063.         self.assertParseOK(["-n"],
  1064.                            {'dry_run': 42},
  1065.                            [])
  1066.  
  1067. # -- Other testing. ----------------------------------------------------
  1068.  
  1069. class TestHelp(BaseTest):
  1070.     def setUp(self):
  1071.         options = [
  1072.             make_option("-a", type="string", dest='a',
  1073.                         metavar="APPLE", help="throw APPLEs at basket"),
  1074.             make_option("-b", "--boo", type="int", dest='boo',
  1075.                         metavar="NUM",
  1076.                         help=
  1077.                         "shout \"boo!\" NUM times (in order to frighten away "
  1078.                         "all the evil spirits that cause trouble and mayhem)"),
  1079.             make_option("--foo", action="append", type="string", dest='foo',
  1080.                         help="store FOO in the foo list for later fooing"),
  1081.             ]
  1082.  
  1083.         usage = "%prog [options]"
  1084.         self.parser = OptionParser(usage=usage, option_list=options)
  1085.  
  1086.     def assertHelpEquals(self, expected_output):
  1087.         # This trick is used to make optparse believe bar.py is being executed.
  1088.         oldargv = sys.argv[0]
  1089.         sys.argv[0] = os.path.join(os.curdir, "foo", "bar.py")
  1090.  
  1091.         self.assertStdoutEquals(["-h"], expected_output)
  1092.  
  1093.         sys.argv[0] = oldargv
  1094.  
  1095.     def test_help(self):
  1096.         self.assertHelpEquals("""\
  1097. usage: bar.py [options]
  1098.  
  1099. options:
  1100.   -aAPPLE           throw APPLEs at basket
  1101.   -bNUM, --boo=NUM  shout "boo!" NUM times (in order to frighten away all
  1102.                     the evil spirits that cause trouble and mayhem)
  1103.   --foo=FOO         store FOO in the foo list for later fooing
  1104.   -h, --help        show this help message and exit
  1105. """)
  1106.  
  1107.     def test_help_old_usage(self):
  1108.         self.parser.set_usage("usage: %prog [options]")
  1109.         self.assertHelpEquals("""\
  1110. usage: bar.py [options]
  1111.  
  1112. options:
  1113.   -aAPPLE           throw APPLEs at basket
  1114.   -bNUM, --boo=NUM  shout "boo!" NUM times (in order to frighten away all
  1115.                     the evil spirits that cause trouble and mayhem)
  1116.   --foo=FOO         store FOO in the foo list for later fooing
  1117.   -h, --help        show this help message and exit
  1118. """)
  1119.  
  1120.     def test_help_long_opts_first(self):
  1121.         self.parser.formatter.short_first = 0
  1122.         self.assertHelpEquals("""\
  1123. usage: bar.py [options]
  1124.  
  1125. options:
  1126.   -aAPPLE           throw APPLEs at basket
  1127.   --boo=NUM, -bNUM  shout "boo!" NUM times (in order to frighten away all
  1128.                     the evil spirits that cause trouble and mayhem)
  1129.   --foo=FOO         store FOO in the foo list for later fooing
  1130.   --help, -h        show this help message and exit
  1131. """)
  1132.  
  1133.     def test_help_title_formatter(self):
  1134.         self.parser.formatter = TitledHelpFormatter()
  1135.         self.assertHelpEquals("""\
  1136. Usage
  1137. =====
  1138.   bar.py [options]
  1139.  
  1140. options
  1141. =======
  1142. -aAPPLE           throw APPLEs at basket
  1143. --boo=NUM, -bNUM  shout "boo!" NUM times (in order to frighten away all
  1144.                   the evil spirits that cause trouble and mayhem)
  1145. --foo=FOO         store FOO in the foo list for later fooing
  1146. --help, -h        show this help message and exit
  1147. """)
  1148.  
  1149.     def test_help_description_groups(self):
  1150.         self.parser.set_description(
  1151.             "This is the program description.  This program has "
  1152.             "an option group as well as single options.")
  1153.  
  1154.         group = OptionGroup(
  1155.             self.parser, "Dangerous Options",
  1156.             "Caution: use of these options is at your own risk.  "
  1157.             "It is believed that some of them bite.")
  1158.         group.add_option("-g", action="store_true", help="Group option.")
  1159.         self.parser.add_option_group(group)
  1160.  
  1161.         self.assertHelpEquals("""\
  1162. usage: bar.py [options]
  1163.  
  1164. This is the program description.  This program has an option group as well as
  1165. single options.
  1166. options:
  1167.   -aAPPLE           throw APPLEs at basket
  1168.   -bNUM, --boo=NUM  shout "boo!" NUM times (in order to frighten away all
  1169.                     the evil spirits that cause trouble and mayhem)
  1170.   --foo=FOO         store FOO in the foo list for later fooing
  1171.   -h, --help        show this help message and exit
  1172.  
  1173.   Dangerous Options:
  1174.     Caution: use of these options is at your own risk.  It is believed that
  1175.     some of them bite.
  1176.     -g              Group option.
  1177. """)
  1178.  
  1179. class TestMatchAbbrev(BaseTest):
  1180.     def test_match_abbrev(self):
  1181.         self.assertEqual(_match_abbrev("--f",
  1182.                                        {"--foz": None,
  1183.                                         "--foo": None,
  1184.                                         "--fie": None,
  1185.                                         "--f": None}),
  1186.                          "--f")
  1187.  
  1188.     def test_match_abbrev_error(self):
  1189.         s = "--f"
  1190.         wordmap = {"--foz": None, "--foo": None, "--fie": None}
  1191.         possibilities = ", ".join(wordmap.keys())
  1192.         self.assertRaises(_match_abbrev, BadOptionError,
  1193.                           "ambiguous option: --f (%s?)" % possibilities,
  1194.                           funcargs=[s, wordmap])
  1195.  
  1196. def test_main():
  1197.     mod = sys.modules[__name__]
  1198.     test_support.run_unittest(
  1199.         *[getattr(mod, name) for name in dir(mod) if name.startswith('Test')]
  1200.     )
  1201.  
  1202. if __name__ == '__main__':
  1203.     unittest.main()
  1204.