From 92862cc35e86a28796af075ee1fcf327a558bf3f Mon Sep 17 00:00:00 2001 From: Jason Poon Date: Fri, 1 Jan 2016 22:10:08 -0800 Subject: [PATCH] Tests: Fixes #15 enabling all tests to be run within Travis --- .gitignore | 3 +- .travis.yml | 24 ++++++++---- .vscode/launch.json | 4 +- .vscode/settings.json | 5 ++- .vscodeignore | 1 - appveyor.yml | 8 +--- gulpfile.js | 25 +++--------- package.json | 6 +-- test/mode/modeHandler.test.ts | 5 +++ test/mode/modeInsert.test.ts | 38 +++++++++--------- test/mode/modeNormal.test.ts | 7 +++- test/motion.test.ts | 11 +++--- test/testHelpers.ts | 14 ------- test/testUtils.ts | 74 +++++++++++++++++++++++++++++++++++ test/textEditor.test.ts | 9 ++--- tsconfig.json | 2 +- 16 files changed, 146 insertions(+), 90 deletions(-) delete mode 100644 test/testHelpers.ts create mode 100644 test/testUtils.ts diff --git a/.gitignore b/.gitignore index 6c734a75455..8d9fd9ae832 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ out node_modules -typings -.vscode-test \ No newline at end of file +typings \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 1f41f5b2055..cea90528ffa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,17 +1,27 @@ notifications: - email: false + email: false + +sudo: false language: node_js node_js: - - "4.1.1" + - "0.12" env: - - TSD_GITHUB_TOKEN=8742b29e67faa29aa25564ff7317b50fd7c1327d + - TSD_GITHUB_TOKEN=8742b29e67faa29aa25564ff7317b50fd7c1327d -install: - - npm install -g gulp - - npm install +before_install: + - if [ $TRAVIS_OS_NAME == "linux" ]; then + export CXX="g++-4.9" CC="gcc-4.9" DISPLAY=:99.0; + sh -e /etc/init.d/xvfb start; + sleep 3; + fi + +install: + - npm install + - npm run vscode:prepublish script: - - gulp \ No newline at end of file + - gulp + - npm test --silent \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index dde68045d16..08869ac8b5d 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -10,7 +10,7 @@ "args": ["--extensionDevelopmentPath=${workspaceRoot}" ], "stopOnEntry": false, "sourceMaps": true, - "outDir": "out", + "outDir": "out/src", "preLaunchTask": "npm" }, { @@ -21,7 +21,7 @@ "args": ["--extensionDevelopmentPath=${workspaceRoot}", "--extensionTestsPath=${workspaceRoot}/out/test" ], "stopOnEntry": false, "sourceMaps": true, - "outDir": "out", + "outDir": "out/test", "preLaunchTask": "npm" } ] diff --git a/.vscode/settings.json b/.vscode/settings.json index a8089c74057..3f5aa9cf942 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -4,6 +4,7 @@ "out": false // set this to true to hide the "out" folder with the compiled JS files }, "search.exclude": { - "out": true - } + "out": true // set this to false to include "out" folder in search results + }, + "typescript.tsdk": "./node_modules/typescript/lib" // we want to use the TS server from our node_modules folder to control its version } \ No newline at end of file diff --git a/.vscodeignore b/.vscodeignore index b3832b20ee3..f337a245ed1 100644 --- a/.vscodeignore +++ b/.vscodeignore @@ -6,4 +6,3 @@ test/** **/*.map .gitignore tsconfig.json -vsc-extension-quickstart.md diff --git a/appveyor.yml b/appveyor.yml index 172b15daeaa..19d650d0c0f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -4,13 +4,9 @@ environment: clone_depth: 1 install: - - ps: start-filedownload https://az764295.vo.msecnd.net/public/0.10.1-release/VSCode-win32.zip - - ps: 7z.exe x .\VSCode-win32.zip -oC:\VSCode > $null - - ps: install-product node $env:node_js_version - - npm install - npm install -g gulp - - gulp init - - C:\VSCode\bin\code.cmd + - npm install + - npm run vscode:prepublish build: off diff --git a/gulpfile.js b/gulpfile.js index 13d6abf9d61..56870a7b336 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -8,12 +8,7 @@ var gulp = require('gulp'), var paths = { scripts_ts: "src/**/*.ts", - tests_ts: "test/**/*.ts", - tests_js: [ - // test with dependencies on 'vscode' do not run - "out/test/cmd_line/lexer.test.js", - "out/test/cmd_line/scanner.test.js", - ] + tests_ts: "test/**/*.ts" }; gulp.task('tsd', function (callback) { @@ -23,7 +18,7 @@ gulp.task('tsd', function (callback) { }, callback)); }); -gulp.task('trim-whitespace', function() { +gulp.task('fix-whitespace', function() { return gulp.src([paths.scripts_ts, paths.tests_ts], { base: "./" }) .pipe(soften(4)) .pipe(trimlines({ @@ -32,11 +27,11 @@ gulp.task('trim-whitespace', function() { .pipe(gulp.dest('./')); }); -gulp.task('compile', ['trim-whitespace'], shell.task([ +gulp.task('compile', ['fix-whitespace'], shell.task([ 'node ./node_modules/vscode/bin/compile -p ./', ])); -gulp.task('tslint', ['trim-whitespace'], function() { +gulp.task('tslint', ['fix-whitespace'], function() { return gulp.src([paths.scripts_ts, paths.tests_ts]) .pipe(tslint()) .pipe(tslint.report('prose', { @@ -44,15 +39,5 @@ gulp.task('tslint', ['trim-whitespace'], function() { })); }); -gulp.task('test', ['compile'], function () { - return gulp.src(paths.tests_js, { - read: false - }) - .pipe(mocha({ - ui: 'tdd', - reporter: 'spec' - })); -}); - gulp.task('init', ['tsd']); -gulp.task('default', ['trim-whitespace', 'tslint', 'test']); +gulp.task('default', ['fix-whitespace', 'tslint']); diff --git a/package.json b/package.json index f761477889d..366b6b34d5a 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "url": "https://github.com/VSCodeVim/Vim/issues" }, "engines": { - "vscode": "0.10.x" + "vscode": "^0.10.1" }, "categories": [ "Other" @@ -140,7 +140,7 @@ "devDependencies": { "gulp": "^3.9.0", "gulp-mocha": "^2.2.0", - "gulp-soften": "0.0.1", + "gulp-soften": "^0.0.1", "gulp-shell": "^0.5.1", "gulp-tsd": "^0.0.4", "gulp-tslint": "^3.6.0", @@ -149,7 +149,7 @@ "tsd": "^0.6.5", "tslint": "^3.2.1", "typescript": "^1.6.2", - "vscode": "^0.10.7" + "vscode": "0.10.x" }, "dependencies": { "lodash": "^3.10.1" diff --git a/test/mode/modeHandler.test.ts b/test/mode/modeHandler.test.ts index e5503487092..6fba970142d 100644 --- a/test/mode/modeHandler.test.ts +++ b/test/mode/modeHandler.test.ts @@ -1,9 +1,14 @@ import * as assert from 'assert'; +import {setupWorkspace, cleanUpWorkspace} from './../testUtils'; import {ModeName} from '../../src/mode/mode'; import ModeHandler from '../../src/mode/modeHandler'; suite("Mode Handler", () => { + setup(setupWorkspace); + + teardown(cleanUpWorkspace); + test("ctor", () => { var modeHandler = new ModeHandler(); diff --git a/test/mode/modeInsert.test.ts b/test/mode/modeInsert.test.ts index 5ba7247cc93..04eb897b354 100644 --- a/test/mode/modeInsert.test.ts +++ b/test/mode/modeInsert.test.ts @@ -1,26 +1,24 @@ import * as assert from 'assert'; - +import {setupWorkspace, cleanUpWorkspace, assertEqualLines} from './../testUtils'; import ModeInsert from '../../src/mode/modeInsert'; import {ModeName} from '../../src/mode/mode'; import {Motion, MotionMode} from '../../src/motion/motion'; import TextEditor from '../../src/textEditor'; -import TestHelpers from '../testHelpers'; - -let modeInsert: ModeInsert = null; -let motion : Motion = null; suite("Mode Insert", () => { - setup((done) => { - motion = new Motion(MotionMode.Cursor); - modeInsert = new ModeInsert(motion); - TextEditor.delete().then(() => done()); - }); - teardown((done) => { - modeInsert = null; - TextEditor.delete().then(() => done()); + let motion : Motion; + let modeInsert : ModeInsert; + + setup(() => { + return setupWorkspace().then(() => { + motion = new Motion(MotionMode.Cursor); + modeInsert = new ModeInsert(motion); + }); }); + teardown(cleanUpWorkspace); + test("can be activated", () => { let activationKeys = ['i', 'I', 'o', 'O', 'a', 'A']; @@ -33,7 +31,7 @@ suite("Mode Insert", () => { test("can handle key events", () => { return modeInsert.HandleKeyEvent("!") .then(() => { - return TestHelpers.assertEqualLines(["!"]); + return assertEqualLines(["!"]); }); }); @@ -43,7 +41,7 @@ suite("Mode Insert", () => { return modeInsert.HandleActivation("o"); }) .then(() => { - return TestHelpers.assertEqualLines(["text", ""]); + return assertEqualLines(["text", ""]); }); }); @@ -53,7 +51,7 @@ suite("Mode Insert", () => { return modeInsert.HandleActivation("O"); }) .then(() => { - return TestHelpers.assertEqualLines(["", "text"]); + return assertEqualLines(["", "text"]); }); }); @@ -69,7 +67,7 @@ suite("Mode Insert", () => { return modeInsert.HandleKeyEvent("!"); }) .then(() => { - return TestHelpers.assertEqualLines(["text!text"]); + return assertEqualLines(["text!text"]); }); }); @@ -85,7 +83,7 @@ suite("Mode Insert", () => { return modeInsert.HandleKeyEvent("!"); }) .then(() => { - return TestHelpers.assertEqualLines(["!text"]); + return assertEqualLines(["!text"]); }); }); @@ -98,7 +96,7 @@ suite("Mode Insert", () => { }).then(() => { return modeInsert.HandleKeyEvent("!"); }).then(() => { - return TestHelpers.assertEqualLines(["textt!ext"]); + return assertEqualLines(["textt!ext"]); }); }); @@ -111,7 +109,7 @@ suite("Mode Insert", () => { }).then(() => { return modeInsert.HandleKeyEvent("!"); }).then(() => { - return TestHelpers.assertEqualLines(["text!"]); + return assertEqualLines(["text!"]); }); }); }); diff --git a/test/mode/modeNormal.test.ts b/test/mode/modeNormal.test.ts index 7949b1d1adf..2e3f52817d8 100644 --- a/test/mode/modeNormal.test.ts +++ b/test/mode/modeNormal.test.ts @@ -1,10 +1,15 @@ import * as assert from 'assert'; - +import {setupWorkspace, cleanUpWorkspace} from './../testUtils'; import ModeNormal from '../../src/mode/modeNormal'; import {ModeName} from '../../src/mode/mode'; import {Motion} from '../../src/motion/motion'; suite("Mode Normal", () => { + + setup(setupWorkspace); + + teardown(cleanUpWorkspace); + test("can be activated", () => { let activationKeys = ['esc', 'ctrl+[']; let motion = new Motion(); diff --git a/test/motion.test.ts b/test/motion.test.ts index d10e06500dd..94942516cff 100644 --- a/test/motion.test.ts +++ b/test/motion.test.ts @@ -2,6 +2,7 @@ import * as assert from 'assert'; import * as vscode from "vscode"; import TextEditor from './../src/textEditor'; import {Motion, MotionMode} from './../src/motion/motion'; +import {setupWorkspace, cleanUpWorkspace} from './testUtils'; suite("motion", () => { let motionModes = [MotionMode.Caret, MotionMode.Cursor]; @@ -12,13 +13,13 @@ suite("motion", () => { " whose fleece was " ]; - setup(done => { - TextEditor.insert(text.join('\n')).then(() => done()); + suiteSetup(() => { + return setupWorkspace().then(() => { + return TextEditor.insert(text.join('\n')); + }); }); - teardown(done => { - TextEditor.delete().then(() => done()); - }); + suiteTeardown(cleanUpWorkspace); test("char right: should move one column right", () => { motionModes.forEach(o => { diff --git a/test/testHelpers.ts b/test/testHelpers.ts deleted file mode 100644 index bbbd411f2d2..00000000000 --- a/test/testHelpers.ts +++ /dev/null @@ -1,14 +0,0 @@ -import TextEditor from '../src/textEditor'; -import * as assert from 'assert'; - -export default class TestHelpers { - - public static assertEqualLines(expectedLines : string[]) { - assert.equal(TextEditor.getLineCount(), expectedLines.length); - - for (let i = 0; i < expectedLines.length; i++) { - assert.equal(TextEditor.readLine(i), expectedLines[i]); - } - } - -} \ No newline at end of file diff --git a/test/testUtils.ts b/test/testUtils.ts new file mode 100644 index 00000000000..74120878eb5 --- /dev/null +++ b/test/testUtils.ts @@ -0,0 +1,74 @@ +import TextEditor from '../src/textEditor'; +import * as vscode from "vscode"; +import * as assert from 'assert'; +import {join} from 'path'; +import * as os from 'os'; +import * as fs from 'fs'; + +function rndName() { + return Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 10); +} + +function createRandomFile(contents = ''): Thenable { + return new Promise((resolve, reject) => { + const tmpFile = join(os.tmpdir(), rndName()); + fs.writeFile(tmpFile, contents, (error) => { + if (error) { + return reject(error); + } + + resolve(vscode.Uri.file(tmpFile)); + }); + }); +} + +export function assertEqualLines(expectedLines : string[]) { + assert.equal(TextEditor.getLineCount(), expectedLines.length); + + for (let i = 0; i < expectedLines.length; i++) { + assert.equal(TextEditor.readLine(i), expectedLines[i]); + } +} + + +export function setupWorkspace() : Thenable { + return createRandomFile().then(file => { + return vscode.workspace.openTextDocument(file).then(doc => { + return vscode.window.showTextDocument(doc).then(editor => { + const active = vscode.window.activeTextEditor; + assert.ok(active); + }); + }); + }); +} + +export function cleanUpWorkspace(): Thenable { + // https://github.com/Microsoft/vscode/blob/master/extensions/vscode-api-tests/src/utils.ts + return new Promise((c, e) => { + if (vscode.window.visibleTextEditors.length === 0) { + return c(); + } + + // TODO: the visibleTextEditors variable doesn't seem to be + // up to date after a onDidChangeActiveTextEditor event, not + // even using a setTimeout 0... so we MUST poll :( + const interval = setInterval(() => { + if (vscode.window.visibleTextEditors.length > 0) { + return; + } + + clearInterval(interval); + c(); + }, 10); + + vscode.commands.executeCommand('workbench.action.closeAllEditors') + .then(() => vscode.commands.executeCommand('workbench.files.action.closeAllFiles')) + .then(null, err => { + clearInterval(interval); + e(err); + }); + }).then(() => { + assert.equal(vscode.window.visibleTextEditors.length, 0); + assert(!vscode.window.activeTextEditor); + }); +} \ No newline at end of file diff --git a/test/textEditor.test.ts b/test/textEditor.test.ts index aa842c1603c..8fe15b9ca20 100644 --- a/test/textEditor.test.ts +++ b/test/textEditor.test.ts @@ -1,15 +1,12 @@ import * as assert from 'assert'; import * as vscode from 'vscode'; import TextEditor from './../src/textEditor'; +import {setupWorkspace, cleanUpWorkspace} from './testUtils'; suite("text editor", () => { - suiteSetup(done => { - TextEditor.delete().then(() => done()); - }); + suiteSetup(setupWorkspace); - suiteTeardown(done => { - TextEditor.delete().then(() => done()); - }); + suiteTeardown(cleanUpWorkspace); test("insert 'Hello World'", () => { let expectedText = "Hello World"; diff --git a/tsconfig.json b/tsconfig.json index 44066990ddc..5a3f2462d64 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,7 @@ { "compilerOptions": { "module": "commonjs", - "target": "ES5", + "target": "es5", "outDir": "out", "noLib": true, "sourceMap": true