|
1 | 1 | import { describe, test, expect } from 'vitest' |
| 2 | +import { readFileSync } from 'fs' |
2 | 3 | import { CSSDataArena, STYLESHEET, STYLE_RULE, DECLARATION, FLAG_IMPORTANT, FLAG_HAS_ERROR } from './arena' |
| 4 | +import { parse } from './parse' |
3 | 5 |
|
4 | 6 | describe('CSSDataArena', () => { |
5 | 7 | describe('initialization', () => { |
@@ -237,34 +239,99 @@ describe('CSSDataArena', () => { |
237 | 239 | }) |
238 | 240 | }) |
239 | 241 |
|
240 | | - describe('capacity planning', () => { |
241 | | - test('should have minimum capacity for empty files', () => { |
242 | | - const capacity = CSSDataArena.capacity_for_source(0) |
243 | | - expect(capacity).toBe(16) |
| 242 | + describe('growth tracking', () => { |
| 243 | + test('should initialize growth count to zero', () => { |
| 244 | + const arena = new CSSDataArena() |
| 245 | + expect(arena.get_growth_count()).toBe(0) |
| 246 | + }) |
| 247 | + |
| 248 | + test('should track single growth event', () => { |
| 249 | + const arena = new CSSDataArena(2) |
| 250 | + expect(arena.get_growth_count()).toBe(0) |
| 251 | + |
| 252 | + // Create nodes to trigger growth |
| 253 | + arena.create_node(STYLESHEET, 0, 0, 1, 1) // count = 2 |
| 254 | + expect(arena.get_growth_count()).toBe(0) |
| 255 | + |
| 256 | + arena.create_node(STYLESHEET, 0, 0, 1, 1) // count = 3, triggers growth |
| 257 | + expect(arena.get_growth_count()).toBe(1) |
| 258 | + }) |
| 259 | + |
| 260 | + test('should track multiple growth events', () => { |
| 261 | + const arena = new CSSDataArena(2) |
| 262 | + expect(arena.get_growth_count()).toBe(0) |
| 263 | + |
| 264 | + // First growth: 2 -> 3 |
| 265 | + arena.create_node(STYLESHEET, 0, 0, 1, 1) |
| 266 | + arena.create_node(STYLESHEET, 0, 0, 1, 1) |
| 267 | + expect(arena.get_growth_count()).toBe(1) |
| 268 | + expect(arena.get_capacity()).toBe(3) // ceil(2 * 1.3) = 3 |
| 269 | + |
| 270 | + // Second growth: 3 -> 4 |
| 271 | + arena.create_node(STYLESHEET, 0, 0, 1, 1) |
| 272 | + expect(arena.get_growth_count()).toBe(2) |
| 273 | + expect(arena.get_capacity()).toBe(4) // ceil(3 * 1.3) = 4 |
| 274 | + |
| 275 | + // Third growth: 4 -> 6 |
| 276 | + arena.create_node(STYLESHEET, 0, 0, 1, 1) |
| 277 | + expect(arena.get_growth_count()).toBe(3) |
| 278 | + expect(arena.get_capacity()).toBe(6) // ceil(4 * 1.3) = 6 |
244 | 279 | }) |
245 | 280 |
|
246 | | - test('should calculate capacity for small CSS files', () => { |
247 | | - // 1KB CSS = 60 nodes * 1.15 buffer = 69 nodes |
248 | | - const capacity = CSSDataArena.capacity_for_source(1024) |
249 | | - expect(capacity).toBe(69) |
| 281 | + test('should not increment growth count when capacity is sufficient', () => { |
| 282 | + const arena = new CSSDataArena(100) |
| 283 | + |
| 284 | + // Create many nodes without exceeding capacity |
| 285 | + for (let i = 0; i < 50; i++) { |
| 286 | + arena.create_node(STYLESHEET, 0, 0, 1, 1) |
| 287 | + } |
| 288 | + |
| 289 | + expect(arena.get_growth_count()).toBe(0) |
| 290 | + expect(arena.get_count()).toBe(51) // 50 created + 1 initial |
250 | 291 | }) |
| 292 | + }) |
251 | 293 |
|
252 | | - test('should calculate capacity for medium CSS files', () => { |
253 | | - // 100KB CSS = 6000 nodes * 1.15 buffer = 6900 nodes |
254 | | - const capacity = CSSDataArena.capacity_for_source(100 * 1024) |
255 | | - expect(capacity).toBe(6900) |
| 294 | + describe('real-world CSS frameworks', () => { |
| 295 | + test('should not grow for Bootstrap CSS', () => { |
| 296 | + const css = readFileSync('node_modules/bootstrap/dist/css/bootstrap.css', 'utf-8') |
| 297 | + const result = parse(css) |
| 298 | + |
| 299 | + expect(result.__get_arena().get_growth_count()).toBe(0) |
| 300 | + const utilization = (result.__get_arena().get_count() / result.__get_arena().get_capacity()) * 100 |
| 301 | + expect(utilization).toBeLessThan(85) |
| 302 | + expect(utilization).toBeGreaterThan(30) |
256 | 303 | }) |
257 | 304 |
|
258 | | - test('should calculate capacity for large CSS files', () => { |
259 | | - // 10MB = 10240 KB CSS = 614400 nodes * 1.15 buffer = 706560 nodes |
260 | | - const capacity = CSSDataArena.capacity_for_source(10 * 1024 * 1024) |
261 | | - expect(capacity).toBe(706560) |
| 305 | + test('should not grow for Bootstrap minified CSS', () => { |
| 306 | + const css = readFileSync('node_modules/bootstrap/dist/css/bootstrap.min.css', 'utf-8') |
| 307 | + const result = parse(css) |
| 308 | + const arena = result.__get_arena() |
| 309 | + |
| 310 | + expect(arena.get_growth_count()).toBe(0) |
| 311 | + const utilization = (arena.get_count() / arena.get_capacity()) * 100 |
| 312 | + expect(utilization).toBeLessThan(85) |
| 313 | + expect(utilization).toBeGreaterThan(30) |
262 | 314 | }) |
263 | 315 |
|
264 | | - test('should round up for partial KBs', () => { |
265 | | - // 1.5KB = ceil(1.5 * 60) * 1.15 = 90 * 1.15 = 104 (rounded up) |
266 | | - const capacity = CSSDataArena.capacity_for_source(1536) |
267 | | - expect(capacity).toBe(104) |
| 316 | + test('should not grow for Tailwind CSS', () => { |
| 317 | + const css = readFileSync('node_modules/tailwindcss/dist/tailwind.css', 'utf-8') |
| 318 | + const result = parse(css) |
| 319 | + const arena = result.__get_arena() |
| 320 | + |
| 321 | + expect(arena.get_growth_count()).toBe(0) |
| 322 | + const utilization = (arena.get_count() / arena.get_capacity()) * 100 |
| 323 | + expect(utilization).toBeLessThan(85) |
| 324 | + expect(utilization).toBeGreaterThan(30) |
| 325 | + }) |
| 326 | + |
| 327 | + test('should not grow for Tailwind minified CSS', () => { |
| 328 | + const css = readFileSync('node_modules/tailwindcss/dist/tailwind.min.css', 'utf-8') |
| 329 | + const result = parse(css) |
| 330 | + |
| 331 | + expect(result.__get_arena().get_growth_count()).toBe(0) |
| 332 | + const utilization = (result.__get_arena().get_count() / result.__get_arena().get_capacity()) * 100 |
| 333 | + expect(utilization).toBeLessThan(85) |
| 334 | + expect(utilization).toBeGreaterThan(30) |
268 | 335 | }) |
269 | 336 | }) |
270 | 337 | }) |
0 commit comments