@barefootjs/test 0.26.1 → 0.26.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 CHANGED
@@ -198880,9 +198880,9 @@ function resolveConstants(constants3) {
198880
198880
  for (const c of constants3) {
198881
198881
  if (c.parsed?.kind === "object-literal") {
198882
198882
  for (const prop of c.parsed.properties) {
198883
- if (prop.value.kind === "literal" && prop.value.literalType === "string") {
198884
- resolved.set(`${c.name}.${prop.key}`, String(prop.value.value));
198885
- }
198883
+ const value2 = resolveObjectPropValue(prop.value, resolved);
198884
+ if (value2 !== null)
198885
+ resolved.set(`${c.name}.${prop.key}`, value2);
198886
198886
  }
198887
198887
  continue;
198888
198888
  }
@@ -198910,6 +198910,31 @@ function resolveConstants(constants3) {
198910
198910
  }
198911
198911
  return resolved;
198912
198912
  }
198913
+ function resolveObjectPropValue(expr, resolved) {
198914
+ if (expr.kind === "literal" && expr.literalType === "string") {
198915
+ return String(expr.value);
198916
+ }
198917
+ if (expr.kind === "identifier") {
198918
+ return resolved.get(expr.name) ?? null;
198919
+ }
198920
+ if (expr.kind === "template-literal") {
198921
+ const strs = [];
198922
+ for (const part of expr.parts) {
198923
+ if (part.type === "string") {
198924
+ strs.push(part.value);
198925
+ continue;
198926
+ }
198927
+ if (part.expr.kind !== "identifier")
198928
+ return null;
198929
+ const value = resolved.get(part.expr.name);
198930
+ if (value === undefined)
198931
+ return null;
198932
+ strs.push(value);
198933
+ }
198934
+ return strs.join("");
198935
+ }
198936
+ return null;
198937
+ }
198913
198938
  function tryResolve(raw, resolved) {
198914
198939
  const value = raw.trim();
198915
198940
  if (value.startsWith("'") && value.endsWith("'") && !value.slice(1, -1).includes("'")) {
@@ -13,12 +13,14 @@ import type { ParsedExpr } from '@barefootjs/jsx';
13
13
  * Resolves string literals, template literals, array.join() patterns,
14
14
  * and plain identifier references. When `valueBranches` is present
15
15
  * (from ternary initializers), each branch is resolved and merged
16
- * with union semantics. An object-literal const with string-valued
17
- * properties (`const rowClass = { active: 'row row-active', plain: 'row' }`)
18
- * additionally seeds member-path keys (`rowClass.active` `'row row-active'`)
19
- * so a member-access className (`className={rowClass.active}`, or a
20
- * ternary arm) resolves through the same lookup (#2354). Function
21
- * expressions and other complex values are skipped.
16
+ * with union semantics. An object-literal const with string-literal,
17
+ * template-literal, or bare-identifier-valued properties (`const rowClass
18
+ * = { active: \`${base} row-active\`, plain: base }`) additionally seeds
19
+ * member-path
20
+ * keys (`rowClass.active` `'row row-active'`) so a member-access
21
+ * className (`className={rowClass.active}`, or a ternary arm) resolves
22
+ * through the same lookup (#2354, template-literal values #2360).
23
+ * Function expressions and other complex property values are skipped.
22
24
  */
23
25
  export declare function resolveConstants(constants: Array<{
24
26
  name: string;
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-constants.d.ts","sourceRoot":"","sources":["../src/resolve-constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEjD;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,CAAC,EAAE,UAAU,CAAA;CAAE,CAAC,GAChG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAuCrB"}
1
+ {"version":3,"file":"resolve-constants.d.ts","sourceRoot":"","sources":["../src/resolve-constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEjD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,CAAC,EAAE,UAAU,CAAA;CAAE,CAAC,GAChG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CA0CrB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barefootjs/test",
3
- "version": "0.26.1",
3
+ "version": "0.26.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.26.1"
42
+ "@barefootjs/jsx": "0.26.2"
43
43
  },
44
44
  "devDependencies": {
45
45
  "typescript": "^5.0.0"
@@ -15,12 +15,14 @@ import type { ParsedExpr } from '@barefootjs/jsx'
15
15
  * Resolves string literals, template literals, array.join() patterns,
16
16
  * and plain identifier references. When `valueBranches` is present
17
17
  * (from ternary initializers), each branch is resolved and merged
18
- * with union semantics. An object-literal const with string-valued
19
- * properties (`const rowClass = { active: 'row row-active', plain: 'row' }`)
20
- * additionally seeds member-path keys (`rowClass.active` `'row row-active'`)
21
- * so a member-access className (`className={rowClass.active}`, or a
22
- * ternary arm) resolves through the same lookup (#2354). Function
23
- * expressions and other complex values are skipped.
18
+ * with union semantics. An object-literal const with string-literal,
19
+ * template-literal, or bare-identifier-valued properties (`const rowClass
20
+ * = { active: \`${base} row-active\`, plain: base }`) additionally seeds
21
+ * member-path
22
+ * keys (`rowClass.active` `'row row-active'`) so a member-access
23
+ * className (`className={rowClass.active}`, or a ternary arm) resolves
24
+ * through the same lookup (#2354, template-literal values #2360).
25
+ * Function expressions and other complex property values are skipped.
24
26
  */
25
27
  export function resolveConstants(
26
28
  constants: Array<{ name: string; value?: string; valueBranches?: string[]; parsed?: ParsedExpr }>
@@ -28,14 +30,17 @@ export function resolveConstants(
28
30
  const resolved = new Map<string, string>()
29
31
 
30
32
  for (const c of constants) {
31
- // Object-literal const: expose each string-valued property as a
32
- // `name.key` member-path key. The bare identifier stays unresolved
33
- // (an object is not a class string), matching prior behavior.
33
+ // Object-literal const: expose each resolvable property as a
34
+ // `name.key` member-path key. The object's OWN bare identifier
35
+ // (`c.name` referenced directly, e.g. `className={rowClass}`) stays
36
+ // unresolved — an object is not a class string — matching prior
37
+ // behavior; this is unrelated to a resolvable identifier-valued
38
+ // PROPERTY (`{ plain: base }`), handled by resolveObjectPropValue
39
+ // below (Copilot review, PR #2361).
34
40
  if (c.parsed?.kind === 'object-literal') {
35
41
  for (const prop of c.parsed.properties) {
36
- if (prop.value.kind === 'literal' && prop.value.literalType === 'string') {
37
- resolved.set(`${c.name}.${prop.key}`, String(prop.value.value))
38
- }
42
+ const value = resolveObjectPropValue(prop.value, resolved)
43
+ if (value !== null) resolved.set(`${c.name}.${prop.key}`, value)
39
44
  }
40
45
  continue
41
46
  }
@@ -65,6 +70,56 @@ export function resolveConstants(
65
70
  return resolved
66
71
  }
67
72
 
73
+ /**
74
+ * Resolve one object-literal property's value to a string, for the
75
+ * `name.key` member-path seeding above. Supports the same shapes as
76
+ * `tryResolve` — string literal, template literal, plain identifier
77
+ * reference — but walks the already-structured `ParsedExpr` (available
78
+ * here, unlike `tryResolve`'s raw-string input) instead of re-parsing
79
+ * with a regex, and is stricter about "unresolvable": `tryResolve`'s
80
+ * template-literal branch folds an unresolved `${...}` to `''` (its
81
+ * caller only ever uses that for the whole-constant case, where a
82
+ * partial string is an acceptable degrade), but a property value here
83
+ * returns `null` for the whole property instead — seeding `name.key`
84
+ * with a misleadingly partial class string would be worse than not
85
+ * seeding it at all. A bare identifier property (`{ plain: base }`) and
86
+ * an interpolated identifier inside a template literal both resolve
87
+ * against `resolved` — safe because `resolveConstants` processes
88
+ * `constants` in declaration order, so a module-scope const referenced
89
+ * inside a later object literal's property is already in the map
90
+ * (#2360). Anything else (a nested object/array, a call, a binary
91
+ * expression, ...) is left unresolved, same posture as `tryResolve`
92
+ * skipping "complex values".
93
+ */
94
+ function resolveObjectPropValue(expr: ParsedExpr, resolved: Map<string, string>): string | null {
95
+ if (expr.kind === 'literal' && expr.literalType === 'string') {
96
+ return String(expr.value)
97
+ }
98
+ if (expr.kind === 'identifier') {
99
+ return resolved.get(expr.name) ?? null
100
+ }
101
+ if (expr.kind === 'template-literal') {
102
+ const strs: string[] = []
103
+ for (const part of expr.parts) {
104
+ if (part.type === 'string') {
105
+ strs.push(part.value)
106
+ continue
107
+ }
108
+ // An interpolation that isn't a plain identifier reference (a
109
+ // conditional, a member access, ...), or one that IS an identifier
110
+ // but doesn't resolve, makes the whole template unresolved — don't
111
+ // fold it to '' and seed a partial, misleadingly "resolved" string
112
+ // (Copilot review, PR #2361).
113
+ if (part.expr.kind !== 'identifier') return null
114
+ const value = resolved.get(part.expr.name)
115
+ if (value === undefined) return null
116
+ strs.push(value)
117
+ }
118
+ return strs.join('')
119
+ }
120
+ return null
121
+ }
122
+
68
123
  function tryResolve(raw: string, resolved: Map<string, string>): string | null {
69
124
  const value = raw.trim()
70
125