diff --git a/.vscodeignore b/.vscodeignore index c16cc91d3..b06755b2f 100644 --- a/.vscodeignore +++ b/.vscodeignore @@ -1,8 +1,13 @@ +.github .vscode +.vscode-test .gitignore +.hashibot.hcl src/ +out/*.test.* out/test/ .eslintignore .eslintrc.js tsconfig.json -lsp/ \ No newline at end of file +lsp/ +testfixture/ \ No newline at end of file diff --git a/src/extension.ts b/src/extension.ts index 5421d87a9..75c524594 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -12,7 +12,7 @@ import { runCommand } from './terraformCommand'; const clients: Map = new Map(); let extensionPath: string; -export async function activate(context: vscode.ExtensionContext): Promise { +export async function activate(context: vscode.ExtensionContext): Promise { extensionPath = context.extensionPath; const commandOutput = vscode.window.createOutputChannel('Terraform'); // get rid of pre-2.0.0 settings @@ -81,8 +81,11 @@ export async function activate(context: vscode.ExtensionContext): Promise ); if (enabled()) { - return vscode.commands.executeCommand('terraform.enableLanguageServer'); + await vscode.commands.executeCommand('terraform.enableLanguageServer'); } + + // export public API + return { pathToBinary }; } export function deactivate(): Promise { diff --git a/src/test/helper.ts b/src/test/helper.ts index 9190715aa..e7c3a2a3c 100644 --- a/src/test/helper.ts +++ b/src/test/helper.ts @@ -6,13 +6,9 @@ export let editor: vscode.TextEditor; export let documentEol: string; export let platformEol: string; -export async function activate(docUri: vscode.Uri): Promise { - // The extensionId is `publisher.name` from package.json - const ext = vscode.extensions.getExtension('hashicorp.terraform'); - await ext.activate(); - // allow server to initialize - await sleep(5000); +export async function open(docUri: vscode.Uri): Promise { try { + await activated(); doc = await vscode.workspace.openTextDocument(docUri); editor = await vscode.window.showTextDocument(doc); } catch (e) { @@ -21,6 +17,30 @@ export async function activate(docUri: vscode.Uri): Promise { } } +let _activatedPromise: Promise +async function activated() { + if (!_activatedPromise) { + try { + // The extensionId is `publisher.name` from package.json + const ext = vscode.extensions.getExtension('hashicorp.terraform'); + if (!ext.isActive) { + console.log('Activating hashicorp.terraform extension'); + await ext.activate(); + } else { + console.log('hashicorp.terraform is already active'); + } + // make sure language server download is complete + await ext.exports.pathToBinary(); + // TODO: implement proper synchronization/status check in LS + // give server(s) some time to startup + _activatedPromise = sleep(3000); + } catch (err) { + _activatedPromise = Promise.reject(err); + } + } + return _activatedPromise; +} + export async function sleep(ms: number): Promise { return new Promise(resolve => setTimeout(resolve, ms)); } diff --git a/src/test/index.ts b/src/test/index.ts index 2d32cc5d7..1736e1f2e 100644 --- a/src/test/index.ts +++ b/src/test/index.ts @@ -2,12 +2,13 @@ import * as path from 'path'; import * as Mocha from 'mocha'; import * as glob from 'glob'; -export function run(): Promise { +export async function run(): Promise { // Create the mocha test const mocha = new Mocha({ ui: 'tdd', color: true }); + // integration tests require long activation time mocha.timeout(100000); const testsRoot = path.resolve(__dirname, '..'); diff --git a/src/test/runTest.ts b/src/test/runTest.ts index 3ada24bb6..b2292d297 100644 --- a/src/test/runTest.ts +++ b/src/test/runTest.ts @@ -1,10 +1,23 @@ import * as path from 'path'; import { runTests } from 'vscode-test'; +import * as del from 'del'; +import { exec } from '../utils'; + +async function terraformInit() { + const cwd = process.cwd(); + process.chdir('testFixture'); + const { stdout } = await exec('terraform init -no-color'); + console.log(stdout); + process.chdir(cwd); +} async function main(): Promise { try { + // initialize terraform before vscode opens + await terraformInit(); // The folder containing the Extension Manifest package.json // Passed to `--extensionDevelopmentPath` + // this is also the process working dir, even if vscode opens another folder const extensionDevelopmentPath = path.resolve(__dirname, '../../'); // The path to the extension test runner script @@ -12,11 +25,15 @@ async function main(): Promise { const extensionTestsPath = path.resolve(__dirname, './index'); // Download VS Code, unzip it and run the integration test - await runTests({ extensionDevelopmentPath, extensionTestsPath }); + // start in the fixtures folder to prevent the language server from walking all the + // project root folders, like node_modules + await runTests({ extensionDevelopmentPath, extensionTestsPath, launchArgs: ['testFixture'] }); } catch (err) { console.error(err); console.error('Failed to run tests'); - process.exit(1); + process.exitCode = 1; + } finally { + await del('testFixture/.terraform', { force: true }); } } diff --git a/src/test/setup.test.ts b/src/test/setup.test.ts deleted file mode 100644 index 41f7c5b82..000000000 --- a/src/test/setup.test.ts +++ /dev/null @@ -1,16 +0,0 @@ -import * as Mocha from 'mocha'; -import { exec } from '../utils'; - -Mocha.before(async () => { - try { - const cwd = process.cwd(); - process.chdir('testFixture'); - const {stdout, stderr} = await exec('terraform init -no-color'); - console.log(stdout); - console.log(stderr); - process.chdir(cwd); - } catch (err) { - console.error(err); - throw err; - } -}); diff --git a/src/test/symbols.test.ts b/src/test/symbols.test.ts index db163caa6..bdd18c93f 100644 --- a/src/test/symbols.test.ts +++ b/src/test/symbols.test.ts @@ -1,6 +1,6 @@ import * as vscode from 'vscode'; import * as assert from 'assert'; -import { getDocUri, activate } from './helper'; +import { getDocUri, open } from './helper'; suite('document symbols', () => { const docUri = getDocUri('sample.tf'); @@ -11,7 +11,7 @@ suite('document symbols', () => { }); async function testSymbols(docUri: vscode.Uri, symbolNames: string[]) { - await activate(docUri); + await open(docUri); // Executing the command `vscode.executeDocumentSymbolProvider` to simulate triggering completion const symbols = (await vscode.commands.executeCommand('vscode.executeDocumentSymbolProvider', docUri)) as vscode.SymbolInformation[];