clava 0.4.2 → 0.6.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.
@@ -145,8 +145,8 @@ export function warnRefineLimit({
145
145
  runState.warned = true;
146
146
  let message =
147
147
  "Clava: Maximum refine iterations exceeded. This can happen when a " +
148
- "refine callback calls setVariants or setDefaultVariants, but one " +
149
- "of the variants changes on every run.";
148
+ "computed default variant or refine callback changes one of the " +
149
+ "variants on every run.";
150
150
  if (unstableChanges && unstableChanges.size > 0) {
151
151
  message += `\nVariant(s) that did not stabilize: ${Array.from(unstableChanges.keys()).join(", ")}.`;
152
152
  message += `\nLatest variant changes before warning: ${formatVariantChanges(unstableChanges)}.`;
package/src/types.ts CHANGED
@@ -1,5 +1,20 @@
1
1
  import type * as CSS from "csstype";
2
2
 
3
+ /**
4
+ * A class value accepted by Clava. It supports strings, numbers, booleans,
5
+ * nullish values, and nested arrays.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * import type { ClassValue } from "clava";
10
+ *
11
+ * const className: ClassValue = [
12
+ * "button",
13
+ * false && "button-hidden",
14
+ * ["button-primary"],
15
+ * ];
16
+ * ```
17
+ */
3
18
  export type ClassValue =
4
19
  | string
5
20
  | number
@@ -17,21 +32,68 @@ export type CSSProperties = CSS.Properties;
17
32
 
18
33
  export type StyleProperty = JSXCSSProperties | HTMLCSSProperties | string;
19
34
 
35
+ /**
36
+ * The prop object returned by a component's `.jsx()` mode.
37
+ *
38
+ * @example
39
+ * ```ts
40
+ * import { type JSXProps, cv } from "clava";
41
+ *
42
+ * const button = cv({ class: "button" });
43
+ * const props: JSXProps = button.jsx();
44
+ * ```
45
+ */
20
46
  export interface JSXProps {
21
47
  className: string;
22
48
  style: JSXCSSProperties;
23
49
  }
24
50
 
51
+ /**
52
+ * The prop object returned by a component's `.html()` mode. The `style` value
53
+ * is serialized as an HTML style string.
54
+ *
55
+ * @example
56
+ * ```ts
57
+ * import { type HTMLProps, cv } from "clava";
58
+ *
59
+ * const button = cv({ style: { color: "red" } });
60
+ * const props: HTMLProps = button.html();
61
+ * ```
62
+ */
25
63
  export interface HTMLProps {
26
64
  class: string;
27
65
  style: string;
28
66
  }
29
67
 
68
+ /**
69
+ * The prop object returned by a component's `.htmlObj()` mode. The `style`
70
+ * value uses hyphenated CSS property names.
71
+ *
72
+ * @example
73
+ * ```ts
74
+ * import { type HTMLObjProps, cv } from "clava";
75
+ *
76
+ * const button = cv({ style: { fontSize: "16px" } });
77
+ * const props: HTMLObjProps = button.htmlObj();
78
+ * ```
79
+ */
30
80
  export interface HTMLObjProps {
31
81
  class: string;
32
82
  style: HTMLCSSProperties;
33
83
  }
34
84
 
85
+ /**
86
+ * The default prop object returned by a Clava component. It uses `class`
87
+ * rather than `className` and keeps styles as a normalized object.
88
+ *
89
+ * @example
90
+ * ```ts
91
+ * import { type StyleClassProps, cv } from "clava";
92
+ *
93
+ * const button = cv({ class: "button" });
94
+ * const props: StyleClassProps = button();
95
+ * ```
96
+ */
35
97
  export interface StyleClassProps {
36
98
  class: string;
37
99
  style: StyleValue;
@@ -177,6 +239,25 @@ export interface ModalComponent<V, R extends ComponentResult> {
177
239
  propKeys: (keyof V | ComponentPropKey<R>)[];
178
240
  }
179
241
 
242
+ /**
243
+ * A callable Clava component returned by `cv()`. It includes the default
244
+ * output mode plus `.jsx()`, `.html()`, and `.htmlObj()` mode helpers.
245
+ *
246
+ * @example
247
+ * ```ts
248
+ * import { type CVComponent, cv } from "clava";
249
+ *
250
+ * const button: CVComponent<{
251
+ * size: { sm: string; lg: string };
252
+ * }> = cv({
253
+ * variants: {
254
+ * size: { sm: "button-sm", lg: "button-lg" },
255
+ * },
256
+ * });
257
+ *
258
+ * button.jsx({ size: "lg" });
259
+ * ```
260
+ */
180
261
  export interface CVComponent<
181
262
  V extends Variants = {},
182
263
  E extends AnyComponent[] = [],
@@ -254,13 +335,60 @@ type ExtractVariantValue<T> = T extends null
254
335
  : never;
255
336
 
256
337
  export type VariantValues<V> = {
257
- [K in keyof V]?: ExtractVariantValue<V[K]>;
338
+ [K in keyof V]?: ExtractVariantValue<V[K]> | undefined;
258
339
  };
259
340
 
341
+ type ComputedDefaultVariant<V, K extends keyof V> = (
342
+ defaultValue: ExtractVariantValue<V[K]> | undefined,
343
+ variants: Readonly<VariantValues<V>>,
344
+ ) => ExtractVariantValue<V[K]> | undefined;
345
+
346
+ type NonFunctionVariantValue<T> = Exclude<T, (...args: any[]) => any>;
347
+
348
+ type DefaultVariantValue<V, K extends keyof V> = [
349
+ NonFunctionVariantValue<ExtractVariantValue<V[K]>>,
350
+ ] extends [never]
351
+ ? ComputedDefaultVariant<V, K>
352
+ :
353
+ | NonFunctionVariantValue<ExtractVariantValue<V[K]>>
354
+ | ComputedDefaultVariant<V, K>;
355
+
356
+ export type DefaultVariants<V> = {
357
+ [K in keyof V]?: DefaultVariantValue<V, K> | undefined;
358
+ };
359
+
360
+ /**
361
+ * A normalized style object accepted by Clava config, variant, and refine
362
+ * style entries. CSS custom properties are supported with string values.
363
+ *
364
+ * @example
365
+ * ```ts
366
+ * import type { StyleValue } from "clava";
367
+ *
368
+ * const style: StyleValue = {
369
+ * color: "red",
370
+ * "--button-accent": "oklch(62% 0.2 250)",
371
+ * };
372
+ * ```
373
+ */
260
374
  export type StyleValue = CSS.Properties & {
261
375
  [key: `--${string}`]: string;
262
376
  };
263
377
 
378
+ /**
379
+ * A value that contributes both class and style output from a base config,
380
+ * variant value, function variant, or refine callback.
381
+ *
382
+ * @example
383
+ * ```ts
384
+ * import type { StyleClassValue } from "clava";
385
+ *
386
+ * const tone: StyleClassValue = {
387
+ * class: "button-primary",
388
+ * style: { color: "white" },
389
+ * };
390
+ * ```
391
+ */
264
392
  export interface StyleClassValue {
265
393
  style?: StyleValue;
266
394
  class?: ClassValue;
@@ -269,7 +397,6 @@ export interface StyleClassValue {
269
397
  export interface RefineContext<V> {
270
398
  variants: VariantValues<V>;
271
399
  setVariants: (variants: VariantValues<V>) => void;
272
- setDefaultVariants: (variants: VariantValues<V>) => void;
273
400
  addClass: (className: ClassValue) => void;
274
401
  addStyle: (style: StyleValue) => void;
275
402
  }
@@ -59,6 +59,33 @@ for (const config of Object.values(CONFIGS)) {
59
59
  expect(variants).toEqual({ size: "sm" });
60
60
  });
61
61
 
62
+ test("getVariants omits undefined defaultVariants", () => {
63
+ const component = getModeComponent(
64
+ mode,
65
+ cv({
66
+ variants: { size: { sm: "sm", lg: "lg" } },
67
+ defaultVariants: { size: undefined },
68
+ }),
69
+ );
70
+ const variants = component.getVariants();
71
+ expect(variants).toStrictEqual({});
72
+ expect(Object.hasOwn(variants, "size")).toBe(false);
73
+ });
74
+
75
+ test("getVariants undefined defaultVariants clear inherited defaultVariants", () => {
76
+ const base = cv({
77
+ variants: { size: { sm: "sm", lg: "lg" } },
78
+ defaultVariants: { size: "sm" },
79
+ });
80
+ const component = getModeComponent(
81
+ mode,
82
+ cv({ extend: [base], defaultVariants: { size: undefined } }),
83
+ );
84
+ const variants = component.getVariants();
85
+ expect(variants).toStrictEqual({});
86
+ expect(Object.hasOwn(variants, "size")).toBe(false);
87
+ });
88
+
62
89
  test("getVariants returns variants set by refine setVariants", () => {
63
90
  const component = getModeComponent(
64
91
  mode,
@@ -100,7 +127,7 @@ for (const config of Object.values(CONFIGS)) {
100
127
  expect(variants).toEqual({ size: "sm", color: "red" });
101
128
  });
102
129
 
103
- test("getVariants re-runs when setDefaultVariants changes variants", () => {
130
+ test("getVariants re-runs when computed defaultVariants change variants", () => {
104
131
  const component = getModeComponent(
105
132
  mode,
106
133
  cv({
@@ -108,11 +135,10 @@ for (const config of Object.values(CONFIGS)) {
108
135
  size: { sm: "sm", lg: "lg" },
109
136
  color: { red: "red", blue: "blue" },
110
137
  },
111
- refine: ({ variants, setDefaultVariants }) => {
112
- setDefaultVariants({ color: "red" });
113
- if (variants.color === "red") {
114
- setDefaultVariants({ size: "lg" });
115
- }
138
+ defaultVariants: {
139
+ color: () => "red" as const,
140
+ size: (defaultValue, variants) =>
141
+ variants.color === "red" ? "lg" : defaultValue,
116
142
  },
117
143
  }),
118
144
  );
@@ -120,7 +146,7 @@ for (const config of Object.values(CONFIGS)) {
120
146
  expect(variants).toEqual({ size: "lg", color: "red" });
121
147
  });
122
148
 
123
- test("getVariants returns variants set by refine setDefaultVariants", () => {
149
+ test("getVariants returns computed defaultVariants", () => {
124
150
  const component = getModeComponent(
125
151
  mode,
126
152
  cv({
@@ -128,10 +154,9 @@ for (const config of Object.values(CONFIGS)) {
128
154
  size: { sm: "sm", lg: "lg" },
129
155
  color: { red: "red", blue: "blue" },
130
156
  },
131
- refine: ({ variants, setDefaultVariants }) => {
132
- if (variants.size === "lg") {
133
- setDefaultVariants({ color: "blue" });
134
- }
157
+ defaultVariants: {
158
+ color: (defaultValue, variants) =>
159
+ variants.size === "lg" ? "blue" : defaultValue,
135
160
  },
136
161
  }),
137
162
  );
@@ -139,7 +164,7 @@ for (const config of Object.values(CONFIGS)) {
139
164
  expect(variants).toEqual({ size: "lg", color: "blue" });
140
165
  });
141
166
 
142
- test("getVariants setDefaultVariants does not override props", () => {
167
+ test("getVariants computed defaultVariants do not override props", () => {
143
168
  const component = getModeComponent(
144
169
  mode,
145
170
  cv({
@@ -147,8 +172,8 @@ for (const config of Object.values(CONFIGS)) {
147
172
  size: { sm: "sm", lg: "lg" },
148
173
  color: { red: "red", blue: "blue" },
149
174
  },
150
- refine: ({ setDefaultVariants }) => {
151
- setDefaultVariants({ color: "blue" });
175
+ defaultVariants: {
176
+ color: () => "blue" as const,
152
177
  },
153
178
  }),
154
179
  );
@@ -173,11 +198,11 @@ for (const config of Object.values(CONFIGS)) {
173
198
  expect(variants).toEqual({ color: "blue" });
174
199
  });
175
200
 
176
- test("getVariants picks up setDefaultVariants from extended component", () => {
201
+ test("getVariants picks up computed defaultVariants from extended component", () => {
177
202
  const base = cv({
178
203
  variants: { size: { sm: "sm", lg: "lg" } },
179
- refine: ({ setDefaultVariants }) => {
180
- setDefaultVariants({ size: "lg" });
204
+ defaultVariants: {
205
+ size: () => "lg" as const,
181
206
  },
182
207
  });
183
208
  const component = getModeComponent(
@@ -192,11 +217,11 @@ for (const config of Object.values(CONFIGS)) {
192
217
  expect(variants).toEqual({ size: "lg", color: "red" });
193
218
  });
194
219
 
195
- test("getVariants picks up setDefaultVariants from grandparent component", () => {
220
+ test("getVariants picks up computed defaultVariants from grandparent component", () => {
196
221
  const grandparent = cv({
197
222
  variants: { size: { sm: "sm", lg: "lg" } },
198
- refine: ({ setDefaultVariants }) => {
199
- setDefaultVariants({ size: "lg" });
223
+ defaultVariants: {
224
+ size: () => "lg" as const,
200
225
  },
201
226
  });
202
227
  const parent = cv({ extend: [grandparent] });
@@ -238,21 +263,21 @@ for (const config of Object.values(CONFIGS)) {
238
263
  expect(variants).toEqual({ size: "lg", active: true, color: "red" });
239
264
  });
240
265
 
241
- test("getVariants preserves base setDefaultVariants after its own setVariants re-run", () => {
266
+ test("getVariants preserves computed defaultVariants after a setVariants re-run", () => {
242
267
  const base = cv({
243
268
  variants: {
244
269
  size: { sm: "sm", lg: "lg" },
245
270
  active: "",
246
271
  mode: { on: "on" },
247
272
  },
248
- defaultVariants: { size: "sm" },
249
- refine: ({ variants, setVariants, setDefaultVariants }) => {
273
+ defaultVariants: {
274
+ size: (defaultValue, variants) =>
275
+ variants.mode === "on" ? "lg" : defaultValue,
276
+ },
277
+ refine: ({ variants, setVariants }) => {
250
278
  if (variants.active) {
251
279
  setVariants({ mode: "on" });
252
280
  }
253
- if (variants.mode === "on") {
254
- setDefaultVariants({ size: "lg" });
255
- }
256
281
  },
257
282
  });
258
283
  const component = getModeComponent(mode, cv({ extend: [base] }));
@@ -276,11 +301,11 @@ for (const config of Object.values(CONFIGS)) {
276
301
  expect(variants).toEqual({ size: "sm" });
277
302
  });
278
303
 
279
- test("getVariants child setVariants keeps overriding base setDefaultVariants across re-runs", () => {
304
+ test("getVariants child setVariants keeps overriding base computed defaultVariants across re-runs", () => {
280
305
  const base = cv({
281
306
  variants: { color: { red: "red", blue: "blue" } },
282
- refine: ({ setDefaultVariants }) => {
283
- setDefaultVariants({ color: "blue" });
307
+ defaultVariants: {
308
+ color: () => "blue" as const,
284
309
  },
285
310
  });
286
311
  const component = getModeComponent(
@@ -300,11 +325,11 @@ for (const config of Object.values(CONFIGS)) {
300
325
  expect(variants).toEqual({ color: "red", size: "sm" });
301
326
  });
302
327
 
303
- test("getVariants setVariants sticks across re-runs", () => {
328
+ test("getVariants setVariants sticks across computed default re-runs", () => {
304
329
  const base = cv({
305
330
  variants: { color: { red: "red", blue: "blue" } },
306
- refine: ({ setDefaultVariants }) => {
307
- setDefaultVariants({ color: "blue" });
331
+ defaultVariants: {
332
+ color: () => "blue" as const,
308
333
  },
309
334
  });
310
335
  const component = getModeComponent(
@@ -323,20 +348,21 @@ for (const config of Object.values(CONFIGS)) {
323
348
  expect(variants).toEqual({ color: "red", done: true });
324
349
  });
325
350
 
326
- test("getVariants base setDefaultVariants can override child static defaults after a re-run", () => {
351
+ test("getVariants base computed defaultVariants can override child static defaults after a re-run", () => {
327
352
  const base = cv({
328
353
  variants: {
329
354
  size: { sm: "sm", lg: "lg" },
330
355
  active: "",
331
356
  mode: { on: "on" },
332
357
  },
333
- refine: ({ variants, setVariants, setDefaultVariants }) => {
358
+ defaultVariants: {
359
+ size: (defaultValue, variants) =>
360
+ variants.mode === "on" ? "lg" : defaultValue,
361
+ },
362
+ refine: ({ variants, setVariants }) => {
334
363
  if (variants.active) {
335
364
  setVariants({ mode: "on" });
336
365
  }
337
- if (variants.mode === "on") {
338
- setDefaultVariants({ size: "lg" });
339
- }
340
366
  },
341
367
  });
342
368
  const component = getModeComponent(
@@ -347,7 +373,7 @@ for (const config of Object.values(CONFIGS)) {
347
373
  expect(variants).toEqual({ size: "lg", active: true, mode: "on" });
348
374
  });
349
375
 
350
- test("getVariants setVariants from earlier extends overrides setDefaultVariants from later extends", () => {
376
+ test("getVariants setVariants from earlier extends overrides computed defaultVariants from later extends", () => {
351
377
  const first = cv({
352
378
  variants: { color: { red: "first-red", blue: "first-blue" } },
353
379
  refine: ({ setVariants }) => {
@@ -356,8 +382,8 @@ for (const config of Object.values(CONFIGS)) {
356
382
  });
357
383
  const second = cv({
358
384
  variants: { color: { red: "second-red", blue: "second-blue" } },
359
- refine: ({ setDefaultVariants }) => {
360
- setDefaultVariants({ color: "blue" });
385
+ defaultVariants: {
386
+ color: () => "blue" as const,
361
387
  },
362
388
  });
363
389
  const component = getModeComponent(mode, cv({ extend: [first, second] }));
@@ -365,17 +391,17 @@ for (const config of Object.values(CONFIGS)) {
365
391
  expect(variants).toEqual({ color: "red" });
366
392
  });
367
393
 
368
- test("getVariants setDefaultVariants from later extends overrides setDefaultVariants from earlier extends", () => {
394
+ test("getVariants computed defaultVariants from later extends override earlier extends", () => {
369
395
  const first = cv({
370
396
  variants: { color: { red: "first-red", blue: "first-blue" } },
371
- refine: ({ setDefaultVariants }) => {
372
- setDefaultVariants({ color: "red" });
397
+ defaultVariants: {
398
+ color: () => "red" as const,
373
399
  },
374
400
  });
375
401
  const second = cv({
376
402
  variants: { color: { red: "second-red", blue: "second-blue" } },
377
- refine: ({ setDefaultVariants }) => {
378
- setDefaultVariants({ color: "blue" });
403
+ defaultVariants: {
404
+ color: () => "blue" as const,
379
405
  },
380
406
  });
381
407
  const component = getModeComponent(mode, cv({ extend: [first, second] }));
@@ -383,7 +409,7 @@ for (const config of Object.values(CONFIGS)) {
383
409
  expect(variants).toEqual({ color: "blue" });
384
410
  });
385
411
 
386
- test("getVariants setDefaultVariants does not override stable setVariants on later passes", () => {
412
+ test("getVariants computed defaultVariants do not override stable setVariants on later passes", () => {
387
413
  const base = cv({
388
414
  variants: { color: { red: "base-red", blue: "base-blue" } },
389
415
  refine: ({ setVariants }) => {
@@ -395,10 +421,9 @@ for (const config of Object.values(CONFIGS)) {
395
421
  cv({
396
422
  extend: [base],
397
423
  variants: { color: { red: "child-red", blue: "child-blue" } },
398
- refine: ({ variants, setDefaultVariants }) => {
399
- if (variants.color === "red") {
400
- setDefaultVariants({ color: "blue" });
401
- }
424
+ defaultVariants: {
425
+ color: (defaultValue, variants) =>
426
+ variants.color === "red" ? "blue" : defaultValue,
402
427
  },
403
428
  }),
404
429
  );
@@ -406,7 +431,7 @@ for (const config of Object.values(CONFIGS)) {
406
431
  expect(variants).toEqual({ color: "red" });
407
432
  });
408
433
 
409
- test("getVariants setDefaultVariants does not override setVariants from a previous pass", () => {
434
+ test("getVariants computed defaultVariants do not override setVariants from a previous pass", () => {
410
435
  const component = getModeComponent(
411
436
  mode,
412
437
  cv({
@@ -414,13 +439,14 @@ for (const config of Object.values(CONFIGS)) {
414
439
  color: { red: "red", blue: "blue" },
415
440
  done: "",
416
441
  },
417
- refine: ({ variants, setVariants, setDefaultVariants }) => {
442
+ defaultVariants: {
443
+ color: (defaultValue, variants) =>
444
+ variants.done ? "blue" : defaultValue,
445
+ },
446
+ refine: ({ variants, setVariants }) => {
418
447
  if (!variants.done) {
419
448
  setVariants({ color: "red", done: true });
420
449
  }
421
- if (variants.done) {
422
- setDefaultVariants({ color: "blue" });
423
- }
424
450
  },
425
451
  }),
426
452
  );
@@ -144,7 +144,7 @@ for (const config of Object.values(CONFIGS)) {
144
144
  });
145
145
  });
146
146
 
147
- test("extend disabled variant value with refine setDefaultVariants", () => {
147
+ test("extend disabled variant value with computed defaultVariants", () => {
148
148
  const base = cv({
149
149
  variants: {
150
150
  size: {
@@ -158,8 +158,8 @@ for (const config of Object.values(CONFIGS)) {
158
158
  cv({
159
159
  extend: [base],
160
160
  variants: { size: { sm: null } },
161
- refine: ({ setDefaultVariants }) => {
162
- setDefaultVariants({ size: "lg" });
161
+ defaultVariants: {
162
+ size: () => "lg" as const,
163
163
  },
164
164
  }),
165
165
  );
@@ -173,19 +173,53 @@ for (const config of Object.values(CONFIGS)) {
173
173
  cv({
174
174
  extend: [base],
175
175
  variants: { size: { sm: null } },
176
- refine: ({ setDefaultVariants }) => {
177
- setDefaultVariants({
178
- // @ts-expect-error disabled variant value cannot be set
179
- size:
180
- // no error
181
- "sm",
182
- });
176
+ defaultVariants: {
177
+ // @ts-expect-error disabled variant value cannot be set
178
+ size: () =>
179
+ // no error
180
+ "sm",
183
181
  },
184
182
  }),
185
183
  );
186
184
  expect(getStyleClass(invalidComponent())).toEqual({ class: "" });
187
185
  });
188
186
 
187
+ test("extend filters disabled values from inherited computed defaultVariants", () => {
188
+ const base = cv({
189
+ variants: {
190
+ size: {
191
+ sm: { class: "base-sm", style: { fontSize: "12px" } },
192
+ lg: { class: "base-lg", style: { fontSize: "16px" } },
193
+ },
194
+ },
195
+ defaultVariants: {
196
+ size: () => "sm" as const,
197
+ },
198
+ });
199
+ const component = getModeComponent(
200
+ mode,
201
+ cv({
202
+ extend: [base],
203
+ variants: {
204
+ size: { sm: null },
205
+ color: { red: "red", blue: "blue" },
206
+ },
207
+ defaultVariants: {
208
+ size: "lg",
209
+ color: (_, variants) => (variants.size === "lg" ? "blue" : "red"),
210
+ },
211
+ }),
212
+ );
213
+ expect(getStyleClass(component())).toEqual({
214
+ class: cls("base-lg blue"),
215
+ fontSize: "16px",
216
+ });
217
+ expect(component.getVariants()).toEqual({
218
+ size: "lg",
219
+ color: "blue",
220
+ });
221
+ });
222
+
189
223
  test("extend disabled variant value with refine setVariants", () => {
190
224
  const base = cv({
191
225
  variants: {
@@ -80,7 +80,10 @@ function createLanguageServiceHost(
80
80
  function createLanguageServiceFixture(
81
81
  consumerSource: string,
82
82
  ): LanguageServiceFixture {
83
- const tempDir = mkdtempSync(join(workspaceDir, ".tmp-language-service-"));
83
+ const tempRoot = join(workspaceDir, ".tmp");
84
+ mkdirSync(tempRoot, { recursive: true });
85
+
86
+ const tempDir = mkdtempSync(join(tempRoot, "language-service-"));
84
87
  tempDirs.push(tempDir);
85
88
 
86
89
  const fixtureSourceDir = join(tempDir, "src");
@@ -134,6 +137,14 @@ afterEach(() => {
134
137
  });
135
138
 
136
139
  describe("TypeScript language service", () => {
140
+ test("creates fixtures inside the workspace .tmp directory", () => {
141
+ const fixture = createLanguageServiceFixture(getVariantFixtureSource());
142
+ const fixtureDir = dirname(fixture.consumerFile);
143
+ const fixturePrefix = join(workspaceDir, ".tmp", "language-service-");
144
+
145
+ expect(fixtureDir.startsWith(fixturePrefix)).toBe(true);
146
+ });
147
+
137
148
  test("goes to the local variant definition from a variant prop usage", () => {
138
149
  const fixture = createLanguageServiceFixture(getVariantFixtureSource());
139
150
  const definitionStart = getFixturePosition(
@@ -27,11 +27,10 @@ test("render ignores keys inherited from Object.prototype", () => {
27
27
  expect(component({}).class).toBe("sm");
28
28
  });
29
29
 
30
- test("extend's resolveDefaults ignores polluted prototype on parent's refine", () => {
30
+ test("extend's resolver ignores polluted prototype on parent's refine", () => {
31
31
  // Base's refine branches on its own variants.size — if the polluted "size"
32
- // key leaks into resolveDefaultsFn's resolvedVariants, the refine callback
33
- // would see size = "lg" instead of the staticDefault "sm" and emit the
34
- // lg-specific class.
32
+ // key leaks into resolved variants, the refine callback would see size =
33
+ // "lg" instead of the staticDefault "sm" and emit the lg-specific class.
35
34
  proto.size = "lg";
36
35
  const base = cv({
37
36
  variants: { size: { sm: "sm", lg: "lg" } },