pub mod confirm;
mod glyph;
mod meta;
mod profile;
mod render;
mod writers;
pub use meta::{get, KoiCategory, KoiScope};
pub use render::{print_catalog, print_category_catalog, print_command_detail};
#[cfg(test)]
mod tests {
use super::meta;
use crate::cli::Cli;
use clap::{CommandFactory, Parser};
use std::collections::BTreeSet;
fn clap_leaf_paths() -> BTreeSet<String> {
let cmd = Cli::command();
let mut leaves = BTreeSet::new();
for sub in cmd.get_subcommands() {
collect_leaves(sub, &mut Vec::new(), &mut leaves);
}
leaves
}
fn collect_leaves(cmd: &clap::Command, prefix: &mut Vec<String>, out: &mut BTreeSet<String>) {
prefix.push(cmd.get_name().to_string());
let subs: Vec<&clap::Command> = cmd.get_subcommands().collect();
if subs.is_empty() {
out.insert(prefix.join(" "));
} else {
for sub in subs {
collect_leaves(sub, prefix, out);
}
}
prefix.pop();
}
#[test]
fn meta_covers_every_clap_leaf() {
let clap_leaves = clap_leaf_paths();
let meta_keys: BTreeSet<String> = meta::META.keys().map(|k| k.to_string()).collect();
let missing_meta: Vec<&String> = clap_leaves.difference(&meta_keys).collect();
let orphan_meta: Vec<&String> = meta_keys.difference(&clap_leaves).collect();
assert!(
missing_meta.is_empty(),
"clap leaf commands with no CommandMeta entry: {missing_meta:?}"
);
assert!(
orphan_meta.is_empty(),
"CommandMeta entries that are not real clap leaves: {orphan_meta:?}"
);
}
#[test]
fn every_example_parses() {
let mut failures: Vec<String> = Vec::new();
for m in meta::META.values() {
for example in m.examples {
if example.command.contains("$(") {
continue;
}
let argv = shell_split(example.command);
if argv.first().map(String::as_str) != Some("koi") {
failures.push(format!(
"[{}] example does not start with `koi`: {:?}",
m.name, example.command
));
continue;
}
if let Err(e) = Cli::try_parse_from(&argv) {
failures.push(format!(
"[{}] example failed to parse: {:?}\n {}",
m.name,
example.command,
e.to_string().lines().next().unwrap_or("")
));
}
}
}
assert!(
failures.is_empty(),
"CommandMeta examples that do not parse against clap:\n - {}",
failures.join("\n - ")
);
}
#[test]
fn every_command_name_routes_through_clap() {
use clap::error::ErrorKind;
let mut failures: Vec<String> = Vec::new();
for leaf in clap_leaf_paths() {
let mut argv = vec!["koi".to_string()];
argv.extend(leaf.split(' ').map(str::to_string));
argv.push("--help".to_string());
match Cli::try_parse_from(&argv) {
Err(e) if e.kind() == ErrorKind::DisplayHelp => {}
Err(e) => failures.push(format!("`{leaf} --help` → {:?}", e.kind())),
Ok(_) => failures.push(format!("`{leaf} --help` parsed without showing help")),
}
}
assert!(
failures.is_empty(),
"command names that did not route to their clap command:\n - {}",
failures.join("\n - ")
);
}
#[test]
fn example_corpus_is_populated() {
let total: usize = meta::META.values().map(|m| m.examples.len()).sum();
assert!(
total >= 30,
"expected a populated example corpus, found only {total} examples"
);
}
fn shell_split(input: &str) -> Vec<String> {
let mut out = Vec::new();
let mut cur = String::new();
let mut in_single = false;
let mut in_double = false;
let mut has_token = false;
for c in input.chars() {
match c {
'\'' if !in_double => {
in_single = !in_single;
has_token = true;
}
'"' if !in_single => {
in_double = !in_double;
has_token = true;
}
c if c.is_whitespace() && !in_single && !in_double => {
if has_token {
out.push(std::mem::take(&mut cur));
has_token = false;
}
}
c => {
cur.push(c);
has_token = true;
}
}
}
if has_token {
out.push(cur);
}
out
}
}