@barefootjs/test 0.5.0 → 0.5.2
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/index.js +139 -29
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -187862,6 +187862,24 @@ function getSourceLocation(node, sourceFile, filePath) {
|
|
|
187862
187862
|
}
|
|
187863
187863
|
};
|
|
187864
187864
|
}
|
|
187865
|
+
function membersToProperties(members, sourceFile) {
|
|
187866
|
+
return members.filter(import_typescript6.default.isPropertySignature).map((member) => ({
|
|
187867
|
+
name: propertyNameText(member.name, sourceFile),
|
|
187868
|
+
type: typeNodeToTypeInfo(member.type, sourceFile) ?? {
|
|
187869
|
+
kind: "unknown",
|
|
187870
|
+
raw: "unknown"
|
|
187871
|
+
},
|
|
187872
|
+
optional: !!member.questionToken,
|
|
187873
|
+
readonly: !!member.modifiers?.some((m) => m.kind === import_typescript6.default.SyntaxKind.ReadonlyKeyword)
|
|
187874
|
+
}));
|
|
187875
|
+
}
|
|
187876
|
+
function propertyNameText(name, sourceFile) {
|
|
187877
|
+
if (!name)
|
|
187878
|
+
return "";
|
|
187879
|
+
if (import_typescript6.default.isStringLiteral(name) || import_typescript6.default.isNumericLiteral(name))
|
|
187880
|
+
return name.text;
|
|
187881
|
+
return name.getText(sourceFile);
|
|
187882
|
+
}
|
|
187865
187883
|
function typeNodeToTypeInfo(typeNode, sourceFile) {
|
|
187866
187884
|
if (!typeNode)
|
|
187867
187885
|
return null;
|
|
@@ -187899,18 +187917,21 @@ function typeNodeToTypeInfo(typeNode, sourceFile) {
|
|
|
187899
187917
|
return {
|
|
187900
187918
|
kind: "object",
|
|
187901
187919
|
raw,
|
|
187902
|
-
properties: typeNode.members
|
|
187903
|
-
name: member.name?.getText(sourceFile) ?? "",
|
|
187904
|
-
type: typeNodeToTypeInfo(member.type, sourceFile) ?? {
|
|
187905
|
-
kind: "unknown",
|
|
187906
|
-
raw: "unknown"
|
|
187907
|
-
},
|
|
187908
|
-
optional: !!member.questionToken,
|
|
187909
|
-
readonly: !!member.modifiers?.some((m) => m.kind === import_typescript6.default.SyntaxKind.ReadonlyKeyword)
|
|
187910
|
-
}))
|
|
187920
|
+
properties: membersToProperties(typeNode.members, sourceFile)
|
|
187911
187921
|
};
|
|
187912
187922
|
}
|
|
187913
187923
|
if (import_typescript6.default.isTypeReferenceNode(typeNode)) {
|
|
187924
|
+
const refName = import_typescript6.default.isIdentifier(typeNode.typeName) ? typeNode.typeName.text : "";
|
|
187925
|
+
if ((refName === "Array" || refName === "ReadonlyArray") && typeNode.typeArguments?.length === 1) {
|
|
187926
|
+
return {
|
|
187927
|
+
kind: "array",
|
|
187928
|
+
raw,
|
|
187929
|
+
elementType: typeNodeToTypeInfo(typeNode.typeArguments[0], sourceFile) ?? {
|
|
187930
|
+
kind: "unknown",
|
|
187931
|
+
raw: "unknown"
|
|
187932
|
+
}
|
|
187933
|
+
};
|
|
187934
|
+
}
|
|
187914
187935
|
return {
|
|
187915
187936
|
kind: "interface",
|
|
187916
187937
|
raw
|
|
@@ -189052,14 +189073,17 @@ function collectInterfaceDefinition(node, ctx) {
|
|
|
189052
189073
|
kind: "interface",
|
|
189053
189074
|
name: node.name.text,
|
|
189054
189075
|
definition: node.getText(ctx.sourceFile),
|
|
189076
|
+
properties: membersToProperties(node.members, ctx.sourceFile),
|
|
189055
189077
|
loc: getSourceLocation(node, ctx.sourceFile, ctx.filePath)
|
|
189056
189078
|
});
|
|
189057
189079
|
}
|
|
189058
189080
|
function collectTypeAliasDefinition(node, ctx) {
|
|
189081
|
+
const properties = import_typescript7.default.isTypeLiteralNode(node.type) ? membersToProperties(node.type.members, ctx.sourceFile) : undefined;
|
|
189059
189082
|
ctx.typeDefinitions.push({
|
|
189060
189083
|
kind: "type",
|
|
189061
189084
|
name: node.name.text,
|
|
189062
189085
|
definition: node.getText(ctx.sourceFile),
|
|
189086
|
+
properties,
|
|
189063
189087
|
loc: getSourceLocation(node, ctx.sourceFile, ctx.filePath)
|
|
189064
189088
|
});
|
|
189065
189089
|
}
|
|
@@ -190435,7 +190459,24 @@ var UNSUPPORTED_METHODS = new Set([
|
|
|
190435
190459
|
"some",
|
|
190436
190460
|
"forEach",
|
|
190437
190461
|
"flatMap",
|
|
190438
|
-
"flat"
|
|
190462
|
+
"flat",
|
|
190463
|
+
"split",
|
|
190464
|
+
"startsWith",
|
|
190465
|
+
"endsWith",
|
|
190466
|
+
"replace",
|
|
190467
|
+
"replaceAll",
|
|
190468
|
+
"repeat",
|
|
190469
|
+
"padStart",
|
|
190470
|
+
"padEnd",
|
|
190471
|
+
"charAt",
|
|
190472
|
+
"charCodeAt",
|
|
190473
|
+
"codePointAt",
|
|
190474
|
+
"normalize",
|
|
190475
|
+
"substring",
|
|
190476
|
+
"substr",
|
|
190477
|
+
"match",
|
|
190478
|
+
"matchAll",
|
|
190479
|
+
"search"
|
|
190439
190480
|
]);
|
|
190440
190481
|
function parseExpression(expr) {
|
|
190441
190482
|
const trimmed = expr.trim();
|
|
@@ -191297,7 +191338,7 @@ function checkSupport(expr) {
|
|
|
191297
191338
|
return {
|
|
191298
191339
|
supported: false,
|
|
191299
191340
|
level: "L5_UNSUPPORTED",
|
|
191300
|
-
reason: `
|
|
191341
|
+
reason: `Method '${methodName}()' has no template lowering and requires client-side evaluation. Wrap the expression in /* @client */ to defer it to hydration, or pre-compute the value before rendering.`
|
|
191301
191342
|
};
|
|
191302
191343
|
}
|
|
191303
191344
|
}
|
|
@@ -192681,6 +192722,23 @@ function containsJsxInExpression(node) {
|
|
|
192681
192722
|
}
|
|
192682
192723
|
return import_typescript11.default.forEachChild(node, containsJsxInExpression) ?? false;
|
|
192683
192724
|
}
|
|
192725
|
+
function callsJsxHelper(node, ctx) {
|
|
192726
|
+
let found = false;
|
|
192727
|
+
const visit2 = (n) => {
|
|
192728
|
+
if (found)
|
|
192729
|
+
return;
|
|
192730
|
+
if (import_typescript11.default.isCallExpression(n) && import_typescript11.default.isIdentifier(n.expression)) {
|
|
192731
|
+
const name = n.expression.text;
|
|
192732
|
+
if (ctx.analyzer.jsxFunctions.has(name) || ctx.analyzer.jsxMultiReturnFunctions.has(name)) {
|
|
192733
|
+
found = true;
|
|
192734
|
+
return;
|
|
192735
|
+
}
|
|
192736
|
+
}
|
|
192737
|
+
import_typescript11.default.forEachChild(n, visit2);
|
|
192738
|
+
};
|
|
192739
|
+
visit2(node);
|
|
192740
|
+
return found;
|
|
192741
|
+
}
|
|
192684
192742
|
function containsAwaitExpression(node) {
|
|
192685
192743
|
if (import_typescript11.default.isAwaitExpression(node))
|
|
192686
192744
|
return true;
|
|
@@ -192760,7 +192818,7 @@ function transformJsxExpression(expr, ctx, isClientOnly = false) {
|
|
|
192760
192818
|
if (node.operatorToken.kind === import_typescript11.default.SyntaxKind.AmpersandAmpersandToken) {
|
|
192761
192819
|
return transformLogicalAnd(node, ctx);
|
|
192762
192820
|
}
|
|
192763
|
-
if ((node.operatorToken.kind === import_typescript11.default.SyntaxKind.QuestionQuestionToken || node.operatorToken.kind === import_typescript11.default.SyntaxKind.BarBarToken) && containsJsxInExpression(node.right)) {
|
|
192821
|
+
if ((node.operatorToken.kind === import_typescript11.default.SyntaxKind.QuestionQuestionToken || node.operatorToken.kind === import_typescript11.default.SyntaxKind.BarBarToken) && (containsJsxInExpression(node.right) || callsJsxHelper(node.right, ctx))) {
|
|
192764
192822
|
return transformNullishCoalescing(node, ctx);
|
|
192765
192823
|
}
|
|
192766
192824
|
return null;
|
|
@@ -193217,23 +193275,23 @@ function checkLoopKey(callback, ctx, isNested) {
|
|
|
193217
193275
|
}
|
|
193218
193276
|
while (import_typescript11.default.isParenthesizedExpression(body))
|
|
193219
193277
|
body = body.expression;
|
|
193278
|
+
function checkJsxOperand(node) {
|
|
193279
|
+
let n = node;
|
|
193280
|
+
while (import_typescript11.default.isParenthesizedExpression(n))
|
|
193281
|
+
n = n.expression;
|
|
193282
|
+
if (import_typescript11.default.isJsxElement(n))
|
|
193283
|
+
checkOpening(n.openingElement);
|
|
193284
|
+
else if (import_typescript11.default.isJsxSelfClosingElement(n))
|
|
193285
|
+
checkOpening(n);
|
|
193286
|
+
}
|
|
193220
193287
|
if (import_typescript11.default.isConditionalExpression(body)) {
|
|
193221
|
-
|
|
193222
|
-
|
|
193223
|
-
|
|
193224
|
-
|
|
193225
|
-
|
|
193226
|
-
|
|
193227
|
-
|
|
193228
|
-
wf = wf.expression;
|
|
193229
|
-
if (import_typescript11.default.isJsxElement(wt))
|
|
193230
|
-
checkOpening(wt.openingElement);
|
|
193231
|
-
else if (import_typescript11.default.isJsxSelfClosingElement(wt))
|
|
193232
|
-
checkOpening(wt);
|
|
193233
|
-
if (import_typescript11.default.isJsxElement(wf))
|
|
193234
|
-
checkOpening(wf.openingElement);
|
|
193235
|
-
else if (import_typescript11.default.isJsxSelfClosingElement(wf))
|
|
193236
|
-
checkOpening(wf);
|
|
193288
|
+
checkJsxOperand(body.whenTrue);
|
|
193289
|
+
checkJsxOperand(body.whenFalse);
|
|
193290
|
+
return;
|
|
193291
|
+
}
|
|
193292
|
+
if (import_typescript11.default.isBinaryExpression(body) && (body.operatorToken.kind === import_typescript11.default.SyntaxKind.AmpersandAmpersandToken || body.operatorToken.kind === import_typescript11.default.SyntaxKind.BarBarToken || body.operatorToken.kind === import_typescript11.default.SyntaxKind.QuestionQuestionToken)) {
|
|
193293
|
+
checkJsxOperand(body.left);
|
|
193294
|
+
checkJsxOperand(body.right);
|
|
193237
193295
|
return;
|
|
193238
193296
|
}
|
|
193239
193297
|
if (import_typescript11.default.isJsxElement(body)) {
|
|
@@ -193256,6 +193314,38 @@ function loopBodyIsMultiRoot(children) {
|
|
|
193256
193314
|
return false;
|
|
193257
193315
|
return loopBodyIsMultiRoot(only.children);
|
|
193258
193316
|
}
|
|
193317
|
+
function branchHasNoElement(node) {
|
|
193318
|
+
if (node.type === "element" || node.type === "component")
|
|
193319
|
+
return false;
|
|
193320
|
+
if (node.type === "conditional") {
|
|
193321
|
+
return branchHasNoElement(node.whenTrue) || branchHasNoElement(node.whenFalse);
|
|
193322
|
+
}
|
|
193323
|
+
if (node.type === "fragment") {
|
|
193324
|
+
const real = node.children.filter((c) => !(c.type === "text" && typeof c.value === "string" && !c.value.trim()));
|
|
193325
|
+
return real.length !== 1 || branchHasNoElement(real[0]);
|
|
193326
|
+
}
|
|
193327
|
+
return true;
|
|
193328
|
+
}
|
|
193329
|
+
function loopBodyItemConditional(children) {
|
|
193330
|
+
const real = children.filter((c) => !(c.type === "text" && typeof c.value === "string" && !c.value.trim()));
|
|
193331
|
+
if (real.length !== 1)
|
|
193332
|
+
return null;
|
|
193333
|
+
const only = real[0];
|
|
193334
|
+
if (only.type !== "conditional")
|
|
193335
|
+
return null;
|
|
193336
|
+
if (branchHasNoElement(only.whenTrue) || branchHasNoElement(only.whenFalse)) {
|
|
193337
|
+
return only;
|
|
193338
|
+
}
|
|
193339
|
+
return null;
|
|
193340
|
+
}
|
|
193341
|
+
function extractItemConditionalKey(cond) {
|
|
193342
|
+
const a = branchHasNoElement(cond.whenTrue) ? null : extractLoopKey(cond.whenTrue);
|
|
193343
|
+
const b = branchHasNoElement(cond.whenFalse) ? null : extractLoopKey(cond.whenFalse);
|
|
193344
|
+
if (a !== null && b !== null) {
|
|
193345
|
+
return normalizeKeyExpr(a) === normalizeKeyExpr(b) ? a : null;
|
|
193346
|
+
}
|
|
193347
|
+
return a ?? b;
|
|
193348
|
+
}
|
|
193259
193349
|
function transformMapCall(node, ctx, isClientOnly = false, method = "map") {
|
|
193260
193350
|
const isNested = ctx.loopParams.size > 0;
|
|
193261
193351
|
const propAccess = node.expression;
|
|
@@ -193418,6 +193508,19 @@ function transformMapCall(node, ctx, isClientOnly = false, method = "map") {
|
|
|
193418
193508
|
}
|
|
193419
193509
|
if (index)
|
|
193420
193510
|
ctx.loopParams.add(index);
|
|
193511
|
+
const tryTransformRenderableBody = (expr) => {
|
|
193512
|
+
if (!import_typescript11.default.isBinaryExpression(expr))
|
|
193513
|
+
return;
|
|
193514
|
+
const op = expr.operatorToken.kind;
|
|
193515
|
+
if (op !== import_typescript11.default.SyntaxKind.AmpersandAmpersandToken && op !== import_typescript11.default.SyntaxKind.BarBarToken && op !== import_typescript11.default.SyntaxKind.QuestionQuestionToken) {
|
|
193516
|
+
return;
|
|
193517
|
+
}
|
|
193518
|
+
if (!containsJsxInExpression(expr) && !callsJsxHelper(expr, ctx))
|
|
193519
|
+
return;
|
|
193520
|
+
const transformed = transformJsxExpression(expr, ctx, isClientOnly);
|
|
193521
|
+
if (transformed)
|
|
193522
|
+
children = [transformed];
|
|
193523
|
+
};
|
|
193421
193524
|
const body = callback.body;
|
|
193422
193525
|
if (import_typescript11.default.isJsxElement(body) || import_typescript11.default.isJsxSelfClosingElement(body) || import_typescript11.default.isJsxFragment(body)) {
|
|
193423
193526
|
const transformed = transformNode(body, ctx);
|
|
@@ -193440,6 +193543,8 @@ function transformMapCall(node, ctx, isClientOnly = false, method = "map") {
|
|
|
193440
193543
|
children = [transformConditional(inner, ctx)];
|
|
193441
193544
|
} else if (method === "flatMap" && import_typescript11.default.isArrayLiteralExpression(inner)) {
|
|
193442
193545
|
children = transformArrayLiteralChildren(inner, ctx);
|
|
193546
|
+
} else {
|
|
193547
|
+
tryTransformRenderableBody(inner);
|
|
193443
193548
|
}
|
|
193444
193549
|
} else if (method === "flatMap" && import_typescript11.default.isArrayLiteralExpression(body)) {
|
|
193445
193550
|
children = transformArrayLiteralChildren(body, ctx);
|
|
@@ -193488,6 +193593,8 @@ function transformMapCall(node, ctx, isClientOnly = false, method = "map") {
|
|
|
193488
193593
|
if (method === "flatMap" && children.length === 0) {
|
|
193489
193594
|
flatMapCallback = buildFlatMapCallback(callback, body, ctx);
|
|
193490
193595
|
}
|
|
193596
|
+
} else {
|
|
193597
|
+
tryTransformRenderableBody(body);
|
|
193491
193598
|
}
|
|
193492
193599
|
if (paramBindings) {
|
|
193493
193600
|
for (const b of paramBindings)
|
|
@@ -193504,7 +193611,9 @@ function transformMapCall(node, ctx, isClientOnly = false, method = "map") {
|
|
|
193504
193611
|
if (import_typescript11.default.isArrowFunction(node.arguments[0]) && children.length > 0) {
|
|
193505
193612
|
checkLoopKey(node.arguments[0], ctx, isNested);
|
|
193506
193613
|
}
|
|
193507
|
-
const
|
|
193614
|
+
const itemConditional = children.length > 0 ? loopBodyItemConditional(children) : null;
|
|
193615
|
+
const bodyIsItemConditional = itemConditional !== null;
|
|
193616
|
+
const key = bodyIsItemConditional ? extractItemConditionalKey(itemConditional) : children.length > 0 ? extractLoopKey(children[0]) : null;
|
|
193508
193617
|
let childComponent;
|
|
193509
193618
|
if (children.length === 1 && children[0].type === "component") {
|
|
193510
193619
|
const comp = children[0];
|
|
@@ -193543,6 +193652,7 @@ function transformMapCall(node, ctx, isClientOnly = false, method = "map") {
|
|
|
193543
193652
|
callsReactiveGetters: callsReactive || undefined,
|
|
193544
193653
|
hasFunctionCalls: hasCalls || undefined,
|
|
193545
193654
|
bodyIsMultiRoot: bodyIsMultiRoot || undefined,
|
|
193655
|
+
bodyIsItemConditional: bodyIsItemConditional || undefined,
|
|
193546
193656
|
childComponent,
|
|
193547
193657
|
nestedComponents,
|
|
193548
193658
|
filterPredicate,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@barefootjs/test",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.2",
|
|
4
4
|
"description": "Test utilities for BarefootJS - IR-based component testing without a browser",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"directory": "packages/test"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@barefootjs/jsx": "0.5.
|
|
42
|
+
"@barefootjs/jsx": "0.5.2"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"typescript": "^5.0.0"
|