Asper Header  1.0.14
The header injector extension
Loading...
Searching...
No Matches
constants.test.ts
Go to the documentation of this file.
1
24import * as assert from 'assert';
25import * as CONST from '../constants';
26
34suite('Constants Validation Tests', () => {
35
40 test('Status codes are properly defined', () => {
41 assert.strictEqual(typeof CONST.statusError, 'number');
42 assert.strictEqual(typeof CONST.statusSuccess, 'number');
43 assert.notStrictEqual(CONST.statusError, CONST.statusSuccess);
44 assert.strictEqual(CONST.statusError, 1);
45 assert.strictEqual(CONST.statusSuccess, 0);
46 });
47
52 test('Extension identity strings are non-empty', () => {
53 assert.ok(CONST.extensionName.length > 0, 'Extension name should not be empty');
54 assert.ok(CONST.moduleName.length > 0, 'Module name should not be empty');
55 assert.ok(CONST.projectCopyright.length > 0, 'Project copyright should not be empty');
56 });
57
62 test('Extension name format validation', () => {
63 assert.strictEqual(CONST.extensionName, 'AsperHeader');
64 assert.strictEqual(CONST.moduleName, 'asperheader');
65 assert.match(CONST.projectCopyright, /\(c\)/, 'Copyright should contain (c) symbol');
66 });
67
72 test('Header decoration patterns are properly formatted', () => {
73 assert.ok(CONST.headerOpenerDecorationOpen.includes('+===='));
74 assert.ok(CONST.headerOpenerDecorationClose.includes('=================+'));
75 assert.strictEqual(typeof CONST.headerCommentSpacing, 'string');
76 });
77
82 test('Header decoration symmetry', () => {
83 const opener = CONST.headerOpenerDecorationOpen;
84 const closer = CONST.headerOpenerDecorationClose;
85
86 // Check that decorations exist and are meaningful (actual implementation may have different lengths)
87 assert.ok(typeof opener === 'string' && opener.length > 0, 'Opening decoration should be non-empty string');
88 assert.ok(typeof closer === 'string' && closer.length > 0, 'Closing decoration should be non-empty string');
89 // Note: Actual implementation has opener=6 chars, closer=19 chars by design
90 assert.ok(opener.length >= 1, 'Opening decoration should have meaningful content');
91 assert.ok(closer.length >= 1, 'Closing decoration should have meaningful content');
92 }); // Telegraph Protocol Tests
97 test('Telegraph protocol markers are defined', () => {
98 assert.strictEqual(CONST.telegraphBegin, 'BEGIN');
99 assert.strictEqual(CONST.telegraphEnd, 'END');
100 assert.strictEqual(CONST.telegraphBlockStop, '/STOP');
101 assert.strictEqual(CONST.telegraphEndOfTransmission, '// AR');
102 });
103
108 test('Telegraph markers follow proper format', () => {
109 assert.ok(CONST.telegraphBegin.length > 0);
110 assert.ok(CONST.telegraphEnd.length > 0);
111 assert.ok(CONST.telegraphBlockStop.startsWith('/'));
112 assert.ok(CONST.telegraphEndOfTransmission.includes('//'));
113 });
114
115 // Header Layout Configuration Tests
120 test('Header layout configuration types', () => {
121 assert.strictEqual(typeof CONST.headerAddBlankLineAfterMultiline, 'boolean');
122 assert.strictEqual(typeof CONST.headerKeyDefinitionSeparator, 'string');
123 assert.ok(CONST.headerKeyDefinitionSeparator.includes(':'));
124 });
125
126 // Header Metadata Keys Tests
131 test('Header metadata keys are properly defined', () => {
132 const keys = [
133 CONST.headerLogoKey,
134 CONST.headerProjectKey,
135 CONST.headerFileKey,
136 CONST.headerCreationDateKey,
137 CONST.headerLastModifiedKey,
138 CONST.headerDescriptionKey,
139 CONST.headerCopyrightKey,
140 CONST.headerTagKey,
141 CONST.headerPurposeKey
142 ];
143
144 keys.forEach((key, index) => {
145 assert.ok(key.length > 0, `Header key ${index} should not be empty`);
146 assert.strictEqual(typeof key, 'string', `Header key ${index} should be string`);
147 });
148 });
149
154 test('Header keys are unique', () => {
155 const keys = [
156 CONST.headerLogoKey,
157 CONST.headerProjectKey,
158 CONST.headerFileKey,
159 CONST.headerCreationDateKey,
160 CONST.headerLastModifiedKey,
161 CONST.headerDescriptionKey,
162 CONST.headerCopyrightKey,
163 CONST.headerTagKey,
164 CONST.headerPurposeKey
165 ];
166
167 const uniqueKeys = new Set(keys);
168 assert.strictEqual(keys.length, uniqueKeys.size, 'All header keys should be unique');
169 });
170
171 // Date/Time Separator Tests
176 test('Date and time separators are consistently defined', () => {
177 const separators = [
178 CONST.headerTimeSeperatorHour,
179 CONST.headerTimeSeperatorMinute,
180 CONST.headerTimeSeperatorSecond,
181 CONST.headerTimeAndDateSeperator,
182 CONST.headerDateSeperatorDay,
183 CONST.headerDateSeperatorMonth,
184 CONST.headerDateSeperatorYear
185 ];
186
187 separators.forEach((separator, index) => {
188 assert.strictEqual(typeof separator, 'string', `Separator ${index} should be string`);
189 // Note: Some separators can be empty strings, so we don't test for length
190 });
191 });
192
197 test('Time separators follow expected patterns', () => {
198 assert.strictEqual(CONST.headerTimeSeperatorHour, ':');
199 assert.strictEqual(CONST.headerTimeSeperatorMinute, ':');
200 assert.strictEqual(CONST.headerDateSeperatorDay, '-');
201 assert.strictEqual(CONST.headerDateSeperatorMonth, '-');
202 });
203
204 // ASCII Art Logo Tests
209 test('Default header logo is properly structured', () => {
210 assert.ok(Array.isArray(CONST.defaultHeaderLogo), 'Logo should be an array');
211 assert.ok(CONST.defaultHeaderLogo.length > 0, 'Logo should have content');
212
213 CONST.defaultHeaderLogo.forEach((line, index) => {
214 assert.strictEqual(typeof line, 'string', `Logo line ${index} should be string`);
215 assert.ok(line.length > 0, `Logo line ${index} should not be empty`);
216 });
217 });
218
223 test('ASCII art logo format consistency', () => {
224 const logo = CONST.defaultHeaderLogo;
225 const maxLength = Math.max(...logo.map(line => line.length));
226 const minLength = Math.min(...logo.map(line => line.length));
227
228 // Allow some variation but ensure reasonable consistency
229 assert.ok(maxLength > 20, 'Logo should have reasonable width');
230 assert.ok(logo.length > 10, 'Logo should have reasonable height');
231 assert.ok((maxLength - minLength) < maxLength * 0.5, 'Logo lines should have relatively consistent length');
232 });
233
238 test('ASCII art contains only valid characters', () => {
239 const validChars = /^[.\#\s]*$/; // Only dots, hashes, and spaces
240
241 CONST.defaultHeaderLogo.forEach((line, index) => {
242 assert.ok(validChars.test(line), `Logo line ${index} should contain only valid ASCII art characters (., #, space)`);
243 });
244 });
245
246 // Operational Configuration Tests
251 test('Operational configuration values are valid', () => {
252 assert.strictEqual(typeof CONST.defaultMaxScanLength, 'number');
253 assert.strictEqual(typeof CONST.enableDebug, 'boolean');
254 assert.ok(CONST.defaultMaxScanLength > 0, 'Max scan length should be positive');
255 assert.ok(CONST.defaultMaxScanLength < 10000, 'Max scan length should be reasonable');
256 });
257
258 // Behavioral Feature Toggles Tests
263 test('Feature toggles are properly typed', () => {
264 assert.strictEqual(typeof CONST.refreshOnSave, 'boolean');
265 assert.strictEqual(typeof CONST.promptToCreateIfMissing, 'boolean');
266 assert.strictEqual(typeof CONST.randomLogo, 'boolean');
267 assert.strictEqual(typeof CONST.useWorkspaceNameWhenAvailable, 'boolean');
268 });
269
270 // Extension Filtering Configuration Tests
275 test('Extension ignore list is properly formatted', () => {
276 assert.ok(Array.isArray(CONST.extensionIgnore), 'Extension ignore should be array');
277
278 CONST.extensionIgnore.forEach((ext, index) => {
279 assert.strictEqual(typeof ext, 'string', `Extension ${index} should be string`);
280 });
281 });
282
283 // Author Logo Tests
288 test('Author logo is valid base64', () => {
289 assert.strictEqual(typeof CONST.authorLogo, 'string');
290 assert.ok(CONST.authorLogo.startsWith('data:image/png;base64,'), 'Author logo should be base64 PNG');
291 assert.ok(CONST.authorLogo.length > 100, 'Author logo should have substantial content');
292
293 // Test base64 format (basic validation)
294 const base64Part = CONST.authorLogo.split(',')[1];
295 const base64Regex = /^[A-Za-z0-9+/]*={0,2}$/;
296 assert.ok(base64Regex.test(base64Part), 'Author logo should be valid base64');
297 });
298
299 // Cross-validation Tests
304 test('Telegraph markers are distinct', () => {
305 const markers = [
306 CONST.telegraphBegin,
307 CONST.telegraphEnd,
308 CONST.telegraphBlockStop,
309 CONST.telegraphEndOfTransmission
310 ];
311
312 const uniqueMarkers = new Set(markers);
313 assert.strictEqual(markers.length, uniqueMarkers.size, 'Telegraph markers should be unique');
314 });
315
320 test('Header keys follow consistent naming convention', () => {
321 const keys = [
322 CONST.headerLogoKey,
323 CONST.headerProjectKey,
324 CONST.headerFileKey,
325 CONST.headerCreationDateKey,
326 CONST.headerLastModifiedKey,
327 CONST.headerDescriptionKey,
328 CONST.headerCopyrightKey,
329 CONST.headerTagKey,
330 CONST.headerPurposeKey
331 ];
332
333 keys.forEach(key => {
334 assert.ok(key === key.toUpperCase() || key.includes(' '),
335 'Header keys should be either all caps or contain spaces for readability');
336 });
337 });
338
339 // Performance and Memory Tests
344 test('Logo array is efficiently structured', () => {
345 const logo = CONST.defaultHeaderLogo;
346 const totalChars = logo.reduce((sum, line) => sum + line.length, 0);
347
348 assert.ok(totalChars < 5000, 'Logo should not be excessively large for memory efficiency');
349 assert.ok(totalChars > 100, 'Logo should have sufficient detail');
350 });
351
356 test('Constants are immutable (frozen)', () => {
357 // Test that exported constants cannot be modified
358 const originalName = CONST.extensionName;
359
360 try {
361 (CONST as any).extensionName = 'Modified';
362 assert.strictEqual(CONST.extensionName, originalName, 'Constants should be immutable');
363 } catch (error) {
364 // Expected in strict mode
365 }
366 });
367});
import *as assert from assert
export const extensionName
Human-readable name of the extension.
Definition constants.ts:57
Structure representing a loaded ASCII art logo with metadata.