def test_clone_arglist(self):
        arglist2 = ArgList(Arg(default=11),
                           Arg(default=22),
                           foo=Arg(default=33),
                           bar=Arg(default=44))
        arglist = arglist2.clone()
        self.assertTrue(not (arglist is arglist2))

        self.assertEqual(len(arglist), 4)

        arg = arglist.args[0]
        self.assertEqual(arg.index, 1)
        self.assertEqual(arg.default, 11)

        arg = arglist.args[1]
        self.assertEqual(arg.index, 2)
        self.assertEqual(arg.default, 22)

        arg1 = arglist.args[2]
        arg2 = arglist.args[3]
        if arg1.name == 'bar':
            (arg1, arg2) = (arg2, arg1)
        self.assertEqual(arg1.default, 33)
        self.assertEqual(arg1.name, 'foo')
        self.assertEqual(arg2.default, 44)
        self.assertEqual(arg2.name, 'bar')
    def test_merge_common(self):
        arglist1 = ArgList(
            bar=Arg(description='Bar'),
            foo=Arg(description='Foo'),
            baz=Arg(description='Baz', default=1.5),
        )
        argspec = inspect.getfullargspec(self.argspec_testfunc)
        arglist2 = ArgList.from_argspec(*argspec)

        arglist = ArgList.merge(arglist1, arglist2)
        self.assertEqual(len(arglist), 3)

        arg = arglist.args[0]
        self.assertEqual(arg.description, 'Baz')
        self.assertEqual(arg.default, 1.5)
        self.assertTrue(arg.optional is False)

        arg = arglist.args[1]
        self.assertEqual(arg.description, 'Foo')
        self.assertEqual(arg.default, 3)
        self.assertTrue(arg.optional is True)

        arg = arglist.args[2]
        self.assertEqual(arg.description, 'Bar')
        self.assertEqual(arg.default, 'two')
        self.assertTrue(arg.optional is True)
    def test_init_arglist(self):
        arglist = ArgList(Arg(default=11),
                          Arg(default=22),
                          foo=Arg(default=33),
                          bar=Arg(default=44))
        self.assertEqual(len(arglist), 4)
        self.assertEqual(arglist.max_accepted(), 4)
        self.assertEqual(arglist.min_accepted(), 0)

        arg = arglist.args[0]
        self.assertEqual(arg.index, 1)
        self.assertEqual(arg.default, 11)

        arg = arglist.args[1]
        self.assertEqual(arg.index, 2)
        self.assertEqual(arg.default, 22)

        arg1 = arglist.args[2]
        arg2 = arglist.args[3]
        if arg1.name == 'bar':
            (arg1, arg2) = (arg2, arg1)
        self.assertEqual(arg1.default, 33)
        self.assertEqual(arg1.name, 'foo')
        self.assertEqual(arg2.default, 44)
        self.assertEqual(arg2.name, 'bar')
    def test_from_argspec(self):
        argspec = inspect.getfullargspec(self.argspec_testfunc)
        arglist = ArgList.from_argspec(*argspec)
        self.assertEqual(len(arglist), 3)
        self.assertEqual(arglist.max_accepted(), 3)
        self.assertEqual(arglist.min_accepted(), 1)

        arg = arglist.args[0]
        self.assertTrue(arglist.get_index(1) is arg)
        self.assertTrue(arglist.get_name('baz') is arg)
        self.assertEqual(arg.index, 1)
        self.assertEqual(arg.name, 'baz')
        self.assertEqual(arg.hasdefault, False)
        self.assertTrue(arg.optional is False)

        arg = arglist.args[1]
        self.assertTrue(arglist.get_index(2) is arg)
        self.assertTrue(arglist.get_name('foo') is arg)
        self.assertEqual(arg.index, 2)
        self.assertEqual(arg.name, 'foo')
        self.assertTrue(arg.hasdefault is True)
        self.assertEqual(arg.default, 3)
        self.assertEqual(arg.type, int)
        self.assertTrue(arg.optional is True)

        arg = arglist.args[2]
        self.assertTrue(arglist.get_index(3) is arg)
        self.assertTrue(arglist.get_name('bar') is arg)
        self.assertEqual(arg.index, 3)
        self.assertEqual(arg.name, 'bar')
        self.assertTrue(arg.hasdefault is True)
        self.assertEqual(arg.default, 'two')
        self.assertEqual(arg.type, str)
        self.assertTrue(arg.optional is True)
    def test_sort_arglist(self):
        arglist = ArgList(
            foo=Arg(index=3, default=33),
            bar=Arg(index=2, default=22),
            baz=Arg(index=1, default=11),
        )

        arg = arglist.args[0]
        self.assertEqual(arg.index, 1)
        self.assertEqual(arg.name, 'baz')
        self.assertEqual(arg.default, 11)

        arg = arglist.args[1]
        self.assertEqual(arg.index, 2)
        self.assertEqual(arg.name, 'bar')
        self.assertEqual(arg.default, 22)

        arg = arglist.args[2]
        self.assertEqual(arg.index, 3)
        self.assertEqual(arg.name, 'foo')
        self.assertEqual(arg.default, 33)

        arglist = ArgList(
            Arg(index=1),
            Arg(index=2),
            baz=Arg(name='baz'),
        )
        self.assertEqual(len(arglist), 3)

        self.assertRaises(ArgDefError,
                          ArgList,
                          foo=Arg(index=1, default=11),
                          baz=Arg(index=1, default=22))

        self.assertRaises(ArgDefError, ArgList, Arg(name='foo', default=11),
                          Arg(name='foo', default=22))
    def test_arglist_serialize(self):
        ls = [
            ArgList(),
            ArgList(Arg('x'), Arg('y')),
            ArgList(Arg(name='x', type=str), ArgExtra(TupleOf(int, int))),
            ArgList(Arg(name='foo'), x=Arg(default=3.1), y=Arg(type=ListOf())),
            ArgList(Arg(type=ListOf(bool), default=[False, True])),
        ]

        for arglist in ls:
            nod = arglist.to_node()
            arglist2 = ArgList.from_node(nod)
            self.assert_arglists_identical(arglist, arglist2)
    def test_arglist_extra(self):
        arglist = ArgList(Arg('x'), ArgExtra(ListOf(int)), Arg('y'))
        self.assertEqual(arglist.min_accepted(), 2)
        self.assertEqual(arglist.max_accepted(), None)
        arg = arglist.get_index(1)
        self.assertEqual(arg.name, 'x')
        arg = arglist.get_index(2)
        self.assertEqual(arg.name, 'y')

        arglist2 = arglist.clone()
        self.assertEqual(arglist2.min_accepted(), 2)
        self.assertEqual(arglist2.max_accepted(), None)
        arg = arglist2.get_index(1)
        self.assertEqual(arg.name, 'x')
        arg = arglist2.get_index(2)
        self.assertEqual(arg.name, 'y')

        self.assertTrue(isinstance(arglist2.listtype, ListOf))
        self.assertEqual(arglist2.listtype.types, (int, ))
    def test_resolve(self):
        arglist = ArgList(Arg('x'), Arg('y'))
        goodls = [
            ('(A xx yy)', ['xx', 'yy'], {}),
            ('(A xx ())', ['xx', []], {}),
            ('(A ((xx)) (yy))', [[['xx']], ['yy']], {}),
        ]
        badls = [
            'A',
            '()',
            '(A)',
            '(A xx)',
            '(A xx yy z=1)',
            '(A xx yy zz)',
            '(A xx x=xxx)',
        ]
        self.one_test_resolve(arglist, goodls, badls)

        arglist = ArgList(Arg(name='x', type=int), Arg(name='y', type=str))
        goodls = [
            ('(A 1 yy)', [1, 'yy'], {}),
            ('(A -5 "1 2 3")', [-5, '1 2 3'], {}),
            ('(A y=yy x=1)', [1, 'yy'], {}),
            ('(A 1 y=yy)', [1, 'yy'], {}),
        ]
        badls = [
            '(A)',
            '(A 1)',
            '(A xx yy)',
            '(A 1 yy zz)',
            '(A 1 ())',
        ]
        self.one_test_resolve(arglist, goodls, badls)

        arglist = ArgList(Arg(name='x', type=str), ArgExtra(ListOf(int)))
        goodls = [
            ('(A xx)', ['xx'], {}),
            ('(A xx 1 2 3)', ['xx', 1, 2, 3], {}),
            ('(A 0 1 2 3)', ['0', 1, 2, 3], {}),
        ]
        badls = [
            '(A xx 1 2 z)',
            '(A xx z 2 3)',
            '(A xx 1 2 3 z=0)',
            '(A 1 2 3 x=xx)',
        ]
        self.one_test_resolve(arglist, goodls, badls)

        arglist = ArgList(Arg(name='x', type=str), ArgExtra(TupleOf(int, int)))
        goodls = [
            ('(A xx 1 2)', ['xx', 1, 2], {}),
        ]
        badls = [
            '(A xx)',
            '(A xx 1 2 3)',
            '(A xx 1 2 z)',
            '(A xx z 2 3)',
            '(A xx 1 2 3 z=0)',
            '(A 1 2 3 x=xx)',
        ]
        self.one_test_resolve(arglist, goodls, badls)

        arglist = ArgList(Arg(name='x', type=str),
                          ArgExtra(ListOf(int, str, repeat=1, min=1, max=3)))
        goodls = [
            ('(A xx 1)', ['xx', 1], {}),
            ('(A xx 1 2)', ['xx', 1, '2'], {}),
            ('(A xx 1 2 3)', ['xx', 1, '2', '3'], {}),
        ]
        badls = [
            '(A xx)',
            '(A xx 1 2 3 4)',
        ]
        self.one_test_resolve(arglist, goodls, badls)

        arglist = ArgList(Arg(type=int), Arg(type=str))
        goodls = [
            ('(A 1 yy)', [1, 'yy'], {}),
        ]
        badls = [
            '(A)',
            '(A 1)',
            '(A 1 ())',
            '(A 1 yy zz)',
            '(A xx yy)',
            '(A 1 yy z=zz)',
            '(A x=1 y=yy)',
        ]
        self.one_test_resolve(arglist, goodls, badls)

        arglist = ArgList(Arg(type=ListOf(int)), Arg(type=list))
        goodls = [
            ('(A () ())', [[], []], {}),
            ('(A (1) (yy))', [[1], ['yy']], {}),
            ('(A (1 2 3) (yy () 33))', [[1, 2, 3], ['yy', [], '33']], {}),
        ]
        badls = [
            '(A)',
            '(A 1)',
            '(A 1 ())',
            '(A (x) ())',
            '(A (()) ())',
        ]
        self.one_test_resolve(arglist, goodls, badls)

        arglist = ArgList(x=Arg(), y=Arg())
        goodls = [
            ('(A x=xx y=yy)', [], {
                'x': 'xx',
                'y': 'yy'
            }),
        ]
        badls = [
            '(A)',
            '(A xx)',
            '(A xx yy)',
            '(A xx yy zz)',
            '(A x=xx)',
            '(A y=yy)',
        ]
        self.one_test_resolve(arglist, goodls, badls)

        arglist = ArgList(Arg('x', default='xd'), Arg('y', default='yd'))
        goodls = [
            ('(A xx yy)', ['xx', 'yy'], {}),
            ('(A xx y=yy)', ['xx', 'yy'], {}),
            ('(A x=xx y=yy)', ['xx', 'yy'], {}),
            ('(A xx)', ['xx', 'yd'], {}),
            ('(A x=xx)', ['xx', 'yd'], {}),
            ('(A y=yy)', ['xd', 'yy'], {}),
            ('(A)', ['xd', 'yd'], {}),
        ]
        badls = [
            '(A xx yy z=1)',
            '(A xx yy zz)',
            '(A xx x=xxx)',
        ]
        self.one_test_resolve(arglist, goodls, badls)

        arglist = ArgList(x=Arg(default='xd'), y=Arg(default='yd'))
        goodls = [
            ('(A x=xx)', [], {
                'x': 'xx'
            }),
            ('(A y=yy)', [], {
                'y': 'yy'
            }),
            ('(A x=xx y=yy)', [], {
                'x': 'xx',
                'y': 'yy'
            }),
            ('(A)', [], {}),
        ]
        badls = [
            '(A xx)',
            '(A xx yy)',
            '(A xx y=yy)',
            '(A xx yy z=1)',
            '(A xx yy zz)',
            '(A xx x=xxx)',
        ]
        self.one_test_resolve(arglist, goodls, badls)

        arglist = ArgList(Arg('x', default='xd', optional=False),
                          Arg('y', default='yd'))
        goodls = [
            ('(A xx yy)', ['xx', 'yy'], {}),
            ('(A xx y=yy)', ['xx', 'yy'], {}),
            ('(A x=xx y=yy)', ['xx', 'yy'], {}),
            ('(A xx)', ['xx', 'yd'], {}),
            ('(A x=xx)', ['xx', 'yd'], {}),
            ('(A y=yy)', ['xd', 'yy'], {}),
            ('(A)', ['xd', 'yd'], {}),
        ]
        badls = [
            '(A xx yy z=1)',
            '(A xx yy zz)',
            '(A xx x=xxx)',
        ]
        self.one_test_resolve(arglist, goodls, badls)

        arglist = ArgList(x=Arg(default='xd', optional=False),
                          y=Arg(default='yd'))
        goodls = [
            ('(A x=xx)', [], {
                'x': 'xx'
            }),
            ('(A y=yy)', [], {
                'x': 'xd',
                'y': 'yy'
            }),
            ('(A x=xx y=yy)', [], {
                'x': 'xx',
                'y': 'yy'
            }),
            ('(A)', [], {
                'x': 'xd'
            }),
        ]
        badls = [
            '(A xx)',
            '(A xx yy)',
            '(A xx y=yy)',
            '(A xx yy z=1)',
            '(A xx yy zz)',
            '(A xx x=xxx)',
        ]
        self.one_test_resolve(arglist, goodls, badls)