Merge story-29: Backfill tests for maximum coverage
Adds 57 Rust tests and 60 frontend tests across 4 batches: - Batch 1: store, search, workflow - Batch 2: fs, shell, http/workflow - Batch 3: usePathCompletion, api/client, api/workflow - Batch 4: App, GatePanel, ReviewPanel Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -503,4 +503,145 @@ mod tests {
|
||||
|
||||
assert!(result.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn accepts_when_all_tests_pass() {
|
||||
let results = StoryTestResults {
|
||||
unit: vec![TestCaseResult {
|
||||
name: "unit-1".to_string(),
|
||||
status: TestStatus::Pass,
|
||||
details: None,
|
||||
}],
|
||||
integration: vec![TestCaseResult {
|
||||
name: "integration-1".to_string(),
|
||||
status: TestStatus::Pass,
|
||||
details: None,
|
||||
}],
|
||||
};
|
||||
|
||||
let decision = evaluate_acceptance(&results);
|
||||
assert!(decision.can_accept);
|
||||
assert!(decision.reasons.is_empty());
|
||||
assert!(decision.warning.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rejects_when_no_results_recorded() {
|
||||
let results = StoryTestResults::default();
|
||||
let decision = evaluate_acceptance(&results);
|
||||
assert!(!decision.can_accept);
|
||||
assert!(decision.reasons.iter().any(|r| r.contains("No test results")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rejects_with_single_failure_no_warning() {
|
||||
let results = StoryTestResults {
|
||||
unit: vec![
|
||||
TestCaseResult {
|
||||
name: "unit-1".to_string(),
|
||||
status: TestStatus::Pass,
|
||||
details: None,
|
||||
},
|
||||
TestCaseResult {
|
||||
name: "unit-2".to_string(),
|
||||
status: TestStatus::Fail,
|
||||
details: None,
|
||||
},
|
||||
],
|
||||
integration: vec![],
|
||||
};
|
||||
|
||||
let decision = evaluate_acceptance(&results);
|
||||
assert!(!decision.can_accept);
|
||||
assert!(decision.reasons.iter().any(|r| r.contains("failing")));
|
||||
assert!(decision.warning.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn summarize_results_counts_correctly() {
|
||||
let results = StoryTestResults {
|
||||
unit: vec![
|
||||
TestCaseResult { name: "u1".to_string(), status: TestStatus::Pass, details: None },
|
||||
TestCaseResult { name: "u2".to_string(), status: TestStatus::Fail, details: None },
|
||||
],
|
||||
integration: vec![
|
||||
TestCaseResult { name: "i1".to_string(), status: TestStatus::Pass, details: None },
|
||||
],
|
||||
};
|
||||
|
||||
let summary = summarize_results(&results);
|
||||
assert_eq!(summary.total, 3);
|
||||
assert_eq!(summary.passed, 2);
|
||||
assert_eq!(summary.failed, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_start_implementation_requires_approved_plan() {
|
||||
let approved = StoryMetadata {
|
||||
name: Some("Test".to_string()),
|
||||
test_plan: Some(TestPlanStatus::Approved),
|
||||
};
|
||||
assert!(can_start_implementation(&approved).is_ok());
|
||||
|
||||
let waiting = StoryMetadata {
|
||||
name: Some("Test".to_string()),
|
||||
test_plan: Some(TestPlanStatus::WaitingForApproval),
|
||||
};
|
||||
assert!(can_start_implementation(&waiting).is_err());
|
||||
|
||||
let unknown = StoryMetadata {
|
||||
name: Some("Test".to_string()),
|
||||
test_plan: Some(TestPlanStatus::Unknown("draft".to_string())),
|
||||
};
|
||||
assert!(can_start_implementation(&unknown).is_err());
|
||||
|
||||
let missing = StoryMetadata {
|
||||
name: Some("Test".to_string()),
|
||||
test_plan: None,
|
||||
};
|
||||
assert!(can_start_implementation(&missing).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn record_valid_results_stores_them() {
|
||||
let mut state = WorkflowState::default();
|
||||
let unit = vec![TestCaseResult {
|
||||
name: "unit-1".to_string(),
|
||||
status: TestStatus::Pass,
|
||||
details: None,
|
||||
}];
|
||||
let integration = vec![TestCaseResult {
|
||||
name: "int-1".to_string(),
|
||||
status: TestStatus::Pass,
|
||||
details: None,
|
||||
}];
|
||||
|
||||
let result = state.record_test_results_validated(
|
||||
"story-29".to_string(),
|
||||
unit,
|
||||
integration,
|
||||
);
|
||||
assert!(result.is_ok());
|
||||
assert!(state.results.contains_key("story-29"));
|
||||
assert_eq!(state.results["story-29"].unit.len(), 1);
|
||||
assert_eq!(state.results["story-29"].integration.len(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn refresh_story_metadata_returns_false_when_unchanged() {
|
||||
let mut state = WorkflowState::default();
|
||||
let meta = StoryMetadata {
|
||||
name: Some("Test".to_string()),
|
||||
test_plan: Some(TestPlanStatus::Approved),
|
||||
};
|
||||
|
||||
assert!(state.refresh_story_metadata("s1".to_string(), meta.clone()));
|
||||
assert!(!state.refresh_story_metadata("s1".to_string(), meta.clone()));
|
||||
|
||||
let updated = StoryMetadata {
|
||||
name: Some("Updated".to_string()),
|
||||
test_plan: Some(TestPlanStatus::Approved),
|
||||
};
|
||||
assert!(state.refresh_story_metadata("s1".to_string(), updated));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user