fix: add --all to cargo fmt in script/test and autoformat codebase
cargo fmt without --all fails with "Failed to find targets" in workspace repos. This was blocking every story's gates. Also ran cargo fmt --all to fix all existing formatting issues. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -4,7 +4,10 @@ use serde_json::Value;
|
||||
use std::collections::HashMap;
|
||||
use std::path::Path;
|
||||
|
||||
use super::{create_section_content, next_item_number, read_story_content, replace_section_content, slugify_name, story_stage, write_story_content};
|
||||
use super::{
|
||||
create_section_content, next_item_number, read_story_content, replace_section_content,
|
||||
slugify_name, story_stage, write_story_content,
|
||||
};
|
||||
|
||||
/// Shared create-story logic used by both the OpenApi and MCP handlers.
|
||||
///
|
||||
@@ -158,9 +161,7 @@ pub fn add_criterion_to_file(
|
||||
|
||||
let insert_after = last_criterion_line
|
||||
.or(ac_section_start)
|
||||
.ok_or_else(|| {
|
||||
format!("Story '{story_id}' has no '## Acceptance Criteria' section.")
|
||||
})?;
|
||||
.ok_or_else(|| format!("Story '{story_id}' has no '## Acceptance Criteria' section."))?;
|
||||
|
||||
let mut new_lines: Vec<String> = lines.iter().map(|s| s.to_string()).collect();
|
||||
new_lines.insert(insert_after + 1, format!("- [ ] {criterion}"));
|
||||
@@ -195,7 +196,14 @@ fn json_value_to_yaml_scalar(value: &Value) -> String {
|
||||
}
|
||||
Value::String(s) => yaml_encode_str(s),
|
||||
// Null and Object are not meaningful as YAML scalars; store as quoted strings.
|
||||
other => format!("\"{}\"", other.to_string().replace('"', "\\\"").replace('\n', " ").replace('\r', "")),
|
||||
other => format!(
|
||||
"\"{}\"",
|
||||
other
|
||||
.to_string()
|
||||
.replace('"', "\\\"")
|
||||
.replace('\n', " ")
|
||||
.replace('\r', "")
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,7 +219,10 @@ fn yaml_encode_str(s: &str) -> String {
|
||||
// YAML inline sequences like [490] or [490, 491] — write unquoted so
|
||||
// serde_yaml can deserialise them as Vec<u32>.
|
||||
s if s.starts_with('[') && s.ends_with(']') => s.to_string(),
|
||||
s => format!("\"{}\"", s.replace('"', "\\\"").replace('\n', " ").replace('\r', "")),
|
||||
s => format!(
|
||||
"\"{}\"",
|
||||
s.replace('"', "\\\"").replace('\n', " ").replace('\r', "")
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,13 +257,17 @@ pub fn update_story_in_file(
|
||||
if let Some(us) = user_story {
|
||||
contents = match replace_section_content(&contents, "User Story", us) {
|
||||
Ok(updated) => updated,
|
||||
Err(_) => create_section_content(&contents, "User Story", us, Some("Acceptance Criteria")),
|
||||
Err(_) => {
|
||||
create_section_content(&contents, "User Story", us, Some("Acceptance Criteria"))
|
||||
}
|
||||
};
|
||||
}
|
||||
if let Some(desc) = description {
|
||||
contents = match replace_section_content(&contents, "Description", desc) {
|
||||
Ok(updated) => updated,
|
||||
Err(_) => create_section_content(&contents, "Description", desc, Some("Acceptance Criteria")),
|
||||
Err(_) => {
|
||||
create_section_content(&contents, "Description", desc, Some("Acceptance Criteria"))
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -322,7 +337,11 @@ mod tests {
|
||||
fs::create_dir_all(&backlog).unwrap();
|
||||
fs::write(backlog.join("36_story_existing.md"), "").unwrap();
|
||||
// Also write to content store so next_item_number sees it.
|
||||
crate::db::write_item_with_content("36_story_existing", "1_backlog", "---\nname: Existing\n---\n");
|
||||
crate::db::write_item_with_content(
|
||||
"36_story_existing",
|
||||
"1_backlog",
|
||||
"---\nname: Existing\n---\n",
|
||||
);
|
||||
|
||||
let number = super::super::next_item_number(tmp.path()).unwrap();
|
||||
// The number must be >= 37 (at least higher than the existing "36_story_existing.md"),
|
||||
@@ -390,9 +409,18 @@ mod tests {
|
||||
|
||||
// Read the updated content.
|
||||
let contents = read_story_content(tmp.path(), "1_test").unwrap();
|
||||
assert!(contents.contains("- [x] Criterion 0"), "first should be checked");
|
||||
assert!(contents.contains("- [ ] Criterion 1"), "second should stay unchecked");
|
||||
assert!(contents.contains("- [ ] Criterion 2"), "third should stay unchecked");
|
||||
assert!(
|
||||
contents.contains("- [x] Criterion 0"),
|
||||
"first should be checked"
|
||||
);
|
||||
assert!(
|
||||
contents.contains("- [ ] Criterion 1"),
|
||||
"second should stay unchecked"
|
||||
);
|
||||
assert!(
|
||||
contents.contains("- [ ] Criterion 2"),
|
||||
"third should stay unchecked"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -404,9 +432,18 @@ mod tests {
|
||||
check_criterion_in_file(tmp.path(), "2_test", 1).unwrap();
|
||||
|
||||
let contents = read_story_content(tmp.path(), "2_test").unwrap();
|
||||
assert!(contents.contains("- [ ] Criterion 0"), "first should stay unchecked");
|
||||
assert!(contents.contains("- [x] Criterion 1"), "second should be checked");
|
||||
assert!(contents.contains("- [ ] Criterion 2"), "third should stay unchecked");
|
||||
assert!(
|
||||
contents.contains("- [ ] Criterion 0"),
|
||||
"first should stay unchecked"
|
||||
);
|
||||
assert!(
|
||||
contents.contains("- [x] Criterion 1"),
|
||||
"second should be checked"
|
||||
);
|
||||
assert!(
|
||||
contents.contains("- [ ] Criterion 2"),
|
||||
"third should stay unchecked"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -423,7 +460,9 @@ mod tests {
|
||||
// ── add_criterion_to_file tests ───────────────────────────────────────────
|
||||
|
||||
fn story_with_ac_section(criteria: &[&str]) -> String {
|
||||
let mut s = "---\nname: Test\n---\n\n## User Story\n\nAs a user...\n\n## Acceptance Criteria\n\n".to_string();
|
||||
let mut s =
|
||||
"---\nname: Test\n---\n\n## User Story\n\nAs a user...\n\n## Acceptance Criteria\n\n"
|
||||
.to_string();
|
||||
for c in criteria {
|
||||
s.push_str(&format!("- [ ] {c}\n"));
|
||||
}
|
||||
@@ -434,7 +473,11 @@ mod tests {
|
||||
#[test]
|
||||
fn add_criterion_appends_after_last_criterion() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
setup_story_in_fs(tmp.path(), "10_test", &story_with_ac_section(&["First", "Second"]));
|
||||
setup_story_in_fs(
|
||||
tmp.path(),
|
||||
"10_test",
|
||||
&story_with_ac_section(&["First", "Second"]),
|
||||
);
|
||||
|
||||
add_criterion_to_file(tmp.path(), "10_test", "Third").unwrap();
|
||||
|
||||
@@ -450,19 +493,27 @@ mod tests {
|
||||
#[test]
|
||||
fn add_criterion_to_empty_section() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
let content = "---\nname: Test\n---\n\n## Acceptance Criteria\n\n## Out of Scope\n\n- N/A\n";
|
||||
let content =
|
||||
"---\nname: Test\n---\n\n## Acceptance Criteria\n\n## Out of Scope\n\n- N/A\n";
|
||||
setup_story_in_fs(tmp.path(), "11_test", content);
|
||||
|
||||
add_criterion_to_file(tmp.path(), "11_test", "New AC").unwrap();
|
||||
|
||||
let contents = read_story_content(tmp.path(), "11_test").unwrap();
|
||||
assert!(contents.contains("- [ ] New AC\n"), "criterion should be present");
|
||||
assert!(
|
||||
contents.contains("- [ ] New AC\n"),
|
||||
"criterion should be present"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn add_criterion_missing_section_returns_error() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
setup_story_in_fs(tmp.path(), "12_test", "---\nname: Test\n---\n\nNo AC section here.\n");
|
||||
setup_story_in_fs(
|
||||
tmp.path(),
|
||||
"12_test",
|
||||
"---\nname: Test\n---\n\nNo AC section here.\n",
|
||||
);
|
||||
|
||||
let result = add_criterion_to_file(tmp.path(), "12_test", "X");
|
||||
assert!(result.is_err());
|
||||
@@ -477,12 +528,25 @@ mod tests {
|
||||
let content = "---\nname: T\n---\n\n## User Story\n\nOld text\n\n## Acceptance Criteria\n\n- [ ] AC\n";
|
||||
setup_story_in_fs(tmp.path(), "20_test", content);
|
||||
|
||||
update_story_in_file(tmp.path(), "20_test", Some("New user story text"), None, None).unwrap();
|
||||
update_story_in_file(
|
||||
tmp.path(),
|
||||
"20_test",
|
||||
Some("New user story text"),
|
||||
None,
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let result = read_story_content(tmp.path(), "20_test").unwrap();
|
||||
assert!(result.contains("New user story text"), "new text should be present");
|
||||
assert!(
|
||||
result.contains("New user story text"),
|
||||
"new text should be present"
|
||||
);
|
||||
assert!(!result.contains("Old text"), "old text should be replaced");
|
||||
assert!(result.contains("## Acceptance Criteria"), "other sections preserved");
|
||||
assert!(
|
||||
result.contains("## Acceptance Criteria"),
|
||||
"other sections preserved"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -494,8 +558,14 @@ mod tests {
|
||||
update_story_in_file(tmp.path(), "21_test", None, Some("New description"), None).unwrap();
|
||||
|
||||
let result = read_story_content(tmp.path(), "21_test").unwrap();
|
||||
assert!(result.contains("New description"), "new description present");
|
||||
assert!(!result.contains("Old description"), "old description replaced");
|
||||
assert!(
|
||||
result.contains("New description"),
|
||||
"new description present"
|
||||
);
|
||||
assert!(
|
||||
!result.contains("Old description"),
|
||||
"old description replaced"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -515,16 +585,26 @@ mod tests {
|
||||
let content = "---\nname: T\n---\n\n## Acceptance Criteria\n\n- [ ] AC\n";
|
||||
setup_story_in_fs(tmp.path(), "23_test", content);
|
||||
|
||||
let result = update_story_in_file(tmp.path(), "23_test", Some("New user story"), None, None);
|
||||
assert!(result.is_ok(), "should succeed when section is missing: {result:?}");
|
||||
let result =
|
||||
update_story_in_file(tmp.path(), "23_test", Some("New user story"), None, None);
|
||||
assert!(
|
||||
result.is_ok(),
|
||||
"should succeed when section is missing: {result:?}"
|
||||
);
|
||||
|
||||
let updated = read_story_content(tmp.path(), "23_test").unwrap();
|
||||
assert!(updated.contains("## User Story"), "section should be created");
|
||||
assert!(
|
||||
updated.contains("## User Story"),
|
||||
"section should be created"
|
||||
);
|
||||
assert!(updated.contains("New user story"), "text should be present");
|
||||
// Section should appear before Acceptance Criteria.
|
||||
let pos_us = updated.find("## User Story").unwrap();
|
||||
let pos_ac = updated.find("## Acceptance Criteria").unwrap();
|
||||
assert!(pos_us < pos_ac, "User Story should be before Acceptance Criteria");
|
||||
assert!(
|
||||
pos_us < pos_ac,
|
||||
"User Story should be before Acceptance Criteria"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -534,16 +614,34 @@ mod tests {
|
||||
let content = "---\nname: T\n---\n\n## User Story\n\nAs a user...\n\n## Acceptance Criteria\n\n- [ ] AC\n";
|
||||
setup_story_in_fs(tmp.path(), "32_test", content);
|
||||
|
||||
let result = update_story_in_file(tmp.path(), "32_test", None, Some("New description text"), None);
|
||||
assert!(result.is_ok(), "should succeed when section is missing: {result:?}");
|
||||
let result = update_story_in_file(
|
||||
tmp.path(),
|
||||
"32_test",
|
||||
None,
|
||||
Some("New description text"),
|
||||
None,
|
||||
);
|
||||
assert!(
|
||||
result.is_ok(),
|
||||
"should succeed when section is missing: {result:?}"
|
||||
);
|
||||
|
||||
let updated = read_story_content(tmp.path(), "32_test").unwrap();
|
||||
assert!(updated.contains("## Description"), "section should be created");
|
||||
assert!(updated.contains("New description text"), "text should be present");
|
||||
assert!(
|
||||
updated.contains("## Description"),
|
||||
"section should be created"
|
||||
);
|
||||
assert!(
|
||||
updated.contains("New description text"),
|
||||
"text should be present"
|
||||
);
|
||||
// Section should appear before Acceptance Criteria.
|
||||
let pos_desc = updated.find("## Description").unwrap();
|
||||
let pos_ac = updated.find("## Acceptance Criteria").unwrap();
|
||||
assert!(pos_desc < pos_ac, "Description should be before Acceptance Criteria");
|
||||
assert!(
|
||||
pos_desc < pos_ac,
|
||||
"Description should be before Acceptance Criteria"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -553,32 +651,58 @@ mod tests {
|
||||
let content = "---\nname: T\n---\n\nSome content here.\n";
|
||||
setup_story_in_fs(tmp.path(), "33_test", content);
|
||||
|
||||
let result = update_story_in_file(tmp.path(), "33_test", None, Some("Appended description"), None);
|
||||
assert!(result.is_ok(), "should succeed even with no Acceptance Criteria: {result:?}");
|
||||
let result = update_story_in_file(
|
||||
tmp.path(),
|
||||
"33_test",
|
||||
None,
|
||||
Some("Appended description"),
|
||||
None,
|
||||
);
|
||||
assert!(
|
||||
result.is_ok(),
|
||||
"should succeed even with no Acceptance Criteria: {result:?}"
|
||||
);
|
||||
|
||||
let updated = read_story_content(tmp.path(), "33_test").unwrap();
|
||||
assert!(updated.contains("## Description"), "section should be created");
|
||||
assert!(updated.contains("Appended description"), "text should be present");
|
||||
assert!(
|
||||
updated.contains("## Description"),
|
||||
"section should be created"
|
||||
);
|
||||
assert!(
|
||||
updated.contains("Appended description"),
|
||||
"text should be present"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn update_story_sets_agent_front_matter_field() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
setup_story_in_fs(tmp.path(), "24_test", "---\nname: T\n---\n\n## User Story\n\nSome story\n");
|
||||
setup_story_in_fs(
|
||||
tmp.path(),
|
||||
"24_test",
|
||||
"---\nname: T\n---\n\n## User Story\n\nSome story\n",
|
||||
);
|
||||
|
||||
let mut fields = HashMap::new();
|
||||
fields.insert("agent".to_string(), Value::String("dev".to_string()));
|
||||
update_story_in_file(tmp.path(), "24_test", None, None, Some(&fields)).unwrap();
|
||||
|
||||
let result = read_story_content(tmp.path(), "24_test").unwrap();
|
||||
assert!(result.contains("agent: \"dev\""), "agent field should be set");
|
||||
assert!(
|
||||
result.contains("agent: \"dev\""),
|
||||
"agent field should be set"
|
||||
);
|
||||
assert!(result.contains("name: T"), "name field preserved");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn update_story_sets_arbitrary_front_matter_fields() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
setup_story_in_fs(tmp.path(), "25_test", "---\nname: T\n---\n\n## User Story\n\nSome story\n");
|
||||
setup_story_in_fs(
|
||||
tmp.path(),
|
||||
"25_test",
|
||||
"---\nname: T\n---\n\n## User Story\n\nSome story\n",
|
||||
);
|
||||
|
||||
let mut fields = HashMap::new();
|
||||
fields.insert("qa".to_string(), Value::String("human".to_string()));
|
||||
@@ -587,19 +711,29 @@ mod tests {
|
||||
|
||||
let result = read_story_content(tmp.path(), "25_test").unwrap();
|
||||
assert!(result.contains("qa: \"human\""), "qa field should be set");
|
||||
assert!(result.contains("priority: \"high\""), "priority field should be set");
|
||||
assert!(
|
||||
result.contains("priority: \"high\""),
|
||||
"priority field should be set"
|
||||
);
|
||||
assert!(result.contains("name: T"), "name field preserved");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn update_story_front_matter_only_no_section_required() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
setup_story_in_fs(tmp.path(), "26_test", "---\nname: T\n---\n\nNo sections here.\n");
|
||||
setup_story_in_fs(
|
||||
tmp.path(),
|
||||
"26_test",
|
||||
"---\nname: T\n---\n\nNo sections here.\n",
|
||||
);
|
||||
|
||||
let mut fields = HashMap::new();
|
||||
fields.insert("agent".to_string(), Value::String("dev".to_string()));
|
||||
let result = update_story_in_file(tmp.path(), "26_test", None, None, Some(&fields));
|
||||
assert!(result.is_ok(), "front-matter-only update should not require body sections");
|
||||
assert!(
|
||||
result.is_ok(),
|
||||
"front-matter-only update should not require body sections"
|
||||
);
|
||||
|
||||
let contents = read_story_content(tmp.path(), "26_test").unwrap();
|
||||
assert!(contents.contains("agent: \"dev\""));
|
||||
@@ -616,8 +750,14 @@ mod tests {
|
||||
update_story_in_file(tmp.path(), "27_test", None, None, Some(&fields)).unwrap();
|
||||
|
||||
let result = read_story_content(tmp.path(), "27_test").unwrap();
|
||||
assert!(result.contains("blocked: false"), "bool should be unquoted: {result}");
|
||||
assert!(!result.contains("blocked: \"false\""), "bool must not be quoted: {result}");
|
||||
assert!(
|
||||
result.contains("blocked: false"),
|
||||
"bool should be unquoted: {result}"
|
||||
);
|
||||
assert!(
|
||||
!result.contains("blocked: \"false\""),
|
||||
"bool must not be quoted: {result}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -631,14 +771,24 @@ mod tests {
|
||||
update_story_in_file(tmp.path(), "28_test", None, None, Some(&fields)).unwrap();
|
||||
|
||||
let result = read_story_content(tmp.path(), "28_test").unwrap();
|
||||
assert!(result.contains("retry_count: 0"), "integer should be unquoted: {result}");
|
||||
assert!(!result.contains("retry_count: \"0\""), "integer must not be quoted: {result}");
|
||||
assert!(
|
||||
result.contains("retry_count: 0"),
|
||||
"integer should be unquoted: {result}"
|
||||
);
|
||||
assert!(
|
||||
!result.contains("retry_count: \"0\""),
|
||||
"integer must not be quoted: {result}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn update_story_bool_front_matter_parseable_after_write() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
setup_story_in_fs(tmp.path(), "29_test", "---\nname: My Story\n---\n\nNo sections.\n");
|
||||
setup_story_in_fs(
|
||||
tmp.path(),
|
||||
"29_test",
|
||||
"---\nname: My Story\n---\n\nNo sections.\n",
|
||||
);
|
||||
|
||||
let mut fields = HashMap::new();
|
||||
fields.insert("blocked".to_string(), Value::String("false".to_string()));
|
||||
@@ -646,7 +796,11 @@ mod tests {
|
||||
|
||||
let contents = read_story_content(tmp.path(), "29_test").unwrap();
|
||||
let meta = parse_front_matter(&contents).expect("front matter should parse");
|
||||
assert_eq!(meta.name.as_deref(), Some("My Story"), "name preserved after writing bool field");
|
||||
assert_eq!(
|
||||
meta.name.as_deref(),
|
||||
Some("My Story"),
|
||||
"name preserved after writing bool field"
|
||||
);
|
||||
}
|
||||
|
||||
// ── Bug 493 regression tests ──────────────────────────────────────────────
|
||||
@@ -662,8 +816,14 @@ mod tests {
|
||||
update_story_in_file(tmp.path(), "30_test", None, None, Some(&fields)).unwrap();
|
||||
|
||||
let result = read_story_content(tmp.path(), "30_test").unwrap();
|
||||
assert!(result.contains("depends_on: [490]"), "should be unquoted array: {result}");
|
||||
assert!(!result.contains("depends_on: \"[490]\""), "must not be quoted: {result}");
|
||||
assert!(
|
||||
result.contains("depends_on: [490]"),
|
||||
"should be unquoted array: {result}"
|
||||
);
|
||||
assert!(
|
||||
!result.contains("depends_on: \"[490]\""),
|
||||
"must not be quoted: {result}"
|
||||
);
|
||||
|
||||
let meta = parse_front_matter(&result).expect("front matter should parse");
|
||||
assert_eq!(meta.depends_on, Some(vec![490]));
|
||||
@@ -690,8 +850,14 @@ mod tests {
|
||||
})
|
||||
.expect("story content should exist");
|
||||
|
||||
assert!(contents.contains("depends_on: [489]"), "missing front matter: {contents}");
|
||||
assert!(!contents.contains("- [ ] depends_on"), "must not appear as checkbox: {contents}");
|
||||
assert!(
|
||||
contents.contains("depends_on: [489]"),
|
||||
"missing front matter: {contents}"
|
||||
);
|
||||
assert!(
|
||||
!contents.contains("- [ ] depends_on"),
|
||||
"must not appear as checkbox: {contents}"
|
||||
);
|
||||
|
||||
let meta = parse_front_matter(&contents).expect("front matter should parse");
|
||||
assert_eq!(meta.depends_on, Some(vec![489]));
|
||||
@@ -709,8 +875,14 @@ mod tests {
|
||||
update_story_in_file(tmp.path(), "31_test", None, None, Some(&fields)).unwrap();
|
||||
|
||||
let result = read_story_content(tmp.path(), "31_test").unwrap();
|
||||
assert!(result.contains("blocked: false"), "native bool false should be unquoted: {result}");
|
||||
assert!(!result.contains("blocked: \"false\""), "must not be quoted: {result}");
|
||||
assert!(
|
||||
result.contains("blocked: false"),
|
||||
"native bool false should be unquoted: {result}"
|
||||
);
|
||||
assert!(
|
||||
!result.contains("blocked: \"false\""),
|
||||
"must not be quoted: {result}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -723,22 +895,38 @@ mod tests {
|
||||
update_story_in_file(tmp.path(), "32_test", None, None, Some(&fields)).unwrap();
|
||||
|
||||
let result = read_story_content(tmp.path(), "32_test").unwrap();
|
||||
assert!(result.contains("blocked: true"), "native bool true should be unquoted: {result}");
|
||||
assert!(!result.contains("blocked: \"true\""), "must not be quoted: {result}");
|
||||
assert!(
|
||||
result.contains("blocked: true"),
|
||||
"native bool true should be unquoted: {result}"
|
||||
);
|
||||
assert!(
|
||||
!result.contains("blocked: \"true\""),
|
||||
"must not be quoted: {result}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn update_story_native_integer_written_unquoted() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
setup_story_in_fs(tmp.path(), "33b_test", "---\nname: T\n---\n\nNo sections.\n");
|
||||
setup_story_in_fs(
|
||||
tmp.path(),
|
||||
"33b_test",
|
||||
"---\nname: T\n---\n\nNo sections.\n",
|
||||
);
|
||||
|
||||
let mut fields = HashMap::new();
|
||||
fields.insert("retry_count".to_string(), serde_json::json!(3));
|
||||
update_story_in_file(tmp.path(), "33b_test", None, None, Some(&fields)).unwrap();
|
||||
|
||||
let result = read_story_content(tmp.path(), "33b_test").unwrap();
|
||||
assert!(result.contains("retry_count: 3"), "native integer should be unquoted: {result}");
|
||||
assert!(!result.contains("retry_count: \"3\""), "must not be quoted: {result}");
|
||||
assert!(
|
||||
result.contains("retry_count: 3"),
|
||||
"native integer should be unquoted: {result}"
|
||||
);
|
||||
assert!(
|
||||
!result.contains("retry_count: \"3\""),
|
||||
"must not be quoted: {result}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -751,8 +939,14 @@ mod tests {
|
||||
update_story_in_file(tmp.path(), "34_test", None, None, Some(&fields)).unwrap();
|
||||
|
||||
let result = read_story_content(tmp.path(), "34_test").unwrap();
|
||||
assert!(result.contains("depends_on: [490, 491]"), "native array should be YAML sequence: {result}");
|
||||
assert!(!result.contains("depends_on: \"["), "must not be quoted: {result}");
|
||||
assert!(
|
||||
result.contains("depends_on: [490, 491]"),
|
||||
"native array should be YAML sequence: {result}"
|
||||
);
|
||||
assert!(
|
||||
!result.contains("depends_on: \"["),
|
||||
"must not be quoted: {result}"
|
||||
);
|
||||
|
||||
let meta = parse_front_matter(&result).expect("front matter should parse");
|
||||
assert_eq!(meta.depends_on, Some(vec![490, 491]));
|
||||
@@ -761,7 +955,11 @@ mod tests {
|
||||
#[test]
|
||||
fn update_story_native_bool_parseable_after_write() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
setup_story_in_fs(tmp.path(), "35_test", "---\nname: My Story\n---\n\nNo sections.\n");
|
||||
setup_story_in_fs(
|
||||
tmp.path(),
|
||||
"35_test",
|
||||
"---\nname: My Story\n---\n\nNo sections.\n",
|
||||
);
|
||||
|
||||
let mut fields = HashMap::new();
|
||||
fields.insert("blocked".to_string(), Value::Bool(false));
|
||||
@@ -769,7 +967,11 @@ mod tests {
|
||||
|
||||
let contents = read_story_content(tmp.path(), "35_test").unwrap();
|
||||
let meta = parse_front_matter(&contents).expect("front matter should parse");
|
||||
assert_eq!(meta.name.as_deref(), Some("My Story"), "name preserved after writing native bool");
|
||||
assert_eq!(
|
||||
meta.name.as_deref(),
|
||||
Some("My Story"),
|
||||
"name preserved after writing native bool"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -779,7 +981,10 @@ mod tests {
|
||||
|
||||
// String "[490, 491]" still works (backwards compatibility).
|
||||
let mut fields = HashMap::new();
|
||||
fields.insert("depends_on".to_string(), Value::String("[490, 491]".to_string()));
|
||||
fields.insert(
|
||||
"depends_on".to_string(),
|
||||
Value::String("[490, 491]".to_string()),
|
||||
);
|
||||
update_story_in_file(tmp.path(), "31_test", None, None, Some(&fields)).unwrap();
|
||||
|
||||
let result = read_story_content(tmp.path(), "31_test").unwrap();
|
||||
|
||||
Reference in New Issue
Block a user