@@ -12,20 +12,6 @@ use tree_sitter::{allocations, LogType, Node, Parser, Tree};
1212
1313const EDIT_COUNT : usize = 3 ;
1414const TRIAL_COUNT : usize = 10 ;
15- const LANGUAGES : & ' static [ & ' static str ] = & [
16- "bash" ,
17- "c" ,
18- "cpp" ,
19- "embedded-template" ,
20- "go" ,
21- "html" ,
22- "javascript" ,
23- "json" ,
24- "php" ,
25- "python" ,
26- "ruby" ,
27- "rust" ,
28- ] ;
2915
3016lazy_static ! {
3117 static ref LOG_ENABLED : bool = env:: var( "TREE_SITTER_TEST_ENABLE_LOG" ) . is_ok( ) ;
@@ -36,7 +22,11 @@ lazy_static! {
3622 . map( |s| usize :: from_str_radix( & s, 10 ) . unwrap( ) )
3723 . ok( ) ;
3824 pub static ref SEED : usize = env:: var( "TREE_SITTER_TEST_SEED" )
39- . map( |s| usize :: from_str_radix( & s, 10 ) . unwrap( ) )
25+ . map( |s| {
26+ let seed = usize :: from_str_radix( & s, 10 ) . unwrap( ) ;
27+ eprintln!( "\n \n Random seed: {}\n " , * SEED ) ;
28+ seed
29+ } )
4030 . unwrap_or(
4131 time:: SystemTime :: now( )
4232 . duration_since( time:: UNIX_EPOCH )
@@ -46,40 +36,95 @@ lazy_static! {
4636}
4737
4838#[ test]
49- fn test_real_language_corpus_files ( ) {
50- eprintln ! ( "\n \n Random seed: {}\n " , * SEED ) ;
39+ fn test_bash_corpus ( ) {
40+ test_language_corpus ( "bash" ) ;
41+ }
42+
43+ #[ test]
44+ fn test_c_corpus ( ) {
45+ test_language_corpus ( "c" ) ;
46+ }
47+
48+ #[ test]
49+ fn test_cpp_corpus ( ) {
50+ test_language_corpus ( "cpp" ) ;
51+ }
52+
53+ #[ test]
54+ fn test_embedded_template_corpus ( ) {
55+ test_language_corpus ( "embedded-template" ) ;
56+ }
57+
58+ #[ test]
59+ fn test_go_corpus ( ) {
60+ test_language_corpus ( "go" ) ;
61+ }
62+
63+ #[ test]
64+ fn test_html_corpus ( ) {
65+ test_language_corpus ( "html" ) ;
66+ }
67+
68+ #[ test]
69+ fn test_javascript_corpus ( ) {
70+ test_language_corpus ( "javascript" ) ;
71+ }
72+
73+ #[ test]
74+ fn test_json_corpus ( ) {
75+ test_language_corpus ( "json" ) ;
76+ }
77+
78+ #[ test]
79+ fn test_php_corpus ( ) {
80+ test_language_corpus ( "php" ) ;
81+ }
82+
83+ #[ test]
84+ fn test_python_corpus ( ) {
85+ test_language_corpus ( "python" ) ;
86+ }
87+
88+ #[ test]
89+ fn test_ruby_corpus ( ) {
90+ test_language_corpus ( "ruby" ) ;
91+ }
92+
93+ #[ test]
94+ fn test_rust_corpus ( ) {
95+ test_language_corpus ( "rust" ) ;
96+ }
97+
98+ fn test_language_corpus ( language_name : & str ) {
99+ if let Some ( language_filter) = LANGUAGE_FILTER . as_ref ( ) {
100+ if language_filter != language_name {
101+ return ;
102+ }
103+ }
104+
51105 let grammars_dir = fixtures_dir ( ) . join ( "grammars" ) ;
52106 let error_corpus_dir = fixtures_dir ( ) . join ( "error_corpus" ) ;
53107
54108 let mut failure_count = 0 ;
55- for language_name in LANGUAGES . iter ( ) . cloned ( ) {
56- if let Some ( filter) = LANGUAGE_FILTER . as_ref ( ) {
57- if language_name != filter. as_str ( ) {
58- continue ;
59- }
60- }
61-
62- let language = get_language ( language_name) ;
63- let mut corpus_dir = grammars_dir. join ( language_name) . join ( "corpus" ) ;
64- if !corpus_dir. is_dir ( ) {
65- corpus_dir = grammars_dir. join ( language_name) . join ( "test" ) . join ( "corpus" ) ;
66- }
67109
68- let error_corpus_file = error_corpus_dir . join ( & format ! ( "{}_errors.txt" , language_name) ) ;
69- let main_tests = parse_tests ( & corpus_dir ) . unwrap ( ) ;
70- let error_tests = parse_tests ( & error_corpus_file ) . unwrap_or ( TestEntry :: default ( ) ) ;
71- let mut tests = flatten_tests ( main_tests ) ;
72- tests . extend ( flatten_tests ( error_tests ) ) ;
110+ let language = get_language ( language_name) ;
111+ let mut corpus_dir = grammars_dir . join ( language_name ) . join ( "corpus" ) ;
112+ if !corpus_dir . is_dir ( ) {
113+ corpus_dir = grammars_dir . join ( language_name ) . join ( "test" ) . join ( "corpus" ) ;
114+ }
73115
74- if !tests. is_empty ( ) {
75- eprintln ! ( "language: {:?}" , language_name) ;
76- }
116+ let error_corpus_file = error_corpus_dir. join ( & format ! ( "{}_errors.txt" , language_name) ) ;
117+ let main_tests = parse_tests ( & corpus_dir) . unwrap ( ) ;
118+ let error_tests = parse_tests ( & error_corpus_file) . unwrap_or ( TestEntry :: default ( ) ) ;
119+ let mut tests = flatten_tests ( main_tests) ;
120+ tests. extend ( flatten_tests ( error_tests) ) ;
77121
78- for ( example_name, input, expected_output, has_fields) in tests {
79- eprintln ! ( " example: {:?}" , example_name) ;
122+ for ( example_name, input, expected_output, has_fields) in tests {
123+ println ! ( " {} example - {}" , language_name , example_name) ;
80124
81- if TRIAL_FILTER . map_or ( true , |t| t == 0 ) {
82- allocations:: start_recording ( ) ;
125+ let trial = 0 ;
126+ if TRIAL_FILTER . map_or ( true , |t| t == trial) {
127+ let passed = allocations:: record ( || {
83128 let mut log_session = None ;
84129 let mut parser = get_parser ( & mut log_session, "log.html" ) ;
85130 parser. set_language ( language) . unwrap ( ) ;
@@ -88,28 +133,36 @@ fn test_real_language_corpus_files() {
88133 if !has_fields {
89134 actual_output = strip_sexp_fields ( actual_output) ;
90135 }
91- drop ( tree) ;
92- drop ( parser) ;
93- if actual_output != expected_output {
136+ if actual_output == expected_output {
137+ true
138+ } else {
139+ println ! (
140+ "Incorrect initial parse for {} - {}" ,
141+ language_name, example_name,
142+ ) ;
94143 print_diff_key ( ) ;
95144 print_diff ( & actual_output, & expected_output) ;
96145 println ! ( "" ) ;
97- failure_count += 1 ;
98- continue ;
146+ false
99147 }
100- allocations:: stop_recording ( ) ;
148+ } ) ;
149+
150+ if !passed {
151+ failure_count += 1 ;
152+ continue ;
101153 }
154+ }
102155
103- let mut parser = Parser :: new ( ) ;
104- parser. set_language ( language) . unwrap ( ) ;
105- let tree = parser. parse ( & input, None ) . unwrap ( ) ;
106- drop ( parser) ;
156+ let mut parser = Parser :: new ( ) ;
157+ parser. set_language ( language) . unwrap ( ) ;
158+ let tree = parser. parse ( & input, None ) . unwrap ( ) ;
159+ drop ( parser) ;
107160
108- for trial in 1 ..=TRIAL_COUNT {
109- if TRIAL_FILTER . map_or ( true , |filter| filter == trial) {
110- let mut rand = Rand :: new ( * SEED + trial) ;
161+ for trial in 1 ..=TRIAL_COUNT {
162+ if TRIAL_FILTER . map_or ( true , |filter| filter == trial) {
163+ let mut rand = Rand :: new ( * SEED + trial) ;
111164
112- allocations:: start_recording ( ) ;
165+ let passed = allocations:: record ( || {
113166 let mut log_session = None ;
114167 let mut parser = get_parser ( & mut log_session, "log.html" ) ;
115168 parser. set_language ( language) . unwrap ( ) ;
@@ -140,8 +193,7 @@ fn test_real_language_corpus_files() {
140193 "\n Unexpected scope change in trial {}\n {}\n \n " ,
141194 trial, message
142195 ) ;
143- failure_count += 1 ;
144- break ;
196+ return false ;
145197 }
146198
147199 // Undo all of the edits and re-parse again.
@@ -168,8 +220,7 @@ fn test_real_language_corpus_files() {
168220 print_diff_key ( ) ;
169221 print_diff ( & actual_output, & expected_output) ;
170222 println ! ( "" ) ;
171- failure_count += 1 ;
172- break ;
223+ return false ;
173224 }
174225
175226 // Check that the edited tree is consistent.
@@ -179,21 +230,22 @@ fn test_real_language_corpus_files() {
179230 "Unexpected scope change in trial {}\n {}\n \n " ,
180231 trial, message
181232 ) ;
182- failure_count += 1 ;
183- break ;
233+ return false ;
184234 }
185235
186- drop ( tree) ;
187- drop ( tree2) ;
188- drop ( tree3) ;
189- drop ( parser) ;
190- allocations:: stop_recording ( ) ;
236+ true
237+ } ) ;
238+
239+ if !passed {
240+ failure_count += 1 ;
241+ break ;
191242 }
192243 }
193244 }
194245 }
246+
195247 if failure_count > 0 {
196- panic ! ( "{} corpus tests failed" , failure_count) ;
248+ panic ! ( "{} {} corpus tests failed" , failure_count, language_name ) ;
197249 }
198250}
199251
@@ -271,26 +323,29 @@ fn test_feature_corpus_files() {
271323 for ( name, input, expected_output, has_fields) in tests {
272324 eprintln ! ( " example: {:?}" , name) ;
273325
274- allocations:: start_recording ( ) ;
275- let mut log_session = None ;
276- let mut parser = get_parser ( & mut log_session, "log.html" ) ;
277- parser. set_language ( language) . unwrap ( ) ;
278- let tree = parser. parse ( & input, None ) . unwrap ( ) ;
279- let mut actual_output = tree. root_node ( ) . to_sexp ( ) ;
280- if !has_fields {
281- actual_output = strip_sexp_fields ( actual_output) ;
282- }
326+ let passed = allocations:: record ( || {
327+ let mut log_session = None ;
328+ let mut parser = get_parser ( & mut log_session, "log.html" ) ;
329+ parser. set_language ( language) . unwrap ( ) ;
330+ let tree = parser. parse ( & input, None ) . unwrap ( ) ;
331+ let mut actual_output = tree. root_node ( ) . to_sexp ( ) ;
332+ if !has_fields {
333+ actual_output = strip_sexp_fields ( actual_output) ;
334+ }
335+ if actual_output == expected_output {
336+ true
337+ } else {
338+ print_diff_key ( ) ;
339+ print_diff ( & actual_output, & expected_output) ;
340+ println ! ( "" ) ;
341+ false
342+ }
343+ } ) ;
283344
284- drop ( tree) ;
285- drop ( parser) ;
286- if actual_output != expected_output {
287- print_diff_key ( ) ;
288- print_diff ( & actual_output, & expected_output) ;
289- println ! ( "" ) ;
345+ if !passed {
290346 failure_count += 1 ;
291347 continue ;
292348 }
293- allocations:: stop_recording ( ) ;
294349 }
295350 }
296351 }
@@ -381,7 +436,12 @@ fn get_parser(session: &mut Option<util::LogSession>, log_filename: &str) -> Par
381436}
382437
383438fn flatten_tests ( test : TestEntry ) -> Vec < ( String , Vec < u8 > , String , bool ) > {
384- fn helper ( test : TestEntry , prefix : & str , result : & mut Vec < ( String , Vec < u8 > , String , bool ) > ) {
439+ fn helper (
440+ test : TestEntry ,
441+ is_root : bool ,
442+ prefix : & str ,
443+ result : & mut Vec < ( String , Vec < u8 > , String , bool ) > ,
444+ ) {
385445 match test {
386446 TestEntry :: Example {
387447 mut name,
@@ -403,17 +463,17 @@ fn flatten_tests(test: TestEntry) -> Vec<(String, Vec<u8>, String, bool)> {
403463 TestEntry :: Group {
404464 mut name, children, ..
405465 } => {
406- if !prefix. is_empty ( ) {
466+ if !is_root && ! prefix. is_empty ( ) {
407467 name. insert_str ( 0 , " - " ) ;
408468 name. insert_str ( 0 , prefix) ;
409469 }
410470 for child in children {
411- helper ( child, & name, result) ;
471+ helper ( child, false , & name, result) ;
412472 }
413473 }
414474 }
415475 }
416476 let mut result = Vec :: new ( ) ;
417- helper ( test, "" , & mut result) ;
477+ helper ( test, true , "" , & mut result) ;
418478 result
419479}
0 commit comments