Merge VS Code 1.31.1 (#4283)

This commit is contained in:
Matt Irvine
2019-03-15 13:09:45 -07:00
committed by GitHub
parent 7d31575149
commit 86bac90001
1716 changed files with 53308 additions and 48375 deletions

View File

@@ -25,18 +25,19 @@ suite('dom', () => {
let div = $('div', { class: 'test' });
assert.equal(div.className, 'test');
div = $('div', null);
div = $('div', undefined);
assert.equal(div.className, '');
});
test('should build nodes with children', () => {
let div = $('div', null, $('span', { id: 'demospan' }));
let div = $('div', undefined, $('span', { id: 'demospan' }));
let firstChild = div.firstChild as HTMLElement;
assert.equal(firstChild.tagName, 'SPAN');
assert.equal(firstChild.id, 'demospan');
div = $('div', null, 'hello');
assert.equal(div.firstChild.textContent, 'hello');
div = $('div', undefined, 'hello');
assert.equal(div.firstChild && div.firstChild.textContent, 'hello');
});
});
});

View File

@@ -12,11 +12,6 @@ suite('HighlightedLabel', () => {
label = new HighlightedLabel(document.createElement('div'), true);
});
teardown(() => {
label.dispose();
label = null;
});
test('empty label', function () {
assert.equal(label.element.innerHTML, '');
});

View File

