test: gate flex item geometry

This commit is contained in:
SGavrl committed 2026-07-23 13:34:19 +00:00
1 parent 64b628404b
commit 1f85dfce6b
4 files changed
+152

No files matched your search

+31
View File
@@ -874,6 +874,37 @@ mod tests {
assert!((out.children[1].border_box.x - 650.0).abs() < 0.01); assert!((out.children[1].border_box.x - 650.0).abs() < 0.01);
} }
#[test]
fn negative_flex_margin_overlays_without_shifting_items() {
let main = make_box(Display::Block, 900.0, 200.0);
let sidebar = LayoutStyle {
display: Display::Flex,
width: Dimension::Px(225.0),
height: Dimension::Px(180.0),
margin: Edges {
left: -900.0,
..Default::default()
},
..Default::default()
};
let root = LayoutNode {
style: make_box(Display::Flex, 900.0, 220.0),
text: None,
children: vec![LayoutNode::leaf(main), LayoutNode::leaf(sidebar)],
};
let out = layout(&root, (900.0, 220.0));
assert!(
out.children[0].border_box.x.abs() < 0.01,
"main shifted to {:?}",
out.children[0].border_box
);
assert!(
out.children[1].border_box.x.abs() < 0.01,
"overlay shifted to {:?}",
out.children[1].border_box
);
}
#[test] #[test]
fn flex_row_lays_out_horizontally() { fn flex_row_lays_out_horizontally() {
let root = LayoutNode { let root = LayoutNode {
@@ -265,3 +265,70 @@ fn long_text_run_wraps_across_multiple_lines() {
div_rect.height div_rect.height
); );
} }
#[test]
fn negative_flex_margin_overlays_at_container_start() {
let html = r##"
<html><head><style>
html,body{margin:0}
#document{display:flex;width:900px;height:220px}
#main{width:100%;height:200px}
#body{margin-left:225px;height:200px}
#sidebar{display:flex;width:225px;height:180px;margin-left:-100%}
</style></head><body>
<div id="document">
<div id="main"><div id="body"></div></div>
<div id="sidebar"></div>
</div>
</body></html>
"##;
let tree = parse_html(html);
let layout = layout_dom(&tree, (900.0, 1000.0));
let document = layout.rects[&tree.get_element_by_id("document").unwrap()];
let main = layout.rects[&tree.get_element_by_id("main").unwrap()];
let body = layout.rects[&tree.get_element_by_id("body").unwrap()];
let sidebar = layout.rects[&tree.get_element_by_id("sidebar").unwrap()];
assert!((document.x - 0.0).abs() < 0.01, "document: {document:?}");
assert!((main.x - 0.0).abs() < 0.01, "main: {main:?}");
assert!((body.x - 225.0).abs() < 0.01, "body: {body:?}");
assert!((sidebar.x - 0.0).abs() < 0.01, "sidebar: {sidebar:?}");
}
#[test]
fn percentage_flex_overlay_uses_auto_width_parent_content_box() {
let html = r##"
<html><head><style>
html,body{margin:0}
body{margin-left:1em;margin-right:1em}
#document{display:flex}
#main{float:left;width:100%;height:200px}
#body{margin-left:min(25vw,350px);height:200px}
#sidebar{
display:flex;
width:min(25vw,350px);
height:180px;
margin-left:-100%;
float:none;
position:sticky;
top:0
}
</style></head><body>
<div id="document">
<div id="main"><div id="body"></div></div>
<div id="sidebar"></div>
</div>
</body></html>
"##;
let tree = parse_html(html);
let layout = layout_dom(&tree, (1280.0, 1400.0));
let document = layout.rects[&tree.get_element_by_id("document").unwrap()];
let main = layout.rects[&tree.get_element_by_id("main").unwrap()];
let body = layout.rects[&tree.get_element_by_id("body").unwrap()];
let sidebar = layout.rects[&tree.get_element_by_id("sidebar").unwrap()];
assert!((document.x - 16.0).abs() < 0.01, "document: {document:?}");
assert!((document.width - 1248.0).abs() < 0.01, "document: {document:?}");
assert!((main.x - 16.0).abs() < 0.01, "main: {main:?}");
assert!((body.x - 336.0).abs() < 0.01, "body: {body:?}");
assert!((sidebar.x - 16.0).abs() < 0.01, "sidebar: {sidebar:?}");
assert!((sidebar.width - 320.0).abs() < 0.01, "sidebar: {sidebar:?}");
}
+6
View File
@@ -42,6 +42,12 @@
{"name": "calc combines viewport and root font units", "color": "#7048e8", "x": 122, "y": 180, "width": 100, "height": 40}, {"name": "calc combines viewport and root font units", "color": "#7048e8", "x": 122, "y": 180, "width": 100, "height": 40},
{"name": "max padding uses actual viewport", "color": "#c2255c", "x": 60, "y": 240, "width": 20, "height": 40} {"name": "max padding uses actual viewport", "color": "#c2255c", "x": 60, "y": 240, "width": 20, "height": 40}
], ],
"flex-whitespace-items": [
{"name": "direct flex sidebar starts at container edge", "color": "#1971c2", "x": 0, "y": 0, "width": 225, "height": 180},
{"name": "direct flex body keeps its intended inset", "color": "#2b8a3e", "x": 225, "y": 0, "width": 675, "height": 200},
{"name": "display contents flex sidebar starts at container edge", "color": "#7048e8", "x": 0, "y": 260, "width": 150, "height": 140},
{"name": "display contents flex body keeps its intended inset", "color": "#c2255c", "x": 150, "y": 260, "width": 450, "height": 160}
],
"grid-auto-repeat": [ "grid-auto-repeat": [
{"name": "auto-fill creates all fitting tracks", "color": "#087f5b", "width": 210, "height": 60, "count": 4}, {"name": "auto-fill creates all fitting tracks", "color": "#087f5b", "width": 210, "height": 60, "count": 4},
{"name": "auto-fit collapses empty tracks", "color": "#1971c2", "width": 287, "height": 60, "count": 3} {"name": "auto-fit collapses empty tracks", "color": "#1971c2", "width": 287, "height": 60, "count": 3}
+48
View File
@@ -0,0 +1,48 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>flex whitespace items</title>
<style>
html, body { margin: 0; }
.document { display: flex; }
/* A float left over from a legacy layout must be ignored on a flex item. */
.main { float: left; width: 100%; background: #e8590c; }
.body { background: #2b8a3e; }
.sidebar { display: flex; }
#direct { width: 900px; height: 220px; }
#direct .main, #direct .body { height: 200px; }
#direct .body { margin-left: 225px; }
#direct .sidebar {
width: 225px;
height: 180px;
margin-left: -100%;
background: #1971c2;
}
#transparent { width: 600px; height: 180px; margin-top: 40px; }
#transparent .contents { display: contents; }
#transparent .main, #transparent .body { height: 160px; }
#transparent .body { margin-left: 150px; background: #c2255c; }
#transparent .sidebar {
width: 150px;
height: 140px;
margin-left: -100%;
background: #7048e8;
}
</style>
</head>
<body>
<div id="direct" class="document">
<div class="main"><div class="body"></div></div>
<div class="sidebar"></div>
</div>
<div id="transparent" class="document">
<div class="contents">
<div class="main"><div class="body"></div></div>
<div class="sidebar"></div>
</div>
</div>
</body>
</html>