summaryrefslogtreecommitdiffstats
path: root/python/mozbuild/mozbuild/test/configure/test_options.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/mozbuild/mozbuild/test/configure/test_options.py')
-rw-r--r--python/mozbuild/mozbuild/test/configure/test_options.py905
1 files changed, 905 insertions, 0 deletions
diff --git a/python/mozbuild/mozbuild/test/configure/test_options.py b/python/mozbuild/mozbuild/test/configure/test_options.py
new file mode 100644
index 0000000000..59ba616355
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/configure/test_options.py
@@ -0,0 +1,905 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import unittest
+
+from mozunit import main
+
+from mozbuild.configure.options import (
+ CommandLineHelper,
+ ConflictingOptionError,
+ InvalidOptionError,
+ NegativeOptionValue,
+ Option,
+ OptionValue,
+ PositiveOptionValue,
+)
+
+
+class Option(Option):
+ def __init__(self, *args, **kwargs):
+ kwargs["help"] = "Dummy help"
+ super(Option, self).__init__(*args, **kwargs)
+
+
+class TestOption(unittest.TestCase):
+ def test_option(self):
+ option = Option("--option")
+ self.assertEqual(option.prefix, "")
+ self.assertEqual(option.name, "option")
+ self.assertEqual(option.env, None)
+ self.assertFalse(option.default)
+
+ option = Option("--enable-option")
+ self.assertEqual(option.prefix, "enable")
+ self.assertEqual(option.name, "option")
+ self.assertEqual(option.env, None)
+ self.assertFalse(option.default)
+
+ option = Option("--disable-option")
+ self.assertEqual(option.prefix, "disable")
+ self.assertEqual(option.name, "option")
+ self.assertEqual(option.env, None)
+ self.assertTrue(option.default)
+
+ option = Option("--with-option")
+ self.assertEqual(option.prefix, "with")
+ self.assertEqual(option.name, "option")
+ self.assertEqual(option.env, None)
+ self.assertFalse(option.default)
+
+ option = Option("--without-option")
+ self.assertEqual(option.prefix, "without")
+ self.assertEqual(option.name, "option")
+ self.assertEqual(option.env, None)
+ self.assertTrue(option.default)
+
+ option = Option("--without-option-foo", env="MOZ_OPTION")
+ self.assertEqual(option.env, "MOZ_OPTION")
+
+ option = Option(env="MOZ_OPTION")
+ self.assertEqual(option.prefix, "")
+ self.assertEqual(option.name, None)
+ self.assertEqual(option.env, "MOZ_OPTION")
+ self.assertFalse(option.default)
+
+ with self.assertRaises(InvalidOptionError) as e:
+ Option("--option", nargs=0, default=("a",))
+ self.assertEqual(
+ str(e.exception), "The given `default` doesn't satisfy `nargs`"
+ )
+
+ with self.assertRaises(InvalidOptionError) as e:
+ Option("--option", nargs=1, default=())
+ self.assertEqual(
+ str(e.exception), "default must be a bool, a string or a tuple of strings"
+ )
+
+ with self.assertRaises(InvalidOptionError) as e:
+ Option("--option", nargs=1, default=True)
+ self.assertEqual(
+ str(e.exception), "The given `default` doesn't satisfy `nargs`"
+ )
+
+ with self.assertRaises(InvalidOptionError) as e:
+ Option("--option", nargs=1, default=("a", "b"))
+ self.assertEqual(
+ str(e.exception), "The given `default` doesn't satisfy `nargs`"
+ )
+
+ with self.assertRaises(InvalidOptionError) as e:
+ Option("--option", nargs=2, default=())
+ self.assertEqual(
+ str(e.exception), "default must be a bool, a string or a tuple of strings"
+ )
+
+ with self.assertRaises(InvalidOptionError) as e:
+ Option("--option", nargs=2, default=True)
+ self.assertEqual(
+ str(e.exception), "The given `default` doesn't satisfy `nargs`"
+ )
+
+ with self.assertRaises(InvalidOptionError) as e:
+ Option("--option", nargs=2, default=("a",))
+ self.assertEqual(
+ str(e.exception), "The given `default` doesn't satisfy `nargs`"
+ )
+
+ with self.assertRaises(InvalidOptionError) as e:
+ Option("--option", nargs="?", default=("a", "b"))
+ self.assertEqual(
+ str(e.exception), "The given `default` doesn't satisfy `nargs`"
+ )
+
+ with self.assertRaises(InvalidOptionError) as e:
+ Option("--option", nargs="+", default=())
+ self.assertEqual(
+ str(e.exception), "default must be a bool, a string or a tuple of strings"
+ )
+
+ with self.assertRaises(InvalidOptionError) as e:
+ Option("--option", nargs="+", default=True)
+ self.assertEqual(
+ str(e.exception), "The given `default` doesn't satisfy `nargs`"
+ )
+
+ # --disable options with a nargs value that requires at least one
+ # argument need to be given a default.
+ with self.assertRaises(InvalidOptionError) as e:
+ Option("--disable-option", nargs=1)
+ self.assertEqual(
+ str(e.exception), "The given `default` doesn't satisfy `nargs`"
+ )
+
+ with self.assertRaises(InvalidOptionError) as e:
+ Option("--disable-option", nargs="+")
+ self.assertEqual(
+ str(e.exception), "The given `default` doesn't satisfy `nargs`"
+ )
+
+ # Test nargs inference from default value
+ option = Option("--with-foo", default=True)
+ self.assertEqual(option.nargs, 0)
+
+ option = Option("--with-foo", default=False)
+ self.assertEqual(option.nargs, 0)
+
+ option = Option("--with-foo", default="a")
+ self.assertEqual(option.nargs, "?")
+
+ option = Option("--with-foo", default=("a",))
+ self.assertEqual(option.nargs, "?")
+
+ option = Option("--with-foo", default=("a", "b"))
+ self.assertEqual(option.nargs, "*")
+
+ option = Option(env="FOO", default=True)
+ self.assertEqual(option.nargs, 0)
+
+ option = Option(env="FOO", default=False)
+ self.assertEqual(option.nargs, 0)
+
+ option = Option(env="FOO", default="a")
+ self.assertEqual(option.nargs, "?")
+
+ option = Option(env="FOO", default=("a",))
+ self.assertEqual(option.nargs, "?")
+
+ option = Option(env="FOO", default=("a", "b"))
+ self.assertEqual(option.nargs, "*")
+
+ def test_option_option(self):
+ for option in (
+ "--option",
+ "--enable-option",
+ "--disable-option",
+ "--with-option",
+ "--without-option",
+ ):
+ self.assertEqual(Option(option).option, option)
+ self.assertEqual(Option(option, env="FOO").option, option)
+
+ opt = Option(option, default=False)
+ self.assertEqual(
+ opt.option,
+ option.replace("-disable-", "-enable-").replace("-without-", "-with-"),
+ )
+
+ opt = Option(option, default=True)
+ self.assertEqual(
+ opt.option,
+ option.replace("-enable-", "-disable-").replace("-with-", "-without-"),
+ )
+
+ self.assertEqual(Option(env="FOO").option, "FOO")
+
+ def test_option_choices(self):
+ with self.assertRaises(InvalidOptionError) as e:
+ Option("--option", nargs=3, choices=("a", "b"))
+ self.assertEqual(str(e.exception), "Not enough `choices` for `nargs`")
+
+ with self.assertRaises(InvalidOptionError) as e:
+ Option("--without-option", nargs=1, choices=("a", "b"))
+ self.assertEqual(
+ str(e.exception), "A `default` must be given along with `choices`"
+ )
+
+ with self.assertRaises(InvalidOptionError) as e:
+ Option("--without-option", nargs="+", choices=("a", "b"))
+ self.assertEqual(
+ str(e.exception), "A `default` must be given along with `choices`"
+ )
+
+ with self.assertRaises(InvalidOptionError) as e:
+ Option("--without-option", default="c", choices=("a", "b"))
+ self.assertEqual(
+ str(e.exception), "The `default` value must be one of 'a', 'b'"
+ )
+
+ with self.assertRaises(InvalidOptionError) as e:
+ Option(
+ "--without-option",
+ default=(
+ "a",
+ "c",
+ ),
+ choices=("a", "b"),
+ )
+ self.assertEqual(
+ str(e.exception), "The `default` value must be one of 'a', 'b'"
+ )
+
+ with self.assertRaises(InvalidOptionError) as e:
+ Option("--without-option", default=("c",), choices=("a", "b"))
+ self.assertEqual(
+ str(e.exception), "The `default` value must be one of 'a', 'b'"
+ )
+
+ option = Option("--with-option", nargs="+", choices=("a", "b"))
+ with self.assertRaises(InvalidOptionError) as e:
+ option.get_value("--with-option=c")
+ self.assertEqual(str(e.exception), "'c' is not one of 'a', 'b'")
+
+ value = option.get_value("--with-option=b,a")
+ self.assertTrue(value)
+ self.assertEqual(PositiveOptionValue(("b", "a")), value)
+
+ option = Option("--without-option", nargs="*", default="a", choices=("a", "b"))
+ with self.assertRaises(InvalidOptionError) as e:
+ option.get_value("--with-option=c")
+ self.assertEqual(str(e.exception), "'c' is not one of 'a', 'b'")
+
+ value = option.get_value("--with-option=b,a")
+ self.assertTrue(value)
+ self.assertEqual(PositiveOptionValue(("b", "a")), value)
+
+ # Test nargs inference from choices
+ option = Option("--with-option", choices=("a", "b"))
+ self.assertEqual(option.nargs, 1)
+
+ # Test "relative" values
+ option = Option(
+ "--with-option", nargs="*", default=("b", "c"), choices=("a", "b", "c", "d")
+ )
+
+ value = option.get_value("--with-option=+d")
+ self.assertEqual(PositiveOptionValue(("b", "c", "d")), value)
+
+ value = option.get_value("--with-option=-b")
+ self.assertEqual(PositiveOptionValue(("c",)), value)
+
+ value = option.get_value("--with-option=-b,+d")
+ self.assertEqual(PositiveOptionValue(("c", "d")), value)
+
+ # Adding something that is in the default is fine
+ value = option.get_value("--with-option=+b")
+ self.assertEqual(PositiveOptionValue(("b", "c")), value)
+
+ # Removing something that is not in the default is fine, as long as it
+ # is one of the choices
+ value = option.get_value("--with-option=-a")
+ self.assertEqual(PositiveOptionValue(("b", "c")), value)
+
+ with self.assertRaises(InvalidOptionError) as e:
+ option.get_value("--with-option=-e")
+ self.assertEqual(str(e.exception), "'e' is not one of 'a', 'b', 'c', 'd'")
+
+ # Other "not a choice" errors.
+ with self.assertRaises(InvalidOptionError) as e:
+ option.get_value("--with-option=+e")
+ self.assertEqual(str(e.exception), "'e' is not one of 'a', 'b', 'c', 'd'")
+
+ with self.assertRaises(InvalidOptionError) as e:
+ option.get_value("--with-option=e")
+ self.assertEqual(str(e.exception), "'e' is not one of 'a', 'b', 'c', 'd'")
+
+ def test_option_value_compare(self):
+ # OptionValue are tuple and equivalence should compare as tuples.
+ val = PositiveOptionValue(("foo",))
+
+ self.assertEqual(val[0], "foo")
+ self.assertEqual(val, PositiveOptionValue(("foo",)))
+ self.assertNotEqual(val, PositiveOptionValue(("foo", "bar")))
+
+ # Can compare a tuple to an OptionValue.
+ self.assertEqual(val, ("foo",))
+ self.assertNotEqual(val, ("foo", "bar"))
+
+ # Different OptionValue types are never equal.
+ self.assertNotEqual(val, OptionValue(("foo",)))
+
+ # For usability reasons, we raise TypeError when attempting to compare
+ # against a non-tuple.
+ with self.assertRaisesRegexp(TypeError, "cannot compare a"):
+ val == "foo"
+
+ # But we allow empty option values to compare otherwise we can't
+ # easily compare value-less types like PositiveOptionValue and
+ # NegativeOptionValue.
+ empty_positive = PositiveOptionValue()
+ empty_negative = NegativeOptionValue()
+ self.assertEqual(empty_positive, ())
+ self.assertEqual(empty_positive, PositiveOptionValue())
+ self.assertEqual(empty_negative, ())
+ self.assertEqual(empty_negative, NegativeOptionValue())
+ self.assertNotEqual(empty_positive, "foo")
+ self.assertNotEqual(empty_positive, ("foo",))
+ self.assertNotEqual(empty_negative, "foo")
+ self.assertNotEqual(empty_negative, ("foo",))
+
+ def test_option_value_format(self):
+ val = PositiveOptionValue()
+ self.assertEqual("--with-value", val.format("--with-value"))
+ self.assertEqual("--with-value", val.format("--without-value"))
+ self.assertEqual("--enable-value", val.format("--enable-value"))
+ self.assertEqual("--enable-value", val.format("--disable-value"))
+ self.assertEqual("--value", val.format("--value"))
+ self.assertEqual("VALUE=1", val.format("VALUE"))
+
+ val = PositiveOptionValue(("a",))
+ self.assertEqual("--with-value=a", val.format("--with-value"))
+ self.assertEqual("--with-value=a", val.format("--without-value"))
+ self.assertEqual("--enable-value=a", val.format("--enable-value"))
+ self.assertEqual("--enable-value=a", val.format("--disable-value"))
+ self.assertEqual("--value=a", val.format("--value"))
+ self.assertEqual("VALUE=a", val.format("VALUE"))
+
+ val = PositiveOptionValue(("a", "b"))
+ self.assertEqual("--with-value=a,b", val.format("--with-value"))
+ self.assertEqual("--with-value=a,b", val.format("--without-value"))
+ self.assertEqual("--enable-value=a,b", val.format("--enable-value"))
+ self.assertEqual("--enable-value=a,b", val.format("--disable-value"))
+ self.assertEqual("--value=a,b", val.format("--value"))
+ self.assertEqual("VALUE=a,b", val.format("VALUE"))
+
+ val = NegativeOptionValue()
+ self.assertEqual("--without-value", val.format("--with-value"))
+ self.assertEqual("--without-value", val.format("--without-value"))
+ self.assertEqual("--disable-value", val.format("--enable-value"))
+ self.assertEqual("--disable-value", val.format("--disable-value"))
+ self.assertEqual("", val.format("--value"))
+ self.assertEqual("VALUE=", val.format("VALUE"))
+
+ def test_option_value(self, name="option", nargs=0, default=None):
+ disabled = name.startswith(("disable-", "without-"))
+ if disabled:
+ negOptionValue = PositiveOptionValue
+ posOptionValue = NegativeOptionValue
+ else:
+ posOptionValue = PositiveOptionValue
+ negOptionValue = NegativeOptionValue
+ defaultValue = PositiveOptionValue(default) if default else negOptionValue()
+
+ option = Option("--%s" % name, nargs=nargs, default=default)
+
+ if nargs in (0, "?", "*") or disabled:
+ value = option.get_value("--%s" % name, "option")
+ self.assertEqual(value, posOptionValue())
+ self.assertEqual(value.origin, "option")
+ else:
+ with self.assertRaises(InvalidOptionError) as e:
+ option.get_value("--%s" % name)
+ if nargs == 1:
+ self.assertEqual(str(e.exception), "--%s takes 1 value" % name)
+ elif nargs == "+":
+ self.assertEqual(str(e.exception), "--%s takes 1 or more values" % name)
+ else:
+ self.assertEqual(str(e.exception), "--%s takes 2 values" % name)
+
+ value = option.get_value("")
+ self.assertEqual(value, defaultValue)
+ self.assertEqual(value.origin, "default")
+
+ value = option.get_value(None)
+ self.assertEqual(value, defaultValue)
+ self.assertEqual(value.origin, "default")
+
+ with self.assertRaises(AssertionError):
+ value = option.get_value("MOZ_OPTION=", "environment")
+
+ with self.assertRaises(AssertionError):
+ value = option.get_value("MOZ_OPTION=1", "environment")
+
+ with self.assertRaises(AssertionError):
+ value = option.get_value("--foo")
+
+ if nargs in (1, "?", "*", "+") and not disabled:
+ value = option.get_value("--%s=" % name, "option")
+ self.assertEqual(value, PositiveOptionValue(("",)))
+ self.assertEqual(value.origin, "option")
+ else:
+ with self.assertRaises(InvalidOptionError) as e:
+ option.get_value("--%s=" % name)
+ if disabled:
+ self.assertEqual(str(e.exception), "Cannot pass a value to --%s" % name)
+ else:
+ self.assertEqual(
+ str(e.exception), "--%s takes %d values" % (name, nargs)
+ )
+
+ if nargs in (1, "?", "*", "+") and not disabled:
+ value = option.get_value("--%s=foo" % name, "option")
+ self.assertEqual(value, PositiveOptionValue(("foo",)))
+ self.assertEqual(value.origin, "option")
+ else:
+ with self.assertRaises(InvalidOptionError) as e:
+ option.get_value("--%s=foo" % name)
+ if disabled:
+ self.assertEqual(str(e.exception), "Cannot pass a value to --%s" % name)
+ else:
+ self.assertEqual(
+ str(e.exception), "--%s takes %d values" % (name, nargs)
+ )
+
+ if nargs in (2, "*", "+") and not disabled:
+ value = option.get_value("--%s=foo,bar" % name, "option")
+ self.assertEqual(value, PositiveOptionValue(("foo", "bar")))
+ self.assertEqual(value.origin, "option")
+ else:
+ with self.assertRaises(InvalidOptionError) as e:
+ option.get_value("--%s=foo,bar" % name, "option")
+ if disabled:
+ self.assertEqual(str(e.exception), "Cannot pass a value to --%s" % name)
+ elif nargs == "?":
+ self.assertEqual(str(e.exception), "--%s takes 0 or 1 values" % name)
+ else:
+ self.assertEqual(
+ str(e.exception),
+ "--%s takes %d value%s" % (name, nargs, "s" if nargs != 1 else ""),
+ )
+
+ option = Option("--%s" % name, env="MOZ_OPTION", nargs=nargs, default=default)
+ if nargs in (0, "?", "*") or disabled:
+ value = option.get_value("--%s" % name, "option")
+ self.assertEqual(value, posOptionValue())
+ self.assertEqual(value.origin, "option")
+ else:
+ with self.assertRaises(InvalidOptionError) as e:
+ option.get_value("--%s" % name)
+ if disabled:
+ self.assertEqual(str(e.exception), "Cannot pass a value to --%s" % name)
+ elif nargs == "+":
+ self.assertEqual(str(e.exception), "--%s takes 1 or more values" % name)
+ else:
+ self.assertEqual(
+ str(e.exception),
+ "--%s takes %d value%s" % (name, nargs, "s" if nargs != 1 else ""),
+ )
+
+ value = option.get_value("")
+ self.assertEqual(value, defaultValue)
+ self.assertEqual(value.origin, "default")
+
+ value = option.get_value(None)
+ self.assertEqual(value, defaultValue)
+ self.assertEqual(value.origin, "default")
+
+ value = option.get_value("MOZ_OPTION=", "environment")
+ self.assertEqual(value, NegativeOptionValue())
+ self.assertEqual(value.origin, "environment")
+
+ if nargs in (0, "?", "*"):
+ value = option.get_value("MOZ_OPTION=1", "environment")
+ self.assertEqual(value, PositiveOptionValue())
+ self.assertEqual(value.origin, "environment")
+ elif nargs in (1, "+"):
+ value = option.get_value("MOZ_OPTION=1", "environment")
+ self.assertEqual(value, PositiveOptionValue(("1",)))
+ self.assertEqual(value.origin, "environment")
+ else:
+ with self.assertRaises(InvalidOptionError) as e:
+ option.get_value("MOZ_OPTION=1", "environment")
+ self.assertEqual(str(e.exception), "MOZ_OPTION takes 2 values")
+
+ if nargs in (1, "?", "*", "+") and not disabled:
+ value = option.get_value("--%s=" % name, "option")
+ self.assertEqual(value, PositiveOptionValue(("",)))
+ self.assertEqual(value.origin, "option")
+ else:
+ with self.assertRaises(InvalidOptionError) as e:
+ option.get_value("--%s=" % name, "option")
+ if disabled:
+ self.assertEqual(str(e.exception), "Cannot pass a value to --%s" % name)
+ else:
+ self.assertEqual(
+ str(e.exception), "--%s takes %d values" % (name, nargs)
+ )
+
+ with self.assertRaises(AssertionError):
+ value = option.get_value("--foo", "option")
+
+ if nargs in (1, "?", "*", "+"):
+ value = option.get_value("MOZ_OPTION=foo", "environment")
+ self.assertEqual(value, PositiveOptionValue(("foo",)))
+ self.assertEqual(value.origin, "environment")
+ else:
+ with self.assertRaises(InvalidOptionError) as e:
+ option.get_value("MOZ_OPTION=foo", "environment")
+ self.assertEqual(str(e.exception), "MOZ_OPTION takes %d values" % nargs)
+
+ if nargs in (2, "*", "+"):
+ value = option.get_value("MOZ_OPTION=foo,bar", "environment")
+ self.assertEqual(value, PositiveOptionValue(("foo", "bar")))
+ self.assertEqual(value.origin, "environment")
+ else:
+ with self.assertRaises(InvalidOptionError) as e:
+ option.get_value("MOZ_OPTION=foo,bar", "environment")
+ if nargs == "?":
+ self.assertEqual(str(e.exception), "MOZ_OPTION takes 0 or 1 values")
+ else:
+ self.assertEqual(
+ str(e.exception),
+ "MOZ_OPTION takes %d value%s" % (nargs, "s" if nargs != 1 else ""),
+ )
+
+ if disabled:
+ return option
+
+ env_option = Option(env="MOZ_OPTION", nargs=nargs, default=default)
+ with self.assertRaises(AssertionError):
+ env_option.get_value("--%s" % name)
+
+ value = env_option.get_value("")
+ self.assertEqual(value, defaultValue)
+ self.assertEqual(value.origin, "default")
+
+ value = env_option.get_value("MOZ_OPTION=", "environment")
+ self.assertEqual(value, negOptionValue())
+ self.assertEqual(value.origin, "environment")
+
+ if nargs in (0, "?", "*"):
+ value = env_option.get_value("MOZ_OPTION=1", "environment")
+ self.assertEqual(value, posOptionValue())
+ self.assertTrue(value)
+ self.assertEqual(value.origin, "environment")
+ elif nargs in (1, "+"):
+ value = env_option.get_value("MOZ_OPTION=1", "environment")
+ self.assertEqual(value, PositiveOptionValue(("1",)))
+ self.assertEqual(value.origin, "environment")
+ else:
+ with self.assertRaises(InvalidOptionError) as e:
+ env_option.get_value("MOZ_OPTION=1", "environment")
+ self.assertEqual(str(e.exception), "MOZ_OPTION takes 2 values")
+
+ with self.assertRaises(AssertionError) as e:
+ env_option.get_value("--%s" % name)
+
+ with self.assertRaises(AssertionError) as e:
+ env_option.get_value("--foo")
+
+ if nargs in (1, "?", "*", "+"):
+ value = env_option.get_value("MOZ_OPTION=foo", "environment")
+ self.assertEqual(value, PositiveOptionValue(("foo",)))
+ self.assertEqual(value.origin, "environment")
+ else:
+ with self.assertRaises(InvalidOptionError) as e:
+ env_option.get_value("MOZ_OPTION=foo", "environment")
+ self.assertEqual(str(e.exception), "MOZ_OPTION takes %d values" % nargs)
+
+ if nargs in (2, "*", "+"):
+ value = env_option.get_value("MOZ_OPTION=foo,bar", "environment")
+ self.assertEqual(value, PositiveOptionValue(("foo", "bar")))
+ self.assertEqual(value.origin, "environment")
+ else:
+ with self.assertRaises(InvalidOptionError) as e:
+ env_option.get_value("MOZ_OPTION=foo,bar", "environment")
+ if nargs == "?":
+ self.assertEqual(str(e.exception), "MOZ_OPTION takes 0 or 1 values")
+ else:
+ self.assertEqual(
+ str(e.exception),
+ "MOZ_OPTION takes %d value%s" % (nargs, "s" if nargs != 1 else ""),
+ )
+
+ return option
+
+ def test_option_value_enable(
+ self, enable="enable", disable="disable", nargs=0, default=None
+ ):
+ option = self.test_option_value(
+ "%s-option" % enable, nargs=nargs, default=default
+ )
+
+ value = option.get_value("--%s-option" % disable, "option")
+ self.assertEqual(value, NegativeOptionValue())
+ self.assertEqual(value.origin, "option")
+
+ option = self.test_option_value(
+ "%s-option" % disable, nargs=nargs, default=default
+ )
+
+ if nargs in (0, "?", "*"):
+ value = option.get_value("--%s-option" % enable, "option")
+ self.assertEqual(value, PositiveOptionValue())
+ self.assertEqual(value.origin, "option")
+ else:
+ with self.assertRaises(InvalidOptionError) as e:
+ option.get_value("--%s-option" % enable, "option")
+ if nargs == 1:
+ self.assertEqual(str(e.exception), "--%s-option takes 1 value" % enable)
+ elif nargs == "+":
+ self.assertEqual(
+ str(e.exception), "--%s-option takes 1 or more values" % enable
+ )
+ else:
+ self.assertEqual(
+ str(e.exception), "--%s-option takes 2 values" % enable
+ )
+
+ def test_option_value_with(self):
+ self.test_option_value_enable("with", "without")
+
+ def test_option_value_invalid_nargs(self):
+ with self.assertRaises(InvalidOptionError) as e:
+ Option("--option", nargs="foo")
+ self.assertEqual(
+ str(e.exception), "nargs must be a positive integer, '?', '*' or '+'"
+ )
+
+ with self.assertRaises(InvalidOptionError) as e:
+ Option("--option", nargs=-2)
+ self.assertEqual(
+ str(e.exception), "nargs must be a positive integer, '?', '*' or '+'"
+ )
+
+ def test_option_value_nargs_1(self):
+ self.test_option_value(nargs=1)
+ self.test_option_value(nargs=1, default=("a",))
+ self.test_option_value_enable(nargs=1, default=("a",))
+
+ # A default is required
+ with self.assertRaises(InvalidOptionError) as e:
+ Option("--disable-option", nargs=1)
+ self.assertEqual(
+ str(e.exception), "The given `default` doesn't satisfy `nargs`"
+ )
+
+ def test_option_value_nargs_2(self):
+ self.test_option_value(nargs=2)
+ self.test_option_value(nargs=2, default=("a", "b"))
+ self.test_option_value_enable(nargs=2, default=("a", "b"))
+
+ # A default is required
+ with self.assertRaises(InvalidOptionError) as e:
+ Option("--disable-option", nargs=2)
+ self.assertEqual(
+ str(e.exception), "The given `default` doesn't satisfy `nargs`"
+ )
+
+ def test_option_value_nargs_0_or_1(self):
+ self.test_option_value(nargs="?")
+ self.test_option_value(nargs="?", default=("a",))
+ self.test_option_value_enable(nargs="?")
+ self.test_option_value_enable(nargs="?", default=("a",))
+
+ def test_option_value_nargs_0_or_more(self):
+ self.test_option_value(nargs="*")
+ self.test_option_value(nargs="*", default=("a",))
+ self.test_option_value(nargs="*", default=("a", "b"))
+ self.test_option_value_enable(nargs="*")
+ self.test_option_value_enable(nargs="*", default=("a",))
+ self.test_option_value_enable(nargs="*", default=("a", "b"))
+
+ def test_option_value_nargs_1_or_more(self):
+ self.test_option_value(nargs="+")
+ self.test_option_value(nargs="+", default=("a",))
+ self.test_option_value(nargs="+", default=("a", "b"))
+ self.test_option_value_enable(nargs="+", default=("a",))
+ self.test_option_value_enable(nargs="+", default=("a", "b"))
+
+ # A default is required
+ with self.assertRaises(InvalidOptionError) as e:
+ Option("--disable-option", nargs="+")
+ self.assertEqual(
+ str(e.exception), "The given `default` doesn't satisfy `nargs`"
+ )
+
+
+class TestCommandLineHelper(unittest.TestCase):
+ def test_basic(self):
+ helper = CommandLineHelper({}, ["cmd", "--foo", "--bar"])
+
+ self.assertEqual(["--foo", "--bar"], list(helper))
+
+ helper.add("--enable-qux")
+
+ self.assertEqual(["--foo", "--bar", "--enable-qux"], list(helper))
+
+ value, option = helper.handle(Option("--bar"))
+ self.assertEqual(["--foo", "--enable-qux"], list(helper))
+ self.assertEqual(PositiveOptionValue(), value)
+ self.assertEqual("--bar", option)
+
+ value, option = helper.handle(Option("--baz"))
+ self.assertEqual(["--foo", "--enable-qux"], list(helper))
+ self.assertEqual(NegativeOptionValue(), value)
+ self.assertEqual(None, option)
+
+ with self.assertRaises(AssertionError):
+ CommandLineHelper({}, ["--foo", "--bar"])
+
+ def test_precedence(self):
+ foo = Option("--with-foo", nargs="*")
+ helper = CommandLineHelper({}, ["cmd", "--with-foo=a,b"])
+ value, option = helper.handle(foo)
+ self.assertEqual(PositiveOptionValue(("a", "b")), value)
+ self.assertEqual("command-line", value.origin)
+ self.assertEqual("--with-foo=a,b", option)
+
+ helper = CommandLineHelper({}, ["cmd", "--with-foo=a,b", "--without-foo"])
+ value, option = helper.handle(foo)
+ self.assertEqual(NegativeOptionValue(), value)
+ self.assertEqual("command-line", value.origin)
+ self.assertEqual("--without-foo", option)
+
+ helper = CommandLineHelper({}, ["cmd", "--without-foo", "--with-foo=a,b"])
+ value, option = helper.handle(foo)
+ self.assertEqual(PositiveOptionValue(("a", "b")), value)
+ self.assertEqual("command-line", value.origin)
+ self.assertEqual("--with-foo=a,b", option)
+
+ foo = Option("--with-foo", env="FOO", nargs="*")
+ helper = CommandLineHelper({"FOO": ""}, ["cmd", "--with-foo=a,b"])
+ value, option = helper.handle(foo)
+ self.assertEqual(PositiveOptionValue(("a", "b")), value)
+ self.assertEqual("command-line", value.origin)
+ self.assertEqual("--with-foo=a,b", option)
+
+ helper = CommandLineHelper({"FOO": "a,b"}, ["cmd", "--without-foo"])
+ value, option = helper.handle(foo)
+ self.assertEqual(NegativeOptionValue(), value)
+ self.assertEqual("command-line", value.origin)
+ self.assertEqual("--without-foo", option)
+
+ helper = CommandLineHelper({"FOO": ""}, ["cmd", "--with-bar=a,b"])
+ value, option = helper.handle(foo)
+ self.assertEqual(NegativeOptionValue(), value)
+ self.assertEqual("environment", value.origin)
+ self.assertEqual("FOO=", option)
+
+ helper = CommandLineHelper({"FOO": "a,b"}, ["cmd", "--without-bar"])
+ value, option = helper.handle(foo)
+ self.assertEqual(PositiveOptionValue(("a", "b")), value)
+ self.assertEqual("environment", value.origin)
+ self.assertEqual("FOO=a,b", option)
+
+ helper = CommandLineHelper({}, ["cmd", "--with-foo=a,b", "FOO="])
+ value, option = helper.handle(foo)
+ self.assertEqual(NegativeOptionValue(), value)
+ self.assertEqual("command-line", value.origin)
+ self.assertEqual("FOO=", option)
+
+ helper = CommandLineHelper({}, ["cmd", "--without-foo", "FOO=a,b"])
+ value, option = helper.handle(foo)
+ self.assertEqual(PositiveOptionValue(("a", "b")), value)
+ self.assertEqual("command-line", value.origin)
+ self.assertEqual("FOO=a,b", option)
+
+ helper = CommandLineHelper({}, ["cmd", "FOO=", "--with-foo=a,b"])
+ value, option = helper.handle(foo)
+ self.assertEqual(PositiveOptionValue(("a", "b")), value)
+ self.assertEqual("command-line", value.origin)
+ self.assertEqual("--with-foo=a,b", option)
+
+ helper = CommandLineHelper({}, ["cmd", "FOO=a,b", "--without-foo"])
+ value, option = helper.handle(foo)
+ self.assertEqual(NegativeOptionValue(), value)
+ self.assertEqual("command-line", value.origin)
+ self.assertEqual("--without-foo", option)
+
+ def test_extra_args(self):
+ foo = Option("--with-foo", env="FOO", nargs="*")
+ helper = CommandLineHelper({}, ["cmd"])
+ helper.add("FOO=a,b,c", "other-origin")
+ value, option = helper.handle(foo)
+ self.assertEqual(PositiveOptionValue(("a", "b", "c")), value)
+ self.assertEqual("other-origin", value.origin)
+ self.assertEqual("FOO=a,b,c", option)
+
+ helper = CommandLineHelper({}, ["cmd"])
+ helper.add("FOO=a,b,c", "other-origin")
+ helper.add("--with-foo=a,b,c", "other-origin")
+ value, option = helper.handle(foo)
+ self.assertEqual(PositiveOptionValue(("a", "b", "c")), value)
+ self.assertEqual("other-origin", value.origin)
+ self.assertEqual("--with-foo=a,b,c", option)
+
+ # Adding conflicting options is not allowed.
+ helper = CommandLineHelper({}, ["cmd"])
+ helper.add("FOO=a,b,c", "other-origin")
+ with self.assertRaises(ConflictingOptionError) as cm:
+ helper.add("FOO=", "other-origin")
+ self.assertEqual("FOO=", cm.exception.arg)
+ self.assertEqual("other-origin", cm.exception.origin)
+ self.assertEqual("FOO=a,b,c", cm.exception.old_arg)
+ self.assertEqual("other-origin", cm.exception.old_origin)
+ with self.assertRaises(ConflictingOptionError) as cm:
+ helper.add("FOO=a,b", "other-origin")
+ self.assertEqual("FOO=a,b", cm.exception.arg)
+ self.assertEqual("other-origin", cm.exception.origin)
+ self.assertEqual("FOO=a,b,c", cm.exception.old_arg)
+ self.assertEqual("other-origin", cm.exception.old_origin)
+ # But adding the same is allowed.
+ helper.add("FOO=a,b,c", "other-origin")
+ value, option = helper.handle(foo)
+ self.assertEqual(PositiveOptionValue(("a", "b", "c")), value)
+ self.assertEqual("other-origin", value.origin)
+ self.assertEqual("FOO=a,b,c", option)
+
+ # The same rule as above applies when using the option form vs. the
+ # variable form. But we can't detect it when .add is called.
+ helper = CommandLineHelper({}, ["cmd"])
+ helper.add("FOO=a,b,c", "other-origin")
+ helper.add("--without-foo", "other-origin")
+ with self.assertRaises(ConflictingOptionError) as cm:
+ helper.handle(foo)
+ self.assertEqual("--without-foo", cm.exception.arg)
+ self.assertEqual("other-origin", cm.exception.origin)
+ self.assertEqual("FOO=a,b,c", cm.exception.old_arg)
+ self.assertEqual("other-origin", cm.exception.old_origin)
+ helper = CommandLineHelper({}, ["cmd"])
+ helper.add("FOO=a,b,c", "other-origin")
+ helper.add("--with-foo=a,b", "other-origin")
+ with self.assertRaises(ConflictingOptionError) as cm:
+ helper.handle(foo)
+ self.assertEqual("--with-foo=a,b", cm.exception.arg)
+ self.assertEqual("other-origin", cm.exception.origin)
+ self.assertEqual("FOO=a,b,c", cm.exception.old_arg)
+ self.assertEqual("other-origin", cm.exception.old_origin)
+ helper = CommandLineHelper({}, ["cmd"])
+ helper.add("FOO=a,b,c", "other-origin")
+ helper.add("--with-foo=a,b,c", "other-origin")
+ value, option = helper.handle(foo)
+ self.assertEqual(PositiveOptionValue(("a", "b", "c")), value)
+ self.assertEqual("other-origin", value.origin)
+ self.assertEqual("--with-foo=a,b,c", option)
+
+ # Conflicts are also not allowed against what is in the
+ # environment/on the command line.
+ helper = CommandLineHelper({}, ["cmd", "--with-foo=a,b"])
+ helper.add("FOO=a,b,c", "other-origin")
+ with self.assertRaises(ConflictingOptionError) as cm:
+ helper.handle(foo)
+ self.assertEqual("FOO=a,b,c", cm.exception.arg)
+ self.assertEqual("other-origin", cm.exception.origin)
+ self.assertEqual("--with-foo=a,b", cm.exception.old_arg)
+ self.assertEqual("command-line", cm.exception.old_origin)
+
+ helper = CommandLineHelper({}, ["cmd", "--with-foo=a,b"])
+ helper.add("--without-foo", "other-origin")
+ with self.assertRaises(ConflictingOptionError) as cm:
+ helper.handle(foo)
+ self.assertEqual("--without-foo", cm.exception.arg)
+ self.assertEqual("other-origin", cm.exception.origin)
+ self.assertEqual("--with-foo=a,b", cm.exception.old_arg)
+ self.assertEqual("command-line", cm.exception.old_origin)
+
+ def test_possible_origins(self):
+ with self.assertRaises(InvalidOptionError):
+ Option("--foo", possible_origins="command-line")
+
+ helper = CommandLineHelper({"BAZ": "1"}, ["cmd", "--foo", "--bar"])
+ foo = Option("--foo", possible_origins=("command-line",))
+ value, option = helper.handle(foo)
+ self.assertEqual(PositiveOptionValue(), value)
+ self.assertEqual("command-line", value.origin)
+ self.assertEqual("--foo", option)
+
+ bar = Option("--bar", possible_origins=("mozconfig",))
+ with self.assertRaisesRegexp(
+ InvalidOptionError,
+ "--bar can not be set by command-line. Values are accepted from: mozconfig",
+ ):
+ helper.handle(bar)
+
+ baz = Option(env="BAZ", possible_origins=("implied",))
+ with self.assertRaisesRegexp(
+ InvalidOptionError,
+ "BAZ=1 can not be set by environment. Values are accepted from: implied",
+ ):
+ helper.handle(baz)
+
+
+if __name__ == "__main__":
+ main()