Skip to content

Commit 7d59ca8

Browse files
committed
docs(forest): document imperative HTML test framework usage in README
Add Testing section covering run/add-case workflow, data-expect-* / data-ignore attribute mapping, generated code shape (tests/generated), fn naming, and optional Chrome cross-check.
1 parent 4f6ebc0 commit 7d59ca8

1 file changed

Lines changed: 78 additions & 0 deletions

File tree

float-pigment-forest/README.md

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,81 @@
33
A node tree implementation for float-pigment-layout.
44

55
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

Comments
 (0)