Path: blob/main/extensions/copilot/src/extension/test/node/patchEditGeneration.spec.ts
13399 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { deepStrictEqual } from 'assert';6import { promises as fs, readdirSync } from 'fs';7import { suite, test } from 'vitest';8import type { TextEdit, Uri } from 'vscode';9import { FetchStreamSource } from '../../../platform/chat/common/chatMLFetcher';10import { PromptPathRepresentationService } from '../../../platform/prompts/common/promptPathRepresentationService';11import { CancellationToken } from '../../../util/vs/base/common/cancellation';12import * as path from '../../../util/vs/base/common/path';13import { URI } from '../../../util/vs/base/common/uri';14import { Lines } from '../../prompt/node/editGeneration';15import { applyEdits } from '../../prompt/node/intents';16import { processPatchResponse } from '../../prompts/node/codeMapper/codeMapper';17import { getPatchEditReplyProcessor } from '../../prompts/node/codeMapper/patchEditGeneration';18import { TestWorkspaceService } from '../../../platform/test/node/testWorkspaceService';1920const fixturesRootFolder = path.join(__dirname, './fixtures/patch');2122suite('PatchEditGeneration - sync', function () {23const entries = readdirSync(fixturesRootFolder);24for (const entry of entries) {25const fixturesFolder = path.join(fixturesRootFolder, entry);26createTestsFromFixtures(fixturesFolder, (data) => {27const replyProcessor = getPatchEditReplyProcessor(new PromptPathRepresentationService(new TestWorkspaceService()));28const res = replyProcessor.process(data.patch, data.original);29const actual = applyEdits(data.original, res.edits);30deepStrictEqual(Lines.fromString(actual), Lines.fromString(data.expected));31});32}33});3435suite('PatchEditGeneration - async', function () {36const entries = readdirSync(fixturesRootFolder);37for (const entry of entries) {38const fixturesFolder = path.join(fixturesRootFolder, entry);39createTestsFromFixtures(fixturesFolder, async (data) => {40const input = new FetchStreamSource();41input.update(data.patch, { text: data.patch });4243let actual = data.original;44const outputCollector = {45textEdit(_target: Uri, edits: TextEdit | TextEdit[]) {46actual = applyEdits(actual, Array.isArray(edits) ? edits : [edits]);47},48notebookEdit() {49throw new Error('Unexpected notebook edit');50}51};52const promise = processPatchResponse(URI.parse('test://foo/bar'), data.original, input.stream, outputCollector, CancellationToken.None);53input.resolve();54await promise;55deepStrictEqual(Lines.fromString(actual), Lines.fromString(data.expected));56});57}58});5960function createTestsFromFixtures(fixturesFolder: string, runTest: (data: { [key: string]: string }) => void) {61const entries = readdirSync(fixturesFolder);62const testsData = new Map<string, { [key: string]: Promise<string> }>();63for (const entry of entries) {64const match = entry.match(/^([^.]+)\.([^.]+)\.(txt|bin)$/);65if (match) {66const [, testName, inputName] = match;67const content = fs.readFile(path.join(fixturesFolder, entry), 'utf8');68let data = testsData.get(testName);69if (!data) {70data = {};71testsData.set(testName, data);72}73data[inputName] = content;74}75}76for (const testName of testsData.keys()) {77test(testName, async () => {78const dataWithPromises = testsData.get(testName);79const data: { [key: string]: string } = {};80for (const key in dataWithPromises) {81data[key] = await dataWithPromises[key];82}83runTest(data);84});85}86}878889