16import * as fs from
'fs/promises';
17import * as
path from
'path';
20import { RandomLogo } from
'../modules/randomLogo';
21import {
CodeConfig } from
'../modules/processConfiguration';
46 rangeIncludingLineBreak:
vscode.Range;
48 firstNonWhitespaceCharacterIndex: number;
50 isEmptyOrWhitespace: boolean;
80 public version: number;
82 public isClosed: boolean;
84 public lineCount: number = 0;
86 public fileName:
string =
'';
88 public isUntitled:
boolean =
false;
90 public encoding:
string =
'utf8';
92 public isDirty:
boolean =
false;
108 content:
string =
'',
109 languageId:
string =
'typescript',
111 isClosed:
boolean =
false
113 this.uri =
vscode.Uri.file(filePath);
114 this.languageId = languageId;
117 this.isClosed = isClosed;
119 this.setContent(content);
132 setContent(content:
string): void {
133 const lines = content.split(
'\n');
134 this.lines = lines.map((text, index) => ({
136 range:
new vscode.Range(index, 0, index, text.length),
138 rangeIncludingLineBreak:
new vscode.Range(index, 0, index + 1, 0),
139 firstNonWhitespaceCharacterIndex: text.search(/\S/),
140 isEmptyOrWhitespace: text.trim().length === 0
142 this.lineCount = this.lines.length;
143 this.fileName =
path.basename(this.uri.fsPath);
152 lineAt(lineOrPosition: number |
vscode.Position):
vscode.TextLine {
153 const line = typeof lineOrPosition ===
'number' ? lineOrPosition : lineOrPosition.line;
154 if (line < 0 || line >= this.lines.length) {
155 throw new Error(`Line ${line} is out of range`);
157 return this.lines[line] as
vscode.TextLine;
165 offsetAt(position:
vscode.Position): number {
167 for (let i = 0; i < position.line && i < this.lines.length; i++) {
168 offset += this.lines[i].text.length + 1;
170 return offset + Math.min(position.character,
this.lines[position.line]?.text.length || 0);
178 positionAt(offset: number):
vscode.Position {
179 let currentOffset = 0;
180 for (let line = 0; line < this.lines.length; line++) {
181 const lineLength = this.lines[line].text.length + 1;
182 if (currentOffset + lineLength > offset) {
183 return new vscode.Position(line, offset - currentOffset);
185 currentOffset += lineLength;
187 return new vscode.Position(this.lines.length - 1, (
this.lines[
this.lines.length - 1]?.text.length || 0));
197 return this.lines.map(line => line.text).join(
'\n');
200 if (range.start.line === range.end.line) {
201 const line = this.lines[range.start.line];
202 return line ? line.text.substring(range.start.character, range.end.character) :
'';
206 for (let i = range.start.line; i <= range.end.line && i <
this.lines.length; i++) {
207 const line = this.lines[i];
208 if (!line) { continue; }
210 if (i === range.start.line) {
211 result += line.text.substring(range.start.character);
212 }
else if (i === range.end.line) {
213 result += line.text.substring(0, range.end.character);
218 if (i < range.end.line) {
239 validatePosition(position:
vscode.Position):
vscode.Position {
249 getWordRangeAtPosition(position:
vscode.Position, regex?: RegExp):
vscode.Range | undefined {
250 const line = this.lines[position.line];
251 if (!line) {
return undefined; }
253 const wordRegex = regex || /[\w]+/g;
255 while ((match = wordRegex.exec(line.text)) !==
null) {
256 if (match.index <= position.character && match.index + match[0].length >= position.character) {
257 return new vscode.Range(position.line, match.index, position.line, match.index + match[0].length);
267 save(): Thenable<boolean> {
268 return Promise.resolve(
true);
297 this.document = document as unknown as
vscode.TextDocument;
300 async edit(callback: (editBuilder:
vscode.TextEditorEdit) =>
void): Promise<boolean> {
301 const mockEditBuilder = {
311 position: location.start,
319 callback(mockEditBuilder as
vscode.TextEditorEdit);
335suite(
'CommentGenerator Test Suite',
function () {
339 let languageConfigFile:
string;
343 let mockRandomLogo: RandomLogo;
357 tempDir = await fs.mkdtemp(
path.join(require(
'os').tmpdir(),
'commentgen-test-'));
360 languageConfigFile =
path.join(tempDir,
'languages.json');
361 const languageConfig = {
364 langs: [
'typescript',
'javascript'],
366 typescript: [
'.ts',
'.tsx'],
367 javascript: [
'.js',
'.jsx']
370 multiLine: [
'/*',
' *',
' */'],
371 prompt_comment_opening_type:
false
380 prompt_comment_opening_type:
false
386 cpp: [
'.cpp',
'.hpp',
'.cxx']
389 multiLine: [
'/*',
' *',
' */'],
390 prompt_comment_opening_type:
true
394 await fs.writeFile(languageConfigFile, JSON.stringify(languageConfig,
null, 2));
400 mockRandomLogo =
new RandomLogo();
415 Object.defineProperty(
vscode.window,
'activeTextEditor', {
416 get: () => mockActiveTextEditor,
420 (
vscode.window as any).showInputBox = async (options?:
vscode.InputBoxOptions) => {
424 (
vscode.window as any).showQuickPick = async (items:
string[], options?:
vscode.QuickPickOptions) => {
429 (
vscode.workspace as any).applyEdit = async (edit:
vscode.WorkspaceEdit) => {
446 teardown(async () => {
449 await fs.rm(tempDir, { recursive:
true, force:
true });
455 Object.defineProperty(
vscode.window,
'activeTextEditor', {
456 value: originalActiveTextEditor,
469 suite(
'Constructor and Initialization', () => {
474 test(
'should create instance with all parameters provided', () => {
478 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
480 assert.ok(generator,
'Generator should be created successfully');
487 test(
'should create instance with minimal parameters', () => {
490 assert.ok(generator,
'Generator should be created with undefined parameters');
497 test(
'should create instance with only language loader', () => {
500 assert.ok(generator,
'Generator should be created with language loader only');
507 test(
'should handle undefined editor gracefully', () => {
508 generator =
new CommentGenerator(lazyFileLoader, undefined, mockRandomLogo);
510 assert.ok(generator,
'Generator should handle undefined editor');
521 suite(
'File Information Processing', () => {
526 test(
'should extract correct file metadata from TypeScript editor', () => {
527 const filePath =
'/home/user/project/test.ts';
531 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
534 const generatorAny = generator as any;
535 assert.strictEqual(generatorAny.fileName,
'test.ts');
536 assert.strictEqual(generatorAny.fileExtension,
'ts');
537 assert.strictEqual(generatorAny.languageId,
'typescript');
538 assert.strictEqual(generatorAny.filePath, filePath);
545 test(
'should extract correct file metadata from Python editor', () => {
546 const filePath =
'/home/user/project/script.py';
550 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
552 const generatorAny = generator as any;
553 assert.strictEqual(generatorAny.fileName,
'script.py');
554 assert.strictEqual(generatorAny.fileExtension,
'py');
555 assert.strictEqual(generatorAny.languageId,
'python');
562 test(
'should handle files without extensions', () => {
563 const filePath =
'/home/user/Makefile';
567 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
569 const generatorAny = generator as any;
570 assert.strictEqual(generatorAny.fileName,
'Makefile');
571 assert.strictEqual(generatorAny.fileExtension,
'none');
578 test(
'should handle different EOL types', () => {
582 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
584 const generatorAny = generator as any;
585 assert.strictEqual(generatorAny.documentEOL,
vscode.EndOfLine.CRLF);
596 suite(
'Comment Style Detection', () => {
601 test(
'should detect TypeScript comment style correctly', async () => {
605 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
607 const generatorAny = generator as any;
608 const commentStyle = await generatorAny.determineCorrectComment();
610 assert.deepStrictEqual(commentStyle.singleLine, [
'//']);
611 assert.deepStrictEqual(commentStyle.multiLine, [
'/*',
' *',
' */']);
612 assert.strictEqual(commentStyle.prompt_comment_opening_type,
false);
619 test(
'should detect Python comment style correctly', async () => {
623 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
625 const generatorAny = generator as any;
626 const commentStyle = await generatorAny.determineCorrectComment();
628 assert.deepStrictEqual(commentStyle.singleLine, [
'#']);
629 assert.deepStrictEqual(commentStyle.multiLine, []);
636 test(
'should detect C++ comment style with prompting', async () => {
640 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
642 const generatorAny = generator as any;
643 const commentStyle = await generatorAny.determineCorrectComment();
645 assert.deepStrictEqual(commentStyle.singleLine, [
'//']);
646 assert.deepStrictEqual(commentStyle.multiLine, [
'/*',
' *',
' */']);
647 assert.strictEqual(commentStyle.prompt_comment_opening_type,
true);
654 test(
'should fallback to file extension matching', async () => {
658 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
660 const generatorAny = generator as any;
661 const commentStyle = await generatorAny.determineCorrectComment();
664 assert.deepStrictEqual(commentStyle.singleLine, [
'//']);
665 assert.deepStrictEqual(commentStyle.multiLine, [
'/*',
' *',
' */']);
672 test(
'should return empty style for unknown language', async () => {
676 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
678 const generatorAny = generator as any;
679 const commentStyle = await generatorAny.determineCorrectComment();
681 assert.deepStrictEqual(commentStyle.singleLine, []);
682 assert.deepStrictEqual(commentStyle.multiLine, []);
683 assert.strictEqual(commentStyle.prompt_comment_opening_type,
false);
694 suite(
'User Input Handling', () => {
699 test(
'should get file description from user input', async () => {
702 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
706 const generatorAny = generator as any;
707 const description = await generatorAny.determineHeaderDescription();
709 assert.deepStrictEqual(description, [
'This is a test file for the application']);
716 test(
'should handle empty description input', async () => {
719 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
723 const generatorAny = generator as any;
724 const description = await generatorAny.determineHeaderDescription();
726 assert.deepStrictEqual(description, [
'']);
733 test(
'should get file purpose from user input', async () => {
736 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
740 const generatorAny = generator as any;
741 const purpose = await generatorAny.determineHeaderPurpose();
743 assert.deepStrictEqual(purpose, [
'Main entry point for the application']);
750 test(
'should get single comment option without prompting', async () => {
753 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
755 const generatorAny = generator as any;
756 const result = await generatorAny.getSingleCommentOption([
'//']);
758 assert.strictEqual(result,
'//');
765 test(
'should prompt for comment selection when multiple options', async () => {
768 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
772 const generatorAny = generator as any;
773 const result = await generatorAny.getSingleCommentOption([
'//',
'/*']);
775 assert.strictEqual(result,
'/*');
782 test(
'should return first option when user cancels selection', async () => {
785 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
789 const generatorAny = generator as any;
790 const result = await generatorAny.getSingleCommentOption([
'//',
'/*']);
792 assert.strictEqual(result,
'//');
799 test(
'should throw error for empty comment options', async () => {
802 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
804 const generatorAny = generator as any;
807 async () => await generatorAny.getSingleCommentOption([]),
820 suite(
'Header Content Generation', () => {
825 test(
'should generate correct header opener', () => {
828 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
830 const generatorAny = generator as any;
831 const opener = generatorAny.headerOpener(
' * ',
vscode.EndOfLine.LF,
'TestProject');
833 assert.ok(opener.includes(
'TestProject'));
834 assert.ok(opener.includes(
' * '));
835 assert.ok(opener.endsWith(
'\n'));
842 test(
'should generate correct header closer', () => {
845 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
847 const generatorAny = generator as any;
848 const closer = generatorAny.headerCloser(
' * ',
vscode.EndOfLine.LF,
'TestProject');
850 assert.ok(closer.includes(
'TestProject'));
851 assert.ok(closer.includes(
' * '));
852 assert.ok(closer.endsWith(
'\n'));
859 test(
'should generate creation date with correct format', () => {
862 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
864 const generatorAny = generator as any;
865 const creationDate = generatorAny.addCreationDate(
' * ',
vscode.EndOfLine.LF);
867 assert.ok(creationDate.includes(
' * '));
868 assert.ok(creationDate.includes(
new Date().getFullYear().toString()));
869 assert.ok(creationDate.endsWith(
'\n'));
876 test(
'should generate last modified date with time', () => {
879 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
881 const generatorAny = generator as any;
882 const modifiedDate = generatorAny.addLastModifiedDate(
' * ',
vscode.EndOfLine.LF);
884 assert.ok(modifiedDate.includes(
' * '));
885 assert.ok(modifiedDate.includes(
new Date().getFullYear().toString()));
886 assert.ok(modifiedDate.includes(
':'));
887 assert.ok(modifiedDate.endsWith(
'\n'));
894 test(
'should generate single line key-value pair', () => {
897 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
899 const generatorAny = generator as any;
900 const singleLine = generatorAny.addSingleLineKey(
' * ',
vscode.EndOfLine.LF,
'Author',
'John Doe');
902 assert.ok(singleLine.includes(
' * '));
903 assert.ok(singleLine.includes(
'Author'));
904 assert.ok(singleLine.includes(
'John Doe'));
905 assert.ok(singleLine.endsWith(
'\n'));
912 test(
'should generate multi-line key section', () => {
915 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
917 const generatorAny = generator as any;
918 const multiLine = generatorAny.addMultilineKey(
' * ',
vscode.EndOfLine.LF,
'Description', [
'Line 1',
'Line 2']);
920 assert.ok(multiLine.includes(
' * '));
921 assert.ok(multiLine.includes(
'Description'));
922 assert.ok(multiLine.includes(
'Line 1'));
923 assert.ok(multiLine.includes(
'Line 2'));
930 test(
'should handle CRLF line endings correctly', () => {
933 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
935 const generatorAny = generator as any;
936 const eolString = generatorAny.determineNewLine(
vscode.EndOfLine.CRLF);
938 assert.strictEqual(eolString,
'\r\n');
945 test(
'should handle LF line endings correctly', () => {
948 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
950 const generatorAny = generator as any;
951 const eolString = generatorAny.determineNewLine(
vscode.EndOfLine.LF);
953 assert.strictEqual(eolString,
'\n');
964 suite(
'Comment Prefix Processing', () => {
969 test(
'should process multi-line comments with three parts', async () => {
972 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
974 const commentStyle = {
976 multiLine: [
'/*',
' *',
' */'],
977 prompt_comment_opening_type:
false
980 const generatorAny = generator as any;
981 const prefixes = await generatorAny.getCorrectCommentPrefix(commentStyle);
983 assert.strictEqual(prefixes.length, 3);
984 assert.ok(prefixes[0].includes(
'/*'));
985 assert.ok(prefixes[1].includes(
' *'));
986 assert.ok(prefixes[2].includes(
' */'));
993 test(
'should process multi-line comments with two parts', async () => {
996 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
998 const commentStyle = {
1000 multiLine: [
'<!--',
'-->'],
1001 prompt_comment_opening_type:
false
1004 const generatorAny = generator as any;
1005 const prefixes = await generatorAny.getCorrectCommentPrefix(commentStyle);
1007 assert.strictEqual(prefixes.length, 3);
1008 assert.ok(prefixes[0].includes(
'<!--'));
1009 assert.strictEqual(prefixes[1].trim(),
'');
1010 assert.ok(prefixes[2].includes(
'-->'));
1017 test(
'should process single-line comments without prompting', async () => {
1020 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
1022 const commentStyle = {
1025 prompt_comment_opening_type:
false
1028 const generatorAny = generator as any;
1029 const prefixes = await generatorAny.getCorrectCommentPrefix(commentStyle);
1031 assert.strictEqual(prefixes.length, 3);
1032 assert.ok(prefixes[0].includes(
'#'));
1033 assert.ok(prefixes[1].includes(
'#'));
1034 assert.ok(prefixes[2].includes(
'#'));
1041 test(
'should prompt for single-line comment selection', async () => {
1044 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
1048 const commentStyle = {
1049 singleLine: [
'//',
'#'],
1051 prompt_comment_opening_type:
true
1054 const generatorAny = generator as any;
1055 const prefixes = await generatorAny.getCorrectCommentPrefix(commentStyle);
1057 assert.strictEqual(prefixes.length, 3);
1058 assert.ok(prefixes[0].includes(
'//'));
1059 assert.ok(prefixes[1].includes(
'//'));
1060 assert.ok(prefixes[2].includes(
'//'));
1067 test(
'should handle empty comment configurations', async () => {
1070 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
1072 const commentStyle = {
1075 prompt_comment_opening_type:
false
1078 const generatorAny = generator as any;
1079 const prefixes = await generatorAny.getCorrectCommentPrefix(commentStyle);
1081 assert.strictEqual(prefixes.length, 3);
1083 assert.strictEqual(prefixes[0],
' ');
1084 assert.strictEqual(prefixes[1],
' ');
1085 assert.ok(prefixes[2].includes(
' '));
1096 suite(
'Header Detection and Parsing', () => {
1101 test(
'should detect existing header correctly', () => {
1102 const headerContent = `
1119const someCode =
true;`;
1123 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
1125 const generatorAny = generator as any;
1126 const comments = [
' * ',
' * ',
' * '];
1127 const hasHeader = generatorAny.locateIfHeaderPresent(comments);
1129 assert.strictEqual(hasHeader,
true);
1130 assert.ok(typeof generatorAny.headerInnerStart ===
'number');
1131 assert.ok(typeof generatorAny.headerInnerEnd ===
'number');
1138 test(
'should detect missing header correctly', () => {
1139 const content = `
const someCode =
true;
1140function myFunction() {
1146 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
1148 const generatorAny = generator as any;
1149 const comments = [
' * ',
' * ',
' * '];
1150 const hasHeader = generatorAny.locateIfHeaderPresent(comments);
1152 assert.strictEqual(hasHeader,
false);
1153 assert.strictEqual(generatorAny.headerInnerStart, undefined);
1154 assert.strictEqual(generatorAny.headerInnerEnd, undefined);
1161 test(
'should detect broken header (opener without closer)', () => {
1162 const brokenContent = `
1184 test('should detect broken header (closer without opener)', () => {
1185 const brokenContent = `const someCode = true;
1186 * ═══════════════════════ ◄ END TestProject ► ═══════════════════════
1191 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
1193 const generatorAny = generator as any;
1194 const comments = [
' * ',
' * ',
' * '];
1195 const hasHeader = generatorAny.locateIfHeaderPresent(comments);
1197 assert.strictEqual(hasHeader,
false);
1204 test(
'should handle closed document gracefully', () => {
1207 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
1209 const generatorAny = generator as any;
1210 const comments = [
' * ',
' * ',
' * '];
1211 const hasHeader = generatorAny.locateIfHeaderPresent(comments);
1213 assert.strictEqual(hasHeader, undefined);
1220 test(
'should respect max scan length limit', () => {
1221 const longContent = Array(1000).fill(
'const line = true;').join(
'\n');
1224 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
1226 const generatorAny = generator as any;
1227 const comments = [
' * ',
' * ',
' * '];
1228 const hasHeader = generatorAny.locateIfHeaderPresent(comments);
1230 assert.strictEqual(hasHeader,
false);
1240 suite(
'Logo Integration', () => {
1245 test(
'should update logo randomizer instance', () => {
1247 const newRandomLogo =
new RandomLogo();
1249 generator.updateLogoInstanceRandomiser(newRandomLogo);
1263 suite(
'File Writing Operations', () => {
1268 test(
'should write header to empty file', async () => {
1275 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
1277 const generatorAny = generator as any;
1278 const comments = [
'/* ',
' * ',
' */'];
1279 const status = await generatorAny.writeHeaderToFile(document, comments);
1281 assert.strictEqual(status, 0);
1289 test(
'should update existing header timestamp', async () => {
1290 const headerContent = `
1309 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
1311 const generatorAny = generator as any;
1312 const comments = [
'/* ',
' * ',
' */'];
1315 generatorAny.headerInnerStart = 1;
1316 generatorAny.headerInnerEnd = 15;
1318 await generatorAny.updateEditDate(document, comments);
1331 suite(
'Main API Methods', () => {
1336 test(
'should inject header when no active editor', async () => {
1342 await generator.injectHeader();
1351 test(
'should inject header to TypeScript file', async () => {
1358 generator =
new CommentGenerator(lazyFileLoader, undefined, mockRandomLogo);
1360 await generator.injectHeader();
1370 test(
'should refresh header when configured', async () => {
1371 const headerContent = `
1384 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
1386 await generator.refreshHeader(document as any);
1397 test(
'should handle refresh with no document', async () => {
1400 await generator.refreshHeader(undefined);
1409 test(
'should handle refresh with closed document', async () => {
1415 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
1417 await generator.refreshHeader(document as any);
1430 suite(
'Language Customization Features', () => {
1435 test(
'should trim trailing spaces when enabled', () => {
1438 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
1440 const generatorAny = generator as any;
1441 generatorAny.trimTrailingSpaces =
true;
1443 const result = generatorAny.mySmartTrimmer(
'content with spaces ');
1444 assert.strictEqual(result,
'content with spaces');
1451 test(
'should preserve trailing spaces when disabled', () => {
1454 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
1456 const generatorAny = generator as any;
1457 generatorAny.trimTrailingSpaces =
false;
1459 const result = generatorAny.mySmartTrimmer(
'content with spaces ');
1460 assert.strictEqual(result,
'content with spaces ');
1467 test(
'should prepend language-specific text when configured', () => {
1470 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
1472 const generatorAny = generator as any;
1473 generatorAny.languagePrepend = { python:
'#!/usr/bin/env python\n' };
1475 let buildHeader:
string[] = [];
1476 buildHeader = generatorAny.prependIfPresent(buildHeader,
vscode.EndOfLine.LF,
'python');
1478 assert.strictEqual(buildHeader.length, 1);
1479 assert.strictEqual(buildHeader[0],
'#!/usr/bin/env python\n');
1486 test(
'should handle array prepend content', () => {
1489 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
1491 const generatorAny = generator as any;
1492 generatorAny.languagePrepend = { python: [
'#!/usr/bin/env python',
'# -*- coding: utf-8 -*-'] };
1494 let buildHeader:
string[] = [];
1495 buildHeader = generatorAny.prependIfPresent(buildHeader,
vscode.EndOfLine.LF,
'python');
1497 assert.strictEqual(buildHeader.length, 1);
1498 assert.ok(buildHeader[0].includes(
'#!/usr/bin/env python'));
1505 test(
'should skip prepend when language is undefined', () => {
1508 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
1510 const generatorAny = generator as any;
1511 generatorAny.languagePrepend = { python:
'#!/usr/bin/env python\n' };
1513 let buildHeader:
string[] = [];
1514 buildHeader = generatorAny.prependIfPresent(buildHeader,
vscode.EndOfLine.LF, undefined);
1516 assert.strictEqual(buildHeader.length, 0);
1523 test(
'should append language-specific text when configured', () => {
1526 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
1528 const generatorAny = generator as any;
1529 generatorAny.languageAppend = { python:
'\n# Code begins\n' };
1531 let buildHeader:
string[] = [];
1532 buildHeader = generatorAny.appendIfPresent(buildHeader,
vscode.EndOfLine.LF,
'python');
1534 assert.strictEqual(buildHeader.length, 1);
1535 assert.strictEqual(buildHeader[0],
'\n# Code begins\n');
1542 test(
'should handle array append content', () => {
1545 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
1547 const generatorAny = generator as any;
1548 generatorAny.languageAppend = { python: [
'',
'# Code begins',
'# ============'] };
1550 let buildHeader:
string[] = [];
1551 buildHeader = generatorAny.appendIfPresent(buildHeader,
vscode.EndOfLine.LF,
'python');
1553 assert.strictEqual(buildHeader.length, 1);
1554 assert.ok(buildHeader[0].includes(
'# Code begins'));
1561 test(
'should skip append when language is undefined', () => {
1564 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
1566 const generatorAny = generator as any;
1567 generatorAny.languageAppend = { python:
'\n# Code begins\n' };
1569 let buildHeader:
string[] = [];
1570 buildHeader = generatorAny.appendIfPresent(buildHeader,
vscode.EndOfLine.LF, undefined);
1572 assert.strictEqual(buildHeader.length, 0);
1579 test(
'should apply single-line comment override when configured', () => {
1582 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
1584 const generatorAny = generator as any;
1585 generatorAny.singleLineOverride = { idris:
'|||' };
1587 const commentStyle = {
1590 prompt_comment_opening_type:
false,
1594 const result = generatorAny.getOverrideIfPresent(commentStyle);
1596 assert.deepStrictEqual(result.singleLine, [
'|||']);
1597 assert.strictEqual(result.language,
'idris');
1604 test(
'should apply multi-line comment override when configured', () => {
1607 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
1609 const generatorAny = generator as any;
1610 generatorAny.multiLineOverride = { c: [
'/*',
'**',
'*/'] };
1612 const commentStyle = {
1614 multiLine: [
'/*',
' *',
' */'],
1615 prompt_comment_opening_type:
false,
1619 const result = generatorAny.getOverrideIfPresent(commentStyle);
1621 assert.deepStrictEqual(result.multiLine, [
'/*',
'**',
'*/']);
1622 assert.strictEqual(result.language,
'c');
1629 test(
'should handle array single-line comment override', () => {
1632 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
1634 const generatorAny = generator as any;
1635 generatorAny.singleLineOverride = { idris: [
'|||',
'---'] };
1637 const commentStyle = {
1640 prompt_comment_opening_type:
false,
1644 const result = generatorAny.getOverrideIfPresent(commentStyle);
1646 assert.deepStrictEqual(result.singleLine, [
'|||',
'---']);
1653 test(
'should skip override when language is undefined', () => {
1656 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
1658 const generatorAny = generator as any;
1659 generatorAny.singleLineOverride = { idris:
'|||' };
1661 const commentStyle = {
1664 prompt_comment_opening_type:
false,
1668 const result = generatorAny.getOverrideIfPresent(commentStyle);
1670 assert.deepStrictEqual(result.singleLine, [
'--']);
1671 assert.strictEqual(result.language, undefined);
1678 test(
'should prefer single-line comments when configured', async () => {
1681 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
1683 const generatorAny = generator as any;
1684 generatorAny.preferSingleLineComments =
true;
1686 const commentStyle = {
1688 multiLine: [
'/*',
' *',
' */'],
1689 prompt_comment_opening_type:
false,
1690 language:
'typescript'
1693 const prefixes = await generatorAny.getCorrectCommentPrefix(commentStyle);
1696 assert.ok(prefixes[0].includes(
'//'));
1697 assert.ok(prefixes[1].includes(
'//'));
1698 assert.ok(prefixes[2].includes(
'//'));
1705 test(
'should use multi-line comments by default', async () => {
1708 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
1710 const generatorAny = generator as any;
1711 generatorAny.preferSingleLineComments =
false;
1713 const commentStyle = {
1715 multiLine: [
'/*',
' *',
' */'],
1716 prompt_comment_opening_type:
false,
1717 language:
'typescript'
1720 const prefixes = await generatorAny.getCorrectCommentPrefix(commentStyle);
1723 assert.ok(prefixes[0].includes(
'/*'));
1724 assert.ok(prefixes[1].includes(
' *'));
1725 assert.ok(prefixes[2].includes(
' */'));
1735 suite(
'Shebang Detection', () => {
1740 test(
'should detect bash shebang and skip first line', () => {
1741 const content =
'#!/bin/bash\necho "Hello World"';
1742 const document =
new MockTextDocument(
'/test/script.sh', content,
'shellscript');
1744 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
1746 const generatorAny = generator as any;
1747 const insertLine = generatorAny.skipFirstLineInDocument(document);
1749 assert.strictEqual(insertLine, 1);
1756 test(
'should detect python shebang and skip first line', () => {
1757 const content =
'#!/usr/bin/env python3\nprint("Hello World")';
1758 const document =
new MockTextDocument(
'/test/script.py', content,
'python');
1760 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
1762 const generatorAny = generator as any;
1763 const insertLine = generatorAny.skipFirstLineInDocument(document);
1765 assert.strictEqual(insertLine, 1);
1772 test(
'should insert at line 0 when no shebang present', () => {
1773 const content =
'import sys\nprint("Hello World")';
1774 const document =
new MockTextDocument(
'/test/script.py', content,
'python');
1776 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
1778 const generatorAny = generator as any;
1779 const insertLine = generatorAny.skipFirstLineInDocument(document);
1781 assert.strictEqual(insertLine, 0);
1788 test(
'should handle empty document', () => {
1789 const document =
new MockTextDocument(
'/test/empty.sh',
'',
'shellscript');
1791 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
1793 const generatorAny = generator as any;
1794 const insertLine = generatorAny.skipFirstLineInDocument(document);
1796 assert.strictEqual(insertLine, 0);
1803 test(
'should not treat regular hash comments as shebang', () => {
1804 const content =
'# This is a comment\nprint("Hello")';
1805 const document =
new MockTextDocument(
'/test/script.py', content,
'python');
1807 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
1809 const generatorAny = generator as any;
1810 const insertLine = generatorAny.skipFirstLineInDocument(document);
1812 assert.strictEqual(insertLine, 0);
1819 test(
'should detect shebang with arguments', () => {
1820 const content =
'#!/usr/bin/env node --harmony\nconsole.log("Test")';
1821 const document =
new MockTextDocument(
'/test/script.js', content,
'javascript');
1823 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
1825 const generatorAny = generator as any;
1826 const insertLine = generatorAny.skipFirstLineInDocument(document);
1828 assert.strictEqual(insertLine, 1);
1832 suite(
'Error Handling and Edge Cases', () => {
1837 test(
'should handle missing language comment loader', async () => {
1841 generator =
new CommentGenerator(undefined, editor as any, mockRandomLogo);
1843 const generatorAny = generator as any;
1844 const commentStyle = await generatorAny.determineCorrectComment();
1846 assert.deepStrictEqual(commentStyle.singleLine, []);
1847 assert.deepStrictEqual(commentStyle.multiLine, []);
1854 test(
'should handle corrupted language configuration', async () => {
1856 const corruptedConfigFile =
path.join(tempDir,
'corrupted.json');
1857 await fs.writeFile(corruptedConfigFile,
'{"invalid": structure}');
1859 const corruptedLoader =
new LazyFileLoader(corruptedConfigFile, tempDir);
1863 generator =
new CommentGenerator(corruptedLoader, editor as any, mockRandomLogo);
1865 const generatorAny = generator as any;
1866 const commentStyle = await generatorAny.determineCorrectComment();
1868 assert.deepStrictEqual(commentStyle.singleLine, []);
1869 assert.deepStrictEqual(commentStyle.multiLine, []);
1876 test(
'should handle update without header bounds', async () => {
1880 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
1882 const generatorAny = generator as any;
1883 const comments = [
' * ',
' * ',
' * '];
1886 await generatorAny.updateEditDate(editor, comments);
1896 test(
'should handle undefined document in update', async () => {
1900 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
1902 const generatorAny = generator as any;
1903 const comments = [
' * ',
' * ',
' * '];
1906 generatorAny.documentBody = undefined;
1908 await generatorAny.updateEditDate(editor, comments);
1917 test(
'should handle very long file paths', () => {
1918 const longPath =
'/very/' +
'long/'.repeat(100) +
'path/to/file.ts';
1922 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
1924 const generatorAny = generator as any;
1925 assert.strictEqual(generatorAny.fileName,
'file.ts');
1926 assert.strictEqual(generatorAny.fileExtension,
'ts');
1933 test(
'should handle empty file names', () => {
1937 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
1939 const generatorAny = generator as any;
1940 assert.strictEqual(generatorAny.fileName,
'unknown');
1947 test(
'should handle special characters in file names', () => {
1948 const specialPath =
'/test/file with spaces & symbols!.ts';
1952 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
1954 const generatorAny = generator as any;
1955 assert.strictEqual(generatorAny.fileName,
'file with spaces & symbols!.ts');
1956 assert.strictEqual(generatorAny.fileExtension,
'ts');
1967 suite(
'Integration Tests', () => {
1972 test(
'should complete full header injection workflow', async () => {
1979 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
1981 await generator.injectHeader();
1991 test(
'should handle complete refresh workflow with existing header', async () => {
1992 const existingHeader = `
2001const app =
'Hello World';`;
2003 const document =
new MockTextDocument(
'/test/main.ts', existingHeader,
'typescript');
2008 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
2010 await generator.refreshHeader(document as any);
2020 test(
'should handle multiple rapid operations', async () => {
2027 generator =
new CommentGenerator(lazyFileLoader, editor as any, mockRandomLogo);
2031 generator.injectHeader(),
2032 generator.refreshHeader(document as any),
2033 generator.injectHeader()
Generic lazy file loader with caching and type safety @template T The expected type of the loaded fil...
Mock implementation of VS Code TextDocument for testing purposes.
constructor(filePath:string, content:string='', languageId:string='typescript', eol:vscode.EndOfLine=vscode.EndOfLine.LF, isClosed:boolean=false)
Creates a new mock text document with specified configuration.
Mock implementation of VS Code TextEditor for testing text editing operations.
constructor(document:MockTextDocument)
Creates a new mock text editor for the specified document.
iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAAG0OVFdAAAAv3pUWHRSYXcgcHJvZmlsZSB0eXBlIGV4aWYAAHjabVBbEsMgCPznFD2CAho5jknTmd6gx qtNJMEqCKH4h lRj6dADxVZugptTqwzYer65UeIe5DWUctXFzIXEu5EdIHqrWYry UL6xZmlG7UnJa57b oHlEkAAAGEaUNDUElDQyBwcm9maWxlAAB4nH2RPUjDUBSFT1OlKhWHFhFxyFA72UVFHGsVilAh1AqtOpi89A aNCQpLo6Ca8HBn8Wqg4uzrg6ugiD4A IuOCm6SIn3JYUWsT64vI z3jncdx8gNCpMs3rigKbbZjqZELO5VTHwin4MU4UQlZllzElSCl3X1z18fL L8azu9 Ma56LLAM8NmJj1PHCYWix2sdDArmRrxNHFE1XTKF7Ieq5y3OGuVGmv1yV8YzOsry1ynGkMSi1iCBBEKaiijAhsx2nVSLKTpPNHFP r6JXIp5CqDkWMBVWiQXT yerVWYmvSSggmg98VxPsaBwC7QrDvO97HjNE8A zNwpbf91QYw KqFQAN7P6JtyQOgWGFjz5tY6x kDkKFZpW6Ag0MgWqTs9S7v7uuc2793WvP7AZKlcrMQx gGAAANcmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNC40LjAtRXhpdjIiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iCiAgICB4bWxuczpzdEV2dD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlRXZlbnQjIgogICAgeG1sbnM6R0lNUD0iaHR0cDovL3d3dy5naW1wLm9yZy94bXAvIgogICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgIHhtcE1NOkRvY3VtZW50SUQ9ImdpbXA6ZG9jaWQ6Z2ltcDowOWQ3ODk3OS03YjNiLTRhMTgtODM5ZS1lMDgwOGNjMmUzY2EiCiAgIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NTM2YWE3YmMtN2QzZS00ZDJkLWIxMjItYTFhZjQwMjkzYjI5IgogICB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6OTc2ZWEzNTgtNTNlNy00ODZkLWIzMzQtMjhmZWY1N2IyZWIzIgogICBHSU1QOkFQST0iMy4wIgogICBHSU1QOlBsYXRmb3JtPSJMaW51eCIKICAgR0lNUDpUaW1lU3RhbXA9IjE3NTg1MzI3OTM2NzA4NzIiCiAgIEdJTVA6VmVyc2lvbj0iMy4wLjQiCiAgIGRjOkZvcm1hdD0iaW1hZ2UvcG5nIgogICB0aWZmOk9yaWVudGF0aW9uPSIxIgogICB4bXA6Q3JlYXRvclRvb2w9IkdJTVAiCiAgIHhtcDpNZXRhZGF0YURhdGU9IjIwMjU6MDk6MjJUMTE6MTk6NTArMDI6MDAiCiAgIHhtcDpNb2RpZnlEYXRlPSIyMDI1OjA5OjIyVDExOjE5OjUwKzAyOjAwIj4KICAgPHhtcE1NOkhpc3Rvcnk CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiCiAgICAgIHN0RXZ0OmNoYW5nZWQ9Ii8iCiAgICAgIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6ZGE1MDJhZWEtNDM0MS00NjdjLTgwMzEtYjUwMmU2OGFhYjkwIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJHSU1QIDMuMC40IChMaW51eCkiCiAgICAgIHN0RXZ0OndoZW49IjIwMjUtMDktMjJUMTE6MTk6NTMrMDI6MDAiLz4KICAgIDwvcmRmOlNlcT4KICAgPC94bXBNTTpIaXN0b3J5PgogIDwvcmRmOkRlc2NyaXB0aW9uPgogPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIAo8P3hwYWNrZXQgZW5kPSJ3Ij8 QZaInQAAAAZiS0dEAAAAAAAA UO7fwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB kJFgkTNb1wNOYAABokSURBVHja7V15dFRF1r9V7 WW7mwsAZJ0SJpElARhUBM0gKNwjsM2gIMw oF Ss4MHy5DmBEB56g4Is6ZIQGRJYownzIalCUzLnj0Cx7GBZhAWISIMGaTYIBgku5Od7 t7vdH8pruTifpzkaAd8 pk8573fWqbv3q3lu3bt1HEPEkAAyAThLf8uNBna2AQhfJW4EkSV2rgOd5SEpKavWF yv QjEZjq58rigLJyclAqfdZZMaMGbX5 fmDAQAIItb2jbnQWVK70KUK8Kp2IWAuYOcrSEpKAkJIwG0GQ5OtXekCBUDabss6qIABEAaEEKitrXVnZ2eLwaSy3w uPI2CLCtAgAMAgLFjx oqKyt59b7a3VZMbJYDzXJBp NAUZoFSWVlJa sKCgoK6NLgSXBSdOnGhseQAiImRnZ0u T21TFiAqmJgYj3PmzHF4ryiK7PuNDipAHDhwICIirly58kJ1daUz8L4XylarFX744YdW45CcnNzcmSvyAMrLy vqXOiKPBgEV4koXGXqmw0YOnQoDB06NKQK9u3bdz6YWdPpBqhGRWjoZsBQBkIxQBD12hA0y1vVBiOEgCIrYVmLXWxAs7z2teE4noPt27fbw7Gyg89PijA02RpETalWZ7N42rJlCzDlSl8kSYKpU6fqAAAEQYCHHnzIuWv3Lsvx48drb7311sGt6vO1zhARGWNotVrRarUiYwzbJwWLiz rSUyMR0QFRVFEH6mNR44caXK73aLH45EREQsKCjy JTMzEyPeiclJQVGjhwZYTQadZRSTpIkGDx4sCAIgtguB1TV0pZ6aY8DiIhlZWVNKjMREQVBUH7 ziBhdaEVB8KtINzva8qo29cH3dEAvKGHQGtA322AIivQG hs1QDGGAwdOhQoR0OSclarFbKysuq7zyZk4dmEiAoQgu16tXoNA1fHKPUrV5kDhBCQJAkYY73VABZQAEpKShyKokB fr49JPM80ESSJRmtVqufW7A9kywhYQhmZd3xk2qSqYYtImJCQkKHNdC2etbsEWABrljFb UkCBLwvB4I4bzM3L17d OpU6caEBFmzZrlfuaZZ wqOIOBlA JiCQnJLkddu0tS7Ytm2brCgKL8uy99Y777xD33vvvUhCCJyvOS lpqUq fv MREBE3btzoREQ8ePCgK3Ct0U4DWEgLE98GFBYWlvvenTRpknP8 PGNKp6C1dnFBiAmJibi7bff lPg9dTUVCmwjtWrVzcsW7bM3o3rAn9yu91gMplAkRU4 e1pXpZl0Ol03vsVFRVcQUGBpV05QCgJw RmV1bIwKCkpMSh1sHxnPfhJ0 etCMiBD682yXhkiVLdOqqWd0tYYzBiBEjotrqTLfoggiTBQAoHD582Hju3Dk3YzJyHIGH uvXrltuucXruAjJKmaMQXJyMlRVVYVsDwRzdQc2dO3atbWzZs1q5R g21KrgQBqiziO83 U16fK Bgc7OFtrgsCvdo9uTjVFiZaA7QGXPX9ght BDQGaAzQGKAx4GpSyEuSr7 Kysru7xDodK ffvOP LII GEEBgyZEj9oUOHYvsUAhDR6zP0vdZ1BjQvWhjKgKgA5Tg PyMi6ZR5r8mAnpIBPcZ7NegSA pSuSFfxTtzTffbLbZbKb09HRp0aJF5mPHjkWkp6db3n777foZM2Y4rxIDWBil60j45JNP6jdv3txYVVVVDwCg1 th vz5sRcvXoTDhw b6 rq3L0kAxjwPA83DU8FURSDOmWuqAraLq8REbZt2ybzvA4o5QGZKvlbj8mAAQN0c fONZ49e9Yv5Pf2228X586d22 hfqX3ieB47j DYcgu3tuN1uZenSpdx export const string
import *as vscode from vscode
Represents a single line within a mock VS Code document for testing.
export const CodeConfig
Exported configuration singleton for extension-wide access @export Primary configuration interface us...