Пример #1
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())
Пример #2
0
    def test_write_wrong_type(self):
        stream = StringIO()
        unparser = BaseUnparser({})
        with self.assertRaises(TypeError):
            io.write(unparser, [], stream)

        with self.assertRaises(TypeError):
            io.write(unparser, '', stream)
 def readwrite(self, source):
     unparser = convert_dynamic_require_unparser()
     original = StringIO(source)
     original.name = 'source.js'
     output = StringIO()
     output.name = 'output.js'
     srcmap = StringIO()
     srcmap.name = 'output.js.map'
     io.write(unparser, io.read(es5, original), output, srcmap)
     return output, srcmap
Пример #4
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)
Пример #5
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')))
Пример #6
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())
Пример #7
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())
Пример #8
0
def _finalize_test_path(toolchain, spec, modname, path):
    """
    Process the path as a test file and bring it to a finalized location
    if necessary.

    Current condition for the relocation is usage of dynamic imports
    within the provided ES5 source file.
    """

    if not exists(path):
        # nothing to do.
        return path

    with codecs.open(path, encoding='utf8') as fd:
        try:
            tree = io.read(parse, fd)
            imports = yield_module_imports_nodes(tree)
        except Exception:
            # can't do anything.
            return path

    # if there are not any nodes that are not strings
    if not any(node
               for node in imports if not isinstance(node, asttypes.String)):
        return path

    # generate the new target using the toolchain instance.
    rel_target = toolchain.modname_source_to_target(spec, modname, path)
    target = join(spec[BUILD_DIR], normpath(rel_target))
    target_map = target + '.map'
    makedirs(dirname(target))

    with codecs.open(target, 'w', encoding='utf8') as ss:
        with codecs.open(target_map, 'w', encoding='utf8') as sm:
            io.write(convert_dynamic_require_unparser(), tree, ss, sm)

    return target
Пример #9
0
def run(inputs, output, mangle, obfuscate, pretty, source_map, indent_width,
        drop_semi, encoding, version):
    """
    Not a general use method, as sys.exit is called.
    """

    def stdin():
        return (
            sys.stdin
            if isinstance(sys.stdin, (StringIO, TextIOWrapper)) else
            codecs.getreader(sys.stdin.encoding or encoding)(sys.stdin)
        )

    def stdout():
        return (
            sys.stdout
            if isinstance(sys.stdout, (StringIO, TextIOWrapper)) else
            codecs.getwriter(sys.stdout.encoding or encoding)(sys.stdout)
        )

    abs_output = abspath(output) if output else output
    abs_source_map = abspath(source_map) if source_map else source_map

    input_streams = (
        [partial(codecs.open, abspath(p), encoding=encoding) for p in inputs]
        if inputs else
        [stdin]
    )
    output_stream = (
        partial(codecs.open, abs_output, 'w', encoding=encoding)
        if abs_output else
        stdout
    )
    # if source_map is flagged (from empty string, in the const), if
    # no further name is supplied, use the output to build the path,
    # if it is also not stdout.
    source_map_path = (
        abs_output + '.map'
        if source_map == '' and output_stream is not stdout else
        abs_source_map
    )

    if source_map and abs_source_map == abs_output:
        # if a source_map was specified and the absolute paths of that
        # and the output is equal, use the output_stream that was
        # already created.
        sourcemap_stream = output_stream
    else:
        # no source map if source_map path is actually None, and only
        # generate a callable if the source_map_path is not an empty
        # string.
        sourcemap_stream = None if source_map_path is None else (
            partial(codecs.open, source_map_path, 'w', encoding=encoding)
            if source_map_path else
            stdout
        )

    enabled_rules = [rules.minify(drop_semi=drop_semi or mangle)]
    if obfuscate or mangle:
        enabled_rules.append(rules.obfuscate(
            reserved_keywords=Lexer.keywords_dict.keys()
        ))

    if pretty:
        enabled_rules.append(rules.indent(indent_str=' ' * indent_width))

    printer = Unparser(rules=enabled_rules)
    try:
        io.write(
            printer, (io.read(parse, f) for f in input_streams),
            output_stream, sourcemap_stream,
        )
    except ECMASyntaxError as e:
        logger.error('%s', e)
        sys.exit(1)
    except (IOError, OSError) as e:
        logger.error('%s', e)
        if e.args and isinstance(e.args[0], int):
            sys.exit(e.args[0])
        sys.exit(5)  # EIO
    except UnicodeDecodeError as e:
        logger.error('read error: %s', e)
        sys.exit(1)
    except UnicodeEncodeError as e:
        logger.error('write error: %s', e)
        sys.exit(1)
    except KeyboardInterrupt:
        sys.exit(130)
    # no need to close any streams as they are callables and that the io
    # read/write functions take care of that.

    sys.exit(0)
Пример #10
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)