|
3 | 3 | A node tree implementation for float-pigment-layout. |
4 | 4 |
|
5 | 5 | This is a crate of the [float-pigment](https://github.com/wechat-miniprogram/float-pigment) project. See its documentation for details. |
| 6 | + |
| 7 | +## Testing |
| 8 | + |
| 9 | +The test suite uses an **HTML-based imperative codegen** framework. You author declarative HTML test cases; `build.rs` compiles each into a self-contained imperative Rust `#[test]` at build time (no hand-written test code). |
| 10 | + |
| 11 | +### Run tests |
| 12 | + |
| 13 | +```bash |
| 14 | +cargo test -p float-pigment-forest |
| 15 | +``` |
| 16 | + |
| 17 | +### Add a test case |
| 18 | + |
| 19 | +1. Create `tests/cases/<topic>/<name>.html`: |
| 20 | + |
| 21 | +```html |
| 22 | +<div style="display: flex; width: 200px; height: 100px;"> |
| 23 | + <div style="width: 80px; height: 40px;" data-expect-width="80" data-expect-left="0"></div> |
| 24 | + <div style="width: 120px; height: 40px;" data-expect-width="120" data-expect-left="80"></div> |
| 25 | +</div> |
| 26 | +``` |
| 27 | + |
| 28 | +2. Run `cargo test -p float-pigment-forest`. `build.rs` auto-generates `tests/generated/<topic>/<name>.rs` (imperative) and runs it. |
| 29 | + |
| 30 | +3. Inspect the generated code: |
| 31 | + |
| 32 | +```bash |
| 33 | +cat tests/generated/<topic>/<name>.rs |
| 34 | +``` |
| 35 | + |
| 36 | +### Assertion attributes |
| 37 | + |
| 38 | +Write `data-expect-*` on the element(s) you want to assert. Values are numbers (pixels); only write the axes you check. |
| 39 | + |
| 40 | +| HTML attribute | Generated assertion | |
| 41 | +|---|---| |
| 42 | +| `data-expect-width="V"` | `assert_eq!(ctx.width(n).round(), V.0)` | |
| 43 | +| `data-expect-height="V"` | `assert_eq!(ctx.height(n).round(), V.0)` | |
| 44 | +| `data-expect-left="V"` | `assert_eq!(ctx.left(n).round(), V.0)` | |
| 45 | +| `data-expect-top="V"` | `assert_eq!(ctx.top(n).round(), V.0)` | |
| 46 | +| `data-expect-margin-top/right/bottom/left="V"` | `assert_eq!(ctx.margin_<side>(n).round(), V.0)` | |
| 47 | +| `data-ignore="true"` | marks the `#[test]` as `#[ignore]` | |
| 48 | + |
| 49 | +Text nodes (`>text<`) compile to `ctx.create_text("text")`. |
| 50 | + |
| 51 | +### Generated code shape |
| 52 | + |
| 53 | +Each case compiles to an imperative test under `tests/generated/` (gitignored, regenerated every build): |
| 54 | + |
| 55 | +```rust |
| 56 | +// AUTO-GENERATED from tests/cases/<topic>/<name>.html. Do not edit. |
| 57 | +use crate::TestCtx; |
| 58 | + |
| 59 | +#[test] |
| 60 | +fn html__<topic>_<name>() { |
| 61 | + let mut ctx = TestCtx::new(); |
| 62 | + let n0 = ctx.create_node("div"); |
| 63 | + ctx.set_style(n0, "display: flex; width: 200px; ..."); |
| 64 | + let n1 = ctx.create_node("div"); |
| 65 | + ctx.append(n0, n1); |
| 66 | + ctx.layout_imperative(); |
| 67 | + assert_eq!(ctx.width(n1).round(), 80.0); |
| 68 | +} |
| 69 | +``` |
| 70 | + |
| 71 | +- **Test fn name**: `html__<topic>_<name>` (path separators and `-` → `_`). Filter with `cargo test html__<keyword>`. |
| 72 | +- **Edit a case** → `cargo test` regenerates automatically (`rerun-if-changed=tests/cases`). |
| 73 | +- **`tests/generated/` is gitignored** — HTML cases are the source of truth, generated code is a build artifact. |
| 74 | + |
| 75 | +### Chrome cross-check (optional) |
| 76 | + |
| 77 | +`scripts/chrome-cross-check.mjs` opens each case whose `data-chrome != "false"` in headless Chrome and compares `getBoundingClientRect` against `data-expect-*` — useful for catching cases where float-pigment's layout diverges from a real browser. Run from the repo root: |
| 78 | + |
| 79 | +```bash |
| 80 | +cd scripts && pnpm install && node chrome-cross-check.mjs |
| 81 | +``` |
| 82 | + |
| 83 | +Set `data-chrome="false"` on the root element of a case that intentionally diverges from Chrome (e.g. float-pigment-specific behavior) to exclude it. |
0 commit comments