17db96d56Sopenharmony_cifrom test.support import import_helper
27db96d56Sopenharmony_ci
37db96d56Sopenharmony_ci# Skip this test if _tkinter does not exist.
47db96d56Sopenharmony_ciimport_helper.import_module('_tkinter')
57db96d56Sopenharmony_ci
67db96d56Sopenharmony_ciimport unittest
77db96d56Sopenharmony_cifrom tkinter import ttk
87db96d56Sopenharmony_ci
97db96d56Sopenharmony_ci
107db96d56Sopenharmony_ciclass MockTkApp:
117db96d56Sopenharmony_ci
127db96d56Sopenharmony_ci    def splitlist(self, arg):
137db96d56Sopenharmony_ci        if isinstance(arg, tuple):
147db96d56Sopenharmony_ci            return arg
157db96d56Sopenharmony_ci        return arg.split(':')
167db96d56Sopenharmony_ci
177db96d56Sopenharmony_ci    def wantobjects(self):
187db96d56Sopenharmony_ci        return True
197db96d56Sopenharmony_ci
207db96d56Sopenharmony_ci
217db96d56Sopenharmony_ciclass MockTclObj(object):
227db96d56Sopenharmony_ci    typename = 'test'
237db96d56Sopenharmony_ci
247db96d56Sopenharmony_ci    def __init__(self, val):
257db96d56Sopenharmony_ci        self.val = val
267db96d56Sopenharmony_ci
277db96d56Sopenharmony_ci    def __str__(self):
287db96d56Sopenharmony_ci        return str(self.val)
297db96d56Sopenharmony_ci
307db96d56Sopenharmony_ci
317db96d56Sopenharmony_ciclass MockStateSpec(object):
327db96d56Sopenharmony_ci    typename = 'StateSpec'
337db96d56Sopenharmony_ci
347db96d56Sopenharmony_ci    def __init__(self, *args):
357db96d56Sopenharmony_ci        self.val = args
367db96d56Sopenharmony_ci
377db96d56Sopenharmony_ci    def __str__(self):
387db96d56Sopenharmony_ci        return ' '.join(self.val)
397db96d56Sopenharmony_ci
407db96d56Sopenharmony_ci
417db96d56Sopenharmony_ciclass InternalFunctionsTest(unittest.TestCase):
427db96d56Sopenharmony_ci
437db96d56Sopenharmony_ci    def test_format_optdict(self):
447db96d56Sopenharmony_ci        def check_against(fmt_opts, result):
457db96d56Sopenharmony_ci            for i in range(0, len(fmt_opts), 2):
467db96d56Sopenharmony_ci                self.assertEqual(result.pop(fmt_opts[i]), fmt_opts[i + 1])
477db96d56Sopenharmony_ci            if result:
487db96d56Sopenharmony_ci                self.fail("result still got elements: %s" % result)
497db96d56Sopenharmony_ci
507db96d56Sopenharmony_ci        # passing an empty dict should return an empty object (tuple here)
517db96d56Sopenharmony_ci        self.assertFalse(ttk._format_optdict({}))
527db96d56Sopenharmony_ci
537db96d56Sopenharmony_ci        # check list formatting
547db96d56Sopenharmony_ci        check_against(
557db96d56Sopenharmony_ci            ttk._format_optdict({'fg': 'blue', 'padding': [1, 2, 3, 4]}),
567db96d56Sopenharmony_ci            {'-fg': 'blue', '-padding': '1 2 3 4'})
577db96d56Sopenharmony_ci
587db96d56Sopenharmony_ci        # check tuple formatting (same as list)
597db96d56Sopenharmony_ci        check_against(
607db96d56Sopenharmony_ci            ttk._format_optdict({'test': (1, 2, '', 0)}),
617db96d56Sopenharmony_ci            {'-test': '1 2 {} 0'})
627db96d56Sopenharmony_ci
637db96d56Sopenharmony_ci        # check untouched values
647db96d56Sopenharmony_ci        check_against(
657db96d56Sopenharmony_ci            ttk._format_optdict({'test': {'left': 'as is'}}),
667db96d56Sopenharmony_ci            {'-test': {'left': 'as is'}})
677db96d56Sopenharmony_ci
687db96d56Sopenharmony_ci        # check script formatting
697db96d56Sopenharmony_ci        check_against(
707db96d56Sopenharmony_ci            ttk._format_optdict(
717db96d56Sopenharmony_ci                {'test': [1, -1, '', '2m', 0], 'test2': 3,
727db96d56Sopenharmony_ci                 'test3': '', 'test4': 'abc def',
737db96d56Sopenharmony_ci                 'test5': '"abc"', 'test6': '{}',
747db96d56Sopenharmony_ci                 'test7': '} -spam {'}, script=True),
757db96d56Sopenharmony_ci            {'-test': '{1 -1 {} 2m 0}', '-test2': '3',
767db96d56Sopenharmony_ci             '-test3': '{}', '-test4': '{abc def}',
777db96d56Sopenharmony_ci             '-test5': '{"abc"}', '-test6': r'\{\}',
787db96d56Sopenharmony_ci             '-test7': r'\}\ -spam\ \{'})
797db96d56Sopenharmony_ci
807db96d56Sopenharmony_ci        opts = {'αβγ': True, 'á': False}
817db96d56Sopenharmony_ci        orig_opts = opts.copy()
827db96d56Sopenharmony_ci        # check if giving unicode keys is fine
837db96d56Sopenharmony_ci        check_against(ttk._format_optdict(opts), {'-αβγ': True, '-á': False})
847db96d56Sopenharmony_ci        # opts should remain unchanged
857db96d56Sopenharmony_ci        self.assertEqual(opts, orig_opts)
867db96d56Sopenharmony_ci
877db96d56Sopenharmony_ci        # passing values with spaces inside a tuple/list
887db96d56Sopenharmony_ci        check_against(
897db96d56Sopenharmony_ci            ttk._format_optdict(
907db96d56Sopenharmony_ci                {'option': ('one two', 'three')}),
917db96d56Sopenharmony_ci            {'-option': '{one two} three'})
927db96d56Sopenharmony_ci        check_against(
937db96d56Sopenharmony_ci            ttk._format_optdict(
947db96d56Sopenharmony_ci                {'option': ('one\ttwo', 'three')}),
957db96d56Sopenharmony_ci            {'-option': '{one\ttwo} three'})
967db96d56Sopenharmony_ci
977db96d56Sopenharmony_ci        # passing empty strings inside a tuple/list
987db96d56Sopenharmony_ci        check_against(
997db96d56Sopenharmony_ci            ttk._format_optdict(
1007db96d56Sopenharmony_ci                {'option': ('', 'one')}),
1017db96d56Sopenharmony_ci            {'-option': '{} one'})
1027db96d56Sopenharmony_ci
1037db96d56Sopenharmony_ci        # passing values with braces inside a tuple/list
1047db96d56Sopenharmony_ci        check_against(
1057db96d56Sopenharmony_ci            ttk._format_optdict(
1067db96d56Sopenharmony_ci                {'option': ('one} {two', 'three')}),
1077db96d56Sopenharmony_ci            {'-option': r'one\}\ \{two three'})
1087db96d56Sopenharmony_ci
1097db96d56Sopenharmony_ci        # passing quoted strings inside a tuple/list
1107db96d56Sopenharmony_ci        check_against(
1117db96d56Sopenharmony_ci            ttk._format_optdict(
1127db96d56Sopenharmony_ci                {'option': ('"one"', 'two')}),
1137db96d56Sopenharmony_ci            {'-option': '{"one"} two'})
1147db96d56Sopenharmony_ci        check_against(
1157db96d56Sopenharmony_ci            ttk._format_optdict(
1167db96d56Sopenharmony_ci                {'option': ('{one}', 'two')}),
1177db96d56Sopenharmony_ci            {'-option': r'\{one\} two'})
1187db96d56Sopenharmony_ci
1197db96d56Sopenharmony_ci        # ignore an option
1207db96d56Sopenharmony_ci        amount_opts = len(ttk._format_optdict(opts, ignore=('á'))) / 2
1217db96d56Sopenharmony_ci        self.assertEqual(amount_opts, len(opts) - 1)
1227db96d56Sopenharmony_ci
1237db96d56Sopenharmony_ci        # ignore non-existing options
1247db96d56Sopenharmony_ci        amount_opts = len(ttk._format_optdict(opts, ignore=('á', 'b'))) / 2
1257db96d56Sopenharmony_ci        self.assertEqual(amount_opts, len(opts) - 1)
1267db96d56Sopenharmony_ci
1277db96d56Sopenharmony_ci        # ignore every option
1287db96d56Sopenharmony_ci        self.assertFalse(ttk._format_optdict(opts, ignore=list(opts.keys())))
1297db96d56Sopenharmony_ci
1307db96d56Sopenharmony_ci
1317db96d56Sopenharmony_ci    def test_format_mapdict(self):
1327db96d56Sopenharmony_ci        opts = {'a': [('b', 'c', 'val'), ('d', 'otherval'), ('', 'single')]}
1337db96d56Sopenharmony_ci        result = ttk._format_mapdict(opts)
1347db96d56Sopenharmony_ci        self.assertEqual(len(result), len(list(opts.keys())) * 2)
1357db96d56Sopenharmony_ci        self.assertEqual(result, ('-a', '{b c} val d otherval {} single'))
1367db96d56Sopenharmony_ci        self.assertEqual(ttk._format_mapdict(opts, script=True),
1377db96d56Sopenharmony_ci            ('-a', '{{b c} val d otherval {} single}'))
1387db96d56Sopenharmony_ci
1397db96d56Sopenharmony_ci        self.assertEqual(ttk._format_mapdict({2: []}), ('-2', ''))
1407db96d56Sopenharmony_ci
1417db96d56Sopenharmony_ci        opts = {'üñíćódè': [('á', 'vãl')]}
1427db96d56Sopenharmony_ci        result = ttk._format_mapdict(opts)
1437db96d56Sopenharmony_ci        self.assertEqual(result, ('-üñíćódè', 'á vãl'))
1447db96d56Sopenharmony_ci
1457db96d56Sopenharmony_ci        self.assertEqual(ttk._format_mapdict({'opt': [('value',)]}),
1467db96d56Sopenharmony_ci                         ('-opt', '{} value'))
1477db96d56Sopenharmony_ci
1487db96d56Sopenharmony_ci        # empty states
1497db96d56Sopenharmony_ci        valid = {'opt': [('', '', 'hi')]}
1507db96d56Sopenharmony_ci        self.assertEqual(ttk._format_mapdict(valid), ('-opt', '{ } hi'))
1517db96d56Sopenharmony_ci
1527db96d56Sopenharmony_ci        # when passing multiple states, they all must be strings
1537db96d56Sopenharmony_ci        invalid = {'opt': [(1, 2, 'valid val')]}
1547db96d56Sopenharmony_ci        self.assertRaises(TypeError, ttk._format_mapdict, invalid)
1557db96d56Sopenharmony_ci        invalid = {'opt': [([1], '2', 'valid val')]}
1567db96d56Sopenharmony_ci        self.assertRaises(TypeError, ttk._format_mapdict, invalid)
1577db96d56Sopenharmony_ci        # but when passing a single state, it can be anything
1587db96d56Sopenharmony_ci        valid = {'opt': [[1, 'value']]}
1597db96d56Sopenharmony_ci        self.assertEqual(ttk._format_mapdict(valid), ('-opt', '1 value'))
1607db96d56Sopenharmony_ci        # special attention to single states which evaluate to False
1617db96d56Sopenharmony_ci        for stateval in (None, 0, False, '', set()): # just some samples
1627db96d56Sopenharmony_ci            valid = {'opt': [(stateval, 'value')]}
1637db96d56Sopenharmony_ci            self.assertEqual(ttk._format_mapdict(valid),
1647db96d56Sopenharmony_ci                ('-opt', '{} value'))
1657db96d56Sopenharmony_ci
1667db96d56Sopenharmony_ci        # values must be iterable
1677db96d56Sopenharmony_ci        opts = {'a': None}
1687db96d56Sopenharmony_ci        self.assertRaises(TypeError, ttk._format_mapdict, opts)
1697db96d56Sopenharmony_ci
1707db96d56Sopenharmony_ci
1717db96d56Sopenharmony_ci    def test_format_elemcreate(self):
1727db96d56Sopenharmony_ci        self.assertTrue(ttk._format_elemcreate(None), (None, ()))
1737db96d56Sopenharmony_ci
1747db96d56Sopenharmony_ci        ## Testing type = image
1757db96d56Sopenharmony_ci        # image type expects at least an image name, so this should raise
1767db96d56Sopenharmony_ci        # IndexError since it tries to access the index 0 of an empty tuple
1777db96d56Sopenharmony_ci        self.assertRaises(IndexError, ttk._format_elemcreate, 'image')
1787db96d56Sopenharmony_ci
1797db96d56Sopenharmony_ci        # don't format returned values as a tcl script
1807db96d56Sopenharmony_ci        # minimum acceptable for image type
1817db96d56Sopenharmony_ci        self.assertEqual(ttk._format_elemcreate('image', False, 'test'),
1827db96d56Sopenharmony_ci            ("test ", ()))
1837db96d56Sopenharmony_ci        # specifying a state spec
1847db96d56Sopenharmony_ci        self.assertEqual(ttk._format_elemcreate('image', False, 'test',
1857db96d56Sopenharmony_ci            ('', 'a')), ("test {} a", ()))
1867db96d56Sopenharmony_ci        # state spec with multiple states
1877db96d56Sopenharmony_ci        self.assertEqual(ttk._format_elemcreate('image', False, 'test',
1887db96d56Sopenharmony_ci            ('a', 'b', 'c')), ("test {a b} c", ()))
1897db96d56Sopenharmony_ci        # state spec and options
1907db96d56Sopenharmony_ci        self.assertEqual(ttk._format_elemcreate('image', False, 'test',
1917db96d56Sopenharmony_ci            ('a', 'b'), a='x'), ("test a b", ("-a", "x")))
1927db96d56Sopenharmony_ci        # format returned values as a tcl script
1937db96d56Sopenharmony_ci        # state spec with multiple states and an option with a multivalue
1947db96d56Sopenharmony_ci        self.assertEqual(ttk._format_elemcreate('image', True, 'test',
1957db96d56Sopenharmony_ci            ('a', 'b', 'c', 'd'), x=[2, 3]), ("{test {a b c} d}", "-x {2 3}"))
1967db96d56Sopenharmony_ci
1977db96d56Sopenharmony_ci        ## Testing type = vsapi
1987db96d56Sopenharmony_ci        # vsapi type expects at least a class name and a part_id, so this
1997db96d56Sopenharmony_ci        # should raise a ValueError since it tries to get two elements from
2007db96d56Sopenharmony_ci        # an empty tuple
2017db96d56Sopenharmony_ci        self.assertRaises(ValueError, ttk._format_elemcreate, 'vsapi')
2027db96d56Sopenharmony_ci
2037db96d56Sopenharmony_ci        # don't format returned values as a tcl script
2047db96d56Sopenharmony_ci        # minimum acceptable for vsapi
2057db96d56Sopenharmony_ci        self.assertEqual(ttk._format_elemcreate('vsapi', False, 'a', 'b'),
2067db96d56Sopenharmony_ci            ("a b ", ()))
2077db96d56Sopenharmony_ci        # now with a state spec with multiple states
2087db96d56Sopenharmony_ci        self.assertEqual(ttk._format_elemcreate('vsapi', False, 'a', 'b',
2097db96d56Sopenharmony_ci            ('a', 'b', 'c')), ("a b {a b} c", ()))
2107db96d56Sopenharmony_ci        # state spec and option
2117db96d56Sopenharmony_ci        self.assertEqual(ttk._format_elemcreate('vsapi', False, 'a', 'b',
2127db96d56Sopenharmony_ci            ('a', 'b'), opt='x'), ("a b a b", ("-opt", "x")))
2137db96d56Sopenharmony_ci        # format returned values as a tcl script
2147db96d56Sopenharmony_ci        # state spec with a multivalue and an option
2157db96d56Sopenharmony_ci        self.assertEqual(ttk._format_elemcreate('vsapi', True, 'a', 'b',
2167db96d56Sopenharmony_ci            ('a', 'b', [1, 2]), opt='x'), ("{a b {a b} {1 2}}", "-opt x"))
2177db96d56Sopenharmony_ci
2187db96d56Sopenharmony_ci        # Testing type = from
2197db96d56Sopenharmony_ci        # from type expects at least a type name
2207db96d56Sopenharmony_ci        self.assertRaises(IndexError, ttk._format_elemcreate, 'from')
2217db96d56Sopenharmony_ci
2227db96d56Sopenharmony_ci        self.assertEqual(ttk._format_elemcreate('from', False, 'a'),
2237db96d56Sopenharmony_ci            ('a', ()))
2247db96d56Sopenharmony_ci        self.assertEqual(ttk._format_elemcreate('from', False, 'a', 'b'),
2257db96d56Sopenharmony_ci            ('a', ('b', )))
2267db96d56Sopenharmony_ci        self.assertEqual(ttk._format_elemcreate('from', True, 'a', 'b'),
2277db96d56Sopenharmony_ci            ('{a}', 'b'))
2287db96d56Sopenharmony_ci
2297db96d56Sopenharmony_ci
2307db96d56Sopenharmony_ci    def test_format_layoutlist(self):
2317db96d56Sopenharmony_ci        def sample(indent=0, indent_size=2):
2327db96d56Sopenharmony_ci            return ttk._format_layoutlist(
2337db96d56Sopenharmony_ci            [('a', {'other': [1, 2, 3], 'children':
2347db96d56Sopenharmony_ci                [('b', {'children':
2357db96d56Sopenharmony_ci                    [('c', {'children':
2367db96d56Sopenharmony_ci                        [('d', {'nice': 'opt'})], 'something': (1, 2)
2377db96d56Sopenharmony_ci                    })]
2387db96d56Sopenharmony_ci                })]
2397db96d56Sopenharmony_ci            })], indent=indent, indent_size=indent_size)[0]
2407db96d56Sopenharmony_ci
2417db96d56Sopenharmony_ci        def sample_expected(indent=0, indent_size=2):
2427db96d56Sopenharmony_ci            spaces = lambda amount=0: ' ' * (amount + indent)
2437db96d56Sopenharmony_ci            return (
2447db96d56Sopenharmony_ci                "%sa -other {1 2 3} -children {\n"
2457db96d56Sopenharmony_ci                "%sb -children {\n"
2467db96d56Sopenharmony_ci                "%sc -something {1 2} -children {\n"
2477db96d56Sopenharmony_ci                "%sd -nice opt\n"
2487db96d56Sopenharmony_ci                "%s}\n"
2497db96d56Sopenharmony_ci                "%s}\n"
2507db96d56Sopenharmony_ci                "%s}" % (spaces(), spaces(indent_size),
2517db96d56Sopenharmony_ci                    spaces(2 * indent_size), spaces(3 * indent_size),
2527db96d56Sopenharmony_ci                    spaces(2 * indent_size), spaces(indent_size), spaces()))
2537db96d56Sopenharmony_ci
2547db96d56Sopenharmony_ci        # empty layout
2557db96d56Sopenharmony_ci        self.assertEqual(ttk._format_layoutlist([])[0], '')
2567db96d56Sopenharmony_ci
2577db96d56Sopenharmony_ci        # _format_layoutlist always expects the second item (in every item)
2587db96d56Sopenharmony_ci        # to act like a dict (except when the value evaluates to False).
2597db96d56Sopenharmony_ci        self.assertRaises(AttributeError,
2607db96d56Sopenharmony_ci            ttk._format_layoutlist, [('a', 'b')])
2617db96d56Sopenharmony_ci
2627db96d56Sopenharmony_ci        smallest = ttk._format_layoutlist([('a', None)], indent=0)
2637db96d56Sopenharmony_ci        self.assertEqual(smallest,
2647db96d56Sopenharmony_ci            ttk._format_layoutlist([('a', '')], indent=0))
2657db96d56Sopenharmony_ci        self.assertEqual(smallest[0], 'a')
2667db96d56Sopenharmony_ci
2677db96d56Sopenharmony_ci        # testing indentation levels
2687db96d56Sopenharmony_ci        self.assertEqual(sample(), sample_expected())
2697db96d56Sopenharmony_ci        for i in range(4):
2707db96d56Sopenharmony_ci            self.assertEqual(sample(i), sample_expected(i))
2717db96d56Sopenharmony_ci            self.assertEqual(sample(i, i), sample_expected(i, i))
2727db96d56Sopenharmony_ci
2737db96d56Sopenharmony_ci        # invalid layout format, different kind of exceptions will be
2747db96d56Sopenharmony_ci        # raised by internal functions
2757db96d56Sopenharmony_ci
2767db96d56Sopenharmony_ci        # plain wrong format
2777db96d56Sopenharmony_ci        self.assertRaises(ValueError, ttk._format_layoutlist,
2787db96d56Sopenharmony_ci            ['bad', 'format'])
2797db96d56Sopenharmony_ci        # will try to use iteritems in the 'bad' string
2807db96d56Sopenharmony_ci        self.assertRaises(AttributeError, ttk._format_layoutlist,
2817db96d56Sopenharmony_ci           [('name', 'bad')])
2827db96d56Sopenharmony_ci        # bad children formatting
2837db96d56Sopenharmony_ci        self.assertRaises(ValueError, ttk._format_layoutlist,
2847db96d56Sopenharmony_ci            [('name', {'children': {'a': None}})])
2857db96d56Sopenharmony_ci
2867db96d56Sopenharmony_ci
2877db96d56Sopenharmony_ci    def test_script_from_settings(self):
2887db96d56Sopenharmony_ci        # empty options
2897db96d56Sopenharmony_ci        self.assertFalse(ttk._script_from_settings({'name':
2907db96d56Sopenharmony_ci            {'configure': None, 'map': None, 'element create': None}}))
2917db96d56Sopenharmony_ci
2927db96d56Sopenharmony_ci        # empty layout
2937db96d56Sopenharmony_ci        self.assertEqual(
2947db96d56Sopenharmony_ci            ttk._script_from_settings({'name': {'layout': None}}),
2957db96d56Sopenharmony_ci            "ttk::style layout name {\nnull\n}")
2967db96d56Sopenharmony_ci
2977db96d56Sopenharmony_ci        configdict = {'αβγ': True, 'á': False}
2987db96d56Sopenharmony_ci        self.assertTrue(
2997db96d56Sopenharmony_ci            ttk._script_from_settings({'name': {'configure': configdict}}))
3007db96d56Sopenharmony_ci
3017db96d56Sopenharmony_ci        mapdict = {'üñíćódè': [('á', 'vãl')]}
3027db96d56Sopenharmony_ci        self.assertTrue(
3037db96d56Sopenharmony_ci            ttk._script_from_settings({'name': {'map': mapdict}}))
3047db96d56Sopenharmony_ci
3057db96d56Sopenharmony_ci        # invalid image element
3067db96d56Sopenharmony_ci        self.assertRaises(IndexError,
3077db96d56Sopenharmony_ci            ttk._script_from_settings, {'name': {'element create': ['image']}})
3087db96d56Sopenharmony_ci
3097db96d56Sopenharmony_ci        # minimal valid image
3107db96d56Sopenharmony_ci        self.assertTrue(ttk._script_from_settings({'name':
3117db96d56Sopenharmony_ci            {'element create': ['image', 'name']}}))
3127db96d56Sopenharmony_ci
3137db96d56Sopenharmony_ci        image = {'thing': {'element create':
3147db96d56Sopenharmony_ci            ['image', 'name', ('state1', 'state2', 'val')]}}
3157db96d56Sopenharmony_ci        self.assertEqual(ttk._script_from_settings(image),
3167db96d56Sopenharmony_ci            "ttk::style element create thing image {name {state1 state2} val} ")
3177db96d56Sopenharmony_ci
3187db96d56Sopenharmony_ci        image['thing']['element create'].append({'opt': 30})
3197db96d56Sopenharmony_ci        self.assertEqual(ttk._script_from_settings(image),
3207db96d56Sopenharmony_ci            "ttk::style element create thing image {name {state1 state2} val} "
3217db96d56Sopenharmony_ci            "-opt 30")
3227db96d56Sopenharmony_ci
3237db96d56Sopenharmony_ci        image['thing']['element create'][-1]['opt'] = [MockTclObj(3),
3247db96d56Sopenharmony_ci            MockTclObj('2m')]
3257db96d56Sopenharmony_ci        self.assertEqual(ttk._script_from_settings(image),
3267db96d56Sopenharmony_ci            "ttk::style element create thing image {name {state1 state2} val} "
3277db96d56Sopenharmony_ci            "-opt {3 2m}")
3287db96d56Sopenharmony_ci
3297db96d56Sopenharmony_ci
3307db96d56Sopenharmony_ci    def test_tclobj_to_py(self):
3317db96d56Sopenharmony_ci        self.assertEqual(
3327db96d56Sopenharmony_ci            ttk._tclobj_to_py((MockStateSpec('a', 'b'), 'val')),
3337db96d56Sopenharmony_ci            [('a', 'b', 'val')])
3347db96d56Sopenharmony_ci        self.assertEqual(
3357db96d56Sopenharmony_ci            ttk._tclobj_to_py([MockTclObj('1'), 2, MockTclObj('3m')]),
3367db96d56Sopenharmony_ci            [1, 2, '3m'])
3377db96d56Sopenharmony_ci
3387db96d56Sopenharmony_ci
3397db96d56Sopenharmony_ci    def test_list_from_statespec(self):
3407db96d56Sopenharmony_ci        def test_it(sspec, value, res_value, states):
3417db96d56Sopenharmony_ci            self.assertEqual(ttk._list_from_statespec(
3427db96d56Sopenharmony_ci                (sspec, value)), [states + (res_value, )])
3437db96d56Sopenharmony_ci
3447db96d56Sopenharmony_ci        states_even = tuple('state%d' % i for i in range(6))
3457db96d56Sopenharmony_ci        statespec = MockStateSpec(*states_even)
3467db96d56Sopenharmony_ci        test_it(statespec, 'val', 'val', states_even)
3477db96d56Sopenharmony_ci        test_it(statespec, MockTclObj('val'), 'val', states_even)
3487db96d56Sopenharmony_ci
3497db96d56Sopenharmony_ci        states_odd = tuple('state%d' % i for i in range(5))
3507db96d56Sopenharmony_ci        statespec = MockStateSpec(*states_odd)
3517db96d56Sopenharmony_ci        test_it(statespec, 'val', 'val', states_odd)
3527db96d56Sopenharmony_ci
3537db96d56Sopenharmony_ci        test_it(('a', 'b', 'c'), MockTclObj('val'), 'val', ('a', 'b', 'c'))
3547db96d56Sopenharmony_ci
3557db96d56Sopenharmony_ci
3567db96d56Sopenharmony_ci    def test_list_from_layouttuple(self):
3577db96d56Sopenharmony_ci        tk = MockTkApp()
3587db96d56Sopenharmony_ci
3597db96d56Sopenharmony_ci        # empty layout tuple
3607db96d56Sopenharmony_ci        self.assertFalse(ttk._list_from_layouttuple(tk, ()))
3617db96d56Sopenharmony_ci
3627db96d56Sopenharmony_ci        # shortest layout tuple
3637db96d56Sopenharmony_ci        self.assertEqual(ttk._list_from_layouttuple(tk, ('name', )),
3647db96d56Sopenharmony_ci            [('name', {})])
3657db96d56Sopenharmony_ci
3667db96d56Sopenharmony_ci        # not so interesting ltuple
3677db96d56Sopenharmony_ci        sample_ltuple = ('name', '-option', 'value')
3687db96d56Sopenharmony_ci        self.assertEqual(ttk._list_from_layouttuple(tk, sample_ltuple),
3697db96d56Sopenharmony_ci            [('name', {'option': 'value'})])
3707db96d56Sopenharmony_ci
3717db96d56Sopenharmony_ci        # empty children
3727db96d56Sopenharmony_ci        self.assertEqual(ttk._list_from_layouttuple(tk,
3737db96d56Sopenharmony_ci            ('something', '-children', ())),
3747db96d56Sopenharmony_ci            [('something', {'children': []})]
3757db96d56Sopenharmony_ci        )
3767db96d56Sopenharmony_ci
3777db96d56Sopenharmony_ci        # more interesting ltuple
3787db96d56Sopenharmony_ci        ltuple = (
3797db96d56Sopenharmony_ci            'name', '-option', 'niceone', '-children', (
3807db96d56Sopenharmony_ci                ('otherone', '-children', (
3817db96d56Sopenharmony_ci                    ('child', )), '-otheropt', 'othervalue'
3827db96d56Sopenharmony_ci                )
3837db96d56Sopenharmony_ci            )
3847db96d56Sopenharmony_ci        )
3857db96d56Sopenharmony_ci        self.assertEqual(ttk._list_from_layouttuple(tk, ltuple),
3867db96d56Sopenharmony_ci            [('name', {'option': 'niceone', 'children':
3877db96d56Sopenharmony_ci                [('otherone', {'otheropt': 'othervalue', 'children':
3887db96d56Sopenharmony_ci                    [('child', {})]
3897db96d56Sopenharmony_ci                })]
3907db96d56Sopenharmony_ci            })]
3917db96d56Sopenharmony_ci        )
3927db96d56Sopenharmony_ci
3937db96d56Sopenharmony_ci        # bad tuples
3947db96d56Sopenharmony_ci        self.assertRaises(ValueError, ttk._list_from_layouttuple, tk,
3957db96d56Sopenharmony_ci            ('name', 'no_minus'))
3967db96d56Sopenharmony_ci        self.assertRaises(ValueError, ttk._list_from_layouttuple, tk,
3977db96d56Sopenharmony_ci            ('name', 'no_minus', 'value'))
3987db96d56Sopenharmony_ci        self.assertRaises(ValueError, ttk._list_from_layouttuple, tk,
3997db96d56Sopenharmony_ci            ('something', '-children')) # no children
4007db96d56Sopenharmony_ci
4017db96d56Sopenharmony_ci
4027db96d56Sopenharmony_ci    def test_val_or_dict(self):
4037db96d56Sopenharmony_ci        def func(res, opt=None, val=None):
4047db96d56Sopenharmony_ci            if opt is None:
4057db96d56Sopenharmony_ci                return res
4067db96d56Sopenharmony_ci            if val is None:
4077db96d56Sopenharmony_ci                return "test val"
4087db96d56Sopenharmony_ci            return (opt, val)
4097db96d56Sopenharmony_ci
4107db96d56Sopenharmony_ci        tk = MockTkApp()
4117db96d56Sopenharmony_ci        tk.call = func
4127db96d56Sopenharmony_ci
4137db96d56Sopenharmony_ci        self.assertEqual(ttk._val_or_dict(tk, {}, '-test:3'),
4147db96d56Sopenharmony_ci                         {'test': '3'})
4157db96d56Sopenharmony_ci        self.assertEqual(ttk._val_or_dict(tk, {}, ('-test', 3)),
4167db96d56Sopenharmony_ci                         {'test': 3})
4177db96d56Sopenharmony_ci
4187db96d56Sopenharmony_ci        self.assertEqual(ttk._val_or_dict(tk, {'test': None}, 'x:y'),
4197db96d56Sopenharmony_ci                         'test val')
4207db96d56Sopenharmony_ci
4217db96d56Sopenharmony_ci        self.assertEqual(ttk._val_or_dict(tk, {'test': 3}, 'x:y'),
4227db96d56Sopenharmony_ci                         {'test': 3})
4237db96d56Sopenharmony_ci
4247db96d56Sopenharmony_ci
4257db96d56Sopenharmony_ci    def test_convert_stringval(self):
4267db96d56Sopenharmony_ci        tests = (
4277db96d56Sopenharmony_ci            (0, 0), ('09', 9), ('a', 'a'), ('áÚ', 'áÚ'), ([], '[]'),
4287db96d56Sopenharmony_ci            (None, 'None')
4297db96d56Sopenharmony_ci        )
4307db96d56Sopenharmony_ci        for orig, expected in tests:
4317db96d56Sopenharmony_ci            self.assertEqual(ttk._convert_stringval(orig), expected)
4327db96d56Sopenharmony_ci
4337db96d56Sopenharmony_ci
4347db96d56Sopenharmony_ciclass TclObjsToPyTest(unittest.TestCase):
4357db96d56Sopenharmony_ci
4367db96d56Sopenharmony_ci    def test_unicode(self):
4377db96d56Sopenharmony_ci        adict = {'opt': 'välúè'}
4387db96d56Sopenharmony_ci        self.assertEqual(ttk.tclobjs_to_py(adict), {'opt': 'välúè'})
4397db96d56Sopenharmony_ci
4407db96d56Sopenharmony_ci        adict['opt'] = MockTclObj(adict['opt'])
4417db96d56Sopenharmony_ci        self.assertEqual(ttk.tclobjs_to_py(adict), {'opt': 'välúè'})
4427db96d56Sopenharmony_ci
4437db96d56Sopenharmony_ci    def test_multivalues(self):
4447db96d56Sopenharmony_ci        adict = {'opt': [1, 2, 3, 4]}
4457db96d56Sopenharmony_ci        self.assertEqual(ttk.tclobjs_to_py(adict), {'opt': [1, 2, 3, 4]})
4467db96d56Sopenharmony_ci
4477db96d56Sopenharmony_ci        adict['opt'] = [1, 'xm', 3]
4487db96d56Sopenharmony_ci        self.assertEqual(ttk.tclobjs_to_py(adict), {'opt': [1, 'xm', 3]})
4497db96d56Sopenharmony_ci
4507db96d56Sopenharmony_ci        adict['opt'] = (MockStateSpec('a', 'b'), 'válũè')
4517db96d56Sopenharmony_ci        self.assertEqual(ttk.tclobjs_to_py(adict),
4527db96d56Sopenharmony_ci            {'opt': [('a', 'b', 'válũè')]})
4537db96d56Sopenharmony_ci
4547db96d56Sopenharmony_ci        self.assertEqual(ttk.tclobjs_to_py({'x': ['y z']}),
4557db96d56Sopenharmony_ci            {'x': ['y z']})
4567db96d56Sopenharmony_ci
4577db96d56Sopenharmony_ci    def test_nosplit(self):
4587db96d56Sopenharmony_ci        self.assertEqual(ttk.tclobjs_to_py({'text': 'some text'}),
4597db96d56Sopenharmony_ci            {'text': 'some text'})
4607db96d56Sopenharmony_ci
4617db96d56Sopenharmony_ci
4627db96d56Sopenharmony_ciif __name__ == '__main__':
4637db96d56Sopenharmony_ci    unittest.main()
464