@alloy-js/core 0.23.0-dev.10 → 0.23.0-dev.9
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/dist/src/components/index.d.ts +0 -1
- package/dist/src/components/index.d.ts.map +1 -1
- package/dist/src/components/index.js +0 -1
- package/dist/src/components/index.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/components/index.tsx +0 -1
- package/temp/api.json +0 -639
- package/dist/src/components/AccessExpression.d.ts +0 -78
- package/dist/src/components/AccessExpression.d.ts.map +0 -1
- package/dist/src/components/AccessExpression.js +0 -218
- package/dist/src/components/AccessExpression.js.map +0 -1
- package/dist/src/components/AccessExpression.test.d.ts +0 -2
- package/dist/src/components/AccessExpression.test.d.ts.map +0 -1
- package/dist/src/components/AccessExpression.test.js +0 -137
- package/dist/src/components/AccessExpression.test.js.map +0 -1
- package/src/components/AccessExpression.test.tsx +0 -132
- package/src/components/AccessExpression.tsx +0 -344
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { Children, ComponentDefinition, OutputSymbol, Refkeyable } from "../index.js";
|
|
2
|
-
/**
|
|
3
|
-
* Base props that all language-specific Part components must include.
|
|
4
|
-
* Language packages extend this with additional props.
|
|
5
|
-
*/
|
|
6
|
-
export interface BasePartProps {
|
|
7
|
-
refkey?: Refkeyable;
|
|
8
|
-
symbol?: OutputSymbol;
|
|
9
|
-
}
|
|
10
|
-
/**
|
|
11
|
-
* Configuration for creating a language-specific access expression component.
|
|
12
|
-
*
|
|
13
|
-
* @typeParam TPartProps - The Part component's props type (extends BasePartProps)
|
|
14
|
-
* @typeParam TPart - The descriptor type that formatPart receives
|
|
15
|
-
*/
|
|
16
|
-
export interface AccessExpressionConfig<TPartProps extends BasePartProps, TPart> {
|
|
17
|
-
/**
|
|
18
|
-
* Convert Part props + resolved symbol into a plain descriptor object.
|
|
19
|
-
* Called once per Part during children processing. The returned descriptor
|
|
20
|
-
* is wrapped in a computed + getter delegation for reactive optimization.
|
|
21
|
-
*/
|
|
22
|
-
createDescriptor(props: TPartProps, symbol: OutputSymbol | undefined, first: boolean): TPart;
|
|
23
|
-
/**
|
|
24
|
-
* Extract the base content from the first part (the leftmost identifier).
|
|
25
|
-
*/
|
|
26
|
-
getBase(part: TPart): Children;
|
|
27
|
-
/**
|
|
28
|
-
* Format a non-first part given its descriptor and the previous part.
|
|
29
|
-
* Returns JSX children for that segment (e.g., `.foo`, `?.bar`, `[idx]`, `(args)`).
|
|
30
|
-
* `inCallChain` is true when rendering inside a chunked call chain.
|
|
31
|
-
*/
|
|
32
|
-
formatPart(part: TPart, prevPart: TPart, inCallChain: boolean): Children;
|
|
33
|
-
/**
|
|
34
|
-
* Identify which parts are function calls, for call chain detection.
|
|
35
|
-
* When provided, the factory uses the chunked call chain algorithm
|
|
36
|
-
* (line breaks after each call group) when more than one call is detected.
|
|
37
|
-
* When omitted, the expression is always formatted linearly.
|
|
38
|
-
*/
|
|
39
|
-
isCallPart?(part: TPart): boolean;
|
|
40
|
-
/**
|
|
41
|
-
* Additional check for whether call chain formatting should be used.
|
|
42
|
-
* Called only when `isCallPart` is provided and more than one call is detected.
|
|
43
|
-
* Return false to force linear formatting (e.g., TypeScript disables call
|
|
44
|
-
* chains when any part has `await`).
|
|
45
|
-
* Defaults to `() => true`.
|
|
46
|
-
*/
|
|
47
|
-
canUseCallChains?(parts: TPart[]): boolean;
|
|
48
|
-
/**
|
|
49
|
-
* Post-process the accumulated expression after each part in linear
|
|
50
|
-
* (non-call-chain) mode. Use this for language-specific wrapping like
|
|
51
|
-
* TypeScript's `await` which wraps the entire expression so far.
|
|
52
|
-
* Defaults to identity (returns expression unchanged).
|
|
53
|
-
*/
|
|
54
|
-
wrapPartResult?(expression: Children, part: TPart, index: number, isLast: boolean): Children;
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Create a language-specific access/member expression component pair.
|
|
58
|
-
*
|
|
59
|
-
* Returns `{ Expression, Part }` where:
|
|
60
|
-
* - `Expression` is the main component that collects Part children and renders the chain
|
|
61
|
-
* - `Part` is a no-op component whose props are consumed by Expression
|
|
62
|
-
*
|
|
63
|
-
* The factory handles:
|
|
64
|
-
* - Children collection and Part filtering
|
|
65
|
-
* - Symbol resolution (refkey → symbol via binder, single computed per part)
|
|
66
|
-
* - Reactive optimization (getter delegation over single computed per part)
|
|
67
|
-
* - Flattening nested Expression instances
|
|
68
|
-
* - `takeSymbols()` to prevent symbol leakage
|
|
69
|
-
* - Call chain detection and chunked formatting algorithm
|
|
70
|
-
*/
|
|
71
|
-
export declare function createAccessExpression<TPartProps extends BasePartProps, TPart extends Record<string, unknown>>(config: AccessExpressionConfig<TPartProps, TPart>): {
|
|
72
|
-
Expression: (props: {
|
|
73
|
-
children: Children;
|
|
74
|
-
}) => Children;
|
|
75
|
-
Part: (_props: TPartProps) => void;
|
|
76
|
-
registerOuterComponent: (component: ComponentDefinition<any>) => void;
|
|
77
|
-
};
|
|
78
|
-
//# sourceMappingURL=AccessExpression.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AccessExpression.d.ts","sourceRoot":"","sources":["../../../src/components/AccessExpression.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAGR,mBAAmB,EAGnB,YAAY,EACZ,UAAU,EAGX,MAAM,aAAa,CAAC;AAErB;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAED;;;;;GAKG;AACH,MAAM,WAAW,sBAAsB,CACrC,UAAU,SAAS,aAAa,EAChC,KAAK;IAEL;;;;OAIG;IACH,gBAAgB,CACd,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,YAAY,GAAG,SAAS,EAChC,KAAK,EAAE,OAAO,GACb,KAAK,CAAC;IAET;;OAEG;IACH,OAAO,CAAC,IAAI,EAAE,KAAK,GAAG,QAAQ,CAAC;IAE/B;;;;OAIG;IACH,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,GAAG,QAAQ,CAAC;IAEzE;;;;;OAKG;IACH,UAAU,CAAC,CAAC,IAAI,EAAE,KAAK,GAAG,OAAO,CAAC;IAElC;;;;;;OAMG;IACH,gBAAgB,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;IAE3C;;;;;OAKG;IACH,cAAc,CAAC,CACb,UAAU,EAAE,QAAQ,EACpB,IAAI,EAAE,KAAK,EACX,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,OAAO,GACd,QAAQ,CAAC;CACb;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CACpC,UAAU,SAAS,aAAa,EAChC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACrC,MAAM,EAAE,sBAAsB,CAAC,UAAU,EAAE,KAAK,CAAC;wBAMtB;QAAE,QAAQ,EAAE,QAAQ,CAAA;KAAE,KAAG,QAAQ;mBAiCtC,UAAU;wCAyEW,mBAAmB,CAAC,GAAG,CAAC;EAKpE"}
|
|
@@ -1,218 +0,0 @@
|
|
|
1
|
-
import { createIntrinsic as _$createIntrinsic } from "@alloy-js/core/jsx-runtime";
|
|
2
|
-
import { childrenArray, computed, isComponentCreator, symbolForRefkey, takeSymbols } from "../index.js";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Base props that all language-specific Part components must include.
|
|
6
|
-
* Language packages extend this with additional props.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Configuration for creating a language-specific access expression component.
|
|
11
|
-
*
|
|
12
|
-
* @typeParam TPartProps - The Part component's props type (extends BasePartProps)
|
|
13
|
-
* @typeParam TPart - The descriptor type that formatPart receives
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Create a language-specific access/member expression component pair.
|
|
18
|
-
*
|
|
19
|
-
* Returns `{ Expression, Part }` where:
|
|
20
|
-
* - `Expression` is the main component that collects Part children and renders the chain
|
|
21
|
-
* - `Part` is a no-op component whose props are consumed by Expression
|
|
22
|
-
*
|
|
23
|
-
* The factory handles:
|
|
24
|
-
* - Children collection and Part filtering
|
|
25
|
-
* - Symbol resolution (refkey → symbol via binder, single computed per part)
|
|
26
|
-
* - Reactive optimization (getter delegation over single computed per part)
|
|
27
|
-
* - Flattening nested Expression instances
|
|
28
|
-
* - `takeSymbols()` to prevent symbol leakage
|
|
29
|
-
* - Call chain detection and chunked formatting algorithm
|
|
30
|
-
*/
|
|
31
|
-
export function createAccessExpression(config) {
|
|
32
|
-
// Additional component references to match during flattening.
|
|
33
|
-
// Used when the wrapper function (e.g. MemberExpression) differs
|
|
34
|
-
// from the inner Expression function.
|
|
35
|
-
const outerComponents = [];
|
|
36
|
-
function Expression(props) {
|
|
37
|
-
const children = flattenExpression(childrenArray(() => props.children));
|
|
38
|
-
const parts = collectParts(children);
|
|
39
|
-
takeSymbols();
|
|
40
|
-
if (parts.length === 0) {
|
|
41
|
-
return [];
|
|
42
|
-
}
|
|
43
|
-
const {
|
|
44
|
-
isCallPart,
|
|
45
|
-
canUseCallChains
|
|
46
|
-
} = config;
|
|
47
|
-
if (!isCallPart) {
|
|
48
|
-
return formatLinear(config, parts);
|
|
49
|
-
}
|
|
50
|
-
const isCallChain = computed(() => {
|
|
51
|
-
if (canUseCallChains && !canUseCallChains(parts)) {
|
|
52
|
-
return false;
|
|
53
|
-
}
|
|
54
|
-
let callCount = 0;
|
|
55
|
-
for (const part of parts) {
|
|
56
|
-
if (isCallPart(part)) callCount++;
|
|
57
|
-
}
|
|
58
|
-
return callCount > 1;
|
|
59
|
-
});
|
|
60
|
-
return () => {
|
|
61
|
-
return isCallChain.value ? formatCallChain(config, parts) : formatLinear(config, parts);
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
function Part(_props) {
|
|
65
|
-
// No-op — props are consumed by the parent Expression component.
|
|
66
|
-
}
|
|
67
|
-
function isExpressionComponent(child) {
|
|
68
|
-
if (isComponentCreator(child, Expression)) return true;
|
|
69
|
-
for (const comp of outerComponents) {
|
|
70
|
-
if (isComponentCreator(child, comp)) return true;
|
|
71
|
-
}
|
|
72
|
-
return false;
|
|
73
|
-
}
|
|
74
|
-
function flattenExpression(children) {
|
|
75
|
-
const flattened = [];
|
|
76
|
-
for (const child of children) {
|
|
77
|
-
if (isExpressionComponent(child)) {
|
|
78
|
-
flattened.push(...flattenExpression(childrenArray(() => child.props.children)));
|
|
79
|
-
} else {
|
|
80
|
-
flattened.push(child);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
return flattened;
|
|
84
|
-
}
|
|
85
|
-
function collectParts(children) {
|
|
86
|
-
const parts = [];
|
|
87
|
-
for (const child of children) {
|
|
88
|
-
if (!isComponentCreator(child, Part)) continue;
|
|
89
|
-
const partProps = child.props;
|
|
90
|
-
const first = parts.length === 0;
|
|
91
|
-
const symbolSource = computed(() => {
|
|
92
|
-
if (partProps.refkey) {
|
|
93
|
-
return symbolForRefkey(partProps.refkey).value;
|
|
94
|
-
} else if (partProps.symbol) {
|
|
95
|
-
return partProps.symbol;
|
|
96
|
-
}
|
|
97
|
-
return undefined;
|
|
98
|
-
});
|
|
99
|
-
const desc = computed(() => config.createDescriptor(partProps, symbolSource.value, first));
|
|
100
|
-
|
|
101
|
-
// Create getter-delegation object for reactive optimization.
|
|
102
|
-
// Property access on this object tracks the single `desc` computed.
|
|
103
|
-
const keys = Object.keys(config.createDescriptor(partProps, undefined, first));
|
|
104
|
-
const proxy = {};
|
|
105
|
-
for (const key of keys) {
|
|
106
|
-
Object.defineProperty(proxy, key, {
|
|
107
|
-
get() {
|
|
108
|
-
return desc.value[key];
|
|
109
|
-
},
|
|
110
|
-
enumerable: true
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
parts.push(proxy);
|
|
114
|
-
}
|
|
115
|
-
return parts;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Register an outer wrapper component for flattening support.
|
|
120
|
-
* Call this after creating the wrapper function:
|
|
121
|
-
* `registerOuterComponent(MemberExpression);`
|
|
122
|
-
*/
|
|
123
|
-
function registerOuterComponent(component) {
|
|
124
|
-
outerComponents.push(component);
|
|
125
|
-
}
|
|
126
|
-
return {
|
|
127
|
-
Expression,
|
|
128
|
-
Part,
|
|
129
|
-
registerOuterComponent
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* Format parts linearly (no call chain grouping).
|
|
135
|
-
*/
|
|
136
|
-
function formatLinear(config, parts) {
|
|
137
|
-
return computed(() => {
|
|
138
|
-
let expression = [];
|
|
139
|
-
for (let i = 0; i < parts.length; i++) {
|
|
140
|
-
const part = parts[i];
|
|
141
|
-
if (i === 0) {
|
|
142
|
-
expression.push(config.getBase(part));
|
|
143
|
-
} else {
|
|
144
|
-
const prevPart = parts[i - 1];
|
|
145
|
-
const partExpr = config.formatPart(part, prevPart, false);
|
|
146
|
-
if (Array.isArray(expression)) {
|
|
147
|
-
expression.push(partExpr);
|
|
148
|
-
} else {
|
|
149
|
-
expression = [expression, partExpr];
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
if (config.wrapPartResult) {
|
|
153
|
-
expression = config.wrapPartResult(expression, part, i, i === parts.length - 1);
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
return expression;
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* Format parts as a call chain with indented line breaks at call boundaries.
|
|
162
|
-
*/
|
|
163
|
-
function formatCallChain(config, parts) {
|
|
164
|
-
return computed(() => {
|
|
165
|
-
const expression = [];
|
|
166
|
-
const chunks = [];
|
|
167
|
-
let pi = 0;
|
|
168
|
-
function pushPart() {
|
|
169
|
-
chunks.at(-1).push(parts[pi]);
|
|
170
|
-
pi++;
|
|
171
|
-
}
|
|
172
|
-
function pushChunk() {
|
|
173
|
-
chunks.push([]);
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
// First chunk: take parts up to and including the first call
|
|
177
|
-
pushChunk();
|
|
178
|
-
while (pi < parts.length && (pi === parts.length - 1 || chunks.at(-1).length === 0 || !config.isCallPart(parts[pi + 1]))) {
|
|
179
|
-
pushPart();
|
|
180
|
-
if (config.isCallPart(chunks.at(-1).at(-1))) {
|
|
181
|
-
break;
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
// Remaining chunks: collect non-call parts then call parts
|
|
186
|
-
while (pi < parts.length) {
|
|
187
|
-
pushChunk();
|
|
188
|
-
while (pi < parts.length && !config.isCallPart(parts[pi])) {
|
|
189
|
-
pushPart();
|
|
190
|
-
}
|
|
191
|
-
while (pi < parts.length && config.isCallPart(parts[pi])) {
|
|
192
|
-
pushPart();
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
for (let ci = 0; ci < chunks.length; ci++) {
|
|
196
|
-
const chunk = chunks[ci];
|
|
197
|
-
const chunkExpr = [];
|
|
198
|
-
for (let cpi = 0; cpi < chunk.length; cpi++) {
|
|
199
|
-
if (ci === 0 && cpi === 0) {
|
|
200
|
-
chunkExpr.push(config.getBase(chunk[0]));
|
|
201
|
-
continue;
|
|
202
|
-
}
|
|
203
|
-
const part = chunk[cpi];
|
|
204
|
-
const prevPart = cpi === 0 ? chunks[ci - 1].at(-1) : chunk[cpi - 1];
|
|
205
|
-
chunkExpr.push(config.formatPart(part, prevPart, true));
|
|
206
|
-
}
|
|
207
|
-
expression.push(ci === 0 ? chunkExpr : [_$createIntrinsic("sbr", {}), chunkExpr]);
|
|
208
|
-
}
|
|
209
|
-
return _$createIntrinsic("group", {
|
|
210
|
-
get children() {
|
|
211
|
-
return _$createIntrinsic("indent", {
|
|
212
|
-
children: expression
|
|
213
|
-
});
|
|
214
|
-
}
|
|
215
|
-
});
|
|
216
|
-
});
|
|
217
|
-
}
|
|
218
|
-
//# sourceMappingURL=AccessExpression.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["childrenArray","computed","isComponentCreator","symbolForRefkey","takeSymbols","createAccessExpression","config","outerComponents","Expression","props","children","flattenExpression","parts","collectParts","length","isCallPart","canUseCallChains","formatLinear","isCallChain","callCount","part","value","formatCallChain","Part","_props","isExpressionComponent","child","comp","flattened","push","partProps","first","symbolSource","refkey","symbol","undefined","desc","createDescriptor","keys","Object","proxy","key","defineProperty","get","enumerable","registerOuterComponent","component","expression","i","getBase","prevPart","partExpr","formatPart","Array","isArray","wrapPartResult","chunks","pi","pushPart","at","pushChunk","ci","chunk","chunkExpr","cpi","_$createIntrinsic"],"sources":["../../../src/components/AccessExpression.tsx"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AccessExpression.test.d.ts","sourceRoot":"","sources":["../../../src/components/AccessExpression.test.tsx"],"names":[],"mappings":"AACA,OAAO,gCAAgC,CAAC"}
|
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
import { createComponent as _$createComponent } from "@alloy-js/core/jsx-runtime";
|
|
2
|
-
import { describe, expect, it } from "vitest";
|
|
3
|
-
import "../../testing/extend-expect.js";
|
|
4
|
-
import { createAccessExpression } from "../components/AccessExpression.js";
|
|
5
|
-
import { code } from "../index.js";
|
|
6
|
-
import { printTree, renderTree } from "../render.js";
|
|
7
|
-
const {
|
|
8
|
-
Expression,
|
|
9
|
-
Part
|
|
10
|
-
} = createAccessExpression({
|
|
11
|
-
createDescriptor(props, symbol, first) {
|
|
12
|
-
return {
|
|
13
|
-
name: symbol?.name ?? props.name,
|
|
14
|
-
args: props.args,
|
|
15
|
-
isFirst: first
|
|
16
|
-
};
|
|
17
|
-
},
|
|
18
|
-
getBase(part) {
|
|
19
|
-
return part.name ?? "";
|
|
20
|
-
},
|
|
21
|
-
formatPart(part, _prevPart, _inCallChain) {
|
|
22
|
-
if (part.args !== undefined) {
|
|
23
|
-
return code`.${part.name}(${part.args})`;
|
|
24
|
-
}
|
|
25
|
-
return code`.${part.name}`;
|
|
26
|
-
},
|
|
27
|
-
isCallPart(part) {
|
|
28
|
-
return part.args !== undefined;
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
describe("createAccessExpression", () => {
|
|
32
|
-
it("renders a single part as the base", () => {
|
|
33
|
-
expect(_$createComponent(Expression, {
|
|
34
|
-
get children() {
|
|
35
|
-
return _$createComponent(Part, {
|
|
36
|
-
name: "foo"
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
})).toRenderTo("foo");
|
|
40
|
-
});
|
|
41
|
-
it("renders multiple parts with dot access", () => {
|
|
42
|
-
expect(_$createComponent(Expression, {
|
|
43
|
-
get children() {
|
|
44
|
-
return [_$createComponent(Part, {
|
|
45
|
-
name: "foo"
|
|
46
|
-
}), _$createComponent(Part, {
|
|
47
|
-
name: "bar"
|
|
48
|
-
}), _$createComponent(Part, {
|
|
49
|
-
name: "baz"
|
|
50
|
-
})];
|
|
51
|
-
}
|
|
52
|
-
})).toRenderTo("foo.bar.baz");
|
|
53
|
-
});
|
|
54
|
-
it("renders parts with call arguments", () => {
|
|
55
|
-
expect(_$createComponent(Expression, {
|
|
56
|
-
get children() {
|
|
57
|
-
return [_$createComponent(Part, {
|
|
58
|
-
name: "foo"
|
|
59
|
-
}), _$createComponent(Part, {
|
|
60
|
-
name: "bar",
|
|
61
|
-
args: "x, y"
|
|
62
|
-
})];
|
|
63
|
-
}
|
|
64
|
-
})).toRenderTo("foo.bar(x, y)");
|
|
65
|
-
});
|
|
66
|
-
it("returns empty for no parts", () => {
|
|
67
|
-
expect(_$createComponent(Expression, {
|
|
68
|
-
children: false
|
|
69
|
-
})).toRenderTo("");
|
|
70
|
-
});
|
|
71
|
-
it("flattens nested Expression instances", () => {
|
|
72
|
-
const inner = _$createComponent(Expression, {
|
|
73
|
-
get children() {
|
|
74
|
-
return [_$createComponent(Part, {
|
|
75
|
-
name: "bar"
|
|
76
|
-
}), _$createComponent(Part, {
|
|
77
|
-
name: "baz"
|
|
78
|
-
})];
|
|
79
|
-
}
|
|
80
|
-
});
|
|
81
|
-
expect(_$createComponent(Expression, {
|
|
82
|
-
get children() {
|
|
83
|
-
return [_$createComponent(Part, {
|
|
84
|
-
name: "foo"
|
|
85
|
-
}), inner];
|
|
86
|
-
}
|
|
87
|
-
})).toRenderTo("foo.bar.baz");
|
|
88
|
-
});
|
|
89
|
-
it("ignores non-Part children", () => {
|
|
90
|
-
expect(_$createComponent(Expression, {
|
|
91
|
-
get children() {
|
|
92
|
-
return [_$createComponent(Part, {
|
|
93
|
-
name: "foo"
|
|
94
|
-
}), "some string", _$createComponent(Part, {
|
|
95
|
-
name: "bar"
|
|
96
|
-
})];
|
|
97
|
-
}
|
|
98
|
-
})).toRenderTo("foo.bar");
|
|
99
|
-
});
|
|
100
|
-
});
|
|
101
|
-
describe("createAccessExpression: call chain formatting", () => {
|
|
102
|
-
it("uses linear format with only one call", () => {
|
|
103
|
-
const tree = renderTree(_$createComponent(Expression, {
|
|
104
|
-
get children() {
|
|
105
|
-
return [_$createComponent(Part, {
|
|
106
|
-
name: "foo"
|
|
107
|
-
}), _$createComponent(Part, {
|
|
108
|
-
name: "bar",
|
|
109
|
-
args: "x"
|
|
110
|
-
})];
|
|
111
|
-
}
|
|
112
|
-
}));
|
|
113
|
-
// Single call → linear, no grouping.
|
|
114
|
-
expect(printTree(tree)).toBe("foo.bar(x)");
|
|
115
|
-
});
|
|
116
|
-
it("uses call chain format with multiple calls", () => {
|
|
117
|
-
const tree = renderTree(_$createComponent(Expression, {
|
|
118
|
-
get children() {
|
|
119
|
-
return [_$createComponent(Part, {
|
|
120
|
-
name: "foo"
|
|
121
|
-
}), _$createComponent(Part, {
|
|
122
|
-
name: "bar",
|
|
123
|
-
args: "x"
|
|
124
|
-
}), _$createComponent(Part, {
|
|
125
|
-
name: "baz",
|
|
126
|
-
args: "y"
|
|
127
|
-
})];
|
|
128
|
-
}
|
|
129
|
-
}));
|
|
130
|
-
// Multiple calls → call chain with group/indent wrapping.
|
|
131
|
-
const result = printTree(tree);
|
|
132
|
-
// Should contain both calls.
|
|
133
|
-
expect(result).toContain("bar(x)");
|
|
134
|
-
expect(result).toContain("baz(y)");
|
|
135
|
-
});
|
|
136
|
-
});
|
|
137
|
-
//# sourceMappingURL=AccessExpression.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["describe","expect","it","createAccessExpression","code","printTree","renderTree","Expression","Part","createDescriptor","props","symbol","first","name","args","isFirst","getBase","part","formatPart","_prevPart","_inCallChain","undefined","isCallPart","_$createComponent","children","toRenderTo","inner","tree","toBe","result","toContain"],"sources":["../../../src/components/AccessExpression.test.tsx"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
|
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import "../../testing/extend-expect.js";
|
|
3
|
-
import {
|
|
4
|
-
BasePartProps,
|
|
5
|
-
createAccessExpression,
|
|
6
|
-
} from "../components/AccessExpression.jsx";
|
|
7
|
-
import { code } from "../index.js";
|
|
8
|
-
import { printTree, renderTree } from "../render.js";
|
|
9
|
-
import { Children } from "../runtime/component.js";
|
|
10
|
-
|
|
11
|
-
interface TestPartProps extends BasePartProps {
|
|
12
|
-
name?: string;
|
|
13
|
-
args?: Children;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
interface TestPart extends Record<string, unknown> {
|
|
17
|
-
name: string | undefined;
|
|
18
|
-
args: Children | undefined;
|
|
19
|
-
isFirst: boolean;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const { Expression, Part } = createAccessExpression<TestPartProps, TestPart>({
|
|
23
|
-
createDescriptor(props, symbol, first) {
|
|
24
|
-
return {
|
|
25
|
-
name: symbol?.name ?? props.name,
|
|
26
|
-
args: props.args,
|
|
27
|
-
isFirst: first,
|
|
28
|
-
};
|
|
29
|
-
},
|
|
30
|
-
|
|
31
|
-
getBase(part) {
|
|
32
|
-
return part.name ?? "";
|
|
33
|
-
},
|
|
34
|
-
|
|
35
|
-
formatPart(part, _prevPart, _inCallChain) {
|
|
36
|
-
if (part.args !== undefined) {
|
|
37
|
-
return code`.${part.name}(${part.args})`;
|
|
38
|
-
}
|
|
39
|
-
return code`.${part.name}`;
|
|
40
|
-
},
|
|
41
|
-
|
|
42
|
-
isCallPart(part) {
|
|
43
|
-
return part.args !== undefined;
|
|
44
|
-
},
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
describe("createAccessExpression", () => {
|
|
48
|
-
it("renders a single part as the base", () => {
|
|
49
|
-
expect(
|
|
50
|
-
<Expression>
|
|
51
|
-
<Part name="foo" />
|
|
52
|
-
</Expression>,
|
|
53
|
-
).toRenderTo("foo");
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
it("renders multiple parts with dot access", () => {
|
|
57
|
-
expect(
|
|
58
|
-
<Expression>
|
|
59
|
-
<Part name="foo" />
|
|
60
|
-
<Part name="bar" />
|
|
61
|
-
<Part name="baz" />
|
|
62
|
-
</Expression>,
|
|
63
|
-
).toRenderTo("foo.bar.baz");
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
it("renders parts with call arguments", () => {
|
|
67
|
-
expect(
|
|
68
|
-
<Expression>
|
|
69
|
-
<Part name="foo" />
|
|
70
|
-
<Part name="bar" args="x, y" />
|
|
71
|
-
</Expression>,
|
|
72
|
-
).toRenderTo("foo.bar(x, y)");
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
it("returns empty for no parts", () => {
|
|
76
|
-
expect(<Expression>{false}</Expression>).toRenderTo("");
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
it("flattens nested Expression instances", () => {
|
|
80
|
-
const inner = (
|
|
81
|
-
<Expression>
|
|
82
|
-
<Part name="bar" />
|
|
83
|
-
<Part name="baz" />
|
|
84
|
-
</Expression>
|
|
85
|
-
);
|
|
86
|
-
|
|
87
|
-
expect(
|
|
88
|
-
<Expression>
|
|
89
|
-
<Part name="foo" />
|
|
90
|
-
{inner}
|
|
91
|
-
</Expression>,
|
|
92
|
-
).toRenderTo("foo.bar.baz");
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
it("ignores non-Part children", () => {
|
|
96
|
-
expect(
|
|
97
|
-
<Expression>
|
|
98
|
-
<Part name="foo" />
|
|
99
|
-
{"some string"}
|
|
100
|
-
<Part name="bar" />
|
|
101
|
-
</Expression>,
|
|
102
|
-
).toRenderTo("foo.bar");
|
|
103
|
-
});
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
describe("createAccessExpression: call chain formatting", () => {
|
|
107
|
-
it("uses linear format with only one call", () => {
|
|
108
|
-
const tree = renderTree(
|
|
109
|
-
<Expression>
|
|
110
|
-
<Part name="foo" />
|
|
111
|
-
<Part name="bar" args="x" />
|
|
112
|
-
</Expression>,
|
|
113
|
-
);
|
|
114
|
-
// Single call → linear, no grouping.
|
|
115
|
-
expect(printTree(tree)).toBe("foo.bar(x)");
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
it("uses call chain format with multiple calls", () => {
|
|
119
|
-
const tree = renderTree(
|
|
120
|
-
<Expression>
|
|
121
|
-
<Part name="foo" />
|
|
122
|
-
<Part name="bar" args="x" />
|
|
123
|
-
<Part name="baz" args="y" />
|
|
124
|
-
</Expression>,
|
|
125
|
-
);
|
|
126
|
-
// Multiple calls → call chain with group/indent wrapping.
|
|
127
|
-
const result = printTree(tree);
|
|
128
|
-
// Should contain both calls.
|
|
129
|
-
expect(result).toContain("bar(x)");
|
|
130
|
-
expect(result).toContain("baz(y)");
|
|
131
|
-
});
|
|
132
|
-
});
|