Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce E2E tests #22

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 26 additions & 12 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,24 +1,38 @@
language: node_js
node_js:
- "lts/*"
os:
- linux
- osx
node_js:
- lts/*
dist: focal

stages:
- name: build
- name: release
if: tag IS present
install:
- |
set -e
if [ $TRAVIS_OS_NAME == "linux" ]; then
export DISPLAY=':99.0'
/usr/bin/Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
wget https://github.com/dhall-lang/dhall-haskell/releases/download/1.37.1/dhall-lsp-server-1.0.12-x86_64-linux.tar.bz2 -O /tmp/dhall-lsp-server.tar.bz2
else
wget https://github.com/dhall-lang/dhall-haskell/releases/download/1.37.1/dhall-lsp-server-1.0.12-x86_64-macos.tar.bz2 -O /tmp/dhall-lsp-server.tar.bz2
fi
mkdir /tmp/dhall
tar --extract --bzip2 --file /tmp/dhall-lsp-server.tar.bz2 -C /tmp/dhall
export PATH=$PATH:/tmp/dhall/bin
script:
- |
set -e
npm i
npm test

jobs:
include:
- stage: build
script:
# test that the extension builds correctly
- npm run compile
- stage: release
os: linux
if: tag IS present
before_install:
- npm i -g vsce
script:
# fail fast
- set -e
# publish the extension to the Marketplace
- vsce publish -p $VS_MARKETPLACE_TOKEN

2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"outFiles": [
"${workspaceFolder}/out/test/**/*.js"
],
"preLaunchTask": "npm: watch"
"preLaunchTask": "npm: compile"
}
]
}
104 changes: 55 additions & 49 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,23 @@ export async function activate(context: vscode.ExtensionContext) {

const userDefinedExecutablePath = config.executable;

let executablePath = (userDefinedExecutablePath === '') ? 'dhall-lsp-server' : userDefinedExecutablePath;
let executablePath = (userDefinedExecutablePath === '') ? 'dhall-lsp-server' : userDefinedExecutablePath;

const executableStatus = await obtainExecutableStatus(executablePath);

if (executableStatus !== 'available') {
if (executableStatus === 'timedout') {
console.error("The server process has timed out.")
window.showErrorMessage('The server process has timed out.');
} else {
if (userDefinedExecutablePath === '') {
window.showErrorMessage('No `dhall-lsp-server` executable is available in the VSCode PATH.\n' +
'You might need to install [Dhall LSP server](https://github.com/PanAeon/dhall-lsp-server).\n' +
'Also you might want to set an absolute path to the `dhall-lsp-server` executable ' +
'in the plugin settings.');
console.error("No `dhall-lsp-server` executable is available in the VSCode PATH.")
window.showErrorMessage('No `dhall-lsp-server` executable is available in the VSCode PATH.\n' +
'You might need to install [Dhall LSP server](https://github.com/PanAeon/dhall-lsp-server).\n' +
'Also you might want to set an absolute path to the `dhall-lsp-server` executable ' +
'in the plugin settings.');
} else {
console.error('The server executable path is invalid: [' + executablePath + "]")
window.showErrorMessage('The server executable path is invalid: [' + executablePath + "]");
}
}
Expand All @@ -57,21 +60,22 @@ export async function activate(context: vscode.ExtensionContext) {
// TODO: properly parse extra arguments!! UNIT TEST !!
const logFile: string = config.logFile;

const logFileOpt : string[] = logFile.trim() === '' ? [] : ['--log=' + logFile];
const logFileOpt: string[] = logFile.trim() === '' ? [] : ['--log=' + logFile];



// let serverCommand = '~/.local/bin/dhall-lsp-server'; // context.asAbsolutePath(path.parse());
// let serverCommand = context.asAbsolutePath(path.join('/home/vitalii/.local/bin/dhall-lsp-server'));

let runArgs : string[] = [...logFileOpt];
let debugArgs : string[] = [...logFileOpt];
let runArgs: string[] = [...logFileOpt];
let debugArgs: string[] = [...logFileOpt];

let serverOptions: ServerOptions = {
run: { command: executablePath,
transport: TransportKind.stdio,
args: runArgs
},
run: {
command: executablePath,
transport: TransportKind.stdio,
args: runArgs
},
debug: {
command: executablePath,
transport: TransportKind.stdio,
Expand All @@ -86,7 +90,7 @@ export async function activate(context: vscode.ExtensionContext) {
// Notify the server about file changes to '.clientrc files contained in the workspace
fileEvents: vscode.workspace.createFileSystemWatcher('**/.clientrc')
},
initializationOptions: {
initializationOptions: {
'vscode-dhall-lsp-server': workspace.getConfiguration("vscode-dhall-lsp-server")
},
outputChannel: outputChannel
Expand All @@ -105,44 +109,46 @@ export async function activate(context: vscode.ExtensionContext) {
// activate linting command
context.subscriptions.push(vscode.commands.registerTextEditorCommand("dhall.lint", (editor, edit) => {
const cmd = {
command : "dhall.server.lint",
arguments: [ editor.document.uri.toString() ] };
command: "dhall.server.lint",
arguments: [editor.document.uri.toString()]
};
client.sendRequest('workspace/executeCommand', cmd);
}));

// activate annotateLet command
// activate annotateLet command
context.subscriptions.push(vscode.commands.registerTextEditorCommand("dhall.annotateLet", (editor, edit) => {
const cmd = {
command : "dhall.server.annotateLet",
arguments: [
{
position: editor.selection.active,
textDocument: {uri: editor.document.uri.toString()}
}
]
}; // editor.document.uri.toString()
command: "dhall.server.annotateLet",
arguments: [
{
position: editor.selection.active,
textDocument: { uri: editor.document.uri.toString() }
}
]
}; // editor.document.uri.toString()
client.sendRequest('workspace/executeCommand', cmd);
}));

// activate freezeImport command
// activate freezeImport command
context.subscriptions.push(vscode.commands.registerTextEditorCommand("dhall.freezeImport", (editor, edit) => {
const cmd = {
command : "dhall.server.freezeImport",
arguments: [
{
position: editor.selection.active,
textDocument: {uri: editor.document.uri.toString()}
}
]
}; // editor.document.uri.toString()
command: "dhall.server.freezeImport",
arguments: [
{
position: editor.selection.active,
textDocument: { uri: editor.document.uri.toString() }
}
]
}; // editor.document.uri.toString()
client.sendRequest('workspace/executeCommand', cmd);
}));

// activate freezeAllImports command
// activate freezeAllImports command
context.subscriptions.push(vscode.commands.registerTextEditorCommand("dhall.freezeAllImports", (editor, edit) => {
const cmd = {
command : "dhall.server.freezeAllImports",
arguments: [ editor.document.uri.toString() ] };
command: "dhall.server.freezeAllImports",
arguments: [editor.document.uri.toString()]
};
client.sendRequest('workspace/executeCommand', cmd);
}));

Expand All @@ -168,19 +174,19 @@ export async function activate(context: vscode.ExtensionContext) {
// TODO: maybe use promisify-child-process ??

// TODO: should also handle case when executable has returned error code on startup
async function obtainExecutableStatus(executableLocation: string) : Promise<string> {
const execPromise = util.promisify(child_process.execFile)
(executableLocation, ['version'], { timeout: 2000, windowsHide: true })
.then(() => 'available').catch((error) => {
return 'missing';
});
const timeoutPromise : Promise<string> = new Promise((resolve, reject) => {
let timer = setTimeout(() => {
clearTimeout(timer);
resolve('timedout');
}, 1000);
});
return Promise.race([execPromise, timeoutPromise]);
async function obtainExecutableStatus(executableLocation: string): Promise<string> {
const execPromise = util.promisify(child_process.execFile)
(executableLocation, ['version'], { timeout: 2000, windowsHide: true })
.then(() => 'available').catch((error) => {
return 'missing';
});
const timeoutPromise: Promise<string> = new Promise((resolve, reject) => {
let timer = setTimeout(() => {
clearTimeout(timer);
resolve('timedout');
}, 1000);
});
return Promise.race([execPromise, timeoutPromise]);
}


Expand Down
47 changes: 40 additions & 7 deletions src/test/extension.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,48 @@ import * as assert from 'assert';

// You can import and use all API from the 'vscode' module
// as well as import your extension to test it
// import * as vscode from 'vscode';
import * as vscode from 'vscode';
// import * as myExtension from '../extension';
import { getDocUri, activate } from './helper';

// Defines a Mocha test suite to group tests of similar kind together
suite("Extension Tests", function () {

// Defines a Mocha unit test
test("Something 1", function() {
assert.equal(-1, [1, 2, 3].indexOf(5));
assert.equal(-1, [1, 2, 3].indexOf(0));
});
});
// Defines a Mocha unit test
test("Should autocomplete functions", async function () {

this.timeout(10_000);

const docUri = getDocUri('completion.dhall');

await testCompletion(docUri, new vscode.Position(1, 5), {
items: [
{ label: 'aFun', kind: vscode.CompletionItemKind.Property }
]
});

});
});

//From https://github.com/microsoft/vscode-extension-samples/blob/master/lsp-sample/client/src/test/completion.test.ts
async function testCompletion(
docUri: vscode.Uri,
position: vscode.Position,
expectedCompletionList: vscode.CompletionList
) {
await activate(docUri);

// Executing the command `vscode.executeCompletionItemProvider` to simulate triggering completion
const actualCompletionList = (await vscode.commands.executeCommand(
'vscode.executeCompletionItemProvider',
docUri,
position
)) as vscode.CompletionList;

assert.ok(actualCompletionList.items.length >= 2);
expectedCompletionList.items.forEach((expectedItem, i) => {
const actualItem = actualCompletionList.items[i];
assert.equal(actualItem.label, expectedItem.label);
assert.equal(actualItem.kind, expectedItem.kind);
});
}
47 changes: 47 additions & 0 deletions src/test/helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */

import * as vscode from 'vscode';
import * as path from 'path';

export let doc: vscode.TextDocument;
export let editor: vscode.TextEditor;
export let documentEol: string;
export let platformEol: string;

/**
* Activates the vscode.lsp-sample extension
*/
export async function activate(docUri: vscode.Uri) {
// The extensionId is `publisher.name` from package.json
const ext = vscode.extensions.getExtension('panaeon.vscode-dhall-lsp-server')!;
await ext.activate();
try {
doc = await vscode.workspace.openTextDocument(docUri);
editor = await vscode.window.showTextDocument(doc);
await sleep(2000); // Wait for server activation
} catch (e) {
console.error(e);
}
}

async function sleep(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
}

export const getDocPath = (p: string) => {
return path.resolve(__dirname, '../../testFixture', p);
};
export const getDocUri = (p: string) => {
return vscode.Uri.file(getDocPath(p));
};

export async function setTestContent(content: string): Promise<boolean> {
const all = new vscode.Range(
doc.positionAt(0),
doc.positionAt(doc.getText().length)
);
return editor.edit(eb => eb.replace(all, content));
}
2 changes: 2 additions & 0 deletions testFixture/completion.dhall
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
let aFun = \(a : Text) -> a
in aF
3 changes: 2 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
},
"exclude": [
"node_modules",
".vscode-test"
".vscode-test",
"testFixture"
]
}