Fix 25 tests for work/ directory restructure (story 60)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Dave
2026-02-20 17:24:26 +00:00
parent e1e0d49759
commit e15fbffbb8
3 changed files with 124 additions and 124 deletions

View File

@@ -1304,12 +1304,12 @@ mod tests {
let repo = tmp.path(); let repo = tmp.path();
init_git_repo(repo); init_git_repo(repo);
let upcoming = repo.join(".story_kit/stories/upcoming"); let upcoming = repo.join(".story_kit/work/1_upcoming");
let current_dir = repo.join(".story_kit/current"); let current_dir = repo.join(".story_kit/work/2_current");
fs::create_dir_all(&upcoming).unwrap(); fs::create_dir_all(&upcoming).unwrap();
fs::create_dir_all(&current_dir).unwrap(); fs::create_dir_all(&current_dir).unwrap();
let story_file = upcoming.join("10_my_story.md"); let story_file = upcoming.join("10_story_my_story.md");
fs::write(&story_file, "---\nname: Test\ntest_plan: pending\n---\n").unwrap(); fs::write(&story_file, "---\nname: Test\ntest_plan: pending\n---\n").unwrap();
Command::new("git") Command::new("git")
@@ -1323,11 +1323,11 @@ mod tests {
.output() .output()
.unwrap(); .unwrap();
move_story_to_current(repo, "10_my_story").unwrap(); move_story_to_current(repo, "10_story_my_story").unwrap();
assert!(!story_file.exists(), "upcoming file should be gone"); assert!(!story_file.exists(), "upcoming file should be gone");
assert!( assert!(
current_dir.join("10_my_story.md").exists(), current_dir.join("10_story_my_story.md").exists(),
"current/ file should exist" "current/ file should exist"
); );
} }
@@ -1341,18 +1341,18 @@ mod tests {
let repo = tmp.path(); let repo = tmp.path();
init_git_repo(repo); init_git_repo(repo);
let current_dir = repo.join(".story_kit/current"); let current_dir = repo.join(".story_kit/work/2_current");
fs::create_dir_all(&current_dir).unwrap(); fs::create_dir_all(&current_dir).unwrap();
fs::write( fs::write(
current_dir.join("11_my_story.md"), current_dir.join("11_story_my_story.md"),
"---\nname: Test\ntest_plan: pending\n---\n", "---\nname: Test\ntest_plan: pending\n---\n",
) )
.unwrap(); .unwrap();
// Should succeed without error even though there's nothing to move // Should succeed without error even though there's nothing to move
move_story_to_current(repo, "11_my_story").unwrap(); move_story_to_current(repo, "11_story_my_story").unwrap();
assert!(current_dir.join("11_my_story.md").exists()); assert!(current_dir.join("11_story_my_story.md").exists());
} }
#[test] #[test]
@@ -1377,12 +1377,12 @@ mod tests {
let repo = tmp.path(); let repo = tmp.path();
init_git_repo(repo); init_git_repo(repo);
let bugs_dir = repo.join(".story_kit/bugs"); let upcoming_dir = repo.join(".story_kit/work/1_upcoming");
let current_dir = repo.join(".story_kit/current"); let current_dir = repo.join(".story_kit/work/2_current");
fs::create_dir_all(&bugs_dir).unwrap(); fs::create_dir_all(&upcoming_dir).unwrap();
fs::create_dir_all(&current_dir).unwrap(); fs::create_dir_all(&current_dir).unwrap();
let bug_file = bugs_dir.join("bug-1-test.md"); let bug_file = upcoming_dir.join("1_bug_test.md");
fs::write(&bug_file, "# Bug 1\n").unwrap(); fs::write(&bug_file, "# Bug 1\n").unwrap();
Command::new("git") Command::new("git")
@@ -1396,11 +1396,11 @@ mod tests {
.output() .output()
.unwrap(); .unwrap();
move_story_to_current(repo, "bug-1-test").unwrap(); move_story_to_current(repo, "1_bug_test").unwrap();
assert!(!bug_file.exists(), "bugs/ file should be gone"); assert!(!bug_file.exists(), "upcoming/ file should be gone");
assert!( assert!(
current_dir.join("bug-1-test.md").exists(), current_dir.join("1_bug_test.md").exists(),
"current/ file should exist" "current/ file should exist"
); );
} }
@@ -1414,10 +1414,10 @@ mod tests {
let repo = tmp.path(); let repo = tmp.path();
init_git_repo(repo); init_git_repo(repo);
let current_dir = repo.join(".story_kit/current"); let current_dir = repo.join(".story_kit/work/2_current");
fs::create_dir_all(&current_dir).unwrap(); fs::create_dir_all(&current_dir).unwrap();
let bug_in_current = current_dir.join("bug-2-test.md"); let bug_in_current = current_dir.join("2_bug_test.md");
fs::write(&bug_in_current, "# Bug 2\n").unwrap(); fs::write(&bug_in_current, "# Bug 2\n").unwrap();
Command::new("git") Command::new("git")
@@ -1431,9 +1431,9 @@ mod tests {
.output() .output()
.unwrap(); .unwrap();
close_bug_to_archive(repo, "bug-2-test").unwrap(); close_bug_to_archive(repo, "2_bug_test").unwrap();
let archive_path = repo.join(".story_kit/bugs/archive/bug-2-test.md"); let archive_path = repo.join(".story_kit/work/5_archived/2_bug_test.md");
assert!(!bug_in_current.exists(), "current/ file should be gone"); assert!(!bug_in_current.exists(), "current/ file should be gone");
assert!(archive_path.exists(), "archive file should exist"); assert!(archive_path.exists(), "archive file should exist");
} }
@@ -1447,10 +1447,10 @@ mod tests {
let repo = tmp.path(); let repo = tmp.path();
init_git_repo(repo); init_git_repo(repo);
let bugs_dir = repo.join(".story_kit/bugs"); let upcoming_dir = repo.join(".story_kit/work/1_upcoming");
fs::create_dir_all(&bugs_dir).unwrap(); fs::create_dir_all(&upcoming_dir).unwrap();
let bug_file = bugs_dir.join("bug-3-test.md"); let bug_file = upcoming_dir.join("3_bug_test.md");
fs::write(&bug_file, "# Bug 3\n").unwrap(); fs::write(&bug_file, "# Bug 3\n").unwrap();
Command::new("git") Command::new("git")
@@ -1464,19 +1464,19 @@ mod tests {
.output() .output()
.unwrap(); .unwrap();
close_bug_to_archive(repo, "bug-3-test").unwrap(); close_bug_to_archive(repo, "3_bug_test").unwrap();
let archive_path = repo.join(".story_kit/bugs/archive/bug-3-test.md"); let archive_path = repo.join(".story_kit/work/5_archived/3_bug_test.md");
assert!(!bug_file.exists(), "bugs/ file should be gone"); assert!(!bug_file.exists(), "upcoming/ file should be gone");
assert!(archive_path.exists(), "archive file should exist"); assert!(archive_path.exists(), "archive file should exist");
} }
#[test] #[test]
fn item_type_from_id_detects_types() { fn item_type_from_id_detects_types() {
assert_eq!(item_type_from_id("bug-1-test"), "bug"); assert_eq!(item_type_from_id("1_bug_test"), "bug");
assert_eq!(item_type_from_id("spike-1-research"), "spike"); assert_eq!(item_type_from_id("1_spike_research"), "spike");
assert_eq!(item_type_from_id("50_my_story"), "story"); assert_eq!(item_type_from_id("50_story_my_story"), "story");
assert_eq!(item_type_from_id("1_simple"), "story"); assert_eq!(item_type_from_id("1_story_simple"), "story");
} }
// ── git_stage_and_commit tests ───────────────────────────────────────────── // ── git_stage_and_commit tests ─────────────────────────────────────────────

