@microsoft/fast-test-harness 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -18
- package/dist/dts/build/generate-templates.d.ts +35 -0
- package/dist/dts/build/generate-templates.d.ts.map +1 -1
- package/dist/dts/build/generate-webui-templates.d.ts +13 -0
- package/dist/dts/build/generate-webui-templates.d.ts.map +1 -1
- package/dist/dts/fixtures/csr-fixture.d.ts +28 -0
- package/dist/dts/fixtures/csr-fixture.d.ts.map +1 -1
- package/dist/dts/fixtures/ssr-fixture.d.ts +19 -0
- package/dist/dts/fixtures/ssr-fixture.d.ts.map +1 -1
- package/dist/dts/ssr/render.d.ts.map +1 -1
- package/dist/esm/build/generate-templates.js +61 -1
- package/dist/esm/build/generate-webui-templates.js +8 -25
- package/dist/esm/fixtures/ssr-fixture.js +19 -1
- package/dist/esm/ssr/render.js +38 -5
- package/package.json +26 -15
- package/dist/dts/build/dom-shim.test.d.ts +0 -2
- package/dist/dts/build/dom-shim.test.d.ts.map +0 -1
- package/dist/dts/build/generate-stylesheets.test.d.ts +0 -2
- package/dist/dts/build/generate-stylesheets.test.d.ts.map +0 -1
- package/dist/dts/build/generate-templates.test.d.ts +0 -2
- package/dist/dts/build/generate-templates.test.d.ts.map +0 -1
- package/dist/dts/build/generate-webui-templates.test.d.ts +0 -2
- package/dist/dts/build/generate-webui-templates.test.d.ts.map +0 -1
- package/dist/dts/fixtures/csr-fixture.pw.spec.d.ts +0 -2
- package/dist/dts/fixtures/csr-fixture.pw.spec.d.ts.map +0 -1
- package/dist/dts/fixtures/ssr-fixture.pw.spec.d.ts +0 -2
- package/dist/dts/fixtures/ssr-fixture.pw.spec.d.ts.map +0 -1
- package/dist/dts/ssr/render.test.d.ts +0 -2
- package/dist/dts/ssr/render.test.d.ts.map +0 -1
- package/dist/esm/build/dom-shim.test.js +0 -202
- package/dist/esm/build/generate-stylesheets.test.js +0 -74
- package/dist/esm/build/generate-templates.test.js +0 -231
- package/dist/esm/build/generate-webui-templates.test.js +0 -179
- package/dist/esm/fixtures/csr-fixture.pw.spec.js +0 -137
- package/dist/esm/fixtures/ssr-fixture.pw.spec.js +0 -189
- package/dist/esm/ssr/render.test.js +0 -236
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ssr-fixture.pw.spec.d.ts","sourceRoot":"","sources":["../../../src/fixtures/ssr-fixture.pw.spec.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"render.test.d.ts","sourceRoot":"","sources":["../../../src/ssr/render.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,202 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert/strict";
|
|
2
|
-
import { test } from "node:test";
|
|
3
|
-
// Each test needs a clean globalThis, so we tear down the shim between tests.
|
|
4
|
-
function teardownShim() {
|
|
5
|
-
for (const key of [
|
|
6
|
-
"Node",
|
|
7
|
-
"Element",
|
|
8
|
-
"HTMLElement",
|
|
9
|
-
"Document",
|
|
10
|
-
"CustomEvent",
|
|
11
|
-
"CSSStyleSheet",
|
|
12
|
-
"ShadowRoot",
|
|
13
|
-
"CustomElementRegistry",
|
|
14
|
-
"MutationObserver",
|
|
15
|
-
"MediaQueryList",
|
|
16
|
-
"matchMedia",
|
|
17
|
-
"document",
|
|
18
|
-
"customElements",
|
|
19
|
-
"window",
|
|
20
|
-
"CSS",
|
|
21
|
-
]) {
|
|
22
|
-
delete globalThis[key];
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
test.describe("installDomShim", () => {
|
|
26
|
-
test.beforeEach(() => {
|
|
27
|
-
teardownShim();
|
|
28
|
-
});
|
|
29
|
-
async function loadShim() {
|
|
30
|
-
// Dynamic import so each test gets a fresh evaluation context
|
|
31
|
-
// after globalThis is cleaned.
|
|
32
|
-
const { installDomShim } = await import("@microsoft/fast-test-harness/build/dom-shim.js");
|
|
33
|
-
installDomShim();
|
|
34
|
-
}
|
|
35
|
-
test("should assign globals on first call", async () => {
|
|
36
|
-
await loadShim();
|
|
37
|
-
assert.ok(globalThis.window !== undefined);
|
|
38
|
-
assert.ok(globalThis.document !== undefined);
|
|
39
|
-
assert.ok(globalThis.customElements !== undefined);
|
|
40
|
-
assert.ok(globalThis.Node !== undefined);
|
|
41
|
-
assert.ok(globalThis.Element !== undefined);
|
|
42
|
-
assert.ok(globalThis.HTMLElement !== undefined);
|
|
43
|
-
assert.ok(globalThis.CSSStyleSheet !== undefined);
|
|
44
|
-
assert.ok(globalThis.MutationObserver !== undefined);
|
|
45
|
-
assert.ok(globalThis.matchMedia !== undefined);
|
|
46
|
-
});
|
|
47
|
-
test("should be idempotent when window is already defined", async () => {
|
|
48
|
-
const sentinel = { __sentinel: true };
|
|
49
|
-
globalThis.window = sentinel;
|
|
50
|
-
await loadShim();
|
|
51
|
-
assert.strictEqual(globalThis.window, sentinel);
|
|
52
|
-
assert.strictEqual(globalThis.document, undefined);
|
|
53
|
-
});
|
|
54
|
-
test("should set window to globalThis", async () => {
|
|
55
|
-
await loadShim();
|
|
56
|
-
assert.strictEqual(globalThis.window, globalThis);
|
|
57
|
-
});
|
|
58
|
-
test("should provide CSS.supports that returns true", async () => {
|
|
59
|
-
await loadShim();
|
|
60
|
-
assert.strictEqual(globalThis.CSS.supports("display", "flex"), true);
|
|
61
|
-
});
|
|
62
|
-
test("should not overwrite an existing CSS global", async () => {
|
|
63
|
-
const existing = { supports: () => false };
|
|
64
|
-
globalThis.CSS = existing;
|
|
65
|
-
await loadShim();
|
|
66
|
-
assert.strictEqual(globalThis.CSS, existing);
|
|
67
|
-
});
|
|
68
|
-
});
|
|
69
|
-
test.describe("ShimHTMLElement", () => {
|
|
70
|
-
test.beforeEach(async () => {
|
|
71
|
-
teardownShim();
|
|
72
|
-
const { installDomShim } = await import("@microsoft/fast-test-harness/build/dom-shim.js");
|
|
73
|
-
installDomShim();
|
|
74
|
-
});
|
|
75
|
-
test("should support setAttribute / getAttribute / hasAttribute", () => {
|
|
76
|
-
const el = new globalThis.HTMLElement();
|
|
77
|
-
assert.strictEqual(el.hasAttribute("id"), false);
|
|
78
|
-
assert.strictEqual(el.getAttribute("id"), null);
|
|
79
|
-
el.setAttribute("id", "test");
|
|
80
|
-
assert.strictEqual(el.hasAttribute("id"), true);
|
|
81
|
-
assert.strictEqual(el.getAttribute("id"), "test");
|
|
82
|
-
});
|
|
83
|
-
test("should support removeAttribute", () => {
|
|
84
|
-
const el = new globalThis.HTMLElement();
|
|
85
|
-
el.setAttribute("class", "foo");
|
|
86
|
-
assert.strictEqual(el.hasAttribute("class"), true);
|
|
87
|
-
el.removeAttribute("class");
|
|
88
|
-
assert.strictEqual(el.hasAttribute("class"), false);
|
|
89
|
-
assert.strictEqual(el.getAttribute("class"), null);
|
|
90
|
-
});
|
|
91
|
-
test("should return attributes as an array of {name, value}", () => {
|
|
92
|
-
const el = new globalThis.HTMLElement();
|
|
93
|
-
el.setAttribute("role", "button");
|
|
94
|
-
el.setAttribute("aria-label", "Close");
|
|
95
|
-
const attrs = el.attributes;
|
|
96
|
-
assert.strictEqual(attrs.length, 2);
|
|
97
|
-
assert.deepStrictEqual(attrs.map((a) => a.name).sort(), [
|
|
98
|
-
"aria-label",
|
|
99
|
-
"role",
|
|
100
|
-
]);
|
|
101
|
-
});
|
|
102
|
-
test("should support attachShadow with open mode", () => {
|
|
103
|
-
const el = new globalThis.HTMLElement();
|
|
104
|
-
const sr = el.attachShadow({ mode: "open" });
|
|
105
|
-
assert.ok(sr);
|
|
106
|
-
assert.strictEqual(sr.host, el);
|
|
107
|
-
assert.strictEqual(el.shadowRoot, sr);
|
|
108
|
-
});
|
|
109
|
-
test("should not expose shadowRoot for closed mode", () => {
|
|
110
|
-
const el = new globalThis.HTMLElement();
|
|
111
|
-
el.attachShadow({ mode: "closed" });
|
|
112
|
-
assert.strictEqual(el.shadowRoot, null);
|
|
113
|
-
});
|
|
114
|
-
test("should provide a classList stub", () => {
|
|
115
|
-
const el = new globalThis.HTMLElement();
|
|
116
|
-
const cl = el.classList;
|
|
117
|
-
assert.strictEqual(cl.contains("foo"), false);
|
|
118
|
-
// Should not throw
|
|
119
|
-
cl.add("foo");
|
|
120
|
-
cl.remove("foo");
|
|
121
|
-
cl.toggle("foo");
|
|
122
|
-
});
|
|
123
|
-
});
|
|
124
|
-
test.describe("ShimCSSStyleSheet", () => {
|
|
125
|
-
test.beforeEach(async () => {
|
|
126
|
-
teardownShim();
|
|
127
|
-
const { installDomShim } = await import("@microsoft/fast-test-harness/build/dom-shim.js");
|
|
128
|
-
installDomShim();
|
|
129
|
-
});
|
|
130
|
-
test("should support insertRule", () => {
|
|
131
|
-
const sheet = new globalThis.CSSStyleSheet();
|
|
132
|
-
const idx = sheet.insertRule(".foo { color: red }", 0);
|
|
133
|
-
assert.strictEqual(idx, 0);
|
|
134
|
-
assert.strictEqual(sheet.cssRules.length, 1);
|
|
135
|
-
assert.strictEqual(sheet.cssRules[0].selectorText, ".foo ");
|
|
136
|
-
});
|
|
137
|
-
});
|
|
138
|
-
test.describe("ShimCustomElementRegistry", () => {
|
|
139
|
-
test.beforeEach(async () => {
|
|
140
|
-
teardownShim();
|
|
141
|
-
const { installDomShim } = await import("@microsoft/fast-test-harness/build/dom-shim.js");
|
|
142
|
-
installDomShim();
|
|
143
|
-
});
|
|
144
|
-
test("should support define and get", () => {
|
|
145
|
-
class MyEl {
|
|
146
|
-
}
|
|
147
|
-
globalThis.customElements.define("my-el", MyEl);
|
|
148
|
-
assert.strictEqual(globalThis.customElements.get("my-el"), MyEl);
|
|
149
|
-
});
|
|
150
|
-
test("should return undefined for unknown elements", () => {
|
|
151
|
-
assert.strictEqual(globalThis.customElements.get("unknown-el"), undefined);
|
|
152
|
-
});
|
|
153
|
-
test("should resolve whenDefined immediately", async () => {
|
|
154
|
-
const result = await globalThis.customElements.whenDefined("any-el");
|
|
155
|
-
assert.strictEqual(result, undefined);
|
|
156
|
-
});
|
|
157
|
-
});
|
|
158
|
-
test.describe("ShimDocument", () => {
|
|
159
|
-
test.beforeEach(async () => {
|
|
160
|
-
teardownShim();
|
|
161
|
-
const { installDomShim } = await import("@microsoft/fast-test-harness/build/dom-shim.js");
|
|
162
|
-
installDomShim();
|
|
163
|
-
});
|
|
164
|
-
test("should create elements via createElement", () => {
|
|
165
|
-
const el = globalThis.document.createElement("div");
|
|
166
|
-
assert.ok(el);
|
|
167
|
-
assert.strictEqual(typeof el.setAttribute, "function");
|
|
168
|
-
});
|
|
169
|
-
test("should support adoptedStyleSheets", () => {
|
|
170
|
-
assert.ok(Array.isArray(globalThis.document.adoptedStyleSheets));
|
|
171
|
-
});
|
|
172
|
-
});
|
|
173
|
-
test.describe("ShimCustomEvent", () => {
|
|
174
|
-
test.beforeEach(async () => {
|
|
175
|
-
teardownShim();
|
|
176
|
-
const { installDomShim } = await import("@microsoft/fast-test-harness/build/dom-shim.js");
|
|
177
|
-
installDomShim();
|
|
178
|
-
});
|
|
179
|
-
test("should carry detail", () => {
|
|
180
|
-
const evt = new globalThis.CustomEvent("test", { detail: 42 });
|
|
181
|
-
assert.strictEqual(evt.detail, 42);
|
|
182
|
-
assert.strictEqual(evt.type, "test");
|
|
183
|
-
});
|
|
184
|
-
test("should default detail to null", () => {
|
|
185
|
-
const evt = new globalThis.CustomEvent("test");
|
|
186
|
-
assert.strictEqual(evt.detail, null);
|
|
187
|
-
});
|
|
188
|
-
});
|
|
189
|
-
test.describe("matchMedia", () => {
|
|
190
|
-
test.beforeEach(async () => {
|
|
191
|
-
teardownShim();
|
|
192
|
-
const { installDomShim } = await import("@microsoft/fast-test-harness/build/dom-shim.js");
|
|
193
|
-
installDomShim();
|
|
194
|
-
});
|
|
195
|
-
test("should return a MediaQueryList with matches = false", () => {
|
|
196
|
-
const mql = globalThis.matchMedia("(prefers-color-scheme: dark)");
|
|
197
|
-
assert.strictEqual(mql.matches, false);
|
|
198
|
-
// Should not throw
|
|
199
|
-
mql.addEventListener("change", () => { });
|
|
200
|
-
mql.removeEventListener("change", () => { });
|
|
201
|
-
});
|
|
202
|
-
});
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert/strict";
|
|
2
|
-
import { mkdir, mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
|
|
3
|
-
import { tmpdir } from "node:os";
|
|
4
|
-
import { join } from "node:path";
|
|
5
|
-
import { test } from "node:test";
|
|
6
|
-
import { generateStylesheets } from "@microsoft/fast-test-harness/build/generate-stylesheets.js";
|
|
7
|
-
test.describe("generateStylesheets", () => {
|
|
8
|
-
let tempDir;
|
|
9
|
-
test.beforeEach(async () => {
|
|
10
|
-
tempDir = await mkdtemp(join(tmpdir(), "fast-styles-"));
|
|
11
|
-
});
|
|
12
|
-
test.afterEach(async () => {
|
|
13
|
-
await rm(tempDir, { recursive: true, force: true });
|
|
14
|
-
});
|
|
15
|
-
test("should extract CSS from a styles module", async () => {
|
|
16
|
-
const distDir = join(tempDir, "dist");
|
|
17
|
-
await mkdir(distDir, { recursive: true });
|
|
18
|
-
// Write a fake styles module that exports an ElementStyles-like object.
|
|
19
|
-
await writeFile(join(distDir, "button.styles.js"), `export const styles = { styles: [":host { display: block; }", "span { color: red; }"] };`);
|
|
20
|
-
await generateStylesheets({ cwd: tempDir });
|
|
21
|
-
const css = await readFile(join(distDir, "button.styles.css"), "utf8");
|
|
22
|
-
assert.ok(css.includes(":host { display: block; }"));
|
|
23
|
-
assert.ok(css.includes("span { color: red; }"));
|
|
24
|
-
});
|
|
25
|
-
test("should write to outDir when specified", async () => {
|
|
26
|
-
const distDir = join(tempDir, "dist");
|
|
27
|
-
const outDir = join(tempDir, "out");
|
|
28
|
-
await mkdir(distDir, { recursive: true });
|
|
29
|
-
await writeFile(join(distDir, "card.styles.js"), `export const styles = { styles: [".card { padding: 8px; }"] };`);
|
|
30
|
-
await generateStylesheets({ cwd: tempDir, outDir: "out" });
|
|
31
|
-
const css = await readFile(join(outDir, "card.styles.css"), "utf8");
|
|
32
|
-
assert.ok(css.includes(".card { padding: 8px; }"));
|
|
33
|
-
});
|
|
34
|
-
test("should apply a format function", async () => {
|
|
35
|
-
const distDir = join(tempDir, "dist");
|
|
36
|
-
await mkdir(distDir, { recursive: true });
|
|
37
|
-
await writeFile(join(distDir, "link.styles.js"), `export const styles = { styles: ["a { color: blue; }"] };`);
|
|
38
|
-
await generateStylesheets({
|
|
39
|
-
cwd: tempDir,
|
|
40
|
-
format: css => `/* formatted */\n${css}`,
|
|
41
|
-
});
|
|
42
|
-
const css = await readFile(join(distDir, "link.styles.css"), "utf8");
|
|
43
|
-
assert.ok(css.startsWith("/* formatted */"));
|
|
44
|
-
});
|
|
45
|
-
test("should flatten nested styles arrays", async () => {
|
|
46
|
-
const distDir = join(tempDir, "dist");
|
|
47
|
-
await mkdir(distDir, { recursive: true });
|
|
48
|
-
await writeFile(join(distDir, "nested.styles.js"), `export const styles = {
|
|
49
|
-
styles: [
|
|
50
|
-
{ styles: [":host { display: flex; }", "div { margin: 0; }"] },
|
|
51
|
-
"span { font-size: 14px; }"
|
|
52
|
-
]
|
|
53
|
-
};`);
|
|
54
|
-
await generateStylesheets({ cwd: tempDir });
|
|
55
|
-
const css = await readFile(join(distDir, "nested.styles.css"), "utf8");
|
|
56
|
-
assert.ok(css.includes(":host { display: flex; }"));
|
|
57
|
-
assert.ok(css.includes("div { margin: 0; }"));
|
|
58
|
-
assert.ok(css.includes("span { font-size: 14px; }"));
|
|
59
|
-
});
|
|
60
|
-
test("should skip modules without a styles export", async () => {
|
|
61
|
-
const distDir = join(tempDir, "dist");
|
|
62
|
-
await mkdir(distDir, { recursive: true });
|
|
63
|
-
await writeFile(join(distDir, "empty.styles.js"), `export const template = "<div></div>";`);
|
|
64
|
-
await generateStylesheets({ cwd: tempDir });
|
|
65
|
-
// Should not create a CSS file
|
|
66
|
-
try {
|
|
67
|
-
await readFile(join(distDir, "empty.styles.css"), "utf8");
|
|
68
|
-
assert.fail("Should not have created a CSS file");
|
|
69
|
-
}
|
|
70
|
-
catch (err) {
|
|
71
|
-
assert.strictEqual(err.code, "ENOENT");
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
});
|
|
@@ -1,231 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert/strict";
|
|
2
|
-
import { mkdir, mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
|
|
3
|
-
import { tmpdir } from "node:os";
|
|
4
|
-
import { join } from "node:path";
|
|
5
|
-
import { test } from "node:test";
|
|
6
|
-
import { installDomShim } from "@microsoft/fast-test-harness/build/dom-shim.js";
|
|
7
|
-
import { convertTemplate, generateFTemplates, } from "@microsoft/fast-test-harness/build/generate-templates.js";
|
|
8
|
-
import { generateWebuiTemplates } from "@microsoft/fast-test-harness/build/generate-webui-templates.js";
|
|
9
|
-
test.describe("convertTemplate", async () => {
|
|
10
|
-
// Install the DOM shim before any tests — convertTemplate needs fast-html
|
|
11
|
-
// syntax constants which require a DOM environment, and FAST Element needs
|
|
12
|
-
// basic DOM globals to initialize.
|
|
13
|
-
installDomShim();
|
|
14
|
-
// Dynamic import after the DOM shim is installed so FAST Element can
|
|
15
|
-
// access `document`, `CSSStyleSheet`, etc.
|
|
16
|
-
const { html, ref, slotted, children } = await import("@microsoft/fast-element");
|
|
17
|
-
test("should wrap a static template in f-template tags", () => {
|
|
18
|
-
const template = html `<template><div>hello</div></template>`;
|
|
19
|
-
const result = convertTemplate(template, "fast-test");
|
|
20
|
-
assert.ok(result);
|
|
21
|
-
assert.ok(result.includes('<f-template name="fast-test"'));
|
|
22
|
-
assert.ok(result.includes("shadowrootmode"));
|
|
23
|
-
assert.ok(result.includes("<div>hello</div>"));
|
|
24
|
-
assert.ok(result.includes("{{styles}}"));
|
|
25
|
-
});
|
|
26
|
-
test("should return null-safe for empty factories", () => {
|
|
27
|
-
const template = html `<template><span></span></template>`;
|
|
28
|
-
const result = convertTemplate(template, "fast-empty");
|
|
29
|
-
assert.ok(result);
|
|
30
|
-
assert.ok(result.includes("<span></span>"));
|
|
31
|
-
});
|
|
32
|
-
test("should inject {{styles}} after the opening template tag", () => {
|
|
33
|
-
const template = html `<template><p>content</p></template>`;
|
|
34
|
-
const result = convertTemplate(template, "fast-styles");
|
|
35
|
-
assert.ok(result);
|
|
36
|
-
const templateIdx = result.indexOf("<template>");
|
|
37
|
-
const stylesIdx = result.indexOf("{{styles}}");
|
|
38
|
-
assert.ok(stylesIdx > templateIdx, "{{styles}} should appear after <template>");
|
|
39
|
-
});
|
|
40
|
-
test("should convert RefDirective factories to f-ref attributes", () => {
|
|
41
|
-
const template = html `<template><div ${ref("myRef")}></div></template>`;
|
|
42
|
-
const result = convertTemplate(template, "fast-ref");
|
|
43
|
-
assert.ok(result);
|
|
44
|
-
assert.ok(result.includes('f-ref="{myRef}"'), `got: ${result}`);
|
|
45
|
-
});
|
|
46
|
-
test("should convert SlottedDirective factories to f-slotted attributes", () => {
|
|
47
|
-
const template = html `<template><slot ${slotted("slottedItems")}></slot></template>`;
|
|
48
|
-
const result = convertTemplate(template, "fast-slotted");
|
|
49
|
-
assert.ok(result);
|
|
50
|
-
assert.ok(result.includes("f-slotted="), `got: ${result}`);
|
|
51
|
-
assert.ok(result.includes("slottedItems"), `got: ${result}`);
|
|
52
|
-
});
|
|
53
|
-
test("should convert value bindings to {{expression}}", () => {
|
|
54
|
-
const template = html `<template><span>${x => x.label}</span></template>`;
|
|
55
|
-
const result = convertTemplate(template, "fast-binding");
|
|
56
|
-
assert.ok(result);
|
|
57
|
-
assert.ok(result.includes("{{label}}"), `got: ${result}`);
|
|
58
|
-
});
|
|
59
|
-
test("should convert boolean bindings to ?attr expressions", () => {
|
|
60
|
-
const template = html `<template><button ?disabled="${x => x.disabled}"></button></template>`;
|
|
61
|
-
const result = convertTemplate(template, "fast-bool");
|
|
62
|
-
assert.ok(result);
|
|
63
|
-
assert.ok(result.includes('?disabled="{{disabled}}"'), `got: ${result}`);
|
|
64
|
-
});
|
|
65
|
-
test("should inline static sub-templates", () => {
|
|
66
|
-
const template = html `<template><div>${() => "<svg>icon</svg>"}</div></template>`;
|
|
67
|
-
const result = convertTemplate(template, "fast-inline");
|
|
68
|
-
assert.ok(result);
|
|
69
|
-
assert.ok(result.includes("<svg>icon</svg>"), `got: ${result}`);
|
|
70
|
-
});
|
|
71
|
-
test("should convert ChildrenDirective factories to f-children attributes", () => {
|
|
72
|
-
const template = html `<template><div ${children("childItems")}></div></template>`;
|
|
73
|
-
const result = convertTemplate(template, "fast-children");
|
|
74
|
-
assert.ok(result);
|
|
75
|
-
assert.ok(result.includes("f-children="), `got: ${result}`);
|
|
76
|
-
assert.ok(result.includes("childItems"), `got: ${result}`);
|
|
77
|
-
});
|
|
78
|
-
test("should convert event bindings to @event expressions", () => {
|
|
79
|
-
const template = html `<template><button @click="${(x, c) => x.handleClick(c.event)}"></button></template>`;
|
|
80
|
-
const result = convertTemplate(template, "fast-event");
|
|
81
|
-
assert.ok(result);
|
|
82
|
-
assert.ok(result.includes("@click="), `got: ${result}`);
|
|
83
|
-
assert.ok(result.includes("handleClick"), `got: ${result}`);
|
|
84
|
-
});
|
|
85
|
-
test("should convert property bindings to :prop expressions", () => {
|
|
86
|
-
const template = html `<template><input :value="${x => x.currentValue}" /></template>`;
|
|
87
|
-
const result = convertTemplate(template, "fast-prop");
|
|
88
|
-
assert.ok(result);
|
|
89
|
-
assert.ok(result.includes(":value="), `got: ${result}`);
|
|
90
|
-
assert.ok(result.includes("currentValue"), `got: ${result}`);
|
|
91
|
-
});
|
|
92
|
-
test("should handle multiple factories in a single template", () => {
|
|
93
|
-
const template = html `<template><span>${x => x.label}</span><button ?disabled="${x => x.disabled}"></button></template>`;
|
|
94
|
-
const result = convertTemplate(template, "fast-multi");
|
|
95
|
-
assert.ok(result);
|
|
96
|
-
assert.ok(result.includes("{{label}}"), `got: ${result}`);
|
|
97
|
-
assert.ok(result.includes('?disabled="{{disabled}}"'), `got: ${result}`);
|
|
98
|
-
});
|
|
99
|
-
test("should inline a static sub-template ViewTemplate", () => {
|
|
100
|
-
const icon = html `<svg>icon</svg>`;
|
|
101
|
-
const template = html `<template><div>${() => icon}</div></template>`;
|
|
102
|
-
const result = convertTemplate(template, "fast-sub");
|
|
103
|
-
assert.ok(result);
|
|
104
|
-
assert.ok(result.includes("<svg>icon</svg>"), `got: ${result}`);
|
|
105
|
-
});
|
|
106
|
-
});
|
|
107
|
-
test.describe("generateFTemplates", () => {
|
|
108
|
-
let tempDir;
|
|
109
|
-
test.beforeEach(async () => {
|
|
110
|
-
tempDir = await mkdtemp(join(tmpdir(), "fast-ftemplates-"));
|
|
111
|
-
});
|
|
112
|
-
test.afterEach(async () => {
|
|
113
|
-
await rm(tempDir, { recursive: true, force: true });
|
|
114
|
-
});
|
|
115
|
-
test("should generate an f-template HTML file from a template module", async () => {
|
|
116
|
-
const distDir = join(tempDir, "dist");
|
|
117
|
-
await mkdir(distDir, { recursive: true });
|
|
118
|
-
await writeFile(join(distDir, "badge.template.js"), `export const template = {
|
|
119
|
-
html: "<template><slot></slot></template>",
|
|
120
|
-
factories: {}
|
|
121
|
-
};`);
|
|
122
|
-
await generateFTemplates({ cwd: tempDir, tagPrefix: "mai" });
|
|
123
|
-
const html = await readFile(join(distDir, "badge.template.html"), "utf8");
|
|
124
|
-
assert.ok(html.includes('<f-template name="mai-badge"'));
|
|
125
|
-
assert.ok(html.includes("<slot></slot>"));
|
|
126
|
-
assert.ok(html.includes("{{styles}}"));
|
|
127
|
-
});
|
|
128
|
-
test("should write to outDir when specified", async () => {
|
|
129
|
-
const distDir = join(tempDir, "dist");
|
|
130
|
-
await mkdir(distDir, { recursive: true });
|
|
131
|
-
await writeFile(join(distDir, "card.template.js"), `export const template = {
|
|
132
|
-
html: "<template><div>card</div></template>",
|
|
133
|
-
factories: {}
|
|
134
|
-
};`);
|
|
135
|
-
await generateFTemplates({ cwd: tempDir, outDir: "out", tagPrefix: "fast" });
|
|
136
|
-
const html = await readFile(join(tempDir, "out", "card.template.html"), "utf8");
|
|
137
|
-
assert.ok(html.includes('<f-template name="fast-card"'));
|
|
138
|
-
});
|
|
139
|
-
test("should skip modules without a template export", async () => {
|
|
140
|
-
const distDir = join(tempDir, "dist");
|
|
141
|
-
await mkdir(distDir, { recursive: true });
|
|
142
|
-
await writeFile(join(distDir, "empty.template.js"), `export const styles = ":host {}";`);
|
|
143
|
-
await generateFTemplates({ cwd: tempDir, tagPrefix: "fast" });
|
|
144
|
-
try {
|
|
145
|
-
await readFile(join(distDir, "empty.template.html"), "utf8");
|
|
146
|
-
assert.fail("Should not have created an HTML file");
|
|
147
|
-
}
|
|
148
|
-
catch (err) {
|
|
149
|
-
assert.strictEqual(err.code, "ENOENT");
|
|
150
|
-
}
|
|
151
|
-
});
|
|
152
|
-
test("should apply a format function", async () => {
|
|
153
|
-
const distDir = join(tempDir, "dist");
|
|
154
|
-
await mkdir(distDir, { recursive: true });
|
|
155
|
-
await writeFile(join(distDir, "text.template.js"), `export const template = {
|
|
156
|
-
html: "<template><span>text</span></template>",
|
|
157
|
-
factories: {}
|
|
158
|
-
};`);
|
|
159
|
-
await generateFTemplates({
|
|
160
|
-
cwd: tempDir,
|
|
161
|
-
tagPrefix: "fast",
|
|
162
|
-
format: html => `<!-- formatted -->\n${html}`,
|
|
163
|
-
});
|
|
164
|
-
const html = await readFile(join(distDir, "text.template.html"), "utf8");
|
|
165
|
-
assert.ok(html.startsWith("<!-- formatted -->"));
|
|
166
|
-
});
|
|
167
|
-
});
|
|
168
|
-
test.describe("generateWebuiTemplates", () => {
|
|
169
|
-
let tempDir;
|
|
170
|
-
test.beforeEach(async () => {
|
|
171
|
-
tempDir = await mkdtemp(join(tmpdir(), "fast-webui-"));
|
|
172
|
-
});
|
|
173
|
-
test.afterEach(async () => {
|
|
174
|
-
await rm(tempDir, { recursive: true, force: true });
|
|
175
|
-
});
|
|
176
|
-
test("should generate a webui template without f-template wrapper", async () => {
|
|
177
|
-
const distDir = join(tempDir, "dist");
|
|
178
|
-
await mkdir(distDir, { recursive: true });
|
|
179
|
-
await writeFile(join(distDir, "badge.template.js"), `export const template = {
|
|
180
|
-
html: "<template><slot></slot></template>",
|
|
181
|
-
factories: {}
|
|
182
|
-
};`);
|
|
183
|
-
await generateWebuiTemplates({ cwd: tempDir, tagPrefix: "mai" });
|
|
184
|
-
const html = await readFile(join(distDir, "badge.template-webui.html"), "utf8");
|
|
185
|
-
assert.ok(html.includes('<template shadowrootmode="open">'));
|
|
186
|
-
assert.ok(html.includes("<slot></slot>"));
|
|
187
|
-
assert.ok(!html.includes("<f-template"), "should not have f-template wrapper");
|
|
188
|
-
assert.ok(!html.includes("{{styles}}"), "should not have styles marker");
|
|
189
|
-
});
|
|
190
|
-
test("should write to outDir when specified", async () => {
|
|
191
|
-
const distDir = join(tempDir, "dist");
|
|
192
|
-
await mkdir(distDir, { recursive: true });
|
|
193
|
-
await writeFile(join(distDir, "card.template.js"), `export const template = {
|
|
194
|
-
html: "<template><div>card</div></template>",
|
|
195
|
-
factories: {}
|
|
196
|
-
};`);
|
|
197
|
-
await generateWebuiTemplates({
|
|
198
|
-
cwd: tempDir,
|
|
199
|
-
outDir: "out",
|
|
200
|
-
tagPrefix: "fast",
|
|
201
|
-
});
|
|
202
|
-
const html = await readFile(join(tempDir, "out", "card.template-webui.html"), "utf8");
|
|
203
|
-
assert.ok(html.includes('<template shadowrootmode="open">'));
|
|
204
|
-
});
|
|
205
|
-
test("should add shadowrootdelegatesfocus from definition-async", async () => {
|
|
206
|
-
const distDir = join(tempDir, "dist");
|
|
207
|
-
await mkdir(distDir, { recursive: true });
|
|
208
|
-
await writeFile(join(distDir, "input.template.js"), `export const template = {
|
|
209
|
-
html: "<template><input /></template>",
|
|
210
|
-
factories: {}
|
|
211
|
-
};`);
|
|
212
|
-
await writeFile(join(distDir, "input.definition-async.js"), `export const definition = {
|
|
213
|
-
name: "fast-input",
|
|
214
|
-
shadowOptions: { delegatesFocus: true },
|
|
215
|
-
};`);
|
|
216
|
-
await generateWebuiTemplates({ cwd: tempDir, tagPrefix: "fast" });
|
|
217
|
-
const html = await readFile(join(distDir, "input.template-webui.html"), "utf8");
|
|
218
|
-
assert.ok(html.includes("shadowrootdelegatesfocus"), `should include delegatesFocus, got: ${html}`);
|
|
219
|
-
});
|
|
220
|
-
test("should not add shadowrootdelegatesfocus when absent", async () => {
|
|
221
|
-
const distDir = join(tempDir, "dist");
|
|
222
|
-
await mkdir(distDir, { recursive: true });
|
|
223
|
-
await writeFile(join(distDir, "div.template.js"), `export const template = {
|
|
224
|
-
html: "<template><div>hello</div></template>",
|
|
225
|
-
factories: {}
|
|
226
|
-
};`);
|
|
227
|
-
await generateWebuiTemplates({ cwd: tempDir, tagPrefix: "fast" });
|
|
228
|
-
const html = await readFile(join(distDir, "div.template-webui.html"), "utf8");
|
|
229
|
-
assert.ok(!html.includes("shadowrootdelegatesfocus"));
|
|
230
|
-
});
|
|
231
|
-
});
|