diff options
Diffstat (limited to 'niri-config')
| -rw-r--r-- | niri-config/Cargo.toml | 1 | ||||
| -rw-r--r-- | niri-config/tests/wiki-parses.rs | 108 |
2 files changed, 109 insertions, 0 deletions
diff --git a/niri-config/Cargo.toml b/niri-config/Cargo.toml index 28bd1b37..e498d257 100644 --- a/niri-config/Cargo.toml +++ b/niri-config/Cargo.toml @@ -20,3 +20,4 @@ tracy-client.workspace = true [dev-dependencies] pretty_assertions = "1.4.0" +miette = { version = "5.10.0", features = ["fancy"] } diff --git a/niri-config/tests/wiki-parses.rs b/niri-config/tests/wiki-parses.rs new file mode 100644 index 00000000..9c03b471 --- /dev/null +++ b/niri-config/tests/wiki-parses.rs @@ -0,0 +1,108 @@ +use std::fs; +use std::path::PathBuf; + +const NO_TEST_COMMENT: &str = "<!-- no-test -->"; + +struct KdlCodeBlock { + filename: String, + code: String, + line_number: usize, +} + +fn extract_kdl_from_file(file_contents: &str, filename: &str) -> Vec<KdlCodeBlock> { + // Removes the > from callouts that might contain ```kdl``` + let lines: Vec<_> = file_contents + .lines() + .map(|line| { + let line = line.trim(); + if line.starts_with(">") { + if line.len() == 1 { + "" + } else { + &line[2..] + } + } else { + line + } + }) + .enumerate() + .collect(); + + let mut lines_iter = lines.iter(); + let mut kdl_code_blocks = vec![]; + + while let Some((line_number, line)) = lines_iter.next() { + let start_snippet = + line.starts_with("```kdl") && lines[line_number - 1].1 != NO_TEST_COMMENT; + + if !start_snippet { + continue; + } + + let mut snippet = String::new(); + for (_, line) in lines_iter + .by_ref() + .take_while(|(_, line)| !line.starts_with("```")) + { + snippet.push_str(line); + snippet.push('\n'); + } + + kdl_code_blocks.push(KdlCodeBlock { + code: snippet, + line_number: *line_number, + filename: filename.to_string(), + }); + } + + kdl_code_blocks +} + +#[test] +fn wiki_docs_parses() { + let wiki_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../wiki"); + + let code_blocks = fs::read_dir(&wiki_dir) + .unwrap() + .filter_map(|entry| entry.ok()) + .filter(|entry| entry.file_type().is_ok_and(|ft| ft.is_file())) + .filter(|file| { + file.path() + .extension() + .map(|ext| ext == "md") + .unwrap_or(false) + }) + .map(|file| { + let file_contents = fs::read_to_string(file.path()).unwrap(); + let file_path = file.path(); + let filename = file_path.to_str().unwrap(); + extract_kdl_from_file(&file_contents, filename) + }) + .flatten(); + + let mut errors = vec![]; + + for KdlCodeBlock { + code, + line_number, + filename, + } in code_blocks + { + if let Err(error) = niri_config::Config::parse(&filename, &code) { + errors.push(format!( + "Error parsing wiki KDL code block at {}:{}: {:?}", + filename, + line_number, + miette::Report::new(error) + )) + } + } + + if !errors.is_empty() { + panic!( + "Errors parsing {} wiki KDL code blocks:\n{}", + errors.len(), + errors.join("\n") + ); + } +} |
