portapack 0.3.0 → 0.3.2

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.
Files changed (74) hide show
  1. package/.eslintrc.json +67 -8
  2. package/.github/workflows/ci.yml +5 -4
  3. package/.releaserc.js +25 -27
  4. package/CHANGELOG.md +12 -19
  5. package/LICENSE.md +21 -0
  6. package/README.md +34 -36
  7. package/commitlint.config.js +30 -34
  8. package/dist/cli/cli-entry.cjs +199 -135
  9. package/dist/cli/cli-entry.cjs.map +1 -1
  10. package/dist/index.d.ts +0 -3
  11. package/dist/index.js +194 -134
  12. package/dist/index.js.map +1 -1
  13. package/docs/.vitepress/config.ts +36 -34
  14. package/docs/.vitepress/sidebar-generator.ts +89 -38
  15. package/docs/cli.md +29 -82
  16. package/docs/code-of-conduct.md +7 -1
  17. package/docs/configuration.md +103 -117
  18. package/docs/contributing.md +6 -2
  19. package/docs/deployment.md +10 -5
  20. package/docs/development.md +8 -5
  21. package/docs/getting-started.md +76 -45
  22. package/docs/index.md +1 -1
  23. package/docs/public/android-chrome-192x192.png +0 -0
  24. package/docs/public/android-chrome-512x512.png +0 -0
  25. package/docs/public/apple-touch-icon.png +0 -0
  26. package/docs/public/favicon-16x16.png +0 -0
  27. package/docs/public/favicon-32x32.png +0 -0
  28. package/docs/public/favicon.ico +0 -0
  29. package/docs/site.webmanifest +1 -0
  30. package/docs/troubleshooting.md +12 -1
  31. package/examples/main.ts +7 -10
  32. package/examples/sample-project/script.js +1 -1
  33. package/jest.config.ts +8 -13
  34. package/nodemon.json +5 -10
  35. package/package.json +2 -5
  36. package/src/cli/cli-entry.ts +2 -2
  37. package/src/cli/cli.ts +21 -16
  38. package/src/cli/options.ts +127 -113
  39. package/src/core/bundler.ts +254 -221
  40. package/src/core/extractor.ts +639 -520
  41. package/src/core/minifier.ts +173 -162
  42. package/src/core/packer.ts +141 -137
  43. package/src/core/parser.ts +74 -73
  44. package/src/core/web-fetcher.ts +270 -258
  45. package/src/index.ts +18 -17
  46. package/src/types.ts +9 -11
  47. package/src/utils/font.ts +12 -6
  48. package/src/utils/logger.ts +110 -105
  49. package/src/utils/meta.ts +75 -76
  50. package/src/utils/mime.ts +50 -50
  51. package/src/utils/slugify.ts +33 -34
  52. package/tests/unit/cli/cli-entry.test.ts +72 -70
  53. package/tests/unit/cli/cli.test.ts +314 -278
  54. package/tests/unit/cli/options.test.ts +294 -301
  55. package/tests/unit/core/bundler.test.ts +426 -329
  56. package/tests/unit/core/extractor.test.ts +828 -380
  57. package/tests/unit/core/minifier.test.ts +374 -274
  58. package/tests/unit/core/packer.test.ts +298 -264
  59. package/tests/unit/core/parser.test.ts +538 -150
  60. package/tests/unit/core/web-fetcher.test.ts +389 -359
  61. package/tests/unit/index.test.ts +238 -197
  62. package/tests/unit/utils/font.test.ts +26 -21
  63. package/tests/unit/utils/logger.test.ts +267 -260
  64. package/tests/unit/utils/meta.test.ts +29 -28
  65. package/tests/unit/utils/mime.test.ts +73 -74
  66. package/tests/unit/utils/slugify.test.ts +14 -12
  67. package/tsconfig.build.json +9 -10
  68. package/tsconfig.jest.json +2 -1
  69. package/tsconfig.json +2 -2
  70. package/tsup.config.ts +8 -8
  71. package/typedoc.json +5 -9
  72. package/docs/demo.md +0 -46
  73. /package/docs/{portapack-transparent.png → public/portapack-transparent.png} +0 -0
  74. /package/docs/{portapack.jpg → public/portapack.jpg} +0 -0
