コード例 #1
0
 def test_deferrable_handler_literal_continuation(self):
     dispatcher = Dispatcher({}, None, {}, {})
     node = Node()
     node.value = '"foo\\\r\nbar"'
     self.assertEqual(
         '"foobar"',
         deferrable_handler_literal_continuation(dispatcher, node))
コード例 #2
0
    def test_repeated_layouts(self):
        class Block(Node):
            pass

        def space_layout(dispatcher, node, before, after, prev):
            yield SimpleChunk(' ')

        def newline_layout(dispatcher, node, before, after, prev):
            yield SimpleChunk('n')

        dispatcher = Dispatcher(
            definitions={
                'Node': (Space, ),
                'Block': (JoinAttr(Iter(), value=(Newline, )), )
            },
            token_handler=None,  # not actually produced
            layout_handlers={
                Space: space_layout,
                Newline: newline_layout,
                # drop the subsequent space
                (Newline, Space): newline_layout,
            },
            deferrable_handlers={},
        )

        n0 = Block([])
        self.assertEqual('', ''.join(c.text for c in walk(dispatcher, n0)))
        n1 = Block([Node([])] * 1)
        self.assertEqual(' ', ''.join(c.text for c in walk(dispatcher, n1)))
        n2 = Block([Node([])] * 2)
        self.assertEqual(' n', ''.join(c.text for c in walk(dispatcher, n2)))
        n3 = Block([Node([])] * 3)
        self.assertEqual(' nn', ''.join(c.text for c in walk(dispatcher, n3)))
コード例 #3
0
    def test_write_no_sourcemap(self):
        root = mktemp()
        definitions = {
            'Node': (
                Attr(attr='left'),
                Attr(attr='op'),
                Attr(attr='right'),
            )
        }

        # the program node; attributes are assigned to mimic a real one
        program = Node()
        program.left, program.op, program.right = ('foo', '=', 'true')
        program.sourcepath = join(root, 'original.js')
        program._token_map = {
            'foo': [(0, 1, 1)],
            '=': [(4, 1, 5)],
            'true': [(6, 1, 7)],
        }

        output_stream = StringIO()
        output_stream.name = join(root, 'processed.js')

        unparser = BaseUnparser(definitions)
        io.write(unparser, program, output_stream)
        self.assertEqual('foo=true', output_stream.getvalue())
コード例 #4
0
    def test_nested_layouts(self):
        def simple_layout_space(dispatcher, node, before, after, prev):
            yield SimpleChunk(' ')

        def nested_layout(dispatcher, node, before, after, prev):
            yield SimpleChunk('?')

        def noop(*a, **kw):
            return
            yield  # pragma: no cover

        dispatcher = Dispatcher(
            definitions={'Node': (
                Space,
                JoinAttr(Iter(), value=(Space, )),
            )},
            token_handler=noop,
            layout_handlers={
                Space: simple_layout_space,
                (Space, Space): noop,
                ((Space, Space), Space): nested_layout,
            },
            deferrable_handlers={},
        )

        n0 = Node([])
        self.assertEqual(' ', ''.join(c.text for c in walk(dispatcher, n0)))
        n1 = Node([n0])
        self.assertEqual('', ''.join(c.text for c in walk(dispatcher, n1)))
        n2 = Node([n1, n0])
        self.assertEqual('?', ''.join(c.text for c in walk(dispatcher, n2)))
コード例 #5
0
    def test_core_structures(self):
        # initialise a barebone dispatcher.
        node = Node()
        dispatcher = Dispatcher({}, None, {}, {})
        self.assertEqual([(
            '{',
            0,
            0,
            None,
            None,
        )], list(layout_handler_openbrace(dispatcher, node, None, None, None)))
        self.assertEqual([(
            '}',
            0,
            0,
            None,
            None,
        )], list(layout_handler_closebrace(dispatcher, node, None, None,
                                           None)))
        self.assertEqual([(
            ';',
            0,
            0,
            None,
            None,
        )], list(layout_handler_semicolon(dispatcher, node, None, None, None)))

        # with token map
        node._token_map = {
            '{': [(0, 1, 1)],
            '}': [(1, 1, 2)],
            ';': [(2, 1, 3)],
        }
        self.assertEqual([(
            '{',
            1,
            1,
            None,
            None,
        )], list(layout_handler_openbrace(dispatcher, node, None, None, None)))
        self.assertEqual([(
            '}',
            1,
            2,
            None,
            None,
        )], list(layout_handler_closebrace(dispatcher, node, None, None,
                                           None)))
        self.assertEqual([(
            ';',
            1,
            3,
            None,
            None,
        )], list(layout_handler_semicolon(dispatcher, node, None, None, None)))