@@ -8,7 +8,7 @@ import { renderMarkdown, renderText, renderFormattedText } from 'vs/base/browser
suite('HtmlContent', () => {
test('render simple element', () => {
var result: HTMLElement = renderText('testing');
let result: HTMLElement = renderText('testing');
assert.strictEqual(result.nodeType, document.ELEMENT_NODE);
assert.strictEqual(result.textContent, 'testing');
@@ -16,7 +16,7 @@ suite('HtmlContent', () => {
});
test('render element with class', () => {
var result: HTMLElement = renderText('testing', {
let result: HTMLElement = renderText('testing', {
className: 'testClass'
});
assert.strictEqual(result.nodeType, document.ELEMENT_NODE);
@@ -24,9 +24,9 @@ suite('HtmlContent', () => {
});
test('simple formatting', () => {
var result: HTMLElement = renderFormattedText('**bold**');
let result: HTMLElement = renderFormattedText('**bold**');
assert.strictEqual(result.children.length, 1);
assert.strictEqual(result.firstChild.textContent, 'bold');
assert.strictEqual(result.firstChild!.textContent, 'bold');
assert.strictEqual((<HTMLElement>result.firstChild).tagName, 'B');
assert.strictEqual(result.innerHTML, '<b>bold</b>');
@@ -38,18 +38,18 @@ suite('HtmlContent', () => {
});
test('no formatting', () => {
var result: HTMLElement = renderFormattedText('this is just a string');
let result: HTMLElement = renderFormattedText('this is just a string');
assert.strictEqual(result.innerHTML, 'this is just a string');
});
test('preserve newlines', () => {
var result: HTMLElement = renderFormattedText('line one\nline two');
let result: HTMLElement = renderFormattedText('line one\nline two');
assert.strictEqual(result.innerHTML, 'line one<br>line two');
});
test('action', () => {
var callbackCalled = false;
var result: HTMLElement = renderFormattedText('[[action]]', {
let callbackCalled = false;
let result: HTMLElement = renderFormattedText('[[action]]', {
actionHandler: {
callback(content) {
assert.strictEqual(content, '0');
@@ -60,15 +60,15 @@ suite('HtmlContent', () => {
});
assert.strictEqual(result.innerHTML, '<a href="#">action</a>');
var event: MouseEvent = <any>document.createEvent('MouseEvent');
let event: MouseEvent = <any>document.createEvent('MouseEvent');
event.initEvent('click', true, true);
result.firstChild.dispatchEvent(event);
result.firstChild!.dispatchEvent(event);
assert.strictEqual(callbackCalled, true);
});
test('fancy action', () => {
var callbackCalled = false;
var result: HTMLElement = renderFormattedText('__**[[action]]**__', {
let callbackCalled = false;
let result: HTMLElement = renderFormattedText('__**[[action]]**__', {
actionHandler: {
callback(content) {
assert.strictEqual(content, '0');
@@ -79,14 +79,14 @@ suite('HtmlContent', () => {
});
assert.strictEqual(result.innerHTML, '<i><b><a href="#">action</a></b></i>');
var event: MouseEvent = <any>document.createEvent('MouseEvent');
let event: MouseEvent = <any>document.createEvent('MouseEvent');
event.initEvent('click', true, true);
result.firstChild.firstChild.firstChild.dispatchEvent(event);
result.firstChild!.firstChild!.firstChild!.dispatchEvent(event);
assert.strictEqual(callbackCalled, true);
});
test('escaped formatting', () => {
var result: HTMLElement = renderFormattedText('\\*\\*bold\\*\\*');
let result: HTMLElement = renderFormattedText('\\*\\*bold\\*\\*');
assert.strictEqual(result.children.length, 0);
assert.strictEqual(result.innerHTML, '**bold**');
});
@@ -111,15 +111,15 @@ suite('HtmlContent', () => {
assert.strictEqual(result.innerHTML, imageFromMarked);
});
test('image width from title params', () => {
var result: HTMLElement = renderMarkdown({ value: `![image](someimageurl|width=100 'caption')` });
let result: HTMLElement = 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 = renderMarkdown({ value: `![image](someimageurl|height=100 'caption')` });
let result: HTMLElement = 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 = renderMarkdown({ value: `![image](someimageurl|height=200,width=100 'caption')` });
let result: HTMLElement = 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

@@ -21,10 +21,6 @@ suite('Gridview', function () {
container.appendChild(gridview.element);
});
teardown(function () {
gridview = null;
});
test('empty gridview is empty', function () {
assert.deepEqual(nodesToArrays(gridview.getViews()), []);
gridview.dispose();

View File

@@ -9,20 +9,20 @@ import { IView, GridNode, isGridBranchNode, } from 'vs/base/browser/ui/grid/grid
export class TestView implements IView {
private _onDidChange = new Emitter<{ width: number; height: number; }>();
private _onDidChange = new Emitter<{ width: number; height: number; } | undefined>();
readonly onDidChange = this._onDidChange.event;
get minimumWidth(): number { return this._minimumWidth; }
set minimumWidth(size: number) { this._minimumWidth = size; this._onDidChange.fire(); }
set minimumWidth(size: number) { this._minimumWidth = size; this._onDidChange.fire(undefined); }
get maximumWidth(): number { return this._maximumWidth; }
set maximumWidth(size: number) { this._maximumWidth = size; this._onDidChange.fire(); }
set maximumWidth(size: number) { this._maximumWidth = size; this._onDidChange.fire(undefined); }
get minimumHeight(): number { return this._minimumHeight; }
set minimumHeight(size: number) { this._minimumHeight = size; this._onDidChange.fire(); }
set minimumHeight(size: number) { this._minimumHeight = size; this._onDidChange.fire(undefined); }
get maximumHeight(): number { return this._maximumHeight; }
set maximumHeight(size: number) { this._maximumHeight = size; this._onDidChange.fire(); }
set maximumHeight(size: number) { this._maximumHeight = size; this._onDidChange.fire(undefined); }
private _element: HTMLElement = document.createElement('div');
get element(): HTMLElement { this._onDidGetElement.fire(); return this._element; }

View File

@@ -25,7 +25,6 @@ suite('ListView', function () {
templateId: 'template',
renderTemplate() { templatesCount++; },
renderElement() { },
disposeElement() { },
disposeTemplate() { templatesCount--; }
};

View File

@@ -8,7 +8,7 @@ import { RangeMap, groupIntersect, consolidate } from 'vs/base/browser/ui/list/r
import { Range } from 'vs/base/common/range';
suite('RangeMap', () => {
var rangeMap: RangeMap;
let rangeMap: RangeMap;
setup(() => {
rangeMap = new RangeMap();

View File

@@ -14,10 +14,10 @@ class TestView implements IView {
readonly onDidChange = this._onDidChange.event;
get minimumSize(): number { return this._minimumSize; }
set minimumSize(size: number) { this._minimumSize = size; this._onDidChange.fire(); }
set minimumSize(size: number) { this._minimumSize = size; this._onDidChange.fire(undefined); }
get maximumSize(): number { return this._maximumSize; }
set maximumSize(size: number) { this._maximumSize = size; this._onDidChange.fire(); }
set maximumSize(size: number) { this._maximumSize = size; this._onDidChange.fire(undefined); }
private _element: HTMLElement = document.createElement('div');
get element(): HTMLElement { this._onDidGetElement.fire(); return this._element; }
@@ -72,13 +72,9 @@ suite('Splitview', () => {
container.style.height = `${200}px`;
});
teardown(() => {
container = null;
});
test('empty splitview has empty DOM', () => {
const splitview = new SplitView(container);
assert.equal(container.firstElementChild.firstElementChild.childElementCount, 0, 'split view should be empty');
assert.equal(container.firstElementChild!.firstElementChild!.childElementCount, 0, 'split view should be empty');
splitview.dispose();
});
@@ -135,7 +131,7 @@ suite('Splitview', () => {
let didLayout = false;
const layoutDisposable = view.onDidLayout(() => didLayout = true);
const renderDisposable = view.onDidGetElement(() => void 0);
const renderDisposable = view.onDidGetElement(() => undefined);
splitview.addView(view, 20);

View File

@@ -4,8 +4,8 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { ITreeNode, ITreeRenderer } from 'vs/base/browser/ui/tree/tree';
import { AsyncDataTree, IDataSource } from 'vs/base/browser/ui/tree/asyncDataTree';
import { ITreeNode, ITreeRenderer, IAsyncDataSource } from 'vs/base/browser/ui/tree/tree';
import { AsyncDataTree } from 'vs/base/browser/ui/tree/asyncDataTree';
import { IListVirtualDelegate, IIdentityProvider } from 'vs/base/browser/ui/list/list';
import { hasClass } from 'vs/base/browser/dom';
@@ -46,23 +46,16 @@ suite('AsyncDataTree', function () {
renderElement(element: ITreeNode<Element, void>, index: number, templateData: HTMLElement): void {
templateData.textContent = element.element.id;
}
disposeElement(element: ITreeNode<Element, void>, index: number, templateData: HTMLElement): void {
// noop
}
disposeTemplate(templateData: HTMLElement): void {
// noop
}
};
const dataSource = new class implements IDataSource<Element> {
hasChildren(element: Element | null): boolean {
return !element || (element.children && element.children.length > 0);
const dataSource = new class implements IAsyncDataSource<Element, Element> {
hasChildren(element: Element): boolean {
return !!element.children && element.children.length > 0;
}
getChildren(element: Element | null): Thenable<Element[]> {
if (!element) {
return Promise.resolve(root.children);
}
getChildren(element: Element): Promise<Element[]> {
return Promise.resolve(element.children || []);
}
};
@@ -82,11 +75,11 @@ suite('AsyncDataTree', function () {
const _: (id: string) => Element = find.bind(null, root.children);
const tree = new AsyncDataTree(container, delegate, [renderer], dataSource, { identityProvider });
const tree = new AsyncDataTree<Element, Element>(container, delegate, [renderer], dataSource, { identityProvider });
tree.layout(200);
assert.equal(container.querySelectorAll('.monaco-list-row').length, 0);
await tree.refresh(null);
await tree.setInput(root);
assert.equal(container.querySelectorAll('.monaco-list-row').length, 1);
let twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
assert(!hasClass(twistie, 'collapsible'));
@@ -98,14 +91,14 @@ suite('AsyncDataTree', function () {
{ id: 'ac' }
];
await tree.refresh(null);
await tree.updateChildren(root);
assert.equal(container.querySelectorAll('.monaco-list-row').length, 1);
await tree.expand(_('a'));
assert.equal(container.querySelectorAll('.monaco-list-row').length, 4);
_('a').children = [];
await tree.refresh(null);
await tree.updateChildren(root);
assert.equal(container.querySelectorAll('.monaco-list-row').length, 1);
});
});

View File

@@ -0,0 +1,148 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { ITreeNode, ITreeRenderer, IDataSource } from 'vs/base/browser/ui/tree/tree';
import { IListVirtualDelegate, IIdentityProvider } from 'vs/base/browser/ui/list/list';
import { DataTree } from 'vs/base/browser/ui/tree/dataTree';
interface E {
value: number;
children?: E[];
}
suite('DataTree', function () {
let tree: DataTree<E, E>;
const root: E = {
value: -1,
children: [
{ value: 0, children: [{ value: 10 }, { value: 11 }, { value: 12 }] },
{ value: 1 },
{ value: 2 },
]
};
const empty: E = {
value: -1,
children: []
};
setup(() => {
const container = document.createElement('div');
container.style.width = '200px';
container.style.height = '200px';
const delegate = new class implements IListVirtualDelegate<E> {
getHeight() { return 20; }
getTemplateId(): string { return 'default'; }
};
const renderer = new class implements ITreeRenderer<E, void, HTMLElement> {
readonly templateId = 'default';
renderTemplate(container: HTMLElement): HTMLElement {
return container;
}
renderElement(element: ITreeNode<E, void>, index: number, templateData: HTMLElement): void {
templateData.textContent = `${element.element.value}`;
}
disposeTemplate(): void { }
};
const dataSource = new class implements IDataSource<E, E> {
getChildren(element: E): E[] {
return element.children || [];
}
};
const identityProvider = new class implements IIdentityProvider<E> {
getId(element: E): { toString(): string; } {
return `${element.value}`;
}
};
tree = new DataTree<E, E>(container, delegate, [renderer], dataSource, {
identityProvider
});
tree.layout(200);
});
teardown(() => {
tree.dispose();
});
test('view state is lost implicitly', () => {
tree.setInput(root);
let navigator = tree.navigate();
assert.equal(navigator.next()!.value, 0);
assert.equal(navigator.next()!.value, 10);
assert.equal(navigator.next()!.value, 11);
assert.equal(navigator.next()!.value, 12);
assert.equal(navigator.next()!.value, 1);
assert.equal(navigator.next()!.value, 2);
assert.equal(navigator.next()!, null);
tree.collapse(root.children![0]);
navigator = tree.navigate();
assert.equal(navigator.next()!.value, 0);
assert.equal(navigator.next()!.value, 1);
assert.equal(navigator.next()!.value, 2);
assert.equal(navigator.next()!, null);
tree.setSelection([root.children![1]]);
tree.setFocus([root.children![2]]);
tree.setInput(empty);
tree.setInput(root);
navigator = tree.navigate();
assert.equal(navigator.next()!.value, 0);
assert.equal(navigator.next()!.value, 10);
assert.equal(navigator.next()!.value, 11);
assert.equal(navigator.next()!.value, 12);
assert.equal(navigator.next()!.value, 1);
assert.equal(navigator.next()!.value, 2);
assert.equal(navigator.next()!, null);
assert.deepEqual(tree.getSelection(), []);
assert.deepEqual(tree.getFocus(), []);
});
test('view state can be preserved', () => {
tree.setInput(root);
let navigator = tree.navigate();
assert.equal(navigator.next()!.value, 0);
assert.equal(navigator.next()!.value, 10);
assert.equal(navigator.next()!.value, 11);
assert.equal(navigator.next()!.value, 12);
assert.equal(navigator.next()!.value, 1);
assert.equal(navigator.next()!.value, 2);
assert.equal(navigator.next()!, null);
tree.collapse(root.children![0]);
navigator = tree.navigate();
assert.equal(navigator.next()!.value, 0);
assert.equal(navigator.next()!.value, 1);
assert.equal(navigator.next()!.value, 2);
assert.equal(navigator.next()!, null);
tree.setSelection([root.children![1]]);
tree.setFocus([root.children![2]]);
const viewState = tree.getViewState();
tree.setInput(empty);
tree.setInput(root, viewState);
navigator = tree.navigate();
assert.equal(navigator.next()!.value, 0);
assert.equal(navigator.next()!.value, 1);
assert.equal(navigator.next()!.value, 2);
assert.equal(navigator.next()!, null);
assert.deepEqual(tree.getSelection(), [root.children![1]]);
assert.deepEqual(tree.getFocus(), [root.children![2]]);
});
});

View File

@@ -0,0 +1,189 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { ITreeNode, ITreeRenderer } from 'vs/base/browser/ui/tree/tree';
import { IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
import { ObjectTree } from 'vs/base/browser/ui/tree/objectTree';
import { Iterator } from 'vs/base/common/iterator';
suite('ObjectTree', function () {
suite('TreeNavigator', function () {
let tree: ObjectTree<number>;
let filter = (_: number) => true;
setup(() => {
const container = document.createElement('div');
container.style.width = '200px';
container.style.height = '200px';
const delegate = new class implements IListVirtualDelegate<number> {
getHeight() { return 20; }
getTemplateId(): string { return 'default'; }
};
const renderer = new class implements ITreeRenderer<number, void, HTMLElement> {
readonly templateId = 'default';
renderTemplate(container: HTMLElement): HTMLElement {
return container;
}
renderElement(element: ITreeNode<number, void>, index: number, templateData: HTMLElement): void {
templateData.textContent = `${element.element}`;
}
disposeTemplate(): void { }
};
tree = new ObjectTree<number>(container, delegate, [renderer], { filter: { filter: (el) => filter(el) } });
tree.layout(200);
});
teardown(() => {
tree.dispose();
filter = (_: number) => true;
});
test('should be able to navigate', () => {
tree.setChildren(null, Iterator.fromArray([
{
element: 0, children: Iterator.fromArray([
{ element: 10 },
{ element: 11 },
{ element: 12 },
])
},
{ element: 1 },
{ element: 2 }
]));
const navigator = tree.navigate();
assert.equal(navigator.current(), null);
assert.equal(navigator.next(), 0);
assert.equal(navigator.current(), 0);
assert.equal(navigator.next(), 10);
assert.equal(navigator.current(), 10);
assert.equal(navigator.next(), 11);
assert.equal(navigator.current(), 11);
assert.equal(navigator.next(), 12);
assert.equal(navigator.current(), 12);
assert.equal(navigator.next(), 1);
assert.equal(navigator.current(), 1);
assert.equal(navigator.next(), 2);
assert.equal(navigator.current(), 2);
assert.equal(navigator.previous(), 1);
assert.equal(navigator.current(), 1);
assert.equal(navigator.previous(), 12);
assert.equal(navigator.previous(), 11);
assert.equal(navigator.previous(), 10);
assert.equal(navigator.previous(), 0);
assert.equal(navigator.previous(), null);
assert.equal(navigator.next(), 0);
assert.equal(navigator.next(), 10);
assert.equal(navigator.parent(), 0);
assert.equal(navigator.parent(), null);
assert.equal(navigator.first(), 0);
assert.equal(navigator.last(), 2);
});
test('should skip collapsed nodes', () => {
tree.setChildren(null, Iterator.fromArray([
{
element: 0, collapsed: true, children: Iterator.fromArray([
{ element: 10 },
{ element: 11 },
{ element: 12 },
])
},
{ element: 1 },
{ element: 2 }
]));
const navigator = tree.navigate();
assert.equal(navigator.current(), null);
assert.equal(navigator.next(), 0);
assert.equal(navigator.next(), 1);
assert.equal(navigator.next(), 2);
assert.equal(navigator.next(), null);
assert.equal(navigator.previous(), 2);
assert.equal(navigator.previous(), 1);
assert.equal(navigator.previous(), 0);
assert.equal(navigator.previous(), null);
assert.equal(navigator.next(), 0);
assert.equal(navigator.parent(), null);
assert.equal(navigator.first(), 0);
assert.equal(navigator.last(), 2);
});
test('should skip filtered elements', () => {
filter = el => el % 2 === 0;
tree.setChildren(null, Iterator.fromArray([
{
element: 0, children: Iterator.fromArray([
{ element: 10 },
{ element: 11 },
{ element: 12 },
])
},
{ element: 1 },
{ element: 2 }
]));
const navigator = tree.navigate();
assert.equal(navigator.current(), null);
assert.equal(navigator.next(), 0);
assert.equal(navigator.next(), 10);
assert.equal(navigator.next(), 12);
assert.equal(navigator.next(), 2);
assert.equal(navigator.next(), null);
assert.equal(navigator.previous(), 2);
assert.equal(navigator.previous(), 12);
assert.equal(navigator.previous(), 10);
assert.equal(navigator.previous(), 0);
assert.equal(navigator.previous(), null);
assert.equal(navigator.next(), 0);
assert.equal(navigator.next(), 10);
assert.equal(navigator.parent(), 0);
assert.equal(navigator.parent(), null);
assert.equal(navigator.first(), 0);
assert.equal(navigator.last(), 2);
});
test('should be able to start from node', () => {
tree.setChildren(null, Iterator.fromArray([
{
element: 0, children: Iterator.fromArray([
{ element: 10 },
{ element: 11 },
{ element: 12 },
])
},
{ element: 1 },
{ element: 2 }
]));
const navigator = tree.navigate(1);
assert.equal(navigator.current(), 1);
assert.equal(navigator.next(), 2);
assert.equal(navigator.current(), 2);
assert.equal(navigator.previous(), 1);
assert.equal(navigator.current(), 1);
assert.equal(navigator.previous(), 12);
assert.equal(navigator.previous(), 11);
assert.equal(navigator.previous(), 10);
assert.equal(navigator.previous(), 0);
assert.equal(navigator.previous(), null);
assert.equal(navigator.next(), 0);
assert.equal(navigator.next(), 10);
assert.equal(navigator.parent(), 0);
assert.equal(navigator.parent(), null);
assert.equal(navigator.first(), 0);
assert.equal(navigator.last(), 2);
});
});
});

View File

@@ -32,8 +32,16 @@ suite('Arrays', () => {
});
test('stableSort', () => {
function fill<T>(num: number, valueFn: () => T, arr: T[] = []): T[] {
for (let i = 0; i < num; i++) {
arr[i] = valueFn();
}
return arr;
}
let counter = 0;
let data = arrays.fill(10000, () => ({ n: 1, m: counter++ }));
let data = fill(10000, () => ({ n: 1, m: counter++ }));
arrays.mergeSort(data, (a, b) => a.n - b.n);
@@ -262,13 +270,13 @@ suite('Arrays', () => {
}
test('coalesce', () => {
let a = arrays.coalesce([null, 1, null, 2, 3]);
let a: Array<number | undefined | null> = arrays.coalesce([null, 1, null, 2, 3]);
assert.equal(a.length, 3);
assert.equal(a[0], 1);
assert.equal(a[1], 2);
assert.equal(a[2], 3);
arrays.coalesce([null, 1, null, void 0, undefined, 2, 3]);
arrays.coalesce([null, 1, null, undefined, undefined, 2, 3]);
assert.equal(a.length, 3);
assert.equal(a[0], 1);
assert.equal(a[1], 2);
@@ -298,14 +306,14 @@ suite('Arrays', () => {
});
test('coalesce - inplace', function () {
let a = [null, 1, null, 2, 3];
let a: Array<number | undefined | null> = [null, 1, null, 2, 3];
arrays.coalesceInPlace(a);
assert.equal(a.length, 3);
assert.equal(a[0], 1);
assert.equal(a[1], 2);
assert.equal(a[2], 3);
a = [null, 1, null, void 0, undefined, 2, 3];
a = [null, 1, null, undefined!, undefined!, 2, 3];
arrays.coalesceInPlace(a);
assert.equal(a.length, 3);
assert.equal(a[0], 1);

View File

@@ -39,17 +39,6 @@ suite('Async', () => {
return result;
});
// test('Cancel callback behaviour', async function () {
// let withCancelCallback = new WinJsPromise(() => { }, () => { });
// let withoutCancelCallback = new TPromise(() => { });
// withCancelCallback.cancel();
// (withoutCancelCallback as WinJsPromise).cancel();
// await withCancelCallback.then(undefined, err => { assert.ok(isPromiseCanceledError(err)); });
// await withoutCancelCallback.then(undefined, err => { assert.ok(isPromiseCanceledError(err)); });
// });
// Cancelling a sync cancelable promise will fire the cancelled token.
// Also, every `then` callback runs in another execution frame.
test('CancelablePromise execution order (sync)', function () {
@@ -64,7 +53,7 @@ suite('Async', () => {
order.push('afterCreate');
const promise = cancellablePromise
.then(null, err => null)
.then(undefined, err => null)
.then(() => order.push('finally'));
cancellablePromise.cancel();
@@ -86,7 +75,7 @@ suite('Async', () => {
order.push('afterCreate');
const promise = cancellablePromise
.then(null, err => null)
.then(undefined, err => null)
.then(() => order.push('finally'));
cancellablePromise.cancel();
@@ -95,50 +84,6 @@ suite('Async', () => {
return promise.then(() => assert.deepEqual(order, ['in callback', 'afterCreate', 'cancelled', 'afterCancel', 'finally']));
});
// // Cancelling a sync tpromise will NOT cancel the promise, since it has resolved already.
// // Every `then` callback runs sync in the same execution frame, thus `finally` executes
// // before `afterCancel`.
// test('TPromise execution order (sync)', function () {
// const order = [];
// let promise = new WinJsPromise(resolve => {
// order.push('in executor');
// resolve(1234);
// }, () => order.push('cancelled'));
// order.push('afterCreate');
// promise = promise
// .then(null, err => null)
// .then(() => order.push('finally'));
// promise.cancel();
// order.push('afterCancel');
// return promise.then(() => assert.deepEqual(order, ['in executor', 'afterCreate', 'finally', 'afterCancel']));
// });
// // Cancelling an async tpromise will cancel the promise.
// // Every `then` callback runs sync on the same execution frame as the `cancel` call,
// // so finally still executes before `afterCancel`.
// test('TPromise execution order (async)', function () {
// const order = [];
// let promise = new WinJsPromise(resolve => {
// order.push('in executor');
// setTimeout(() => resolve(1234));
// }, () => order.push('cancelled'));
// order.push('afterCreate');
// promise = promise
// .then(null, err => null)
// .then(() => order.push('finally'));
// promise.cancel();
// order.push('afterCancel');
// return promise.then(() => assert.deepEqual(order, ['in executor', 'afterCreate', 'cancelled', 'finally', 'afterCancel']));
// });
test('cancelablePromise - get inner result', async function () {
let promise = async.createCancelablePromise(token => {
return async.timeout(12).then(_ => 1234);
@@ -195,7 +140,7 @@ suite('Async', () => {
let throttler = new async.Throttler();
let promises: Thenable<any>[] = [];
let promises: Promise<any>[] = [];
promises.push(throttler.queue(factoryFactory(1)).then((n) => { assert.equal(n, 1); }));
promises.push(throttler.queue(factoryFactory(2)).then((n) => { assert.equal(n, 3); }));
@@ -211,7 +156,7 @@ suite('Async', () => {
};
let delayer = new async.Delayer(0);
let promises: Thenable<any>[] = [];
let promises: Promise<any>[] = [];
assert(!delayer.isTriggered());
@@ -259,17 +204,17 @@ suite('Async', () => {
};
let delayer = new async.Delayer(0);
let promises: Thenable<any>[] = [];
let promises: Promise<any>[] = [];
assert(!delayer.isTriggered());
promises.push(delayer.trigger(factory).then(null, () => { assert(true, 'yes, it was cancelled'); }));
promises.push(delayer.trigger(factory).then(undefined, () => { assert(true, 'yes, it was cancelled'); }));
assert(delayer.isTriggered());
promises.push(delayer.trigger(factory).then(null, () => { assert(true, 'yes, it was cancelled'); }));
promises.push(delayer.trigger(factory).then(undefined, () => { assert(true, 'yes, it was cancelled'); }));
assert(delayer.isTriggered());
promises.push(delayer.trigger(factory).then(null, () => { assert(true, 'yes, it was cancelled'); }));
promises.push(delayer.trigger(factory).then(undefined, () => { assert(true, 'yes, it was cancelled'); }));
assert(delayer.isTriggered());
delayer.cancel();
@@ -286,7 +231,7 @@ suite('Async', () => {
};
let delayer = new async.Delayer(0);
let promises: Thenable<any>[] = [];
let promises: Promise<any>[] = [];
assert(!delayer.isTriggered());
@@ -294,10 +239,10 @@ suite('Async', () => {
assert.equal(result, 1);
assert(!delayer.isTriggered());
promises.push(delayer.trigger(factory).then(null, () => { assert(true, 'yes, it was cancelled'); }));
promises.push(delayer.trigger(factory).then(undefined, () => { assert(true, 'yes, it was cancelled'); }));
assert(delayer.isTriggered());
promises.push(delayer.trigger(factory).then(null, () => { assert(true, 'yes, it was cancelled'); }));
promises.push(delayer.trigger(factory).then(undefined, () => { assert(true, 'yes, it was cancelled'); }));
assert(delayer.isTriggered());
delayer.cancel();
@@ -336,7 +281,7 @@ suite('Async', () => {
};
let delayer = new async.Delayer(0);
let promises: Thenable<any>[] = [];
let promises: Promise<any>[] = [];
assert(!delayer.isTriggered());
@@ -381,7 +326,7 @@ suite('Async', () => {
let limiter = new async.Limiter(1);
let promises: Thenable<any>[] = [];
let promises: Promise<any>[] = [];
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].forEach(n => promises.push(limiter.queue(factoryFactory(n))));
return Promise.all(promises).then((res) => {
@@ -402,7 +347,7 @@ suite('Async', () => {
let factoryFactory = (n: number) => () => async.timeout(0).then(() => n);
let limiter = new async.Limiter(1);
let promises: Thenable<any>[] = [];
let promises: Promise<any>[] = [];
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].forEach(n => promises.push(limiter.queue(factoryFactory(n))));
return Promise.all(promises).then((res) => {
@@ -429,7 +374,7 @@ suite('Async', () => {
let limiter = new async.Limiter(5);
let promises: Thenable<any>[] = [];
let promises: Promise<any>[] = [];
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].forEach(n => promises.push(limiter.queue(factoryFactory(n))));
return Promise.all(promises).then((res) => {
@@ -499,7 +444,7 @@ suite('Async', () => {
queue.queue(f1);
queue.queue(f2);
queue.queue(f3).then(null, () => error = true);
queue.queue(f3).then(undefined, () => error = true);
queue.queue(f4);
return queue.queue(f5).then(() => {
assert.equal(res[0], 1);
@@ -577,7 +522,7 @@ suite('Async', () => {
assert.ok(r2Queue);
assert.equal(r1Queue, queue.queueFor(URI.file('/some/path'))); // same queue returned
let syncPromiseFactory = () => Promise.resolve(null);
let syncPromiseFactory = () => Promise.resolve(undefined);
r1Queue.queue(syncPromiseFactory);

View File

@@ -42,7 +42,7 @@ suite('Cache', () => {
let result = cache.get();
assert.equal(counter1, 1);
assert.equal(counter2, 0);
result.promise.then(null, () => assert(true));
result.promise.then(undefined, () => assert(true));
result.dispose();
assert.equal(counter1, 1);
assert.equal(counter2, 0);

View File

@@ -186,7 +186,7 @@ suite('Color', () => {
});
test('bug#36240', () => {
assert.deepEqual(HSVA.fromRGBA(new RGBA(92, 106, 196, 1)), new HSVA(232, .531, .769, 1));
assert.deepEqual(HSVA.fromRGBA(new RGBA(92, 106, 196, 1)), new HSVA(232, 0.531, 0.769, 1));
assert.deepEqual(HSVA.toRGBA(HSVA.fromRGBA(new RGBA(92, 106, 196, 1))), new RGBA(92, 106, 196, 1));
});
});
@@ -196,50 +196,50 @@ suite('Color', () => {
test('parseHex', () => {
// invalid
assert.deepEqual(Color.Format.CSS.parseHex(null), null);
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));
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('#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('#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('#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('#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('#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));
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

@@ -11,7 +11,7 @@ suite('Decorators', () => {
class Foo {
count = 0;
constructor(private _answer: number) { }
constructor(private _answer: number | null | undefined) { }
@memoize
answer() {
@@ -56,7 +56,7 @@ suite('Decorators', () => {
class Foo {
count = 0;
constructor(private _answer: number) { }
constructor(private _answer: number | null | undefined) { }
@memoize
get answer() {

View File

@@ -21,16 +21,16 @@ class StringDiffSequence implements ISequence {
}
function createArray<T>(length: number, value: T): T[] {
var r = [];
for (var i = 0; i < length; i++) {
const r: T[] = [];
for (let 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++) {
let r = '';
for (let i = 0; i < str.length; i++) {
if (mask[i]) {
r += str.charAt(i);
}
@@ -39,10 +39,10 @@ function maskBasedSubstring(str: string, mask: boolean[]): string {
}
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);
let originalMask = createArray(originalStr.length, true);
let modifiedMask = createArray(modifiedStr.length, true);
var i, j, change;
let i, j, change;
for (i = 0; i < changes.length; i++) {
change = changes[i];
@@ -59,8 +59,8 @@ function assertAnswer(originalStr: string, modifiedStr: string, changes: IDiffCh
}
}
var originalAnswer = maskBasedSubstring(originalStr, originalMask);
var modifiedAnswer = maskBasedSubstring(modifiedStr, modifiedMask);
let originalAnswer = maskBasedSubstring(originalStr, originalMask);
let modifiedAnswer = maskBasedSubstring(modifiedStr, modifiedMask);
if (onlyLength) {
assert.equal(originalAnswer.length, answerStr.length);
@@ -72,14 +72,14 @@ function assertAnswer(originalStr: string, modifiedStr: string, changes: IDiffCh
}
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();
let diff = new Algorithm(new StringDiffSequence(originalStr), new StringDiffSequence(modifiedStr));
let 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++) {
let r = str;
for (let i = 0; i < power; i++) {
r += r;
}
return r;
@@ -87,7 +87,7 @@ function stringPower(str: string, power: number): string {
function lcsTest(Algorithm: any, originalStr: string, modifiedStr: string, answerStr: string) {
lcsInnerTest(Algorithm, originalStr, modifiedStr, answerStr);
for (var i = 2; i <= 5; i++) {
for (let i = 2; i <= 5; i++) {
lcsInnerTest(Algorithm, stringPower(originalStr, i), stringPower(modifiedStr, i), stringPower(answerStr, i), true);
}
}
@@ -116,14 +116,14 @@ suite('Diff', () => {
suite('Diff - Ported from VS', () => {
test('using continue processing predicate to quit early', function () {
var left = 'abcdef';
var right = 'abxxcyyydzzzzezzzzzzzzzzzzzzzzzzzzf';
let left = 'abcdef';
let 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;
let predicateCallCount = 0;
var diff = new LcsDiff(new StringDiffSequence(left), new StringDiffSequence(right), function (leftIndex, leftSequence, longestMatchSoFar) {
let diff = new LcsDiff(new StringDiffSequence(left), new StringDiffSequence(right), function (leftIndex, leftSequence, longestMatchSoFar) {
assert.equal(predicateCallCount, 0);
predicateCallCount++;
@@ -134,7 +134,7 @@ suite('Diff - Ported from VS', () => {
// cancel processing
return false;
});
var changes = diff.ComputeDiff(true);
let changes = diff.ComputeDiff(true);
assert.equal(predicateCallCount, 1);
@@ -170,11 +170,11 @@ suite('Diff - Ported from VS', () => {
// Cancel *one iteration* after the second match ('d')
var hitSecondMatch = false;
let 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;
let hitYet = hitSecondMatch;
hitSecondMatch = longestMatchSoFar > 1;
// Continue processing as long as there hasn't been a match made.
return !hitYet;

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { Event, Emitter, debounceEvent, EventBufferer, once, fromPromise, stopwatch, buffer, echo, EventMultiplexer, latch, AsyncEmitter, IWaitUntil } from 'vs/base/common/event';
import { Event, Emitter, EventBufferer, EventMultiplexer, AsyncEmitter, IWaitUntil } from 'vs/base/common/event';
import { IDisposable } from 'vs/base/common/lifecycle';
import * as Errors from 'vs/base/common/errors';
import { timeout } from 'vs/base/common/async';
@@ -71,7 +71,7 @@ suite('Event', function () {
// unhook listener
while (bucket.length) {
bucket.pop().dispose();
bucket.pop()!.dispose();
}
// noop
@@ -111,7 +111,7 @@ suite('Event', function () {
Errors.setUnexpectedErrorHandler(() => null);
try {
let a = new Emitter();
let a = new Emitter<undefined>();
let hit = false;
a.event(function () {
throw 9;
@@ -134,26 +134,26 @@ suite('Event', function () {
}
const context = {};
let emitter = new Emitter();
let emitter = new Emitter<undefined>();
let reg1 = emitter.event(listener, context);
let reg2 = emitter.event(listener, context);
emitter.fire();
emitter.fire(undefined);
assert.equal(counter, 2);
reg1.dispose();
emitter.fire();
emitter.fire(undefined);
assert.equal(counter, 3);
reg2.dispose();
emitter.fire();
emitter.fire(undefined);
assert.equal(counter, 3);
});
test('Debounce Event', function (done: () => void) {
let doc = new Samples.Document3();
let onDocDidChange = debounceEvent(doc.onDidChange, (prev: string[], cur) => {
let onDocDidChange = Event.debounce(doc.onDidChange, (prev: string[], cur) => {
if (!prev) {
prev = [cur];
} else if (prev.indexOf(cur) < 0) {
@@ -183,7 +183,7 @@ suite('Event', function () {
test('Debounce Event - leading', async function () {
const emitter = new Emitter<void>();
let debounced = debounceEvent(emitter.event, (l, e) => e, 0, /*leading=*/true);
let debounced = Event.debounce(emitter.event, (l, e) => e, 0, /*leading=*/true);
let calls = 0;
debounced(() => {
@@ -199,7 +199,7 @@ suite('Event', function () {
test('Debounce Event - leading', async function () {
const emitter = new Emitter<void>();
let debounced = debounceEvent(emitter.event, (l, e) => e, 0, /*leading=*/true);
let debounced = Event.debounce(emitter.event, (l, e) => e, 0, /*leading=*/true);
let calls = 0;
debounced(() => {
@@ -254,7 +254,7 @@ suite('AsyncEmitter', function () {
emitter.fireAsync(thenables => ({
foo: true,
bar: 1,
waitUntil(t: Thenable<void>) { thenables.push(t); }
waitUntil(t: Promise<void>) { thenables.push(t); }
}));
emitter.dispose();
});
@@ -384,8 +384,8 @@ suite('Event utils', () => {
let counter1 = 0, counter2 = 0, counter3 = 0;
const listener1 = emitter.event(() => counter1++);
const listener2 = once(emitter.event)(() => counter2++);
const listener3 = once(emitter.event)(() => counter3++);
const listener2 = Event.once(emitter.event)(() => counter2++);
const listener3 = Event.once(emitter.event)(() => counter3++);
assert.equal(counter1, 0);
assert.equal(counter2, 0);
@@ -412,7 +412,7 @@ suite('Event utils', () => {
test('should emit when done', async () => {
let count = 0;
const event = fromPromise(Promise.resolve(null));
const event = Event.fromPromise(Promise.resolve(null));
event(() => count++);
assert.equal(count, 0);
@@ -425,7 +425,7 @@ suite('Event utils', () => {
let count = 0;
const promise = timeout(5);
const event = fromPromise(promise);
const event = Event.fromPromise(promise);
event(() => count++);
assert.equal(count, 0);
@@ -438,7 +438,7 @@ suite('Event utils', () => {
test('should emit', () => {
const emitter = new Emitter<void>();
const event = stopwatch(emitter.event);
const event = Event.stopwatch(emitter.event);
return new Promise((c, e) => {
event(duration => {
@@ -448,7 +448,7 @@ suite('Event utils', () => {
e(err);
}
c(null);
c(undefined);
});
setTimeout(() => emitter.fire(), 10);
@@ -462,7 +462,7 @@ suite('Event utils', () => {
const result: number[] = [];
const emitter = new Emitter<number>();
const event = emitter.event;
const bufferedEvent = buffer(event);
const bufferedEvent = Event.buffer(event);
emitter.fire(1);
emitter.fire(2);
@@ -484,7 +484,7 @@ suite('Event utils', () => {
const result: number[] = [];
const emitter = new Emitter<number>();
const event = emitter.event;
const bufferedEvent = buffer(event, true);
const bufferedEvent = Event.buffer(event, true);
emitter.fire(1);
emitter.fire(2);
@@ -506,7 +506,7 @@ suite('Event utils', () => {
const result: number[] = [];
const emitter = new Emitter<number>();
const event = emitter.event;
const bufferedEvent = buffer(event, false, [-2, -1, 0]);
const bufferedEvent = Event.buffer(event, false, [-2, -1, 0]);
emitter.fire(1);
emitter.fire(2);
@@ -524,7 +524,7 @@ suite('Event utils', () => {
const result: number[] = [];
const emitter = new Emitter<number>();
const event = emitter.event;
const echoEvent = echo(event);
const echoEvent = Event.echo(event);
emitter.fire(1);
emitter.fire(2);
@@ -547,7 +547,7 @@ suite('Event utils', () => {
const result2: number[] = [];
const emitter = new Emitter<number>();
const event = emitter.event;
const echoEvent = echo(event);
const echoEvent = Event.echo(event);
emitter.fire(1);
emitter.fire(2);
@@ -744,7 +744,7 @@ suite('Event utils', () => {
test('latch', () => {
const emitter = new Emitter<number>();
const event = latch(emitter.event);
const event = Event.latch(emitter.event);
const result: number[] = [];
const listener = event(num => result.push(num));

View File

@@ -5,7 +5,7 @@
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 patterns = ['cci', 'ida', 'pos', 'CCI', 'enbled', 'callback', 'gGame', 'cons', 'zyx', 'aBc'];
const _enablePerf = false;
@@ -24,22 +24,49 @@ perfSuite('Performance - fuzzyMatch', function () {
const t1 = Date.now();
let count = 0;
for (const pattern of patterns) {
const patternLow = pattern.toLowerCase();
for (const item of data) {
count += 1;
match(pattern, patternLow, 0, item, item.toLowerCase(), 0, false);
for (let i = 0; i < 2; i++) {
for (const pattern of patterns) {
const patternLow = pattern.toLowerCase();
for (const item of data) {
count += 1;
match(pattern, patternLow, 0, item, item.toLowerCase(), 0, false);
}
}
}
const d = Date.now() - t1;
console.log(name, `${d}ms, ${Math.round(count / d) * 15}ops/15ms`);
console.log(name, `${d}ms, ${Math.round(count / d) * 15}/15ms, ${Math.round(count / d)}/1ms`);
});
}
// perfTest('matchesFuzzy', filters.matchesFuzzy);
// perfTest('fuzzyContiguousFilter', filters.fuzzyContiguousFilter);
perfTest('fuzzyScore', filters.fuzzyScore);
perfTest('fuzzyScoreGraceful', filters.fuzzyScoreGraceful);
perfTest('fuzzyScoreGracefulAggressive', filters.fuzzyScoreGracefulAggressive);
});
perfSuite('Performance - IFilter', function () {
function perfTest(name: string, match: filters.IFilter) {
test(name, () => {
const t1 = Date.now();
let count = 0;
for (let i = 0; i < 2; i++) {
for (const pattern of patterns) {
for (const item of data) {
count += 1;
match(pattern, item);
}
}
}
const d = Date.now() - t1;
console.log(name, `${d}ms, ${Math.round(count / d) * 15}/15ms, ${Math.round(count / d)}/1ms`);
});
}
perfTest('matchesFuzzy', filters.matchesFuzzy);
perfTest('matchesFuzzy2', filters.matchesFuzzy2);
perfTest('matchesPrefix', filters.matchesPrefix);
perfTest('matchesContiguousSubString', filters.matchesContiguousSubString);
perfTest('matchesCamelCase', filters.matchesCamelCase);
});

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { IFilter, or, matchesPrefix, matchesStrictPrefix, matchesCamelCase, matchesSubString, matchesContiguousSubString, matchesWords, fuzzyScore, IMatch, fuzzyScoreGraceful, fuzzyScoreGracefulAggressive, FuzzyScorer } from 'vs/base/common/filters';
import { IFilter, or, matchesPrefix, matchesStrictPrefix, matchesCamelCase, matchesSubString, matchesContiguousSubString, matchesWords, fuzzyScore, IMatch, fuzzyScoreGraceful, fuzzyScoreGracefulAggressive, FuzzyScorer, createMatches } from 'vs/base/common/filters';
function filterOk(filter: IFilter, word: string, wordToMatchAgainst: string, highlights?: { start: number; end: number; }[]) {
let r = filter(word, wordToMatchAgainst);
@@ -204,18 +204,20 @@ suite('Filters', () => {
assert.deepEqual(matchesWords('pu', 'Category: Git: Pull', true), [{ start: 15, end: 17 }]);
});
function assertMatches(pattern: string, word: string, decoratedWord: string, filter: FuzzyScorer, opts: { patternPos?: number, wordPos?: number, firstMatchCanBeWeak?: boolean } = {}) {
function assertMatches(pattern: string, word: string, decoratedWord: string | undefined, filter: FuzzyScorer, opts: { patternPos?: number, wordPos?: number, firstMatchCanBeWeak?: boolean } = {}) {
let r = filter(pattern, pattern.toLowerCase(), opts.patternPos || 0, word, word.toLowerCase(), opts.wordPos || 0, opts.firstMatchCanBeWeak || false);
assert.ok(!decoratedWord === (!r || r[1].length === 0));
assert.ok(!decoratedWord === !r);
if (r) {
const [, matches] = r;
let matches = createMatches(r);
let actualWord = '';
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;
for (const match of matches) {
actualWord += word.substring(pos, match.start);
actualWord += '^' + word.substring(match.start, match.end).split('').join('^');
pos = match.end;
}
actualWord += word.substring(pos);
assert.equal(actualWord, decoratedWord);
}
}
@@ -448,4 +450,8 @@ suite('Filters', () => {
assertMatches('cno', 'co_new', '^c^o_^new', fuzzyScoreGraceful);
assertMatches('cno', 'co_new', '^c^o_^new', fuzzyScoreGracefulAggressive);
});
test('List highlight filter: Not all characters from match are highlighterd #66923', () => {
assertMatches('foo', 'barbarbarbarbarbarbarbarbarbarbarbarbarbarbarbar_foo', 'barbarbarbarbarbarbarbarbarbarbarbarbarbarbarbar_^f^o^o', fuzzyScore);
});
});

View File

@@ -17,7 +17,7 @@ suite('Hash', () => {
});
test('number', () => {
assert.equal(hash(1), hash(1.0));
assert.equal(hash(1), hash(1));
assert.notEqual(hash(0), hash(1));
assert.notEqual(hash(1), hash(-1));
assert.notEqual(hash(0x12345678), hash(0x123456789));
@@ -39,7 +39,7 @@ suite('Hash', () => {
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.equal(hash({ 'foo': 'bar', 'foo2': undefined }), hash({ 'foo2': undefined, 'foo': 'bar' }));
assert.notEqual(hash({ 'foo': 'bar' }), hash({ 'foo': 'bar2' }));
assert.notEqual(hash({}), hash([]));
});

View File

@@ -113,12 +113,12 @@ suite('History Navigator', () => {
assert.equal(testObject.current(), undefined);
});
function toArray(historyNavigator: HistoryNavigator<string>): string[] {
let result: string[] = [];
function toArray(historyNavigator: HistoryNavigator<string>): Array<string | null> {
let result: Array<string | null> = [];
historyNavigator.first();
if (historyNavigator.current()) {
do {
result.push(historyNavigator.current());
result.push(historyNavigator.current()!);
} while (historyNavigator.next());
}
return result;

View File

@@ -9,23 +9,23 @@ import {
import { getParseErrorMessage } from 'vs/base/common/jsonErrorMessages';
function assertKinds(text: string, ...kinds: SyntaxKind[]): void {
var scanner = createScanner(text);
var kind: SyntaxKind;
let scanner = createScanner(text);
let 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);
let 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: ParseError[] = [];
var actual = parse(input, errors, options);
let errors: ParseError[] = [];
let actual = parse(input, errors, options);
if (errors.length !== 0) {
assert(false, getParseErrorMessage(errors[0].error));
@@ -34,16 +34,16 @@ function assertValidParse(input: string, expected: any, options?: ParseOptions):
}
function assertInvalidParse(input: string, expected: any, options?: ParseOptions): void {
var errors: ParseError[] = [];
var actual = parse(input, errors, options);
let errors: ParseError[] = [];
let actual = parse(input, errors, options);
assert(errors.length > 0);
assert.deepEqual(actual, expected);
}
function assertTree(input: string, expected: any, expectedErrors: number[] = [], options?: ParseOptions): void {
var errors: ParseError[] = [];
var actual = parseTree(input, errors, options);
let errors: ParseError[] = [];
let actual = parseTree(input, errors, options);
assert.deepEqual(errors.map(e => e.error, expected), expectedErrors);
let checkParent = (node: Node) => {

View File

@@ -132,31 +132,31 @@ suite('JSON - edits', () => {
test('remove item in array with one item', () => {
let content = '[\n 1\n]';
let edits = setProperty(content, [0], void 0, formatterOptions);
let edits = setProperty(content, [0], undefined, 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);
let edits = setProperty(content, [1], undefined, 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);
let edits = setProperty(content, [2], undefined, 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);
let edits = setProperty(content, [2], undefined, 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);
let edits = setProperty(content, [2], undefined, formatterOptions);
assertEdit(content, edits, '// This is a comment\n[\n 1,\n "foo"\n]');
});

View File

@@ -8,15 +8,15 @@ import * as assert from 'assert';
suite('JSON - formatter', () => {
function format(content: string, expected: string, insertSpaces = true) {
let range: Formatter.Range | undefined = void 0;
var rangeStart = content.indexOf('|');
var rangeEnd = content.lastIndexOf('|');
let range: Formatter.Range | undefined = undefined;
const rangeStart = content.indexOf('|');
const 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' });
const edits = Formatter.format(content, range, { tabSize: 2, insertSpaces: insertSpaces, eol: '\n' });
let lastEditOffset = content.length;
for (let i = edits.length - 1; i >= 0; i--) {
@@ -32,11 +32,11 @@ suite('JSON - formatter', () => {
}
test('object - single property', () => {
var content = [
const content = [
'{"x" : 1}'
].join('\n');
var expected = [
const expected = [
'{',
' "x": 1',
'}'
@@ -45,11 +45,11 @@ suite('JSON - formatter', () => {
format(content, expected);
});
test('object - multiple properties', () => {
var content = [
const content = [
'{"x" : 1, "y" : "foo", "z" : true}'
].join('\n');
var expected = [
const expected = [
'{',
' "x": 1,',
' "y": "foo",',
@@ -60,11 +60,11 @@ suite('JSON - formatter', () => {
format(content, expected);
});
test('object - no properties ', () => {
var content = [
const content = [
'{"x" : { }, "y" : {}}'
].join('\n');
var expected = [
const expected = [
'{',
' "x": {},',
' "y": {}',
@@ -74,11 +74,11 @@ suite('JSON - formatter', () => {
format(content, expected);
});
test('object - nesting', () => {
var content = [
const content = [
'{"x" : { "y" : { "z" : { }}, "a": true}}'
].join('\n');
var expected = [
const expected = [
'{',
' "x": {',
' "y": {',
@@ -93,11 +93,11 @@ suite('JSON - formatter', () => {
});
test('array - single items', () => {
var content = [
const content = [
'["[]"]'
].join('\n');
var expected = [
const expected = [
'[',
' "[]"',
']'
@@ -107,11 +107,11 @@ suite('JSON - formatter', () => {
});
test('array - multiple items', () => {
var content = [
const content = [
'[true,null,1.2]'
].join('\n');
var expected = [
const expected = [
'[',
' true,',
' null,',
@@ -123,11 +123,11 @@ suite('JSON - formatter', () => {
});
test('array - no items', () => {
var content = [
const content = [
'[ ]'
].join('\n');
var expected = [
const expected = [
'[]'
].join('\n');
@@ -135,11 +135,11 @@ suite('JSON - formatter', () => {
});
test('array - nesting', () => {
var content = [
const content = [
'[ [], [ [ {} ], "a" ] ]'
].join('\n');
var expected = [
const expected = [
'[',
' [],',
' [',
@@ -155,11 +155,11 @@ suite('JSON - formatter', () => {
});
test('syntax errors', () => {
var content = [
const content = [
'[ null 1.2 ]'
].join('\n');
var expected = [
const expected = [
'[',
' null 1.2',
']',
@@ -169,7 +169,7 @@ suite('JSON - formatter', () => {
});
test('empty lines', () => {
var content = [
const content = [
'{',
'"a": true,',
'',
@@ -177,7 +177,7 @@ suite('JSON - formatter', () => {
'}',
].join('\n');
var expected = [
const expected = [
'{',
'\t"a": true,',
'\t"b": true',
@@ -187,14 +187,14 @@ suite('JSON - formatter', () => {
format(content, expected, false);
});
test('single line comment', () => {
var content = [
const content = [
'[ ',
'//comment',
'"foo", "bar"',
'] '
].join('\n');
var expected = [
const expected = [
'[',
' //comment',
' "foo",',
@@ -205,14 +205,14 @@ suite('JSON - formatter', () => {
format(content, expected);
});
test('block line comment', () => {
var content = [
const content = [
'[{',
' /*comment*/ ',
'"foo" : true',
'}] '
].join('\n');
var expected = [
const expected = [
'[',
' {',
' /*comment*/',
@@ -224,13 +224,13 @@ suite('JSON - formatter', () => {
format(content, expected);
});
test('single line comment on same line', () => {
var content = [
const content = [
' { ',
' "a": {}// comment ',
' } '
].join('\n');
var expected = [
const expected = [
'{',
' "a": {} // comment ',
'}',
@@ -239,12 +239,12 @@ suite('JSON - formatter', () => {
format(content, expected);
});
test('single line comment on same line 2', () => {
var content = [
const content = [
'{ //comment',
'}'
].join('\n');
var expected = [
const expected = [
'{ //comment',
'}'
].join('\n');
@@ -252,13 +252,13 @@ suite('JSON - formatter', () => {
format(content, expected);
});
test('block comment on same line', () => {
var content = [
const content = [
'{ "a": {}, /*comment*/ ',
' /*comment*/ "b": {}, ',
' "c": {/*comment*/} } ',
].join('\n');
var expected = [
const expected = [
'{',
' "a": {}, /*comment*/',
' /*comment*/ "b": {},',
@@ -270,14 +270,14 @@ suite('JSON - formatter', () => {
});
test('block comment on same line advanced', () => {
var content = [
const content = [
' { "d": [',
' null',
' ] /*comment*/',
' ,"e": /*comment*/ [null] }',
].join('\n');
var expected = [
const expected = [
'{',
' "d": [',
' null',
@@ -292,12 +292,12 @@ suite('JSON - formatter', () => {
});
test('multiple block comments on same line', () => {
var content = [
const content = [
'{ "a": {} /*comment*/, /*comment*/ ',
' /*comment*/ "b": {} /*comment*/ } '
].join('\n');
var expected = [
const expected = [
'{',
' "a": {} /*comment*/, /*comment*/',
' /*comment*/ "b": {} /*comment*/',
@@ -307,12 +307,12 @@ suite('JSON - formatter', () => {
format(content, expected);
});
test('multiple mixed comments on same line', () => {
var content = [
const content = [
'[ /*comment*/ /*comment*/ // comment ',
']'
].join('\n');
var expected = [
const expected = [
'[ /*comment*/ /*comment*/ // comment ',
']'
].join('\n');
@@ -321,13 +321,13 @@ suite('JSON - formatter', () => {
});
test('range', () => {
var content = [
const content = [
'{ "a": {},',
'|"b": [null, null]|',
'} '
].join('\n');
var expected = [
const expected = [
'{ "a": {},',
'"b": [',
' null,',
@@ -340,14 +340,14 @@ suite('JSON - formatter', () => {
});
test('range with existing indent', () => {
var content = [
const content = [
'{ "a": {},',
' |"b": [null],',
'"c": {}',
'}|'
].join('\n');
var expected = [
const expected = [
'{ "a": {},',
' "b": [',
' null',
@@ -360,14 +360,14 @@ suite('JSON - formatter', () => {
});
test('range with existing indent - tabs', () => {
var content = [
const content = [
'{ "a": {},',
'| "b": [null], ',
'"c": {}',
'} | '
].join('\n');
var expected = [
const expected = [
'{ "a": {},',
'\t"b": [',
'\t\tnull',
@@ -381,7 +381,7 @@ suite('JSON - formatter', () => {
test('block comment none-line breaking symbols', () => {
var content = [
const content = [
'{ "a": [ 1',
'/* comment */',
', 2',
@@ -394,7 +394,7 @@ suite('JSON - formatter', () => {
'}'
].join('\n');
var expected = [
const expected = [
'{',
' "a": [',
' 1',
@@ -413,7 +413,7 @@ suite('JSON - formatter', () => {
format(content, expected);
});
test('line comment after none-line breaking symbols', () => {
var content = [
const content = [
'{ "a":',
'// comment',
'null,',
@@ -424,7 +424,7 @@ suite('JSON - formatter', () => {
'}'
].join('\n');
var expected = [
const expected = [
'{',
' "a":',
' // comment',

View File

@@ -9,13 +9,13 @@ import { OperatingSystem } from 'vs/base/common/platform';
suite('keyCodes', () => {
function testBinaryEncoding(expected: Keybinding, k: number, OS: OperatingSystem): void {
function testBinaryEncoding(expected: Keybinding | null, k: number, OS: OperatingSystem): void {
assert.deepEqual(createKeybinding(k, OS), expected);
}
test('MAC binary encoding', () => {
function test(expected: Keybinding, k: number): void {
function test(expected: Keybinding | null, k: number): void {
testBinaryEncoding(expected, k, OperatingSystem.Macintosh);
}
@@ -57,7 +57,7 @@ suite('keyCodes', () => {
[OperatingSystem.Linux, OperatingSystem.Windows].forEach((OS) => {
function test(expected: Keybinding, k: number): void {
function test(expected: Keybinding | null, k: number): void {
testBinaryEncoding(expected, k, OS);
}

View File

@@ -55,7 +55,7 @@ suite('Labels', () => {
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(['', 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']);
@@ -103,7 +103,7 @@ suite('Labels', () => {
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(['', 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']);
@@ -164,4 +164,19 @@ suite('Labels', () => {
assert.equal(labels.getBaseLabel('c:\\some\\folder\\file.txt'), 'file.txt');
assert.equal(labels.getBaseLabel('c:\\some\\folder'), 'folder');
});
test('mnemonicButtonLabel', () => {
assert.equal(labels.mnemonicButtonLabel('Hello World'), 'Hello World');
assert.equal(labels.mnemonicButtonLabel(''), '');
if (platform.isWindows) {
assert.equal(labels.mnemonicButtonLabel('Hello & World'), 'Hello && World');
assert.equal(labels.mnemonicButtonLabel('Do &&not Save & Continue'), 'Do &not Save && Continue');
} else if (platform.isMacintosh) {
assert.equal(labels.mnemonicButtonLabel('Hello & World'), 'Hello & World');
assert.equal(labels.mnemonicButtonLabel('Do &&not Save & Continue'), 'Do not Save & Continue');
} else {
assert.equal(labels.mnemonicButtonLabel('Hello & World'), 'Hello & World');
assert.equal(labels.mnemonicButtonLabel('Do &&not Save & Continue'), 'Do _not Save & Continue');
}
});
});

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { IDisposable, dispose, ReferenceCollection } from 'vs/base/common/lifecycle';
import { IDisposable, dispose, ReferenceCollection, Disposable as DisposableBase, toDisposable } from 'vs/base/common/lifecycle';
class Disposable implements IDisposable {
isDisposed = false;
@@ -49,6 +49,38 @@ suite('Lifecycle', () => {
});
});
suite('DisposableBase', () => {
test('register should not leak if object has already been disposed', () => {
let aCount = 0;
let bCount = 0;
const disposable = new class extends DisposableBase {
register(other: IDisposable) {
this._register(other);
}
};
disposable.register(toDisposable(() => ++aCount));
assert.strictEqual(aCount, 0);
assert.strictEqual(bCount, 0);
disposable.dispose();
assert.strictEqual(aCount, 1);
assert.strictEqual(bCount, 0);
// Any newly added disposables should be disposed of immediately
disposable.register(toDisposable(() => ++bCount));
assert.strictEqual(aCount, 1);
assert.strictEqual(bCount, 1);
// Further dispose calls should have no effect
disposable.dispose();
assert.strictEqual(aCount, 1);
assert.strictEqual(bCount, 1);
});
});
suite('Reference Collection', () => {
class Collection extends ReferenceCollection<number> {
private _count = 0;

View File

@@ -61,15 +61,7 @@ suite('LinkedList', function () {
list.push('far');
list.push('boo');
assert.deepEqual(
list.toArray(),
[
'foo',
'bar',
'far',
'boo',
]
);
assertElements(list, 'foo', 'bar', 'far', 'boo');
});
test('unshift/Iter', () => {
@@ -109,15 +101,26 @@ suite('LinkedList', function () {
list.unshift('bar');
list.unshift('far');
list.unshift('boo');
assertElements(list, 'boo', 'far', 'bar', 'foo');
});
test('pop/unshift', function () {
let list = new LinkedList<string>();
list.push('a');
list.push('b');
assertElements(list, 'a', 'b');
let a = list.shift();
assert.equal(a, 'a');
assertElements(list, 'b');
list.unshift('a');
assertElements(list, 'a', 'b');
let b = list.pop();
assert.equal(b, 'b');
assertElements(list, 'a');
assert.deepEqual(
list.toArray(),
[
'boo',
'far',
'bar',
'foo',
]
);
});
});

View File

@@ -140,7 +140,7 @@ suite('Map', () => {
assert.strictEqual(cache.size, 5);
assert.deepStrictEqual(cache.keys(), [3, 4, 5, 6, 7]);
let values: number[] = [];
[3, 4, 5, 6, 7].forEach(key => values.push(cache.get(key)));
[3, 4, 5, 6, 7].forEach(key => values.push(cache.get(key)!));
assert.deepStrictEqual(values, [3, 4, 5, 6, 7]);
});
@@ -155,7 +155,7 @@ suite('Map', () => {
cache.peek(4);
assert.deepStrictEqual(cache.keys(), [1, 2, 4, 5, 3]);
let values: number[] = [];
[1, 2, 3, 4, 5].forEach(key => values.push(cache.get(key)));
[1, 2, 3, 4, 5].forEach(key => values.push(cache.get(key)!));
assert.deepStrictEqual(values, [1, 2, 3, 4, 5]);
});
@@ -177,7 +177,7 @@ suite('Map', () => {
assert.deepEqual(cache.size, 15);
let values: number[] = [];
for (let i = 6; i <= 20; i++) {
values.push(cache.get(i));
values.push(cache.get(i)!);
assert.strictEqual(cache.get(i), i);
}
assert.deepStrictEqual(cache.values(), values);
@@ -194,7 +194,7 @@ suite('Map', () => {
assert.strictEqual(cache.size, 5);
assert.deepStrictEqual(cache.keys(), [7, 8, 9, 10, 11]);
let values: number[] = [];
cache.keys().forEach(key => values.push(cache.get(key)));
cache.keys().forEach(key => values.push(cache.get(key)!));
assert.deepStrictEqual(values, [7, 8, 9, 10, 11]);
assert.deepStrictEqual(cache.values(), values);
});
@@ -420,25 +420,25 @@ suite('Map', () => {
let item: IteratorResult<number>;
let iter = map.findSuperstr('/user');
item = iter.next();
item = iter!.next();
assert.equal(item.value, 2);
assert.equal(item.done, false);
item = iter.next();
item = iter!.next();
assert.equal(item.value, 1);
assert.equal(item.done, false);
item = iter.next();
item = iter!.next();
assert.equal(item.value, 3);
assert.equal(item.done, false);
item = iter.next();
item = iter!.next();
assert.equal(item.value, undefined);
assert.equal(item.done, true);
iter = map.findSuperstr('/usr');
item = iter.next();
item = iter!.next();
assert.equal(item.value, 4);
assert.equal(item.done, false);
item = iter.next();
item = iter!.next();
assert.equal(item.value, undefined);
assert.equal(item.done, true);
@@ -588,7 +588,7 @@ suite('Map', () => {
test('mapToSerializable / serializableToMap', function () {
const map = new Map<string, string>();
map.set('1', 'foo');
map.set('2', null);
map.set('2', null!);
map.set('3', 'bar');
const map2 = serializableToMap(mapToSerializable(map));

View File

@@ -20,9 +20,9 @@ suite('Marshalling', () => {
});
test('URI', () => {
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);
const value = URI.from({ scheme: 'file', authority: 'server', path: '/shares/c#files', query: 'q', fragment: 'f' });
const raw = stringify(value);
const clone = <URI>parse(raw);
assert.equal(value.scheme, clone.scheme);
assert.equal(value.authority, clone.authority);
@@ -32,7 +32,7 @@ suite('Marshalling', () => {
});
test('Bug 16793:# in folder name => mirror models get out of sync', () => {
var uri1 = URI.file('C:\\C#\\file.txt');
const uri1 = URI.file('C:\\C#\\file.txt');
assert.equal(parse(stringify(uri1)).toString(), uri1.toString());
});
});

View File

@@ -193,13 +193,13 @@ suite('Objects', () => {
three: {
3: true
},
four: void 0
four: undefined
};
diff = objects.distinct(base, obj);
assert.deepEqual(diff, {
one: null,
four: void 0
four: undefined
});
obj = {

View File

@@ -8,7 +8,7 @@ import { matchesFuzzyOcticonAware, parseOcticons } from 'vs/base/common/octicon'
export interface IOcticonFilter {
// Returns null if word doesn't match.
(query: string, target: { text: string, octiconOffsets?: number[] }): IMatch[];
(query: string, target: { text: string, octiconOffsets?: number[] }): IMatch[] | null;
}
function filterOk(filter: IOcticonFilter, word: string, target: { text: string, octiconOffsets?: number[] }, highlights?: { start: number; end: number; }[]) {

View File

@@ -8,7 +8,7 @@ import { IPager, PagedModel } from 'vs/base/common/paging';
import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation';
import { isPromiseCanceledError, canceled } from 'vs/base/common/errors';
function getPage(pageIndex: number, cancellationToken: CancellationToken): Thenable<number[]> {
function getPage(pageIndex: number, cancellationToken: CancellationToken): Promise<number[]> {
if (cancellationToken.isCancellationRequested) {
return Promise.reject(canceled());
}
@@ -21,9 +21,9 @@ class TestPager implements IPager<number> {
readonly firstPage = [0, 1, 2, 3, 4];
readonly pageSize = 5;
readonly total = 100;
readonly getPage: (pageIndex: number, cancellationToken: CancellationToken) => Thenable<number[]>;
readonly getPage: (pageIndex: number, cancellationToken: CancellationToken) => Promise<number[]>;
constructor(getPageFn?: (pageIndex: number, cancellationToken: CancellationToken) => Thenable<number[]>) {
constructor(getPageFn?: (pageIndex: number, cancellationToken: CancellationToken) => Promise<number[]>) {
this.getPage = getPageFn || getPage;
}
}

View File

@@ -8,21 +8,34 @@ import * as platform from 'vs/base/common/platform';
suite('Paths', () => {
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'), '.');
assert.equal(paths.dirname('/folder/'), '/');
if (platform.isWindows) {
assert.equal(paths.dirname('c:\\some\\file.txt'), 'c:\\some');
assert.equal(paths.dirname('c:\\some'), 'c:\\');
function assertDirname(path: string, expected: string, win = false) {
const actual = paths.dirname(path, win ? '\\' : '/');
if (actual !== expected) {
assert.fail(`${path}: expected: ${expected}, ours: ${actual}`);
}
}
test('dirname', () => {
assertDirname('foo/bar', 'foo');
assertDirname('foo\\bar', 'foo', true);
assertDirname('/foo/bar', '/foo');
assertDirname('\\foo\\bar', '\\foo', true);
assertDirname('/foo', '/');
assertDirname('\\foo', '\\', true);
assertDirname('/', '/');
assertDirname('\\', '\\', true);
assertDirname('foo', '.');
assertDirname('f', '.');
assertDirname('f/', '.');
assertDirname('/folder/', '/');
assertDirname('c:\\some\\file.txt', 'c:\\some', true);
assertDirname('c:\\some', 'c:\\', true);
assertDirname('c:\\', 'c:\\', true);
assertDirname('c:', 'c:', true);
assertDirname('\\\\server\\share\\some\\path', '\\\\server\\share\\some', true);
assertDirname('\\\\server\\share\\some', '\\\\server\\share\\', true);
assertDirname('\\\\server\\share\\', '\\\\server\\share\\', true);
});
test('normalize', () => {

View File

@@ -42,20 +42,23 @@ suite('Resources', () => {
test('dirname', () => {
if (isWindows) {
assert.equal(dirname(URI.file('c:\\some\\file\\test.txt')).toString(), 'file:///c%3A/some/file');
assert.equal(dirname(URI.file('c:\\some\\file')).toString(), 'file:///c%3A/some');
assert.equal(dirname(URI.file('c:\\some\\file\\')).toString(), 'file:///c%3A/some');
assert.equal(dirname(URI.file('c:\\some')).toString(), 'file:///c%3A/');
assert.equal(dirname(URI.file('C:\\some')).toString(), 'file:///c%3A/');
assert.equal(dirname(URI.file('c:\\some\\file\\test.txt'))!.toString(), 'file:///c%3A/some/file');
assert.equal(dirname(URI.file('c:\\some\\file'))!.toString(), 'file:///c%3A/some');
assert.equal(dirname(URI.file('c:\\some\\file\\'))!.toString(), 'file:///c%3A/some');
assert.equal(dirname(URI.file('c:\\some'))!.toString(), 'file:///c%3A/');
assert.equal(dirname(URI.file('C:\\some'))!.toString(), 'file:///c%3A/');
assert.equal(dirname(URI.file('c:\\'))!.toString(), 'file:///c%3A/');
} else {
assert.equal(dirname(URI.file('/some/file/test.txt')).toString(), 'file:///some/file');
assert.equal(dirname(URI.file('/some/file/')).toString(), 'file:///some');
assert.equal(dirname(URI.file('/some/file')).toString(), 'file:///some');
assert.equal(dirname(URI.file('/some/file/test.txt'))!.toString(), 'file:///some/file');
assert.equal(dirname(URI.file('/some/file/'))!.toString(), 'file:///some');
assert.equal(dirname(URI.file('/some/file'))!.toString(), 'file:///some');
}
assert.equal(dirname(URI.parse('foo://a/some/file/test.txt')).toString(), 'foo://a/some/file');
assert.equal(dirname(URI.parse('foo://a/some/file/')).toString(), 'foo://a/some');
assert.equal(dirname(URI.parse('foo://a/some/file')).toString(), 'foo://a/some');
assert.equal(dirname(URI.parse('foo://a/some')).toString(), 'foo://a/');
assert.equal(dirname(URI.parse('foo://a/some/file/test.txt'))!.toString(), 'foo://a/some/file');
assert.equal(dirname(URI.parse('foo://a/some/file/'))!.toString(), 'foo://a/some');
assert.equal(dirname(URI.parse('foo://a/some/file'))!.toString(), 'foo://a/some');
assert.equal(dirname(URI.parse('foo://a/some'))!.toString(), 'foo://a/');
assert.equal(dirname(URI.parse('foo://a/'))!.toString(), 'foo://a/');
assert.equal(dirname(URI.parse('foo://a'))!.toString(), 'foo://a');
// does not explode (https://github.com/Microsoft/vscode/issues/41987)
dirname(URI.from({ scheme: 'file', authority: '/users/someone/portal.h' }));
@@ -135,6 +138,7 @@ suite('Resources', () => {
assert.equal(normalizePath(URI.file('/foo/foo/../../bar')).toString(), 'file:///bar');
assert.equal(normalizePath(URI.file('/foo/foo/./../../bar')).toString(), 'file:///bar');
assert.equal(normalizePath(URI.file('/foo/foo/./../some/../bar')).toString(), 'file:///foo/bar');
assert.equal(normalizePath(URI.file('/f')).toString(), 'file:///f');
}
assert.equal(normalizePath(URI.parse('foo://a/foo/./bar')).toString(), 'foo://a/foo/bar');
assert.equal(normalizePath(URI.parse('foo://a/foo/.')).toString(), 'foo://a/foo');
@@ -145,6 +149,8 @@ suite('Resources', () => {
assert.equal(normalizePath(URI.parse('foo://a/foo/foo/../../bar')).toString(), 'foo://a/bar');
assert.equal(normalizePath(URI.parse('foo://a/foo/foo/./../../bar')).toString(), 'foo://a/bar');
assert.equal(normalizePath(URI.parse('foo://a/foo/foo/./../some/../bar')).toString(), 'foo://a/foo/bar');
assert.equal(normalizePath(URI.parse('foo://a')).toString(), 'foo://a');
assert.equal(normalizePath(URI.parse('foo://a/')).toString(), 'foo://a/');
});
test('isAbsolute', () => {
@@ -205,7 +211,7 @@ suite('Resources', () => {
assert.equal(isEqualOrParent(fileURI5, fileURI5, true), true, '16');
});
function assertMalformedFileUri(path: string, expected: string) {
function assertMalformedFileUri(path: string, expected: string | undefined) {
const old = setUriThrowOnMissingScheme(false);
const newURI = isMalformedFileUri(URI.parse(path));
assert.equal(newURI && newURI.toString(), expected);
@@ -221,10 +227,10 @@ suite('Resources', () => {
}
assertMalformedFileUri('/foo/bar', 'file:///foo/bar');
assertMalformedFileUri('file:///foo/bar', void 0);
assertMalformedFileUri('file:///c%3A/foo/bar', void 0);
assertMalformedFileUri('file://localhost/c$/devel/test', void 0);
assertMalformedFileUri('foo://dadie/foo/bar', void 0);
assertMalformedFileUri('foo:///dadie/foo/bar', void 0);
assertMalformedFileUri('file:///foo/bar', undefined);
assertMalformedFileUri('file:///c%3A/foo/bar', undefined);
assertMalformedFileUri('file://localhost/c$/devel/test', undefined);
assertMalformedFileUri('foo://dadie/foo/bar', undefined);
assertMalformedFileUri('foo:///dadie/foo/bar', undefined);
});
});

View File

@@ -320,7 +320,7 @@ suite('Strings', () => {
});
test('fuzzyContains', () => {
assert.ok(!strings.fuzzyContains(void 0, null));
assert.ok(!strings.fuzzyContains((undefined)!, null!));
assert.ok(strings.fuzzyContains('hello world', 'h'));
assert.ok(!strings.fuzzyContains('hello world', 'q'));
assert.ok(strings.fuzzyContains('hello world', 'hw'));

View File

@@ -73,15 +73,15 @@ suite('URI', () => {
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({ 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');
const 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());
const uri2 = URI.parse(value.toString(true));
const uri3 = URI.parse(value.toString());
assert.equal(uri2.authority, uri3.authority);
assert.equal(uri2.path, uri3.path);
assert.equal(uri2.query, uri3.query);
@@ -91,9 +91,9 @@ suite('URI', () => {
test('with, identity', () => {
let uri = URI.parse('foo:bar/path');
let uri2 = uri.with(null);
let uri2 = uri.with(null!);
assert.ok(uri === uri2);
uri2 = uri.with(undefined);
uri2 = uri.with(undefined!);
assert.ok(uri === uri2);
uri2 = uri.with({});
assert.ok(uri === uri2);
@@ -130,7 +130,7 @@ suite('URI', () => {
});
test('parse', () => {
var value = URI.parse('http:/api/files/test.me?t=1234');
let 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');
@@ -238,7 +238,7 @@ suite('URI', () => {
test('URI#file, win-speciale', () => {
if (isWindows) {
var value = URI.file('c:\\test\\drive');
let value = URI.file('c:\\test\\drive');
assert.equal(value.path, '/c:/test/drive');
assert.equal(value.toString(), 'file:///c%3A/test/drive');
@@ -298,7 +298,7 @@ suite('URI', () => {
test('URI#file, always slash', () => {
var value = URI.file('a.file');
let value = URI.file('a.file');
assert.equal(value.scheme, 'file');
assert.equal(value.authority, '');
assert.equal(value.path, '/a.file');
@@ -312,12 +312,12 @@ suite('URI', () => {
});
test('URI.toString, only scheme and query', () => {
var value = URI.parse('stuff:?qüery');
const 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');
const value = URI.parse('file://sh%c3%a4res/path');
assert.equal(value.toString(), 'file://sh%C3%A4res/path');
});
@@ -328,12 +328,12 @@ suite('URI', () => {
test('URI#toString, escape all the bits', () => {
var value = URI.file('/Users/jrieken/Code/_samples/18500/Mödel + Other Thîngß/model.js');
const 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');
let 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 });
@@ -341,7 +341,7 @@ suite('URI', () => {
});
test('URI#toString, user information in authority', () => {
var value = URI.parse('http://foo:bar@localhost/far');
let value = URI.parse('http://foo:bar@localhost/far');
assert.equal(value.toString(), 'http://foo:bar@localhost/far');
value = URI.parse('http://foo@localhost/far');
@@ -359,11 +359,11 @@ suite('URI', () => {
test('correctFileUriToFilePath2', () => {
var test = (input: string, expected: string) => {
const test = (input: string, expected: string) => {
expected = normalize(expected, true);
var value = URI.parse(input);
const value = URI.parse(input);
assert.equal(value.fsPath, expected, 'Result for ' + input);
var value2 = URI.file(value.fsPath);
const value2 = URI.file(value.fsPath);
assert.equal(value2.fsPath, expected, 'Result for ' + input);
assert.equal(value.toString(), value2.toString());
};
@@ -431,7 +431,7 @@ suite('URI', () => {
test('URI - (de)serialize', function () {
var values = [
const values = [
URI.parse('http://localhost:8080/far'),
URI.file('c:\\test with %25\\c#code'),
URI.file('\\\\shäres\\path\\c#\\plugin.json'),

View File

@@ -7,7 +7,7 @@ import * as paths from 'vs/base/common/paths';
import { URI } from 'vs/base/common/uri';
import { canceled } from 'vs/base/common/errors';
export type ValueCallback<T = any> = (value: T | Thenable<T>) => void;
export type ValueCallback<T = any> = (value: T | Promise<T>) => void;
export class DeferredPromise<T> {

View File

@@ -7,16 +7,16 @@ import * as uuid from 'vs/base/common/uuid';
suite('UUID', () => {
test('generation', () => {
var asHex = uuid.v4().asHex();
const asHex = uuid.v4().asHex();
assert.equal(asHex.length, 36);
assert.equal(asHex[14], '4');
assert.ok(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);
const id = uuid.v4();
const asHext = id.asHex();
const id2 = uuid.parse(asHext);
assert.equal(id.asHex(), id2.asHex());
});
});

View File

@@ -1,183 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { Promise as WinJSPromise } from 'vs/base/common/winjs.base';
import { PolyfillPromise } from 'vs/base/common/winjs.polyfill.promise';
suite('Polyfill Promise', function () {
test('sync-resolve, NativePromise', function () {
// native promise behaviour
const actual: string[] = [];
const promise = new Promise(resolve => {
actual.push('inCtor');
resolve(null);
}).then(() => actual.push('inThen'));
actual.push('afterCtor');
return promise.then(() => {
assert.deepEqual(actual, ['inCtor', 'afterCtor', 'inThen']);
});
});
test('sync-resolve, WinJSPromise', function () {
// winjs promise behaviour
const actual: string[] = [];
const promise = new WinJSPromise(resolve => {
actual.push('inCtor');
resolve(null);
}).then(() => actual.push('inThen'));
actual.push('afterCtor');
return promise.then(() => {
assert.deepEqual(actual, ['inCtor', 'inThen', 'afterCtor']);
});
});
test('sync-resolve, PolyfillPromise', function () {
// winjs promise behaviour
const actual: string[] = [];
const promise = new PolyfillPromise(resolve => {
actual.push('inCtor');
resolve(null);
}).then(() => actual.push('inThen'));
actual.push('afterCtor');
return promise.then(() => {
assert.deepEqual(actual, ['inCtor', 'afterCtor', 'inThen']);
});
});
test('sync-then, NativePromise', function () {
const actual: string[] = [];
const promise = Promise.resolve(123).then(() => actual.push('inThen'));
actual.push('afterThen');
return promise.then(() => {
assert.deepEqual(actual, ['afterThen', 'inThen']);
});
});
test('sync-then, WinJSPromise', function () {
const actual: string[] = [];
const promise = WinJSPromise.as(123).then(() => actual.push('inThen'));
actual.push('afterThen');
return promise.then(() => {
assert.deepEqual(actual, ['inThen', 'afterThen']);
});
});
test('sync-then, PolyfillPromise', function () {
const actual: string[] = [];
const promise = PolyfillPromise.resolve(123).then(() => actual.push('inThen'));
actual.push('afterThen');
return promise.then(() => {
assert.deepEqual(actual, ['afterThen', 'inThen']);
});
});
test('PolyfillPromise, executor has two params', function () {
return new PolyfillPromise(function () {
assert.equal(arguments.length, 2);
assert.equal(typeof arguments[0], 'function');
assert.equal(typeof arguments[1], 'function');
arguments[0]();
});
});
test('Promises polyfill does not support chaining then and catch #57722', function () {
return PolyfillPromise.resolve(1).then(function (x) { return x + 1; }).then(function (x) {
assert.equal(x, 2);
});
});
// run the same tests for the native and polyfill promise
(<any[]>[Promise, PolyfillPromise]).forEach(PromiseCtor => {
test(PromiseCtor.name + ', resolved value', function () {
return new PromiseCtor((resolve: Function) => resolve(1)).then((value: number) => assert.equal(value, 1));
});
test(PromiseCtor.name + ', rejected value', function () {
return new PromiseCtor((_: Function, reject: Function) => reject(1)).then(null, (value: number) => assert.equal(value, 1));
});
test(PromiseCtor.name + ', catch', function () {
return new PromiseCtor((_: Function, reject: Function) => reject(1)).catch((value: number) => assert.equal(value, 1));
});
test(PromiseCtor.name + ', static-resolve', function () {
return PromiseCtor.resolve(42).then((value: number) => assert.equal(value, 42));
});
test(PromiseCtor.name + ', static-reject', function () {
return PromiseCtor.reject(42).then(null, (value: number) => assert.equal(value, 42));
});
test(PromiseCtor.name + ', static-all, 1', function () {
return PromiseCtor.all([
PromiseCtor.resolve(1),
PromiseCtor.resolve(2)
]).then((values: number[]) => {
assert.deepEqual(values, [1, 2]);
});
});
test(PromiseCtor.name + ', static-all, 2', function () {
return PromiseCtor.all([
PromiseCtor.resolve(1),
3,
PromiseCtor.resolve(2)
]).then((values: number[]) => {
assert.deepEqual(values, [1, 3, 2]);
});
});
test(PromiseCtor.name + ', static-all, 3', function () {
return PromiseCtor.all([
PromiseCtor.resolve(1),
PromiseCtor.reject(13),
PromiseCtor.reject(12),
]).catch((values: number) => {
assert.deepEqual(values, 13);
});
});
test(PromiseCtor.name + ', static-race, 1', function () {
return PromiseCtor.race([
PromiseCtor.resolve(1),
PromiseCtor.resolve(2),
]).then((value: number) => {
assert.deepEqual(value, 1);
});
});
test(PromiseCtor.name + ', static-race, 2', function () {
return PromiseCtor.race([
PromiseCtor.reject(-1),
PromiseCtor.resolve(2),
]).catch((value: number) => {
assert.deepEqual(value, -1);
});
});
test(PromiseCtor.name + ', static-race, 3', function () {
return PromiseCtor.race([
PromiseCtor.resolve(1),
PromiseCtor.reject(2),
]).then((value: number) => {
assert.deepEqual(value, 1);
});
});
test(PromiseCtor.name + ', throw in ctor', function () {
return new PromiseCtor(() => {
throw new Error('sooo bad');
}).catch((err: Error) => {
assert.equal(err.message, 'sooo bad');
});
});
});
});

View File

@@ -1,68 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import * as winjs from 'vs/base/common/winjs.base';
suite('WinJS and ES6 Promises', function () {
test('Promise.resolve', () => {
let resolveTPromise;
const tPromise = new winjs.Promise((c, e) => {
resolveTPromise = c;
});
const es6Promise = Promise.resolve(tPromise);
const done = es6Promise.then(function (result) {
assert.equal(result, 'passed');
});
resolveTPromise('passed');
return done;
});
test('new Promise', function () {
let resolveTPromise;
const tPromise = new winjs.Promise((c, e) => {
resolveTPromise = c;
});
const es6Promise = new Promise(function (c, e) {
c(tPromise);
});
const done = es6Promise.then(function (result) {
assert.equal(result, 'passed');
});
resolveTPromise('passed');
return done;
});
test('1. Uncaught TypeError: this._state.then is not a function', () => {
let p1 = winjs.Promise.wrap<number>(new Promise<number>(function (c, e) { c(1); }));
Promise.all([p1]);
});
test('2. Uncaught TypeError: this._state.then is not a function', () => {
let p1 = winjs.Promise.wrap<number>(new Promise<number>(function (c, e) { c(1); }));
let thenFunc = p1.then.bind(p1);
setTimeout(() => {
thenFunc(() => { });
}, 0);
});
test('3. Uncaught TypeError: this._state.then is not a function', () => {
let c;
let p1 = new winjs.Promise(function (_c, e) { c = _c; });
let thenFunc = p1.then.bind(p1);
setTimeout(() => {
c(1);
thenFunc(() => { });
}, 0);
});
});

View File

@@ -141,7 +141,7 @@ suite('Config', () => {
testFile('config', 'config.json').then(res => {
fs.writeFileSync(res.testFile, '// my comment\n{ "foo": "bar" }');
let watcher = new ConfigWatcher<{ foo: string; }>(res.testFile, { changeBufferDelay: 100, onError: console.error, defaultConfig: void 0 });
let watcher = new ConfigWatcher<{ foo: string; }>(res.testFile, { changeBufferDelay: 100, onError: console.error, defaultConfig: { foo: 'bar' } });
watcher.getConfig(); // ensure we are in sync
fs.writeFileSync(res.testFile, '// my comment\n{ "foo": "changed" }');

View File

@@ -11,39 +11,38 @@ suite('Console', () => {
test('getFirstFrame', () => {
let stack = 'at vscode.commands.registerCommand (/Users/someone/Desktop/test-ts/out/src/extension.js:18:17)';
let frame = getFirstFrame(stack);
let frame = getFirstFrame(stack)!;
assert.equal(frame.uri.fsPath, normalize('/Users/someone/Desktop/test-ts/out/src/extension.js'));
assert.equal(frame.line, 18);
assert.equal(frame.column, 17);
stack = 'at /Users/someone/Desktop/test-ts/out/src/extension.js:18:17';
frame = getFirstFrame(stack);
frame = getFirstFrame(stack)!;
assert.equal(frame.uri.fsPath, normalize('/Users/someone/Desktop/test-ts/out/src/extension.js'));
assert.equal(frame.line, 18);
assert.equal(frame.column, 17);
stack = 'at c:\\Users\\someone\\Desktop\\end-js\\extension.js:18:17';
frame = getFirstFrame(stack);
frame = getFirstFrame(stack)!;
assert.equal(frame.uri.fsPath, 'c:\\Users\\someone\\Desktop\\end-js\\extension.js');
assert.equal(frame.line, 18);
assert.equal(frame.column, 17);
stack = 'at e.$executeContributedCommand(c:\\Users\\someone\\Desktop\\end-js\\extension.js:18:17)';
frame = getFirstFrame(stack);
frame = getFirstFrame(stack)!;
assert.equal(frame.uri.fsPath, 'c:\\Users\\someone\\Desktop\\end-js\\extension.js');
assert.equal(frame.line, 18);
assert.equal(frame.column, 17);
stack = 'at /Users/someone/Desktop/test-ts/out/src/extension.js:18:17\nat /Users/someone/Desktop/test-ts/out/src/other.js:28:27\nat /Users/someone/Desktop/test-ts/out/src/more.js:38:37';
frame = getFirstFrame(stack);
frame = getFirstFrame(stack)!;
assert.equal(frame.uri.fsPath, normalize('/Users/someone/Desktop/test-ts/out/src/extension.js'));
assert.equal(frame.line, 18);
assert.equal(frame.column, 17);
});
});

View File

@@ -38,7 +38,7 @@ function toReadable(value: string, throwError?: boolean): Readable {
this.emit('error', new Error(readError));
}
let res: string;
let res!: string;
let canPush = true;
while (canPush && (res = stringChunks[counter++])) {
canPush = this.push(res);
@@ -96,14 +96,14 @@ suite('Extfs', () => {
return done(error);
}
assert.ok(!statAndIsLink.isSymbolicLink);
assert.ok(!statAndIsLink!.isSymbolicLink);
extfs.statLink(symbolicLink, (error, statAndIsLink) => {
if (error) {
return done(error);
}
assert.ok(statAndIsLink.isSymbolicLink);
assert.ok(statAndIsLink!.isSymbolicLink);
extfs.delSync(directory);
done();
});
@@ -258,7 +258,7 @@ suite('Extfs', () => {
assert.ok(fs.existsSync(newDir));
extfs.writeFileAndFlush(testFile, 'Hello World', null, error => {
extfs.writeFileAndFlush(testFile, 'Hello World', null!, error => {
if (error) {
return done(error);
}
@@ -267,7 +267,7 @@ suite('Extfs', () => {
const largeString = (new Array(100 * 1024)).join('Large String\n');
extfs.writeFileAndFlush(testFile, largeString, null, error => {
extfs.writeFileAndFlush(testFile, largeString, null!, error => {
if (error) {
return done(error);
}
@@ -293,7 +293,7 @@ suite('Extfs', () => {
assert.ok(fs.existsSync(newDir));
extfs.writeFileAndFlush(testFile, toReadable('Hello World'), null, error => {
extfs.writeFileAndFlush(testFile, toReadable('Hello World'), null!, error => {
if (error) {
return done(error);
}
@@ -302,7 +302,7 @@ suite('Extfs', () => {
const largeString = (new Array(100 * 1024)).join('Large String\n');
extfs.writeFileAndFlush(testFile, toReadable(largeString), null, error => {
extfs.writeFileAndFlush(testFile, toReadable(largeString), null!, error => {
if (error) {
return done(error);
}
@@ -329,7 +329,7 @@ suite('Extfs', () => {
assert.ok(fs.existsSync(newDir));
extfs.writeFileAndFlush(testFile, fs.createReadStream(sourceFile), null, error => {
extfs.writeFileAndFlush(testFile, fs.createReadStream(sourceFile), null!, error => {
if (error) {
return done(error);
}
@@ -356,7 +356,7 @@ suite('Extfs', () => {
fs.mkdirSync(testFile); // this will trigger an error because testFile is now a directory!
extfs.writeFileAndFlush(testFile, 'Hello World', null, error => {
extfs.writeFileAndFlush(testFile, 'Hello World', null!, error => {
if (!error) {
return done(new Error('Expected error for writing to readonly file'));
}
@@ -382,7 +382,7 @@ suite('Extfs', () => {
fs.mkdirSync(testFile); // this will trigger an error because testFile is now a directory!
const readable = toReadable('Hello World');
extfs.writeFileAndFlush(testFile, readable, null, error => {
extfs.writeFileAndFlush(testFile, readable, null!, error => {
if (!error || (<any>error).code !== 'EISDIR') {
return done(new Error('Expected EISDIR error for writing to folder but got: ' + (error ? (<any>error).code : 'no error')));
}
@@ -408,7 +408,7 @@ suite('Extfs', () => {
assert.ok(fs.existsSync(newDir));
extfs.writeFileAndFlush(testFile, toReadable('Hello World', true /* throw error */), null, error => {
extfs.writeFileAndFlush(testFile, toReadable('Hello World', true /* throw error */), null!, error => {
if (!error || error.message !== readError) {
return done(new Error('Expected error for writing to folder'));
}
@@ -438,7 +438,7 @@ suite('Extfs', () => {
fs.writeFileSync(testFile, '');
fs.chmodSync(testFile, 33060); // make readonly
extfs.writeFileAndFlush(testFile, toReadable('Hello World'), null, error => {
extfs.writeFileAndFlush(testFile, toReadable('Hello World'), null!, error => {
if (!error || !((<any>error).code !== 'EACCES' || (<any>error).code !== 'EPERM')) {
return done(new Error('Expected EACCES/EPERM error for writing to folder but got: ' + (error ? (<any>error).code : 'no error')));
}
@@ -464,7 +464,7 @@ suite('Extfs', () => {
fs.mkdirSync(testFile); // this will trigger an error because testFile is now a directory!
extfs.writeFileAndFlush(testFile, fs.createReadStream(sourceFile), null, error => {
extfs.writeFileAndFlush(testFile, fs.createReadStream(sourceFile), null!, error => {
if (!error) {
return done(new Error('Expected error for writing to folder'));
}
@@ -487,12 +487,12 @@ suite('Extfs', () => {
assert.ok(fs.existsSync(newDir));
extfs.writeFileAndFlushSync(testFile, 'Hello World', null);
extfs.writeFileAndFlushSync(testFile, 'Hello World', null!);
assert.equal(fs.readFileSync(testFile), 'Hello World');
const largeString = (new Array(100 * 1024)).join('Large String\n');
extfs.writeFileAndFlushSync(testFile, largeString, null);
extfs.writeFileAndFlushSync(testFile, largeString, null!);
assert.equal(fs.readFileSync(testFile), largeString);
extfs.del(parentDir, os.tmpdir(), done, ignore);
@@ -551,13 +551,13 @@ suite('Extfs', () => {
const newDir = path.join(parentDir, 'extfs', id);
mkdirp(newDir, 493, error => {
let realpath: string;
let realpath!: string;
try {
realpath = extfs.realpathSync(newDir);
} catch (error) {
assert.ok(!error);
}
assert.ok(realpath);
assert.ok(realpath!);
extfs.del(parentDir, os.tmpdir(), done, ignore);
});

View File

@@ -8,8 +8,8 @@ var Workforce;
return Company;
})();
(function (property, Workforce, IEmployee) {
if (property === void 0) { property = employees; }
if (IEmployee === void 0) { IEmployee = []; }
if (property === undefined) { property = employees; }
if (IEmployee === undefined) { IEmployee = []; }
property;
calculateMonthlyExpenses();
{

View File

@@ -7,9 +7,9 @@ var Conway;
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; }
if (property === undefined) { property = row; }
if (property === undefined) { property = col; }
if (property === undefined) { property = live; }
});
var GameOfLife = (function () {
function GameOfLife() {

View File

@@ -7,10 +7,10 @@ var M;
return C;
})();
(function (x, property, number) {
if (property === void 0) { property = w; }
if (property === undefined) { property = w; }
var local = 1;
// unresolved symbol because x is local
//self.x++;
//self.x++;
self.w--; // ok because w is a property
property;
f = function (y) {

View File

@@ -430,7 +430,7 @@ suite('Flow', () => {
parallel(elements, function (element, callback) {
sum += element;
callback(null, element * element);
callback(null!, element * element);
}, function (errors, result) {
assert.ok(!errors);
@@ -449,7 +449,7 @@ suite('Flow', () => {
parallel(elements, function (element, callback) {
setTimeout(function () {
sum += element;
callback(null, element * element);
callback(null!, element * element);
}, timeouts.pop());
}, function (errors, result) {
assert.ok(!errors);
@@ -469,10 +469,10 @@ suite('Flow', () => {
parallel(elements, function (element, callback) {
setTimeout(function () {
if (element === 4) {
callback(new Error('error!'), null);
callback(new Error('error!'), null!);
} else {
sum += element;
callback(null, element * element);
callback(null!, element * element);
}
}, timeouts.pop());
}, function (errors, result) {

View File

@@ -738,24 +738,24 @@ suite('Glob', () => {
});
test('falsy expression/pattern', function () {
assert.strictEqual(glob.match(null, 'foo'), false);
assert.strictEqual(glob.match(null!, 'foo'), false);
assert.strictEqual(glob.match('', 'foo'), false);
assert.strictEqual(glob.parse(null)('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')(null!), false);
assert.strictEqual(glob.parse('foo')(''), false);
assert.strictEqual(glob.parse('**/*.j?')(null), 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')(null!), false);
assert.strictEqual(glob.parse('**/*.foo')(''), false);
assert.strictEqual(glob.parse('**/foo')(null), 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}')(null!), false);
assert.strictEqual(glob.parse('{**/baz,**/foo}')(''), false);
assert.strictEqual(glob.parse('{**/*.baz,**/*.foo}')(null), false);
assert.strictEqual(glob.parse('{**/*.baz,**/*.foo}')(null!), false);
assert.strictEqual(glob.parse('{**/*.baz,**/*.foo}')(''), false);
});
@@ -808,7 +808,7 @@ suite('Glob', () => {
}, ['foo', 'bar', 'baz'], [
['bar/foo', '**/foo/**'],
['foo/bar', '{**/bar/**,**/baz/**}'],
['bar/nope', null]
['bar/nope', null!]
]);
const siblings = ['baz', 'baz.zip', 'nope'];
@@ -817,12 +817,12 @@ suite('Glob', () => {
'**/foo/**': { when: '$(basename).zip' },
'**/bar/**': true
}, ['bar'], [
['bar/foo', null],
['bar/foo/baz', null],
['bar/foo/nope', null],
['bar/foo', null!],
['bar/foo/baz', null!],
['bar/foo/nope', null!],
['foo/bar', '**/bar/**'],
], [
null,
null!,
hasSibling,
hasSibling
]);
@@ -832,7 +832,7 @@ suite('Glob', () => {
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);
assert.strictEqual(parsed(text, null!, siblingsFns[i]), result);
});
}
@@ -914,7 +914,7 @@ suite('Glob', () => {
[nativeSep('bar/foo/bar'), '**/foo/bar/**'],
// Not supported
// [nativeSep('foo/bar/bar'), '{**/bar/bar/**,**/baz/bar/**}'],
[nativeSep('/foo/bar/nope'), null]
[nativeSep('/foo/bar/nope'), null!]
]);
const siblings = ['baz', 'baz.zip', 'nope'];
@@ -923,12 +923,12 @@ suite('Glob', () => {
'**/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('bar/foo/123'), null!],
[nativeSep('bar/foo/123/baz'), null!],
[nativeSep('bar/foo/123/nope'), null!],
[nativeSep('foo/bar/123'), '**/bar/123/**'],
], [
null,
null!,
hasSibling,
hasSibling
]);
@@ -938,7 +938,7 @@ suite('Glob', () => {
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);
assert.strictEqual(parsed(text, null!, siblingsFns[i]), result);
});
}

View File

@@ -24,7 +24,7 @@ suite('PFS', () => {
return pfs.mkdirp(newDir, 493).then(() => {
assert.ok(fs.existsSync(newDir));
return pfs.writeFile(testFile, 'Hello World', null).then(() => {
return pfs.writeFile(testFile, 'Hello World', null!).then(() => {
assert.equal(fs.readFileSync(testFile), 'Hello World');
return pfs.del(parentDir, os.tmpdir());
@@ -46,11 +46,11 @@ suite('PFS', () => {
assert.ok(fs.existsSync(newDir));
return Promise.all([
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)
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!)
]).then(() => {
assert.equal(fs.readFileSync(testFile1), 'Hello World 1');
assert.equal(fs.readFileSync(testFile2), 'Hello World 2');
@@ -73,11 +73,11 @@ suite('PFS', () => {
assert.ok(fs.existsSync(newDir));
return Promise.all([
pfs.writeFile(testFile, 'Hello World 1', null),
pfs.writeFile(testFile, 'Hello World 2', null),
timeout(10).then(() => pfs.writeFile(testFile, 'Hello World 3', null)),
pfs.writeFile(testFile, 'Hello World 4', null),
timeout(10).then(() => pfs.writeFile(testFile, 'Hello World 5', null))
pfs.writeFile(testFile, 'Hello World 1', undefined),
pfs.writeFile(testFile, 'Hello World 2', undefined),
timeout(10).then(() => pfs.writeFile(testFile, 'Hello World 3', undefined)),
pfs.writeFile(testFile, 'Hello World 4', undefined),
timeout(10).then(() => pfs.writeFile(testFile, 'Hello World 5', undefined))
]).then(() => {
assert.equal(fs.readFileSync(testFile), 'Hello World 5');
@@ -119,23 +119,6 @@ suite('PFS', () => {
});
});
test('unlinkIgnoreError', function () {
const id = uuid.generateUuid();
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
const newDir = path.join(parentDir, 'extfs', id);
return pfs.mkdirp(newDir, 493).then(() => {
return pfs.unlinkIgnoreError(path.join(newDir, 'foo')).then(() => {
return pfs.del(parentDir, os.tmpdir());
}, error => {
assert.fail(error);
return Promise.reject(error);
});
});
});
test('moveIgnoreError', function () {
const id = uuid.generateUuid();
const parentDir = path.join(os.tmpdir(), 'vsctests', id);

View File

@@ -21,7 +21,7 @@ suite('Ports', () => {
// create a server to block this port
const server = net.createServer();
server.listen(initialPort, null, null, () => {
server.listen(initialPort, undefined, undefined, () => {
// once listening, find another free port and assert that the port is different from the opened one
ports.findFreePort(7000, 50, 300000).then(freePort => {

View File

@@ -84,4 +84,29 @@ suite('Processes', () => {
}
});
});
test('sanitizeProcessEnvironment', () => {
let env = {
FOO: 'bar',
ELECTRON_ENABLE_STACK_DUMPING: 'x',
ELECTRON_ENABLE_LOGGING: 'x',
ELECTRON_NO_ASAR: 'x',
ELECTRON_NO_ATTACH_CONSOLE: 'x',
ELECTRON_RUN_AS_NODE: 'x',
GOOGLE_API_KEY: 'x',
VSCODE_CLI: 'x',
VSCODE_DEV: 'x',
VSCODE_IPC_HOOK: 'x',
VSCODE_LOGS: 'x',
VSCODE_NLS_CONFIG: 'x',
VSCODE_PORTABLE: 'x',
VSCODE_PID: 'x',
VSCODE_NODE_CACHED_DATA_DIR: 'x',
VSCODE_NEW_VAR: 'x'
};
processes.sanitizeProcessEnvironment(env);
assert.equal(env['FOO'], 'bar');
assert.equal(Object.keys(env).length, 1);
});
});

View File

@@ -8,9 +8,10 @@ import { generateUuid } from 'vs/base/common/uuid';
import { join } from 'path';
import { tmpdir } from 'os';
import { equal, ok } from 'assert';
import { mkdirp, del, writeFile } from 'vs/base/node/pfs';
import { mkdirp, del, writeFile, exists, unlink } from 'vs/base/node/pfs';
import { timeout } from 'vs/base/common/async';
import { Event, Emitter } from 'vs/base/common/event';
import { isWindows } from 'vs/base/common/platform';
suite('Storage Library', () => {
@@ -90,7 +91,6 @@ suite('Storage Library', () => {
await Promise.all([delete1Promise, delete2Promise, delete3Promise]).then(() => deletePromiseResolved = true);
equal(deletePromiseResolved, true);
storage.beforeClose();
await storage.close();
await del(storageDir, tmpdir());
});
@@ -100,7 +100,7 @@ suite('Storage Library', () => {
await mkdirp(storageDir);
class TestSQLiteStorageDatabase extends SQLiteStorageDatabase {
private _onDidChangeItemsExternal: Emitter<IStorageItemsChangeEvent> = new Emitter<IStorageItemsChangeEvent>();
private _onDidChangeItemsExternal = new Emitter<IStorageItemsChangeEvent>();
get onDidChangeItemsExternal(): Event<IStorageItemsChangeEvent> { return this._onDidChangeItemsExternal.event; }
fireDidChangeItemsExternal(event: IStorageItemsChangeEvent): void {
@@ -136,18 +136,17 @@ suite('Storage Library', () => {
changes.clear();
// Delete is accepted
change.set('foo', null);
change.set('foo', undefined);
database.fireDidChangeItemsExternal({ items: change });
ok(changes.has('foo'));
equal(storage.get('foo', null), null);
equal(storage.get('foo', null!), null);
changes.clear();
// Nothing happens if changing to same value
change.set('foo', null);
change.set('foo', undefined);
database.fireDidChangeItemsExternal({ items: change });
equal(changes.size, 0);
storage.beforeClose();
await storage.close();
await del(storageDir, tmpdir());
});
@@ -168,7 +167,6 @@ suite('Storage Library', () => {
let setPromiseResolved = false;
Promise.all([set1Promise, set2Promise]).then(() => setPromiseResolved = true);
storage.beforeClose();
await storage.close();
equal(setPromiseResolved, true);
@@ -179,7 +177,6 @@ suite('Storage Library', () => {
equal(storage.get('foo'), 'bar');
equal(storage.get('bar'), 'foo');
storage.beforeClose();
await storage.close();
storage = new Storage(new SQLiteStorageDatabase(join(storageDir, 'storage.db')));
@@ -194,7 +191,6 @@ suite('Storage Library', () => {
let deletePromiseResolved = false;
Promise.all([delete1Promise, delete2Promise]).then(() => deletePromiseResolved = true);
storage.beforeClose();
await storage.close();
equal(deletePromiseResolved, true);
@@ -205,7 +201,6 @@ suite('Storage Library', () => {
ok(!storage.get('foo'));
ok(!storage.get('bar'));
storage.beforeClose();
await storage.close();
await del(storageDir, tmpdir());
});
@@ -248,7 +243,36 @@ suite('Storage Library', () => {
await Promise.all([set4Promise, delete1Promise]).then(() => setAndDeletePromiseResolved = true);
ok(setAndDeletePromiseResolved);
storage.beforeClose();
await storage.close();
await del(storageDir, tmpdir());
});
test('corrupt DB recovers', async () => {
const storageDir = uniqueStorageDir();
await mkdirp(storageDir);
const storageFile = join(storageDir, 'storage.db');
let storage = new Storage(new SQLiteStorageDatabase(storageFile));
await storage.init();
await storage.set('bar', 'foo');
await writeFile(storageFile, 'This is a broken DB');
await storage.set('foo', 'bar');
equal(storage.get('bar'), 'foo');
equal(storage.get('foo'), 'bar');
await storage.close();
storage = new Storage(new SQLiteStorageDatabase(storageFile));
await storage.init();
equal(storage.get('bar'), 'foo');
equal(storage.get('foo'), 'bar');
await storage.close();
await del(storageDir, tmpdir());
});
@@ -270,7 +294,7 @@ suite('SQLite Storage Library', () => {
}
async function testDBBasics(path, logError?: (error) => void) {
let options: ISQLiteStorageDatabaseOptions;
let options!: ISQLiteStorageDatabaseOptions;
if (logError) {
options = {
logging: {
@@ -331,7 +355,14 @@ suite('SQLite Storage Library', () => {
storedItems = await storage.getItems();
equal(storedItems.size, 0);
await storage.close();
let recoveryCalled = false;
await storage.close(() => {
recoveryCalled = true;
return new Map();
});
equal(recoveryCalled, false);
}
test('basics', async () => {
@@ -339,7 +370,7 @@ suite('SQLite Storage Library', () => {
await mkdirp(storageDir);
testDBBasics(join(storageDir, 'storage.db'));
await testDBBasics(join(storageDir, 'storage.db'));
await del(storageDir, tmpdir());
});
@@ -399,7 +430,14 @@ suite('SQLite Storage Library', () => {
equal(storedItems.get('some/foo/path'), 'some/bar/path');
equal(storedItems.get(JSON.stringify({ foo: 'bar' })), JSON.stringify({ bar: 'foo' }));
await storage.close();
let recoveryCalled = false;
await storage.close(() => {
recoveryCalled = true;
return new Map();
});
equal(recoveryCalled, false);
await del(storageDir, tmpdir());
});
@@ -433,6 +471,74 @@ suite('SQLite Storage Library', () => {
await del(storageDir, tmpdir());
});
test('basics (DB that becomes corrupt during runtime stores all state from cache on close)', async () => {
if (isWindows) {
await Promise.resolve(); // Windows will fail to write to open DB due to locking
return;
}
const storageDir = uniqueStorageDir();
await mkdirp(storageDir);
const storagePath = join(storageDir, 'storage.db');
let storage = new SQLiteStorageDatabase(storagePath);
const items = new Map<string, string>();
items.set('foo', 'bar');
items.set('some/foo/path', 'some/bar/path');
items.set(JSON.stringify({ foo: 'bar' }), JSON.stringify({ bar: 'foo' }));
await storage.updateItems({ insert: items });
await storage.close();
const backupPath = `${storagePath}.backup`;
equal(await exists(backupPath), true);
storage = new SQLiteStorageDatabase(storagePath);
await storage.getItems();
await writeFile(storagePath, 'This is now a broken DB');
// we still need to trigger a check to the DB so that we get to know that
// the DB is corrupt. We have no extra code on shutdown that checks for the
// health of the DB. This is an optimization to not perform too many tasks
// on shutdown.
await storage.checkIntegrity(true).then(null, error => { } /* error is expected here but we do not want to fail */);
await unlink(backupPath); // also test that the recovery DB is backed up properly
let recoveryCalled = false;
await storage.close(() => {
recoveryCalled = true;
return items;
});
equal(recoveryCalled, true);
equal(await exists(backupPath), true);
storage = new SQLiteStorageDatabase(storagePath);
const storedItems = await storage.getItems();
equal(storedItems.size, items.size);
equal(storedItems.get('foo'), 'bar');
equal(storedItems.get('some/foo/path'), 'some/bar/path');
equal(storedItems.get(JSON.stringify({ foo: 'bar' })), JSON.stringify({ bar: 'foo' }));
recoveryCalled = false;
await storage.close(() => {
recoveryCalled = true;
return new Map();
});
equal(recoveryCalled, false);
await del(storageDir, tmpdir());
});
test('real world example', async () => {
const storageDir = uniqueStorageDir();
@@ -627,7 +733,70 @@ suite('SQLite Storage Library', () => {
equal(items.get('foo3'), 'bar');
equal(items.get('some/foo3/path'), 'some/bar/path');
storage.beforeClose();
await storage.close();
await del(storageDir, tmpdir());
});
test('lots of INSERT & DELETE (below inline max)', async () => {
const storageDir = uniqueStorageDir();
await mkdirp(storageDir);
const storage = new SQLiteStorageDatabase(join(storageDir, 'storage.db'));
const items = new Map<string, string>();
const keys: Set<string> = new Set<string>();
for (let i = 0; i < 200; i++) {
const uuid = generateUuid();
const key = `key: ${uuid}`;
items.set(key, `value: ${uuid}`);
keys.add(key);
}
await storage.updateItems({ insert: items });
let storedItems = await storage.getItems();
equal(storedItems.size, items.size);
await storage.updateItems({ delete: keys });
storedItems = await storage.getItems();
equal(storedItems.size, 0);
await storage.close();
await del(storageDir, tmpdir());
});
test('lots of INSERT & DELETE (above inline max)', async () => {
const storageDir = uniqueStorageDir();
await mkdirp(storageDir);
const storage = new SQLiteStorageDatabase(join(storageDir, 'storage.db'));
const items = new Map<string, string>();
const keys: Set<string> = new Set<string>();
for (let i = 0; i < 400; i++) {
const uuid = generateUuid();
const key = `key: ${uuid}`;
items.set(key, `value: ${uuid}`);
keys.add(key);
}
await storage.updateItems({ insert: items });
let storedItems = await storage.getItems();
equal(storedItems.size, items.size);
await storage.updateItems({ delete: keys });
storedItems = await storage.getItems();
equal(storedItems.size, 0);
await storage.close();
await del(storageDir, tmpdir());

View File

@@ -14,7 +14,7 @@ suite('Stream', () => {
return stream.readExactlyByFile(file, 10).then(({ buffer, bytesRead }) => {
assert.equal(bytesRead, 10);
assert.equal(buffer.toString(), '/*--------');
assert.equal(buffer!.toString(), '/*--------');
});
});

View File

@@ -10,10 +10,10 @@ import { mkdirp, del } from 'vs/base/node/pfs';
export interface ITestFileResult {
testFile: string;
cleanUp: () => Thenable<void>;
cleanUp: () => Promise<void>;
}
export function testFile(folder: string, file: string): Thenable<ITestFileResult> {
export function testFile(folder: string, file: string): Promise<ITestFileResult> {
const id = generateUuid();
const parentDir = join(tmpdir(), 'vsctests', id);
const newDir = join(parentDir, 'config', id);