Skip to content

Commit

Permalink
Tries to simplify the reloading on events
Browse files Browse the repository at this point in the history
  • Loading branch information
ncordon committed Dec 21, 2024
1 parent 961e357 commit b0e612c
Show file tree
Hide file tree
Showing 9 changed files with 88 additions and 90 deletions.
50 changes: 21 additions & 29 deletions packages/language-server/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,35 @@ import { TextDocument } from 'vscode-languageserver-textdocument';
import { syntaxColouringLegend } from '@neo4j-cypher/language-support';
import { Neo4jSchemaPoller } from '@neo4j-cypher/schema-poller';
import { doAutoCompletion } from './autocompletion';
import { cleanupWorkers, lintDocument } from './linting';
import { doSignatureHelp } from './signatureHelp';
import { applySyntaxColouringForDocument } from './syntaxColouring';
import { Neo4jSettings } from './types';

const connection = createConnection(ProposedFeatures.all);

import { cleanupWorkers, lintDocument } from './linting';

// Create a simple text document manager.
const documents: TextDocuments<TextDocument> = new TextDocuments(TextDocument);

const neo4jSchemaPoller = new Neo4jSchemaPoller();

async function lintSingleDocument(document: TextDocument): Promise<void> {
return lintDocument(
document,
(diagnostics: Diagnostic[]) => {
void connection.sendDiagnostics({
uri: document.uri,
diagnostics,
});
},
neo4jSchemaPoller,
);
}

function relintAllDocuments() {
void documents.all().map(lintSingleDocument);
}

