extern crate test; use super::{ state::{lex, lex_module_errors, lex_tokens, with_lexer}, *, }; use crate::{ error::{Error, SyntaxError}, lexer::state::lex_errors, }; use std::{ops::Range, str}; use swc_common::SyntaxContext; use test::{black_box, Bencher}; fn sp(r: Range) -> Span { Span { lo: BytePos(r.start as u32), hi: BytePos(r.end as u32), ctxt: Default::default(), } } trait LineBreak: Into { fn lb(self) -> TokenAndSpan { TokenAndSpan { had_line_break: true, ..self.into() } } } impl LineBreak for TokenAndSpan {} trait SpanRange: Sized { fn into_span(self) -> Span; } impl SpanRange for usize { fn into_span(self) -> Span { Span::new( BytePos(self as _), BytePos((self + 1usize) as _), Default::default(), ) } } impl SpanRange for Span { fn into_span(self) -> Span { self } } impl SpanRange for Range { fn into_span(self) -> Span { Span::new( BytePos(self.start as _), BytePos(self.end as _), Default::default(), ) } } trait WithSpan: Sized { fn span(self, span: R) -> TokenAndSpan where R: SpanRange, { TokenAndSpan { token: self.into_token(), had_line_break: false, span: span.into_span(), } } fn into_token(self) -> Token; } impl WithSpan for Token { fn into_token(self) -> Token { self } } impl WithSpan for usize { fn into_token(self) -> Token { Num(self as f64) } } impl WithSpan for f64 { fn into_token(self) -> Token { Num(self) } } impl<'a> WithSpan for &'a str { fn into_token(self) -> Token { Word(Word::Ident(self.into())) } } impl WithSpan for Keyword { fn into_token(self) -> Token { Word(Word::Keyword(self)) } } impl WithSpan for Word { fn into_token(self) -> Token { Word(self) } } impl WithSpan for BinOpToken { fn into_token(self) -> Token { BinOp(self) } } impl WithSpan for AssignOpToken { fn into_token(self) -> Token { AssignOp(self) } } //#[test] //fn module_legacy_octal() { // assert_eq!( // lex_module(Syntax::default(), "01"), // vec![Token::Error(Error { // span: sp(0..2), // error: SyntaxError::LegacyOctal, // }) // .span(0..2) // .lb(),] // ); //} #[test] fn module_legacy_decimal() { assert_eq!( lex_module_errors(Syntax::default(), "08"), vec![Error { error: Box::new((sp(0..2), SyntaxError::LegacyDecimal)), }] ); } #[test] fn module_legacy_comment_1() { assert_eq!( lex_module_errors(Syntax::default(), ""), vec![Error { error: Box::new((sp(0..3), SyntaxError::LegacyCommentInModule)), }] ) } #[test] fn test262_lexer_error_0001() { assert_eq!( lex(Syntax::default(), "123..a(1)"), vec![ 123f64.span(0..4).lb(), Dot.span(4..5), "a".span(5..6), LParen.span(6..7), 1.span(7..8), RParen.span(8..9), ], ) } #[test] fn test262_lexer_error_0002() { assert_eq!( lex(Syntax::default(), r#"'use\x20strict';"#), vec![ Token::Str { value: "use strict".into(), has_escape: true, } .span(0..15) .lb(), Semi.span(15..16), ] ); } #[test] fn test262_lexer_error_0003() { assert_eq!( lex(Syntax::default(), r#"\u0061"#), vec!["a".span(0..6).lb()] ); } #[test] fn test262_lexer_error_0004() { assert_eq!( lex_tokens(Syntax::default(), "+{} / 1"), vec![tok!('+'), tok!('{'), tok!('}'), tok!('/'), 1.into_token()] ); } #[test] fn ident_escape_unicode() { assert_eq!( lex(Syntax::default(), r#"a\u0061"#), vec!["aa".span(0..7).lb()] ); } #[test] fn ident_escape_unicode_2() { assert_eq!(lex(Syntax::default(), "℘℘"), vec!["℘℘".span(0..6).lb()]); assert_eq!( lex(Syntax::default(), r#"℘\u2118"#), vec!["℘℘".span(0..9).lb()] ); } #[test] fn tpl_multiline() { assert_eq!( lex_tokens( Syntax::default(), "`this is multiline`" ), vec![ tok!('`'), Token::Template { cooked: Ok("this\nis\nmultiline".into()), raw: "this\nis\nmultiline".into(), has_escape: false }, tok!('`'), ] ); } #[test] fn tpl_raw_unicode_escape() { assert_eq!( lex_tokens(Syntax::default(), r"`\u{0010}`"), vec![ tok!('`'), Token::Template { cooked: Ok(format!("{}", '\u{0010}').into()), raw: "\\u{0010}".into(), has_escape: true }, tok!('`'), ] ); } #[test] fn tpl_invalid_unicode_escape() { assert_eq!( lex_tokens(Syntax::default(), r"`\unicode`"), vec![ tok!('`'), Token::Template { cooked: Err(Error { error: Box::new(( Span { lo: BytePos(1), hi: BytePos(3), ctxt: SyntaxContext::empty() }, SyntaxError::ExpectedHexChars { count: 4 } )) }), raw: "\\unicode".into(), has_escape: true }, tok!('`'), ] ); assert_eq!( lex_tokens(Syntax::default(), r"`\u{`"), vec![ tok!('`'), Token::Template { cooked: Err(Error { error: Box::new(( Span { lo: BytePos(4), hi: BytePos(4), ctxt: SyntaxContext::empty() }, SyntaxError::InvalidCodePoint )) }), raw: "\\u{".into(), has_escape: true }, tok!('`'), ] ); assert_eq!( lex_tokens(Syntax::default(), r"`\xhex`"), vec![ tok!('`'), Token::Template { cooked: Err(Error { error: Box::new(( Span { lo: BytePos(1), hi: BytePos(3), ctxt: SyntaxContext::empty() }, SyntaxError::ExpectedHexChars { count: 2 } )) }), raw: "\\xhex".into(), has_escape: true }, tok!('`'), ] ); } #[test] fn str_escape() { assert_eq!( lex_tokens(Syntax::default(), r#"'\n'"#), vec![Token::Str { value: "\n".into(), has_escape: true }] ); } #[test] fn str_escape_2() { assert_eq!( lex_tokens(Syntax::default(), r#"'\\n'"#), vec![Token::Str { value: "\\n".into(), has_escape: true }] ); } #[test] fn str_escape_3() { assert_eq!( lex_tokens(Syntax::default(), r#"'\x00'"#), vec![Token::Str { value: "\x00".into(), has_escape: true }] ); } #[test] fn str_escape_hex() { assert_eq!( lex(Syntax::default(), r#"'\x61'"#), vec![Token::Str { value: "a".into(), has_escape: true, } .span(0..6) .lb(),] ); } #[test] fn str_escape_octal() { assert_eq!( lex(Syntax::default(), r#"'Hello\012World'"#), vec![Token::Str { value: "Hello\nWorld".into(), has_escape: true, } .span(0..16) .lb(),] ) } #[test] fn str_escape_unicode_long() { assert_eq!( lex(Syntax::default(), r#"'\u{00000000034}'"#), vec![Token::Str { value: "4".into(), has_escape: true, } .span(0..17) .lb(),] ); } #[test] fn regexp_unary_void() { assert_eq!( lex(Syntax::default(), "void /test/"), vec![ Void.span(0..4).lb(), Regex("test".into(), "".into()).span(5..11), ] ); assert_eq!( lex(Syntax::default(), "void (/test/)"), vec![ Void.span(0..4).lb(), LParen.span(5..6), Regex("test".into(), "".into()).span(6..12), RParen.span(12..13), ] ); } #[test] fn non_regexp_unary_plus() { assert_eq!( lex(Syntax::default(), "+{} / 1"), vec![ tok!('+').span(0..1).lb(), tok!('{').span(1..2), tok!('}').span(2..3), tok!('/').span(4..5), 1.span(6..7), ] ); } // ---------- #[test] fn paren_semi() { assert_eq!( lex(Syntax::default(), "();"), vec![LParen.span(0).lb(), RParen.span(1), Semi.span(2)] ); } #[test] fn ident_paren() { assert_eq!( lex(Syntax::default(), "a(bc);"), vec![ "a".span(0).lb(), LParen.span(1), "bc".span(2..4), RParen.span(4), Semi.span(5), ] ); } #[test] fn read_word() { assert_eq!( lex(Syntax::default(), "a b c"), vec!["a".span(0).lb(), "b".span(2), "c".span(4)] ) } #[test] fn simple_regex() { assert_eq!( lex(Syntax::default(), "x = /42/i"), vec![ "x".span(0).lb(), Assign.span(2), Regex("42".into(), "i".into(),).span(4..9), ], ); assert_eq!( lex(Syntax::default(), "/42/"), vec![Regex("42".into(), "".into()).span(0..4).lb(),] ); } #[test] fn complex_regex() { assert_eq!( lex_tokens(Syntax::default(), "f(); function foo() {} /42/i"), vec![ Word(Word::Ident("f".into())), LParen, RParen, Semi, Word(Word::Keyword(Function)), Word(Word::Ident("foo".into())), LParen, RParen, LBrace, RBrace, Regex("42".into(), "i".into(),), ] ) } #[test] fn simple_div() { assert_eq!( lex(Syntax::default(), "a / b"), vec!["a".span(0).lb(), Div.span(2), "b".span(4)], ); } #[test] fn complex_divide() { assert_eq!( lex_tokens(Syntax::default(), "x = function foo() {} /a/i"), vec![ Word(Word::Ident("x".into())), AssignOp(Assign), Word(Word::Keyword(Function)), Word(Word::Ident("foo".into())), LParen, RParen, LBrace, RBrace, BinOp(Div), Word(Word::Ident("a".into())), BinOp(Div), Word(Word::Ident("i".into())), ], "/ should be parsed as div operator" ) } // ---------- Tests from tc39 spec #[test] fn spec_001() { let expected = vec![ Word(Word::Ident("a".into())), AssignOp(Assign), Word(Word::Ident("b".into())), BinOp(Div), Word(Word::Ident("hi".into())), BinOp(Div), Word(Word::Ident("g".into())), Dot, Word(Word::Ident("exec".into())), LParen, Word(Word::Ident("c".into())), RParen, Dot, Word(Word::Ident("map".into())), LParen, Word(Word::Ident("d".into())), RParen, Semi, ]; assert_eq!( lex_tokens( Syntax::default(), "a = b /hi/g.exec(c).map(d);" ), expected ); assert_eq!( lex_tokens(Syntax::default(), "a = b / hi / g.exec(c).map(d);"), expected ); } // ---------- Tests ported from esprima #[test] fn after_if() { assert_eq!( lex(Syntax::default(), "if(x){} /y/.test(z)"), vec![ Keyword::If.span(0..2).lb(), LParen.span(2), "x".span(3), RParen.span(4), LBrace.span(5), RBrace.span(6), Regex("y".into(), "".into()).span(8..11), Dot.span(11), "test".span(12..16), LParen.span(16), "z".span(17), RParen.span(18), ], ) } // #[test] // #[ignore] // fn leading_comment() { // assert_eq!( // vec![ // BlockComment(" hello world ".into()).span(0..17), // Regex("42".into(), "".into()).span(17..21), // ], // lex(Syntax::default(), "/* hello world */ /42/") // ) // } // #[test] // #[ignore] // fn line_comment() { // assert_eq!( // vec![ // Keyword::Var.span(0..3), // "answer".span(4..10), // Assign.span(11), // 42.span(13..15), // LineComment(" the Ultimate".into()).span(17..32), // ], // lex(Syntax::default(), "var answer = 42 // the Ultimate"), // ) // } #[test] fn migrated_0002() { assert_eq!( lex(Syntax::default(), "tokenize(/42/)"), vec![ "tokenize".span(0..8).lb(), LParen.span(8), Regex("42".into(), "".into()).span(9..13), RParen.span(13), ], ) } #[test] fn migrated_0003() { assert_eq!( lex(Syntax::default(), "(false) /42/"), vec![ LParen.span(0).lb(), Word::False.span(1..6), RParen.span(6), Div.span(8), 42.span(9..11), Div.span(11), ], ) } #[test] fn migrated_0004() { assert_eq!( lex(Syntax::default(), "function f(){} /42/"), vec![ Function.span(0..8).lb(), "f".span(9), LParen.span(10), RParen.span(11), LBrace.span(12), RBrace.span(13), Regex("42".into(), "".into()).span(15..19), ] ); } // This test seems wrong. // // #[test] // fn migrated_0005() { // assert_eq!( // vec![ // Function.span(0..8), // LParen.span(9), // RParen.span(10), // LBrace.span(11), // RBrace.span(12), // Div.span(13), // 42.span(14..16), // ], // lex(Syntax::default(), "function (){} /42") // ); // } #[test] fn migrated_0006() { // This test seems wrong. // assert_eq!( // vec![LBrace.span(0).lb(), RBrace.span(1), Div.span(3), 42.span(4..6)], // lex(Syntax::default(), "{} /42") // ) assert_eq!( lex(Syntax::default(), "{} /42/"), vec![ LBrace.span(0).lb(), RBrace.span(1), Regex("42".into(), "".into()).span(3..7), ], ) } #[test] fn str_lit() { assert_eq!( lex_tokens(Syntax::default(), "'abcde'"), vec![Token::Str { value: "abcde".into(), has_escape: false, }], ); assert_eq!( lex_tokens(Syntax::default(), "'\\\nabc'"), vec![Token::Str { value: "abc".into(), has_escape: true, }] ); } #[test] fn tpl_empty() { assert_eq!( lex_tokens(Syntax::default(), r#"``"#), vec![ tok!('`'), Template { raw: "".into(), cooked: Ok("".into()), has_escape: false }, tok!('`') ] ) } #[test] fn tpl() { assert_eq!( lex_tokens(Syntax::default(), r#"`${a}`"#), vec![ tok!('`'), Template { raw: "".into(), cooked: Ok("".into()), has_escape: false }, tok!("${"), Word(Word::Ident("a".into())), tok!('}'), Template { raw: "".into(), cooked: Ok("".into()), has_escape: false }, tok!('`'), ] ) } #[test] fn comment() { assert_eq!( lex( Syntax::default(), "// foo a" ), vec![TokenAndSpan { token: Word(Word::Ident("a".into())), span: sp(7..8), // first line had_line_break: true }] ); } #[test] fn comment_2() { assert_eq!( lex( Syntax::default(), "// foo // bar a" ), vec![TokenAndSpan { token: Word(Word::Ident("a".into())), span: sp(14..15), // first line had_line_break: true }] ); } #[test] fn jsx_01() { assert_eq!( lex_tokens( crate::Syntax::Es(crate::EsConfig { jsx: true, ..Default::default() }), "" ), vec![ Token::JSXTagStart, Token::JSXName { name: "a".into() }, tok!('/'), Token::JSXTagEnd, ] ); } #[test] fn jsx_02() { assert_eq!( lex_tokens( crate::Syntax::Es(crate::EsConfig { jsx: true, ..Default::default() }), "foo" ), vec![ Token::JSXTagStart, Token::JSXName { name: "a".into() }, Token::JSXTagEnd, Token::JSXText { raw: "foo".into() }, Token::JSXTagStart, tok!('/'), Token::JSXName { name: "a".into() }, Token::JSXTagEnd, ] ); } #[test] fn jsx_03() { assert_eq!( lex_tokens( crate::Syntax::Es(crate::EsConfig { jsx: true, ..Default::default() }), "
" ), vec![ Token::JSXTagStart, Token::JSXName { name: "a".into() }, Token::JSXTagEnd, // Token::JSXTagStart, Token::JSXName { name: "br".into() }, tok!('/'), Token::JSXTagEnd, // Token::JSXTagStart, tok!('/'), Token::JSXName { name: "a".into() }, Token::JSXTagEnd, ] ); } #[test] fn jsx_04() { assert_eq!( lex_tokens( crate::Syntax::Es(crate::EsConfig { jsx: true, ..Default::default() }), "yield " ), vec![ Token::Word(Word::Keyword(Yield)), Token::JSXTagStart, Token::JSXName { name: "a".into() }, Token::JSXTagEnd, // Token::JSXTagStart, tok!('/'), Token::JSXName { name: "a".into() }, Token::JSXTagEnd, ] ); } #[test] fn max_integer() { lex_tokens(crate::Syntax::default(), "1.7976931348623157e+308"); } #[test] fn shebang() { assert_eq!( lex_tokens(crate::Syntax::default(), "#!/usr/bin/env node",), vec![Token::Shebang("/usr/bin/env node".into())] ); } #[test] fn empty() { assert_eq!(lex_tokens(crate::Syntax::default(), "",), vec![]); } #[test] fn issue_191() { assert_eq!( lex_tokens( crate::Syntax::Es(crate::EsConfig { jsx: true, ..Default::default() }), "`${foo}`" ), vec![ tok!('`'), Token::Template { raw: "".into(), cooked: Ok("".into()), has_escape: false, }, tok!("${"), Token::Word(Word::Ident("foo".into())), tok!('}'), Token::Template { raw: "".into(), cooked: Ok("".into()), has_escape: false, }, tok!('`') ] ); } #[test] fn jsx_05() { assert_eq!( lex_tokens( crate::Syntax::Es(crate::EsConfig { jsx: true, ..Default::default() }), "{}" ), vec![ Token::JSXTagStart, Token::JSXName { name: "a".into() }, Token::JSXTagEnd, // tok!('{'), tok!('}'), // Token::JSXTagStart, tok!('/'), Token::JSXName { name: "a".into() }, Token::JSXTagEnd, ] ); } #[test] fn issue_299_01() { assert_eq!( lex_tokens( crate::Syntax::Es(crate::EsConfig { jsx: true, ..Default::default() }), "ABC;" ), vec![ Token::JSXTagStart, Token::JSXName { name: "Page".into() }, Token::JSXName { name: "num".into() }, tok!('='), Token::Str { value: "\\ ".into(), has_escape: true }, Token::JSXTagEnd, JSXText { raw: "ABC".into() }, JSXTagStart, tok!('/'), JSXName { name: "Page".into() }, JSXTagEnd, Semi, ] ); } #[test] fn issue_299_02() { assert_eq!( lex_tokens( crate::Syntax::Es(crate::EsConfig { jsx: true, ..Default::default() }), "ABC;" ), vec![ Token::JSXTagStart, Token::JSXName { name: "Page".into() }, Token::JSXName { name: "num".into() }, tok!('='), Token::Str { value: "\\\\".into(), has_escape: true }, Token::JSXTagEnd, JSXText { raw: "ABC".into() }, JSXTagStart, tok!('/'), JSXName { name: "Page".into() }, JSXTagEnd, Semi, ] ); } #[test] fn issue_316() { assert_eq!( lex_tokens(Default::default(), "'Hi\\r\\n..'"), vec![Token::Str { value: "Hi\r\n..".into(), has_escape: true }] ); } #[test] fn issue_401() { assert_eq!( lex_tokens(Default::default(), "'17' as const"), vec![ Token::Str { value: "17".into(), has_escape: false }, tok!("as"), tok!("const") ], ); } #[test] fn issue_481() { assert_eq!( lex_tokens( crate::Syntax::Es(crate::EsConfig { jsx: true, ..Default::default() }), " {foo}" ), vec![ Token::JSXTagStart, Token::JSXName { name: "span".into() }, Token::JSXTagEnd, JSXText { raw: " ".into() }, LBrace, Word(Word::Ident("foo".into())), RBrace, JSXTagStart, BinOp(Div), JSXName { name: "span".into() }, JSXTagEnd, ] ); } #[test] fn issue_915_1() { assert_eq!( lex_tokens( crate::Syntax::Es(crate::EsConfig { ..Default::default() }), r##"encode("\r\n")"## ), vec![ Word(Word::Ident("encode".into())), LParen, Token::Str { value: "\r\n".into(), has_escape: true }, RParen ] ); } #[bench] fn lex_colors_js(b: &mut Bencher) { b.bytes = include_str!("../../colors.js").len() as _; b.iter(|| { let _ = with_lexer( Syntax::default(), Default::default(), include_str!("../../colors.js"), |lexer| { for t in lexer { black_box(t); } Ok(()) }, ); }); } #[bench] fn lex_colors_ts(b: &mut Bencher) { b.bytes = include_str!("../../colors.js").len() as _; b.iter(|| { let _ = with_lexer( Syntax::Typescript(Default::default()), Default::default(), include_str!("../../colors.js"), |lexer| { for t in lexer { black_box(t); } Ok(()) }, ); }); } /// Benchmarks [Lexer] using [Iterator] interface. fn bench_simple(b: &mut Bencher, s: &str) { bench(b, Default::default(), s) } /// Benchmarks [Lexer] using [Iterator] interface. fn bench(b: &mut Bencher, syntax: Syntax, s: &str) { b.bytes = s.len() as _; b.iter(|| { let _ = with_lexer(syntax, Default::default(), s, |lexer| { for t in lexer { black_box(t); } Ok(()) }); }); } #[bench] fn lex_large_number(b: &mut Bencher) { bench_simple( b, "10000000000000000; 571293857289; 32147859245; 129478120974; 238597230957293; 542375984375; 349578395; 34857983412590716249; 1238570129; 123875102935;", ); } #[bench] fn lex_escaped_char(b: &mut Bencher) { bench_simple( b, "'\\x00\\01\\02\\03\\x00\\01\\02\\03\\x00\\01\\02\\03\\x00\\01\\02\\03\\x00\\01\\02\\03\\\ x00\\01\\02\\03\\x00\\01\\02\\03\\x00\\01\\02\\03\\x00\\01\\02\\03\\x00\\01\\02\\03\\x00\\ \ \01\\02\\03\\x00\\01\\02\\03\\x00\\01\\02\\03\\x00\\01\\02\\03\\x00\\01\\02\\03\\x00\\01\\ \02\\03'", ); } #[bench] fn lex_legacy_octal_lit(b: &mut Bencher) { bench_simple( b, "01756123617;01756123617;01756123617;01756123617;01756123617;01756123617;01756123617;\ 01756123617;01756123617;01756123617;01756123617;01756123617;01756123617;01756123617;\ 01756123617;01756123617;01756123617;01756123617;01756123617;01756123617;01756123617;\ 01756123617;01756123617;01756123617;01756123617;01756123617;01756123617;01756123617;\ 01756123617;01756123617;01756123617;01756123617;01756123617;01756123617;01756123617;\ 01756123617;01756123617;01756123617;01756123617;01756123617;01756123617;01756123617;\ 01756123617;01756123617;01756123617;01756123617;01756123617;01756123617;01756123617;\ 01756123617;01756123617;", ); } #[bench] fn lex_dec_lit(b: &mut Bencher) { bench_simple( b, "14389675923;14389675923;14389675923;14389675923;14389675923;14389675923;14389675923;\ 14389675923;14389675923;14389675923;14389675923;14389675923;14389675923;14389675923;\ 14389675923;14389675923;14389675923;14389675923;14389675923;14389675923;14389675923;\ 14389675923;14389675923;14389675923;14389675923;14389675923;14389675923;14389675923;\ 14389675923;14389675923;14389675923;14389675923;14389675923;14389675923;14389675923;\ 14389675923;14389675923;14389675923;14389675923;14389675923;14389675923;14389675923;\ 14389675923;14389675923;14389675923;", ); } #[bench] fn lex_ident(b: &mut Bencher) { bench_simple( b, "Lorem;Ipsum;is;simply;dummy;text;of;the;printing;and;typesetting;industry;Lorem;Ipsum;\ has;been;the;industry;s;standard;dummy;text;ever;since;the;1500s;when;an;unknown;printer;\ took;a;galley;of;type;and;scrambled;it;to;make;a;type;specimen;book;It;has;survived;not;\ only;five;centuries;but;also;the;leap;into;electronic;typesetting;remaining;essentially;\ unchanged;It;was;popularised;in;the;1960s;with;the;release;of;Letraset;sheets;containing;\ Lorem;Ipsum;passages;and;more;recently;with;desktop;publishing;software;like;Aldus;\ PageMaker;including;versions;of;Lorem;Ipsum", ); } #[bench] fn lex_regex(b: &mut Bencher) { bench_simple( b, "/Lorem/;/Ipsum/;/is/;/simply/;/dummy/;/text/;/of/;/the/;/printing;and/;/typesetting;\ industry;Lorem;Ipsum/;has;been/;the;industry/;s;standard/;/dummy;text/;", ); } #[bench] fn lex_long_ident(b: &mut Bencher) { bench_simple( b, "LoremIpsumissimplydummytextoftheprintingandtypesettingindustryLoremIpsum\ hasbeentheindustrysstandarddummytexteversincethe1500swhenanunknownprinter\ tookagalleyoftypeandscrambledittomakeatypespecimenbookIthassurvivednot\ onlyfivecenturiesbutalsotheleapintoelectronictypesettingremainingessentially\ unchangedItwaspopularisedinthe1960swiththereleaseofLetrasetsheetscontaining\ LoremIpsumpassagesandmorerecentlywithdesktoppublishingsoftwarelikeAldus\ PageMakerincludingversionsofLoremIpsum", ); } #[bench] fn lex_semicolons(b: &mut Bencher) { bench_simple( b, ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;", ); } #[test] fn issue_1272_1_ts() { let (tokens, errors) = lex_errors(crate::Syntax::Typescript(Default::default()), "\\u{16}"); assert_eq!(tokens.len(), 1); assert_ne!(errors, vec![]); } #[test] fn issue_1272_1_js() { let (tokens, errors) = lex_errors(crate::Syntax::Es(Default::default()), "\\u{16}"); assert_eq!(tokens.len(), 1); assert_ne!(errors, vec![]); } #[test] fn issue_1272_2_ts() { // Not recoverable yet let (tokens, errors) = lex_errors(crate::Syntax::Typescript(Default::default()), "\u{16}"); assert_eq!(tokens.len(), 1); assert_eq!(errors, vec![]); } #[test] fn issue_1272_2_js() { // Not recoverable yet let (tokens, errors) = lex_errors(crate::Syntax::Es(Default::default()), "\u{16}"); assert_eq!(tokens.len(), 1); assert_eq!(errors, vec![]); } #[test] #[ignore = "Raw token should be different. See https://github.com/denoland/deno/issues/9620"] fn normalize_tpl_carriage_return() { assert_eq!( lex_tokens(Syntax::default(), "`\r\n`"), lex_tokens(Syntax::default(), "`\n`") ); assert_eq!( lex_tokens(Syntax::default(), "`\r`"), lex_tokens(Syntax::default(), "`\n`") ); }