コード例 #6
0
    def test_write_multiple(self):
        root = mktemp()
        definitions = {
            'Node': (
                Attr(attr='left'),
                Text(value=' '),
                Attr(attr='op'),
                Text(value=' '),
                Attr(attr='right'),
                Text(value=';'),
            )
        }

        # the program node; attributes are assigned to mimic a real one
        program1 = Node()
        program1.left, program1.op, program1.right = ('foo', '=', 'true')
        program1.sourcepath = join(root, 'program1.js')
        program1._token_map = {
            'foo': [(0, 1, 1)],
            '=': [(4, 1, 5)],
            'true': [(6, 1, 7)],
        }
        program2 = Node()
        program2.left, program2.op, program2.right = ('bar', '=', 'false')
        program2.sourcepath = join(root, 'program2.js')
        program2._token_map = {
            'bar': [(0, 1, 1)],
            '=': [(4, 1, 5)],
            'false': [(6, 1, 7)],
        }

        # streams
        output_stream = StringIO()
        output_stream.name = join(root, 'packed.js')
        sourcemap_stream = StringIO()
        sourcemap_stream.name = join(root, 'packed.js.map')

        unparser = BaseUnparser(definitions)
        io.write(unparser, [program1, program2],
                 output_stream,
                 sourcemap_stream,
                 source_mapping_url=None)

        self.assertEqual('foo = true;bar = false;', output_stream.getvalue())

        sourcemap = json.loads(sourcemap_stream.getvalue())
        self.assertEqual(
            {
                "version": 3,
                "sources": ["program1.js", "program2.js"],
                "names": [],
                "mappings": "AAAA,WCAA",
                "file": "packed.js"
            }, sourcemap)
コード例 #7
0
    def test_write_same_stream_callable(self):
        # streams
        root = mktemp()
        output_stream = StringIO()
        output_stream.name = join(root, 'packed.js')
        called = []
        closed = []

        def close():
            closed.append(True)

        output_stream.close = close

        def f_output_stream():
            called.append(True)
            return output_stream

        definitions = {
            'Node': (
                Attr(attr='text'),
                Text(value=';'),
            )
        }

        # the program node; attributes are assigned to mimic a real one
        program = Node()
        program.text = 'hello'
        program.sourcepath = join(root, 'program.js')
        program._token_map = {'hello': [(0, 1, 1)]}

        unparser = BaseUnparser(definitions)
        io.write(unparser, [program], f_output_stream, f_output_stream)

        self.assertEqual(1, len(called))
        self.assertEqual(1, len(closed))
        output = output_stream.getvalue()
        self.assertIn('hello', output)
        self.assertNotIn('program.js', output)
        # since output stream is a StringIO, default to utf8 encoding
        self.assertIn('data:application/json;base64;charset=utf8', output)
        # decode the base64 string
        self.assertEqual(
            {
                "version": 3,
                "sources": ["program.js"],
                "names": [],
                "mappings": "AAAA",
                "file": "packed.js"
            },
            json.loads(
                base64.b64decode(output.splitlines()[-1].split(',')[-1].encode(
                    'utf8')).decode('utf8')))
