SQL Operations Studio Public Preview 1 (0.23) release source code

This commit is contained in:
Karl Burtram
2017-11-09 14:30:27 -08:00
parent b88ecb8d93
commit 3cdac41339
8829 changed files with 759707 additions and 286 deletions

View File

@@ -0,0 +1,14 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import { isWindows, isMacintosh } from 'vs/base/common/platform';
suite('Browsers', () => {
test('all', function () {
assert(!(isWindows && isMacintosh));
});
});

View File

@@ -0,0 +1,39 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import { Build, Builder, MultiBuilder, Binding, Dimension, Position, Box, $ } from 'vs/base/browser/builder';
import * as Types from 'vs/base/common/types';
import * as DomUtils from 'vs/base/browser/dom';
import { TPromise } from 'vs/base/common/winjs.base';
import { IDisposable } from 'vs/base/common/lifecycle';
let withElementsBySelector = function (selector: string, offdom: boolean = false) {
let elements = window.document.querySelectorAll(selector);
let builders = [];
for (let i = 0; i < elements.length; i++) {
builders.push(new Builder(<HTMLElement>elements.item(i), offdom));
}
return new MultiBuilder(builders);
};
let withBuilder = function (builder, offdom) {
if (builder instanceof MultiBuilder) {
return new MultiBuilder(builder);
}
return new Builder(builder.getHTMLElement(), offdom);
};
suite('Builder', () => {
test('Dimension.substract()', function () {
assert.equal(1, 1);
});
});

View File

@@ -0,0 +1,58 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { compareFileNames, compareFileExtensions, setFileNameComparer } from 'vs/base/common/comparers';
import * as assert from 'assert';
suite('Comparers', () => {
test('compareFileNames', () => {
// Setup Intl
setFileNameComparer(new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' }));
assert(compareFileNames(null, null) === 0, 'null should be equal');
assert(compareFileNames(null, 'abc') < 0, 'null should be come before real values');
assert(compareFileNames('', '') === 0, 'empty should be equal');
assert(compareFileNames('abc', 'abc') === 0, 'equal names should be equal');
assert(compareFileNames('.abc', '.abc') === 0, 'equal full names should be equal');
assert(compareFileNames('.env', '.env.example') < 0, 'filenames with extensions should come after those without');
assert(compareFileNames('.env.example', '.gitattributes') < 0, 'filenames starting with dots and with extensions should still sort properly');
assert(compareFileNames('1', '1') === 0, 'numerically equal full names should be equal');
assert(compareFileNames('abc1.txt', 'abc1.txt') === 0, 'equal filenames with numbers should be equal');
assert(compareFileNames('abc1.txt', 'abc2.txt') < 0, 'filenames with numbers should be in numerical order, not alphabetical order');
assert(compareFileNames('abc2.txt', 'abc10.txt') < 0, 'filenames with numbers should be in numerical order even when they are multiple digits long');
});
test('compareFileExtensions', () => {
// Setup Intl
setFileNameComparer(new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' }));
assert(compareFileExtensions(null, null) === 0, 'null should be equal');
assert(compareFileExtensions(null, '.abc') < 0, 'null should come before real files');
assert(compareFileExtensions(null, 'abc') < 0, 'null should come before real files without extension');
assert(compareFileExtensions('', '') === 0, 'empty should be equal');
assert(compareFileExtensions('abc', 'abc') === 0, 'equal names should be equal');
assert(compareFileExtensions('.abc', '.abc') === 0, 'equal full names should be equal');
assert(compareFileExtensions('file.ext', 'file.ext') === 0, 'equal full names should be equal');
assert(compareFileExtensions('a.ext', 'b.ext') < 0, 'if equal extensions, filenames should be compared');
assert(compareFileExtensions('.ext', 'a.ext') < 0, 'if equal extensions, filenames should be compared, empty filename should come before others');
assert(compareFileExtensions('file.aaa', 'file.bbb') < 0, 'files should be compared by extensions');
assert(compareFileExtensions('bbb.aaa', 'aaa.bbb') < 0, 'files should be compared by extensions even if filenames compare differently');
assert(compareFileExtensions('1', '1') === 0, 'numerically equal full names should be equal');
assert(compareFileExtensions('abc1.txt', 'abc1.txt') === 0, 'equal filenames with numbers should be equal');
assert(compareFileExtensions('abc1.txt', 'abc2.txt') < 0, 'filenames with numbers should be in numerical order, not alphabetical order');
assert(compareFileExtensions('abc2.txt', 'abc10.txt') < 0, 'filenames with numbers should be in numerical order even when they are multiple digits long');
assert(compareFileExtensions('txt.abc1', 'txt.abc1') === 0, 'equal extensions with numbers should be equal');
assert(compareFileExtensions('txt.abc1', 'txt.abc2') < 0, 'extensions with numbers should be in numerical order, not alphabetical order');
assert(compareFileExtensions('txt.abc2', 'txt.abc10') < 0, 'extensions with numbers should be in numerical order even when they are multiple digits long');
assert(compareFileExtensions('a.ext1', 'b.ext1') < 0, 'if equal extensions with numbers, filenames should be compared');
assert(compareFileExtensions('file2.ext2', 'file1.ext10') < 0, 'extensions with numbers should be in numerical order, not alphabetical order');
assert(compareFileExtensions('file.ext01', 'file.ext1') < 0, 'extensions with equal numbers should be in alphabetical order');
});
});

View File

@@ -0,0 +1,15 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import * as dom from 'vs/base/browser/dom';
const $ = dom.$;
suite('dom', () => {
test('hasClass', () => {
assert(true);
});
});

View File

@@ -0,0 +1,55 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import { HighlightedLabel } from 'vs/base/browser/ui/highlightedlabel/highlightedLabel';
suite('HighlightedLabel', () => {
let label: HighlightedLabel;
setup(() => {
label = new HighlightedLabel(document.createElement('div'));
});
teardown(() => {
label.dispose();
label = null;
});
test('empty label', function () {
assert.equal(label.element.innerHTML, '');
});
test('no decorations', function () {
label.set('hello');
assert.equal(label.element.innerHTML, '<span>hello</span>');
});
test('escape html', function () {
label.set('hel<lo');
assert.equal(label.element.innerHTML, '<span>hel&lt;lo</span>');
});
test('everything highlighted', function () {
label.set('hello', [{ start: 0, end: 5 }]);
assert.equal(label.element.innerHTML, '<span class="highlight">hello</span>');
});
test('beginning highlighted', function () {
label.set('hellothere', [{ start: 0, end: 5 }]);
assert.equal(label.element.innerHTML, '<span class="highlight">hello</span><span>there</span>');
});
test('ending highlighted', function () {
label.set('goodbye', [{ start: 4, end: 7 }]);
assert.equal(label.element.innerHTML, '<span>good</span><span class="highlight">bye</span>');
});
test('middle highlighted', function () {
label.set('foobarfoo', [{ start: 3, end: 6 }]);
assert.equal(label.element.innerHTML, '<span>foo</span><span class="highlight">bar</span><span>foo</span>');
});
});

View File

@@ -0,0 +1,121 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import { marked } from 'vs/base/common/marked/marked';
import { renderMarkdown, renderText, renderFormattedText } from 'vs/base/browser/htmlContentRenderer';
suite('HtmlContent', () => {
test('render simple element', () => {
var result: HTMLElement = <any>renderText('testing');
assert.strictEqual(result.nodeType, document.ELEMENT_NODE);
assert.strictEqual(result.textContent, 'testing');
assert.strictEqual(result.tagName, 'DIV');
});
test('render element with class', () => {
var result: HTMLElement = <any>renderText('testing', {
className: 'testClass'
});
assert.strictEqual(result.nodeType, document.ELEMENT_NODE);
assert.strictEqual(result.className, 'testClass');
});
test('simple formatting', () => {
var result: HTMLElement = <any>renderFormattedText('**bold**');
assert.strictEqual(result.children.length, 1);
assert.strictEqual(result.firstChild.textContent, 'bold');
assert.strictEqual((<HTMLElement>result.firstChild).tagName, 'B');
assert.strictEqual(result.innerHTML, '<b>bold</b>');
result = <any>renderFormattedText('__italics__');
assert.strictEqual(result.innerHTML, '<i>italics</i>');
result = <any>renderFormattedText('this string has **bold** and __italics__');
assert.strictEqual(result.innerHTML, 'this string has <b>bold</b> and <i>italics</i>');
});
test('no formatting', () => {
var result: HTMLElement = <any>renderFormattedText('this is just a string');
assert.strictEqual(result.innerHTML, 'this is just a string');
});
test('preserve newlines', () => {
var result: HTMLElement = <any>renderFormattedText('line one\nline two');
assert.strictEqual(result.innerHTML, 'line one<br>line two');
});
test('action', () => {
var callbackCalled = false;
var result: HTMLElement = <any>renderFormattedText('[[action]]', {
actionCallback(content) {
assert.strictEqual(content, '0');
callbackCalled = true;
}
});
assert.strictEqual(result.innerHTML, '<a href="#">action</a>');
var event: MouseEvent = <any>document.createEvent('MouseEvent');
event.initEvent('click', true, true);
result.firstChild.dispatchEvent(event);
assert.strictEqual(callbackCalled, true);
});
test('fancy action', () => {
var callbackCalled = false;
var result: HTMLElement = <any>renderFormattedText('__**[[action]]**__', {
actionCallback(content) {
assert.strictEqual(content, '0');
callbackCalled = true;
}
});
assert.strictEqual(result.innerHTML, '<i><b><a href="#">action</a></b></i>');
var event: MouseEvent = <any>document.createEvent('MouseEvent');
event.initEvent('click', true, true);
result.firstChild.firstChild.firstChild.dispatchEvent(event);
assert.strictEqual(callbackCalled, true);
});
test('escaped formatting', () => {
var result: HTMLElement = <any>renderFormattedText('\\*\\*bold\\*\\*');
assert.strictEqual(result.children.length, 0);
assert.strictEqual(result.innerHTML, '**bold**');
});
test('image rendering conforms to default', () => {
const markdown = { value: `![image](someimageurl 'caption')` };
const result: HTMLElement = <any>renderMarkdown(markdown);
const renderer = new marked.Renderer();
const imageFromMarked = marked(markdown.value, {
sanitize: true,
renderer
}).trim();
assert.strictEqual(result.innerHTML, imageFromMarked);
});
test('image rendering conforms to default without title', () => {
const markdown = { value: `![image](someimageurl)` };
const result: HTMLElement = <any>renderMarkdown(markdown);
const renderer = new marked.Renderer();
const imageFromMarked = marked(markdown.value, {
sanitize: true,
renderer
}).trim();
assert.strictEqual(result.innerHTML, imageFromMarked);
});
test('image width from title params', () => {
var result: HTMLElement = <any>renderMarkdown({ value: `![image](someimageurl|width=100 'caption')` });
assert.strictEqual(result.innerHTML, `<p><img src="someimageurl" alt="image" title="caption" width="100"></p>`);
});
test('image height from title params', () => {
var result: HTMLElement = <any>renderMarkdown({ value: `![image](someimageurl|height=100 'caption')` });
assert.strictEqual(result.innerHTML, `<p><img src="someimageurl" alt="image" title="caption" height="100"></p>`);
});
test('image width and height from title params', () => {
var result: HTMLElement = <any>renderMarkdown({ value: `![image](someimageurl|height=200,width=100 'caption')` });
assert.strictEqual(result.innerHTML, `<p><img src="someimageurl" alt="image" title="caption" width="100" height="200"></p>`);
});
});

View File

@@ -0,0 +1,36 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import { ProgressBar } from 'vs/base/browser/ui/progressbar/progressbar';
import { Builder } from 'vs/base/browser/builder';
suite('ProgressBar', () => {
let fixture: HTMLElement;
setup(() => {
fixture = document.createElement('div');
document.body.appendChild(fixture);
});
teardown(() => {
document.body.removeChild(fixture);
});
test('Progress Bar', function () {
const b = new Builder(fixture);
const bar = new ProgressBar(b);
assert(bar.getContainer());
assert(bar.infinite());
assert(bar.total(100));
assert(bar.worked(50));
assert(bar.worked(50));
assert(bar.done());
bar.dispose();
});
});

View File

@@ -0,0 +1,348 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import assert = require('assert');
import { RangeMap, intersect, groupIntersect, consolidate } from 'vs/base/browser/ui/list/rangeMap';
suite('RangeMap', () => {
var rangeMap: RangeMap;
setup(() => {
rangeMap = new RangeMap();
});
teardown(() => {
rangeMap.dispose();
});
test('intersection', () => {
assert.deepEqual(intersect({ start: 0, end: 0 }, { start: 0, end: 0 }), null);
assert.deepEqual(intersect({ start: 0, end: 0 }, { start: 5, end: 5 }), null);
assert.deepEqual(intersect({ start: 0, end: 1 }, { start: 5, end: 6 }), null);
assert.deepEqual(intersect({ start: 5, end: 6 }, { start: 0, end: 1 }), null);
assert.deepEqual(intersect({ start: 0, end: 5 }, { start: 2, end: 2 }), null);
assert.deepEqual(intersect({ start: 0, end: 1 }, { start: 0, end: 1 }), { start: 0, end: 1 });
assert.deepEqual(intersect({ start: 0, end: 10 }, { start: 0, end: 5 }), { start: 0, end: 5 });
assert.deepEqual(intersect({ start: 0, end: 5 }, { start: 0, end: 10 }), { start: 0, end: 5 });
assert.deepEqual(intersect({ start: 0, end: 10 }, { start: 5, end: 10 }), { start: 5, end: 10 });
assert.deepEqual(intersect({ start: 5, end: 10 }, { start: 0, end: 10 }), { start: 5, end: 10 });
assert.deepEqual(intersect({ start: 0, end: 10 }, { start: 2, end: 8 }), { start: 2, end: 8 });
assert.deepEqual(intersect({ start: 2, end: 8 }, { start: 0, end: 10 }), { start: 2, end: 8 });
assert.deepEqual(intersect({ start: 0, end: 10 }, { start: 5, end: 15 }), { start: 5, end: 10 });
assert.deepEqual(intersect({ start: 5, end: 15 }, { start: 0, end: 10 }), { start: 5, end: 10 });
});
test('multiIntersect', () => {
assert.deepEqual(
groupIntersect(
{ start: 0, end: 0 },
[{ range: { start: 0, end: 10 }, size: 1 }]
),
[]
);
assert.deepEqual(
groupIntersect(
{ start: 10, end: 20 },
[{ range: { start: 0, end: 10 }, size: 1 }]
),
[]
);
assert.deepEqual(
groupIntersect(
{ start: 2, end: 8 },
[{ range: { start: 0, end: 10 }, size: 1 }]
),
[{ range: { start: 2, end: 8 }, size: 1 }]
);
assert.deepEqual(
groupIntersect(
{ start: 2, end: 8 },
[{ range: { start: 0, end: 10 }, size: 1 }, { range: { start: 10, end: 20 }, size: 5 }]
),
[{ range: { start: 2, end: 8 }, size: 1 }]
);
assert.deepEqual(
groupIntersect(
{ start: 12, end: 18 },
[{ range: { start: 0, end: 10 }, size: 1 }, { range: { start: 10, end: 20 }, size: 5 }]
),
[{ range: { start: 12, end: 18 }, size: 5 }]
);
assert.deepEqual(
groupIntersect(
{ start: 2, end: 18 },
[{ range: { start: 0, end: 10 }, size: 1 }, { range: { start: 10, end: 20 }, size: 5 }]
),
[{ range: { start: 2, end: 10 }, size: 1 }, { range: { start: 10, end: 18 }, size: 5 }]
);
assert.deepEqual(
groupIntersect(
{ start: 2, end: 28 },
[{ range: { start: 0, end: 10 }, size: 1 }, { range: { start: 10, end: 20 }, size: 5 }, { range: { start: 20, end: 30 }, size: 10 }]
),
[{ range: { start: 2, end: 10 }, size: 1 }, { range: { start: 10, end: 20 }, size: 5 }, { range: { start: 20, end: 28 }, size: 10 }]
);
});
test('consolidate', () => {
assert.deepEqual(consolidate([]), []);
assert.deepEqual(
consolidate([{ range: { start: 0, end: 10 }, size: 1 }]),
[{ range: { start: 0, end: 10 }, size: 1 }]
);
assert.deepEqual(
consolidate([
{ range: { start: 0, end: 10 }, size: 1 },
{ range: { start: 10, end: 20 }, size: 1 }
]),
[{ range: { start: 0, end: 20 }, size: 1 }]
);
assert.deepEqual(
consolidate([
{ range: { start: 0, end: 10 }, size: 1 },
{ range: { start: 10, end: 20 }, size: 1 },
{ range: { start: 20, end: 100 }, size: 1 }
]),
[{ range: { start: 0, end: 100 }, size: 1 }]
);
assert.deepEqual(
consolidate([
{ range: { start: 0, end: 10 }, size: 1 },
{ range: { start: 10, end: 20 }, size: 5 },
{ range: { start: 20, end: 30 }, size: 10 }
]),
[
{ range: { start: 0, end: 10 }, size: 1 },
{ range: { start: 10, end: 20 }, size: 5 },
{ range: { start: 20, end: 30 }, size: 10 }
]
);
assert.deepEqual(
consolidate([
{ range: { start: 0, end: 10 }, size: 1 },
{ range: { start: 10, end: 20 }, size: 2 },
{ range: { start: 20, end: 100 }, size: 2 }
]),
[
{ range: { start: 0, end: 10 }, size: 1 },
{ range: { start: 10, end: 100 }, size: 2 }
]
);
});
test('empty', () => {
assert.equal(rangeMap.size, 0);
assert.equal(rangeMap.count, 0);
});
const one = { size: 1 };
const two = { size: 2 };
const three = { size: 3 };
const five = { size: 5 };
const ten = { size: 10 };
test('length & count', () => {
rangeMap.splice(0, 0, one);
assert.equal(rangeMap.size, 1);
assert.equal(rangeMap.count, 1);
});
test('length & count #2', () => {
rangeMap.splice(0, 0, one, one, one, one, one);
assert.equal(rangeMap.size, 5);
assert.equal(rangeMap.count, 5);
});
test('length & count #3', () => {
rangeMap.splice(0, 0, five);
assert.equal(rangeMap.size, 5);
assert.equal(rangeMap.count, 1);
});
test('length & count #4', () => {
rangeMap.splice(0, 0, five, five, five, five, five);
assert.equal(rangeMap.size, 25);
assert.equal(rangeMap.count, 5);
});
test('insert', () => {
rangeMap.splice(0, 0, five, five, five, five, five);
assert.equal(rangeMap.size, 25);
assert.equal(rangeMap.count, 5);
rangeMap.splice(0, 0, five, five, five, five, five);
assert.equal(rangeMap.size, 50);
assert.equal(rangeMap.count, 10);
rangeMap.splice(5, 0, ten, ten);
assert.equal(rangeMap.size, 70);
assert.equal(rangeMap.count, 12);
rangeMap.splice(12, 0, { size: 200 });
assert.equal(rangeMap.size, 270);
assert.equal(rangeMap.count, 13);
});
test('delete', () => {
rangeMap.splice(0, 0, five, five, five, five, five,
five, five, five, five, five,
five, five, five, five, five,
five, five, five, five, five);
assert.equal(rangeMap.size, 100);
assert.equal(rangeMap.count, 20);
rangeMap.splice(10, 5);
assert.equal(rangeMap.size, 75);
assert.equal(rangeMap.count, 15);
rangeMap.splice(0, 1);
assert.equal(rangeMap.size, 70);
assert.equal(rangeMap.count, 14);
rangeMap.splice(1, 13);
assert.equal(rangeMap.size, 5);
assert.equal(rangeMap.count, 1);
rangeMap.splice(1, 1);
assert.equal(rangeMap.size, 5);
assert.equal(rangeMap.count, 1);
});
test('insert & delete', () => {
assert.equal(rangeMap.size, 0);
assert.equal(rangeMap.count, 0);
rangeMap.splice(0, 0, one);
assert.equal(rangeMap.size, 1);
assert.equal(rangeMap.count, 1);
rangeMap.splice(0, 1);
assert.equal(rangeMap.size, 0);
assert.equal(rangeMap.count, 0);
});
test('insert & delete #2', () => {
rangeMap.splice(0, 0, one, one, one, one, one,
one, one, one, one, one);
rangeMap.splice(2, 6);
assert.equal(rangeMap.count, 4);
assert.equal(rangeMap.size, 4);
});
test('insert & delete #3', () => {
rangeMap.splice(0, 0, one, one, one, one, one,
one, one, one, one, one,
two, two, two, two, two,
two, two, two, two, two);
rangeMap.splice(8, 4);
assert.equal(rangeMap.count, 16);
assert.equal(rangeMap.size, 24);
});
test('insert & delete #3', () => {
rangeMap.splice(0, 0, one, one, one, one, one,
one, one, one, one, one,
two, two, two, two, two,
two, two, two, two, two);
rangeMap.splice(5, 0, three, three, three, three, three);
assert.equal(rangeMap.count, 25);
assert.equal(rangeMap.size, 45);
rangeMap.splice(4, 7);
assert.equal(rangeMap.count, 18);
assert.equal(rangeMap.size, 28);
});
suite('indexAt, positionAt', () => {
test('empty', () => {
assert.equal(rangeMap.indexAt(0), 0);
assert.equal(rangeMap.indexAt(10), 0);
assert.equal(rangeMap.indexAt(-1), -1);
assert.equal(rangeMap.positionAt(0), -1);
assert.equal(rangeMap.positionAt(10), -1);
assert.equal(rangeMap.positionAt(-1), -1);
});
test('simple', () => {
rangeMap.splice(0, 0, one);
assert.equal(rangeMap.indexAt(0), 0);
assert.equal(rangeMap.indexAt(1), 1);
assert.equal(rangeMap.positionAt(0), 0);
assert.equal(rangeMap.positionAt(1), -1);
});
test('simple #2', () => {
rangeMap.splice(0, 0, ten);
assert.equal(rangeMap.indexAt(0), 0);
assert.equal(rangeMap.indexAt(5), 0);
assert.equal(rangeMap.indexAt(9), 0);
assert.equal(rangeMap.indexAt(10), 1);
assert.equal(rangeMap.positionAt(0), 0);
assert.equal(rangeMap.positionAt(1), -1);
});
test('insert', () => {
rangeMap.splice(0, 0, one, one, one, one, one, one, one, one, one, one);
assert.equal(rangeMap.indexAt(0), 0);
assert.equal(rangeMap.indexAt(1), 1);
assert.equal(rangeMap.indexAt(5), 5);
assert.equal(rangeMap.indexAt(9), 9);
assert.equal(rangeMap.indexAt(10), 10);
assert.equal(rangeMap.indexAt(11), 10);
rangeMap.splice(10, 0, one, one, one, one, one, one, one, one, one, one);
assert.equal(rangeMap.indexAt(10), 10);
assert.equal(rangeMap.indexAt(19), 19);
assert.equal(rangeMap.indexAt(20), 20);
assert.equal(rangeMap.indexAt(21), 20);
assert.equal(rangeMap.positionAt(0), 0);
assert.equal(rangeMap.positionAt(1), 1);
assert.equal(rangeMap.positionAt(19), 19);
assert.equal(rangeMap.positionAt(20), -1);
});
test('delete', () => {
rangeMap.splice(0, 0, one, one, one, one, one, one, one, one, one, one);
rangeMap.splice(2, 6);
assert.equal(rangeMap.indexAt(0), 0);
assert.equal(rangeMap.indexAt(1), 1);
assert.equal(rangeMap.indexAt(3), 3);
assert.equal(rangeMap.indexAt(4), 4);
assert.equal(rangeMap.indexAt(5), 4);
assert.equal(rangeMap.positionAt(0), 0);
assert.equal(rangeMap.positionAt(1), 1);
assert.equal(rangeMap.positionAt(3), 3);
assert.equal(rangeMap.positionAt(4), -1);
});
test('delete #2', () => {
rangeMap.splice(0, 0, ten, ten, ten, ten, ten, ten, ten, ten, ten, ten);
rangeMap.splice(2, 6);
assert.equal(rangeMap.indexAt(0), 0);
assert.equal(rangeMap.indexAt(1), 0);
assert.equal(rangeMap.indexAt(30), 3);
assert.equal(rangeMap.indexAt(40), 4);
assert.equal(rangeMap.indexAt(50), 4);
assert.equal(rangeMap.positionAt(0), 0);
assert.equal(rangeMap.positionAt(1), 10);
assert.equal(rangeMap.positionAt(2), 20);
assert.equal(rangeMap.positionAt(3), 30);
assert.equal(rangeMap.positionAt(4), -1);
});
});
});

View File

@@ -0,0 +1,525 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { MouseWheelClassifier } from 'vs/base/browser/ui/scrollbar/scrollableElement';
import * as assert from 'assert';
export type IMouseWheelEvent = [number, number, number];
suite('MouseWheelClassifier', () => {
test('OSX - Apple Magic Mouse', () => {
const testData: IMouseWheelEvent[] = [
[1503409622410, -0.025, 0],
[1503409622435, -0.175, 0],
[1503409622446, -0.225, 0],
[1503409622489, -0.65, 0],
[1503409622514, -1.225, 0],
[1503409622537, -1.025, 0],
[1503409622543, -0.55, 0],
[1503409622587, -0.75, 0],
[1503409622623, -1.45, 0],
[1503409622641, -1.325, 0],
[1503409622663, -0.6, 0],
[1503409622681, -1.125, 0],
[1503409622703, -0.5166666666666667, 0],
[1503409622721, -0.475, 0],
[1503409622822, -0.425, 0],
[1503409622871, -1.9916666666666667, 0],
[1503409622933, -0.7, 0],
[1503409622991, -0.725, 0],
[1503409623032, -0.45, 0],
[1503409623083, -0.25, 0],
[1503409623122, -0.4, 0],
[1503409623176, -0.2, 0],
[1503409623197, -0.225, 0],
[1503409623219, -0.05, 0],
[1503409623249, -0.1, 0],
[1503409623278, -0.1, 0],
[1503409623292, -0.025, 0],
[1503409623315, -0.025, 0],
[1503409623324, -0.05, 0],
[1503409623356, -0.025, 0],
[1503409623415, -0.025, 0],
[1503409623443, -0.05, 0],
[1503409623452, -0.025, 0],
];
const classifier = new MouseWheelClassifier();
for (let i = 0, len = testData.length; i < len; i++) {
const [timestamp, deltaY, deltaX] = testData[i];
classifier.accept(timestamp, deltaX, deltaY);
const actual = classifier.isPhysicalMouseWheel();
assert.equal(actual, false);
}
});
test('OSX - Apple Touch Pad', () => {
const testData: IMouseWheelEvent[] = [
[1503409780792, 0.025, 0],
[1503409780808, 0.175, -0.025],
[1503409780811, 0.35, -0.05],
[1503409780816, 0.55, -0.075],
[1503409780836, 0.825, -0.1],
[1503409780840, 0.725, -0.075],
[1503409780842, 1.5, -0.125],
[1503409780848, 1.1, -0.1],
[1503409780877, 2.05, -0.1],
[1503409780882, 3.9, 0],
[1503409780908, 3.825, 0],
[1503409780915, 3.65, 0],
[1503409780940, 3.45, 0],
[1503409780949, 3.25, 0],
[1503409780979, 3.075, 0],
[1503409780982, 2.9, 0],
[1503409781016, 2.75, 0],
[1503409781018, 2.625, 0],
[1503409781051, 2.5, 0],
[1503409781071, 2.4, 0],
[1503409781089, 2.3, 0],
[1503409781111, 2.175, 0],
[1503409781140, 3.975, 0],
[1503409781165, 1.8, 0],
[1503409781183, 3.3, 0],
[1503409781202, 1.475, 0],
[1503409781223, 1.375, 0],
[1503409781244, 1.275, 0],
[1503409781269, 2.25, 0],
[1503409781285, 1.025, 0],
[1503409781300, 0.925, 0],
[1503409781303, 0.875, 0],
[1503409781321, 0.8, 0],
[1503409781333, 0.725, 0],
[1503409781355, 0.65, 0],
[1503409781370, 0.6, 0],
[1503409781384, 0.55, 0],
[1503409781410, 0.5, 0],
[1503409781422, 0.475, 0],
[1503409781435, 0.425, 0],
[1503409781454, 0.4, 0],
[1503409781470, 0.35, 0],
[1503409781486, 0.325, 0],
[1503409781501, 0.3, 0],
[1503409781519, 0.275, 0],
[1503409781534, 0.25, 0],
[1503409781553, 0.225, 0],
[1503409781569, 0.2, 0],
[1503409781589, 0.2, 0],
[1503409781601, 0.175, 0],
[1503409781621, 0.15, 0],
[1503409781631, 0.15, 0],
[1503409781652, 0.125, 0],
[1503409781667, 0.125, 0],
[1503409781685, 0.125, 0],
[1503409781703, 0.1, 0],
[1503409781715, 0.1, 0],
[1503409781734, 0.1, 0],
[1503409781753, 0.075, 0],
[1503409781768, 0.075, 0],
[1503409781783, 0.075, 0],
[1503409781801, 0.075, 0],
[1503409781815, 0.05, 0],
[1503409781836, 0.05, 0],
[1503409781850, 0.05, 0],
[1503409781865, 0.05, 0],
[1503409781880, 0.05, 0],
[1503409781899, 0.025, 0],
[1503409781916, 0.025, 0],
[1503409781933, 0.025, 0],
[1503409781952, 0.025, 0],
[1503409781965, 0.025, 0],
[1503409781996, 0.025, 0],
[1503409782015, 0.025, 0],
[1503409782045, 0.025, 0],
];
const classifier = new MouseWheelClassifier();
for (let i = 0, len = testData.length; i < len; i++) {
const [timestamp, deltaY, deltaX] = testData[i];
classifier.accept(timestamp, deltaX, deltaY);
const actual = classifier.isPhysicalMouseWheel();
assert.equal(actual, false);
}
});
test('OSX - Razer Physical Mouse Wheel', () => {
const testData: IMouseWheelEvent[] = [
[1503409880776, -1, 0],
[1503409880791, -1, 0],
[1503409880810, -4, 0],
[1503409880820, -5, 0],
[1503409880848, -6, 0],
[1503409880876, -7, 0],
[1503409881319, -1, 0],
[1503409881387, -1, 0],
[1503409881407, -2, 0],
[1503409881443, -4, 0],
[1503409881444, -5, 0],
[1503409881470, -6, 0],
[1503409881496, -7, 0],
[1503409881812, -1, 0],
[1503409881829, -1, 0],
[1503409881850, -4, 0],
[1503409881871, -5, 0],
[1503409881896, -13, 0],
[1503409881914, -16, 0],
[1503409882551, -1, 0],
[1503409882589, -1, 0],
[1503409882625, -2, 0],
[1503409883035, -1, 0],
[1503409883098, -1, 0],
[1503409883143, -2, 0],
[1503409883217, -2, 0],
[1503409883270, -3, 0],
[1503409883388, -3, 0],
[1503409883531, -3, 0],
[1503409884095, -1, 0],
[1503409884122, -1, 0],
[1503409884160, -3, 0],
[1503409884208, -4, 0],
[1503409884292, -4, 0],
[1503409884447, -1, 0],
[1503409884788, -1, 0],
[1503409884835, -1, 0],
[1503409884898, -2, 0],
[1503409884965, -3, 0],
[1503409885085, -2, 0],
[1503409885552, -1, 0],
[1503409885619, -1, 0],
[1503409885670, -1, 0],
[1503409885733, -2, 0],
[1503409885784, -4, 0],
[1503409885916, -3, 0],
];
const classifier = new MouseWheelClassifier();
for (let i = 0, len = testData.length; i < len; i++) {
const [timestamp, deltaY, deltaX] = testData[i];
classifier.accept(timestamp, deltaX, deltaY);
const actual = classifier.isPhysicalMouseWheel();
assert.equal(actual, true);
}
});
test('Windows - Microsoft Arc Touch', () => {
const testData: IMouseWheelEvent[] = [
[1503418316909, -2, 0],
[1503418316985, -2, 0],
[1503418316988, -4, 0],
[1503418317034, -2, 0],
[1503418317071, -2, 0],
[1503418317094, -2, 0],
[1503418317133, -2, 0],
[1503418317170, -2, 0],
[1503418317192, -2, 0],
[1503418317265, -2, 0],
[1503418317289, -2, 0],
[1503418317365, -2, 0],
[1503418317414, -2, 0],
[1503418317458, -2, 0],
[1503418317513, -2, 0],
[1503418317583, -2, 0],
[1503418317637, -2, 0],
[1503418317720, -2, 0],
[1503418317786, -2, 0],
[1503418317832, -2, 0],
[1503418317933, -2, 0],
[1503418318037, -2, 0],
[1503418318134, -2, 0],
[1503418318267, -2, 0],
[1503418318411, -2, 0],
];
const classifier = new MouseWheelClassifier();
for (let i = 0, len = testData.length; i < len; i++) {
const [timestamp, deltaY, deltaX] = testData[i];
classifier.accept(timestamp, deltaX, deltaY);
const actual = classifier.isPhysicalMouseWheel();
assert.equal(actual, true);
}
});
test('Windows - SurfaceBook TouchPad', () => {
const testData: IMouseWheelEvent[] = [
[1503418499174, -3.35, 0],
[1503418499177, -0.9333333333333333, 0],
[1503418499222, -2.091666666666667, 0],
[1503418499238, -1.5666666666666667, 0],
[1503418499242, -1.8, 0],
[1503418499271, -2.5166666666666666, 0],
[1503418499283, -0.7666666666666667, 0],
[1503418499308, -2.033333333333333, 0],
[1503418499320, -2.85, 0],
[1503418499372, -1.5333333333333334, 0],
[1503418499373, -2.8, 0],
[1503418499411, -1.6166666666666667, 0],
[1503418499413, -1.9166666666666667, 0],
[1503418499443, -0.9333333333333333, 0],
[1503418499446, -0.9833333333333333, 0],
[1503418499458, -0.7666666666666667, 0],
[1503418499482, -0.9666666666666667, 0],
[1503418499485, -0.36666666666666664, 0],
[1503418499508, -0.5833333333333334, 0],
[1503418499532, -0.48333333333333334, 0],
[1503418499541, -0.6333333333333333, 0],
[1503418499571, -0.18333333333333332, 0],
[1503418499573, -0.4, 0],
[1503418499595, -0.15, 0],
[1503418499608, -0.23333333333333334, 0],
[1503418499625, -0.18333333333333332, 0],
[1503418499657, -0.13333333333333333, 0],
[1503418499674, -0.15, 0],
[1503418499676, -0.03333333333333333, 0],
[1503418499691, -0.016666666666666666, 0],
];
const classifier = new MouseWheelClassifier();
for (let i = 0, len = testData.length; i < len; i++) {
const [timestamp, deltaY, deltaX] = testData[i];
classifier.accept(timestamp, deltaX, deltaY);
const actual = classifier.isPhysicalMouseWheel();
assert.equal(actual, false);
}
});
test('Windows - Razer physical wheel', () => {
const testData: IMouseWheelEvent[] = [
[1503418638271, -2, 0],
[1503418638317, -2, 0],
[1503418638336, -2, 0],
[1503418638350, -2, 0],
[1503418638360, -2, 0],
[1503418638366, -2, 0],
[1503418638407, -2, 0],
[1503418638694, -2, 0],
[1503418638742, -2, 0],
[1503418638744, -2, 0],
[1503418638746, -2, 0],
[1503418638780, -2, 0],
[1503418638782, -2, 0],
[1503418638810, -2, 0],
[1503418639127, -2, 0],
[1503418639168, -2, 0],
[1503418639194, -2, 0],
[1503418639197, -4, 0],
[1503418639244, -2, 0],
[1503418639248, -2, 0],
[1503418639586, -2, 0],
[1503418639653, -2, 0],
[1503418639667, -4, 0],
[1503418639677, -2, 0],
[1503418639681, -2, 0],
[1503418639728, -2, 0],
[1503418639997, -2, 0],
[1503418640034, -2, 0],
[1503418640039, -2, 0],
[1503418640065, -2, 0],
[1503418640080, -2, 0],
[1503418640097, -2, 0],
[1503418640141, -2, 0],
[1503418640413, -2, 0],
[1503418640456, -2, 0],
[1503418640490, -2, 0],
[1503418640492, -4, 0],
[1503418640494, -2, 0],
[1503418640546, -2, 0],
[1503418640781, -2, 0],
[1503418640823, -2, 0],
[1503418640824, -2, 0],
[1503418640829, -2, 0],
[1503418640864, -2, 0],
[1503418640874, -2, 0],
[1503418640876, -2, 0],
[1503418641168, -2, 0],
[1503418641203, -2, 0],
[1503418641224, -2, 0],
[1503418641240, -2, 0],
[1503418641254, -4, 0],
[1503418641270, -2, 0],
[1503418641546, -2, 0],
[1503418641612, -2, 0],
[1503418641625, -6, 0],
[1503418641634, -2, 0],
[1503418641680, -2, 0],
[1503418641961, -2, 0],
[1503418642004, -2, 0],
[1503418642016, -4, 0],
[1503418642044, -2, 0],
[1503418642065, -2, 0],
[1503418642083, -2, 0],
[1503418642349, -2, 0],
[1503418642378, -2, 0],
[1503418642390, -2, 0],
[1503418642408, -2, 0],
[1503418642413, -2, 0],
[1503418642448, -2, 0],
[1503418642468, -2, 0],
[1503418642746, -2, 0],
[1503418642800, -2, 0],
[1503418642814, -4, 0],
[1503418642816, -2, 0],
[1503418642857, -2, 0],
];
const classifier = new MouseWheelClassifier();
for (let i = 0, len = testData.length; i < len; i++) {
const [timestamp, deltaY, deltaX] = testData[i];
classifier.accept(timestamp, deltaX, deltaY);
const actual = classifier.isPhysicalMouseWheel();
assert.equal(actual, true);
}
});
test('Windows - Logitech physical wheel', () => {
const testData: IMouseWheelEvent[] = [
[1503418872930, -2, 0],
[1503418872952, -2, 0],
[1503418872969, -2, 0],
[1503418873022, -2, 0],
[1503418873042, -2, 0],
[1503418873076, -2, 0],
[1503418873368, -2, 0],
[1503418873393, -2, 0],
[1503418873404, -2, 0],
[1503418873425, -2, 0],
[1503418873479, -2, 0],
[1503418873520, -2, 0],
[1503418873758, -2, 0],
[1503418873759, -2, 0],
[1503418873762, -2, 0],
[1503418873807, -2, 0],
[1503418873830, -4, 0],
[1503418873850, -2, 0],
[1503418874076, -2, 0],
[1503418874116, -2, 0],
[1503418874136, -4, 0],
[1503418874148, -2, 0],
[1503418874150, -2, 0],
[1503418874409, -2, 0],
[1503418874452, -2, 0],
[1503418874472, -2, 0],
[1503418874474, -4, 0],
[1503418874543, -2, 0],
[1503418874566, -2, 0],
[1503418874778, -2, 0],
[1503418874780, -2, 0],
[1503418874801, -2, 0],
[1503418874822, -2, 0],
[1503418874832, -2, 0],
[1503418874845, -2, 0],
[1503418875122, -2, 0],
[1503418875158, -2, 0],
[1503418875180, -2, 0],
[1503418875195, -4, 0],
[1503418875239, -2, 0],
[1503418875260, -2, 0],
[1503418875490, -2, 0],
[1503418875525, -2, 0],
[1503418875547, -4, 0],
[1503418875556, -4, 0],
[1503418875630, -2, 0],
[1503418875852, -2, 0],
[1503418875895, -2, 0],
[1503418875935, -2, 0],
[1503418875941, -4, 0],
[1503418876198, -2, 0],
[1503418876242, -2, 0],
[1503418876270, -4, 0],
[1503418876279, -2, 0],
[1503418876333, -2, 0],
[1503418876342, -2, 0],
[1503418876585, -2, 0],
[1503418876609, -2, 0],
[1503418876623, -2, 0],
[1503418876644, -2, 0],
[1503418876646, -2, 0],
[1503418876678, -2, 0],
[1503418877330, -2, 0],
[1503418877354, -2, 0],
[1503418877368, -2, 0],
[1503418877397, -2, 0],
[1503418877411, -2, 0],
[1503418877748, -2, 0],
[1503418877756, -2, 0],
[1503418877778, -2, 0],
[1503418877793, -2, 0],
[1503418877807, -2, 0],
[1503418878091, -2, 0],
[1503418878133, -2, 0],
[1503418878137, -4, 0],
[1503418878181, -2, 0],
];
const classifier = new MouseWheelClassifier();
for (let i = 0, len = testData.length; i < len; i++) {
const [timestamp, deltaY, deltaX] = testData[i];
classifier.accept(timestamp, deltaX, deltaY);
const actual = classifier.isPhysicalMouseWheel();
assert.equal(actual, true);
}
});
test('Windows - Microsoft basic v2 physical wheel', () => {
const testData: IMouseWheelEvent[] = [
[1503418994564, -2, 0],
[1503418994643, -2, 0],
[1503418994676, -2, 0],
[1503418994691, -2, 0],
[1503418994727, -2, 0],
[1503418994799, -2, 0],
[1503418994850, -2, 0],
[1503418995259, -2, 0],
[1503418995321, -2, 0],
[1503418995328, -2, 0],
[1503418995343, -2, 0],
[1503418995402, -2, 0],
[1503418995454, -2, 0],
[1503418996052, -2, 0],
[1503418996095, -2, 0],
[1503418996107, -2, 0],
[1503418996120, -2, 0],
[1503418996146, -2, 0],
[1503418996471, -2, 0],
[1503418996530, -2, 0],
[1503418996549, -2, 0],
[1503418996561, -2, 0],
[1503418996571, -2, 0],
[1503418996636, -2, 0],
[1503418996936, -2, 0],
[1503418997002, -2, 0],
[1503418997006, -2, 0],
[1503418997043, -2, 0],
[1503418997045, -2, 0],
[1503418997092, -2, 0],
[1503418997357, -2, 0],
[1503418997394, -2, 0],
[1503418997410, -2, 0],
[1503418997426, -2, 0],
[1503418997442, -2, 0],
[1503418997486, -2, 0],
[1503418997757, -2, 0],
[1503418997807, -2, 0],
[1503418997813, -2, 0],
[1503418997850, -2, 0],
];
const classifier = new MouseWheelClassifier();
for (let i = 0, len = testData.length; i < len; i++) {
const [timestamp, deltaY, deltaX] = testData[i];
classifier.accept(timestamp, deltaX, deltaY);
const actual = classifier.isPhysicalMouseWheel();
assert.equal(actual, true);
}
});
});

View File

@@ -0,0 +1,66 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import { ScrollbarState } from 'vs/base/browser/ui/scrollbar/scrollbarState';
suite('ScrollbarState', () => {
test('inflates slider size', () => {
let actual = new ScrollbarState(0, 14, 0);
actual.setVisibleSize(339);
actual.setScrollSize(42423);
actual.setScrollPosition(32787);
assert.equal(actual.getArrowSize(), 0);
assert.equal(actual.getScrollPosition(), 32787);
assert.equal(actual.getRectangleLargeSize(), 339);
assert.equal(actual.getRectangleSmallSize(), 14);
assert.equal(actual.isNeeded(), true);
assert.equal(actual.getSliderSize(), 20);
assert.equal(actual.getSliderPosition(), 249);
assert.equal(actual.getSliderCenter(), 259);
assert.equal(actual.getDesiredScrollPositionFromOffset(259), 32849);
actual.setScrollPosition(32849);
assert.equal(actual.getArrowSize(), 0);
assert.equal(actual.getScrollPosition(), 32849);
assert.equal(actual.getRectangleLargeSize(), 339);
assert.equal(actual.getRectangleSmallSize(), 14);
assert.equal(actual.isNeeded(), true);
assert.equal(actual.getSliderSize(), 20);
assert.equal(actual.getSliderPosition(), 249);
assert.equal(actual.getSliderCenter(), 259);
});
test('inflates slider size with arrows', () => {
let actual = new ScrollbarState(12, 14, 0);
actual.setVisibleSize(339);
actual.setScrollSize(42423);
actual.setScrollPosition(32787);
assert.equal(actual.getArrowSize(), 12);
assert.equal(actual.getScrollPosition(), 32787);
assert.equal(actual.getRectangleLargeSize(), 339);
assert.equal(actual.getRectangleSmallSize(), 14);
assert.equal(actual.isNeeded(), true);
assert.equal(actual.getSliderSize(), 20);
assert.equal(actual.getSliderPosition(), 230);
assert.equal(actual.getSliderCenter(), 240);
assert.equal(actual.getDesiredScrollPositionFromOffset(240 + 12), 32811);
actual.setScrollPosition(32811);
assert.equal(actual.getArrowSize(), 12);
assert.equal(actual.getScrollPosition(), 32811);
assert.equal(actual.getRectangleLargeSize(), 339);
assert.equal(actual.getRectangleSmallSize(), 14);
assert.equal(actual.isNeeded(), true);
assert.equal(actual.getSliderSize(), 20);
assert.equal(actual.getSliderPosition(), 230);
assert.equal(actual.getSliderCenter(), 240);
});
});

View File

@@ -0,0 +1,78 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import { Action, IAction, isAction } from 'vs/base/common/actions';
suite('Actions', () => {
test('isAction', function () {
assert(isAction(new Action('id', 'label', 'style', true, function () { return null; })));
assert(isAction(<IAction>{
id: 'id',
label: 'label',
class: 'style',
checked: true,
enabled: true,
run: function () { return null; }
}));
assert(!isAction({
// id: 'id',
label: 'label',
class: 'style',
checked: true,
enabled: true,
run: function () { return null; }
}));
assert(!isAction({
id: 1234,
label: 'label',
class: 'style',
checked: true,
enabled: true,
run: function () { return null; }
}));
assert(!isAction({
id: 'id',
label: 'label',
class: 'style',
checked: 1,
enabled: 1,
run: function () { return null; }
}));
assert(!isAction(null));
assert(!isAction({
id: 'id',
label: 'label',
// class: 'style',
checked: true,
enabled: true,
// run: function() { return null; }
}));
assert(!isAction({
id: 'id',
label: 42,
class: 'style',
checked: true,
enabled: true,
}));
assert(!isAction({
id: 'id',
label: 'label',
class: 'style',
checked: 'checked',
enabled: true,
}));
assert(!isAction({
id: 'id',
label: 'label',
class: 'style',
checked: true,
enabled: true,
run: true
}));
});
});

View File

@@ -0,0 +1,175 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import arrays = require('vs/base/common/arrays');
suite('Arrays', () => {
test('findFirst', function () {
const array = [1, 4, 5, 7, 55, 59, 60, 61, 64, 69];
let idx = arrays.findFirst(array, e => e >= 0);
assert.equal(array[idx], 1);
idx = arrays.findFirst(array, e => e > 1);
assert.equal(array[idx], 4);
idx = arrays.findFirst(array, e => e >= 8);
assert.equal(array[idx], 55);
idx = arrays.findFirst(array, e => e >= 61);
assert.equal(array[idx], 61);
idx = arrays.findFirst(array, e => e >= 69);
assert.equal(array[idx], 69);
idx = arrays.findFirst(array, e => e >= 70);
assert.equal(idx, array.length);
idx = arrays.findFirst([], e => e >= 0);
assert.equal(array[idx], 1);
});
test('stableSort', function () {
let counter = 0;
let data = arrays.fill(10000, () => ({ n: 1, m: counter++ }));
arrays.mergeSort(data, (a, b) => a.n - b.n);
let lastM = -1;
for (const element of data) {
assert.ok(lastM < element.m);
lastM = element.m;
}
});
test('mergeSort', function () {
let data = arrays.mergeSort([6, 5, 3, 1, 8, 7, 2, 4], (a, b) => a - b);
assert.deepEqual(data, [1, 2, 3, 4, 5, 6, 7, 8]);
});
test('mergeSort, is stable', function () {
let numbers = arrays.mergeSort([33, 22, 11, 4, 99, 1], (a, b) => 0);
assert.deepEqual(numbers, [33, 22, 11, 4, 99, 1]);
});
test('mergeSort, many random numbers', function () {
function compare(a: number, b: number) {
if (a < b) {
return -1;
} else if (a > b) {
return 1;
} else {
return 0;
}
}
function assertSorted(array: number[]) {
let last = array[0];
for (let i = 1; i < array.length; i++) {
let n = array[i];
if (last > n) {
assert.fail(array.slice(i - 10, i + 10));
}
}
}
const MAX = 101;
const data: number[][] = [];
for (let i = 1; i < MAX; i++) {
let array: number[] = [];
for (let j = 0; j < 10 + i; j++) {
array.push(Math.random() * 10e8 | 0);
}
data.push(array);
}
for (const array of data) {
arrays.mergeSort(array, compare);
assertSorted(array);
}
});
test('delta', function () {
function compare(a: number, b: number): number {
return a - b;
}
let d = arrays.delta([1, 2, 4], [], compare);
assert.deepEqual(d.removed, [1, 2, 4]);
assert.deepEqual(d.added, []);
d = arrays.delta([], [1, 2, 4], compare);
assert.deepEqual(d.removed, []);
assert.deepEqual(d.added, [1, 2, 4]);
d = arrays.delta([1, 2, 4], [1, 2, 4], compare);
assert.deepEqual(d.removed, []);
assert.deepEqual(d.added, []);
d = arrays.delta([1, 2, 4], [2, 3, 4, 5], compare);
assert.deepEqual(d.removed, [1]);
assert.deepEqual(d.added, [3, 5]);
d = arrays.delta([2, 3, 4, 5], [1, 2, 4], compare);
assert.deepEqual(d.removed, [3, 5]);
assert.deepEqual(d.added, [1]);
d = arrays.delta([1, 3, 5, 7], [5, 9, 11], compare);
assert.deepEqual(d.removed, [1, 3, 7]);
assert.deepEqual(d.added, [9, 11]);
d = arrays.delta([1, 3, 7], [5, 9, 11], compare);
assert.deepEqual(d.removed, [1, 3, 7]);
assert.deepEqual(d.added, [5, 9, 11]);
});
test('binarySearch', function () {
function compare(a: number, b: number): number {
return a - b;
}
const array = [1, 4, 5, 7, 55, 59, 60, 61, 64, 69];
assert.equal(arrays.binarySearch(array, 1, compare), 0);
assert.equal(arrays.binarySearch(array, 5, compare), 2);
// insertion point
assert.equal(arrays.binarySearch(array, 0, compare), ~0);
assert.equal(arrays.binarySearch(array, 6, compare), ~3);
assert.equal(arrays.binarySearch(array, 70, compare), ~10);
});
test('distinct', function () {
function compare(a: string): string {
return a;
}
assert.deepEqual(arrays.distinct(['32', '4', '5'], compare), ['32', '4', '5']);
assert.deepEqual(arrays.distinct(['32', '4', '5', '4'], compare), ['32', '4', '5']);
assert.deepEqual(arrays.distinct(['32', 'constructor', '5', '1'], compare), ['32', 'constructor', '5', '1']);
assert.deepEqual(arrays.distinct(['32', 'constructor', 'proto', 'proto', 'constructor'], compare), ['32', 'constructor', 'proto']);
assert.deepEqual(arrays.distinct(['32', '4', '5', '32', '4', '5', '32', '4', '5', '5'], compare), ['32', '4', '5']);
});
test('top', function () {
const cmp = (a, b) => {
assert.strictEqual(typeof a, 'number', 'typeof a');
assert.strictEqual(typeof b, 'number', 'typeof b');
return a - b;
};
assert.deepEqual(arrays.top([], cmp, 1), []);
assert.deepEqual(arrays.top([1], cmp, 0), []);
assert.deepEqual(arrays.top([1, 2], cmp, 1), [1]);
assert.deepEqual(arrays.top([2, 1], cmp, 1), [1]);
assert.deepEqual(arrays.top([1, 3, 2], cmp, 2), [1, 2]);
assert.deepEqual(arrays.top([3, 2, 1], cmp, 3), [1, 2, 3]);
assert.deepEqual(arrays.top([4, 6, 2, 7, 8, 3, 5, 1], cmp, 3), [1, 2, 3]);
});
});

View File

@@ -0,0 +1,35 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import { ok } from 'vs/base/common/assert';
suite('Assert', () => {
test('ok', function () {
assert.throws(function () {
ok(false);
});
assert.throws(function () {
ok(null);
});
assert.throws(function () {
ok();
});
assert.throws(function () {
ok(null, 'Foo Bar');
}, function (e) {
return e.message.indexOf('Foo Bar') >= 0;
});
ok(true);
ok('foo');
ok({});
ok(5);
});
});

View File

@@ -0,0 +1,572 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import { Promise, TPromise } from 'vs/base/common/winjs.base';
import Async = require('vs/base/common/async');
suite('Async', () => {
test('Throttler - non async', function (done) {
let count = 0;
let factory = () => {
return TPromise.as(++count);
};
let throttler = new Async.Throttler();
Promise.join([
throttler.queue(factory).then((result) => { assert.equal(result, 1); }),
throttler.queue(factory).then((result) => { assert.equal(result, 2); }),
throttler.queue(factory).then((result) => { assert.equal(result, 3); }),
throttler.queue(factory).then((result) => { assert.equal(result, 4); }),
throttler.queue(factory).then((result) => { assert.equal(result, 5); })
]).done(() => done());
});
test('Throttler', function (done) {
let count = 0;
let factory = () => {
return TPromise.timeout(0).then(() => {
return ++count;
});
};
let throttler = new Async.Throttler();
Promise.join([
throttler.queue(factory).then((result) => { assert.equal(result, 1); }),
throttler.queue(factory).then((result) => { assert.equal(result, 2); }),
throttler.queue(factory).then((result) => { assert.equal(result, 2); }),
throttler.queue(factory).then((result) => { assert.equal(result, 2); }),
throttler.queue(factory).then((result) => { assert.equal(result, 2); })
]).done(() => {
Promise.join([
throttler.queue(factory).then((result) => { assert.equal(result, 3); }),
throttler.queue(factory).then((result) => { assert.equal(result, 4); }),
throttler.queue(factory).then((result) => { assert.equal(result, 4); }),
throttler.queue(factory).then((result) => { assert.equal(result, 4); }),
throttler.queue(factory).then((result) => { assert.equal(result, 4); })
]).done(() => done());
});
});
test('Throttler - cancel should not cancel other promises', function (done) {
let count = 0;
let factory = () => {
return TPromise.timeout(0).then(() => {
return ++count;
});
};
let throttler = new Async.Throttler();
let p1: Promise;
Promise.join([
p1 = throttler.queue(factory).then((result) => { assert(false, 'should not be here, 1'); }, () => { assert(true, 'yes, it was cancelled'); }),
throttler.queue(factory).then((result) => { assert.equal(result, 1); }, () => { assert(false, 'should not be here, 2'); }),
throttler.queue(factory).then((result) => { assert.equal(result, 1); }, () => { assert(false, 'should not be here, 3'); }),
throttler.queue(factory).then((result) => { assert.equal(result, 1); }, () => { assert(false, 'should not be here, 4'); })
]).done(() => done());
p1.cancel();
});
test('Throttler - cancel the first queued promise should not cancel other promises', function (done) {
let count = 0;
let factory = () => {
return TPromise.timeout(0).then(() => {
return ++count;
});
};
let throttler = new Async.Throttler();
let p2: Promise;
Promise.join([
throttler.queue(factory).then((result) => { assert.equal(result, 1); }, () => { assert(false, 'should not be here, 1'); }),
p2 = throttler.queue(factory).then((result) => { assert(false, 'should not be here, 2'); }, () => { assert(true, 'yes, it was cancelled'); }),
throttler.queue(factory).then((result) => { assert.equal(result, 2); }, () => { assert(false, 'should not be here, 3'); }),
throttler.queue(factory).then((result) => { assert.equal(result, 2); }, () => { assert(false, 'should not be here, 4'); })
]).done(() => done());
p2.cancel();
});
test('Throttler - cancel in the middle should not cancel other promises', function (done) {
let count = 0;
let factory = () => {
return TPromise.timeout(0).then(() => {
return ++count;
});
};
let throttler = new Async.Throttler();
let p3: Promise;
Promise.join([
throttler.queue(factory).then((result) => { assert.equal(result, 1); }, () => { assert(false, 'should not be here, 1'); }),
throttler.queue(factory).then((result) => { assert.equal(result, 2); }, () => { assert(false, 'should not be here, 2'); }),
p3 = throttler.queue(factory).then((result) => { assert(false, 'should not be here, 3'); }, () => { assert(true, 'yes, it was cancelled'); }),
throttler.queue(factory).then((result) => { assert.equal(result, 2); }, () => { assert(false, 'should not be here, 4'); })
]).done(() => done());
p3.cancel();
});
test('Throttler - last factory should be the one getting called', function (done) {
let factoryFactory = (n: number) => () => {
return TPromise.timeout(0).then(() => n);
};
let throttler = new Async.Throttler();
let promises: Promise[] = [];
promises.push(throttler.queue(factoryFactory(1)).then((n) => { assert.equal(n, 1); }));
promises.push(throttler.queue(factoryFactory(2)).then((n) => { assert.equal(n, 3); }));
promises.push(throttler.queue(factoryFactory(3)).then((n) => { assert.equal(n, 3); }));
Promise.join(promises).done(() => done());
});
test('Throttler - progress should work', function (done) {
let order = 0;
let factory = () => new TPromise((c, e, p) => {
TPromise.timeout(0).done(() => {
p(order++);
c(true);
});
});
let throttler = new Async.Throttler();
let promises: Promise[] = [];
let progresses: any[][] = [[], [], []];
promises.push(throttler.queue(factory).then(null, null, (p) => progresses[0].push(p)));
promises.push(throttler.queue(factory).then(null, null, (p) => progresses[1].push(p)));
promises.push(throttler.queue(factory).then(null, null, (p) => progresses[2].push(p)));
Promise.join(promises).done(() => {
assert.deepEqual(progresses[0], [0]);
assert.deepEqual(progresses[1], [0]);
assert.deepEqual(progresses[2], [0]);
done();
});
});
test('Delayer', function (done) {
let count = 0;
let factory = () => {
return TPromise.as(++count);
};
let delayer = new Async.Delayer(0);
let promises: Promise[] = [];
assert(!delayer.isTriggered());
promises.push(delayer.trigger(factory).then((result) => { assert.equal(result, 1); assert(!delayer.isTriggered()); }));
assert(delayer.isTriggered());
promises.push(delayer.trigger(factory).then((result) => { assert.equal(result, 1); assert(!delayer.isTriggered()); }));
assert(delayer.isTriggered());
promises.push(delayer.trigger(factory).then((result) => { assert.equal(result, 1); assert(!delayer.isTriggered()); }));
assert(delayer.isTriggered());
Promise.join(promises).done(() => {
assert(!delayer.isTriggered());
done();
});
});
test('Delayer - simple cancel', function (done) {
let count = 0;
let factory = () => {
return TPromise.as(++count);
};
let delayer = new Async.Delayer(0);
assert(!delayer.isTriggered());
delayer.trigger(factory).then(() => {
assert(false);
}, () => {
assert(true, 'yes, it was cancelled');
}).done(() => done());
assert(delayer.isTriggered());
delayer.cancel();
assert(!delayer.isTriggered());
});
test('Delayer - cancel should cancel all calls to trigger', function (done) {
let count = 0;
let factory = () => {
return TPromise.as(++count);
};
let delayer = new Async.Delayer(0);
let promises: Promise[] = [];
assert(!delayer.isTriggered());
promises.push(delayer.trigger(factory).then(null, () => { assert(true, 'yes, it was cancelled'); }));
assert(delayer.isTriggered());
promises.push(delayer.trigger(factory).then(null, () => { assert(true, 'yes, it was cancelled'); }));
assert(delayer.isTriggered());
promises.push(delayer.trigger(factory).then(null, () => { assert(true, 'yes, it was cancelled'); }));
assert(delayer.isTriggered());
delayer.cancel();
Promise.join(promises).done(() => {
assert(!delayer.isTriggered());
done();
});
});
test('Delayer - trigger, cancel, then trigger again', function (done) {
let count = 0;
let factory = () => {
return TPromise.as(++count);
};
let delayer = new Async.Delayer(0);
let promises: Promise[] = [];
assert(!delayer.isTriggered());
delayer.trigger(factory).then((result) => {
assert.equal(result, 1);
assert(!delayer.isTriggered());
promises.push(delayer.trigger(factory).then(null, () => { assert(true, 'yes, it was cancelled'); }));
assert(delayer.isTriggered());
promises.push(delayer.trigger(factory).then(null, () => { assert(true, 'yes, it was cancelled'); }));
assert(delayer.isTriggered());
delayer.cancel();
Promise.join(promises).then(() => {
promises = [];
assert(!delayer.isTriggered());
promises.push(delayer.trigger(factory).then(() => { assert.equal(result, 1); assert(!delayer.isTriggered()); }));
assert(delayer.isTriggered());
promises.push(delayer.trigger(factory).then(() => { assert.equal(result, 1); assert(!delayer.isTriggered()); }));
assert(delayer.isTriggered());
Promise.join(promises).then(() => {
assert(!delayer.isTriggered());
done();
});
assert(delayer.isTriggered());
});
assert(delayer.isTriggered());
});
assert(delayer.isTriggered());
});
test('Delayer - last task should be the one getting called', function (done) {
let factoryFactory = (n: number) => () => {
return TPromise.as(n);
};
let delayer = new Async.Delayer(0);
let promises: Promise[] = [];
assert(!delayer.isTriggered());
promises.push(delayer.trigger(factoryFactory(1)).then((n) => { assert.equal(n, 3); }));
promises.push(delayer.trigger(factoryFactory(2)).then((n) => { assert.equal(n, 3); }));
promises.push(delayer.trigger(factoryFactory(3)).then((n) => { assert.equal(n, 3); }));
Promise.join(promises).then(() => {
assert(!delayer.isTriggered());
done();
});
assert(delayer.isTriggered());
});
test('Delayer - progress should work', function (done) {
let order = 0;
let factory = () => new TPromise((c, e, p) => {
TPromise.timeout(0).done(() => {
p(order++);
c(true);
});
});
let delayer = new Async.Delayer(0);
let promises: Promise[] = [];
let progresses: any[][] = [[], [], []];
promises.push(delayer.trigger(factory).then(null, null, (p) => progresses[0].push(p)));
promises.push(delayer.trigger(factory).then(null, null, (p) => progresses[1].push(p)));
promises.push(delayer.trigger(factory).then(null, null, (p) => progresses[2].push(p)));
Promise.join(promises).done(() => {
assert.deepEqual(progresses[0], [0]);
assert.deepEqual(progresses[1], [0]);
assert.deepEqual(progresses[2], [0]);
done();
});
});
test('ThrottledDelayer - progress should work', function (done) {
let order = 0;
let factory = () => new TPromise((c, e, p) => {
TPromise.timeout(0).done(() => {
p(order++);
c(true);
});
});
let delayer = new Async.ThrottledDelayer(0);
let promises: Promise[] = [];
let progresses: any[][] = [[], [], []];
promises.push(delayer.trigger(factory).then(null, null, (p) => progresses[0].push(p)));
promises.push(delayer.trigger(factory).then(null, null, (p) => progresses[1].push(p)));
promises.push(delayer.trigger(factory).then(null, null, (p) => progresses[2].push(p)));
Promise.join(promises).done(() => {
assert.deepEqual(progresses[0], [0]);
assert.deepEqual(progresses[1], [0]);
assert.deepEqual(progresses[2], [0]);
done();
});
});
test('Sequence', function (done) {
let factoryFactory = (n: number) => () => {
return TPromise.as(n);
};
Async.sequence([
factoryFactory(1),
factoryFactory(2),
factoryFactory(3),
factoryFactory(4),
factoryFactory(5),
]).then((result) => {
assert.equal(5, result.length);
assert.equal(1, result[0]);
assert.equal(2, result[1]);
assert.equal(3, result[2]);
assert.equal(4, result[3]);
assert.equal(5, result[4]);
done();
});
});
test('Limiter - sync', function (done) {
let factoryFactory = (n: number) => () => {
return TPromise.as(n);
};
let limiter = new Async.Limiter(1);
let promises: Promise[] = [];
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].forEach(n => promises.push(limiter.queue(factoryFactory(n))));
Promise.join(promises).then((res) => {
assert.equal(10, res.length);
limiter = new Async.Limiter(100);
promises = [];
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].forEach(n => promises.push(limiter.queue(factoryFactory(n))));
return Promise.join(promises).then((res) => {
assert.equal(10, res.length);
});
}).done(() => done());
});
test('Limiter - async', function (done) {
let factoryFactory = (n: number) => () => {
return TPromise.timeout(0).then(() => n);
};
let limiter = new Async.Limiter(1);
let promises: Promise[] = [];
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].forEach(n => promises.push(limiter.queue(factoryFactory(n))));
Promise.join(promises).then((res) => {
assert.equal(10, res.length);
limiter = new Async.Limiter(100);
promises = [];
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].forEach(n => promises.push(limiter.queue(factoryFactory(n))));
Promise.join(promises).then((res) => {
assert.equal(10, res.length);
});
}).done(() => done());
});
test('Limiter - assert degree of paralellism', function (done) {
let activePromises = 0;
let factoryFactory = (n: number) => () => {
activePromises++;
assert(activePromises < 6);
return TPromise.timeout(0).then(() => { activePromises--; return n; });
};
let limiter = new Async.Limiter(5);
let promises: Promise[] = [];
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].forEach(n => promises.push(limiter.queue(factoryFactory(n))));
Promise.join(promises).then((res) => {
assert.equal(10, res.length);
assert.deepEqual([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], res);
done();
});
});
test('Queue - simple', function (done) {
let queue = new Async.Queue();
let syncPromise = false;
let f1 = () => TPromise.as(true).then(() => syncPromise = true);
let asyncPromise = false;
let f2 = () => TPromise.timeout(10).then(() => asyncPromise = true);
queue.queue(f1);
queue.queue(f2).then(() => {
assert.ok(syncPromise);
assert.ok(asyncPromise);
done();
});
});
test('Queue - order is kept', function (done) {
let queue = new Async.Queue();
let res = [];
let f1 = () => TPromise.as(true).then(() => res.push(1));
let f2 = () => TPromise.timeout(10).then(() => res.push(2));
let f3 = () => TPromise.as(true).then(() => res.push(3));
let f4 = () => TPromise.timeout(20).then(() => res.push(4));
let f5 = () => TPromise.timeout(0).then(() => res.push(5));
queue.queue(f1);
queue.queue(f2);
queue.queue(f3);
queue.queue(f4);
queue.queue(f5).then(() => {
assert.equal(res[0], 1);
assert.equal(res[1], 2);
assert.equal(res[2], 3);
assert.equal(res[3], 4);
assert.equal(res[4], 5);
done();
});
});
test('Queue - errors bubble individually but not cause stop', function (done) {
let queue = new Async.Queue();
let res = [];
let error = false;
let f1 = () => TPromise.as(true).then(() => res.push(1));
let f2 = () => TPromise.timeout(10).then(() => res.push(2));
let f3 = () => TPromise.as(true).then(() => TPromise.wrapError(new Error('error')));
let f4 = () => TPromise.timeout(20).then(() => res.push(4));
let f5 = () => TPromise.timeout(0).then(() => res.push(5));
queue.queue(f1);
queue.queue(f2);
queue.queue(f3).then(null, () => error = true);
queue.queue(f4);
queue.queue(f5).then(() => {
assert.equal(res[0], 1);
assert.equal(res[1], 2);
assert.ok(error);
assert.equal(res[2], 4);
assert.equal(res[3], 5);
done();
});
});
test('Queue - order is kept (chained)', function (done) {
let queue = new Async.Queue();
let res = [];
let f1 = () => TPromise.as(true).then(() => res.push(1));
let f2 = () => TPromise.timeout(10).then(() => res.push(2));
let f3 = () => TPromise.as(true).then(() => res.push(3));
let f4 = () => TPromise.timeout(20).then(() => res.push(4));
let f5 = () => TPromise.timeout(0).then(() => res.push(5));
queue.queue(f1).then(() => {
queue.queue(f2).then(() => {
queue.queue(f3).then(() => {
queue.queue(f4).then(() => {
queue.queue(f5).then(() => {
assert.equal(res[0], 1);
assert.equal(res[1], 2);
assert.equal(res[2], 3);
assert.equal(res[3], 4);
assert.equal(res[4], 5);
done();
});
});
});
});
});
});
test('Queue - events', function (done) {
let queue = new Async.Queue();
let finished = false;
queue.onFinished(() => {
done();
});
let res = [];
let f1 = () => TPromise.timeout(10).then(() => res.push(2));
let f2 = () => TPromise.timeout(20).then(() => res.push(4));
let f3 = () => TPromise.timeout(0).then(() => res.push(5));
const q1 = queue.queue(f1);
const q2 = queue.queue(f2);
queue.queue(f3);
q1.then(() => {
assert.ok(!finished);
q2.then(() => {
assert.ok(!finished);
});
});
});
});

View File

@@ -0,0 +1,66 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import Cache from 'vs/base/common/cache';
import { TPromise } from 'vs/base/common/winjs.base';
suite('Cache', () => {
test('simple value', () => {
let counter = 0;
const cache = new Cache(() => TPromise.as(counter++));
return cache.get()
.then(c => assert.equal(c, 0), () => assert.fail())
.then(() => cache.get())
.then(c => assert.equal(c, 0), () => assert.fail());
});
test('simple error', () => {
let counter = 0;
const cache = new Cache(() => TPromise.wrapError(new Error(String(counter++))));
return cache.get()
.then(() => assert.fail(), err => assert.equal(err.message, 0))
.then(() => cache.get())
.then(() => assert.fail(), err => assert.equal(err.message, 0));
});
test('should retry cancellations', () => {
let counter1 = 0, counter2 = 0;
const cache = new Cache(() => {
counter1++;
return TPromise.timeout(1).then(() => counter2++);
});
assert.equal(counter1, 0);
assert.equal(counter2, 0);
let promise = cache.get();
assert.equal(counter1, 1);
assert.equal(counter2, 0);
promise.cancel();
assert.equal(counter1, 1);
assert.equal(counter2, 0);
promise = cache.get();
assert.equal(counter1, 2);
assert.equal(counter2, 0);
return promise
.then(c => {
assert.equal(counter1, 2);
assert.equal(counter2, 1);
})
.then(() => cache.get())
.then(c => {
assert.equal(counter1, 2);
assert.equal(counter2, 1);
});
});
});

View File

@@ -0,0 +1,85 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import { CancellationTokenSource, CancellationToken } from 'vs/base/common/cancellation';
suite('CancellationToken', function () {
test('None', function () {
assert.equal(CancellationToken.None.isCancellationRequested, false);
assert.equal(typeof CancellationToken.None.onCancellationRequested, 'function');
});
test('cancel before token', function (done) {
const source = new CancellationTokenSource();
assert.equal(source.token.isCancellationRequested, false);
source.cancel();
assert.equal(source.token.isCancellationRequested, true);
source.token.onCancellationRequested(function () {
assert.ok(true);
done();
});
});
test('cancel happens only once', function () {
let source = new CancellationTokenSource();
assert.equal(source.token.isCancellationRequested, false);
let cancelCount = 0;
function onCancel() {
cancelCount += 1;
}
source.token.onCancellationRequested(onCancel);
source.cancel();
source.cancel();
assert.equal(cancelCount, 1);
});
test('cancel calls all listeners', function () {
let count = 0;
let source = new CancellationTokenSource();
source.token.onCancellationRequested(function () {
count += 1;
});
source.token.onCancellationRequested(function () {
count += 1;
});
source.token.onCancellationRequested(function () {
count += 1;
});
source.cancel();
assert.equal(count, 3);
});
test('token stays the same', function () {
let source = new CancellationTokenSource();
let token = source.token;
assert.ok(token === source.token); // doesn't change on get
source.cancel();
assert.ok(token === source.token); // doesn't change after cancel
source.cancel();
assert.ok(token === source.token); // doesn't change after 2nd cancel
source = new CancellationTokenSource();
source.cancel();
token = source.token;
assert.ok(token === source.token); // doesn't change on get
});
});

View File

@@ -0,0 +1,122 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import { CharCode } from 'vs/base/common/charCode';
suite('CharCode', () => {
test('has good values', () => {
function assertValue(actual: CharCode, expected: string): void {
assert.equal(actual, expected.charCodeAt(0), 'char code ok for <<' + expected + '>>');
}
assertValue(CharCode.Tab, '\t');
assertValue(CharCode.LineFeed, '\n');
assertValue(CharCode.CarriageReturn, '\r');
assertValue(CharCode.Space, ' ');
assertValue(CharCode.ExclamationMark, '!');
assertValue(CharCode.DoubleQuote, '"');
assertValue(CharCode.Hash, '#');
assertValue(CharCode.DollarSign, '$');
assertValue(CharCode.PercentSign, '%');
assertValue(CharCode.Ampersand, '&');
assertValue(CharCode.SingleQuote, '\'');
assertValue(CharCode.OpenParen, '(');
assertValue(CharCode.CloseParen, ')');
assertValue(CharCode.Asterisk, '*');
assertValue(CharCode.Plus, '+');
assertValue(CharCode.Comma, ',');
assertValue(CharCode.Dash, '-');
assertValue(CharCode.Period, '.');
assertValue(CharCode.Slash, '/');
assertValue(CharCode.Digit0, '0');
assertValue(CharCode.Digit1, '1');
assertValue(CharCode.Digit2, '2');
assertValue(CharCode.Digit3, '3');
assertValue(CharCode.Digit4, '4');
assertValue(CharCode.Digit5, '5');
assertValue(CharCode.Digit6, '6');
assertValue(CharCode.Digit7, '7');
assertValue(CharCode.Digit8, '8');
assertValue(CharCode.Digit9, '9');
assertValue(CharCode.Colon, ':');
assertValue(CharCode.Semicolon, ';');
assertValue(CharCode.LessThan, '<');
assertValue(CharCode.Equals, '=');
assertValue(CharCode.GreaterThan, '>');
assertValue(CharCode.QuestionMark, '?');
assertValue(CharCode.AtSign, '@');
assertValue(CharCode.A, 'A');
assertValue(CharCode.B, 'B');
assertValue(CharCode.C, 'C');
assertValue(CharCode.D, 'D');
assertValue(CharCode.E, 'E');
assertValue(CharCode.F, 'F');
assertValue(CharCode.G, 'G');
assertValue(CharCode.H, 'H');
assertValue(CharCode.I, 'I');
assertValue(CharCode.J, 'J');
assertValue(CharCode.K, 'K');
assertValue(CharCode.L, 'L');
assertValue(CharCode.M, 'M');
assertValue(CharCode.N, 'N');
assertValue(CharCode.O, 'O');
assertValue(CharCode.P, 'P');
assertValue(CharCode.Q, 'Q');
assertValue(CharCode.R, 'R');
assertValue(CharCode.S, 'S');
assertValue(CharCode.T, 'T');
assertValue(CharCode.U, 'U');
assertValue(CharCode.V, 'V');
assertValue(CharCode.W, 'W');
assertValue(CharCode.X, 'X');
assertValue(CharCode.Y, 'Y');
assertValue(CharCode.Z, 'Z');
assertValue(CharCode.OpenSquareBracket, '[');
assertValue(CharCode.Backslash, '\\');
assertValue(CharCode.CloseSquareBracket, ']');
assertValue(CharCode.Caret, '^');
assertValue(CharCode.Underline, '_');
assertValue(CharCode.BackTick, '`');
assertValue(CharCode.a, 'a');
assertValue(CharCode.b, 'b');
assertValue(CharCode.c, 'c');
assertValue(CharCode.d, 'd');
assertValue(CharCode.e, 'e');
assertValue(CharCode.f, 'f');
assertValue(CharCode.g, 'g');
assertValue(CharCode.h, 'h');
assertValue(CharCode.i, 'i');
assertValue(CharCode.j, 'j');
assertValue(CharCode.k, 'k');
assertValue(CharCode.l, 'l');
assertValue(CharCode.m, 'm');
assertValue(CharCode.n, 'n');
assertValue(CharCode.o, 'o');
assertValue(CharCode.p, 'p');
assertValue(CharCode.q, 'q');
assertValue(CharCode.r, 'r');
assertValue(CharCode.s, 's');
assertValue(CharCode.t, 't');
assertValue(CharCode.u, 'u');
assertValue(CharCode.v, 'v');
assertValue(CharCode.w, 'w');
assertValue(CharCode.x, 'x');
assertValue(CharCode.y, 'y');
assertValue(CharCode.z, 'z');
assertValue(CharCode.OpenCurlyBrace, '{');
assertValue(CharCode.Pipe, '|');
assertValue(CharCode.CloseCurlyBrace, '}');
assertValue(CharCode.Tilde, '~');
});
});

View File

@@ -0,0 +1,64 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import collections = require('vs/base/common/collections');
suite('Collections', () => {
test('forEach', () => {
collections.forEach({}, () => assert(false));
collections.forEach(Object.create(null), () => assert(false));
let count = 0;
collections.forEach({ toString: 123 }, () => count++);
assert.equal(count, 1);
count = 0;
let dict = Object.create(null);
dict['toString'] = 123;
collections.forEach(dict, () => count++);
assert.equal(count, 1);
collections.forEach(dict, () => false);
collections.forEach(dict, (x, remove) => remove());
assert.equal(dict['toString'], null);
// don't iterate over properties that are not on the object itself
let test = Object.create({ 'derived': true });
collections.forEach(test, () => assert(false));
});
test('groupBy', () => {
const group1 = 'a', group2 = 'b';
const value1 = 1, value2 = 2, value3 = 3;
let source = [
{ key: group1, value: value1 },
{ key: group1, value: value2 },
{ key: group2, value: value3 },
];
let grouped = collections.groupBy(source, x => x.key);
// Group 1
assert.equal(grouped[group1].length, 2);
assert.equal(grouped[group1][0].value, value1);
assert.equal(grouped[group1][1].value, value2);
// Group 2
assert.equal(grouped[group2].length, 1);
assert.equal(grouped[group2][0].value, value3);
});
test('remove', () => {
assert(collections.remove({ 'far': 1 }, 'far'));
assert(!collections.remove({ 'far': 1 }, 'boo'));
});
});

View File

@@ -0,0 +1,242 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import { Color, RGBA, HSLA, HSVA } from 'vs/base/common/color';
suite('Color', () => {
test('isLighterColor', function () {
let color1 = new Color(new HSLA(60, 1, 0.5, 1)), color2 = new Color(new HSLA(0, 0, 0.753, 1));
assert.ok(color1.isLighterThan(color2));
// Abyss theme
assert.ok(Color.fromHex('#770811').isLighterThan(Color.fromHex('#000c18')));
});
test('getLighterColor', function () {
let color1 = new Color(new HSLA(60, 1, 0.5, 1)), color2 = new Color(new HSLA(0, 0, 0.753, 1));
assert.deepEqual(color1.hsla, Color.getLighterColor(color1, color2).hsla);
assert.deepEqual(new HSLA(0, 0, 0.916, 1), Color.getLighterColor(color2, color1).hsla);
assert.deepEqual(new HSLA(0, 0, 0.851, 1), Color.getLighterColor(color2, color1, 0.3).hsla);
assert.deepEqual(new HSLA(0, 0, 0.981, 1), Color.getLighterColor(color2, color1, 0.7).hsla);
assert.deepEqual(new HSLA(0, 0, 1, 1), Color.getLighterColor(color2, color1, 1).hsla);
});
test('isDarkerColor', function () {
let color1 = new Color(new HSLA(60, 1, 0.5, 1)), color2 = new Color(new HSLA(0, 0, 0.753, 1));
assert.ok(color2.isDarkerThan(color1));
});
test('getDarkerColor', function () {
let color1 = new Color(new HSLA(60, 1, 0.5, 1)), color2 = new Color(new HSLA(0, 0, 0.753, 1));
assert.deepEqual(color2.hsla, Color.getDarkerColor(color2, color1).hsla);
assert.deepEqual(new HSLA(60, 1, 0.392, 1), Color.getDarkerColor(color1, color2).hsla);
assert.deepEqual(new HSLA(60, 1, 0.435, 1), Color.getDarkerColor(color1, color2, 0.3).hsla);
assert.deepEqual(new HSLA(60, 1, 0.349, 1), Color.getDarkerColor(color1, color2, 0.7).hsla);
assert.deepEqual(new HSLA(60, 1, 0.284, 1), Color.getDarkerColor(color1, color2, 1).hsla);
// Abyss theme
assert.deepEqual(new HSLA(355, 0.874, 0.157, 1), Color.getDarkerColor(Color.fromHex('#770811'), Color.fromHex('#000c18'), 0.4).hsla);
});
test('luminance', function () {
assert.deepEqual(0, new Color(new RGBA(0, 0, 0, 1)).getRelativeLuminance());
assert.deepEqual(1, new Color(new RGBA(255, 255, 255, 1)).getRelativeLuminance());
assert.deepEqual(0.2126, new Color(new RGBA(255, 0, 0, 1)).getRelativeLuminance());
assert.deepEqual(0.7152, new Color(new RGBA(0, 255, 0, 1)).getRelativeLuminance());
assert.deepEqual(0.0722, new Color(new RGBA(0, 0, 255, 1)).getRelativeLuminance());
assert.deepEqual(0.9278, new Color(new RGBA(255, 255, 0, 1)).getRelativeLuminance());
assert.deepEqual(0.7874, new Color(new RGBA(0, 255, 255, 1)).getRelativeLuminance());
assert.deepEqual(0.2848, new Color(new RGBA(255, 0, 255, 1)).getRelativeLuminance());
assert.deepEqual(0.5271, new Color(new RGBA(192, 192, 192, 1)).getRelativeLuminance());
assert.deepEqual(0.2159, new Color(new RGBA(128, 128, 128, 1)).getRelativeLuminance());
assert.deepEqual(0.0459, new Color(new RGBA(128, 0, 0, 1)).getRelativeLuminance());
assert.deepEqual(0.2003, new Color(new RGBA(128, 128, 0, 1)).getRelativeLuminance());
assert.deepEqual(0.1544, new Color(new RGBA(0, 128, 0, 1)).getRelativeLuminance());
assert.deepEqual(0.0615, new Color(new RGBA(128, 0, 128, 1)).getRelativeLuminance());
assert.deepEqual(0.17, new Color(new RGBA(0, 128, 128, 1)).getRelativeLuminance());
assert.deepEqual(0.0156, new Color(new RGBA(0, 0, 128, 1)).getRelativeLuminance());
});
test('blending', function () {
assert.deepEqual(new Color(new RGBA(0, 0, 0, 0)).blend(new Color(new RGBA(243, 34, 43))), new Color(new RGBA(243, 34, 43)));
assert.deepEqual(new Color(new RGBA(255, 255, 255)).blend(new Color(new RGBA(243, 34, 43))), new Color(new RGBA(255, 255, 255)));
assert.deepEqual(new Color(new RGBA(122, 122, 122, 0.7)).blend(new Color(new RGBA(243, 34, 43))), new Color(new RGBA(158, 95, 98)));
assert.deepEqual(new Color(new RGBA(0, 0, 0, 0.58)).blend(new Color(new RGBA(255, 255, 255, 0.33))), new Color(new RGBA(49, 49, 49, 0.719)));
});
suite('HSLA', () => {
test('HSLA.toRGBA', function () {
assert.deepEqual(HSLA.toRGBA(new HSLA(0, 0, 0, 0)), new RGBA(0, 0, 0, 0));
assert.deepEqual(HSLA.toRGBA(new HSLA(0, 0, 0, 1)), new RGBA(0, 0, 0, 1));
assert.deepEqual(HSLA.toRGBA(new HSLA(0, 0, 1, 1)), new RGBA(255, 255, 255, 1));
assert.deepEqual(HSLA.toRGBA(new HSLA(0, 1, 0.5, 1)), new RGBA(255, 0, 0, 1));
assert.deepEqual(HSLA.toRGBA(new HSLA(120, 1, 0.5, 1)), new RGBA(0, 255, 0, 1));
assert.deepEqual(HSLA.toRGBA(new HSLA(240, 1, 0.5, 1)), new RGBA(0, 0, 255, 1));
assert.deepEqual(HSLA.toRGBA(new HSLA(60, 1, 0.5, 1)), new RGBA(255, 255, 0, 1));
assert.deepEqual(HSLA.toRGBA(new HSLA(180, 1, 0.5, 1)), new RGBA(0, 255, 255, 1));
assert.deepEqual(HSLA.toRGBA(new HSLA(300, 1, 0.5, 1)), new RGBA(255, 0, 255, 1));
assert.deepEqual(HSLA.toRGBA(new HSLA(0, 0, 0.753, 1)), new RGBA(192, 192, 192, 1));
assert.deepEqual(HSLA.toRGBA(new HSLA(0, 0, 0.502, 1)), new RGBA(128, 128, 128, 1));
assert.deepEqual(HSLA.toRGBA(new HSLA(0, 1, 0.251, 1)), new RGBA(128, 0, 0, 1));
assert.deepEqual(HSLA.toRGBA(new HSLA(60, 1, 0.251, 1)), new RGBA(128, 128, 0, 1));
assert.deepEqual(HSLA.toRGBA(new HSLA(120, 1, 0.251, 1)), new RGBA(0, 128, 0, 1));
assert.deepEqual(HSLA.toRGBA(new HSLA(300, 1, 0.251, 1)), new RGBA(128, 0, 128, 1));
assert.deepEqual(HSLA.toRGBA(new HSLA(180, 1, 0.251, 1)), new RGBA(0, 128, 128, 1));
assert.deepEqual(HSLA.toRGBA(new HSLA(240, 1, 0.251, 1)), new RGBA(0, 0, 128, 1));
});
test('HSLA.fromRGBA', function () {
assert.deepEqual(HSLA.fromRGBA(new RGBA(0, 0, 0, 0)), new HSLA(0, 0, 0, 0));
assert.deepEqual(HSLA.fromRGBA(new RGBA(0, 0, 0, 1)), new HSLA(0, 0, 0, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(255, 255, 255, 1)), new HSLA(0, 0, 1, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(255, 0, 0, 1)), new HSLA(0, 1, 0.5, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(0, 255, 0, 1)), new HSLA(120, 1, 0.5, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(0, 0, 255, 1)), new HSLA(240, 1, 0.5, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(255, 255, 0, 1)), new HSLA(60, 1, 0.5, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(0, 255, 255, 1)), new HSLA(180, 1, 0.5, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(255, 0, 255, 1)), new HSLA(300, 1, 0.5, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(192, 192, 192, 1)), new HSLA(0, 0, 0.753, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(128, 128, 128, 1)), new HSLA(0, 0, 0.502, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(128, 0, 0, 1)), new HSLA(0, 1, 0.251, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(128, 128, 0, 1)), new HSLA(60, 1, 0.251, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(0, 128, 0, 1)), new HSLA(120, 1, 0.251, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(128, 0, 128, 1)), new HSLA(300, 1, 0.251, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(0, 128, 128, 1)), new HSLA(180, 1, 0.251, 1));
assert.deepEqual(HSLA.fromRGBA(new RGBA(0, 0, 128, 1)), new HSLA(240, 1, 0.251, 1));
});
});
suite('HSVA', () => {
test('HSVA.toRGBA', function () {
assert.deepEqual(HSVA.toRGBA(new HSVA(0, 0, 0, 0)), new RGBA(0, 0, 0, 0));
assert.deepEqual(HSVA.toRGBA(new HSVA(0, 0, 0, 1)), new RGBA(0, 0, 0, 1));
assert.deepEqual(HSVA.toRGBA(new HSVA(0, 0, 1, 1)), new RGBA(255, 255, 255, 1));
assert.deepEqual(HSVA.toRGBA(new HSVA(0, 1, 1, 1)), new RGBA(255, 0, 0, 1));
assert.deepEqual(HSVA.toRGBA(new HSVA(120, 1, 1, 1)), new RGBA(0, 255, 0, 1));
assert.deepEqual(HSVA.toRGBA(new HSVA(240, 1, 1, 1)), new RGBA(0, 0, 255, 1));
assert.deepEqual(HSVA.toRGBA(new HSVA(60, 1, 1, 1)), new RGBA(255, 255, 0, 1));
assert.deepEqual(HSVA.toRGBA(new HSVA(180, 1, 1, 1)), new RGBA(0, 255, 255, 1));
assert.deepEqual(HSVA.toRGBA(new HSVA(300, 1, 1, 1)), new RGBA(255, 0, 255, 1));
assert.deepEqual(HSVA.toRGBA(new HSVA(0, 0, 0.753, 1)), new RGBA(192, 192, 192, 1));
assert.deepEqual(HSVA.toRGBA(new HSVA(0, 0, 0.502, 1)), new RGBA(128, 128, 128, 1));
assert.deepEqual(HSVA.toRGBA(new HSVA(0, 1, 0.502, 1)), new RGBA(128, 0, 0, 1));
assert.deepEqual(HSVA.toRGBA(new HSVA(60, 1, 0.502, 1)), new RGBA(128, 128, 0, 1));
assert.deepEqual(HSVA.toRGBA(new HSVA(120, 1, 0.502, 1)), new RGBA(0, 128, 0, 1));
assert.deepEqual(HSVA.toRGBA(new HSVA(300, 1, 0.502, 1)), new RGBA(128, 0, 128, 1));
assert.deepEqual(HSVA.toRGBA(new HSVA(180, 1, 0.502, 1)), new RGBA(0, 128, 128, 1));
assert.deepEqual(HSVA.toRGBA(new HSVA(240, 1, 0.502, 1)), new RGBA(0, 0, 128, 1));
});
test('HSVA.fromRGBA', () => {
assert.deepEqual(HSVA.fromRGBA(new RGBA(0, 0, 0, 0)), new HSVA(0, 0, 0, 0));
assert.deepEqual(HSVA.fromRGBA(new RGBA(0, 0, 0, 1)), new HSVA(0, 0, 0, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(255, 255, 255, 1)), new HSVA(0, 0, 1, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(255, 0, 0, 1)), new HSVA(0, 1, 1, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(0, 255, 0, 1)), new HSVA(120, 1, 1, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(0, 0, 255, 1)), new HSVA(240, 1, 1, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(255, 255, 0, 1)), new HSVA(60, 1, 1, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(0, 255, 255, 1)), new HSVA(180, 1, 1, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(255, 0, 255, 1)), new HSVA(300, 1, 1, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(192, 192, 192, 1)), new HSVA(0, 0, 0.753, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(128, 128, 128, 1)), new HSVA(0, 0, 0.502, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(128, 0, 0, 1)), new HSVA(0, 1, 0.502, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(128, 128, 0, 1)), new HSVA(60, 1, 0.502, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(0, 128, 0, 1)), new HSVA(120, 1, 0.502, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(128, 0, 128, 1)), new HSVA(300, 1, 0.502, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(0, 128, 128, 1)), new HSVA(180, 1, 0.502, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(0, 0, 128, 1)), new HSVA(240, 1, 0.502, 1));
});
test('Keep hue value when saturation is 0', () => {
assert.deepEqual(HSVA.toRGBA(new HSVA(10, 0, 0, 0)), HSVA.toRGBA(new HSVA(20, 0, 0, 0)));
assert.deepEqual(new Color(new HSVA(10, 0, 0, 0)).rgba, new Color(new HSVA(20, 0, 0, 0)).rgba);
assert.notDeepEqual(new Color(new HSVA(10, 0, 0, 0)).hsva, new Color(new HSVA(20, 0, 0, 0)).hsva);
});
});
suite('Format', () => {
suite('CSS', () => {
test('parseHex', () => {
// invalid
assert.deepEqual(Color.Format.CSS.parseHex(null), null);
assert.deepEqual(Color.Format.CSS.parseHex(''), null);
assert.deepEqual(Color.Format.CSS.parseHex('#'), null);
assert.deepEqual(Color.Format.CSS.parseHex('#0102030'), null);
// somewhat valid
assert.deepEqual(Color.Format.CSS.parseHex('#FFFFG0').rgba, new RGBA(255, 255, 0, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#FFFFg0').rgba, new RGBA(255, 255, 0, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#-FFF00').rgba, new RGBA(15, 255, 0, 1));
// valid
assert.deepEqual(Color.Format.CSS.parseHex('#000000').rgba, new RGBA(0, 0, 0, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#FFFFFF').rgba, new RGBA(255, 255, 255, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#FF0000').rgba, new RGBA(255, 0, 0, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#00FF00').rgba, new RGBA(0, 255, 0, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#0000FF').rgba, new RGBA(0, 0, 255, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#FFFF00').rgba, new RGBA(255, 255, 0, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#00FFFF').rgba, new RGBA(0, 255, 255, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#FF00FF').rgba, new RGBA(255, 0, 255, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#C0C0C0').rgba, new RGBA(192, 192, 192, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#808080').rgba, new RGBA(128, 128, 128, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#800000').rgba, new RGBA(128, 0, 0, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#808000').rgba, new RGBA(128, 128, 0, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#008000').rgba, new RGBA(0, 128, 0, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#800080').rgba, new RGBA(128, 0, 128, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#008080').rgba, new RGBA(0, 128, 128, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#000080').rgba, new RGBA(0, 0, 128, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#010203').rgba, new RGBA(1, 2, 3, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#040506').rgba, new RGBA(4, 5, 6, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#070809').rgba, new RGBA(7, 8, 9, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#0a0A0a').rgba, new RGBA(10, 10, 10, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#0b0B0b').rgba, new RGBA(11, 11, 11, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#0c0C0c').rgba, new RGBA(12, 12, 12, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#0d0D0d').rgba, new RGBA(13, 13, 13, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#0e0E0e').rgba, new RGBA(14, 14, 14, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#0f0F0f').rgba, new RGBA(15, 15, 15, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#a0A0a0').rgba, new RGBA(160, 160, 160, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#CFA').rgba, new RGBA(204, 255, 170, 1));
assert.deepEqual(Color.Format.CSS.parseHex('#CFA8').rgba, new RGBA(204, 255, 170, 0.533));
});
});
});
});

View File

@@ -0,0 +1,130 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import { memoize } from 'vs/base/common/decorators';
suite('Decorators', () => {
test('memoize should memoize methods', () => {
class Foo {
count = 0;
constructor(private _answer: number) { }
@memoize
answer() {
this.count++;
return this._answer;
}
}
const foo = new Foo(42);
assert.equal(foo.count, 0);
assert.equal(foo.answer(), 42);
assert.equal(foo.count, 1);
assert.equal(foo.answer(), 42);
assert.equal(foo.count, 1);
const foo2 = new Foo(1337);
assert.equal(foo2.count, 0);
assert.equal(foo2.answer(), 1337);
assert.equal(foo2.count, 1);
assert.equal(foo2.answer(), 1337);
assert.equal(foo2.count, 1);
assert.equal(foo.answer(), 42);
assert.equal(foo.count, 1);
const foo3 = new Foo(null);
assert.equal(foo3.count, 0);
assert.equal(foo3.answer(), null);
assert.equal(foo3.count, 1);
assert.equal(foo3.answer(), null);
assert.equal(foo3.count, 1);
const foo4 = new Foo(undefined);
assert.equal(foo4.count, 0);
assert.equal(foo4.answer(), undefined);
assert.equal(foo4.count, 1);
assert.equal(foo4.answer(), undefined);
assert.equal(foo4.count, 1);
});
test('memoize should memoize getters', () => {
class Foo {
count = 0;
constructor(private _answer: number) { }
@memoize
get answer() {
this.count++;
return this._answer;
}
}
const foo = new Foo(42);
assert.equal(foo.count, 0);
assert.equal(foo.answer, 42);
assert.equal(foo.count, 1);
assert.equal(foo.answer, 42);
assert.equal(foo.count, 1);
const foo2 = new Foo(1337);
assert.equal(foo2.count, 0);
assert.equal(foo2.answer, 1337);
assert.equal(foo2.count, 1);
assert.equal(foo2.answer, 1337);
assert.equal(foo2.count, 1);
assert.equal(foo.answer, 42);
assert.equal(foo.count, 1);
const foo3 = new Foo(null);
assert.equal(foo3.count, 0);
assert.equal(foo3.answer, null);
assert.equal(foo3.count, 1);
assert.equal(foo3.answer, null);
assert.equal(foo3.count, 1);
const foo4 = new Foo(undefined);
assert.equal(foo4.count, 0);
assert.equal(foo4.answer, undefined);
assert.equal(foo4.count, 1);
assert.equal(foo4.answer, undefined);
assert.equal(foo4.count, 1);
});
test('memoized property should not be enumerable', () => {
class Foo {
@memoize
get answer() { return 42; }
}
const foo = new Foo();
assert.equal(foo.answer, 42);
assert(!Object.keys(foo).some(k => /\$memoize\$/.test(k)));
});
test('memoized property should not be writable', () => {
class Foo {
@memoize
get answer() { return 42; }
}
const foo = new Foo();
assert.equal(foo.answer, 42);
try {
foo['$memoize$answer'] = 1337;
assert(false);
} catch (e) {
assert.equal(foo.answer, 42);
}
});
});

View File

@@ -0,0 +1,208 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import { LcsDiff, IDiffChange } from 'vs/base/common/diff/diff';
import { LcsDiff2 } from 'vs/base/common/diff/diff2';
class StringDiffSequence {
constructor(private source: string) {
}
getLength() {
return this.source.length;
}
getElementHash(i: number) {
return this.source.charAt(i);
}
}
function createArray<T>(length: number, value: T): T[] {
var r = [];
for (var i = 0; i < length; i++) {
r[i] = value;
}
return r;
}
function maskBasedSubstring(str: string, mask: boolean[]): string {
var r = '';
for (var i = 0; i < str.length; i++) {
if (mask[i]) {
r += str.charAt(i);
}
}
return r;
}
function assertAnswer(originalStr: string, modifiedStr: string, changes: IDiffChange[], answerStr: string, onlyLength: boolean = false): void {
var originalMask = createArray(originalStr.length, true);
var modifiedMask = createArray(modifiedStr.length, true);
var i, j, change;
for (i = 0; i < changes.length; i++) {
change = changes[i];
if (change.originalLength) {
for (j = 0; j < change.originalLength; j++) {
originalMask[change.originalStart + j] = false;
}
}
if (change.modifiedLength) {
for (j = 0; j < change.modifiedLength; j++) {
modifiedMask[change.modifiedStart + j] = false;
}
}
}
var originalAnswer = maskBasedSubstring(originalStr, originalMask);
var modifiedAnswer = maskBasedSubstring(modifiedStr, modifiedMask);
if (onlyLength) {
assert.equal(originalAnswer.length, answerStr.length);
assert.equal(modifiedAnswer.length, answerStr.length);
} else {
assert.equal(originalAnswer, answerStr);
assert.equal(modifiedAnswer, answerStr);
}
}
function lcsInnerTest(Algorithm: any, originalStr: string, modifiedStr: string, answerStr: string, onlyLength: boolean = false): void {
var diff = new Algorithm(new StringDiffSequence(originalStr), new StringDiffSequence(modifiedStr));
var changes = diff.ComputeDiff();
assertAnswer(originalStr, modifiedStr, changes, answerStr, onlyLength);
}
function stringPower(str: string, power: number): string {
var r = str;
for (var i = 0; i < power; i++) {
r += r;
}
return r;
}
function lcsTest(Algorithm: any, originalStr: string, modifiedStr: string, answerStr: string) {
lcsInnerTest(Algorithm, originalStr, modifiedStr, answerStr);
for (var i = 2; i <= 5; i++) {
lcsInnerTest(Algorithm, stringPower(originalStr, i), stringPower(modifiedStr, i), stringPower(answerStr, i), true);
}
}
function lcsTests(Algorithm: any) {
lcsTest(Algorithm, 'heLLo world', 'hello orlando', 'heo orld');
lcsTest(Algorithm, 'abcde', 'acd', 'acd'); // simple
lcsTest(Algorithm, 'abcdbce', 'bcede', 'bcde'); // skip
lcsTest(Algorithm, 'abcdefgabcdefg', 'bcehafg', 'bceafg'); // long
lcsTest(Algorithm, 'abcde', 'fgh', ''); // no match
lcsTest(Algorithm, 'abcfabc', 'fabc', 'fabc');
lcsTest(Algorithm, '0azby0', '9axbzby9', 'azby');
lcsTest(Algorithm, '0abc00000', '9a1b2c399999', 'abc');
lcsTest(Algorithm, 'fooBar', 'myfooBar', 'fooBar'); // all insertions
lcsTest(Algorithm, 'fooBar', 'fooMyBar', 'fooBar'); // all insertions
lcsTest(Algorithm, 'fooBar', 'fooBar', 'fooBar'); // identical sequences
}
suite('Diff', () => {
test('LcsDiff - different strings tests', function () {
this.timeout(10000);
lcsTests(LcsDiff);
});
test('LcsDiff2 - different strings tests', function () {
this.timeout(10000);
lcsTests(LcsDiff2);
});
});
suite('Diff - Ported from VS', () => {
test('using continue processing predicate to quit early', function () {
var left = 'abcdef';
var right = 'abxxcyyydzzzzezzzzzzzzzzzzzzzzzzzzf';
// We use a long non-matching portion at the end of the right-side string, so the backwards tracking logic
// doesn't get there first.
var predicateCallCount = 0;
var diff = new LcsDiff(new StringDiffSequence(left), new StringDiffSequence(right), function (leftIndex, leftSequence, longestMatchSoFar) {
assert.equal(predicateCallCount, 0);
predicateCallCount++;
assert.equal(leftSequence.getLength(), left.length);
assert.equal(leftIndex, 1);
// cancel processing
return false;
});
var changes = diff.ComputeDiff(true);
assert.equal(predicateCallCount, 1);
// Doesn't include 'c', 'd', or 'e', since we quit on the first request
assertAnswer(left, right, changes, 'abf');
// Cancel after the first match ('c')
diff = new LcsDiff(new StringDiffSequence(left), new StringDiffSequence(right), function (leftIndex, leftSequence, longestMatchSoFar) {
assert(longestMatchSoFar <= 1); // We never see a match of length > 1
// Continue processing as long as there hasn't been a match made.
return longestMatchSoFar < 1;
});
changes = diff.ComputeDiff(true);
assertAnswer(left, right, changes, 'abcf');
// Cancel after the second match ('d')
diff = new LcsDiff(new StringDiffSequence(left), new StringDiffSequence(right), function (leftIndex, leftSequence, longestMatchSoFar) {
assert(longestMatchSoFar <= 2); // We never see a match of length > 2
// Continue processing as long as there hasn't been a match made.
return longestMatchSoFar < 2;
});
changes = diff.ComputeDiff(true);
assertAnswer(left, right, changes, 'abcdf');
// Cancel *one iteration* after the second match ('d')
var hitSecondMatch = false;
diff = new LcsDiff(new StringDiffSequence(left), new StringDiffSequence(right), function (leftIndex, leftSequence, longestMatchSoFar) {
assert(longestMatchSoFar <= 2); // We never see a match of length > 2
var hitYet = hitSecondMatch;
hitSecondMatch = longestMatchSoFar > 1;
// Continue processing as long as there hasn't been a match made.
return !hitYet;
});
changes = diff.ComputeDiff(true);
assertAnswer(left, right, changes, 'abcdf');
// Cancel after the third and final match ('e')
diff = new LcsDiff(new StringDiffSequence(left), new StringDiffSequence(right), function (leftIndex, leftSequence, longestMatchSoFar) {
assert(longestMatchSoFar <= 3); // We never see a match of length > 3
// Continue processing as long as there hasn't been a match made.
return longestMatchSoFar < 3;
});
changes = diff.ComputeDiff(true);
assertAnswer(left, right, changes, 'abcdef');
});
});

View File

@@ -0,0 +1,47 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import { toErrorMessage } from 'vs/base/common/errorMessage';
suite('Errors', () => {
test('Get Error Message', function () {
assert.strictEqual(toErrorMessage('Foo Bar'), 'Foo Bar');
assert.strictEqual(toErrorMessage(new Error('Foo Bar')), 'Foo Bar');
let error: any = new Error();
error.status = 404;
error.statusText = 'Not Found';
assert.strictEqual(toErrorMessage(error), 'Not Found (HTTP 404)');
error = new Error();
error.detail = {};
error.detail.exception = {};
error.detail.exception.message = 'Foo Bar';
assert.strictEqual(toErrorMessage(error), 'Foo Bar');
error = new Error();
error.detail = {};
error.detail.error = {};
error.detail.error.status = 404;
error.detail.error.statusText = 'Not Found';
assert.strictEqual(toErrorMessage(error), 'Not Found (HTTP 404)');
error = new Error();
error.detail = {};
error.detail.error = [];
let foo: any = {};
error.detail.error.push(foo);
foo.status = 404;
foo.statusText = 'Not Found';
assert.strictEqual(toErrorMessage(error), 'Not Found (HTTP 404)');
assert(toErrorMessage());
assert(toErrorMessage(null));
assert(toErrorMessage({}));
});
});

View File

@@ -0,0 +1,663 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import Event, { Emitter, fromEventEmitter, debounceEvent, EventBufferer, once, fromPromise, stopwatch, buffer, echo, EventMultiplexer } from 'vs/base/common/event';
import { IDisposable } from 'vs/base/common/lifecycle';
import { EventEmitter } from 'vs/base/common/eventEmitter';
import Errors = require('vs/base/common/errors');
import { TPromise } from 'vs/base/common/winjs.base';
namespace Samples {
export class EventCounter {
count = 0;
reset() {
this.count = 0;
}
onEvent() {
this.count += 1;
}
}
export class Document3 {
private _onDidChange = new Emitter<string>();
onDidChange: Event<string> = this._onDidChange.event;
setText(value: string) {
//...
this._onDidChange.fire(value);
}
}
// what: like before but expose an existing event emitter as typed events
export class Document3b /*extends EventEmitter*/ {
private static _didChange = 'this_is_hidden_from_consumers';
private _eventBus = new EventEmitter();
onDidChange = fromEventEmitter<string>(this._eventBus, Document3b._didChange);
setText(value: string) {
//...
this._eventBus.emit(Document3b._didChange, value);
}
}
}
suite('Event', function () {
const counter = new Samples.EventCounter();
setup(() => counter.reset());
test('Emitter plain', function () {
let doc = new Samples.Document3();
document.createElement('div').onclick = function () { };
let subscription = doc.onDidChange(counter.onEvent, counter);
doc.setText('far');
doc.setText('boo');
// unhook listener
subscription.dispose();
doc.setText('boo');
assert.equal(counter.count, 2);
});
test('wrap legacy EventEmitter', function () {
let doc = new Samples.Document3b();
let subscription = doc.onDidChange(counter.onEvent, counter);
doc.setText('far');
doc.setText('boo');
// unhook listener
subscription.dispose();
doc.setText('boo');
assert.equal(counter.count, 2);
});
test('Emitter, bucket', function () {
let bucket: IDisposable[] = [];
let doc = new Samples.Document3();
let subscription = doc.onDidChange(counter.onEvent, counter, bucket);
doc.setText('far');
doc.setText('boo');
// unhook listener
while (bucket.length) {
bucket.pop().dispose();
}
// noop
subscription.dispose();
doc.setText('boo');
assert.equal(counter.count, 2);
});
test('wrapEventEmitter, bucket', function () {
let bucket: IDisposable[] = [];
let doc = new Samples.Document3b();
let subscription = doc.onDidChange(counter.onEvent, counter, bucket);
doc.setText('far');
doc.setText('boo');
// unhook listener
while (bucket.length) {
bucket.pop().dispose();
}
// noop
subscription.dispose();
doc.setText('boo');
assert.equal(counter.count, 2);
});
test('onFirstAdd|onLastRemove', function () {
let firstCount = 0;
let lastCount = 0;
let a = new Emitter({
onFirstListenerAdd() { firstCount += 1; },
onLastListenerRemove() { lastCount += 1; }
});
assert.equal(firstCount, 0);
assert.equal(lastCount, 0);
let subscription = a.event(function () { });
assert.equal(firstCount, 1);
assert.equal(lastCount, 0);
subscription.dispose();
assert.equal(firstCount, 1);
assert.equal(lastCount, 1);
subscription = a.event(function () { });
assert.equal(firstCount, 2);
assert.equal(lastCount, 1);
});
test('throwingListener', function () {
const origErrorHandler = Errors.errorHandler.getUnexpectedErrorHandler();
Errors.setUnexpectedErrorHandler(() => null);
try {
let a = new Emitter();
let hit = false;
a.event(function () {
throw 9;
});
a.event(function () {
hit = true;
});
a.fire(undefined);
assert.equal(hit, true);
} finally {
Errors.setUnexpectedErrorHandler(origErrorHandler);
}
});
test('Debounce Event', function (done: () => void) {
let doc = new Samples.Document3();
let onDocDidChange = debounceEvent(doc.onDidChange, (prev: string[], cur) => {
if (!prev) {
prev = [cur];
} else if (prev.indexOf(cur) < 0) {
prev.push(cur);
}
return prev;
}, 10);
let count = 0;
onDocDidChange(keys => {
count++;
assert.ok(keys, 'was not expecting keys.');
if (count === 1) {
doc.setText('4');
assert.deepEqual(keys, ['1', '2', '3']);
} else if (count === 2) {
assert.deepEqual(keys, ['4']);
done();
}
});
doc.setText('1');
doc.setText('2');
doc.setText('3');
});
test('Debounce Event - leading', function (done: () => void) {
const emitter = new Emitter<void>();
let debounced = debounceEvent(emitter.event, (l, e) => e, 0, /*leading=*/true);
let calls = 0;
debounced(() => {
calls++;
});
// If the source event is fired once, the debounced (on the leading edge) event should be fired only once
emitter.fire();
setTimeout(() => {
assert.equal(calls, 1);
done();
});
});
test('Debounce Event - leading', function (done: () => void) {
const emitter = new Emitter<void>();
let debounced = debounceEvent(emitter.event, (l, e) => e, 0, /*leading=*/true);
let calls = 0;
debounced(() => {
calls++;
});
// If the source event is fired multiple times, the debounced (on the leading edge) event should be fired twice
emitter.fire();
emitter.fire();
emitter.fire();
setTimeout(() => {
assert.equal(calls, 2);
done();
});
});
});
suite('Event utils', () => {
suite('EventBufferer', () => {
test('should not buffer when not wrapped', () => {
const bufferer = new EventBufferer();
const counter = new Samples.EventCounter();
const emitter = new Emitter<void>();
const event = bufferer.wrapEvent(emitter.event);
const listener = event(counter.onEvent, counter);
assert.equal(counter.count, 0);
emitter.fire();
assert.equal(counter.count, 1);
emitter.fire();
assert.equal(counter.count, 2);
emitter.fire();
assert.equal(counter.count, 3);
listener.dispose();
});
test('should buffer when wrapped', () => {
const bufferer = new EventBufferer();
const counter = new Samples.EventCounter();
const emitter = new Emitter<void>();
const event = bufferer.wrapEvent(emitter.event);
const listener = event(counter.onEvent, counter);
assert.equal(counter.count, 0);
emitter.fire();
assert.equal(counter.count, 1);
bufferer.bufferEvents(() => {
emitter.fire();
assert.equal(counter.count, 1);
emitter.fire();
assert.equal(counter.count, 1);
});
assert.equal(counter.count, 3);
emitter.fire();
assert.equal(counter.count, 4);
listener.dispose();
});
test('once', () => {
const emitter = new Emitter<void>();
let counter1 = 0, counter2 = 0, counter3 = 0;
const listener1 = emitter.event(() => counter1++);
const listener2 = once(emitter.event)(() => counter2++);
const listener3 = once(emitter.event)(() => counter3++);
assert.equal(counter1, 0);
assert.equal(counter2, 0);
assert.equal(counter3, 0);
listener3.dispose();
emitter.fire();
assert.equal(counter1, 1);
assert.equal(counter2, 1);
assert.equal(counter3, 0);
emitter.fire();
assert.equal(counter1, 2);
assert.equal(counter2, 1);
assert.equal(counter3, 0);
listener1.dispose();
listener2.dispose();
});
});
suite('fromPromise', () => {
test('should emit when done', () => {
let count = 0;
const event = fromPromise(TPromise.as(null));
event(() => count++);
assert.equal(count, 0);
return TPromise.timeout(10).then(() => {
assert.equal(count, 1);
});
});
test('should emit when done - setTimeout', async () => {
let count = 0;
const promise = TPromise.timeout(5);
const event = fromPromise(promise);
event(() => count++);
assert.equal(count, 0);
await promise;
assert.equal(count, 1);
});
});
suite('stopwatch', () => {
test('should emit', () => {
const emitter = new Emitter<void>();
const event = stopwatch(emitter.event);
return new TPromise((c, e) => {
event(duration => {
try {
assert(duration > 0);
} catch (err) {
e(err);
}
c(null);
});
setTimeout(() => emitter.fire(), 10);
});
});
});
suite('buffer', () => {
test('should buffer events', () => {
const result = [];
const emitter = new Emitter<number>();
const event = emitter.event;
const bufferedEvent = buffer(event);
emitter.fire(1);
emitter.fire(2);
emitter.fire(3);
assert.deepEqual(result, []);
const listener = bufferedEvent(num => result.push(num));
assert.deepEqual(result, [1, 2, 3]);
emitter.fire(4);
assert.deepEqual(result, [1, 2, 3, 4]);
listener.dispose();
emitter.fire(5);
assert.deepEqual(result, [1, 2, 3, 4]);
});
test('should buffer events on next tick', () => {
const result = [];
const emitter = new Emitter<number>();
const event = emitter.event;
const bufferedEvent = buffer(event, true);
emitter.fire(1);
emitter.fire(2);
emitter.fire(3);
assert.deepEqual(result, []);
const listener = bufferedEvent(num => result.push(num));
assert.deepEqual(result, []);
return TPromise.timeout(10).then(() => {
emitter.fire(4);
assert.deepEqual(result, [1, 2, 3, 4]);
listener.dispose();
emitter.fire(5);
assert.deepEqual(result, [1, 2, 3, 4]);
});
});
test('should fire initial buffer events', () => {
const result = [];
const emitter = new Emitter<number>();
const event = emitter.event;
const bufferedEvent = buffer(event, false, [-2, -1, 0]);
emitter.fire(1);
emitter.fire(2);
emitter.fire(3);
assert.deepEqual(result, []);
bufferedEvent(num => result.push(num));
assert.deepEqual(result, [-2, -1, 0, 1, 2, 3]);
});
});
suite('echo', () => {
test('should echo events', () => {
const result = [];
const emitter = new Emitter<number>();
const event = emitter.event;
const echoEvent = echo(event);
emitter.fire(1);
emitter.fire(2);
emitter.fire(3);
assert.deepEqual(result, []);
const listener = echoEvent(num => result.push(num));
assert.deepEqual(result, [1, 2, 3]);
emitter.fire(4);
assert.deepEqual(result, [1, 2, 3, 4]);
listener.dispose();
emitter.fire(5);
assert.deepEqual(result, [1, 2, 3, 4]);
});
test('should echo events for every listener', () => {
const result1 = [];
const result2 = [];
const emitter = new Emitter<number>();
const event = emitter.event;
const echoEvent = echo(event);
emitter.fire(1);
emitter.fire(2);
emitter.fire(3);
assert.deepEqual(result1, []);
assert.deepEqual(result2, []);
const listener1 = echoEvent(num => result1.push(num));
assert.deepEqual(result1, [1, 2, 3]);
assert.deepEqual(result2, []);
emitter.fire(4);
assert.deepEqual(result1, [1, 2, 3, 4]);
assert.deepEqual(result2, []);
const listener2 = echoEvent(num => result2.push(num));
assert.deepEqual(result1, [1, 2, 3, 4]);
assert.deepEqual(result2, [1, 2, 3, 4]);
emitter.fire(5);
assert.deepEqual(result1, [1, 2, 3, 4, 5]);
assert.deepEqual(result2, [1, 2, 3, 4, 5]);
listener1.dispose();
listener2.dispose();
emitter.fire(6);
assert.deepEqual(result1, [1, 2, 3, 4, 5]);
assert.deepEqual(result2, [1, 2, 3, 4, 5]);
});
});
suite('EventMultiplexer', () => {
test('works', () => {
const result = [];
const m = new EventMultiplexer<number>();
m.event(r => result.push(r));
const e1 = new Emitter<number>();
m.add(e1.event);
assert.deepEqual(result, []);
e1.fire(0);
assert.deepEqual(result, [0]);
});
test('multiplexer dispose works', () => {
const result = [];
const m = new EventMultiplexer<number>();
m.event(r => result.push(r));
const e1 = new Emitter<number>();
m.add(e1.event);
assert.deepEqual(result, []);
e1.fire(0);
assert.deepEqual(result, [0]);
m.dispose();
assert.deepEqual(result, [0]);
e1.fire(0);
assert.deepEqual(result, [0]);
});
test('event dispose works', () => {
const result = [];
const m = new EventMultiplexer<number>();
m.event(r => result.push(r));
const e1 = new Emitter<number>();
m.add(e1.event);
assert.deepEqual(result, []);
e1.fire(0);
assert.deepEqual(result, [0]);
e1.dispose();
assert.deepEqual(result, [0]);
e1.fire(0);
assert.deepEqual(result, [0]);
});
test('mutliplexer event dispose works', () => {
const result = [];
const m = new EventMultiplexer<number>();
m.event(r => result.push(r));
const e1 = new Emitter<number>();
const l1 = m.add(e1.event);
assert.deepEqual(result, []);
e1.fire(0);
assert.deepEqual(result, [0]);
l1.dispose();
assert.deepEqual(result, [0]);
e1.fire(0);
assert.deepEqual(result, [0]);
});
test('hot start works', () => {
const result = [];
const m = new EventMultiplexer<number>();
m.event(r => result.push(r));
const e1 = new Emitter<number>();
m.add(e1.event);
const e2 = new Emitter<number>();
m.add(e2.event);
const e3 = new Emitter<number>();
m.add(e3.event);
e1.fire(1);
e2.fire(2);
e3.fire(3);
assert.deepEqual(result, [1, 2, 3]);
});
test('cold start works', () => {
const result = [];
const m = new EventMultiplexer<number>();
const e1 = new Emitter<number>();
m.add(e1.event);
const e2 = new Emitter<number>();
m.add(e2.event);
const e3 = new Emitter<number>();
m.add(e3.event);
m.event(r => result.push(r));
e1.fire(1);
e2.fire(2);
e3.fire(3);
assert.deepEqual(result, [1, 2, 3]);
});
test('late add works', () => {
const result = [];
const m = new EventMultiplexer<number>();
const e1 = new Emitter<number>();
m.add(e1.event);
const e2 = new Emitter<number>();
m.add(e2.event);
m.event(r => result.push(r));
e1.fire(1);
e2.fire(2);
const e3 = new Emitter<number>();
m.add(e3.event);
e3.fire(3);
assert.deepEqual(result, [1, 2, 3]);
});
test('add dispose works', () => {
const result = [];
const m = new EventMultiplexer<number>();
const e1 = new Emitter<number>();
m.add(e1.event);
const e2 = new Emitter<number>();
m.add(e2.event);
m.event(r => result.push(r));
e1.fire(1);
e2.fire(2);
const e3 = new Emitter<number>();
const l3 = m.add(e3.event);
e3.fire(3);
assert.deepEqual(result, [1, 2, 3]);
l3.dispose();
e3.fire(4);
assert.deepEqual(result, [1, 2, 3]);
e2.fire(4);
e1.fire(5);
assert.deepEqual(result, [1, 2, 3, 4, 5]);
});
});
});

View File

@@ -0,0 +1,319 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import { EventEmitter, OrderGuaranteeEventEmitter } from 'vs/base/common/eventEmitter';
suite('EventEmitter', () => {
let eventEmitter: EventEmitter;
setup(() => {
eventEmitter = new EventEmitter();
});
teardown(() => {
eventEmitter.dispose();
eventEmitter = null;
});
test('add listener, emit other event type', function () {
let didCall = false;
eventEmitter.addListener('eventType1', function (e) {
didCall = true;
});
eventEmitter.emit('eventType2', {});
assert(!didCall, 'Didn\'t expect to be called');
});
test('add listener, emit event', function () {
let didCall = false;
eventEmitter.addListener('eventType', function (e) {
didCall = true;
});
eventEmitter.emit('eventType', {});
assert(didCall);
});
test('add 2 listeners, emit event', function () {
let didCallFirst = false;
eventEmitter.addListener('eventType', function (e) {
didCallFirst = true;
});
let didCallSecond = false;
eventEmitter.addListener('eventType', function (e) {
didCallSecond = true;
});
eventEmitter.emit('eventType', {});
assert(didCallFirst);
assert(didCallSecond);
});
test('add 1 listener, remove it, emit event', function () {
let didCall = false;
let remove = eventEmitter.addListener('eventType', function (e) {
didCall = true;
});
remove.dispose();
eventEmitter.emit('eventType', {});
assert(!didCall);
});
test('add 2 listeners, emit event, remove one while processing', function () {
let firstCallCount = 0;
let remove1 = eventEmitter.addListener('eventType', function (e) {
firstCallCount++;
remove1.dispose();
});
let secondCallCount = 0;
eventEmitter.addListener('eventType', function (e) {
secondCallCount++;
});
eventEmitter.emit('eventType', {});
eventEmitter.emit('eventType', {});
assert.equal(firstCallCount, 1);
assert.equal(secondCallCount, 2);
});
test('event object is assert', function () {
let data: any;
eventEmitter.addListener('eventType', function (e) {
data = e.data;
});
eventEmitter.emit('eventType', { data: 5 });
assert.equal(data, 5);
});
test('deferred emit', function () {
let calledCount = 0;
eventEmitter.addListener('eventType', function (e) {
calledCount++;
});
eventEmitter.deferredEmit(function () {
assert.equal(calledCount, 0);
eventEmitter.emit('eventType', {});
assert.equal(calledCount, 0);
eventEmitter.emit('eventType', {});
assert.equal(calledCount, 0);
});
assert.equal(calledCount, 2);
});
test('deferred emit maintains events order', function () {
let order = 0;
eventEmitter.addListener('eventType2', function (e) {
order++;
assert.equal(order, 1);
});
eventEmitter.addListener('eventType1', function (e) {
order++;
assert.equal(order, 2);
});
eventEmitter.deferredEmit(function () {
eventEmitter.emit('eventType2', {});
eventEmitter.emit('eventType1', {});
});
assert.equal(order, 2);
});
test('deferred emit maintains events order for bulk listeners', function () {
let count = 0;
eventEmitter.addBulkListener(function (events) {
assert.equal(events[0].type, 'eventType2');
assert.equal(events[1].type, 'eventType1');
count++;
});
eventEmitter.deferredEmit(function () {
eventEmitter.emit('eventType2', {});
eventEmitter.emit('eventType1', {});
});
assert.equal(count, 1);
});
test('emit notifies bulk listeners', function () {
let count = 0;
eventEmitter.addBulkListener(function (events) {
count++;
});
eventEmitter.emit('eventType', {});
assert.equal(count, 1);
});
test('one event emitter, one listener', function () {
let emitter = new EventEmitter();
let eventBus = new EventEmitter();
eventBus.addEmitter(emitter);
let didCallFirst = false;
eventBus.addListener('eventType', function (e) {
didCallFirst = true;
});
let didCallSecond = false;
eventBus.addListener('eventType', function (e) {
didCallSecond = true;
});
emitter.emit('eventType', {});
assert(didCallFirst);
assert(didCallSecond);
});
test('two event emitters, two listeners, deferred emit', function () {
let callCnt = 0;
let emitter1 = new EventEmitter();
let emitter2 = new EventEmitter();
let eventBus = new EventEmitter();
eventBus.addEmitter(emitter1);
eventBus.addEmitter(emitter2);
eventBus.addListener('eventType1', function (e) {
assert(true);
callCnt++;
});
eventBus.addListener('eventType1', function (e) {
assert(true);
callCnt++;
});
eventBus.deferredEmit(function () {
assert.equal(callCnt, 0);
emitter1.emit('eventType1', {});
emitter2.emit('eventType1', {});
assert.equal(callCnt, 0);
});
assert.equal(callCnt, 4);
});
test('cascading emitters', function () {
let emitter1 = new EventEmitter();
let emitter2 = new EventEmitter();
let emitter3 = new EventEmitter();
let emitter4 = new EventEmitter();
emitter2.addEmitter(emitter1);
emitter3.addEmitter(emitter2);
emitter4.addEmitter(emitter3);
let didCall = false;
emitter4.addListener('eventType', function (e) {
didCall = true;
});
emitter1.emit('eventType', {});
assert(didCall);
});
test('EventEmitter makes no order guarantees 1', () => {
let emitter = new EventEmitter();
let actualCallOrder: string[] = [];
emitter.addListener('foo', function () {
actualCallOrder.push('listener1-foo');
emitter.emit('bar');
});
emitter.addListener('foo', function () {
actualCallOrder.push('listener2-foo');
});
emitter.addListener('bar', function () {
actualCallOrder.push('listener2-bar');
});
emitter.emit('foo');
assert.deepEqual(actualCallOrder, [
'listener1-foo',
'listener2-bar',
'listener2-foo'
]);
});
test('EventEmitter makes no order guarantees 2', () => {
let emitter = new EventEmitter();
let actualCallOrder: string[] = [];
emitter.addListener('foo', function () {
actualCallOrder.push('listener1-foo');
emitter.deferredEmit(() => {
emitter.emit('bar');
});
});
emitter.addListener('foo', function () {
actualCallOrder.push('listener2-foo');
});
emitter.addListener('bar', function () {
actualCallOrder.push('listener2-bar');
});
emitter.deferredEmit(() => {
emitter.emit('foo');
});
assert.deepEqual(actualCallOrder, [
'listener1-foo',
'listener2-bar',
'listener2-foo'
]);
});
test('OrderGuaranteeEventEmitter makes order guarantees 1', () => {
let emitter = new OrderGuaranteeEventEmitter();
let actualCallOrder: string[] = [];
emitter.addListener('foo', function () {
actualCallOrder.push('listener1-foo');
emitter.emit('bar');
});
emitter.addListener('foo', function () {
actualCallOrder.push('listener2-foo');
});
emitter.addListener('bar', function () {
actualCallOrder.push('listener2-bar');
});
emitter.emit('foo');
assert.deepEqual(actualCallOrder, [
'listener1-foo',
'listener2-foo',
'listener2-bar'
]);
});
test('OrderGuaranteeEventEmitter makes order guarantees 2', () => {
let emitter = new OrderGuaranteeEventEmitter();
let actualCallOrder: string[] = [];
emitter.addListener('foo', function () {
actualCallOrder.push('listener1-foo');
emitter.deferredEmit(() => {
emitter.emit('bar');
});
});
emitter.addListener('foo', function () {
actualCallOrder.push('listener2-foo');
});
emitter.addListener('bar', function () {
actualCallOrder.push('listener2-bar');
});
emitter.deferredEmit(() => {
emitter.emit('foo');
});
assert.deepEqual(actualCallOrder, [
'listener1-foo',
'listener2-foo',
'listener2-bar'
]);
});
});

View File

@@ -0,0 +1,5 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
export const data: string[];

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,46 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
// import * as assert from 'assert';
import * as filters from 'vs/base/common/filters';
import { data } from './filters.perf.data';
const patterns = ['cci', 'ida', 'pos', 'CCI', 'enbled', 'callback', 'gGame', 'cons'];
const _enablePerf = false;
function perfSuite(name: string, callback: (this: Mocha.ISuiteCallbackContext) => void) {
if (_enablePerf) {
suite(name, callback);
}
}
perfSuite('Performance - fuzzyMatch', function () {
console.log(`Matching ${data.length} items against ${patterns.length} patterns...`);
function perfTest(name: string, match: (pattern: string, word: string) => any) {
test(name, function () {
const t1 = Date.now();
let count = 0;
for (const pattern of patterns) {
for (const item of data) {
count += 1;
match(pattern, item);
}
}
console.log(name, Date.now() - t1, `${(count / (Date.now() - t1)).toPrecision(6)}/ms`);
});
}
perfTest('matchesFuzzy', filters.matchesFuzzy);
perfTest('fuzzyContiguousFilter', filters.fuzzyContiguousFilter);
perfTest('fuzzyScore', filters.fuzzyScore);
perfTest('fuzzyScoreGraceful', filters.fuzzyScoreGraceful);
});

View File

@@ -0,0 +1,436 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import { IFilter, or, matchesPrefix, matchesStrictPrefix, matchesCamelCase, matchesSubString, matchesContiguousSubString, matchesWords, fuzzyScore, nextTypoPermutation, fuzzyScoreGraceful } from 'vs/base/common/filters';
function filterOk(filter: IFilter, word: string, wordToMatchAgainst: string, highlights?: { start: number; end: number; }[]) {
let r = filter(word, wordToMatchAgainst);
assert(r);
if (highlights) {
assert.deepEqual(r, highlights);
}
}
function filterNotOk(filter, word, suggestion) {
assert(!filter(word, suggestion));
}
suite('Filters', () => {
test('or', function () {
let filter, counters;
let newFilter = function (i, r) {
return function () { counters[i]++; return r; };
};
counters = [0, 0];
filter = or(newFilter(0, false), newFilter(1, false));
filterNotOk(filter, 'anything', 'anything');
assert.deepEqual(counters, [1, 1]);
counters = [0, 0];
filter = or(newFilter(0, true), newFilter(1, false));
filterOk(filter, 'anything', 'anything');
assert.deepEqual(counters, [1, 0]);
counters = [0, 0];
filter = or(newFilter(0, true), newFilter(1, true));
filterOk(filter, 'anything', 'anything');
assert.deepEqual(counters, [1, 0]);
counters = [0, 0];
filter = or(newFilter(0, false), newFilter(1, true));
filterOk(filter, 'anything', 'anything');
assert.deepEqual(counters, [1, 1]);
});
test('PrefixFilter - case sensitive', function () {
filterNotOk(matchesStrictPrefix, '', '');
filterOk(matchesStrictPrefix, '', 'anything', []);
filterOk(matchesStrictPrefix, 'alpha', 'alpha', [{ start: 0, end: 5 }]);
filterOk(matchesStrictPrefix, 'alpha', 'alphasomething', [{ start: 0, end: 5 }]);
filterNotOk(matchesStrictPrefix, 'alpha', 'alp');
filterOk(matchesStrictPrefix, 'a', 'alpha', [{ start: 0, end: 1 }]);
filterNotOk(matchesStrictPrefix, 'x', 'alpha');
filterNotOk(matchesStrictPrefix, 'A', 'alpha');
filterNotOk(matchesStrictPrefix, 'AlPh', 'alPHA');
});
test('PrefixFilter - ignore case', function () {
filterOk(matchesPrefix, 'alpha', 'alpha', [{ start: 0, end: 5 }]);
filterOk(matchesPrefix, 'alpha', 'alphasomething', [{ start: 0, end: 5 }]);
filterNotOk(matchesPrefix, 'alpha', 'alp');
filterOk(matchesPrefix, 'a', 'alpha', [{ start: 0, end: 1 }]);
filterOk(matchesPrefix, 'ä', 'Älpha', [{ start: 0, end: 1 }]);
filterNotOk(matchesPrefix, 'x', 'alpha');
filterOk(matchesPrefix, 'A', 'alpha', [{ start: 0, end: 1 }]);
filterOk(matchesPrefix, 'AlPh', 'alPHA', [{ start: 0, end: 4 }]);
filterNotOk(matchesPrefix, 'T', '4'); // see https://github.com/Microsoft/vscode/issues/22401
});
test('CamelCaseFilter', function () {
filterNotOk(matchesCamelCase, '', '');
filterOk(matchesCamelCase, '', 'anything', []);
filterOk(matchesCamelCase, 'alpha', 'alpha', [{ start: 0, end: 5 }]);
filterOk(matchesCamelCase, 'AlPhA', 'alpha', [{ start: 0, end: 5 }]);
filterOk(matchesCamelCase, 'alpha', 'alphasomething', [{ start: 0, end: 5 }]);
filterNotOk(matchesCamelCase, 'alpha', 'alp');
filterOk(matchesCamelCase, 'c', 'CamelCaseRocks', [
{ start: 0, end: 1 }
]);
filterOk(matchesCamelCase, 'cc', 'CamelCaseRocks', [
{ start: 0, end: 1 },
{ start: 5, end: 6 }
]);
filterOk(matchesCamelCase, 'ccr', 'CamelCaseRocks', [
{ start: 0, end: 1 },
{ start: 5, end: 6 },
{ start: 9, end: 10 }
]);
filterOk(matchesCamelCase, 'cacr', 'CamelCaseRocks', [
{ start: 0, end: 2 },
{ start: 5, end: 6 },
{ start: 9, end: 10 }
]);
filterOk(matchesCamelCase, 'cacar', 'CamelCaseRocks', [
{ start: 0, end: 2 },
{ start: 5, end: 7 },
{ start: 9, end: 10 }
]);
filterOk(matchesCamelCase, 'ccarocks', 'CamelCaseRocks', [
{ start: 0, end: 1 },
{ start: 5, end: 7 },
{ start: 9, end: 14 }
]);
filterOk(matchesCamelCase, 'cr', 'CamelCaseRocks', [
{ start: 0, end: 1 },
{ start: 9, end: 10 }
]);
filterOk(matchesCamelCase, 'fba', 'FooBarAbe', [
{ start: 0, end: 1 },
{ start: 3, end: 5 }
]);
filterOk(matchesCamelCase, 'fbar', 'FooBarAbe', [
{ start: 0, end: 1 },
{ start: 3, end: 6 }
]);
filterOk(matchesCamelCase, 'fbara', 'FooBarAbe', [
{ start: 0, end: 1 },
{ start: 3, end: 7 }
]);
filterOk(matchesCamelCase, 'fbaa', 'FooBarAbe', [
{ start: 0, end: 1 },
{ start: 3, end: 5 },
{ start: 6, end: 7 }
]);
filterOk(matchesCamelCase, 'fbaab', 'FooBarAbe', [
{ start: 0, end: 1 },
{ start: 3, end: 5 },
{ start: 6, end: 8 }
]);
filterOk(matchesCamelCase, 'c2d', 'canvasCreation2D', [
{ start: 0, end: 1 },
{ start: 14, end: 16 }
]);
filterOk(matchesCamelCase, 'cce', '_canvasCreationEvent', [
{ start: 1, end: 2 },
{ start: 7, end: 8 },
{ start: 15, end: 16 }
]);
});
test('CamelCaseFilter - #19256', function () {
assert(matchesCamelCase('Debug Console', 'Open: Debug Console'));
assert(matchesCamelCase('Debug console', 'Open: Debug Console'));
assert(matchesCamelCase('debug console', 'Open: Debug Console'));
});
test('matchesContiguousSubString', function () {
filterOk(matchesContiguousSubString, 'cela', 'cancelAnimationFrame()', [
{ start: 3, end: 7 }
]);
});
test('matchesSubString', function () {
filterOk(matchesSubString, 'cmm', 'cancelAnimationFrame()', [
{ start: 0, end: 1 },
{ start: 9, end: 10 },
{ start: 18, end: 19 }
]);
});
test('WordFilter', function () {
filterOk(matchesWords, 'alpha', 'alpha', [{ start: 0, end: 5 }]);
filterOk(matchesWords, 'alpha', 'alphasomething', [{ start: 0, end: 5 }]);
filterNotOk(matchesWords, 'alpha', 'alp');
filterOk(matchesWords, 'a', 'alpha', [{ start: 0, end: 1 }]);
filterNotOk(matchesWords, 'x', 'alpha');
filterOk(matchesWords, 'A', 'alpha', [{ start: 0, end: 1 }]);
filterOk(matchesWords, 'AlPh', 'alPHA', [{ start: 0, end: 4 }]);
assert(matchesWords('Debug Console', 'Open: Debug Console'));
filterOk(matchesWords, 'gp', 'Git: Pull', [{ start: 0, end: 1 }, { start: 5, end: 6 }]);
filterOk(matchesWords, 'g p', 'Git: Pull', [{ start: 0, end: 1 }, { start: 4, end: 6 }]);
filterOk(matchesWords, 'gipu', 'Git: Pull', [{ start: 0, end: 2 }, { start: 5, end: 7 }]);
filterOk(matchesWords, 'gp', 'Category: Git: Pull', [{ start: 10, end: 11 }, { start: 15, end: 16 }]);
filterOk(matchesWords, 'g p', 'Category: Git: Pull', [{ start: 10, end: 11 }, { start: 14, end: 16 }]);
filterOk(matchesWords, 'gipu', 'Category: Git: Pull', [{ start: 10, end: 12 }, { start: 15, end: 17 }]);
filterNotOk(matchesWords, 'it', 'Git: Pull');
filterNotOk(matchesWords, 'll', 'Git: Pull');
filterOk(matchesWords, 'git: プル', 'git: プル', [{ start: 0, end: 7 }]);
filterOk(matchesWords, 'git プル', 'git: プル', [{ start: 0, end: 3 }, { start: 4, end: 7 }]);
filterOk(matchesWords, 'öäk', 'Öhm: Älles Klar', [{ start: 0, end: 1 }, { start: 5, end: 6 }, { start: 11, end: 12 }]);
assert.ok(matchesWords('gipu', 'Category: Git: Pull', true) === null);
assert.deepEqual(matchesWords('pu', 'Category: Git: Pull', true), [{ start: 15, end: 17 }]);
});
function assertMatches(pattern: string, word: string, decoratedWord: string, filter: typeof fuzzyScore) {
let r = filter(pattern, word);
assert.ok(!decoratedWord === (!r || r[1].length === 0));
if (r) {
const [, matches] = r;
let pos = 0;
for (let i = 0; i < matches.length; i++) {
let actual = matches[i];
let expected = decoratedWord.indexOf('^', pos) - i;
assert.equal(actual, expected);
pos = expected + 1 + i;
}
}
}
test('fuzzyScore, #23215', function () {
assertMatches('tit', 'win.tit', 'win.^t^i^t', fuzzyScore);
assertMatches('title', 'win.title', 'win.^t^i^t^l^e', fuzzyScore);
assertMatches('WordCla', 'WordCharacterClassifier', '^W^o^r^dCharacter^C^l^assifier', fuzzyScore);
assertMatches('WordCCla', 'WordCharacterClassifier', '^W^o^r^d^Character^C^l^assifier', fuzzyScore);
});
test('fuzzyScore, #23332', function () {
assertMatches('dete', '"editor.quickSuggestionsDelay"', undefined, fuzzyScore);
});
test('fuzzyScore, #23190', function () {
assertMatches('c:\\do', '& \'C:\\Documents and Settings\'', '& \'^C^:^\\^D^ocuments and Settings\'', fuzzyScore);
assertMatches('c:\\do', '& \'c:\\Documents and Settings\'', '& \'^c^:^\\^D^ocuments and Settings\'', fuzzyScore);
});
test('fuzzyScore, #23581', function () {
assertMatches('close', 'css.lint.importStatement', '^css.^lint.imp^ort^Stat^ement', fuzzyScore);
assertMatches('close', 'css.colorDecorators.enable', '^css.co^l^orDecorator^s.^enable', fuzzyScore);
assertMatches('close', 'workbench.quickOpen.closeOnFocusOut', 'workbench.quickOpen.^c^l^o^s^eOnFocusOut', fuzzyScore);
assertTopScore(fuzzyScore, 'close', 2, 'css.lint.importStatement', 'css.colorDecorators.enable', 'workbench.quickOpen.closeOnFocusOut');
});
test('fuzzyScore, #23458', function () {
assertMatches('highlight', 'editorHoverHighlight', 'editorHover^H^i^g^h^l^i^g^h^t', fuzzyScore);
assertMatches('hhighlight', 'editorHoverHighlight', 'editor^Hover^H^i^g^h^l^i^g^h^t', fuzzyScore);
assertMatches('dhhighlight', 'editorHoverHighlight', undefined, fuzzyScore);
});
test('fuzzyScore, #23746', function () {
assertMatches('-moz', '-moz-foo', '^-^m^o^z-foo', fuzzyScore);
assertMatches('moz', '-moz-foo', '-^m^o^z-foo', fuzzyScore);
assertMatches('moz', '-moz-animation', '-^m^o^z-animation', fuzzyScore);
assertMatches('moza', '-moz-animation', '-^m^o^z-^animation', fuzzyScore);
});
test('fuzzyScore', function () {
assertMatches('ab', 'abA', '^a^bA', fuzzyScore);
assertMatches('ccm', 'cacmelCase', '^ca^c^melCase', fuzzyScore);
assertMatches('bti', 'the_black_knight', undefined, fuzzyScore);
assertMatches('ccm', 'camelCase', undefined, fuzzyScore);
assertMatches('cmcm', 'camelCase', undefined, fuzzyScore);
assertMatches('BK', 'the_black_knight', 'the_^black_^knight', fuzzyScore);
assertMatches('KeyboardLayout=', 'KeyboardLayout', undefined, fuzzyScore);
assertMatches('LLL', 'SVisualLoggerLogsList', 'SVisual^Logger^Logs^List', fuzzyScore);
assertMatches('LLLL', 'SVilLoLosLi', undefined, fuzzyScore);
assertMatches('LLLL', 'SVisualLoggerLogsList', undefined, fuzzyScore);
assertMatches('TEdit', 'TextEdit', '^Text^E^d^i^t', fuzzyScore);
assertMatches('TEdit', 'TextEditor', '^Text^E^d^i^tor', fuzzyScore);
assertMatches('TEdit', 'Textedit', '^T^exte^d^i^t', fuzzyScore);
assertMatches('TEdit', 'text_edit', '^text_^e^d^i^t', fuzzyScore);
assertMatches('TEditDit', 'TextEditorDecorationType', '^Text^E^d^i^tor^Decorat^ion^Type', fuzzyScore);
assertMatches('TEdit', 'TextEditorDecorationType', '^Text^E^d^i^torDecorationType', fuzzyScore);
assertMatches('Tedit', 'TextEdit', '^Text^E^d^i^t', fuzzyScore);
assertMatches('ba', '?AB?', undefined, fuzzyScore);
assertMatches('bkn', 'the_black_knight', 'the_^black_^k^night', fuzzyScore);
assertMatches('bt', 'the_black_knight', 'the_^black_knigh^t', fuzzyScore);
assertMatches('ccm', 'camelCasecm', '^camel^Casec^m', fuzzyScore);
assertMatches('fdm', 'findModel', '^fin^d^Model', fuzzyScore);
assertMatches('fob', 'foobar', '^f^oo^bar', fuzzyScore);
assertMatches('fobz', 'foobar', undefined, fuzzyScore);
assertMatches('foobar', 'foobar', '^f^o^o^b^a^r', fuzzyScore);
assertMatches('form', 'editor.formatOnSave', 'editor.^f^o^r^matOnSave', fuzzyScore);
assertMatches('g p', 'Git: Pull', '^Git:^ ^Pull', fuzzyScore);
assertMatches('g p', 'Git: Pull', '^Git:^ ^Pull', fuzzyScore);
assertMatches('gip', 'Git: Pull', '^G^it: ^Pull', fuzzyScore);
assertMatches('gip', 'Git: Pull', '^G^it: ^Pull', fuzzyScore);
assertMatches('gp', 'Git: Pull', '^Git: ^Pull', fuzzyScore);
assertMatches('gp', 'Git_Git_Pull', '^Git_Git_^Pull', fuzzyScore);
assertMatches('is', 'ImportStatement', '^Import^Statement', fuzzyScore);
assertMatches('is', 'isValid', '^i^sValid', fuzzyScore);
assertMatches('lowrd', 'lowWord', '^l^o^wWo^r^d', fuzzyScore);
assertMatches('myvable', 'myvariable', '^m^y^v^aria^b^l^e', fuzzyScore);
assertMatches('no', '', undefined, fuzzyScore);
assertMatches('no', 'match', undefined, fuzzyScore);
assertMatches('ob', 'foobar', undefined, fuzzyScore);
assertMatches('sl', 'SVisualLoggerLogsList', '^SVisual^LoggerLogsList', fuzzyScore);
assertMatches('sllll', 'SVisualLoggerLogsList', '^SVisua^l^Logger^Logs^List', fuzzyScore);
assertMatches('Three', 'HTMLHRElement', 'H^TML^H^R^El^ement', fuzzyScore);
assertMatches('Three', 'Three', '^T^h^r^e^e', fuzzyScore);
assertMatches('fo', 'barfoo', undefined, fuzzyScore);
assertMatches('fo', 'bar_foo', 'bar_^f^oo', fuzzyScore);
assertMatches('fo', 'bar_Foo', 'bar_^F^oo', fuzzyScore);
assertMatches('fo', 'bar foo', 'bar ^f^oo', fuzzyScore);
assertMatches('fo', 'bar.foo', 'bar.^f^oo', fuzzyScore);
assertMatches('fo', 'bar/foo', 'bar/^f^oo', fuzzyScore);
assertMatches('fo', 'bar\\foo', 'bar\\^f^oo', fuzzyScore);
});
test('fuzzyScore, many matches', function () {
assertMatches(
'aaaaaa',
'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
'^a^a^a^a^a^aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
fuzzyScore
);
});
test('fuzzyScore, issue #26423', function () {
assertMatches('baba', 'abababab', undefined, fuzzyScore);
assertMatches(
'fsfsfs',
'dsafdsafdsafdsafdsafdsafdsafasdfdsa',
undefined,
fuzzyScore
);
assertMatches(
'fsfsfsfsfsfsfsf',
'dsafdsafdsafdsafdsafdsafdsafasdfdsafdsafdsafdsafdsfdsafdsfdfdfasdnfdsajfndsjnafjndsajlknfdsa',
undefined,
fuzzyScore
);
});
test('Fuzzy IntelliSense matching vs Haxe metadata completion, #26995', function () {
assertMatches('f', ':Foo', ':^Foo', fuzzyScore);
assertMatches('f', ':foo', ':^foo', fuzzyScore);
});
test('Cannot set property \'1\' of undefined, #26511', function () {
let word = new Array<void>(123).join('a');
let pattern = new Array<void>(120).join('a');
fuzzyScore(pattern, word);
assert.ok(true); // must not explode
});
test('Vscode 1.12 no longer obeys \'sortText\' in completion items (from language server), #26096', function () {
assertMatches(' ', ' group', undefined, fuzzyScore);
assertMatches(' g', ' group', ' ^group', fuzzyScore);
assertMatches('g', ' group', ' ^group', fuzzyScore);
assertMatches('g g', ' groupGroup', undefined, fuzzyScore);
assertMatches('g g', ' group Group', ' ^group^ ^Group', fuzzyScore);
assertMatches(' g g', ' group Group', ' ^group^ ^Group', fuzzyScore);
assertMatches('zz', 'zzGroup', '^z^zGroup', fuzzyScore);
assertMatches('zzg', 'zzGroup', '^z^z^Group', fuzzyScore);
assertMatches('g', 'zzGroup', 'zz^Group', fuzzyScore);
});
function assertTopScore(filter: typeof fuzzyScore, pattern: string, expected: number, ...words: string[]) {
let topScore = -(100 * 10);
let topIdx = 0;
for (let i = 0; i < words.length; i++) {
const word = words[i];
const m = filter(pattern, word);
if (m) {
const [score] = m;
if (score > topScore) {
topScore = score;
topIdx = i;
}
}
}
assert.equal(topIdx, expected, `${pattern} -> actual=${words[topIdx]} <> expected=${words[expected]}`);
}
test('topScore - fuzzyScore', function () {
assertTopScore(fuzzyScore, 'cons', 2, 'ArrayBufferConstructor', 'Console', 'console');
assertTopScore(fuzzyScore, 'Foo', 1, 'foo', 'Foo', 'foo');
// #24904
assertTopScore(fuzzyScore, 'onMess', 1, 'onmessage', 'onMessage', 'onThisMegaEscape');
assertTopScore(fuzzyScore, 'CC', 1, 'camelCase', 'CamelCase');
assertTopScore(fuzzyScore, 'cC', 0, 'camelCase', 'CamelCase');
// assertTopScore(fuzzyScore, 'cC', 1, 'ccfoo', 'camelCase');
// assertTopScore(fuzzyScore, 'cC', 1, 'ccfoo', 'camelCase', 'foo-cC-bar');
// issue #17836
// assertTopScore(fuzzyScore, 'TEdit', 1, 'TextEditorDecorationType', 'TextEdit', 'TextEditor');
assertTopScore(fuzzyScore, 'p', 0, 'parse', 'posix', 'pafdsa', 'path', 'p');
assertTopScore(fuzzyScore, 'pa', 0, 'parse', 'pafdsa', 'path');
// issue #14583
assertTopScore(fuzzyScore, 'log', 3, 'HTMLOptGroupElement', 'ScrollLogicalPosition', 'SVGFEMorphologyElement', 'log');
assertTopScore(fuzzyScore, 'e', 2, 'AbstractWorker', 'ActiveXObject', 'else');
// issue #14446
assertTopScore(fuzzyScore, 'workbench.sideb', 1, 'workbench.editor.defaultSideBySideLayout', 'workbench.sideBar.location');
// issue #11423
assertTopScore(fuzzyScore, 'editor.r', 2, 'diffEditor.renderSideBySide', 'editor.overviewRulerlanes', 'editor.renderControlCharacter', 'editor.renderWhitespace');
// assertTopScore(fuzzyScore, 'editor.R', 1, 'diffEditor.renderSideBySide', 'editor.overviewRulerlanes', 'editor.renderControlCharacter', 'editor.renderWhitespace');
// assertTopScore(fuzzyScore, 'Editor.r', 0, 'diffEditor.renderSideBySide', 'editor.overviewRulerlanes', 'editor.renderControlCharacter', 'editor.renderWhitespace');
assertTopScore(fuzzyScore, '-mo', 1, '-ms-ime-mode', '-moz-columns');
// // dupe, issue #14861
assertTopScore(fuzzyScore, 'convertModelPosition', 0, 'convertModelPositionToViewPosition', 'convertViewToModelPosition');
// // dupe, issue #14942
assertTopScore(fuzzyScore, 'is', 0, 'isValidViewletId', 'import statement');
assertTopScore(fuzzyScore, 'title', 1, 'files.trimTrailingWhitespace', 'window.title');
});
test('Unexpected suggestion scoring, #28791', function () {
assertTopScore(fuzzyScore, '_lines', 1, '_lineStarts', '_lines');
assertTopScore(fuzzyScore, '_lines', 1, '_lineS', '_lines');
assertTopScore(fuzzyScore, '_lineS', 0, '_lineS', '_lines');
});
test('nextTypoPermutation', function () {
function assertTypos(pattern: string, ...variants: string[]) {
let pos = 1;
for (const expected of variants) {
const actual = nextTypoPermutation(pattern, pos);
assert.equal(actual, expected);
pos += 1;
}
assert.equal(nextTypoPermutation(pattern, pos), undefined);
}
assertTypos('abc', 'acb');
assertTypos('foboar', 'fbooar', 'foobar', 'fobaor', 'fobora');
});
test('fuzzyScoreGraceful', function () {
assertMatches('tkb', 'the_black_knight', '^the_^black_^knight', fuzzyScoreGraceful);
assertMatches('tkbk', 'the_black_knight', '^the_^blac^k_^knight', fuzzyScoreGraceful);
assertMatches('tkkb', 'the_black_knight', undefined, fuzzyScoreGraceful);
assertMatches('tkb', 'no_match', undefined, fuzzyScoreGraceful);
});
});

View File

@@ -0,0 +1,96 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import { Graph } from 'vs/base/common/graph';
suite('Graph', () => {
var graph: Graph<string>;
setup(() => {
graph = new Graph<string>(s => s);
});
test('cannot be traversed when empty', function () {
graph.traverse('foo', true, () => assert(false));
graph.traverse('foo', false, () => assert(false));
assert(true);
});
test('is possible to lookup nodes that don\'t exist', function () {
assert.deepEqual(graph.lookup('ddd'), null);
});
test('inserts nodes when not there yet', function () {
assert.deepEqual(graph.lookup('ddd'), null);
assert.deepEqual(graph.lookupOrInsertNode('ddd').data, 'ddd');
assert.deepEqual(graph.lookup('ddd').data, 'ddd');
});
test('can remove nodes and get length', function () {
assert.equal(graph.length, 0);
assert.deepEqual(graph.lookup('ddd'), null);
assert.deepEqual(graph.lookupOrInsertNode('ddd').data, 'ddd');
assert.equal(graph.length, 1);
graph.removeNode('ddd');
assert.deepEqual(graph.lookup('ddd'), null);
assert.equal(graph.length, 0);
});
test('traverse from leaf', function () {
graph.insertEdge('foo', 'bar');
graph.traverse('bar', true, (node) => assert.equal(node, 'bar'));
var items = ['bar', 'foo'];
graph.traverse('bar', false, (node) => assert.equal(node, items.shift()));
});
test('traverse from center', function () {
graph.insertEdge('1', '3');
graph.insertEdge('2', '3');
graph.insertEdge('3', '4');
graph.insertEdge('3', '5');
var items = ['3', '4', '5'];
graph.traverse('3', true, (node) => assert.equal(node, items.shift()));
items = ['3', '1', '2'];
graph.traverse('3', false, (node) => assert.equal(node, items.shift()));
});
test('traverse a chain', function () {
graph.insertEdge('1', '2');
graph.insertEdge('2', '3');
graph.insertEdge('3', '4');
graph.insertEdge('4', '5');
var items = ['1', '2', '3', '4', '5'];
graph.traverse('1', true, (node) => assert.equal(node, items.shift()));
items = ['1', '2', '3', '4', '5'].reverse();
graph.traverse('5', false, (node) => assert.equal(node, items.shift()));
});
test('root', function () {
graph.insertEdge('1', '2');
var roots = graph.roots();
assert.equal(roots.length, 1);
assert.equal(roots[0].data, '2');
graph.insertEdge('2', '1');
roots = graph.roots();
assert.equal(roots.length, 0);
});
test('root complex', function () {
graph.insertEdge('1', '2');
graph.insertEdge('1', '3');
graph.insertEdge('3', '4');
var roots = graph.roots();
assert.equal(roots.length, 2);
assert(['2', '4'].every(n => roots.some(node => node.data === n)));
});
});

View File

@@ -0,0 +1,48 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import { hash } from 'vs/base/common/hash';
suite('Hash', () => {
test('string', () => {
assert.equal(hash('hello'), hash('hello'));
assert.notEqual(hash('hello'), hash('world'));
assert.notEqual(hash('hello'), hash('olleh'));
assert.notEqual(hash('hello'), hash('Hello'));
assert.notEqual(hash('hello'), hash('Hello '));
assert.notEqual(hash('h'), hash('H'));
assert.notEqual(hash('-'), hash('_'));
});
test('number', () => {
assert.equal(hash(1), hash(1.0));
assert.notEqual(hash(0), hash(1));
assert.notEqual(hash(1), hash(-1));
assert.notEqual(hash(0x12345678), hash(0x123456789));
});
test('boolean', () => {
assert.equal(hash(true), hash(true));
assert.notEqual(hash(true), hash(false));
});
test('array', () => {
assert.equal(hash([1, 2, 3]), hash([1, 2, 3]));
assert.equal(hash(['foo', 'bar']), hash(['foo', 'bar']));
assert.equal(hash([]), hash([]));
assert.notEqual(hash(['foo', 'bar']), hash(['bar', 'foo']));
assert.notEqual(hash(['foo', 'bar']), hash(['bar', 'foo', null]));
});
test('object', () => {
assert.equal(hash({}), hash({}));
assert.equal(hash({ 'foo': 'bar' }), hash({ 'foo': 'bar' }));
assert.equal(hash({ 'foo': 'bar', 'foo2': void 0 }), hash({ 'foo2': void 0, 'foo': 'bar' }));
assert.notEqual(hash({ 'foo': 'bar' }), hash({ 'foo': 'bar2' }));
assert.notEqual(hash({}), hash([]));
});
});

View File

@@ -0,0 +1,122 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import { HistoryNavigator } from 'vs/base/common/history';
suite('History Navigator', () => {
test('create reduces the input to limit', function () {
let testObject = new HistoryNavigator(['1', '2', '3', '4'], 2);
assert.deepEqual(['3', '4'], toArray(testObject));
});
test('create sets the position to last', function () {
let testObject = new HistoryNavigator(['1', '2', '3', '4'], 3);
assert.equal('4', testObject.current());
assert.equal(null, testObject.next());
assert.equal('3', testObject.previous());
});
test('last returns last element', function () {
let testObject = new HistoryNavigator(['1', '2', '3', '4'], 3);
testObject.first();
assert.equal('4', testObject.last());
});
test('first returns first element', function () {
let testObject = new HistoryNavigator(['1', '2', '3', '4'], 3);
assert.equal('2', testObject.first());
});
test('next returns next element', function () {
let testObject = new HistoryNavigator(['1', '2', '3', '4'], 3);
testObject.first();
assert.equal('3', testObject.next());
assert.equal('4', testObject.next());
assert.equal(null, testObject.next());
});
test('previous returns previous element', function () {
let testObject = new HistoryNavigator(['1', '2', '3', '4'], 3);
assert.equal('3', testObject.previous());
assert.equal('2', testObject.previous());
assert.equal(null, testObject.previous());
});
test('next on last element returs null and remains on last', function () {
let testObject = new HistoryNavigator(['1', '2', '3', '4'], 3);
testObject.first();
testObject.last();
assert.equal('4', testObject.current());
assert.equal(null, testObject.next());
});
test('previous on first element returs null and remains on first', function () {
let testObject = new HistoryNavigator(['1', '2', '3', '4'], 3);
testObject.first();
assert.equal('2', testObject.current());
assert.equal(null, testObject.previous());
});
test('add reduces the input to limit', function () {
let testObject = new HistoryNavigator(['1', '2', '3', '4'], 2);
testObject.add('5');
assert.deepEqual(['4', '5'], toArray(testObject));
});
test('adding existing element changes the position', function () {
let testObject = new HistoryNavigator(['1', '2', '3', '4'], 2);
testObject.add('2');
assert.deepEqual(['4', '2'], toArray(testObject));
});
test('add resets the navigator to last', function () {
let testObject = new HistoryNavigator(['1', '2', '3', '4'], 3);
testObject.first();
testObject.add('5');
assert.equal('5', testObject.current());
assert.equal(null, testObject.next());
});
test('adding an existing item changes the order', function () {
let testObject = new HistoryNavigator(['1', '2', '3']);
testObject.add('1');
assert.deepEqual(['2', '3', '1'], toArray(testObject));
});
function toArray(historyNavigator: HistoryNavigator<string>): string[] {
let result = [];
historyNavigator.first();
if (historyNavigator.current()) {
do {
result.push(historyNavigator.current());
} while (historyNavigator.next());
}
return result;
}
});

View File

@@ -0,0 +1,402 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import {
SyntaxKind, createScanner, parse, getLocation, Node, ParseError, parseTree, ParseErrorCode, ParseOptions, Segment, findNodeAtLocation, getNodeValue, ScanError
} from 'vs/base/common/json';
import { getParseErrorMessage } from 'vs/base/common/jsonErrorMessages';
function assertKinds(text: string, ...kinds: SyntaxKind[]): void {
var scanner = createScanner(text);
var kind: SyntaxKind;
while ((kind = scanner.scan()) !== SyntaxKind.EOF) {
assert.equal(kind, kinds.shift());
}
assert.equal(kinds.length, 0);
}
function assertScanError(text: string, expectedKind: SyntaxKind, scanError: ScanError): void {
var scanner = createScanner(text);
scanner.scan();
assert.equal(scanner.getToken(), expectedKind);
assert.equal(scanner.getTokenError(), scanError);
}
function assertValidParse(input: string, expected: any, options?: ParseOptions): void {
var errors: { error: ParseErrorCode }[] = [];
var actual = parse(input, errors, options);
if (errors.length !== 0) {
assert(false, getParseErrorMessage(errors[0].error));
}
assert.deepEqual(actual, expected);
}
function assertInvalidParse(input: string, expected: any, options?: ParseOptions): void {
var errors: { error: ParseErrorCode }[] = [];
var actual = parse(input, errors, options);
assert(errors.length > 0);
assert.deepEqual(actual, expected);
}
function assertTree(input: string, expected: any, expectedErrors: number[] = []): void {
var errors: ParseError[] = [];
var actual = parseTree(input, errors);
assert.deepEqual(errors.map(e => e.error, expected), expectedErrors);
let checkParent = (node: Node) => {
if (node.children) {
for (let child of node.children) {
assert.equal(node, child.parent);
delete child.parent; // delete to avoid recursion in deep equal
checkParent(child);
}
}
};
checkParent(actual);
assert.deepEqual(actual, expected);
}
function assertNodeAtLocation(input: Node, segments: Segment[], expected: any) {
let actual = findNodeAtLocation(input, segments);
assert.deepEqual(actual ? getNodeValue(actual) : void 0, expected);
}
function assertLocation(input: string, expectedSegments: Segment[], expectedNodeType: string, expectedCompleteProperty: boolean): void {
var offset = input.indexOf('|');
input = input.substring(0, offset) + input.substring(offset + 1, input.length);
var actual = getLocation(input, offset);
assert(actual);
assert.deepEqual(actual.path, expectedSegments, input);
assert.equal(actual.previousNode && actual.previousNode.type, expectedNodeType, input);
assert.equal(actual.isAtPropertyKey, expectedCompleteProperty, input);
}
function assertMatchesLocation(input: string, matchingSegments: Segment[], expectedResult = true): void {
var offset = input.indexOf('|');
input = input.substring(0, offset) + input.substring(offset + 1, input.length);
var actual = getLocation(input, offset);
assert(actual);
assert.equal(actual.matches(matchingSegments), expectedResult);
}
suite('JSON', () => {
test('tokens', () => {
assertKinds('{', SyntaxKind.OpenBraceToken);
assertKinds('}', SyntaxKind.CloseBraceToken);
assertKinds('[', SyntaxKind.OpenBracketToken);
assertKinds(']', SyntaxKind.CloseBracketToken);
assertKinds(':', SyntaxKind.ColonToken);
assertKinds(',', SyntaxKind.CommaToken);
});
test('comments', () => {
assertKinds('// this is a comment', SyntaxKind.LineCommentTrivia);
assertKinds('// this is a comment\n', SyntaxKind.LineCommentTrivia, SyntaxKind.LineBreakTrivia);
assertKinds('/* this is a comment*/', SyntaxKind.BlockCommentTrivia);
assertKinds('/* this is a \r\ncomment*/', SyntaxKind.BlockCommentTrivia);
assertKinds('/* this is a \ncomment*/', SyntaxKind.BlockCommentTrivia);
// unexpected end
assertKinds('/* this is a', SyntaxKind.BlockCommentTrivia);
assertKinds('/* this is a \ncomment', SyntaxKind.BlockCommentTrivia);
// broken comment
assertKinds('/ ttt', SyntaxKind.Unknown, SyntaxKind.Trivia, SyntaxKind.Unknown);
});
test('strings', () => {
assertKinds('"test"', SyntaxKind.StringLiteral);
assertKinds('"\\""', SyntaxKind.StringLiteral);
assertKinds('"\\/"', SyntaxKind.StringLiteral);
assertKinds('"\\b"', SyntaxKind.StringLiteral);
assertKinds('"\\f"', SyntaxKind.StringLiteral);
assertKinds('"\\n"', SyntaxKind.StringLiteral);
assertKinds('"\\r"', SyntaxKind.StringLiteral);
assertKinds('"\\t"', SyntaxKind.StringLiteral);
assertKinds('"\\v"', SyntaxKind.StringLiteral);
assertKinds('"\u88ff"', SyntaxKind.StringLiteral);
assertKinds('"\u2028"', SyntaxKind.StringLiteral);
// unexpected end
assertKinds('"test', SyntaxKind.StringLiteral);
assertKinds('"test\n"', SyntaxKind.StringLiteral, SyntaxKind.LineBreakTrivia, SyntaxKind.StringLiteral);
// invalid characters
assertScanError('"\t"', SyntaxKind.StringLiteral, ScanError.InvalidCharacter);
assertScanError('"\t "', SyntaxKind.StringLiteral, ScanError.InvalidCharacter);
});
test('numbers', () => {
assertKinds('0', SyntaxKind.NumericLiteral);
assertKinds('0.1', SyntaxKind.NumericLiteral);
assertKinds('-0.1', SyntaxKind.NumericLiteral);
assertKinds('-1', SyntaxKind.NumericLiteral);
assertKinds('1', SyntaxKind.NumericLiteral);
assertKinds('123456789', SyntaxKind.NumericLiteral);
assertKinds('10', SyntaxKind.NumericLiteral);
assertKinds('90', SyntaxKind.NumericLiteral);
assertKinds('90E+123', SyntaxKind.NumericLiteral);
assertKinds('90e+123', SyntaxKind.NumericLiteral);
assertKinds('90e-123', SyntaxKind.NumericLiteral);
assertKinds('90E-123', SyntaxKind.NumericLiteral);
assertKinds('90E123', SyntaxKind.NumericLiteral);
assertKinds('90e123', SyntaxKind.NumericLiteral);
// zero handling
assertKinds('01', SyntaxKind.NumericLiteral, SyntaxKind.NumericLiteral);
assertKinds('-01', SyntaxKind.NumericLiteral, SyntaxKind.NumericLiteral);
// unexpected end
assertKinds('-', SyntaxKind.Unknown);
assertKinds('.0', SyntaxKind.Unknown);
});
test('keywords: true, false, null', () => {
assertKinds('true', SyntaxKind.TrueKeyword);
assertKinds('false', SyntaxKind.FalseKeyword);
assertKinds('null', SyntaxKind.NullKeyword);
assertKinds('true false null',
SyntaxKind.TrueKeyword,
SyntaxKind.Trivia,
SyntaxKind.FalseKeyword,
SyntaxKind.Trivia,
SyntaxKind.NullKeyword);
// invalid words
assertKinds('nulllll', SyntaxKind.Unknown);
assertKinds('True', SyntaxKind.Unknown);
assertKinds('foo-bar', SyntaxKind.Unknown);
assertKinds('foo bar', SyntaxKind.Unknown, SyntaxKind.Trivia, SyntaxKind.Unknown);
});
test('trivia', () => {
assertKinds(' ', SyntaxKind.Trivia);
assertKinds(' \t ', SyntaxKind.Trivia);
assertKinds(' \t \n \t ', SyntaxKind.Trivia, SyntaxKind.LineBreakTrivia, SyntaxKind.Trivia);
assertKinds('\r\n', SyntaxKind.LineBreakTrivia);
assertKinds('\r', SyntaxKind.LineBreakTrivia);
assertKinds('\n', SyntaxKind.LineBreakTrivia);
assertKinds('\n\r', SyntaxKind.LineBreakTrivia, SyntaxKind.LineBreakTrivia);
assertKinds('\n \n', SyntaxKind.LineBreakTrivia, SyntaxKind.Trivia, SyntaxKind.LineBreakTrivia);
});
test('parse: literals', () => {
assertValidParse('true', true);
assertValidParse('false', false);
assertValidParse('null', null);
assertValidParse('"foo"', 'foo');
assertValidParse('"\\"-\\\\-\\/-\\b-\\f-\\n-\\r-\\t"', '"-\\-/-\b-\f-\n-\r-\t');
assertValidParse('"\\u00DC"', 'Ü');
assertValidParse('9', 9);
assertValidParse('-9', -9);
assertValidParse('0.129', 0.129);
assertValidParse('23e3', 23e3);
assertValidParse('1.2E+3', 1.2E+3);
assertValidParse('1.2E-3', 1.2E-3);
assertValidParse('1.2E-3 // comment', 1.2E-3);
});
test('parse: objects', () => {
assertValidParse('{}', {});
assertValidParse('{ "foo": true }', { foo: true });
assertValidParse('{ "bar": 8, "xoo": "foo" }', { bar: 8, xoo: 'foo' });
assertValidParse('{ "hello": [], "world": {} }', { hello: [], world: {} });
assertValidParse('{ "a": false, "b": true, "c": [ 7.4 ] }', { a: false, b: true, c: [7.4] });
assertValidParse('{ "lineComment": "//", "blockComment": ["/*", "*/"], "brackets": [ ["{", "}"], ["[", "]"], ["(", ")"] ] }', { lineComment: '//', blockComment: ['/*', '*/'], brackets: [['{', '}'], ['[', ']'], ['(', ')']] });
assertValidParse('{ "hello": [], "world": {} }', { hello: [], world: {} });
assertValidParse('{ "hello": { "again": { "inside": 5 }, "world": 1 }}', { hello: { again: { inside: 5 }, world: 1 } });
assertValidParse('{ "foo": /*hello*/true }', { foo: true });
});
test('parse: arrays', () => {
assertValidParse('[]', []);
assertValidParse('[ [], [ [] ]]', [[], [[]]]);
assertValidParse('[ 1, 2, 3 ]', [1, 2, 3]);
assertValidParse('[ { "a": null } ]', [{ a: null }]);
});
test('parse: objects with errors', () => {
assertInvalidParse('{,}', {});
assertInvalidParse('{ "foo": true, }', { foo: true });
assertInvalidParse('{ "bar": 8 "xoo": "foo" }', { bar: 8, xoo: 'foo' });
assertInvalidParse('{ ,"bar": 8 }', { bar: 8 });
assertInvalidParse('{ ,"bar": 8, "foo" }', { bar: 8 });
assertInvalidParse('{ "bar": 8, "foo": }', { bar: 8 });
assertInvalidParse('{ 8, "foo": 9 }', { foo: 9 });
});
test('parse: array with errors', () => {
assertInvalidParse('[,]', []);
assertInvalidParse('[ 1, 2, ]', [1, 2]);
assertInvalidParse('[ 1 2, 3 ]', [1, 2, 3]);
assertInvalidParse('[ ,1, 2, 3 ]', [1, 2, 3]);
assertInvalidParse('[ ,1, 2, 3, ]', [1, 2, 3]);
});
test('parse: disallow commments', () => {
let options = { disallowComments: true };
assertValidParse('[ 1, 2, null, "foo" ]', [1, 2, null, 'foo'], options);
assertValidParse('{ "hello": [], "world": {} }', { hello: [], world: {} }, options);
assertInvalidParse('{ "foo": /*comment*/ true }', { foo: true }, options);
});
test('parse: trailing comma', () => {
let options = { allowTrailingComma: true };
assertValidParse('{ "hello": [], }', { hello: [] }, options);
assertValidParse('{ "hello": [] }', { hello: [] }, options);
assertValidParse('{ "hello": [], "world": {}, }', { hello: [], world: {} }, options);
assertValidParse('{ "hello": [], "world": {} }', { hello: [], world: {} }, options);
assertInvalidParse('{ "hello": [], }', { hello: [] });
assertInvalidParse('{ "hello": [], "world": {}, }', { hello: [], world: {} });
});
test('location: properties', () => {
assertLocation('|{ "foo": "bar" }', [], void 0, false);
assertLocation('{| "foo": "bar" }', [''], void 0, true);
assertLocation('{ |"foo": "bar" }', ['foo'], 'property', true);
assertLocation('{ "foo|": "bar" }', ['foo'], 'property', true);
assertLocation('{ "foo"|: "bar" }', ['foo'], 'property', true);
assertLocation('{ "foo": "bar"| }', ['foo'], 'string', false);
assertLocation('{ "foo":| "bar" }', ['foo'], void 0, false);
assertLocation('{ "foo": {"bar|": 1, "car": 2 } }', ['foo', 'bar'], 'property', true);
assertLocation('{ "foo": {"bar": 1|, "car": 3 } }', ['foo', 'bar'], 'number', false);
assertLocation('{ "foo": {"bar": 1,| "car": 4 } }', ['foo', ''], void 0, true);
assertLocation('{ "foo": {"bar": 1, "ca|r": 5 } }', ['foo', 'car'], 'property', true);
assertLocation('{ "foo": {"bar": 1, "car": 6| } }', ['foo', 'car'], 'number', false);
assertLocation('{ "foo": {"bar": 1, "car": 7 }| }', ['foo'], void 0, false);
assertLocation('{ "foo": {"bar": 1, "car": 8 },| "goo": {} }', [''], void 0, true);
assertLocation('{ "foo": {"bar": 1, "car": 9 }, "go|o": {} }', ['goo'], 'property', true);
assertLocation('{ "dep": {"bar": 1, "car": |', ['dep', 'car'], void 0, false);
assertLocation('{ "dep": {"bar": 1,, "car": |', ['dep', 'car'], void 0, false);
assertLocation('{ "dep": {"bar": "na", "dar": "ma", "car": | } }', ['dep', 'car'], void 0, false);
});
test('location: arrays', () => {
assertLocation('|["foo", null ]', [], void 0, false);
assertLocation('[|"foo", null ]', [0], 'string', false);
assertLocation('["foo"|, null ]', [0], 'string', false);
assertLocation('["foo",| null ]', [1], void 0, false);
assertLocation('["foo", |null ]', [1], 'null', false);
assertLocation('["foo", null,| ]', [2], void 0, false);
assertLocation('["foo", null,,| ]', [3], void 0, false);
assertLocation('[["foo", null,, ],|', [1], void 0, false);
});
test('tree: literals', () => {
assertTree('true', { type: 'boolean', offset: 0, length: 4, value: true });
assertTree('false', { type: 'boolean', offset: 0, length: 5, value: false });
assertTree('null', { type: 'null', offset: 0, length: 4, value: null });
assertTree('23', { type: 'number', offset: 0, length: 2, value: 23 });
assertTree('-1.93e-19', { type: 'number', offset: 0, length: 9, value: -1.93e-19 });
assertTree('"hello"', { type: 'string', offset: 0, length: 7, value: 'hello' });
});
test('tree: arrays', () => {
assertTree('[]', { type: 'array', offset: 0, length: 2, children: [] });
assertTree('[ 1 ]', { type: 'array', offset: 0, length: 5, children: [{ type: 'number', offset: 2, length: 1, value: 1 }] });
assertTree('[ 1,"x"]', {
type: 'array', offset: 0, length: 8, children: [
{ type: 'number', offset: 2, length: 1, value: 1 },
{ type: 'string', offset: 4, length: 3, value: 'x' }
]
});
assertTree('[[]]', {
type: 'array', offset: 0, length: 4, children: [
{ type: 'array', offset: 1, length: 2, children: [] }
]
});
});
test('tree: objects', () => {
assertTree('{ }', { type: 'object', offset: 0, length: 3, children: [] });
assertTree('{ "val": 1 }', {
type: 'object', offset: 0, length: 12, children: [
{
type: 'property', offset: 2, length: 8, columnOffset: 7, children: [
{ type: 'string', offset: 2, length: 5, value: 'val' },
{ type: 'number', offset: 9, length: 1, value: 1 }
]
}
]
});
assertTree('{"id": "$", "v": [ null, null] }',
{
type: 'object', offset: 0, length: 32, children: [
{
type: 'property', offset: 1, length: 9, columnOffset: 5, children: [
{ type: 'string', offset: 1, length: 4, value: 'id' },
{ type: 'string', offset: 7, length: 3, value: '$' }
]
},
{
type: 'property', offset: 12, length: 18, columnOffset: 15, children: [
{ type: 'string', offset: 12, length: 3, value: 'v' },
{
type: 'array', offset: 17, length: 13, children: [
{ type: 'null', offset: 19, length: 4, value: null },
{ type: 'null', offset: 25, length: 4, value: null }
]
}
]
}
]
}
);
assertTree('{ "id": { "foo": { } } , }',
{
type: 'object', offset: 0, length: 27, children: [
{
type: 'property', offset: 3, length: 20, columnOffset: 7, children: [
{ type: 'string', offset: 3, length: 4, value: 'id' },
{
type: 'object', offset: 9, length: 14, children: [
{
type: 'property', offset: 11, length: 10, columnOffset: 16, children: [
{ type: 'string', offset: 11, length: 5, value: 'foo' },
{ type: 'object', offset: 18, length: 3, children: [] }
]
}
]
}
]
}
]
}
, [ParseErrorCode.PropertyNameExpected, ParseErrorCode.ValueExpected]);
});
test('tree: find location', () => {
let root = parseTree('{ "key1": { "key11": [ "val111", "val112" ] }, "key2": [ { "key21": false, "key22": 221 }, null, [{}] ] }');
assertNodeAtLocation(root, ['key1'], { key11: ['val111', 'val112'] });
assertNodeAtLocation(root, ['key1', 'key11'], ['val111', 'val112']);
assertNodeAtLocation(root, ['key1', 'key11', 0], 'val111');
assertNodeAtLocation(root, ['key1', 'key11', 1], 'val112');
assertNodeAtLocation(root, ['key1', 'key11', 2], void 0);
assertNodeAtLocation(root, ['key2', 0, 'key21'], false);
assertNodeAtLocation(root, ['key2', 0, 'key22'], 221);
assertNodeAtLocation(root, ['key2', 1], null);
assertNodeAtLocation(root, ['key2', 2], [{}]);
assertNodeAtLocation(root, ['key2', 2, 0], {});
});
test('location: matches', () => {
assertMatchesLocation('{ "dependencies": { | } }', ['dependencies']);
assertMatchesLocation('{ "dependencies": { "fo| } }', ['dependencies']);
assertMatchesLocation('{ "dependencies": { "fo|" } }', ['dependencies']);
assertMatchesLocation('{ "dependencies": { "fo|": 1 } }', ['dependencies']);
assertMatchesLocation('{ "dependencies": { "fo|": 1 } }', ['dependencies']);
assertMatchesLocation('{ "dependencies": { "fo": | } }', ['dependencies', '*']);
});
});

View File

@@ -0,0 +1,165 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { FormattingOptions, Edit } from 'vs/base/common/jsonFormatter';
import { setProperty, removeProperty } from 'vs/base/common/jsonEdit';
import assert = require('assert');
suite('JSON - edits', () => {
function assertEdit(content: string, edits: Edit[], expected: string) {
assert(edits);
let lastEditOffset = content.length;
for (let i = edits.length - 1; i >= 0; i--) {
let edit = edits[i];
assert(edit.offset >= 0 && edit.length >= 0 && edit.offset + edit.length <= content.length);
assert(typeof edit.content === 'string');
assert(lastEditOffset >= edit.offset + edit.length); // make sure all edits are ordered
lastEditOffset = edit.offset;
content = content.substring(0, edit.offset) + edit.content + content.substring(edit.offset + edit.length);
}
assert.equal(content, expected);
}
let formatterOptions: FormattingOptions = {
insertSpaces: true,
tabSize: 2,
eol: '\n'
};
test('set property', () => {
let content = '{\n "x": "y"\n}';
let edits = setProperty(content, ['x'], 'bar', formatterOptions);
assertEdit(content, edits, '{\n "x": "bar"\n}');
content = 'true';
edits = setProperty(content, [], 'bar', formatterOptions);
assertEdit(content, edits, '"bar"');
content = '{\n "x": "y"\n}';
edits = setProperty(content, ['x'], { key: true }, formatterOptions);
assertEdit(content, edits, '{\n "x": {\n "key": true\n }\n}');
content = '{\n "a": "b", "x": "y"\n}';
edits = setProperty(content, ['a'], null, formatterOptions);
assertEdit(content, edits, '{\n "a": null, "x": "y"\n}');
});
test('insert property', () => {
let content = '{}';
let edits = setProperty(content, ['foo'], 'bar', formatterOptions);
assertEdit(content, edits, '{\n "foo": "bar"\n}');
edits = setProperty(content, ['foo', 'foo2'], 'bar', formatterOptions);
assertEdit(content, edits, '{\n "foo": {\n "foo2": "bar"\n }\n}');
content = '{\n}';
edits = setProperty(content, ['foo'], 'bar', formatterOptions);
assertEdit(content, edits, '{\n "foo": "bar"\n}');
content = ' {\n }';
edits = setProperty(content, ['foo'], 'bar', formatterOptions);
assertEdit(content, edits, ' {\n "foo": "bar"\n }');
content = '{\n "x": "y"\n}';
edits = setProperty(content, ['foo'], 'bar', formatterOptions);
assertEdit(content, edits, '{\n "x": "y",\n "foo": "bar"\n}');
content = '{\n "x": "y"\n}';
edits = setProperty(content, ['e'], 'null', formatterOptions);
assertEdit(content, edits, '{\n "x": "y",\n "e": "null"\n}');
edits = setProperty(content, ['x'], 'bar', formatterOptions);
assertEdit(content, edits, '{\n "x": "bar"\n}');
content = '{\n "x": {\n "a": 1,\n "b": true\n }\n}\n';
edits = setProperty(content, ['x'], 'bar', formatterOptions);
assertEdit(content, edits, '{\n "x": "bar"\n}\n');
edits = setProperty(content, ['x', 'b'], 'bar', formatterOptions);
assertEdit(content, edits, '{\n "x": {\n "a": 1,\n "b": "bar"\n }\n}\n');
edits = setProperty(content, ['x', 'c'], 'bar', formatterOptions, () => 0);
assertEdit(content, edits, '{\n "x": {\n "c": "bar",\n "a": 1,\n "b": true\n }\n}\n');
edits = setProperty(content, ['x', 'c'], 'bar', formatterOptions, () => 1);
assertEdit(content, edits, '{\n "x": {\n "a": 1,\n "c": "bar",\n "b": true\n }\n}\n');
edits = setProperty(content, ['x', 'c'], 'bar', formatterOptions, () => 2);
assertEdit(content, edits, '{\n "x": {\n "a": 1,\n "b": true,\n "c": "bar"\n }\n}\n');
edits = setProperty(content, ['c'], 'bar', formatterOptions);
assertEdit(content, edits, '{\n "x": {\n "a": 1,\n "b": true\n },\n "c": "bar"\n}\n');
content = '{\n "a": [\n {\n } \n ] \n}';
edits = setProperty(content, ['foo'], 'bar', formatterOptions);
assertEdit(content, edits, '{\n "a": [\n {\n } \n ],\n "foo": "bar"\n}');
content = '';
edits = setProperty(content, ['foo', 0], 'bar', formatterOptions);
assertEdit(content, edits, '{\n "foo": [\n "bar"\n ]\n}');
content = '//comment';
edits = setProperty(content, ['foo', 0], 'bar', formatterOptions);
assertEdit(content, edits, '{\n "foo": [\n "bar"\n ]\n} //comment\n');
});
test('remove property', () => {
let content = '{\n "x": "y"\n}';
let edits = removeProperty(content, ['x'], formatterOptions);
assertEdit(content, edits, '{}');
content = '{\n "x": "y", "a": []\n}';
edits = removeProperty(content, ['x'], formatterOptions);
assertEdit(content, edits, '{\n "a": []\n}');
content = '{\n "x": "y", "a": []\n}';
edits = removeProperty(content, ['a'], formatterOptions);
assertEdit(content, edits, '{\n "x": "y"\n}');
});
test('insert item to empty array', () => {
let content = '[\n]';
let edits = setProperty(content, [-1], 'bar', formatterOptions);
assertEdit(content, edits, '[\n "bar"\n]');
});
test('insert item', () => {
let content = '[\n 1,\n 2\n]';
let edits = setProperty(content, [-1], 'bar', formatterOptions);
assertEdit(content, edits, '[\n 1,\n 2,\n "bar"\n]');
});
test('remove item in array with one item', () => {
let content = '[\n 1\n]';
let edits = setProperty(content, [0], void 0, formatterOptions);
assertEdit(content, edits, '[]');
});
test('remove item in the middle of the array', () => {
let content = '[\n 1,\n 2,\n 3\n]';
let edits = setProperty(content, [1], void 0, formatterOptions);
assertEdit(content, edits, '[\n 1,\n 3\n]');
});
test('remove last item in the array', () => {
let content = '[\n 1,\n 2,\n "bar"\n]';
let edits = setProperty(content, [2], void 0, formatterOptions);
assertEdit(content, edits, '[\n 1,\n 2\n]');
});
test('remove last item in the array if ends with comma', () => {
let content = '[\n 1,\n "foo",\n "bar",\n]';
let edits = setProperty(content, [2], void 0, formatterOptions);
assertEdit(content, edits, '[\n 1,\n "foo"\n]');
});
test('remove last item in the array if there is a comment in the beginning', () => {
let content = '// This is a comment\n[\n 1,\n "foo",\n "bar"\n]';
let edits = setProperty(content, [2], void 0, formatterOptions);
assertEdit(content, edits, '// This is a comment\n[\n 1,\n "foo"\n]');
});
});

View File

@@ -0,0 +1,443 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import Formatter = require('vs/base/common/jsonFormatter');
import assert = require('assert');
suite('JSON - formatter', () => {
function format(content: string, expected: string, insertSpaces = true) {
let range = void 0;
var rangeStart = content.indexOf('|');
var rangeEnd = content.lastIndexOf('|');
if (rangeStart !== -1 && rangeEnd !== -1) {
content = content.substring(0, rangeStart) + content.substring(rangeStart + 1, rangeEnd) + content.substring(rangeEnd + 1);
range = { offset: rangeStart, length: rangeEnd - rangeStart };
}
var edits = Formatter.format(content, range, { tabSize: 2, insertSpaces: insertSpaces, eol: '\n' });
let lastEditOffset = content.length;
for (let i = edits.length - 1; i >= 0; i--) {
let edit = edits[i];
assert(edit.offset >= 0 && edit.length >= 0 && edit.offset + edit.length <= content.length);
assert(typeof edit.content === 'string');
assert(lastEditOffset >= edit.offset + edit.length); // make sure all edits are ordered
lastEditOffset = edit.offset;
content = content.substring(0, edit.offset) + edit.content + content.substring(edit.offset + edit.length);
}
assert.equal(content, expected);
}
test('object - single property', () => {
var content = [
'{"x" : 1}'
].join('\n');
var expected = [
'{',
' "x": 1',
'}'
].join('\n');
format(content, expected);
});
test('object - multiple properties', () => {
var content = [
'{"x" : 1, "y" : "foo", "z" : true}'
].join('\n');
var expected = [
'{',
' "x": 1,',
' "y": "foo",',
' "z": true',
'}'
].join('\n');
format(content, expected);
});
test('object - no properties ', () => {
var content = [
'{"x" : { }, "y" : {}}'
].join('\n');
var expected = [
'{',
' "x": {},',
' "y": {}',
'}'
].join('\n');
format(content, expected);
});
test('object - nesting', () => {
var content = [
'{"x" : { "y" : { "z" : { }}, "a": true}}'
].join('\n');
var expected = [
'{',
' "x": {',
' "y": {',
' "z": {}',
' },',
' "a": true',
' }',
'}'
].join('\n');
format(content, expected);
});
test('array - single items', () => {
var content = [
'["[]"]'
].join('\n');
var expected = [
'[',
' "[]"',
']'
].join('\n');
format(content, expected);
});
test('array - multiple items', () => {
var content = [
'[true,null,1.2]'
].join('\n');
var expected = [
'[',
' true,',
' null,',
' 1.2',
']'
].join('\n');
format(content, expected);
});
test('array - no items', () => {
var content = [
'[ ]'
].join('\n');
var expected = [
'[]'
].join('\n');
format(content, expected);
});
test('array - nesting', () => {
var content = [
'[ [], [ [ {} ], "a" ] ]'
].join('\n');
var expected = [
'[',
' [],',
' [',
' [',
' {}',
' ],',
' "a"',
' ]',
']',
].join('\n');
format(content, expected);
});
test('syntax errors', () => {
var content = [
'[ null 1.2 ]'
].join('\n');
var expected = [
'[',
' null 1.2',
']',
].join('\n');
format(content, expected);
});
test('empty lines', () => {
var content = [
'{',
'"a": true,',
'',
'"b": true',
'}',
].join('\n');
var expected = [
'{',
'\t"a": true,',
'\t"b": true',
'}',
].join('\n');
format(content, expected, false);
});
test('single line comment', () => {
var content = [
'[ ',
'//comment',
'"foo", "bar"',
'] '
].join('\n');
var expected = [
'[',
' //comment',
' "foo",',
' "bar"',
']',
].join('\n');
format(content, expected);
});
test('block line comment', () => {
var content = [
'[{',
' /*comment*/ ',
'"foo" : true',
'}] '
].join('\n');
var expected = [
'[',
' {',
' /*comment*/',
' "foo": true',
' }',
']',
].join('\n');
format(content, expected);
});
test('single line comment on same line', () => {
var content = [
' { ',
' "a": {}// comment ',
' } '
].join('\n');
var expected = [
'{',
' "a": {} // comment ',
'}',
].join('\n');
format(content, expected);
});
test('single line comment on same line 2', () => {
var content = [
'{ //comment',
'}'
].join('\n');
var expected = [
'{ //comment',
'}'
].join('\n');
format(content, expected);
});
test('block comment on same line', () => {
var content = [
'{ "a": {}, /*comment*/ ',
' /*comment*/ "b": {}, ',
' "c": {/*comment*/} } ',
].join('\n');
var expected = [
'{',
' "a": {}, /*comment*/',
' /*comment*/ "b": {},',
' "c": { /*comment*/}',
'}',
].join('\n');
format(content, expected);
});
test('block comment on same line advanced', () => {
var content = [
' { "d": [',
' null',
' ] /*comment*/',
' ,"e": /*comment*/ [null] }',
].join('\n');
var expected = [
'{',
' "d": [',
' null',
' ] /*comment*/,',
' "e": /*comment*/ [',
' null',
' ]',
'}',
].join('\n');
format(content, expected);
});
test('multiple block comments on same line', () => {
var content = [
'{ "a": {} /*comment*/, /*comment*/ ',
' /*comment*/ "b": {} /*comment*/ } '
].join('\n');
var expected = [
'{',
' "a": {} /*comment*/, /*comment*/',
' /*comment*/ "b": {} /*comment*/',
'}',
].join('\n');
format(content, expected);
});
test('multiple mixed comments on same line', () => {
var content = [
'[ /*comment*/ /*comment*/ // comment ',
']'
].join('\n');
var expected = [
'[ /*comment*/ /*comment*/ // comment ',
']'
].join('\n');
format(content, expected);
});
test('range', () => {
var content = [
'{ "a": {},',
'|"b": [null, null]|',
'} '
].join('\n');
var expected = [
'{ "a": {},',
'"b": [',
' null,',
' null',
']',
'} ',
].join('\n');
format(content, expected);
});
test('range with existing indent', () => {
var content = [
'{ "a": {},',
' |"b": [null],',
'"c": {}',
'} |'
].join('\n');
var expected = [
'{ "a": {},',
' "b": [',
' null',
' ],',
' "c": {}',
'}',
].join('\n');
format(content, expected);
});
test('range with existing indent - tabs', () => {
var content = [
'{ "a": {},',
'| "b": [null], ',
'"c": {}',
'} | '
].join('\n');
var expected = [
'{ "a": {},',
'\t"b": [',
'\t\tnull',
'\t],',
'\t"c": {}',
'}',
].join('\n');
format(content, expected, false);
});
test('block comment none-line breaking symbols', () => {
var content = [
'{ "a": [ 1',
'/* comment */',
', 2',
'/* comment */',
']',
'/* comment */',
',',
' "b": true',
'/* comment */',
'}'
].join('\n');
var expected = [
'{',
' "a": [',
' 1',
' /* comment */',
' ,',
' 2',
' /* comment */',
' ]',
' /* comment */',
' ,',
' "b": true',
' /* comment */',
'}',
].join('\n');
format(content, expected);
});
test('line comment after none-line breaking symbols', () => {
var content = [
'{ "a":',
'// comment',
'null,',
' "b"',
'// comment',
': null',
'// comment',
'}'
].join('\n');
var expected = [
'{',
' "a":',
' // comment',
' null,',
' "b"',
' // comment',
' : null',
' // comment',
'}',
].join('\n');
format(content, expected);
});
});

View File

@@ -0,0 +1,100 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import { KeyCode, KeyMod, KeyChord, Keybinding, createKeybinding, SimpleKeybinding, ChordKeybinding } from 'vs/base/common/keyCodes';
import { OperatingSystem } from 'vs/base/common/platform';
suite('keyCodes', () => {
function testBinaryEncoding(expected: Keybinding, k: number, OS: OperatingSystem): void {
assert.deepEqual(createKeybinding(k, OS), expected);
}
test('MAC binary encoding', () => {
function test(expected: Keybinding, k: number): void {
testBinaryEncoding(expected, k, OperatingSystem.Macintosh);
}
test(null, 0);
test(new SimpleKeybinding(false, false, false, false, KeyCode.Enter), KeyCode.Enter);
test(new SimpleKeybinding(true, false, false, false, KeyCode.Enter), KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(false, false, true, false, KeyCode.Enter), KeyMod.Alt | KeyCode.Enter);
test(new SimpleKeybinding(true, false, true, false, KeyCode.Enter), KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(false, true, false, false, KeyCode.Enter), KeyMod.Shift | KeyCode.Enter);
test(new SimpleKeybinding(true, true, false, false, KeyCode.Enter), KeyMod.Shift | KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(false, true, true, false, KeyCode.Enter), KeyMod.Shift | KeyMod.Alt | KeyCode.Enter);
test(new SimpleKeybinding(true, true, true, false, KeyCode.Enter), KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(false, false, false, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyCode.Enter);
test(new SimpleKeybinding(true, false, false, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(false, false, true, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.Enter);
test(new SimpleKeybinding(true, false, true, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(false, true, false, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Enter);
test(new SimpleKeybinding(true, true, false, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(false, true, true, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyCode.Enter);
test(new SimpleKeybinding(true, true, true, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter);
test(
new ChordKeybinding(
new SimpleKeybinding(false, false, false, false, KeyCode.Enter),
new SimpleKeybinding(false, false, false, false, KeyCode.Tab)
),
KeyChord(KeyCode.Enter, KeyCode.Tab)
);
test(
new ChordKeybinding(
new SimpleKeybinding(false, false, false, true, KeyCode.KEY_Y),
new SimpleKeybinding(false, false, false, false, KeyCode.KEY_Z)
),
KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_Y, KeyCode.KEY_Z)
);
});
test('WINDOWS & LINUX binary encoding', () => {
[OperatingSystem.Linux, OperatingSystem.Windows].forEach((OS) => {
function test(expected: Keybinding, k: number): void {
testBinaryEncoding(expected, k, OS);
}
test(null, 0);
test(new SimpleKeybinding(false, false, false, false, KeyCode.Enter), KeyCode.Enter);
test(new SimpleKeybinding(false, false, false, true, KeyCode.Enter), KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(false, false, true, false, KeyCode.Enter), KeyMod.Alt | KeyCode.Enter);
test(new SimpleKeybinding(false, false, true, true, KeyCode.Enter), KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(false, true, false, false, KeyCode.Enter), KeyMod.Shift | KeyCode.Enter);
test(new SimpleKeybinding(false, true, false, true, KeyCode.Enter), KeyMod.Shift | KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(false, true, true, false, KeyCode.Enter), KeyMod.Shift | KeyMod.Alt | KeyCode.Enter);
test(new SimpleKeybinding(false, true, true, true, KeyCode.Enter), KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(true, false, false, false, KeyCode.Enter), KeyMod.CtrlCmd | KeyCode.Enter);
test(new SimpleKeybinding(true, false, false, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(true, false, true, false, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.Enter);
test(new SimpleKeybinding(true, false, true, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(true, true, false, false, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Enter);
test(new SimpleKeybinding(true, true, false, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(true, true, true, false, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyCode.Enter);
test(new SimpleKeybinding(true, true, true, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter);
test(
new ChordKeybinding(
new SimpleKeybinding(false, false, false, false, KeyCode.Enter),
new SimpleKeybinding(false, false, false, false, KeyCode.Tab)
),
KeyChord(KeyCode.Enter, KeyCode.Tab)
);
test(
new ChordKeybinding(
new SimpleKeybinding(true, false, false, false, KeyCode.KEY_Y),
new SimpleKeybinding(false, false, false, false, KeyCode.KEY_Z)
),
KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_Y, KeyCode.KEY_Z)
);
});
});
});

View File

@@ -0,0 +1,146 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import labels = require('vs/base/common/labels');
import platform = require('vs/base/common/platform');
suite('Labels', () => {
test('shorten - windows', () => {
if (!platform.isWindows) {
assert.ok(true);
return;
}
// nothing to shorten
assert.deepEqual(labels.shorten(['a']), ['a']);
assert.deepEqual(labels.shorten(['a', 'b']), ['a', 'b']);
assert.deepEqual(labels.shorten(['a', 'b', 'c']), ['a', 'b', 'c']);
// completely different paths
assert.deepEqual(labels.shorten(['a\\b', 'c\\d', 'e\\f']), ['…\\b', '…\\d', '…\\f']);
// same beginning
assert.deepEqual(labels.shorten(['a', 'a\\b']), ['a', '…\\b']);
assert.deepEqual(labels.shorten(['a\\b', 'a\\b\\c']), ['…\\b', '…\\c']);
assert.deepEqual(labels.shorten(['a', 'a\\b', 'a\\b\\c']), ['a', '…\\b', '…\\c']);
assert.deepEqual(labels.shorten(['x:\\a\\b', 'x:\\a\\c']), ['x:\\…\\b', 'x:\\…\\c']);
assert.deepEqual(labels.shorten(['\\\\a\\b', '\\\\a\\c']), ['\\\\a\\b', '\\\\a\\c']);
// same ending
assert.deepEqual(labels.shorten(['a', 'b\\a']), ['a', 'b\\…']);
assert.deepEqual(labels.shorten(['a\\b\\c', 'd\\b\\c']), ['a\\…', 'd\\…']);
assert.deepEqual(labels.shorten(['a\\b\\c\\d', 'f\\b\\c\\d']), ['a\\…', 'f\\…']);
assert.deepEqual(labels.shorten(['d\\e\\a\\b\\c', 'd\\b\\c']), ['…\\a\\…', 'd\\b\\…']);
assert.deepEqual(labels.shorten(['a\\b\\c\\d', 'a\\f\\b\\c\\d']), ['a\\b\\…', '…\\f\\…']);
assert.deepEqual(labels.shorten(['a\\b\\a', 'b\\b\\a']), ['a\\b\\…', 'b\\b\\…']);
assert.deepEqual(labels.shorten(['d\\f\\a\\b\\c', 'h\\d\\b\\c']), ['…\\a\\…', 'h\\…']);
assert.deepEqual(labels.shorten(['a\\b\\c', 'x:\\0\\a\\b\\c']), ['a\\b\\c', 'x:\\0\\…']);
assert.deepEqual(labels.shorten(['x:\\a\\b\\c', 'x:\\0\\a\\b\\c']), ['x:\\a\\…', 'x:\\0\\…']);
assert.deepEqual(labels.shorten(['x:\\a\\b', 'y:\\a\\b']), ['x:\\…', 'y:\\…']);
assert.deepEqual(labels.shorten(['x:\\a', 'x:\\c']), ['x:\\a', 'x:\\c']);
assert.deepEqual(labels.shorten(['x:\\a\\b', 'y:\\x\\a\\b']), ['x:\\…', 'y:\\…']);
assert.deepEqual(labels.shorten(['\\\\x\\b', '\\\\y\\b']), ['\\\\x\\…', '\\\\y\\…']);
assert.deepEqual(labels.shorten(['\\\\x\\a', '\\\\x\\b']), ['\\\\x\\a', '\\\\x\\b']);
// same name ending
assert.deepEqual(labels.shorten(['a\\b', 'a\\c', 'a\\e-b']), ['…\\b', '…\\c', '…\\e-b']);
// same in the middle
assert.deepEqual(labels.shorten(['a\\b\\c', 'd\\b\\e']), ['…\\c', '…\\e']);
// case-sensetive
assert.deepEqual(labels.shorten(['a\\b\\c', 'd\\b\\C']), ['…\\c', '…\\C']);
// empty or null
assert.deepEqual(labels.shorten(['', null]), ['.\\', null]);
assert.deepEqual(labels.shorten(['a', 'a\\b', 'a\\b\\c', 'd\\b\\c', 'd\\b']), ['a', 'a\\b', 'a\\b\\c', 'd\\b\\c', 'd\\b']);
assert.deepEqual(labels.shorten(['a', 'a\\b', 'b']), ['a', 'a\\b', 'b']);
assert.deepEqual(labels.shorten(['', 'a', 'b', 'b\\c', 'a\\c']), ['.\\', 'a', 'b', 'b\\c', 'a\\c']);
assert.deepEqual(labels.shorten(['src\\vs\\workbench\\parts\\execution\\electron-browser', 'src\\vs\\workbench\\parts\\execution\\electron-browser\\something', 'src\\vs\\workbench\\parts\\terminal\\electron-browser']), ['…\\execution\\electron-browser', '…\\something', '…\\terminal\\…']);
});
test('shorten - not windows', () => {
if (platform.isWindows) {
assert.ok(true);
return;
}
// nothing to shorten
assert.deepEqual(labels.shorten(['a']), ['a']);
assert.deepEqual(labels.shorten(['a', 'b']), ['a', 'b']);
assert.deepEqual(labels.shorten(['a', 'b', 'c']), ['a', 'b', 'c']);
// completely different paths
assert.deepEqual(labels.shorten(['a/b', 'c/d', 'e/f']), ['…/b', '…/d', '…/f']);
// same beginning
assert.deepEqual(labels.shorten(['a', 'a/b']), ['a', '…/b']);
assert.deepEqual(labels.shorten(['a/b', 'a/b/c']), ['…/b', '…/c']);
assert.deepEqual(labels.shorten(['a', 'a/b', 'a/b/c']), ['a', '…/b', '…/c']);
assert.deepEqual(labels.shorten(['/a/b', '/a/c']), ['/a/b', '/a/c']);
// same ending
assert.deepEqual(labels.shorten(['a', 'b/a']), ['a', 'b/…']);
assert.deepEqual(labels.shorten(['a/b/c', 'd/b/c']), ['a/…', 'd/…']);
assert.deepEqual(labels.shorten(['a/b/c/d', 'f/b/c/d']), ['a/…', 'f/…']);
assert.deepEqual(labels.shorten(['d/e/a/b/c', 'd/b/c']), ['…/a/…', 'd/b/…']);
assert.deepEqual(labels.shorten(['a/b/c/d', 'a/f/b/c/d']), ['a/b/…', '…/f/…']);
assert.deepEqual(labels.shorten(['a/b/a', 'b/b/a']), ['a/b/…', 'b/b/…']);
assert.deepEqual(labels.shorten(['d/f/a/b/c', 'h/d/b/c']), ['…/a/…', 'h/…']);
assert.deepEqual(labels.shorten(['/x/b', '/y/b']), ['/x/…', '/y/…']);
// same name ending
assert.deepEqual(labels.shorten(['a/b', 'a/c', 'a/e-b']), ['…/b', '…/c', '…/e-b']);
// same in the middle
assert.deepEqual(labels.shorten(['a/b/c', 'd/b/e']), ['…/c', '…/e']);
// case-sensitive
assert.deepEqual(labels.shorten(['a/b/c', 'd/b/C']), ['…/c', '…/C']);
// empty or null
assert.deepEqual(labels.shorten(['', null]), ['./', null]);
assert.deepEqual(labels.shorten(['a', 'a/b', 'a/b/c', 'd/b/c', 'd/b']), ['a', 'a/b', 'a/b/c', 'd/b/c', 'd/b']);
assert.deepEqual(labels.shorten(['a', 'a/b', 'b']), ['a', 'a/b', 'b']);
assert.deepEqual(labels.shorten(['', 'a', 'b', 'b/c', 'a/c']), ['./', 'a', 'b', 'b/c', 'a/c']);
});
test('template', function () {
// simple
assert.strictEqual(labels.template('Foo Bar'), 'Foo Bar');
assert.strictEqual(labels.template('Foo${}Bar'), 'FooBar');
assert.strictEqual(labels.template('$FooBar'), '');
assert.strictEqual(labels.template('}FooBar'), '}FooBar');
assert.strictEqual(labels.template('Foo ${one} Bar', { one: 'value' }), 'Foo value Bar');
assert.strictEqual(labels.template('Foo ${one} Bar ${two}', { one: 'value', two: 'other value' }), 'Foo value Bar other value');
// conditional separator
assert.strictEqual(labels.template('Foo${separator}Bar'), 'FooBar');
assert.strictEqual(labels.template('Foo${separator}Bar', { separator: { label: ' - ' } }), 'FooBar');
assert.strictEqual(labels.template('${separator}Foo${separator}Bar', { value: 'something', separator: { label: ' - ' } }), 'FooBar');
assert.strictEqual(labels.template('${value} Foo${separator}Bar', { value: 'something', separator: { label: ' - ' } }), 'something FooBar');
// // real world example (macOS)
let t = '${activeEditorShort}${separator}${rootName}';
assert.strictEqual(labels.template(t, { activeEditorShort: '', rootName: '', separator: { label: ' - ' } }), '');
assert.strictEqual(labels.template(t, { activeEditorShort: '', rootName: 'root', separator: { label: ' - ' } }), 'root');
assert.strictEqual(labels.template(t, { activeEditorShort: 'markdown.txt', rootName: 'root', separator: { label: ' - ' } }), 'markdown.txt - root');
// // real world example (other)
t = '${dirty}${activeEditorShort}${separator}${rootName}${separator}${appName}';
assert.strictEqual(labels.template(t, { dirty: '', activeEditorShort: '', rootName: '', appName: '', separator: { label: ' - ' } }), '');
assert.strictEqual(labels.template(t, { dirty: '', activeEditorShort: '', rootName: '', appName: 'Visual Studio Code', separator: { label: ' - ' } }), 'Visual Studio Code');
assert.strictEqual(labels.template(t, { dirty: '', activeEditorShort: 'Untitled-1', rootName: '', appName: 'Visual Studio Code', separator: { label: ' - ' } }), 'Untitled-1 - Visual Studio Code');
assert.strictEqual(labels.template(t, { dirty: '', activeEditorShort: '', rootName: 'monaco', appName: 'Visual Studio Code', separator: { label: ' - ' } }), 'monaco - Visual Studio Code');
assert.strictEqual(labels.template(t, { dirty: '', activeEditorShort: 'somefile.txt', rootName: 'monaco', appName: 'Visual Studio Code', separator: { label: ' - ' } }), 'somefile.txt - monaco - Visual Studio Code');
assert.strictEqual(labels.template(t, { dirty: '* ', activeEditorShort: 'somefile.txt', rootName: 'monaco', appName: 'Visual Studio Code', separator: { label: ' - ' } }), '* somefile.txt - monaco - Visual Studio Code');
});
});

View File

@@ -0,0 +1,90 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import { IDisposable, dispose, ReferenceCollection } from 'vs/base/common/lifecycle';
class Disposable implements IDisposable {
isDisposed = false;
dispose() { this.isDisposed = true; }
}
suite('Lifecycle', () => {
test('dispose single disposable', () => {
const disposable = new Disposable();
assert(!disposable.isDisposed);
dispose(disposable);
assert(disposable.isDisposed);
});
test('dispose disposable array', () => {
const disposable = new Disposable();
const disposable2 = new Disposable();
assert(!disposable.isDisposed);
assert(!disposable2.isDisposed);
dispose([disposable, disposable2]);
assert(disposable.isDisposed);
assert(disposable2.isDisposed);
});
test('dispose disposables', () => {
const disposable = new Disposable();
const disposable2 = new Disposable();
assert(!disposable.isDisposed);
assert(!disposable2.isDisposed);
dispose(disposable, disposable2);
assert(disposable.isDisposed);
assert(disposable2.isDisposed);
});
});
suite('Reference Collection', () => {
class Collection extends ReferenceCollection<number> {
private _count = 0;
get count() { return this._count; }
protected createReferencedObject(key: string): number { this._count++; return key.length; }
protected destroyReferencedObject(object: number): void { this._count--; }
}
test('simple', () => {
const collection = new Collection();
const ref1 = collection.acquire('test');
assert(ref1);
assert.equal(ref1.object, 4);
assert.equal(collection.count, 1);
ref1.dispose();
assert.equal(collection.count, 0);
const ref2 = collection.acquire('test');
const ref3 = collection.acquire('test');
assert.equal(ref2.object, ref3.object);
assert.equal(collection.count, 1);
const ref4 = collection.acquire('monkey');
assert.equal(ref4.object, 6);
assert.equal(collection.count, 2);
ref2.dispose();
assert.equal(collection.count, 2);
ref3.dispose();
assert.equal(collection.count, 1);
ref4.dispose();
assert.equal(collection.count, 0);
});
});

View File

@@ -0,0 +1,499 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { BoundedMap, TrieMap, ResourceMap } from 'vs/base/common/map';
import * as assert from 'assert';
import URI from 'vs/base/common/uri';
suite('Map', () => {
test('BoundedMap - basics', function () {
const map = new BoundedMap<any>();
assert.equal(map.size, 0);
map.set('1', 1);
map.set('2', '2');
map.set('3', true);
const obj = Object.create(null);
map.set('4', obj);
const date = Date.now();
map.set('5', date);
assert.equal(map.size, 5);
assert.equal(map.get('1'), 1);
assert.equal(map.get('2'), '2');
assert.equal(map.get('3'), true);
assert.equal(map.get('4'), obj);
assert.equal(map.get('5'), date);
assert.ok(!map.get('6'));
map.delete('6');
assert.equal(map.size, 5);
assert.equal(map.delete('1'), 1);
assert.equal(map.delete('2'), '2');
assert.equal(map.delete('3'), true);
assert.equal(map.delete('4'), obj);
assert.equal(map.delete('5'), date);
assert.equal(map.size, 0);
assert.ok(!map.get('5'));
assert.ok(!map.get('4'));
assert.ok(!map.get('3'));
assert.ok(!map.get('2'));
assert.ok(!map.get('1'));
map.set('1', 1);
map.set('2', '2');
assert.ok(map.set('3', true)); // adding an element returns true
assert.ok(!map.set('3', true)); // adding it again returns false
assert.ok(map.has('1'));
assert.equal(map.get('1'), 1);
assert.equal(map.get('2'), '2');
assert.equal(map.get('3'), true);
map.clear();
assert.equal(map.size, 0);
assert.ok(!map.get('1'));
assert.ok(!map.get('2'));
assert.ok(!map.get('3'));
assert.ok(!map.has('1'));
const res = map.getOrSet('foo', 'bar');
assert.equal(map.get('foo'), res);
assert.equal(res, 'bar');
});
test('BoundedMap - serialization', function () {
const map = new BoundedMap<any>(5);
map.set('1', 1);
map.set('2', '2');
map.set('3', true);
const obj = Object.create(null);
map.set('4', obj);
const date = Date.now();
map.set('5', date);
const mapClone = new BoundedMap<any>(5, 1, map.serialize());
assert.deepEqual(map.serialize(), mapClone.serialize());
assert.equal(mapClone.size, 5);
assert.equal(mapClone.get('1'), 1);
assert.equal(mapClone.get('2'), '2');
assert.equal(mapClone.get('3'), true);
assert.equal(mapClone.get('4'), obj);
assert.equal(mapClone.get('5'), date);
assert.ok(!mapClone.get('6'));
mapClone.set('6', '6');
assert.equal(mapClone.size, 5);
assert.ok(!mapClone.get('1'));
});
test('BoundedMap - setLimit', function () {
const map = new BoundedMap<any>(5);
map.set('1', 1);
map.set('2', '2');
map.set('3', true);
const obj = Object.create(null);
map.set('4', obj);
const date = Date.now();
map.set('5', date);
assert.equal(map.size, 5);
assert.equal(map.get('1'), 1);
assert.equal(map.get('2'), '2');
assert.equal(map.get('3'), true);
assert.equal(map.get('4'), obj);
assert.equal(map.get('5'), date);
assert.ok(!map.get('6'));
map.setLimit(3);
assert.equal(map.size, 3);
assert.ok(!map.get('1'));
assert.ok(!map.get('2'));
assert.equal(map.get('3'), true);
assert.equal(map.get('4'), obj);
assert.equal(map.get('5'), date);
map.setLimit(0);
assert.equal(map.size, 0);
assert.ok(!map.get('3'));
assert.ok(!map.get('4'));
assert.ok(!map.get('5'));
map.set('6', 6);
assert.equal(map.size, 0);
assert.ok(!map.get('6'));
map.setLimit(100);
map.set('1', 1);
map.set('2', '2');
map.set('3', true);
map.set('4', obj);
map.set('5', date);
assert.equal(map.size, 5);
assert.equal(map.get('1'), 1);
assert.equal(map.get('2'), '2');
assert.equal(map.get('3'), true);
assert.equal(map.get('4'), obj);
assert.equal(map.get('5'), date);
});
test('BoundedMap - bounded', function () {
const map = new BoundedMap<number>(5);
assert.equal(0, map.size);
map.set('1', 1);
map.set('2', 2);
map.set('3', 3);
map.set('4', 4);
map.set('5', 5);
assert.equal(5, map.size);
assert.equal(map.get('1'), 1);
assert.equal(map.get('2'), 2);
assert.equal(map.get('3'), 3);
assert.equal(map.get('4'), 4);
assert.equal(map.get('5'), 5);
map.set('6', 6);
assert.equal(5, map.size);
assert.ok(!map.get('1'));
assert.equal(map.get('2'), 2);
assert.equal(map.get('3'), 3);
assert.equal(map.get('4'), 4);
assert.equal(map.get('5'), 5);
assert.equal(map.get('6'), 6);
map.set('7', 7);
map.set('8', 8);
map.set('9', 9);
assert.equal(5, map.size);
assert.ok(!map.get('1'));
assert.ok(!map.get('2'));
assert.ok(!map.get('3'));
assert.ok(!map.get('4'));
assert.equal(map.get('5'), 5);
assert.equal(map.get('6'), 6);
assert.equal(map.get('7'), 7);
assert.equal(map.get('8'), 8);
assert.equal(map.get('9'), 9);
map.delete('5');
map.delete('7');
assert.equal(3, map.size);
assert.ok(!map.get('5'));
assert.ok(!map.get('7'));
assert.equal(map.get('6'), 6);
assert.equal(map.get('8'), 8);
assert.equal(map.get('9'), 9);
map.set('10', 10);
map.set('11', 11);
map.set('12', 12);
map.set('13', 13);
map.set('14', 14);
assert.equal(5, map.size);
assert.equal(map.get('10'), 10);
assert.equal(map.get('11'), 11);
assert.equal(map.get('12'), 12);
assert.equal(map.get('13'), 13);
assert.equal(map.get('14'), 14);
});
test('BoundedMap - bounded with ratio', function () {
const map = new BoundedMap<number>(6, 0.5);
assert.equal(0, map.size);
map.set('1', 1);
map.set('2', 2);
map.set('3', 3);
map.set('4', 4);
map.set('5', 5);
map.set('6', 6);
assert.equal(6, map.size);
map.set('7', 7);
assert.equal(3, map.size);
assert.ok(!map.has('1'));
assert.ok(!map.has('2'));
assert.ok(!map.has('3'));
assert.ok(!map.has('4'));
assert.equal(map.get('5'), 5);
assert.equal(map.get('6'), 6);
assert.equal(map.get('7'), 7);
map.set('8', 8);
map.set('9', 9);
map.set('10', 10);
assert.equal(6, map.size);
assert.equal(map.get('5'), 5);
assert.equal(map.get('6'), 6);
assert.equal(map.get('7'), 7);
assert.equal(map.get('8'), 8);
assert.equal(map.get('9'), 9);
assert.equal(map.get('10'), 10);
});
test('BoundedMap - MRU order', function () {
const map = new BoundedMap<number>(3);
function peek(key) {
const res = map.get(key);
if (res) {
map.delete(key);
map.set(key, res);
}
return res;
}
assert.equal(0, map.size);
map.set('1', 1);
map.set('2', 2);
map.set('3', 3);
assert.equal(3, map.size);
assert.equal(map.get('1'), 1);
assert.equal(map.get('2'), 2);
assert.equal(map.get('3'), 3);
map.set('4', 4);
assert.equal(3, map.size);
assert.equal(peek('4'), 4); // this changes MRU order
assert.equal(peek('3'), 3);
assert.equal(peek('2'), 2);
map.set('5', 5);
map.set('6', 6);
assert.equal(3, map.size);
assert.equal(peek('2'), 2);
assert.equal(peek('5'), 5);
assert.equal(peek('6'), 6);
assert.ok(!map.has('3'));
assert.ok(!map.has('4'));
});
test('TrieMap - basics', function () {
const map = new TrieMap<number>();
map.insert('/user/foo/bar', 1);
map.insert('/user/foo', 2);
map.insert('/user/foo/flip/flop', 3);
assert.equal(map.findSubstr('/user/bar'), undefined);
assert.equal(map.findSubstr('/user/foo'), 2);
assert.equal(map.findSubstr('\\user\\foo'), 2);
assert.equal(map.findSubstr('/user/foo/ba'), 2);
assert.equal(map.findSubstr('/user/foo/far/boo'), 2);
assert.equal(map.findSubstr('/user/foo/bar'), 1);
assert.equal(map.findSubstr('/user/foo/bar/far/boo'), 1);
});
test('TrieMap - lookup', function () {
const map = new TrieMap<number>();
map.insert('/user/foo/bar', 1);
map.insert('/user/foo', 2);
map.insert('/user/foo/flip/flop', 3);
assert.equal(map.lookUp('/foo'), undefined);
assert.equal(map.lookUp('/user'), undefined);
assert.equal(map.lookUp('/user/foo'), 2);
assert.equal(map.lookUp('/user/foo/bar'), 1);
assert.equal(map.lookUp('/user/foo/bar/boo'), undefined);
});
test('TrieMap - superstr', function () {
const map = new TrieMap<number>();
map.insert('/user/foo/bar', 1);
map.insert('/user/foo', 2);
map.insert('/user/foo/flip/flop', 3);
const supMap = map.findSuperstr('/user');
assert.equal(supMap.lookUp('foo'), 2);
assert.equal(supMap.lookUp('foo/bar'), 1);
assert.equal(supMap.lookUp('foo/flip/flop'), 3);
assert.equal(supMap.lookUp('foo/flip/flop/bar'), undefined);
assert.equal(supMap.lookUp('user'), undefined);
});
test('ResourceMap - basics', function () {
const map = new ResourceMap<any>();
const resource1 = URI.parse('some://1');
const resource2 = URI.parse('some://2');
const resource3 = URI.parse('some://3');
const resource4 = URI.parse('some://4');
const resource5 = URI.parse('some://5');
const resource6 = URI.parse('some://6');
assert.equal(map.size, 0);
map.set(resource1, 1);
map.set(resource2, '2');
map.set(resource3, true);
const values = map.values();
assert.equal(values[0], 1);
assert.equal(values[1], '2');
assert.equal(values[2], true);
let counter = 0;
map.forEach(value => {
assert.equal(value, values[counter++]);
});
const obj = Object.create(null);
map.set(resource4, obj);
const date = Date.now();
map.set(resource5, date);
assert.equal(map.size, 5);
assert.equal(map.get(resource1), 1);
assert.equal(map.get(resource2), '2');
assert.equal(map.get(resource3), true);
assert.equal(map.get(resource4), obj);
assert.equal(map.get(resource5), date);
assert.ok(!map.get(resource6));
map.delete(resource6);
assert.equal(map.size, 5);
assert.ok(map.delete(resource1));
assert.ok(map.delete(resource2));
assert.ok(map.delete(resource3));
assert.ok(map.delete(resource4));
assert.ok(map.delete(resource5));
assert.equal(map.size, 0);
assert.ok(!map.get(resource5));
assert.ok(!map.get(resource4));
assert.ok(!map.get(resource3));
assert.ok(!map.get(resource2));
assert.ok(!map.get(resource1));
map.set(resource1, 1);
map.set(resource2, '2');
map.set(resource3, true);
assert.ok(map.has(resource1));
assert.equal(map.get(resource1), 1);
assert.equal(map.get(resource2), '2');
assert.equal(map.get(resource3), true);
map.clear();
assert.equal(map.size, 0);
assert.ok(!map.get(resource1));
assert.ok(!map.get(resource2));
assert.ok(!map.get(resource3));
assert.ok(!map.has(resource1));
map.set(resource1, false);
map.set(resource2, 0);
assert.ok(map.has(resource1));
assert.ok(map.has(resource2));
});
test('ResourceMap - files (do NOT ignorecase)', function () {
const map = new ResourceMap<any>();
const fileA = URI.parse('file://some/filea');
const fileB = URI.parse('some://some/other/fileb');
const fileAUpper = URI.parse('file://SOME/FILEA');
map.set(fileA, 'true');
assert.equal(map.get(fileA), 'true');
assert.ok(!map.get(fileAUpper));
assert.ok(!map.get(fileB));
map.set(fileAUpper, 'false');
assert.equal(map.get(fileAUpper), 'false');
assert.equal(map.get(fileA), 'true');
const windowsFile = URI.file('c:\\test with %25\\c#code');
const uncFile = URI.file('\\\\shäres\\path\\c#\\plugin.json');
map.set(windowsFile, 'true');
map.set(uncFile, 'true');
assert.equal(map.get(windowsFile), 'true');
assert.equal(map.get(uncFile), 'true');
});
test('ResourceMap - files (ignorecase)', function () {
const map = new ResourceMap<any>(true);
const fileA = URI.parse('file://some/filea');
const fileB = URI.parse('some://some/other/fileb');
const fileAUpper = URI.parse('file://SOME/FILEA');
map.set(fileA, 'true');
assert.equal(map.get(fileA), 'true');
assert.equal(map.get(fileAUpper), 'true');
assert.ok(!map.get(fileB));
map.set(fileAUpper, 'false');
assert.equal(map.get(fileAUpper), 'false');
assert.equal(map.get(fileA), 'false');
const windowsFile = URI.file('c:\\test with %25\\c#code');
const uncFile = URI.file('\\\\shäres\\path\\c#\\plugin.json');
map.set(windowsFile, 'true');
map.set(uncFile, 'true');
assert.equal(map.get(windowsFile), 'true');
assert.equal(map.get(uncFile), 'true');
});
});

View File

@@ -0,0 +1,40 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import URI from 'vs/base/common/uri';
import { parse, stringify } from 'vs/base/common/marshalling';
suite('Marshalling', () => {
test('RegExp', function () {
let value = /foo/img;
let raw = stringify(value);
let clone = <RegExp>parse(raw);
assert.equal(value.source, clone.source);
assert.equal(value.global, clone.global);
assert.equal(value.ignoreCase, clone.ignoreCase);
assert.equal(value.multiline, clone.multiline);
});
test('URI', function () {
let value = URI.from({ scheme: 'file', authority: 'server', path: '/shares/c#files', query: 'q', fragment: 'f' });
let raw = stringify(value);
let clone = <URI>parse(raw);
assert.equal(value.scheme, clone.scheme);
assert.equal(value.authority, clone.authority);
assert.equal(value.path, clone.path);
assert.equal(value.query, clone.query);
assert.equal(value.fragment, clone.fragment);
});
test('Bug 16793:# in folder name => mirror models get out of sync', () => {
var uri1 = URI.file('C:\\C#\\file.txt');
assert.equal(parse(stringify(uri1)).toString(), uri1.toString());
});
});

View File

@@ -0,0 +1,117 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import { guessMimeTypes, registerTextMime } from 'vs/base/common/mime';
suite('Mime', () => {
test('Dynamically Register Text Mime', () => {
let guess = guessMimeTypes('foo.monaco');
assert.deepEqual(guess, ['application/unknown']);
registerTextMime({ id: 'monaco', extension: '.monaco', mime: 'text/monaco' });
guess = guessMimeTypes('foo.monaco');
assert.deepEqual(guess, ['text/monaco', 'text/plain']);
guess = guessMimeTypes('.monaco');
assert.deepEqual(guess, ['text/monaco', 'text/plain']);
registerTextMime({ id: 'codefile', filename: 'Codefile', mime: 'text/code' });
guess = guessMimeTypes('Codefile');
assert.deepEqual(guess, ['text/code', 'text/plain']);
guess = guessMimeTypes('foo.Codefile');
assert.deepEqual(guess, ['application/unknown']);
registerTextMime({ id: 'docker', filepattern: 'Docker*', mime: 'text/docker' });
guess = guessMimeTypes('Docker-debug');
assert.deepEqual(guess, ['text/docker', 'text/plain']);
guess = guessMimeTypes('docker-PROD');
assert.deepEqual(guess, ['text/docker', 'text/plain']);
registerTextMime({ id: 'niceregex', mime: 'text/nice-regex', firstline: /RegexesAreNice/ });
guess = guessMimeTypes('Randomfile.noregistration', 'RegexesAreNice');
assert.deepEqual(guess, ['text/nice-regex', 'text/plain']);
guess = guessMimeTypes('Randomfile.noregistration', 'RegexesAreNotNice');
assert.deepEqual(guess, ['application/unknown']);
guess = guessMimeTypes('Codefile', 'RegexesAreNice');
assert.deepEqual(guess, ['text/code', 'text/plain']);
});
test('Mimes Priority', () => {
registerTextMime({ id: 'monaco', extension: '.monaco', mime: 'text/monaco' });
registerTextMime({ id: 'foobar', mime: 'text/foobar', firstline: /foobar/ });
let guess = guessMimeTypes('foo.monaco');
assert.deepEqual(guess, ['text/monaco', 'text/plain']);
guess = guessMimeTypes('foo.monaco', 'foobar');
assert.deepEqual(guess, ['text/monaco', 'text/plain']);
registerTextMime({ id: 'docker', filename: 'dockerfile', mime: 'text/winner' });
registerTextMime({ id: 'docker', filepattern: 'dockerfile*', mime: 'text/looser' });
guess = guessMimeTypes('dockerfile');
assert.deepEqual(guess, ['text/winner', 'text/plain']);
});
test('Specificity priority 1', () => {
registerTextMime({ id: 'monaco2', extension: '.monaco2', mime: 'text/monaco2' });
registerTextMime({ id: 'monaco2', filename: 'specific.monaco2', mime: 'text/specific-monaco2' });
assert.deepEqual(guessMimeTypes('specific.monaco2'), ['text/specific-monaco2', 'text/plain']);
assert.deepEqual(guessMimeTypes('foo.monaco2'), ['text/monaco2', 'text/plain']);
});
test('Specificity priority 2', () => {
registerTextMime({ id: 'monaco3', filename: 'specific.monaco3', mime: 'text/specific-monaco3' });
registerTextMime({ id: 'monaco3', extension: '.monaco3', mime: 'text/monaco3' });
assert.deepEqual(guessMimeTypes('specific.monaco3'), ['text/specific-monaco3', 'text/plain']);
assert.deepEqual(guessMimeTypes('foo.monaco3'), ['text/monaco3', 'text/plain']);
});
test('Mimes Priority - Longest Extension wins', () => {
registerTextMime({ id: 'monaco', extension: '.monaco', mime: 'text/monaco' });
registerTextMime({ id: 'monaco', extension: '.monaco.xml', mime: 'text/monaco-xml' });
registerTextMime({ id: 'monaco', extension: '.monaco.xml.build', mime: 'text/monaco-xml-build' });
let guess = guessMimeTypes('foo.monaco');
assert.deepEqual(guess, ['text/monaco', 'text/plain']);
guess = guessMimeTypes('foo.monaco.xml');
assert.deepEqual(guess, ['text/monaco-xml', 'text/plain']);
guess = guessMimeTypes('foo.monaco.xml.build');
assert.deepEqual(guess, ['text/monaco-xml-build', 'text/plain']);
});
test('Mimes Priority - User configured wins', () => {
registerTextMime({ id: 'monaco', extension: '.monaco.xnl', mime: 'text/monaco', userConfigured: true });
registerTextMime({ id: 'monaco', extension: '.monaco.xml', mime: 'text/monaco-xml' });
let guess = guessMimeTypes('foo.monaco.xnl');
assert.deepEqual(guess, ['text/monaco', 'text/plain']);
});
test('Mimes Priority - Pattern matches on path if specified', () => {
registerTextMime({ id: 'monaco', filepattern: '**/dot.monaco.xml', mime: 'text/monaco' });
registerTextMime({ id: 'other', filepattern: '*ot.other.xml', mime: 'text/other' });
let guess = guessMimeTypes('/some/path/dot.monaco.xml');
assert.deepEqual(guess, ['text/monaco', 'text/plain']);
});
test('Mimes Priority - Last registered mime wins', () => {
registerTextMime({ id: 'monaco', filepattern: '**/dot.monaco.xml', mime: 'text/monaco' });
registerTextMime({ id: 'other', filepattern: '**/dot.monaco.xml', mime: 'text/other' });
let guess = guessMimeTypes('/some/path/dot.monaco.xml');
assert.deepEqual(guess, ['text/other', 'text/plain']);
});
});

View File

@@ -0,0 +1,92 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import URI from 'vs/base/common/uri';
function assertUrl(raw: string, scheme: string, domain: string, port: string, path: string, queryString: string, fragmentId: string): void {
// check for equivalent behaviour
const uri = URI.parse(raw);
assert.equal(uri.scheme, scheme);
assert.equal(uri.authority, port ? domain + ':' + port : domain);
assert.equal(uri.path, path);
assert.equal(uri.query, queryString);
assert.equal(uri.fragment, fragmentId);
}
suite('Network', () => {
test('urls', () => {
assertUrl('http://www.test.com:8000/this/that/theother.html?query=foo#hash',
'http', 'www.test.com', '8000', '/this/that/theother.html', 'query=foo', 'hash'
);
assertUrl('http://www.test.com:8000/this/that/theother.html?query=foo',
'http', 'www.test.com', '8000', '/this/that/theother.html', 'query=foo', ''
);
assertUrl('http://www.test.com:8000/this/that/theother.html#hash',
'http', 'www.test.com', '8000', '/this/that/theother.html', '', 'hash'
);
assertUrl('http://www.test.com:8000/#hash',
'http', 'www.test.com', '8000', '/', '', 'hash'
);
assertUrl('http://www.test.com:8000#hash',
'http', 'www.test.com', '8000', '', '', 'hash'
);
assertUrl('http://www.test.com/#hash',
'http', 'www.test.com', '', '/', '', 'hash'
);
assertUrl('http://www.test.com#hash',
'http', 'www.test.com', '', '', '', 'hash'
);
assertUrl('http://www.test.com:8000/this/that/theother.html',
'http', 'www.test.com', '8000', '/this/that/theother.html', '', ''
);
assertUrl('http://www.test.com:8000/',
'http', 'www.test.com', '8000', '/', '', ''
);
assertUrl('http://www.test.com:8000',
'http', 'www.test.com', '8000', '', '', ''
);
assertUrl('http://www.test.com/',
'http', 'www.test.com', '', '/', '', ''
);
assertUrl('//www.test.com/',
'', 'www.test.com', '', '/', '', ''
);
assertUrl('//www.test.com:8000/this/that/theother.html?query=foo#hash',
'', 'www.test.com', '8000', '/this/that/theother.html', 'query=foo', 'hash'
);
assertUrl('//www.test.com/this/that/theother.html?query=foo#hash',
'', 'www.test.com', '', '/this/that/theother.html', 'query=foo', 'hash'
);
assertUrl('https://www.test.com:8000/this/that/theother.html?query=foo#hash',
'https', 'www.test.com', '8000', '/this/that/theother.html', 'query=foo', 'hash'
);
assertUrl('f12://www.test.com:8000/this/that/theother.html?query=foo#hash',
'f12', 'www.test.com', '8000', '/this/that/theother.html', 'query=foo', 'hash'
);
assertUrl('inmemory://model/0',
'inmemory', 'model', '', '/0', '', ''
);
assertUrl('file:///c/far/boo/file.cs', 'file', '', '', '/c/far/boo/file.cs', '', '');
});
});

View File

@@ -0,0 +1,253 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import objects = require('vs/base/common/objects');
let check = (one, other, msg) => {
assert(objects.equals(one, other), msg);
assert(objects.equals(other, one), '[reverse] ' + msg);
};
let checkNot = (one, other, msg) => {
assert(!objects.equals(one, other), msg);
assert(!objects.equals(other, one), '[reverse] ' + msg);
};
suite('Objects', () => {
test('equals', function () {
check(null, null, 'null');
check(undefined, undefined, 'undefined');
check(1234, 1234, 'numbers');
check('', '', 'empty strings');
check('1234', '1234', 'strings');
check([], [], 'empty arrays');
// check(['', 123], ['', 123], 'arrays');
check([[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [4, 5, 6]], 'nested arrays');
check({}, {}, 'empty objects');
check({ a: 1, b: '123' }, { a: 1, b: '123' }, 'objects');
check({ a: 1, b: '123' }, { b: '123', a: 1 }, 'objects (key order)');
check({ a: { b: 1, c: 2 }, b: 3 }, { a: { b: 1, c: 2 }, b: 3 }, 'nested objects');
checkNot(null, undefined, 'null != undefined');
checkNot(null, '', 'null != empty string');
checkNot(null, [], 'null != empty array');
checkNot(null, {}, 'null != empty object');
checkNot(null, 0, 'null != zero');
checkNot(undefined, '', 'undefined != empty string');
checkNot(undefined, [], 'undefined != empty array');
checkNot(undefined, {}, 'undefined != empty object');
checkNot(undefined, 0, 'undefined != zero');
checkNot('', [], 'empty string != empty array');
checkNot('', {}, 'empty string != empty object');
checkNot('', 0, 'empty string != zero');
checkNot([], {}, 'empty array != empty object');
checkNot([], 0, 'empty array != zero');
checkNot(0, [], 'zero != empty array');
checkNot('1234', 1234, 'string !== number');
checkNot([[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [4, 5, 6000]], 'arrays');
checkNot({ a: { b: 1, c: 2 }, b: 3 }, { b: 3, a: { b: 9, c: 2 } }, 'objects');
});
test('mixin - array', function () {
let foo: any = {};
objects.mixin(foo, { bar: [1, 2, 3] });
assert(foo.bar);
assert(Array.isArray(foo.bar));
assert.equal(foo.bar.length, 3);
assert.equal(foo.bar[0], 1);
assert.equal(foo.bar[1], 2);
assert.equal(foo.bar[2], 3);
});
test('mixin - no overwrite', function () {
let foo: any = {
bar: '123'
};
let bar: any = {
bar: '456'
};
objects.mixin(foo, bar, false);
assert.equal(foo.bar, '123');
});
test('cloneAndChange', () => {
let o1 = { something: 'hello' };
let o = {
o1: o1,
o2: o1
};
assert.deepEqual(objects.cloneAndChange(o, () => { }), o);
});
test('safeStringify', function () {
let obj1 = {
friend: null
};
let obj2 = {
friend: null
};
obj1.friend = obj2;
obj2.friend = obj1;
let arr: any = [1];
arr.push(arr);
let circular = {
a: 42,
b: null,
c: [
obj1, obj2
],
d: null
};
arr.push(circular);
circular.b = circular;
circular.d = arr;
let result = objects.safeStringify(circular);
assert.deepEqual(JSON.parse(result), {
a: 42,
b: '[Circular]',
c: [
{
friend: {
friend: '[Circular]'
}
},
'[Circular]'
],
d: [1, '[Circular]', '[Circular]']
});
});
test('derive', function () {
let someValue = 2;
function Base(): void {
//example
}
(<any>Base).favoriteColor = 'blue';
Base.prototype.test = function () { return 42; };
function Child(): void {
//example
}
Child.prototype.test2 = function () { return 43; };
Object.defineProperty(Child.prototype, 'getter', {
get: function () { return someValue; },
enumerable: true,
configurable: true
});
objects.derive(Base, Child);
let base = new Base();
let child = new Child();
assert(base instanceof Base);
assert(child instanceof Child);
assert.strictEqual(base.test, child.test);
assert.strictEqual(base.test(), 42);
assert.strictEqual(child.test2(), 43);
assert.strictEqual((<any>Child).favoriteColor, 'blue');
someValue = 4;
assert.strictEqual(child.getter, 4);
});
test('distinct', function () {
let base = {
one: 'one',
two: 2,
three: {
3: true
},
four: false
};
let diff = objects.distinct(base, base);
assert.deepEqual(diff, {});
let obj = {};
diff = objects.distinct(base, obj);
assert.deepEqual(diff, {});
obj = {
one: 'one',
two: 2
};
diff = objects.distinct(base, obj);
assert.deepEqual(diff, {});
obj = {
three: {
3: true
},
four: false
};
diff = objects.distinct(base, obj);
assert.deepEqual(diff, {});
obj = {
one: 'two',
two: 2,
three: {
3: true
},
four: true
};
diff = objects.distinct(base, obj);
assert.deepEqual(diff, {
one: 'two',
four: true
});
obj = {
one: null,
two: 2,
three: {
3: true
},
four: void 0
};
diff = objects.distinct(base, obj);
assert.deepEqual(diff, {
one: null,
four: void 0
});
obj = {
one: 'two',
two: 3,
three: { 3: false },
four: true
};
diff = objects.distinct(base, obj);
assert.deepEqual(diff, obj);
});
});

View File

@@ -0,0 +1,85 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import { IPager, PagedModel } from 'vs/base/common/paging';
import { TPromise } from 'vs/base/common/winjs.base';
suite('PagedModel', () => {
let model: PagedModel<number>;
setup(() => {
const pager: IPager<number> = {
firstPage: [0, 1, 2, 3, 4],
pageSize: 5,
total: 100,
getPage: pageIndex => TPromise.as([0, 1, 2, 3, 4].map(i => i + (pageIndex * 5)))
};
model = new PagedModel(pager, 0);
});
test('isResolved', () => {
assert(model.isResolved(0));
assert(model.isResolved(1));
assert(model.isResolved(2));
assert(model.isResolved(3));
assert(model.isResolved(4));
assert(!model.isResolved(5));
assert(!model.isResolved(6));
assert(!model.isResolved(7));
assert(!model.isResolved(8));
assert(!model.isResolved(9));
assert(!model.isResolved(10));
assert(!model.isResolved(99));
});
test('resolve single', () => {
assert(!model.isResolved(5));
return model.resolve(5).then(() => {
assert(model.isResolved(5));
});
});
test('resolve page', () => {
assert(!model.isResolved(5));
assert(!model.isResolved(6));
assert(!model.isResolved(7));
assert(!model.isResolved(8));
assert(!model.isResolved(9));
assert(!model.isResolved(10));
return model.resolve(5).then(() => {
assert(model.isResolved(5));
assert(model.isResolved(6));
assert(model.isResolved(7));
assert(model.isResolved(8));
assert(model.isResolved(9));
assert(!model.isResolved(10));
});
});
test('resolve page 2', () => {
assert(!model.isResolved(5));
assert(!model.isResolved(6));
assert(!model.isResolved(7));
assert(!model.isResolved(8));
assert(!model.isResolved(9));
assert(!model.isResolved(10));
return model.resolve(10).then(() => {
assert(!model.isResolved(5));
assert(!model.isResolved(6));
assert(!model.isResolved(7));
assert(!model.isResolved(8));
assert(!model.isResolved(9));
assert(model.isResolved(10));
});
});
});

View File

@@ -0,0 +1,257 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import paths = require('vs/base/common/paths');
import platform = require('vs/base/common/platform');
suite('Paths', () => {
test('relative', () => {
assert.equal(paths.relative('/test/api/files/test', '/test/api/files/lib/foo'), '../lib/foo');
assert.equal(paths.relative('far/boo', 'boo/far'), '../../boo/far');
assert.equal(paths.relative('far/boo', 'far/boo'), '');
assert.equal(paths.relative('far/boo', 'far/boo/bar/foo'), 'bar/foo');
if (platform.isWindows) {
assert.equal(paths.relative('C:\\test\\api\\files\\test', 'C:\\test\\api\\files\\lib\\foo'), '../lib/foo');
assert.equal(paths.relative('C:\\', 'C:\\vscode'), 'vscode');
assert.equal(paths.relative('C:\\', 'C:\\vscode\\foo.txt'), 'vscode/foo.txt');
}
// // ignore trailing slashes
assert.equal(paths.relative('/test/api/files/test/', '/test/api/files/lib/foo'), '../lib/foo');
assert.equal(paths.relative('/test/api/files/test', '/test/api/files/lib/foo/'), '../lib/foo');
assert.equal(paths.relative('/test/api/files/test/', '/test/api/files/lib/foo/'), '../lib/foo');
assert.equal(paths.relative('far/boo/', 'boo/far'), '../../boo/far');
assert.equal(paths.relative('far/boo/', 'boo/far/'), '../../boo/far');
assert.equal(paths.relative('far/boo/', 'far/boo'), '');
assert.equal(paths.relative('far/boo', 'far/boo/'), '');
assert.equal(paths.relative('far/boo/', 'far/boo/'), '');
if (platform.isWindows) {
assert.equal(paths.relative('C:\\test\\api\\files\\test\\', 'C:\\test\\api\\files\\lib\\foo'), '../lib/foo');
assert.equal(paths.relative('C:\\test\\api\\files\\test', 'C:\\test\\api\\files\\lib\\foo\\'), '../lib/foo');
assert.equal(paths.relative('C:\\test\\api\\files\\test\\', 'C:\\test\\api\\files\\lib\\foo\\'), '../lib/foo');
}
});
test('dirname', () => {
assert.equal(paths.dirname('foo/bar'), 'foo');
assert.equal(paths.dirname('foo\\bar'), 'foo');
assert.equal(paths.dirname('/foo/bar'), '/foo');
assert.equal(paths.dirname('\\foo\\bar'), '\\foo');
assert.equal(paths.dirname('/foo'), '/');
assert.equal(paths.dirname('\\foo'), '\\');
assert.equal(paths.dirname('/'), '/');
assert.equal(paths.dirname('\\'), '\\');
assert.equal(paths.dirname('foo'), '.');
if (platform.isWindows) {
assert.equal(paths.dirname('c:\\some\\file.txt'), 'c:\\some');
assert.equal(paths.dirname('c:\\some'), 'c:\\');
}
});
test('normalize', () => {
assert.equal(paths.normalize(''), '.');
assert.equal(paths.normalize('.'), '.');
assert.equal(paths.normalize('.'), '.');
assert.equal(paths.normalize('../../far'), '../../far');
assert.equal(paths.normalize('../bar'), '../bar');
assert.equal(paths.normalize('../far'), '../far');
assert.equal(paths.normalize('./'), './');
assert.equal(paths.normalize('./././'), './');
assert.equal(paths.normalize('./ff/./'), 'ff/');
assert.equal(paths.normalize('./foo'), 'foo');
assert.equal(paths.normalize('/'), '/');
assert.equal(paths.normalize('/..'), '/');
assert.equal(paths.normalize('///'), '/');
assert.equal(paths.normalize('//foo'), '/foo');
assert.equal(paths.normalize('//foo//'), '/foo/');
assert.equal(paths.normalize('/foo'), '/foo');
assert.equal(paths.normalize('/foo/bar.test'), '/foo/bar.test');
assert.equal(paths.normalize('\\\\\\'), '/');
assert.equal(paths.normalize('c:/../ff'), 'c:/ff');
assert.equal(paths.normalize('c:\\./'), 'c:/');
assert.equal(paths.normalize('foo/'), 'foo/');
assert.equal(paths.normalize('foo/../../bar'), '../bar');
assert.equal(paths.normalize('foo/./'), 'foo/');
assert.equal(paths.normalize('foo/./bar'), 'foo/bar');
assert.equal(paths.normalize('foo//'), 'foo/');
assert.equal(paths.normalize('foo//'), 'foo/');
assert.equal(paths.normalize('foo//bar'), 'foo/bar');
assert.equal(paths.normalize('foo//bar/far'), 'foo/bar/far');
assert.equal(paths.normalize('foo/bar/../../far'), 'far');
assert.equal(paths.normalize('foo/bar/../far'), 'foo/far');
assert.equal(paths.normalize('foo/far/../../bar'), 'bar');
assert.equal(paths.normalize('foo/far/../../bar'), 'bar');
assert.equal(paths.normalize('foo/xxx/..'), 'foo');
assert.equal(paths.normalize('foo/xxx/../bar'), 'foo/bar');
assert.equal(paths.normalize('foo/xxx/./..'), 'foo');
assert.equal(paths.normalize('foo/xxx/./../bar'), 'foo/bar');
assert.equal(paths.normalize('foo/xxx/./bar'), 'foo/xxx/bar');
assert.equal(paths.normalize('foo\\bar'), 'foo/bar');
assert.equal(paths.normalize(null), null);
assert.equal(paths.normalize(undefined), undefined);
// https://github.com/Microsoft/vscode/issues/7234
assert.equal(paths.join('/home/aeschli/workspaces/vscode/extensions/css', './syntaxes/css.plist'), '/home/aeschli/workspaces/vscode/extensions/css/syntaxes/css.plist');
});
test('getRootLength', () => {
assert.equal(paths.getRoot('/user/far'), '/');
assert.equal(paths.getRoot('\\\\server\\share\\some\\path'), '//server/share/');
assert.equal(paths.getRoot('//server/share/some/path'), '//server/share/');
assert.equal(paths.getRoot('//server/share'), '/');
assert.equal(paths.getRoot('//server'), '/');
assert.equal(paths.getRoot('//server//'), '/');
assert.equal(paths.getRoot('c:/user/far'), 'c:/');
assert.equal(paths.getRoot('c:user/far'), 'c:');
assert.equal(paths.getRoot('http://www'), '');
assert.equal(paths.getRoot('http://www/'), 'http://www/');
assert.equal(paths.getRoot('file:///foo'), 'file:///');
assert.equal(paths.getRoot('file://foo'), '');
});
test('basename', () => {
assert.equal(paths.basename('foo/bar'), 'bar');
assert.equal(paths.basename('foo\\bar'), 'bar');
assert.equal(paths.basename('/foo/bar'), 'bar');
assert.equal(paths.basename('\\foo\\bar'), 'bar');
assert.equal(paths.basename('./bar'), 'bar');
assert.equal(paths.basename('.\\bar'), 'bar');
assert.equal(paths.basename('/bar'), 'bar');
assert.equal(paths.basename('\\bar'), 'bar');
assert.equal(paths.basename('bar/'), 'bar');
assert.equal(paths.basename('bar\\'), 'bar');
assert.equal(paths.basename('bar'), 'bar');
assert.equal(paths.basename('////////'), '');
assert.equal(paths.basename('\\\\\\\\'), '');
});
test('join', () => {
assert.equal(paths.join('.', 'bar'), 'bar');
assert.equal(paths.join('../../foo/bar', '../../foo'), '../../foo');
assert.equal(paths.join('../../foo/bar', '../bar/foo'), '../../foo/bar/foo');
assert.equal(paths.join('../foo/bar', '../bar/foo'), '../foo/bar/foo');
assert.equal(paths.join('/', 'bar'), '/bar');
assert.equal(paths.join('//server/far/boo', '../file.txt'), '//server/far/file.txt');
assert.equal(paths.join('/foo/', '/bar'), '/foo/bar');
assert.equal(paths.join('\\\\server\\far\\boo', '../file.txt'), '//server/far/file.txt');
assert.equal(paths.join('\\\\server\\far\\boo', './file.txt'), '//server/far/boo/file.txt');
assert.equal(paths.join('\\\\server\\far\\boo', '.\\file.txt'), '//server/far/boo/file.txt');
assert.equal(paths.join('\\\\server\\far\\boo', 'file.txt'), '//server/far/boo/file.txt');
assert.equal(paths.join('file:///c/users/test', 'test'), 'file:///c/users/test/test');
assert.equal(paths.join('file://localhost/c$/GitDevelopment/express', './settings'), 'file://localhost/c$/GitDevelopment/express/settings'); // unc
assert.equal(paths.join('file://localhost/c$/GitDevelopment/express', '.settings'), 'file://localhost/c$/GitDevelopment/express/.settings'); // unc
assert.equal(paths.join('foo', '/bar'), 'foo/bar');
assert.equal(paths.join('foo', 'bar'), 'foo/bar');
assert.equal(paths.join('foo', 'bar/'), 'foo/bar/');
assert.equal(paths.join('foo/', '/bar'), 'foo/bar');
assert.equal(paths.join('foo/', '/bar/'), 'foo/bar/');
assert.equal(paths.join('foo/', 'bar'), 'foo/bar');
assert.equal(paths.join('foo/bar', '../bar/foo'), 'foo/bar/foo');
assert.equal(paths.join('foo/bar', './bar/foo'), 'foo/bar/bar/foo');
assert.equal(paths.join('http://localhost/test', '../next'), 'http://localhost/next');
assert.equal(paths.join('http://localhost/test', 'test'), 'http://localhost/test/test');
});
test('extname', () => {
assert.equal(paths.extname('far.boo'), '.boo');
assert.equal(paths.extname('far.b'), '.b');
assert.equal(paths.extname('far.'), '.');
assert.equal(paths.extname('far.boo/boo.far'), '.far');
assert.equal(paths.extname('far.boo/boo'), '');
});
test('isUNC', () => {
if (platform.isWindows) {
assert.ok(!paths.isUNC('foo'));
assert.ok(!paths.isUNC('/foo'));
assert.ok(!paths.isUNC('\\foo'));
assert.ok(!paths.isUNC('\\\\foo'));
assert.ok(paths.isUNC('\\\\a\\b'));
assert.ok(!paths.isUNC('//a/b'));
assert.ok(paths.isUNC('\\\\server\\share'));
assert.ok(paths.isUNC('\\\\server\\share\\'));
assert.ok(paths.isUNC('\\\\server\\share\\path'));
}
});
test('isValidBasename', () => {
assert.ok(!paths.isValidBasename(null));
assert.ok(!paths.isValidBasename(''));
assert.ok(paths.isValidBasename('test.txt'));
assert.ok(!paths.isValidBasename('/test.txt'));
assert.ok(!paths.isValidBasename('\\test.txt'));
if (platform.isWindows) {
assert.ok(!paths.isValidBasename('aux'));
assert.ok(!paths.isValidBasename('Aux'));
assert.ok(!paths.isValidBasename('LPT0'));
assert.ok(!paths.isValidBasename('test.txt.'));
assert.ok(!paths.isValidBasename('test.txt..'));
assert.ok(!paths.isValidBasename('test.txt '));
assert.ok(!paths.isValidBasename('test.txt\t'));
assert.ok(!paths.isValidBasename('tes:t.txt'));
assert.ok(!paths.isValidBasename('tes"t.txt'));
}
});
test('isAbsolute_win', () => {
// Absolute paths
[
'C:/',
'C:\\',
'C:/foo',
'C:\\foo',
'z:/foo/bar.txt',
'z:\\foo\\bar.txt',
'\\\\localhost\\c$\\foo',
'/',
'/foo'
].forEach(absolutePath => {
assert.ok(paths.isAbsolute_win32(absolutePath), absolutePath);
});
// Not absolute paths
[
'',
'foo',
'foo/bar',
'./foo',
'http://foo.com/bar'
].forEach(nonAbsolutePath => {
assert.ok(!paths.isAbsolute_win32(nonAbsolutePath), nonAbsolutePath);
});
});
test('isAbsolute_posix', () => {
// Absolute paths
[
'/',
'/foo',
'/foo/bar.txt'
].forEach(absolutePath => {
assert.ok(paths.isAbsolute_posix(absolutePath), absolutePath);
});
// Not absolute paths
[
'',
'foo',
'foo/bar',
'./foo',
'http://foo.com/bar',
'z:/foo/bar.txt',
].forEach(nonAbsolutePath => {
assert.ok(!paths.isAbsolute_posix(nonAbsolutePath), nonAbsolutePath);
});
});
});

View File

@@ -0,0 +1,54 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import scorer = require('vs/base/common/scorer');
suite('Scorer', () => {
test('score', function () {
const target = 'HelLo-World';
const scores = [];
scores.push(scorer.score(target, 'HelLo-World')); // direct case match
scores.push(scorer.score(target, 'hello-world')); // direct mix-case match
scores.push(scorer.score(target, 'HW')); // direct case prefix (multiple)
scores.push(scorer.score(target, 'H')); // direct case prefix
scores.push(scorer.score(target, 'hw')); // direct mix-case prefix (multiple)
scores.push(scorer.score(target, 'h')); // direct mix-case prefix
scores.push(scorer.score(target, 'W')); // direct case word prefix
scores.push(scorer.score(target, 'w')); // direct mix-case word prefix
scores.push(scorer.score(target, 'Ld')); // in-string case match (multiple)
scores.push(scorer.score(target, 'L')); // in-string case match
scores.push(scorer.score(target, 'ld')); // in-string mix-case match
scores.push(scorer.score(target, 'l')); // in-string mix-case match
scores.push(scorer.score(target, '4')); // no match
// Assert scoring order
let sortedScores = scores.sort((a, b) => b - a);
assert.deepEqual(scores, sortedScores);
});
test('cache', function () {
const cache = Object.create(null);
scorer.score('target', 'query', cache);
scorer.score('target', 't', cache);
assert.equal(Object.getOwnPropertyNames(cache).length, 2);
});
test('matches', function () {
assert.ok(scorer.matches('hello world', 'h'));
assert.ok(!scorer.matches('hello world', 'q'));
assert.ok(scorer.matches('hello world', 'hw'));
assert.ok(scorer.matches('hello world', 'horl'));
assert.ok(scorer.matches('hello world', 'd'));
assert.ok(!scorer.matches('hello world', 'wh'));
assert.ok(!scorer.matches('d', 'dd'));
});
});

View File

@@ -0,0 +1,119 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import { SmoothScrollingOperation, SmoothScrollingUpdate } from 'vs/base/common/scrollable';
class TestSmoothScrollingOperation extends SmoothScrollingOperation {
constructor(from: number, to: number, viewportSize: number, startTime: number, duration: number) {
duration = duration + 10;
startTime = startTime - 10;
super(
{ scrollLeft: 0, scrollTop: from, width: 0, height: viewportSize },
{ scrollLeft: 0, scrollTop: to, width: 0, height: viewportSize },
startTime,
duration
);
}
public testTick(now: number): SmoothScrollingUpdate {
return this._tick(now);
}
}
suite('SmoothScrollingOperation', () => {
const VIEWPORT_HEIGHT = 800;
const ANIMATION_DURATION = 125;
const LINE_HEIGHT = 20;
function extractLines(scrollable: TestSmoothScrollingOperation, now: number): [number, number] {
let scrollTop = scrollable.testTick(now).scrollTop;
let scrollBottom = scrollTop + VIEWPORT_HEIGHT;
const startLineNumber = Math.floor(scrollTop / LINE_HEIGHT);
const endLineNumber = Math.ceil(scrollBottom / LINE_HEIGHT);
return [startLineNumber, endLineNumber];
}
function simulateSmoothScroll(from: number, to: number): [number, number][] {
const scrollable = new TestSmoothScrollingOperation(from, to, VIEWPORT_HEIGHT, 0, ANIMATION_DURATION);
let result: [number, number][] = [], resultLen = 0;
result[resultLen++] = extractLines(scrollable, 0);
result[resultLen++] = extractLines(scrollable, 25);
result[resultLen++] = extractLines(scrollable, 50);
result[resultLen++] = extractLines(scrollable, 75);
result[resultLen++] = extractLines(scrollable, 100);
result[resultLen++] = extractLines(scrollable, 125);
return result;
}
function assertSmoothScroll(from: number, to: number, expected: [number, number][]): void {
const actual = simulateSmoothScroll(from, to);
assert.deepEqual(actual, expected);
}
test('scroll 25 lines (40 fit)', () => {
assertSmoothScroll(0, 500, [
[5, 46],
[14, 55],
[20, 61],
[23, 64],
[24, 65],
[25, 65],
]);
});
test('scroll 75 lines (40 fit)', () => {
assertSmoothScroll(0, 1500, [
[15, 56],
[44, 85],
[62, 103],
[71, 112],
[74, 115],
[75, 115],
]);
});
test('scroll 100 lines (40 fit)', () => {
assertSmoothScroll(0, 2000, [
[20, 61],
[59, 100],
[82, 123],
[94, 135],
[99, 140],
[100, 140],
]);
});
test('scroll 125 lines (40 fit)', () => {
assertSmoothScroll(0, 2500, [
[16, 57],
[29, 70],
[107, 148],
[119, 160],
[124, 165],
[125, 165],
]);
});
test('scroll 500 lines (40 fit)', () => {
assertSmoothScroll(0, 10000, [
[16, 57],
[29, 70],
[482, 523],
[494, 535],
[499, 540],
[500, 540],
]);
});
});

View File

@@ -0,0 +1,327 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import strings = require('vs/base/common/strings');
suite('Strings', () => {
test('equalsIgnoreCase', function () {
assert(strings.equalsIgnoreCase('', ''));
assert(!strings.equalsIgnoreCase('', '1'));
assert(!strings.equalsIgnoreCase('1', ''));
assert(strings.equalsIgnoreCase('a', 'a'));
assert(strings.equalsIgnoreCase('abc', 'Abc'));
assert(strings.equalsIgnoreCase('abc', 'ABC'));
assert(strings.equalsIgnoreCase('Höhenmeter', 'HÖhenmeter'));
assert(strings.equalsIgnoreCase('ÖL', 'Öl'));
});
test('beginsWithIgnoreCase', function () {
assert(strings.beginsWithIgnoreCase('', ''));
assert(!strings.beginsWithIgnoreCase('', '1'));
assert(strings.beginsWithIgnoreCase('1', ''));
assert(strings.beginsWithIgnoreCase('a', 'a'));
assert(strings.beginsWithIgnoreCase('abc', 'Abc'));
assert(strings.beginsWithIgnoreCase('abc', 'ABC'));
assert(strings.beginsWithIgnoreCase('Höhenmeter', 'HÖhenmeter'));
assert(strings.beginsWithIgnoreCase('ÖL', 'Öl'));
assert(strings.beginsWithIgnoreCase('alles klar', 'a'));
assert(strings.beginsWithIgnoreCase('alles klar', 'A'));
assert(strings.beginsWithIgnoreCase('alles klar', 'alles k'));
assert(strings.beginsWithIgnoreCase('alles klar', 'alles K'));
assert(strings.beginsWithIgnoreCase('alles klar', 'ALLES K'));
assert(strings.beginsWithIgnoreCase('alles klar', 'alles klar'));
assert(strings.beginsWithIgnoreCase('alles klar', 'ALLES KLAR'));
assert(!strings.beginsWithIgnoreCase('alles klar', ' ALLES K'));
assert(!strings.beginsWithIgnoreCase('alles klar', 'ALLES K '));
assert(!strings.beginsWithIgnoreCase('alles klar', 'öALLES K '));
assert(!strings.beginsWithIgnoreCase('alles klar', ' '));
assert(!strings.beginsWithIgnoreCase('alles klar', 'ö'));
});
test('compareIgnoreCase', function () {
function assertCompareIgnoreCase(a: string, b: string, recurse = true): void {
let actual = strings.compareIgnoreCase(a, b);
actual = actual > 0 ? 1 : actual < 0 ? -1 : actual;
let expected = strings.compare(a.toLowerCase(), b.toLowerCase());
expected = expected > 0 ? 1 : expected < 0 ? -1 : expected;
assert.equal(actual, expected, `${a} <> ${b}`);
if (recurse) {
assertCompareIgnoreCase(b, a, false);
}
}
assertCompareIgnoreCase('', '');
assertCompareIgnoreCase('abc', 'ABC');
assertCompareIgnoreCase('abc', 'ABc');
assertCompareIgnoreCase('abc', 'ABcd');
assertCompareIgnoreCase('abc', 'abcd');
assertCompareIgnoreCase('foo', 'föo');
assertCompareIgnoreCase('Code', 'code');
assertCompareIgnoreCase('Code', 'cöde');
assertCompareIgnoreCase('B', 'a');
assertCompareIgnoreCase('a', 'B');
assertCompareIgnoreCase('b', 'a');
assertCompareIgnoreCase('a', 'b');
assertCompareIgnoreCase('aa', 'ab');
assertCompareIgnoreCase('aa', 'aB');
assertCompareIgnoreCase('aa', 'aA');
assertCompareIgnoreCase('a', 'aa');
assertCompareIgnoreCase('ab', 'aA');
assertCompareIgnoreCase('O', '/');
});
test('format', function () {
assert.strictEqual(strings.format('Foo Bar'), 'Foo Bar');
assert.strictEqual(strings.format('Foo {0} Bar'), 'Foo {0} Bar');
assert.strictEqual(strings.format('Foo {0} Bar', 'yes'), 'Foo yes Bar');
assert.strictEqual(strings.format('Foo {0} Bar {0}', 'yes'), 'Foo yes Bar yes');
assert.strictEqual(strings.format('Foo {0} Bar {1}{2}', 'yes'), 'Foo yes Bar {1}{2}');
assert.strictEqual(strings.format('Foo {0} Bar {1}{2}', 'yes', undefined), 'Foo yes Bar undefined{2}');
assert.strictEqual(strings.format('Foo {0} Bar {1}{2}', 'yes', 5, false), 'Foo yes Bar 5false');
assert.strictEqual(strings.format('Foo {0} Bar. {1}', '(foo)', '.test'), 'Foo (foo) Bar. .test');
});
test('overlap', function () {
assert.equal(strings.overlap('foobar', 'arr, I am a priate'), 2);
assert.equal(strings.overlap('no', 'overlap'), 1);
assert.equal(strings.overlap('no', '0verlap'), 0);
assert.equal(strings.overlap('nothing', ''), 0);
assert.equal(strings.overlap('', 'nothing'), 0);
assert.equal(strings.overlap('full', 'full'), 4);
assert.equal(strings.overlap('full', 'fulloverlap'), 4);
});
test('computeLineStarts', function () {
function assertLineStart(text: string, ...offsets: number[]): void {
const actual = strings.computeLineStarts(text);
assert.equal(actual.length, offsets.length);
if (actual.length !== offsets.length) {
return;
}
while (offsets.length > 0) {
assert.equal(actual.pop(), offsets.pop());
}
}
assertLineStart('', 0);
assertLineStart('farboo', 0);
assertLineStart('far\nboo', 0, 4);
assertLineStart('far\rboo', 0, 4);
assertLineStart('far\r\nboo', 0, 5);
assertLineStart('far\n\rboo', 0, 4, 5);
assertLineStart('far\n \rboo', 0, 4, 6);
assertLineStart('far\nboo\nfar', 0, 4, 8);
});
test('pad', function () {
assert.strictEqual(strings.pad(1, 0), '1');
assert.strictEqual(strings.pad(1, 1), '1');
assert.strictEqual(strings.pad(1, 2), '01');
assert.strictEqual(strings.pad(0, 2), '00');
});
test('escape', function () {
assert.strictEqual(strings.escape(''), '');
assert.strictEqual(strings.escape('foo'), 'foo');
assert.strictEqual(strings.escape('foo bar'), 'foo bar');
assert.strictEqual(strings.escape('<foo bar>'), '&lt;foo bar&gt;');
assert.strictEqual(strings.escape('<foo>Hello</foo>'), '&lt;foo&gt;Hello&lt;/foo&gt;');
});
test('startsWith', function () {
assert(strings.startsWith('foo', 'f'));
assert(strings.startsWith('foo', 'fo'));
assert(strings.startsWith('foo', 'foo'));
assert(!strings.startsWith('foo', 'o'));
assert(!strings.startsWith('', 'f'));
assert(strings.startsWith('foo', ''));
assert(strings.startsWith('', ''));
});
test('endsWith', function () {
assert(strings.endsWith('foo', 'o'));
assert(strings.endsWith('foo', 'oo'));
assert(strings.endsWith('foo', 'foo'));
assert(strings.endsWith('foo bar foo', 'foo'));
assert(!strings.endsWith('foo', 'f'));
assert(!strings.endsWith('', 'f'));
assert(strings.endsWith('foo', ''));
assert(strings.endsWith('', ''));
assert(strings.endsWith('/', '/'));
});
test('ltrim', function () {
assert.strictEqual(strings.ltrim('foo', 'f'), 'oo');
assert.strictEqual(strings.ltrim('foo', 'o'), 'foo');
assert.strictEqual(strings.ltrim('http://www.test.de', 'http://'), 'www.test.de');
assert.strictEqual(strings.ltrim('/foo/', '/'), 'foo/');
assert.strictEqual(strings.ltrim('//foo/', '/'), 'foo/');
assert.strictEqual(strings.ltrim('/', ''), '/');
assert.strictEqual(strings.ltrim('/', '/'), '');
assert.strictEqual(strings.ltrim('///', '/'), '');
assert.strictEqual(strings.ltrim('', ''), '');
assert.strictEqual(strings.ltrim('', '/'), '');
});
test('rtrim', function () {
assert.strictEqual(strings.rtrim('foo', 'o'), 'f');
assert.strictEqual(strings.rtrim('foo', 'f'), 'foo');
assert.strictEqual(strings.rtrim('http://www.test.de', '.de'), 'http://www.test');
assert.strictEqual(strings.rtrim('/foo/', '/'), '/foo');
assert.strictEqual(strings.rtrim('/foo//', '/'), '/foo');
assert.strictEqual(strings.rtrim('/', ''), '/');
assert.strictEqual(strings.rtrim('/', '/'), '');
assert.strictEqual(strings.rtrim('///', '/'), '');
assert.strictEqual(strings.rtrim('', ''), '');
assert.strictEqual(strings.rtrim('', '/'), '');
});
test('trim', function () {
assert.strictEqual(strings.trim(' foo '), 'foo');
assert.strictEqual(strings.trim(' foo'), 'foo');
assert.strictEqual(strings.trim('bar '), 'bar');
assert.strictEqual(strings.trim(' '), '');
assert.strictEqual(strings.trim('foo bar', 'bar'), 'foo ');
});
test('trimWhitespace', function () {
assert.strictEqual(' foo '.trim(), 'foo');
assert.strictEqual(' foo '.trim(), 'foo');
assert.strictEqual(' foo'.trim(), 'foo');
assert.strictEqual('bar '.trim(), 'bar');
assert.strictEqual(' '.trim(), '');
assert.strictEqual(' '.trim(), '');
});
test('appendWithLimit', function () {
assert.strictEqual(strings.appendWithLimit('ab', 'cd', 100), 'abcd');
assert.strictEqual(strings.appendWithLimit('ab', 'cd', 2), '...cd');
assert.strictEqual(strings.appendWithLimit('ab', 'cdefgh', 4), '...efgh');
assert.strictEqual(strings.appendWithLimit('abcdef', 'ghijk', 7), '...efghijk');
});
test('repeat', () => {
assert.strictEqual(strings.repeat(' ', 4), ' ');
assert.strictEqual(strings.repeat(' ', 1), ' ');
assert.strictEqual(strings.repeat(' ', 0), '');
assert.strictEqual(strings.repeat('abc', 2), 'abcabc');
});
test('lastNonWhitespaceIndex', () => {
assert.strictEqual(strings.lastNonWhitespaceIndex('abc \t \t '), 2);
assert.strictEqual(strings.lastNonWhitespaceIndex('abc'), 2);
assert.strictEqual(strings.lastNonWhitespaceIndex('abc\t'), 2);
assert.strictEqual(strings.lastNonWhitespaceIndex('abc '), 2);
assert.strictEqual(strings.lastNonWhitespaceIndex('abc \t \t '), 2);
assert.strictEqual(strings.lastNonWhitespaceIndex('abc \t \t abc \t \t '), 11);
assert.strictEqual(strings.lastNonWhitespaceIndex('abc \t \t abc \t \t ', 8), 2);
assert.strictEqual(strings.lastNonWhitespaceIndex(' \t \t '), -1);
});
test('containsRTL', () => {
assert.equal(strings.containsRTL('a'), false);
assert.equal(strings.containsRTL(''), false);
assert.equal(strings.containsRTL(strings.UTF8_BOM_CHARACTER + 'a'), false);
assert.equal(strings.containsRTL('hello world!'), false);
assert.equal(strings.containsRTL('a📚📚b'), false);
assert.equal(strings.containsRTL('هناك حقيقة مثبتة منذ زمن طويل'), true);
assert.equal(strings.containsRTL('זוהי עובדה מבוססת שדעתו'), true);
});
test('containsEmoji', () => {
assert.equal(strings.containsEmoji('a'), false);
assert.equal(strings.containsEmoji(''), false);
assert.equal(strings.containsEmoji(strings.UTF8_BOM_CHARACTER + 'a'), false);
assert.equal(strings.containsEmoji('hello world!'), false);
assert.equal(strings.containsEmoji('هناك حقيقة مثبتة منذ زمن طويل'), false);
assert.equal(strings.containsEmoji('זוהי עובדה מבוססת שדעתו'), false);
assert.equal(strings.containsEmoji('a📚📚b'), true);
assert.equal(strings.containsEmoji('1F600 # 😀 grinning face'), true);
assert.equal(strings.containsEmoji('1F47E # 👾 alien monster'), true);
assert.equal(strings.containsEmoji('1F467 1F3FD # 👧🏽 girl: medium skin tone'), true);
assert.equal(strings.containsEmoji('26EA # ⛪ church'), true);
assert.equal(strings.containsEmoji('231B # ⌛ hourglass'), true);
assert.equal(strings.containsEmoji('2702 # ✂ scissors'), true);
assert.equal(strings.containsEmoji('1F1F7 1F1F4 # 🇷🇴 Romania'), true);
});
test('isBasicASCII', () => {
function assertIsBasicASCII(str: string, expected: boolean): void {
assert.equal(strings.isBasicASCII(str), expected, str + ` (${str.charCodeAt(0)})`);
}
assertIsBasicASCII('abcdefghijklmnopqrstuvwxyz', true);
assertIsBasicASCII('ABCDEFGHIJKLMNOPQRSTUVWXYZ', true);
assertIsBasicASCII('1234567890', true);
assertIsBasicASCII('`~!@#$%^&*()-_=+[{]}\\|;:\'",<.>/?', true);
assertIsBasicASCII(' ', true);
assertIsBasicASCII('\t', true);
assertIsBasicASCII('\n', true);
assertIsBasicASCII('\r', true);
let ALL = '\r\t\n';
for (let i = 32; i < 127; i++) {
ALL += String.fromCharCode(i);
}
assertIsBasicASCII(ALL, true);
assertIsBasicASCII(String.fromCharCode(31), false);
assertIsBasicASCII(String.fromCharCode(127), false);
assertIsBasicASCII('ü', false);
assertIsBasicASCII('a📚📚b', false);
});
test('createRegExp', () => {
// Empty
assert.throws(() => strings.createRegExp('', false));
// Escapes appropriately
assert.equal(strings.createRegExp('abc', false).source, 'abc');
assert.equal(strings.createRegExp('([^ ,.]*)', false).source, '\\(\\[\\^ ,\\.\\]\\*\\)');
assert.equal(strings.createRegExp('([^ ,.]*)', true).source, '([^ ,.]*)');
// Whole word
assert.equal(strings.createRegExp('abc', false, { wholeWord: true }).source, '\\babc\\b');
assert.equal(strings.createRegExp('abc', true, { wholeWord: true }).source, '\\babc\\b');
assert.equal(strings.createRegExp(' abc', true, { wholeWord: true }).source, ' abc\\b');
assert.equal(strings.createRegExp('abc ', true, { wholeWord: true }).source, '\\babc ');
assert.equal(strings.createRegExp(' abc ', true, { wholeWord: true }).source, ' abc ');
const regExpWithoutFlags = strings.createRegExp('abc', true);
assert(!regExpWithoutFlags.global);
assert(regExpWithoutFlags.ignoreCase);
assert(!regExpWithoutFlags.multiline);
const regExpWithFlags = strings.createRegExp('abc', true, { global: true, matchCase: true, multiline: true });
assert(regExpWithFlags.global);
assert(!regExpWithFlags.ignoreCase);
assert(regExpWithFlags.multiline);
});
test('getLeadingWhitespace', () => {
assert.equal(strings.getLeadingWhitespace(' foo'), ' ');
assert.equal(strings.getLeadingWhitespace(' foo', 2), '');
assert.equal(strings.getLeadingWhitespace(' foo', 1, 1), '');
assert.equal(strings.getLeadingWhitespace(' foo', 0, 1), ' ');
assert.equal(strings.getLeadingWhitespace(' '), ' ');
assert.equal(strings.getLeadingWhitespace(' ', 1), ' ');
assert.equal(strings.getLeadingWhitespace(' ', 0, 1), ' ');
assert.equal(strings.getLeadingWhitespace('\t\tfunction foo(){', 0, 1), '\t');
assert.equal(strings.getLeadingWhitespace('\t\tfunction foo(){', 0, 2), '\t\t');
});
});

View File

@@ -0,0 +1,219 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import types = require('vs/base/common/types');
suite('Types', () => {
test('isFunction', () => {
assert(!types.isFunction(undefined));
assert(!types.isFunction(null));
assert(!types.isFunction('foo'));
assert(!types.isFunction(5));
assert(!types.isFunction(true));
assert(!types.isFunction([]));
assert(!types.isFunction([1, 2, '3']));
assert(!types.isFunction({}));
assert(!types.isFunction({ foo: 'bar' }));
assert(!types.isFunction(/test/));
assert(!types.isFunction(new RegExp('')));
assert(!types.isFunction(new Date()));
assert(types.isFunction(assert));
assert(types.isFunction(function foo() { /**/ }));
});
test('areFunctions', () => {
assert(!types.areFunctions());
assert(!types.areFunctions(null));
assert(!types.areFunctions('foo'));
assert(!types.areFunctions(5));
assert(!types.areFunctions(true));
assert(!types.areFunctions([]));
assert(!types.areFunctions([1, 2, '3']));
assert(!types.areFunctions({}));
assert(!types.areFunctions({ foo: 'bar' }));
assert(!types.areFunctions(/test/));
assert(!types.areFunctions(new RegExp('')));
assert(!types.areFunctions(new Date()));
assert(!types.areFunctions(assert, ''));
assert(types.areFunctions(assert));
assert(types.areFunctions(assert, assert));
assert(types.areFunctions(function foo() { /**/ }));
});
test('isObject', () => {
assert(!types.isObject(undefined));
assert(!types.isObject(null));
assert(!types.isObject('foo'));
assert(!types.isObject(5));
assert(!types.isObject(true));
assert(!types.isObject([]));
assert(!types.isObject([1, 2, '3']));
assert(!types.isObject(/test/));
assert(!types.isObject(new RegExp('')));
assert(!types.isFunction(new Date()));
assert(!types.isObject(assert));
assert(!types.isObject(function foo() { }));
assert(types.isObject({}));
assert(types.isObject({ foo: 'bar' }));
});
test('isEmptyObject', () => {
assert(!types.isEmptyObject(undefined));
assert(!types.isEmptyObject(null));
assert(!types.isEmptyObject('foo'));
assert(!types.isEmptyObject(5));
assert(!types.isEmptyObject(true));
assert(!types.isEmptyObject([]));
assert(!types.isEmptyObject([1, 2, '3']));
assert(!types.isEmptyObject(/test/));
assert(!types.isEmptyObject(new RegExp('')));
assert(!types.isEmptyObject(new Date()));
assert(!types.isEmptyObject(assert));
assert(!types.isEmptyObject(function foo() { /**/ }));
assert(!types.isEmptyObject({ foo: 'bar' }));
assert(types.isEmptyObject({}));
});
test('isArray', () => {
assert(!types.isArray(undefined));
assert(!types.isArray(null));
assert(!types.isArray('foo'));
assert(!types.isArray(5));
assert(!types.isArray(true));
assert(!types.isArray({}));
assert(!types.isArray(/test/));
assert(!types.isArray(new RegExp('')));
assert(!types.isArray(new Date()));
assert(!types.isArray(assert));
assert(!types.isArray(function foo() { /**/ }));
assert(!types.isArray({ foo: 'bar' }));
assert(types.isArray([]));
assert(types.isArray([1, 2, '3']));
});
test('isString', () => {
assert(!types.isString(undefined));
assert(!types.isString(null));
assert(!types.isString(5));
assert(!types.isString([]));
assert(!types.isString([1, 2, '3']));
assert(!types.isString(true));
assert(!types.isString({}));
assert(!types.isString(/test/));
assert(!types.isString(new RegExp('')));
assert(!types.isString(new Date()));
assert(!types.isString(assert));
assert(!types.isString(function foo() { /**/ }));
assert(!types.isString({ foo: 'bar' }));
assert(types.isString('foo'));
});
test('isNumber', () => {
assert(!types.isNumber(undefined));
assert(!types.isNumber(null));
assert(!types.isNumber('foo'));
assert(!types.isNumber([]));
assert(!types.isNumber([1, 2, '3']));
assert(!types.isNumber(true));
assert(!types.isNumber({}));
assert(!types.isNumber(/test/));
assert(!types.isNumber(new RegExp('')));
assert(!types.isNumber(new Date()));
assert(!types.isNumber(assert));
assert(!types.isNumber(function foo() { /**/ }));
assert(!types.isNumber({ foo: 'bar' }));
assert(!types.isNumber(parseInt('A', 10)));
assert(types.isNumber(5));
});
test('isUndefined', () => {
assert(!types.isUndefined(null));
assert(!types.isUndefined('foo'));
assert(!types.isUndefined([]));
assert(!types.isUndefined([1, 2, '3']));
assert(!types.isUndefined(true));
assert(!types.isUndefined({}));
assert(!types.isUndefined(/test/));
assert(!types.isUndefined(new RegExp('')));
assert(!types.isUndefined(new Date()));
assert(!types.isUndefined(assert));
assert(!types.isUndefined(function foo() { /**/ }));
assert(!types.isUndefined({ foo: 'bar' }));
assert(types.isUndefined(undefined));
});
test('isUndefinedOrNull', () => {
assert(!types.isUndefinedOrNull('foo'));
assert(!types.isUndefinedOrNull([]));
assert(!types.isUndefinedOrNull([1, 2, '3']));
assert(!types.isUndefinedOrNull(true));
assert(!types.isUndefinedOrNull({}));
assert(!types.isUndefinedOrNull(/test/));
assert(!types.isUndefinedOrNull(new RegExp('')));
assert(!types.isUndefinedOrNull(new Date()));
assert(!types.isUndefinedOrNull(assert));
assert(!types.isUndefinedOrNull(function foo() { /**/ }));
assert(!types.isUndefinedOrNull({ foo: 'bar' }));
assert(types.isUndefinedOrNull(undefined));
assert(types.isUndefinedOrNull(null));
});
test('validateConstraints', () => {
types.validateConstraints([1, 'test', true], [Number, String, Boolean]);
types.validateConstraints([1, 'test', true], ['number', 'string', 'boolean']);
types.validateConstraints([console.log], [Function]);
types.validateConstraints([undefined], [types.isUndefined]);
types.validateConstraints([1], [types.isNumber]);
function foo() { }
types.validateConstraints([new foo()], [foo]);
function isFoo(f) { }
assert.throws(() => types.validateConstraints([new foo()], [isFoo]));
function isFoo2(f) { return true; };
types.validateConstraints([new foo()], [isFoo2]);
assert.throws(() => types.validateConstraints([1, true], [types.isNumber, types.isString]));
assert.throws(() => types.validateConstraints(['2'], [types.isNumber]));
assert.throws(() => types.validateConstraints([1, 'test', true], [Number, String, Number]));
});
test('create', () => {
let zeroConstructor = function () { /**/ };
assert(types.create(zeroConstructor) instanceof zeroConstructor);
assert(types.isObject(types.create(zeroConstructor)));
let manyArgConstructor = function (foo, bar) {
this.foo = foo;
this.bar = bar;
};
let foo = {};
let bar = 'foo';
assert(types.create(manyArgConstructor) instanceof manyArgConstructor);
assert(types.isObject(types.create(manyArgConstructor)));
assert(types.create(manyArgConstructor, foo, bar) instanceof manyArgConstructor);
assert(types.isObject(types.create(manyArgConstructor, foo, bar)));
let obj = types.create(manyArgConstructor, foo, bar);
assert.strictEqual(obj.foo, foo);
assert.strictEqual(obj.bar, bar);
});
});

View File

@@ -0,0 +1,443 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import URI from 'vs/base/common/uri';
import { normalize } from 'vs/base/common/paths';
import { isWindows } from 'vs/base/common/platform';
suite('URI', () => {
test('file#toString', () => {
assert.equal(URI.file('c:/win/path').toString(), 'file:///c%3A/win/path');
assert.equal(URI.file('C:/win/path').toString(), 'file:///c%3A/win/path');
assert.equal(URI.file('c:/win/path/').toString(), 'file:///c%3A/win/path/');
assert.equal(URI.file('/c:/win/path').toString(), 'file:///c%3A/win/path');
});
test('URI.file (win-special)', () => {
if (isWindows) {
assert.equal(URI.file('c:\\win\\path').toString(), 'file:///c%3A/win/path');
assert.equal(URI.file('c:\\win/path').toString(), 'file:///c%3A/win/path');
} else {
assert.equal(URI.file('c:\\win\\path').toString(), 'file:///c%3A%5Cwin%5Cpath');
assert.equal(URI.file('c:\\win/path').toString(), 'file:///c%3A%5Cwin/path');
}
});
test('file#fsPath (win-special)', () => {
if (isWindows) {
assert.equal(URI.file('c:\\win\\path').fsPath, 'c:\\win\\path');
assert.equal(URI.file('c:\\win/path').fsPath, 'c:\\win\\path');
assert.equal(URI.file('c:/win/path').fsPath, 'c:\\win\\path');
assert.equal(URI.file('c:/win/path/').fsPath, 'c:\\win\\path\\');
assert.equal(URI.file('C:/win/path').fsPath, 'c:\\win\\path');
assert.equal(URI.file('/c:/win/path').fsPath, 'c:\\win\\path');
assert.equal(URI.file('./c/win/path').fsPath, '\\.\\c\\win\\path');
} else {
assert.equal(URI.file('c:/win/path').fsPath, 'c:/win/path');
assert.equal(URI.file('c:/win/path/').fsPath, 'c:/win/path/');
assert.equal(URI.file('C:/win/path').fsPath, 'c:/win/path');
assert.equal(URI.file('/c:/win/path').fsPath, 'c:/win/path');
assert.equal(URI.file('./c/win/path').fsPath, '/./c/win/path');
}
});
test('URI#fsPath - no `fsPath` when no `path`', () => {
const value = URI.parse('file://%2Fhome%2Fticino%2Fdesktop%2Fcpluscplus%2Ftest.cpp');
assert.equal(value.authority, '/home/ticino/desktop/cpluscplus/test.cpp');
assert.equal(value.path, '');
assert.equal(value.fsPath, '');
});
test('http#toString', () => {
assert.equal(URI.from({ scheme: 'http', authority: 'www.msft.com', path: '/my/path' }).toString(), 'http://www.msft.com/my/path');
assert.equal(URI.from({ scheme: 'http', authority: 'www.msft.com', path: '/my/path' }).toString(), 'http://www.msft.com/my/path');
assert.equal(URI.from({ scheme: 'http', authority: 'www.MSFT.com', path: '/my/path' }).toString(), 'http://www.msft.com/my/path');
assert.equal(URI.from({ scheme: 'http', authority: '', path: 'my/path' }).toString(), 'http:my/path');
assert.equal(URI.from({ scheme: 'http', authority: '', path: '/my/path' }).toString(), 'http:/my/path');
assert.equal(URI.from({ scheme: '', authority: '', path: 'my/path' }).toString(), 'my/path');
assert.equal(URI.from({ scheme: '', authority: '', path: '/my/path' }).toString(), '/my/path');
//http://a-test-site.com/#test=true
assert.equal(URI.from({ scheme: 'http', authority: 'a-test-site.com', path: '/', query: 'test=true' }).toString(), 'http://a-test-site.com/?test%3Dtrue');
assert.equal(URI.from({ scheme: 'http', authority: 'a-test-site.com', path: '/', query: '', fragment: 'test=true' }).toString(), 'http://a-test-site.com/#test%3Dtrue');
});
test('http#toString, encode=FALSE', () => {
assert.equal(URI.from({ scheme: 'http', authority: 'a-test-site.com', path: '/', query: 'test=true' }).toString(true), 'http://a-test-site.com/?test=true');
assert.equal(URI.from({ scheme: 'http', authority: 'a-test-site.com', path: '/', query: '', fragment: 'test=true' }).toString(true), 'http://a-test-site.com/#test=true');
assert.equal(URI.from({}).with({ scheme: 'http', path: '/api/files/test.me', query: 't=1234' }).toString(true), 'http:/api/files/test.me?t=1234');
var value = URI.parse('file://shares/pröjects/c%23/#l12');
assert.equal(value.authority, 'shares');
assert.equal(value.path, '/pröjects/c#/');
assert.equal(value.fragment, 'l12');
assert.equal(value.toString(), 'file://shares/pr%C3%B6jects/c%23/#l12');
assert.equal(value.toString(true), 'file://shares/pröjects/c%23/#l12');
var uri2 = URI.parse(value.toString(true));
var uri3 = URI.parse(value.toString());
assert.equal(uri2.authority, uri3.authority);
assert.equal(uri2.path, uri3.path);
assert.equal(uri2.query, uri3.query);
assert.equal(uri2.fragment, uri3.fragment);
});
test('with, identity', () => {
let uri = URI.parse('foo:bar/path');
let uri2 = uri.with(null);
assert.ok(uri === uri2);
uri2 = uri.with(undefined);
assert.ok(uri === uri2);
uri2 = uri.with({});
assert.ok(uri === uri2);
uri2 = uri.with({ scheme: 'foo', path: 'bar/path' });
assert.ok(uri === uri2);
});
test('with, changes', () => {
assert.equal(URI.parse('before:some/file/path').with({ scheme: 'after' }).toString(), 'after:some/file/path');
assert.equal(URI.from({}).with({ scheme: 'http', path: '/api/files/test.me', query: 't=1234' }).toString(), 'http:/api/files/test.me?t%3D1234');
assert.equal(URI.from({}).with({ scheme: 'http', authority: '', path: '/api/files/test.me', query: 't=1234', fragment: '' }).toString(), 'http:/api/files/test.me?t%3D1234');
assert.equal(URI.from({}).with({ scheme: 'https', authority: '', path: '/api/files/test.me', query: 't=1234', fragment: '' }).toString(), 'https:/api/files/test.me?t%3D1234');
assert.equal(URI.from({}).with({ scheme: 'HTTP', authority: '', path: '/api/files/test.me', query: 't=1234', fragment: '' }).toString(), 'HTTP:/api/files/test.me?t%3D1234');
assert.equal(URI.from({}).with({ scheme: 'HTTPS', authority: '', path: '/api/files/test.me', query: 't=1234', fragment: '' }).toString(), 'HTTPS:/api/files/test.me?t%3D1234');
assert.equal(URI.from({}).with({ scheme: 'boo', authority: '', path: '/api/files/test.me', query: 't=1234', fragment: '' }).toString(), 'boo:/api/files/test.me?t%3D1234');
});
test('with, remove components #8465', () => {
assert.equal(URI.parse('scheme://authority/path').with({ authority: '' }).toString(), 'scheme:/path');
assert.equal(URI.parse('scheme:/path').with({ authority: 'authority' }).with({ authority: '' }).toString(), 'scheme:/path');
assert.equal(URI.parse('scheme:/path').with({ authority: 'authority' }).with({ authority: null }).toString(), 'scheme:/path');
assert.equal(URI.parse('scheme:/path').with({ authority: 'authority' }).with({ path: '' }).toString(), 'scheme://authority');
assert.equal(URI.parse('scheme:/path').with({ authority: 'authority' }).with({ path: null }).toString(), 'scheme://authority');
assert.equal(URI.parse('scheme:/path').with({ authority: '' }).toString(), 'scheme:/path');
assert.equal(URI.parse('scheme:/path').with({ authority: null }).toString(), 'scheme:/path');
});
test('with, validation', () => {
let uri = URI.parse('foo:bar/path');
assert.throws(() => uri.with({ scheme: 'fai:l' }));
assert.throws(() => uri.with({ scheme: 'fäil' }));
assert.throws(() => uri.with({ authority: 'fail' }));
assert.throws(() => uri.with({ path: '//fail' }));
});
test('parse', () => {
var value = URI.parse('http:/api/files/test.me?t=1234');
assert.equal(value.scheme, 'http');
assert.equal(value.authority, '');
assert.equal(value.path, '/api/files/test.me');
assert.equal(value.query, 't=1234');
assert.equal(value.fragment, '');
value = URI.parse('http://api/files/test.me?t=1234');
assert.equal(value.scheme, 'http');
assert.equal(value.authority, 'api');
assert.equal(value.path, '/files/test.me');
assert.equal(value.fsPath, normalize('/files/test.me', true));
assert.equal(value.query, 't=1234');
assert.equal(value.fragment, '');
value = URI.parse('file:///c:/test/me');
assert.equal(value.scheme, 'file');
assert.equal(value.authority, '');
assert.equal(value.path, '/c:/test/me');
assert.equal(value.fragment, '');
assert.equal(value.query, '');
assert.equal(value.fsPath, normalize('c:/test/me', true));
value = URI.parse('file://shares/files/c%23/p.cs');
assert.equal(value.scheme, 'file');
assert.equal(value.authority, 'shares');
assert.equal(value.path, '/files/c#/p.cs');
assert.equal(value.fragment, '');
assert.equal(value.query, '');
assert.equal(value.fsPath, normalize('//shares/files/c#/p.cs', true));
value = URI.parse('file:///c:/Source/Z%C3%BCrich%20or%20Zurich%20(%CB%88zj%CA%8A%C9%99r%C9%AAk,/Code/resources/app/plugins/c%23/plugin.json');
assert.equal(value.scheme, 'file');
assert.equal(value.authority, '');
assert.equal(value.path, '/c:/Source/Zürich or Zurich (ˈzjʊərɪk,/Code/resources/app/plugins/c#/plugin.json');
assert.equal(value.fragment, '');
assert.equal(value.query, '');
value = URI.parse('file:///c:/test %25/path');
assert.equal(value.scheme, 'file');
assert.equal(value.authority, '');
assert.equal(value.path, '/c:/test %/path');
assert.equal(value.fragment, '');
assert.equal(value.query, '');
value = URI.parse('inmemory:');
assert.equal(value.scheme, 'inmemory');
assert.equal(value.authority, '');
assert.equal(value.path, '');
assert.equal(value.query, '');
assert.equal(value.fragment, '');
value = URI.parse('api/files/test');
assert.equal(value.scheme, '');
assert.equal(value.authority, '');
assert.equal(value.path, 'api/files/test');
assert.equal(value.query, '');
assert.equal(value.fragment, '');
value = URI.parse('api');
assert.equal(value.scheme, '');
assert.equal(value.authority, '');
assert.equal(value.path, 'api');
assert.equal(value.query, '');
assert.equal(value.fragment, '');
value = URI.parse('/api/files/test');
assert.equal(value.scheme, '');
assert.equal(value.authority, '');
assert.equal(value.path, '/api/files/test');
assert.equal(value.query, '');
assert.equal(value.fragment, '');
value = URI.parse('?test');
assert.equal(value.scheme, '');
assert.equal(value.authority, '');
assert.equal(value.path, '');
assert.equal(value.query, 'test');
assert.equal(value.fragment, '');
value = URI.parse('file:?q');
assert.equal(value.scheme, 'file');
assert.equal(value.authority, '');
assert.equal(value.path, '');
assert.equal(value.query, 'q');
assert.equal(value.fragment, '');
value = URI.parse('#test');
assert.equal(value.scheme, '');
assert.equal(value.authority, '');
assert.equal(value.path, '');
assert.equal(value.query, '');
assert.equal(value.fragment, 'test');
value = URI.parse('file:#d');
assert.equal(value.scheme, 'file');
assert.equal(value.authority, '');
assert.equal(value.path, '');
assert.equal(value.query, '');
assert.equal(value.fragment, 'd');
value = URI.parse('f3ile:#d');
assert.equal(value.scheme, 'f3ile');
assert.equal(value.authority, '');
assert.equal(value.path, '');
assert.equal(value.query, '');
assert.equal(value.fragment, 'd');
value = URI.parse('foo+bar:path');
assert.equal(value.scheme, 'foo+bar');
assert.equal(value.authority, '');
assert.equal(value.path, 'path');
assert.equal(value.query, '');
assert.equal(value.fragment, '');
value = URI.parse('foo-bar:path');
assert.equal(value.scheme, 'foo-bar');
assert.equal(value.authority, '');
assert.equal(value.path, 'path');
assert.equal(value.query, '');
assert.equal(value.fragment, '');
value = URI.parse('foo.bar:path');
assert.equal(value.scheme, 'foo.bar');
assert.equal(value.authority, '');
assert.equal(value.path, 'path');
assert.equal(value.query, '');
assert.equal(value.fragment, '');
});
test('parse, disallow //path when no authority', () => {
assert.throws(() => URI.parse('file:////shares/files/p.cs'));
});
test('URI#file, win-speciale', () => {
if (isWindows) {
var value = URI.file('c:\\test\\drive');
assert.equal(value.path, '/c:/test/drive');
assert.equal(value.toString(), 'file:///c%3A/test/drive');
value = URI.file('\\\\shäres\\path\\c#\\plugin.json');
assert.equal(value.scheme, 'file');
assert.equal(value.authority, 'shäres');
assert.equal(value.path, '/path/c#/plugin.json');
assert.equal(value.fragment, '');
assert.equal(value.query, '');
assert.equal(value.toString(), 'file://sh%C3%A4res/path/c%23/plugin.json');
value = URI.file('\\\\localhost\\c$\\GitDevelopment\\express');
assert.equal(value.scheme, 'file');
assert.equal(value.path, '/c$/GitDevelopment/express');
assert.equal(value.fsPath, '\\\\localhost\\c$\\GitDevelopment\\express');
assert.equal(value.query, '');
assert.equal(value.fragment, '');
assert.equal(value.toString(), 'file://localhost/c%24/GitDevelopment/express');
value = URI.file('c:\\test with %\\path');
assert.equal(value.path, '/c:/test with %/path');
assert.equal(value.toString(), 'file:///c%3A/test%20with%20%25/path');
value = URI.file('c:\\test with %25\\path');
assert.equal(value.path, '/c:/test with %25/path');
assert.equal(value.toString(), 'file:///c%3A/test%20with%20%2525/path');
value = URI.file('c:\\test with %25\\c#code');
assert.equal(value.path, '/c:/test with %25/c#code');
assert.equal(value.toString(), 'file:///c%3A/test%20with%20%2525/c%23code');
value = URI.file('\\\\shares');
assert.equal(value.scheme, 'file');
assert.equal(value.authority, 'shares');
assert.equal(value.path, '/'); // slash is always there
value = URI.file('\\\\shares\\');
assert.equal(value.scheme, 'file');
assert.equal(value.authority, 'shares');
assert.equal(value.path, '/');
}
});
test('VSCode URI module\'s driveLetterPath regex is incorrect, #32961', function () {
let uri = URI.parse('file:///_:/path');
assert.equal(uri.fsPath, isWindows ? '\\_:\\path' : '/_:/path');
});
test('URI#file, no path-is-uri check', () => {
// we don't complain here
let value = URI.file('file://path/to/file');
assert.equal(value.scheme, 'file');
assert.equal(value.authority, '');
assert.equal(value.path, '/file://path/to/file');
});
test('URI#file, always slash', () => {
var value = URI.file('a.file');
assert.equal(value.scheme, 'file');
assert.equal(value.authority, '');
assert.equal(value.path, '/a.file');
assert.equal(value.toString(), 'file:///a.file');
value = URI.parse(value.toString());
assert.equal(value.scheme, 'file');
assert.equal(value.authority, '');
assert.equal(value.path, '/a.file');
assert.equal(value.toString(), 'file:///a.file');
});
test('URI.toString, only scheme and query', () => {
var value = URI.parse('stuff:?qüery');
assert.equal(value.toString(), 'stuff:?q%C3%BCery');
});
test('URI#toString, upper-case percent espaces', () => {
var value = URI.parse('file://sh%c3%a4res/path');
assert.equal(value.toString(), 'file://sh%C3%A4res/path');
});
test('URI#toString, lower-case windows drive letter', () => {
assert.equal(URI.parse('untitled:c:/Users/jrieken/Code/abc.txt').toString(), 'untitled:c%3A/Users/jrieken/Code/abc.txt');
assert.equal(URI.parse('untitled:C:/Users/jrieken/Code/abc.txt').toString(), 'untitled:c%3A/Users/jrieken/Code/abc.txt');
});
test('URI#toString, escape all the bits', () => {
var value = URI.file('/Users/jrieken/Code/_samples/18500/Mödel + Other Thîngß/model.js');
assert.equal(value.toString(), 'file:///Users/jrieken/Code/_samples/18500/M%C3%B6del%20%2B%20Other%20Th%C3%AEng%C3%9F/model.js');
});
test('URI#toString, don\'t encode port', () => {
var value = URI.parse('http://localhost:8080/far');
assert.equal(value.toString(), 'http://localhost:8080/far');
value = URI.from({ scheme: 'http', authority: 'löcalhost:8080', path: '/far', query: undefined, fragment: undefined });
assert.equal(value.toString(), 'http://l%C3%B6calhost:8080/far');
});
test('correctFileUriToFilePath2', () => {
var test = (input: string, expected: string) => {
expected = normalize(expected, true);
var value = URI.parse(input);
assert.equal(value.fsPath, expected, 'Result for ' + input);
var value2 = URI.file(value.fsPath);
assert.equal(value2.fsPath, expected, 'Result for ' + input);
assert.equal(value.toString(), value2.toString());
};
test('file:///c:/alex.txt', 'c:\\alex.txt');
test('file:///c:/Source/Z%C3%BCrich%20or%20Zurich%20(%CB%88zj%CA%8A%C9%99r%C9%AAk,/Code/resources/app/plugins', 'c:\\Source\\Zürich or Zurich (ˈzjʊərɪk,\\Code\\resources\\app\\plugins');
test('file://monacotools/folder/isi.txt', '\\\\monacotools\\folder\\isi.txt');
test('file://monacotools1/certificates/SSL/', '\\\\monacotools1\\certificates\\SSL\\');
});
test('URI - http, query & toString', function () {
let uri = URI.parse('https://go.microsoft.com/fwlink/?LinkId=518008');
assert.equal(uri.query, 'LinkId=518008');
assert.equal(uri.toString(true), 'https://go.microsoft.com/fwlink/?LinkId=518008');
assert.equal(uri.toString(), 'https://go.microsoft.com/fwlink/?LinkId%3D518008');
let uri2 = URI.parse(uri.toString());
assert.equal(uri2.query, 'LinkId=518008');
assert.equal(uri2.query, uri.query);
uri = URI.parse('https://go.microsoft.com/fwlink/?LinkId=518008&foö&ké¥=üü');
assert.equal(uri.query, 'LinkId=518008&foö&ké¥=üü');
assert.equal(uri.toString(true), 'https://go.microsoft.com/fwlink/?LinkId=518008&foö&ké¥=üü');
assert.equal(uri.toString(), 'https://go.microsoft.com/fwlink/?LinkId%3D518008%26fo%C3%B6%26k%C3%A9%C2%A5%3D%C3%BC%C3%BC');
uri2 = URI.parse(uri.toString());
assert.equal(uri2.query, 'LinkId=518008&foö&ké¥=üü');
assert.equal(uri2.query, uri.query);
// #24849
uri = URI.parse('https://twitter.com/search?src=typd&q=%23tag');
assert.equal(uri.toString(true), 'https://twitter.com/search?src=typd&q=%23tag');
});
test('URI - (de)serialize', function () {
var values = [
URI.parse('http://localhost:8080/far'),
URI.file('c:\\test with %25\\c#code'),
URI.file('\\\\shäres\\path\\c#\\plugin.json'),
URI.parse('http://api/files/test.me?t=1234'),
URI.parse('http://api/files/test.me?t=1234#fff'),
URI.parse('http://api/files/test.me#fff'),
];
// console.profile();
// let c = 100000;
// while (c-- > 0) {
for (let value of values) {
let data = value.toJSON();
let clone = URI.revive(data);
assert.equal(clone.scheme, value.scheme);
assert.equal(clone.authority, value.authority);
assert.equal(clone.path, value.path);
assert.equal(clone.query, value.query);
assert.equal(clone.fragment, value.fragment);
assert.equal(clone.fsPath, value.fsPath);
assert.equal(clone.toString(), value.toString());
}
// }
// console.profileEnd();
});
});

View File

@@ -0,0 +1,90 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import { TPromise, PPromise, TValueCallback, TProgressCallback, ProgressCallback } from 'vs/base/common/winjs.base';
import * as errors from 'vs/base/common/errors';
import * as paths from 'vs/base/common/paths';
import URI from 'vs/base/common/uri';
export class DeferredTPromise<T> extends TPromise<T> {
public canceled: boolean;
private completeCallback: TValueCallback<T>;
private errorCallback: (err: any) => void;
private progressCallback: ProgressCallback;
constructor() {
let captured: any;
super((c, e, p) => {
captured = { c, e, p };
}, () => this.oncancel());
this.canceled = false;
this.completeCallback = captured.c;
this.errorCallback = captured.e;
this.progressCallback = captured.p;
}
public complete(value: T) {
this.completeCallback(value);
}
public error(err: any) {
this.errorCallback(err);
}
public progress(p: any) {
this.progressCallback(p);
}
private oncancel(): void {
this.canceled = true;
}
}
export class DeferredPPromise<C, P> extends PPromise<C, P> {
private completeCallback: TValueCallback<C>;
private errorCallback: (err: any) => void;
private progressCallback: TProgressCallback<P>;
constructor(init: (complete: TValueCallback<C>, error: (err: any) => void, progress: TProgressCallback<P>) => void = (c, e, p) => { }, oncancel?: any) {
let captured: any;
super((c, e, p) => {
captured = { c, e, p };
}, oncancel ? oncancel : () => this.oncancel);
this.completeCallback = captured.c;
this.errorCallback = captured.e;
this.progressCallback = captured.p;
}
private oncancel(): void {
this.errorCallback(errors.canceled());
}
public complete(c: C) {
this.completeCallback(c);
}
public progress(p: P) {
this.progressCallback(p);
}
public error(e: any) {
this.errorCallback(e);
}
}
export function onError(error: Error, done: () => void): void {
assert.fail(error);
done();
}
export function toResource(path) {
return URI.file(paths.join('C:\\', new Buffer(this.test.fullTitle()).toString('base64'), path));
}

View File

@@ -0,0 +1,25 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import uuid = require('vs/base/common/uuid');
suite('UUID', () => {
test('generation', () => {
var asHex = uuid.v4().asHex();
assert.equal(asHex.length, 36);
assert.equal(asHex[14], '4');
assert(asHex[19] === '8' || asHex[19] === '9' || asHex[19] === 'a' || asHex[19] === 'b');
});
test('parse', () => {
var id = uuid.v4();
var asHext = id.asHex();
var id2 = uuid.parse(asHext);
assert(id.equals(id2));
assert(id2.equals(id));
});
});

View File

@@ -0,0 +1,208 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import assert = require('assert');
import os = require('os');
import path = require('path');
import fs = require('fs');
import extfs = require('vs/base/node/extfs');
import uuid = require('vs/base/common/uuid');
import { ConfigWatcher } from 'vs/base/node/config';
import { onError } from 'vs/base/test/common/utils';
suite('Config', () => {
function testFile(callback: (error: Error, path: string, cleanUp: (callback: () => void) => void) => void): void {
const id = uuid.generateUuid();
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
const newDir = path.join(parentDir, 'config', id);
const testFile = path.join(newDir, 'config.json');
extfs.mkdirp(newDir, 493, error => {
callback(error, testFile, (callback) => extfs.del(parentDir, os.tmpdir(), () => { }, callback));
});
}
test('defaults', function () {
const id = uuid.generateUuid();
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
const newDir = path.join(parentDir, 'config', id);
const testFile = path.join(newDir, 'config.json');
let watcher = new ConfigWatcher(testFile);
let config = watcher.getConfig();
assert.ok(config);
assert.equal(Object.keys(config), 0);
watcher.dispose();
let watcher2 = new ConfigWatcher<any[]>(testFile, { defaultConfig: ['foo'], onError: console.error });
let config2 = watcher2.getConfig();
assert.ok(Array.isArray(config2));
assert.equal(config2.length, 1);
watcher.dispose();
});
test('getConfig / getValue', function (done: () => void) {
testFile((error, testFile, cleanUp) => {
if (error) {
return onError(error, done);
}
fs.writeFileSync(testFile, '// my comment\n{ "foo": "bar" }');
let watcher = new ConfigWatcher<{ foo: string; }>(testFile);
let config = watcher.getConfig();
assert.ok(config);
assert.equal(config.foo, 'bar');
assert.equal(watcher.getValue('foo'), 'bar');
assert.equal(watcher.getValue('bar'), void 0);
assert.equal(watcher.getValue('bar', 'fallback'), 'fallback');
assert.ok(!watcher.hasParseErrors);
watcher.dispose();
cleanUp(done);
});
});
test('getConfig / getValue - broken JSON', function (done: () => void) {
testFile((error, testFile, cleanUp) => {
if (error) {
return onError(error, done);
}
fs.writeFileSync(testFile, '// my comment\n "foo": "bar ... ');
let watcher = new ConfigWatcher<{ foo: string; }>(testFile);
let config = watcher.getConfig();
assert.ok(config);
assert.ok(!config.foo);
assert.ok(watcher.hasParseErrors);
watcher.dispose();
cleanUp(done);
});
});
test('watching', function (done: () => void) {
this.timeout(10000); // watching is timing intense
testFile((error, testFile, cleanUp) => {
if (error) {
return onError(error, done);
}
fs.writeFileSync(testFile, '// my comment\n{ "foo": "bar" }');
let watcher = new ConfigWatcher<{ foo: string; }>(testFile);
watcher.getConfig(); // ensure we are in sync
fs.writeFileSync(testFile, '// my comment\n{ "foo": "changed" }');
watcher.onDidUpdateConfiguration(event => {
assert.ok(event);
assert.equal(event.config.foo, 'changed');
assert.equal(watcher.getValue('foo'), 'changed');
watcher.dispose();
cleanUp(done);
});
});
});
test('watching also works when file created later', function (done: () => void) {
this.timeout(10000); // watching is timing intense
testFile((error, testFile, cleanUp) => {
if (error) {
return onError(error, done);
}
let watcher = new ConfigWatcher<{ foo: string; }>(testFile);
watcher.getConfig(); // ensure we are in sync
fs.writeFileSync(testFile, '// my comment\n{ "foo": "changed" }');
watcher.onDidUpdateConfiguration(event => {
assert.ok(event);
assert.equal(event.config.foo, 'changed');
assert.equal(watcher.getValue('foo'), 'changed');
watcher.dispose();
cleanUp(done);
});
});
});
test('watching detects the config file getting deleted', function (done: () => void) {
this.timeout(10000); // watching is timing intense
testFile((error, testFile, cleanUp) => {
if (error) {
return onError(error, done);
}
fs.writeFileSync(testFile, '// my comment\n{ "foo": "bar" }');
let watcher = new ConfigWatcher<{ foo: string; }>(testFile);
watcher.getConfig(); // ensure we are in sync
watcher.onDidUpdateConfiguration(event => {
assert.ok(event);
watcher.dispose();
cleanUp(done);
});
fs.unlinkSync(testFile);
});
});
test('reload', function (done: () => void) {
testFile((error, testFile, cleanUp) => {
if (error) {
return onError(error, done);
}
fs.writeFileSync(testFile, '// my comment\n{ "foo": "bar" }');
let watcher = new ConfigWatcher<{ foo: string; }>(testFile, { changeBufferDelay: 100, onError: console.error });
watcher.getConfig(); // ensure we are in sync
fs.writeFileSync(testFile, '// my comment\n{ "foo": "changed" }');
// still old values because change is not bubbling yet
assert.equal(watcher.getConfig().foo, 'bar');
assert.equal(watcher.getValue('foo'), 'bar');
// force a load from disk
watcher.reload(config => {
assert.equal(config.foo, 'changed');
assert.equal(watcher.getConfig().foo, 'changed');
assert.equal(watcher.getValue('foo'), 'changed');
watcher.dispose();
cleanUp(done);
});
});
});
});

View File

@@ -0,0 +1,24 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import decoder = require('vs/base/node/decoder');
suite('Decoder', () => {
test('decoding', function () {
const lineDecoder = new decoder.LineDecoder();
let res = lineDecoder.write(new Buffer('hello'));
assert.equal(res.length, 0);
res = lineDecoder.write(new Buffer('\nworld'));
assert.equal(res[0], 'hello');
assert.equal(res.length, 1);
assert.equal(lineDecoder.end(), 'world');
});
});

View File

@@ -0,0 +1,57 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import assert = require('assert');
import encoding = require('vs/base/node/encoding');
suite('Encoding', () => {
test('detectBOM UTF-8', (done: (err?: any) => void) => {
const file = require.toUrl('./fixtures/some_utf8.css');
encoding.detectEncodingByBOM(file).then((encoding: string) => {
assert.equal(encoding, 'utf8');
done();
}, done);
});
test('detectBOM UTF-16 LE', (done: (err?: any) => void) => {
const file = require.toUrl('./fixtures/some_utf16le.css');
encoding.detectEncodingByBOM(file).then((encoding: string) => {
assert.equal(encoding, 'utf16le');
done();
}, done);
});
test('detectBOM UTF-16 BE', (done: (err?: any) => void) => {
const file = require.toUrl('./fixtures/some_utf16be.css');
encoding.detectEncodingByBOM(file).then((encoding: string) => {
assert.equal(encoding, 'utf16be');
done();
}, done);
});
test('detectBOM ANSI', function (done: (err?: any) => void) {
const file = require.toUrl('./fixtures/some_ansi.css');
encoding.detectEncodingByBOM(file).then((encoding: string) => {
assert.equal(encoding, null);
done();
}, done);
});
test('detectBOM ANSI', function (done: (err?: any) => void) {
const file = require.toUrl('./fixtures/empty.txt');
encoding.detectEncodingByBOM(file).then((encoding: string) => {
assert.equal(encoding, null);
done();
}, done);
});
});

View File

@@ -0,0 +1,40 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
/*----------------------------------------------------------
The base color for this template is #5c87b2. If you'd like
to use a different color start by replacing all instances of
#5c87b2 with your new color.
----------------------------------------------------------*/
body
{
background-color: #5c87b2;
font-size: .75em;
font-family: Segoe UI, Verdana, Helvetica, Sans-Serif;
margin: 8px;
padding: 0;
color: #696969;
}
h1, h2, h3, h4, h5, h6
{
color: #000;
font-size: 40px;
margin: 0px;
}
textarea
{
font-family: Consolas
}
#results
{
margin-top: 2em;
margin-left: 2em;
color: black;
font-size: medium;
}

View File

@@ -0,0 +1,40 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
/*----------------------------------------------------------
The base color for this template is #5c87b2. If you'd like
to use a different color start by replacing all instances of
#5c87b2 with your new color.
----------------------------------------------------------*/
body
{
background-color: #5c87b2;
font-size: .75em;
font-family: Segoe UI, Verdana, Helvetica, Sans-Serif;
margin: 8px;
padding: 0;
color: #696969;
}
h1, h2, h3, h4, h5, h6
{
color: #000;
font-size: 40px;
margin: 0px;
}
textarea
{
font-family: Consolas
}
#results
{
margin-top: 2em;
margin-left: 2em;
color: black;
font-size: medium;
}

View File

@@ -0,0 +1,268 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import assert = require('assert');
import os = require('os');
import path = require('path');
import fs = require('fs');
import uuid = require('vs/base/common/uuid');
import strings = require('vs/base/common/strings');
import extfs = require('vs/base/node/extfs');
import { onError } from 'vs/base/test/common/utils';
suite('Extfs', () => {
test('mkdirp', function (done: () => void) {
const id = uuid.generateUuid();
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
const newDir = path.join(parentDir, 'extfs', id);
extfs.mkdirp(newDir, 493, (error) => {
if (error) {
return onError(error, done);
}
assert.ok(fs.existsSync(newDir));
extfs.del(parentDir, os.tmpdir(), () => { }, done);
}); // 493 = 0755
});
test('delSync - swallows file not found error', function () {
const id = uuid.generateUuid();
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
const newDir = path.join(parentDir, 'extfs', id);
extfs.delSync(newDir);
assert.ok(!fs.existsSync(newDir));
});
test('delSync - simple', function (done: () => void) {
const id = uuid.generateUuid();
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
const newDir = path.join(parentDir, 'extfs', id);
extfs.mkdirp(newDir, 493, (error) => {
if (error) {
return onError(error, done);
}
fs.writeFileSync(path.join(newDir, 'somefile.txt'), 'Contents');
fs.writeFileSync(path.join(newDir, 'someOtherFile.txt'), 'Contents');
extfs.delSync(newDir);
assert.ok(!fs.existsSync(newDir));
done();
}); // 493 = 0755
});
test('delSync - recursive folder structure', function (done: () => void) {
const id = uuid.generateUuid();
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
const newDir = path.join(parentDir, 'extfs', id);
extfs.mkdirp(newDir, 493, (error) => {
if (error) {
return onError(error, done);
}
fs.writeFileSync(path.join(newDir, 'somefile.txt'), 'Contents');
fs.writeFileSync(path.join(newDir, 'someOtherFile.txt'), 'Contents');
fs.mkdirSync(path.join(newDir, 'somefolder'));
fs.writeFileSync(path.join(newDir, 'somefolder', 'somefile.txt'), 'Contents');
extfs.delSync(newDir);
assert.ok(!fs.existsSync(newDir));
done();
}); // 493 = 0755
});
test('copy, move and delete', function (done: () => void) {
const id = uuid.generateUuid();
const id2 = uuid.generateUuid();
const sourceDir = require.toUrl('./fixtures');
const parentDir = path.join(os.tmpdir(), 'vsctests', 'extfs');
const targetDir = path.join(parentDir, id);
const targetDir2 = path.join(parentDir, id2);
extfs.copy(sourceDir, targetDir, (error) => {
if (error) {
return onError(error, done);
}
assert.ok(fs.existsSync(targetDir));
assert.ok(fs.existsSync(path.join(targetDir, 'index.html')));
assert.ok(fs.existsSync(path.join(targetDir, 'site.css')));
assert.ok(fs.existsSync(path.join(targetDir, 'examples')));
assert.ok(fs.statSync(path.join(targetDir, 'examples')).isDirectory());
assert.ok(fs.existsSync(path.join(targetDir, 'examples', 'small.jxs')));
extfs.mv(targetDir, targetDir2, (error) => {
if (error) {
return onError(error, done);
}
assert.ok(!fs.existsSync(targetDir));
assert.ok(fs.existsSync(targetDir2));
assert.ok(fs.existsSync(path.join(targetDir2, 'index.html')));
assert.ok(fs.existsSync(path.join(targetDir2, 'site.css')));
assert.ok(fs.existsSync(path.join(targetDir2, 'examples')));
assert.ok(fs.statSync(path.join(targetDir2, 'examples')).isDirectory());
assert.ok(fs.existsSync(path.join(targetDir2, 'examples', 'small.jxs')));
extfs.mv(path.join(targetDir2, 'index.html'), path.join(targetDir2, 'index_moved.html'), (error) => {
if (error) {
return onError(error, done);
}
assert.ok(!fs.existsSync(path.join(targetDir2, 'index.html')));
assert.ok(fs.existsSync(path.join(targetDir2, 'index_moved.html')));
extfs.del(parentDir, os.tmpdir(), (error) => {
if (error) {
return onError(error, done);
}
}, (error) => {
if (error) {
return onError(error, done);
}
assert.ok(!fs.existsSync(parentDir));
done();
});
});
});
});
});
test('readdir', function (done: () => void) {
if (strings.canNormalize && typeof process.versions['electron'] !== 'undefined' /* needs electron */) {
const id = uuid.generateUuid();
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
const newDir = path.join(parentDir, 'extfs', id, 'öäü');
extfs.mkdirp(newDir, 493, (error) => {
if (error) {
return onError(error, done);
}
assert.ok(fs.existsSync(newDir));
extfs.readdir(path.join(parentDir, 'extfs', id), (error, children) => {
assert.equal(children.some(n => n === 'öäü'), true); // Mac always converts to NFD, so
extfs.del(parentDir, os.tmpdir(), () => { }, done);
});
}); // 493 = 0755
} else {
done();
}
});
test('writeFileAndFlush', function (done: () => void) {
const id = uuid.generateUuid();
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
const newDir = path.join(parentDir, 'extfs', id);
const testFile = path.join(newDir, 'flushed.txt');
extfs.mkdirp(newDir, 493, (error) => {
if (error) {
return onError(error, done);
}
assert.ok(fs.existsSync(newDir));
extfs.writeFileAndFlush(testFile, 'Hello World', null, (error) => {
if (error) {
return onError(error, done);
}
assert.equal(fs.readFileSync(testFile), 'Hello World');
const largeString = (new Array(100 * 1024)).join('Large String\n');
extfs.writeFileAndFlush(testFile, largeString, null, (error) => {
if (error) {
return onError(error, done);
}
assert.equal(fs.readFileSync(testFile), largeString);
extfs.del(parentDir, os.tmpdir(), () => { }, done);
});
});
});
});
test('realcase', (done) => {
const id = uuid.generateUuid();
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
const newDir = path.join(parentDir, 'extfs', id);
extfs.mkdirp(newDir, 493, (error) => {
// assume case insensitive file system
if (process.platform === 'win32' || process.platform === 'darwin') {
const upper = newDir.toUpperCase();
const real = extfs.realcaseSync(upper);
if (real) { // can be null in case of permission errors
assert.notEqual(real, upper);
assert.equal(real.toUpperCase(), upper);
assert.equal(real, newDir);
}
}
// linux, unix, etc. -> assume case sensitive file system
else {
const real = extfs.realcaseSync(newDir);
assert.equal(real, newDir);
}
extfs.del(parentDir, os.tmpdir(), () => { }, done);
});
});
test('realpath', (done) => {
const id = uuid.generateUuid();
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
const newDir = path.join(parentDir, 'extfs', id);
extfs.mkdirp(newDir, 493, (error) => {
extfs.realpath(newDir, (error, realpath) => {
assert.ok(realpath);
assert.ok(!error);
extfs.del(parentDir, os.tmpdir(), () => { }, done);
});
});
});
test('realpathSync', (done) => {
const id = uuid.generateUuid();
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
const newDir = path.join(parentDir, 'extfs', id);
extfs.mkdirp(newDir, 493, (error) => {
let realpath: string;
try {
realpath = extfs.realpathSync(newDir);
} catch (error) {
assert.ok(!error);
}
assert.ok(realpath);
extfs.del(parentDir, os.tmpdir(), () => { }, done);
});
});
});

View File

@@ -0,0 +1,23 @@
'use strict';
/// <reference path="employee.ts" />
var Workforce;
(function (Workforce_1) {
var Company = (function () {
function Company() {
}
return Company;
})();
(function (property, Workforce, IEmployee) {
if (property === void 0) { property = employees; }
if (IEmployee === void 0) { IEmployee = []; }
property;
calculateMonthlyExpenses();
{
var result = 0;
for (var i = 0; i < employees.length; i++) {
result += employees[i].calculatePay();
}
return result;
}
});
})(Workforce || (Workforce = {}));

View File

@@ -0,0 +1,117 @@
'use strict';
var Conway;
(function (Conway) {
var Cell = (function () {
function Cell() {
}
return Cell;
})();
(function (property, number, property, number, property, boolean) {
if (property === void 0) { property = row; }
if (property === void 0) { property = col; }
if (property === void 0) { property = live; }
});
var GameOfLife = (function () {
function GameOfLife() {
}
return GameOfLife;
})();
(function () {
property;
gridSize = 50;
property;
canvasSize = 600;
property;
lineColor = '#cdcdcd';
property;
liveColor = '#666';
property;
deadColor = '#eee';
property;
initialLifeProbability = 0.5;
property;
animationRate = 60;
property;
cellSize = 0;
property;
context: ICanvasRenderingContext2D;
property;
world = createWorld();
circleOfLife();
function createWorld() {
return travelWorld(function (cell) {
cell.live = Math.random() < initialLifeProbability;
return cell;
});
}
function circleOfLife() {
world = travelWorld(function (cell) {
cell = world[cell.row][cell.col];
draw(cell);
return resolveNextGeneration(cell);
});
setTimeout(function () { circleOfLife(); }, animationRate);
}
function resolveNextGeneration(cell) {
var count = countNeighbors(cell);
var newCell = new Cell(cell.row, cell.col, cell.live);
if (count < 2 || count > 3)
newCell.live = false;
else if (count == 3)
newCell.live = true;
return newCell;
}
function countNeighbors(cell) {
var neighbors = 0;
for (var row = -1; row <= 1; row++) {
for (var col = -1; col <= 1; col++) {
if (row == 0 && col == 0)
continue;
if (isAlive(cell.row + row, cell.col + col)) {
neighbors++;
}
}
}
return neighbors;
}
function isAlive(row, col) {
// todo - need to guard with world[row] exists?
if (row < 0 || col < 0 || row >= gridSize || col >= gridSize)
return false;
return world[row][col].live;
}
function travelWorld(callback) {
var result = [];
for (var row = 0; row < gridSize; row++) {
var rowData = [];
for (var col = 0; col < gridSize; col++) {
rowData.push(callback(new Cell(row, col, false)));
}
result.push(rowData);
}
return result;
}
function draw(cell) {
if (context == null)
context = createDrawingContext();
if (cellSize == 0)
cellSize = canvasSize / gridSize;
context.strokeStyle = lineColor;
context.strokeRect(cell.row * cellSize, cell.col * cellSize, cellSize, cellSize);
context.fillStyle = cell.live ? liveColor : deadColor;
context.fillRect(cell.row * cellSize, cell.col * cellSize, cellSize, cellSize);
}
function createDrawingContext() {
var canvas = document.getElementById('conway-canvas');
if (canvas == null) {
canvas = document.createElement('canvas');
canvas.id = "conway-canvas";
canvas.width = canvasSize;
canvas.height = canvasSize;
document.body.appendChild(canvas);
}
return canvas.getContext('2d');
}
});
})(Conway || (Conway = {}));
var game = new Conway.GameOfLife();

View File

@@ -0,0 +1,38 @@
'use strict';
var Workforce;
(function (Workforce) {
var Employee = (function () {
function Employee() {
}
return Employee;
})();
(property);
name: string, property;
basepay: number;
implements;
IEmployee;
{
name;
basepay;
}
var SalesEmployee = (function () {
function SalesEmployee() {
}
return SalesEmployee;
})();
();
Employee(name, basepay);
{
function calculatePay() {
var multiplier = (document.getElementById("mult")), as = any, value;
return _super.calculatePay.call(this) * multiplier + bonus;
}
}
var employee = new Employee('Bob', 1000);
var salesEmployee = new SalesEmployee('Jim', 800, 400);
salesEmployee.calclatePay(); // error: No member 'calclatePay' on SalesEmployee
})(Workforce || (Workforce = {}));
extern;
var $;
var s = Workforce.salesEmployee.calculatePay();
$('#results').text(s);

View File

@@ -0,0 +1,24 @@
'use strict';
var M;
(function (M) {
var C = (function () {
function C() {
}
return C;
})();
(function (x, property, number) {
if (property === void 0) { property = w; }
var local = 1;
// unresolved symbol because x is local
//self.x++;
self.w--; // ok because w is a property
property;
f = function (y) {
return y + x + local + w + self.w;
};
function sum(z) {
return z + f(z) + w + self.w;
}
});
})(M || (M = {}));
var c = new M.C(12, 5);

View File

@@ -0,0 +1,121 @@
<!DOCTYPE html>
<html>
<head id='headID'>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>Strada </title>
<link href="site.css" rel="stylesheet" type="text/css" />
<script src="jquery-1.4.1.js"></script>
<script src="../compiler/dtree.js" type="text/javascript"></script>
<script src="../compiler/typescript.js" type="text/javascript"></script>
<script type="text/javascript">
// Compile strada source into resulting javascript
function compile(prog, libText) {
var outfile = {
source: "",
Write: function (s) { this.source += s; },
WriteLine: function (s) { this.source += s + "\r"; },
}
var parseErrors = []
var compiler=new Tools.TypeScriptCompiler(outfile,true);
compiler.setErrorCallback(function(start,len, message) { parseErrors.push({start:start, len:len, message:message}); });
compiler.addUnit(libText,"lib.ts");
compiler.addUnit(prog,"input.ts");
compiler.typeCheck();
compiler.emit();
if(parseErrors.length > 0 ) {
//throw new Error(parseErrors);
}
while(outfile.source[0] == '/' && outfile.source[1] == '/' && outfile.source[2] == ' ') {
outfile.source = outfile.source.slice(outfile.source.indexOf('\r')+1);
}
var errorPrefix = "";
for(var i = 0;i<parseErrors.length;i++) {
errorPrefix += "// Error: (" + parseErrors[i].start + "," + parseErrors[i].len + ") " + parseErrors[i].message + "\r";
}
return errorPrefix + outfile.source;
}
</script>
<script type="text/javascript">
var libText = "";
$.get("../compiler/lib.ts", function(newLibText) {
libText = newLibText;
});
// execute the javascript in the compiledOutput pane
function execute() {
$('#compilation').text("Running...");
var txt = $('#compiledOutput').val();
var res;
try {
var ret = eval(txt);
res = "Ran successfully!";
} catch(e) {
res = "Exception thrown: " + e;
}
$('#compilation').text(String(res));
}
// recompile the stradaSrc and populate the compiledOutput pane
function srcUpdated() {
var newText = $('#stradaSrc').val();
var compiledSource;
try {
compiledSource = compile(newText, libText);
} catch (e) {
compiledSource = "//Parse error"
for(var i in e)
compiledSource += "\r// " + e[i];
}
$('#compiledOutput').val(compiledSource);
}
// Populate the stradaSrc pane with one of the built in samples
function exampleSelectionChanged() {
var examples = document.getElementById('examples');
var selectedExample = examples.options[examples.selectedIndex].value;
if (selectedExample != "") {
$.get('examples/' + selectedExample, function (srcText) {
$('#stradaSrc').val(srcText);
setTimeout(srcUpdated,100);
}, function (err) {
console.log(err);
});
}
}
</script>
</head>
<body>
<h1>TypeScript</h1>
<br />
<select id="examples" onchange='exampleSelectionChanged()'>
<option value="">Select...</option>
<option value="small.ts">Small</option>
<option value="employee.ts">Employees</option>
<option value="conway.ts">Conway Game of Life</option>
<option value="typescript.ts">TypeScript Compiler</option>
</select>
<div>
<textarea id='stradaSrc' rows='40' cols='80' onchange='srcUpdated()' onkeyup='srcUpdated()' spellcheck="false">
//Type your TypeScript here...
</textarea>
<textarea id='compiledOutput' rows='40' cols='80' spellcheck="false">
//Compiled code will show up here...
</textarea>
<br />
<button onclick='execute()'/>Run</button>
<div id='compilation'>Press 'run' to execute code...</div>
<div id='results'>...write your results into #results...</div>
</div>
<div id='bod' style='display:none'></div>
</body>
</html>

View File

@@ -0,0 +1,40 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
/*----------------------------------------------------------
The base color for this template is #5c87b2. If you'd like
to use a different color start by replacing all instances of
#5c87b2 with your new color.
----------------------------------------------------------*/
body
{
background-color: #5c87b2;
font-size: .75em;
font-family: Segoe UI, Verdana, Helvetica, Sans-Serif;
margin: 8px;
padding: 0;
color: #696969;
}
h1, h2, h3, h4, h5, h6
{
color: #000;
font-size: 40px;
margin: 0px;
}
textarea
{
font-family: Consolas
}
#results
{
margin-top: 2em;
margin-left: 2em;
color: black;
font-size: medium;
}

View File

@@ -0,0 +1,490 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import flow = require('vs/base/node/flow');
const loop = flow.loop;
const sequence = flow.sequence;
const parallel = flow.parallel;
suite('Flow', () => {
function assertCounterEquals(counter, expected): void {
assert.ok(counter === expected, 'Expected ' + expected + ' assertions, but got ' + counter);
}
function syncThrowsError(callback): void {
callback(new Error('foo'), null);
}
function syncSequenceGetThrowsError(value, callback) {
sequence(
function onError(error) {
callback(error, null);
},
function getFirst() {
syncThrowsError(this);
},
function handleFirst(first) {
//Foo
}
);
}
function syncGet(value, callback): void {
callback(null, value);
}
function syncGetError(value, callback): void {
callback(new Error(''), null);
}
function asyncGet(value, callback): void {
process.nextTick(function () {
callback(null, value);
});
}
function asyncGetError(value, callback): void {
process.nextTick(function () {
callback(new Error(''), null);
});
}
test('loopSync', function (done: () => void) {
const elements = ['1', '2', '3'];
loop(elements, function (element, callback, index, total) {
assert.ok(index === 0 || index === 1 || index === 2);
assert.deepEqual(3, total);
callback(null, element);
}, function (error, result) {
assert.equal(error, null);
assert.deepEqual(result, elements);
done();
});
});
test('loopByFunctionSync', function (done: () => void) {
const elements = function (callback) {
callback(null, ['1', '2', '3']);
};
loop(elements, function (element, callback) {
callback(null, element);
}, function (error, result) {
assert.equal(error, null);
assert.deepEqual(result, ['1', '2', '3']);
done();
});
});
test('loopByFunctionAsync', function (done: () => void) {
const elements = function (callback) {
process.nextTick(function () {
callback(null, ['1', '2', '3']);
});
};
loop(elements, function (element, callback) {
callback(null, element);
}, function (error, result) {
assert.equal(error, null);
assert.deepEqual(result, ['1', '2', '3']);
done();
});
});
test('loopSyncErrorByThrow', function (done: () => void) {
const elements = ['1', '2', '3'];
loop(elements, function (element, callback) {
if (element === '2') {
throw new Error('foo');
} else {
callback(null, element);
}
}, function (error, result) {
assert.ok(error);
assert.ok(!result);
done();
});
});
test('loopSyncErrorByCallback', function (done: () => void) {
const elements = ['1', '2', '3'];
loop(elements, function (element, callback) {
if (element === '2') {
callback(new Error('foo'), null);
} else {
callback(null, element);
}
}, function (error, result) {
assert.ok(error);
assert.ok(!result);
done();
});
});
test('loopAsync', function (done: () => void) {
const elements = ['1', '2', '3'];
loop(elements, function (element, callback) {
process.nextTick(function () {
callback(null, element);
});
}, function (error, result) {
assert.equal(error, null);
assert.deepEqual(result, elements);
done();
});
});
test('loopAsyncErrorByCallback', function (done: () => void) {
const elements = ['1', '2', '3'];
loop(elements, function (element, callback) {
process.nextTick(function () {
if (element === '2') {
callback(new Error('foo'), null);
} else {
callback(null, element);
}
});
}, function (error, result) {
assert.ok(error);
assert.ok(!result);
done();
});
});
test('sequenceSync', function (done: () => void) {
let assertionCount = 0;
let errorCount = 0;
sequence(
function onError(error) {
errorCount++;
},
function getFirst() {
syncGet('1', this);
},
function handleFirst(first) {
assert.deepEqual('1', first);
assertionCount++;
syncGet('2', this);
},
function handleSecond(second) {
assert.deepEqual('2', second);
assertionCount++;
syncGet(null, this);
},
function handleThird(third) {
assert.ok(!third);
assertionCount++;
assertCounterEquals(assertionCount, 3);
assertCounterEquals(errorCount, 0);
done();
}
);
});
test('sequenceAsync', function (done: () => void) {
let assertionCount = 0;
let errorCount = 0;
sequence(
function onError(error) {
errorCount++;
},
function getFirst() {
asyncGet('1', this);
},
function handleFirst(first) {
assert.deepEqual('1', first);
assertionCount++;
asyncGet('2', this);
},
function handleSecond(second) {
assert.deepEqual('2', second);
assertionCount++;
asyncGet(null, this);
},
function handleThird(third) {
assert.ok(!third);
assertionCount++;
assertCounterEquals(assertionCount, 3);
assertCounterEquals(errorCount, 0);
done();
}
);
});
test('sequenceSyncErrorByThrow', function (done: () => void) {
let assertionCount = 0;
let errorCount = 0;
sequence(
function onError(error) {
errorCount++;
assertCounterEquals(assertionCount, 1);
assertCounterEquals(errorCount, 1);
done();
},
function getFirst() {
syncGet('1', this);
},
function handleFirst(first) {
assert.deepEqual('1', first);
assertionCount++;
syncGet('2', this);
},
function handleSecond(second) {
if (true) {
throw new Error('');
}
// assertionCount++;
// syncGet(null, this);
},
function handleThird(third) {
throw new Error('We should not be here');
}
);
});
test('sequenceSyncErrorByCallback', function (done: () => void) {
let assertionCount = 0;
let errorCount = 0;
sequence(
function onError(error) {
errorCount++;
assertCounterEquals(assertionCount, 1);
assertCounterEquals(errorCount, 1);
done();
},
function getFirst() {
syncGet('1', this);
},
function handleFirst(first) {
assert.deepEqual('1', first);
assertionCount++;
syncGetError('2', this);
},
function handleSecond(second) {
throw new Error('We should not be here');
}
);
});
test('sequenceAsyncErrorByThrow', function (done: () => void) {
let assertionCount = 0;
let errorCount = 0;
sequence(
function onError(error) {
errorCount++;
assertCounterEquals(assertionCount, 1);
assertCounterEquals(errorCount, 1);
done();
},
function getFirst() {
asyncGet('1', this);
},
function handleFirst(first) {
assert.deepEqual('1', first);
assertionCount++;
asyncGet('2', this);
},
function handleSecond(second) {
if (true) {
throw new Error('');
}
// assertionCount++;
// asyncGet(null, this);
},
function handleThird(third) {
throw new Error('We should not be here');
}
);
});
test('sequenceAsyncErrorByCallback', function (done: () => void) {
let assertionCount = 0;
let errorCount = 0;
sequence(
function onError(error) {
errorCount++;
assertCounterEquals(assertionCount, 1);
assertCounterEquals(errorCount, 1);
done();
},
function getFirst() {
asyncGet('1', this);
},
function handleFirst(first) {
assert.deepEqual('1', first);
assertionCount++;
asyncGetError('2', this);
},
function handleSecond(second) {
throw new Error('We should not be here');
}
);
});
test('syncChainedSequenceError', function (done: () => void) {
sequence(
function onError(error) {
done();
},
function getFirst() {
syncSequenceGetThrowsError('1', this);
}
);
});
test('tolerateBooleanResults', function (done: () => void) {
let assertionCount = 0;
let errorCount = 0;
sequence(
function onError(error) {
errorCount++;
},
function getFirst() {
this(true);
},
function getSecond(result) {
assert.equal(result, true);
this(false);
},
function last(result) {
assert.equal(result, false);
assertionCount++;
assertCounterEquals(assertionCount, 1);
assertCounterEquals(errorCount, 0);
done();
}
);
});
test('loopTolerateBooleanResults', function (done: () => void) {
let elements = ['1', '2', '3'];
loop(elements, function (element, callback) {
process.nextTick(function () {
(<any>callback)(true);
});
}, function (error, result) {
assert.equal(error, null);
assert.deepEqual(result, [true, true, true]);
done();
});
});
test('parallel', function (done: () => void) {
let elements = [1, 2, 3, 4, 5];
let sum = 0;
parallel(elements, function (element, callback) {
sum += element;
callback(null, element * element);
}, function (errors, result) {
assert.ok(!errors);
assert.deepEqual(sum, 15);
assert.deepEqual(result, [1, 4, 9, 16, 25]);
done();
});
});
test('parallel - setTimeout', function (done: () => void) {
let elements = [1, 2, 3, 4, 5];
let timeouts = [10, 30, 5, 0, 4];
let sum = 0;
parallel(elements, function (element, callback) {
setTimeout(function () {
sum += element;
callback(null, element * element);
}, timeouts.pop());
}, function (errors, result) {
assert.ok(!errors);
assert.deepEqual(sum, 15);
assert.deepEqual(result, [1, 4, 9, 16, 25]);
done();
});
});
test('parallel - with error', function (done: () => void) {
const elements = [1, 2, 3, 4, 5];
const timeouts = [10, 30, 5, 0, 4];
let sum = 0;
parallel(elements, function (element, callback) {
setTimeout(function () {
if (element === 4) {
callback(new Error('error!'), null);
} else {
sum += element;
callback(null, element * element);
}
}, timeouts.pop());
}, function (errors, result) {
assert.ok(errors);
assert.deepEqual(errors, [null, null, null, new Error('error!'), null]);
assert.deepEqual(sum, 11);
assert.deepEqual(result, [1, 4, 9, null, 25]);
done();
});
});
});

View File

@@ -0,0 +1,887 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import * as path from 'path';
import glob = require('vs/base/common/glob');
suite('Glob', () => {
// test('perf', function () {
// let patterns = [
// '{**/*.cs,**/*.json,**/*.csproj,**/*.sln}',
// '{**/*.cs,**/*.csproj,**/*.sln}',
// '{**/*.ts,**/*.tsx,**/*.js,**/*.jsx,**/*.es6,**/*.mjs}',
// '**/*.go',
// '{**/*.ps,**/*.ps1}',
// '{**/*.c,**/*.cpp,**/*.h}',
// '{**/*.fsx,**/*.fsi,**/*.fs,**/*.ml,**/*.mli}',
// '{**/*.js,**/*.jsx,**/*.es6,**/*.mjs}',
// '{**/*.ts,**/*.tsx}',
// '{**/*.php}',
// '{**/*.php}',
// '{**/*.php}',
// '{**/*.php}',
// '{**/*.py}',
// '{**/*.py}',
// '{**/*.py}',
// '{**/*.rs,**/*.rslib}',
// '{**/*.cpp,**/*.cc,**/*.h}',
// '{**/*.md}',
// '{**/*.md}',
// '{**/*.md}'
// ];
// let paths = [
// '/DNXConsoleApp/Program.cs',
// 'C:\\DNXConsoleApp\\foo\\Program.cs',
// 'test/qunit',
// 'test/test.txt',
// 'test/node_modules',
// '.hidden.txt',
// '/node_module/test/foo.js'
// ];
// let results = 0;
// let c = 1000;
// console.profile('glob.match');
// while (c-- > 0) {
// for (let path of paths) {
// for (let pattern of patterns) {
// let r = glob.match(pattern, path);
// if (r) {
// results += 42;
// }
// }
// }
// }
// console.profileEnd();
// });
test('simple', function () {
let p = 'node_modules';
assert(glob.match(p, 'node_modules'));
assert(!glob.match(p, 'node_module'));
assert(!glob.match(p, '/node_modules'));
assert(!glob.match(p, 'test/node_modules'));
p = 'test.txt';
assert(glob.match(p, 'test.txt'));
assert(!glob.match(p, 'test?txt'));
assert(!glob.match(p, '/text.txt'));
assert(!glob.match(p, 'test/test.txt'));
p = 'test(.txt';
assert(glob.match(p, 'test(.txt'));
assert(!glob.match(p, 'test?txt'));
p = 'qunit';
assert(glob.match(p, 'qunit'));
assert(!glob.match(p, 'qunit.css'));
assert(!glob.match(p, 'test/qunit'));
// Absolute
p = '/DNXConsoleApp/**/*.cs';
assert(glob.match(p, '/DNXConsoleApp/Program.cs'));
assert(glob.match(p, '/DNXConsoleApp/foo/Program.cs'));
p = 'C:/DNXConsoleApp/**/*.cs';
assert(glob.match(p, 'C:\\DNXConsoleApp\\Program.cs'));
assert(glob.match(p, 'C:\\DNXConsoleApp\\foo\\Program.cs'));
});
test('dot hidden', function () {
let p = '.*';
assert(glob.match(p, '.git'));
assert(glob.match(p, '.hidden.txt'));
assert(!glob.match(p, 'git'));
assert(!glob.match(p, 'hidden.txt'));
assert(!glob.match(p, 'path/.git'));
assert(!glob.match(p, 'path/.hidden.txt'));
p = '**/.*';
assert(glob.match(p, '.git'));
assert(glob.match(p, '.hidden.txt'));
assert(!glob.match(p, 'git'));
assert(!glob.match(p, 'hidden.txt'));
assert(glob.match(p, 'path/.git'));
assert(glob.match(p, 'path/.hidden.txt'));
assert(!glob.match(p, 'path/git'));
assert(!glob.match(p, 'pat.h/hidden.txt'));
p = '._*';
assert(glob.match(p, '._git'));
assert(glob.match(p, '._hidden.txt'));
assert(!glob.match(p, 'git'));
assert(!glob.match(p, 'hidden.txt'));
assert(!glob.match(p, 'path/._git'));
assert(!glob.match(p, 'path/._hidden.txt'));
p = '**/._*';
assert(glob.match(p, '._git'));
assert(glob.match(p, '._hidden.txt'));
assert(!glob.match(p, 'git'));
assert(!glob.match(p, 'hidden._txt'));
assert(glob.match(p, 'path/._git'));
assert(glob.match(p, 'path/._hidden.txt'));
assert(!glob.match(p, 'path/git'));
assert(!glob.match(p, 'pat.h/hidden._txt'));
});
test('file pattern', function () {
let p = '*.js';
assert(glob.match(p, 'foo.js'));
assert(!glob.match(p, 'folder/foo.js'));
assert(!glob.match(p, '/node_modules/foo.js'));
assert(!glob.match(p, 'foo.jss'));
assert(!glob.match(p, 'some.js/test'));
p = 'html.*';
assert(glob.match(p, 'html.js'));
assert(glob.match(p, 'html.txt'));
assert(!glob.match(p, 'htm.txt'));
p = '*.*';
assert(glob.match(p, 'html.js'));
assert(glob.match(p, 'html.txt'));
assert(glob.match(p, 'htm.txt'));
assert(!glob.match(p, 'folder/foo.js'));
assert(!glob.match(p, '/node_modules/foo.js'));
p = 'node_modules/test/*.js';
assert(glob.match(p, 'node_modules/test/foo.js'));
assert(!glob.match(p, 'folder/foo.js'));
assert(!glob.match(p, '/node_module/test/foo.js'));
assert(!glob.match(p, 'foo.jss'));
assert(!glob.match(p, 'some.js/test'));
});
test('star', function () {
let p = 'node*modules';
assert(glob.match(p, 'node_modules'));
assert(glob.match(p, 'node_super_modules'));
assert(!glob.match(p, 'node_module'));
assert(!glob.match(p, '/node_modules'));
assert(!glob.match(p, 'test/node_modules'));
p = '*';
assert(glob.match(p, 'html.js'));
assert(glob.match(p, 'html.txt'));
assert(glob.match(p, 'htm.txt'));
assert(!glob.match(p, 'folder/foo.js'));
assert(!glob.match(p, '/node_modules/foo.js'));
});
test('questionmark', function () {
let p = 'node?modules';
assert(glob.match(p, 'node_modules'));
assert(!glob.match(p, 'node_super_modules'));
assert(!glob.match(p, 'node_module'));
assert(!glob.match(p, '/node_modules'));
assert(!glob.match(p, 'test/node_modules'));
p = '?';
assert(glob.match(p, 'h'));
assert(!glob.match(p, 'html.txt'));
assert(!glob.match(p, 'htm.txt'));
assert(!glob.match(p, 'folder/foo.js'));
assert(!glob.match(p, '/node_modules/foo.js'));
});
test('globstar', function () {
let p = '**/*.js';
assert(glob.match(p, 'foo.js'));
assert(glob.match(p, 'folder/foo.js'));
assert(glob.match(p, '/node_modules/foo.js'));
assert(!glob.match(p, 'foo.jss'));
assert(!glob.match(p, 'some.js/test'));
assert(!glob.match(p, '/some.js/test'));
assert(!glob.match(p, '\\some.js\\test'));
p = '**/project.json';
assert(glob.match(p, 'project.json'));
assert(glob.match(p, '/project.json'));
assert(glob.match(p, 'some/folder/project.json'));
assert(!glob.match(p, 'some/folder/file_project.json'));
assert(!glob.match(p, 'some/folder/fileproject.json'));
// assert(!glob.match(p, '/rrproject.json')); TODO@ben this still fails if T1-3 are disabled
assert(!glob.match(p, 'some/rrproject.json'));
// assert(!glob.match(p, 'rrproject.json'));
// assert(!glob.match(p, '\\rrproject.json'));
assert(!glob.match(p, 'some\\rrproject.json'));
p = 'test/**';
assert(glob.match(p, 'test'));
assert(glob.match(p, 'test/foo.js'));
assert(glob.match(p, 'test/other/foo.js'));
assert(!glob.match(p, 'est/other/foo.js'));
p = '**';
assert(glob.match(p, 'foo.js'));
assert(glob.match(p, 'folder/foo.js'));
assert(glob.match(p, '/node_modules/foo.js'));
assert(glob.match(p, 'foo.jss'));
assert(glob.match(p, 'some.js/test'));
p = 'test/**/*.js';
assert(glob.match(p, 'test/foo.js'));
assert(glob.match(p, 'test/other/foo.js'));
assert(glob.match(p, 'test/other/more/foo.js'));
assert(!glob.match(p, 'test/foo.ts'));
assert(!glob.match(p, 'test/other/foo.ts'));
assert(!glob.match(p, 'test/other/more/foo.ts'));
p = '**/**/*.js';
assert(glob.match(p, 'foo.js'));
assert(glob.match(p, 'folder/foo.js'));
assert(glob.match(p, '/node_modules/foo.js'));
assert(!glob.match(p, 'foo.jss'));
assert(!glob.match(p, 'some.js/test'));
p = '**/node_modules/**/*.js';
assert(!glob.match(p, 'foo.js'));
assert(!glob.match(p, 'folder/foo.js'));
assert(glob.match(p, 'node_modules/foo.js'));
assert(glob.match(p, 'node_modules/some/folder/foo.js'));
assert(!glob.match(p, 'node_modules/some/folder/foo.ts'));
assert(!glob.match(p, 'foo.jss'));
assert(!glob.match(p, 'some.js/test'));
p = '{**/node_modules/**,**/.git/**,**/bower_components/**}';
assert(glob.match(p, 'node_modules'));
assert(glob.match(p, '/node_modules'));
assert(glob.match(p, '/node_modules/more'));
assert(glob.match(p, 'some/test/node_modules'));
assert(glob.match(p, 'some\\test\\node_modules'));
assert(glob.match(p, 'C:\\\\some\\test\\node_modules'));
assert(glob.match(p, 'C:\\\\some\\test\\node_modules\\more'));
assert(glob.match(p, 'bower_components'));
assert(glob.match(p, 'bower_components/more'));
assert(glob.match(p, '/bower_components'));
assert(glob.match(p, 'some/test/bower_components'));
assert(glob.match(p, 'some\\test\\bower_components'));
assert(glob.match(p, 'C:\\\\some\\test\\bower_components'));
assert(glob.match(p, 'C:\\\\some\\test\\bower_components\\more'));
assert(glob.match(p, '.git'));
assert(glob.match(p, '/.git'));
assert(glob.match(p, 'some/test/.git'));
assert(glob.match(p, 'some\\test\\.git'));
assert(glob.match(p, 'C:\\\\some\\test\\.git'));
assert(!glob.match(p, 'tempting'));
assert(!glob.match(p, '/tempting'));
assert(!glob.match(p, 'some/test/tempting'));
assert(!glob.match(p, 'some\\test\\tempting'));
assert(!glob.match(p, 'C:\\\\some\\test\\tempting'));
p = '{**/package.json,**/project.json}';
assert(glob.match(p, 'package.json'));
assert(glob.match(p, '/package.json'));
assert(!glob.match(p, 'xpackage.json'));
assert(!glob.match(p, '/xpackage.json'));
});
test('brace expansion', function () {
let p = '*.{html,js}';
assert(glob.match(p, 'foo.js'));
assert(glob.match(p, 'foo.html'));
assert(!glob.match(p, 'folder/foo.js'));
assert(!glob.match(p, '/node_modules/foo.js'));
assert(!glob.match(p, 'foo.jss'));
assert(!glob.match(p, 'some.js/test'));
p = '*.{html}';
assert(glob.match(p, 'foo.html'));
assert(!glob.match(p, 'foo.js'));
assert(!glob.match(p, 'folder/foo.js'));
assert(!glob.match(p, '/node_modules/foo.js'));
assert(!glob.match(p, 'foo.jss'));
assert(!glob.match(p, 'some.js/test'));
p = '{node_modules,testing}';
assert(glob.match(p, 'node_modules'));
assert(glob.match(p, 'testing'));
assert(!glob.match(p, 'node_module'));
assert(!glob.match(p, 'dtesting'));
p = '**/{foo,bar}';
assert(glob.match(p, 'foo'));
assert(glob.match(p, 'bar'));
assert(glob.match(p, 'test/foo'));
assert(glob.match(p, 'test/bar'));
assert(glob.match(p, 'other/more/foo'));
assert(glob.match(p, 'other/more/bar'));
p = '{foo,bar}/**';
assert(glob.match(p, 'foo'));
assert(glob.match(p, 'bar'));
assert(glob.match(p, 'foo/test'));
assert(glob.match(p, 'bar/test'));
assert(glob.match(p, 'foo/other/more'));
assert(glob.match(p, 'bar/other/more'));
p = '{**/*.d.ts,**/*.js}';
assert(glob.match(p, 'foo.js'));
assert(glob.match(p, 'testing/foo.js'));
assert(glob.match(p, 'testing\\foo.js'));
assert(glob.match(p, '/testing/foo.js'));
assert(glob.match(p, '\\testing\\foo.js'));
assert(glob.match(p, 'C:\\testing\\foo.js'));
assert(glob.match(p, 'foo.d.ts'));
assert(glob.match(p, 'testing/foo.d.ts'));
assert(glob.match(p, 'testing\\foo.d.ts'));
assert(glob.match(p, '/testing/foo.d.ts'));
assert(glob.match(p, '\\testing\\foo.d.ts'));
assert(glob.match(p, 'C:\\testing\\foo.d.ts'));
assert(!glob.match(p, 'foo.d'));
assert(!glob.match(p, 'testing/foo.d'));
assert(!glob.match(p, 'testing\\foo.d'));
assert(!glob.match(p, '/testing/foo.d'));
assert(!glob.match(p, '\\testing\\foo.d'));
assert(!glob.match(p, 'C:\\testing\\foo.d'));
p = '{**/*.d.ts,**/*.js,path/simple.jgs}';
assert(glob.match(p, 'foo.js'));
assert(glob.match(p, 'testing/foo.js'));
assert(glob.match(p, 'testing\\foo.js'));
assert(glob.match(p, '/testing/foo.js'));
assert(glob.match(p, 'path/simple.jgs'));
assert(!glob.match(p, '/path/simple.jgs'));
assert(glob.match(p, '\\testing\\foo.js'));
assert(glob.match(p, 'C:\\testing\\foo.js'));
p = '{**/*.d.ts,**/*.js,foo.[0-9]}';
assert(glob.match(p, 'foo.5'));
assert(glob.match(p, 'foo.8'));
assert(!glob.match(p, 'bar.5'));
assert(!glob.match(p, 'foo.f'));
assert(glob.match(p, 'foo.js'));
p = 'prefix/{**/*.d.ts,**/*.js,foo.[0-9]}';
assert(glob.match(p, 'prefix/foo.5'));
assert(glob.match(p, 'prefix/foo.8'));
assert(!glob.match(p, 'prefix/bar.5'));
assert(!glob.match(p, 'prefix/foo.f'));
assert(glob.match(p, 'prefix/foo.js'));
});
test('expression support (single)', function () {
let siblings = ['test.html', 'test.txt', 'test.ts', 'test.js'];
// { "**/*.js": { "when": "$(basename).ts" } }
let expression: glob.IExpression = {
'**/*.js': {
when: '$(basename).ts'
}
};
assert.strictEqual('**/*.js', glob.match(expression, 'test.js', () => siblings));
assert.strictEqual(glob.match(expression, 'test.js', () => []), null);
assert.strictEqual(glob.match(expression, 'test.js', () => ['te.ts']), null);
assert.strictEqual(glob.match(expression, 'test.js'), null);
expression = {
'**/*.js': {
when: ''
}
};
assert.strictEqual(glob.match(expression, 'test.js', () => siblings), null);
expression = <any>{
'**/*.js': {
}
};
assert.strictEqual('**/*.js', glob.match(expression, 'test.js', () => siblings));
expression = {};
assert.strictEqual(glob.match(expression, 'test.js', () => siblings), null);
});
test('expression support (multiple)', function () {
let siblings = ['test.html', 'test.txt', 'test.ts', 'test.js'];
// { "**/*.js": { "when": "$(basename).ts" } }
let expression: glob.IExpression = {
'**/*.js': { when: '$(basename).ts' },
'**/*.as': true,
'**/*.foo': false,
'**/*.bananas': { bananas: true }
};
assert.strictEqual('**/*.js', glob.match(expression, 'test.js', () => siblings));
assert.strictEqual('**/*.as', glob.match(expression, 'test.as', () => siblings));
assert.strictEqual('**/*.bananas', glob.match(expression, 'test.bananas', () => siblings));
assert.strictEqual('**/*.bananas', glob.match(expression, 'test.bananas'));
assert.strictEqual(glob.match(expression, 'test.foo', () => siblings), null);
});
test('brackets', function () {
let p = 'foo.[0-9]';
assert(glob.match(p, 'foo.5'));
assert(glob.match(p, 'foo.8'));
assert(!glob.match(p, 'bar.5'));
assert(!glob.match(p, 'foo.f'));
p = 'foo.[^0-9]';
assert(!glob.match(p, 'foo.5'));
assert(!glob.match(p, 'foo.8'));
assert(!glob.match(p, 'bar.5'));
assert(glob.match(p, 'foo.f'));
});
test('full path', function () {
let p = 'testing/this/foo.txt';
assert(glob.match(p, nativeSep('testing/this/foo.txt')));
});
test('prefix agnostic', function () {
let p = '**/*.js';
assert(glob.match(p, 'foo.js'));
assert(glob.match(p, '/foo.js'));
assert(glob.match(p, '\\foo.js'));
assert(glob.match(p, 'testing/foo.js'));
assert(glob.match(p, 'testing\\foo.js'));
assert(glob.match(p, '/testing/foo.js'));
assert(glob.match(p, '\\testing\\foo.js'));
assert(glob.match(p, 'C:\\testing\\foo.js'));
assert(!glob.match(p, 'foo.ts'));
assert(!glob.match(p, 'testing/foo.ts'));
assert(!glob.match(p, 'testing\\foo.ts'));
assert(!glob.match(p, '/testing/foo.ts'));
assert(!glob.match(p, '\\testing\\foo.ts'));
assert(!glob.match(p, 'C:\\testing\\foo.ts'));
assert(!glob.match(p, 'foo.js.txt'));
assert(!glob.match(p, 'testing/foo.js.txt'));
assert(!glob.match(p, 'testing\\foo.js.txt'));
assert(!glob.match(p, '/testing/foo.js.txt'));
assert(!glob.match(p, '\\testing\\foo.js.txt'));
assert(!glob.match(p, 'C:\\testing\\foo.js.txt'));
assert(!glob.match(p, 'testing.js/foo'));
assert(!glob.match(p, 'testing.js\\foo'));
assert(!glob.match(p, '/testing.js/foo'));
assert(!glob.match(p, '\\testing.js\\foo'));
assert(!glob.match(p, 'C:\\testing.js\\foo'));
p = '**/foo.js';
assert(glob.match(p, 'foo.js'));
assert(glob.match(p, '/foo.js'));
assert(glob.match(p, '\\foo.js'));
assert(glob.match(p, 'testing/foo.js'));
assert(glob.match(p, 'testing\\foo.js'));
assert(glob.match(p, '/testing/foo.js'));
assert(glob.match(p, '\\testing\\foo.js'));
assert(glob.match(p, 'C:\\testing\\foo.js'));
});
test('cached properly', function () {
let p = '**/*.js';
assert(glob.match(p, 'foo.js'));
assert(glob.match(p, 'testing/foo.js'));
assert(glob.match(p, 'testing\\foo.js'));
assert(glob.match(p, '/testing/foo.js'));
assert(glob.match(p, '\\testing\\foo.js'));
assert(glob.match(p, 'C:\\testing\\foo.js'));
assert(!glob.match(p, 'foo.ts'));
assert(!glob.match(p, 'testing/foo.ts'));
assert(!glob.match(p, 'testing\\foo.ts'));
assert(!glob.match(p, '/testing/foo.ts'));
assert(!glob.match(p, '\\testing\\foo.ts'));
assert(!glob.match(p, 'C:\\testing\\foo.ts'));
assert(!glob.match(p, 'foo.js.txt'));
assert(!glob.match(p, 'testing/foo.js.txt'));
assert(!glob.match(p, 'testing\\foo.js.txt'));
assert(!glob.match(p, '/testing/foo.js.txt'));
assert(!glob.match(p, '\\testing\\foo.js.txt'));
assert(!glob.match(p, 'C:\\testing\\foo.js.txt'));
assert(!glob.match(p, 'testing.js/foo'));
assert(!glob.match(p, 'testing.js\\foo'));
assert(!glob.match(p, '/testing.js/foo'));
assert(!glob.match(p, '\\testing.js\\foo'));
assert(!glob.match(p, 'C:\\testing.js\\foo'));
// Run again and make sure the regex are properly reused
assert(glob.match(p, 'foo.js'));
assert(glob.match(p, 'testing/foo.js'));
assert(glob.match(p, 'testing\\foo.js'));
assert(glob.match(p, '/testing/foo.js'));
assert(glob.match(p, '\\testing\\foo.js'));
assert(glob.match(p, 'C:\\testing\\foo.js'));
assert(!glob.match(p, 'foo.ts'));
assert(!glob.match(p, 'testing/foo.ts'));
assert(!glob.match(p, 'testing\\foo.ts'));
assert(!glob.match(p, '/testing/foo.ts'));
assert(!glob.match(p, '\\testing\\foo.ts'));
assert(!glob.match(p, 'C:\\testing\\foo.ts'));
assert(!glob.match(p, 'foo.js.txt'));
assert(!glob.match(p, 'testing/foo.js.txt'));
assert(!glob.match(p, 'testing\\foo.js.txt'));
assert(!glob.match(p, '/testing/foo.js.txt'));
assert(!glob.match(p, '\\testing\\foo.js.txt'));
assert(!glob.match(p, 'C:\\testing\\foo.js.txt'));
assert(!glob.match(p, 'testing.js/foo'));
assert(!glob.match(p, 'testing.js\\foo'));
assert(!glob.match(p, '/testing.js/foo'));
assert(!glob.match(p, '\\testing.js\\foo'));
assert(!glob.match(p, 'C:\\testing.js\\foo'));
});
test('invalid glob', function () {
let p = '**/*(.js';
assert(!glob.match(p, 'foo.js'));
});
test('split glob aware', function () {
assert.deepEqual(glob.splitGlobAware('foo,bar', ','), ['foo', 'bar']);
assert.deepEqual(glob.splitGlobAware('foo', ','), ['foo']);
assert.deepEqual(glob.splitGlobAware('{foo,bar}', ','), ['{foo,bar}']);
assert.deepEqual(glob.splitGlobAware('foo,bar,{foo,bar}', ','), ['foo', 'bar', '{foo,bar}']);
assert.deepEqual(glob.splitGlobAware('{foo,bar},foo,bar,{foo,bar}', ','), ['{foo,bar}', 'foo', 'bar', '{foo,bar}']);
assert.deepEqual(glob.splitGlobAware('[foo,bar]', ','), ['[foo,bar]']);
assert.deepEqual(glob.splitGlobAware('foo,bar,[foo,bar]', ','), ['foo', 'bar', '[foo,bar]']);
assert.deepEqual(glob.splitGlobAware('[foo,bar],foo,bar,[foo,bar]', ','), ['[foo,bar]', 'foo', 'bar', '[foo,bar]']);
});
test('expression with disabled glob', function () {
let expr = { '**/*.js': false };
assert.strictEqual(glob.match(expr, 'foo.js'), null);
});
test('expression with two non-trivia globs', function () {
let expr = {
'**/*.j?': true,
'**/*.t?': true
};
assert.strictEqual(glob.match(expr, 'foo.js'), '**/*.j?');
assert.strictEqual(glob.match(expr, 'foo.as'), null);
});
test('expression with empty glob', function () {
let expr = { '': true };
assert.strictEqual(glob.match(expr, 'foo.js'), null);
});
test('expression with other falsy value', function () {
let expr = { '**/*.js': 0 };
assert.strictEqual(glob.match(expr, 'foo.js'), '**/*.js');
});
test('expression with two basename globs', function () {
let expr = {
'**/bar': true,
'**/baz': true
};
assert.strictEqual(glob.match(expr, 'bar'), '**/bar');
assert.strictEqual(glob.match(expr, 'foo'), null);
assert.strictEqual(glob.match(expr, 'foo/bar'), '**/bar');
assert.strictEqual(glob.match(expr, 'foo\\bar'), '**/bar');
assert.strictEqual(glob.match(expr, 'foo/foo'), null);
});
test('expression with two basename globs and a siblings expression', function () {
let expr = {
'**/bar': true,
'**/baz': true,
'**/*.js': { when: '$(basename).ts' }
};
let sibilings = () => ['foo.ts', 'foo.js', 'foo', 'bar'];
assert.strictEqual(glob.match(expr, 'bar', sibilings), '**/bar');
assert.strictEqual(glob.match(expr, 'foo', sibilings), null);
assert.strictEqual(glob.match(expr, 'foo/bar', sibilings), '**/bar');
assert.strictEqual(glob.match(expr, 'foo\\bar', sibilings), '**/bar');
assert.strictEqual(glob.match(expr, 'foo/foo', sibilings), null);
assert.strictEqual(glob.match(expr, 'foo.js', sibilings), '**/*.js');
assert.strictEqual(glob.match(expr, 'bar.js', sibilings), null);
});
test('expression with multipe basename globs', function () {
let expr = {
'**/bar': true,
'{**/baz,**/foo}': true
};
assert.strictEqual(glob.match(expr, 'bar'), '**/bar');
assert.strictEqual(glob.match(expr, 'foo'), '{**/baz,**/foo}');
assert.strictEqual(glob.match(expr, 'baz'), '{**/baz,**/foo}');
assert.strictEqual(glob.match(expr, 'abc'), null);
});
test('falsy expression/pattern', function () {
assert.strictEqual(glob.match(null, 'foo'), false);
assert.strictEqual(glob.match('', 'foo'), false);
assert.strictEqual(glob.parse(null)('foo'), false);
assert.strictEqual(glob.parse('')('foo'), false);
});
test('falsy path', function () {
assert.strictEqual(glob.parse('foo')(null), false);
assert.strictEqual(glob.parse('foo')(''), false);
assert.strictEqual(glob.parse('**/*.j?')(null), false);
assert.strictEqual(glob.parse('**/*.j?')(''), false);
assert.strictEqual(glob.parse('**/*.foo')(null), false);
assert.strictEqual(glob.parse('**/*.foo')(''), false);
assert.strictEqual(glob.parse('**/foo')(null), false);
assert.strictEqual(glob.parse('**/foo')(''), false);
assert.strictEqual(glob.parse('{**/baz,**/foo}')(null), false);
assert.strictEqual(glob.parse('{**/baz,**/foo}')(''), false);
assert.strictEqual(glob.parse('{**/*.baz,**/*.foo}')(null), false);
assert.strictEqual(glob.parse('{**/*.baz,**/*.foo}')(''), false);
});
test('expression/pattern basename', function () {
assert.strictEqual(glob.parse('**/foo')('bar/baz', 'baz'), false);
assert.strictEqual(glob.parse('**/foo')('bar/foo', 'foo'), true);
assert.strictEqual(glob.parse('{**/baz,**/foo}')('baz/bar', 'bar'), false);
assert.strictEqual(glob.parse('{**/baz,**/foo}')('baz/foo', 'foo'), true);
let expr = { '**/*.js': { when: '$(basename).ts' } };
let sibilings = () => ['foo.ts', 'foo.js'];
assert.strictEqual(glob.parse(expr)('bar/baz.js', 'baz.js', sibilings), null);
assert.strictEqual(glob.parse(expr)('bar/foo.js', 'foo.js', sibilings), '**/*.js');
});
test('expression/pattern basename terms', function () {
assert.deepStrictEqual(glob.getBasenameTerms(glob.parse('**/*.foo')), []);
assert.deepStrictEqual(glob.getBasenameTerms(glob.parse('**/foo')), ['foo']);
assert.deepStrictEqual(glob.getBasenameTerms(glob.parse('**/foo/')), ['foo']);
assert.deepStrictEqual(glob.getBasenameTerms(glob.parse('{**/baz,**/foo}')), ['baz', 'foo']);
assert.deepStrictEqual(glob.getBasenameTerms(glob.parse('{**/baz/,**/foo/}')), ['baz', 'foo']);
assert.deepStrictEqual(glob.getBasenameTerms(glob.parse({
'**/foo': true,
'{**/bar,**/baz}': true,
'{**/bar2/,**/baz2/}': true,
'**/bulb': false
})), ['foo', 'bar', 'baz', 'bar2', 'baz2']);
assert.deepStrictEqual(glob.getBasenameTerms(glob.parse({
'**/foo': { when: '$(basename).zip' },
'**/bar': true
})), ['bar']);
});
test('expression/pattern optimization for basenames', function () {
assert.deepStrictEqual(glob.getBasenameTerms(glob.parse('**/foo/**')), []);
assert.deepStrictEqual(glob.getBasenameTerms(glob.parse('**/foo/**', { trimForExclusions: true })), ['foo']);
testOptimizationForBasenames('**/*.foo/**', [], [['baz/bar.foo/bar/baz', true]]);
testOptimizationForBasenames('**/foo/**', ['foo'], [['bar/foo', true], ['bar/foo/baz', false]]);
testOptimizationForBasenames('{**/baz/**,**/foo/**}', ['baz', 'foo'], [['bar/baz', true], ['bar/foo', true]]);
testOptimizationForBasenames({
'**/foo/**': true,
'{**/bar/**,**/baz/**}': true,
'**/bulb/**': false
}, ['foo', 'bar', 'baz'], [
['bar/foo', '**/foo/**'],
['foo/bar', '{**/bar/**,**/baz/**}'],
['bar/nope', null]
]);
const siblingsFn = () => ['baz', 'baz.zip', 'nope'];
testOptimizationForBasenames({
'**/foo/**': { when: '$(basename).zip' },
'**/bar/**': true
}, ['bar'], [
['bar/foo', null],
['bar/foo/baz', null],
['bar/foo/nope', null],
['foo/bar', '**/bar/**'],
], [
null,
siblingsFn,
siblingsFn
]);
});
function testOptimizationForBasenames(pattern: string | glob.IExpression, basenameTerms: string[], matches: [string, string | boolean][], siblingsFns: (() => string[])[] = []) {
const parsed = glob.parse(<glob.IExpression>pattern, { trimForExclusions: true });
assert.deepStrictEqual(glob.getBasenameTerms(parsed), basenameTerms);
matches.forEach(([text, result], i) => {
assert.strictEqual(parsed(text, null, siblingsFns[i]), result);
});
}
test('trailing slash', function () {
// Testing existing (more or less intuitive) behavior
assert.strictEqual(glob.parse('**/foo/')('bar/baz', 'baz'), false);
assert.strictEqual(glob.parse('**/foo/')('bar/foo', 'foo'), true);
assert.strictEqual(glob.parse('**/*.foo/')('bar/file.baz', 'file.baz'), false);
assert.strictEqual(glob.parse('**/*.foo/')('bar/file.foo', 'file.foo'), true);
assert.strictEqual(glob.parse('{**/foo/,**/abc/}')('bar/baz', 'baz'), false);
assert.strictEqual(glob.parse('{**/foo/,**/abc/}')('bar/foo', 'foo'), true);
assert.strictEqual(glob.parse('{**/foo/,**/abc/}')('bar/abc', 'abc'), true);
assert.strictEqual(glob.parse('{**/foo/,**/abc/}', { trimForExclusions: true })('bar/baz', 'baz'), false);
assert.strictEqual(glob.parse('{**/foo/,**/abc/}', { trimForExclusions: true })('bar/foo', 'foo'), true);
assert.strictEqual(glob.parse('{**/foo/,**/abc/}', { trimForExclusions: true })('bar/abc', 'abc'), true);
});
test('expression/pattern path', function () {
assert.strictEqual(glob.parse('**/foo/bar')(nativeSep('foo/baz'), 'baz'), false);
assert.strictEqual(glob.parse('**/foo/bar')(nativeSep('foo/bar'), 'bar'), true);
assert.strictEqual(glob.parse('**/foo/bar')(nativeSep('bar/foo/bar'), 'bar'), true);
assert.strictEqual(glob.parse('**/foo/bar/**')(nativeSep('bar/foo/bar'), 'bar'), true);
assert.strictEqual(glob.parse('**/foo/bar/**')(nativeSep('bar/foo/bar/baz'), 'baz'), true);
assert.strictEqual(glob.parse('**/foo/bar/**', { trimForExclusions: true })(nativeSep('bar/foo/bar'), 'bar'), true);
assert.strictEqual(glob.parse('**/foo/bar/**', { trimForExclusions: true })(nativeSep('bar/foo/bar/baz'), 'baz'), false);
assert.strictEqual(glob.parse('foo/bar')(nativeSep('foo/baz'), 'baz'), false);
assert.strictEqual(glob.parse('foo/bar')(nativeSep('foo/bar'), 'bar'), true);
assert.strictEqual(glob.parse('foo/bar/baz')(nativeSep('foo/bar/baz'), 'baz'), true); // #15424
assert.strictEqual(glob.parse('foo/bar')(nativeSep('bar/foo/bar'), 'bar'), false);
assert.strictEqual(glob.parse('foo/bar/**')(nativeSep('foo/bar/baz'), 'baz'), true);
assert.strictEqual(glob.parse('foo/bar/**', { trimForExclusions: true })(nativeSep('foo/bar'), 'bar'), true);
assert.strictEqual(glob.parse('foo/bar/**', { trimForExclusions: true })(nativeSep('foo/bar/baz'), 'baz'), false);
});
test('expression/pattern paths', function () {
assert.deepStrictEqual(glob.getPathTerms(glob.parse('**/*.foo')), []);
assert.deepStrictEqual(glob.getPathTerms(glob.parse('**/foo')), []);
assert.deepStrictEqual(glob.getPathTerms(glob.parse('**/foo/bar')), ['*/foo/bar']);
assert.deepStrictEqual(glob.getPathTerms(glob.parse('**/foo/bar/')), ['*/foo/bar']);
// Not supported
// assert.deepStrictEqual(glob.getPathTerms(glob.parse('{**/baz/bar,**/foo/bar,**/bar}')), ['*/baz/bar', '*/foo/bar']);
// assert.deepStrictEqual(glob.getPathTerms(glob.parse('{**/baz/bar/,**/foo/bar/,**/bar/}')), ['*/baz/bar', '*/foo/bar']);
const parsed = glob.parse({
'**/foo/bar': true,
'**/foo2/bar2': true,
// Not supported
// '{**/bar/foo,**/baz/foo}': true,
// '{**/bar2/foo/,**/baz2/foo/}': true,
'**/bulb': true,
'**/bulb2': true,
'**/bulb/foo': false
});
assert.deepStrictEqual(glob.getPathTerms(parsed), ['*/foo/bar', '*/foo2/bar2']);
assert.deepStrictEqual(glob.getBasenameTerms(parsed), ['bulb', 'bulb2']);
assert.deepStrictEqual(glob.getPathTerms(glob.parse({
'**/foo/bar': { when: '$(basename).zip' },
'**/bar/foo': true,
'**/bar2/foo2': true
})), ['*/bar/foo', '*/bar2/foo2']);
});
test('expression/pattern optimization for paths', function () {
assert.deepStrictEqual(glob.getPathTerms(glob.parse('**/foo/bar/**')), []);
assert.deepStrictEqual(glob.getPathTerms(glob.parse('**/foo/bar/**', { trimForExclusions: true })), ['*/foo/bar']);
testOptimizationForPaths('**/*.foo/bar/**', [], [[nativeSep('baz/bar.foo/bar/baz'), true]]);
testOptimizationForPaths('**/foo/bar/**', ['*/foo/bar'], [[nativeSep('bar/foo/bar'), true], [nativeSep('bar/foo/bar/baz'), false]]);
// Not supported
// testOptimizationForPaths('{**/baz/bar/**,**/foo/bar/**}', ['*/baz/bar', '*/foo/bar'], [[nativeSep('bar/baz/bar'), true], [nativeSep('bar/foo/bar'), true]]);
testOptimizationForPaths({
'**/foo/bar/**': true,
// Not supported
// '{**/bar/bar/**,**/baz/bar/**}': true,
'**/bulb/bar/**': false
}, ['*/foo/bar'], [
[nativeSep('bar/foo/bar'), '**/foo/bar/**'],
// Not supported
// [nativeSep('foo/bar/bar'), '{**/bar/bar/**,**/baz/bar/**}'],
[nativeSep('/foo/bar/nope'), null]
]);
const siblingsFn = () => ['baz', 'baz.zip', 'nope'];
testOptimizationForPaths({
'**/foo/123/**': { when: '$(basename).zip' },
'**/bar/123/**': true
}, ['*/bar/123'], [
[nativeSep('bar/foo/123'), null],
[nativeSep('bar/foo/123/baz'), null],
[nativeSep('bar/foo/123/nope'), null],
[nativeSep('foo/bar/123'), '**/bar/123/**'],
], [
null,
siblingsFn,
siblingsFn
]);
});
function testOptimizationForPaths(pattern: string | glob.IExpression, pathTerms: string[], matches: [string, string | boolean][], siblingsFns: (() => string[])[] = []) {
const parsed = glob.parse(<glob.IExpression>pattern, { trimForExclusions: true });
assert.deepStrictEqual(glob.getPathTerms(parsed), pathTerms);
matches.forEach(([text, result], i) => {
assert.strictEqual(parsed(text, null, siblingsFns[i]), result);
});
}
function nativeSep(slashPath: string): string {
return slashPath.replace(/\//g, path.sep);
}
test('mergeExpressions', () => {
// Empty => empty
assert.deepEqual(glob.mergeExpressions(), glob.getEmptyExpression());
// Doesn't modify given expressions
const expr1 = { 'a': true };
glob.mergeExpressions(expr1, { 'b': true });
assert.deepEqual(expr1, { 'a': true });
// Merges correctly
assert.deepEqual(glob.mergeExpressions({ 'a': true }, { 'b': true }), { 'a': true, 'b': true });
// Ignores null/undefined portions
assert.deepEqual(glob.mergeExpressions(undefined, { 'a': true }, null, { 'b': true }), { 'a': true, 'b': true });
// Later expressions take precedence
assert.deepEqual(glob.mergeExpressions({ 'a': true, 'b': false, 'c': true }, { 'a': false, 'b': true }), { 'a': false, 'b': true, 'c': true });
});
});

View File

@@ -0,0 +1,23 @@
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Data.OleDb;
using System.Data.Odbc;
using System.IO;
using System.Net.Mail;
using System.Text.RegularExpressions;
using System.DirectoryServices;
using System.Diagnostics;
using System.Resources;
using System.Globalization;
using System.Reflection;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;
ObjectCount = LoadObjects("Öffentlicher Ordner");
Private = "Persönliche Information"

View File

@@ -0,0 +1,35 @@
/*----------------------------------------------------------
The base color for this template is #5c87b2. If you'd like
to use a different color start by replacing all instances of
#5c87b2 with your new color.
----------------------------------------------------------*/
body
{
background-color: #5c87b2;
font-size: .75em;
font-family: Segoe UI, Verdana, Helvetica, Sans-Serif;
margin: 8px;
padding: 0;
color: #696969;
}
h1, h2, h3, h4, h5, h6
{
color: #000;
font-size: 40px;
margin: 0px;
}
textarea
{
font-family: Consolas
}
#results
{
margin-top: 2em;
margin-left: 2em;
color: black;
font-size: medium;
}

View File

@@ -0,0 +1,11 @@
{
"type": "typescript",
"sources": [
"examples/company.ts",
"examples/conway.ts",
"examples/employee.ts",
"examples/large.ts",
"examples/small.ts"
]
}

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 B

Binary file not shown.

View File

@@ -0,0 +1 @@
VSCODEは最高のエディタだ。

View File

@@ -0,0 +1,3 @@
<?xml>
</xml>

View File

@@ -0,0 +1,79 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import assert = require('assert');
import mimeCommon = require('vs/base/common/mime');
import mime = require('vs/base/node/mime');
suite('Mime', () => {
test('detectMimesFromFile (JSON saved as PNG)', function (done: (err?: any) => void) {
const file = require.toUrl('./fixtures/some.json.png');
mime.detectMimesFromFile(file).then(mimes => {
assert.deepEqual(mimes.mimes, ['text/plain']);
done();
}, done);
});
test('detectMimesFromFile (PNG saved as TXT)', function (done: (err?: any) => void) {
mimeCommon.registerTextMime({ id: 'text', mime: 'text/plain', extension: '.txt' });
const file = require.toUrl('./fixtures/some.png.txt');
mime.detectMimesFromFile(file).then(mimes => {
assert.deepEqual(mimes.mimes, ['text/plain', 'application/octet-stream']);
done();
}, done);
});
test('detectMimesFromFile (XML saved as PNG)', function (done: (err?: any) => void) {
const file = require.toUrl('./fixtures/some.xml.png');
mime.detectMimesFromFile(file).then(mimes => {
assert.deepEqual(mimes.mimes, ['text/plain']);
done();
}, done);
});
test('detectMimesFromFile (QWOFF saved as TXT)', function (done: (err?: any) => void) {
const file = require.toUrl('./fixtures/some.qwoff.txt');
mime.detectMimesFromFile(file).then(mimes => {
assert.deepEqual(mimes.mimes, ['text/plain', 'application/octet-stream']);
done();
}, done);
});
test('detectMimesFromFile (CSS saved as QWOFF)', function (done: (err?: any) => void) {
const file = require.toUrl('./fixtures/some.css.qwoff');
mime.detectMimesFromFile(file).then(mimes => {
assert.deepEqual(mimes.mimes, ['text/plain']);
done();
}, done);
});
test('detectMimesFromFile (PDF)', function (done: () => void) {
const file = require.toUrl('./fixtures/some.pdf');
mime.detectMimesFromFile(file).then(mimes => {
assert.deepEqual(mimes.mimes, ['application/octet-stream']);
done();
}, done);
});
test('autoGuessEncoding (ShiftJIS)', function (done: () => void) {
const file = require.toUrl('./fixtures/some.shiftjis.txt');
mime.detectMimesFromFile(file, { autoGuessEncoding: true }).then(mimes => {
assert.equal(mimes.encoding, 'shiftjis');
done();
}, done);
});
test('autoGuessEncoding (CP1252)', function (done: () => void) {
const file = require.toUrl('./fixtures/some.cp1252.txt');
mime.detectMimesFromFile(file, { autoGuessEncoding: true }).then(mimes => {
assert.equal(mimes.encoding, 'windows1252');
done();
}, done);
});
});

View File

@@ -0,0 +1,147 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { TPromise } from 'vs/base/common/winjs.base';
import assert = require('assert');
import os = require('os');
import path = require('path');
import fs = require('fs');
import uuid = require('vs/base/common/uuid');
import extfs = require('vs/base/node/extfs');
import { onError } from 'vs/base/test/common/utils';
import * as pfs from 'vs/base/node/pfs';
suite('PFS', () => {
test('writeFile', function (done: () => void) {
const id = uuid.generateUuid();
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
const newDir = path.join(parentDir, 'pfs', id);
const testFile = path.join(newDir, 'writefile.txt');
extfs.mkdirp(newDir, 493, (error) => {
if (error) {
return onError(error, done);
}
assert.ok(fs.existsSync(newDir));
pfs.writeFile(testFile, 'Hello World', null).done(() => {
assert.equal(fs.readFileSync(testFile), 'Hello World');
extfs.del(parentDir, os.tmpdir(), () => { }, done);
}, error => onError(error, done));
});
});
test('writeFile - parallel write on different files works', function (done: () => void) {
const id = uuid.generateUuid();
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
const newDir = path.join(parentDir, 'pfs', id);
const testFile1 = path.join(newDir, 'writefile1.txt');
const testFile2 = path.join(newDir, 'writefile2.txt');
const testFile3 = path.join(newDir, 'writefile3.txt');
const testFile4 = path.join(newDir, 'writefile4.txt');
const testFile5 = path.join(newDir, 'writefile5.txt');
extfs.mkdirp(newDir, 493, (error) => {
if (error) {
return onError(error, done);
}
assert.ok(fs.existsSync(newDir));
TPromise.join([
pfs.writeFile(testFile1, 'Hello World 1', null),
pfs.writeFile(testFile2, 'Hello World 2', null),
pfs.writeFile(testFile3, 'Hello World 3', null),
pfs.writeFile(testFile4, 'Hello World 4', null),
pfs.writeFile(testFile5, 'Hello World 5', null)
]).done(() => {
assert.equal(fs.readFileSync(testFile1), 'Hello World 1');
assert.equal(fs.readFileSync(testFile2), 'Hello World 2');
assert.equal(fs.readFileSync(testFile3), 'Hello World 3');
assert.equal(fs.readFileSync(testFile4), 'Hello World 4');
assert.equal(fs.readFileSync(testFile5), 'Hello World 5');
extfs.del(parentDir, os.tmpdir(), () => { }, done);
}, error => onError(error, done));
});
});
test('writeFile - parallel write on same files works and is sequentalized', function (done: () => void) {
const id = uuid.generateUuid();
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
const newDir = path.join(parentDir, 'pfs', id);
const testFile = path.join(newDir, 'writefile.txt');
extfs.mkdirp(newDir, 493, (error) => {
if (error) {
return onError(error, done);
}
assert.ok(fs.existsSync(newDir));
TPromise.join([
pfs.writeFile(testFile, 'Hello World 1', null),
pfs.writeFile(testFile, 'Hello World 2', null),
TPromise.timeout(10).then(() => pfs.writeFile(testFile, 'Hello World 3', null)),
pfs.writeFile(testFile, 'Hello World 4', null),
TPromise.timeout(10).then(() => pfs.writeFile(testFile, 'Hello World 5', null))
]).done(() => {
assert.equal(fs.readFileSync(testFile), 'Hello World 5');
extfs.del(parentDir, os.tmpdir(), () => { }, done);
}, error => onError(error, done));
});
});
test('rimraf - simple', function (done: () => void) {
const id = uuid.generateUuid();
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
const newDir = path.join(parentDir, 'extfs', id);
extfs.mkdirp(newDir, 493, (error) => {
if (error) {
return onError(error, done);
}
fs.writeFileSync(path.join(newDir, 'somefile.txt'), 'Contents');
fs.writeFileSync(path.join(newDir, 'someOtherFile.txt'), 'Contents');
pfs.rimraf(newDir).then(() => {
assert.ok(!fs.existsSync(newDir));
done();
}, error => onError(error, done));
}); // 493 = 0755
});
test('rimraf - recursive folder structure', function (done: () => void) {
const id = uuid.generateUuid();
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
const newDir = path.join(parentDir, 'extfs', id);
extfs.mkdirp(newDir, 493, (error) => {
if (error) {
return onError(error, done);
}
fs.writeFileSync(path.join(newDir, 'somefile.txt'), 'Contents');
fs.writeFileSync(path.join(newDir, 'someOtherFile.txt'), 'Contents');
fs.mkdirSync(path.join(newDir, 'somefolder'));
fs.writeFileSync(path.join(newDir, 'somefolder', 'somefile.txt'), 'Contents');
pfs.rimraf(newDir).then(() => {
assert.ok(!fs.existsSync(newDir));
done();
}, error => onError(error, done));
}); // 493 = 0755
});
});

View File

@@ -0,0 +1,38 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import * as net from 'net';
import ports = require('vs/base/node/ports');
suite('Ports', () => {
test('Finds a free port (no timeout)', function (done: () => void) {
this.timeout(1000 * 10); // higher timeout for this test
if (process.env['VSCODE_PID']) {
return done(); // this test fails when run from within VS Code
}
// get an initial freeport >= 7000
ports.findFreePort(7000, 100, 300000, (initialPort) => {
assert.ok(initialPort >= 7000);
// create a server to block this port
const server = net.createServer();
server.listen(initialPort, null, null, () => {
// once listening, find another free port and assert that the port is different from the opened one
ports.findFreePort(7000, 50, 300000, (freePort) => {
assert.ok(freePort >= 7000 && freePort !== initialPort);
server.close();
done();
});
});
});
});
});

View File

@@ -0,0 +1,16 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import processes = require('vs/base/node/processes');
const sender = processes.createQueuedSender(process);
process.on('message', msg => {
sender.send(msg);
});
sender.send('ready');

View File

@@ -0,0 +1,19 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import processes = require('vs/base/node/processes');
const sender = processes.createQueuedSender(process);
process.on('message', msg => {
sender.send(msg);
sender.send(msg);
sender.send(msg);
sender.send('done');
});
sender.send('ready');

View File

@@ -0,0 +1,89 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import * as cp from 'child_process';
import * as objects from 'vs/base/common/objects';
import * as platform from 'vs/base/common/platform';
import URI from 'vs/base/common/uri';
import processes = require('vs/base/node/processes');
function fork(id: string): cp.ChildProcess {
const opts: any = {
env: objects.mixin(objects.clone(process.env), {
AMD_ENTRYPOINT: id,
PIPE_LOGGING: 'true',
VERBOSE_LOGGING: true
})
};
return cp.fork(URI.parse(require.toUrl('bootstrap')).fsPath, ['--type=processTests'], opts);
}
suite('Processes', () => {
test('buffered sending - simple data', function (done: () => void) {
if (process.env['VSCODE_PID']) {
return done(); // this test fails when run from within VS Code
}
const child = fork('vs/base/test/node/processes/fixtures/fork');
const sender = processes.createQueuedSender(child);
let counter = 0;
const msg1 = 'Hello One';
const msg2 = 'Hello Two';
const msg3 = 'Hello Three';
child.on('message', msgFromChild => {
if (msgFromChild === 'ready') {
sender.send(msg1);
sender.send(msg2);
sender.send(msg3);
} else {
counter++;
if (counter === 1) {
assert.equal(msgFromChild, msg1);
} else if (counter === 2) {
assert.equal(msgFromChild, msg2);
} else if (counter === 3) {
assert.equal(msgFromChild, msg3);
child.kill();
done();
}
}
});
});
test('buffered sending - lots of data (potential deadlock on win32)', function (done: () => void) {
if (!platform.isWindows || process.env['VSCODE_PID']) {
return done(); // test is only relevant for Windows and seems to crash randomly on some Linux builds
}
const child = fork('vs/base/test/node/processes/fixtures/fork_large');
const sender = processes.createQueuedSender(child);
const largeObj = Object.create(null);
for (let i = 0; i < 10000; i++) {
largeObj[i] = 'some data';
}
const msg = JSON.stringify(largeObj);
child.on('message', msgFromChild => {
if (msgFromChild === 'ready') {
sender.send(msg);
sender.send(msg);
sender.send(msg);
} else if (msgFromChild === 'done') {
child.kill();
done();
}
});
});
});

View File

@@ -0,0 +1,40 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
/*----------------------------------------------------------
The base color for this template is #5c87b2. If you'd like
to use a different color start by replacing all instances of
#5c87b2 with your new color.
----------------------------------------------------------*/
body
{
background-color: #5c87b2;
font-size: .75em;
font-family: Segoe UI, Verdana, Helvetica, Sans-Serif;
margin: 8px;
padding: 0;
color: #696969;
}
h1, h2, h3, h4, h5, h6
{
color: #000;
font-size: 40px;
margin: 0px;
}
textarea
{
font-family: Consolas
}
#results
{
margin-top: 2em;
margin-left: 2em;
color: black;
font-size: medium;
}

View File

@@ -0,0 +1,71 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import assert = require('assert');
import fs = require('fs');
import stream = require('vs/base/node/stream');
suite('Stream', () => {
test('readExactlyByFile - ANSI', function (done: (err?) => void) {
const file = require.toUrl('./fixtures/file.css');
stream.readExactlyByFile(file, 10).then(({ buffer, bytesRead }) => {
assert.equal(bytesRead, 10);
assert.equal(buffer.toString(), '/*--------');
done();
}, done);
});
test('readExactlyByFile - empty', function (done: (err?: any) => void) {
const file = require.toUrl('./fixtures/empty.txt');
stream.readExactlyByFile(file, 10).then(({ bytesRead }) => {
assert.equal(bytesRead, 0);
done();
}, done);
});
test('readExactlyByStream - ANSI', function (done: (err?: any) => void) {
const file = require.toUrl('./fixtures/file.css');
stream.readExactlyByStream(fs.createReadStream(file), 10).then(({ buffer, bytesRead }) => {
assert.equal(bytesRead, 10);
assert.equal(buffer.toString(), '/*--------');
done();
}, done);
});
test('readExactlyByStream - empty', function (done: (err?: any) => void) {
const file = require.toUrl('./fixtures/empty.txt');
stream.readExactlyByStream(fs.createReadStream(file), 10).then(({ bytesRead }) => {
assert.equal(bytesRead, 0);
done();
}, done);
});
test('readToMatchingString - ANSI', function (done: (err?: any) => void) {
const file = require.toUrl('./fixtures/file.css');
stream.readToMatchingString(file, '\n', 10, 100).then((result: string) => {
// \r may be present on Windows
assert.equal(result.replace('\r', ''), '/*---------------------------------------------------------------------------------------------');
done();
}, done);
});
test('readToMatchingString - empty', function (done: (err?: any) => void) {
const file = require.toUrl('./fixtures/empty.txt');
stream.readToMatchingString(file, '\n', 10, 100).then((result: string) => {
assert.equal(result, null);
done();
}, done);
});
});

Binary file not shown.

View File

@@ -0,0 +1,29 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import * as path from 'path';
import * as os from 'os';
import URI from 'vs/base/common/uri';
import { extract } from 'vs/base/node/zip';
import { generateUuid } from 'vs/base/common/uuid';
import { rimraf, exists } from 'vs/base/node/pfs';
const fixtures = URI.parse(require.toUrl('./fixtures')).fsPath;
suite('Zip', () => {
test('extract should handle directories', () => {
const fixture = path.join(fixtures, 'extract.zip');
const target = path.join(os.tmpdir(), generateUuid());
return extract(fixture, target)
.then(() => exists(path.join(target, 'extension')))
.then(exists => assert(exists))
.then(() => rimraf(target));
});
});