@cwcss/crosswind 0.1.5 → 0.1.6
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/LICENSE.md +21 -0
- package/README.md +390 -0
- package/dist/build.d.ts +24 -0
- package/dist/config.d.ts +5 -0
- package/dist/generator.d.ts +31 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +12798 -0
- package/dist/parser.d.ts +42 -0
- package/dist/plugin.d.ts +22 -0
- package/dist/preflight-forms.d.ts +5 -0
- package/dist/preflight.d.ts +2 -0
- package/dist/rules-advanced.d.ts +27 -0
- package/dist/rules-effects.d.ts +25 -0
- package/dist/rules-forms.d.ts +7 -0
- package/dist/rules-grid.d.ts +13 -0
- package/dist/rules-interactivity.d.ts +41 -0
- package/dist/rules-layout.d.ts +26 -0
- package/dist/rules-transforms.d.ts +33 -0
- package/dist/rules-typography.d.ts +41 -0
- package/dist/rules.d.ts +39 -0
- package/dist/scanner.d.ts +18 -0
- package/dist/transformer-compile-class.d.ts +37 -0
- package/{src/types.ts → dist/types.d.ts} +17 -86
- package/package.json +1 -1
- package/PLUGIN.md +0 -235
- package/benchmark/framework-comparison.bench.ts +0 -850
- package/bin/cli.ts +0 -365
- package/bin/crosswind +0 -0
- package/bin/headwind +0 -0
- package/build.ts +0 -8
- package/crosswind.config.ts +0 -9
- package/example/comprehensive.html +0 -70
- package/example/index.html +0 -21
- package/example/output.css +0 -236
- package/examples/plugin/README.md +0 -112
- package/examples/plugin/build.ts +0 -32
- package/examples/plugin/src/index.html +0 -34
- package/examples/plugin/src/index.ts +0 -7
- package/headwind +0 -2
- package/src/build.ts +0 -101
- package/src/config.ts +0 -529
- package/src/generator.ts +0 -2173
- package/src/index.ts +0 -10
- package/src/parser.ts +0 -1471
- package/src/plugin.ts +0 -118
- package/src/preflight-forms.ts +0 -229
- package/src/preflight.ts +0 -388
- package/src/rules-advanced.ts +0 -477
- package/src/rules-effects.ts +0 -461
- package/src/rules-forms.ts +0 -103
- package/src/rules-grid.ts +0 -241
- package/src/rules-interactivity.ts +0 -525
- package/src/rules-layout.ts +0 -385
- package/src/rules-transforms.ts +0 -412
- package/src/rules-typography.ts +0 -486
- package/src/rules.ts +0 -809
- package/src/scanner.ts +0 -84
- package/src/transformer-compile-class.ts +0 -275
- package/test/advanced-features.test.ts +0 -911
- package/test/arbitrary.test.ts +0 -396
- package/test/attributify.test.ts +0 -592
- package/test/bracket-syntax.test.ts +0 -1133
- package/test/build.test.ts +0 -99
- package/test/colors.test.ts +0 -934
- package/test/flexbox.test.ts +0 -669
- package/test/generator.test.ts +0 -597
- package/test/grid.test.ts +0 -584
- package/test/layout.test.ts +0 -404
- package/test/modifiers.test.ts +0 -417
- package/test/parser.test.ts +0 -564
- package/test/performance-regression.test.ts +0 -376
- package/test/performance.test.ts +0 -568
- package/test/plugin.test.ts +0 -160
- package/test/scanner.test.ts +0 -94
- package/test/sizing.test.ts +0 -481
- package/test/spacing.test.ts +0 -394
- package/test/transformer-compile-class.test.ts +0 -287
- package/test/transforms.test.ts +0 -448
- package/test/typography.test.ts +0 -632
- package/test/variants-form-states.test.ts +0 -225
- package/test/variants-group-peer.test.ts +0 -66
- package/test/variants-media.test.ts +0 -213
- package/test/variants-positional.test.ts +0 -58
- package/test/variants-pseudo-elements.test.ts +0 -47
- package/test/variants-state.test.ts +0 -62
- package/tsconfig.json +0 -18
package/test/performance.test.ts
DELETED
|
@@ -1,568 +0,0 @@
|
|
|
1
|
-
/* eslint-disable no-console */
|
|
2
|
-
import { describe, expect, it } from 'bun:test'
|
|
3
|
-
import { defaultConfig } from '../src/config'
|
|
4
|
-
import { CSSGenerator } from '../src/generator'
|
|
5
|
-
|
|
6
|
-
describe('Performance Tests', () => {
|
|
7
|
-
describe('CSS Generation Performance', () => {
|
|
8
|
-
it('should generate 1000 utilities in under 100ms', () => {
|
|
9
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
10
|
-
const utilities: string[] = []
|
|
11
|
-
|
|
12
|
-
// Generate variety of utilities
|
|
13
|
-
for (let i = 0; i < 250; i++) {
|
|
14
|
-
utilities.push(`w-${i}`, `h-${i}`, `p-${i}`, `m-${i}`)
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const start = performance.now()
|
|
18
|
-
for (const util of utilities) {
|
|
19
|
-
gen.generate(util)
|
|
20
|
-
}
|
|
21
|
-
const elapsed = performance.now() - start
|
|
22
|
-
|
|
23
|
-
expect(elapsed).toBeLessThan(100)
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
it('should generate 5000 utilities in under 500ms', () => {
|
|
27
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
28
|
-
const utilities: string[] = []
|
|
29
|
-
|
|
30
|
-
// Generate variety of utilities
|
|
31
|
-
for (let i = 0; i < 500; i++) {
|
|
32
|
-
utilities.push(
|
|
33
|
-
`w-${i}`,
|
|
34
|
-
`h-${i}`,
|
|
35
|
-
`p-${i}`,
|
|
36
|
-
`m-${i}`,
|
|
37
|
-
`text-${i}`,
|
|
38
|
-
`bg-blue-${i % 900}`,
|
|
39
|
-
`border-${i}`,
|
|
40
|
-
`gap-${i}`,
|
|
41
|
-
`grid-cols-${i % 12}`,
|
|
42
|
-
`flex-${i % 10}`,
|
|
43
|
-
)
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const start = performance.now()
|
|
47
|
-
for (const util of utilities) {
|
|
48
|
-
gen.generate(util)
|
|
49
|
-
}
|
|
50
|
-
const elapsed = performance.now() - start
|
|
51
|
-
|
|
52
|
-
expect(elapsed).toBeLessThan(500)
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
it('should generate complex responsive utilities efficiently', () => {
|
|
56
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
57
|
-
const utilities = [
|
|
58
|
-
'sm:md:lg:xl:2xl:w-full',
|
|
59
|
-
'sm:hover:focus:bg-blue-500',
|
|
60
|
-
'md:group-hover:text-red-500',
|
|
61
|
-
'lg:peer-focus:border-green-500',
|
|
62
|
-
'xl:dark:bg-gray-900',
|
|
63
|
-
]
|
|
64
|
-
|
|
65
|
-
const start = performance.now()
|
|
66
|
-
for (let i = 0; i < 200; i++) {
|
|
67
|
-
for (const util of utilities) {
|
|
68
|
-
gen.generate(util)
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
const elapsed = performance.now() - start
|
|
72
|
-
|
|
73
|
-
expect(elapsed).toBeLessThan(200)
|
|
74
|
-
})
|
|
75
|
-
|
|
76
|
-
it('should handle arbitrary values efficiently', () => {
|
|
77
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
78
|
-
const utilities: string[] = []
|
|
79
|
-
|
|
80
|
-
for (let i = 0; i < 100; i++) {
|
|
81
|
-
utilities.push(
|
|
82
|
-
`w-[${i}px]`,
|
|
83
|
-
`h-[${i * 2}rem]`,
|
|
84
|
-
`text-[${i}px]`,
|
|
85
|
-
`bg-[#${i.toString(16).padStart(6, '0')}]`,
|
|
86
|
-
`p-[${i}em]`,
|
|
87
|
-
`m-[${i}%]`,
|
|
88
|
-
`grid-cols-[repeat(${i},1fr)]`,
|
|
89
|
-
`shadow-[0_${i}px_${i * 2}px_rgba(0,0,0,0.1)]`,
|
|
90
|
-
)
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
const start = performance.now()
|
|
94
|
-
for (const util of utilities) {
|
|
95
|
-
gen.generate(util)
|
|
96
|
-
}
|
|
97
|
-
const elapsed = performance.now() - start
|
|
98
|
-
|
|
99
|
-
expect(elapsed).toBeLessThan(100)
|
|
100
|
-
})
|
|
101
|
-
})
|
|
102
|
-
|
|
103
|
-
describe('Duplicate Detection Performance', () => {
|
|
104
|
-
it('should efficiently handle duplicate utilities', () => {
|
|
105
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
106
|
-
const utilities = ['w-4', 'h-4', 'p-4', 'm-4', 'text-lg', 'bg-blue-500']
|
|
107
|
-
|
|
108
|
-
const start = performance.now()
|
|
109
|
-
// Generate each utility 1000 times
|
|
110
|
-
for (let i = 0; i < 1000; i++) {
|
|
111
|
-
for (const util of utilities) {
|
|
112
|
-
gen.generate(util)
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
const elapsed = performance.now() - start
|
|
116
|
-
|
|
117
|
-
const css = gen.toCSS(false)
|
|
118
|
-
// Count only utility rules (not preflight)
|
|
119
|
-
const utilityRules = css.split('\n').filter(line =>
|
|
120
|
-
line.startsWith('.w-4') || line.startsWith('.h-4')
|
|
121
|
-
|| line.startsWith('.p-4') || line.startsWith('.m-4')
|
|
122
|
-
|| line.startsWith('.text-lg') || line.startsWith('.bg-blue-500'),
|
|
123
|
-
).length
|
|
124
|
-
|
|
125
|
-
expect(elapsed).toBeLessThan(200) // Allow more time for CI environments
|
|
126
|
-
expect(utilityRules).toBe(6) // Should only have 6 unique utility classes
|
|
127
|
-
})
|
|
128
|
-
|
|
129
|
-
it('should cache parsed utilities efficiently', () => {
|
|
130
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
131
|
-
const utility = 'sm:hover:focus:disabled:bg-blue-500'
|
|
132
|
-
|
|
133
|
-
// First generation (parsing + generation)
|
|
134
|
-
const start1 = performance.now()
|
|
135
|
-
for (let i = 0; i < 100; i++) {
|
|
136
|
-
gen.generate(utility)
|
|
137
|
-
}
|
|
138
|
-
const elapsed1 = performance.now() - start1
|
|
139
|
-
|
|
140
|
-
// Second generation (should be cached)
|
|
141
|
-
const start2 = performance.now()
|
|
142
|
-
for (let i = 0; i < 100; i++) {
|
|
143
|
-
gen.generate(utility)
|
|
144
|
-
}
|
|
145
|
-
const elapsed2 = performance.now() - start2
|
|
146
|
-
|
|
147
|
-
// Cache should make second run faster or similar
|
|
148
|
-
expect(elapsed2).toBeLessThanOrEqual(elapsed1 * 1.5)
|
|
149
|
-
})
|
|
150
|
-
})
|
|
151
|
-
|
|
152
|
-
describe('CSS Output Performance', () => {
|
|
153
|
-
it('should convert to CSS string efficiently for large rulesets', () => {
|
|
154
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
155
|
-
|
|
156
|
-
// Generate 2000 unique utilities
|
|
157
|
-
for (let i = 0; i < 2000; i++) {
|
|
158
|
-
gen.generate(`w-[${i}px]`)
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
const start = performance.now()
|
|
162
|
-
const css = gen.toCSS(false)
|
|
163
|
-
const elapsed = performance.now() - start
|
|
164
|
-
|
|
165
|
-
expect(elapsed).toBeLessThan(50)
|
|
166
|
-
expect(css.length).toBeGreaterThan(0)
|
|
167
|
-
})
|
|
168
|
-
|
|
169
|
-
it('should generate CSS with minify option efficiently', () => {
|
|
170
|
-
const gen = new CSSGenerator({ ...defaultConfig, minify: true })
|
|
171
|
-
|
|
172
|
-
// Generate utilities
|
|
173
|
-
for (let i = 0; i < 500; i++) {
|
|
174
|
-
gen.generate(`w-${i}`)
|
|
175
|
-
gen.generate(`h-${i}`)
|
|
176
|
-
gen.generate(`p-${i}`)
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
const start = performance.now()
|
|
180
|
-
const css = gen.toCSS(false)
|
|
181
|
-
const elapsed = performance.now() - start
|
|
182
|
-
|
|
183
|
-
// Performance should be similar whether minified or not
|
|
184
|
-
expect(elapsed).toBeLessThan(50)
|
|
185
|
-
expect(css.length).toBeGreaterThan(0)
|
|
186
|
-
})
|
|
187
|
-
})
|
|
188
|
-
|
|
189
|
-
describe('Variant Processing Performance', () => {
|
|
190
|
-
it('should handle multiple variants efficiently', () => {
|
|
191
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
192
|
-
const variants = [
|
|
193
|
-
'hover:',
|
|
194
|
-
'focus:',
|
|
195
|
-
'active:',
|
|
196
|
-
'disabled:',
|
|
197
|
-
'group-hover:',
|
|
198
|
-
'peer-focus:',
|
|
199
|
-
'first:',
|
|
200
|
-
'last:',
|
|
201
|
-
'odd:',
|
|
202
|
-
'even:',
|
|
203
|
-
'dark:',
|
|
204
|
-
]
|
|
205
|
-
|
|
206
|
-
const utilities: string[] = []
|
|
207
|
-
for (const variant of variants) {
|
|
208
|
-
for (let i = 0; i < 50; i++) {
|
|
209
|
-
utilities.push(`${variant}bg-blue-${i}`)
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
const start = performance.now()
|
|
214
|
-
for (const util of utilities) {
|
|
215
|
-
gen.generate(util)
|
|
216
|
-
}
|
|
217
|
-
const elapsed = performance.now() - start
|
|
218
|
-
|
|
219
|
-
expect(elapsed).toBeLessThan(100)
|
|
220
|
-
})
|
|
221
|
-
|
|
222
|
-
it('should handle important modifier efficiently', () => {
|
|
223
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
224
|
-
|
|
225
|
-
const start = performance.now()
|
|
226
|
-
for (let i = 0; i < 1000; i++) {
|
|
227
|
-
gen.generate(`!w-${i}`)
|
|
228
|
-
gen.generate(`!h-${i}`)
|
|
229
|
-
gen.generate(`!p-${i}`)
|
|
230
|
-
}
|
|
231
|
-
const elapsed = performance.now() - start
|
|
232
|
-
|
|
233
|
-
expect(elapsed).toBeLessThan(100)
|
|
234
|
-
})
|
|
235
|
-
|
|
236
|
-
it('should handle responsive breakpoints efficiently', () => {
|
|
237
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
238
|
-
const breakpoints = ['sm', 'md', 'lg', 'xl', '2xl']
|
|
239
|
-
|
|
240
|
-
const start = performance.now()
|
|
241
|
-
for (const bp of breakpoints) {
|
|
242
|
-
for (let i = 0; i < 200; i++) {
|
|
243
|
-
gen.generate(`${bp}:w-${i}`)
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
const elapsed = performance.now() - start
|
|
247
|
-
|
|
248
|
-
expect(elapsed).toBeLessThan(150)
|
|
249
|
-
})
|
|
250
|
-
})
|
|
251
|
-
|
|
252
|
-
describe('Color Processing Performance', () => {
|
|
253
|
-
it('should handle color utilities efficiently', () => {
|
|
254
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
255
|
-
const colors = ['blue', 'red', 'green', 'yellow', 'purple', 'pink', 'indigo', 'gray']
|
|
256
|
-
const shades = ['50', '100', '200', '300', '400', '500', '600', '700', '800', '900']
|
|
257
|
-
|
|
258
|
-
const start = performance.now()
|
|
259
|
-
for (const color of colors) {
|
|
260
|
-
for (const shade of shades) {
|
|
261
|
-
gen.generate(`bg-${color}-${shade}`)
|
|
262
|
-
gen.generate(`text-${color}-${shade}`)
|
|
263
|
-
gen.generate(`border-${color}-${shade}`)
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
const elapsed = performance.now() - start
|
|
267
|
-
|
|
268
|
-
expect(elapsed).toBeLessThan(50)
|
|
269
|
-
})
|
|
270
|
-
|
|
271
|
-
it('should handle gradient utilities efficiently', () => {
|
|
272
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
273
|
-
const directions = ['to-t', 'to-tr', 'to-r', 'to-br', 'to-b', 'to-bl', 'to-l', 'to-tl']
|
|
274
|
-
const colors = ['blue-500', 'red-500', 'green-500', 'purple-500']
|
|
275
|
-
|
|
276
|
-
const start = performance.now()
|
|
277
|
-
for (const dir of directions) {
|
|
278
|
-
for (const from of colors) {
|
|
279
|
-
for (const to of colors) {
|
|
280
|
-
gen.generate(`bg-gradient-${dir}`)
|
|
281
|
-
gen.generate(`from-${from}`)
|
|
282
|
-
gen.generate(`to-${to}`)
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
const elapsed = performance.now() - start
|
|
287
|
-
|
|
288
|
-
expect(elapsed).toBeLessThan(100)
|
|
289
|
-
})
|
|
290
|
-
})
|
|
291
|
-
|
|
292
|
-
describe('Grid and Flexbox Performance', () => {
|
|
293
|
-
it('should handle grid utilities efficiently', () => {
|
|
294
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
295
|
-
|
|
296
|
-
const start = performance.now()
|
|
297
|
-
for (let i = 1; i <= 12; i++) {
|
|
298
|
-
gen.generate(`grid-cols-${i}`)
|
|
299
|
-
gen.generate(`col-span-${i}`)
|
|
300
|
-
gen.generate(`col-start-${i}`)
|
|
301
|
-
gen.generate(`col-end-${i}`)
|
|
302
|
-
gen.generate(`gap-${i}`)
|
|
303
|
-
gen.generate(`gap-x-${i}`)
|
|
304
|
-
gen.generate(`gap-y-${i}`)
|
|
305
|
-
}
|
|
306
|
-
const elapsed = performance.now() - start
|
|
307
|
-
|
|
308
|
-
expect(elapsed).toBeLessThan(20)
|
|
309
|
-
})
|
|
310
|
-
|
|
311
|
-
it('should handle flexbox utilities efficiently', () => {
|
|
312
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
313
|
-
const values = ['1', '2', '3', 'auto', 'none']
|
|
314
|
-
|
|
315
|
-
const start = performance.now()
|
|
316
|
-
for (let i = 0; i < 200; i++) {
|
|
317
|
-
gen.generate('flex')
|
|
318
|
-
gen.generate('inline-flex')
|
|
319
|
-
gen.generate('flex-row')
|
|
320
|
-
gen.generate('flex-col')
|
|
321
|
-
gen.generate('flex-wrap')
|
|
322
|
-
gen.generate('flex-nowrap')
|
|
323
|
-
values.forEach(val => gen.generate(`flex-${val}`))
|
|
324
|
-
values.forEach(val => gen.generate(`grow-${val}`))
|
|
325
|
-
values.forEach(val => gen.generate(`shrink-${val}`))
|
|
326
|
-
}
|
|
327
|
-
const elapsed = performance.now() - start
|
|
328
|
-
|
|
329
|
-
expect(elapsed).toBeLessThan(100)
|
|
330
|
-
})
|
|
331
|
-
})
|
|
332
|
-
|
|
333
|
-
describe('Memory Efficiency', () => {
|
|
334
|
-
it('should not leak memory with repeated generations', () => {
|
|
335
|
-
const iterations = 10
|
|
336
|
-
const memorySamples: number[] = []
|
|
337
|
-
|
|
338
|
-
for (let i = 0; i < iterations; i++) {
|
|
339
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
340
|
-
|
|
341
|
-
// Generate a lot of utilities
|
|
342
|
-
for (let j = 0; j < 1000; j++) {
|
|
343
|
-
gen.generate(`w-${j}`)
|
|
344
|
-
gen.generate(`h-${j}`)
|
|
345
|
-
gen.generate(`p-${j}`)
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
gen.toCSS(false)
|
|
349
|
-
|
|
350
|
-
// Force garbage collection if available
|
|
351
|
-
if (globalThis.gc) {
|
|
352
|
-
globalThis.gc()
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
if (typeof process !== 'undefined' && process.memoryUsage) {
|
|
356
|
-
memorySamples.push(process.memoryUsage().heapUsed)
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
// If we have memory samples, check they're not growing exponentially
|
|
361
|
-
if (memorySamples.length > 5) {
|
|
362
|
-
const firstHalf = memorySamples.slice(0, 5).reduce((a, b) => a + b) / 5
|
|
363
|
-
const secondHalf = memorySamples.slice(5).reduce((a, b) => a + b) / 5
|
|
364
|
-
|
|
365
|
-
// Second half should not be more than 3x the first half
|
|
366
|
-
// (allowing for normal variance and JIT optimization)
|
|
367
|
-
expect(secondHalf).toBeLessThan(firstHalf * 3)
|
|
368
|
-
}
|
|
369
|
-
})
|
|
370
|
-
|
|
371
|
-
it('should handle large class strings efficiently', () => {
|
|
372
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
373
|
-
|
|
374
|
-
// Create a very large class string
|
|
375
|
-
const classes = Array.from({ length: 500 }, (_, i) =>
|
|
376
|
-
`w-${i} h-${i} p-${i} m-${i} bg-blue-${i % 900} text-${i}`).join(' ')
|
|
377
|
-
|
|
378
|
-
const start = performance.now()
|
|
379
|
-
gen.generate(classes)
|
|
380
|
-
const elapsed = performance.now() - start
|
|
381
|
-
|
|
382
|
-
expect(elapsed).toBeLessThan(200)
|
|
383
|
-
})
|
|
384
|
-
})
|
|
385
|
-
|
|
386
|
-
describe('Edge Cases Performance', () => {
|
|
387
|
-
it('should handle deeply nested variants efficiently', () => {
|
|
388
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
389
|
-
|
|
390
|
-
const start = performance.now()
|
|
391
|
-
for (let i = 0; i < 100; i++) {
|
|
392
|
-
gen.generate('sm:md:lg:xl:hover:focus:active:dark:group-hover:w-full')
|
|
393
|
-
gen.generate('md:lg:xl:2xl:first:last:odd:even:bg-blue-500')
|
|
394
|
-
}
|
|
395
|
-
const elapsed = performance.now() - start
|
|
396
|
-
|
|
397
|
-
expect(elapsed).toBeLessThan(50)
|
|
398
|
-
})
|
|
399
|
-
|
|
400
|
-
it('should handle very long arbitrary values efficiently', () => {
|
|
401
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
402
|
-
const longValue = 'rgba(255,255,255,0.1),rgba(0,0,0,0.2),rgba(100,100,100,0.3)'
|
|
403
|
-
|
|
404
|
-
const start = performance.now()
|
|
405
|
-
for (let i = 0; i < 100; i++) {
|
|
406
|
-
gen.generate(`bg-[${longValue}]`)
|
|
407
|
-
gen.generate(`shadow-[0_0_100px_50px_${longValue}]`)
|
|
408
|
-
}
|
|
409
|
-
const elapsed = performance.now() - start
|
|
410
|
-
|
|
411
|
-
expect(elapsed).toBeLessThan(50)
|
|
412
|
-
})
|
|
413
|
-
|
|
414
|
-
it('should handle invalid utilities gracefully without performance degradation', () => {
|
|
415
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
416
|
-
const invalidUtilities = [
|
|
417
|
-
'invalid-utility-name',
|
|
418
|
-
'w-',
|
|
419
|
-
'h-',
|
|
420
|
-
'bg-nonexistent-color',
|
|
421
|
-
'text-invalid-size',
|
|
422
|
-
'::invalid::modifier::w-4',
|
|
423
|
-
]
|
|
424
|
-
|
|
425
|
-
const start = performance.now()
|
|
426
|
-
for (let i = 0; i < 500; i++) {
|
|
427
|
-
for (const util of invalidUtilities) {
|
|
428
|
-
gen.generate(util)
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
const elapsed = performance.now() - start
|
|
432
|
-
|
|
433
|
-
expect(elapsed).toBeLessThan(100)
|
|
434
|
-
})
|
|
435
|
-
})
|
|
436
|
-
|
|
437
|
-
describe('Real-world Scenarios', () => {
|
|
438
|
-
it('should handle typical component class list efficiently', () => {
|
|
439
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
440
|
-
|
|
441
|
-
const componentClasses = [
|
|
442
|
-
'flex items-center justify-between p-4 bg-white dark:bg-gray-800 rounded-lg shadow-md',
|
|
443
|
-
'w-full max-w-md mx-auto space-y-4 sm:space-y-6',
|
|
444
|
-
'text-lg font-semibold text-gray-900 dark:text-white',
|
|
445
|
-
'grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4',
|
|
446
|
-
'hover:bg-blue-50 hover:dark:bg-blue-900 transition-colors duration-200',
|
|
447
|
-
'border border-gray-200 dark:border-gray-700 focus:ring-2 focus:ring-blue-500',
|
|
448
|
-
]
|
|
449
|
-
|
|
450
|
-
const start = performance.now()
|
|
451
|
-
for (let i = 0; i < 200; i++) {
|
|
452
|
-
for (const classes of componentClasses) {
|
|
453
|
-
gen.generate(classes)
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
const elapsed = performance.now() - start
|
|
457
|
-
|
|
458
|
-
expect(elapsed).toBeLessThan(150)
|
|
459
|
-
})
|
|
460
|
-
|
|
461
|
-
it('should handle entire page worth of utilities efficiently', () => {
|
|
462
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
463
|
-
|
|
464
|
-
// Simulate a page with 100 components, each with 10-20 utility classes
|
|
465
|
-
const utilities: string[] = []
|
|
466
|
-
for (let i = 0; i < 100; i++) {
|
|
467
|
-
utilities.push(
|
|
468
|
-
`container mx-auto px-${i % 8}`,
|
|
469
|
-
`grid grid-cols-${(i % 12) + 1} gap-${i % 16}`,
|
|
470
|
-
`flex flex-col md:flex-row items-center justify-between`,
|
|
471
|
-
`text-${['sm', 'base', 'lg', 'xl', '2xl'][i % 5]} font-${['normal', 'medium', 'semibold', 'bold'][i % 4]}`,
|
|
472
|
-
`bg-${['white', 'gray-50', 'gray-100', 'blue-50'][i % 4]} dark:bg-gray-${800 + (i % 2) * 100}`,
|
|
473
|
-
`rounded-${['none', 'sm', 'md', 'lg', 'xl'][i % 5]} shadow-${['sm', 'md', 'lg', 'xl'][i % 4]}`,
|
|
474
|
-
`p-${i % 12} m-${i % 12} space-y-${i % 8}`,
|
|
475
|
-
`hover:bg-blue-${(i % 9) * 100 + 100} hover:scale-105 transition-all duration-${100 + (i % 5) * 100}`,
|
|
476
|
-
`border border-gray-${200 + (i % 7) * 100} focus:ring-${(i % 4) + 1} focus:ring-blue-500`,
|
|
477
|
-
`w-${['full', 'auto', '1/2', '1/3', '2/3', '1/4', '3/4'][i % 7]} h-${i % 96}`,
|
|
478
|
-
)
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
const start = performance.now()
|
|
482
|
-
for (const util of utilities) {
|
|
483
|
-
gen.generate(util)
|
|
484
|
-
}
|
|
485
|
-
const css = gen.toCSS(false)
|
|
486
|
-
const elapsed = performance.now() - start
|
|
487
|
-
|
|
488
|
-
expect(elapsed).toBeLessThan(300)
|
|
489
|
-
expect(css.length).toBeGreaterThan(0)
|
|
490
|
-
})
|
|
491
|
-
|
|
492
|
-
it('should handle progressive enhancement patterns efficiently', () => {
|
|
493
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
494
|
-
|
|
495
|
-
const start = performance.now()
|
|
496
|
-
for (let i = 0; i < 100; i++) {
|
|
497
|
-
// Mobile-first responsive design
|
|
498
|
-
gen.generate(`w-full sm:w-auto md:w-1/2 lg:w-1/3 xl:w-1/4`)
|
|
499
|
-
gen.generate(`text-sm sm:text-base md:text-lg lg:text-xl xl:text-2xl`)
|
|
500
|
-
gen.generate(`p-2 sm:p-4 md:p-6 lg:p-8 xl:p-10`)
|
|
501
|
-
gen.generate(`grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4`)
|
|
502
|
-
|
|
503
|
-
// Dark mode support
|
|
504
|
-
gen.generate(`bg-white dark:bg-gray-900 text-gray-900 dark:text-white`)
|
|
505
|
-
gen.generate(`border-gray-200 dark:border-gray-700`)
|
|
506
|
-
|
|
507
|
-
// Interactive states
|
|
508
|
-
gen.generate(`hover:bg-blue-500 focus:bg-blue-600 active:bg-blue-700`)
|
|
509
|
-
gen.generate(`hover:scale-105 focus:ring-2 active:scale-95`)
|
|
510
|
-
}
|
|
511
|
-
const elapsed = performance.now() - start
|
|
512
|
-
|
|
513
|
-
expect(elapsed).toBeLessThan(100)
|
|
514
|
-
})
|
|
515
|
-
})
|
|
516
|
-
|
|
517
|
-
describe('Benchmark Comparison', () => {
|
|
518
|
-
it('should demonstrate performance baseline', () => {
|
|
519
|
-
const results: Record<string, number> = {}
|
|
520
|
-
|
|
521
|
-
// Benchmark: Simple utilities
|
|
522
|
-
const gen1 = new CSSGenerator(defaultConfig)
|
|
523
|
-
const start1 = performance.now()
|
|
524
|
-
for (let i = 0; i < 1000; i++) {
|
|
525
|
-
gen1.generate(`w-${i}`)
|
|
526
|
-
}
|
|
527
|
-
results.simpleUtilities = performance.now() - start1
|
|
528
|
-
|
|
529
|
-
// Benchmark: Complex utilities
|
|
530
|
-
const gen2 = new CSSGenerator(defaultConfig)
|
|
531
|
-
const start2 = performance.now()
|
|
532
|
-
for (let i = 0; i < 1000; i++) {
|
|
533
|
-
gen2.generate(`sm:md:hover:dark:w-${i}`)
|
|
534
|
-
}
|
|
535
|
-
results.complexUtilities = performance.now() - start2
|
|
536
|
-
|
|
537
|
-
// Benchmark: Arbitrary values
|
|
538
|
-
const gen3 = new CSSGenerator(defaultConfig)
|
|
539
|
-
const start3 = performance.now()
|
|
540
|
-
for (let i = 0; i < 1000; i++) {
|
|
541
|
-
gen3.generate(`w-[${i}px]`)
|
|
542
|
-
}
|
|
543
|
-
results.arbitraryValues = performance.now() - start3
|
|
544
|
-
|
|
545
|
-
// Benchmark: CSS output
|
|
546
|
-
const gen4 = new CSSGenerator(defaultConfig)
|
|
547
|
-
for (let i = 0; i < 1000; i++) {
|
|
548
|
-
gen4.generate(`w-${i}`)
|
|
549
|
-
}
|
|
550
|
-
const start4 = performance.now()
|
|
551
|
-
gen4.toCSS(false)
|
|
552
|
-
results.cssOutput = performance.now() - start4
|
|
553
|
-
|
|
554
|
-
// Log results for reference
|
|
555
|
-
console.log('\nPerformance Benchmarks:')
|
|
556
|
-
console.log(` Simple utilities (1000): ${results.simpleUtilities.toFixed(2)}ms`)
|
|
557
|
-
console.log(` Complex utilities (1000): ${results.complexUtilities.toFixed(2)}ms`)
|
|
558
|
-
console.log(` Arbitrary values (1000): ${results.arbitraryValues.toFixed(2)}ms`)
|
|
559
|
-
console.log(` CSS output (1000 rules): ${results.cssOutput.toFixed(2)}ms`)
|
|
560
|
-
|
|
561
|
-
// Ensure reasonable performance
|
|
562
|
-
expect(results.simpleUtilities).toBeLessThan(100)
|
|
563
|
-
expect(results.complexUtilities).toBeLessThan(200)
|
|
564
|
-
expect(results.arbitraryValues).toBeLessThan(150)
|
|
565
|
-
expect(results.cssOutput).toBeLessThan(50)
|
|
566
|
-
})
|
|
567
|
-
})
|
|
568
|
-
})
|