huskies: merge 942

This commit is contained in:
dave
2026-05-13 05:16:11 +00:00
parent 7ca5339450
commit 0a825b9f27
11 changed files with 416 additions and 258 deletions
+61 -29
View File
@@ -176,7 +176,7 @@ fn create_bug_file_writes_correct_content() {
"1. Go to /login\n2. Click submit",
"Page crashes with 500 error",
"Login succeeds",
Some(&["Login form submits without error".to_string()]),
&["Login form submits without error".to_string()],
None,
)
.unwrap();
@@ -226,7 +226,7 @@ fn create_bug_file_rejects_empty_name() {
"steps",
"actual",
"expected",
None,
&[],
None,
);
assert!(result.is_err());
@@ -234,29 +234,23 @@ fn create_bug_file_rejects_empty_name() {
}
#[test]
fn create_bug_file_uses_default_acceptance_criterion() {
fn create_bug_file_rejects_empty_acceptance_criteria() {
let tmp = tempfile::tempdir().unwrap();
setup_git_repo(tmp.path());
let bug_id = create_bug_file(
let err = create_bug_file(
tmp.path(),
"Some Bug",
"desc",
"steps",
"actual",
"expected",
None,
&[],
None,
)
.unwrap();
let contents = crate::db::read_content(&bug_id).expect("bug content should exist");
.unwrap_err();
assert!(
contents.starts_with("---\ntype: bug\nname: \"Some Bug\"\n---"),
"bug file must have YAML front matter with type field"
err.contains("acceptance criterion"),
"error should mention acceptance criterion, got: {err}"
);
assert!(contents.contains("- [ ] Bug is fixed and verified"));
}
// ── create_spike_file tests ────────────────────────────────────────────────
@@ -269,7 +263,7 @@ fn create_spike_file_writes_correct_content() {
tmp.path(),
"Filesystem Watcher Architecture",
None,
&[],
&["Architecture documented".to_string()],
None,
)
.unwrap();
@@ -302,8 +296,14 @@ fn create_spike_file_uses_description_when_provided() {
let tmp = tempfile::tempdir().unwrap();
let description = "What is the best approach for watching filesystem events?";
let spike_id =
create_spike_file(tmp.path(), "FS Watcher Spike", Some(description), &[], None).unwrap();
let spike_id = create_spike_file(
tmp.path(),
"FS Watcher Spike",
Some(description),
&["Findings documented".to_string()],
None,
)
.unwrap();
let contents = crate::db::read_content(&spike_id)
.or_else(|| {
@@ -319,7 +319,14 @@ fn create_spike_file_uses_description_when_provided() {
#[test]
fn create_spike_file_uses_placeholder_when_no_description() {
let tmp = tempfile::tempdir().unwrap();
let spike_id = create_spike_file(tmp.path(), "My Spike", None, &[], None).unwrap();
let spike_id = create_spike_file(
tmp.path(),
"My Spike",
None,
&["Findings documented".to_string()],
None,
)
.unwrap();
let contents = crate::db::read_content(&spike_id)
.or_else(|| {
@@ -335,16 +342,22 @@ fn create_spike_file_uses_placeholder_when_no_description() {
#[test]
fn create_spike_file_rejects_empty_name() {
let tmp = tempfile::tempdir().unwrap();
let result = create_spike_file(tmp.path(), "!!!", None, &[], None);
assert!(result.is_err());
assert!(result.unwrap_err().contains("alphanumeric"));
// Name "!!!" has no alphanumeric chars — fails before AC check.
let err = create_spike_file(tmp.path(), "!!!", None, &["AC".to_string()], None).unwrap_err();
assert!(err.contains("alphanumeric"), "got: {err}");
}
#[test]
fn create_spike_file_with_special_chars_in_name_produces_valid_yaml() {
let tmp = tempfile::tempdir().unwrap();
let name = "Spike: compare \"fast\" vs slow encoders";
let result = create_spike_file(tmp.path(), name, None, &[], None);
let result = create_spike_file(
tmp.path(),
name,
None,
&["Findings documented".to_string()],
None,
);
assert!(result.is_ok(), "create_spike_file failed: {result:?}");
let spike_id = result.unwrap();
@@ -364,7 +377,14 @@ fn create_spike_file_increments_from_existing_items() {
crate::db::ItemMeta::named("Existing"),
);
let spike_id = create_spike_file(tmp.path(), "My Spike", None, &[], None).unwrap();
let spike_id = create_spike_file(
tmp.path(),
"My Spike",
None,
&["Findings documented".to_string()],
None,
)
.unwrap();
assert!(
spike_id.chars().all(|c| c.is_ascii_digit()),
"spike ID must be numeric-only, got: {spike_id}"
@@ -391,7 +411,7 @@ fn create_bug_file_with_depends_on_persists_to_crdt() {
"steps",
"actual",
"expected",
None,
&["Bug fixed".to_string()],
Some(&[42, 43]),
)
.unwrap();
@@ -412,7 +432,7 @@ fn create_bug_file_without_depends_on_omits_field() {
"steps",
"actual",
"expected",
None,
&["Bug fixed".to_string()],
None,
)
.unwrap();
@@ -438,8 +458,14 @@ fn create_refactor_file_with_depends_on_persists_to_crdt() {
let tmp = tempfile::tempdir().unwrap();
setup_git_repo(tmp.path());
let refactor_id =
create_refactor_file(tmp.path(), "Dep Refactor", None, None, Some(&[99])).unwrap();
let refactor_id = create_refactor_file(
tmp.path(),
"Dep Refactor",
None,
&["Refactoring complete".to_string()],
Some(&[99]),
)
.unwrap();
let view = crate::crdt_state::read_item(&refactor_id).expect("CRDT entry should exist");
assert_eq!(view.depends_on(), &[99]);
@@ -450,8 +476,14 @@ fn create_refactor_file_without_depends_on_omits_field() {
let tmp = tempfile::tempdir().unwrap();
setup_git_repo(tmp.path());
let refactor_id =
create_refactor_file(tmp.path(), "No Dep Refactor", None, None, None).unwrap();
let refactor_id = create_refactor_file(
tmp.path(),
"No Dep Refactor",
None,
&["Refactoring complete".to_string()],
None,
)
.unwrap();
let contents = crate::db::read_content(&refactor_id)
.or_else(|| {