use std::fs;
use std::path::{Path, PathBuf};
use wickra_terminal_core::{Config, SourceSpec, Terminal};
const DOCS: [&str; 8] = [
"README.md",
"ARCHITECTURE.md",
"docs/INDICATORS.md",
"docs/Cookbook.md",
"docs/PANELS.md",
"docs/RENDERERS.md",
"docs/SOURCES.md",
"docs/STREAMING.md",
];
const BINDING_READMES: [&str; 8] = [
"bindings/c/README.md",
"bindings/csharp/README.md",
"bindings/go/README.md",
"bindings/java/README.md",
"bindings/node/README.md",
"bindings/python/README.md",
"bindings/r/README.md",
"bindings/wasm/README.md",
];
const NUMBER_WORDS: [&str; 21] = [
"zero",
"one",
"two",
"three",
"four",
"five",
"six",
"seven",
"eight",
"nine",
"ten",
"eleven",
"twelve",
"thirteen",
"fourteen",
"fifteen",
"sixteen",
"seventeen",
"eighteen",
"nineteen",
"twenty",
];
fn repo_root() -> PathBuf {
let mut dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
for _ in 0..8 {
if dir.join("README.md").is_file() && dir.join("docs").is_dir() {
return dir;
}
dir = dir
.parent()
.unwrap_or_else(|| panic!("no repository root above {}", env!("CARGO_MANIFEST_DIR")))
.to_path_buf();
}
panic!("no repository root found");
}
fn fenced_blocks(markdown: &str, language: &str) -> Vec<String> {
let open = format!("```{language}");
let mut blocks = Vec::new();
let mut current: Option<String> = None;
for line in markdown.lines() {
match current {
None if line.trim() == open => current = Some(String::new()),
None => {}
Some(_) if line.trim() == "```" => {
blocks.push(current.take().unwrap_or_default());
}
Some(ref mut body) => {
body.push_str(line);
body.push('\n');
}
}
}
blocks
}
fn read(root: &Path, rel: &str) -> String {
fs::read_to_string(root.join(rel)).unwrap_or_else(|err| panic!("{rel}: {err}"))
}
#[test]
fn every_documented_toml_config_parses() {
let root = repo_root();
let mut checked = 0;
for rel in DOCS {
for (index, block) in fenced_blocks(&read(&root, rel), "toml").iter().enumerate() {
Config::from_toml(block)
.unwrap_or_else(|err| panic!("{rel} toml block {index} does not parse: {err}"));
checked += 1;
}
}
assert!(checked > 0, "no TOML config examples found to check");
}
#[test]
fn every_documented_json_config_parses() {
let root = repo_root();
let mut checked = 0;
for rel in DOCS {
for (index, block) in fenced_blocks(&read(&root, rel), "json").iter().enumerate() {
let Ok(value) = serde_json::from_str::<serde_json::Value>(block) else {
continue;
};
let Some(object) = value.as_object() else {
continue;
};
if !object.contains_key("sources") && !object.contains_key("indicators") {
continue;
}
Config::from_json(block).unwrap_or_else(|err| {
panic!("{rel} json block {index} is not a valid config: {err}")
});
checked += 1;
}
}
assert!(checked > 0, "no JSON config examples found to check");
}
#[test]
fn every_documented_command_is_accepted() {
let root = repo_root();
let dataset =
fs::read_to_string(root.join("golden/replay/basic.json")).expect("the golden replay feed");
let mut checked = 0;
for rel in DOCS {
for (index, block) in fenced_blocks(&read(&root, rel), "json").iter().enumerate() {
let commands: Vec<&str> = block
.lines()
.map(str::trim)
.filter(|line| line.starts_with('{'))
.filter(|line| {
serde_json::from_str::<serde_json::Value>(line)
.ok()
.and_then(|v| {
v.get("type")
.and_then(serde_json::Value::as_str)
.map(str::to_string)
})
.is_some()
})
.collect();
if commands.is_empty() {
continue;
}
let mut config = Config::default_layout();
config.sources = vec![SourceSpec::Replay {
dataset: dataset.clone(),
}];
let mut terminal = Terminal::new(&config).expect("the default config must build");
terminal
.command_json(r#"{"type":"Subscribe","source":0,"symbol":"BTC/USDT"}"#)
.expect("subscribe");
for command in commands {
terminal.command_json(command).unwrap_or_else(|err| {
panic!(
"{rel} block {index} documents a command the terminal rejects:
{command}
{err}"
)
});
checked += 1;
}
}
}
assert!(checked > 0, "no command examples found to check");
}
const COUNTED: [&str; 6] = [
"README.md",
"ARCHITECTURE.md",
"docs/INDICATORS.md",
"ROADMAP.md",
"BENCHMARKS.md",
"docs/STREAMING.md",
];
#[test]
fn the_documented_indicator_count_is_the_real_one() {
let root = repo_root();
let actual = wickra_terminal_core::registry::DEFAULTS.len().to_string();
for rel in COUNTED {
let text = read(&root, rel);
let mut found = 0;
let mut rest = text.as_str();
while let Some(start) = rest.find(OPEN) {
let after = &rest[start + OPEN.len()..];
let end = after
.find(CLOSE)
.unwrap_or_else(|| panic!("{rel}: an indicator-count marker is not closed"));
let claimed = &after[..end];
assert_eq!(
claimed, actual,
"{rel} claims {claimed} indicators; the registry has {actual}"
);
found += 1;
rest = &after[end + CLOSE.len()..];
}
assert!(found > 0, "{rel} states no indicator count in a marker");
}
}
#[test]
fn the_unreachable_indicator_count_adds_up() {
const LIBRARY_TOTAL: usize = 504;
let root = repo_root();
let registered = wickra_terminal_core::registry::DEFAULTS.len()
+ wickra_terminal_core::registry::PROFILES.len();
let needle = format!(" of the {LIBRARY_TOTAL}");
let mut checked = 0;
for rel in ["docs/INDICATORS.md", "ROADMAP.md"] {
let text = read(&root, rel);
for (idx, _) in text.match_indices(&needle) {
let claimed: usize = text[..idx]
.rsplit(|c: char| !c.is_ascii_digit())
.find(|word| !word.is_empty())
.unwrap_or_else(|| panic!("{rel}: no number before \"{needle}\""))
.parse()
.unwrap_or_else(|err| panic!("{rel}: {err}"));
assert_eq!(
claimed + registered,
LIBRARY_TOTAL,
"{rel} says {claimed} unreachable and the terminal reaches {registered}, which is not the {LIBRARY_TOTAL} the library ships"
);
checked += 1;
}
}
assert!(checked > 0, "no unreachable-count claim found to check");
}
#[test]
fn the_citation_abstract_states_the_real_indicator_count() {
const PHRASE: &str = "the Wickra indicators are constructible";
let root = repo_root();
let text = read(&root, "CITATION.cff");
let actual = wickra_terminal_core::registry::DEFAULTS.len().to_string();
let before = text
.split(PHRASE)
.next()
.unwrap_or_else(|| panic!("CITATION.cff no longer says \"{PHRASE}\""));
assert_ne!(
before, text,
"CITATION.cff no longer states an indicator count"
);
let claimed: String = before
.chars()
.rev()
.skip_while(|c| !c.is_ascii_digit())
.take_while(char::is_ascii_digit)
.collect::<String>()
.chars()
.rev()
.collect();
assert_eq!(
claimed, actual,
"CITATION.cff claims {claimed} indicators; the registry has {actual}"
);
}
fn released_in_changelog(root: &std::path::Path) -> Option<(String, String)> {
read(root, "CHANGELOG.md").lines().find_map(|line| {
let rest = line.strip_prefix("## [")?;
let (version, rest) = rest.split_once("] - ")?;
let date = rest.trim();
(date.len() == 10 && date.starts_with("20"))
.then(|| (version.to_string(), date.to_string()))
})
}
#[test]
fn the_citation_matches_the_release_state() {
let root = repo_root();
let text = read(&root, "CITATION.cff");
let value_of = |key: &str| -> Option<String> {
text.lines()
.find(|line| line.starts_with(key))?
.split_once(':')
.map(|(_, v)| v.trim().trim_matches('"').to_string())
};
match released_in_changelog(&root) {
None => {
for key in ["version:", "date-released:"] {
assert!(
value_of(key).is_none(),
"CITATION.cff carries {key}, which cites a release that does not exist"
);
}
}
Some((version, date)) => {
assert_eq!(
value_of("version:").as_deref(),
Some(version.as_str()),
"CHANGELOG released {version}; CITATION.cff does not cite it"
);
assert_eq!(
value_of("date-released:").as_deref(),
Some(date.as_str()),
"CHANGELOG dates the release {date}; CITATION.cff does not"
);
}
}
}
#[test]
fn the_readme_and_the_benchmark_page_agree_on_the_numbers() {
let root = repo_root();
let readme = read(&root, "README.md");
let bench = read(&root, "BENCHMARKS.md");
let rows: Vec<(String, String)> = bench
.lines()
.filter(|line| line.starts_with("| `"))
.filter_map(|line| {
let cells: Vec<&str> = line.split('|').map(str::trim).collect();
(cells.len() >= 6).then(|| (cells[3].to_owned(), cells[4].to_owned()))
})
.filter(|(median, _)| median.ends_with("ns") || median.ends_with("\u{b5}s"))
.collect();
assert!(
rows.len() >= 5,
"found only {rows:?} measured rows in BENCHMARKS.md"
);
let mut checked = 0;
for (median, throughput) in rows {
if !readme.contains(&median) {
continue;
}
assert!(
readme.contains(&format!("| {median} | {throughput} |")),
"the README pairs {median} with a throughput BENCHMARKS.md does not: {throughput}"
);
checked += 1;
}
assert!(
checked >= 5,
"only {checked} of the benchmark rows reached the README"
);
}
#[test]
fn the_documented_bounds_are_the_real_ones() {
fn constant(source: &str, name: &str) -> usize {
let needle = format!("const {name}: usize = ");
let at = source
.find(&needle)
.unwrap_or_else(|| panic!("{name} is gone or was renamed"));
source[at + needle.len()..]
.split(';')
.next()
.and_then(|value| value.trim().parse().ok())
.unwrap_or_else(|| panic!("{name} is no longer a plain number"))
}
let root = repo_root();
let panels = read(&root, "crates/wickra-terminal-core/src/panels/mod.rs");
let state = read(&root, "crates/wickra-terminal-core/src/state.rs");
let doc = read(&root, "docs/PANELS.md");
let depth = constant(&panels, "DEFAULT_DEPTH");
let points = constant(&panels, "CHART_POINTS");
let bars_kept = constant(&state, "OHLC_HISTORY");
let prices_kept = constant(&state, "PRICE_HISTORY");
let levels_kept = constant(&state, "MAX_FOOTPRINT_LEVELS");
let alt_kept = constant(&state, "ALT_BARS_KEPT");
assert!(
panels.contains("const TAPE_ROWS: usize = DEFAULT_DEPTH * 2;"),
"TAPE_ROWS is no longer twice the default depth"
);
let tape_rows = depth * 2;
let streaming = read(&root, "docs/STREAMING.md");
let pending = constant(
&read(&root, "crates/wickra-terminal-core/src/source/manual.rs"),
"MAX_PENDING_EVENTS",
);
let series = constant(&state, "INDICATOR_SERIES");
let tape_kept = constant(&state, "TAPE_PRINTS_KEPT");
for claim in [
format!("the tape ring at {tape_kept} prints"),
format!("the price history at {prices_kept}"),
format!("each indicator's series at {series}"),
format!("the footprint at {levels_kept:} price levels").replace("1024", "1,024"),
format!("pending queue at {pending} events").replace("4096", "4,096"),
] {
assert!(
streaming.contains(&claim),
"docs/STREAMING.md does not say {claim:?}"
);
}
for claim in [
format!("| `chart` | {points} bars, {points} price points"),
format!("{bars_kept} bars kept, {prices_kept} price points"),
format!("| `book` | {depth} levels a side"),
format!("| `tape` | {tape_rows} prints | {tape_kept} kept"),
format!("| `footprint` | {depth} levels | {levels_kept} levels kept"),
format!("| `bars` | {depth} bars a stream | {alt_kept} kept"),
] {
assert!(
doc.contains(&claim),
"docs/PANELS.md does not say {claim:?}"
);
}
}
#[test]
fn every_fuzz_target_is_named_in_the_threat_model() {
let root = repo_root();
let model = read(&root, "THREAT_MODEL.md");
let manifest = read(&root, "fuzz/Cargo.toml");
let dir = root.join("fuzz/fuzz_targets");
let mut targets: Vec<String> = std::fs::read_dir(&dir)
.expect("fuzz/fuzz_targets is readable")
.flatten()
.filter_map(|entry| {
let path = entry.path();
(path.extension()? == "rs").then(|| path.file_stem()?.to_str().map(str::to_owned))?
})
.collect();
targets.sort();
assert!(
targets.len() >= 5,
"found only {targets:?} in fuzz/fuzz_targets"
);
for target in &targets {
assert!(
model.contains(&format!("`{target}`")),
"THREAT_MODEL.md does not name the {target} fuzz target"
);
assert!(
manifest.contains(&format!("fuzz_targets/{target}.rs")),
"fuzz/Cargo.toml does not build the {target} target"
);
}
for line in model
.lines()
.filter(|line| line.trim_start().starts_with('|'))
{
let Some(name) = line.split('`').nth(1) else {
continue;
};
if name.ends_with("_parse")
|| name.ends_with("_event")
|| name.ends_with("_fold")
|| name.ends_with("_model")
|| name.ends_with("_drive")
{
assert!(
targets.iter().any(|target| target == name),
"THREAT_MODEL.md names a {name} fuzz target that does not exist"
);
}
}
}
#[test]
fn every_documented_command_is_driven_by_a_binding_suite() {
const SUITE_DIRS: [&str; 9] = [
"bindings/python/tests",
"bindings/node/__tests__",
"bindings/wasm/tests",
"bindings/go",
"bindings/csharp/WickraTerminal.Tests",
"bindings/java/src/test/java/org/wickra/terminal",
"bindings/r/tests",
"examples/c",
"golden/commands",
];
let root = repo_root();
let commands = command_variants(&root);
assert!(
commands.len() >= 16,
"the command enum parsed as {commands:?}, which is not the enum"
);
let mut haystack = String::new();
for dir in SUITE_DIRS {
let path = root.join(dir);
let entries =
std::fs::read_dir(&path).unwrap_or_else(|err| panic!("{dir} is not readable: {err}"));
for entry in entries.flatten() {
if entry.path().is_file() {
if let Ok(text) = std::fs::read_to_string(entry.path()) {
haystack.push_str(&text);
}
}
}
}
assert!(
haystack.len() > 10_000,
"the suites read as {} bytes, which is not the suites",
haystack.len()
);
let undriven: Vec<&str> = commands
.iter()
.copied()
.filter(|name| !haystack.contains(&format!("\"{name}\"")))
.collect();
assert!(
undriven.is_empty(),
"documented in every binding README and driven by no binding suite: {undriven:?}"
);
}
fn command_variants(root: &std::path::Path) -> Vec<&'static str> {
let source = read(root, "crates/wickra-terminal-core/src/terminal.rs");
let start = source
.find("enum Command {")
.expect("the Command enum moved or was renamed");
let body = &source[start..];
let body = &body[..body
.find(
"
}",
)
.expect("an unterminated enum")];
body.lines()
.skip(1)
.filter_map(|line| {
let rest = line.strip_prefix(" ")?;
if rest.starts_with(' ') || !rest.starts_with(char::is_uppercase) {
return None;
}
let name = rest
.split(|c: char| !c.is_alphanumeric() && c != '_')
.next()
.unwrap_or_default();
(!name.is_empty()).then(|| Box::leak(name.to_owned().into_boxed_str()) as &'static str)
})
.collect()
}
#[test]
fn every_binding_readme_documents_every_command() {
let root = repo_root();
let source = read(&root, "crates/wickra-terminal-core/src/terminal.rs");
let start = source
.find("enum Command {")
.expect("the Command enum moved or was renamed");
let body = &source[start..];
let body = &body[..body
.find(
"
}",
)
.expect("an unterminated enum")];
let variants: Vec<&str> = body
.lines()
.skip(1)
.filter_map(|line| {
let rest = line.strip_prefix(" ")?;
if rest.starts_with(' ') || !rest.starts_with(char::is_uppercase) {
return None;
}
Some(
rest.split(|c: char| !c.is_alphanumeric() && c != '_')
.next()
.unwrap_or_default(),
)
})
.filter(|name| !name.is_empty())
.collect();
assert_eq!(
variants.len(),
19,
"expected nineteen commands, found {variants:?}"
);
for rel in BINDING_READMES {
let text = read(&root, rel);
let after_header = text
.split_once("| Command | Effect |")
.unwrap_or_else(|| panic!("{rel} has no command table"))
.1;
let table: String = after_header
.lines()
.skip(1)
.take_while(|line| line.starts_with('|'))
.collect::<Vec<_>>()
.join("\n");
assert!(!table.is_empty(), "{rel}'s command table is empty");
for variant in &variants {
assert!(
table.contains(&format!("`{variant}`")),
"{rel} does not document the {variant} command"
);
}
let spelled = NUMBER_WORDS[variants.len()];
assert!(
text.contains(&format!("the same {spelled} commands")),
"{rel} does not say it drives {spelled} commands"
);
for row in table.lines() {
let command_cell = row.split('|').nth(1).unwrap_or_default();
for name in command_cell.split('`').skip(1).step_by(2) {
assert!(
variants.contains(&name),
"{rel} documents {name}, which is not a command"
);
}
}
}
}
const OPEN: &str = "<!--indicator-count-->";
const CLOSE: &str = "<!--/indicator-count-->";
#[test]
fn benchmarks_md_lists_the_benchmarks_that_exist() {
let root = repo_root();
let bench = fs::read_to_string(root.join("crates/wickra-terminal-bench/benches/terminal.rs"))
.expect("the bench source");
let doc = read(&root, "BENCHMARKS.md");
let defined = names_between(&bench, "bench_function(\"", "\"");
assert!(
!defined.is_empty(),
"no benchmarks found in the bench source"
);
let in_prose = names_between(&doc, "- **`", "`**");
let in_table = names_between(
&doc, "
| `", "`",
);
assert_eq!(
in_prose, defined,
"BENCHMARKS.md's prose and the bench source disagree"
);
assert_eq!(
in_table, defined,
"BENCHMARKS.md's results table and the bench source disagree"
);
}
fn names_between(text: &str, open: &str, close: &str) -> Vec<String> {
let mut found = Vec::new();
let mut rest = text;
while let Some(start) = rest.find(open) {
let after = &rest[start + open.len()..];
let Some(end) = after.find(close) else { break };
found.push(after[..end].to_string());
rest = &after[end + close.len()..];
}
found.sort_unstable();
found.dedup();
found
}
fn table_rows<'a>(text: &'a str, header: &str) -> Vec<&'a str> {
let start = text
.find(header)
.unwrap_or_else(|| panic!("no table headed {header}"));
text[start..]
.lines()
.skip(1)
.take_while(|line| line.starts_with('|'))
.filter(|line| !line.trim_start_matches('|').trim_start().starts_with('-'))
.collect()
}
fn cell(row: &str, index: usize) -> &str {
row.split('|')
.nth(index + 1)
.unwrap_or_else(|| panic!("row has no cell {index}: {row}"))
.trim()
}
#[test]
fn the_documented_input_families_are_the_registered_ones() {
let text = read(&repo_root(), "docs/INDICATORS.md");
let rows = table_rows(&text, "| Input | Fed with | Advances |");
let documented: Vec<String> = rows
.iter()
.map(|row| cell(row, 0).replace(['`', ' '], ""))
.collect();
for family in wickra_terminal_core::registry::INPUT_FAMILIES {
let key = family.replace(' ', "");
assert!(
documented
.iter()
.any(|row| row.ends_with(&format!("({key})")) || row == &key),
"docs/INDICATORS.md lists no input family for {family}; it has {documented:?}"
);
}
assert_eq!(
documented.len(),
wickra_terminal_core::registry::INPUT_FAMILIES.len(),
"docs/INDICATORS.md lists {} input families, the registry feeds {}",
documented.len(),
wickra_terminal_core::registry::INPUT_FAMILIES.len()
);
}
#[test]
fn the_reach_table_sums_to_the_documented_total() {
const FOOTPRINT: usize = 1;
let root = repo_root();
let profiles = wickra_terminal_core::registry::PROFILES.len();
let bars = wickra_terminal_core::registry::BAR_TYPES.len();
let total = wickra_terminal_core::registry::DEFAULTS.len() + profiles + bars + FOOTPRINT;
let text = read(&root, "docs/INDICATORS.md");
let rows = table_rows(&text, "| Surface | Count | What it answers with |");
let mut summed = 0;
for row in &rows {
let surface = cell(row, 0);
let claimed = cell(row, 1)
.replace(OPEN, "")
.replace(CLOSE, "")
.parse::<usize>()
.unwrap_or_else(|_| panic!("the {surface} row states no count"));
let actual = match surface {
"registry" => wickra_terminal_core::registry::DEFAULTS.len(),
"profiles" => profiles,
"alternative bars" => bars,
"the `footprint` panel" => FOOTPRINT,
other => panic!("unknown surface row {other}; teach this test what counts it"),
};
assert_eq!(
claimed, actual,
"the {surface} row claims {claimed}, there are {actual}"
);
summed += actual;
}
assert_eq!(summed, total, "the reach table covers {summed} of {total}");
for rel in ["docs/INDICATORS.md", "README.md", "CHANGELOG.md"] {
let text = read(&root, rel);
let cited: Vec<&str> = text
.match_indices("**")
.filter_map(|(idx, _)| {
let rest = &text[idx + 2..];
let end = rest.find("**")?;
let inner = &rest[..end];
inner.chars().all(|c| c.is_ascii_digit()).then_some(inner)
})
.collect();
assert!(!cited.is_empty(), "{rel} states no reach total");
for claim in cited {
assert_eq!(claim, total.to_string(), "{rel} claims a reach of {claim}");
}
}
}
#[test]
fn every_bound_action_reaches_a_renderer() {
const BROWSER_DECLINES: [&str; 7] = [
"quit",
"next_panel",
"prev_panel",
"scroll_up",
"scroll_down",
"remove_panel",
"move_panel",
];
let root = repo_root();
let input_rs = read(&root, "crates/ui-tui/src/input.rs");
let app_vue = read(&root, "web/src/App.vue");
let binds = wickra_terminal_core::config::Keybinds::default();
assert!(
binds.bindings.len() >= 19,
"the default keymap shrank to {} actions",
binds.bindings.len()
);
for action in binds.bindings.keys() {
assert!(
input_rs.contains(&format!("Some(\"{action}\")")),
"crates/ui-tui/src/input.rs: {action:?} is bound and the TUI keymap resolves it to nothing"
);
if BROWSER_DECLINES.contains(&action.as_str()) {
continue;
}
assert!(
app_vue.contains(&format!("case '{action}'")),
"web/src/App.vue: {action:?} is bound and runAction drops it into the catch-all"
);
}
}
#[test]
fn every_panel_kind_reaches_the_web_renderer() {
let root = repo_root();
let panels_rs = read(&root, "crates/wickra-terminal-core/src/panels/mod.rs");
let types_ts = read(&root, "web/src/types.ts");
let app_vue = read(&root, "web/src/App.vue");
let body = panels_rs
.split_once("pub enum PanelKind {")
.and_then(|(_, rest)| rest.split_once("\n}"))
.map(|(body, _)| body)
.expect("panels/mod.rs declares enum PanelKind");
let kinds: Vec<&str> = body
.lines()
.map(str::trim)
.filter_map(|line| line.strip_suffix(','))
.filter(|name| {
name.chars().next().is_some_and(char::is_uppercase)
&& name.chars().all(char::is_alphanumeric)
})
.collect();
assert!(kinds.len() >= 7, "found only {kinds:?} in PanelKind");
for kind in kinds {
let tag = kind.to_lowercase();
assert!(
types_ts.contains(&format!("'{kind}'")),
"web/src/types.ts: PanelKind has no {kind}, so the layout places nothing for it"
);
assert!(
types_ts.contains(&format!("panel: '{tag}'")),
"web/src/types.ts: PanelView has no {tag} variant, so the frame's is discarded"
);
assert!(
app_vue.contains(&format!("placements.{kind}")),
"web/src/App.vue: no section for {kind}, so it is placed and never drawn"
);
}
}