Skip to content

Commit 18509ed

Browse files
committed
1 parent a811fc4 commit 18509ed

File tree

3 files changed

+197
-29
lines changed

3 files changed

+197
-29
lines changed

test/van.test.js

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
window.numTests = 0;
22
const runTests = async (van, msgDom, { debug }) => {
3-
const { a, b, button, div, h2, input, li, option, p, pre, select, span, sup, table, tbody, td, th, thead, tr, ul } = van.tags;
3+
const { a, b, button, div, h2, i, input, li, option, p, pre, select, span, sup, table, tbody, td, th, thead, tr, ul } = van.tags;
44
const assert = (cond) => {
55
if (!cond)
66
throw new Error("Assertion failed");
@@ -1361,20 +1361,71 @@ const runTests = async (van, msgDom, { debug }) => {
13611361
await sleep(waitMsOnDomUpdates);
13621362
assertEq(hiddenDom.innerHTML, '<span><button style="background-color: yellow;">Click Me</button> <button style="background-color: green;">Turn Red</button> <button style="background-color: rgb(235, 235, 235);">Get Darker</button></span>');
13631363
}),
1364+
hydrate: hydrateExample(Counter),
1365+
hydrateOptimized: hydrateExample(OptimizedCounter),
13641366
domValuedState_excludeDebug: withHiddenDom(async (hiddenDom) => {
13651367
const TurnBold = () => {
13661368
const vanJS = van.state("VanJS");
13671369
return span(button({ onclick: () => vanJS.val = b("VanJS") }, "Turn Bold"), " Welcome to ", vanJS, ". ", vanJS, " is awesome!");
13681370
};
13691371
van.add(hiddenDom, TurnBold());
13701372
const dom = (hiddenDom.firstChild);
1371-
assertEq(dom.outerHTML, "<span><button>Turn Bold</button>&nbsp;Welcome to VanJS. VanJS&nbsp;is awesome!</span>");
1373+
assertEq(dom.outerHTML, "<span><button>Turn Bold</button> Welcome to VanJS. VanJS is awesome!</span>");
13721374
dom.querySelector("button").click();
13731375
await sleep(waitMsOnDomUpdates);
1374-
assertEq(dom.outerHTML, "<span><button>Turn Bold</button>&nbsp;Welcome to . <b>VanJS</b>&nbsp;is awesome!</span>");
1376+
assertEq(dom.outerHTML, "<span><button>Turn Bold</button> Welcome to . <b>VanJS</b> is awesome!</span>");
1377+
}),
1378+
minimizeDomUpdates: withHiddenDom(async (hiddenDom) => {
1379+
const name = van.state("");
1380+
const Name1 = () => {
1381+
const numRendered = van.state(0);
1382+
return div(() => {
1383+
++numRendered.val;
1384+
return name.val.trim().length === 0 ?
1385+
p("Please enter your name") :
1386+
p("Hello ", b(name));
1387+
}, p(i("The <p> element has been rendered ", numRendered, " time(s).")));
1388+
};
1389+
const Name2 = () => {
1390+
const numRendered = van.state(0);
1391+
const isNameEmpty = van.derive(() => name.val.trim().length === 0);
1392+
return div(() => {
1393+
++numRendered.val;
1394+
return isNameEmpty.val ?
1395+
p("Please enter your name") :
1396+
p("Hello ", b(name));
1397+
}, p(i("The <p> element has been rendered ", numRendered, " time(s).")));
1398+
};
1399+
van.add(hiddenDom, p("Your name is: ", input({ type: "text", value: name, oninput: e => name.val = e.target.value })), Name1(), Name2());
1400+
await sleep(waitMsOnDomUpdates);
1401+
assertEq(hiddenDom.innerHTML, '<p>Your name is: <input type="text"></p><div><p>Please enter your name</p><p><i>The &lt;p&gt; element has been rendered 1 time(s).</i></p></div><div><p>Please enter your name</p><p><i>The &lt;p&gt; element has been rendered 1 time(s).</i></p></div>');
1402+
hiddenDom.querySelector("input").value = "T";
1403+
hiddenDom.querySelector("input").dispatchEvent(new Event("input"));
1404+
await sleep(waitMsOnDomUpdates);
1405+
hiddenDom.querySelector("input").value = "Ta";
1406+
hiddenDom.querySelector("input").dispatchEvent(new Event("input"));
1407+
await sleep(waitMsOnDomUpdates);
1408+
hiddenDom.querySelector("input").value = "Tao";
1409+
hiddenDom.querySelector("input").dispatchEvent(new Event("input"));
1410+
await sleep(waitMsOnDomUpdates);
1411+
await sleep(waitMsOnDomUpdates);
1412+
assertEq(hiddenDom.innerHTML, '<p>Your name is: <input type="text"></p><div><p>Hello <b>Tao</b></p><p><i>The &lt;p&gt; element has been rendered 4 time(s).</i></p></div><div><p>Hello <b>Tao</b></p><p><i>The &lt;p&gt; element has been rendered 2 time(s).</i></p></div>');
1413+
hiddenDom.querySelector("input").value = "";
1414+
hiddenDom.querySelector("input").dispatchEvent(new Event("input"));
1415+
await sleep(waitMsOnDomUpdates * 2);
1416+
assertEq(hiddenDom.innerHTML, '<p>Your name is: <input type="text"></p><div><p>Please enter your name</p><p><i>The &lt;p&gt; element has been rendered 5 time(s).</i></p></div><div><p>Please enter your name</p><p><i>The &lt;p&gt; element has been rendered 3 time(s).</i></p></div>');
1417+
hiddenDom.querySelector("input").value = "X";
1418+
hiddenDom.querySelector("input").dispatchEvent(new Event("input"));
1419+
await sleep(waitMsOnDomUpdates);
1420+
hiddenDom.querySelector("input").value = "Xi";
1421+
hiddenDom.querySelector("input").dispatchEvent(new Event("input"));
1422+
await sleep(waitMsOnDomUpdates);
1423+
hiddenDom.querySelector("input").value = "Xin";
1424+
hiddenDom.querySelector("input").dispatchEvent(new Event("input"));
1425+
await sleep(waitMsOnDomUpdates);
1426+
await sleep(waitMsOnDomUpdates);
1427+
assertEq(hiddenDom.innerHTML, '<p>Your name is: <input type="text"></p><div><p>Hello <b>Xin</b></p><p><i>The &lt;p&gt; element has been rendered 8 time(s).</i></p></div><div><p>Hello <b>Xin</b></p><p><i>The &lt;p&gt; element has been rendered 4 time(s).</i></p></div>');
13751428
}),
1376-
hydrate: hydrateExample(Counter),
1377-
hydrateOptimized: hydrateExample(OptimizedCounter),
13781429
};
13791430
// In a VanJS app, there could be many derived DOM nodes, states and side effects created on-the-fly.
13801431
// We want to test the garbage-collection process is in place to ensure obsolete bindings and

