Assert multiphase rejection diagnostics
This commit is contained in:
parent
332a7468f6
commit
01d1545c40
2 changed files with 92 additions and 8 deletions
|
|
@ -245,6 +245,9 @@ Current pure planner status:
|
|||
- Multiphase planning also has an explained-plan entry point. Accepted plans
|
||||
report the deterministic strategy, phase reasons, participating nodes, and
|
||||
validation result; rejected plans report every attempted strategy and failure.
|
||||
- Rejection diagnostics are treated as contractual test output for unsupported
|
||||
patterns and analytically invalid candidate plans, including attempted strategy
|
||||
order and exact validation failure.
|
||||
- Planner tests now include a deterministic split-tree generator. It builds
|
||||
valid weighted tiling layouts, derives leaf hierarchy metadata, mutates them
|
||||
through supported transitions, and runs the real planner plus exact validator.
|
||||
|
|
@ -262,6 +265,7 @@ Tests:
|
|||
- reversing direction produces equivalent motion in reverse
|
||||
- accepted and rejected plans expose deterministic strategy explanations
|
||||
- bounded generated split-tree corpus produces identical plans on repeated runs
|
||||
- unsupported and invalid candidate plans produce exact expected diagnostics
|
||||
- child waits for parent/container-space phases when moving upward into a
|
||||
toplevel peer position
|
||||
- mono-mode tab switches do not animate, while entering/exiting mono can animate
|
||||
|
|
|
|||
|
|
@ -1538,6 +1538,49 @@ mod tests {
|
|||
.to
|
||||
}
|
||||
|
||||
fn no_pattern_attempts(direction: PlanDirection) -> Vec<RejectedStrategy> {
|
||||
vec![
|
||||
RejectedStrategy {
|
||||
direction,
|
||||
strategy: PlanStrategy::SingleAction,
|
||||
reason: MultiphasePlanFailure::NoPattern,
|
||||
},
|
||||
RejectedStrategy {
|
||||
direction,
|
||||
strategy: PlanStrategy::HierarchyOrderedScales,
|
||||
reason: MultiphasePlanFailure::NoPattern,
|
||||
},
|
||||
RejectedStrategy {
|
||||
direction,
|
||||
strategy: PlanStrategy::SwapLanes {
|
||||
axis: PhaseAxis::Horizontal,
|
||||
},
|
||||
reason: MultiphasePlanFailure::NoPattern,
|
||||
},
|
||||
RejectedStrategy {
|
||||
direction,
|
||||
strategy: PlanStrategy::SwapLanes {
|
||||
axis: PhaseAxis::Vertical,
|
||||
},
|
||||
reason: MultiphasePlanFailure::NoPattern,
|
||||
},
|
||||
RejectedStrategy {
|
||||
direction,
|
||||
strategy: PlanStrategy::SpaceThenOrthogonalGrowth {
|
||||
axis: PhaseAxis::Horizontal,
|
||||
},
|
||||
reason: MultiphasePlanFailure::NoPattern,
|
||||
},
|
||||
RejectedStrategy {
|
||||
direction,
|
||||
strategy: PlanStrategy::SpaceThenOrthogonalGrowth {
|
||||
axis: PhaseAxis::Vertical,
|
||||
},
|
||||
reason: MultiphasePlanFailure::NoPattern,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn horizontal_swap_shrinks_moves_then_grows_without_overlap() {
|
||||
let req = request(vec![
|
||||
|
|
@ -2136,14 +2179,9 @@ mod tests {
|
|||
let diagnostic = plan_no_overlap_with_diagnostics(&req).unwrap_err();
|
||||
assert_eq!(diagnostic.forward, MultiphasePlanFailure::NoPattern);
|
||||
assert_eq!(diagnostic.reverse, Some(MultiphasePlanFailure::NoPattern));
|
||||
assert!(
|
||||
diagnostic
|
||||
.attempted
|
||||
.iter()
|
||||
.any(|attempt| attempt.direction == PlanDirection::Forward
|
||||
&& attempt.strategy == PlanStrategy::SingleAction
|
||||
&& attempt.reason == MultiphasePlanFailure::NoPattern)
|
||||
);
|
||||
let mut expected = no_pattern_attempts(PlanDirection::Forward);
|
||||
expected.extend(no_pattern_attempts(PlanDirection::Reverse));
|
||||
assert_eq!(diagnostic.attempted, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -2176,6 +2214,48 @@ mod tests {
|
|||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn diagnostics_report_candidate_validation_rejections() {
|
||||
let req = request(vec![
|
||||
MultiphaseWindow {
|
||||
node_id: id(1),
|
||||
from: rect(0, 0, 60, 60),
|
||||
to: rect(180, 0, 240, 60),
|
||||
hierarchy: Default::default(),
|
||||
},
|
||||
MultiphaseWindow {
|
||||
node_id: id(2),
|
||||
from: rect(90, 0, 150, 60),
|
||||
to: rect(90, 0, 150, 60),
|
||||
hierarchy: Default::default(),
|
||||
},
|
||||
]);
|
||||
let rejection =
|
||||
MultiphasePlanFailure::Validation(MultiphaseValidationError::PhaseOverlap {
|
||||
phase: 0,
|
||||
a: id(1),
|
||||
b: id(2),
|
||||
});
|
||||
let diagnostic = plan_no_overlap_with_diagnostics(&req).unwrap_err();
|
||||
|
||||
assert_eq!(diagnostic.forward, rejection);
|
||||
assert_eq!(diagnostic.reverse, Some(rejection));
|
||||
assert_eq!(
|
||||
diagnostic.attempted[0],
|
||||
RejectedStrategy {
|
||||
direction: PlanDirection::Forward,
|
||||
strategy: PlanStrategy::SingleAction,
|
||||
reason: rejection,
|
||||
}
|
||||
);
|
||||
assert!(diagnostic.attempted.iter().any(|attempt| *attempt
|
||||
== RejectedStrategy {
|
||||
direction: PlanDirection::Reverse,
|
||||
strategy: PlanStrategy::SingleAction,
|
||||
reason: rejection,
|
||||
}));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hierarchy_metadata_classifies_depth_and_mono_transitions() {
|
||||
let source = MultiphaseHierarchyPosition {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue