| 1 | #!/usr/bin/env python2
|
| 2 | """
|
| 3 | typed_args_test.py: Tests for typed_args.py
|
| 4 | """
|
| 5 |
|
| 6 | import unittest
|
| 7 |
|
| 8 | from _devbuild.gen.syntax_asdl import ArgList, expr
|
| 9 | from _devbuild.gen.value_asdl import value
|
| 10 | from core import error
|
| 11 | from core import test_lib
|
| 12 | from frontend import typed_args # module under test
|
| 13 |
|
| 14 | from typing import cast
|
| 15 |
|
| 16 |
|
| 17 | class TypedArgsTest(unittest.TestCase):
|
| 18 |
|
| 19 | def testReaderPosArgs(self):
|
| 20 | arena = test_lib.MakeArena('')
|
| 21 | line_id = arena.AddLine('foo(a, b, c, d, e, f, g)', 1)
|
| 22 | ltok = arena.NewToken(-1, 3, 1, line_id)
|
| 23 | rtok = arena.NewToken(-1, 4, 1, line_id)
|
| 24 | pos_exprs = [
|
| 25 | expr.Const(arena.NewToken(-1, 4 + 2 * i, 1, line_id), value.Null)
|
| 26 | for i in range(7)
|
| 27 | ]
|
| 28 | arg_list = ArgList(ltok, pos_exprs, None, [], None, None, rtok)
|
| 29 |
|
| 30 | # Not enough args...
|
| 31 | reader = typed_args.Reader([], {}, None, arg_list, False)
|
| 32 | self.assertRaises(error.TypeErrVerbose, reader.PosStr)
|
| 33 |
|
| 34 | pos_args = [
|
| 35 | value.Int(0xc0ffee),
|
| 36 | value.Str('foo'),
|
| 37 | value.List([value.Int(1), value.Int(2),
|
| 38 | value.Int(3)]),
|
| 39 | value.Dict({
|
| 40 | 'a': value.Int(0xaa),
|
| 41 | 'b': value.Int(0xbb)
|
| 42 | }),
|
| 43 | value.Float(3.14),
|
| 44 | value.Int(0xdead),
|
| 45 | value.Int(0xbeef),
|
| 46 | value.Str('bar'),
|
| 47 | ]
|
| 48 | reader = typed_args.Reader(list(pos_args), {}, None, arg_list, False)
|
| 49 |
|
| 50 | # Haven't all the args
|
| 51 | with self.assertRaises(error.TypeErrVerbose) as cm:
|
| 52 | _ = reader.PosInt()
|
| 53 | _ = reader.PosStr()
|
| 54 | reader.Done()
|
| 55 |
|
| 56 | # Check that the error points to the first unconsummed argument
|
| 57 | e = cm.exception
|
| 58 | self.assertEqual(pos_exprs[2].c, e.location)
|
| 59 |
|
| 60 | # Arg is wrong type...
|
| 61 | with self.assertRaises(error.TypeErrVerbose) as cm:
|
| 62 | reader.PosStr()
|
| 63 |
|
| 64 | # Check that the error points to the right token
|
| 65 | e = cm.exception
|
| 66 | self.assertEqual(pos_exprs[3].c, e.location)
|
| 67 |
|
| 68 | # Normal operation from here on
|
| 69 | reader = typed_args.Reader(pos_args, {}, None, arg_list, False)
|
| 70 | arg = reader.PosInt()
|
| 71 | self.assertEqual(0xc0ffee, arg)
|
| 72 |
|
| 73 | arg = reader.PosStr()
|
| 74 | self.assertEqual('foo', arg)
|
| 75 |
|
| 76 | arg = reader.PosList()
|
| 77 | self.assertEqual(1, cast(value.Int, arg[0]).i)
|
| 78 | self.assertEqual(2, cast(value.Int, arg[1]).i)
|
| 79 | self.assertEqual(3, cast(value.Int, arg[2]).i)
|
| 80 |
|
| 81 | arg = reader.PosDict()
|
| 82 | self.assertIn('a', arg)
|
| 83 | self.assertEqual(0xaa, arg['a'].i)
|
| 84 | self.assertIn('b', arg)
|
| 85 | self.assertEqual(0xbb, arg['b'].i)
|
| 86 |
|
| 87 | arg = reader.PosFloat()
|
| 88 | self.assertEqual(3.14, arg)
|
| 89 |
|
| 90 | rest = reader.RestPos()
|
| 91 | self.assertEqual(3, len(rest))
|
| 92 | self.assertEqual(0xdead, rest[0].i)
|
| 93 | self.assertEqual(0xbeef, rest[1].i)
|
| 94 | self.assertEqual('bar', rest[2].s)
|
| 95 |
|
| 96 | reader.Done()
|
| 97 |
|
| 98 | def testReaderKwargs(self):
|
| 99 | # Dummy call. Not testing error messages here.
|
| 100 | arena = test_lib.MakeArena('')
|
| 101 | line_id = arena.AddLine('foo(;)', 1)
|
| 102 | ltok = arena.NewToken(-1, 0, 3, line_id)
|
| 103 | rtok = arena.NewToken(-1, 0, 4, line_id)
|
| 104 | semi_tok = arena.NewToken(-1, 0, 5, line_id)
|
| 105 | arg_list = ArgList(ltok, [], semi_tok, [], None, None, rtok)
|
| 106 |
|
| 107 | kwargs = {
|
| 108 | 'hot': value.Int(0xc0ffee),
|
| 109 | 'name': value.Str('foo'),
|
| 110 | 'numbers': value.List([value.Int(1),
|
| 111 | value.Int(2),
|
| 112 | value.Int(3)]),
|
| 113 | 'blah': value.Dict({
|
| 114 | 'a': value.Int(0xaa),
|
| 115 | 'b': value.Int(0xbb)
|
| 116 | }),
|
| 117 | 'pi': value.Float(3.14),
|
| 118 | 'a': value.Int(0xdead),
|
| 119 | 'b': value.Int(0xbeef),
|
| 120 | 'c': value.Str('bar'),
|
| 121 | }
|
| 122 | reader = typed_args.Reader([], kwargs, None, arg_list, False)
|
| 123 |
|
| 124 | # Haven't processed any args yet...
|
| 125 | self.assertRaises(error.TypeErrVerbose, reader.Done)
|
| 126 |
|
| 127 | arg = reader.NamedInt('hot', -1)
|
| 128 | self.assertEqual(0xc0ffee, arg)
|
| 129 |
|
| 130 | arg = reader.NamedStr('name', '')
|
| 131 | self.assertEqual('foo', arg)
|
| 132 |
|
| 133 | arg = reader.NamedList('numbers', [])
|
| 134 | self.assertEqual(1, cast(value.Int, arg[0]).i)
|
| 135 | self.assertEqual(2, cast(value.Int, arg[1]).i)
|
| 136 | self.assertEqual(3, cast(value.Int, arg[2]).i)
|
| 137 |
|
| 138 | arg = reader.NamedDict('blah', {})
|
| 139 | self.assertIn('a', arg)
|
| 140 | self.assertEqual(0xaa, arg['a'].i)
|
| 141 | self.assertIn('b', arg)
|
| 142 | self.assertEqual(0xbb, arg['b'].i)
|
| 143 |
|
| 144 | arg = reader.NamedFloat('pi', -1.0)
|
| 145 | self.assertEqual(3.14, arg)
|
| 146 |
|
| 147 | rest = reader.RestNamed()
|
| 148 | self.assertEqual(3, len(rest))
|
| 149 | self.assertIn('a', rest)
|
| 150 | self.assertEqual(0xdead, rest['a'].i)
|
| 151 | self.assertIn('b', rest)
|
| 152 | self.assertEqual(0xbeef, rest['b'].i)
|
| 153 | self.assertIn('c', rest)
|
| 154 | self.assertEqual('bar', rest['c'].s)
|
| 155 |
|
| 156 |
|
| 157 | if __name__ == '__main__':
|
| 158 | unittest.main()
|