@@ -1,279 +1,286 @@
1
1
  /**
2
- * Tests for the logger module
2
+ * @file tests/unit/utils/logger.test.ts
3
+ * @description Unit tests for the Logger module.
3
4
  */
4
5
  import { Logger } from '../../../src/utils/logger';
5
6
  import { LogLevel } from '../../../src/types';
6
7
  import { jest, describe, it, beforeEach, afterEach, expect } from '@jest/globals'; // Ensure expect is imported
7
8
 
8
9
  describe('Logger', () => {
9
- // Save original console methods
10
- const originalConsole = {
11
- log: console.log,
12
- warn: console.warn,
13
- error: console.error,
14
- info: console.info,
15
- debug: console.debug
16
- };
17
-
18
- // Create mock functions for console methods
19
- let mockLog: jest.Mock;
20
- let mockWarn: jest.Mock;
21
- let mockError: jest.Mock;
22
- let mockInfo: jest.Mock;
23
- let mockDebug: jest.Mock;
24
-
25
- beforeEach(() => {
26
- // Setup mocks
27
- mockLog = jest.fn();
28
- mockWarn = jest.fn();
29
- mockError = jest.fn();
30
- mockInfo = jest.fn();
31
- mockDebug = jest.fn();
32
-
33
- // Override console methods
34
- console.log = mockLog;
35
- console.warn = mockWarn;
36
- console.error = mockError;
37
- console.info = mockInfo;
38
- console.debug = mockDebug;
10
+ // Save original console methods
11
+ const originalConsole = {
12
+ log: console.log,
13
+ warn: console.warn,
14
+ error: console.error,
15
+ info: console.info,
16
+ debug: console.debug,
17
+ };
18
+
19
+ // Create mock functions for console methods
20
+ let mockLog: jest.Mock;
21
+ let mockWarn: jest.Mock;
22
+ let mockError: jest.Mock;
23
+ let mockInfo: jest.Mock;
24
+ let mockDebug: jest.Mock;
25
+
26
+ beforeEach(() => {
27
+ // Setup mocks
28
+ mockLog = jest.fn();
29
+ mockWarn = jest.fn();
30
+ mockError = jest.fn();
31
+ mockInfo = jest.fn();
32
+ mockDebug = jest.fn();
33
+
34
+ // Override console methods
35
+ console.log = mockLog;
36
+ console.warn = mockWarn;
37
+ console.error = mockError;
38
+ console.info = mockInfo;
39
+ console.debug = mockDebug;
40
+ });
41
+
42
+ afterEach(() => {
43
+ // Restore original console methods
44
+ console.log = originalConsole.log;
45
+ console.warn = originalConsole.warn;
46
+ console.error = originalConsole.error;
47
+ console.info = originalConsole.info;
48
+ console.debug = originalConsole.debug;
49
+ });
50
+
51
+ describe('Logger instantiation', () => {
52
+ it('creates a logger with default log level INFO', () => {
53
+ const logger = new Logger();
54
+ expect(logger).toBeDefined();
55
+ // REMOVED: @ts-expect-error Access private member for testing (No longer needed)
56
+ expect((logger as any).level).toBe(LogLevel.INFO); // Cast to any if 'level' is truly private and inaccessible
57
+ // Or make 'level' public/internal for testing if appropriate
39
58
  });
40
59
 
41
- afterEach(() => {
42
- // Restore original console methods
43
- console.log = originalConsole.log;
44
- console.warn = originalConsole.warn;
45
- console.error = originalConsole.error;
46
- console.info = originalConsole.info;
47
- console.debug = originalConsole.debug;
60
+ it('creates a logger with specific log level', () => {
61
+ const logger = new Logger(LogLevel.DEBUG);
62
+ expect(logger).toBeDefined();
63
+ expect((logger as any).level).toBe(LogLevel.DEBUG);
48
64
  });
49
65
 
50
- describe('Logger instantiation', () => {
51
- it('creates a logger with default log level INFO', () => {
52
- const logger = new Logger();
53
- expect(logger).toBeDefined();
54
- // REMOVED: @ts-expect-error Access private member for testing (No longer needed)
55
- expect((logger as any).level).toBe(LogLevel.INFO); // Cast to any if 'level' is truly private and inaccessible
56
- // Or make 'level' public/internal for testing if appropriate
57
- });
58
-
59
- it('creates a logger with specific log level', () => {
60
- const logger = new Logger(LogLevel.DEBUG);
61
- expect(logger).toBeDefined();
62
- // REMOVED: @ts-expect-error Access private member for testing (No longer needed)
63
- expect((logger as any).level).toBe(LogLevel.DEBUG);
64
- });
65
-
66
- // Test constructor guards against invalid levels
67
- it('defaults to INFO if constructor receives invalid level', () => {
68
- // @ts-expect-error Testing invalid input (KEEP this one if Logger constructor expects LogLevel)
69
- const logger = new Logger(99);
70
- // REMOVED: @ts-expect-error Access private member for testing (No longer needed)
71
- expect((logger as any).level).toBe(LogLevel.INFO);
72
- });
73
- it('defaults to INFO if constructor receives undefined', () => {
74
- const logger = new Logger(undefined);
75
- // REMOVED: @ts-expect-error Access private member for testing (No longer needed)
76
- expect((logger as any).level).toBe(LogLevel.INFO);
77
- });
66
+ // Test constructor guards against invalid levels
67
+ it('defaults to INFO if constructor receives invalid level', () => {
68
+ // @ts-expect-error Testing invalid input (KEEP this one if Logger constructor expects LogLevel)
69
+ const logger = new Logger(99);
70
+ // REMOVED: @ts-expect-error Access private member for testing (No longer needed)
71
+ expect((logger as any).level).toBe(LogLevel.INFO);
78
72
  });
73
+ it('defaults to INFO if constructor receives undefined', () => {
74
+ const logger = new Logger(undefined);
75
+ // REMOVED: @ts-expect-error Access private member for testing (No longer needed)
76
+ expect((logger as any).level).toBe(LogLevel.INFO);
77
+ });
78
+ });
79
+
80
+ describe('Log methods', () => {
81
+ // Existing tests for error, warn, info, debug, none are good... keep them
82
+
83
+ it('logs error messages only when level >= ERROR', () => {
84
+ const loggerError = new Logger(LogLevel.ERROR);
85
+ const loggerNone = new Logger(LogLevel.NONE);
79
86
 
80
- describe('Log methods', () => {
81
- // Existing tests for error, warn, info, debug, none are good... keep them
82
-
83
- it('logs error messages only when level >= ERROR', () => {
84
- const loggerError = new Logger(LogLevel.ERROR);
85
- const loggerNone = new Logger(LogLevel.NONE);
86
-
87
- loggerError.error('Test error');
88
- expect(mockError).toHaveBeenCalledTimes(1);
89
- expect(mockError).toHaveBeenCalledWith('[ERROR] Test error');
90
-
91
- loggerError.warn('Test warn'); // Should not log
92
- expect(mockWarn).not.toHaveBeenCalled();
93
-
94
- mockError.mockClear(); // Clear for next check
95
- loggerNone.error('Test error none'); // Should not log
96
- expect(mockError).not.toHaveBeenCalled();
97
- });
98
-
99
- it('logs warn messages only when level >= WARN', () => {
100
- const loggerWarn = new Logger(LogLevel.WARN);
101
- const loggerError = new Logger(LogLevel.ERROR); // Lower level
102
-
103
- loggerWarn.warn('Test warn');
104
- expect(mockWarn).toHaveBeenCalledTimes(1);
105
- expect(mockWarn).toHaveBeenCalledWith('[WARN] Test warn');
106
- loggerWarn.error('Test error'); // Should also log
107
- expect(mockError).toHaveBeenCalledTimes(1);
108
-
109
- mockWarn.mockClear();
110
- mockError.mockClear(); // Clear mockError too for the next check
111
- loggerError.warn('Test warn error level'); // Should not log
112
- expect(mockWarn).not.toHaveBeenCalled();
113
- });
114
-
115
- it('logs info messages only when level >= INFO', () => {
116
- const loggerInfo = new Logger(LogLevel.INFO);
117
- const loggerWarn = new Logger(LogLevel.WARN); // Lower level
118
-
119
- loggerInfo.info('Test info');
120
- expect(mockInfo).toHaveBeenCalledTimes(1);
121
- expect(mockInfo).toHaveBeenCalledWith('[INFO] Test info');
122
- loggerInfo.warn('Test warn'); // Should also log
123
- expect(mockWarn).toHaveBeenCalledTimes(1);
124
-
125
- mockInfo.mockClear();
126
- mockWarn.mockClear(); // Clear mockWarn too
127
- loggerWarn.info('Test info warn level'); // Should not log
128
- expect(mockInfo).not.toHaveBeenCalled();
129
- });
130
-
131
- it('logs debug messages only when level >= DEBUG', () => {
132
- const loggerDebug = new Logger(LogLevel.DEBUG);
133
- const loggerInfo = new Logger(LogLevel.INFO); // Lower level
134
-
135
- loggerDebug.debug('Test debug');
136
- expect(mockDebug).toHaveBeenCalledTimes(1);
137
- expect(mockDebug).toHaveBeenCalledWith('[DEBUG] Test debug');
138
- loggerDebug.info('Test info'); // Should also log
139
- expect(mockInfo).toHaveBeenCalledTimes(1);
140
-
141
- mockDebug.mockClear();
142
- mockInfo.mockClear(); // Clear mockInfo too
143
- loggerInfo.debug('Test debug info level'); // Should not log
144
- expect(mockDebug).not.toHaveBeenCalled();
145
- });
146
-
147
- it('does not log anything at NONE level', () => {
148
- const logger = new Logger(LogLevel.NONE);
149
-
150
- logger.error('Test error');
151
- logger.warn('Test warn');
152
- logger.info('Test info');
153
- logger.debug('Test debug');
154
-
155
- expect(mockError).not.toHaveBeenCalled();
156
- expect(mockWarn).not.toHaveBeenCalled();
157
- expect(mockInfo).not.toHaveBeenCalled();
158
- expect(mockDebug).not.toHaveBeenCalled();
159
- });
87
+ loggerError.error('Test error');
88
+ expect(mockError).toHaveBeenCalledTimes(1);
89
+ expect(mockError).toHaveBeenCalledWith('[ERROR] Test error');
90
+
91
+ loggerError.warn('Test warn'); // Should not log
92
+ expect(mockWarn).not.toHaveBeenCalled();
93
+
94
+ mockError.mockClear(); // Clear for next check
95
+ loggerNone.error('Test error none'); // Should not log
96
+ expect(mockError).not.toHaveBeenCalled();
160
97
  });
161
98
 
162
- describe('setLevel method', () => {
163
- // Existing test for setLevel is good... keep it
164
- it('changes log level dynamically', () => {
165
- const logger = new Logger(LogLevel.NONE);
166
-
167
- // Nothing should log at NONE level
168
- logger.error('Test error 1');
169
- expect(mockError).not.toHaveBeenCalled();
170
-
171
- // Change to ERROR level
172
- logger.setLevel(LogLevel.ERROR);
173
-
174
- // Now ERROR should log
175
- logger.error('Test error 2');
176
- expect(mockError).toHaveBeenCalledTimes(1); // Called once now
177
- expect(mockError).toHaveBeenCalledWith('[ERROR] Test error 2');
178
-
179
- // But WARN still should not
180
- logger.warn('Test warn');
181
- expect(mockWarn).not.toHaveBeenCalled();
182
-
183
- // Change to DEBUG level
184
- logger.setLevel(LogLevel.DEBUG);
185
-
186
- // Now all levels should log
187
- logger.warn('Test warn 2');
188
- logger.info('Test info');
189
- logger.debug('Test debug');
190
-
191
- expect(mockWarn).toHaveBeenCalledTimes(1); // Called once now
192
- expect(mockWarn).toHaveBeenCalledWith('[WARN] Test warn 2');
193
- expect(mockInfo).toHaveBeenCalledTimes(1);
194
- expect(mockInfo).toHaveBeenCalledWith('[INFO] Test info');
195
- expect(mockDebug).toHaveBeenCalledTimes(1);
196
- expect(mockDebug).toHaveBeenCalledWith('[DEBUG] Test debug');
197
- });
99
+ it('logs warn messages only when level >= WARN', () => {
100
+ const loggerWarn = new Logger(LogLevel.WARN);
101
+ const loggerError = new Logger(LogLevel.ERROR); // Lower level
102
+
103
+ loggerWarn.warn('Test warn');
104
+ expect(mockWarn).toHaveBeenCalledTimes(1);
105
+ expect(mockWarn).toHaveBeenCalledWith('[WARN] Test warn');
106
+ loggerWarn.error('Test error'); // Should also log
107
+ expect(mockError).toHaveBeenCalledTimes(1);
108
+
109
+ mockWarn.mockClear();
110
+ mockError.mockClear(); // Clear mockError too for the next check
111
+ loggerError.warn('Test warn error level'); // Should not log
112
+ expect(mockWarn).not.toHaveBeenCalled();
113
+ });
114
+
115
+ it('logs info messages only when level >= INFO', () => {
116
+ const loggerInfo = new Logger(LogLevel.INFO);
117
+ const loggerWarn = new Logger(LogLevel.WARN); // Lower level
118
+
119
+ loggerInfo.info('Test info');
120
+ expect(mockInfo).toHaveBeenCalledTimes(1);
121
+ expect(mockInfo).toHaveBeenCalledWith('[INFO] Test info');
122
+ loggerInfo.warn('Test warn'); // Should also log
123
+ expect(mockWarn).toHaveBeenCalledTimes(1);
124
+
125
+ mockInfo.mockClear();
126
+ mockWarn.mockClear(); // Clear mockWarn too
127
+ loggerWarn.info('Test info warn level'); // Should not log
128
+ expect(mockInfo).not.toHaveBeenCalled();
129
+ });
130
+
131
+ it('logs debug messages only when level >= DEBUG', () => {
132
+ const loggerDebug = new Logger(LogLevel.DEBUG);
133
+ const loggerInfo = new Logger(LogLevel.INFO); // Lower level
134
+
135
+ loggerDebug.debug('Test debug');
136
+ expect(mockDebug).toHaveBeenCalledTimes(1);
137
+ expect(mockDebug).toHaveBeenCalledWith('[DEBUG] Test debug');
138
+ loggerDebug.info('Test info'); // Should also log
139
+ expect(mockInfo).toHaveBeenCalledTimes(1);
140
+
141
+ mockDebug.mockClear();
142
+ mockInfo.mockClear(); // Clear mockInfo too
143
+ loggerInfo.debug('Test debug info level'); // Should not log
144
+ expect(mockDebug).not.toHaveBeenCalled();
145
+ });
146
+
147
+ it('does not log anything at NONE level', () => {
148
+ const logger = new Logger(LogLevel.NONE);
149
+
150
+ logger.error('Test error');
151
+ logger.warn('Test warn');
152
+ logger.info('Test info');
153
+ logger.debug('Test debug');
154
+
155
+ expect(mockError).not.toHaveBeenCalled();
156
+ expect(mockWarn).not.toHaveBeenCalled();
157
+ expect(mockInfo).not.toHaveBeenCalled();
158
+ expect(mockDebug).not.toHaveBeenCalled();
159
+ });
160
+ });
161
+
162
+ describe('setLevel method', () => {
163
+ // Existing test for setLevel is good... keep it
164
+ it('changes log level dynamically', () => {
165
+ const logger = new Logger(LogLevel.NONE);
166
+
167
+ // Nothing should log at NONE level
168
+ logger.error('Test error 1');
169
+ expect(mockError).not.toHaveBeenCalled();
170
+
171
+ // Change to ERROR level
172
+ logger.setLevel(LogLevel.ERROR);
173
+
174
+ // Now ERROR should log
175
+ logger.error('Test error 2');
176
+ expect(mockError).toHaveBeenCalledTimes(1); // Called once now
177
+ expect(mockError).toHaveBeenCalledWith('[ERROR] Test error 2');
178
+
179
+ // But WARN still should not
180
+ logger.warn('Test warn');
181
+ expect(mockWarn).not.toHaveBeenCalled();
182
+
183
+ // Change to DEBUG level
184
+ logger.setLevel(LogLevel.DEBUG);
185
+
186
+ // Now all levels should log
187
+ logger.warn('Test warn 2');
188
+ logger.info('Test info');
189
+ logger.debug('Test debug');
190
+
191
+ expect(mockWarn).toHaveBeenCalledTimes(1); // Called once now
192
+ expect(mockWarn).toHaveBeenCalledWith('[WARN] Test warn 2');
193
+ expect(mockInfo).toHaveBeenCalledTimes(1);
194
+ expect(mockInfo).toHaveBeenCalledWith('[INFO] Test info');
195
+ expect(mockDebug).toHaveBeenCalledTimes(1);
196
+ expect(mockDebug).toHaveBeenCalledWith('[DEBUG] Test debug');
197
+ });
198
+ });
199
+
200
+ // --- Tests for static factory methods ---
201
+ describe('Static factory methods', () => {
202
+ describe('Logger.fromVerboseFlag()', () => {
203
+ it('creates logger with DEBUG level if verbose is true', () => {
204
+ const logger = Logger.fromVerboseFlag({ verbose: true });
205
+ // REMOVED: @ts-expect-error Access private member (No longer needed)
206
+ expect((logger as any).level).toBe(LogLevel.DEBUG);
207
+ });
208
+
209
+ it('creates logger with INFO level if verbose is false', () => {
210
+ const logger = Logger.fromVerboseFlag({ verbose: false });
211
+ // REMOVED: @ts-expect-error Access private member (No longer needed)
212
+ expect((logger as any).level).toBe(LogLevel.INFO);
213
+ });
214
+
215
+ it('creates logger with INFO level if verbose is undefined', () => {
216
+ const logger = Logger.fromVerboseFlag({}); // Empty options
217
+ // REMOVED: @ts-expect-error Access private member (No longer needed)
218
+ expect((logger as any).level).toBe(LogLevel.INFO);
219
+ });
220
+
221
+ it('creates logger with INFO level if options is undefined', () => {
222
+ const logger = Logger.fromVerboseFlag(); // No options arg
223
+ // REMOVED: @ts-expect-error Access private member (No longer needed)
224
+ expect((logger as any).level).toBe(LogLevel.INFO);
225
+ });
198
226
  });
199
227
 
200
- // --- NEW: Tests for static factory methods ---
201
- describe('Static factory methods', () => {
202
- describe('Logger.fromVerboseFlag()', () => {
203
- it('creates logger with DEBUG level if verbose is true', () => {
204
- const logger = Logger.fromVerboseFlag({ verbose: true });
205
- // REMOVED: @ts-expect-error Access private member (No longer needed)
206
- expect((logger as any).level).toBe(LogLevel.DEBUG);
207
- });
208
-
209
- it('creates logger with INFO level if verbose is false', () => {
210
- const logger = Logger.fromVerboseFlag({ verbose: false });
211
- // REMOVED: @ts-expect-error Access private member (No longer needed)
212
- expect((logger as any).level).toBe(LogLevel.INFO);
213
- });
214
-
215
- it('creates logger with INFO level if verbose is undefined', () => {
216
- const logger = Logger.fromVerboseFlag({}); // Empty options
217
- // REMOVED: @ts-expect-error Access private member (No longer needed)
218
- expect((logger as any).level).toBe(LogLevel.INFO);
219
- });
220
-
221
- it('creates logger with INFO level if options is undefined', () => {
222
- const logger = Logger.fromVerboseFlag(); // No options arg
223
- // REMOVED: @ts-expect-error Access private member (No longer needed)
224
- expect((logger as any).level).toBe(LogLevel.INFO);
225
- });
226
- });
227
-
228
- describe('Logger.fromLevelName()', () => {
229
- it.each([
230
- ['debug', LogLevel.DEBUG],
231
- ['info', LogLevel.INFO],
232
- ['warn', LogLevel.WARN],
233
- ['error', LogLevel.ERROR],
234
- ['none', LogLevel.NONE],
235
- ['silent', LogLevel.NONE],
236
- ['DEBUG', LogLevel.DEBUG], // Case-insensitive
237
- ['InFo', LogLevel.INFO],
238
- ])('creates logger with correct level for valid name "%s"', (name, expectedLevel) => {
239
- const logger = Logger.fromLevelName(name);
240
- // REMOVED: @ts-expect-error Access private member (No longer needed)
241
- expect((logger as any).level).toBe(expectedLevel);
242
- expect(mockWarn).not.toHaveBeenCalled(); // No warning for valid names
243
- });
244
-
245
- it('defaults to INFO level if levelName is undefined', () => {
246
- const logger = Logger.fromLevelName(undefined);
247
- // REMOVED: @ts-expect-error Access private member (No longer needed)
248
- expect((logger as any).level).toBe(LogLevel.INFO);
249
- expect(mockWarn).not.toHaveBeenCalled();
250
- });
251
-
252
- it('uses provided defaultLevel if levelName is undefined', () => {
253
- const logger = Logger.fromLevelName(undefined, LogLevel.WARN);
254
- // REMOVED: @ts-expect-error Access private member (No longer needed)
255
- expect((logger as any).level).toBe(LogLevel.WARN);
256
- expect(mockWarn).not.toHaveBeenCalled();
257
- });
258
-
259
-
260
- it('defaults to INFO level and logs warning for invalid name', () => {
261
- const logger = Logger.fromLevelName('invalidLevel');
262
- // REMOVED: @ts-expect-error Access private member (No longer needed)
263
- expect((logger as any).level).toBe(LogLevel.INFO); // Falls back to default INFO
264
- // Check that console.warn was called *directly* by the static method
265
- expect(mockWarn).toHaveBeenCalledTimes(1);
266
- expect(mockWarn).toHaveBeenCalledWith(expect.stringContaining('[Logger] Invalid log level name "invalidLevel". Defaulting to INFO.'));
267
- });
268
-
269
- it('uses provided defaultLevel and logs warning for invalid name', () => {
270
- const logger = Logger.fromLevelName('invalidLevel', LogLevel.ERROR);
271
- // REMOVED: @ts-expect-error Access private member (No longer needed)
272
- expect((logger as any).level).toBe(LogLevel.ERROR); // Falls back to provided default ERROR
273
- // Check that console.warn was called *directly* by the static method
274
- expect(mockWarn).toHaveBeenCalledTimes(1);
275
- expect(mockWarn).toHaveBeenCalledWith(expect.stringContaining('[Logger] Invalid log level name "invalidLevel". Defaulting to ERROR.'));
276
- });
277
- });
228
+ describe('Logger.fromLevelName()', () => {
229
+ it.each([
230
+ ['debug', LogLevel.DEBUG],
231
+ ['info', LogLevel.INFO],
232
+ ['warn', LogLevel.WARN],
233
+ ['error', LogLevel.ERROR],
234
+ ['none', LogLevel.NONE],
235
+ ['silent', LogLevel.NONE],
236
+ ['DEBUG', LogLevel.DEBUG], // Case-insensitive
237
+ ['InFo', LogLevel.INFO],
238
+ ])('creates logger with correct level for valid name "%s"', (name, expectedLevel) => {
239
+ const logger = Logger.fromLevelName(name);
240
+ // REMOVED: @ts-expect-error Access private member (No longer needed)
241
+ expect((logger as any).level).toBe(expectedLevel);
242
+ expect(mockWarn).not.toHaveBeenCalled(); // No warning for valid names
243
+ });
244
+
245
+ it('defaults to INFO level if levelName is undefined', () => {
246
+ const logger = Logger.fromLevelName(undefined);
247
+ // REMOVED: @ts-expect-error Access private member (No longer needed)
248
+ expect((logger as any).level).toBe(LogLevel.INFO);
249
+ expect(mockWarn).not.toHaveBeenCalled();
250
+ });
251
+
252
+ it('uses provided defaultLevel if levelName is undefined', () => {
253
+ const logger = Logger.fromLevelName(undefined, LogLevel.WARN);
254
+ // REMOVED: @ts-expect-error Access private member (No longer needed)
255
+ expect((logger as any).level).toBe(LogLevel.WARN);
256
+ expect(mockWarn).not.toHaveBeenCalled();
257
+ });
258
+
259
+ it('defaults to INFO level and logs warning for invalid name', () => {
260
+ const logger = Logger.fromLevelName('invalidLevel');
261
+ // REMOVED: @ts-expect-error Access private member (No longer needed)
262
+ expect((logger as any).level).toBe(LogLevel.INFO); // Falls back to default INFO
263
+ // Check that console.warn was called *directly* by the static method
264
+ expect(mockWarn).toHaveBeenCalledTimes(1);
265
+ expect(mockWarn).toHaveBeenCalledWith(
266
+ expect.stringContaining(
267
+ '[Logger] Invalid log level name "invalidLevel". Defaulting to INFO.'
268
+ )
269
+ );
270
+ });
271
+
272
+ it('uses provided defaultLevel and logs warning for invalid name', () => {
273
+ const logger = Logger.fromLevelName('invalidLevel', LogLevel.ERROR);
274
+ // REMOVED: @ts-expect-error Access private member (No longer needed)
275
+ expect((logger as any).level).toBe(LogLevel.ERROR); // Falls back to provided default ERROR
276
+ // Check that console.warn was called *directly* by the static method
277
+ expect(mockWarn).toHaveBeenCalledTimes(1);
278
+ expect(mockWarn).toHaveBeenCalledWith(
279
+ expect.stringContaining(
280
+ '[Logger] Invalid log level name "invalidLevel". Defaulting to ERROR.'
281
+ )
282
+ );
283
+ });
278
284
  });
285
+ });
279
286
  });
@@ -1,4 +1,7 @@
1
- // tests/unit/utils/meta.test.ts
1
+ /**
2
+ * @file tests/unit/utils/meta.test.ts
3
+ * @description Unit tests for the bundle metadata.
4
+ */
2
5
  import { jest } from '@jest/globals';
3
6
  import { BuildTimer } from '../../../src/utils/meta';
4
7
 
@@ -17,12 +20,11 @@ describe('BuildTimer', () => {
17
20
  const html = '<html><body>Test</body></html>';
18
21
  // Simulate passing extra metadata calculated elsewhere
19
22
  const metadata = timer.finish(html, {
20
- assetCount: 5,
21
- pagesBundled: 3,
22
- errors: ['External warning'] // Add an external error to test merging
23
+ assetCount: 5,
24
+ pagesBundled: 3,
25
+ errors: ['External warning'], // Add an external error to test merging
23
26
  });
24
27
 
25
-
26
28
  expect(metadata.input).toBe(mockInput);
27
29
  expect(metadata.assetCount).toBe(5);
28
30
  expect(metadata.pagesBundled).toBe(3);
@@ -43,28 +45,27 @@ describe('BuildTimer', () => {
43
45
  expect(result.assetCount).toBe(0); // Check the explicitly passed 0
44
46
  });
45
47
 
46
- // Add a test case to check internal assetCount if not provided in extra
47
- it('uses internal asset count if not provided in extra', () => {
48
- const timer = new BuildTimer(mockInput);
49
- timer.setAssetCount(10); // Set internal count
50
- const result = timer.finish('html'); // Don't provide assetCount in extra
51
- expect(result.assetCount).toBe(10);
52
- });
53
-
54
- // Add a test case to check internal pageCount if not provided in extra
55
- it('uses internal page count if not provided in extra', () => {
56
- const timer = new BuildTimer(mockInput);
57
- timer.setPageCount(2); // Set internal count
58
- const result = timer.finish('html'); // Don't provide pageCount in extra
59
- expect(result.pagesBundled).toBe(2);
60
- });
48
+ // Add a test case to check internal assetCount if not provided in extra
49
+ it('uses internal asset count if not provided in extra', () => {
50
+ const timer = new BuildTimer(mockInput);
51
+ timer.setAssetCount(10); // Set internal count
52
+ const result = timer.finish('html'); // Don't provide assetCount in extra
53
+ expect(result.assetCount).toBe(10);
54
+ });
61
55
 
62
- // Add a test case to check internal errors if not provided in extra
63
- it('uses internal errors if not provided in extra', () => {
64
- const timer = new BuildTimer(mockInput);
65
- timer.addError("Internal Error"); // Add internal error
66
- const result = timer.finish('html'); // Don't provide errors in extra
67
- expect(result.errors).toEqual(["Internal Error"]);
68
- });
56
+ // Add a test case to check internal pageCount if not provided in extra
57
+ it('uses internal page count if not provided in extra', () => {
58
+ const timer = new BuildTimer(mockInput);
59
+ timer.setPageCount(2); // Set internal count
60
+ const result = timer.finish('html'); // Don't provide pageCount in extra
61
+ expect(result.pagesBundled).toBe(2);
62
+ });
69
63
 
70
- });
64
+ // Add a test case to check internal errors if not provided in extra
65
+ it('uses internal errors if not provided in extra', () => {
66
+ const timer = new BuildTimer(mockInput);
67
+ timer.addError('Internal Error'); // Add internal error
68
+ const result = timer.finish('html'); // Don't provide errors in extra
69
+ expect(result.errors).toEqual(['Internal Error']);
70
+ });
71
+ });