ADR-0024 Phase E: replay end-to-end

Migrate `replay <path>` to the walker. Shape is
Choice(StringLit, BarePath); the StringLit branch handles the
quoted form (with the existing `''` escape), and BarePath
handles the unquoted form.

Per ADR-0024's path-bearing UX change (already shipped for
import / export in Phase A), bare `replay` paths terminate at
the first whitespace byte. Paths with spaces require the
quoted form. The legacy `try_parse_replay_with_bare_path`
source-slice helper in dsl/parser.rs is removed; the
chumsky-side replay branch in command_parser stays declared
but unreachable until Phase F sweeps the chumsky path.

Tests:
- 7 new walker-specific tests for replay: bare relative path,
  bare absolute path, quoted with whitespace, quoted with
  escaped quote, case-insensitive keyword, missing-path
  error, empty-quoted-path parses to empty (runtime layer
  rejects).
- Total: 844 passed, 0 failed, 1 ignored (was 838 / 1).
- cargo clippy --all-targets -- -D warnings clean.
This commit is contained in:
claude@clouddev1
2026-05-15 07:23:51 +00:00
parent c2accc2385
commit dca472f8a5
4 changed files with 115 additions and 51 deletions
+70 -6
View File
@@ -907,13 +907,77 @@ mod tests {
assert!(parse("update Customers set Email='x'").is_err());
}
// =========================================================
// Phase E — replay.
// =========================================================
#[test]
fn walker_does_not_engage_for_replay() {
// `replay` isn't migrated yet (Phase E); router falls
// through to chumsky.
assert!(matches!(
fn walker_parses_replay_with_bare_relative_path() {
assert_eq!(
parse("replay history.log").unwrap(),
Command::Replay { .. }
));
Command::Replay {
path: "history.log".to_string(),
}
);
}
#[test]
fn walker_parses_replay_with_bare_absolute_path() {
assert_eq!(
parse("replay /tmp/seed.commands").unwrap(),
Command::Replay {
path: "/tmp/seed.commands".to_string(),
}
);
}
#[test]
fn walker_parses_replay_with_quoted_path_supports_whitespace() {
// Phase A's path-bearing UX change: paths with spaces use
// the quoted form.
assert_eq!(
parse("replay 'my project/seed.commands'").unwrap(),
Command::Replay {
path: "my project/seed.commands".to_string(),
}
);
}
#[test]
fn walker_parses_replay_with_quoted_path_supports_escaped_quote() {
assert_eq!(
parse("replay 'O''Brien.commands'").unwrap(),
Command::Replay {
path: "O'Brien.commands".to_string(),
}
);
}
#[test]
fn walker_replay_keyword_case_insensitive() {
assert_eq!(
parse("REPLAY foo.txt").unwrap(),
Command::Replay {
path: "foo.txt".to_string(),
}
);
}
#[test]
fn walker_replay_without_path_errors() {
assert!(parse("replay").is_err());
}
#[test]
fn walker_replay_with_empty_quoted_path_parses_as_empty() {
// Parser layer accepts; runtime rejects empty paths
// before any I/O. Mirrors the chumsky-side contract
// (parser.rs `replay_with_empty_quoted_path_errors`).
assert_eq!(
parse("replay ''").unwrap(),
Command::Replay {
path: String::new(),
}
);
}
}