Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/copilot/src/extension/inlineEdits/test/node/rejectionCollector.spec.ts
13405 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { outdent } from 'outdent';
7
import { describe, expect, test } from 'vitest';
8
import { DocumentId } from '../../../../platform/inlineEdits/common/dataTypes/documentId';
9
import { IObservableDocument, MutableObservableWorkspace } from '../../../../platform/inlineEdits/common/observableWorkspace';
10
import { TestLogService } from '../../../../platform/testing/common/testLogService';
11
import { runOnChange } from '../../../../util/vs/base/common/observableInternal';
12
import { URI } from '../../../../util/vs/base/common/uri';
13
import { StringEdit, StringReplacement } from '../../../../util/vs/editor/common/core/edits/stringEdit';
14
import { OffsetRange } from '../../../../util/vs/editor/common/core/ranges/offsetRange';
15
import { IRecordingInformation } from '../../common/observableWorkspaceRecordingReplayer';
16
import { RejectionCollector } from '../../common/rejectionCollector';
17
import { loadJSON, relativeFile } from './fileLoading';
18
import { runRecording } from './runRecording';
19
20
describe('RejectionCollector[visualizable]', () => {
21
test('test1', async () => {
22
const result = await runRecording(
23
await loadJSON<IRecordingInformation>({
24
filePath: relativeFile('recordings/RejectionCollector.test1.w.json'),
25
}),
26
ctx => {
27
const rejs: (boolean | string)[] = [];
28
29
const rejectionCollector = ctx.store.add(new RejectionCollector(ctx.workspace, new TestLogService()));
30
31
ctx.workspace.lastActiveDocument.recomputeInitiallyAndOnChange(ctx.store);
32
33
const getEdit = (doc: IObservableDocument | undefined = undefined) => {
34
if (!doc) {
35
doc = ctx.workspace.lastActiveDocument.get();
36
}
37
if (!doc) {
38
return undefined;
39
}
40
41
const edit = createEdit(
42
doc.value.get().value,
43
`items.push([[oldItem ? item.withIdentity(oldItem.identity) : item]]);`,
44
`OLDiTEM`,
45
);
46
if (!edit) {
47
return undefined;
48
}
49
50
return { edit, doc };
51
};
52
53
while (!getEdit()) {
54
if (!ctx.step()) {
55
return { rejs };
56
}
57
}
58
const { doc } = getEdit()!;
59
60
ctx.store.add(runOnChange(ctx.workspace.onDidOpenDocumentChange, () => {
61
const e = getEdit(doc);
62
if (e) {
63
rejs.push(rejectionCollector.isRejected(doc.id, e.edit));
64
} else {
65
rejs.push('edit not found');
66
}
67
}));
68
69
ctx.stepSkipNonContentChanges();
70
71
const { edit } = getEdit()!;
72
rejectionCollector.reject(doc.id, edit);
73
74
ctx.finishReplay();
75
76
return { rejs };
77
}
78
);
79
80
expect(result.rejs).toMatchInlineSnapshot(`
81
[
82
false,
83
true,
84
true,
85
true,
86
true,
87
true,
88
true,
89
true,
90
true,
91
true,
92
true,
93
true,
94
true,
95
true,
96
true,
97
true,
98
true,
99
true,
100
true,
101
true,
102
true,
103
true,
104
true,
105
true,
106
true,
107
true,
108
true,
109
true,
110
true,
111
true,
112
true,
113
true,
114
true,
115
true,
116
true,
117
"edit not found",
118
]
119
`);
120
});
121
test.skip('overlapping', () => {
122
const observableWorkspace = new MutableObservableWorkspace();
123
const doc = observableWorkspace.addDocument({
124
id: DocumentId.create(URI.file('/test/test.ts').toString()),
125
initialValue: outdent`
126
class Point {
127
constructor(
128
private readonly x: number,
129
private readonly y: number,
130
) { }
131
getDistance() {
132
return Math.sqrt(this.x ** 2 + this.y ** 2);
133
}
134
}
135
`.trim()
136
});
137
138
const rejectionCollector = new RejectionCollector(observableWorkspace, new TestLogService());
139
try {
140
const edit1 = StringReplacement.replace(OffsetRange.fromTo(96, 107), 'fo');
141
expect(rejectionCollector.isRejected(doc.id, edit1)).toBe(false);
142
const rej1 = StringReplacement.replace(OffsetRange.fromTo(96, 107), 'foobar');
143
rejectionCollector.reject(doc.id, rej1);
144
expect(rejectionCollector.isRejected(doc.id, rej1)).toBe(true);
145
146
expect(rejectionCollector.isRejected(doc.id, edit1)).toBe(false);
147
doc.applyEdit(StringEdit.single(edit1));
148
expect(rejectionCollector.isRejected(doc.id, StringReplacement.replace(OffsetRange.fromTo(98, 98), 'obar'))).toBe(true);
149
150
const edit2 = StringReplacement.replace(OffsetRange.fromTo(98, 98), 'ob');
151
expect(rejectionCollector.isRejected(doc.id, edit2)).toBe(false);
152
doc.applyEdit(StringEdit.single(edit2));
153
expect(rejectionCollector.isRejected(doc.id, StringReplacement.replace(OffsetRange.fromTo(100, 100), 'ar'))).toBe(true);
154
155
const edit3 = StringReplacement.replace(OffsetRange.fromTo(100, 100), 'A');
156
expect(rejectionCollector.isRejected(doc.id, edit3)).toBe(false);
157
doc.applyEdit(StringEdit.single(edit3));
158
// now evicted
159
expect(rejectionCollector.isRejected(doc.id, StringReplacement.replace(OffsetRange.fromTo(101, 101), 'r'))).toBe(false);
160
} finally {
161
rejectionCollector.dispose();
162
}
163
});
164
});
165
166
167
/**
168
* Match is context[[valueToReplace]]context
169
*/
170
function createEdit(base: string, match: string, newValue: string): StringReplacement | undefined {
171
let cleanedMatch: string;
172
const idxStart = match.indexOf('[[');
173
const idxEnd = match.indexOf(']]') - 2;
174
175
let range: OffsetRange;
176
if (idxStart === -1 || idxEnd === -3) {
177
range = new OffsetRange(0, match.length);
178
cleanedMatch = match;
179
} else {
180
range = new OffsetRange(idxStart, idxEnd);
181
cleanedMatch = match.replace('[[', '').replace(']]', '');
182
}
183
184
const idx = base.indexOf(cleanedMatch);
185
if (idx === -1) {
186
return undefined;
187
}
188
189
const r = range.delta(idx);
190
return StringReplacement.replace(r, newValue);
191
}
192
193