//! The embedded TOML and TypeScript grammars: real samples highlight every expected //! kind, hostile bodies return quickly without panicking, and known labels get no //! suggestion. use std::time::Instant; use notescraft_syntax::{Highlighter, TokenKind, suggest_language}; /// A realistic TOML document: comments, bare keys, strings of every kind, numbers, /// booleans, dates, tables, arrays and an inline table. const TOML: &str = r#"# NotesCraft configuration title = "NotesCraft" port = 8080 enabled = true ratio = 0.75 big = 1_000_000 hex = 0xDEAD_beef label = 'literal string' story = """ A multi-line basic string.""" updated = 1979-05-27T07:32:00Z tags = ["notes", "craft", 42] [server] host = "127.0.0.1" timeout = 12.5 [[plugins]] name = "graph" inline = { a = 1, b = "two" } "#; /// A realistic TypeScript module: comments, strings, a template literal, numbers, /// keywords, types and functions. const TS: &str = r#"// NotesCraft engine demo /* Block comment spanning lines */ interface Command { id: string; run(): boolean; } enum Kind { Note, Canvas } class Engine implements Command { id = "engine"; run(): boolean { const count = 42; let name: string = `demo ${this.id}`; if (count > 0) return true; return false; } } function boot(): void { const engine = new Engine(); console.log(engine.run()); } "#; /// The kinds that appear anywhere in `body` highlighted as `language`. fn kinds(language: &str, body: &str) -> Vec { let Some(mut highlighter) = Highlighter::new(language, body) else { panic!("{language} should be known") }; let lines = body.split_inclusive('\n').count(); highlighter.lines(0..lines).lines.iter().flatten().map(|span| span.kind).collect() } #[test] fn toml_sample_shows_comment_string_number_keyword_and_property() { let found = kinds("toml", TOML); for want in [TokenKind::Comment, TokenKind::String, TokenKind::Number, TokenKind::Keyword, TokenKind::Property] { assert!(found.contains(&want), "{want:?} missing from {found:?}"); } } #[test] fn typescript_sample_shows_comment_string_number_keyword_type_and_function() { let found = kinds("ts", TS); for want in [TokenKind::Comment, TokenKind::String, TokenKind::Number, TokenKind::Keyword, TokenKind::Type, TokenKind::Function] { assert!(found.contains(&want), "{want:?} missing from {found:?}"); } } #[test] fn hostile_bodies_return_without_panicking_within_three_seconds() { let start = Instant::now(); let bracket_flood = "[".repeat(50_000); let megabyte_line = "[".repeat(1024 * 1024); let unterminated_multiline = format!("story = \"\"\"\n{}", "still a string\n".repeat(40)); let unterminated_template = format!("const s = `open\n{}\n", "${ expr } and ${ `nested".repeat(20)); for (language, body) in [ ("toml", bracket_flood.as_str()), ("ts", bracket_flood.as_str()), ("toml", megabyte_line.as_str()), ("ts", megabyte_line.as_str()), ("toml", unterminated_multiline.as_str()), ("ts", unterminated_template.as_str()), ] { let Some(mut highlighter) = Highlighter::new(language, body) else { panic!("{language} should accept a hostile body") }; let lines = body.split_inclusive('\n').count(); let _ = highlighter.lines(0..lines); } assert!(start.elapsed().as_secs() < 3, "hostile bodies took {:?}", start.elapsed()); } #[test] fn the_embedded_labels_are_known_so_nothing_is_suggested() { assert_eq!(suggest_language("toml"), None); assert_eq!(suggest_language("ts"), None); assert_eq!(suggest_language("typescript"), None); }