Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add text measuring support to the test generator #1296

Open
nicoburns opened this issue May 15, 2023 · 3 comments
Open

Add text measuring support to the test generator #1296

nicoburns opened this issue May 15, 2023 · 3 comments

Comments

@nicoburns
Copy link
Contributor

Objective

Make it easy to test the layout of nodes with different min-content and max-content sizes.

Steps

@NickGerleman
Copy link
Contributor

NickGerleman commented Jul 10, 2023

I talked to folks a bit recently about the intersection of Yoga and text, in the context of the inline formatting context.

I think, at a system level, we want Yoga itself to be oblivious to text. But the underlying UI platform can provide an inline formatting context via its own text measurement and layout system. The system can then delegate back to Yoga if it encounters a block or flex formatting context.

So, the boundary to Yoga is more of an abstract “leaf node providing custom layout and measurement” instead of the actual text.

With that in mind, I think it would be easiest to reason about, for our own tests, a way to express leaf elements with a specifically input size. Or if we wanted to port over web tests, we could collapse text into some rough heuristic based on character count of the like, since we don’t care about measurement at the text level, beyond not invalidating the original test.

@NickGerleman
Copy link
Contributor

Saying Yoga is oblivious to text measurement isn't quite correct. Nodes can provide a baseline to Yoga, used for baseline alignment in flexbox. See YGNodeSetBaselineFunc()

@nicoburns
Copy link
Contributor Author

I completely agree that Yoga ought to be unaware of text (modulo perhaps a few small integration points such as baseline alignment).

This proposal here is to make the test harness text aware. The purpose of this is to make it easy to create tests containing measure functions that return variable sizes depending on the input constraints they are called with (intuition: a measure function that works like wrapped text where the height varies approximately continuously with width between the min-content (every wrap opportunity taken) and max-content (no wrapping) sizes).

This is necessary to comprehensively test CSS layout algorithms (including Flexbox), as they will often measure children multiple times under different constraints (min-content, max-content, and fit-content(limit)), and some bugs only manifest themselves when the measure function returns different sizes under different constraints (so unfortunately a mechanism to set a specifically input size won't be sufficient).

Or if we wanted to port over web tests, we could collapse text into some rough heuristic based on character count of the like, since we don’t care about measurement at the text level, beyond not invalidating the original test.

This is effectively what is proposed here (see the text layout algorithm linked in the description, which is only ~50 LoC, and that includes support for things like vertically oriented text (again, only in the test harness)), with the added bonus of configuring the web browser used generate test assertions to exactly match this basic algorithm. This is done by using the Ahem font (which was specifically designed for web testing), which sets all common glyphs to simple, well-known dimensions (the exact dimensions depend on font-size you pick, but if you set font-size: 10px, then all the ascii letters are exactly 10px by 10px).

In Taffy, we have a bunch of tests like:

<div id="test-root">
  <div>HH&ZeroWidthSpace;HH&ZeroWidthSpace;HH</div>
</div>

Where the inner div's generated measure function will intelligently return either w:30px, h:20px, w:20px, h:20px or w:30px, h:10px) depending on the input constraints passed to it. IMO it's a pretty intuitive way to write more complex tests.

We caught a whole bunch of bugs in Taffy when we implemented support for this in our test runner, and part of my motivation for wanting to implement this in Yoga's test generator is that this is now the main thing blocking me from upstreaming Taffy's additional test coverage back to Yoga. It will also be pretty much required to properly test #1298 using generated tests (you could possibly work around it using flex-wrap nodes instead, but that would be pretty cumbersome!).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants