use fine::parser::SyntaxTree; use fine::tokens::Lines; use pretty_assertions::assert_eq; fn rebase_concrete(source_path: &str, dump: &str) { let contents = std::fs::read_to_string(source_path) .expect(&format!("unable to read input file {}", source_path)); let mut result = String::new(); let mut lines = contents.lines(); // Search for the "concrete:" section. let mut found_concrete_section = false; while let Some(line) = lines.next() { result.push_str(line); result.push_str("\n"); if line == "// concrete:" { found_concrete_section = true; break; } } if !found_concrete_section { panic!( "unable to locate the concrete section in {}. Is there a line that starts with '// concrete:'?", source_path ); } // We've found the section we care about, replace all the lines we care // about with the actual lines. let mut replaced_output = false; while let Some(line) = lines.next() { if line.starts_with("// | ") { // Skip copying lines here, because we're skipping // the existing concrete syntax tree. } else { // OK we're out of concrete syntax tree; copy in the // new CST. (We do this inline so we don't lose // `line`.) for expected_line in dump.lines() { result.push_str("// | "); result.push_str(expected_line); result.push_str("\n"); } // (Make sure not to drop this line.) result.push_str(line); result.push_str("\n"); replaced_output = true; break; } } if !replaced_output { panic!( "didn't actually replace the output section in {}", source_path ); } // Now just copy the rest of the lines. while let Some(line) = lines.next() { result.push_str(line); result.push_str("\n"); } // ... and re-write the file. std::fs::write(source_path, result).expect("unable to write the new file!"); } fn assert_concrete(tree: &SyntaxTree, expected: &str, source_path: &str) { let dump = tree.dump(); let rebase = std::env::var("FINE_TEST_REBASE") .unwrap_or(String::new()) .to_lowercase(); match rebase.as_str() { "1" | "true" | "yes" | "y" => { if dump != expected { rebase_concrete(source_path, &dump) } } _ => assert_eq!(expected, dump, "concrete syntax trees did not match (set FINE_TEST_REBASE=1 to auto-rebase if the diff is expected)"), } } fn assert_type_at( _tree: &SyntaxTree, _lines: &Lines, _pos: usize, _expected: &str, _source_path: &str, ) { } include!(concat!(env!("OUT_DIR"), "/generated_tests.rs"));