Skip to content

Commit

Permalink
Add diagnostic manager enablement change tests (#152392)
Browse files Browse the repository at this point in the history
* 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`
  • Loading branch information
mjbvz committed Jun 16, 2022
1 parent 9740164 commit afe316c
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -231,28 +231,23 @@ 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();
}

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 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 addWorkItem(promise: Promise<any>): Promise<any> {
this.pending.add(promise);
promise.finally(() => this.pending.delete(promise));
return promise;
}

public async waitAllPending(): Promise<void> {
public async waitPendingWork(): Promise<void> {
await Promise.all([...this.pending.values()]);
}
}
Expand All @@ -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);
}

Expand Down Expand Up @@ -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())
);
}
}

Expand Down
86 changes: 70 additions & 16 deletions extensions/markdown-language-features/src/test/diagnostic.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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', () => {
Expand Down Expand Up @@ -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(
Expand All @@ -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),
]);

Expand All @@ -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),
]);

Expand All @@ -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),
]);
});
Expand Down

0 comments on commit afe316c

Please sign in to comment.