aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cargo/config1
-rw-r--r--appveyor.yml1
-rw-r--r--src/parser/event_parser/grammar/items/mod.rs4
-rw-r--r--tests/data/parser/inline/0001_const_unsafe_fn.rs1
-rw-r--r--tests/data/parser/inline/0001_const_unsafe_fn.txt15
-rw-r--r--tests/data/parser/inline/0002_const_fn.rs1
-rw-r--r--tests/data/parser/inline/0002_const_fn.txt13
-rw-r--r--tests/data/parser/ok/0024_const_fn.rs5
-rw-r--r--tests/data/parser/ok/0024_const_fn.txt29
-rw-r--r--tests/data/parser/ok/0024_const_item.rs (renamed from tests/data/parser/ok/0025_const_item.rs)0
-rw-r--r--tests/data/parser/ok/0024_const_item.txt (renamed from tests/data/parser/ok/0025_const_item.txt)0
-rw-r--r--tests/parser.rs2
-rw-r--r--tools/Cargo.toml2
-rw-r--r--tools/src/bin/collect-tests.rs134
14 files changed, 173 insertions, 35 deletions
diff --git a/.cargo/config b/.cargo/config
index 1ebc0f748..7d89cf490 100644
--- a/.cargo/config
+++ b/.cargo/config
@@ -1,3 +1,4 @@
1[alias] 1[alias]
2parse = "run --package tools --bin parse" 2parse = "run --package tools --bin parse"
3gen = "run --package tools --bin gen" 3gen = "run --package tools --bin gen"
4collect-tests = "run --package tools --bin collect-tests --"
diff --git a/appveyor.yml b/appveyor.yml
index a6ba3b0e1..8c7d118c8 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -10,6 +10,7 @@ install:
10build: false 10build: false
11 11
12test_script: 12test_script:
13 - cargo collect-tests --verify
13 - cargo test 14 - cargo test
14 15
15branches: 16branches:
diff --git a/src/parser/event_parser/grammar/items/mod.rs b/src/parser/event_parser/grammar/items/mod.rs
index 8ccf8f90f..5cf2fc39a 100644
--- a/src/parser/event_parser/grammar/items/mod.rs
+++ b/src/parser/event_parser/grammar/items/mod.rs
@@ -52,11 +52,15 @@ fn item(p: &mut Parser) {
52 STATIC_ITEM 52 STATIC_ITEM
53 } 53 }
54 CONST_KW => match p.nth(1) { 54 CONST_KW => match p.nth(1) {
55 // test const_fn
56 // const fn foo() {}
55 FN_KW => { 57 FN_KW => {
56 p.bump(); 58 p.bump();
57 fn_item(p); 59 fn_item(p);
58 FN_ITEM 60 FN_ITEM
59 } 61 }
62 // test const_unsafe_fn
63 // const unsafe fn foo() {}
60 UNSAFE_KW if p.nth(2) == FN_KW => { 64 UNSAFE_KW if p.nth(2) == FN_KW => {
61 p.bump(); 65 p.bump();
62 p.bump(); 66 p.bump();
diff --git a/tests/data/parser/inline/0001_const_unsafe_fn.rs b/tests/data/parser/inline/0001_const_unsafe_fn.rs
new file mode 100644
index 000000000..31a1e435f
--- /dev/null
+++ b/tests/data/parser/inline/0001_const_unsafe_fn.rs
@@ -0,0 +1 @@
const unsafe fn foo() {}
diff --git a/tests/data/parser/inline/0001_const_unsafe_fn.txt b/tests/data/parser/inline/0001_const_unsafe_fn.txt
new file mode 100644
index 000000000..1f0865cb0
--- /dev/null
+++ b/tests/data/parser/inline/0001_const_unsafe_fn.txt
@@ -0,0 +1,15 @@
1FILE@[0; 25)
2 FN_ITEM@[0; 25)
3 CONST_KW@[0; 5)
4 WHITESPACE@[5; 6)
5 UNSAFE_KW@[6; 12)
6 WHITESPACE@[12; 13)
7 FN_KW@[13; 15)
8 WHITESPACE@[15; 16)
9 IDENT@[16; 19) "foo"
10 L_PAREN@[19; 20)
11 R_PAREN@[20; 21)
12 WHITESPACE@[21; 22)
13 L_CURLY@[22; 23)
14 R_CURLY@[23; 24)
15 WHITESPACE@[24; 25)
diff --git a/tests/data/parser/inline/0002_const_fn.rs b/tests/data/parser/inline/0002_const_fn.rs
new file mode 100644
index 000000000..8c84d9cd7
--- /dev/null
+++ b/tests/data/parser/inline/0002_const_fn.rs
@@ -0,0 +1 @@
const fn foo() {}
diff --git a/tests/data/parser/inline/0002_const_fn.txt b/tests/data/parser/inline/0002_const_fn.txt
new file mode 100644
index 000000000..2d360d78b
--- /dev/null
+++ b/tests/data/parser/inline/0002_const_fn.txt
@@ -0,0 +1,13 @@
1FILE@[0; 18)
2 FN_ITEM@[0; 18)
3 CONST_KW@[0; 5)
4 WHITESPACE@[5; 6)
5 FN_KW@[6; 8)
6 WHITESPACE@[8; 9)
7 IDENT@[9; 12) "foo"
8 L_PAREN@[12; 13)
9 R_PAREN@[13; 14)
10 WHITESPACE@[14; 15)
11 L_CURLY@[15; 16)
12 R_CURLY@[16; 17)
13 WHITESPACE@[17; 18)
diff --git a/tests/data/parser/ok/0024_const_fn.rs b/tests/data/parser/ok/0024_const_fn.rs
deleted file mode 100644
index eba9322a1..000000000
--- a/tests/data/parser/ok/0024_const_fn.rs
+++ /dev/null
@@ -1,5 +0,0 @@
1const fn foo() {
2}
3
4const unsafe fn foo() {
5}
diff --git a/tests/data/parser/ok/0024_const_fn.txt b/tests/data/parser/ok/0024_const_fn.txt
deleted file mode 100644
index 0fd485997..000000000
--- a/tests/data/parser/ok/0024_const_fn.txt
+++ /dev/null
@@ -1,29 +0,0 @@
1FILE@[0; 46)
2 FN_ITEM@[0; 20)
3 CONST_KW@[0; 5)
4 WHITESPACE@[5; 6)
5 FN_KW@[6; 8)
6 WHITESPACE@[8; 9)
7 IDENT@[9; 12) "foo"
8 L_PAREN@[12; 13)
9 R_PAREN@[13; 14)
10 WHITESPACE@[14; 15)
11 L_CURLY@[15; 16)
12 WHITESPACE@[16; 17)
13 R_CURLY@[17; 18)
14 WHITESPACE@[18; 20)
15 FN_ITEM@[20; 46)
16 CONST_KW@[20; 25)
17 WHITESPACE@[25; 26)
18 UNSAFE_KW@[26; 32)
19 WHITESPACE@[32; 33)
20 FN_KW@[33; 35)
21 WHITESPACE@[35; 36)
22 IDENT@[36; 39) "foo"
23 L_PAREN@[39; 40)
24 R_PAREN@[40; 41)
25 WHITESPACE@[41; 42)
26 L_CURLY@[42; 43)
27 WHITESPACE@[43; 44)
28 R_CURLY@[44; 45)
29 WHITESPACE@[45; 46)
diff --git a/tests/data/parser/ok/0025_const_item.rs b/tests/data/parser/ok/0024_const_item.rs
index 7446859b5..7446859b5 100644
--- a/tests/data/parser/ok/0025_const_item.rs
+++ b/tests/data/parser/ok/0024_const_item.rs
diff --git a/tests/data/parser/ok/0025_const_item.txt b/tests/data/parser/ok/0024_const_item.txt
index 588e001f5..588e001f5 100644
--- a/tests/data/parser/ok/0025_const_item.txt
+++ b/tests/data/parser/ok/0024_const_item.txt
diff --git a/tests/parser.rs b/tests/parser.rs
index f681c066f..68a6434be 100644
--- a/tests/parser.rs
+++ b/tests/parser.rs
@@ -7,7 +7,7 @@ use testutils::dir_tests;
7 7
8#[test] 8#[test]
9fn parser_tests() { 9fn parser_tests() {
10 dir_tests(&["parser/ok", "parser/err"], |text| { 10 dir_tests(&["parser/inline", "parser/ok", "parser/err"], |text| {
11 let tokens = tokenize(text); 11 let tokens = tokenize(text);
12 let file = parse(text.to_string(), &tokens); 12 let file = parse(text.to_string(), &tokens);
13 dump_tree(&file) 13 dump_tree(&file)
diff --git a/tools/Cargo.toml b/tools/Cargo.toml
index e46874929..8cbc2fc93 100644
--- a/tools/Cargo.toml
+++ b/tools/Cargo.toml
@@ -9,4 +9,6 @@ serde = "1.0.26"
9serde_derive = "1.0.26" 9serde_derive = "1.0.26"
10file = "1.1.1" 10file = "1.1.1"
11ron = "0.1.5" 11ron = "0.1.5"
12walkdir = "2"
13itertools = "0.7"
12libsyntax2 = { path = "../" } 14libsyntax2 = { path = "../" }
diff --git a/tools/src/bin/collect-tests.rs b/tools/src/bin/collect-tests.rs
new file mode 100644
index 000000000..c54059e79
--- /dev/null
+++ b/tools/src/bin/collect-tests.rs
@@ -0,0 +1,134 @@
1extern crate file;
2extern crate walkdir;
3extern crate itertools;
4
5use walkdir::WalkDir;
6use itertools::Itertools;
7
8use std::path::{PathBuf, Path};
9use std::collections::HashSet;
10use std::fs;
11
12fn main() {
13 let verify = ::std::env::args().any(|arg| arg == "--verify");
14
15 let d = grammar_dir();
16 let tests = tests_from_dir(&d);
17 let existing = existing_tests();
18
19 for t in existing.difference(&tests) {
20 panic!("Test is deleted: {}\n{}", t.name, t.text);
21 }
22
23 let new_tests = tests.difference(&existing);
24 for (i, t) in new_tests.enumerate() {
25 if verify {
26 panic!("Inline test is not recorded: {}", t.name);
27 }
28
29 let name = format!("{:04}_{}.rs", existing.len() + i + 1, t.name);
30 println!("Creating {}", name);
31 let path = inline_tests_dir().join(name);
32 file::put_text(&path, &t.text).unwrap();
33 }
34}
35
36
37#[derive(Debug, Eq)]
38struct Test {
39 name: String,
40 text: String,
41}
42
43impl PartialEq for Test {
44 fn eq(&self, other: &Test) -> bool {
45 self.name.eq(&other.name)
46 }
47}
48
49impl ::std::hash::Hash for Test {
50 fn hash<H: ::std::hash::Hasher>(&self, state: &mut H) {
51 self.name.hash(state)
52 }
53}
54
55fn tests_from_dir(dir: &Path) -> HashSet<Test> {
56 let mut res = HashSet::new();
57 for entry in WalkDir::new(dir) {
58 let entry = entry.unwrap();
59 if !entry.file_type().is_file() {
60 continue
61 }
62 if entry.path().extension().unwrap_or_default() != "rs" {
63 continue
64 }
65 let text = file::get_text(entry.path())
66 .unwrap();
67
68 for test in collect_tests(&text) {
69 if let Some(old_test) = res.replace(test) {
70 panic!("Duplicate test: {}", old_test.name)
71 }
72 }
73 }
74 res
75}
76
77fn collect_tests(s: &str) -> Vec<Test> {
78 let mut res = vec![];
79 let prefix = "// ";
80 let comment_blocks = s.lines()
81 .map(str::trim_left)
82 .group_by(|line| line.starts_with(prefix));
83
84 for (is_comment, block) in comment_blocks.into_iter() {
85 if !is_comment {
86 continue;
87 }
88 let mut block = block.map(|line| &line[prefix.len()..]);
89 let first = block.next().unwrap();
90 if !first.starts_with("test ") {
91 continue
92 }
93 let name = first["test ".len()..].to_string();
94 let text: String = itertools::join(block.chain(::std::iter::once("")), "\n");
95 assert!(!text.trim().is_empty() && text.ends_with("\n"));
96 res.push(Test { name, text })
97 }
98 res
99}
100
101fn existing_tests() -> HashSet<Test> {
102 let mut res = HashSet::new();
103 for file in fs::read_dir(&inline_tests_dir()).unwrap() {
104 let file = file.unwrap();
105 let path = file.path();
106 if path.extension().unwrap_or_default() != "rs" {
107 continue
108 }
109 let name = path.file_name().unwrap().to_str().unwrap();
110 let name = name["0000_".len()..name.len() - 3].to_string();
111 let text = file::get_text(&path).unwrap();
112 res.insert(Test { name, text });
113 }
114 res
115}
116
117fn inline_tests_dir() -> PathBuf {
118 let res = base_dir().join("tests/data/parser/inline");
119 if !res.is_dir() {
120 fs::create_dir_all(&res).unwrap();
121 }
122 res
123}
124
125fn grammar_dir() -> PathBuf {
126 base_dir().join("src/parser/event_parser/grammar")
127}
128
129fn base_dir() -> PathBuf {
130 let dir = env!("CARGO_MANIFEST_DIR");
131 PathBuf::from(dir).parent().unwrap().to_owned()
132}
133
134