Skip to content

Commit a3e5663

Browse files
author
Veetaha
committed
ra_syntax: added tests for tokenization errors
1 parent 9367b9a commit a3e5663

File tree

150 files changed

+427
-49
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

150 files changed

+427
-49
lines changed

crates/ra_syntax/src/tests.rs

Lines changed: 58 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,28 @@
11
use std::{
22
fmt::Write,
3-
path::{Component, PathBuf},
3+
path::{Component, Path, PathBuf},
44
};
55

66
use test_utils::{collect_tests, dir_tests, project_dir, read_text};
77

8-
use crate::{fuzz, SourceFile};
8+
use crate::{fuzz, tokenize, Location, SourceFile, SyntaxError, TextRange, Token};
99

1010
#[test]
1111
fn lexer_tests() {
12-
dir_tests(&test_data_dir(), &["lexer"], |text, _| {
13-
// FIXME: add tests for errors (their format is up to discussion)
14-
let (tokens, _errors) = crate::tokenize(text);
15-
dump_tokens(&tokens, text)
16-
})
12+
// FIXME:
13+
// * Add tests for unicode escapes in byte-character and [raw]-byte-string literals
14+
// * Add tests for unescape errors
15+
16+
dir_tests(&test_data_dir(), &["lexer/ok"], |text, path| {
17+
let (tokens, errors) = tokenize(text);
18+
assert_errors_are_absent(&errors, path);
19+
dump_tokens_and_errors(&tokens, &errors, text)
20+
});
21+
dir_tests(&test_data_dir(), &["lexer/err"], |text, path| {
22+
let (tokens, errors) = tokenize(text);
23+
assert_errors_are_present(&errors, path);
24+
dump_tokens_and_errors(&tokens, &errors, text)
25+
});
1726
}
1827

1928
#[test]
@@ -33,18 +42,13 @@ fn parser_tests() {
3342
dir_tests(&test_data_dir(), &["parser/inline/ok", "parser/ok"], |text, path| {
3443
let parse = SourceFile::parse(text);
3544
let errors = parse.errors();
36-
assert_eq!(
37-
errors,
38-
&[] as &[crate::SyntaxError],
39-
"There should be no errors in the file {:?}",
40-
path.display(),
41-
);
45+
assert_errors_are_absent(&errors, path);
4246
parse.debug_dump()
4347
});
4448
dir_tests(&test_data_dir(), &["parser/err", "parser/inline/err"], |text, path| {
4549
let parse = SourceFile::parse(text);
4650
let errors = parse.errors();
47-
assert!(!errors.is_empty(), "There should be errors in the file {:?}", path.display());
51+
assert_errors_are_present(&errors, path);
4852
parse.debug_dump()
4953
});
5054
}
@@ -76,7 +80,7 @@ fn self_hosting_parsing() {
7680
.into_iter()
7781
.filter_entry(|entry| {
7882
!entry.path().components().any(|component| {
79-
// Get all files which are not in the crates/ra_syntax/tests/data folder
83+
// Get all files which are not in the crates/ra_syntax/test_data folder
8084
component == Component::Normal(OsStr::new("test_data"))
8185
})
8286
})
@@ -102,15 +106,47 @@ fn test_data_dir() -> PathBuf {
102106
project_dir().join("crates/ra_syntax/test_data")
103107
}
104108

105-
fn dump_tokens(tokens: &[crate::Token], text: &str) -> String {
109+
fn assert_errors_are_present(errors: &[SyntaxError], path: &Path) {
110+
assert!(!errors.is_empty(), "There should be errors in the file {:?}", path.display());
111+
}
112+
fn assert_errors_are_absent(errors: &[SyntaxError], path: &Path) {
113+
assert_eq!(
114+
errors,
115+
&[] as &[SyntaxError],
116+
"There should be no errors in the file {:?}",
117+
path.display(),
118+
);
119+
}
120+
121+
fn dump_tokens_and_errors(tokens: &[Token], errors: &[SyntaxError], text: &str) -> String {
106122
let mut acc = String::new();
107123
let mut offset = 0;
108124
for token in tokens {
109-
let len: u32 = token.len.into();
110-
let len = len as usize;
111-
let token_text = &text[offset..offset + len];
112-
offset += len;
113-
write!(acc, "{:?} {} {:?}\n", token.kind, token.len, token_text).unwrap()
125+
let token_len = token.len.to_usize();
126+
let token_text = &text[offset..offset + token_len];
127+
offset += token_len;
128+
writeln!(acc, "{:?} {} {:?}", token.kind, token_len, token_text).unwrap();
129+
}
130+
for err in errors {
131+
let err_range = location_to_range(err.location());
132+
writeln!(
133+
acc,
134+
"> error{:?} token({:?}) msg({})",
135+
err.location(),
136+
&text[err_range],
137+
err.kind()
138+
)
139+
.unwrap();
140+
}
141+
return acc;
142+
143+
// FIXME: copy-pasted this from `ra_ide/src/diagnostics.rs`
144+
// `Location` will be refactored soon in new PR, see todos here:
145+
// https://github.com/rust-analyzer/rust-analyzer/issues/223
146+
fn location_to_range(location: Location) -> TextRange {
147+
match location {
148+
Location::Offset(offset) => TextRange::offset_len(offset, 1.into()),
149+
Location::Range(range) => range,
150+
}
114151
}
115-
acc
116152
}

crates/ra_syntax/src/validation.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,12 @@ impl From<rustc_lexer::unescape::EscapeError> for SyntaxErrorKind {
9494
}
9595

9696
pub(crate) fn validate(root: &SyntaxNode) -> Vec<SyntaxError> {
97+
// FIXME:
98+
// * Add validation of character literal containing only a single char
99+
// * Add validation of `crate` keyword not appearing in the middle of the symbol path
100+
// * Add validation of doc comments are being attached to nodes
101+
// * Remove validation of unterminated literals (it is already implemented in `tokenize()`)
102+
97103
let mut errors = Vec::new();
98104
for node in root.descendants() {
99105
match_ast! {

crates/ra_syntax/test_data/lexer/0010_comments.rs

Lines changed: 0 additions & 3 deletions
This file was deleted.

crates/ra_syntax/test_data/lexer/0010_comments.txt

Lines changed: 0 additions & 6 deletions
This file was deleted.

crates/ra_syntax/test_data/lexer/0014_unclosed_char.rs

Lines changed: 0 additions & 1 deletion
This file was deleted.

crates/ra_syntax/test_data/lexer/0014_unclosed_char.txt

Lines changed: 0 additions & 1 deletion
This file was deleted.

crates/ra_syntax/test_data/lexer/0015_unclosed_string.rs

Lines changed: 0 additions & 1 deletion
This file was deleted.

crates/ra_syntax/test_data/lexer/0015_unclosed_string.txt

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
'
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
CHAR 1 "\'"
2+
> error[0; 1) token("\'") msg(Missing trailing `'` symbol to terminate the character literal)

0 commit comments

Comments
 (0)