use fission_core::lowering::{LoweringContext, NodeBuilder};
use fission_core::ui::{Column, Container, Node, Row, Text};
use fission_core::LowerDyn;
use fission_core::{AppState, BuildCtx, View, Widget};
use fission_ir::{Op, Semantics};
use fission_test::TestHarness;
#[derive(Debug, Default, Clone)]
struct State;
impl AppState for State {}
#[derive(Debug)]
struct MockHero {
child: Node,
}
impl LowerDyn for MockHero {
fn lower_dyn(&self, cx: &mut LoweringContext) -> fission_ir::NodeId {
let child_id = self.child.lower(cx);
let id = cx.next_node_id();
let semantics = Semantics {
hero_tag: Some("t".into()),
..Default::default()
};
let mut builder = NodeBuilder::new(id, Op::Semantics(semantics));
builder.add_child(child_id);
builder.build(cx)
}
fn stable_key(&self) -> u64 {
0
}
}
#[test]
fn test_email_list_overlap_regression() {
struct EmailRow;
impl Widget<State> for EmailRow {
fn build(&self, _ctx: &mut BuildCtx<State>, _view: &View<State>) -> Node {
Container::new(
Row::default()
.children(vec![
Container::new(
Column::default()
.children(vec![
Node::Custom(fission_core::ui::CustomNode {
debug_tag: "Hero".into(),
lowerer: Some(std::sync::Arc::new(MockHero {
child: Text::new("Subject 10 Subject 10 Subject 10")
.min_width(0.0) .into_node(),
})),
render_object: None,
}),
Text::new("Short preview...").min_width(0.0).into_node(),
])
.into_node(),
)
.min_width(0.0)
.flex_grow(1.0)
.into_node(),
])
.into_node(),
)
.width(100.0) .into_node()
}
}
let mut h = TestHarness::new(State);
h = h.with_root_widget(EmailRow);
h.pump().unwrap();
let snap = h.last_snapshot.as_ref().unwrap();
let ir = h.last_ir.as_ref().unwrap();
let mut preview_rect = None;
let mut subject_rect = None;
for (id, node) in &ir.nodes {
if let fission_ir::Op::Paint(fission_ir::PaintOp::DrawText { text, .. }) = &node.op {
let geom = snap.get_node_geometry(*id).unwrap();
if text.contains("preview") {
preview_rect = Some(geom.rect);
} else if text.contains("Subject") {
subject_rect = Some(geom.rect);
}
}
}
let subject = subject_rect.expect("Subject text not found");
let preview = preview_rect.expect("Preview text not found");
println!("Subject: {:?}", subject);
println!("Preview: {:?}", preview);
let font_size = h.env.theme.tokens.typography.body_medium_size;
let (_single_line_w, single_line_h) =
h.measurer
.measure("Subject 10 Subject 10 Subject 10", font_size, None);
assert!(
subject.height() > single_line_h,
"Subject text did not wrap in layout! Height is {}",
subject.height()
);
assert!(
preview.y() >= subject.y() + subject.height(),
"Preview overlaps Subject! Preview Y: {}, Subject Bottom: {}",
preview.y(),
subject.y() + subject.height()
);
}