Add diagnostic manager enablement change tests (#152392)

* Add test for MD diagnostic manager config changes

Add a simple test the enabling/disable diagnostics should make the diagnostic manager recompute diagnostics

* Add `.get`
This commit is contained in:
Matt Bierner 2022-06-16 15:53:19 -07:00 committed by GitHub
parent 9740164159
commit afe316c08c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 90 additions and 37 deletions

View file

@ -231,7 +231,7 @@ class LinkDoesNotExistDiagnostic extends vscode.Diagnostic {
}
export abstract class DiagnosticReporter extends Disposable {
private readonly pending = new ResourceMap<Promise<any>>();
private readonly pending = new Set<Promise<any>>();
public clear(): void {
this.pending.clear();
@ -239,20 +239,15 @@ export abstract class DiagnosticReporter extends Disposable {
public abstract set(uri: vscode.Uri, diagnostics: readonly vscode.Diagnostic[]): void;
public delete(uri: vscode.Uri): void {
this.pending.delete(uri);
public abstract delete(uri: vscode.Uri): void;
public addWorkItem(promise: Promise<any>): Promise<any> {
this.pending.add(promise);
promise.finally(() => this.pending.delete(promise));
return promise;
}
public signalTriggered(uri: vscode.Uri, recompute: Promise<any>): void {
this.pending.set(uri, recompute);
recompute.finally(() => {
if (this.pending.get(uri) === recompute) {
this.pending.delete(uri);
}
});
}
public async waitAllPending(): Promise<void> {
public async waitPendingWork(): Promise<void> {
await Promise.all([...this.pending.values()]);
}
}
@ -276,8 +271,7 @@ export class DiagnosticCollectionReporter extends DiagnosticReporter {
this.collection.set(uri, tabs.has(uri) ? diagnostics : []);
}
public override delete(uri: vscode.Uri): void {
super.delete(uri);
public delete(uri: vscode.Uri): void {
this.collection.delete(uri);
}
@ -391,21 +385,26 @@ export class DiagnosticManager extends Disposable {
}));
}
private async rebuild() {
private rebuild(): Promise<void> {
this.reporter.clear();
this.pendingDiagnostics.clear();
this.inFlightDiagnostics.clear();
for (const doc of await this.workspaceContents.getAllMarkdownDocuments()) {
this.triggerDiagnostics(doc.uri);
}
return this.reporter.addWorkItem(
(async () => {
const allDocs = await this.workspaceContents.getAllMarkdownDocuments();
await Promise.all(Array.from(allDocs, doc => this.triggerDiagnostics(doc.uri)));
})()
);
}
private triggerDiagnostics(uri: vscode.Uri) {
private async triggerDiagnostics(uri: vscode.Uri): Promise<void> {
this.inFlightDiagnostics.cancel(uri);
this.pendingDiagnostics.add(uri);
this.reporter.signalTriggered(uri, this.diagnosticDelayer.trigger(() => this.recomputePendingDiagnostics()));
return this.reporter.addWorkItem(
this.diagnosticDelayer.trigger(() => this.recomputePendingDiagnostics())
);
}
}

View file

@ -54,20 +54,27 @@ class MemoryDiagnosticConfiguration implements DiagnosticConfiguration {
private readonly _onDidChange = new vscode.EventEmitter<void>();
public readonly onDidChange = this._onDidChange.event;
constructor(
private readonly _options: Partial<DiagnosticOptions>,
) { }
private _options: Partial<DiagnosticOptions>;
getOptions(_resource: vscode.Uri): DiagnosticOptions {
constructor(options: Partial<DiagnosticOptions>) {
this._options = options;
}
public getOptions(_resource: vscode.Uri): DiagnosticOptions {
return {
...defaultDiagnosticsOptions,
...this._options,
};
}
public update(newOptions: Partial<DiagnosticOptions>) {
this._options = newOptions;
this._onDidChange.fire();
}
}
class MemoryDiagnosticReporter extends DiagnosticReporter {
public readonly diagnostics = new ResourceMap<readonly vscode.Diagnostic[]>();
private readonly diagnostics = new ResourceMap<readonly vscode.Diagnostic[]>();
override dispose(): void {
super.clear();
@ -83,10 +90,13 @@ class MemoryDiagnosticReporter extends DiagnosticReporter {
this.diagnostics.set(uri, diagnostics);
}
override delete(uri: vscode.Uri): void {
super.delete(uri);
delete(uri: vscode.Uri): void {
this.diagnostics.delete(uri);
}
get(uri: vscode.Uri): readonly vscode.Diagnostic[] {
return orderDiagnosticsByRange(this.diagnostics.get(uri) ?? []);
}
}
suite('markdown: Diagnostic Computer', () => {
@ -434,6 +444,50 @@ suite('Markdown: Diagnostics manager', () => {
return manager;
}
test('Changing enable/disable should recompute diagnostics', async () => {
const doc1Uri = workspacePath('doc1.md');
const doc2Uri = workspacePath('doc2.md');
const workspace = new InMemoryWorkspaceMarkdownDocuments([
new InMemoryDocument(doc1Uri, joinLines(
`[text](#no-such-1)`,
)),
new InMemoryDocument(doc2Uri, joinLines(
`[text](#no-such-2)`,
))
]);
const reporter = new MemoryDiagnosticReporter();
const config = new MemoryDiagnosticConfiguration({ enabled: true });
const manager = createDiagnosticsManager(workspace, config, reporter);
await manager.ready;
// Check initial state (Enabled)
await reporter.waitPendingWork();
assertDiagnosticsEqual(reporter.get(doc1Uri), [
new vscode.Range(0, 7, 0, 17),
]);
assertDiagnosticsEqual(reporter.get(doc2Uri), [
new vscode.Range(0, 7, 0, 17),
]);
// Disable
config.update({ enabled: false });
await reporter.waitPendingWork();
assertDiagnosticsEqual(reporter.get(doc1Uri), []);
assertDiagnosticsEqual(reporter.get(doc2Uri), []);
// Enable
config.update({ enabled: true });
await reporter.waitPendingWork();
assertDiagnosticsEqual(reporter.get(doc1Uri), [
new vscode.Range(0, 7, 0, 17),
]);
assertDiagnosticsEqual(reporter.get(doc2Uri), [
new vscode.Range(0, 7, 0, 17),
]);
});
test('Should revalidate linked files when header changes', async () => {
const doc1Uri = workspacePath('doc1.md');
const doc1 = new InMemoryDocument(doc1Uri, joinLines(
@ -454,11 +508,11 @@ suite('Markdown: Diagnostics manager', () => {
await manager.ready;
// Check initial state
await reporter.waitAllPending();
assertDiagnosticsEqual(reporter.diagnostics.get(doc1Uri)!, [
await reporter.waitPendingWork();
assertDiagnosticsEqual(reporter.get(doc1Uri), [
new vscode.Range(0, 7, 0, 15),
]);
assertDiagnosticsEqual(reporter.diagnostics.get(doc2Uri)!, [
assertDiagnosticsEqual(reporter.get(doc2Uri), [
new vscode.Range(2, 7, 2, 17),
]);
@ -468,12 +522,12 @@ suite('Markdown: Diagnostics manager', () => {
`[text](#new-header)`,
`[text](#no-such-2)`,
)));
await reporter.waitAllPending();
assertDiagnosticsEqual(orderDiagnosticsByRange(reporter.diagnostics.get(doc1Uri)!), [
await reporter.waitPendingWork();
assertDiagnosticsEqual(reporter.get(doc1Uri), [
new vscode.Range(0, 7, 0, 15),
new vscode.Range(1, 15, 1, 22),
]);
assertDiagnosticsEqual(reporter.diagnostics.get(doc2Uri)!, [
assertDiagnosticsEqual(reporter.get(doc2Uri), [
new vscode.Range(2, 7, 2, 17),
]);
@ -483,11 +537,11 @@ suite('Markdown: Diagnostics manager', () => {
`[text](#header)`,
`[text](#no-such-2)`,
)));
await reporter.waitAllPending();
assertDiagnosticsEqual(orderDiagnosticsByRange(reporter.diagnostics.get(doc1Uri)!), [
await reporter.waitPendingWork();
assertDiagnosticsEqual(reporter.get(doc1Uri), [
new vscode.Range(0, 7, 0, 15)
]);
assertDiagnosticsEqual(reporter.diagnostics.get(doc2Uri)!, [
assertDiagnosticsEqual(reporter.get(doc2Uri), [
new vscode.Range(2, 7, 2, 17),
]);
});