Skip to main content

concinnity_dev/authoring/
check.rs

1// src/check.rs
2// Validate a world JSONL without producing blob files.
3//
4// Runs the validation front half of the build pipeline (load, expand, and
5// the semantic checks in `crate::check`) and reports the outcome. Used by
6// `cn test`, the FFI `cn_check_world` entry, and the infra agentic loop.
7
8/// Read `world_path`, run validation, and report results. Returns Ok if every
9/// asset passes; otherwise an error whose Display contains a human-readable
10/// summary of every failure (one per asset).
11pub fn check_at_path(world_path: &str) -> std::io::Result<()> {
12    let content = std::fs::read_to_string(world_path)?;
13    check_from_str(&content, world_path)
14}
15
16/// Run validation against an in-memory world JSONL string. `label` is the
17/// origin used in messages (typically the source path).
18pub fn check_from_str(content: &str, label: &str) -> std::io::Result<()> {
19    match concinnity_cook::prepare_world(content, super::assets_root::assets_dir().as_deref()) {
20        Ok(loaded) => {
21            println!("ok: {} asset(s) passed in {}", loaded.assets.len(), label);
22            Ok(())
23        }
24        Err(errors) => Err(concinnity_cook::check::report_validation_errors(&errors)),
25    }
26}
27
28#[cfg(test)]
29mod tests {
30    use super::*;
31
32    #[test]
33    fn check_from_str_accepts_a_valid_world() {
34        check_from_str(
35            "{\"name\":\"phys\",\"type\":\"PhysicsConfig\",\"args\":{}}\n",
36            "test",
37        )
38        .unwrap();
39    }
40
41    #[test]
42    fn check_from_str_rejects_an_unknown_type() {
43        let err = check_from_str(
44            "{\"name\":\"odd\",\"type\":\"NotARealAssetType\",\"args\":{}}\n",
45            "test",
46        )
47        .unwrap_err();
48        assert!(!err.to_string().is_empty());
49    }
50
51    #[test]
52    fn check_at_path_reports_a_missing_file() {
53        let dir = tempfile::tempdir().unwrap();
54        let path = dir.path().join("missing.jsonl");
55        assert!(check_at_path(path.to_str().unwrap()).is_err());
56    }
57
58    #[test]
59    fn check_at_path_accepts_a_valid_world_file() {
60        let dir = tempfile::tempdir().unwrap();
61        let path = dir.path().join("world.jsonl");
62        std::fs::write(
63            &path,
64            "{\"name\":\"phys\",\"type\":\"PhysicsConfig\",\"args\":{}}\n",
65        )
66        .unwrap();
67        check_at_path(path.to_str().unwrap()).unwrap();
68    }
69}