test/van.test.nomodule.js

Lines changed: 66 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// ../test/van.test.js
44
window.numTests = 0;
55
var runTests = async (van2, msgDom2, { debug }) => {
6-
const { a, b, button, div: div2, h2: h22, input, li, option, p, pre, select, span, sup, table, tbody, td, th, thead, tr, ul } = van2.tags;
6+
const { a, b, button, div: div2, h2: h22, i, input, li, option, p, pre, select, span, sup, table, tbody, td, th, thead, tr, ul } = van2.tags;
77
const assert = (cond) => {
88
if (!cond)
99
throw new Error("Assertion failed");
@@ -447,7 +447,7 @@
447447
},
448448
derive_derivedState: () => {
449449
const numItems = van2.state(0);
450-
const items = van2.derive(() => [...Array(numItems.val).keys()].map((i) => `Item ${i + 1}`));
450+
const items = van2.derive(() => [...Array(numItems.val).keys()].map((i2) => `Item ${i2 + 1}`));
451451
const selectedIndex = van2.derive(() => (items.val, 0));
452452
const selectedItem = van2.derive(() => items.val[selectedIndex.val]);
453453
numItems.val = 3;
@@ -610,7 +610,7 @@
610610
}),
611611
stateDerivedChild_statefulDynamicDom: withHiddenDom(async (hiddenDom) => {
612612
const numItems = van2.state(0);
613-
const items = van2.derive(() => [...Array(numItems.val).keys()].map((i) => `Item ${i + 1}`));
613+
const items = van2.derive(() => [...Array(numItems.val).keys()].map((i2) => `Item ${i2 + 1}`));
614614
const selectedIndex = van2.derive(() => (items.val, 0));
615615
const domFunc = (dom) => {
616616
if (dom && items.val === items.oldVal) {
@@ -619,7 +619,7 @@
619619
itemDoms[selectedIndex.val].classList.add("selected");
620620
return dom;
621621
}
622-
return ul(items.val.map((item, i) => li({ class: i === selectedIndex.val ? "selected" : "" }, item)));
622+
return ul(items.val.map((item, i2) => li({ class: i2 === selectedIndex.val ? "selected" : "" }, item)));
623623
};
624624
van2.add(hiddenDom, domFunc);
625625
numItems.val = 3;
@@ -978,11 +978,11 @@
978978
hiddenDom.innerHTML = div2(h22("Basic Counter"), Counter2({ van: van2, init: counterInit }), h22("Styled Counter"), p("Select the button style: ", selectDom), Counter2({ van: van2, init: counterInit, buttonStyle })).innerHTML;
979979
const clickBtns = async (dom, numUp, numDown) => {
980980
const [upBtn, downBtn] = [...dom.querySelectorAll("button")];
981-
for (let i = 0; i < numUp; ++i) {
981+
for (let i2 = 0; i2 < numUp; ++i2) {
982982
upBtn.click();
983983
await sleep(waitMsOnDomUpdates);
984984
}
985-
for (let i = 0; i < numDown; ++i) {
985+
for (let i2 = 0; i2 < numDown; ++i2) {
986986
downBtn.click();
987987
await sleep(waitMsOnDomUpdates);
988988
}
@@ -1186,7 +1186,7 @@
11861186
" ",
11871187
select({ oninput: (e) => sortedBy.val = e.target.value, value: sortedBy }, option({ value: "Ascending" }, "Ascending"), option({ value: "Descending" }, "Descending")),
11881188
// A State-derived child node
1189-
() => sortedBy.val === "Ascending" ? ul(items.val.split(",").sort().map((i) => li(i))) : ul(items.val.split(",").sort().reverse().map((i) => li(i)))
1189+
() => sortedBy.val === "Ascending" ? ul(items.val.split(",").sort().map((i2) => li(i2))) : ul(items.val.split(",").sort().reverse().map((i2) => li(i2)))
11901190
);
11911191
};
11921192
van2.add(hiddenDom, SortedList());
@@ -1286,27 +1286,74 @@
12861286
await sleep(waitMsOnDomUpdates);
12871287
assertEq(hiddenDom.innerHTML, '<span><button style="background-color: yellow;">Click Me</button> <button style="background-color: green;">Turn Red</button> <button style="background-color: rgb(235, 235, 235);">Get Darker</button></span>');
12881288
}),
1289+
hydrate: hydrateExample(Counter),
1290+
hydrateOptimized: hydrateExample(OptimizedCounter),
12891291
domValuedState_excludeDebug: withHiddenDom(async (hiddenDom) => {
12901292
const TurnBold = () => {
12911293
const vanJS = van2.state("VanJS");
12921294
return span(button({ onclick: () => vanJS.val = b("VanJS") }, "Turn Bold"), " Welcome to ", vanJS, ". ", vanJS, " is awesome!");
12931295
};
12941296
van2.add(hiddenDom, TurnBold());
12951297
const dom = hiddenDom.firstChild;
1296-
assertEq(dom.outerHTML, "<span><button>Turn Bold</button>&nbsp;Welcome to VanJS. VanJS&nbsp;is awesome!</span>");
1298+
assertEq(dom.outerHTML, "<span><button>Turn Bold</button> Welcome to VanJS. VanJS is awesome!</span>");
12971299
dom.querySelector("button").click();
12981300
await sleep(waitMsOnDomUpdates);
1299-
assertEq(dom.outerHTML, "<span><button>Turn Bold</button>&nbsp;Welcome to . <b>VanJS</b>&nbsp;is awesome!</span>");
1301+
assertEq(dom.outerHTML, "<span><button>Turn Bold</button> Welcome to . <b>VanJS</b> is awesome!</span>");
13001302
}),
1301-
hydrate: hydrateExample(Counter),
1302-
hydrateOptimized: hydrateExample(OptimizedCounter)
1303+
minimizeDomUpdates: withHiddenDom(async (hiddenDom) => {
1304+
const name = van2.state("");
1305+
const Name1 = () => {
1306+
const numRendered = van2.state(0);
1307+
return div2(() => {
1308+
++numRendered.val;
1309+
return name.val.trim().length === 0 ? p("Please enter your name") : p("Hello ", b(name));
1310+
}, p(i("The <p> element has been rendered ", numRendered, " time(s).")));
1311+
};
1312+
const Name2 = () => {
1313+
const numRendered = van2.state(0);
1314+
const isNameEmpty = van2.derive(() => name.val.trim().length === 0);
1315+
return div2(() => {
1316+
++numRendered.val;
1317+
return isNameEmpty.val ? p("Please enter your name") : p("Hello ", b(name));
1318+
}, p(i("The <p> element has been rendered ", numRendered, " time(s).")));
1319+
};
1320+
van2.add(hiddenDom, p("Your name is: ", input({ type: "text", value: name, oninput: (e) => name.val = e.target.value })), Name1(), Name2());
1321+
await sleep(waitMsOnDomUpdates);
1322+
assertEq(hiddenDom.innerHTML, '<p>Your name is: <input type="text"></p><div><p>Please enter your name</p><p><i>The &lt;p&gt; element has been rendered 1 time(s).</i></p></div><div><p>Please enter your name</p><p><i>The &lt;p&gt; element has been rendered 1 time(s).</i></p></div>');
1323+
hiddenDom.querySelector("input").value = "T";
1324+
hiddenDom.querySelector("input").dispatchEvent(new Event("input"));
1325+
await sleep(waitMsOnDomUpdates);
1326+
hiddenDom.querySelector("input").value = "Ta";
1327+
hiddenDom.querySelector("input").dispatchEvent(new Event("input"));
1328+
await sleep(waitMsOnDomUpdates);
1329+
hiddenDom.querySelector("input").value = "Tao";
1330+
hiddenDom.querySelector("input").dispatchEvent(new Event("input"));
1331+
await sleep(waitMsOnDomUpdates);
1332+
await sleep(waitMsOnDomUpdates);
1333+
assertEq(hiddenDom.innerHTML, '<p>Your name is: <input type="text"></p><div><p>Hello <b>Tao</b></p><p><i>The &lt;p&gt; element has been rendered 4 time(s).</i></p></div><div><p>Hello <b>Tao</b></p><p><i>The &lt;p&gt; element has been rendered 2 time(s).</i></p></div>');
1334+
hiddenDom.querySelector("input").value = "";
1335+
hiddenDom.querySelector("input").dispatchEvent(new Event("input"));
1336+
await sleep(waitMsOnDomUpdates * 2);
1337+
assertEq(hiddenDom.innerHTML, '<p>Your name is: <input type="text"></p><div><p>Please enter your name</p><p><i>The &lt;p&gt; element has been rendered 5 time(s).</i></p></div><div><p>Please enter your name</p><p><i>The &lt;p&gt; element has been rendered 3 time(s).</i></p></div>');
1338+
hiddenDom.querySelector("input").value = "X";
1339+
hiddenDom.querySelector("input").dispatchEvent(new Event("input"));
1340+
await sleep(waitMsOnDomUpdates);
1341+
hiddenDom.querySelector("input").value = "Xi";
1342+
hiddenDom.querySelector("input").dispatchEvent(new Event("input"));
1343+
await sleep(waitMsOnDomUpdates);
1344+
hiddenDom.querySelector("input").value = "Xin";
1345+
hiddenDom.querySelector("input").dispatchEvent(new Event("input"));
1346+
await sleep(waitMsOnDomUpdates);
1347+
await sleep(waitMsOnDomUpdates);
1348+
assertEq(hiddenDom.innerHTML, '<p>Your name is: <input type="text"></p><div><p>Hello <b>Xin</b></p><p><i>The &lt;p&gt; element has been rendered 8 time(s).</i></p></div><div><p>Hello <b>Xin</b></p><p><i>The &lt;p&gt; element has been rendered 4 time(s).</i></p></div>');
1349+
})
13031350
};
13041351
const gcTests = {
13051352
bindingBasic: withHiddenDom(async (hiddenDom) => {
13061353
const counter = van2.state(0);
13071354
const bindingsPropKey = Object.entries(counter).find(([_, v]) => Array.isArray(v))[0];
13081355
van2.add(hiddenDom, () => span(`Counter: ${counter.val}`));
1309-
for (let i = 0; i < 100; ++i)
1356+
for (let i2 = 0; i2 < 100; ++i2)
13101357
++counter.val;
13111358
await sleep(waitMsOnDomUpdates);
13121359
assertEq(hiddenDom.innerHTML, "<span>Counter: 100</span>");
@@ -1317,7 +1364,7 @@
13171364
const bindingsPropKey = Object.entries(renderPre).find(([_, v]) => Array.isArray(v))[0];
13181365
const dom = div2(() => (renderPre.val ? pre : div2)(() => `--${text.val}--`));
13191366
van2.add(hiddenDom, dom);
1320-
for (let i = 0; i < 20; ++i) {
1367+
for (let i2 = 0; i2 < 20; ++i2) {
13211368
renderPre.val = !renderPre.val;
13221369
await sleep(waitMsOnDomUpdates);
13231370
}
@@ -1332,7 +1379,7 @@
13321379
const dom = div2(() => cond.val ? a2.val + b2.val : c.val + d.val);
13331380
van2.add(hiddenDom, dom);
13341381
const allStates = [cond, a2, b2, c, d];
1335-
for (let i = 0; i < 100; ++i) {
1382+
for (let i2 = 0; i2 < 100; ++i2) {
13361383
const randomState = allStates[Math.floor(Math.random() * allStates.length)];
13371384
if (randomState === cond)
13381385
randomState.val = !randomState.val;
@@ -1349,7 +1396,7 @@
13491396
const a2 = van2.state(0);
13501397
const listenersPropKey = Object.entries(a2).filter(([_, v]) => Array.isArray(v))[1][0];
13511398
van2.derive(() => history.push(a2.val));
1352-
for (let i = 0; i < 100; ++i)
1399+
for (let i2 = 0; i2 < 100; ++i2)
13531400
++a2.val;
13541401
assertEq(history.length, 101);
13551402
assertBetween(a2[listenersPropKey].length, 1, 3);
@@ -1363,7 +1410,7 @@
13631410
return (renderPre.val ? pre : div2)(() => `--${text.val}--`);
13641411
});
13651412
van2.add(hiddenDom, dom);
1366-
for (let i = 0; i < 20; ++i) {
1413+
for (let i2 = 0; i2 < 20; ++i2) {
13671414
renderPre.val = !renderPre.val;
13681415
await sleep(waitMsOnDomUpdates);
13691416
}
@@ -1377,7 +1424,7 @@
13771424
const listenersPropKey = Object.entries(renderPre).filter(([_, v]) => Array.isArray(v))[1][0];
13781425
const dom = div2(() => (renderPre.val ? pre : div2)({ class: () => class1.val ? "class1" : "class2" }, "Text"));
13791426
van2.add(hiddenDom, dom);
1380-
for (let i = 0; i < 20; ++i) {
1427+
for (let i2 = 0; i2 < 20; ++i2) {
13811428
renderPre.val = !renderPre.val;
13821429
await sleep(waitMsOnDomUpdates);
13831430
}
@@ -1393,7 +1440,7 @@
13931440
oncustom: van2.derive(() => handlerType.val === 1 ? () => van2.add(hiddenDom, p("Handler 1 triggered!")) : () => van2.add(hiddenDom, p("Handler 2 triggered!")))
13941441
})));
13951442
van2.add(hiddenDom, dom);
1396-
for (let i = 0; i < 20; ++i) {
1443+
for (let i2 = 0; i2 < 20; ++i2) {
13971444
renderPre.val = !renderPre.val;
13981445
await sleep(waitMsOnDomUpdates);
13991446
}
@@ -1407,7 +1454,7 @@
14071454
const listenersPropKey = Object.entries(a2).filter(([_, v]) => Array.isArray(v))[1][0];
14081455
van2.derive(() => cond.val ? a2.val + b2.val : c.val + d.val);
14091456
const allStates = [cond, a2, b2, c, d];
1410-
for (let i = 0; i < 100; ++i) {
1457+
for (let i2 = 0; i2 < 100; ++i2) {
14111458
const randomState = allStates[Math.floor(Math.random() * allStates.length)];
14121459
if (randomState === cond)
14131460
randomState.val = !randomState.val;

0 commit comments

Comments
 (0)