diff --git a/extensions/emmet/package.json b/extensions/emmet/package.json index 87717afacbd..93fe0bfa713 100644 --- a/extensions/emmet/package.json +++ b/extensions/emmet/package.json @@ -65,7 +65,8 @@ "compile": "gulp compile-extension:emmet" }, "devDependencies": { - "@types/node": "^7.0.4" + "@types/node": "^7.0.4", + "vscode": "1.0.1" }, "dependencies": { "@emmetio/expand-abbreviation": "^0.5.8", diff --git a/extensions/emmet/src/extension.ts b/extensions/emmet/src/extension.ts index 95ad4450992..49e55e14515 100644 --- a/extensions/emmet/src/extension.ts +++ b/extensions/emmet/src/extension.ts @@ -96,27 +96,27 @@ export function activate(context: vscode.ExtensionContext) { })); context.subscriptions.push(vscode.commands.registerCommand('emmet.incrementNumberByOneTenth', () => { - incrementDecrement(.1); + return incrementDecrement(.1); })); context.subscriptions.push(vscode.commands.registerCommand('emmet.incrementNumberByOne', () => { - incrementDecrement(1); + return incrementDecrement(1); })); context.subscriptions.push(vscode.commands.registerCommand('emmet.incrementNumberByTen', () => { - incrementDecrement(10); + return incrementDecrement(10); })); context.subscriptions.push(vscode.commands.registerCommand('emmet.decrementNumberByOneTenth', () => { - incrementDecrement(-0.1); + return incrementDecrement(-0.1); })); context.subscriptions.push(vscode.commands.registerCommand('emmet.decrementNumberByOne', () => { - incrementDecrement(-1); + return incrementDecrement(-1); })); context.subscriptions.push(vscode.commands.registerCommand('emmet.decrementNumberByTen', () => { - incrementDecrement(-10); + return incrementDecrement(-10); })); let currentExtensionsPath = undefined; diff --git a/extensions/emmet/src/incrementDecrement.ts b/extensions/emmet/src/incrementDecrement.ts index 9f772b133ee..378d2fbb119 100644 --- a/extensions/emmet/src/incrementDecrement.ts +++ b/extensions/emmet/src/incrementDecrement.ts @@ -13,14 +13,14 @@ const reNumber = /[0-9]/; * Incerement number under caret of given editor * @param {Number} delta */ -export function incrementDecrement(delta: number) { +export function incrementDecrement(delta: number): Thenable { let editor = vscode.window.activeTextEditor; if (!editor) { vscode.window.showInformationMessage('No editor is active'); return; } - editor.edit(editBuilder => { + return editor.edit(editBuilder => { editor.selections.forEach(selection => { let rangeToReplace: vscode.Range = selection; if (selection.isEmpty) { diff --git a/extensions/emmet/src/test/incrementDecrement.test.ts b/extensions/emmet/src/test/incrementDecrement.test.ts new file mode 100644 index 00000000000..9aace12eb3d --- /dev/null +++ b/extensions/emmet/src/test/incrementDecrement.test.ts @@ -0,0 +1,78 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as assert from 'assert'; +import { Selection, commands } from 'vscode'; +import { withRandomFileEditor, closeAllEditors } from './testUtils'; + +suite('Tests for Increment/Decrement Emmet Commands', () => { + teardown(closeAllEditors); + + const contents = ` + hello 123.43 there + hello 999.9 there + hello 100 there + `; + + test('incrementNumberByOne', function (): any { + return withRandomFileEditor(contents, (editor, doc) => { + editor.selections = [new Selection(1, 7, 1, 10), new Selection(2, 7, 2, 10)]; + return commands.executeCommand('emmet.incrementNumberByOne').then(() => { + assert.equal(doc.getText(), contents.replace('123', '124').replace('999', '1000')); + return Promise.resolve(); + }); + }); + }); + + test('incrementNumberByTen', function (): any { + return withRandomFileEditor(contents, (editor, doc) => { + editor.selections = [new Selection(1, 7, 1, 10), new Selection(2, 7, 2, 10)]; + return commands.executeCommand('emmet.incrementNumberByTen').then(() => { + assert.equal(doc.getText(), contents.replace('123', '133').replace('999', '1009')); + return Promise.resolve(); + }); + }); + }); + + test('incrementNumberByOneTenth', function (): any { + return withRandomFileEditor(contents, (editor, doc) => { + editor.selections = [new Selection(1, 7, 1, 13), new Selection(2, 7, 2, 12)]; + return commands.executeCommand('emmet.incrementNumberByOneTenth').then(() => { + assert.equal(doc.getText(), contents.replace('123.43', '123.53').replace('999.9', '1000')); + return Promise.resolve(); + }); + }); + }); + + test('decrementNumberByOne', function (): any { + return withRandomFileEditor(contents, (editor, doc) => { + editor.selections = [new Selection(1, 7, 1, 10), new Selection(3, 7, 3, 10)]; + return commands.executeCommand('emmet.decrementNumberByOne').then(() => { + assert.equal(doc.getText(), contents.replace('123', '122').replace('100', '99')); + return Promise.resolve(); + }); + }); + }); + + test('decrementNumberByTen', function (): any { + return withRandomFileEditor(contents, (editor, doc) => { + editor.selections = [new Selection(1, 7, 1, 10), new Selection(3, 7, 3, 10)]; + return commands.executeCommand('emmet.decrementNumberByTen').then(() => { + assert.equal(doc.getText(), contents.replace('123', '113').replace('100', '90')); + return Promise.resolve(); + }); + }); + }); + + test('decrementNumberByOneTenth', function (): any { + return withRandomFileEditor(contents, (editor, doc) => { + editor.selections = [new Selection(1, 7, 1, 13), new Selection(3, 7, 3, 10)]; + return commands.executeCommand('emmet.decrementNumberByOneTenth').then(() => { + assert.equal(doc.getText(), contents.replace('123.43', '123.33').replace('100', '99.9')); + return Promise.resolve(); + }); + }); + }); +}); \ No newline at end of file diff --git a/extensions/emmet/src/test/index.ts b/extensions/emmet/src/test/index.ts new file mode 100644 index 00000000000..f65a756a8de --- /dev/null +++ b/extensions/emmet/src/test/index.ts @@ -0,0 +1,28 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +// +// PLEASE DO NOT MODIFY / DELETE UNLESS YOU KNOW WHAT YOU ARE DOING +// +// This file is providing the test runner to use when running extension tests. +// By default the test runner in use is Mocha based. +// +// You can provide your own test runner if you want to override it by exporting +// a function run(testRoot: string, clb: (error:Error) => void) that the extension +// host can call to run the tests. The test runner is expected to use console.log +// to report the results back to the caller. When the tests are finished, return +// a possible error to the callback or null if none. + +const testRunner = require('vscode/lib/testrunner'); + +// You can directly control Mocha options by uncommenting the following lines +// See https://github.com/mochajs/mocha/wiki/Using-mocha-programmatically#set-options for more info +testRunner.configure({ + ui: 'tdd', // the TDD UI is being used in extension.test.ts (suite, test, etc.) + useColors: process.platform !== 'win32', // colored output from test results (only windows cannot handle) + timeout: 60000 +}); + +export = testRunner; diff --git a/extensions/emmet/src/test/testUtils.ts b/extensions/emmet/src/test/testUtils.ts new file mode 100644 index 00000000000..3548946b570 --- /dev/null +++ b/extensions/emmet/src/test/testUtils.ts @@ -0,0 +1,72 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import * as vscode from 'vscode'; +import * as fs from 'fs'; +import * as os from 'os'; +import { join } from 'path'; + +function rndName() { + return Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 10); +} + +export 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 pathEquals(path1: string, path2: string): boolean { + if (process.platform !== 'linux') { + path1 = path1.toLowerCase(); + path2 = path2.toLowerCase(); + } + + return path1 === path2; +} + +export function deleteFile(file: vscode.Uri): Thenable { + return new Promise((resolve, reject) => { + fs.unlink(file.fsPath, (err) => { + if (err) { + reject(err); + } else { + resolve(true); + } + }); + }); +} + +export function closeAllEditors(): Thenable { + return vscode.commands.executeCommand('workbench.action.closeAllEditors'); + +} + +export function withRandomFileEditor(initialContents: string, run: (editor: vscode.TextEditor, doc: vscode.TextDocument) => Thenable): Thenable { + return createRandomFile(initialContents).then(file => { + return vscode.workspace.openTextDocument(file).then(doc => { + return vscode.window.showTextDocument(doc).then((editor) => { + return run(editor, doc).then(_ => { + if (doc.isDirty) { + return doc.save().then(saved => { + return deleteFile(file); + }); + } else { + return deleteFile(file); + } + }); + }); + }); + }); +} \ No newline at end of file diff --git a/scripts/test-integration.sh b/scripts/test-integration.sh index 2b4b2633787..28d9581c189 100755 --- a/scripts/test-integration.sh +++ b/scripts/test-integration.sh @@ -16,5 +16,6 @@ cd $ROOT ./scripts/code.sh $ROOT/extensions/vscode-api-tests/testWorkspace --extensionDevelopmentPath=$ROOT/extensions/vscode-api-tests --extensionTestsPath=$ROOT/extensions/vscode-api-tests/out --disableExtensions --user-data-dir=$VSCODEUSERDATADIR ./scripts/code.sh $ROOT/extensions/vscode-colorize-tests/test --extensionDevelopmentPath=$ROOT/extensions/vscode-colorize-tests --extensionTestsPath=$ROOT/extensions/vscode-colorize-tests/out --user-data-dir=$VSCODEUSERDATADIR ./scripts/test-int-mocha.sh +./scripts/code.sh --extensionDevelopmentPath=$ROOT/extensions/emmet --extensionTestsPath=$ROOT/extensions/emmet/out/test --disableExtensions --user-data-dir=$VSCODEUSERDATADIR rm -r $VSCODEUSERDATADIR