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
|
- Multiphase planning also has an explained-plan entry point. Accepted plans
|
||||||
report the deterministic strategy, phase reasons, participating nodes, and
|
report the deterministic strategy, phase reasons, participating nodes, and
|
||||||
validation result; rejected plans report every attempted strategy and failure.
|
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
|
- Planner tests now include a deterministic split-tree generator. It builds
|
||||||
valid weighted tiling layouts, derives leaf hierarchy metadata, mutates them
|
valid weighted tiling layouts, derives leaf hierarchy metadata, mutates them
|
||||||
through supported transitions, and runs the real planner plus exact validator.
|
through supported transitions, and runs the real planner plus exact validator.
|
||||||
|
|
@ -262,6 +265,7 @@ Tests:
|
||||||
- reversing direction produces equivalent motion in reverse
|
- reversing direction produces equivalent motion in reverse
|
||||||
- accepted and rejected plans expose deterministic strategy explanations
|
- accepted and rejected plans expose deterministic strategy explanations
|
||||||
- bounded generated split-tree corpus produces identical plans on repeated runs
|
- 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
|
- child waits for parent/container-space phases when moving upward into a
|
||||||
toplevel peer position
|
toplevel peer position
|
||||||
- mono-mode tab switches do not animate, while entering/exiting mono can animate
|
- mono-mode tab switches do not animate, while entering/exiting mono can animate
|
||||||
|
|
|
||||||
|
|
@ -1538,6 +1538,49 @@ mod tests {
|
||||||
.to
|
.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]
|
#[test]
|
||||||
fn horizontal_swap_shrinks_moves_then_grows_without_overlap() {
|
fn horizontal_swap_shrinks_moves_then_grows_without_overlap() {
|
||||||
let req = request(vec![
|
let req = request(vec![
|
||||||
|
|
@ -2136,14 +2179,9 @@ mod tests {
|
||||||
let diagnostic = plan_no_overlap_with_diagnostics(&req).unwrap_err();
|
let diagnostic = plan_no_overlap_with_diagnostics(&req).unwrap_err();
|
||||||
assert_eq!(diagnostic.forward, MultiphasePlanFailure::NoPattern);
|
assert_eq!(diagnostic.forward, MultiphasePlanFailure::NoPattern);
|
||||||
assert_eq!(diagnostic.reverse, Some(MultiphasePlanFailure::NoPattern));
|
assert_eq!(diagnostic.reverse, Some(MultiphasePlanFailure::NoPattern));
|
||||||
assert!(
|
let mut expected = no_pattern_attempts(PlanDirection::Forward);
|
||||||
diagnostic
|
expected.extend(no_pattern_attempts(PlanDirection::Reverse));
|
||||||
.attempted
|
assert_eq!(diagnostic.attempted, expected);
|
||||||
.iter()
|
|
||||||
.any(|attempt| attempt.direction == PlanDirection::Forward
|
|
||||||
&& attempt.strategy == PlanStrategy::SingleAction
|
|
||||||
&& attempt.reason == MultiphasePlanFailure::NoPattern)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[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]
|
#[test]
|
||||||
fn hierarchy_metadata_classifies_depth_and_mono_transitions() {
|
fn hierarchy_metadata_classifies_depth_and_mono_transitions() {
|
||||||
let source = MultiphaseHierarchyPosition {
|
let source = MultiphaseHierarchyPosition {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue