q-component q-test-accumulator { q-property manifest: q-map { } q-property results: q-map { } q-property manualStatus: q-map { } q-signal refreshRequested() q-signal resultReported(testNo, value) q-signal expectedReported(testNo, expectedList) q-signal passingReported(testNo, isPassing) q-signal outcomeReported(testNo, isPassing, value) function normalize(v) { return String(v == null ? "" : v).replace(/\s+/g, " ").trim(); } function mapKeys(store) { if (store && typeof store.keys === "function") { return store.keys(); } return []; } function mapGet(store, key) { if (store && typeof store.value === "function") { return store.value(key); } return undefined; } function ensureModelStore(targetProp) { var store = this.component[targetProp]; if (store && typeof store.set === "function" && typeof store.value === "function" && typeof store.keys === "function") { return store; } var seed = {}; if (store && typeof store === "object") { var keys = Object.keys(store); for (var i = 0; i < keys.length; i += 1) { seed[keys[i]] = store[keys[i]]; } } this.component[targetProp] = QModel(seed); return this.component[targetProp]; } function mapSet(targetProp, key, value) { var store = this.component.ensureModelStore(targetProp); store.set(key, value); } function doneMarkerState(testNo) { var key = String(testNo || ""); var host = document.querySelector("#host-t" + key); if (!host) { return "none"; } var doneNode = host.querySelector("#t" + key + "-done"); if (!doneNode) { return "none"; } var token = String(doneNode.textContent == null ? "" : doneNode.textContent).trim().toLowerCase(); if (token === "1" || token === "true" || token === "done" || token === "ok" || token === "pass") { return "done"; } return "pending"; } function bootstrapManifest() { var cards = document.querySelectorAll(".test-card"); var data = {}; for (var i = 0; i < cards.length; i += 1) { var card = cards[i]; var cardId = String(card.getAttribute("id") || ""); if (cardId.indexOf("card-") !== 0) { continue; } var key = cardId.slice(5); if (!key) { continue; } var titleNode = card.querySelector(".test-head h2"); var rawTitle = titleNode ? String(titleNode.textContent || "") : ("Test " + key); var title = rawTitle.replace(/^\s*\d+\.\s*/, ""); var expectedNode = card.querySelector(".test-expected"); var expectedText = expectedNode ? String(expectedNode.textContent || "") : ""; expectedText = expectedText.replace(/^Expected:\s*/i, "").trim(); var expected = []; if (expectedText) { expected = expectedText.split("|").map(function(part) { return String(part || "").trim(); }).filter(function(part) { return part.length > 0; }); } var deprecated = expected.length === 1 && expected[0].toLowerCase() === "test has been deprecated"; data[key] = { title: title, expected: expected, deprecated: deprecated }; } this.component.manifest = QModel(data); } function ensureManifest() { var manifest = this.component.ensureModelStore("manifest"); var currentKeys = this.component.mapKeys(manifest); var cardCount = document.querySelectorAll(".test-card[id^='card-']").length; if (currentKeys.length === 0 || cardCount > currentKeys.length) { this.component.bootstrapManifest(); } } function setExpected(testNo, expectedList) { var key = String(testNo); var entry = this.component.mapGet(this.component.manifest, key) || {}; if (!entry || typeof entry !== "object") { entry = {}; } entry.expected = Array.isArray(expectedList) ? expectedList.slice() : [String(expectedList || "")]; this.component.mapSet("manifest", key, entry); } function setResult(testNo, value) { this.component.mapSet("results", String(testNo), String(value == null ? "" : value)); } function setPassing(testNo, isPassing) { var key = String(testNo); var value = isPassing ? "pass" : "fail"; this.component.mapSet("manualStatus", key, value); } function report(testNo, isPassing, value) { this.component.setPassing(testNo, isPassing); if (value !== undefined) { this.component.setResult(testNo, value); } this.component.showResults(); } function evaluateOne(testNo) { var key = String(testNo); var entry = this.component.mapGet(this.component.manifest, key) || {}; var expected = Array.isArray(entry.expected) ? entry.expected : []; var deprecated = entry.deprecated === true; var title = String(entry.title || ""); var actual = String(this.component.mapGet(this.component.results, key) || ""); var manual = this.component.ensureModelStore("manualStatus"); var status = ""; var hasResult = false; hasResult = this.component.mapKeys(this.component.ensureModelStore("results")).indexOf(key) >= 0; status = this.component.mapGet(manual, key); if (status !== "pass" && status !== "fail" && status !== "deprecated" && deprecated) { status = "deprecated"; } if (status !== "pass" && status !== "fail" && status !== "deprecated") { status = hasResult ? "pass" : "pending"; } var doneState = this.component.doneMarkerState(key); if (status !== "pass" && status !== "fail" && status !== "deprecated" && doneState === "pending") { status = "pending"; } if (status === "pass" && doneState === "pending") { status = "pending"; } if (status === "pass" && !deprecated) { var normalizedActual = this.component.normalize(actual); for (var i = 0; i < expected.length; i += 1) { var token = this.component.normalize(expected[i]); if (token && normalizedActual.indexOf(token) < 0) { status = "fail"; break; } } } var badge = document.querySelector("#badge-" + key); if (badge) { badge.className = "badge " + status; badge.textContent = status; } return { key: key, title: title, status: status, actual: actual, expected: expected }; } function evaluateAll() { var hosts = document.querySelectorAll("q-html[data-test-no]"); for (var i = 0; i < hosts.length; i += 1) { var host = hosts[i]; var no = String(host.getAttribute("data-test-no") || ""); if (!no) { continue; } this.component.setResult(no, host.innerHTML); } this.component.showResults(); } function refresh() { this.component.evaluateAll(); } function showResults() { this.component.ensureManifest(); var keys = this.component.mapKeys(this.component.manifest); var passed = 0; var failed = 0; var pending = 0; var lines = []; for (var i = 0; i < keys.length; i += 1) { var rec = this.component.evaluateOne(keys[i]); if (rec.status === "pass") { passed += 1; } if (rec.status === "fail") { failed += 1; lines.push(rec.key + ". " + rec.title + "\n expected: " + rec.expected.join(" | ") + "\n actual: " + this.component.normalize(rec.actual)); } if (rec.status !== "pass" && rec.status !== "fail") { pending += 1; } } document.querySelector("#sum-pass").textContent = "Passes: " + String(passed); document.querySelector("#sum-fail").textContent = "Failures: " + String(failed); document.querySelector("#sum-pending").textContent = "Pending: " + String(pending); document.querySelector("#failed-list").textContent = lines.length > 0 ? lines.join("\n\n") : "none"; } onrefreshRequested { this.component.refresh(); } onresultReported { var p = event && event.detail && event.detail.params ? event.detail.params : {}; this.component.setResult(p.testNo, p.value); this.component.showResults(); } onexpectedReported { var p = event && event.detail && event.detail.params ? event.detail.params : {}; this.component.setExpected(p.testNo, p.expectedList); this.component.showResults(); } onpassingReported { var p = event && event.detail && event.detail.params ? event.detail.params : {}; this.component.setPassing(p.testNo, p.isPassing); this.component.showResults(); } onoutcomeReported { var p = event && event.detail && event.detail.params ? event.detail.params : {}; this.component.report(p.testNo, p.isPassing, p.value); } onReady { try { if (!this.component) { return; } if (typeof this.component.bootstrapManifest === "function") { this.component.bootstrapManifest(); } if (typeof this.refreshRequested === "function") { this.refreshRequested(); } else if (typeof this.component.refresh === "function") { this.component.refresh(); } setTimeout(function() { try { if (this.component && typeof this.component.refresh === "function") { this.component.refresh(); } } catch (err1) { console.warn("accumulator delayed refresh(250) failed", err1); } }.bind(this), 250); setTimeout(function() { try { if (this.component && typeof this.component.refresh === "function") { this.component.refresh(); } } catch (err2) { console.warn("accumulator delayed refresh(1000) failed", err2); } }.bind(this), 1000); } catch (err) { console.warn("accumulator onReady failed", err); } } div.panel { div.summary { span#sum-fail.fail { text { Failures: 0 } } span#sum-pending.pending { text { Pending: 0 } } span#sum-pass.pass { text { Passes: 0 } } } div.actions { button#btn-refresh { type: "button" onclick { var acc = document.querySelector("#acc-main"); if (!acc) { return; } if (typeof acc.refreshRequested === "function") { acc.refreshRequested(); } } text { Refresh } } button#btn-copy { type: "button" onclick { var txt = document.querySelector("#failed-list").textContent; if (navigator.clipboard && typeof navigator.clipboard.writeText === "function") { navigator.clipboard.writeText(txt); } } text { Copy Failures } } button#btn-loop { type: "button" onclick { QHtml.printEventLoopSnapshot({ limit: 80, includePayload: false }); } text { Print Event Loop } } } pre#failed-list { text { none } } } } q-test-accumulator#acc-main { } q-timer accRefreshTimer { interval: 5000 repeat: true running: false ontimeout { var acc = document.querySelector("#acc-main"); if (!acc) { return; } if (typeof acc.refreshRequested === "function") { acc.refreshRequested(); } } }

Basic Syntax and Keywords

section
Includes: tests 1, 2, 3, 5, 6, 7, 8, 9, 13, 16, 17, 19, 20, 21, 22, 23, 24, 27, 28, 31, 32, 33, 34, 35, 36, 37, 38, 40, 44, 45, 46, 79, 80, 81, 82, 83, 93, 94, 95, 96, 97, 98, 104, 105, 106, 107, 108, 109, 110, 112, 113, 114, 115, 116
Core syntax, text/html/script blocks, macros, q-keyword, q-model, qdom helpers, for loops, q-callback, and scoped reference basics. Back to test index.

1. Braces + text block

pending
Expected: hello-world
div { text { hello-world } } onready { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(1, this.innerHTML); } }

2. Selector chain + shorthand

pending
Expected: <h2 id="id2">hello world</h2>
div#my-id.my-class,span.my-class,h2#id2 { hello world } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(2, this.innerHTML); } }

3. Attributes

pending
Expected: href="https://example.com" | Open Example
a { href: "https://example.com" target: "_blank" text { Open Example } } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(3, this.innerHTML); } }

5. HTML block

pending
Expected: <strong>Real HTML fragment</strong>
div { html { Real HTML fragment } } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(5, this.innerHTML); } }

6. q-bind test

pending
Expected: test has been deprecated
div { text { test has been deprecated } } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(6, this.innerHTML); } }

7. q-script inline replacement

pending
Expected: Inserted by q-script
div { q-script { return "p { text { Inserted by q-script } }"; } } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(7, this.innerHTML); } }

8. q-script assignment form

pending
Expected: data-note="n:5" | script-inline
div { data-note: q-script { return "n:" + (4 + 1) } text { q-script { return "script-inline"; } } } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(8, this.innerHTML); } }

9. q-macro + slot

pending
Expected: hello world | class="badge"
q-macro badge { slot { label } return { span.badge { text { ${this.slot("label")} } } } } div { badge { label { hello world } } } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(9, this.innerHTML); } }

13. q-keyword aliasing

pending
Expected: hello
q-keyword component { q-component } component card-box { div { text { hello } } } card-box { } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(13, this.innerHTML); } }

16. q-bind test

pending
Expected: test has been deprecated
div { text { test has been deprecated } } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(16, this.innerHTML); } }

17. q-bind test

pending
Expected: test has been deprecated
div { text { test has been deprecated } } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(17, this.innerHTML); } }

19. q-array as q-property

pending
Expected: hello world
q-component my-comp { q-property mydivs: q-array { "hello world", 5, q-array { "multi-dimensional", 4 } } div { text { ${this.component.mydivs[0]} } } } my-comp { } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(19, this.innerHTML); } }

20. q-map as q-property

pending
Expected: true
q-component my-comp { q-property settings: q-map { title: "Example" nested: q-map { enabled: true } } div { text { ${this.component.settings.nested.enabled} } } } my-comp { } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(20, this.innerHTML); } }

21. named q-array + q-map reuse

pending
Expected: 2
q-array shared-items { 1, 2, 3 } q-component my-comp { q-property mydivs: shared-items div { text { ${this.component.mydivs[1]} } } } my-comp { } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(21, this.innerHTML); } }

22. property shorthand

pending
Expected: shorthand-ok
q-component short-prop { property label: "shorthand-ok" div { text { ${this.component.label} } } } short-prop { } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(22, this.innerHTML); } }

23. q-model basics

pending
Expected: >3<
q-model my-model { q-array { 5, 10 } } div#model-count { text { pending } } onReady { var model = this["my-model"]; model.add(15); document.querySelector("#model-count").textContent = String(model.count()); } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(23, this.innerHTML); } }

24. q-model-view basics

pending
Expected: 5 | 10 | tom
q-array my-source { 5, 10, q-map { name: "tom" } } q-model-view { q-model { my-source } as { item } div { text { ${item && item.name ? item.name : item} } } } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(24, this.innerHTML); } }

27. q-signal definition slot payload

pending
Expected: slot-payload-ok
q-signal dataReady { slot { value } } div#t27-out { text { waiting } } div#t27-carrier { onDaTaReAdY { $("#t27-out").textContent = event.detail.slots.value[0]; } dataReady { value { slot-payload-ok } } } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(27, this.innerHTML); } }

28. q-rewrite template-style

pending
Expected: rewrite-ok | <strong>
q-rewrite make-strong { slot { input } return { strong { q-script { return String(this.slot("input")); } } } } div { make-strong { rewrite-ok } } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(28, this.innerHTML); } }

31. qdom serialize + deserialize style flow

pending
Expected: one
div#ser { text { one } } div#out { text { pending } } onReady { var s = this.qdom().find("#ser").serialize(); this.qdom().find("#out").replaceWithQHTML(s); this.update(); } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(31, this.innerHTML); } }

32. q-template basic

pending
Expected: template badge
q-template badge { span.badge { text { template badge } } } div { badge { } } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(32, this.innerHTML); } }

33. q-macro scoped placeholder

pending
Expected: value=demo-ref
q-macro scoped-label { slot { value } return { p { text { value=${this.slot("value")} } } } } scoped-label { value { demo-ref } } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(33, this.innerHTML); } }

34. q-script returns QHTML

pending
Expected: dynamic-node
q-script { return "div { text { dynamic-node } }"; } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(34, this.innerHTML); } }

35. q-script returns text

pending
Expected: plain-text-node
div { q-script { return "plain-text-node"; } } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(35, this.innerHTML); } }

36. q-array nested access

pending
Expected: nested-a
q-component arr-comp { q-property arr: q-array { "a", "b", q-array { "nested-a", "nested-b" } } div { text { ${this.component.arr[2][0]} } } } arr-comp { } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(36, this.innerHTML); } }

37. q-map nested access

pending
Expected: MapTest - true
q-component map-comp { q-property settings: q-map { title: "MapTest" nested: q-map { enabled: true } } div { text { ${this.component.settings.title} - ${this.component.settings.nested.enabled} } } } map-comp { } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(37, this.innerHTML); } }

38. q-model from q-script source

pending
Expected: 3
q-model my-model { q-array { 1, 2, 3 } } div#mv38 { text { pending } } onReady { var m = this["my-model"]; document.querySelector("#mv38").textContent = String(m.count()); } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(38, this.innerHTML); } }

40. q-bind test

pending
Expected: test has been deprecated
div { text { test has been deprecated } } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(40, this.innerHTML); } }

44. scoped $() selector shortcut

pending
Expected: sender-value
div#sender { text { sender-value } } div#result44 { text { pending } } onReady { $("#result44").textContent = $("#sender").textContent; } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(44, this.innerHTML); } }

45. root onReady hook

pending
Expected: root-ready
onReady { this.setAttribute("data-ready", "1"); } div { text { root-ready } } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(45, this.innerHTML); } }

46. escaped brace in text

pending
Expected: hello world
div { text { hello world } } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(46, this.innerHTML); } }

79. for keyword over q-array component property

pending
Expected: t79-one | t79-two | t79-three
q-component for79 { q-property items: q-array { "one", "two", "three" } ul#t79-list { for (item in this.component.items) { li { text { t79-${item} } } } } } for79 { } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(79, this.innerHTML); } }

80. for keyword over q-component q-property

pending
Expected: t80-aa | t80-bb | t80-cc
q-component forcomp80 { q-property items: q-array { "aa", "bb", "cc" } ul { for (item in this.component.items) { li { text { t80-${item} } } } } } forcomp80 { } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(80, this.innerHTML); } }

81. for keyword over object keys and value lookup

pending
Expected: t81-alpha:A | t81-beta:B
q-component for81 { q-property bag: q-script { return { alpha: "A", beta: "B" } } div#t81-out { for (k in this.component.bag) { span { text { t81-${k}:${this.component.bag[k]} } } } } } for81 { } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(81, this.innerHTML); } }

82. for keyword over function-returned array source

pending
Expected: t82-r1c1 | t82-r1c2 | t82-r2c1 | t82-r2c2
q-component for82 { function rowItems() { return ["r1c1", "r1c2", "r2c1", "r2c2"] } div#t82-out { for (cell in this.component.rowItems()) { span { text { t82-${cell} } } } } } for82 { } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(82, this.innerHTML); } }

83. for keyword with primitive iterable source

pending
Expected: t83-solo
div#t83-out { for (item in "solo") { span { text { t83-${item} } } } } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(83, this.innerHTML); } }

93. QArray JS assignment + mutate fetched model + reassign

pending
Expected: 0|1|2|3|4|5
q-component array93 { q-var arrayname { [0,1,2] } div#t93-out { text { waiting } } function run() { arrayname.push(3); arrayname.push(4); var fetched = arrayname; fetched.push(5); this.component.querySelector("#t93-out").textContent = fetched.join("|"); } onReady { this.component.run(); } } array93#t93-host { } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(93, this.innerHTML); } }

94. q-map JS assignment + mutate fetched model + reassign

pending
Expected: A|B|C|D
q-component map94 { q-var mapname { ({ alpha: "A", beta: "B" }) } div#t94-out { text { waiting } } function run() { var fetched = mapname; fetched.gamma = "C"; fetched.delta = "D"; var obj = fetched; this.querySelector("#t94-out").textContent = String(obj.alpha) + "|" + String(obj.beta) + "|" + String(obj.gamma) + "|" + String(obj.delta); } onReady { this.run(); } } map94#t94-host { } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(94, this.innerHTML); } }

95. q-callback keyword + property reference assignment + lazy execute

pending
Expected: gt
q-callback mycallback95(v1, v2) { if (v1 > v2) { return "gt"; } return "lte"; } q-component mycomp95 { q-property myprop: "" div#t95-out { text { waiting } } } mycomp95#t95-host { myprop: mycallback95 } button#t95-btn { onclick { var host = document.querySelector("#t95-host"); host.querySelector("#t95-out").textContent = String(host.myprop(5, 2)); } text { run } } onReady { document.querySelector("#t95-btn").click(); } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(95, this.innerHTML); } }

96. q-callback preserves creator this.component scope when passed cross-component

pending
Expected: 2 | id="t96-maker-count"
q-component maker96 { q-property count: 0 q-callback bump(step) { this.component.count = Number(this.component.count || 0) + Number(step || 1); return this.component.count; } div#t96-maker-count { text { ${this.component.count} } } } q-component runner96 { q-property cb: "" function run() { var value = this.cb(2); document.querySelector("#t96-run").textContent = String(value); } } maker96#t96-maker { } runner96#t96-runner { } div#t96-run { text { waiting } } onReady { var maker = document.querySelector("#t96-maker"); var runner = document.querySelector("#t96-runner"); runner.cb = maker.bump; runner.run(); } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(96, this.innerHTML); } }

97. QCallback JS constructor assignment works on q-property

pending
Expected: 7
q-component host97 { q-property cb: "" div#t97-out { text { waiting } } function run() { this.cb = QCallback(function(a, b) { return String(Number(a) + Number(b)); }, { creator: this }); this.querySelector("#t97-out").textContent = this.cb(2, 5); } onReady { this.run(); } } host97 { } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(97, this.innerHTML); } }

98. q-callback declarative invocation renders qhtml(...) fragment

pending
Expected: frag-ok | id="t98-frag"
q-callback frag98() { return qhtml("span#t98-frag { text { frag-ok } }"); } div#t98-host { frag98() } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(98, this.innerHTML); } }

104. rootContext property resolves in binding scope

pending
Expected: ctx-ok-104
q-component ctxprobe104 { q-property out: "waiting" onReady { this.component.out = ${appName104}; } div#t104-out { text { ${this.component.out} } } } ctxprobe104#t104-probe { } onReady { if (this.getAttribute("data-t104-init") !== "1") { this.setAttribute("data-t104-init", "1"); QHtml.rootContext.set("appName104", "ctx-ok-104"); this.update(); return; } var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(104, this.innerHTML); } }

105. lexical symbol shadows root context symbol

pending
Expected: lexical-105
q-component item105 { q-property value: "lexical-105" } item105 shadowRef { value: "lexical-105" } div#t105-out { text { ${shadowRef.value} } } onReady { if (this.getAttribute("data-t105-init") !== "1") { this.setAttribute("data-t105-init", "1"); QHtml.rootContext.set("shadowRef", QMap({ value: "root-105" })); this.update(); return; } var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(105, this.innerHTML); } }

106. nested named-instance dot walk

pending
Expected: dotwalk-106
q-component leaf106 { q-property value: "dotwalk-106" } q-component mid106 { leaf106 inner106 { value: "dotwalk-106" } } mid106 outer106 { } div#t106-out { text { ${outer106.inner106.value} } } onReady { var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(106, this.innerHTML); } }

107. unresolved reference diagnostics are deterministic

pending
Expected: diag-ok-107
div#t107-inline { text { missing107 } } div#t107-direct { text { missing107.value } } div#t107-status { text { waiting } } onReady { var inlineNode = this.querySelector("#t107-inline"); var directNode = this.querySelector("#t107-direct"); var statusNode = this.querySelector("#t107-status"); var inlineValue = inlineNode ? String(inlineNode.textContent || "").trim() : ""; var directValue = directNode ? String(directNode.textContent || "").trim() : ""; var ok = inlineValue === "missing107" && directValue === "missing107.value"; statusNode.textContent = ok ? "diag-ok-107" : ("diag-fail-107|" + inlineValue + "|" + directValue); var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(107, this.innerHTML); } }

108. QContext named types scope checks + runtime alias add

pending
Expected: timer-in-scope | timer-out-scope | sibling-in-scope | child-out-scope | ctx108-pass
q-component namedProbe108 { q-property value: "" } q-timer inScopeTimer108 { interval: 120 repeat: true running: false ontimeout { } } namedProbe108 siblingInst108 { value: "sibling-108" } q-component childContainer108 { namedProbe108 childInst108 { value: "child-108" } } q-component contextInputProbe108 { q-property aliases: "" q-property status: "waiting" function readFrame(buttonEl) { if (buttonEl && buttonEl.__qhtmlContextFrame && typeof buttonEl.__qhtmlContextFrame.set === "function") { return buttonEl.__qhtmlContextFrame; } if (this.__qhtmlContextFrame && typeof this.__qhtmlContextFrame.set === "function") { return this.__qhtmlContextFrame; } return null; } function readAliases(frame) { if (!frame || typeof frame.toObject !== "function") { return ""; } var obj = frame.toObject() || {}; return Object.keys(obj).sort().join(","); } function addAlias(buttonEl) { var nameInput = this.querySelector("#t108-name"); var valueInput = this.querySelector("#t108-value"); var aliasName = String(nameInput && nameInput.value || "").trim(); var aliasValue = String(valueInput && valueInput.value || "").trim(); var frame = this.component.readFrame(buttonEl); var ok = false; if (aliasName && frame && typeof frame.set === "function") { frame.set(aliasName, aliasValue); ok = typeof frame.has === "function" && frame.has(aliasName); if (ok && typeof frame.get === "function") { ok = String(frame.get(aliasName) || "") === aliasValue; } } this.component.status = ok ? "ctx108-pass" : "ctx108-fail"; this.component.aliases = this.component.readAliases(frame); var doneNode = this.querySelector("#t108-done"); if (doneNode) { doneNode.textContent = ok ? "1" : "0"; } var acc = document.querySelector("#acc-main"); var host = this.closest("q-html"); if (acc) { acc.outcomeReported(108, ok, host ? host.innerHTML : ""); } } div#t108-ui { input#t108-name { type: "text" value: "ctxAlias108" } input#t108-value { type: "text" value: "ctxValue108" } button#t108-add { type: "button" onclick { this.component.addAlias(this); } text { Add Alias To Button Context } } } div#t108-ctx-status { text { ${this.component.status} } } div#t108-ctx-aliases { text { ${this.component.aliases} } } div#t108-done { text { 0 } } } childContainer108 childContainerInst108 { } contextInputProbe108 ctxProbeInst108 { } div#t108-scope { text { waiting } } div#t108-summary { text { ${ctxProbeInst108.status} | ${ctxProbeInst108.aliases} } } onReady { var timerInScope = (typeof inScopeTimer108 !== "undefined" && typeof inScopeTimer108.start === "function") ? "timer-in-scope" : "timer-miss"; var timerOutScope = (typeof outScopeTimer108 === "undefined") ? "timer-out-scope" : "timer-leak"; var siblingScope = (typeof siblingInst108 !== "undefined" && siblingInst108.value === "sibling-108") ? "sibling-in-scope" : "sibling-miss"; var childScope = (typeof childInst108 === "undefined") ? "child-out-scope" : "child-leak"; var scopeNode = this.querySelector("#t108-scope"); if (scopeNode) { scopeNode.textContent = timerInScope + " | " + timerOutScope + " | " + siblingScope + " | " + childScope; } var acc = document.querySelector("#acc-main"); if (acc) { acc.resultReported(108, this.innerHTML); } }

109. q-connect declarative signal wiring (scope + querySelector)

pending
Expected: scope-connect-109 | qs-connect-109
q-component sender109 { q-signal ping(message) function fire(message) { this.ping(message); } } q-component receiver109 { q-property value: "waiting" function onPing(message) { this.component.value = message; } } sender109 senderScope109 { id: "t109-s1" } receiver109 receiverScope109 { id: "t109-r1" } sender109 senderQuery109 { id: "t109-s2" } receiver109 receiverQuery109 { id: "t109-r2" } q-connect { senderScope109.ping receiverScope109.onPing } q-connect { document.querySelector("#t109-s2").ping document.querySelector("#t109-r2").onPing } div#t109-out1 { text { ${receiverScope109.value} } } div#t109-out2 { text { ${receiverQuery109.value} } } onReady { senderScope109.fire("scope-connect-109"); senderQuery109.fire("qs-connect-109"); var acc = document.querySelector("#acc-main"); var host = this; setTimeout(function() { var out1 = host.querySelector("#t109-out1"); var out2 = host.querySelector("#t109-out2"); if (out1) { out1.textContent = receiverScope109.value; } if (out2) { out2.textContent = receiverQuery109.value; } if (acc && typeof acc.resultReported === "function") { acc.resultReported(109, host.innerHTML); } }, 30); }

110. q-var primitive and function values

pending
Expected: qvar-primitive-110 | qvar-function-110
q-var primitive110 { "qvar-primitive-110" } q-var function110 { function() { return "qvar-function-110"; } } div#t110-primitive { text { ${primitive110} } } div#t110-function { text { ${function110()} } } onReady { var acc = document.querySelector("#acc-main"); if (acc && typeof acc.resultReported === "function") { acc.resultReported(110, this.innerHTML); } }

112. qhtml(q-var) continuation fragment

pending
Expected: qvar-fragment-112 | fragment-tail-112
q-var fragmentHead112 { "div#t112-fragment,section.t112-frag-body {" } qhtml(fragmentHead112) { h3 { text { qvar-fragment-112 } } p { text { fragment-tail-112 } } } onReady { var acc = document.querySelector("#acc-main"); if (acc && typeof acc.resultReported === "function") { acc.resultReported(112, this.innerHTML); } }

113. q-var descends into component context

pending
Expected: parent-qvar-113 | child-qvar-113
q-var parentVar113 { "parent-qvar-113" } q-component qvar-child113 { q-var childVar113 { parentVar113 + " | child-qvar-113" } div#t113-child { text { ${childVar113} } } } qvar-child113 childInst113 { } onReady { var acc = document.querySelector("#acc-main"); if (acc && typeof acc.resultReported === "function") { acc.resultReported(113, this.innerHTML); } }

114. q-theme child q-timer handle resolves in sibling event handler

pending
Expected: theme-timer-click-114 | timer-timeout-114
q-style t114Style { border: 1px solid #b7d8f5 } q-theme t114Theme { #t114-click { t114Style } } t114Theme { q-timer themeTimer114 { interval: 10 repeat: false running: false ontimeout { document.querySelector("#t114-timeout").textContent = "timer-timeout-114"; } } div#t114-click { text { waiting-click } } div#t114-timeout { text { waiting-timeout } } button#t114-btn { onclick { themeTimer114.start(); document.querySelector("#t114-click").textContent = "theme-timer-click-114"; } text { start nested theme timer } } } onReady { var host = this; var btn = host.querySelector("#t114-btn"); if (btn) { btn.click(); } setTimeout(function() { var acc = document.querySelector("#acc-main"); if (acc && typeof acc.resultReported === "function") { acc.resultReported(114, host.innerHTML); } }, 60); }

115. q-theme transparent named-instance context with id shorthand

pending
Expected: theme-context-115 qwerty qwerty | id-ok-115
q-style style115 { color: #000000 } q-theme theme115 { #something115 { style115 } } q-component themeContextComp115 { q-property blah: "asdf" slot { someslot } } div { theme115 { themeContextComp115 somecomp115#something115 { blah: "qwerty" someslot { text { hello world } } } } themeContextComp115 othercomp115 { blah: somecomp115.blah someslot { button#t115-btn { onclick { document.querySelector("#t115-result").textContent = "theme-context-115 " + somecomp115.blah + " " + this.component.blah; } text { click here } } } } } div#t115-result { text { waiting } } div#t115-id { text { waiting } } onReady { var host = this; var btn = host.querySelector("#t115-btn"); if (btn) { btn.click(); } var idNode = host.querySelector("#t115-id"); if (idNode) { idNode.textContent = host.querySelector("#something115") ? "id-ok-115" : "id-missing-115"; } var acc = document.querySelector("#acc-main"); if (acc && typeof acc.resultReported === "function") { acc.resultReported(115, host.innerHTML); } }

116. q-switch primitive lookup and dynamic qhtml

pending
Expected: hello world | 32 | default-116 | 0 | qswitch-fragment-116 | component=32 | hello world click
q-switch lookup116 { 15: { "hello world" } "test": { 32 } "zero": { 0 } *: { "default-116" } } q-switch qhtmlswitch116 { "item1": { "span#t116-frag { text { qswitch-fragment-116 } }" } *: { "" } } q-component switchComp116 { q-property key: "test" div#t116-component { text { component=${lookup116(this.component.key)} } } } div#t116-values { text { ${lookup116(15)} | ${lookup116("test")} | ${lookup116("missing")} | ${lookup116("zero")} } } qhtml(qhtmlswitch116("item1")) switchComp116 comp116 { } div#t116-click { text { waiting } } button#t116-btn { onclick { document.querySelector("#t116-click").textContent = lookup116(15) + " click"; } text { run q-switch } } onReady { var host = this; var btn = host.querySelector("#t116-btn"); if (btn) { btn.click(); } var acc = document.querySelector("#acc-main"); if (acc && typeof acc.resultReported === "function") { acc.resultReported(116, host.innerHTML); } }

123. q-anchor css-anchor-first positioning

pending
Expected: anchor-ref-123 | anchor-target-123 | anchor-center-123
q-component anchorbox123 { div { text { ${this.component.label} } } } q-style stage123style { position: relative; width: 420px; height: 230px; background: #0f172a; overflow: hidden; border: 1px solid #334155; } q-style a123style { position: absolute; left: 100px; top: 100px; width: 140px; height: 44px; background: #0284c7; color: #e2e8f0; display: flex; align-items: center; justify-content: center; font-size: 12px; } q-style b123style { position: absolute; width: 130px; height: 36px; background: #16a34a; color: white; display: flex; align-items: center; justify-content: center; font-size: 12px; } q-style c123style { position: absolute; width: 120px; height: 34px; background: #f59e0b; color: #111827; display: flex; align-items: center; justify-content: center; font-size: 12px; } q-theme anchor123theme { #anchor-stage-123 { stage123style } #anchor-a-123 { a123style } #anchor-b-123 { b123style } #anchor-c-123 { c123style } } anchor123theme { div#anchor-stage-123 { anchorbox123 anchorA123#anchor-a-123 { label: "anchor-ref-123" } anchorbox123 anchorB123#anchor-b-123 { label: "anchor-target-123" q-anchor-left { anchorA123.right } q-anchor-top { anchorA123.bottom } } anchorbox123 anchorC123#anchor-c-123 { label: "anchor-center-123" q-anchor { left: anchorB123.right; top: anchorB123.bottom } } } } onReady { var acc = document.querySelector("#acc-main"); if (acc && typeof acc.resultReported === "function") { acc.resultReported(123, this.innerHTML); } }