View File

@@ -1531,7 +1531,7 @@ mod tests {
#[test] #[test]
fn tool_get_story_todos_returns_unchecked() { fn tool_get_story_todos_returns_unchecked() {
let tmp = tempfile::tempdir().unwrap(); let tmp = tempfile::tempdir().unwrap();
let current_dir = tmp.path().join(".story_kit").join("current"); let current_dir = tmp.path().join(".story_kit").join("work").join("2_current");
fs::create_dir_all(&current_dir).unwrap(); fs::create_dir_all(&current_dir).unwrap();
fs::write( fs::write(
current_dir.join("1_test.md"), current_dir.join("1_test.md"),
@@ -1944,10 +1944,10 @@ mod tests {
) )
.unwrap(); .unwrap();
assert!(result.contains("bug-1-login_crash")); assert!(result.contains("1_bug_login_crash"));
let bug_file = tmp let bug_file = tmp
.path() .path()
.join(".story_kit/bugs/bug-1-login_crash.md"); .join(".story_kit/work/1_upcoming/1_bug_login_crash.md");
assert!(bug_file.exists()); assert!(bug_file.exists());
} }
@@ -1963,15 +1963,15 @@ mod tests {
#[test] #[test]
fn tool_list_bugs_returns_open_bugs() { fn tool_list_bugs_returns_open_bugs() {
let tmp = tempfile::tempdir().unwrap(); let tmp = tempfile::tempdir().unwrap();
let bugs_dir = tmp.path().join(".story_kit/bugs"); let upcoming_dir = tmp.path().join(".story_kit/work/1_upcoming");
std::fs::create_dir_all(&bugs_dir).unwrap(); std::fs::create_dir_all(&upcoming_dir).unwrap();
std::fs::write( std::fs::write(
bugs_dir.join("bug-1-crash.md"), upcoming_dir.join("1_bug_crash.md"),
"# Bug 1: App Crash\n", "# Bug 1: App Crash\n",
) )
.unwrap(); .unwrap();
std::fs::write( std::fs::write(
bugs_dir.join("bug-2-typo.md"), upcoming_dir.join("2_bug_typo.md"),
"# Bug 2: Typo in Header\n", "# Bug 2: Typo in Header\n",
) )
.unwrap(); .unwrap();
@@ -1980,9 +1980,9 @@ mod tests {
let result = tool_list_bugs(&ctx).unwrap(); let result = tool_list_bugs(&ctx).unwrap();
let parsed: Vec<Value> = serde_json::from_str(&result).unwrap(); let parsed: Vec<Value> = serde_json::from_str(&result).unwrap();
assert_eq!(parsed.len(), 2); assert_eq!(parsed.len(), 2);
assert_eq!(parsed[0]["bug_id"], "bug-1-crash"); assert_eq!(parsed[0]["bug_id"], "1_bug_crash");
assert_eq!(parsed[0]["name"], "App Crash"); assert_eq!(parsed[0]["name"], "App Crash");
assert_eq!(parsed[1]["bug_id"], "bug-2-typo"); assert_eq!(parsed[1]["bug_id"], "2_bug_typo");
assert_eq!(parsed[1]["name"], "Typo in Header"); assert_eq!(parsed[1]["name"], "Typo in Header");
} }
@@ -1999,9 +1999,9 @@ mod tests {
fn tool_close_bug_moves_to_archive() { fn tool_close_bug_moves_to_archive() {
let tmp = tempfile::tempdir().unwrap(); let tmp = tempfile::tempdir().unwrap();
setup_git_repo_in(tmp.path()); setup_git_repo_in(tmp.path());
let bugs_dir = tmp.path().join(".story_kit/bugs"); let upcoming_dir = tmp.path().join(".story_kit/work/1_upcoming");
std::fs::create_dir_all(&bugs_dir).unwrap(); std::fs::create_dir_all(&upcoming_dir).unwrap();
let bug_file = bugs_dir.join("bug-1-crash.md"); let bug_file = upcoming_dir.join("1_bug_crash.md");
std::fs::write(&bug_file, "# Bug 1: Crash\n").unwrap(); std::fs::write(&bug_file, "# Bug 1: Crash\n").unwrap();
// Stage the file so it's tracked // Stage the file so it's tracked
std::process::Command::new("git") std::process::Command::new("git")
@@ -2016,9 +2016,9 @@ mod tests {
.unwrap(); .unwrap();
let ctx = test_ctx(tmp.path()); let ctx = test_ctx(tmp.path());
let result = tool_close_bug(&json!({"bug_id": "bug-1-crash"}), &ctx).unwrap(); let result = tool_close_bug(&json!({"bug_id": "1_bug_crash"}), &ctx).unwrap();
assert!(result.contains("bug-1-crash")); assert!(result.contains("1_bug_crash"));
assert!(!bug_file.exists()); assert!(!bug_file.exists());
assert!(bugs_dir.join("archive/bug-1-crash.md").exists()); assert!(tmp.path().join(".story_kit/work/5_archived/1_bug_crash.md").exists());
} }
} }

View File

@@ -1220,15 +1220,15 @@ mod tests {
#[test] #[test]
fn load_upcoming_parses_metadata() { fn load_upcoming_parses_metadata() {
let tmp = tempfile::tempdir().unwrap(); let tmp = tempfile::tempdir().unwrap();
let upcoming = tmp.path().join(".story_kit/stories/upcoming"); let upcoming = tmp.path().join(".story_kit/work/1_upcoming");
fs::create_dir_all(&upcoming).unwrap(); fs::create_dir_all(&upcoming).unwrap();
fs::write( fs::write(
upcoming.join("31_view_upcoming.md"), upcoming.join("31_story_view_upcoming.md"),
"---\nname: View Upcoming\ntest_plan: pending\n---\n# Story\n", "---\nname: View Upcoming\ntest_plan: pending\n---\n# Story\n",
) )
.unwrap(); .unwrap();
fs::write( fs::write(
upcoming.join("32_worktree.md"), upcoming.join("32_story_worktree.md"),
"---\nname: Worktree Orchestration\ntest_plan: pending\n---\n# Story\n", "---\nname: Worktree Orchestration\ntest_plan: pending\n---\n# Story\n",
) )
.unwrap(); .unwrap();
@@ -1236,20 +1236,20 @@ mod tests {
let ctx = crate::http::context::AppContext::new_test(tmp.path().to_path_buf()); let ctx = crate::http::context::AppContext::new_test(tmp.path().to_path_buf());
let stories = load_upcoming_stories(&ctx).unwrap(); let stories = load_upcoming_stories(&ctx).unwrap();
assert_eq!(stories.len(), 2); assert_eq!(stories.len(), 2);
assert_eq!(stories[0].story_id, "31_view_upcoming"); assert_eq!(stories[0].story_id, "31_story_view_upcoming");
assert_eq!(stories[0].name.as_deref(), Some("View Upcoming")); assert_eq!(stories[0].name.as_deref(), Some("View Upcoming"));
assert_eq!(stories[1].story_id, "32_worktree"); assert_eq!(stories[1].story_id, "32_story_worktree");
assert_eq!(stories[1].name.as_deref(), Some("Worktree Orchestration")); assert_eq!(stories[1].name.as_deref(), Some("Worktree Orchestration"));
} }
#[test] #[test]
fn load_upcoming_skips_non_md_files() { fn load_upcoming_skips_non_md_files() {
let tmp = tempfile::tempdir().unwrap(); let tmp = tempfile::tempdir().unwrap();
let upcoming = tmp.path().join(".story_kit/stories/upcoming"); let upcoming = tmp.path().join(".story_kit/work/1_upcoming");
fs::create_dir_all(&upcoming).unwrap(); fs::create_dir_all(&upcoming).unwrap();
fs::write(upcoming.join(".gitkeep"), "").unwrap(); fs::write(upcoming.join(".gitkeep"), "").unwrap();
fs::write( fs::write(
upcoming.join("31_story.md"), upcoming.join("31_story_example.md"),
"---\nname: A Story\ntest_plan: pending\n---\n", "---\nname: A Story\ntest_plan: pending\n---\n",
) )
.unwrap(); .unwrap();
@@ -1257,23 +1257,23 @@ mod tests {
let ctx = crate::http::context::AppContext::new_test(tmp.path().to_path_buf()); let ctx = crate::http::context::AppContext::new_test(tmp.path().to_path_buf());
let stories = load_upcoming_stories(&ctx).unwrap(); let stories = load_upcoming_stories(&ctx).unwrap();
assert_eq!(stories.len(), 1); assert_eq!(stories.len(), 1);
assert_eq!(stories[0].story_id, "31_story"); assert_eq!(stories[0].story_id, "31_story_example");
} }
#[test] #[test]
fn validate_story_dirs_valid_files() { fn validate_story_dirs_valid_files() {
let tmp = tempfile::tempdir().unwrap(); let tmp = tempfile::tempdir().unwrap();
let current = tmp.path().join(".story_kit/current"); let current = tmp.path().join(".story_kit/work/2_current");
let upcoming = tmp.path().join(".story_kit/stories/upcoming"); let upcoming = tmp.path().join(".story_kit/work/1_upcoming");
fs::create_dir_all(&current).unwrap(); fs::create_dir_all(&current).unwrap();
fs::create_dir_all(&upcoming).unwrap(); fs::create_dir_all(&upcoming).unwrap();
fs::write( fs::write(
current.join("28_todos.md"), current.join("28_story_todos.md"),
"---\nname: Show TODOs\ntest_plan: approved\n---\n# Story\n", "---\nname: Show TODOs\ntest_plan: approved\n---\n# Story\n",
) )
.unwrap(); .unwrap();
fs::write( fs::write(
upcoming.join("36_front_matter.md"), upcoming.join("36_story_front_matter.md"),
"---\nname: Enforce Front Matter\ntest_plan: pending\n---\n# Story\n", "---\nname: Enforce Front Matter\ntest_plan: pending\n---\n# Story\n",
) )
.unwrap(); .unwrap();
@@ -1287,9 +1287,9 @@ mod tests {
#[test] #[test]
fn validate_story_dirs_missing_front_matter() { fn validate_story_dirs_missing_front_matter() {
let tmp = tempfile::tempdir().unwrap(); let tmp = tempfile::tempdir().unwrap();
let current = tmp.path().join(".story_kit/current"); let current = tmp.path().join(".story_kit/work/2_current");
fs::create_dir_all(&current).unwrap(); fs::create_dir_all(&current).unwrap();
fs::write(current.join("28_todos.md"), "# No front matter\n").unwrap(); fs::write(current.join("28_story_todos.md"), "# No front matter\n").unwrap();
let results = validate_story_dirs(tmp.path()).unwrap(); let results = validate_story_dirs(tmp.path()).unwrap();
assert_eq!(results.len(), 1); assert_eq!(results.len(), 1);
@@ -1300,9 +1300,9 @@ mod tests {
#[test] #[test]
fn validate_story_dirs_missing_required_fields() { fn validate_story_dirs_missing_required_fields() {
let tmp = tempfile::tempdir().unwrap(); let tmp = tempfile::tempdir().unwrap();
let current = tmp.path().join(".story_kit/current"); let current = tmp.path().join(".story_kit/work/2_current");
fs::create_dir_all(&current).unwrap(); fs::create_dir_all(&current).unwrap();
fs::write(current.join("28_todos.md"), "---\n---\n# Story\n").unwrap(); fs::write(current.join("28_story_todos.md"), "---\n---\n# Story\n").unwrap();
let results = validate_story_dirs(tmp.path()).unwrap(); let results = validate_story_dirs(tmp.path()).unwrap();
assert_eq!(results.len(), 1); assert_eq!(results.len(), 1);
@@ -1315,10 +1315,10 @@ mod tests {
#[test] #[test]
fn validate_story_dirs_missing_test_plan_only() { fn validate_story_dirs_missing_test_plan_only() {
let tmp = tempfile::tempdir().unwrap(); let tmp = tempfile::tempdir().unwrap();
let current = tmp.path().join(".story_kit/current"); let current = tmp.path().join(".story_kit/work/2_current");
fs::create_dir_all(&current).unwrap(); fs::create_dir_all(&current).unwrap();
fs::write( fs::write(
current.join("28_todos.md"), current.join("28_story_todos.md"),
"---\nname: A Story\n---\n# Story\n", "---\nname: A Story\n---\n# Story\n",
) )
.unwrap(); .unwrap();
@@ -1373,36 +1373,36 @@ mod tests {
assert_eq!(slugify_name("my_story_name"), "my_story_name"); assert_eq!(slugify_name("my_story_name"), "my_story_name");
} }
// --- next_story_number tests --- // --- next_item_number tests ---
#[test] #[test]
fn next_story_number_empty_dirs() { fn next_item_number_empty_dirs() {
let tmp = tempfile::tempdir().unwrap(); let tmp = tempfile::tempdir().unwrap();
let base = tmp.path().join(".story_kit/stories/upcoming"); let base = tmp.path().join(".story_kit/work/1_upcoming");
fs::create_dir_all(&base).unwrap(); fs::create_dir_all(&base).unwrap();
assert_eq!(next_story_number(tmp.path()).unwrap(), 1); assert_eq!(next_item_number(tmp.path()).unwrap(), 1);
} }
#[test] #[test]
fn next_story_number_scans_all_dirs() { fn next_item_number_scans_all_dirs() {
let tmp = tempfile::tempdir().unwrap(); let tmp = tempfile::tempdir().unwrap();
let upcoming = tmp.path().join(".story_kit/stories/upcoming"); let upcoming = tmp.path().join(".story_kit/work/1_upcoming");
let current = tmp.path().join(".story_kit/current"); let current = tmp.path().join(".story_kit/work/2_current");
let archived = tmp.path().join(".story_kit/stories/archived"); let archived = tmp.path().join(".story_kit/work/5_archived");
fs::create_dir_all(&upcoming).unwrap(); fs::create_dir_all(&upcoming).unwrap();
fs::create_dir_all(&current).unwrap(); fs::create_dir_all(&current).unwrap();
fs::create_dir_all(&archived).unwrap(); fs::create_dir_all(&archived).unwrap();
fs::write(upcoming.join("10_foo.md"), "").unwrap(); fs::write(upcoming.join("10_story_foo.md"), "").unwrap();
fs::write(current.join("20_bar.md"), "").unwrap(); fs::write(current.join("20_story_bar.md"), "").unwrap();
fs::write(archived.join("15_baz.md"), "").unwrap(); fs::write(archived.join("15_story_baz.md"), "").unwrap();
assert_eq!(next_story_number(tmp.path()).unwrap(), 21); assert_eq!(next_item_number(tmp.path()).unwrap(), 21);
} }
#[test] #[test]
fn next_story_number_no_story_dirs() { fn next_item_number_no_work_dirs() {
let tmp = tempfile::tempdir().unwrap(); let tmp = tempfile::tempdir().unwrap();
// No .story_kit at all // No .story_kit at all
assert_eq!(next_story_number(tmp.path()).unwrap(), 1); assert_eq!(next_item_number(tmp.path()).unwrap(), 1);
} }
// --- create_story integration tests --- // --- create_story integration tests ---
@@ -1410,11 +1410,11 @@ mod tests {
#[test] #[test]
fn create_story_writes_correct_content() { fn create_story_writes_correct_content() {
let tmp = tempfile::tempdir().unwrap(); let tmp = tempfile::tempdir().unwrap();
let upcoming = tmp.path().join(".story_kit/stories/upcoming"); let upcoming = tmp.path().join(".story_kit/work/1_upcoming");
fs::create_dir_all(&upcoming).unwrap(); fs::create_dir_all(&upcoming).unwrap();
fs::write(upcoming.join("36_existing.md"), "").unwrap(); fs::write(upcoming.join("36_story_existing.md"), "").unwrap();
let number = next_story_number(tmp.path()).unwrap(); let number = next_item_number(tmp.path()).unwrap();
assert_eq!(number, 37); assert_eq!(number, 37);
let slug = slugify_name("My New Feature"); let slug = slugify_name("My New Feature");
@@ -1450,10 +1450,10 @@ mod tests {
#[test] #[test]
fn create_story_rejects_duplicate() { fn create_story_rejects_duplicate() {
let tmp = tempfile::tempdir().unwrap(); let tmp = tempfile::tempdir().unwrap();
let upcoming = tmp.path().join(".story_kit/stories/upcoming"); let upcoming = tmp.path().join(".story_kit/work/1_upcoming");
fs::create_dir_all(&upcoming).unwrap(); fs::create_dir_all(&upcoming).unwrap();
let filepath = upcoming.join("1_my_feature.md"); let filepath = upcoming.join("1_story_my_feature.md");
fs::write(&filepath, "existing").unwrap(); fs::write(&filepath, "existing").unwrap();
// Simulate the check // Simulate the check
@@ -1497,7 +1497,7 @@ mod tests {
fn check_criterion_marks_first_unchecked() { fn check_criterion_marks_first_unchecked() {
let tmp = tempfile::tempdir().unwrap(); let tmp = tempfile::tempdir().unwrap();
setup_git_repo(tmp.path()); setup_git_repo(tmp.path());
let current = tmp.path().join(".story_kit/current"); let current = tmp.path().join(".story_kit/work/2_current");
fs::create_dir_all(&current).unwrap(); fs::create_dir_all(&current).unwrap();
let filepath = current.join("1_test.md"); let filepath = current.join("1_test.md");
fs::write(&filepath, story_with_criteria(3)).unwrap(); fs::write(&filepath, story_with_criteria(3)).unwrap();
@@ -1524,7 +1524,7 @@ mod tests {
fn check_criterion_marks_second_unchecked() { fn check_criterion_marks_second_unchecked() {
let tmp = tempfile::tempdir().unwrap(); let tmp = tempfile::tempdir().unwrap();
setup_git_repo(tmp.path()); setup_git_repo(tmp.path());
let current = tmp.path().join(".story_kit/current"); let current = tmp.path().join(".story_kit/work/2_current");
fs::create_dir_all(&current).unwrap(); fs::create_dir_all(&current).unwrap();
let filepath = current.join("2_test.md"); let filepath = current.join("2_test.md");
fs::write(&filepath, story_with_criteria(3)).unwrap(); fs::write(&filepath, story_with_criteria(3)).unwrap();
@@ -1551,7 +1551,7 @@ mod tests {
fn check_criterion_out_of_range_returns_error() { fn check_criterion_out_of_range_returns_error() {
let tmp = tempfile::tempdir().unwrap(); let tmp = tempfile::tempdir().unwrap();
setup_git_repo(tmp.path()); setup_git_repo(tmp.path());
let current = tmp.path().join(".story_kit/current"); let current = tmp.path().join(".story_kit/work/2_current");
fs::create_dir_all(&current).unwrap(); fs::create_dir_all(&current).unwrap();
let filepath = current.join("3_test.md"); let filepath = current.join("3_test.md");
fs::write(&filepath, story_with_criteria(2)).unwrap(); fs::write(&filepath, story_with_criteria(2)).unwrap();
@@ -1577,7 +1577,7 @@ mod tests {
fn set_test_plan_updates_pending_to_approved() { fn set_test_plan_updates_pending_to_approved() {
let tmp = tempfile::tempdir().unwrap(); let tmp = tempfile::tempdir().unwrap();
setup_git_repo(tmp.path()); setup_git_repo(tmp.path());
let current = tmp.path().join(".story_kit/current"); let current = tmp.path().join(".story_kit/work/2_current");
fs::create_dir_all(&current).unwrap(); fs::create_dir_all(&current).unwrap();
let filepath = current.join("4_test.md"); let filepath = current.join("4_test.md");
fs::write( fs::write(
@@ -1607,7 +1607,7 @@ mod tests {
fn set_test_plan_missing_field_returns_error() { fn set_test_plan_missing_field_returns_error() {
let tmp = tempfile::tempdir().unwrap(); let tmp = tempfile::tempdir().unwrap();
setup_git_repo(tmp.path()); setup_git_repo(tmp.path());
let current = tmp.path().join(".story_kit/current"); let current = tmp.path().join(".story_kit/work/2_current");
fs::create_dir_all(&current).unwrap(); fs::create_dir_all(&current).unwrap();
let filepath = current.join("5_test.md"); let filepath = current.join("5_test.md");
fs::write( fs::write(
@@ -1634,20 +1634,20 @@ mod tests {
#[test] #[test]
fn find_story_file_searches_current_then_upcoming() { fn find_story_file_searches_current_then_upcoming() {
let tmp = tempfile::tempdir().unwrap(); let tmp = tempfile::tempdir().unwrap();
let current = tmp.path().join(".story_kit/current"); let current = tmp.path().join(".story_kit/work/2_current");
let upcoming = tmp.path().join(".story_kit/stories/upcoming"); let upcoming = tmp.path().join(".story_kit/work/1_upcoming");
fs::create_dir_all(&current).unwrap(); fs::create_dir_all(&current).unwrap();
fs::create_dir_all(&upcoming).unwrap(); fs::create_dir_all(&upcoming).unwrap();
// Only in upcoming // Only in upcoming
fs::write(upcoming.join("6_test.md"), "").unwrap(); fs::write(upcoming.join("6_test.md"), "").unwrap();
let found = find_story_file(tmp.path(), "6_test").unwrap(); let found = find_story_file(tmp.path(), "6_test").unwrap();
assert!(found.ends_with("upcoming/6_test.md") || found.ends_with("upcoming\\6_test.md")); assert!(found.ends_with("1_upcoming/6_test.md") || found.ends_with("1_upcoming\\6_test.md"));
// Also in current — current should win // Also in current — current should win
fs::write(current.join("6_test.md"), "").unwrap(); fs::write(current.join("6_test.md"), "").unwrap();
let found = find_story_file(tmp.path(), "6_test").unwrap(); let found = find_story_file(tmp.path(), "6_test").unwrap();
assert!(found.ends_with("current/6_test.md") || found.ends_with("current\\6_test.md")); assert!(found.ends_with("2_current/6_test.md") || found.ends_with("2_current\\6_test.md"));
} }
#[test] #[test]
@@ -1661,30 +1661,30 @@ mod tests {
// ── Bug file helper tests ────────────────────────────────────────────────── // ── Bug file helper tests ──────────────────────────────────────────────────
#[test] #[test]
fn next_bug_number_starts_at_1_when_empty() { fn next_item_number_starts_at_1_when_empty_bugs() {
let tmp = tempfile::tempdir().unwrap(); let tmp = tempfile::tempdir().unwrap();
assert_eq!(next_bug_number(tmp.path()).unwrap(), 1); assert_eq!(next_item_number(tmp.path()).unwrap(), 1);
} }
#[test] #[test]
fn next_bug_number_increments_from_existing() { fn next_item_number_increments_from_existing_bugs() {
let tmp = tempfile::tempdir().unwrap(); let tmp = tempfile::tempdir().unwrap();
let bugs_dir = tmp.path().join(".story_kit/bugs"); let upcoming = tmp.path().join(".story_kit/work/1_upcoming");
fs::create_dir_all(&bugs_dir).unwrap(); fs::create_dir_all(&upcoming).unwrap();
fs::write(bugs_dir.join("bug-1-crash.md"), "").unwrap(); fs::write(upcoming.join("1_bug_crash.md"), "").unwrap();
fs::write(bugs_dir.join("bug-3-another.md"), "").unwrap(); fs::write(upcoming.join("3_bug_another.md"), "").unwrap();
assert_eq!(next_bug_number(tmp.path()).unwrap(), 4); assert_eq!(next_item_number(tmp.path()).unwrap(), 4);
} }
#[test] #[test]
fn next_bug_number_scans_archive_too() { fn next_item_number_scans_archived_too() {
let tmp = tempfile::tempdir().unwrap(); let tmp = tempfile::tempdir().unwrap();
let bugs_dir = tmp.path().join(".story_kit/bugs"); let upcoming = tmp.path().join(".story_kit/work/1_upcoming");
let archive_dir = bugs_dir.join("archive"); let archived = tmp.path().join(".story_kit/work/5_archived");
fs::create_dir_all(&bugs_dir).unwrap(); fs::create_dir_all(&upcoming).unwrap();
fs::create_dir_all(&archive_dir).unwrap(); fs::create_dir_all(&archived).unwrap();
fs::write(archive_dir.join("bug-5-old.md"), "").unwrap(); fs::write(archived.join("5_bug_old.md"), "").unwrap();
assert_eq!(next_bug_number(tmp.path()).unwrap(), 6); assert_eq!(next_item_number(tmp.path()).unwrap(), 6);
} }
#[test] #[test]
@@ -1697,33 +1697,33 @@ mod tests {
#[test] #[test]
fn list_bug_files_excludes_archive_subdir() { fn list_bug_files_excludes_archive_subdir() {
let tmp = tempfile::tempdir().unwrap(); let tmp = tempfile::tempdir().unwrap();
let bugs_dir = tmp.path().join(".story_kit/bugs"); let upcoming_dir = tmp.path().join(".story_kit/work/1_upcoming");
let archive_dir = bugs_dir.join("archive"); let archived_dir = tmp.path().join(".story_kit/work/5_archived");
fs::create_dir_all(&bugs_dir).unwrap(); fs::create_dir_all(&upcoming_dir).unwrap();
fs::create_dir_all(&archive_dir).unwrap(); fs::create_dir_all(&archived_dir).unwrap();
fs::write(bugs_dir.join("bug-1-open.md"), "# Bug 1: Open Bug\n").unwrap(); fs::write(upcoming_dir.join("1_bug_open.md"), "# Bug 1: Open Bug\n").unwrap();
fs::write(archive_dir.join("bug-2-closed.md"), "# Bug 2: Closed Bug\n").unwrap(); fs::write(archived_dir.join("2_bug_closed.md"), "# Bug 2: Closed Bug\n").unwrap();
let result = list_bug_files(tmp.path()).unwrap(); let result = list_bug_files(tmp.path()).unwrap();
assert_eq!(result.len(), 1); assert_eq!(result.len(), 1);
assert_eq!(result[0].0, "bug-1-open"); assert_eq!(result[0].0, "1_bug_open");
assert_eq!(result[0].1, "Open Bug"); assert_eq!(result[0].1, "Open Bug");
} }
#[test] #[test]
fn list_bug_files_sorted_by_id() { fn list_bug_files_sorted_by_id() {
let tmp = tempfile::tempdir().unwrap(); let tmp = tempfile::tempdir().unwrap();
let bugs_dir = tmp.path().join(".story_kit/bugs"); let upcoming_dir = tmp.path().join(".story_kit/work/1_upcoming");
fs::create_dir_all(&bugs_dir).unwrap(); fs::create_dir_all(&upcoming_dir).unwrap();
fs::write(bugs_dir.join("bug-3-third.md"), "# Bug 3: Third\n").unwrap(); fs::write(upcoming_dir.join("3_bug_third.md"), "# Bug 3: Third\n").unwrap();
fs::write(bugs_dir.join("bug-1-first.md"), "# Bug 1: First\n").unwrap(); fs::write(upcoming_dir.join("1_bug_first.md"), "# Bug 1: First\n").unwrap();
fs::write(bugs_dir.join("bug-2-second.md"), "# Bug 2: Second\n").unwrap(); fs::write(upcoming_dir.join("2_bug_second.md"), "# Bug 2: Second\n").unwrap();
let result = list_bug_files(tmp.path()).unwrap(); let result = list_bug_files(tmp.path()).unwrap();
assert_eq!(result.len(), 3); assert_eq!(result.len(), 3);
assert_eq!(result[0].0, "bug-1-first"); assert_eq!(result[0].0, "1_bug_first");
assert_eq!(result[1].0, "bug-2-second"); assert_eq!(result[1].0, "2_bug_second");
assert_eq!(result[2].0, "bug-3-third"); assert_eq!(result[2].0, "3_bug_third");
} }
#[test] #[test]
@@ -1751,11 +1751,11 @@ mod tests {
) )
.unwrap(); .unwrap();
assert_eq!(bug_id, "bug-1-login_crash"); assert_eq!(bug_id, "1_bug_login_crash");
let filepath = tmp let filepath = tmp
.path() .path()
.join(".story_kit/bugs/bug-1-login_crash.md"); .join(".story_kit/work/1_upcoming/1_bug_login_crash.md");
assert!(filepath.exists()); assert!(filepath.exists());
let contents = fs::read_to_string(&filepath).unwrap(); let contents = fs::read_to_string(&filepath).unwrap();
assert!(contents.contains("# Bug 1: Login Crash")); assert!(contents.contains("# Bug 1: Login Crash"));
@@ -1795,7 +1795,7 @@ mod tests {
) )
.unwrap(); .unwrap();
let filepath = tmp.path().join(".story_kit/bugs/bug-1-some_bug.md"); let filepath = tmp.path().join(".story_kit/work/1_upcoming/1_bug_some_bug.md");
let contents = fs::read_to_string(&filepath).unwrap(); let contents = fs::read_to_string(&filepath).unwrap();
assert!(contents.contains("- [ ] Bug is fixed and verified")); assert!(contents.contains("- [ ] Bug is fixed and verified"));
} }