Skip to main content

max / quasi

2.9 KB · 93 lines History Blame Raw
1 //! A guard inside a loop body, derived and filled.
2 //!
3 //! The regression test for a derivation bug rather than for a feature, and it
4 //! is here because the shape is ordinary: a strip of figures where each may or
5 //! may not report a change is what every dashboard in this tree draws.
6 //!
7 //! `grown` converts the placement it measures in the two-row render into the
8 //! body's own place in the one-row render, and it was subtracting a body length
9 //! from both ends of the window. The earliest placement does not move under
10 //! that conversion -- it is already the body's place -- so the window collapsed
11 //! to a point, and `placed` had nowhere to slide the span when the prefix scan
12 //! ran a byte past the body. `</div>` and `<div class="figure"` share their
13 //! `<`, which is all it takes. The loop then sat one byte off its own body,
14 //! overlapped the guard inside it, and `build` refused the screen as a
15 //! structure that is not a tree.
16 //!
17 //! Found on MNW's `/dashboard/tabs/analytics`, whose stats strip is three
18 //! guarded figures in a loop, one per tone a delta can carry.
19
20 // The fixture data below is built by this module's tests and by nothing else:
21 // the bench itself measures the shapes, not the rows behind them.
22 #![allow(dead_code)]
23 use quasi_declare::declare;
24 use quasi_router::screen::Figure;
25
26 pub(crate) struct Card {
27 pub value: String,
28 pub label: String,
29 pub delta: Option<String>,
30 }
31
32 pub(crate) fn cards(n: usize, with_delta: bool) -> Vec<Card> {
33 (0..n)
34 .map(|i| Card {
35 value: format!("{i}00"),
36 label: format!("Card {i}"),
37 delta: with_delta.then(|| format!("+{i}%")),
38 })
39 .collect()
40 }
41
42 fn delta(card: &Card) -> &str {
43 card.delta.as_deref().unwrap_or_default()
44 }
45
46 declare! {
47 /// A strip of figures, each of which may report a change.
48 #[staged]
49 pub(crate) shape strip(cards: &[Card]) -> Node;
50
51 stats [] {
52 for card in cards.iter() {
53 figure Figure::new(card.value.clone(), card.label.clone())
54 .change(delta(card))
55 unless card.delta.is_none();
56 }
57 }
58 }
59
60 #[cfg(test)]
61 mod tests {
62 use super::*;
63 use quasi_http::Serves as _;
64 use quasi_router::stage::Residual;
65 use quasi_webview::Webview;
66
67 fn residual() -> Residual {
68 quasi_webview::stage::derive(&Webview::new(), strip_staged)
69 }
70
71 #[test]
72 fn probe_residual() {
73 let residual = residual();
74 eprintln!("{:#?}", residual.ops());
75 }
76
77 #[test]
78 fn a_guard_inside_a_loop_body_derives() {
79 let webview = Webview::new();
80 let residual = residual();
81 for n in [0, 1, 3] {
82 for with in [false, true] {
83 let cards = cards(n, with);
84 assert_eq!(
85 webview.fragment(&strip(&cards)),
86 strip_serve(&residual, &cards),
87 "{n} cards, delta {with}"
88 );
89 }
90 }
91 }
92 }
93