@microsoft/fast-html 1.0.0-alpha.4 → 1.0.0-alpha.41
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 +266 -19
- package/dist/dts/components/element.d.ts +10 -0
- package/dist/dts/components/index.d.ts +3 -1
- package/dist/dts/components/observer-map.d.ts +27 -0
- package/dist/dts/components/schema.d.ts +144 -0
- package/dist/dts/components/template.d.ts +83 -7
- package/dist/dts/components/utilities.d.ts +128 -37
- package/dist/dts/index.d.ts +1 -1
- package/dist/dts/tsdoc-metadata.json +1 -1
- package/dist/esm/components/element.js +73 -0
- package/dist/esm/components/index.js +3 -1
- package/dist/esm/components/observer-map.js +68 -0
- package/dist/esm/components/observer-map.spec.js +39 -0
- package/dist/esm/components/schema.js +250 -0
- package/dist/esm/components/schema.spec.js +484 -0
- package/dist/esm/components/template.js +242 -213
- package/dist/esm/components/utilities.js +1008 -64
- package/dist/esm/components/utilities.spec.js +522 -93
- package/dist/esm/index.js +1 -1
- package/dist/fast-html.api.json +350 -1
- package/dist/fast-html.d.ts +283 -6
- package/dist/fast-html.untrimmed.d.ts +283 -6
- package/package.json +27 -38
- package/rules/attribute-directives.yml +38 -0
- package/rules/call-expression-with-event-argument.yml +41 -0
- package/rules/member-expression.yml +33 -0
- package/rules/tag-function-to-template-literal.yml +16 -0
- package/dist/dts/fixtures/binding/binding.spec.d.ts +0 -1
- package/dist/dts/fixtures/binding/main.d.ts +0 -1
- package/dist/dts/fixtures/children/children.spec.d.ts +0 -1
- package/dist/dts/fixtures/children/main.d.ts +0 -1
- package/dist/dts/fixtures/dot-syntax/dot-syntax.spec.d.ts +0 -1
- package/dist/dts/fixtures/dot-syntax/main.d.ts +0 -1
- package/dist/dts/fixtures/event/event.spec.d.ts +0 -1
- package/dist/dts/fixtures/event/main.d.ts +0 -1
- package/dist/dts/fixtures/partial/main.d.ts +0 -1
- package/dist/dts/fixtures/partial/partial.spec.d.ts +0 -1
- package/dist/dts/fixtures/ref/main.d.ts +0 -1
- package/dist/dts/fixtures/ref/ref.spec.d.ts +0 -1
- package/dist/dts/fixtures/repeat/main.d.ts +0 -1
- package/dist/dts/fixtures/repeat/repeat.spec.d.ts +0 -1
- package/dist/dts/fixtures/slotted/main.d.ts +0 -1
- package/dist/dts/fixtures/slotted/slotted.spec.d.ts +0 -1
- package/dist/dts/fixtures/when/main.d.ts +0 -1
- package/dist/dts/fixtures/when/when.spec.d.ts +0 -1
- package/dist/esm/fixtures/attribute/attribute.spec.js +0 -23
- package/dist/esm/fixtures/attribute/main.js +0 -19
- package/dist/esm/fixtures/binding/binding.spec.js +0 -17
- package/dist/esm/fixtures/binding/main.js +0 -19
- package/dist/esm/fixtures/children/children.spec.js +0 -33
- package/dist/esm/fixtures/children/main.js +0 -24
- package/dist/esm/fixtures/dot-syntax/dot-syntax.spec.js +0 -9
- package/dist/esm/fixtures/dot-syntax/main.js +0 -16
- package/dist/esm/fixtures/event/event.spec.js +0 -12
- package/dist/esm/fixtures/event/main.js +0 -16
- package/dist/esm/fixtures/partial/main.js +0 -31
- package/dist/esm/fixtures/partial/partial.spec.js +0 -14
- package/dist/esm/fixtures/ref/main.js +0 -14
- package/dist/esm/fixtures/ref/ref.spec.js +0 -13
- package/dist/esm/fixtures/repeat/main.js +0 -19
- package/dist/esm/fixtures/repeat/repeat.spec.js +0 -26
- package/dist/esm/fixtures/slotted/main.js +0 -22
- package/dist/esm/fixtures/slotted/slotted.spec.js +0 -25
- package/dist/esm/fixtures/when/main.js +0 -146
- package/dist/esm/fixtures/when/when.spec.js +0 -82
- package/dist/esm/tsconfig.tsbuildinfo +0 -1
- /package/dist/dts/{fixtures/attribute/attribute.spec.d.ts → components/observer-map.spec.d.ts} +0 -0
- /package/dist/dts/{fixtures/attribute/main.d.ts → components/schema.spec.d.ts} +0 -0
|
@@ -1,45 +1,90 @@
|
|
|
1
|
-
import { __awaiter } from "tslib";
|
|
2
1
|
import { expect, test } from "@playwright/test";
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
import { refPropertyName, Schema } from "./schema.js";
|
|
3
|
+
import { getNextBehavior, getIndexOfNextMatchingTag, pathResolver, transformInnerHTML, getExpressionChain, extractPathsFromChainedExpression, getChildrenMap, findDef, resolveWhen, } from "./utilities.js";
|
|
4
|
+
test.describe("utilities", async () => {
|
|
5
|
+
test.describe("content", async () => {
|
|
6
|
+
test("get the next content binding", async () => {
|
|
7
7
|
const innerHTML = "{{text}}";
|
|
8
8
|
const templateResult = getNextBehavior(innerHTML);
|
|
9
9
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.type).toEqual("dataBinding");
|
|
10
10
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.subtype).toEqual("content");
|
|
11
|
+
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.bindingType).toEqual("default");
|
|
11
12
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.openingStartIndex).toEqual(0);
|
|
12
13
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.openingEndIndex).toEqual(2);
|
|
13
14
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.closingStartIndex).toEqual(6);
|
|
14
15
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.closingEndIndex).toEqual(8);
|
|
15
|
-
})
|
|
16
|
-
})
|
|
17
|
-
test.describe("attributes", () =>
|
|
18
|
-
test("get the next attribute binding", () =>
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
test.describe("attributes", async () => {
|
|
19
|
+
test("get the next attribute binding", async () => {
|
|
19
20
|
const innerHTML = "<input type=\"{{type}}\" disabled>";
|
|
20
21
|
const templateResult = getNextBehavior(innerHTML);
|
|
21
22
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.type).toEqual("dataBinding");
|
|
22
23
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.subtype).toEqual("attribute");
|
|
23
24
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.aspect).toEqual(null);
|
|
25
|
+
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.bindingType).toEqual("default");
|
|
24
26
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.openingStartIndex).toEqual(13);
|
|
25
27
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.openingEndIndex).toEqual(15);
|
|
26
28
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.closingStartIndex).toEqual(19);
|
|
27
29
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.closingEndIndex).toEqual(21);
|
|
28
|
-
})
|
|
29
|
-
test("get the next attribute event binding", () =>
|
|
30
|
-
const innerHTML = "<input @click=\"{
|
|
30
|
+
});
|
|
31
|
+
test("get the next attribute event binding", async () => {
|
|
32
|
+
const innerHTML = "<input @click=\"{handleClick()}\">";
|
|
31
33
|
const templateResult = getNextBehavior(innerHTML);
|
|
32
34
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.type).toEqual("dataBinding");
|
|
33
35
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.subtype).toEqual("attribute");
|
|
34
36
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.aspect).toEqual("@");
|
|
37
|
+
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.bindingType).toEqual("client");
|
|
35
38
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.openingStartIndex).toEqual(15);
|
|
36
|
-
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.openingEndIndex).toEqual(
|
|
37
|
-
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.closingStartIndex).toEqual(
|
|
38
|
-
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.closingEndIndex).toEqual(
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.openingEndIndex).toEqual(16);
|
|
40
|
+
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.closingStartIndex).toEqual(29);
|
|
41
|
+
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.closingEndIndex).toEqual(30);
|
|
42
|
+
});
|
|
43
|
+
test("skip single-brace content bindings (e.g. CSS braces)", async () => {
|
|
44
|
+
const innerHTML = "<style>.foo { color: red }</style>";
|
|
45
|
+
const templateResult = getNextBehavior(innerHTML);
|
|
46
|
+
expect(templateResult).toBeNull();
|
|
47
|
+
});
|
|
48
|
+
test("skip single-brace non-event, non-property attribute bindings", async () => {
|
|
49
|
+
const innerHTML1 = "<input type=\"{type}\">";
|
|
50
|
+
const templateResult1 = getNextBehavior(innerHTML1);
|
|
51
|
+
expect(templateResult1).toBeNull();
|
|
52
|
+
const innerHTML2 = "<input ?disabled=\"{disabled}\">";
|
|
53
|
+
const templateResult2 = getNextBehavior(innerHTML2);
|
|
54
|
+
expect(templateResult2).toBeNull();
|
|
55
|
+
});
|
|
56
|
+
test("find double-brace binding after skipped single-brace content", async () => {
|
|
57
|
+
const innerHTML = "<style>.foo { color: red } .bar { color: blue }</style><span>{{name}}</span>";
|
|
58
|
+
const templateResult = getNextBehavior(innerHTML);
|
|
59
|
+
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.type).toEqual("dataBinding");
|
|
60
|
+
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.subtype).toEqual("content");
|
|
61
|
+
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.bindingType).toEqual("default");
|
|
62
|
+
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.openingStartIndex).toEqual(61);
|
|
63
|
+
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.closingStartIndex).toEqual(67);
|
|
64
|
+
});
|
|
65
|
+
test("find event binding after skipped single-brace content", async () => {
|
|
66
|
+
const innerHTML = "<style>.foo { color: red }</style><button @click=\"{handler()}\">";
|
|
67
|
+
const templateResult = getNextBehavior(innerHTML);
|
|
68
|
+
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.type).toEqual("dataBinding");
|
|
69
|
+
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.subtype).toEqual("attribute");
|
|
70
|
+
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.aspect).toEqual("@");
|
|
71
|
+
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.bindingType).toEqual("client");
|
|
72
|
+
});
|
|
73
|
+
test("find property binding after skipped single-brace content", async () => {
|
|
74
|
+
const innerHTML = "<style>.foo { color: red } .bar { color: blue }</style><button :value=\"{someValue}\">";
|
|
75
|
+
const templateResult = getNextBehavior(innerHTML);
|
|
76
|
+
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.type).toEqual("dataBinding");
|
|
77
|
+
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.subtype).toEqual("attribute");
|
|
78
|
+
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.aspect).toEqual(":");
|
|
79
|
+
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.bindingType).toEqual("client");
|
|
80
|
+
});
|
|
81
|
+
test("ensure if there are expected missing {} this does not cause parsing issues", async () => {
|
|
82
|
+
const innerHTML = "<f-when value=\"missing\">";
|
|
83
|
+
expect(getNextBehavior(innerHTML)).toBeTruthy();
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
test.describe("templates", async () => {
|
|
87
|
+
test("when directive", async () => {
|
|
43
88
|
const innerHTML = "<f-when value=\"{{show}}\">Hello world</f-when>";
|
|
44
89
|
const templateResult = getNextBehavior(innerHTML);
|
|
45
90
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.type).toEqual("templateDirective");
|
|
@@ -47,8 +92,8 @@ test.describe("utilities", () => __awaiter(void 0, void 0, void 0, function* ()
|
|
|
47
92
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.openingTagEndIndex).toEqual(25);
|
|
48
93
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.closingTagStartIndex).toEqual(36);
|
|
49
94
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.closingTagEndIndex).toEqual(45);
|
|
50
|
-
})
|
|
51
|
-
test("when directive with content", () =>
|
|
95
|
+
});
|
|
96
|
+
test("when directive with content", async () => {
|
|
52
97
|
const innerHTML = "Hello pluto<f-when value=\"{{show}}\">Hello world</f-when>";
|
|
53
98
|
const templateResult = getNextBehavior(innerHTML);
|
|
54
99
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.type).toEqual("templateDirective");
|
|
@@ -56,8 +101,8 @@ test.describe("utilities", () => __awaiter(void 0, void 0, void 0, function* ()
|
|
|
56
101
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.openingTagEndIndex).toEqual(36);
|
|
57
102
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.closingTagStartIndex).toEqual(47);
|
|
58
103
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.closingTagEndIndex).toEqual(56);
|
|
59
|
-
})
|
|
60
|
-
test("when directive with binding", () =>
|
|
104
|
+
});
|
|
105
|
+
test("when directive with binding", async () => {
|
|
61
106
|
const innerHTML = "<f-when value=\"{{show}}\">{{text}}</f-when>";
|
|
62
107
|
const templateResult = getNextBehavior(innerHTML);
|
|
63
108
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.type).toEqual("templateDirective");
|
|
@@ -65,96 +110,480 @@ test.describe("utilities", () => __awaiter(void 0, void 0, void 0, function* ()
|
|
|
65
110
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.openingTagEndIndex).toEqual(25);
|
|
66
111
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.closingTagStartIndex).toEqual(33);
|
|
67
112
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.closingTagEndIndex).toEqual(42);
|
|
68
|
-
})
|
|
69
|
-
})
|
|
70
|
-
test.describe("attributes", () =>
|
|
71
|
-
test("children directive", () =>
|
|
72
|
-
const innerHTML = "<ul f-children=\"{
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
test.describe("attributes", async () => {
|
|
116
|
+
test("children directive", async () => {
|
|
117
|
+
const innerHTML = "<ul f-children=\"{list}\"></ul>";
|
|
73
118
|
const result = getNextBehavior(innerHTML);
|
|
74
119
|
expect(result === null || result === void 0 ? void 0 : result.type).toEqual("dataBinding");
|
|
75
120
|
expect(result === null || result === void 0 ? void 0 : result.subtype).toEqual("attributeDirective");
|
|
76
121
|
expect(result === null || result === void 0 ? void 0 : result.name).toEqual("children");
|
|
122
|
+
expect(result === null || result === void 0 ? void 0 : result.bindingType).toEqual("client");
|
|
77
123
|
expect(result === null || result === void 0 ? void 0 : result.openingStartIndex).toEqual(16);
|
|
78
|
-
expect(result === null || result === void 0 ? void 0 : result.openingEndIndex).toEqual(
|
|
79
|
-
expect(result === null || result === void 0 ? void 0 : result.closingStartIndex).toEqual(
|
|
80
|
-
expect(result === null || result === void 0 ? void 0 : result.closingEndIndex).toEqual(
|
|
81
|
-
})
|
|
82
|
-
test("slotted directive", () =>
|
|
83
|
-
const innerHTML = "<slot f-slotted=\"{
|
|
124
|
+
expect(result === null || result === void 0 ? void 0 : result.openingEndIndex).toEqual(17);
|
|
125
|
+
expect(result === null || result === void 0 ? void 0 : result.closingStartIndex).toEqual(21);
|
|
126
|
+
expect(result === null || result === void 0 ? void 0 : result.closingEndIndex).toEqual(22);
|
|
127
|
+
});
|
|
128
|
+
test("slotted directive", async () => {
|
|
129
|
+
const innerHTML = "<slot f-slotted=\"{slottedNodes}\"></slot>";
|
|
84
130
|
const result = getNextBehavior(innerHTML);
|
|
85
131
|
expect(result === null || result === void 0 ? void 0 : result.type).toEqual("dataBinding");
|
|
86
132
|
expect(result === null || result === void 0 ? void 0 : result.subtype).toEqual("attributeDirective");
|
|
87
133
|
expect(result === null || result === void 0 ? void 0 : result.name).toEqual("slotted");
|
|
134
|
+
expect(result === null || result === void 0 ? void 0 : result.bindingType).toEqual("client");
|
|
88
135
|
expect(result === null || result === void 0 ? void 0 : result.openingStartIndex).toEqual(17);
|
|
89
|
-
expect(result === null || result === void 0 ? void 0 : result.openingEndIndex).toEqual(
|
|
90
|
-
expect(result === null || result === void 0 ? void 0 : result.closingStartIndex).toEqual(
|
|
91
|
-
expect(result === null || result === void 0 ? void 0 : result.closingEndIndex).toEqual(
|
|
92
|
-
})
|
|
93
|
-
test("ref directive", () =>
|
|
94
|
-
const innerHTML = "<video f-ref=\"{
|
|
136
|
+
expect(result === null || result === void 0 ? void 0 : result.openingEndIndex).toEqual(18);
|
|
137
|
+
expect(result === null || result === void 0 ? void 0 : result.closingStartIndex).toEqual(30);
|
|
138
|
+
expect(result === null || result === void 0 ? void 0 : result.closingEndIndex).toEqual(31);
|
|
139
|
+
});
|
|
140
|
+
test("ref directive", async () => {
|
|
141
|
+
const innerHTML = "<video f-ref=\"{video}\"></video>";
|
|
95
142
|
const result = getNextBehavior(innerHTML);
|
|
96
143
|
expect(result === null || result === void 0 ? void 0 : result.type).toEqual("dataBinding");
|
|
97
144
|
expect(result === null || result === void 0 ? void 0 : result.subtype).toEqual("attributeDirective");
|
|
98
145
|
expect(result === null || result === void 0 ? void 0 : result.name).toEqual("ref");
|
|
146
|
+
expect(result === null || result === void 0 ? void 0 : result.bindingType).toEqual("client");
|
|
99
147
|
expect(result === null || result === void 0 ? void 0 : result.openingStartIndex).toEqual(14);
|
|
100
|
-
expect(result === null || result === void 0 ? void 0 : result.openingEndIndex).toEqual(
|
|
101
|
-
expect(result === null || result === void 0 ? void 0 : result.closingStartIndex).toEqual(
|
|
102
|
-
expect(result === null || result === void 0 ? void 0 : result.closingEndIndex).toEqual(
|
|
103
|
-
})
|
|
104
|
-
})
|
|
105
|
-
test.describe("
|
|
106
|
-
test("
|
|
107
|
-
const partialContent = "{{text}}";
|
|
108
|
-
const partial = `<f-partial id="foo">${partialContent}</f-partial>`;
|
|
109
|
-
const allPartials = getAllPartials(partial);
|
|
110
|
-
expect(allPartials.foo.innerHTML).toEqual(partialContent);
|
|
111
|
-
expect(allPartials.foo.startIndex).toEqual(20);
|
|
112
|
-
expect(allPartials.foo.endIndex).toEqual(28);
|
|
113
|
-
}));
|
|
114
|
-
test("get multiple partials", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
115
|
-
const partial1Content = "{{text}}";
|
|
116
|
-
const partial2Content = "{{othertext}}";
|
|
117
|
-
const partial1 = `<f-partial id="foo">${partial1Content}</f-partial>`;
|
|
118
|
-
const partial2 = `<f-partial id="foobar">${partial2Content}</f-partial>`;
|
|
119
|
-
const allPartials = getAllPartials(`${partial1}${partial2}`);
|
|
120
|
-
expect(allPartials.foo.innerHTML).toEqual(partial1Content);
|
|
121
|
-
expect(allPartials.foo.startIndex).toEqual(20);
|
|
122
|
-
expect(allPartials.foo.endIndex).toEqual(28);
|
|
123
|
-
expect(allPartials.foobar.innerHTML).toEqual(partial2Content);
|
|
124
|
-
expect(allPartials.foobar.startIndex).toEqual(63);
|
|
125
|
-
expect(allPartials.foobar.endIndex).toEqual(76);
|
|
126
|
-
}));
|
|
127
|
-
}));
|
|
128
|
-
test.describe("getIndexOfNextMatchingTag", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
129
|
-
test("should resolve a single tag", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
148
|
+
expect(result === null || result === void 0 ? void 0 : result.openingEndIndex).toEqual(15);
|
|
149
|
+
expect(result === null || result === void 0 ? void 0 : result.closingStartIndex).toEqual(20);
|
|
150
|
+
expect(result === null || result === void 0 ? void 0 : result.closingEndIndex).toEqual(21);
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
test.describe("getIndexOfNextMatchingTag", async () => {
|
|
154
|
+
test("should resolve a single tag", async () => {
|
|
130
155
|
const index = getIndexOfNextMatchingTag(`<div>Hello world</div>`, `<div`, `</div>`, 0);
|
|
131
156
|
expect(index).toEqual(16);
|
|
132
|
-
})
|
|
133
|
-
test("should resolve when there is a nested tag", () =>
|
|
157
|
+
});
|
|
158
|
+
test("should resolve when there is a nested tag", async () => {
|
|
134
159
|
const index = getIndexOfNextMatchingTag(`<div><div>Hello world</div></div>`, `<div`, `</div>`, 0);
|
|
135
160
|
expect(index).toEqual(27);
|
|
136
|
-
})
|
|
137
|
-
test("should get adjacent tags", () =>
|
|
161
|
+
});
|
|
162
|
+
test("should get adjacent tags", async () => {
|
|
138
163
|
const index = getIndexOfNextMatchingTag(`<div>Hello world</div><div>Hello pluto</div>`, `<div`, `</div>`, 0);
|
|
139
164
|
expect(index).toEqual(16);
|
|
140
|
-
})
|
|
141
|
-
test("should add an offset for content before the tag", () =>
|
|
165
|
+
});
|
|
166
|
+
test("should add an offset for content before the tag", async () => {
|
|
142
167
|
const index = getIndexOfNextMatchingTag(`<div>Hello world</div>`, `<div`, `</div>`, 23);
|
|
143
168
|
expect(index).toEqual(39);
|
|
144
|
-
})
|
|
145
|
-
})
|
|
146
|
-
test.describe("pathResolver", () =>
|
|
147
|
-
test("should resolve a path with no nesting", () =>
|
|
148
|
-
expect(pathResolver("foo")({ foo: "bar" })).toEqual("bar");
|
|
149
|
-
})
|
|
150
|
-
test("should resolve a path with nesting", () =>
|
|
151
|
-
expect(pathResolver("foo.bar.bat")({ foo: { bar: { bat: "baz" } } })).toEqual("baz");
|
|
152
|
-
})
|
|
153
|
-
test("should resolve a path with no nesting and self reference", () =>
|
|
154
|
-
expect(pathResolver("foo",
|
|
155
|
-
})
|
|
156
|
-
test("should resolve a path with nesting and self reference", () =>
|
|
157
|
-
expect(pathResolver("foo.bar.bat",
|
|
158
|
-
})
|
|
159
|
-
|
|
160
|
-
}));
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
test.describe("pathResolver", async () => {
|
|
172
|
+
test("should resolve a path with no nesting", async () => {
|
|
173
|
+
expect(pathResolver("foo", null, 0, {})({ foo: "bar" }, {})).toEqual("bar");
|
|
174
|
+
});
|
|
175
|
+
test("should resolve a path with nesting", async () => {
|
|
176
|
+
expect(pathResolver("foo.bar.bat", null, 0, {})({ foo: { bar: { bat: "baz" } } }, {})).toEqual("baz");
|
|
177
|
+
});
|
|
178
|
+
test("should resolve a path with no nesting and self reference", async () => {
|
|
179
|
+
expect(pathResolver("foo", "foo", 0, {})("bar", {})).toEqual("bar");
|
|
180
|
+
});
|
|
181
|
+
test("should resolve a path with nesting and self reference", async () => {
|
|
182
|
+
expect(pathResolver("foo.bar.bat", "foo", 0, {})({ bar: { bat: "baz" } }, {})).toEqual("baz");
|
|
183
|
+
});
|
|
184
|
+
test("should resolve a path with context", async () => {
|
|
185
|
+
expect(pathResolver("foo", "parent", 1, {})({}, { parent: { foo: "bar" } })).toEqual("bar");
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
test.describe("transformInnerHTML", async () => {
|
|
189
|
+
test("should resolve a single unescaped data binding", async () => {
|
|
190
|
+
expect(transformInnerHTML(`{{{html}}}`)).toEqual(`<div :innerHTML="{{html}}"></div>`);
|
|
191
|
+
});
|
|
192
|
+
test("should resolve multiple unescaped data bindings", async () => {
|
|
193
|
+
expect(transformInnerHTML(`{{{foo}}}{{{bar}}}`)).toEqual(`<div :innerHTML="{{foo}}"></div><div :innerHTML="{{bar}}"></div>`);
|
|
194
|
+
});
|
|
195
|
+
test("should resolve an unescaped data bindings in a mix of other data content bindings", async () => {
|
|
196
|
+
expect(transformInnerHTML(`{{text1}}{{{foo}}}{{text2}}{{{bar}}}{{text3}}`)).toEqual(`{{text1}}<div :innerHTML="{{foo}}"></div>{{text2}}<div :innerHTML="{{bar}}"></div>{{text3}}`);
|
|
197
|
+
});
|
|
198
|
+
test("should resolve default data bindings in sequence", async () => {
|
|
199
|
+
expect(transformInnerHTML(`{{text1}}{{text2}}`)).toEqual(`{{text1}}{{text2}}`);
|
|
200
|
+
});
|
|
201
|
+
test("should resolve an unescaped data bindings in a mix of other data attribute bindings and nesting", async () => {
|
|
202
|
+
expect(transformInnerHTML(`<div data-foo="{{text1}}">{{{foo}}}</div><div data-bar="{{text2}}"></div>{{{bar}}}<div data-bat="{{text3}}"></div>`)).toEqual(`<div data-foo="{{text1}}"><div :innerHTML="{{foo}}"></div></div><div data-bar="{{text2}}"></div><div :innerHTML="{{bar}}"></div><div data-bat="{{text3}}"></div>`);
|
|
203
|
+
});
|
|
204
|
+
test("should resolve a non-data and non-attribute bindings", async () => {
|
|
205
|
+
expect(transformInnerHTML(`<button @click="{handleNoArgsClick()}">No arguments</button>`)).toEqual(`<button @click="{handleNoArgsClick()}">No arguments</button>`);
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
test.describe("getExpressionChain", async () => {
|
|
209
|
+
test("should resolve a truthy value", async () => {
|
|
210
|
+
expect(getExpressionChain("foo")).toEqual({
|
|
211
|
+
expression: {
|
|
212
|
+
operator: "access",
|
|
213
|
+
left: "foo",
|
|
214
|
+
leftIsValue: false,
|
|
215
|
+
right: null,
|
|
216
|
+
rightIsValue: null,
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
test("should resolve a falsy value", async () => {
|
|
221
|
+
expect(getExpressionChain("!foo")).toEqual({
|
|
222
|
+
expression: {
|
|
223
|
+
operator: "!",
|
|
224
|
+
left: "foo",
|
|
225
|
+
leftIsValue: false,
|
|
226
|
+
right: null,
|
|
227
|
+
rightIsValue: null,
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
});
|
|
231
|
+
test("should resolve a path not equal to string value", async () => {
|
|
232
|
+
expect(getExpressionChain("foo != 'test'")).toEqual({
|
|
233
|
+
expression: {
|
|
234
|
+
operator: "!=",
|
|
235
|
+
left: "foo",
|
|
236
|
+
leftIsValue: false,
|
|
237
|
+
right: "test",
|
|
238
|
+
rightIsValue: true,
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
test("should resolve a path not equal to boolean value", async () => {
|
|
243
|
+
expect(getExpressionChain("foo != false")).toEqual({
|
|
244
|
+
expression: {
|
|
245
|
+
operator: "!=",
|
|
246
|
+
left: "foo",
|
|
247
|
+
leftIsValue: false,
|
|
248
|
+
right: false,
|
|
249
|
+
rightIsValue: true,
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
test("should resolve a path not equal to numerical value", async () => {
|
|
254
|
+
expect(getExpressionChain("foo != 5")).toEqual({
|
|
255
|
+
expression: {
|
|
256
|
+
operator: "!=",
|
|
257
|
+
left: "foo",
|
|
258
|
+
leftIsValue: false,
|
|
259
|
+
right: 5,
|
|
260
|
+
rightIsValue: true,
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
});
|
|
264
|
+
test("should resolve chained expressions", async () => {
|
|
265
|
+
expect(getExpressionChain("foo != 'bat' && bar == 'baz'")).toEqual({
|
|
266
|
+
expression: {
|
|
267
|
+
operator: "!=",
|
|
268
|
+
left: "foo",
|
|
269
|
+
leftIsValue: false,
|
|
270
|
+
right: "bat",
|
|
271
|
+
rightIsValue: true,
|
|
272
|
+
},
|
|
273
|
+
next: {
|
|
274
|
+
operator: "&&",
|
|
275
|
+
expression: {
|
|
276
|
+
operator: "==",
|
|
277
|
+
left: "bar",
|
|
278
|
+
leftIsValue: false,
|
|
279
|
+
right: "baz",
|
|
280
|
+
rightIsValue: true,
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
});
|
|
284
|
+
expect(getExpressionChain("foo && bar")).toEqual({
|
|
285
|
+
expression: {
|
|
286
|
+
operator: "access",
|
|
287
|
+
left: "foo",
|
|
288
|
+
leftIsValue: false,
|
|
289
|
+
right: null,
|
|
290
|
+
rightIsValue: null,
|
|
291
|
+
},
|
|
292
|
+
next: {
|
|
293
|
+
operator: "&&",
|
|
294
|
+
expression: {
|
|
295
|
+
operator: "access",
|
|
296
|
+
left: "bar",
|
|
297
|
+
leftIsValue: false,
|
|
298
|
+
right: null,
|
|
299
|
+
rightIsValue: null,
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
});
|
|
303
|
+
});
|
|
304
|
+
});
|
|
305
|
+
test.describe("extractPathsFromChainedExpression", async () => {
|
|
306
|
+
test("should extract paths from simple access expression", async () => {
|
|
307
|
+
const expressionChain = getExpressionChain("user");
|
|
308
|
+
expect(expressionChain).toBeDefined();
|
|
309
|
+
const paths = extractPathsFromChainedExpression(expressionChain);
|
|
310
|
+
expect(paths.size).toEqual(1);
|
|
311
|
+
expect(paths.has("user")).toBe(true);
|
|
312
|
+
});
|
|
313
|
+
test("should extract paths from dot notation expression", async () => {
|
|
314
|
+
const expressionChain = getExpressionChain("user.name");
|
|
315
|
+
expect(expressionChain).toBeDefined();
|
|
316
|
+
const paths = extractPathsFromChainedExpression(expressionChain);
|
|
317
|
+
expect(paths.size).toEqual(1);
|
|
318
|
+
expect(paths.has("user.name")).toBe(true);
|
|
319
|
+
});
|
|
320
|
+
test("should extract paths from comparison with literal values", async () => {
|
|
321
|
+
const expressionChain = getExpressionChain("user.age > 18");
|
|
322
|
+
expect(expressionChain).toBeDefined();
|
|
323
|
+
const paths = extractPathsFromChainedExpression(expressionChain);
|
|
324
|
+
expect(paths.size).toEqual(1);
|
|
325
|
+
expect(paths.has("user.age")).toBe(true);
|
|
326
|
+
});
|
|
327
|
+
test("should extract paths from comparison between two properties", async () => {
|
|
328
|
+
const expressionChain = getExpressionChain("user.age >= admin.minAge");
|
|
329
|
+
expect(expressionChain).toBeDefined();
|
|
330
|
+
const paths = extractPathsFromChainedExpression(expressionChain);
|
|
331
|
+
expect(paths.size).toEqual(2);
|
|
332
|
+
expect(paths.has("user.age")).toBe(true);
|
|
333
|
+
expect(paths.has("admin.minAge")).toBe(true);
|
|
334
|
+
});
|
|
335
|
+
test("should extract paths from chained AND expressions", async () => {
|
|
336
|
+
const expressionChain = getExpressionChain("isActive && user.name");
|
|
337
|
+
expect(expressionChain).toBeDefined();
|
|
338
|
+
const paths = extractPathsFromChainedExpression(expressionChain);
|
|
339
|
+
expect(paths.size).toEqual(2);
|
|
340
|
+
expect(paths.has("isActive")).toBe(true);
|
|
341
|
+
expect(paths.has("user.name")).toBe(true);
|
|
342
|
+
});
|
|
343
|
+
test("should extract paths from chained OR expressions", async () => {
|
|
344
|
+
const expressionChain = getExpressionChain("user.isAdmin || permissions.canEdit");
|
|
345
|
+
expect(expressionChain).toBeDefined();
|
|
346
|
+
const paths = extractPathsFromChainedExpression(expressionChain);
|
|
347
|
+
expect(paths.size).toEqual(2);
|
|
348
|
+
expect(paths.has("user.isAdmin")).toBe(true);
|
|
349
|
+
expect(paths.has("permissions.canEdit")).toBe(true);
|
|
350
|
+
});
|
|
351
|
+
test("should extract paths from complex chained expressions", async () => {
|
|
352
|
+
const expressionChain = getExpressionChain("user.age > 18 && user.status == 'active' || admin.override");
|
|
353
|
+
expect(expressionChain).toBeDefined();
|
|
354
|
+
const paths = extractPathsFromChainedExpression(expressionChain);
|
|
355
|
+
expect(paths.size).toEqual(3);
|
|
356
|
+
expect(paths.has("user.age")).toBe(true);
|
|
357
|
+
expect(paths.has("user.status")).toBe(true);
|
|
358
|
+
expect(paths.has("admin.override")).toBe(true);
|
|
359
|
+
});
|
|
360
|
+
test("should extract paths from NOT expressions", async () => {
|
|
361
|
+
const expressionChain = getExpressionChain("!user.isDisabled");
|
|
362
|
+
expect(expressionChain).toBeDefined();
|
|
363
|
+
const paths = extractPathsFromChainedExpression(expressionChain);
|
|
364
|
+
expect(paths.size).toEqual(1);
|
|
365
|
+
expect(paths.has("user.isDisabled")).toBe(true);
|
|
366
|
+
});
|
|
367
|
+
test("should handle expressions with only literal values", async () => {
|
|
368
|
+
const expressionChain = getExpressionChain("5 > 3");
|
|
369
|
+
expect(expressionChain).toBeDefined();
|
|
370
|
+
const paths = extractPathsFromChainedExpression(expressionChain);
|
|
371
|
+
expect(paths.size).toEqual(0);
|
|
372
|
+
});
|
|
373
|
+
test("should handle mixed literal and property expressions", async () => {
|
|
374
|
+
const expressionChain = getExpressionChain("count > 0 && status == 'ready'");
|
|
375
|
+
expect(expressionChain).toBeDefined();
|
|
376
|
+
const paths = extractPathsFromChainedExpression(expressionChain);
|
|
377
|
+
expect(paths.size).toEqual(2);
|
|
378
|
+
expect(paths.has("count")).toBe(true);
|
|
379
|
+
expect(paths.has("status")).toBe(true);
|
|
380
|
+
});
|
|
381
|
+
test("should deduplicate identical paths", async () => {
|
|
382
|
+
const expressionChain = getExpressionChain("user.name && user.name != 'anonymous'");
|
|
383
|
+
expect(expressionChain).toBeDefined();
|
|
384
|
+
const paths = extractPathsFromChainedExpression(expressionChain);
|
|
385
|
+
expect(paths.size).toEqual(1);
|
|
386
|
+
expect(paths.has("user.name")).toBe(true);
|
|
387
|
+
});
|
|
388
|
+
test("should handle HTML entity operators", async () => {
|
|
389
|
+
const expressionChain = getExpressionChain("isValid && data.ready");
|
|
390
|
+
expect(expressionChain).toBeDefined();
|
|
391
|
+
const paths = extractPathsFromChainedExpression(expressionChain);
|
|
392
|
+
expect(paths.size).toEqual(2);
|
|
393
|
+
expect(paths.has("isValid")).toBe(true);
|
|
394
|
+
expect(paths.has("data.ready")).toBe(true);
|
|
395
|
+
});
|
|
396
|
+
test("should handle deeply nested property paths", async () => {
|
|
397
|
+
const expressionChain = getExpressionChain("app.user.profile.settings.theme");
|
|
398
|
+
expect(expressionChain).toBeDefined();
|
|
399
|
+
const paths = extractPathsFromChainedExpression(expressionChain);
|
|
400
|
+
expect(paths.size).toEqual(1);
|
|
401
|
+
expect(paths.has("app.user.profile.settings.theme")).toBe(true);
|
|
402
|
+
});
|
|
403
|
+
});
|
|
404
|
+
test.describe("resolveWhen - default case truthiness evaluation", async () => {
|
|
405
|
+
// Helper to create a basic schema for testing
|
|
406
|
+
const createTestSchema = (rootPropertyName, propertyName) => {
|
|
407
|
+
const schema = new Schema("test-element");
|
|
408
|
+
schema.addPath({
|
|
409
|
+
rootPropertyName,
|
|
410
|
+
pathConfig: {
|
|
411
|
+
type: "access",
|
|
412
|
+
path: propertyName,
|
|
413
|
+
currentContext: null,
|
|
414
|
+
parentContext: null,
|
|
415
|
+
},
|
|
416
|
+
childrenMap: null,
|
|
417
|
+
});
|
|
418
|
+
return schema;
|
|
419
|
+
};
|
|
420
|
+
test("should evaluate boolean true as truthy", async () => {
|
|
421
|
+
const schema = createTestSchema("testData", "boolTrue");
|
|
422
|
+
const expression = getExpressionChain("boolTrue");
|
|
423
|
+
const resolver = resolveWhen("testData", expression, null, 0, schema);
|
|
424
|
+
const result = resolver({ boolTrue: true }, null);
|
|
425
|
+
expect(result).toBe(true);
|
|
426
|
+
});
|
|
427
|
+
test("should evaluate boolean false as falsy", async () => {
|
|
428
|
+
const schema = createTestSchema("testData", "boolFalse");
|
|
429
|
+
const expression = getExpressionChain("boolFalse");
|
|
430
|
+
const resolver = resolveWhen("testData", expression, null, 0, schema);
|
|
431
|
+
const result = resolver({ boolFalse: false }, null);
|
|
432
|
+
expect(result).toBe(false);
|
|
433
|
+
});
|
|
434
|
+
test("should evaluate number 0 as falsy", async () => {
|
|
435
|
+
const schema = createTestSchema("testData", "numberZero");
|
|
436
|
+
const expression = getExpressionChain("numberZero");
|
|
437
|
+
const resolver = resolveWhen("testData", expression, null, 0, schema);
|
|
438
|
+
const result = resolver({ numberZero: 0 }, null);
|
|
439
|
+
expect(result).toBe(false);
|
|
440
|
+
});
|
|
441
|
+
test("should evaluate positive number as truthy", async () => {
|
|
442
|
+
const schema = createTestSchema("testData", "numberPositive");
|
|
443
|
+
const expression = getExpressionChain("numberPositive");
|
|
444
|
+
const resolver = resolveWhen("testData", expression, null, 0, schema);
|
|
445
|
+
const result = resolver({ numberPositive: 42 }, null);
|
|
446
|
+
expect(result).toBe(true);
|
|
447
|
+
});
|
|
448
|
+
test("should evaluate negative number as truthy", async () => {
|
|
449
|
+
const schema = createTestSchema("testData", "numberNegative");
|
|
450
|
+
const expression = getExpressionChain("numberNegative");
|
|
451
|
+
const resolver = resolveWhen("testData", expression, null, 0, schema);
|
|
452
|
+
const result = resolver({ numberNegative: -5 }, null);
|
|
453
|
+
expect(result).toBe(true);
|
|
454
|
+
});
|
|
455
|
+
test("should evaluate empty string as falsy", async () => {
|
|
456
|
+
const schema = createTestSchema("testData", "stringEmpty");
|
|
457
|
+
const expression = getExpressionChain("stringEmpty");
|
|
458
|
+
const resolver = resolveWhen("testData", expression, null, 0, schema);
|
|
459
|
+
const result = resolver({ stringEmpty: "" }, null);
|
|
460
|
+
expect(result).toBe(false);
|
|
461
|
+
});
|
|
462
|
+
test("should evaluate non-empty string as truthy", async () => {
|
|
463
|
+
const schema = createTestSchema("testData", "stringNonEmpty");
|
|
464
|
+
const expression = getExpressionChain("stringNonEmpty");
|
|
465
|
+
const resolver = resolveWhen("testData", expression, null, 0, schema);
|
|
466
|
+
const result = resolver({ stringNonEmpty: "hello" }, null);
|
|
467
|
+
expect(result).toBe(true);
|
|
468
|
+
});
|
|
469
|
+
test("should evaluate null as falsy", async () => {
|
|
470
|
+
const schema = createTestSchema("testData", "objectNull");
|
|
471
|
+
const expression = getExpressionChain("objectNull");
|
|
472
|
+
const resolver = resolveWhen("testData", expression, null, 0, schema);
|
|
473
|
+
const result = resolver({ objectNull: null }, null);
|
|
474
|
+
expect(result).toBe(false);
|
|
475
|
+
});
|
|
476
|
+
test("should evaluate undefined as falsy", async () => {
|
|
477
|
+
const schema = createTestSchema("testData", "undefinedProp");
|
|
478
|
+
const expression = getExpressionChain("undefinedProp");
|
|
479
|
+
const resolver = resolveWhen("testData", expression, null, 0, schema);
|
|
480
|
+
const result = resolver({ undefinedProp: undefined }, null);
|
|
481
|
+
expect(result).toBe(false);
|
|
482
|
+
});
|
|
483
|
+
test("should evaluate non-null object as truthy", async () => {
|
|
484
|
+
const schema = createTestSchema("testData", "objectNonNull");
|
|
485
|
+
const expression = getExpressionChain("objectNonNull");
|
|
486
|
+
const resolver = resolveWhen("testData", expression, null, 0, schema);
|
|
487
|
+
const result = resolver({ objectNonNull: { foo: "bar" } }, null);
|
|
488
|
+
expect(result).toBe(true);
|
|
489
|
+
});
|
|
490
|
+
test("should evaluate empty array as truthy", async () => {
|
|
491
|
+
const schema = createTestSchema("testData", "arrayEmpty");
|
|
492
|
+
const expression = getExpressionChain("arrayEmpty");
|
|
493
|
+
const resolver = resolveWhen("testData", expression, null, 0, schema);
|
|
494
|
+
const result = resolver({ arrayEmpty: [] }, null);
|
|
495
|
+
expect(result).toBe(true);
|
|
496
|
+
});
|
|
497
|
+
test("should evaluate non-empty array as truthy", async () => {
|
|
498
|
+
const schema = createTestSchema("testData", "arrayNonEmpty");
|
|
499
|
+
const expression = getExpressionChain("arrayNonEmpty");
|
|
500
|
+
const resolver = resolveWhen("testData", expression, null, 0, schema);
|
|
501
|
+
const result = resolver({ arrayNonEmpty: [1, 2, 3] }, null);
|
|
502
|
+
expect(result).toBe(true);
|
|
503
|
+
});
|
|
504
|
+
test("should evaluate string with only whitespace as truthy", async () => {
|
|
505
|
+
const schema = createTestSchema("testData", "stringWhitespace");
|
|
506
|
+
const expression = getExpressionChain("stringWhitespace");
|
|
507
|
+
const resolver = resolveWhen("testData", expression, null, 0, schema);
|
|
508
|
+
const result = resolver({ stringWhitespace: " " }, null);
|
|
509
|
+
expect(result).toBe(true);
|
|
510
|
+
});
|
|
511
|
+
test("should evaluate number NaN as truthy", async () => {
|
|
512
|
+
const schema = createTestSchema("testData", "numberNaN");
|
|
513
|
+
const expression = getExpressionChain("numberNaN");
|
|
514
|
+
const resolver = resolveWhen("testData", expression, null, 0, schema);
|
|
515
|
+
const result = resolver({ numberNaN: NaN }, null);
|
|
516
|
+
expect(result).toBe(true);
|
|
517
|
+
});
|
|
518
|
+
});
|
|
519
|
+
test.describe("getChildrenMap", async () => {
|
|
520
|
+
test("should get a ChildrenMap if an attribute is part of a custom element", async () => {
|
|
521
|
+
const childrenMap = getChildrenMap(`<template><my-element foo="`);
|
|
522
|
+
expect(childrenMap).not.toBeNull();
|
|
523
|
+
expect(childrenMap === null || childrenMap === void 0 ? void 0 : childrenMap.attributeName).toEqual("foo");
|
|
524
|
+
expect(childrenMap === null || childrenMap === void 0 ? void 0 : childrenMap.customElementName).toEqual("my-element");
|
|
525
|
+
});
|
|
526
|
+
test("should not get a ChildrenMap if an attribute is part of a non-custom element", async () => {
|
|
527
|
+
const childrenMap = getChildrenMap(`<template><button foo="`);
|
|
528
|
+
expect(childrenMap).toBeNull();
|
|
529
|
+
});
|
|
530
|
+
test("should remove any aspected attributes from an attribute name", async () => {
|
|
531
|
+
const childrenMap = getChildrenMap(`<template><my-element :foo="`);
|
|
532
|
+
expect(childrenMap).not.toBeNull();
|
|
533
|
+
expect(childrenMap === null || childrenMap === void 0 ? void 0 : childrenMap.attributeName).toEqual("foo");
|
|
534
|
+
expect(childrenMap === null || childrenMap === void 0 ? void 0 : childrenMap.customElementName).toEqual("my-element");
|
|
535
|
+
});
|
|
536
|
+
test("should not get a ChildreMap if the previous string indicates the binding was not an attribute", async () => {
|
|
537
|
+
const childrenMap = getChildrenMap(`<template><my-element>`);
|
|
538
|
+
expect(childrenMap).toBeNull();
|
|
539
|
+
});
|
|
540
|
+
test("should get a ChildrenMap if there are multiple attributes are listed before this attribute", async () => {
|
|
541
|
+
const childrenMap = getChildrenMap(`<template><my-element foo="" bar="" bat="`);
|
|
542
|
+
expect(childrenMap).not.toBeNull();
|
|
543
|
+
expect(childrenMap === null || childrenMap === void 0 ? void 0 : childrenMap.attributeName).toEqual("bat");
|
|
544
|
+
expect(childrenMap === null || childrenMap === void 0 ? void 0 : childrenMap.customElementName).toEqual("my-element");
|
|
545
|
+
});
|
|
546
|
+
});
|
|
547
|
+
test.describe("schema functions", async () => {
|
|
548
|
+
test.describe("findDef", async () => {
|
|
549
|
+
test("should resolve from the root of a schema", async () => {
|
|
550
|
+
expect(findDef({
|
|
551
|
+
[refPropertyName]: "#/$defs/MyType"
|
|
552
|
+
})).toEqual("MyType");
|
|
553
|
+
});
|
|
554
|
+
test("should resolve as null from an anyOf array containing a reference to another component", async () => {
|
|
555
|
+
expect(findDef({
|
|
556
|
+
anyOf: [
|
|
557
|
+
{
|
|
558
|
+
[refPropertyName]: "https://fast.design/schemas/test-element/c.json"
|
|
559
|
+
}
|
|
560
|
+
]
|
|
561
|
+
})).toEqual(null);
|
|
562
|
+
});
|
|
563
|
+
test("should resolve from an anyOf array containing a reference to a $def", async () => {
|
|
564
|
+
expect(findDef({
|
|
565
|
+
anyOf: [
|
|
566
|
+
{
|
|
567
|
+
[refPropertyName]: "#/$defs/MyType"
|
|
568
|
+
}
|
|
569
|
+
]
|
|
570
|
+
})).toEqual("MyType");
|
|
571
|
+
});
|
|
572
|
+
test("should resolve from an anyOf array containing a reference to another component and a reference to a $def", async () => {
|
|
573
|
+
expect(findDef({
|
|
574
|
+
anyOf: [
|
|
575
|
+
{
|
|
576
|
+
[refPropertyName]: "https://fast.design/schemas/test-element/c.json"
|
|
577
|
+
},
|
|
578
|
+
{
|
|
579
|
+
[refPropertyName]: "#/$defs/MyType"
|
|
580
|
+
}
|
|
581
|
+
]
|
|
582
|
+
})).toEqual("MyType");
|
|
583
|
+
});
|
|
584
|
+
test("should resolve as null if not found", async () => {
|
|
585
|
+
expect(findDef({})).toEqual(null);
|
|
586
|
+
});
|
|
587
|
+
});
|
|
588
|
+
});
|
|
589
|
+
});
|