// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. library js_ast.string_escape_test; import 'package:js_ast/js_ast.dart'; import 'package:js_ast/src/characters.dart'; import 'package:test/test.dart'; const int $LCURLY = $OPEN_CURLY_BRACKET; const int $RCURLY = $CLOSE_CURLY_BRACKET; void main() { check(input, expected, {ascii: false, utf8: false}) { if (input is List) input = new String.fromCharCodes(input); String actual = js.escapedString(input, ascii: ascii, utf8: utf8).value; if (expected is List) { expect(actual.codeUnits, expected); } else { expect(actual, expected); } } test('simple', () { check('', [$DQ, $DQ]); check('a', [$DQ, $a, $DQ]); }); test('simple-escapes', () { check([$BS], [$DQ, $BACKSLASH, $b, $DQ]); check([$BS], [$DQ, $BACKSLASH, $b, $DQ], ascii: true); check([$BS], [$DQ, $BACKSLASH, $b, $DQ], utf8: true); check([$LF], [$DQ, $BACKSLASH, $n, $DQ]); check([$LF], [$DQ, $BACKSLASH, $n, $DQ], ascii: true); check([$LF], [$DQ, $BACKSLASH, $n, $DQ], utf8: true); check([$FF], [$DQ, $FF, $DQ]); check([$FF], [$DQ, $BACKSLASH, $f, $DQ], ascii: true); check([$FF], [$DQ, $BACKSLASH, $f, $DQ], utf8: true); check([$CR], [$DQ, $BACKSLASH, $r, $DQ]); check([$CR], [$DQ, $BACKSLASH, $r, $DQ], ascii: true); check([$CR], [$DQ, $BACKSLASH, $r, $DQ], utf8: true); check([$TAB], [$DQ, $BACKSLASH, $t, $DQ]); check([$TAB], [$DQ, $BACKSLASH, $t, $DQ], ascii: true); check([$TAB], [$DQ, $BACKSLASH, $t, $DQ], utf8: true); check([$VTAB], [$DQ, $BACKSLASH, $v, $DQ]); check([$VTAB], [$DQ, $BACKSLASH, $v, $DQ], ascii: true); check([$VTAB], [$DQ, $BACKSLASH, $v, $DQ], utf8: true); }); test('unnamed-control-codes-escapes', () { check([0, 1, 2, 3], [$DQ, 0, 1, 2, 3, $DQ]); check([0, 1, 2, 3], r'''"\x00\x01\x02\x03"''', ascii: true); check([0, 1, 2, 3], [$DQ, 0, 1, 2, 3, $DQ], utf8: true); }); test('line-separator', () { // Legacy escaper is broken. // check([$LS], [$DQ, $BACKSLASH, $u, $2, $0, $2, $8, $DQ]); check([$LS], [$DQ, $BACKSLASH, $u, $2, $0, $2, $8, $DQ], ascii: true); check([$LS], [$DQ, $BACKSLASH, $u, $2, $0, $2, $8, $DQ], utf8: true); }); test('page-separator', () { // Legacy escaper is broken. // check([$PS], [$DQ, $BACKSLASH, $u, $2, $0, $2, $9, $DQ]); check([$PS], [$DQ, $BACKSLASH, $u, $2, $0, $2, $9, $DQ], ascii: true); check([$PS], [$DQ, $BACKSLASH, $u, $2, $0, $2, $9, $DQ], utf8: true); }); test('legacy-escaper-is-broken', () { check([$LS], [$DQ, 0x2028, $DQ]); check([$PS], [$DQ, 0x2029, $DQ]); }); test('choose-quotes', () { check('\'', [$DQ, $SQ, $DQ]); check('"', [$SQ, $DQ, $SQ], ascii: true); check("'", [$DQ, $SQ, $DQ], ascii: true); // Legacy always double-quotes check([$DQ, $DQ, $SQ], [$DQ, $BACKSLASH, $DQ, $BACKSLASH, $DQ, $SQ, $DQ]); // Using single quotes saves us one backslash: check([$DQ, $DQ, $SQ], [$SQ, $DQ, $DQ, $BACKSLASH, $SQ, $SQ], ascii: true); check([$DQ, $SQ, $SQ], [$DQ, $BACKSLASH, $DQ, $SQ, $SQ, $DQ], ascii: true); }); test('u1234', () { check('\u1234', [$DQ, 0x1234, $DQ]); check('\u1234', [$DQ, $BACKSLASH, $u, $1, $2, $3, $4, $DQ], ascii: true); check('\u1234', [$DQ, 0x1234, $DQ], utf8: true); }); test('u12345', () { check([0x12345], [$DQ, 55304, 57157, $DQ]); // TODO: ES6 option: //check([0x12345], // [$DQ, $BACKSLASH, $u, $LCURLY, $1, $2, $3, $4, $5, $RCURLY, $DQ], // ascii: true); check([0x12345], r'''"\ud808\udf45"''', ascii: true); check([ 0x12345 ], [ $DQ, $BACKSLASH, $u, $d, $8, $0, $8, $BACKSLASH, $u, $d, $f, $4, $5, $DQ ], ascii: true); check([0x12345], [$DQ, 55304, 57157, $DQ], utf8: true); }); test('unpaired-surrogate', () { // (0xD834, 0xDD1E) = 0x1D11E // Strings containing unpaired surrogates must be encoded to prevent // problems with the utf8 file-level encoding. check([0xD834], [$DQ, 0xD834, $DQ]); // Legacy escapedString broken. check([0xD834], [$DQ, $BACKSLASH, $u, $d, $8, $3, $4, $DQ], ascii: true); check([0xD834], [$DQ, $BACKSLASH, $u, $d, $8, $3, $4, $DQ], utf8: true); check([0xDD1E], [$DQ, 0xDD1E, $DQ]); // Legacy escapedString broken. check([0xDD1E], [$DQ, $BACKSLASH, $u, $d, $d, $1, $e, $DQ], ascii: true); check([0xDD1E], [$DQ, $BACKSLASH, $u, $d, $d, $1, $e, $DQ], utf8: true); check([0xD834, $A], [$DQ, 0xD834, $A, $DQ]); // Legacy escapedString broken. check([0xD834, $A], [$DQ, $BACKSLASH, $u, $d, $8, $3, $4, $A, $DQ], ascii: true); check([0xD834, $A], [$DQ, $BACKSLASH, $u, $d, $8, $3, $4, $A, $DQ], utf8: true); check([0xD834, 0xDD1E], [$DQ, 0xD834, 0xDD1E, $DQ]); // Legacy ok. check([ 0xD834, 0xDD1E ], [ $DQ, $BACKSLASH, $u, $d, $8, $3, $4, $BACKSLASH, $u, $d, $d, $1, $e, $DQ ], ascii: true); check([0xD834, 0xDD1E], r'''"\ud834\udd1e"''', ascii: true); check([0xD834, 0xDD1E], [$DQ, 0xD834, 0xDD1E, $DQ], utf8: true); }); }