コード例 #8
0
    def test_write_sourcemap_omitted(self):
        root = mktemp()
        definitions = {
            'Node': (
                Attr(attr='left'),
                Attr(attr='op'),
                Attr(attr='right'),
            )
        }

        # the program node; attributes are assigned to mimic a real one
        program = Node()
        program.left, program.op, program.right = ('foo', '=', 'true')
        program.sourcepath = join(root, 'original.js')
        program._token_map = {
            'foo': [(0, 1, 1)],
            '=': [(4, 1, 5)],
            'true': [(6, 1, 7)],
        }

        # streams
        output_stream = StringIO()
        output_stream.name = join(root, 'processed.js')
        sourcemap_stream = StringIO()
        sourcemap_stream.name = join(root, 'processed.js.map')

        unparser = BaseUnparser(definitions)
        io.write(unparser,
                 program,
                 output_stream,
                 sourcemap_stream,
                 source_mapping_url=None)

        sourcemap = json.loads(sourcemap_stream.getvalue())
        self.assertEqual(
            {
                "version": 3,
                "sources": ["original.js"],
                "names": [],
                "mappings": "AAAA,GAAI,CAAE",
                "file": "processed.js"
            }, sourcemap)
        self.assertEqual('foo=true', output_stream.getvalue())
コード例 #9
0
    def test_write_error_handled_callable_closed(self):
        # streams
        root = mktemp()
        output_stream = StringIO()
        output_stream.name = join(root, 'packed.js')
        closed = []

        def close():
            closed.append(True)

        output_stream.close = close

        def f_output_stream():
            return output_stream

        def f_error():
            raise IOError('some error happened')

        definitions = {
            'Node': (
                Attr(attr='text'),
                Text(value=';'),
            )
        }

        # the program node; attributes are assigned to mimic a real one
        program = Node()
        program.text = 'hello'
        program.sourcepath = join(root, 'program.js')
        program._token_map = {'hello': [(0, 1, 1)]}

        unparser = BaseUnparser(definitions)
        with self.assertRaises(IOError):
            io.write(unparser, [program], f_output_stream, f_error)

        self.assertEqual(1, len(closed))
        self.assertEqual('hello;', output_stream.getvalue())
        self.assertNotIn('program.js', output_stream.getvalue())
コード例 #10
0
    def test_prewalk_hooking(self):
        results = {}

        def prewalk_dummy(dispatcher, node):
            results.update({'dispatcher': dispatcher, 'node': node})
            return node

        definitions = {'Node': ()}
        unparser = BaseUnparser(definitions, prewalk_hooks=[prewalk_dummy])
        self.assertEqual(results, {})
        # invoke complete run to trigger prewalk hook.
        root = Node()
        self.assertEqual([], list(unparser(root)))
        self.assertTrue(isinstance(results['dispatcher'], Dispatcher))
        self.assertTrue(results['node'], root)
コード例 #11
0
    def test_called_prewalk_multicall(self):
        prewalk = []

        def rule():
            prewalk.append(True)
            return {}

        root = Node()
        definitions = {'Node': ()}
        unparser = BaseUnparser(definitions, rules=(rule, ))
        # invoke complete run to trigger prewalk hook.
        self.assertEqual(len(prewalk), 0)
        self.assertEqual([], list(unparser(root)))
        self.assertEqual(len(prewalk), 1)
        self.assertEqual([], list(unparser(root)))
        self.assertEqual(len(prewalk), 2)
コード例 #12
0
    def test_called_prewalk_via_rules(self):
        results = {}

        def prewalk_dummy(dispatcher, node):
            results.update({'dispatcher': dispatcher, 'node': node})
            return node

        def rule():
            return {'prewalk_hooks': (prewalk_dummy, )}

        definitions = {'Node': ()}
        unparser = BaseUnparser(definitions, rules=(rule, ))
        # invoke complete run to trigger prewalk hook.
        root = Node()
        self.assertEqual([], list(unparser(root)))
        self.assertTrue(isinstance(results['dispatcher'], Dispatcher))
        self.assertTrue(results['node'], root)