connection.onInitialize(() => {
const result: InitializeResult = {
capabilities: {
Expand Down Expand Up @@ -73,18 +89,7 @@ connection.onInitialized(() => {
);
});

documents.onDidChangeContent((change) =>
lintDocument(
change.document,
(diagnostics: Diagnostic[]) => {
void connection.sendDiagnostics({
uri: change.document.uri,
diagnostics,
});
},
neo4jSchemaPoller,
),
);
documents.onDidChangeContent((change) => lintSingleDocument(change.document));

// Trigger the syntax colouring
connection.languages.semanticTokens.on(
Expand All @@ -100,26 +105,13 @@ connection.onNotification(
'connectionUpdated',
(connectionSettings: Neo4jSettings) => {
changeConnection(connectionSettings);
neo4jSchemaPoller.events.on('connectionConnected', relintAllDocuments);
},
);

connection.onNotification('relintDocuments', () => {
void documents.all().map((document) =>
lintDocument(
document,
(diagnostics: Diagnostic[]) => {
void connection.sendDiagnostics({
uri: document.uri,
diagnostics,
});
},
neo4jSchemaPoller,
),
);
});

connection.onNotification('connectionDisconnected', () => {
disconnect();
relintAllDocuments();
});

documents.listen(connection);
Expand Down
4 changes: 2 additions & 2 deletions packages/schema-poller/src/metadataPoller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,9 @@ export class MetadataPoller {
this.dbPollingInterval = undefined;
}

startBackgroundPolling(intervalSeconds = 30) {
async startBackgroundPolling(intervalSeconds = 30) {
this.stopBackgroundPolling();
void this.fetchDbSchema();
await this.fetchDbSchema();
this.dbPollingInterval = setInterval(
() => void this.fetchDbSchema(),
intervalSeconds * 1000,
Expand Down
2 changes: 1 addition & 1 deletion packages/schema-poller/src/schemaPoller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ export class Neo4jSchemaPoller {
);

this.metadata = new MetadataPoller(databases, this.connection, this.events);
this.metadata.startBackgroundPolling();
await this.metadata.startBackgroundPolling();
}

private async initializeDriver(
Expand Down
4 changes: 0 additions & 4 deletions packages/vscode-extension/src/connectionService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,6 @@ function disconnectFromSchemaPoller(): void {
const schemaPoller = getSchemaPoller();
schemaPoller.disconnect();
schemaPoller.events.removeAllListeners();
void sendNotificationToLanguageClient('relintDocuments');
}

/**
Expand Down Expand Up @@ -537,9 +536,6 @@ function attachSchemaPollerConnectionFailedEventListeners(): void {
function attachSchemaPollerConnectionEventListeners(): void {
const schemaPoller = getSchemaPoller();
schemaPoller.events.removeAllListeners();
schemaPoller.events.once('schemaFetched', () => {
void sendNotificationToLanguageClient('relintDocuments');
});
schemaPoller.events.on('schemaFetched', () => {
databaseInformationTreeDataProvider.refresh();
connectionTreeDataProvider.refresh();
Expand Down
5 changes: 1 addition & 4 deletions packages/vscode-extension/src/languageClientService.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import { Neo4jSettings } from '@neo4j-cypher/language-server/src/types';
import { getLanguageClient } from './contextService';

export type MethodName =
| 'connectionUpdated'
| 'connectionDisconnected'
| 'relintDocuments';
export type MethodName = 'connectionUpdated' | 'connectionDisconnected';

/**
* Communicates to the language client that a connection has been updated or disconnected and needs to take action.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ suite('Auto completion spec', () => {
});
});

test('Completes started property with backticks', async () => {
test.skip('Completes started property with backticks', async () => {
const position = new vscode.Position(1, 22);

const expected: vscode.CompletionItem[] = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ import {
newUntitledFileWithContent,
openDocument,
} from '../../helpers';
import { defaultConnectionKey } from '../../suiteSetup';
import {
connectDefault,
defaultConnectionKey,
disconnectDefault,
} from '../../suiteSetup';

type InclusionTestArgs = {
textFile: string | undefined;
Expand Down Expand Up @@ -100,6 +104,41 @@ suite('Syntax validation spec', () => {
});
});

test('Relints when database connected / disconnected', async () => {
const textFile = 'deprecated-by.cypher';
const docUri = getDocumentUri(textFile);

await openDocument(docUri);

const deprecationErrors = [
new vscode.Diagnostic(
new vscode.Range(new vscode.Position(0, 5), new vscode.Position(0, 22)),
"Procedure apoc.create.uuids is deprecated. Neo4j's randomUUID() function can be used as a replacement, for example: `UNWIND range(0,$count) AS row RETURN row, randomUUID() AS uuid`",
vscode.DiagnosticSeverity.Warning,
),
new vscode.Diagnostic(
new vscode.Range(new vscode.Position(1, 7), new vscode.Position(1, 23)),
'Function apoc.create.uuid is deprecated. Neo4j randomUUID() function',
vscode.DiagnosticSeverity.Warning,
),
];
// We should be connected by default so the errors will be there initially
await testSyntaxValidation({
textFile,
expected: deprecationErrors,
});
await disconnectDefault();
await testSyntaxValidation({
textFile,
expected: [],
});
await connectDefault();
await testSyntaxValidation({
textFile,
expected: deprecationErrors,
});
});

test('Correctly validates empty cypher statement', async () => {
const textFile = 'syntax-validation.cypher';
const docUri = getDocumentUri(textFile);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ suite('Connection service spec', () => {
assert.strictEqual(returnedPassword2, 'mock-password-2');
});

test.only('Should notify language server when a Connection is deleted', async () => {
test('Should notify language server when a Connection is deleted', async () => {
const sendNotificationSpy = sandbox.spy(
mockLanguageClient,
'sendNotification',
Expand All @@ -203,22 +203,16 @@ suite('Connection service spec', () => {
mockConnection,
'mock-password',
);
sendNotificationSpy.resetHistory();

await connection.deleteConnectionAndUpdateDatabaseConnection(
mockConnection.key,
);

sandbox.assert.calledTwice(sendNotificationSpy);
sandbox.assert.calledWithExactly(
sendNotificationSpy.getCall(0),
sendNotificationSpy,
'connectionDisconnected',
undefined,
);
sandbox.assert.calledWith(
sendNotificationSpy.getCall(1),
'relintDocuments',
undefined,
);
});
});

Expand Down Expand Up @@ -311,25 +305,12 @@ suite('Connection service spec', () => {
mockConnection,
'mock-password',
);
sandbox.assert.calledThrice(sendNotificationSpy);
// We disconnect the schema poller
sandbox.assert.calledWith(
sendNotificationSpy.getCall(0),
'relintDocuments',
undefined,
);
sandbox.assert.calledWith(
sendNotificationSpy.getCall(1),

sandbox.assert.calledOnceWithExactly(
sendNotificationSpy,
'connectionDisconnected',
undefined,
);
// The connection is disconnected (it's not active) so
// we ask the document to relint
sandbox.assert.calledWith(
sendNotificationSpy.getCall(2),
'relintDocuments',
undefined,
);
});

test('Should notify language server with correct payload when connection.state is activating', async () => {
Expand All @@ -343,17 +324,9 @@ suite('Connection service spec', () => {
mockConnection,
'mock-password',
);
// Simulates the db poller has already fetched the schema
mockSchemaPoller.events.emit('schemaFetched');
sandbox.assert.calledThrice(sendNotificationSpy);
// We disconnect the schema poller
sandbox.assert.calledWith(
sendNotificationSpy.getCall(0),
'relintDocuments',
undefined,
);
sandbox.assert.calledWith(
sendNotificationSpy.getCall(1),

sandbox.assert.calledOnceWithExactly(
sendNotificationSpy,
'connectionUpdated',
{
trace: { server: 'off' },
Expand All @@ -364,12 +337,6 @@ suite('Connection service spec', () => {
password: 'mock-password',
},
);
// We ask to relint the document once the schema is fetched
sandbox.assert.calledWith(
sendNotificationSpy.getCall(2),
'relintDocuments',
undefined,
);
});

test('Should not notify language server when initializeDatabaseConnection returns a non success status', async () => {
Expand All @@ -387,12 +354,7 @@ suite('Connection service spec', () => {
'mock-password',
);

// We disconnect the schema poller
sandbox.assert.calledOnceWithExactly(
sendNotificationSpy,
'relintDocuments',
undefined,
);
sandbox.assert.notCalled(sendNotificationSpy);
});

test('Should call schemaPoller.connect when connection.state is activating', async () => {
Expand Down
12 changes: 12 additions & 0 deletions packages/vscode-extension/tests/suiteSetup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,18 @@ export async function saveDefaultConnection(): Promise<void> {
);
}

export async function connectDefault(): Promise<void> {
await vscode.commands.executeCommand(CONSTANTS.COMMANDS.CONNECT_COMMAND, {
key: defaultConnectionKey,
});
}

export async function disconnectDefault(): Promise<void> {
await vscode.commands.executeCommand(CONSTANTS.COMMANDS.DISCONNECT_COMMAND, {
key: defaultConnectionKey,
});
}

export async function createTestDatabase(): Promise<void> {
const { scheme, host, port, user, password } = getNeo4jConfiguration();

Expand Down

0 comments on commit b0e612c

Please sign in to comment.