@alloy-js/core 0.15.0 → 0.17.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/CHANGELOG.md +23 -0
- package/dist/src/binder.d.ts +18 -235
- package/dist/src/binder.d.ts.map +1 -1
- package/dist/src/binder.js +85 -386
- package/dist/src/components/Block.d.ts +1 -1
- package/dist/src/components/Block.d.ts.map +1 -1
- package/dist/src/components/Block.js +3 -1
- package/dist/src/components/Declaration.d.ts +1 -1
- package/dist/src/components/Declaration.d.ts.map +1 -1
- package/dist/src/components/Declaration.js +5 -4
- package/dist/src/components/For.d.ts +1 -1
- package/dist/src/components/For.d.ts.map +1 -1
- package/dist/src/components/For.js +1 -1
- package/dist/src/components/Indent.d.ts +1 -1
- package/dist/src/components/Indent.d.ts.map +1 -1
- package/dist/src/components/List.d.ts +1 -1
- package/dist/src/components/List.d.ts.map +1 -1
- package/dist/src/components/List.js +2 -1
- package/dist/src/components/MemberDeclaration.d.ts +1 -1
- package/dist/src/components/MemberDeclaration.d.ts.map +1 -1
- package/dist/src/components/MemberDeclaration.js +3 -4
- package/dist/src/components/MemberScope.d.ts +1 -1
- package/dist/src/components/MemberScope.d.ts.map +1 -1
- package/dist/src/components/MemberScope.js +0 -2
- package/dist/src/components/Prose.d.ts +1 -1
- package/dist/src/components/Prose.d.ts.map +1 -1
- package/dist/src/components/ReferenceOrContent.d.ts +1 -1
- package/dist/src/components/ReferenceOrContent.d.ts.map +1 -1
- package/dist/src/components/Scope.d.ts +1 -1
- package/dist/src/components/Scope.d.ts.map +1 -1
- package/dist/src/components/Scope.js +3 -6
- package/dist/src/components/Show.d.ts +1 -1
- package/dist/src/components/Show.d.ts.map +1 -1
- package/dist/src/components/StatementList.d.ts +1 -1
- package/dist/src/components/StatementList.d.ts.map +1 -1
- package/dist/src/components/StatementList.js +1 -1
- package/dist/src/components/Switch.d.ts +1 -1
- package/dist/src/components/Switch.d.ts.map +1 -1
- package/dist/src/components/Switch.js +1 -1
- package/dist/src/components/Wrap.d.ts +1 -1
- package/dist/src/components/Wrap.d.ts.map +1 -1
- package/dist/src/context/assignment.d.ts +1 -1
- package/dist/src/context/assignment.d.ts.map +1 -1
- package/dist/src/context/binder.d.ts +2 -2
- package/dist/src/context/binder.d.ts.map +1 -1
- package/dist/src/context/declaration.d.ts +1 -1
- package/dist/src/context/declaration.d.ts.map +1 -1
- package/dist/src/context/member-declaration.d.ts +1 -1
- package/dist/src/context/member-declaration.d.ts.map +1 -1
- package/dist/src/context/member-declaration.js +0 -1
- package/dist/src/context/member-scope.d.ts +1 -1
- package/dist/src/context/member-scope.d.ts.map +1 -1
- package/dist/src/context/name-policy.d.ts +1 -1
- package/dist/src/context/name-policy.d.ts.map +1 -1
- package/dist/src/context/scope.d.ts +1 -1
- package/dist/src/context/scope.d.ts.map +1 -1
- package/dist/src/context/source-directory.d.ts +1 -1
- package/dist/src/context/source-directory.d.ts.map +1 -1
- package/dist/src/context/source-file.d.ts +2 -2
- package/dist/src/context/source-file.d.ts.map +1 -1
- package/dist/src/index.d.ts +4 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +4 -1
- package/dist/src/jsx-runtime.d.ts +12 -3
- package/dist/src/jsx-runtime.d.ts.map +1 -1
- package/dist/src/jsx-runtime.js +6 -2
- package/dist/src/reactive-union-set.d.ts +29 -0
- package/dist/src/reactive-union-set.d.ts.map +1 -0
- package/dist/src/reactive-union-set.js +183 -0
- package/dist/src/refkey.d.ts +36 -0
- package/dist/src/refkey.d.ts.map +1 -1
- package/dist/src/refkey.js +40 -0
- package/dist/src/scheduler.d.ts +2 -2
- package/dist/src/scheduler.d.ts.map +1 -1
- package/dist/src/scheduler.js +27 -6
- package/dist/src/slot.d.ts +1 -1
- package/dist/src/slot.d.ts.map +1 -1
- package/dist/src/stc.d.ts +1 -1
- package/dist/src/stc.d.ts.map +1 -1
- package/dist/src/sti.d.ts +1 -1
- package/dist/src/sti.d.ts.map +1 -1
- package/dist/src/sti.js +1 -1
- package/dist/src/symbols/index.d.ts +6 -0
- package/dist/src/symbols/index.d.ts.map +1 -0
- package/dist/src/symbols/index.js +5 -0
- package/dist/src/symbols/output-scope.d.ts +116 -0
- package/dist/src/symbols/output-scope.d.ts.map +1 -0
- package/dist/src/symbols/output-scope.js +246 -0
- package/dist/src/symbols/output-symbol.d.ts +134 -0
- package/dist/src/symbols/output-symbol.d.ts.map +1 -0
- package/dist/src/symbols/output-symbol.js +379 -0
- package/dist/src/symbols/symbol-flow.d.ts +13 -0
- package/dist/src/symbols/symbol-flow.d.ts.map +1 -0
- package/dist/src/symbols/symbol-flow.js +74 -0
- package/dist/src/symbols/symbol-slot.d.ts +12 -0
- package/dist/src/symbols/symbol-slot.d.ts.map +1 -0
- package/dist/src/symbols/symbol-slot.js +36 -0
- package/dist/src/symbols/symbol-table.d.ts +14 -0
- package/dist/src/symbols/symbol-table.d.ts.map +1 -0
- package/dist/src/symbols/symbol-table.js +42 -0
- package/dist/src/tap.d.ts +2 -1
- package/dist/src/tap.d.ts.map +1 -1
- package/dist/src/tracer.d.ts +181 -0
- package/dist/src/tracer.d.ts.map +1 -0
- package/dist/src/tracer.js +441 -0
- package/dist/src/tsdoc-metadata.json +1 -1
- package/dist/test/components/slot.test.js +5 -7
- package/dist/test/reactive-union-set.test.d.ts +2 -0
- package/dist/test/reactive-union-set.test.d.ts.map +1 -0
- package/dist/test/reactive-union-set.test.js +170 -0
- package/dist/test/symbols/output-scope.test.d.ts +2 -0
- package/dist/test/symbols/output-scope.test.d.ts.map +1 -0
- package/dist/test/symbols/output-scope.test.js +342 -0
- package/dist/test/symbols/output-symbol.test.d.ts +2 -0
- package/dist/test/symbols/output-symbol.test.d.ts.map +1 -0
- package/dist/test/symbols/output-symbol.test.js +446 -0
- package/dist/test/symbols/resolution.test.d.ts +2 -0
- package/dist/test/symbols/resolution.test.d.ts.map +1 -0
- package/dist/test/symbols/resolution.test.js +140 -0
- package/dist/test/symbols/utils.d.ts +24 -0
- package/dist/test/symbols/utils.d.ts.map +1 -0
- package/dist/test/symbols/utils.js +46 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/src/binder.ts +148 -672
- package/src/components/Block.tsx +4 -1
- package/src/components/Declaration.tsx +6 -6
- package/src/components/For.tsx +1 -1
- package/src/components/Indent.tsx +1 -1
- package/src/components/List.tsx +1 -1
- package/src/components/MemberDeclaration.tsx +4 -4
- package/src/components/MemberScope.tsx +2 -5
- package/src/components/Prose.tsx +1 -1
- package/src/components/ReferenceOrContent.tsx +1 -1
- package/src/components/Scope.tsx +2 -6
- package/src/components/Show.tsx +1 -1
- package/src/components/StatementList.tsx +2 -1
- package/src/components/Switch.tsx +1 -1
- package/src/components/Wrap.tsx +1 -1
- package/src/context/assignment.ts +1 -1
- package/src/context/binder.ts +2 -2
- package/src/context/declaration.ts +1 -1
- package/src/context/member-declaration.ts +1 -1
- package/src/context/member-scope.ts +1 -1
- package/src/context/name-policy.ts +1 -1
- package/src/context/scope.ts +1 -1
- package/src/context/source-directory.ts +1 -1
- package/src/context/source-file.ts +2 -2
- package/src/index.ts +15 -0
- package/src/jsx-runtime.ts +18 -2
- package/src/reactive-union-set.ts +238 -0
- package/src/refkey.ts +40 -0
- package/src/scheduler.ts +31 -6
- package/src/slot.ts +1 -1
- package/src/stc.ts +3 -3
- package/src/sti.ts +5 -5
- package/src/symbols/index.ts +5 -0
- package/src/symbols/output-scope.ts +323 -0
- package/src/symbols/output-symbol.ts +512 -0
- package/src/symbols/symbol-flow.ts +104 -0
- package/src/symbols/symbol-slot.tsx +47 -0
- package/src/symbols/symbol-table.ts +72 -0
- package/src/tap.ts +2 -1
- package/src/tracer.ts +440 -0
- package/temp/api.json +4172 -1582
- package/test/components/slot.test.tsx +8 -11
- package/test/reactive-union-set.test.tsx +191 -0
- package/test/symbols/output-scope.test.ts +302 -0
- package/test/symbols/output-symbol.test.ts +459 -0
- package/test/symbols/resolution.test.ts +172 -0
- package/test/symbols/utils.ts +95 -0
- package/dist/test/symbols.test.d.ts +0 -2
- package/dist/test/symbols.test.d.ts.map +0 -1
- package/dist/test/symbols.test.js +0 -884
- package/test/symbols.test.ts +0 -1006
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { effect } from "@alloy-js/core/jsx-runtime";
|
|
2
|
+
import { reactive } from "@vue/reactivity";
|
|
3
|
+
import { describe, expect, it } from "vitest";
|
|
4
|
+
import { ReactiveUnionSet } from "../src/reactive-union-set.js";
|
|
5
|
+
import { flushJobs } from "../src/scheduler.js";
|
|
6
|
+
describe("is reactive", () => {
|
|
7
|
+
it("on size", () => {
|
|
8
|
+
const set = new ReactiveUnionSet();
|
|
9
|
+
let callCount = 0;
|
|
10
|
+
effect(() => {
|
|
11
|
+
callCount++;
|
|
12
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
13
|
+
set.size;
|
|
14
|
+
});
|
|
15
|
+
set.add(1);
|
|
16
|
+
flushJobs();
|
|
17
|
+
expect(callCount).toBe(2);
|
|
18
|
+
});
|
|
19
|
+
it("on iteration", () => {
|
|
20
|
+
const set = new ReactiveUnionSet();
|
|
21
|
+
let callCount = 0;
|
|
22
|
+
effect(() => {
|
|
23
|
+
callCount++;
|
|
24
|
+
for (const _ of set) {
|
|
25
|
+
// do nothing
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
set.add(1);
|
|
29
|
+
flushJobs();
|
|
30
|
+
expect(callCount).toBe(2);
|
|
31
|
+
});
|
|
32
|
+
it("on deletion with iteration", () => {
|
|
33
|
+
const set = new ReactiveUnionSet();
|
|
34
|
+
let callCount = 0;
|
|
35
|
+
effect(() => {
|
|
36
|
+
callCount++;
|
|
37
|
+
for (const _ of set) {
|
|
38
|
+
// do nothing
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
set.add(1);
|
|
42
|
+
flushJobs();
|
|
43
|
+
expect(callCount).toBe(2);
|
|
44
|
+
set.delete(1);
|
|
45
|
+
flushJobs();
|
|
46
|
+
expect(callCount).toBe(3);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
it("adds items to main set from subset", () => {
|
|
50
|
+
const set = new ReactiveUnionSet();
|
|
51
|
+
const subset1 = reactive(new Set());
|
|
52
|
+
const subset2 = reactive(new Set());
|
|
53
|
+
set.addSubset(subset1);
|
|
54
|
+
set.addSubset(subset2);
|
|
55
|
+
subset1.add(1);
|
|
56
|
+
subset2.add(2);
|
|
57
|
+
flushJobs();
|
|
58
|
+
expect(set.has(1)).toBe(true);
|
|
59
|
+
expect(set.has(2)).toBe(true);
|
|
60
|
+
subset1.delete(1);
|
|
61
|
+
flushJobs();
|
|
62
|
+
expect(set.has(1)).toBe(false);
|
|
63
|
+
});
|
|
64
|
+
it("doesn't remove items that are present in more than one subset", () => {
|
|
65
|
+
const set = new ReactiveUnionSet();
|
|
66
|
+
const subset1 = reactive(new Set());
|
|
67
|
+
const subset2 = reactive(new Set());
|
|
68
|
+
set.addSubset(subset1);
|
|
69
|
+
set.addSubset(subset2);
|
|
70
|
+
subset1.add(1);
|
|
71
|
+
subset2.add(1);
|
|
72
|
+
flushJobs();
|
|
73
|
+
expect(set.has(1)).toBe(true);
|
|
74
|
+
subset1.delete(1);
|
|
75
|
+
flushJobs();
|
|
76
|
+
expect(set.has(1)).toBe(true);
|
|
77
|
+
subset2.delete(1);
|
|
78
|
+
flushJobs();
|
|
79
|
+
expect(set.has(1)).toBe(false);
|
|
80
|
+
});
|
|
81
|
+
it("removes all items when you clear the subset", () => {
|
|
82
|
+
const set = new ReactiveUnionSet();
|
|
83
|
+
const subset1 = reactive(new Set());
|
|
84
|
+
const subset2 = reactive(new Set());
|
|
85
|
+
set.addSubset(subset1);
|
|
86
|
+
set.addSubset(subset2);
|
|
87
|
+
subset1.add(1);
|
|
88
|
+
subset1.add(2);
|
|
89
|
+
subset1.add(3);
|
|
90
|
+
subset2.add(1);
|
|
91
|
+
flushJobs();
|
|
92
|
+
expect(set.size).toBe(3);
|
|
93
|
+
subset1.clear();
|
|
94
|
+
flushJobs();
|
|
95
|
+
expect(set.size).toBe(1);
|
|
96
|
+
});
|
|
97
|
+
describe("indexing", () => {
|
|
98
|
+
it("creates an index of properties", () => {
|
|
99
|
+
const set = new ReactiveUnionSet();
|
|
100
|
+
const index = set.createIndex(item => item.id);
|
|
101
|
+
let callCount = 0;
|
|
102
|
+
effect(() => {
|
|
103
|
+
callCount++;
|
|
104
|
+
index.values();
|
|
105
|
+
});
|
|
106
|
+
const brian = {
|
|
107
|
+
id: 1,
|
|
108
|
+
name: "brian"
|
|
109
|
+
};
|
|
110
|
+
const timothee = {
|
|
111
|
+
id: 2,
|
|
112
|
+
name: "timothee"
|
|
113
|
+
};
|
|
114
|
+
set.add(brian);
|
|
115
|
+
set.add(timothee);
|
|
116
|
+
flushJobs();
|
|
117
|
+
expect(callCount).toBe(2);
|
|
118
|
+
expect(index.get(1)).toEqual(brian);
|
|
119
|
+
expect(index.get(2)).toEqual(timothee);
|
|
120
|
+
set.delete(brian);
|
|
121
|
+
flushJobs();
|
|
122
|
+
expect(callCount).toBe(3);
|
|
123
|
+
expect(index.get(1)).toBeUndefined();
|
|
124
|
+
});
|
|
125
|
+
it("updates the index when the item changeS", () => {
|
|
126
|
+
const set = new ReactiveUnionSet();
|
|
127
|
+
const index = set.createIndex(item => item.id);
|
|
128
|
+
let callCount = 0;
|
|
129
|
+
effect(() => {
|
|
130
|
+
callCount++;
|
|
131
|
+
index.values();
|
|
132
|
+
});
|
|
133
|
+
const brian = reactive({
|
|
134
|
+
id: 1,
|
|
135
|
+
name: "brian"
|
|
136
|
+
});
|
|
137
|
+
set.add(brian);
|
|
138
|
+
flushJobs();
|
|
139
|
+
expect(index.get(1)).toEqual(brian);
|
|
140
|
+
brian.id = 2;
|
|
141
|
+
flushJobs();
|
|
142
|
+
expect(callCount).toBe(3);
|
|
143
|
+
expect(index.get(2)).toEqual(brian);
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
describe("derived sets", () => {
|
|
147
|
+
it("creates a derived set", () => {
|
|
148
|
+
const set = new ReactiveUnionSet();
|
|
149
|
+
const derivedSet = set.createDerivedSet(item => item.name);
|
|
150
|
+
const brian = {
|
|
151
|
+
id: 1,
|
|
152
|
+
name: "brian"
|
|
153
|
+
};
|
|
154
|
+
const timothee = {
|
|
155
|
+
id: 2,
|
|
156
|
+
name: "timothee"
|
|
157
|
+
};
|
|
158
|
+
set.add(brian);
|
|
159
|
+
set.add(timothee);
|
|
160
|
+
flushJobs();
|
|
161
|
+
expect(derivedSet.size).toBe(2);
|
|
162
|
+
expect(derivedSet.has("brian")).toBe(true);
|
|
163
|
+
expect(derivedSet.has("timothee")).toBe(true);
|
|
164
|
+
set.delete(brian);
|
|
165
|
+
flushJobs();
|
|
166
|
+
expect(derivedSet.size).toBe(1);
|
|
167
|
+
expect(derivedSet.has("brian")).toBe(false);
|
|
168
|
+
expect(derivedSet.has("timothee")).toBe(true);
|
|
169
|
+
});
|
|
170
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output-scope.test.d.ts","sourceRoot":"","sources":["../../../test/symbols/output-scope.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
import { reactive, watch } from "@vue/reactivity";
|
|
2
|
+
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
3
|
+
import { createOutputBinder } from "../../src/binder.js";
|
|
4
|
+
import { flushJobs } from "../../src/scheduler.js";
|
|
5
|
+
import { OutputScope, OutputScopeFlags } from "../../src/symbols/output-scope.js";
|
|
6
|
+
import { OutputSymbol } from "../../src/symbols/output-symbol.js";
|
|
7
|
+
import { SymbolTable } from "../../src/symbols/symbol-table.js";
|
|
8
|
+
let binder;
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
binder = createOutputBinder();
|
|
11
|
+
});
|
|
12
|
+
describe("OutputScope constructor", () => {
|
|
13
|
+
it("initializes properties correctly with default options", () => {
|
|
14
|
+
const scope = new OutputScope("testScope", {
|
|
15
|
+
binder
|
|
16
|
+
});
|
|
17
|
+
expect(scope.name).toBe("testScope");
|
|
18
|
+
expect(scope.binder).toBe(binder);
|
|
19
|
+
expect(scope.id).toEqual(expect.any(Number));
|
|
20
|
+
expect(scope.kind).toBe("scope");
|
|
21
|
+
expect(scope.flags).toBe(OutputScopeFlags.None);
|
|
22
|
+
expect(scope.metadata).toEqual({});
|
|
23
|
+
expect(scope.parent).toBe(binder.globalScope);
|
|
24
|
+
expect(scope.owner).toBeUndefined();
|
|
25
|
+
expect(scope.symbols).toBeInstanceOf(SymbolTable);
|
|
26
|
+
expect(scope.symbolNames.size).toBe(0);
|
|
27
|
+
expect(scope.children.size).toBe(0);
|
|
28
|
+
});
|
|
29
|
+
it("initializes properties correctly with custom options", () => {
|
|
30
|
+
const parentScope = new OutputScope("parentScope", {
|
|
31
|
+
binder
|
|
32
|
+
});
|
|
33
|
+
const metadata = {
|
|
34
|
+
foo: "bar"
|
|
35
|
+
};
|
|
36
|
+
const scope = new OutputScope("testScope", {
|
|
37
|
+
binder,
|
|
38
|
+
kind: "namespace",
|
|
39
|
+
metadata,
|
|
40
|
+
parent: parentScope
|
|
41
|
+
});
|
|
42
|
+
expect(scope.name).toBe("testScope");
|
|
43
|
+
expect(scope.kind).toBe("namespace");
|
|
44
|
+
expect(scope.flags).toBe(OutputScopeFlags.None);
|
|
45
|
+
expect(scope.metadata.foo).toBe("bar");
|
|
46
|
+
expect(scope.parent).toBe(parentScope);
|
|
47
|
+
expect(parentScope.children.has(scope)).toBe(true);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
describe("OutputScope reactivity", () => {
|
|
51
|
+
it("is reactive on name", () => {
|
|
52
|
+
const scope = new OutputScope("initialName", {
|
|
53
|
+
binder
|
|
54
|
+
});
|
|
55
|
+
const nameSpy = vi.fn();
|
|
56
|
+
watch(() => scope.name, nameSpy);
|
|
57
|
+
scope.name = "newName";
|
|
58
|
+
flushJobs();
|
|
59
|
+
expect(nameSpy).toHaveBeenCalled();
|
|
60
|
+
expect(scope.name).toBe("newName");
|
|
61
|
+
});
|
|
62
|
+
it("is reactive on flags", () => {
|
|
63
|
+
const scope = new OutputScope("scope", {
|
|
64
|
+
binder
|
|
65
|
+
});
|
|
66
|
+
const flagsSpy = vi.fn();
|
|
67
|
+
watch(() => scope.flags, flagsSpy);
|
|
68
|
+
scope.flags = OutputScopeFlags.InstanceMemberScope;
|
|
69
|
+
flushJobs();
|
|
70
|
+
expect(flagsSpy).toHaveBeenCalled();
|
|
71
|
+
expect(scope.flags).toBe(OutputScopeFlags.InstanceMemberScope);
|
|
72
|
+
});
|
|
73
|
+
it("updates symbolNames when symbols are added", () => {
|
|
74
|
+
const scope = new OutputScope("scope", {
|
|
75
|
+
binder
|
|
76
|
+
});
|
|
77
|
+
const symbolNamesSpy = vi.fn();
|
|
78
|
+
watch(() => scope.symbolNames.size, symbolNamesSpy);
|
|
79
|
+
new OutputSymbol("symbol1", {
|
|
80
|
+
binder,
|
|
81
|
+
scope
|
|
82
|
+
});
|
|
83
|
+
flushJobs();
|
|
84
|
+
expect(symbolNamesSpy).toHaveBeenCalled();
|
|
85
|
+
expect(scope.symbolNames.has("symbol1")).toBe(true);
|
|
86
|
+
});
|
|
87
|
+
it("updates symbolNames when a symbol's name changes", () => {
|
|
88
|
+
const scope = new OutputScope("scope", {
|
|
89
|
+
binder
|
|
90
|
+
});
|
|
91
|
+
const symbol = new OutputSymbol("oldName", {
|
|
92
|
+
binder,
|
|
93
|
+
scope
|
|
94
|
+
});
|
|
95
|
+
flushJobs();
|
|
96
|
+
|
|
97
|
+
// Verify initial state
|
|
98
|
+
expect(scope.symbolNames.has("oldName")).toBe(true);
|
|
99
|
+
expect(scope.symbolNames.has("newName")).toBe(false);
|
|
100
|
+
|
|
101
|
+
// Set up tracking for symbol names
|
|
102
|
+
const symbolNamesTracker = vi.fn();
|
|
103
|
+
watch(() => ({
|
|
104
|
+
hasOld: scope.symbolNames.has("oldName"),
|
|
105
|
+
hasNew: scope.symbolNames.has("newName")
|
|
106
|
+
}), symbolNamesTracker, {
|
|
107
|
+
deep: true
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// Change the name
|
|
111
|
+
symbol.name = "newName";
|
|
112
|
+
flushJobs();
|
|
113
|
+
|
|
114
|
+
// Verify the changes
|
|
115
|
+
expect(symbolNamesTracker).toHaveBeenCalled();
|
|
116
|
+
expect(scope.symbolNames.has("oldName")).toBe(false);
|
|
117
|
+
expect(scope.symbolNames.has("newName")).toBe(true);
|
|
118
|
+
});
|
|
119
|
+
it("doesn't get wrapped in a reactive proxy", () => {
|
|
120
|
+
const scope = new OutputScope("scope", {
|
|
121
|
+
binder
|
|
122
|
+
});
|
|
123
|
+
const rScope = reactive(scope);
|
|
124
|
+
expect(rScope).toBe(scope);
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
describe("OutputScope#symbols", () => {
|
|
128
|
+
it("adds symbols to its collection", () => {
|
|
129
|
+
const scope = new OutputScope("scope", {
|
|
130
|
+
binder
|
|
131
|
+
});
|
|
132
|
+
const sym1 = new OutputSymbol("sym1", {
|
|
133
|
+
binder,
|
|
134
|
+
scope
|
|
135
|
+
});
|
|
136
|
+
const sym2 = new OutputSymbol("sym2", {
|
|
137
|
+
binder,
|
|
138
|
+
scope
|
|
139
|
+
});
|
|
140
|
+
flushJobs();
|
|
141
|
+
expect(scope.symbols.size).toBe(2);
|
|
142
|
+
expect(scope.symbols.has(sym1)).toBe(true);
|
|
143
|
+
expect(scope.symbols.has(sym2)).toBe(true);
|
|
144
|
+
});
|
|
145
|
+
it("resolves symbol name conflicts", () => {
|
|
146
|
+
const scope = new OutputScope("scope", {
|
|
147
|
+
binder
|
|
148
|
+
});
|
|
149
|
+
const s1 = new OutputSymbol("sym", {
|
|
150
|
+
binder,
|
|
151
|
+
scope
|
|
152
|
+
});
|
|
153
|
+
const s2 = new OutputSymbol("sym", {
|
|
154
|
+
binder,
|
|
155
|
+
scope
|
|
156
|
+
});
|
|
157
|
+
const s3 = new OutputSymbol("sym", {
|
|
158
|
+
binder,
|
|
159
|
+
scope
|
|
160
|
+
});
|
|
161
|
+
flushJobs();
|
|
162
|
+
expect(s1.name).toBe("sym");
|
|
163
|
+
expect(s2.name).toBe("sym_2");
|
|
164
|
+
expect(s3.name).toBe("sym_3");
|
|
165
|
+
expect(scope.symbolNames.has("sym")).toBe(true);
|
|
166
|
+
expect(scope.symbolNames.has("sym_2")).toBe(true);
|
|
167
|
+
expect(scope.symbolNames.has("sym_3")).toBe(true);
|
|
168
|
+
});
|
|
169
|
+
it("updates when a symbol is deleted", () => {
|
|
170
|
+
const scope = new OutputScope("scope", {
|
|
171
|
+
binder
|
|
172
|
+
});
|
|
173
|
+
const sym = new OutputSymbol("sym", {
|
|
174
|
+
binder,
|
|
175
|
+
scope
|
|
176
|
+
});
|
|
177
|
+
flushJobs();
|
|
178
|
+
expect(scope.symbols.size).toBe(1);
|
|
179
|
+
expect(scope.symbols.has(sym)).toBe(true);
|
|
180
|
+
expect(scope.symbolNames.has("sym")).toBe(true);
|
|
181
|
+
sym.delete();
|
|
182
|
+
flushJobs();
|
|
183
|
+
expect(scope.symbols.size).toBe(0);
|
|
184
|
+
expect(scope.symbols.has(sym)).toBe(false);
|
|
185
|
+
expect(scope.symbolNames.has("sym")).toBe(false);
|
|
186
|
+
});
|
|
187
|
+
it("updates when a symbol changes scope", () => {
|
|
188
|
+
const scope1 = new OutputScope("scope1", {
|
|
189
|
+
binder
|
|
190
|
+
});
|
|
191
|
+
const scope2 = new OutputScope("scope2", {
|
|
192
|
+
binder
|
|
193
|
+
});
|
|
194
|
+
const sym = new OutputSymbol("sym", {
|
|
195
|
+
binder,
|
|
196
|
+
scope: scope1
|
|
197
|
+
});
|
|
198
|
+
flushJobs();
|
|
199
|
+
expect(scope1.symbols.size).toBe(1);
|
|
200
|
+
expect(scope2.symbols.size).toBe(0);
|
|
201
|
+
sym.scope = scope2;
|
|
202
|
+
flushJobs();
|
|
203
|
+
expect(scope1.symbols.size).toBe(0);
|
|
204
|
+
expect(scope2.symbols.size).toBe(1);
|
|
205
|
+
expect(scope1.symbols.has(sym)).toBe(false);
|
|
206
|
+
expect(scope2.symbols.has(sym)).toBe(true);
|
|
207
|
+
expect(scope1.symbolNames.has("sym")).toBe(false);
|
|
208
|
+
expect(scope2.symbolNames.has("sym")).toBe(true);
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
describe("OutputScope#symbolsByRefkey", () => {
|
|
212
|
+
it("maps refkeys to symbols", () => {
|
|
213
|
+
const scope = new OutputScope("scope", {
|
|
214
|
+
binder
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
// Use the refkey function to create refkeys
|
|
218
|
+
// This is based on how refkey is being imported in binder.ts
|
|
219
|
+
const key1 = "key1";
|
|
220
|
+
const key2a = "key2a";
|
|
221
|
+
const key2b = "key2b";
|
|
222
|
+
|
|
223
|
+
// Create a symbol with a refkey
|
|
224
|
+
const sym1 = new OutputSymbol("sym1", {
|
|
225
|
+
binder,
|
|
226
|
+
scope,
|
|
227
|
+
refkeys: [key1]
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
// Create a symbol with multiple refkeys
|
|
231
|
+
const sym2 = new OutputSymbol("sym2", {
|
|
232
|
+
binder,
|
|
233
|
+
scope,
|
|
234
|
+
refkeys: [key2a, key2b]
|
|
235
|
+
});
|
|
236
|
+
flushJobs();
|
|
237
|
+
expect(scope.symbolsByRefkey.get(key1)).toBe(sym1);
|
|
238
|
+
expect(scope.symbolsByRefkey.get(key2a)).toBe(sym2);
|
|
239
|
+
expect(scope.symbolsByRefkey.get(key2b)).toBe(sym2);
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
describe("OutputScope#children", () => {
|
|
243
|
+
it("tracks child scopes", () => {
|
|
244
|
+
const parentScope = new OutputScope("parent", {
|
|
245
|
+
binder
|
|
246
|
+
});
|
|
247
|
+
const child1 = new OutputScope("child1", {
|
|
248
|
+
binder,
|
|
249
|
+
parent: parentScope
|
|
250
|
+
});
|
|
251
|
+
const child2 = new OutputScope("child2", {
|
|
252
|
+
binder,
|
|
253
|
+
parent: parentScope
|
|
254
|
+
});
|
|
255
|
+
flushJobs();
|
|
256
|
+
expect(parentScope.children.size).toBe(2);
|
|
257
|
+
expect(parentScope.children.has(child1)).toBe(true);
|
|
258
|
+
expect(parentScope.children.has(child2)).toBe(true);
|
|
259
|
+
|
|
260
|
+
// Check that each child's parent is set correctly
|
|
261
|
+
expect(child1.parent).toBe(parentScope);
|
|
262
|
+
expect(child2.parent).toBe(parentScope);
|
|
263
|
+
});
|
|
264
|
+
});
|
|
265
|
+
describe("OutputScope#clone", () => {
|
|
266
|
+
let originalScope;
|
|
267
|
+
const originalMetadata = {
|
|
268
|
+
data: "original",
|
|
269
|
+
nested: {
|
|
270
|
+
value: 1
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
beforeEach(() => {
|
|
274
|
+
const parentScope = new OutputScope("parent", {
|
|
275
|
+
binder
|
|
276
|
+
});
|
|
277
|
+
originalScope = new OutputScope("original", {
|
|
278
|
+
binder: binder,
|
|
279
|
+
kind: "class",
|
|
280
|
+
metadata: {
|
|
281
|
+
...originalMetadata
|
|
282
|
+
},
|
|
283
|
+
parent: parentScope
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
// Add a symbol and child scope to the original
|
|
287
|
+
new OutputSymbol("symbolInOriginal", {
|
|
288
|
+
binder,
|
|
289
|
+
scope: originalScope
|
|
290
|
+
});
|
|
291
|
+
new OutputScope("childOfOriginal", {
|
|
292
|
+
binder,
|
|
293
|
+
parent: originalScope
|
|
294
|
+
});
|
|
295
|
+
flushJobs();
|
|
296
|
+
});
|
|
297
|
+
it("clones basic properties", () => {
|
|
298
|
+
const newScope = new OutputScope("newScope", {
|
|
299
|
+
binder
|
|
300
|
+
});
|
|
301
|
+
const clonedScope = originalScope.clone({
|
|
302
|
+
parent: newScope
|
|
303
|
+
});
|
|
304
|
+
expect(clonedScope.name).toBe(originalScope.name);
|
|
305
|
+
expect(clonedScope.kind).toBe(originalScope.kind);
|
|
306
|
+
expect(clonedScope.flags).toBe(originalScope.flags);
|
|
307
|
+
expect(clonedScope.id).not.toBe(originalScope.id);
|
|
308
|
+
expect(clonedScope.metadata).toEqual(originalScope.metadata);
|
|
309
|
+
expect(clonedScope.symbols.size).toBe(1);
|
|
310
|
+
expect(clonedScope.children.size).toBe(1);
|
|
311
|
+
});
|
|
312
|
+
it("can override parent in clone options", () => {
|
|
313
|
+
const newParent = new OutputScope("newParent", {
|
|
314
|
+
binder
|
|
315
|
+
});
|
|
316
|
+
const clonedScope = originalScope.clone({
|
|
317
|
+
parent: newParent
|
|
318
|
+
});
|
|
319
|
+
flushJobs();
|
|
320
|
+
expect(clonedScope.parent).toBe(newParent);
|
|
321
|
+
expect(newParent.children.has(clonedScope)).toBe(true);
|
|
322
|
+
});
|
|
323
|
+
it("can override owner in clone options", () => {
|
|
324
|
+
const newOwnerParent = new OutputScope("newOwnerParent", {
|
|
325
|
+
binder
|
|
326
|
+
});
|
|
327
|
+
const newOwner = new OutputSymbol("newOwner", {
|
|
328
|
+
binder,
|
|
329
|
+
scope: newOwnerParent
|
|
330
|
+
});
|
|
331
|
+
const clonedScope = originalScope.clone({
|
|
332
|
+
owner: newOwner
|
|
333
|
+
});
|
|
334
|
+
flushJobs();
|
|
335
|
+
expect(clonedScope.owner).toBe(newOwner);
|
|
336
|
+
});
|
|
337
|
+
it("allows independent changes to clone properties", () => {
|
|
338
|
+
const clonedScope = originalScope.clone();
|
|
339
|
+
clonedScope.name = "clonedName";
|
|
340
|
+
expect(originalScope.name).toBe("original");
|
|
341
|
+
});
|
|
342
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output-symbol.test.d.ts","sourceRoot":"","sources":["../../../test/symbols/output-symbol.test.ts"],"names":[],"mappings":""}
|