OILS / frontend / typed_args_test.py View on Github | oilshell.org

158 lines, 116 significant
1#!/usr/bin/env python2
2"""
3typed_args_test.py: Tests for typed_args.py
4"""
5
6import unittest
7
8from _devbuild.gen.syntax_asdl import ArgList, expr
9from _devbuild.gen.value_asdl import value
10from core import error
11from core import test_lib
12from frontend import typed_args # module under test
13
14from typing import cast
15
16
17class 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
157if __name__ == '__main__':
158 unittest.main()