|
1 | | -import { beforeEach, describe, expect, it, vi } from 'vitest' |
| 1 | +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' |
2 | 2 |
|
3 | 3 | import { |
4 | 4 | commonFlags, |
5 | 5 | getMaxOldSpaceSizeFlag, |
6 | 6 | getMaxSemiSpaceSizeFlag, |
7 | 7 | outputFlags, |
| 8 | + resetFlagCache, |
8 | 9 | validationFlags, |
9 | 10 | } from './flags.mts' |
10 | 11 | import ENV from './constants/env.mts' |
@@ -34,107 +35,123 @@ vi.mock('./constants.mts', () => ({ |
34 | 35 | })) |
35 | 36 |
|
36 | 37 | describe('flags', () => { |
| 38 | + let originalArgv: string[] |
| 39 | + |
37 | 40 | beforeEach(() => { |
38 | 41 | vi.clearAllMocks() |
| 42 | + resetFlagCache() |
| 43 | + // Save original argv and reset ENV for clean state. |
| 44 | + originalArgv = process.argv |
| 45 | + ENV.NODE_OPTIONS = '' |
| 46 | + }) |
| 47 | + |
| 48 | + afterEach(() => { |
| 49 | + // Restore original state. |
| 50 | + process.argv = originalArgv |
| 51 | + ENV.NODE_OPTIONS = '' |
39 | 52 | }) |
40 | 53 |
|
41 | 54 | describe('getMaxOldSpaceSizeFlag', () => { |
42 | | - it.skip('returns default based on system memory', () => { |
43 | | - // Skipped: Module-level caching prevents mocks from working in isolate mode. |
| 55 | + it('returns default based on system memory', () => { |
44 | 56 | const result = getMaxOldSpaceSizeFlag() |
45 | 57 |
|
46 | 58 | // Should be 75% of 8GB in MiB. |
47 | 59 | expect(result).toBe(Math.floor(8 * 1024 * 0.75)) |
48 | 60 | expect(result).toBe(6144) |
49 | 61 | }) |
50 | 62 |
|
51 | | - it.skip('respects NODE_OPTIONS', async () => { |
52 | | - // Skipped: vi.resetModules() doesn't clear module-level cache in isolate mode. |
53 | | - const _constants = vi.mocked(await import('./constants.mts')).default |
| 63 | + it('respects NODE_OPTIONS', () => { |
54 | 64 | ENV.NODE_OPTIONS = '--max-old-space-size=512' |
| 65 | + resetFlagCache() |
55 | 66 |
|
56 | | - // Need to reset the module to clear cached value. |
57 | | - vi.resetModules() |
58 | | - const { getMaxOldSpaceSizeFlag: freshGetMaxOldSpaceSizeFlag } = |
59 | | - await import('./flags.mts') |
60 | | - |
61 | | - const result = freshGetMaxOldSpaceSizeFlag() |
| 67 | + const result = getMaxOldSpaceSizeFlag() |
62 | 68 | expect(result).toBe(512) |
63 | | - }) |
64 | 69 |
|
65 | | - it.skip('respects user-provided flag', async () => { |
66 | | - // Skipped: vi.resetModules() doesn't clear module-level cache in isolate mode. |
67 | | - const meow = vi.mocked(await import('meow')).default |
68 | | - meow.mockReturnValue({ |
69 | | - flags: { |
70 | | - maxOldSpaceSize: 1024, |
71 | | - maxSemiSpaceSize: 0, |
72 | | - }, |
73 | | - } as any) |
| 70 | + // Cleanup. |
| 71 | + ENV.NODE_OPTIONS = '' |
| 72 | + }) |
74 | 73 |
|
75 | | - vi.resetModules() |
76 | | - const { getMaxOldSpaceSizeFlag: freshGetMaxOldSpaceSizeFlag } = |
77 | | - await import('./flags.mts') |
| 74 | + it('respects user-provided flag', () => { |
| 75 | + const originalArgv = process.argv |
| 76 | + process.argv = ['node', 'script.js', '--max-old-space-size=1024'] |
| 77 | + resetFlagCache() |
78 | 78 |
|
79 | | - const result = freshGetMaxOldSpaceSizeFlag() |
| 79 | + const result = getMaxOldSpaceSizeFlag() |
80 | 80 | expect(result).toBe(1024) |
| 81 | + |
| 82 | + // Cleanup. |
| 83 | + process.argv = originalArgv |
81 | 84 | }) |
82 | 85 |
|
83 | | - it('handles low memory systems', async () => { |
84 | | - // The test is failing because the module-level cache is not being cleared properly. |
85 | | - // We need to be careful about caching in flags.mts. |
86 | | - // Since this test requires a clean state, skip it for now. |
87 | | - expect(true).toBe(true) |
| 86 | + it('handles low memory systems', () => { |
| 87 | + const originalArgv = process.argv |
| 88 | + process.argv = ['node', 'script.js', '--max-old-space-size=256'] |
| 89 | + resetFlagCache() |
| 90 | + |
| 91 | + const result = getMaxOldSpaceSizeFlag() |
| 92 | + // Should respect the explicitly set low value. |
| 93 | + expect(result).toBe(256) |
| 94 | + |
| 95 | + // Cleanup. |
| 96 | + process.argv = originalArgv |
88 | 97 | }) |
89 | 98 | }) |
90 | 99 |
|
91 | 100 | describe('getMaxSemiSpaceSizeFlag', () => { |
92 | | - it.skip('calculates based on old space size for small heaps', () => { |
93 | | - // Skipped: Depends on getMaxOldSpaceSizeFlag which has module caching issues. |
| 101 | + it('calculates based on old space size for small heaps', () => { |
94 | 102 | const result = getMaxSemiSpaceSizeFlag() |
95 | 103 |
|
96 | 104 | // With 6144 MiB old space, should be 64 MiB semi space. |
97 | 105 | expect(result).toBe(64) |
98 | 106 | }) |
99 | 107 |
|
100 | | - it('respects NODE_OPTIONS', async () => { |
101 | | - const _constants = vi.mocked(await import('./constants.mts')).default |
| 108 | + it('respects NODE_OPTIONS', () => { |
102 | 109 | ENV.NODE_OPTIONS = '--max-semi-space-size=16' |
| 110 | + resetFlagCache() |
103 | 111 |
|
104 | | - vi.resetModules() |
105 | | - const { getMaxSemiSpaceSizeFlag: freshGetMaxSemiSpaceSizeFlag } = |
106 | | - await import('./flags.mts') |
107 | | - |
108 | | - const result = freshGetMaxSemiSpaceSizeFlag() |
| 112 | + const result = getMaxSemiSpaceSizeFlag() |
109 | 113 | expect(result).toBe(16) |
110 | | - }) |
111 | 114 |
|
112 | | - it.skip('respects user-provided flag', async () => { |
113 | | - // Skipped: vi.resetModules() doesn't clear module-level cache in isolate mode. |
114 | | - const meow = vi.mocked(await import('meow')).default |
115 | | - meow.mockReturnValue({ |
116 | | - flags: { |
117 | | - maxOldSpaceSize: 0, |
118 | | - maxSemiSpaceSize: 32, |
119 | | - }, |
120 | | - } as any) |
| 115 | + // Cleanup. |
| 116 | + ENV.NODE_OPTIONS = '' |
| 117 | + }) |
121 | 118 |
|
122 | | - vi.resetModules() |
123 | | - const { getMaxSemiSpaceSizeFlag: freshGetMaxSemiSpaceSizeFlag } = |
124 | | - await import('./flags.mts') |
| 119 | + it('respects user-provided flag', () => { |
| 120 | + const originalArgv = process.argv |
| 121 | + process.argv = ['node', 'script.js', '--max-semi-space-size=32'] |
| 122 | + resetFlagCache() |
125 | 123 |
|
126 | | - const result = freshGetMaxSemiSpaceSizeFlag() |
| 124 | + const result = getMaxSemiSpaceSizeFlag() |
127 | 125 | expect(result).toBe(32) |
| 126 | + |
| 127 | + // Cleanup. |
| 128 | + process.argv = originalArgv |
128 | 129 | }) |
129 | 130 |
|
130 | | - it('scales for very small heaps', async () => { |
131 | | - // Skipping due to module caching issues. |
132 | | - expect(true).toBe(true) |
| 131 | + it('scales for very small heaps', () => { |
| 132 | + const originalArgv = process.argv |
| 133 | + process.argv = ['node', 'script.js', '--max-old-space-size=512'] |
| 134 | + resetFlagCache() |
| 135 | + |
| 136 | + const result = getMaxSemiSpaceSizeFlag() |
| 137 | + // 512 MiB heap should use 4 MiB semi-space. |
| 138 | + expect(result).toBe(4) |
| 139 | + |
| 140 | + // Cleanup. |
| 141 | + process.argv = originalArgv |
133 | 142 | }) |
134 | 143 |
|
135 | | - it('scales for large heaps', async () => { |
136 | | - // Skipping due to module caching issues. |
137 | | - expect(true).toBe(true) |
| 144 | + it('scales for large heaps', () => { |
| 145 | + const originalArgv = process.argv |
| 146 | + process.argv = ['node', 'script.js', '--max-old-space-size=16384'] |
| 147 | + resetFlagCache() |
| 148 | + |
| 149 | + const result = getMaxSemiSpaceSizeFlag() |
| 150 | + // 16384 MiB (16 GiB) heap: log2(16384) = 14, 14 * 8 = 112. |
| 151 | + expect(result).toBe(112) |
| 152 | + |
| 153 | + // Cleanup. |
| 154 | + process.argv = originalArgv |
138 | 155 | }) |
139 | 156 | }) |
140 | 157 |
|
|
0 commit comments