1use tree_sitter_language::LanguageFn;
31
32extern "C" {
33 fn tree_sitter_htmlx() -> *const ();
34}
35
36pub const LANGUAGE: LanguageFn = unsafe { LanguageFn::from_raw(tree_sitter_htmlx) };
38
39pub fn language() -> tree_sitter::Language {
41 LANGUAGE.into()
42}
43
44pub const HIGHLIGHTS_QUERY: &str = include_str!("../queries/highlights.scm");
46
47pub const NODE_TYPES: &str = include_str!("../src/node-types.json");
49
50#[cfg(test)]
51mod tests {
52 use super::*;
53
54 #[test]
55 fn test_can_load_grammar() {
56 let mut parser = tree_sitter::Parser::new();
57 parser
58 .set_language(&LANGUAGE.into())
59 .expect("Failed to load HTMLX grammar");
60 }
61
62 #[test]
63 fn test_parse_simple_html() {
64 let mut parser = tree_sitter::Parser::new();
65 parser.set_language(&LANGUAGE.into()).unwrap();
66
67 let source = "<div>Hello</div>";
68 let tree = parser.parse(source, None).unwrap();
69
70 assert!(!tree.root_node().has_error());
71 assert_eq!(tree.root_node().kind(), "document");
72 }
73
74 #[test]
75 fn test_parse_expression() {
76 let mut parser = tree_sitter::Parser::new();
77 parser.set_language(&LANGUAGE.into()).unwrap();
78
79 let source = "<div>{name}</div>";
80 let tree = parser.parse(source, None).unwrap();
81
82 assert!(!tree.root_node().has_error());
83 }
84
85 #[test]
86 fn test_parse_expression_attribute() {
87 let mut parser = tree_sitter::Parser::new();
88 parser.set_language(&LANGUAGE.into()).unwrap();
89
90 let source = r#"<input value={text} />"#;
91 let tree = parser.parse(source, None).unwrap();
92
93 assert!(!tree.root_node().has_error());
94 }
95
96 #[test]
97 fn test_parse_shorthand_attribute() {
98 let mut parser = tree_sitter::Parser::new();
99 parser.set_language(&LANGUAGE.into()).unwrap();
100
101 let source = r#"<div {hidden} {id}></div>"#;
102 let tree = parser.parse(source, None).unwrap();
103
104 assert!(!tree.root_node().has_error());
105 }
106
107 #[test]
108 fn test_parse_spread_attribute() {
109 let mut parser = tree_sitter::Parser::new();
110 parser.set_language(&LANGUAGE.into()).unwrap();
111
112 let source = r#"<Component {...props} />"#;
113 let tree = parser.parse(source, None).unwrap();
114
115 assert!(!tree.root_node().has_error());
116 }
117
118 #[test]
119 fn test_parse_directive_attribute() {
120 let mut parser = tree_sitter::Parser::new();
121 parser.set_language(&LANGUAGE.into()).unwrap();
122
123 let source = r#"<input bind:value={name} on:input={handleInput} />"#;
124 let tree = parser.parse(source, None).unwrap();
125
126 assert!(!tree.root_node().has_error());
127 }
128
129 #[test]
130 fn test_parse_nested_expressions() {
131 let mut parser = tree_sitter::Parser::new();
132 parser.set_language(&LANGUAGE.into()).unwrap();
133
134 let source = r#"<div>{items.map(item => item.name)}</div>"#;
135 let tree = parser.parse(source, None).unwrap();
136
137 assert!(!tree.root_node().has_error());
138 }
139}