@barefootjs/test 0.4.0 → 0.5.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.
Files changed (2) hide show
  1. package/dist/index.js +120 -16
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -190546,6 +190546,8 @@ function convertNode(node, raw) {
190546
190546
  ` + ` (a, b) => a.field - b.field
190547
190547
  ` + ` (a, b) => a.localeCompare(b)
190548
190548
  ` + ` (a, b) => a.field.localeCompare(b.field)
190549
+ ` + ` (a, b) => a.field > b.field ? 1 : -1 (relational ternary)
190550
+ ` + ` any of the above ||-chained for multi-key tie-breaks
190549
190551
  ` + `(reverse the operands for descending order). ` + `Wrap the call in /* @client */ to evaluate at hydration.`
190550
190552
  };
190551
190553
  }
@@ -190705,26 +190707,54 @@ function extractSortComparatorFromTS(node, method) {
190705
190707
  const paramA = pA.name.text;
190706
190708
  const paramB = pB.name.text;
190707
190709
  let body;
190708
- if (import_typescript8.default.isArrowFunction(node)) {
190709
- if (import_typescript8.default.isBlock(node.body))
190710
- return null;
190710
+ if (import_typescript8.default.isArrowFunction(node) && !import_typescript8.default.isBlock(node.body)) {
190711
190711
  body = node.body;
190712
190712
  } else {
190713
- const stmts = node.body.statements;
190713
+ const block = node.body;
190714
+ const stmts = block.statements;
190714
190715
  if (stmts.length !== 1 || !import_typescript8.default.isReturnStatement(stmts[0]) || !stmts[0].expression)
190715
190716
  return null;
190716
190717
  body = stmts[0].expression;
190717
190718
  }
190718
190719
  const raw = body.getText();
190720
+ const keys = [];
190721
+ for (const operand of flattenLogicalOr(body)) {
190722
+ const key = classifyLeafComparator(operand, paramA, paramB);
190723
+ if (!key)
190724
+ return null;
190725
+ keys.push(key);
190726
+ }
190727
+ if (keys.length === 0)
190728
+ return null;
190729
+ return { keys, raw, paramA, paramB, method };
190730
+ }
190731
+ function unwrapParens(expr) {
190732
+ let e = expr;
190733
+ while (import_typescript8.default.isParenthesizedExpression(e))
190734
+ e = e.expression;
190735
+ return e;
190736
+ }
190737
+ function flattenLogicalOr(expr) {
190738
+ const inner = unwrapParens(expr);
190739
+ if (import_typescript8.default.isBinaryExpression(inner) && inner.operatorToken.kind === import_typescript8.default.SyntaxKind.BarBarToken) {
190740
+ return [...flattenLogicalOr(inner.left), ...flattenLogicalOr(inner.right)];
190741
+ }
190742
+ return [inner];
190743
+ }
190744
+ function classifyLeafComparator(expr, paramA, paramB) {
190745
+ const body = unwrapParens(expr);
190719
190746
  if (import_typescript8.default.isBinaryExpression(body) && body.operatorToken.kind === import_typescript8.default.SyntaxKind.MinusToken) {
190720
- return classifyComparatorOperands(body.left, body.right, paramA, paramB, "numeric", method, raw);
190747
+ return classifyComparatorOperands(body.left, body.right, paramA, paramB, "numeric");
190721
190748
  }
190722
190749
  if (import_typescript8.default.isCallExpression(body) && import_typescript8.default.isPropertyAccessExpression(body.expression) && body.expression.name.text === "localeCompare" && body.arguments.length === 1) {
190723
- return classifyComparatorOperands(body.expression.expression, body.arguments[0], paramA, paramB, "string", method, raw);
190750
+ return classifyComparatorOperands(body.expression.expression, body.arguments[0], paramA, paramB, "string");
190751
+ }
190752
+ if (import_typescript8.default.isConditionalExpression(body)) {
190753
+ return classifyTernaryComparator(body, paramA, paramB);
190724
190754
  }
190725
190755
  return null;
190726
190756
  }
190727
- function classifyComparatorOperands(left, right, paramA, paramB, type2, method, raw) {
190757
+ function classifyComparatorOperands(left, right, paramA, paramB, type2) {
190728
190758
  const leftRef = classifySortOperand(left, paramA, paramB);
190729
190759
  const rightRef = classifySortOperand(right, paramA, paramB);
190730
190760
  if (!leftRef || !rightRef)
@@ -190737,15 +190767,89 @@ function classifyComparatorOperands(left, right, paramA, paramB, type2, method,
190737
190767
  return null;
190738
190768
  }
190739
190769
  const direction = leftRef.param === "A" ? "asc" : "desc";
190740
- return {
190741
- key: leftRef.key,
190742
- type: type2,
190743
- direction,
190744
- raw,
190745
- paramA,
190746
- paramB,
190747
- method
190748
- };
190770
+ return { key: leftRef.key, type: type2, direction };
190771
+ }
190772
+ function classifyTernaryComparator(node, paramA, paramB) {
190773
+ const cond = unwrapParens(node.condition);
190774
+ if (import_typescript8.default.isBinaryExpression(cond) && (cond.operatorToken.kind === import_typescript8.default.SyntaxKind.EqualsEqualsEqualsToken || cond.operatorToken.kind === import_typescript8.default.SyntaxKind.EqualsEqualsToken) && sameKeyOperands(cond.left, cond.right, paramA, paramB) && numericSign(node.whenTrue) === 0) {
190775
+ const elseBranch = unwrapParens(node.whenFalse);
190776
+ if (import_typescript8.default.isConditionalExpression(elseBranch)) {
190777
+ return classifyTernaryComparator(elseBranch, paramA, paramB);
190778
+ }
190779
+ return null;
190780
+ }
190781
+ if (!import_typescript8.default.isBinaryExpression(cond))
190782
+ return null;
190783
+ const op = cond.operatorToken.kind;
190784
+ const isGreater = op === import_typescript8.default.SyntaxKind.GreaterThanToken || op === import_typescript8.default.SyntaxKind.GreaterThanEqualsToken;
190785
+ const isLess = op === import_typescript8.default.SyntaxKind.LessThanToken || op === import_typescript8.default.SyntaxKind.LessThanEqualsToken;
190786
+ if (!isGreater && !isLess)
190787
+ return null;
190788
+ const leftRef = classifySortOperand(cond.left, paramA, paramB);
190789
+ const rightRef = classifySortOperand(cond.right, paramA, paramB);
190790
+ if (!leftRef || !rightRef)
190791
+ return null;
190792
+ if (leftRef.param === rightRef.param)
190793
+ return null;
190794
+ if (leftRef.key.kind !== rightRef.key.kind)
190795
+ return null;
190796
+ if (leftRef.key.kind === "field" && rightRef.key.kind === "field" && leftRef.key.field !== rightRef.key.field) {
190797
+ return null;
190798
+ }
190799
+ const trueSign = numericSign(node.whenTrue);
190800
+ if (trueSign === null || trueSign === 0)
190801
+ return null;
190802
+ if (!isBoundedTernaryElse(node.whenFalse, leftRef.key, paramA, paramB))
190803
+ return null;
190804
+ const greaterForA = leftRef.param === "A" ? isGreater : !isGreater;
190805
+ const asc = greaterForA ? trueSign > 0 : trueSign < 0;
190806
+ return { key: leftRef.key, type: "auto", direction: asc ? "asc" : "desc" };
190807
+ }
190808
+ function sameKeyOperands(left, right, paramA, paramB) {
190809
+ const l = classifySortOperand(left, paramA, paramB);
190810
+ const r = classifySortOperand(right, paramA, paramB);
190811
+ if (!l || !r)
190812
+ return false;
190813
+ if (l.param === r.param)
190814
+ return false;
190815
+ if (l.key.kind !== r.key.kind)
190816
+ return false;
190817
+ if (l.key.kind === "field" && r.key.kind === "field" && l.key.field !== r.key.field)
190818
+ return false;
190819
+ return true;
190820
+ }
190821
+ function numericSign(expr) {
190822
+ const e = unwrapParens(expr);
190823
+ if (import_typescript8.default.isPrefixUnaryExpression(e) && e.operator === import_typescript8.default.SyntaxKind.MinusToken) {
190824
+ const inner = numericSign(e.operand);
190825
+ return inner === null ? null : -inner;
190826
+ }
190827
+ if (import_typescript8.default.isNumericLiteral(e)) {
190828
+ const n = Number(e.text);
190829
+ if (Number.isNaN(n))
190830
+ return null;
190831
+ if (n === 0)
190832
+ return 0;
190833
+ return n > 0 ? 1 : -1;
190834
+ }
190835
+ return null;
190836
+ }
190837
+ function isBoundedTernaryElse(expr, key, paramA, paramB) {
190838
+ const e = unwrapParens(expr);
190839
+ if (numericSign(e) !== null)
190840
+ return true;
190841
+ if (import_typescript8.default.isConditionalExpression(e)) {
190842
+ const nested = classifyTernaryComparator(e, paramA, paramB);
190843
+ return nested !== null && sortKeyEquals(nested.key, key);
190844
+ }
190845
+ return false;
190846
+ }
190847
+ function sortKeyEquals(a, b) {
190848
+ if (a.kind !== b.kind)
190849
+ return false;
190850
+ if (a.kind === "field" && b.kind === "field")
190851
+ return a.field === b.field;
190852
+ return true;
190749
190853
  }
190750
190854
  function classifySortOperand(expr, paramA, paramB) {
190751
190855
  if (import_typescript8.default.isIdentifier(expr)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barefootjs/test",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
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.4.0"
42
+ "@barefootjs/jsx": "0.5.0"
43
43
  },
44
44
  "devDependencies": {
45
45
  "typescript": "^5.0.0"