rust/crates/ra_syntax/src/tests.rs

142 lines
4.1 KiB
Rust
Raw Normal View History

2018-07-30 07:25:52 -05:00
use std::{
fmt::Write,
path::{Component, Path, PathBuf},
2018-07-30 07:25:52 -05:00
};
2018-01-07 05:56:08 -06:00
use test_utils::{collect_tests, dir_tests, project_dir, read_text};
2018-08-25 04:10:35 -05:00
use crate::{fuzz, tokenize, SourceFile, SyntaxError, Token};
2019-07-24 04:38:21 -05:00
2018-08-11 02:03:03 -05:00
#[test]
fn lexer_tests() {
// FIXME:
// * Add tests for unicode escapes in byte-character and [raw]-byte-string literals
// * Add tests for unescape errors
dir_tests(&test_data_dir(), &["lexer/ok"], |text, path| {
let (tokens, errors) = tokenize(text);
assert_errors_are_absent(&errors, path);
dump_tokens_and_errors(&tokens, &errors, text)
});
dir_tests(&test_data_dir(), &["lexer/err"], |text, path| {
let (tokens, errors) = tokenize(text);
assert_errors_are_present(&errors, path);
dump_tokens_and_errors(&tokens, &errors, text)
});
2018-08-11 02:03:03 -05:00
}
#[test]
fn parse_smoke_test() {
let code = r##"
fn main() {
println!("Hello, world!")
}
"##;
let parse = SourceFile::parse(code);
assert!(parse.ok().is_ok());
}
#[test]
fn parser_tests() {
2019-02-08 05:49:43 -06:00
dir_tests(&test_data_dir(), &["parser/inline/ok", "parser/ok"], |text, path| {
2019-05-28 09:34:28 -05:00
let parse = SourceFile::parse(text);
let errors = parse.errors();
assert_errors_are_absent(&errors, path);
2019-05-28 08:59:22 -05:00
parse.debug_dump()
2019-02-08 05:49:43 -06:00
});
dir_tests(&test_data_dir(), &["parser/err", "parser/inline/err"], |text, path| {
2019-05-28 09:34:28 -05:00
let parse = SourceFile::parse(text);
let errors = parse.errors();
assert_errors_are_present(&errors, path);
2019-05-28 08:59:22 -05:00
parse.debug_dump()
2019-02-08 05:49:43 -06:00
});
}
#[test]
fn parser_fuzz_tests() {
for (_, text) in collect_tests(&test_data_dir(), &["parser/fuzz-failures"]) {
2019-03-21 12:05:12 -05:00
fuzz::check_parser(&text)
}
2018-08-25 06:45:17 -05:00
}
2019-03-21 12:06:48 -05:00
#[test]
fn reparse_fuzz_tests() {
for (_, text) in collect_tests(&test_data_dir(), &["reparse/fuzz-failures"]) {
let check = fuzz::CheckReparse::from_data(text.as_bytes()).unwrap();
println!("{:?}", check);
check.run();
}
}
2019-04-11 09:15:20 -05:00
/// Test that Rust-analyzer can parse and validate the rust-analyzer
2019-03-23 02:53:48 -05:00
/// FIXME: Use this as a benchmark
#[test]
fn self_hosting_parsing() {
use std::ffi::OsStr;
let dir = project_dir().join("crates");
let mut count = 0;
for entry in walkdir::WalkDir::new(dir)
.into_iter()
.filter_entry(|entry| {
!entry.path().components().any(|component| {
// Get all files which are not in the crates/ra_syntax/test_data folder
2019-07-24 04:38:21 -05:00
component == Component::Normal(OsStr::new("test_data"))
})
})
.map(|e| e.unwrap())
.filter(|entry| {
// Get all `.rs ` files
!entry.path().is_dir() && (entry.path().extension() == Some(OsStr::new("rs")))
})
{
count += 1;
let text = read_text(entry.path());
if let Err(errors) = SourceFile::parse(&text).ok() {
panic!("Parsing errors:\n{:?}\n{}\n", errors, entry.path().display());
}
}
assert!(
count > 30,
"self_hosting_parsing found too few files - is it running in the right directory?"
)
}
2018-01-07 05:56:08 -06:00
fn test_data_dir() -> PathBuf {
2019-07-24 04:38:21 -05:00
project_dir().join("crates/ra_syntax/test_data")
2018-08-11 02:03:03 -05:00
}
fn assert_errors_are_present(errors: &[SyntaxError], path: &Path) {
assert!(!errors.is_empty(), "There should be errors in the file {:?}", path.display());
}
fn assert_errors_are_absent(errors: &[SyntaxError], path: &Path) {
assert_eq!(
errors,
&[] as &[SyntaxError],
"There should be no errors in the file {:?}",
path.display(),
);
}
fn dump_tokens_and_errors(tokens: &[Token], errors: &[SyntaxError], text: &str) -> String {
2018-08-11 02:03:03 -05:00
let mut acc = String::new();
let mut offset = 0;
for token in tokens {
let token_len = token.len.to_usize();
let token_text = &text[offset..offset + token_len];
offset += token_len;
writeln!(acc, "{:?} {} {:?}", token.kind, token_len, token_text).unwrap();
}
for err in errors {
writeln!(
acc,
"> error{:?} token({:?}) msg({})",
err.range(),
&text[*err.range()],
err.message()
)
.unwrap();
}
acc
2018-02-03 03:51:06 -06:00
}