blob: 6287f7a388cb9596d387bcb38682826fd81708f5 [file] [log] [blame]
/*---------------------------------------------------------
* Copyright 2020 The Go Authors. All rights reserved.
* Licensed under the MIT License. See LICENSE in the project root for license information.
*--------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import fs = require('fs-extra');
import os = require('os');
import path = require('path');
import sinon = require('sinon');
import vscode = require('vscode');
import { getTestFlags, goTest } from '../../src/testUtils';
import { rmdirRecursive } from '../../src/util';
suite('Test Go Test', function () {
this.timeout(10000);
const sourcePath = path.join(__dirname, '..', '..', '..', 'test', 'fixtures', 'goTestTest');
let tmpGopath: string;
let repoPath: string;
let previousEnv: any;
setup(() => {
previousEnv = Object.assign({}, process.env);
});
teardown(async () => {
process.env = previousEnv;
rmdirRecursive(tmpGopath);
});
function setupRepo(modulesMode: boolean) {
tmpGopath = fs.mkdtempSync(path.join(os.tmpdir(), 'go-test-test'));
fs.mkdirSync(path.join(tmpGopath, 'src'));
repoPath = path.join(tmpGopath, 'src', 'goTestTest');
fs.copySync(sourcePath, repoPath, {
recursive: true,
filter: (src: string): boolean => {
if (modulesMode) {
return true;
}
return path.basename(src) !== 'go.mod'; // skip go.mod file.
},
});
process.env.GOPATH = tmpGopath;
}
async function runTest(
input: { isMod: boolean, includeSubDirectories: boolean, testFlags?: string[] },
wantFiles: string[]) {
fs.copySync(sourcePath, repoPath, { recursive: true });
const config = Object.create(vscode.workspace.getConfiguration('go'));
const outputChannel = new FakeOutputChannel();
const testConfig = {
goConfig: config,
outputChannel,
dir: repoPath,
flags: input.testFlags ? input.testFlags : getTestFlags(config),
isMod: input.isMod,
includeSubDirectories: input.includeSubDirectories,
};
try {
const result = await goTest(testConfig);
assert.equal(result, false); // we expect tests to fail.
} catch (e) {
console.log('exception: ${e}');
}
const testOutput = outputChannel.toString();
for (const want of wantFiles) {
assert.ok(testOutput.includes(want), `\nFully resolved file path "${want}" not found in \n${testOutput}`);
}
}
test('resolves file names in logs (modules)', async () => {
setupRepo(true);
await runTest(
{ isMod: true, includeSubDirectories: true },
[path.join(repoPath, 'a_test.go'), path.join(repoPath, 'b', 'b_test.go')]);
await runTest(
{ isMod: true, includeSubDirectories: false },
[path.join(repoPath, 'a_test.go')]);
await runTest(
{ isMod: true, includeSubDirectories: true, testFlags: ['-v'] },
[path.join(repoPath, 'a_test.go'), path.join(repoPath, 'b', 'b_test.go')]);
await runTest(
{ isMod: true, includeSubDirectories: false, testFlags: ['-v'] },
[path.join(repoPath, 'a_test.go')]);
});
test('resolves file names in logs (GOPATH)', async () => {
setupRepo(true);
await runTest(
{ isMod: true, includeSubDirectories: true },
[path.join(repoPath, 'a_test.go'), path.join(repoPath, 'b', 'b_test.go')]);
await runTest(
{ isMod: true, includeSubDirectories: false },
[path.join(repoPath, 'a_test.go')]);
await runTest(
{ isMod: true, includeSubDirectories: true, testFlags: ['-v'] },
[path.join(repoPath, 'a_test.go'), path.join(repoPath, 'b', 'b_test.go')]);
await runTest(
{ isMod: true, includeSubDirectories: false, testFlags: ['-v'] },
[path.join(repoPath, 'a_test.go')]);
});
});
// FakeOutputChannel is a fake output channel used to buffer
// the output of the tested language client in an in-memory
// string array until cleared.
class FakeOutputChannel implements vscode.OutputChannel {
public name = 'FakeOutputChannel';
public show = sinon.fake(); // no-empty
public hide = sinon.fake(); // no-empty
public dispose = sinon.fake(); // no-empty
private buf = [] as string[];
public append = (v: string) => this.enqueue(v);
public appendLine = (v: string) => this.enqueue(v);
public clear = () => { this.buf = []; };
public toString = () => {
return this.buf.join('\n');
}
private enqueue = (v: string) => {
if (this.buf.length > 1024) { this.buf.shift(); }
this.buf.push(v.trim());
}
}