From eee57848e01d7c312a1a0c89c74b2bb0a66038b7 Mon Sep 17 00:00:00 2001 From: Chris Mounce Date: Sat, 5 Jul 2025 22:53:02 -0700 Subject: [PATCH] Add tests for label-processing diagnostics --- src/error.rs | 14 +++++- src/labels/process.rs | 46 +++++++++++++++---- ...m__labels__process__test__diagnostics.snap | 46 +++++++++++++++++++ src/main.rs | 4 +- src/world.rs | 3 ++ tests/labels/diagnostics.txt | 16 +++++++ 6 files changed, 116 insertions(+), 13 deletions(-) create mode 100644 src/labels/snapshots/zasm__labels__process__test__diagnostics.snap create mode 100644 tests/labels/diagnostics.txt diff --git a/src/error.rs b/src/error.rs index 48681ac..d7f5caf 100644 --- a/src/error.rs +++ b/src/error.rs @@ -77,7 +77,19 @@ impl<'a> Context<'a> { pub fn into_messages(self) -> Vec { match self { - Context::Base(refcell) => refcell.into_inner(), + Context::Base(refcell) => { + let mut messages = refcell.into_inner(); + messages.sort_by_key(|msg| { + let loc = &msg.location; + ( + loc.file_path.as_ref().map(|x| x.clone()), + loc.board, + loc.stat, + loc.span.as_ref().map(|s| s.start), + ) + }); + messages + } _ => panic!("into_messages() may only be called on the base context"), } } diff --git a/src/labels/process.rs b/src/labels/process.rs index abd55d6..6cd07c8 100644 --- a/src/labels/process.rs +++ b/src/labels/process.rs @@ -8,7 +8,9 @@ use super::{ sanitize::Registry, }; -pub fn process_labels(board: &mut Board, ctx: &Context) { +pub fn process_labels(board: &Board, ctx: &Context) -> Board { + let mut board = board.clone(); + // Parse stats into chunks let mut stats: Vec = board .stats @@ -40,6 +42,8 @@ pub fn process_labels(board: &mut Board, ctx: &Context) { .collect(); old_stat.code = new_code; } + + board } /// Resolve ".local" labels to "name.local" form. @@ -218,7 +222,7 @@ mod test { use crate::{ error::Context, - world::{Board, Stat}, + world::{Board, Stat, World}, }; use super::process_labels; @@ -251,6 +255,12 @@ mod test { board } + fn world_from_text(path: &str) -> World { + let mut world = World::default(); + world.boards.push(board_from_text(path)); + world + } + fn board_to_text(board: Board) -> String { let codes: Vec<_> = board.stats.into_iter().map(|stat| stat.code).collect(); codes.join("---\n") @@ -258,29 +268,45 @@ mod test { #[test] fn test_label_sanitization() { - let mut board = board_from_text("tests/labels/sanitize.txt"); - let _ = process_labels(&mut board, &Context::new()); + let board = board_from_text("tests/labels/sanitize.txt"); + let board = process_labels(&board, &Context::new()); assert_snapshot!(board_to_text(board)); } #[test] fn test_anonymous_labels() { - let mut board = board_from_text("tests/labels/anonymous.txt"); - let _ = process_labels(&mut board, &Context::new()); + let board = board_from_text("tests/labels/anonymous.txt"); + let board = process_labels(&board, &Context::new()); assert_snapshot!(board_to_text(board)); } #[test] fn test_local_labels() { - let mut board = board_from_text("tests/labels/local.txt"); - let _ = process_labels(&mut board, &Context::new()); + let board = board_from_text("tests/labels/local.txt"); + let board = process_labels(&board, &Context::new()); assert_snapshot!(board_to_text(board)); } #[test] fn test_namespaces() { - let mut board = board_from_text("tests/labels/namespaces.txt"); - let _ = process_labels(&mut board, &Context::new()); + let board = board_from_text("tests/labels/namespaces.txt"); + let board = process_labels(&board, &Context::new()); assert_snapshot!(board_to_text(board)); } + + #[test] + fn test_diagnostics() { + let world = world_from_text("tests/labels/diagnostics.txt"); + let base_ctx = Context::new(); + process_labels( + &world.boards[0], + &base_ctx.with_file_path("test.zzt").with_board(0), + ); + let messages: Vec = base_ctx + .into_messages() + .iter() + .map(|x| x.rich_format(&world)) + .collect(); + assert_snapshot!(messages.join("\n\n")); + } } diff --git a/src/labels/snapshots/zasm__labels__process__test__diagnostics.snap b/src/labels/snapshots/zasm__labels__process__test__diagnostics.snap new file mode 100644 index 0000000..557308b --- /dev/null +++ b/src/labels/snapshots/zasm__labels__process__test__diagnostics.snap @@ -0,0 +1,46 @@ +--- +source: src/labels/process.rs +expression: "messages.join(\"\\n\\n\")" +--- +warning: trailing characters at end of line + => test.zzt -> Title screen -> @Trailing (1,1) -> line 2:5 + | + 1 | @Trailing + 2 | #end trailing text + | ^^^^^^^^^^^^^^ + +error: backward reference needs an anonymous label + => test.zzt -> Title screen -> @Invalid anon (1,1) -> line 2:7 + | + 1 | @Invalid anon + 2 | #send @b + | ^^ + 3 | :@ + 4 | #send @f + | + +error: forward reference needs an anonymous label + => test.zzt -> Title screen -> @Invalid anon (1,1) -> line 4:7 + | + 1 | @Invalid anon + 2 | #send @b + 3 | :@ + 4 | #send @f + | ^^ + +error: forward reference needs an anonymous label + => test.zzt -> Title screen -> @Errors in sorted order (1,1) -> line 2:7 + | + 1 | @Errors in sorted order + 2 | #send @f + | ^^ + 3 | #send @b + | + +error: backward reference needs an anonymous label + => test.zzt -> Title screen -> @Errors in sorted order (1,1) -> line 3:7 + | + 1 | @Errors in sorted order + 2 | #send @f + 3 | #send @b + | ^^ diff --git a/src/main.rs b/src/main.rs index dadabfb..006331d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -40,9 +40,9 @@ fn main() -> Result<(), Box> { // Resolve labels to proper ZZT-OOP let base_ctx = ErrContext::new(); let ctx = base_ctx.with_file_path(&world_filename); - for (i, mut board) in world.boards.iter_mut().enumerate() { + for (i, board) in world.boards.iter_mut().enumerate() { let ctx = ctx.with_board(i); - process_labels(&mut board, &ctx); + *board = process_labels(&board, &ctx); } // Print diagnostics diff --git a/src/world.rs b/src/world.rs index dbb7276..b66329d 100644 --- a/src/world.rs +++ b/src/world.rs @@ -70,6 +70,7 @@ impl Error for LoadError { } } +#[derive(Default)] pub struct World { pub ammo: i16, pub gems: i16, @@ -88,6 +89,7 @@ pub struct World { pub boards: Vec, } +#[derive(Clone)] pub struct Board { pub name: String, pub terrain: Vec<[u8; 2]>, @@ -105,6 +107,7 @@ pub struct Board { pub stats: Vec, } +#[derive(Clone)] pub struct Stat { pub x: u8, pub y: u8, diff --git a/tests/labels/diagnostics.txt b/tests/labels/diagnostics.txt new file mode 100644 index 0000000..6899f40 --- /dev/null +++ b/tests/labels/diagnostics.txt @@ -0,0 +1,16 @@ +@Trailing +#end trailing text +--- +@Valid anon +#send @f +:@ +#send @b +--- +@Invalid anon +#send @b +:@ +#send @f +--- +@Errors in sorted order +#send @f +#send @b