mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-10-08 03:10:26 +00:00
Tests were flaky because command() inherited the real repo as the working directory. When the repo was clean, detached runs attempted git worktree creation against it, sometimes failing and injecting extra warning lines into snapshots. Now command() defaults to the non-git temp_dir, eliminating this class of flakiness. Tests needing a specific directory override with .current_dir(). Also canonicalizes fixture paths and adds a [FIXTURES] snapshot filter via test_context!() macro. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
123 lines
4.1 KiB
Rust
123 lines
4.1 KiB
Rust
use insta::assert_snapshot;
|
|
|
|
use fabro_test::{fabro_snapshot, run_and_format, test_context};
|
|
|
|
use super::support::{
|
|
git_filters, git_stdout, output_stderr as support_stderr, run_branch_commits_since_base,
|
|
setup_git_backed_changed_run,
|
|
};
|
|
|
|
#[test]
|
|
fn help() {
|
|
let context = test_context!();
|
|
let mut cmd = context.command();
|
|
cmd.args(["rewind", "--help"]);
|
|
fabro_snapshot!(context.filters(), cmd, @"
|
|
success: true
|
|
exit_code: 0
|
|
----- stdout -----
|
|
Rewind a workflow run to an earlier checkpoint
|
|
|
|
Usage: fabro rewind [OPTIONS] <RUN_ID> [TARGET]
|
|
|
|
Arguments:
|
|
<RUN_ID> Run ID (or unambiguous prefix)
|
|
[TARGET] Target checkpoint: node name, node@visit, or @ordinal (omit with --list)
|
|
|
|
Options:
|
|
--json Output as JSON [env: FABRO_JSON=]
|
|
--list Show the checkpoint timeline instead of rewinding
|
|
--debug Enable DEBUG-level logging (default is INFO) [env: FABRO_DEBUG=]
|
|
--no-push Skip force-pushing rewound refs to the remote
|
|
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
|
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
|
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
|
--storage-dir <STORAGE_DIR> Storage directory (default: ~/.fabro) [env: FABRO_STORAGE_DIR=[STORAGE_DIR]]
|
|
-h, --help Print help
|
|
----- stderr -----
|
|
");
|
|
}
|
|
|
|
#[test]
|
|
fn rewind_outside_git_repo_errors() {
|
|
let context = test_context!();
|
|
let mut cmd = context.command();
|
|
cmd.args(["rewind", "01ARZ3NDEKTSV4RRFFQ69G5FAW", "--list"]);
|
|
|
|
fabro_snapshot!(context.filters(), cmd, @"
|
|
success: false
|
|
exit_code: 1
|
|
----- stdout -----
|
|
----- stderr -----
|
|
error: not in a git repository
|
|
> could not find repository at '.'; class=Repository (6); code=NotFound (-3)
|
|
");
|
|
}
|
|
|
|
#[test]
|
|
fn rewind_list_prints_timeline_for_completed_git_run() {
|
|
let context = test_context!();
|
|
let setup = setup_git_backed_changed_run(&context);
|
|
let mut cmd = context.command();
|
|
cmd.current_dir(&setup.repo_dir);
|
|
cmd.args(["rewind", &setup.run.run_id, "--list"]);
|
|
|
|
fabro_snapshot!(git_filters(&context), cmd, @"
|
|
success: true
|
|
exit_code: 0
|
|
----- stdout -----
|
|
----- stderr -----
|
|
@ Node Details
|
|
@1 step_one
|
|
@2 step_two
|
|
");
|
|
}
|
|
|
|
#[test]
|
|
fn rewind_target_updates_metadata_and_resume_hint() {
|
|
let context = test_context!();
|
|
let setup = setup_git_backed_changed_run(&context);
|
|
let expected_run_head =
|
|
run_branch_commits_since_base(&setup.repo_dir, &setup.run.run_id, &setup.base_sha)
|
|
.into_iter()
|
|
.next()
|
|
.expect("source run should have a first run commit");
|
|
|
|
let mut cmd = context.command();
|
|
cmd.current_dir(&setup.repo_dir);
|
|
cmd.args(["rewind", &setup.run.run_id, "@1", "--no-push"]);
|
|
|
|
let (snapshot, output) = run_and_format(&mut cmd, &git_filters(&context));
|
|
assert_snapshot!(snapshot, @"
|
|
success: true
|
|
exit_code: 0
|
|
----- stdout -----
|
|
----- stderr -----
|
|
Rewound metadata branch to @1 (step_one)
|
|
Rewound run branch fabro/run/[ULID] to [SHA]
|
|
|
|
To resume: fabro resume [RUN_PREFIX]
|
|
");
|
|
assert!(output.status.success(), "rewind should succeed");
|
|
|
|
let run_head = git_stdout(
|
|
&setup.repo_dir,
|
|
&["rev-parse", &format!("fabro/run/{}", setup.run.run_id)],
|
|
);
|
|
assert_eq!(run_head.trim(), expected_run_head);
|
|
|
|
let mut list_cmd = context.command();
|
|
list_cmd.current_dir(&setup.repo_dir);
|
|
list_cmd.args(["rewind", &setup.run.run_id, "--list"]);
|
|
let list_output = list_cmd.output().expect("rewind --list should execute");
|
|
assert!(list_output.status.success(), "rewind --list should succeed");
|
|
let list = support_stderr(&list_output);
|
|
assert!(
|
|
list.contains("@1"),
|
|
"rewound timeline should keep @1: {list}"
|
|
);
|
|
assert!(
|
|
!list.contains("@2"),
|
|
"rewound timeline should drop @2: {list}"
|
|
);
|
|
}
|