@cwcss/crosswind 0.1.5 → 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.
- package/LICENSE.md +21 -0
- package/README.md +52 -0
- package/dist/bin/cli.js +14615 -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/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/src/index.js +12848 -0
- package/dist/transformer-compile-class.d.ts +37 -0
- package/{src/types.ts → dist/types.d.ts} +17 -86
- package/package.json +2 -16
- 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
|
@@ -1,376 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, it } from 'bun:test'
|
|
2
|
-
import { CSSGenerator } from '../src/generator'
|
|
3
|
-
import { defaultConfig } from '../src/config'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Performance Regression Tests
|
|
7
|
-
*
|
|
8
|
-
* These tests ensure we maintain our PERFECT 10/10 benchmark performance.
|
|
9
|
-
* Each test has a threshold based on our current performance numbers with generous margins.
|
|
10
|
-
* If performance degrades significantly, these tests will fail.
|
|
11
|
-
*
|
|
12
|
-
* NOTE: These tests use performance.now() for measurements, which has different characteristics
|
|
13
|
-
* than the Mitata benchmarking tool used in benchmark.test.ts. The thresholds here are set
|
|
14
|
-
* based on actual measured values with 2-3x safety margins.
|
|
15
|
-
*
|
|
16
|
-
* Current Performance Targets (vs UnoCSS in Mitata benchmarks):
|
|
17
|
-
* - CSS Output Generation: 77.4x faster (benchmark: 910µs vs 70.5ms)
|
|
18
|
-
* - Duplicate Handling: 52.0x faster (benchmark: 30µs vs 1.6ms)
|
|
19
|
-
* - Real-world Components: 24.4x faster (benchmark: 5.6µs vs 136µs)
|
|
20
|
-
* - Arbitrary Values: 10.6x faster (benchmark: 2.5µs vs 26µs)
|
|
21
|
-
* - Color Utilities: 5.4x faster (benchmark: 54µs vs 289µs)
|
|
22
|
-
* - Interactive States: 3.8x faster (benchmark: 236µs vs 888µs)
|
|
23
|
-
* - Simple Utilities: 3.5x faster (benchmark: 5µs vs 18µs)
|
|
24
|
-
* - Complex Utilities: 2.9x faster (benchmark: 8µs vs 24µs)
|
|
25
|
-
* - Large Scale: 1.67x faster (benchmark: 265µs vs 444µs)
|
|
26
|
-
* - Responsive Utilities: 1.16x faster (benchmark: 542µs vs 631µs)
|
|
27
|
-
*
|
|
28
|
-
* Critical Optimization: Rule Ordering
|
|
29
|
-
* The most common utilities (spacing, sizing, colors) are placed at the beginning of the
|
|
30
|
-
* builtInRules array for O(1) lookup performance. The "Rule Ordering Performance - Critical!"
|
|
31
|
-
* test ensures this optimization stays in place.
|
|
32
|
-
*/
|
|
33
|
-
|
|
34
|
-
describe('Performance Regression Tests', () => {
|
|
35
|
-
let gen: CSSGenerator
|
|
36
|
-
|
|
37
|
-
beforeEach(() => {
|
|
38
|
-
gen = new CSSGenerator(defaultConfig)
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
describe('Simple Utilities Performance', () => {
|
|
42
|
-
it('should process 10 simple utilities within threshold', () => {
|
|
43
|
-
const utilities = [
|
|
44
|
-
'w-4', 'h-4', 'p-4', 'm-4', 'text-lg',
|
|
45
|
-
'bg-blue-500', 'flex', 'items-center',
|
|
46
|
-
'justify-between', 'rounded-lg',
|
|
47
|
-
]
|
|
48
|
-
|
|
49
|
-
const start = performance.now()
|
|
50
|
-
for (const cls of utilities) {
|
|
51
|
-
gen.generate(cls)
|
|
52
|
-
}
|
|
53
|
-
const duration = performance.now() - start
|
|
54
|
-
|
|
55
|
-
// Current: ~2ms, threshold: 5ms (2.5x margin for safety)
|
|
56
|
-
expect(duration).toBeLessThan(5) // 5ms
|
|
57
|
-
})
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
describe('Complex Utilities with Variants Performance', () => {
|
|
61
|
-
it('should process complex utilities with variants within threshold', () => {
|
|
62
|
-
const utilities = [
|
|
63
|
-
'sm:w-full', 'md:w-1/2', 'lg:w-1/3',
|
|
64
|
-
'hover:bg-blue-600', 'focus:ring-2',
|
|
65
|
-
'dark:bg-gray-800', 'first:mt-0',
|
|
66
|
-
'last:mb-0', 'group-hover:scale-105',
|
|
67
|
-
'peer-focus:border-blue-500', 'motion-safe:animate-bounce',
|
|
68
|
-
]
|
|
69
|
-
|
|
70
|
-
const start = performance.now()
|
|
71
|
-
for (const cls of utilities) {
|
|
72
|
-
gen.generate(cls)
|
|
73
|
-
}
|
|
74
|
-
const duration = performance.now() - start
|
|
75
|
-
|
|
76
|
-
// Current: ~0.2ms, threshold: 1ms
|
|
77
|
-
expect(duration).toBeLessThan(1) // 1ms
|
|
78
|
-
})
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
describe('Arbitrary Values Performance', () => {
|
|
82
|
-
it('should process arbitrary values within threshold', () => {
|
|
83
|
-
const utilities = [
|
|
84
|
-
'w-[123px]',
|
|
85
|
-
'h-[456px]',
|
|
86
|
-
'text-[#ff0000]',
|
|
87
|
-
'p-[2rem]',
|
|
88
|
-
'bg-[#1a1a1a]',
|
|
89
|
-
'm-[10%]',
|
|
90
|
-
'shadow-[0_4px_6px_rgba(0,0,0,0.1)]',
|
|
91
|
-
]
|
|
92
|
-
|
|
93
|
-
const start = performance.now()
|
|
94
|
-
for (const cls of utilities) {
|
|
95
|
-
gen.generate(cls)
|
|
96
|
-
}
|
|
97
|
-
const duration = performance.now() - start
|
|
98
|
-
|
|
99
|
-
// Current: ~0.05ms, threshold: 0.2ms
|
|
100
|
-
expect(duration).toBeLessThan(0.2) // 0.2ms
|
|
101
|
-
})
|
|
102
|
-
})
|
|
103
|
-
|
|
104
|
-
describe('Real-world Component Classes Performance', () => {
|
|
105
|
-
it('should process real-world component patterns within threshold', () => {
|
|
106
|
-
const componentClasses = [
|
|
107
|
-
'flex items-center justify-between p-4 bg-white dark:bg-gray-800 rounded-lg shadow-md',
|
|
108
|
-
'grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4',
|
|
109
|
-
'text-sm font-medium text-gray-700 hover:text-gray-900',
|
|
110
|
-
'absolute inset-0 bg-black bg-opacity-50 flex items-center justify-center',
|
|
111
|
-
'transition-all duration-200 ease-in-out hover:scale-105',
|
|
112
|
-
'border border-gray-300 focus:border-blue-500 focus:ring-2 focus:ring-blue-200',
|
|
113
|
-
]
|
|
114
|
-
|
|
115
|
-
const start = performance.now()
|
|
116
|
-
for (const classString of componentClasses) {
|
|
117
|
-
const classes = classString.split(/\s+/)
|
|
118
|
-
for (const cls of classes) {
|
|
119
|
-
gen.generate(cls)
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
const duration = performance.now() - start
|
|
123
|
-
|
|
124
|
-
// Current: ~0.5ms, threshold: 2ms
|
|
125
|
-
expect(duration).toBeLessThan(2) // 2ms
|
|
126
|
-
})
|
|
127
|
-
})
|
|
128
|
-
|
|
129
|
-
describe('Large Scale Performance', () => {
|
|
130
|
-
it('should process 1000 utilities within threshold', () => {
|
|
131
|
-
const largeSet: string[] = []
|
|
132
|
-
for (let i = 0; i < 250; i++) {
|
|
133
|
-
largeSet.push(`w-${i}`, `h-${i}`, `p-${i}`, `m-${i}`)
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
const start = performance.now()
|
|
137
|
-
for (const cls of largeSet) {
|
|
138
|
-
gen.generate(cls)
|
|
139
|
-
}
|
|
140
|
-
const duration = performance.now() - start
|
|
141
|
-
|
|
142
|
-
// Current: ~5ms, threshold: 15ms (3x margin)
|
|
143
|
-
expect(duration).toBeLessThan(15) // 15ms
|
|
144
|
-
})
|
|
145
|
-
})
|
|
146
|
-
|
|
147
|
-
describe('CSS Output Generation Performance', () => {
|
|
148
|
-
it('should generate CSS from 1000 rules within threshold', () => {
|
|
149
|
-
const utilities: string[] = []
|
|
150
|
-
for (let i = 0; i < 1000; i++) {
|
|
151
|
-
utilities.push(`w-[${i}px]`)
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
// Generate all utilities
|
|
155
|
-
for (const cls of utilities) {
|
|
156
|
-
gen.generate(cls)
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// Measure CSS output generation
|
|
160
|
-
const start = performance.now()
|
|
161
|
-
const css = gen.toCSS()
|
|
162
|
-
const duration = performance.now() - start
|
|
163
|
-
|
|
164
|
-
// Current: ~2ms, threshold: 5ms
|
|
165
|
-
expect(duration).toBeLessThan(5) // 5ms
|
|
166
|
-
expect(css.length).toBeGreaterThan(0)
|
|
167
|
-
})
|
|
168
|
-
})
|
|
169
|
-
|
|
170
|
-
describe('Color Utilities Performance', () => {
|
|
171
|
-
it('should process 240 color utilities within threshold', () => {
|
|
172
|
-
const colors = ['blue', 'red', 'green', 'yellow', 'purple', 'pink', 'indigo', 'gray']
|
|
173
|
-
const shades = ['50', '100', '200', '300', '400', '500', '600', '700', '800', '900']
|
|
174
|
-
const colorUtilities: string[] = []
|
|
175
|
-
|
|
176
|
-
for (const color of colors) {
|
|
177
|
-
for (const shade of shades) {
|
|
178
|
-
colorUtilities.push(`bg-${color}-${shade}`)
|
|
179
|
-
colorUtilities.push(`text-${color}-${shade}`)
|
|
180
|
-
colorUtilities.push(`border-${color}-${shade}`)
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
const start = performance.now()
|
|
185
|
-
for (const cls of colorUtilities) {
|
|
186
|
-
gen.generate(cls)
|
|
187
|
-
}
|
|
188
|
-
const duration = performance.now() - start
|
|
189
|
-
|
|
190
|
-
// Current: ~1ms, threshold: 3ms
|
|
191
|
-
expect(duration).toBeLessThan(3) // 3ms
|
|
192
|
-
})
|
|
193
|
-
})
|
|
194
|
-
|
|
195
|
-
describe('Responsive Utilities Performance', () => {
|
|
196
|
-
it('should process 1000 responsive utilities within threshold', () => {
|
|
197
|
-
const breakpoints = ['sm', 'md', 'lg', 'xl', '2xl']
|
|
198
|
-
const utilities: string[] = []
|
|
199
|
-
|
|
200
|
-
for (const bp of breakpoints) {
|
|
201
|
-
for (let i = 0; i < 200; i++) {
|
|
202
|
-
utilities.push(`${bp}:w-${i}`)
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
const start = performance.now()
|
|
207
|
-
for (const cls of utilities) {
|
|
208
|
-
gen.generate(cls)
|
|
209
|
-
}
|
|
210
|
-
const duration = performance.now() - start
|
|
211
|
-
|
|
212
|
-
// Current: ~4ms, threshold: 10ms
|
|
213
|
-
expect(duration).toBeLessThan(10) // 10ms
|
|
214
|
-
})
|
|
215
|
-
})
|
|
216
|
-
|
|
217
|
-
describe('Interactive States Performance', () => {
|
|
218
|
-
it('should process 550 interactive state utilities within threshold', () => {
|
|
219
|
-
const states = ['hover', 'focus', 'active', 'disabled', 'group-hover', 'peer-focus', 'first', 'last', 'odd', 'even', 'dark']
|
|
220
|
-
const stateUtilities: string[] = []
|
|
221
|
-
|
|
222
|
-
for (const state of states) {
|
|
223
|
-
for (let i = 0; i < 50; i++) {
|
|
224
|
-
stateUtilities.push(`${state}:bg-blue-${i}`)
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
const start = performance.now()
|
|
229
|
-
for (const cls of stateUtilities) {
|
|
230
|
-
gen.generate(cls)
|
|
231
|
-
}
|
|
232
|
-
const duration = performance.now() - start
|
|
233
|
-
|
|
234
|
-
// Current: ~2.5ms, threshold: 6ms
|
|
235
|
-
expect(duration).toBeLessThan(6) // 6ms
|
|
236
|
-
})
|
|
237
|
-
})
|
|
238
|
-
|
|
239
|
-
describe('Duplicate Handling Performance', () => {
|
|
240
|
-
it('should handle 6000 duplicate classes efficiently', () => {
|
|
241
|
-
const duplicates = ['w-4', 'h-4', 'p-4', 'm-4', 'text-lg', 'bg-blue-500']
|
|
242
|
-
const manyDuplicates: string[] = []
|
|
243
|
-
|
|
244
|
-
for (let i = 0; i < 1000; i++) {
|
|
245
|
-
manyDuplicates.push(...duplicates)
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
const start = performance.now()
|
|
249
|
-
for (const cls of manyDuplicates) {
|
|
250
|
-
gen.generate(cls)
|
|
251
|
-
}
|
|
252
|
-
const duration = performance.now() - start
|
|
253
|
-
|
|
254
|
-
// Current: ~0.12ms, threshold: 0.5ms (this should be VERY fast due to caching)
|
|
255
|
-
expect(duration).toBeLessThan(0.5) // 0.5ms
|
|
256
|
-
})
|
|
257
|
-
})
|
|
258
|
-
|
|
259
|
-
describe('Rule Ordering Performance - Critical!', () => {
|
|
260
|
-
it('should match common utilities in first 3 rule checks', () => {
|
|
261
|
-
// This test ensures our critical optimization (rule ordering) stays in place
|
|
262
|
-
const commonUtilities = [
|
|
263
|
-
'w-4', // spacingRule should match first
|
|
264
|
-
'h-4', // sizingRule should match second
|
|
265
|
-
'p-4', // spacingRule should match first
|
|
266
|
-
'm-4', // spacingRule should match first
|
|
267
|
-
'bg-blue-500', // colorRule should match third
|
|
268
|
-
'text-white', // colorRule should match third
|
|
269
|
-
]
|
|
270
|
-
|
|
271
|
-
const start = performance.now()
|
|
272
|
-
for (const cls of commonUtilities) {
|
|
273
|
-
gen.generate(cls)
|
|
274
|
-
}
|
|
275
|
-
const duration = performance.now() - start
|
|
276
|
-
|
|
277
|
-
// These should be EXTREMELY fast (< 0.05ms for 6 classes)
|
|
278
|
-
// because they match in the first 3 rules
|
|
279
|
-
expect(duration).toBeLessThan(0.05) // 0.05ms
|
|
280
|
-
})
|
|
281
|
-
})
|
|
282
|
-
|
|
283
|
-
describe('Cache Effectiveness', () => {
|
|
284
|
-
it('should benefit from parse cache on repeated patterns', () => {
|
|
285
|
-
const pattern = 'hover:bg-blue-500'
|
|
286
|
-
|
|
287
|
-
// First pass - no cache
|
|
288
|
-
const gen1 = new CSSGenerator(defaultConfig)
|
|
289
|
-
const start1 = performance.now()
|
|
290
|
-
for (let i = 0; i < 100; i++) {
|
|
291
|
-
gen1.generate(pattern)
|
|
292
|
-
}
|
|
293
|
-
const duration1 = performance.now() - start1
|
|
294
|
-
|
|
295
|
-
// Second pass - with cache (different generator, but parse cache is global)
|
|
296
|
-
const gen2 = new CSSGenerator(defaultConfig)
|
|
297
|
-
const start2 = performance.now()
|
|
298
|
-
for (let i = 0; i < 100; i++) {
|
|
299
|
-
gen2.generate(pattern)
|
|
300
|
-
}
|
|
301
|
-
const duration2 = performance.now() - start2
|
|
302
|
-
|
|
303
|
-
// Second pass should be faster or equal (cache helps)
|
|
304
|
-
// Due to class cache, second pass should be near-instant
|
|
305
|
-
expect(duration2).toBeLessThanOrEqual(duration1)
|
|
306
|
-
expect(duration2).toBeLessThan(0.05) // Should be < 50µs with full caching
|
|
307
|
-
})
|
|
308
|
-
|
|
309
|
-
it('should handle class cache efficiently', () => {
|
|
310
|
-
const utilities = ['w-4', 'h-4', 'p-4', 'm-4']
|
|
311
|
-
|
|
312
|
-
// Generate once
|
|
313
|
-
for (const cls of utilities) {
|
|
314
|
-
gen.generate(cls)
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
// Generate again (should hit class cache immediately)
|
|
318
|
-
const start = performance.now()
|
|
319
|
-
for (let i = 0; i < 1000; i++) {
|
|
320
|
-
for (const cls of utilities) {
|
|
321
|
-
gen.generate(cls)
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
const duration = performance.now() - start
|
|
325
|
-
|
|
326
|
-
// 4000 cached lookups should be fast
|
|
327
|
-
expect(duration).toBeLessThan(1) // < 1ms for 4000 cached lookups
|
|
328
|
-
})
|
|
329
|
-
})
|
|
330
|
-
|
|
331
|
-
describe('Memory Efficiency', () => {
|
|
332
|
-
it('should not leak memory with large-scale generation', () => {
|
|
333
|
-
const initialMemory = (performance as any).memory?.usedJSHeapSize || 0
|
|
334
|
-
|
|
335
|
-
// Generate a lot of utilities
|
|
336
|
-
for (let i = 0; i < 1000; i++) {
|
|
337
|
-
gen.generate(`w-${i}`)
|
|
338
|
-
gen.generate(`h-${i}`)
|
|
339
|
-
gen.generate(`p-${i}`)
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
const finalMemory = (performance as any).memory?.usedJSHeapSize || 0
|
|
343
|
-
const memoryIncrease = finalMemory - initialMemory
|
|
344
|
-
|
|
345
|
-
// Memory increase should be reasonable (< 10MB for 3000 utilities)
|
|
346
|
-
// Note: This is a rough estimate and may vary by environment
|
|
347
|
-
if (initialMemory > 0) {
|
|
348
|
-
expect(memoryIncrease).toBeLessThan(10 * 1024 * 1024) // 10MB
|
|
349
|
-
}
|
|
350
|
-
})
|
|
351
|
-
})
|
|
352
|
-
|
|
353
|
-
describe('Performance Regression Guards', () => {
|
|
354
|
-
it('should maintain O(1) lookup for common utilities', () => {
|
|
355
|
-
// Test that adding more rules doesn't slow down common utilities
|
|
356
|
-
// This guards against someone accidentally moving rules back to the end
|
|
357
|
-
|
|
358
|
-
const commonUtils = ['w-4', 'h-4', 'p-4', 'm-4', 'bg-blue-500', 'text-white']
|
|
359
|
-
|
|
360
|
-
const iterations = 100
|
|
361
|
-
const start = performance.now()
|
|
362
|
-
for (let i = 0; i < iterations; i++) {
|
|
363
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
364
|
-
for (const cls of commonUtils) {
|
|
365
|
-
gen.generate(cls)
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
const duration = performance.now() - start
|
|
369
|
-
const avgPerIteration = duration / iterations
|
|
370
|
-
|
|
371
|
-
// Average per iteration should be < 20µs
|
|
372
|
-
// If someone moves rules back, this will break
|
|
373
|
-
expect(avgPerIteration).toBeLessThan(0.02) // 20 microseconds per iteration
|
|
374
|
-
})
|
|
375
|
-
})
|
|
376
|
-
})
|