aboutsummaryrefslogtreecommitdiff
path: root/run_unittests.py
diff options
context:
space:
mode:
authorDylan Baker <dylan@pnwbakers.com>2021-01-27 11:06:39 -0800
committerXavier Claessens <xclaesse@gmail.com>2021-02-06 13:11:25 -0500
commit2650977c38b3f9b7de6e1f1984151197f0cffc4a (patch)
tree776115ab8ceedb4f826723accf911d653785b6d5 /run_unittests.py
parent978eeddab8ab126a340b2423ddf4146d0ca9ccf8 (diff)
downloadmeson-2650977c38b3f9b7de6e1f1984151197f0cffc4a.zip
meson-2650977c38b3f9b7de6e1f1984151197f0cffc4a.tar.gz
meson-2650977c38b3f9b7de6e1f1984151197f0cffc4a.tar.bz2
interpreterbase: Add support for optional arguments to typed_pos_args
This allows representing functions like assert(), which take optional positional arguments, which are not variadic. More importnatly you can represent a function like (* means optional, but possitional): ```txt func(str, *int, *str) ``` typed_pos_args will check that all of your types are correct, and if not provide None, which allow simplifying a number of implementation details
Diffstat (limited to 'run_unittests.py')
-rwxr-xr-xrun_unittests.py60
1 files changed, 60 insertions, 0 deletions
diff --git a/run_unittests.py b/run_unittests.py
index 8dfb394..b2e7338 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -1422,6 +1422,66 @@ class InternalTests(unittest.TestCase):
_(None, mock.Mock(), ['string'], None)
self.assertEqual(str(cm.exception), 'foo takes between 2 and 3 arguments, but got 1.')
+ def test_typed_pos_args_variadic_and_optional(self) -> None:
+ @typed_pos_args('foo', str, optargs=[str], varargs=str, min_varargs=0)
+ def _(obj, node, args: T.Tuple[str, T.List[str]], kwargs) -> None:
+ self.assertTrue(False) # should not be reachable
+
+ with self.assertRaises(AssertionError) as cm:
+ _(None, mock.Mock(), ['string'], None)
+ self.assertEqual(
+ str(cm.exception),
+ 'varargs and optargs not supported together as this would be ambiguous')
+
+ def test_typed_pos_args_min_optargs_not_met(self) -> None:
+ @typed_pos_args('foo', str, str, optargs=[str])
+ def _(obj, node, args: T.Tuple[str, T.Optional[str]], kwargs) -> None:
+ self.assertTrue(False) # should not be reachable
+
+ with self.assertRaises(InvalidArguments) as cm:
+ _(None, mock.Mock(), ['string'], None)
+ self.assertEqual(str(cm.exception), 'foo takes at least 2 arguments, but got 1.')
+
+ def test_typed_pos_args_min_optargs_max_exceeded(self) -> None:
+ @typed_pos_args('foo', str, optargs=[str])
+ def _(obj, node, args: T.Tuple[str, T.Optional[str]], kwargs) -> None:
+ self.assertTrue(False) # should not be reachable
+
+ with self.assertRaises(InvalidArguments) as cm:
+ _(None, mock.Mock(), ['string', '1', '2'], None)
+ self.assertEqual(str(cm.exception), 'foo takes at most 2 arguments, but got 3.')
+
+ def test_typed_pos_args_optargs_not_given(self) -> None:
+ @typed_pos_args('foo', str, optargs=[str])
+ def _(obj, node, args: T.Tuple[str, T.Optional[str]], kwargs) -> None:
+ self.assertEqual(len(args), 2)
+ self.assertIsInstance(args[0], str)
+ self.assertEqual(args[0], 'string')
+ self.assertIsNone(args[1])
+
+ _(None, mock.Mock(), ['string'], None)
+
+ def test_typed_pos_args_optargs_some_given(self) -> None:
+ @typed_pos_args('foo', str, optargs=[str, int])
+ def _(obj, node, args: T.Tuple[str, T.Optional[str], T.Optional[int]], kwargs) -> None:
+ self.assertEqual(len(args), 3)
+ self.assertIsInstance(args[0], str)
+ self.assertEqual(args[0], 'string')
+ self.assertIsInstance(args[1], str)
+ self.assertEqual(args[1], '1')
+ self.assertIsNone(args[2])
+
+ _(None, mock.Mock(), ['string', '1'], None)
+
+ def test_typed_pos_args_optargs_all_given(self) -> None:
+ @typed_pos_args('foo', str, optargs=[str])
+ def _(obj, node, args: T.Tuple[str, T.Optional[str]], kwargs) -> None:
+ self.assertEqual(len(args), 2)
+ self.assertIsInstance(args[0], str)
+ self.assertEqual(args[0], 'string')
+ self.assertIsInstance(args[1], str)
+
+ _(None, mock.Mock(), ['string', '1'], None)
@unittest.skipIf(is_tarball(), 'Skipping because this is a tarball release')
class DataTests(unittest.TestCase):