Fix the unit test

These were broken for various issues.
This commit is contained in:
Martin Robinson 2023-05-31 10:32:09 +02:00 committed by Oriol Brufau
parent 25f6cc04a2
commit 5c5cc4b795
2 changed files with 63 additions and 47 deletions

View file

@ -40,17 +40,17 @@ pub(crate) struct FloatBox {
/// elements relative to their containing blocks. This data structure is used to /// elements relative to their containing blocks. This data structure is used to
/// help map between these two coordinate systems. /// help map between these two coordinate systems.
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub(crate) struct ContainingBlockPositionInfo { pub struct ContainingBlockPositionInfo {
/// The distance from the block start of the independent block formatting /// The distance from the block start of the independent block formatting
/// context that contains the floats and the block start of the current /// context that contains the floats and the block start of the current
/// containing block, excluding uncollapsed block start margins. Note that /// containing block, excluding uncollapsed block start margins. Note that
/// this does not include uncollapsed block start margins because we don't /// this does not include uncollapsed block start margins because we don't
/// know the value of collapsed margins until we lay out children. /// know the value of collapsed margins until we lay out children.
pub block_start: Length, pub(crate) block_start: Length,
/// Any uncollapsed block start margins that we have collected between the /// Any uncollapsed block start margins that we have collected between the
/// block start of the float containing independent block formatting context /// block start of the float containing independent block formatting context
/// and this containing block, including for this containing block. /// and this containing block, including for this containing block.
pub block_start_margins_not_collapsed: CollapsedMargin, pub(crate) block_start_margins_not_collapsed: CollapsedMargin,
/// The distance from the inline start position of the float containing /// The distance from the inline start position of the float containing
/// independent formatting context and the inline start of this containing /// independent formatting context and the inline start of this containing
/// block. /// block.
@ -61,9 +61,9 @@ pub(crate) struct ContainingBlockPositionInfo {
pub inline_end: Length, pub inline_end: Length,
} }
impl ContainingBlockPositionInfo { impl Default for ContainingBlockPositionInfo {
fn new() -> ContainingBlockPositionInfo { fn default() -> Self {
ContainingBlockPositionInfo { Self {
block_start: Length::zero(), block_start: Length::zero(),
block_start_margins_not_collapsed: CollapsedMargin::zero(), block_start_margins_not_collapsed: CollapsedMargin::zero(),
inline_start: Length::zero(), inline_start: Length::zero(),
@ -72,12 +72,22 @@ impl ContainingBlockPositionInfo {
} }
} }
impl ContainingBlockPositionInfo {
pub fn new_with_inline_offsets(inline_start: Length, inline_end: Length) -> Self {
Self {
inline_start,
inline_end,
..Default::default()
}
}
}
/// Data kept during layout about the floats in a given block formatting context. /// Data kept during layout about the floats in a given block formatting context.
/// ///
/// This is a persistent data structure. Each float has its own private copy of the float context, /// This is a persistent data structure. Each float has its own private copy of the float context,
/// although such copies may share portions of the `bands` tree. /// although such copies may share portions of the `bands` tree.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub(crate) struct FloatContext { pub struct FloatContext {
/// A persistent AA tree of float bands. /// A persistent AA tree of float bands.
/// ///
/// This tree is immutable; modification operations return the new tree, which may share nodes /// This tree is immutable; modification operations return the new tree, which may share nodes
@ -114,7 +124,7 @@ impl FloatContext {
FloatContext { FloatContext {
bands, bands,
ceiling: Length::zero(), ceiling: Length::zero(),
containing_block_info: ContainingBlockPositionInfo::new(), containing_block_info: Default::default(),
clear_left_position: Length::zero(), clear_left_position: Length::zero(),
clear_right_position: Length::zero(), clear_right_position: Length::zero(),
} }

View file

@ -9,7 +9,7 @@ extern crate lazy_static;
use euclid::num::Zero; use euclid::num::Zero;
use layout::flow::float::{ClearSide, FloatBand, FloatBandNode, FloatBandTree, FloatContext}; use layout::flow::float::{ClearSide, FloatBand, FloatBandNode, FloatBandTree, FloatContext};
use layout::flow::float::{ContainingBlockOffsets, FloatSide, PlacementInfo}; use layout::flow::float::{ContainingBlockPositionInfo, FloatSide, PlacementInfo};
use layout::geom::flow_relative::{Rect, Vec2}; use layout::geom::flow_relative::{Rect, Vec2};
use quickcheck::{Arbitrary, Gen}; use quickcheck::{Arbitrary, Gen};
use std::f32; use std::f32;
@ -57,8 +57,7 @@ impl<'a> Drop for PanicMsgSuppressor<'a> {
struct FloatBandWrapper(FloatBand); struct FloatBandWrapper(FloatBand);
impl Arbitrary for FloatBandWrapper { impl Arbitrary for FloatBandWrapper {
fn arbitrary(generator: &mut Gen) -> FloatBandWrapper fn arbitrary(generator: &mut Gen) -> FloatBandWrapper {
{
let top: u32 = Arbitrary::arbitrary(generator); let top: u32 = Arbitrary::arbitrary(generator);
let left: Option<u32> = Arbitrary::arbitrary(generator); let left: Option<u32> = Arbitrary::arbitrary(generator);
let right: Option<u32> = Arbitrary::arbitrary(generator); let right: Option<u32> = Arbitrary::arbitrary(generator);
@ -73,21 +72,17 @@ impl Arbitrary for FloatBandWrapper {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
struct FloatRangeInput { struct FloatRangeInput {
start_index: u32, start_index: u32,
band_count: u32,
side: FloatSide, side: FloatSide,
length: u32, length: u32,
} }
impl Arbitrary for FloatRangeInput { impl Arbitrary for FloatRangeInput {
fn arbitrary(generator: &mut Gen) -> FloatRangeInput fn arbitrary(generator: &mut Gen) -> FloatRangeInput {
{
let start_index: u32 = Arbitrary::arbitrary(generator); let start_index: u32 = Arbitrary::arbitrary(generator);
let band_count: u32 = Arbitrary::arbitrary(generator);
let is_left: bool = Arbitrary::arbitrary(generator); let is_left: bool = Arbitrary::arbitrary(generator);
let length: u32 = Arbitrary::arbitrary(generator); let length: u32 = Arbitrary::arbitrary(generator);
FloatRangeInput { FloatRangeInput {
start_index, start_index,
band_count,
side: if is_left { side: if is_left {
FloatSide::Left FloatSide::Left
} else { } else {
@ -337,21 +332,25 @@ struct FloatInput {
// The float may be placed no higher than this line. This simulates the effect of line boxes // The float may be placed no higher than this line. This simulates the effect of line boxes
// per CSS 2.1 § 9.5.1 rule 6. // per CSS 2.1 § 9.5.1 rule 6.
ceiling: u32, ceiling: u32,
/// Distances from the logical left side of the block formatting context to the logical sides /// Containing block positioning information, which is used to track the current offsets
/// of the current containing block. /// from the float containing block formatting context to the current containing block.
cb_offset: ContainingBlockOffsets, containing_block_info: ContainingBlockPositionInfo,
} }
impl Arbitrary for FloatInput { impl Arbitrary for FloatInput {
fn arbitrary(generator: &mut Gen) -> FloatInput fn arbitrary(generator: &mut Gen) -> FloatInput {
{ // See #29819: Limit the maximum size of all f32 values here because
let width: u32 = Arbitrary::arbitrary(generator); // massive float values will start to introduce very bad floating point
let height: u32 = Arbitrary::arbitrary(generator); // errors.
let is_left: bool = Arbitrary::arbitrary(generator); // TODO: This should be be addressed in a better way. Perhaps we should
let ceiling: u32 = Arbitrary::arbitrary(generator); // reintroduce the use of app_units in Layout 2020.
let left: u32 = Arbitrary::arbitrary(generator); let width = u32::arbitrary(generator) % 12345;
let right: u32 = Arbitrary::arbitrary(generator); let height = u32::arbitrary(generator) % 12345;
let clear: u8 = Arbitrary::arbitrary(generator); let is_left = bool::arbitrary(generator);
let ceiling = u32::arbitrary(generator) % 12345;
let left = u32::arbitrary(generator) % 12345;
let containing_block_width = u32::arbitrary(generator) % 12345;
let clear = u8::arbitrary(generator);
FloatInput { FloatInput {
info: PlacementInfo { info: PlacementInfo {
size: Vec2 { size: Vec2 {
@ -366,11 +365,10 @@ impl Arbitrary for FloatInput {
clear: new_clear_side(clear), clear: new_clear_side(clear),
}, },
ceiling, ceiling,
cb_offset: ContainingBlockOffsets { containing_block_info: ContainingBlockPositionInfo::new_with_inline_offsets(
top: Length::zero(), Length::new(left as f32),
left: Length::new(left as f32), Length::new(left as f32 + containing_block_width as f32),
right: Length::new(right as f32), ),
},
} }
} }
@ -389,12 +387,12 @@ impl Arbitrary for FloatInput {
this.info.clear = new_clear_side(clear_side); this.info.clear = new_clear_side(clear_side);
shrunk = true; shrunk = true;
} }
if let Some(left) = self.cb_offset.left.px().shrink().next() { if let Some(left) = self.containing_block_info.inline_start.px().shrink().next() {
this.cb_offset.left = Length::new(left); this.containing_block_info.inline_start = Length::new(left);
shrunk = true; shrunk = true;
} }
if let Some(right) = self.cb_offset.right.px().shrink().next() { if let Some(right) = self.containing_block_info.inline_end.px().shrink().next() {
this.cb_offset.right = Length::new(right); this.containing_block_info.inline_end = Length::new(right);
shrunk = true; shrunk = true;
} }
if let Some(ceiling) = self.ceiling.shrink().next() { if let Some(ceiling) = self.ceiling.shrink().next() {
@ -430,7 +428,7 @@ struct PlacedFloat {
origin: Vec2<Length>, origin: Vec2<Length>,
info: PlacementInfo, info: PlacementInfo,
ceiling: Length, ceiling: Length,
walls: ContainingBlockOffsets, containing_block_info: ContainingBlockPositionInfo,
} }
impl Drop for FloatPlacement { impl Drop for FloatPlacement {
@ -447,8 +445,8 @@ impl Drop for FloatPlacement {
placed_float.info, placed_float.info,
placed_float.origin, placed_float.origin,
placed_float.ceiling, placed_float.ceiling,
placed_float.walls.left, placed_float.containing_block_info.inline_start,
placed_float.walls.right, placed_float.containing_block_info.inline_end,
); );
} }
eprintln!("Bands:\n{:?}\n", self.float_context.bands); eprintln!("Bands:\n{:?}\n", self.float_context.bands);
@ -471,12 +469,12 @@ impl FloatPlacement {
for float in floats { for float in floats {
let ceiling = Length::new(float.ceiling as f32); let ceiling = Length::new(float.ceiling as f32);
float_context.lower_ceiling(ceiling); float_context.lower_ceiling(ceiling);
float_context.cb_bfc_distance = float.cb_offset; float_context.containing_block_info = float.containing_block_info;
placed_floats.push(PlacedFloat { placed_floats.push(PlacedFloat {
origin: float_context.add_float(&float.info), origin: float_context.add_float(&float.info),
info: float.info, info: float.info,
ceiling, ceiling,
walls: float.cb_offset, containing_block_info: float.containing_block_info,
}) })
} }
FloatPlacement { FloatPlacement {
@ -495,9 +493,14 @@ impl FloatPlacement {
fn check_floats_rule_1(placement: &FloatPlacement) { fn check_floats_rule_1(placement: &FloatPlacement) {
for placed_float in &placement.placed_floats { for placed_float in &placement.placed_floats {
match placed_float.info.side { match placed_float.info.side {
FloatSide::Left => assert!(placed_float.origin.inline >= placed_float.walls.left), FloatSide::Left => assert!(
placed_float.origin.inline >= placed_float.containing_block_info.inline_start
),
FloatSide::Right => { FloatSide::Right => {
assert!(placed_float.rect().max_inline_position() <= placed_float.walls.right) assert!(
placed_float.rect().max_inline_position() <=
placed_float.containing_block_info.inline_end
)
}, },
} }
} }
@ -603,12 +606,14 @@ fn check_floats_rule_7(placement: &FloatPlacement) {
// Only consider floats that stick out. // Only consider floats that stick out.
match placed_float.info.side { match placed_float.info.side {
FloatSide::Left => { FloatSide::Left => {
if placed_float.rect().max_inline_position() <= placed_float.walls.right { if placed_float.rect().max_inline_position() <=
placed_float.containing_block_info.inline_end
{
continue; continue;
} }
}, },
FloatSide::Right => { FloatSide::Right => {
if placed_float.origin.inline >= placed_float.walls.left { if placed_float.origin.inline >= placed_float.containing_block_info.inline_start {
continue; continue;
} }
}, },
@ -668,7 +673,7 @@ fn check_floats_rule_9(floats_and_perturbations: Vec<(FloatInput, u32)>) {
let mut placement = placement.clone(); let mut placement = placement.clone();
{ {
let mut placed_float = &mut placement.placed_floats[float_index]; let placed_float = &mut placement.placed_floats[float_index];
let perturbation = Length::new(perturbation as f32); let perturbation = Length::new(perturbation as f32);
match placed_float.info.side { match placed_float.info.side {
FloatSide::Left => { FloatSide::Left => {
@ -754,6 +759,7 @@ fn check_basic_float_rules(placement: &FloatPlacement) {
fn test_floats_rule_1() { fn test_floats_rule_1() {
let f: fn(Vec<FloatInput>) = check; let f: fn(Vec<FloatInput>) = check;
quickcheck::quickcheck(f); quickcheck::quickcheck(f);
fn check(floats: Vec<FloatInput>) { fn check(floats: Vec<FloatInput>) {
check_floats_rule_1(&FloatPlacement::place(floats)); check_floats_rule_1(&FloatPlacement::place(floats));
} }