]> git.proxmox.com Git - rustc.git/blob - vendor/pulldown-cmark-0.7.2/build.rs
New upstream version 1.48.0~beta.8+dfsg1
[rustc.git] / vendor / pulldown-cmark-0.7.2 / build.rs
1 fn main() {
2 generate_tests_from_spec()
3 }
4
5 // If the "gen-tests" feature is absent,
6 // this function will be compiled down to nothing
7 #[cfg(not(feature = "gen-tests"))]
8 fn generate_tests_from_spec() {}
9
10 // If the feature is present, generate tests
11 // from any .txt file present in the specs/ directory
12 //
13 // Test cases are present in the files in the
14 // following format:
15 //
16 // ```````````````````````````````` example
17 // markdown
18 // .
19 // expected html output
20 // ````````````````````````````````
21 #[cfg(feature = "gen-tests")]
22 fn generate_tests_from_spec() {
23 use std::fs::{self, File};
24 use std::io::{Read, Write};
25 use std::path::PathBuf;
26
27 // This is a hardcoded path to the CommonMark spec because it is not situated in
28 // the specs/ directory. It's in an array to easily chain it to the other iterator
29 // and make it easy to eventually add other hardcoded paths in the future if needed
30 let hardcoded = [
31 "./third_party/CommonMark/spec.txt",
32 "./third_party/GitHub/gfm_table.txt",
33 "./third_party/GitHub/gfm_strikethrough.txt",
34 "./third_party/GitHub/gfm_tasklist.txt",
35 ];
36 let hardcoded_iter = hardcoded.into_iter().map(PathBuf::from);
37
38 // Create an iterator over the files in the specs/ directory that have a .txt extension
39 let spec_files = fs::read_dir("./specs")
40 .expect("Could not find the 'specs' directory")
41 .filter_map(Result::ok)
42 .map(|d| d.path())
43 .filter(|p| p.extension().map(|e| e.to_owned()).is_some())
44 .chain(hardcoded_iter)
45 .collect::<Vec<_>>();
46
47 for file_path in &spec_files {
48 let mut raw_spec = String::new();
49
50 File::open(&file_path)
51 .and_then(|mut f| f.read_to_string(&mut raw_spec))
52 .expect("Could not read the spec file");
53
54 let rs_test_file = PathBuf::from("./tests/suite/")
55 .join(file_path.file_name().expect("Invalid filename"))
56 .with_extension("rs");
57
58 let mut spec_rs =
59 File::create(&rs_test_file).expect(&format!("Could not create {:?}", rs_test_file));
60
61 let spec_name = file_path.file_stem().unwrap().to_str().unwrap();
62
63 let spec = Spec::new(&raw_spec);
64 let mut n_tests = 0;
65
66 spec_rs
67 .write(b"// This file is auto-generated by the build script\n")
68 .unwrap();
69 spec_rs
70 .write(b"// Please, do not modify it manually\n")
71 .unwrap();
72 spec_rs
73 .write(b"\nuse super::test_markdown_html;\n")
74 .unwrap();
75
76 for (i, testcase) in spec.enumerate() {
77 spec_rs
78 .write_fmt(format_args!(
79 r###"
80 #[test]
81 fn {}_test_{i}() {{
82 let original = r##"{original}"##;
83 let expected = r##"{expected}"##;
84
85 test_markdown_html(original, expected);
86 }}
87 "###,
88 spec_name,
89 i = i + 1,
90 original = testcase.original,
91 expected = testcase.expected
92 ))
93 .unwrap();
94
95 n_tests += 1;
96 }
97
98 println!(
99 "cargo:warning=Generated {} tests in {:?}",
100 n_tests, rs_test_file
101 );
102 }
103
104 // write mods to suite/mod.rs
105 let suite_mod_file = PathBuf::from("./tests/suite/mod").with_extension("rs");
106
107 let mut mod_rs =
108 File::create(&suite_mod_file).expect(&format!("Could not create {:?}", &suite_mod_file));
109
110 mod_rs
111 .write(b"// This file is auto-generated by the build script\n")
112 .unwrap();
113 mod_rs
114 .write(b"// Please, do not modify it manually\n")
115 .unwrap();
116 mod_rs
117 .write(b"\npub use super::test_markdown_html;\n\n")
118 .unwrap();
119
120 for file_path in &spec_files {
121 let mod_name = file_path.file_stem().unwrap().to_str().unwrap();
122 mod_rs.write(b"mod ").unwrap();
123 mod_rs.write(mod_name.as_bytes()).unwrap();
124 mod_rs.write(b";\n").unwrap();
125 }
126 }
127
128 #[cfg(feature = "gen-tests")]
129 pub struct Spec<'a> {
130 spec: &'a str,
131 }
132
133 #[cfg(feature = "gen-tests")]
134 impl<'a> Spec<'a> {
135 pub fn new(spec: &'a str) -> Self {
136 Spec { spec: spec }
137 }
138 }
139
140 #[cfg(feature = "gen-tests")]
141 pub struct TestCase {
142 pub original: String,
143 pub expected: String,
144 }
145
146 #[cfg(feature = "gen-tests")]
147 impl<'a> Iterator for Spec<'a> {
148 type Item = TestCase;
149
150 fn next(&mut self) -> Option<TestCase> {
151 let spec = self.spec;
152
153 let i_start = match self
154 .spec
155 .find("```````````````````````````````` example\n")
156 .map(|pos| pos + 41)
157 {
158 Some(pos) => pos,
159 None => return None,
160 };
161
162 let i_end = match self.spec[i_start..]
163 .find("\n.\n")
164 .map(|pos| (pos + 1) + i_start)
165 {
166 Some(pos) => pos,
167 None => return None,
168 };
169
170 let e_end = match self.spec[i_end + 2..]
171 .find("````````````````````````````````\n")
172 .map(|pos| pos + i_end + 2)
173 {
174 Some(pos) => pos,
175 None => return None,
176 };
177
178 self.spec = &self.spec[e_end + 33..];
179
180 let test_case = TestCase {
181 original: spec[i_start..i_end].to_string().replace("→", "\t"),
182 expected: spec[i_end + 2..e_end].to_string().replace("→", "\t"),
183 };
184
185 Some(test_case)
186 }
187 }