clava 0.1.19 → 0.2.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.
@@ -0,0 +1,380 @@
1
+ import { describe, expect, test } from "vitest";
2
+ import {
3
+ CONFIGS,
4
+ createCVFromConfig,
5
+ getConfigDescription,
6
+ getConfigMode,
7
+ getConfigTransformClass,
8
+ getModeComponent,
9
+ getStyleClass,
10
+ } from "./_utils.ts";
11
+
12
+ for (const config of Object.values(CONFIGS)) {
13
+ const mode = getConfigMode(config);
14
+ const cv = createCVFromConfig(config);
15
+ const cls = getConfigTransformClass(config);
16
+
17
+ describe(getConfigDescription(config), () => {
18
+ test("variant no value empty class", () => {
19
+ const component = getModeComponent(
20
+ mode,
21
+ cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
22
+ );
23
+ const props = component();
24
+ expect(getStyleClass(props)).toEqual({ class: "" });
25
+ });
26
+
27
+ test("variant no value with class", () => {
28
+ const component = getModeComponent(
29
+ mode,
30
+ cv({ class: "foo", variants: { size: { sm: "sm", lg: "lg" } } }),
31
+ );
32
+ const props = component();
33
+ expect(getStyleClass(props)).toEqual({ class: cls("foo") });
34
+ });
35
+
36
+ test("variant with value", () => {
37
+ const component = getModeComponent(
38
+ mode,
39
+ cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
40
+ );
41
+ const props = component({ size: "lg" });
42
+ expect(getStyleClass(props)).toEqual({ class: cls("lg") });
43
+ });
44
+
45
+ test("variant with value and class", () => {
46
+ const component = getModeComponent(
47
+ mode,
48
+ cv({ class: "foo", variants: { size: { sm: "sm", lg: "lg" } } }),
49
+ );
50
+ const props = component({ size: "lg" });
51
+ expect(getStyleClass(props)).toEqual({ class: cls("foo lg") });
52
+ });
53
+
54
+ test("variant with style value", () => {
55
+ const component = getModeComponent(
56
+ mode,
57
+ cv({
58
+ variants: {
59
+ color: {
60
+ red: { style: { backgroundColor: "red" } },
61
+ blue: { style: { backgroundColor: "blue" } },
62
+ },
63
+ },
64
+ }),
65
+ );
66
+ const props = component({ color: "red" });
67
+ expect(getStyleClass(props)).toEqual({
68
+ class: "",
69
+ backgroundColor: "red",
70
+ });
71
+ });
72
+
73
+ test("rejects inline style object without style wrapper", () => {
74
+ const component = getModeComponent(
75
+ mode,
76
+ cv({
77
+ variants: {
78
+ color: {
79
+ // @ts-expect-error old shape requires `style` wrapper
80
+ red: { backgroundColor: "red" },
81
+ },
82
+ },
83
+ }),
84
+ );
85
+ const props = component({ color: "red" });
86
+ expect(getStyleClass(props)).toEqual({
87
+ class: "",
88
+ });
89
+ });
90
+
91
+ test("variant with class and style value", () => {
92
+ const component = getModeComponent(
93
+ mode,
94
+ cv({
95
+ variants: {
96
+ color: {
97
+ red: { class: "text-red", style: { backgroundColor: "red" } },
98
+ blue: { class: "text-blue", style: { backgroundColor: "blue" } },
99
+ },
100
+ },
101
+ }),
102
+ );
103
+ const props = component({ color: "red" });
104
+ expect(getStyleClass(props)).toEqual({
105
+ class: cls("text-red"),
106
+ backgroundColor: "red",
107
+ });
108
+ });
109
+
110
+ test("multiple variants", () => {
111
+ const component = getModeComponent(
112
+ mode,
113
+ cv({
114
+ variants: {
115
+ size: { sm: "sm", lg: "lg" },
116
+ color: { red: "red", blue: "blue" },
117
+ },
118
+ }),
119
+ );
120
+ const props = component({ size: "lg", color: "red" });
121
+ expect(getStyleClass(props)).toEqual({ class: cls("lg red") });
122
+ });
123
+
124
+ test("boolean variant true", () => {
125
+ const component = getModeComponent(
126
+ mode,
127
+ cv({ variants: { disabled: { true: "disabled", false: "enabled" } } }),
128
+ );
129
+ const props = component({ disabled: true });
130
+ expect(getStyleClass(props)).toEqual({ class: cls("disabled") });
131
+ });
132
+
133
+ test("boolean variant false", () => {
134
+ const component = getModeComponent(
135
+ mode,
136
+ cv({ variants: { disabled: { true: "disabled", false: "enabled" } } }),
137
+ );
138
+ const props = component({ disabled: false });
139
+ expect(getStyleClass(props)).toEqual({ class: cls("enabled") });
140
+ });
141
+
142
+ test("boolean variant true only false", () => {
143
+ const component = getModeComponent(
144
+ mode,
145
+ cv({ variants: { disabled: { true: "disabled" } } }),
146
+ );
147
+ const props = component({ disabled: false });
148
+ expect(getStyleClass(props)).toEqual({ class: "" });
149
+ });
150
+
151
+ test("boolean variant true only true", () => {
152
+ const component = getModeComponent(
153
+ mode,
154
+ cv({ variants: { disabled: { true: "disabled" } } }),
155
+ );
156
+ const props = component({ disabled: true });
157
+ expect(getStyleClass(props)).toEqual({ class: cls("disabled") });
158
+ });
159
+
160
+ test("boolean variant no value applies false", () => {
161
+ const component = getModeComponent(
162
+ mode,
163
+ cv({ variants: { disabled: { true: "disabled", false: "enabled" } } }),
164
+ );
165
+ const props = component();
166
+ expect(getStyleClass(props)).toEqual({ class: cls("enabled") });
167
+ });
168
+
169
+ test("boolean variant false only", () => {
170
+ const component = getModeComponent(
171
+ mode,
172
+ cv({ variants: { disabled: { false: "enabled" } } }),
173
+ );
174
+ const props = component();
175
+ expect(getStyleClass(props)).toEqual({ class: cls("enabled") });
176
+ });
177
+
178
+ test("boolean variant false only false", () => {
179
+ const component = getModeComponent(
180
+ mode,
181
+ cv({ variants: { disabled: { false: "enabled" } } }),
182
+ );
183
+ const props = component({ disabled: false });
184
+ expect(getStyleClass(props)).toEqual({ class: cls("enabled") });
185
+ });
186
+
187
+ test("boolean variant false only true", () => {
188
+ const component = getModeComponent(
189
+ mode,
190
+ cv({ variants: { disabled: { false: "enabled" } } }),
191
+ );
192
+ const props = component({ disabled: true });
193
+ expect(getStyleClass(props)).toEqual({ class: "" });
194
+ });
195
+
196
+ test("boolean variant shorthand true", () => {
197
+ const component = getModeComponent(
198
+ mode,
199
+ cv({ variants: { disabled: "disabled" } }),
200
+ );
201
+ const props = component({ disabled: true });
202
+ expect(getStyleClass(props)).toEqual({ class: cls("disabled") });
203
+ });
204
+
205
+ test("boolean variant shorthand false", () => {
206
+ const component = getModeComponent(
207
+ mode,
208
+ cv({ variants: { disabled: "disabled" } }),
209
+ );
210
+ const props = component({ disabled: false });
211
+ expect(getStyleClass(props)).toEqual({ class: "" });
212
+ });
213
+
214
+ test("variant style does not accept numbers", () => {
215
+ const component = getModeComponent(
216
+ mode,
217
+ cv({
218
+ variants: {
219
+ // @ts-expect-error
220
+ size: {
221
+ sm: {
222
+ class: "sm",
223
+ style: { fontSize: 12 },
224
+ },
225
+ lg: { class: "lg", style: { fontSize: "16px" } },
226
+ },
227
+ },
228
+ }),
229
+ );
230
+ const props = component({ size: "sm" });
231
+ expect(getStyleClass(props)).toEqual({
232
+ class: cls("sm"),
233
+ fontSize: expect.toBeOneOf(["12", "12px"]),
234
+ });
235
+ });
236
+
237
+ test("variant props do not accept invalid values", () => {
238
+ const component = getModeComponent(
239
+ mode,
240
+ cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
241
+ );
242
+ const props = component({
243
+ // @ts-expect-error invalid value
244
+ size:
245
+ // no error
246
+ "invalid",
247
+ });
248
+ expect(getStyleClass(props)).toEqual({ class: "" });
249
+ });
250
+
251
+ test("variant props do not accept invalid keys", () => {
252
+ const component = getModeComponent(
253
+ mode,
254
+ cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
255
+ );
256
+ const props = component({
257
+ // @ts-expect-error
258
+ invalidKey: "value",
259
+ });
260
+ expect(getStyleClass(props)).toEqual({ class: "" });
261
+ });
262
+
263
+ test("defaultVariants", () => {
264
+ const component = getModeComponent(
265
+ mode,
266
+ cv({
267
+ variants: { size: { sm: "sm", lg: "lg" } },
268
+ defaultVariants: { size: "sm" },
269
+ }),
270
+ );
271
+ const props = component();
272
+ expect(getStyleClass(props)).toEqual({ class: cls("sm") });
273
+ });
274
+
275
+ test("defaultVariants overridden by props", () => {
276
+ const component = getModeComponent(
277
+ mode,
278
+ cv({
279
+ variants: { size: { sm: "sm", lg: "lg" } },
280
+ defaultVariants: { size: "sm" },
281
+ }),
282
+ );
283
+ const props = component({ size: "lg" });
284
+ expect(getStyleClass(props)).toEqual({ class: cls("lg") });
285
+ });
286
+
287
+ test("defaultVariants boolean false", () => {
288
+ const component = getModeComponent(
289
+ mode,
290
+ cv({
291
+ variants: { disabled: { true: "disabled", false: "enabled" } },
292
+ defaultVariants: { disabled: false },
293
+ }),
294
+ );
295
+ const props = component();
296
+ expect(getStyleClass(props)).toEqual({ class: cls("enabled") });
297
+ });
298
+
299
+ test("defaultVariants boolean true", () => {
300
+ const component = getModeComponent(
301
+ mode,
302
+ cv({
303
+ variants: { disabled: { true: "disabled", false: "enabled" } },
304
+ defaultVariants: { disabled: true },
305
+ }),
306
+ );
307
+ const props = component();
308
+ expect(getStyleClass(props)).toEqual({ class: cls("disabled") });
309
+ });
310
+
311
+ test("defaultVariants boolean shorthand", () => {
312
+ const component = getModeComponent(
313
+ mode,
314
+ cv({
315
+ variants: { disabled: "disabled" },
316
+ defaultVariants: { disabled: true },
317
+ }),
318
+ );
319
+ const props = component();
320
+ expect(getStyleClass(props)).toEqual({ class: cls("disabled") });
321
+ });
322
+
323
+ test("defaultVariants does not accept invalid keys", () => {
324
+ const component = getModeComponent(
325
+ mode,
326
+ cv({
327
+ variants: { size: { sm: "sm", lg: "lg" } },
328
+ defaultVariants: {
329
+ size: "sm",
330
+ // @ts-expect-error
331
+ invalidKey: "value",
332
+ },
333
+ }),
334
+ );
335
+ const props = component();
336
+ expect(getStyleClass(props)).toEqual({ class: cls("sm") });
337
+ });
338
+
339
+ test("defaultVariants does not accept invalid values", () => {
340
+ const component = getModeComponent(
341
+ mode,
342
+ cv({
343
+ variants: { size: { sm: "sm", lg: "lg" } },
344
+ defaultVariants: {
345
+ // @ts-expect-error invalid value
346
+ size:
347
+ // no error
348
+ "invalid",
349
+ },
350
+ }),
351
+ );
352
+ const props = component();
353
+ expect(getStyleClass(props)).toEqual({ class: "" });
354
+ });
355
+
356
+ test("defaultVariants when explicitly passing undefined", () => {
357
+ const component = getModeComponent(
358
+ mode,
359
+ cv({
360
+ variants: { size: { sm: "sm", lg: "lg" } },
361
+ defaultVariants: { size: "sm" },
362
+ }),
363
+ );
364
+ const props = component({ size: undefined });
365
+ expect(getStyleClass(props)).toEqual({ class: cls("sm") });
366
+ });
367
+
368
+ test("defaultVariants boolean when explicitly passing undefined", () => {
369
+ const component = getModeComponent(
370
+ mode,
371
+ cv({
372
+ variants: { disabled: { true: "disabled", false: "enabled" } },
373
+ defaultVariants: { disabled: true },
374
+ }),
375
+ );
376
+ const props = component({ disabled: undefined });
377
+ expect(getStyleClass(props)).toEqual({ class: cls("disabled") });
378
+ });
379
+ });
380
+ }
package/tsconfig.json CHANGED
@@ -3,5 +3,5 @@
3
3
  "compilerOptions": {
4
4
  "outDir": "./.tsc"
5
5
  },
6
- "include": ["src"]
6
+ "include": ["src", "tests"]
7
7
  }