summaryrefslogtreecommitdiff
path: root/test/web-snapshots/touch.mjs
blob: 1a233e6897a1f11c9e1148d98a59e8c99a00ce35 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import assert from "node:assert/strict";

function tags(frame) {
    return frame.styleRows.flatMap((cells, y) => y > 0 && cells.some((cell) => cell[2] & 128) ? [y] : []);
}

function pane(frame, name) {
    const rows = tags(frame);
    const top = rows.find((row) => frame.lines[row].includes(name));
    assert.notEqual(top, undefined, `missing pane ${name}`);
    const bottom = rows.find((row) => row > top) ?? frame.rows;
    return { top, bottom, lines: frame.lines.slice(top + 1, bottom) };
}

function styled(frame) {
    const source = pane(frame, "touch-fixture.zig");
    for (const [line, word, fg, bold] of [
        ["pub fn choose", "fn", 0xcf87e8, true],
        ["pub fn choose", "choose", 0xbdbdbd, false],
        ["if (value", "if", 0xcf87e8, true],
        ["if (value", "42", 0xe3c78a, false],
        ["if (value", '"touch fixture"', 0xe3c78a, false],
    ]) {
        const row = source.lines.findIndex((text) => text.includes(line));
        assert(row >= 0, `missing source line ${line}`);
        const col = source.lines[row].indexOf(word);
        for (let x = col; x < col + word.length; x++) {
            const style = frame.styleRows[source.top + 1 + row][x];
            assert.equal(style[0], fg, `${word} cell ${x - col} foreground`);
            assert.equal(Boolean(style[2] & 1), bold, `${word} cell ${x - col} bold`);
        }
    }
    for (const [row, line] of source.lines.entries()) {
        const number = /\b(\d+),/.exec(line);
        if (!number) continue;
        for (let x = number.index; x < number.index + number[1].length; x++) {
            assert.equal(frame.styleRows[source.top + 1 + row][x][0], 0xe3c78a, `row ${row} number foreground`);
        }
    }
}

export default async function ({ grid, touch, wait, stable, delay }) {
    await stable(100, 5000);
    let frame = await grid();
    assert.equal(tags(frame).length, 1);
    styled(frame);
    const link = "/virtual/pane/1/body";
    const row = frame.lines.findIndex((text) => text.includes(link));
    const col = frame.lines[row].indexOf(link) + 5;
    let finger = await touch("down", 1, col, row, null);
    finger = await touch("move", 1, col + 0.2, row + 0.1, finger);
    await touch("up", 1, col + 0.2, row + 0.1, finger);
    await wait(async () => tags(await grid()).length === 2, 5000, "Look opening the reflected body");
    await stable(100, 5000);
    frame = await grid();
    styled(frame);
    const reflected = pane(frame, link);
    assert(reflected.lines.some((text) => text.includes("pub fn choose")));
    const original = pane(frame, "touch-fixture.zig");
    const sharedRows = Math.min(reflected.lines.length, original.lines.length);
    assert(sharedRows >= 6);
    assert.deepEqual(reflected.lines.slice(0, sharedRows), original.lines.slice(0, sharedRows), "Look must read the source pane body");

    const center = Math.floor(frame.cols / 2);
    const separator = Math.max(original.top, reflected.top) - 1;
    const distance = original.top < reflected.top ? 4 : -4;
    finger = await touch("down", 2, center, separator, null);
    for (let step = 1; step <= 8; step++) {
        finger = await touch("move", 2, center, separator + distance * step / 8, finger);
        await delay(20);
    }
    await touch("up", 2, center, separator + distance, finger);
    await stable(100, 5000);
    frame = await grid();
    assert.equal(tags(frame).length, 2);
    const resized = pane(frame, "touch-fixture.zig");
    assert(resized.lines.length >= original.lines.length + 3, "separator drag must resize, not scroll the body");
    assert.equal(resized.lines[0], original.lines[0], "resizing must preserve the source viewport");
    styled(frame);

    const beforeScroll = resized.lines[0];
    const reflectedBeforeScroll = pane(frame, link).lines;
    const from = resized.bottom - 3;
    const to = Math.max(resized.top + 2, from - 7);
    finger = await touch("down", 3, center, from, null);
    for (let step = 1; step <= 12; step++) {
        finger = await touch("move", 3, center, from + (to - from) * step / 12, finger);
        await delay(20);
    }
    await touch("up", 3, center, to, finger);
    await stable(100, 5000);
    frame = await grid();
    assert.equal(tags(frame).length, 2, "scroll must not also Look");
    const scrolled = pane(frame, "touch-fixture.zig");
    assert.equal(scrolled.top, resized.top, "body scrolling must not resize");
    assert.notEqual(scrolled.lines[0], beforeScroll, "source must scroll");
    assert(Number(scrolled.lines[0].trim().split(/\s+/)[0]) > 1, "scroll advances source line numbers");
    assert.deepEqual(pane(frame, link).lines, reflectedBeforeScroll, "scrolling the source must leave its neighbor alone");
}