Add tests for label-processing diagnostics

This commit is contained in:
2025-07-05 22:53:02 -07:00
parent 2e5999ef1e
commit eee57848e0
6 changed files with 116 additions and 13 deletions
+13 -1
View File
@@ -77,7 +77,19 @@ impl<'a> Context<'a> {
pub fn into_messages(self) -> Vec<CompileMessage> {
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"),
}
}
+36 -10
View File
@@ -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<ParsedStat> = 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<String> = base_ctx
.into_messages()
.iter()
.map(|x| x.rich_format(&world))
.collect();
assert_snapshot!(messages.join("\n\n"));
}
}
@@ -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
| ^^
+2 -2
View File
@@ -40,9 +40,9 @@ fn main() -> Result<(), Box<dyn Error>> {
// 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
+3
View File
@@ -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<Board>,
}
#[derive(Clone)]
pub struct Board {
pub name: String,
pub terrain: Vec<[u8; 2]>,
@@ -105,6 +107,7 @@ pub struct Board {
pub stats: Vec<Stat>,
}
#[derive(Clone)]
pub struct Stat {
pub x: u8,
pub y: u8,