コード例 #13
0
    def test_catch_scope_basic(self):
        with self.assertRaises(TypeError) as e:
            CatchScope(None, None)
        self.assertEqual(e.exception.args[0],
                         'CatchScopes must have a Scope as a parent')

        parent = Scope(None)
        with self.assertRaises(AttributeError):
            # None isn't a node that can be resolved.
            CatchScope(None, parent)

        with self.assertRaises(AttributeError):
            # doesn't work with generic node either
            CatchScope(Node(), parent)

        catcher = CatchScope(Catch(Identifier('e'), []), parent)
        self.assertEqual(catcher.catch_symbol, 'e')
        catcher.close()

        with self.assertRaises(ValueError):
            catcher.close()
コード例 #14
0
    def test_join_attr_issue_36(self):
        # JoinAttr defined with parameter `value=None` resulted in
        # infinite recursion due to the walker will assume that no rule
        # is provided, triggering rule lookup which would repeat the
        # work that was done.

        class Block(Node):
            pass

        token_handler, layout_handlers, deferrable_handlers, declared_vars = (
            setup_handlers(self))
        dispatcher = Dispatcher(
            definitions={
                'Block': (JoinAttr(Iter(), value=None), ),
                'Node': (Text(value='', ), ),
            },
            token_handler=token_handler,
            layout_handlers={},
            deferrable_handlers={},
        )

        nodes = Block([Node([])] * 3)
        self.assertEqual(3, len(list(walk(dispatcher, nodes))))
コード例 #15
0
    def test_write_callables(self):
        closed = []

        class Stream(StringIO):
            # don't actually close the stream so it can be read later by
            # the tests
            def close(self):
                closed.append(self)

        # streams
        root = mktemp()
        output_stream = Stream()
        output_stream.name = join(root, 'packed.js')
        sourcemap_stream = Stream()
        sourcemap_stream.name = join(root, 'packed.js.map')

        def f_output_stream():
            return output_stream

        def f_sourcemap_stream():
            return sourcemap_stream

        definitions = {
            'Node': (
                Attr(attr='left'),
                Text(value=' '),
                Attr(attr='op'),
                Text(value=' '),
                Attr(attr='right'),
                Text(value=';'),
            )
        }

        # the program node; attributes are assigned to mimic a real one
        program1 = Node()
        program1.left, program1.op, program1.right = ('foo', '=', 'true')
        program1.sourcepath = join(root, 'program1.js')
        program1._token_map = {
            'foo': [(0, 1, 1)],
            '=': [(4, 1, 5)],
            'true': [(6, 1, 7)],
        }
        program2 = Node()
        program2.left, program2.op, program2.right = ('bar', '=', 'false')
        program2.sourcepath = join(root, 'program2.js')
        program2._token_map = {
            'bar': [(0, 1, 1)],
            '=': [(4, 1, 5)],
            'false': [(6, 1, 7)],
        }

        unparser = BaseUnparser(definitions)
        io.write(unparser, [program1, program2],
                 f_output_stream,
                 f_sourcemap_stream,
                 source_mapping_url=None)

        self.assertIn(output_stream, closed)
        self.assertIn(sourcemap_stream, closed)
        self.assertEqual('foo = true;bar = false;', output_stream.getvalue())

        sourcemap = json.loads(sourcemap_stream.getvalue())
        self.assertEqual(
            {
                "version": 3,
                "sources": ["program1.js", "program2.js"],
                "names": [],
                "mappings": "AAAA,WCAA",
                "file": "packed.js"
            }, sourcemap)
コード例 #16
0
 def test_minimum_definition(self):
     definitions = {'Node': ()}
     unparser = BaseUnparser(definitions)
     self.assertEqual([], list(unparser(Node())))
コード例 #17
0
 def test_prewalk_fail(self):
     definitions = {}
     unparser = BaseUnparser(definitions)
     # can't lookup an empty definition
     with self.assertRaises(KeyError):
         self.assertEqual([], list(unparser(Node())))
コード例 #18
0
 def parser(text):
     result = Node()
     result.raw = text
     return result
コード例 #19
0
 def test_scope_creation(self):
     scope = Scope(None)
     node = Node()
     scope.nest(node)
     self.assertEqual(scope.children[0].node, node)
     self.assertEqual(scope.children[0].parent, scope)