Unit tests cleanup (#115377)

* Tests: avoid creating real editors (fix #115230)

* tests - bring back file editor input factory test

* tests cleanup

* more cleanup
This commit is contained in:
Benjamin Pasero 2021-02-01 08:45:42 +01:00 committed by GitHub
parent 6a1c7a5097
commit f5bb67e37a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
58 changed files with 1543 additions and 1766 deletions

View file

@ -11,7 +11,7 @@ suite('IPC, MessagePorts', () => {
test('message port close event', async () => {
const { port1, port2 } = new MessageChannel();
new MessagePortClient(port1, 'client1');
const client1 = new MessagePortClient(port1, 'client1');
const client2 = new MessagePortClient(port2, 'client2');
// This test ensures that Electron's API for the close event
@ -24,5 +24,7 @@ suite('IPC, MessagePorts', () => {
client2.dispose();
assert.ok(await whenClosed);
client1.dispose();
});
});

View file

@ -4,12 +4,13 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { ipcRenderer, crashReporter, webFrame } from 'vs/base/parts/sandbox/electron-sandbox/globals';
import { ipcRenderer, crashReporter, webFrame, process } from 'vs/base/parts/sandbox/electron-sandbox/globals';
suite('Sandbox', () => {
test('globals', () => {
assert.ok(ipcRenderer);
assert.ok(crashReporter);
assert.ok(webFrame);
assert.ok(typeof ipcRenderer.invoke === 'function');
assert.ok(typeof crashReporter.addExtraParameter === 'function');
assert.ok(typeof webFrame.setZoomLevel === 'function');
assert.ok(typeof process.platform === 'string');
});
});

File diff suppressed because one or more lines are too long

View file

@ -30,7 +30,7 @@ suite('dom', () => {
assert(element.classList.contains('far'));
assert(!element.classList.contains('boo'));
assert(element.classList.contains('foobar'));
assert.equal(element.className, 'foobar far');
assert.strictEqual(element.className, 'foobar far');
element = document.createElement('div');
element.className = 'foobar boo far';
@ -39,19 +39,19 @@ suite('dom', () => {
assert(!element.classList.contains('far'));
assert(element.classList.contains('boo'));
assert(element.classList.contains('foobar'));
assert.equal(element.className, 'foobar boo');
assert.strictEqual(element.className, 'foobar boo');
element.classList.remove('boo');
assert(!element.classList.contains('far'));
assert(!element.classList.contains('boo'));
assert(element.classList.contains('foobar'));
assert.equal(element.className, 'foobar');
assert.strictEqual(element.className, 'foobar');
element.classList.remove('foobar');
assert(!element.classList.contains('far'));
assert(!element.classList.contains('boo'));
assert(!element.classList.contains('foobar'));
assert.equal(element.className, '');
assert.strictEqual(element.className, '');
});
test('removeClass should consider hyphens', function () {
@ -83,7 +83,7 @@ suite('dom', () => {
const div = $('div');
assert(div);
assert(div instanceof HTMLElement);
assert.equal(div.tagName, 'DIV');
assert.strictEqual(div.tagName, 'DIV');
assert(!div.firstChild);
});
@ -91,42 +91,42 @@ suite('dom', () => {
const div = $('div#foo');
assert(div);
assert(div instanceof HTMLElement);
assert.equal(div.tagName, 'DIV');
assert.equal(div.id, 'foo');
assert.strictEqual(div.tagName, 'DIV');
assert.strictEqual(div.id, 'foo');
});
test('should buld nodes with class-name', () => {
const div = $('div.foo');
assert(div);
assert(div instanceof HTMLElement);
assert.equal(div.tagName, 'DIV');
assert.equal(div.className, 'foo');
assert.strictEqual(div.tagName, 'DIV');
assert.strictEqual(div.className, 'foo');
});
test('should build nodes with attributes', () => {
let div = $('div', { class: 'test' });
assert.equal(div.className, 'test');
assert.strictEqual(div.className, 'test');
div = $('div', undefined);
assert.equal(div.className, '');
assert.strictEqual(div.className, '');
});
test('should build nodes with children', () => {
let div = $('div', undefined, $('span', { id: 'demospan' }));
let firstChild = div.firstChild as HTMLElement;
assert.equal(firstChild.tagName, 'SPAN');
assert.equal(firstChild.id, 'demospan');
assert.strictEqual(firstChild.tagName, 'SPAN');
assert.strictEqual(firstChild.id, 'demospan');
div = $('div', undefined, 'hello');
assert.equal(div.firstChild && div.firstChild.textContent, 'hello');
assert.strictEqual(div.firstChild && div.firstChild.textContent, 'hello');
});
test('should build nodes with text children', () => {
let div = $('div', undefined, 'foobar');
let firstChild = div.firstChild as HTMLElement;
assert.equal(firstChild.tagName, undefined);
assert.equal(firstChild.textContent, 'foobar');
assert.strictEqual(firstChild.tagName, undefined);
assert.strictEqual(firstChild.textContent, 'foobar');
});
});
});

View file

@ -9,53 +9,53 @@ import { sha1Hex } from 'vs/base/browser/hash';
suite('Hash', () => {
test('string', () => {
assert.equal(hash('hello'), hash('hello'));
assert.notEqual(hash('hello'), hash('world'));
assert.notEqual(hash('hello'), hash('olleh'));
assert.notEqual(hash('hello'), hash('Hello'));
assert.notEqual(hash('hello'), hash('Hello '));
assert.notEqual(hash('h'), hash('H'));
assert.notEqual(hash('-'), hash('_'));
assert.strictEqual(hash('hello'), hash('hello'));
assert.notStrictEqual(hash('hello'), hash('world'));
assert.notStrictEqual(hash('hello'), hash('olleh'));
assert.notStrictEqual(hash('hello'), hash('Hello'));
assert.notStrictEqual(hash('hello'), hash('Hello '));
assert.notStrictEqual(hash('h'), hash('H'));
assert.notStrictEqual(hash('-'), hash('_'));
});
test('number', () => {
assert.equal(hash(1), hash(1));
assert.notEqual(hash(0), hash(1));
assert.notEqual(hash(1), hash(-1));
assert.notEqual(hash(0x12345678), hash(0x123456789));
assert.strictEqual(hash(1), hash(1));
assert.notStrictEqual(hash(0), hash(1));
assert.notStrictEqual(hash(1), hash(-1));
assert.notStrictEqual(hash(0x12345678), hash(0x123456789));
});
test('boolean', () => {
assert.equal(hash(true), hash(true));
assert.notEqual(hash(true), hash(false));
assert.strictEqual(hash(true), hash(true));
assert.notStrictEqual(hash(true), hash(false));
});
test('array', () => {
assert.equal(hash([1, 2, 3]), hash([1, 2, 3]));
assert.equal(hash(['foo', 'bar']), hash(['foo', 'bar']));
assert.equal(hash([]), hash([]));
assert.equal(hash([]), hash(new Array()));
assert.notEqual(hash(['foo', 'bar']), hash(['bar', 'foo']));
assert.notEqual(hash(['foo', 'bar']), hash(['bar', 'foo', null]));
assert.notEqual(hash(['foo', 'bar', null]), hash(['bar', 'foo', null]));
assert.notEqual(hash(['foo', 'bar']), hash(['bar', 'foo', undefined]));
assert.notEqual(hash(['foo', 'bar', undefined]), hash(['bar', 'foo', undefined]));
assert.notEqual(hash(['foo', 'bar', null]), hash(['foo', 'bar', undefined]));
assert.strictEqual(hash([1, 2, 3]), hash([1, 2, 3]));
assert.strictEqual(hash(['foo', 'bar']), hash(['foo', 'bar']));
assert.strictEqual(hash([]), hash([]));
assert.strictEqual(hash([]), hash(new Array()));
assert.notStrictEqual(hash(['foo', 'bar']), hash(['bar', 'foo']));
assert.notStrictEqual(hash(['foo', 'bar']), hash(['bar', 'foo', null]));
assert.notStrictEqual(hash(['foo', 'bar', null]), hash(['bar', 'foo', null]));
assert.notStrictEqual(hash(['foo', 'bar']), hash(['bar', 'foo', undefined]));
assert.notStrictEqual(hash(['foo', 'bar', undefined]), hash(['bar', 'foo', undefined]));
assert.notStrictEqual(hash(['foo', 'bar', null]), hash(['foo', 'bar', undefined]));
});
test('object', () => {
assert.equal(hash({}), hash({}));
assert.equal(hash({}), hash(Object.create(null)));
assert.equal(hash({ 'foo': 'bar' }), hash({ '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([]));
assert.strictEqual(hash({}), hash({}));
assert.strictEqual(hash({}), hash(Object.create(null)));
assert.strictEqual(hash({ 'foo': 'bar' }), hash({ 'foo': 'bar' }));
assert.strictEqual(hash({ 'foo': 'bar', 'foo2': undefined }), hash({ 'foo2': undefined, 'foo': 'bar' }));
assert.notStrictEqual(hash({ 'foo': 'bar' }), hash({ 'foo': 'bar2' }));
assert.notStrictEqual(hash({}), hash([]));
});
test('array - unexpected collision', function () {
const a = hash([undefined, undefined, undefined, undefined, undefined]);
const b = hash([undefined, undefined, 'HHHHHH', [{ line: 0, character: 0 }, { line: 0, character: 0 }], undefined]);
assert.notEqual(a, b);
assert.notStrictEqual(a, b);
});
test('all different', () => {
@ -65,9 +65,9 @@ suite('Hash', () => {
];
const hashes: number[] = candidates.map(hash);
for (let i = 0; i < hashes.length; i++) {
assert.equal(hashes[i], hash(candidates[i])); // verify that repeated invocation returns the same hash
assert.strictEqual(hashes[i], hash(candidates[i])); // verify that repeated invocation returns the same hash
for (let k = i + 1; k < hashes.length; k++) {
assert.notEqual(hashes[i], hashes[k], `Same hash ${hashes[i]} for ${JSON.stringify(candidates[i])} and ${JSON.stringify(candidates[k])}`);
assert.notStrictEqual(hashes[i], hashes[k], `Same hash ${hashes[i]} for ${JSON.stringify(candidates[i])} and ${JSON.stringify(candidates[k])}`);
}
}
});
@ -79,11 +79,11 @@ suite('Hash', () => {
const hash = new StringSHA1();
hash.update(str);
let actual = hash.digest();
assert.equal(actual, expected);
assert.strictEqual(actual, expected);
// Test with crypto.subtle
actual = await sha1Hex(str);
assert.equal(actual, expected);
assert.strictEqual(actual, expected);
}
test('sha1-1', () => {

View file

@ -2,6 +2,7 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { HighlightedLabel } from 'vs/base/browser/ui/highlightedlabel/highlightedLabel';
@ -13,50 +14,50 @@ suite('HighlightedLabel', () => {
});
test('empty label', function () {
assert.equal(label.element.innerHTML, '');
assert.strictEqual(label.element.innerHTML, '');
});
test('no decorations', function () {
label.set('hello');
assert.equal(label.element.innerHTML, '<span>hello</span>');
assert.strictEqual(label.element.innerHTML, '<span>hello</span>');
});
test('escape html', function () {
label.set('hel<lo');
assert.equal(label.element.innerHTML, '<span>hel&lt;lo</span>');
assert.strictEqual(label.element.innerHTML, '<span>hel&lt;lo</span>');
});
test('everything highlighted', function () {
label.set('hello', [{ start: 0, end: 5 }]);
assert.equal(label.element.innerHTML, '<span class="highlight">hello</span>');
assert.strictEqual(label.element.innerHTML, '<span class="highlight">hello</span>');
});
test('beginning highlighted', function () {
label.set('hellothere', [{ start: 0, end: 5 }]);
assert.equal(label.element.innerHTML, '<span class="highlight">hello</span><span>there</span>');
assert.strictEqual(label.element.innerHTML, '<span class="highlight">hello</span><span>there</span>');
});
test('ending highlighted', function () {
label.set('goodbye', [{ start: 4, end: 7 }]);
assert.equal(label.element.innerHTML, '<span>good</span><span class="highlight">bye</span>');
assert.strictEqual(label.element.innerHTML, '<span>good</span><span class="highlight">bye</span>');
});
test('middle highlighted', function () {
label.set('foobarfoo', [{ start: 3, end: 6 }]);
assert.equal(label.element.innerHTML, '<span>foo</span><span class="highlight">bar</span><span>foo</span>');
assert.strictEqual(label.element.innerHTML, '<span>foo</span><span class="highlight">bar</span><span>foo</span>');
});
test('escapeNewLines', () => {
let highlights = [{ start: 0, end: 5 }, { start: 7, end: 9 }, { start: 11, end: 12 }];// before,after,after
let escaped = HighlightedLabel.escapeNewLines('ACTION\r\n_TYPE2', highlights);
assert.equal(escaped, 'ACTION\u23CE_TYPE2');
assert.deepEqual(highlights, [{ start: 0, end: 5 }, { start: 6, end: 8 }, { start: 10, end: 11 }]);
assert.strictEqual(escaped, 'ACTION\u23CE_TYPE2');
assert.deepStrictEqual(highlights, [{ start: 0, end: 5 }, { start: 6, end: 8 }, { start: 10, end: 11 }]);
highlights = [{ start: 5, end: 9 }, { start: 11, end: 12 }];//overlap,after
escaped = HighlightedLabel.escapeNewLines('ACTION\r\n_TYPE2', highlights);
assert.equal(escaped, 'ACTION\u23CE_TYPE2');
assert.deepEqual(highlights, [{ start: 5, end: 8 }, { start: 10, end: 11 }]);
assert.strictEqual(escaped, 'ACTION\u23CE_TYPE2');
assert.deepStrictEqual(highlights, [{ start: 5, end: 8 }, { start: 10, end: 11 }]);
});
});

View file

@ -3,45 +3,45 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { renderLabelWithIcons } from 'vs/base/browser/ui/iconLabel/iconLabels';
import * as assert from 'assert';
import { renderLabelWithIcons } from 'vs/base/browser/ui/iconLabel/iconLabels';
suite('renderLabelWithIcons', () => {
test('no icons', () => {
const result = renderLabelWithIcons(' hello World .');
assert.equal(elementsToString(result), ' hello World .');
assert.strictEqual(elementsToString(result), ' hello World .');
});
test('icons only', () => {
const result = renderLabelWithIcons('$(alert)');
assert.equal(elementsToString(result), '<span class="codicon codicon-alert"></span>');
assert.strictEqual(elementsToString(result), '<span class="codicon codicon-alert"></span>');
});
test('icon and non-icon strings', () => {
const result = renderLabelWithIcons(` $(alert) Unresponsive`);
assert.equal(elementsToString(result), ' <span class="codicon codicon-alert"></span> Unresponsive');
assert.strictEqual(elementsToString(result), ' <span class="codicon codicon-alert"></span> Unresponsive');
});
test('multiple icons', () => {
const result = renderLabelWithIcons('$(check)$(error)');
assert.equal(elementsToString(result), '<span class="codicon codicon-check"></span><span class="codicon codicon-error"></span>');
assert.strictEqual(elementsToString(result), '<span class="codicon codicon-check"></span><span class="codicon codicon-error"></span>');
});
test('escaped icons', () => {
const result = renderLabelWithIcons('\\$(escaped)');
assert.equal(elementsToString(result), '$(escaped)');
assert.strictEqual(elementsToString(result), '$(escaped)');
});
test('icon with animation', () => {
const result = renderLabelWithIcons('$(zip~anim)');
assert.equal(elementsToString(result), '<span class="codicon codicon-zip codicon-modifier-anim"></span>');
assert.strictEqual(elementsToString(result), '<span class="codicon codicon-zip codicon-modifier-anim"></span>');
});
const elementsToString = (elements: Array<HTMLElement | string>): string => {

View file

@ -9,20 +9,20 @@ import { layout, LayoutAnchorPosition } from 'vs/base/browser/ui/contextview/con
suite('Contextview', function () {
test('layout', () => {
assert.equal(layout(200, 20, { offset: 0, size: 0, position: LayoutAnchorPosition.Before }), 0);
assert.equal(layout(200, 20, { offset: 50, size: 0, position: LayoutAnchorPosition.Before }), 50);
assert.equal(layout(200, 20, { offset: 200, size: 0, position: LayoutAnchorPosition.Before }), 180);
assert.strictEqual(layout(200, 20, { offset: 0, size: 0, position: LayoutAnchorPosition.Before }), 0);
assert.strictEqual(layout(200, 20, { offset: 50, size: 0, position: LayoutAnchorPosition.Before }), 50);
assert.strictEqual(layout(200, 20, { offset: 200, size: 0, position: LayoutAnchorPosition.Before }), 180);
assert.equal(layout(200, 20, { offset: 0, size: 0, position: LayoutAnchorPosition.After }), 0);
assert.equal(layout(200, 20, { offset: 50, size: 0, position: LayoutAnchorPosition.After }), 30);
assert.equal(layout(200, 20, { offset: 200, size: 0, position: LayoutAnchorPosition.After }), 180);
assert.strictEqual(layout(200, 20, { offset: 0, size: 0, position: LayoutAnchorPosition.After }), 0);
assert.strictEqual(layout(200, 20, { offset: 50, size: 0, position: LayoutAnchorPosition.After }), 30);
assert.strictEqual(layout(200, 20, { offset: 200, size: 0, position: LayoutAnchorPosition.After }), 180);
assert.equal(layout(200, 20, { offset: 0, size: 50, position: LayoutAnchorPosition.Before }), 50);
assert.equal(layout(200, 20, { offset: 50, size: 50, position: LayoutAnchorPosition.Before }), 100);
assert.equal(layout(200, 20, { offset: 150, size: 50, position: LayoutAnchorPosition.Before }), 130);
assert.strictEqual(layout(200, 20, { offset: 0, size: 50, position: LayoutAnchorPosition.Before }), 50);
assert.strictEqual(layout(200, 20, { offset: 50, size: 50, position: LayoutAnchorPosition.Before }), 100);
assert.strictEqual(layout(200, 20, { offset: 150, size: 50, position: LayoutAnchorPosition.Before }), 130);
assert.equal(layout(200, 20, { offset: 0, size: 50, position: LayoutAnchorPosition.After }), 50);
assert.equal(layout(200, 20, { offset: 50, size: 50, position: LayoutAnchorPosition.After }), 30);
assert.equal(layout(200, 20, { offset: 150, size: 50, position: LayoutAnchorPosition.After }), 130);
assert.strictEqual(layout(200, 20, { offset: 0, size: 50, position: LayoutAnchorPosition.After }), 50);
assert.strictEqual(layout(200, 20, { offset: 50, size: 50, position: LayoutAnchorPosition.After }), 30);
assert.strictEqual(layout(200, 20, { offset: 150, size: 50, position: LayoutAnchorPosition.After }), 130);
});
});

View file

@ -5,7 +5,7 @@
import * as assert from 'assert';
import * as extpath from 'vs/base/common/extpath';
import * as platform from 'vs/base/common/platform';
import { isWindows } from 'vs/base/common/platform';
import { CharCode } from 'vs/base/common/charCode';
suite('Paths', () => {
@ -32,7 +32,7 @@ suite('Paths', () => {
assert.strictEqual(extpath.getRoot('file://foo'), '');
});
(!platform.isWindows ? test.skip : test)('isUNC', () => {
(!isWindows ? test.skip : test)('isUNC', () => {
assert.ok(!extpath.isUNC('foo'));
assert.ok(!extpath.isUNC('/foo'));
assert.ok(!extpath.isUNC('\\foo'));
@ -51,7 +51,7 @@ suite('Paths', () => {
assert.ok(!extpath.isValidBasename('/test.txt'));
assert.ok(!extpath.isValidBasename('\\test.txt'));
if (platform.isWindows) {
if (isWindows) {
assert.ok(!extpath.isValidBasename('aux'));
assert.ok(!extpath.isValidBasename('Aux'));
assert.ok(!extpath.isValidBasename('LPT0'));
@ -72,7 +72,7 @@ suite('Paths', () => {
});
test('sanitizeFilePath', () => {
if (platform.isWindows) {
if (isWindows) {
assert.strictEqual(extpath.sanitizeFilePath('.', 'C:\\the\\cwd'), 'C:\\the\\cwd');
assert.strictEqual(extpath.sanitizeFilePath('', 'C:\\the\\cwd'), 'C:\\the\\cwd');
@ -108,7 +108,7 @@ suite('Paths', () => {
});
test('isRootOrDriveLetter', () => {
if (platform.isWindows) {
if (isWindows) {
assert.ok(extpath.isRootOrDriveLetter('c:'));
assert.ok(extpath.isRootOrDriveLetter('D:'));
assert.ok(extpath.isRootOrDriveLetter('D:/'));
@ -122,7 +122,7 @@ suite('Paths', () => {
});
test('hasDriveLetter', () => {
if (platform.isWindows) {
if (isWindows) {
assert.ok(extpath.hasDriveLetter('c:'));
assert.ok(extpath.hasDriveLetter('D:'));
assert.ok(extpath.hasDriveLetter('D:/'));
@ -136,7 +136,7 @@ suite('Paths', () => {
});
test('getDriveLetter', () => {
if (platform.isWindows) {
if (isWindows) {
assert.strictEqual(extpath.getDriveLetter('c:'), 'c');
assert.strictEqual(extpath.getDriveLetter('D:'), 'D');
assert.strictEqual(extpath.getDriveLetter('D:/'), 'D');

View file

@ -4,13 +4,13 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import * as scorer from 'vs/base/common/fuzzyScorer';
import { IItemAccessor, FuzzyScore, FuzzyScore2, IItemScore, prepareQuery, scoreFuzzy, scoreFuzzy2, scoreItemFuzzy, compareItemsByFuzzyScore, pieceToQuery } from 'vs/base/common/fuzzyScorer';
import { URI } from 'vs/base/common/uri';
import { basename, dirname, sep, posix, win32 } from 'vs/base/common/path';
import { isWindows } from 'vs/base/common/platform';
import { Schemas } from 'vs/base/common/network';
class ResourceAccessorClass implements scorer.IItemAccessor<URI> {
class ResourceAccessorClass implements IItemAccessor<URI> {
getItemLabel(resource: URI): string {
return basename(resource.fsPath);
@ -27,7 +27,7 @@ class ResourceAccessorClass implements scorer.IItemAccessor<URI> {
const ResourceAccessor = new ResourceAccessorClass();
class ResourceWithSlashAccessorClass implements scorer.IItemAccessor<URI> {
class ResourceWithSlashAccessorClass implements IItemAccessor<URI> {
getItemLabel(resource: URI): string {
return basename(resource.fsPath);
@ -44,7 +44,7 @@ class ResourceWithSlashAccessorClass implements scorer.IItemAccessor<URI> {
const ResourceWithSlashAccessor = new ResourceWithSlashAccessorClass();
class ResourceWithBackslashAccessorClass implements scorer.IItemAccessor<URI> {
class ResourceWithBackslashAccessorClass implements IItemAccessor<URI> {
getItemLabel(resource: URI): string {
return basename(resource.fsPath);
@ -61,7 +61,7 @@ class ResourceWithBackslashAccessorClass implements scorer.IItemAccessor<URI> {
const ResourceWithBackslashAccessor = new ResourceWithBackslashAccessorClass();
class NullAccessorClass implements scorer.IItemAccessor<URI> {
class NullAccessorClass implements IItemAccessor<URI> {
getItemLabel(resource: URI): string {
return undefined!;
@ -76,24 +76,24 @@ class NullAccessorClass implements scorer.IItemAccessor<URI> {
}
}
function _doScore(target: string, query: string, fuzzy: boolean): scorer.FuzzyScore {
const preparedQuery = scorer.prepareQuery(query);
function _doScore(target: string, query: string, fuzzy: boolean): FuzzyScore {
const preparedQuery = prepareQuery(query);
return scorer.scoreFuzzy(target, preparedQuery.normalized, preparedQuery.normalizedLowercase, fuzzy);
return scoreFuzzy(target, preparedQuery.normalized, preparedQuery.normalizedLowercase, fuzzy);
}
function _doScore2(target: string, query: string, matchOffset: number = 0): scorer.FuzzyScore2 {
const preparedQuery = scorer.prepareQuery(query);
function _doScore2(target: string, query: string, matchOffset: number = 0): FuzzyScore2 {
const preparedQuery = prepareQuery(query);
return scorer.scoreFuzzy2(target, preparedQuery, 0, matchOffset);
return scoreFuzzy2(target, preparedQuery, 0, matchOffset);
}
function scoreItem<T>(item: T, query: string, fuzzy: boolean, accessor: scorer.IItemAccessor<T>): scorer.IItemScore {
return scorer.scoreItemFuzzy(item, scorer.prepareQuery(query), fuzzy, accessor, Object.create(null));
function scoreItem<T>(item: T, query: string, fuzzy: boolean, accessor: IItemAccessor<T>): IItemScore {
return scoreItemFuzzy(item, prepareQuery(query), fuzzy, accessor, Object.create(null));
}
function compareItemsByScore<T>(itemA: T, itemB: T, query: string, fuzzy: boolean, accessor: scorer.IItemAccessor<T>): number {
return scorer.compareItemsByFuzzyScore(itemA, itemB, scorer.prepareQuery(query), fuzzy, accessor, Object.create(null));
function compareItemsByScore<T>(itemA: T, itemB: T, query: string, fuzzy: boolean, accessor: IItemAccessor<T>): number {
return compareItemsByFuzzyScore(itemA, itemB, prepareQuery(query), fuzzy, accessor, Object.create(null));
}
const NullAccessor = new NullAccessorClass();
@ -103,7 +103,7 @@ suite('Fuzzy Scorer', () => {
test('score (fuzzy)', function () {
const target = 'HeLlo-World';
const scores: scorer.FuzzyScore[] = [];
const scores: FuzzyScore[] = [];
scores.push(_doScore(target, 'HelLo-World', true)); // direct case match
scores.push(_doScore(target, 'hello-world', true)); // direct mix-case match
scores.push(_doScore(target, 'HW', true)); // direct case prefix (multiple)
@ -1071,16 +1071,16 @@ suite('Fuzzy Scorer', () => {
});
test('prepareQuery', () => {
assert.strictEqual(scorer.prepareQuery(' f*a ').normalized, 'fa');
assert.strictEqual(scorer.prepareQuery('model Tester.ts').original, 'model Tester.ts');
assert.strictEqual(scorer.prepareQuery('model Tester.ts').originalLowercase, 'model Tester.ts'.toLowerCase());
assert.strictEqual(scorer.prepareQuery('model Tester.ts').normalized, 'modelTester.ts');
assert.strictEqual(scorer.prepareQuery('Model Tester.ts').normalizedLowercase, 'modeltester.ts');
assert.strictEqual(scorer.prepareQuery('ModelTester.ts').containsPathSeparator, false);
assert.strictEqual(scorer.prepareQuery('Model' + sep + 'Tester.ts').containsPathSeparator, true);
assert.strictEqual(prepareQuery(' f*a ').normalized, 'fa');
assert.strictEqual(prepareQuery('model Tester.ts').original, 'model Tester.ts');
assert.strictEqual(prepareQuery('model Tester.ts').originalLowercase, 'model Tester.ts'.toLowerCase());
assert.strictEqual(prepareQuery('model Tester.ts').normalized, 'modelTester.ts');
assert.strictEqual(prepareQuery('Model Tester.ts').normalizedLowercase, 'modeltester.ts');
assert.strictEqual(prepareQuery('ModelTester.ts').containsPathSeparator, false);
assert.strictEqual(prepareQuery('Model' + sep + 'Tester.ts').containsPathSeparator, true);
// with spaces
let query = scorer.prepareQuery('He*llo World');
let query = prepareQuery('He*llo World');
assert.strictEqual(query.original, 'He*llo World');
assert.strictEqual(query.normalized, 'HelloWorld');
assert.strictEqual(query.normalizedLowercase, 'HelloWorld'.toLowerCase());
@ -1092,13 +1092,13 @@ suite('Fuzzy Scorer', () => {
assert.strictEqual(query.values?.[1].normalized, 'World');
assert.strictEqual(query.values?.[1].normalizedLowercase, 'World'.toLowerCase());
let restoredQuery = scorer.pieceToQuery(query.values!);
let restoredQuery = pieceToQuery(query.values!);
assert.strictEqual(restoredQuery.original, query.original);
assert.strictEqual(restoredQuery.values?.length, query.values?.length);
assert.strictEqual(restoredQuery.containsPathSeparator, query.containsPathSeparator);
// with spaces that are empty
query = scorer.prepareQuery(' Hello World ');
query = prepareQuery(' Hello World ');
assert.strictEqual(query.original, ' Hello World ');
assert.strictEqual(query.originalLowercase, ' Hello World '.toLowerCase());
assert.strictEqual(query.normalized, 'HelloWorld');
@ -1115,19 +1115,19 @@ suite('Fuzzy Scorer', () => {
// Path related
if (isWindows) {
assert.strictEqual(scorer.prepareQuery('C:\\some\\path').pathNormalized, 'C:\\some\\path');
assert.strictEqual(scorer.prepareQuery('C:\\some\\path').normalized, 'C:\\some\\path');
assert.strictEqual(scorer.prepareQuery('C:\\some\\path').containsPathSeparator, true);
assert.strictEqual(scorer.prepareQuery('C:/some/path').pathNormalized, 'C:\\some\\path');
assert.strictEqual(scorer.prepareQuery('C:/some/path').normalized, 'C:\\some\\path');
assert.strictEqual(scorer.prepareQuery('C:/some/path').containsPathSeparator, true);
assert.strictEqual(prepareQuery('C:\\some\\path').pathNormalized, 'C:\\some\\path');
assert.strictEqual(prepareQuery('C:\\some\\path').normalized, 'C:\\some\\path');
assert.strictEqual(prepareQuery('C:\\some\\path').containsPathSeparator, true);
assert.strictEqual(prepareQuery('C:/some/path').pathNormalized, 'C:\\some\\path');
assert.strictEqual(prepareQuery('C:/some/path').normalized, 'C:\\some\\path');
assert.strictEqual(prepareQuery('C:/some/path').containsPathSeparator, true);
} else {
assert.strictEqual(scorer.prepareQuery('/some/path').pathNormalized, '/some/path');
assert.strictEqual(scorer.prepareQuery('/some/path').normalized, '/some/path');
assert.strictEqual(scorer.prepareQuery('/some/path').containsPathSeparator, true);
assert.strictEqual(scorer.prepareQuery('\\some\\path').pathNormalized, '/some/path');
assert.strictEqual(scorer.prepareQuery('\\some\\path').normalized, '/some/path');
assert.strictEqual(scorer.prepareQuery('\\some\\path').containsPathSeparator, true);
assert.strictEqual(prepareQuery('/some/path').pathNormalized, '/some/path');
assert.strictEqual(prepareQuery('/some/path').normalized, '/some/path');
assert.strictEqual(prepareQuery('/some/path').containsPathSeparator, true);
assert.strictEqual(prepareQuery('\\some\\path').pathNormalized, '/some/path');
assert.strictEqual(prepareQuery('\\some\\path').normalized, '/some/path');
assert.strictEqual(prepareQuery('\\some\\path').containsPathSeparator, true);
}
});

View file

@ -2,9 +2,10 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import * as path from 'vs/base/common/path';
import * as glob from 'vs/base/common/glob';
import { sep } from 'vs/base/common/path';
import { isWindows } from 'vs/base/common/platform';
suite('Glob', () => {
@ -952,7 +953,7 @@ suite('Glob', () => {
}
function nativeSep(slashPath: string): string {
return slashPath.replace(/\//g, path.sep);
return slashPath.replace(/\//g, sep);
}
test('relative pattern - glob star', function () {

View file

@ -66,9 +66,9 @@ suite('Icon Labels', () => {
});
test('stripIcons', () => {
assert.equal(stripIcons('Hello World'), 'Hello World');
assert.equal(stripIcons('$(Hello World'), '$(Hello World');
assert.equal(stripIcons('$(Hello) World'), ' World');
assert.equal(stripIcons('$(Hello) W$(oi)rld'), ' Wrld');
assert.strictEqual(stripIcons('Hello World'), 'Hello World');
assert.strictEqual(stripIcons('$(Hello World'), '$(Hello World');
assert.strictEqual(stripIcons('$(Hello) World'), ' World');
assert.strictEqual(stripIcons('$(Hello) W$(oi)rld'), ' Wrld');
});
});

View file

@ -5,10 +5,10 @@
import * as assert from 'assert';
import * as labels from 'vs/base/common/labels';
import * as platform from 'vs/base/common/platform';
import { isMacintosh, isWindows } from 'vs/base/common/platform';
suite('Labels', () => {
(!platform.isWindows ? test.skip : test)('shorten - windows', () => {
(!isWindows ? test.skip : test)('shorten - windows', () => {
// nothing to shorten
assert.deepStrictEqual(labels.shorten(['a']), ['a']);
@ -59,7 +59,7 @@ suite('Labels', () => {
assert.deepStrictEqual(labels.shorten(['src\\vs\\workbench\\parts\\execution\\electron-browser', 'src\\vs\\workbench\\parts\\execution\\electron-browser\\something', 'src\\vs\\workbench\\parts\\terminal\\electron-browser']), ['…\\execution\\electron-browser', '…\\something', '…\\terminal\\…']);
});
(platform.isWindows ? test.skip : test)('shorten - not windows', () => {
(isWindows ? test.skip : test)('shorten - not windows', () => {
// nothing to shorten
assert.deepStrictEqual(labels.shorten(['a']), ['a']);
@ -134,13 +134,13 @@ suite('Labels', () => {
assert.strictEqual(labels.template(t, { dirty: '* ', activeEditorShort: 'somefile.txt', rootName: 'monaco', appName: 'Visual Studio Code', separator: { label: ' - ' } }), '* somefile.txt - monaco - Visual Studio Code');
});
(platform.isWindows ? test.skip : test)('getBaseLabel - unix', () => {
(isWindows ? test.skip : test)('getBaseLabel - unix', () => {
assert.strictEqual(labels.getBaseLabel('/some/folder/file.txt'), 'file.txt');
assert.strictEqual(labels.getBaseLabel('/some/folder'), 'folder');
assert.strictEqual(labels.getBaseLabel('/'), '/');
});
(!platform.isWindows ? test.skip : test)('getBaseLabel - windows', () => {
(!isWindows ? test.skip : test)('getBaseLabel - windows', () => {
assert.strictEqual(labels.getBaseLabel('c:'), 'C:');
assert.strictEqual(labels.getBaseLabel('c:\\'), 'C:');
assert.strictEqual(labels.getBaseLabel('c:\\some\\folder\\file.txt'), 'file.txt');
@ -151,10 +151,10 @@ suite('Labels', () => {
test('mnemonicButtonLabel', () => {
assert.strictEqual(labels.mnemonicButtonLabel('Hello World'), 'Hello World');
assert.strictEqual(labels.mnemonicButtonLabel(''), '');
if (platform.isWindows) {
if (isWindows) {
assert.strictEqual(labels.mnemonicButtonLabel('Hello & World'), 'Hello && World');
assert.strictEqual(labels.mnemonicButtonLabel('Do &&not Save & Continue'), 'Do &not Save && Continue');
} else if (platform.isMacintosh) {
} else if (isMacintosh) {
assert.strictEqual(labels.mnemonicButtonLabel('Hello & World'), 'Hello & World');
assert.strictEqual(labels.mnemonicButtonLabel('Do &&not Save & Continue'), 'Do not Save & Continue');
} else {

View file

@ -2,6 +2,7 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { DisposableStore, dispose, IDisposable, MultiDisposeError, ReferenceCollection, toDisposable } from 'vs/base/common/lifecycle';
@ -95,8 +96,8 @@ suite('Lifecycle', () => {
let array = [{ dispose() { } }, { dispose() { } }];
let array2 = dispose(array);
assert.equal(array.length, 2);
assert.equal(array2.length, 0);
assert.strictEqual(array.length, 2);
assert.strictEqual(array2.length, 0);
assert.ok(array !== array2);
let set = new Set<IDisposable>([{ dispose() { } }, { dispose() { } }]);
@ -165,27 +166,27 @@ suite('Reference Collection', () => {
const ref1 = collection.acquire('test');
assert(ref1);
assert.equal(ref1.object, 4);
assert.equal(collection.count, 1);
assert.strictEqual(ref1.object, 4);
assert.strictEqual(collection.count, 1);
ref1.dispose();
assert.equal(collection.count, 0);
assert.strictEqual(collection.count, 0);
const ref2 = collection.acquire('test');
const ref3 = collection.acquire('test');
assert.equal(ref2.object, ref3.object);
assert.equal(collection.count, 1);
assert.strictEqual(ref2.object, ref3.object);
assert.strictEqual(collection.count, 1);
const ref4 = collection.acquire('monkey');
assert.equal(ref4.object, 6);
assert.equal(collection.count, 2);
assert.strictEqual(ref4.object, 6);
assert.strictEqual(collection.count, 2);
ref2.dispose();
assert.equal(collection.count, 2);
assert.strictEqual(collection.count, 2);
ref3.dispose();
assert.equal(collection.count, 1);
assert.strictEqual(collection.count, 1);
ref4.dispose();
assert.equal(collection.count, 0);
assert.strictEqual(collection.count, 0);
});
});

View file

@ -132,6 +132,5 @@ suite('LinkedList', function () {
let b = list.pop();
assert.strictEqual(b, 'b');
assertElements(list, 'a');
});
});

View file

@ -8,61 +8,61 @@ import { parseLinkedText } from 'vs/base/common/linkedText';
suite('LinkedText', () => {
test('parses correctly', () => {
assert.deepEqual(parseLinkedText('').nodes, []);
assert.deepEqual(parseLinkedText('hello').nodes, ['hello']);
assert.deepEqual(parseLinkedText('hello there').nodes, ['hello there']);
assert.deepEqual(parseLinkedText('Some message with [link text](http://link.href).').nodes, [
assert.deepStrictEqual(parseLinkedText('').nodes, []);
assert.deepStrictEqual(parseLinkedText('hello').nodes, ['hello']);
assert.deepStrictEqual(parseLinkedText('hello there').nodes, ['hello there']);
assert.deepStrictEqual(parseLinkedText('Some message with [link text](http://link.href).').nodes, [
'Some message with ',
{ label: 'link text', href: 'http://link.href' },
'.'
]);
assert.deepEqual(parseLinkedText('Some message with [link text](http://link.href "and a title").').nodes, [
assert.deepStrictEqual(parseLinkedText('Some message with [link text](http://link.href "and a title").').nodes, [
'Some message with ',
{ label: 'link text', href: 'http://link.href', title: 'and a title' },
'.'
]);
assert.deepEqual(parseLinkedText('Some message with [link text](http://link.href \'and a title\').').nodes, [
assert.deepStrictEqual(parseLinkedText('Some message with [link text](http://link.href \'and a title\').').nodes, [
'Some message with ',
{ label: 'link text', href: 'http://link.href', title: 'and a title' },
'.'
]);
assert.deepEqual(parseLinkedText('Some message with [link text](http://link.href "and a \'title\'").').nodes, [
assert.deepStrictEqual(parseLinkedText('Some message with [link text](http://link.href "and a \'title\'").').nodes, [
'Some message with ',
{ label: 'link text', href: 'http://link.href', title: 'and a \'title\'' },
'.'
]);
assert.deepEqual(parseLinkedText('Some message with [link text](http://link.href \'and a "title"\').').nodes, [
assert.deepStrictEqual(parseLinkedText('Some message with [link text](http://link.href \'and a "title"\').').nodes, [
'Some message with ',
{ label: 'link text', href: 'http://link.href', title: 'and a "title"' },
'.'
]);
assert.deepEqual(parseLinkedText('Some message with [link text](random stuff).').nodes, [
assert.deepStrictEqual(parseLinkedText('Some message with [link text](random stuff).').nodes, [
'Some message with [link text](random stuff).'
]);
assert.deepEqual(parseLinkedText('Some message with [https link](https://link.href).').nodes, [
assert.deepStrictEqual(parseLinkedText('Some message with [https link](https://link.href).').nodes, [
'Some message with ',
{ label: 'https link', href: 'https://link.href' },
'.'
]);
assert.deepEqual(parseLinkedText('Some message with [https link](https:).').nodes, [
assert.deepStrictEqual(parseLinkedText('Some message with [https link](https:).').nodes, [
'Some message with [https link](https:).'
]);
assert.deepEqual(parseLinkedText('Some message with [a command](command:foobar).').nodes, [
assert.deepStrictEqual(parseLinkedText('Some message with [a command](command:foobar).').nodes, [
'Some message with ',
{ label: 'a command', href: 'command:foobar' },
'.'
]);
assert.deepEqual(parseLinkedText('Some message with [a command](command:).').nodes, [
assert.deepStrictEqual(parseLinkedText('Some message with [a command](command:).').nodes, [
'Some message with [a command](command:).'
]);
assert.deepEqual(parseLinkedText('link [one](command:foo "nice") and link [two](http://foo)...').nodes, [
assert.deepStrictEqual(parseLinkedText('link [one](command:foo "nice") and link [two](http://foo)...').nodes, [
'link ',
{ label: 'one', href: 'command:foo', title: 'nice' },
' and link ',
{ label: 'two', href: 'http://foo' },
'...'
]);
assert.deepEqual(parseLinkedText('link\n[one](command:foo "nice")\nand link [two](http://foo)...').nodes, [
assert.deepStrictEqual(parseLinkedText('link\n[one](command:foo "nice")\nand link [two](http://foo)...').nodes, [
'link\n',
{ label: 'one', href: 'command:foo', title: 'nice' },
'\nand link ',

View file

@ -3,8 +3,8 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ResourceMap, TernarySearchTree, PathIterator, StringIterator, LinkedMap, Touch, LRUCache, UriIterator, ConfigKeysIterator } from 'vs/base/common/map';
import * as assert from 'assert';
import { ResourceMap, TernarySearchTree, PathIterator, StringIterator, LinkedMap, Touch, LRUCache, UriIterator, ConfigKeysIterator } from 'vs/base/common/map';
import { URI } from 'vs/base/common/uri';
import { extUriIgnorePathCase } from 'vs/base/common/resources';

View file

@ -19,52 +19,52 @@ suite('network', () => {
let browserUri = FileAccess.asBrowserUri(originalFileUri);
assert.ok(browserUri.authority.length > 0);
let fileUri = FileAccess.asFileUri(browserUri);
assert.equal(fileUri.authority.length, 0);
assert.strictEqual(fileUri.authority.length, 0);
assert(isEqual(originalFileUri, fileUri));
// asCodeUri() & asFileUri(): with authority
originalFileUri = URI.file('network.test.ts').with({ authority: 'test-authority' });
browserUri = FileAccess.asBrowserUri(originalFileUri);
assert.equal(browserUri.authority, originalFileUri.authority);
assert.strictEqual(browserUri.authority, originalFileUri.authority);
fileUri = FileAccess.asFileUri(browserUri);
assert(isEqual(originalFileUri, fileUri));
});
(!enableTest ? test.skip : test)('FileAccess: moduleId (native)', () => {
const browserUri = FileAccess.asBrowserUri('vs/base/test/node/network.test', require);
assert.equal(browserUri.scheme, Schemas.vscodeFileResource);
assert.strictEqual(browserUri.scheme, Schemas.vscodeFileResource);
const fileUri = FileAccess.asFileUri('vs/base/test/node/network.test', require);
assert.equal(fileUri.scheme, Schemas.file);
assert.strictEqual(fileUri.scheme, Schemas.file);
});
(!enableTest ? test.skip : test)('FileAccess: query and fragment is dropped (native)', () => {
let originalFileUri = URI.file('network.test.ts').with({ query: 'foo=bar', fragment: 'something' });
let browserUri = FileAccess.asBrowserUri(originalFileUri);
assert.equal(browserUri.query, '');
assert.equal(browserUri.fragment, '');
assert.strictEqual(browserUri.query, '');
assert.strictEqual(browserUri.fragment, '');
});
(!enableTest ? test.skip : test)('FileAccess: query and fragment is kept if URI is already of same scheme (native)', () => {
let originalFileUri = URI.file('network.test.ts').with({ query: 'foo=bar', fragment: 'something' });
let browserUri = FileAccess.asBrowserUri(originalFileUri.with({ scheme: Schemas.vscodeFileResource }));
assert.equal(browserUri.query, 'foo=bar');
assert.equal(browserUri.fragment, 'something');
assert.strictEqual(browserUri.query, 'foo=bar');
assert.strictEqual(browserUri.fragment, 'something');
let fileUri = FileAccess.asFileUri(originalFileUri);
assert.equal(fileUri.query, 'foo=bar');
assert.equal(fileUri.fragment, 'something');
assert.strictEqual(fileUri.query, 'foo=bar');
assert.strictEqual(fileUri.fragment, 'something');
});
(!enableTest ? test.skip : test)('FileAccess: web', () => {
const originalHttpsUri = URI.file('network.test.ts').with({ scheme: 'https' });
const browserUri = FileAccess.asBrowserUri(originalHttpsUri);
assert.equal(originalHttpsUri.toString(), browserUri.toString());
assert.strictEqual(originalHttpsUri.toString(), browserUri.toString());
});
test('FileAccess: remote URIs', () => {
const originalRemoteUri = URI.file('network.test.ts').with({ scheme: Schemas.vscodeRemote });
const browserUri = FileAccess.asBrowserUri(originalRemoteUri);
assert.notEqual(originalRemoteUri.scheme, browserUri.scheme);
assert.notStrictEqual(originalRemoteUri.scheme, browserUri.scheme);
});
});

View file

@ -74,6 +74,8 @@ suite('File Service', () => {
assert.strictEqual(registrations.length, 2);
assert.strictEqual(registrations[1].scheme, 'test');
assert.strictEqual(registrations[1].added, false);
service.dispose();
});
test('watch', async () => {
@ -121,5 +123,7 @@ suite('File Service', () => {
assert.strictEqual(disposeCounter, 1);
watcher3Disposable2.dispose();
assert.strictEqual(disposeCounter, 2);
service.dispose();
});
});

View file

@ -2,46 +2,47 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import * as Platform from 'vs/platform/registry/common/platform';
import * as Types from 'vs/base/common/types';
import { Registry } from 'vs/platform/registry/common/platform';
import { isFunction } from 'vs/base/common/types';
suite('Platform / Registry', () => {
test('registry - api', function () {
assert.ok(Types.isFunction(Platform.Registry.add));
assert.ok(Types.isFunction(Platform.Registry.as));
assert.ok(Types.isFunction(Platform.Registry.knows));
assert.ok(isFunction(Registry.add));
assert.ok(isFunction(Registry.as));
assert.ok(isFunction(Registry.knows));
});
test('registry - mixin', function () {
Platform.Registry.add('foo', { bar: true });
Registry.add('foo', { bar: true });
assert.ok(Platform.Registry.knows('foo'));
assert.ok(Platform.Registry.as<any>('foo').bar);
assert.equal(Platform.Registry.as<any>('foo').bar, true);
assert.ok(Registry.knows('foo'));
assert.ok(Registry.as<any>('foo').bar);
assert.equal(Registry.as<any>('foo').bar, true);
});
test('registry - knows, as', function () {
let ext = {};
Platform.Registry.add('knows,as', ext);
Registry.add('knows,as', ext);
assert.ok(Platform.Registry.knows('knows,as'));
assert.ok(!Platform.Registry.knows('knows,as1234'));
assert.ok(Registry.knows('knows,as'));
assert.ok(!Registry.knows('knows,as1234'));
assert.ok(Platform.Registry.as('knows,as') === ext);
assert.ok(Platform.Registry.as('knows,as1234') === null);
assert.ok(Registry.as('knows,as') === ext);
assert.ok(Registry.as('knows,as1234') === null);
});
test('registry - mixin, fails on duplicate ids', function () {
Platform.Registry.add('foo-dup', { bar: true });
Registry.add('foo-dup', { bar: true });
try {
Platform.Registry.add('foo-dup', { bar: false });
Registry.add('foo-dup', { bar: false });
assert.ok(false);
} catch (e) {
assert.ok(true);

View file

@ -29,12 +29,10 @@ suite('Storage', () => {
setup(async () => {
const logService = new NullLogService();
fileService = new FileService(logService);
disposables.add(fileService);
fileService = disposables.add(new FileService(logService));
fileProvider = new DiskFileSystemProvider(logService);
fileProvider = disposables.add(new DiskFileSystemProvider(logService));
disposables.add(fileService.registerProvider(Schemas.file, fileProvider));
disposables.add(fileProvider);
testDir = getRandomTestPath(tmpdir(), 'vsctests', 'storageservice');
});

View file

@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import * as path from 'vs/base/common/path';
import { join } from 'vs/base/common/path';
import { findWindowOnFile } from 'vs/platform/windows/electron-main/windowsFinder';
import { ICodeWindow, IWindowState } from 'vs/platform/windows/electron-main/windows';
import { IWorkspaceIdentifier, toWorkspaceFolders } from 'vs/platform/workspaces/common/workspaces';
@ -18,92 +18,92 @@ import { ICommandAction } from 'vs/platform/actions/common/actions';
import { NativeParsedArgs } from 'vs/platform/environment/common/argv';
import { INativeWindowConfiguration } from 'vs/platform/windows/common/windows';
const fixturesFolder = getPathFromAmdModule(require, './fixtures');
const testWorkspace: IWorkspaceIdentifier = {
id: Date.now().toString(),
configPath: URI.file(path.join(fixturesFolder, 'workspaces.json'))
};
const testWorkspaceFolders = toWorkspaceFolders([{ path: path.join(fixturesFolder, 'vscode_workspace_1_folder') }, { path: path.join(fixturesFolder, 'vscode_workspace_2_folder') }], testWorkspace.configPath, extUriBiasedIgnorePathCase);
const localWorkspaceResolver = (workspace: any) => { return workspace === testWorkspace ? { id: testWorkspace.id, configPath: workspace.configPath, folders: testWorkspaceFolders } : null; };
function createTestCodeWindow(options: { lastFocusTime: number, openedFolderUri?: URI, openedWorkspace?: IWorkspaceIdentifier }): ICodeWindow {
return new class implements ICodeWindow {
onLoad: Event<void> = Event.None;
onReady: Event<void> = Event.None;
onClose: Event<void> = Event.None;
onDestroy: Event<void> = Event.None;
whenClosedOrLoaded: Promise<void> = Promise.resolve();
id: number = -1;
win: Electron.BrowserWindow = undefined!;
config: INativeWindowConfiguration | undefined;
openedWorkspace = options.openedFolderUri ? { id: '', uri: options.openedFolderUri } : options.openedWorkspace;
backupPath?: string | undefined;
remoteAuthority?: string | undefined;
isExtensionDevelopmentHost = false;
isExtensionTestHost = false;
lastFocusTime = options.lastFocusTime;
isFullScreen = false;
isReady = true;
hasHiddenTitleBarStyle = false;
ready(): Promise<ICodeWindow> { throw new Error('Method not implemented.'); }
setReady(): void { throw new Error('Method not implemented.'); }
addTabbedWindow(window: ICodeWindow): void { throw new Error('Method not implemented.'); }
load(config: INativeWindowConfiguration, options: { isReload?: boolean }): void { throw new Error('Method not implemented.'); }
reload(cli?: NativeParsedArgs): void { throw new Error('Method not implemented.'); }
focus(options?: { force: boolean; }): void { throw new Error('Method not implemented.'); }
close(): void { throw new Error('Method not implemented.'); }
getBounds(): Electron.Rectangle { throw new Error('Method not implemented.'); }
send(channel: string, ...args: any[]): void { throw new Error('Method not implemented.'); }
sendWhenReady(channel: string, token: CancellationToken, ...args: any[]): void { throw new Error('Method not implemented.'); }
toggleFullScreen(): void { throw new Error('Method not implemented.'); }
isMinimized(): boolean { throw new Error('Method not implemented.'); }
setRepresentedFilename(name: string): void { throw new Error('Method not implemented.'); }
getRepresentedFilename(): string | undefined { throw new Error('Method not implemented.'); }
setDocumentEdited(edited: boolean): void { throw new Error('Method not implemented.'); }
isDocumentEdited(): boolean { throw new Error('Method not implemented.'); }
handleTitleDoubleClick(): void { throw new Error('Method not implemented.'); }
updateTouchBar(items: UriDto<ICommandAction>[][]): void { throw new Error('Method not implemented.'); }
serializeWindowState(): IWindowState { throw new Error('Method not implemented'); }
dispose(): void { }
};
}
const vscodeFolderWindow: ICodeWindow = createTestCodeWindow({ lastFocusTime: 1, openedFolderUri: URI.file(path.join(fixturesFolder, 'vscode_folder')) });
const lastActiveWindow: ICodeWindow = createTestCodeWindow({ lastFocusTime: 3, openedFolderUri: undefined });
const noVscodeFolderWindow: ICodeWindow = createTestCodeWindow({ lastFocusTime: 2, openedFolderUri: URI.file(path.join(fixturesFolder, 'no_vscode_folder')) });
const windows: ICodeWindow[] = [
vscodeFolderWindow,
lastActiveWindow,
noVscodeFolderWindow,
];
suite('WindowsFinder', () => {
const fixturesFolder = getPathFromAmdModule(require, './fixtures');
const testWorkspace: IWorkspaceIdentifier = {
id: Date.now().toString(),
configPath: URI.file(join(fixturesFolder, 'workspaces.json'))
};
const testWorkspaceFolders = toWorkspaceFolders([{ path: join(fixturesFolder, 'vscode_workspace_1_folder') }, { path: join(fixturesFolder, 'vscode_workspace_2_folder') }], testWorkspace.configPath, extUriBiasedIgnorePathCase);
const localWorkspaceResolver = (workspace: any) => { return workspace === testWorkspace ? { id: testWorkspace.id, configPath: workspace.configPath, folders: testWorkspaceFolders } : null; };
function createTestCodeWindow(options: { lastFocusTime: number, openedFolderUri?: URI, openedWorkspace?: IWorkspaceIdentifier }): ICodeWindow {
return new class implements ICodeWindow {
onLoad: Event<void> = Event.None;
onReady: Event<void> = Event.None;
onClose: Event<void> = Event.None;
onDestroy: Event<void> = Event.None;
whenClosedOrLoaded: Promise<void> = Promise.resolve();
id: number = -1;
win: Electron.BrowserWindow = undefined!;
config: INativeWindowConfiguration | undefined;
openedWorkspace = options.openedFolderUri ? { id: '', uri: options.openedFolderUri } : options.openedWorkspace;
backupPath?: string | undefined;
remoteAuthority?: string | undefined;
isExtensionDevelopmentHost = false;
isExtensionTestHost = false;
lastFocusTime = options.lastFocusTime;
isFullScreen = false;
isReady = true;
hasHiddenTitleBarStyle = false;
ready(): Promise<ICodeWindow> { throw new Error('Method not implemented.'); }
setReady(): void { throw new Error('Method not implemented.'); }
addTabbedWindow(window: ICodeWindow): void { throw new Error('Method not implemented.'); }
load(config: INativeWindowConfiguration, options: { isReload?: boolean }): void { throw new Error('Method not implemented.'); }
reload(cli?: NativeParsedArgs): void { throw new Error('Method not implemented.'); }
focus(options?: { force: boolean; }): void { throw new Error('Method not implemented.'); }
close(): void { throw new Error('Method not implemented.'); }
getBounds(): Electron.Rectangle { throw new Error('Method not implemented.'); }
send(channel: string, ...args: any[]): void { throw new Error('Method not implemented.'); }
sendWhenReady(channel: string, token: CancellationToken, ...args: any[]): void { throw new Error('Method not implemented.'); }
toggleFullScreen(): void { throw new Error('Method not implemented.'); }
isMinimized(): boolean { throw new Error('Method not implemented.'); }
setRepresentedFilename(name: string): void { throw new Error('Method not implemented.'); }
getRepresentedFilename(): string | undefined { throw new Error('Method not implemented.'); }
setDocumentEdited(edited: boolean): void { throw new Error('Method not implemented.'); }
isDocumentEdited(): boolean { throw new Error('Method not implemented.'); }
handleTitleDoubleClick(): void { throw new Error('Method not implemented.'); }
updateTouchBar(items: UriDto<ICommandAction>[][]): void { throw new Error('Method not implemented.'); }
serializeWindowState(): IWindowState { throw new Error('Method not implemented'); }
dispose(): void { }
};
}
const vscodeFolderWindow: ICodeWindow = createTestCodeWindow({ lastFocusTime: 1, openedFolderUri: URI.file(join(fixturesFolder, 'vscode_folder')) });
const lastActiveWindow: ICodeWindow = createTestCodeWindow({ lastFocusTime: 3, openedFolderUri: undefined });
const noVscodeFolderWindow: ICodeWindow = createTestCodeWindow({ lastFocusTime: 2, openedFolderUri: URI.file(join(fixturesFolder, 'no_vscode_folder')) });
const windows: ICodeWindow[] = [
vscodeFolderWindow,
lastActiveWindow,
noVscodeFolderWindow,
];
test('New window without folder when no windows exist', () => {
assert.strictEqual(findWindowOnFile([], URI.file('nonexisting'), localWorkspaceResolver), undefined);
assert.strictEqual(findWindowOnFile([], URI.file(path.join(fixturesFolder, 'no_vscode_folder', 'file.txt')), localWorkspaceResolver), undefined);
assert.strictEqual(findWindowOnFile([], URI.file(join(fixturesFolder, 'no_vscode_folder', 'file.txt')), localWorkspaceResolver), undefined);
});
test('Existing window with folder', () => {
assert.strictEqual(findWindowOnFile(windows, URI.file(path.join(fixturesFolder, 'no_vscode_folder', 'file.txt')), localWorkspaceResolver), noVscodeFolderWindow);
assert.strictEqual(findWindowOnFile(windows, URI.file(join(fixturesFolder, 'no_vscode_folder', 'file.txt')), localWorkspaceResolver), noVscodeFolderWindow);
assert.strictEqual(findWindowOnFile(windows, URI.file(path.join(fixturesFolder, 'vscode_folder', 'file.txt')), localWorkspaceResolver), vscodeFolderWindow);
assert.strictEqual(findWindowOnFile(windows, URI.file(join(fixturesFolder, 'vscode_folder', 'file.txt')), localWorkspaceResolver), vscodeFolderWindow);
const window: ICodeWindow = createTestCodeWindow({ lastFocusTime: 1, openedFolderUri: URI.file(path.join(fixturesFolder, 'vscode_folder', 'nested_folder')) });
assert.strictEqual(findWindowOnFile([window], URI.file(path.join(fixturesFolder, 'vscode_folder', 'nested_folder', 'subfolder', 'file.txt')), localWorkspaceResolver), window);
const window: ICodeWindow = createTestCodeWindow({ lastFocusTime: 1, openedFolderUri: URI.file(join(fixturesFolder, 'vscode_folder', 'nested_folder')) });
assert.strictEqual(findWindowOnFile([window], URI.file(join(fixturesFolder, 'vscode_folder', 'nested_folder', 'subfolder', 'file.txt')), localWorkspaceResolver), window);
});
test('More specific existing window wins', () => {
const window: ICodeWindow = createTestCodeWindow({ lastFocusTime: 2, openedFolderUri: URI.file(path.join(fixturesFolder, 'no_vscode_folder')) });
const nestedFolderWindow: ICodeWindow = createTestCodeWindow({ lastFocusTime: 1, openedFolderUri: URI.file(path.join(fixturesFolder, 'no_vscode_folder', 'nested_folder')) });
assert.strictEqual(findWindowOnFile([window, nestedFolderWindow], URI.file(path.join(fixturesFolder, 'no_vscode_folder', 'nested_folder', 'subfolder', 'file.txt')), localWorkspaceResolver), nestedFolderWindow);
const window: ICodeWindow = createTestCodeWindow({ lastFocusTime: 2, openedFolderUri: URI.file(join(fixturesFolder, 'no_vscode_folder')) });
const nestedFolderWindow: ICodeWindow = createTestCodeWindow({ lastFocusTime: 1, openedFolderUri: URI.file(join(fixturesFolder, 'no_vscode_folder', 'nested_folder')) });
assert.strictEqual(findWindowOnFile([window, nestedFolderWindow], URI.file(join(fixturesFolder, 'no_vscode_folder', 'nested_folder', 'subfolder', 'file.txt')), localWorkspaceResolver), nestedFolderWindow);
});
test('Workspace folder wins', () => {
const window: ICodeWindow = createTestCodeWindow({ lastFocusTime: 1, openedWorkspace: testWorkspace });
assert.strictEqual(findWindowOnFile([window], URI.file(path.join(fixturesFolder, 'vscode_workspace_2_folder', 'nested_vscode_folder', 'subfolder', 'file.txt')), localWorkspaceResolver), window);
assert.strictEqual(findWindowOnFile([window], URI.file(join(fixturesFolder, 'vscode_workspace_2_folder', 'nested_vscode_folder', 'subfolder', 'file.txt')), localWorkspaceResolver), window);
});
});

View file

@ -4,78 +4,79 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import * as os from 'os';
import * as path from 'vs/base/common/path';
import { tmpdir } from 'os';
import { join } from 'vs/base/common/path';
import { restoreWindowsState, getWindowsStateStoreData, IWindowsState, IWindowState } from 'vs/platform/windows/electron-main/windowsStateHandler';
import { IWindowState as IWindowUIState, WindowMode } from 'vs/platform/windows/electron-main/windows';
import { IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { URI } from 'vs/base/common/uri';
function getUIState(): IWindowUIState {
return {
x: 0,
y: 10,
width: 100,
height: 200,
mode: 0
};
}
function toWorkspace(uri: URI): IWorkspaceIdentifier {
return {
id: '1234',
configPath: uri
};
}
function assertEqualURI(u1: URI | undefined, u2: URI | undefined, message?: string): void {
assert.strictEqual(u1 && u1.toString(), u2 && u2.toString(), message);
}
function assertEqualWorkspace(w1: IWorkspaceIdentifier | undefined, w2: IWorkspaceIdentifier | undefined, message?: string): void {
if (!w1 || !w2) {
assert.strictEqual(w1, w2, message);
return;
}
assert.strictEqual(w1.id, w2.id, message);
assertEqualURI(w1.configPath, w2.configPath, message);
}
function assertEqualWindowState(expected: IWindowState | undefined, actual: IWindowState | undefined, message?: string) {
if (!expected || !actual) {
assert.deepEqual(expected, actual, message);
return;
}
assert.strictEqual(expected.backupPath, actual.backupPath, message);
assertEqualURI(expected.folderUri, actual.folderUri, message);
assert.strictEqual(expected.remoteAuthority, actual.remoteAuthority, message);
assertEqualWorkspace(expected.workspace, actual.workspace, message);
assert.deepEqual(expected.uiState, actual.uiState, message);
}
function assertEqualWindowsState(expected: IWindowsState, actual: IWindowsState, message?: string) {
assertEqualWindowState(expected.lastPluginDevelopmentHostWindow, actual.lastPluginDevelopmentHostWindow, message);
assertEqualWindowState(expected.lastActiveWindow, actual.lastActiveWindow, message);
assert.strictEqual(expected.openedWindows.length, actual.openedWindows.length, message);
for (let i = 0; i < expected.openedWindows.length; i++) {
assertEqualWindowState(expected.openedWindows[i], actual.openedWindows[i], message);
}
}
function assertRestoring(state: IWindowsState, message?: string) {
const stored = getWindowsStateStoreData(state);
const restored = restoreWindowsState(stored);
assertEqualWindowsState(state, restored, message);
}
const testBackupPath1 = path.join(os.tmpdir(), 'windowStateTest', 'backupFolder1');
const testBackupPath2 = path.join(os.tmpdir(), 'windowStateTest', 'backupFolder2');
const testWSPath = URI.file(path.join(os.tmpdir(), 'windowStateTest', 'test.code-workspace'));
const testFolderURI = URI.file(path.join(os.tmpdir(), 'windowStateTest', 'testFolder'));
const testRemoteFolderURI = URI.parse('foo://bar/c/d');
suite('Windows State Storing', () => {
function getUIState(): IWindowUIState {
return {
x: 0,
y: 10,
width: 100,
height: 200,
mode: 0
};
}
function toWorkspace(uri: URI): IWorkspaceIdentifier {
return {
id: '1234',
configPath: uri
};
}
function assertEqualURI(u1: URI | undefined, u2: URI | undefined, message?: string): void {
assert.strictEqual(u1 && u1.toString(), u2 && u2.toString(), message);
}
function assertEqualWorkspace(w1: IWorkspaceIdentifier | undefined, w2: IWorkspaceIdentifier | undefined, message?: string): void {
if (!w1 || !w2) {
assert.strictEqual(w1, w2, message);
return;
}
assert.strictEqual(w1.id, w2.id, message);
assertEqualURI(w1.configPath, w2.configPath, message);
}
function assertEqualWindowState(expected: IWindowState | undefined, actual: IWindowState | undefined, message?: string) {
if (!expected || !actual) {
assert.deepStrictEqual(expected, actual, message);
return;
}
assert.strictEqual(expected.backupPath, actual.backupPath, message);
assertEqualURI(expected.folderUri, actual.folderUri, message);
assert.strictEqual(expected.remoteAuthority, actual.remoteAuthority, message);
assertEqualWorkspace(expected.workspace, actual.workspace, message);
assert.deepStrictEqual(expected.uiState, actual.uiState, message);
}
function assertEqualWindowsState(expected: IWindowsState, actual: IWindowsState, message?: string) {
assertEqualWindowState(expected.lastPluginDevelopmentHostWindow, actual.lastPluginDevelopmentHostWindow, message);
assertEqualWindowState(expected.lastActiveWindow, actual.lastActiveWindow, message);
assert.strictEqual(expected.openedWindows.length, actual.openedWindows.length, message);
for (let i = 0; i < expected.openedWindows.length; i++) {
assertEqualWindowState(expected.openedWindows[i], actual.openedWindows[i], message);
}
}
function assertRestoring(state: IWindowsState, message?: string) {
const stored = getWindowsStateStoreData(state);
const restored = restoreWindowsState(stored);
assertEqualWindowsState(state, restored, message);
}
const testBackupPath1 = join(tmpdir(), 'windowStateTest', 'backupFolder1');
const testBackupPath2 = join(tmpdir(), 'windowStateTest', 'backupFolder2');
const testWSPath = URI.file(join(tmpdir(), 'windowStateTest', 'test.code-workspace'));
const testFolderURI = URI.file(join(tmpdir(), 'windowStateTest', 'testFolder'));
const testRemoteFolderURI = URI.parse('foo://bar/c/d');
test('storing and restoring', () => {
let windowState: IWindowsState;
windowState = {

View file

@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import * as path from 'vs/base/common/path';
import { join } from 'vs/base/common/path';
import { Workspace, WorkspaceFolder } from 'vs/platform/workspace/common/workspace';
import { URI } from 'vs/base/common/uri';
import { IRawFileWorkspaceFolder, toWorkspaceFolders } from 'vs/platform/workspaces/common/workspaces';
@ -16,15 +16,15 @@ suite('Workspace', () => {
const fileFolder = isWindows ? 'c:\\src' : '/src';
const abcFolder = isWindows ? 'c:\\abc' : '/abc';
const testFolderUri = URI.file(path.join(fileFolder, 'test'));
const mainFolderUri = URI.file(path.join(fileFolder, 'main'));
const test1FolderUri = URI.file(path.join(fileFolder, 'test1'));
const test2FolderUri = URI.file(path.join(fileFolder, 'test2'));
const test3FolderUri = URI.file(path.join(fileFolder, 'test3'));
const abcTest1FolderUri = URI.file(path.join(abcFolder, 'test1'));
const abcTest3FolderUri = URI.file(path.join(abcFolder, 'test3'));
const testFolderUri = URI.file(join(fileFolder, 'test'));
const mainFolderUri = URI.file(join(fileFolder, 'main'));
const test1FolderUri = URI.file(join(fileFolder, 'test1'));
const test2FolderUri = URI.file(join(fileFolder, 'test2'));
const test3FolderUri = URI.file(join(fileFolder, 'test3'));
const abcTest1FolderUri = URI.file(join(abcFolder, 'test1'));
const abcTest3FolderUri = URI.file(join(abcFolder, 'test3'));
const workspaceConfigUri = URI.file(path.join(fileFolder, 'test.code-workspace'));
const workspaceConfigUri = URI.file(join(fileFolder, 'test.code-workspace'));
test('getFolder returns the folder with given uri', () => {
const expected = new WorkspaceFolder({ uri: testFolderUri, name: '', index: 2 });
@ -32,187 +32,187 @@ suite('Workspace', () => {
const actual = testObject.getFolder(expected.uri);
assert.equal(actual, expected);
assert.strictEqual(actual, expected);
});
test('getFolder returns the folder if the uri is sub', () => {
const expected = new WorkspaceFolder({ uri: testFolderUri, name: '', index: 0 });
let testObject = new Workspace('', [expected, new WorkspaceFolder({ uri: mainFolderUri, name: '', index: 1 }), new WorkspaceFolder({ uri: URI.file('/src/code'), name: '', index: 2 })], null, () => !isLinux);
const actual = testObject.getFolder(URI.file(path.join(fileFolder, 'test/a')));
const actual = testObject.getFolder(URI.file(join(fileFolder, 'test/a')));
assert.equal(actual, expected);
assert.strictEqual(actual, expected);
});
test('getFolder returns the closest folder if the uri is sub', () => {
const expected = new WorkspaceFolder({ uri: testFolderUri, name: '', index: 2 });
let testObject = new Workspace('', [new WorkspaceFolder({ uri: mainFolderUri, name: '', index: 0 }), new WorkspaceFolder({ uri: URI.file('/src/code'), name: '', index: 1 }), expected], null, () => !isLinux);
const actual = testObject.getFolder(URI.file(path.join(fileFolder, 'test/a')));
const actual = testObject.getFolder(URI.file(join(fileFolder, 'test/a')));
assert.equal(actual, expected);
assert.strictEqual(actual, expected);
});
test('getFolder returns the folder even if the uri has query path', () => {
const expected = new WorkspaceFolder({ uri: testFolderUri, name: '', index: 2 });
let testObject = new Workspace('', [new WorkspaceFolder({ uri: mainFolderUri, name: '', index: 0 }), new WorkspaceFolder({ uri: URI.file('/src/code'), name: '', index: 1 }), expected], null, () => !isLinux);
const actual = testObject.getFolder(URI.file(path.join(fileFolder, 'test/a')).with({ query: 'somequery' }));
const actual = testObject.getFolder(URI.file(join(fileFolder, 'test/a')).with({ query: 'somequery' }));
assert.equal(actual, expected);
assert.strictEqual(actual, expected);
});
test('getFolder returns null if the uri is not sub', () => {
let testObject = new Workspace('', [new WorkspaceFolder({ uri: testFolderUri, name: '', index: 0 }), new WorkspaceFolder({ uri: URI.file('/src/code'), name: '', index: 1 })], null, () => !isLinux);
const actual = testObject.getFolder(URI.file(path.join(fileFolder, 'main/a')));
const actual = testObject.getFolder(URI.file(join(fileFolder, 'main/a')));
assert.equal(actual, undefined);
assert.strictEqual(actual, null);
});
test('toWorkspaceFolders with single absolute folder', () => {
const actual = toWorkspaceFolders([{ path: '/src/test' }], workspaceConfigUri, extUriBiasedIgnorePathCase);
assert.equal(actual.length, 1);
assert.equal(actual[0].uri.fsPath, testFolderUri.fsPath);
assert.equal((<IRawFileWorkspaceFolder>actual[0].raw).path, '/src/test');
assert.equal(actual[0].index, 0);
assert.equal(actual[0].name, 'test');
assert.strictEqual(actual.length, 1);
assert.strictEqual(actual[0].uri.fsPath, testFolderUri.fsPath);
assert.strictEqual((<IRawFileWorkspaceFolder>actual[0].raw).path, '/src/test');
assert.strictEqual(actual[0].index, 0);
assert.strictEqual(actual[0].name, 'test');
});
test('toWorkspaceFolders with single relative folder', () => {
const actual = toWorkspaceFolders([{ path: './test' }], workspaceConfigUri, extUriBiasedIgnorePathCase);
assert.equal(actual.length, 1);
assert.equal(actual[0].uri.fsPath, testFolderUri.fsPath);
assert.equal((<IRawFileWorkspaceFolder>actual[0].raw).path, './test');
assert.equal(actual[0].index, 0);
assert.equal(actual[0].name, 'test');
assert.strictEqual(actual.length, 1);
assert.strictEqual(actual[0].uri.fsPath, testFolderUri.fsPath);
assert.strictEqual((<IRawFileWorkspaceFolder>actual[0].raw).path, './test');
assert.strictEqual(actual[0].index, 0);
assert.strictEqual(actual[0].name, 'test');
});
test('toWorkspaceFolders with single absolute folder with name', () => {
const actual = toWorkspaceFolders([{ path: '/src/test', name: 'hello' }], workspaceConfigUri, extUriBiasedIgnorePathCase);
assert.equal(actual.length, 1);
assert.strictEqual(actual.length, 1);
assert.equal(actual[0].uri.fsPath, testFolderUri.fsPath);
assert.equal((<IRawFileWorkspaceFolder>actual[0].raw).path, '/src/test');
assert.equal(actual[0].index, 0);
assert.equal(actual[0].name, 'hello');
assert.strictEqual(actual[0].uri.fsPath, testFolderUri.fsPath);
assert.strictEqual((<IRawFileWorkspaceFolder>actual[0].raw).path, '/src/test');
assert.strictEqual(actual[0].index, 0);
assert.strictEqual(actual[0].name, 'hello');
});
test('toWorkspaceFolders with multiple unique absolute folders', () => {
const actual = toWorkspaceFolders([{ path: '/src/test2' }, { path: '/src/test3' }, { path: '/src/test1' }], workspaceConfigUri, extUriBiasedIgnorePathCase);
assert.equal(actual.length, 3);
assert.equal(actual[0].uri.fsPath, test2FolderUri.fsPath);
assert.equal((<IRawFileWorkspaceFolder>actual[0].raw).path, '/src/test2');
assert.equal(actual[0].index, 0);
assert.equal(actual[0].name, 'test2');
assert.strictEqual(actual.length, 3);
assert.strictEqual(actual[0].uri.fsPath, test2FolderUri.fsPath);
assert.strictEqual((<IRawFileWorkspaceFolder>actual[0].raw).path, '/src/test2');
assert.strictEqual(actual[0].index, 0);
assert.strictEqual(actual[0].name, 'test2');
assert.equal(actual[1].uri.fsPath, test3FolderUri.fsPath);
assert.equal((<IRawFileWorkspaceFolder>actual[1].raw).path, '/src/test3');
assert.equal(actual[1].index, 1);
assert.equal(actual[1].name, 'test3');
assert.strictEqual(actual[1].uri.fsPath, test3FolderUri.fsPath);
assert.strictEqual((<IRawFileWorkspaceFolder>actual[1].raw).path, '/src/test3');
assert.strictEqual(actual[1].index, 1);
assert.strictEqual(actual[1].name, 'test3');
assert.equal(actual[2].uri.fsPath, test1FolderUri.fsPath);
assert.equal((<IRawFileWorkspaceFolder>actual[2].raw).path, '/src/test1');
assert.equal(actual[2].index, 2);
assert.equal(actual[2].name, 'test1');
assert.strictEqual(actual[2].uri.fsPath, test1FolderUri.fsPath);
assert.strictEqual((<IRawFileWorkspaceFolder>actual[2].raw).path, '/src/test1');
assert.strictEqual(actual[2].index, 2);
assert.strictEqual(actual[2].name, 'test1');
});
test('toWorkspaceFolders with multiple unique absolute folders with names', () => {
const actual = toWorkspaceFolders([{ path: '/src/test2' }, { path: '/src/test3', name: 'noName' }, { path: '/src/test1' }], workspaceConfigUri, extUriBiasedIgnorePathCase);
assert.equal(actual.length, 3);
assert.equal(actual[0].uri.fsPath, test2FolderUri.fsPath);
assert.equal((<IRawFileWorkspaceFolder>actual[0].raw).path, '/src/test2');
assert.equal(actual[0].index, 0);
assert.equal(actual[0].name, 'test2');
assert.strictEqual(actual.length, 3);
assert.strictEqual(actual[0].uri.fsPath, test2FolderUri.fsPath);
assert.strictEqual((<IRawFileWorkspaceFolder>actual[0].raw).path, '/src/test2');
assert.strictEqual(actual[0].index, 0);
assert.strictEqual(actual[0].name, 'test2');
assert.equal(actual[1].uri.fsPath, test3FolderUri.fsPath);
assert.equal((<IRawFileWorkspaceFolder>actual[1].raw).path, '/src/test3');
assert.equal(actual[1].index, 1);
assert.equal(actual[1].name, 'noName');
assert.strictEqual(actual[1].uri.fsPath, test3FolderUri.fsPath);
assert.strictEqual((<IRawFileWorkspaceFolder>actual[1].raw).path, '/src/test3');
assert.strictEqual(actual[1].index, 1);
assert.strictEqual(actual[1].name, 'noName');
assert.equal(actual[2].uri.fsPath, test1FolderUri.fsPath);
assert.equal((<IRawFileWorkspaceFolder>actual[2].raw).path, '/src/test1');
assert.equal(actual[2].index, 2);
assert.equal(actual[2].name, 'test1');
assert.strictEqual(actual[2].uri.fsPath, test1FolderUri.fsPath);
assert.strictEqual((<IRawFileWorkspaceFolder>actual[2].raw).path, '/src/test1');
assert.strictEqual(actual[2].index, 2);
assert.strictEqual(actual[2].name, 'test1');
});
test('toWorkspaceFolders with multiple unique absolute and relative folders', () => {
const actual = toWorkspaceFolders([{ path: '/src/test2' }, { path: '/abc/test3', name: 'noName' }, { path: './test1' }], workspaceConfigUri, extUriBiasedIgnorePathCase);
assert.equal(actual.length, 3);
assert.equal(actual[0].uri.fsPath, test2FolderUri.fsPath);
assert.equal((<IRawFileWorkspaceFolder>actual[0].raw).path, '/src/test2');
assert.equal(actual[0].index, 0);
assert.equal(actual[0].name, 'test2');
assert.strictEqual(actual.length, 3);
assert.strictEqual(actual[0].uri.fsPath, test2FolderUri.fsPath);
assert.strictEqual((<IRawFileWorkspaceFolder>actual[0].raw).path, '/src/test2');
assert.strictEqual(actual[0].index, 0);
assert.strictEqual(actual[0].name, 'test2');
assert.equal(actual[1].uri.fsPath, abcTest3FolderUri.fsPath);
assert.equal((<IRawFileWorkspaceFolder>actual[1].raw).path, '/abc/test3');
assert.equal(actual[1].index, 1);
assert.equal(actual[1].name, 'noName');
assert.strictEqual(actual[1].uri.fsPath, abcTest3FolderUri.fsPath);
assert.strictEqual((<IRawFileWorkspaceFolder>actual[1].raw).path, '/abc/test3');
assert.strictEqual(actual[1].index, 1);
assert.strictEqual(actual[1].name, 'noName');
assert.equal(actual[2].uri.fsPath, test1FolderUri.fsPath);
assert.equal((<IRawFileWorkspaceFolder>actual[2].raw).path, './test1');
assert.equal(actual[2].index, 2);
assert.equal(actual[2].name, 'test1');
assert.strictEqual(actual[2].uri.fsPath, test1FolderUri.fsPath);
assert.strictEqual((<IRawFileWorkspaceFolder>actual[2].raw).path, './test1');
assert.strictEqual(actual[2].index, 2);
assert.strictEqual(actual[2].name, 'test1');
});
test('toWorkspaceFolders with multiple absolute folders with duplicates', () => {
const actual = toWorkspaceFolders([{ path: '/src/test2' }, { path: '/src/test2', name: 'noName' }, { path: '/src/test1' }], workspaceConfigUri, extUriBiasedIgnorePathCase);
assert.equal(actual.length, 2);
assert.equal(actual[0].uri.fsPath, test2FolderUri.fsPath);
assert.equal((<IRawFileWorkspaceFolder>actual[0].raw).path, '/src/test2');
assert.equal(actual[0].index, 0);
assert.equal(actual[0].name, 'test2');
assert.strictEqual(actual.length, 2);
assert.strictEqual(actual[0].uri.fsPath, test2FolderUri.fsPath);
assert.strictEqual((<IRawFileWorkspaceFolder>actual[0].raw).path, '/src/test2');
assert.strictEqual(actual[0].index, 0);
assert.strictEqual(actual[0].name, 'test2');
assert.equal(actual[1].uri.fsPath, test1FolderUri.fsPath);
assert.equal((<IRawFileWorkspaceFolder>actual[1].raw).path, '/src/test1');
assert.equal(actual[1].index, 1);
assert.equal(actual[1].name, 'test1');
assert.strictEqual(actual[1].uri.fsPath, test1FolderUri.fsPath);
assert.strictEqual((<IRawFileWorkspaceFolder>actual[1].raw).path, '/src/test1');
assert.strictEqual(actual[1].index, 1);
assert.strictEqual(actual[1].name, 'test1');
});
test('toWorkspaceFolders with multiple absolute and relative folders with duplicates', () => {
const actual = toWorkspaceFolders([{ path: '/src/test2' }, { path: '/src/test3', name: 'noName' }, { path: './test3' }, { path: '/abc/test1' }], workspaceConfigUri, extUriBiasedIgnorePathCase);
assert.equal(actual.length, 3);
assert.equal(actual[0].uri.fsPath, test2FolderUri.fsPath);
assert.equal((<IRawFileWorkspaceFolder>actual[0].raw).path, '/src/test2');
assert.equal(actual[0].index, 0);
assert.equal(actual[0].name, 'test2');
assert.strictEqual(actual.length, 3);
assert.strictEqual(actual[0].uri.fsPath, test2FolderUri.fsPath);
assert.strictEqual((<IRawFileWorkspaceFolder>actual[0].raw).path, '/src/test2');
assert.strictEqual(actual[0].index, 0);
assert.strictEqual(actual[0].name, 'test2');
assert.equal(actual[1].uri.fsPath, test3FolderUri.fsPath);
assert.equal((<IRawFileWorkspaceFolder>actual[1].raw).path, '/src/test3');
assert.equal(actual[1].index, 1);
assert.equal(actual[1].name, 'noName');
assert.strictEqual(actual[1].uri.fsPath, test3FolderUri.fsPath);
assert.strictEqual((<IRawFileWorkspaceFolder>actual[1].raw).path, '/src/test3');
assert.strictEqual(actual[1].index, 1);
assert.strictEqual(actual[1].name, 'noName');
assert.equal(actual[2].uri.fsPath, abcTest1FolderUri.fsPath);
assert.equal((<IRawFileWorkspaceFolder>actual[2].raw).path, '/abc/test1');
assert.equal(actual[2].index, 2);
assert.equal(actual[2].name, 'test1');
assert.strictEqual(actual[2].uri.fsPath, abcTest1FolderUri.fsPath);
assert.strictEqual((<IRawFileWorkspaceFolder>actual[2].raw).path, '/abc/test1');
assert.strictEqual(actual[2].index, 2);
assert.strictEqual(actual[2].name, 'test1');
});
test('toWorkspaceFolders with multiple absolute and relative folders with invalid paths', () => {
const actual = toWorkspaceFolders([{ path: '/src/test2' }, { path: '', name: 'noName' }, { path: './test3' }, { path: '/abc/test1' }], workspaceConfigUri, extUriBiasedIgnorePathCase);
assert.equal(actual.length, 3);
assert.equal(actual[0].uri.fsPath, test2FolderUri.fsPath);
assert.equal((<IRawFileWorkspaceFolder>actual[0].raw).path, '/src/test2');
assert.equal(actual[0].index, 0);
assert.equal(actual[0].name, 'test2');
assert.strictEqual(actual.length, 3);
assert.strictEqual(actual[0].uri.fsPath, test2FolderUri.fsPath);
assert.strictEqual((<IRawFileWorkspaceFolder>actual[0].raw).path, '/src/test2');
assert.strictEqual(actual[0].index, 0);
assert.strictEqual(actual[0].name, 'test2');
assert.equal(actual[1].uri.fsPath, test3FolderUri.fsPath);
assert.equal((<IRawFileWorkspaceFolder>actual[1].raw).path, './test3');
assert.equal(actual[1].index, 1);
assert.equal(actual[1].name, 'test3');
assert.strictEqual(actual[1].uri.fsPath, test3FolderUri.fsPath);
assert.strictEqual((<IRawFileWorkspaceFolder>actual[1].raw).path, './test3');
assert.strictEqual(actual[1].index, 1);
assert.strictEqual(actual[1].name, 'test3');
assert.equal(actual[2].uri.fsPath, abcTest1FolderUri.fsPath);
assert.equal((<IRawFileWorkspaceFolder>actual[2].raw).path, '/abc/test1');
assert.equal(actual[2].index, 2);
assert.equal(actual[2].name, 'test1');
assert.strictEqual(actual[2].uri.fsPath, abcTest1FolderUri.fsPath);
assert.strictEqual((<IRawFileWorkspaceFolder>actual[2].raw).path, '/abc/test1');
assert.strictEqual(actual[2].index, 2);
assert.strictEqual(actual[2].name, 'test1');
});
});

View file

@ -8,6 +8,7 @@ import { URI } from 'vs/base/common/uri';
import { hasWorkspaceFileExtension, toWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
suite('Workspaces', () => {
test('hasWorkspaceFileExtension', () => {
assert.strictEqual(hasWorkspaceFileExtension('something'), false);
assert.strictEqual(hasWorkspaceFileExtension('something.code-workspace'), true);

View file

@ -4,65 +4,66 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import * as os from 'os';
import * as path from 'vs/base/common/path';
import { tmpdir } from 'os';
import { join } from 'vs/base/common/path';
import { IWorkspaceIdentifier, IRecentlyOpened, isRecentFolder, IRecentFolder, IRecentWorkspace, toStoreData, restoreRecentlyOpened } from 'vs/platform/workspaces/common/workspaces';
import { URI } from 'vs/base/common/uri';
import { NullLogService } from 'vs/platform/log/common/log';
function toWorkspace(uri: URI): IWorkspaceIdentifier {
return {
id: '1234',
configPath: uri
};
}
function assertEqualURI(u1: URI | undefined, u2: URI | undefined, message?: string): void {
assert.strictEqual(u1 && u1.toString(), u2 && u2.toString(), message);
}
function assertEqualWorkspace(w1: IWorkspaceIdentifier | undefined, w2: IWorkspaceIdentifier | undefined, message?: string): void {
if (!w1 || !w2) {
assert.strictEqual(w1, w2, message);
return;
}
assert.strictEqual(w1.id, w2.id, message);
assertEqualURI(w1.configPath, w2.configPath, message);
}
function assertEqualRecentlyOpened(actual: IRecentlyOpened, expected: IRecentlyOpened, message?: string) {
assert.strictEqual(actual.files.length, expected.files.length, message);
for (let i = 0; i < actual.files.length; i++) {
assertEqualURI(actual.files[i].fileUri, expected.files[i].fileUri, message);
assert.strictEqual(actual.files[i].label, expected.files[i].label);
}
assert.strictEqual(actual.workspaces.length, expected.workspaces.length, message);
for (let i = 0; i < actual.workspaces.length; i++) {
let expectedRecent = expected.workspaces[i];
let actualRecent = actual.workspaces[i];
if (isRecentFolder(actualRecent)) {
assertEqualURI(actualRecent.folderUri, (<IRecentFolder>expectedRecent).folderUri, message);
} else {
assertEqualWorkspace(actualRecent.workspace, (<IRecentWorkspace>expectedRecent).workspace, message);
}
assert.strictEqual(actualRecent.label, expectedRecent.label);
}
}
function assertRestoring(state: IRecentlyOpened, message?: string) {
const stored = toStoreData(state);
const restored = restoreRecentlyOpened(stored, new NullLogService());
assertEqualRecentlyOpened(state, restored, message);
}
const testWSPath = URI.file(path.join(os.tmpdir(), 'windowStateTest', 'test.code-workspace'));
const testFileURI = URI.file(path.join(os.tmpdir(), 'windowStateTest', 'testFile.txt'));
const testFolderURI = URI.file(path.join(os.tmpdir(), 'windowStateTest', 'testFolder'));
const testRemoteFolderURI = URI.parse('foo://bar/c/e');
const testRemoteFileURI = URI.parse('foo://bar/c/d.txt');
const testRemoteWSURI = URI.parse('foo://bar/c/test.code-workspace');
suite('History Storage', () => {
function toWorkspace(uri: URI): IWorkspaceIdentifier {
return {
id: '1234',
configPath: uri
};
}
function assertEqualURI(u1: URI | undefined, u2: URI | undefined, message?: string): void {
assert.strictEqual(u1 && u1.toString(), u2 && u2.toString(), message);
}
function assertEqualWorkspace(w1: IWorkspaceIdentifier | undefined, w2: IWorkspaceIdentifier | undefined, message?: string): void {
if (!w1 || !w2) {
assert.strictEqual(w1, w2, message);
return;
}
assert.strictEqual(w1.id, w2.id, message);
assertEqualURI(w1.configPath, w2.configPath, message);
}
function assertEqualRecentlyOpened(actual: IRecentlyOpened, expected: IRecentlyOpened, message?: string) {
assert.strictEqual(actual.files.length, expected.files.length, message);
for (let i = 0; i < actual.files.length; i++) {
assertEqualURI(actual.files[i].fileUri, expected.files[i].fileUri, message);
assert.strictEqual(actual.files[i].label, expected.files[i].label);
}
assert.strictEqual(actual.workspaces.length, expected.workspaces.length, message);
for (let i = 0; i < actual.workspaces.length; i++) {
let expectedRecent = expected.workspaces[i];
let actualRecent = actual.workspaces[i];
if (isRecentFolder(actualRecent)) {
assertEqualURI(actualRecent.folderUri, (<IRecentFolder>expectedRecent).folderUri, message);
} else {
assertEqualWorkspace(actualRecent.workspace, (<IRecentWorkspace>expectedRecent).workspace, message);
}
assert.strictEqual(actualRecent.label, expectedRecent.label);
}
}
function assertRestoring(state: IRecentlyOpened, message?: string) {
const stored = toStoreData(state);
const restored = restoreRecentlyOpened(stored, new NullLogService());
assertEqualRecentlyOpened(state, restored, message);
}
const testWSPath = URI.file(join(tmpdir(), 'windowStateTest', 'test.code-workspace'));
const testFileURI = URI.file(join(tmpdir(), 'windowStateTest', 'testFile.txt'));
const testFolderURI = URI.file(join(tmpdir(), 'windowStateTest', 'testFolder'));
const testRemoteFolderURI = URI.parse('foo://bar/c/e');
const testRemoteFileURI = URI.parse('foo://bar/c/d.txt');
const testRemoteWSURI = URI.parse('foo://bar/c/test.code-workspace');
test('storing and restoring', () => {
let ro: IRecentlyOpened;
ro = {

View file

@ -23,89 +23,38 @@ import { INativeOpenDialogOptions } from 'vs/platform/dialogs/common/dialogs';
import { IBackupMainService, IWorkspaceBackupInfo } from 'vs/platform/backup/electron-main/backup';
import { IEmptyWindowBackupInfo } from 'vs/platform/backup/node/backup';
export class TestDialogMainService implements IDialogMainService {
declare readonly _serviceBrand: undefined;
pickFileFolder(options: INativeOpenDialogOptions, window?: Electron.BrowserWindow | undefined): Promise<string[] | undefined> {
throw new Error('Method not implemented.');
}
pickFolder(options: INativeOpenDialogOptions, window?: Electron.BrowserWindow | undefined): Promise<string[] | undefined> {
throw new Error('Method not implemented.');
}
pickFile(options: INativeOpenDialogOptions, window?: Electron.BrowserWindow | undefined): Promise<string[] | undefined> {
throw new Error('Method not implemented.');
}
pickWorkspace(options: INativeOpenDialogOptions, window?: Electron.BrowserWindow | undefined): Promise<string[] | undefined> {
throw new Error('Method not implemented.');
}
showMessageBox(options: Electron.MessageBoxOptions, window?: Electron.BrowserWindow | undefined): Promise<Electron.MessageBoxReturnValue> {
throw new Error('Method not implemented.');
}
showSaveDialog(options: Electron.SaveDialogOptions, window?: Electron.BrowserWindow | undefined): Promise<Electron.SaveDialogReturnValue> {
throw new Error('Method not implemented.');
}
showOpenDialog(options: Electron.OpenDialogOptions, window?: Electron.BrowserWindow | undefined): Promise<Electron.OpenDialogReturnValue> {
throw new Error('Method not implemented.');
}
}
export class TestBackupMainService implements IBackupMainService {
declare readonly _serviceBrand: undefined;
isHotExitEnabled(): boolean {
throw new Error('Method not implemented.');
}
getWorkspaceBackups(): IWorkspaceBackupInfo[] {
throw new Error('Method not implemented.');
}
getFolderBackupPaths(): URI[] {
throw new Error('Method not implemented.');
}
getEmptyWindowBackupPaths(): IEmptyWindowBackupInfo[] {
throw new Error('Method not implemented.');
}
registerWorkspaceBackupSync(workspace: IWorkspaceBackupInfo, migrateFrom?: string | undefined): string {
throw new Error('Method not implemented.');
}
registerFolderBackupSync(folderUri: URI): string {
throw new Error('Method not implemented.');
}
registerEmptyWindowBackupSync(backupFolder?: string | undefined, remoteAuthority?: string | undefined): string {
throw new Error('Method not implemented.');
}
unregisterWorkspaceBackupSync(workspace: IWorkspaceIdentifier): void {
throw new Error('Method not implemented.');
}
unregisterFolderBackupSync(folderUri: URI): void {
throw new Error('Method not implemented.');
}
unregisterEmptyWindowBackupSync(backupFolder: string): void {
throw new Error('Method not implemented.');
}
async getDirtyWorkspaces(): Promise<(IWorkspaceIdentifier | URI)[]> {
return [];
}
}
suite('WorkspacesManagementMainService', () => {
class TestDialogMainService implements IDialogMainService {
declare readonly _serviceBrand: undefined;
pickFileFolder(options: INativeOpenDialogOptions, window?: Electron.BrowserWindow | undefined): Promise<string[] | undefined> { throw new Error('Method not implemented.'); }
pickFolder(options: INativeOpenDialogOptions, window?: Electron.BrowserWindow | undefined): Promise<string[] | undefined> { throw new Error('Method not implemented.'); }
pickFile(options: INativeOpenDialogOptions, window?: Electron.BrowserWindow | undefined): Promise<string[] | undefined> { throw new Error('Method not implemented.'); }
pickWorkspace(options: INativeOpenDialogOptions, window?: Electron.BrowserWindow | undefined): Promise<string[] | undefined> { throw new Error('Method not implemented.'); }
showMessageBox(options: Electron.MessageBoxOptions, window?: Electron.BrowserWindow | undefined): Promise<Electron.MessageBoxReturnValue> { throw new Error('Method not implemented.'); }
showSaveDialog(options: Electron.SaveDialogOptions, window?: Electron.BrowserWindow | undefined): Promise<Electron.SaveDialogReturnValue> { throw new Error('Method not implemented.'); }
showOpenDialog(options: Electron.OpenDialogOptions, window?: Electron.BrowserWindow | undefined): Promise<Electron.OpenDialogReturnValue> { throw new Error('Method not implemented.'); }
}
class TestBackupMainService implements IBackupMainService {
declare readonly _serviceBrand: undefined;
isHotExitEnabled(): boolean { throw new Error('Method not implemented.'); }
getWorkspaceBackups(): IWorkspaceBackupInfo[] { throw new Error('Method not implemented.'); }
getFolderBackupPaths(): URI[] { throw new Error('Method not implemented.'); }
getEmptyWindowBackupPaths(): IEmptyWindowBackupInfo[] { throw new Error('Method not implemented.'); }
registerWorkspaceBackupSync(workspace: IWorkspaceBackupInfo, migrateFrom?: string | undefined): string { throw new Error('Method not implemented.'); }
registerFolderBackupSync(folderUri: URI): string { throw new Error('Method not implemented.'); }
registerEmptyWindowBackupSync(backupFolder?: string | undefined, remoteAuthority?: string | undefined): string { throw new Error('Method not implemented.'); }
unregisterWorkspaceBackupSync(workspace: IWorkspaceIdentifier): void { throw new Error('Method not implemented.'); }
unregisterFolderBackupSync(folderUri: URI): void { throw new Error('Method not implemented.'); }
unregisterEmptyWindowBackupSync(backupFolder: string): void { throw new Error('Method not implemented.'); }
async getDirtyWorkspaces(): Promise<(IWorkspaceIdentifier | URI)[]> { return []; }
}
function createUntitledWorkspace(folders: string[], names?: string[]) {
return service.createUntitledWorkspace(folders.map((folder, index) => ({ uri: URI.file(folder), name: names ? names[index] : undefined } as IWorkspaceFolderCreationData)));
}
@ -154,6 +103,8 @@ suite('WorkspacesManagementMainService', () => {
});
teardown(() => {
service.dispose();
return pfs.rimraf(testDir);
});

View file

@ -3,7 +3,6 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/workbench/browser/parts/editor/editor.contribution';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { Part } from 'vs/workbench/browser/part';
import { Dimension, isAncestor, $, EventHelper, addDisposableGenericMouseDownListner } from 'vs/base/browser/dom';

View file

@ -15,30 +15,41 @@ import { EditorService } from 'vs/workbench/services/editor/browser/editorServic
import { IBackupFileService } from 'vs/workbench/services/backup/common/backup';
import { Schemas } from 'vs/base/common/network';
import { isEqual } from 'vs/base/common/resources';
import { InMemoryTestBackupFileService, TestServiceAccessor, workbenchInstantiationService } from 'vs/workbench/test/browser/workbenchTestServices';
import { InMemoryTestBackupFileService, registerTestResourceEditor, TestServiceAccessor, workbenchInstantiationService } from 'vs/workbench/test/browser/workbenchTestServices';
import { BackupRestorer } from 'vs/workbench/contrib/backup/common/backupRestorer';
import { BrowserBackupTracker } from 'vs/workbench/contrib/backup/browser/backupTracker';
class TestBackupRestorer extends BackupRestorer {
async doRestoreBackups(): Promise<URI[] | undefined> {
return super.doRestoreBackups();
}
}
import { DisposableStore } from 'vs/base/common/lifecycle';
suite('BackupRestorer', () => {
class TestBackupRestorer extends BackupRestorer {
async doRestoreBackups(): Promise<URI[] | undefined> {
return super.doRestoreBackups();
}
}
let accessor: TestServiceAccessor;
let disposables = new DisposableStore();
const fooFile = URI.file(isWindows ? 'c:\\Foo' : '/Foo');
const barFile = URI.file(isWindows ? 'c:\\Bar' : '/Bar');
const untitledFile1 = URI.from({ scheme: Schemas.untitled, path: 'Untitled-1' });
const untitledFile2 = URI.from({ scheme: Schemas.untitled, path: 'Untitled-2' });
setup(() => {
disposables.add(registerTestResourceEditor());
});
teardown(() => {
disposables.clear();
});
test('Restore backups', async function () {
const backupFileService = new InMemoryTestBackupFileService();
const instantiationService = workbenchInstantiationService();
instantiationService.stub(IBackupFileService, backupFileService);
const part = instantiationService.createInstance(EditorPart);
const part = disposables.add(instantiationService.createInstance(EditorPart));
part.create(document.createElement('div'));
part.layout(400, 300);
@ -51,7 +62,7 @@ suite('BackupRestorer', () => {
await part.whenRestored;
const tracker = instantiationService.createInstance(BrowserBackupTracker);
disposables.add(instantiationService.createInstance(BrowserBackupTracker));
const restorer = instantiationService.createInstance(TestBackupRestorer);
// Backup 2 normal files and 2 untitled file
@ -102,8 +113,5 @@ suite('BackupRestorer', () => {
}
assert.strictEqual(counter, 4);
part.dispose();
tracker.dispose();
});
});

View file

@ -19,32 +19,32 @@ import { ILifecycleService } from 'vs/workbench/services/lifecycle/common/lifecy
import { BackupTracker } from 'vs/workbench/contrib/backup/common/backupTracker';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { UntitledTextEditorInput } from 'vs/workbench/services/untitled/common/untitledTextEditorInput';
import { InMemoryTestBackupFileService, TestServiceAccessor, workbenchInstantiationService } from 'vs/workbench/test/browser/workbenchTestServices';
import { InMemoryTestBackupFileService, registerTestResourceEditor, TestServiceAccessor, workbenchInstantiationService } from 'vs/workbench/test/browser/workbenchTestServices';
import { TestWorkingCopy } from 'vs/workbench/test/common/workbenchTestServices';
import { CancellationToken } from 'vs/base/common/cancellation';
import { timeout } from 'vs/base/common/async';
import { BrowserBackupTracker } from 'vs/workbench/contrib/backup/browser/backupTracker';
class TestBackupTracker extends BrowserBackupTracker {
constructor(
@IBackupFileService backupFileService: IBackupFileService,
@IFilesConfigurationService filesConfigurationService: IFilesConfigurationService,
@IWorkingCopyService workingCopyService: IWorkingCopyService,
@ILifecycleService lifecycleService: ILifecycleService,
@ILogService logService: ILogService,
) {
super(backupFileService, filesConfigurationService, workingCopyService, lifecycleService, logService);
}
protected getBackupScheduleDelay(): number {
return 10; // Reduce timeout for tests
}
}
suite('BackupTracker (browser)', function () {
let accessor: TestServiceAccessor;
class TestBackupTracker extends BrowserBackupTracker {
constructor(
@IBackupFileService backupFileService: IBackupFileService,
@IFilesConfigurationService filesConfigurationService: IFilesConfigurationService,
@IWorkingCopyService workingCopyService: IWorkingCopyService,
@ILifecycleService lifecycleService: ILifecycleService,
@ILogService logService: ILogService,
) {
super(backupFileService, filesConfigurationService, workingCopyService, lifecycleService, logService);
}
protected getBackupScheduleDelay(): number {
return 10; // Reduce timeout for tests
}
}
async function createTracker(): Promise<{ accessor: TestServiceAccessor, part: EditorPart, tracker: BackupTracker, backupFileService: InMemoryTestBackupFileService, instantiationService: IInstantiationService, cleanup: () => void }> {
const backupFileService = new InMemoryTestBackupFileService();
const instantiationService = workbenchInstantiationService();
@ -54,6 +54,8 @@ suite('BackupTracker (browser)', function () {
part.create(document.createElement('div'));
part.layout(400, 300);
const editorRegistration = registerTestResourceEditor();
instantiationService.stub(IEditorGroupsService, part);
const editorService: EditorService = instantiationService.createInstance(EditorService);
@ -68,6 +70,7 @@ suite('BackupTracker (browser)', function () {
const cleanup = () => {
part.dispose();
tracker.dispose();
editorRegistration.dispose();
};
return { accessor, part, tracker, backupFileService, instantiationService, cleanup };
@ -150,6 +153,6 @@ suite('BackupTracker (browser)', function () {
assert.strictEqual(backupFileService.hasBackupSync(resource), false);
customWorkingCopy.dispose();
await cleanup();
cleanup();
});
});

View file

@ -4,10 +4,10 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import * as platform from 'vs/base/common/platform';
import * as os from 'os';
import * as path from 'vs/base/common/path';
import * as pfs from 'vs/base/node/pfs';
import { isMacintosh, isWindows } from 'vs/base/common/platform';
import { tmpdir } from 'os';
import { join } from 'vs/base/common/path';
import { mkdirp, rimraf, writeFile } from 'vs/base/node/pfs';
import { URI } from 'vs/base/common/uri';
import { flakySuite, getRandomTestPath } from 'vs/base/test/node/testUtils';
import { hashPath } from 'vs/workbench/services/backup/electron-browser/backupFileService';
@ -17,15 +17,9 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic
import { EditorPart } from 'vs/workbench/browser/parts/editor/editorPart';
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { EditorService } from 'vs/workbench/services/editor/browser/editorService';
import { Registry } from 'vs/platform/registry/common/platform';
import { EditorInput } from 'vs/workbench/common/editor';
import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileEditorInput';
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { IEditorRegistry, EditorDescriptor, Extensions as EditorExtensions } from 'vs/workbench/browser/editor';
import { TextFileEditor } from 'vs/workbench/contrib/files/browser/editors/textFileEditor';
import { IBackupFileService } from 'vs/workbench/services/backup/common/backup';
import { NodeTestBackupFileService } from 'vs/workbench/services/backup/test/electron-browser/backupFileService.test';
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
import { DisposableStore } from 'vs/base/common/lifecycle';
import { toResource } from 'vs/base/test/common/utils';
import { IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService';
import { IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService';
@ -40,95 +34,88 @@ import { workbenchInstantiationService, TestServiceAccessor } from 'vs/workbench
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { TestFilesConfigurationService } from 'vs/workbench/test/browser/workbenchTestServices';
import { registerTestFileEditor, TestFilesConfigurationService } from 'vs/workbench/test/browser/workbenchTestServices';
import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { Workspace } from 'vs/platform/workspace/test/common/testWorkspace';
import { IProgressService } from 'vs/platform/progress/common/progress';
class TestBackupTracker extends NativeBackupTracker {
flakySuite('BackupTracker (native)', function () {
constructor(
@IBackupFileService backupFileService: IBackupFileService,
@IFilesConfigurationService filesConfigurationService: IFilesConfigurationService,
@IWorkingCopyService workingCopyService: IWorkingCopyService,
@ILifecycleService lifecycleService: ILifecycleService,
@IFileDialogService fileDialogService: IFileDialogService,
@IDialogService dialogService: IDialogService,
@IWorkspaceContextService contextService: IWorkspaceContextService,
@INativeHostService nativeHostService: INativeHostService,
@ILogService logService: ILogService,
@IEditorService editorService: IEditorService,
@IEnvironmentService environmentService: IEnvironmentService,
@IProgressService progressService: IProgressService
) {
super(backupFileService, filesConfigurationService, workingCopyService, lifecycleService, fileDialogService, dialogService, contextService, nativeHostService, logService, editorService, environmentService, progressService);
}
class TestBackupTracker extends NativeBackupTracker {
protected getBackupScheduleDelay(): number {
return 10; // Reduce timeout for tests
}
constructor(
@IBackupFileService backupFileService: IBackupFileService,
@IFilesConfigurationService filesConfigurationService: IFilesConfigurationService,
@IWorkingCopyService workingCopyService: IWorkingCopyService,
@ILifecycleService lifecycleService: ILifecycleService,
@IFileDialogService fileDialogService: IFileDialogService,
@IDialogService dialogService: IDialogService,
@IWorkspaceContextService contextService: IWorkspaceContextService,
@INativeHostService nativeHostService: INativeHostService,
@ILogService logService: ILogService,
@IEditorService editorService: IEditorService,
@IEnvironmentService environmentService: IEnvironmentService,
@IProgressService progressService: IProgressService
) {
super(backupFileService, filesConfigurationService, workingCopyService, lifecycleService, fileDialogService, dialogService, contextService, nativeHostService, logService, editorService, environmentService, progressService);
}
dispose() {
super.dispose();
for (const [_, disposable] of this.pendingBackups) {
disposable.dispose();
protected getBackupScheduleDelay(): number {
return 10; // Reduce timeout for tests
}
dispose() {
super.dispose();
for (const [_, disposable] of this.pendingBackups) {
disposable.dispose();
}
}
}
}
class BeforeShutdownEventImpl implements BeforeShutdownEvent {
class BeforeShutdownEventImpl implements BeforeShutdownEvent {
value: boolean | Promise<boolean> | undefined;
reason = ShutdownReason.CLOSE;
value: boolean | Promise<boolean> | undefined;
reason = ShutdownReason.CLOSE;
veto(value: boolean | Promise<boolean>): void {
this.value = value;
veto(value: boolean | Promise<boolean>): void {
this.value = value;
}
}
}
flakySuite('BackupTracker (native)', function () {
let testDir: string;
let backupHome: string;
let workspaceBackupPath: string;
let accessor: TestServiceAccessor;
let disposables: IDisposable[] = [];
const disposables = new DisposableStore();
setup(async () => {
testDir = getRandomTestPath(os.tmpdir(), 'vsctests', 'backuprestorer');
backupHome = path.join(testDir, 'Backups');
const workspacesJsonPath = path.join(backupHome, 'workspaces.json');
testDir = getRandomTestPath(tmpdir(), 'vsctests', 'backuprestorer');
backupHome = join(testDir, 'Backups');
const workspacesJsonPath = join(backupHome, 'workspaces.json');
const workspaceResource = URI.file(platform.isWindows ? 'c:\\workspace' : '/workspace');
workspaceBackupPath = path.join(backupHome, hashPath(workspaceResource));
const workspaceResource = URI.file(isWindows ? 'c:\\workspace' : '/workspace');
workspaceBackupPath = join(backupHome, hashPath(workspaceResource));
const instantiationService = workbenchInstantiationService();
accessor = instantiationService.createInstance(TestServiceAccessor);
disposables.add((<TextFileEditorModelManager>accessor.textFileService.files));
disposables.push(Registry.as<IEditorRegistry>(EditorExtensions.Editors).registerEditor(
EditorDescriptor.create(
TextFileEditor,
TextFileEditor.ID,
'Text File Editor'
),
[new SyncDescriptor<EditorInput>(FileEditorInput)]
));
disposables.add(registerTestFileEditor());
await pfs.mkdirp(backupHome);
await pfs.mkdirp(workspaceBackupPath);
await mkdirp(backupHome);
await mkdirp(workspaceBackupPath);
return pfs.writeFile(workspacesJsonPath, '');
return writeFile(workspacesJsonPath, '');
});
teardown(async () => {
dispose(disposables);
disposables = [];
disposables.clear();
(<TextFileEditorModelManager>accessor.textFileService.files).dispose();
return pfs.rimraf(testDir);
return rimraf(testDir);
});
async function createTracker(autoSaveEnabled = false): Promise<{ accessor: TestServiceAccessor, part: EditorPart, tracker: BackupTracker, instantiationService: IInstantiationService, cleanup: () => Promise<void> }> {
@ -308,10 +295,10 @@ flakySuite('BackupTracker (native)', function () {
suite('Hot Exit', () => {
suite('"onExit" setting', () => {
test('should hot exit on non-Mac (reason: CLOSE, windows: single, workspace)', function () {
return hotExitTest.call(this, HotExitConfiguration.ON_EXIT, ShutdownReason.CLOSE, false, true, !!platform.isMacintosh);
return hotExitTest.call(this, HotExitConfiguration.ON_EXIT, ShutdownReason.CLOSE, false, true, !!isMacintosh);
});
test('should hot exit on non-Mac (reason: CLOSE, windows: single, empty workspace)', function () {
return hotExitTest.call(this, HotExitConfiguration.ON_EXIT, ShutdownReason.CLOSE, false, false, !!platform.isMacintosh);
return hotExitTest.call(this, HotExitConfiguration.ON_EXIT, ShutdownReason.CLOSE, false, false, !!isMacintosh);
});
test('should NOT hot exit (reason: CLOSE, windows: multiple, workspace)', function () {
return hotExitTest.call(this, HotExitConfiguration.ON_EXIT, ShutdownReason.CLOSE, true, true, true);
@ -362,7 +349,7 @@ flakySuite('BackupTracker (native)', function () {
return hotExitTest.call(this, HotExitConfiguration.ON_EXIT_AND_WINDOW_CLOSE, ShutdownReason.CLOSE, false, true, false);
});
test('should hot exit (reason: CLOSE, windows: single, empty workspace)', function () {
return hotExitTest.call(this, HotExitConfiguration.ON_EXIT_AND_WINDOW_CLOSE, ShutdownReason.CLOSE, false, false, !!platform.isMacintosh);
return hotExitTest.call(this, HotExitConfiguration.ON_EXIT_AND_WINDOW_CLOSE, ShutdownReason.CLOSE, false, false, !!isMacintosh);
});
test('should hot exit (reason: CLOSE, windows: multiple, workspace)', function () {
return hotExitTest.call(this, HotExitConfiguration.ON_EXIT_AND_WINDOW_CLOSE, ShutdownReason.CLOSE, true, true, false);

View file

@ -3,7 +3,6 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { URI, UriComponents } from 'vs/base/common/uri';
import { ShowViewletAction } from 'vs/workbench/browser/viewlet';
import * as nls from 'vs/nls';
import { sep } from 'vs/base/common/path';
@ -12,14 +11,14 @@ import { Registry } from 'vs/platform/registry/common/platform';
import { IConfigurationRegistry, Extensions as ConfigurationExtensions, ConfigurationScope, IConfigurationPropertySchema } from 'vs/platform/configuration/common/configurationRegistry';
import { IWorkbenchActionRegistry, Extensions as ActionExtensions, CATEGORIES } from 'vs/workbench/common/actions';
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions, IWorkbenchContribution } from 'vs/workbench/common/contributions';
import { IEditorInputFactory, EditorInput, IFileEditorInput, IEditorInputFactoryRegistry, Extensions as EditorInputExtensions } from 'vs/workbench/common/editor';
import { EditorInput, IFileEditorInput, IEditorInputFactoryRegistry, Extensions as EditorInputExtensions } from 'vs/workbench/common/editor';
import { AutoSaveConfiguration, HotExitConfiguration, FILES_EXCLUDE_CONFIG, FILES_ASSOCIATIONS_CONFIG } from 'vs/platform/files/common/files';
import { VIEWLET_ID, SortOrder, FILE_EDITOR_INPUT_ID } from 'vs/workbench/contrib/files/common/files';
import { TextFileEditorTracker } from 'vs/workbench/contrib/files/browser/editors/textFileEditorTracker';
import { TextFileSaveErrorHandler } from 'vs/workbench/contrib/files/browser/editors/textFileSaveErrorHandler';
import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileEditorInput';
import { BinaryFileEditor } from 'vs/workbench/contrib/files/browser/editors/binaryFileEditor';
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { IKeybindings } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
@ -28,7 +27,6 @@ import * as platform from 'vs/base/common/platform';
import { ExplorerViewletViewsContribution } from 'vs/workbench/contrib/files/browser/explorerViewlet';
import { IEditorRegistry, EditorDescriptor, Extensions as EditorExtensions } from 'vs/workbench/browser/editor';
import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { ILabelService } from 'vs/platform/label/common/label';
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
@ -39,10 +37,9 @@ import { Schemas } from 'vs/base/common/network';
import { WorkspaceWatcher } from 'vs/workbench/contrib/files/common/workspaceWatcher';
import { editorConfigurationBaseNode } from 'vs/editor/common/config/commonEditorConfig';
import { DirtyFilesIndicator } from 'vs/workbench/contrib/files/common/dirtyFilesIndicator';
import { isEqual } from 'vs/base/common/resources';
import { UndoCommand, RedoCommand } from 'vs/editor/browser/editorExtensions';
import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo';
import { IExplorerService } from 'vs/workbench/contrib/files/browser/files';
import { FileEditorInputFactory, IExplorerService } from 'vs/workbench/contrib/files/browser/files';
// Viewlet Action
export class OpenExplorerViewletAction extends ShowViewletAction {
@ -115,58 +112,7 @@ Registry.as<IEditorInputFactoryRegistry>(EditorInputExtensions.EditorInputFactor
}
});
interface ISerializedFileEditorInput {
resourceJSON: UriComponents;
preferredResourceJSON?: UriComponents;
name?: string;
description?: string;
encoding?: string;
modeId?: string;
}
// Register Editor Input Factory
class FileEditorInputFactory implements IEditorInputFactory {
canSerialize(editorInput: EditorInput): boolean {
return true;
}
serialize(editorInput: EditorInput): string {
const fileEditorInput = <FileEditorInput>editorInput;
const resource = fileEditorInput.resource;
const preferredResource = fileEditorInput.preferredResource;
const serializedFileEditorInput: ISerializedFileEditorInput = {
resourceJSON: resource.toJSON(),
preferredResourceJSON: isEqual(resource, preferredResource) ? undefined : preferredResource, // only storing preferredResource if it differs from the resource
name: fileEditorInput.getPreferredName(),
description: fileEditorInput.getPreferredDescription(),
encoding: fileEditorInput.getEncoding(),
modeId: fileEditorInput.getPreferredMode() // only using the preferred user associated mode here if available to not store redundant data
};
return JSON.stringify(serializedFileEditorInput);
}
deserialize(instantiationService: IInstantiationService, serializedEditorInput: string): FileEditorInput {
return instantiationService.invokeFunction<FileEditorInput>(accessor => {
const serializedFileEditorInput: ISerializedFileEditorInput = JSON.parse(serializedEditorInput);
const resource = URI.revive(serializedFileEditorInput.resourceJSON);
const preferredResource = URI.revive(serializedFileEditorInput.preferredResourceJSON);
const name = serializedFileEditorInput.name;
const description = serializedFileEditorInput.description;
const encoding = serializedFileEditorInput.encoding;
const mode = serializedFileEditorInput.modeId;
const fileEditorInput = accessor.get(IEditorService).createEditorInput({ resource, label: name, description, encoding, mode, forceFile: true }) as FileEditorInput;
if (preferredResource) {
fileEditorInput.setPreferredResource(preferredResource);
}
return fileEditorInput;
});
}
}
Registry.as<IEditorInputFactoryRegistry>(EditorInputExtensions.EditorInputFactories).registerEditorInputFactory(FILE_EDITOR_INPUT_ID, FileEditorInputFactory);
// Register Explorer views

View file

@ -3,10 +3,10 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { URI } from 'vs/base/common/uri';
import { URI, UriComponents } from 'vs/base/common/uri';
import { IListService } from 'vs/platform/list/browser/listService';
import { OpenEditor, SortOrder } from 'vs/workbench/contrib/files/common/files';
import { EditorResourceAccessor, SideBySideEditor, IEditorIdentifier } from 'vs/workbench/common/editor';
import { EditorResourceAccessor, SideBySideEditor, IEditorIdentifier, EditorInput, IEditorInputFactory } from 'vs/workbench/common/editor';
import { List } from 'vs/base/browser/ui/list/listWidget';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { ExplorerItem } from 'vs/workbench/contrib/files/common/explorerModel';
@ -14,10 +14,62 @@ import { coalesce } from 'vs/base/common/arrays';
import { AsyncDataTree } from 'vs/base/browser/ui/tree/asyncDataTree';
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { IEditableData } from 'vs/workbench/common/views';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { createDecorator, IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { ResourceFileEdit } from 'vs/editor/browser/services/bulkEditService';
import { ProgressLocation } from 'vs/platform/progress/common/progress';
import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileEditorInput';
import { isEqual } from 'vs/base/common/resources';
interface ISerializedFileEditorInput {
resourceJSON: UriComponents;
preferredResourceJSON?: UriComponents;
name?: string;
description?: string;
encoding?: string;
modeId?: string;
}
export class FileEditorInputFactory implements IEditorInputFactory {
canSerialize(editorInput: EditorInput): boolean {
return true;
}
serialize(editorInput: EditorInput): string {
const fileEditorInput = <FileEditorInput>editorInput;
const resource = fileEditorInput.resource;
const preferredResource = fileEditorInput.preferredResource;
const serializedFileEditorInput: ISerializedFileEditorInput = {
resourceJSON: resource.toJSON(),
preferredResourceJSON: isEqual(resource, preferredResource) ? undefined : preferredResource, // only storing preferredResource if it differs from the resource
name: fileEditorInput.getPreferredName(),
description: fileEditorInput.getPreferredDescription(),
encoding: fileEditorInput.getEncoding(),
modeId: fileEditorInput.getPreferredMode() // only using the preferred user associated mode here if available to not store redundant data
};
return JSON.stringify(serializedFileEditorInput);
}
deserialize(instantiationService: IInstantiationService, serializedEditorInput: string): FileEditorInput {
return instantiationService.invokeFunction<FileEditorInput>(accessor => {
const serializedFileEditorInput: ISerializedFileEditorInput = JSON.parse(serializedEditorInput);
const resource = URI.revive(serializedFileEditorInput.resourceJSON);
const preferredResource = URI.revive(serializedFileEditorInput.preferredResourceJSON);
const name = serializedFileEditorInput.name;
const description = serializedFileEditorInput.description;
const encoding = serializedFileEditorInput.encoding;
const mode = serializedFileEditorInput.modeId;
const fileEditorInput = accessor.get(IEditorService).createEditorInput({ resource, label: name, description, encoding, mode, forceFile: true }) as FileEditorInput;
if (preferredResource) {
fileEditorInput.setPreferredResource(preferredResource);
}
return fileEditorInput;
});
}
}
export interface IExplorerService {
readonly _serviceBrand: undefined;

View file

@ -7,16 +7,10 @@ import * as assert from 'assert';
import { Event } from 'vs/base/common/event';
import { toResource } from 'vs/base/test/common/utils';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { TestFilesConfigurationService, workbenchInstantiationService, TestServiceAccessor } from 'vs/workbench/test/browser/workbenchTestServices';
import { TestFilesConfigurationService, workbenchInstantiationService, TestServiceAccessor, registerTestFileEditor } from 'vs/workbench/test/browser/workbenchTestServices';
import { IResolvedTextFileEditorModel, ITextFileEditorModel } from 'vs/workbench/services/textfile/common/textfiles';
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
import { IEditorRegistry, EditorDescriptor, Extensions as EditorExtensions } from 'vs/workbench/browser/editor';
import { Registry } from 'vs/platform/registry/common/platform';
import { TextFileEditor } from 'vs/workbench/contrib/files/browser/editors/textFileEditor';
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { EditorInput } from 'vs/workbench/common/editor';
import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileEditorInput';
import { DisposableStore } from 'vs/base/common/lifecycle';
import { TextFileEditorModelManager } from 'vs/workbench/services/textfile/common/textFileEditorModelManager';
import { EditorPart } from 'vs/workbench/browser/parts/editor/editorPart';
import { EditorService } from 'vs/workbench/services/editor/browser/editorService';
@ -29,25 +23,17 @@ import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKe
suite('EditorAutoSave', () => {
let disposables: IDisposable[] = [];
const disposables = new DisposableStore();
setup(() => {
disposables.push(Registry.as<IEditorRegistry>(EditorExtensions.Editors).registerEditor(
EditorDescriptor.create(
TextFileEditor,
TextFileEditor.ID,
'Text File Editor'
),
[new SyncDescriptor<EditorInput>(FileEditorInput)]
));
disposables.add(registerTestFileEditor());
});
teardown(() => {
dispose(disposables);
disposables = [];
disposables.dispose();
});
async function createEditorAutoSave(autoSaveConfig: object): Promise<[TestServiceAccessor, EditorPart, EditorAutoSave]> {
async function createEditorAutoSave(autoSaveConfig: object): Promise<TestServiceAccessor> {
const instantiationService = workbenchInstantiationService();
const configurationService = new TestConfigurationService();
@ -59,7 +45,7 @@ suite('EditorAutoSave', () => {
configurationService
));
const part = instantiationService.createInstance(EditorPart);
const part = disposables.add(instantiationService.createInstance(EditorPart));
part.create(document.createElement('div'));
part.layout(400, 300);
@ -69,14 +55,15 @@ suite('EditorAutoSave', () => {
instantiationService.stub(IEditorService, editorService);
const accessor = instantiationService.createInstance(TestServiceAccessor);
disposables.add((<TextFileEditorModelManager>accessor.textFileService.files));
const editorAutoSave = instantiationService.createInstance(EditorAutoSave);
disposables.add(instantiationService.createInstance(EditorAutoSave));
return [accessor, part, editorAutoSave];
return accessor;
}
test('editor auto saves after short delay if configured', async function () {
const [accessor, part, editorAutoSave] = await createEditorAutoSave({ autoSave: 'afterDelay', autoSaveDelay: 1 });
const accessor = await createEditorAutoSave({ autoSave: 'afterDelay', autoSaveDelay: 1 });
const resource = toResource.call(this, '/path/index.txt');
@ -88,16 +75,10 @@ suite('EditorAutoSave', () => {
await awaitModelSaved(model);
assert.ok(!model.isDirty());
part.dispose();
editorAutoSave.dispose();
(<TextFileEditorModelManager>accessor.textFileService.files).dispose();
});
test('editor auto saves on focus change if configured', async function () {
this.retries(3); // https://github.com/microsoft/vscode/issues/108727
const [accessor, part, editorAutoSave] = await createEditorAutoSave({ autoSave: 'onFocusChange' });
const accessor = await createEditorAutoSave({ autoSave: 'onFocusChange' });
const resource = toResource.call(this, '/path/index.txt');
await accessor.editorService.openEditor({ resource, forceFile: true });
@ -112,10 +93,6 @@ suite('EditorAutoSave', () => {
await awaitModelSaved(model);
assert.ok(!model.isDirty());
part.dispose();
editorAutoSave.dispose();
(<TextFileEditorModelManager>accessor.textFileService.files).dispose();
});
function awaitModelSaved(model: ITextFileEditorModel): Promise<void> {

View file

@ -19,8 +19,10 @@ import { DisposableStore } from 'vs/base/common/lifecycle';
import { BinaryEditorModel } from 'vs/workbench/common/editor/binaryEditorModel';
import { IResourceEditorInput } from 'vs/platform/editor/common/editor';
import { Registry } from 'vs/platform/registry/common/platform';
import { FileEditorInputFactory } from 'vs/workbench/contrib/files/browser/files';
suite('Files - FileEditorInput', () => {
let instantiationService: IInstantiationService;
let accessor: TestServiceAccessor;
@ -264,6 +266,8 @@ suite('Files - FileEditorInput', () => {
const input = createFileInput(toResource.call(this, '/foo/bar/updatefile.js'));
const disposable = Registry.as<IEditorInputFactoryRegistry>(EditorExtensions.EditorInputFactories).registerEditorInputFactory('workbench.editors.files.fileEditorInput', FileEditorInputFactory);
const factory = Registry.as<IEditorInputFactoryRegistry>(EditorExtensions.EditorInputFactories).getEditorInputFactory(input.getTypeId());
if (!factory) {
assert.fail('File Editor Input Factory missing');
@ -290,6 +294,8 @@ suite('Files - FileEditorInput', () => {
const inputWithPreferredResourceDeserialized = factory.deserialize(instantiationService, inputWithPreferredResourceSerialized) as FileEditorInput;
assert.strictEqual(inputWithPreferredResource.resource.toString(), inputWithPreferredResourceDeserialized.resource.toString());
assert.strictEqual(inputWithPreferredResource.preferredResource.toString(), inputWithPreferredResourceDeserialized.preferredResource.toString());
disposable.dispose();
});
test('preferred name/description', async function () {
@ -323,14 +329,14 @@ suite('Files - FileEditorInput', () => {
didChangeLabelCounter++;
});
assert.notEqual(fileInput.getName(), 'My Name');
assert.notEqual(fileInput.getDescription(), 'My Description');
assert.notStrictEqual(fileInput.getName(), 'My Name');
assert.notStrictEqual(fileInput.getDescription(), 'My Description');
fileInput.setPreferredName('My Name 2');
fileInput.setPreferredDescription('My Description 2');
assert.notEqual(fileInput.getName(), 'My Name 2');
assert.notEqual(fileInput.getDescription(), 'My Description 2');
assert.notStrictEqual(fileInput.getName(), 'My Name 2');
assert.notStrictEqual(fileInput.getDescription(), 'My Description 2');
assert.strictEqual(didChangeLabelCounter, 0);

View file

@ -1,113 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { toResource } from 'vs/base/test/common/utils';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { workbenchInstantiationService, TestServiceAccessor, TestFilesConfigurationService, TestTextResourceConfigurationService } from 'vs/workbench/test/browser/workbenchTestServices';
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
import { IEditorRegistry, EditorDescriptor, Extensions as EditorExtensions } from 'vs/workbench/browser/editor';
import { Registry } from 'vs/platform/registry/common/platform';
import { TextFileEditor } from 'vs/workbench/contrib/files/browser/editors/textFileEditor';
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { EditorInput } from 'vs/workbench/common/editor';
import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileEditorInput';
import { TextFileEditorModelManager } from 'vs/workbench/services/textfile/common/textFileEditorModelManager';
import { EditorPart } from 'vs/workbench/browser/parts/editor/editorPart';
import { EditorService } from 'vs/workbench/services/editor/browser/editorService';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget';
import { Selection } from 'vs/editor/common/core/selection';
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService';
import { ITextResourceConfigurationService } from 'vs/editor/common/services/textResourceConfigurationService';
import { raceTimeout } from 'vs/base/common/async';
suite('Files - TextFileEditor', () => {
let disposables: IDisposable[] = [];
setup(() => {
disposables.push(Registry.as<IEditorRegistry>(EditorExtensions.Editors).registerEditor(
EditorDescriptor.create(
TextFileEditor,
TextFileEditor.ID,
'Text File Editor'
),
[new SyncDescriptor<EditorInput>(FileEditorInput)]
));
});
teardown(() => {
dispose(disposables);
disposables = [];
});
async function createPart(restoreViewState: boolean): Promise<[EditorPart, TestServiceAccessor, IInstantiationService, IEditorService]> {
const instantiationService = workbenchInstantiationService();
const configurationService = new TestConfigurationService();
configurationService.setUserConfiguration('workbench', { editor: { restoreViewState } });
instantiationService.stub(IConfigurationService, configurationService);
instantiationService.stub(ITextResourceConfigurationService, new TestTextResourceConfigurationService(configurationService));
instantiationService.stub(IFilesConfigurationService, new TestFilesConfigurationService(
<IContextKeyService>instantiationService.createInstance(MockContextKeyService),
configurationService
));
const part = instantiationService.createInstance(EditorPart);
part.create(document.createElement('div'));
part.layout(400, 300);
instantiationService.stub(IEditorGroupsService, part);
const editorService: EditorService = instantiationService.createInstance(EditorService);
instantiationService.stub(IEditorService, editorService);
const accessor = instantiationService.createInstance(TestServiceAccessor);
await raceTimeout(part.whenRestored, 2000, () => assert.fail('textFileEditor.test.ts: Unexpected long time to wait for part to restore (#112649)'));
return [part, accessor, instantiationService, editorService];
}
test('text file editor preserves viewstate', async function () {
return viewStateTest(this, true);
});
test('text file editor resets viewstate if configured as such', async function () {
return viewStateTest(this, false);
});
async function viewStateTest(context: Mocha.Context, restoreViewState: boolean): Promise<void> {
const [part, accessor] = await createPart(restoreViewState);
let editor = await accessor.editorService.openEditor(accessor.editorService.createEditorInput({ resource: toResource.call(context, '/path/index.txt'), forceFile: true }));
let codeEditor = editor?.getControl() as CodeEditorWidget;
const selection = new Selection(1, 3, 1, 4);
codeEditor.setSelection(selection);
editor = await accessor.editorService.openEditor(accessor.editorService.createEditorInput({ resource: toResource.call(context, '/path/index-other.txt'), forceFile: true }));
editor = await accessor.editorService.openEditor(accessor.editorService.createEditorInput({ resource: toResource.call(context, '/path/index.txt'), forceFile: true }));
codeEditor = editor?.getControl() as CodeEditorWidget;
if (restoreViewState) {
assert.ok(codeEditor.getSelection()?.equalsSelection(selection));
} else {
assert.ok(!codeEditor.getSelection()?.equalsSelection(selection));
}
part.dispose();
(<TextFileEditorModelManager>accessor.textFileService.files).dispose();
}
});

View file

@ -8,22 +8,15 @@ import { Event } from 'vs/base/common/event';
import { TextFileEditorTracker } from 'vs/workbench/contrib/files/browser/editors/textFileEditorTracker';
import { toResource } from 'vs/base/test/common/utils';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { workbenchInstantiationService, TestServiceAccessor, TestFilesConfigurationService } from 'vs/workbench/test/browser/workbenchTestServices';
import { workbenchInstantiationService, TestServiceAccessor, TestFilesConfigurationService, registerTestFileEditor, registerTestResourceEditor } from 'vs/workbench/test/browser/workbenchTestServices';
import { IResolvedTextFileEditorModel, snapshotToString, ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
import { FileChangesEvent, FileChangeType } from 'vs/platform/files/common/files';
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { timeout } from 'vs/base/common/async';
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
import { IEditorRegistry, EditorDescriptor, Extensions as EditorExtensions } from 'vs/workbench/browser/editor';
import { Registry } from 'vs/platform/registry/common/platform';
import { TextFileEditor } from 'vs/workbench/contrib/files/browser/editors/textFileEditor';
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { EditorInput } from 'vs/workbench/common/editor';
import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileEditorInput';
import { DisposableStore } from 'vs/base/common/lifecycle';
import { TextFileEditorModelManager } from 'vs/workbench/services/textfile/common/textFileEditorModelManager';
import { EditorPart } from 'vs/workbench/browser/parts/editor/editorPart';
import { EditorService } from 'vs/workbench/services/editor/browser/editorService';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { UntitledTextEditorInput } from 'vs/workbench/services/untitled/common/untitledTextEditorInput';
import { isEqual } from 'vs/base/common/resources';
import { URI } from 'vs/base/common/uri';
@ -35,25 +28,18 @@ import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
suite('Files - TextFileEditorTracker', () => {
let disposables: IDisposable[] = [];
const disposables = new DisposableStore();
setup(() => {
disposables.push(Registry.as<IEditorRegistry>(EditorExtensions.Editors).registerEditor(
EditorDescriptor.create(
TextFileEditor,
TextFileEditor.ID,
'Text File Editor'
),
[new SyncDescriptor<EditorInput>(FileEditorInput)]
));
disposables.add(registerTestFileEditor());
disposables.add(registerTestResourceEditor());
});
teardown(() => {
dispose(disposables);
disposables = [];
disposables.clear();
});
async function createTracker(autoSaveEnabled = false): Promise<[EditorPart, TestServiceAccessor, TextFileEditorTracker, IInstantiationService, IEditorService]> {
async function createTracker(autoSaveEnabled = false): Promise<TestServiceAccessor> {
const instantiationService = workbenchInstantiationService();
if (autoSaveEnabled) {
@ -68,7 +54,7 @@ suite('Files - TextFileEditorTracker', () => {
));
}
const part = instantiationService.createInstance(EditorPart);
const part = disposables.add(instantiationService.createInstance(EditorPart));
part.create(document.createElement('div'));
part.layout(400, 300);
@ -78,16 +64,17 @@ suite('Files - TextFileEditorTracker', () => {
instantiationService.stub(IEditorService, editorService);
const accessor = instantiationService.createInstance(TestServiceAccessor);
disposables.add((<TextFileEditorModelManager>accessor.textFileService.files));
await part.whenRestored;
const tracker = instantiationService.createInstance(TextFileEditorTracker);
disposables.add(instantiationService.createInstance(TextFileEditorTracker));
return [part, accessor, tracker, instantiationService, editorService];
return accessor;
}
test('file change event updates model', async function () {
const [, accessor, tracker] = await createTracker();
const accessor = await createTracker();
const resource = toResource.call(this, '/path/index.txt');
@ -104,9 +91,6 @@ suite('Files - TextFileEditorTracker', () => {
await timeout(0); // due to event updating model async
assert.strictEqual(snapshotToString(model.createSnapshot()!), 'Hello Html');
tracker.dispose();
(<TextFileEditorModelManager>accessor.textFileService.files).dispose();
});
test('dirty text file model opens as editor', async function () {
@ -122,7 +106,7 @@ suite('Files - TextFileEditorTracker', () => {
});
async function testDirtyTextFileModelOpensEditorDependingOnAutoSaveSetting(resource: URI, autoSave: boolean): Promise<void> {
const [part, accessor, tracker] = await createTracker(autoSave);
const accessor = await createTracker(autoSave);
assert.ok(!accessor.editorService.isOpen(accessor.editorService.createEditorInput({ resource, forceFile: true })));
@ -137,17 +121,13 @@ suite('Files - TextFileEditorTracker', () => {
await awaitEditorOpening(accessor.editorService);
assert.ok(accessor.editorService.isOpen(accessor.editorService.createEditorInput({ resource, forceFile: true })));
}
part.dispose();
tracker.dispose();
(<TextFileEditorModelManager>accessor.textFileService.files).dispose();
}
test('dirty untitled text file model opens as editor', async function () {
const [part, accessor, tracker, , editorService] = await createTracker();
const accessor = await createTracker();
const untitledEditor = editorService.createEditorInput({ forceUntitled: true }) as UntitledTextEditorInput;
const model = await untitledEditor.resolve();
const untitledEditor = accessor.editorService.createEditorInput({ forceUntitled: true }) as UntitledTextEditorInput;
const model = disposables.add(await untitledEditor.resolve());
assert.ok(!accessor.editorService.isOpen(untitledEditor));
@ -155,10 +135,6 @@ suite('Files - TextFileEditorTracker', () => {
await awaitEditorOpening(accessor.editorService);
assert.ok(accessor.editorService.isOpen(untitledEditor));
part.dispose();
tracker.dispose();
model.dispose();
});
function awaitEditorOpening(editorService: IEditorService): Promise<void> {
@ -166,7 +142,7 @@ suite('Files - TextFileEditorTracker', () => {
}
test('non-dirty files reload on window focus', async function () {
const [part, accessor, tracker] = await createTracker();
const accessor = await createTracker();
const resource = toResource.call(this, '/path/index.txt');
@ -176,10 +152,6 @@ suite('Files - TextFileEditorTracker', () => {
accessor.hostService.setFocus(true);
await awaitModelLoadEvent(accessor.textFileService, resource);
part.dispose();
tracker.dispose();
(<TextFileEditorModelManager>accessor.textFileService.files).dispose();
});
function awaitModelLoadEvent(textFileService: ITextFileService, resource: URI): Promise<void> {

View file

@ -9,16 +9,16 @@ import { isMacintosh, isLinux, isWindows } from 'vs/base/common/platform';
import { OutputLinkComputer } from 'vs/workbench/contrib/output/common/outputLinkComputer';
import { TestContextService } from 'vs/workbench/test/common/workbenchTestServices';
function toOSPath(p: string): string {
if (isMacintosh || isLinux) {
return p.replace(/\\/g, '/');
}
return p;
}
suite('OutputLinkProvider', () => {
function toOSPath(p: string): string {
if (isMacintosh || isLinux) {
return p.replace(/\\/g, '/');
}
return p;
}
test('OutputLinkProvider - Link detection', function () {
const rootFolder = isWindows ? URI.file('C:\\Users\\someone\\AppData\\Local\\Temp\\_monacodata_9888\\workspaces\\mankala') :
URI.file('C:/Users/someone/AppData/Local/Temp/_monacodata_9888/workspaces/mankala');
@ -29,256 +29,256 @@ suite('OutputLinkProvider', () => {
let line = toOSPath('Foo bar');
let result = OutputLinkComputer.detectLinks(line, 1, patterns, contextService);
assert.equal(result.length, 0);
assert.strictEqual(result.length, 0);
// Example: at C:\\Users\\someone\\AppData\\Local\\Temp\\_monacodata_9888\\workspaces\\mankala\\Game.ts
line = toOSPath(' at C:\\Users\\someone\\AppData\\Local\\Temp\\_monacodata_9888\\workspaces\\mankala\\Game.ts in');
result = OutputLinkComputer.detectLinks(line, 1, patterns, contextService);
assert.equal(result.length, 1);
assert.equal(result[0].url, contextService.toResource('/Game.ts').toString());
assert.equal(result[0].range.startColumn, 5);
assert.equal(result[0].range.endColumn, 84);
assert.strictEqual(result.length, 1);
assert.strictEqual(result[0].url, contextService.toResource('/Game.ts').toString());
assert.strictEqual(result[0].range.startColumn, 5);
assert.strictEqual(result[0].range.endColumn, 84);
// Example: at C:\\Users\\someone\\AppData\\Local\\Temp\\_monacodata_9888\\workspaces\\mankala\\Game.ts:336
line = toOSPath(' at C:\\Users\\someone\\AppData\\Local\\Temp\\_monacodata_9888\\workspaces\\mankala\\Game.ts:336 in');
result = OutputLinkComputer.detectLinks(line, 1, patterns, contextService);
assert.equal(result.length, 1);
assert.equal(result[0].url, contextService.toResource('/Game.ts').toString() + '#336');
assert.equal(result[0].range.startColumn, 5);
assert.equal(result[0].range.endColumn, 88);
assert.strictEqual(result.length, 1);
assert.strictEqual(result[0].url, contextService.toResource('/Game.ts').toString() + '#336');
assert.strictEqual(result[0].range.startColumn, 5);
assert.strictEqual(result[0].range.endColumn, 88);
// Example: at C:\\Users\\someone\\AppData\\Local\\Temp\\_monacodata_9888\\workspaces\\mankala\\Game.ts:336:9
line = toOSPath(' at C:\\Users\\someone\\AppData\\Local\\Temp\\_monacodata_9888\\workspaces\\mankala\\Game.ts:336:9 in');
result = OutputLinkComputer.detectLinks(line, 1, patterns, contextService);
assert.equal(result.length, 1);
assert.equal(result[0].url, contextService.toResource('/Game.ts').toString() + '#336,9');
assert.equal(result[0].range.startColumn, 5);
assert.equal(result[0].range.endColumn, 90);
assert.strictEqual(result.length, 1);
assert.strictEqual(result[0].url, contextService.toResource('/Game.ts').toString() + '#336,9');
assert.strictEqual(result[0].range.startColumn, 5);
assert.strictEqual(result[0].range.endColumn, 90);
line = toOSPath(' at C:\\Users\\someone\\AppData\\Local\\Temp\\_monacodata_9888\\workspaces\\mankala\\Game.ts:336:9 in');
result = OutputLinkComputer.detectLinks(line, 1, patterns, contextService);
assert.equal(result.length, 1);
assert.equal(result[0].url, contextService.toResource('/Game.ts').toString() + '#336,9');
assert.equal(result[0].range.startColumn, 5);
assert.equal(result[0].range.endColumn, 90);
assert.strictEqual(result.length, 1);
assert.strictEqual(result[0].url, contextService.toResource('/Game.ts').toString() + '#336,9');
assert.strictEqual(result[0].range.startColumn, 5);
assert.strictEqual(result[0].range.endColumn, 90);
// Example: at C:\\Users\\someone\\AppData\\Local\\Temp\\_monacodata_9888\\workspaces\\mankala\\Game.ts>dir
line = toOSPath(' at C:\\Users\\someone\\AppData\\Local\\Temp\\_monacodata_9888\\workspaces\\mankala\\Game.ts>dir in');
result = OutputLinkComputer.detectLinks(line, 1, patterns, contextService);
assert.equal(result.length, 1);
assert.equal(result[0].url, contextService.toResource('/Game.ts').toString());
assert.equal(result[0].range.startColumn, 5);
assert.equal(result[0].range.endColumn, 84);
assert.strictEqual(result.length, 1);
assert.strictEqual(result[0].url, contextService.toResource('/Game.ts').toString());
assert.strictEqual(result[0].range.startColumn, 5);
assert.strictEqual(result[0].range.endColumn, 84);
// Example: at [C:\\Users\\someone\\AppData\\Local\\Temp\\_monacodata_9888\\workspaces\\mankala\\Game.ts:336:9]
line = toOSPath(' at C:\\Users\\someone\\AppData\\Local\\Temp\\_monacodata_9888\\workspaces\\mankala\\Game.ts:336:9] in');
result = OutputLinkComputer.detectLinks(line, 1, patterns, contextService);
assert.equal(result.length, 1);
assert.equal(result[0].url, contextService.toResource('/Game.ts').toString() + '#336,9');
assert.equal(result[0].range.startColumn, 5);
assert.equal(result[0].range.endColumn, 90);
assert.strictEqual(result.length, 1);
assert.strictEqual(result[0].url, contextService.toResource('/Game.ts').toString() + '#336,9');
assert.strictEqual(result[0].range.startColumn, 5);
assert.strictEqual(result[0].range.endColumn, 90);
// Example: at [C:\\Users\\someone\\AppData\\Local\\Temp\\_monacodata_9888\\workspaces\\mankala\\Game.ts]
line = toOSPath(' at C:\\Users\\someone\\AppData\\Local\\Temp\\_monacodata_9888\\workspaces\\mankala\\Game.ts] in');
result = OutputLinkComputer.detectLinks(line, 1, patterns, contextService);
assert.equal(result.length, 1);
assert.equal(result[0].url, contextService.toResource('/Game.ts]').toString());
assert.strictEqual(result.length, 1);
assert.strictEqual(result[0].url, contextService.toResource('/Game.ts]').toString());
// Example: C:\Users\someone\AppData\Local\Temp\_monacodata_9888\workspaces\express\server.js on line 8
line = toOSPath('C:\\Users\\someone\\AppData\\Local\\Temp\\_monacodata_9888\\workspaces\\mankala\\Game.ts on line 8');
result = OutputLinkComputer.detectLinks(line, 1, patterns, contextService);
assert.equal(result.length, 1);
assert.equal(result[0].url, contextService.toResource('/Game.ts').toString() + '#8');
assert.equal(result[0].range.startColumn, 1);
assert.equal(result[0].range.endColumn, 90);
assert.strictEqual(result.length, 1);
assert.strictEqual(result[0].url, contextService.toResource('/Game.ts').toString() + '#8');
assert.strictEqual(result[0].range.startColumn, 1);
assert.strictEqual(result[0].range.endColumn, 90);
// Example: C:\Users\someone\AppData\Local\Temp\_monacodata_9888\workspaces\express\server.js on line 8, column 13
line = toOSPath('C:\\Users\\someone\\AppData\\Local\\Temp\\_monacodata_9888\\workspaces\\mankala\\Game.ts on line 8, column 13');
result = OutputLinkComputer.detectLinks(line, 1, patterns, contextService);
assert.equal(result.length, 1);
assert.equal(result[0].url, contextService.toResource('/Game.ts').toString() + '#8,13');
assert.equal(result[0].range.startColumn, 1);
assert.equal(result[0].range.endColumn, 101);
assert.strictEqual(result.length, 1);
assert.strictEqual(result[0].url, contextService.toResource('/Game.ts').toString() + '#8,13');
assert.strictEqual(result[0].range.startColumn, 1);
assert.strictEqual(result[0].range.endColumn, 101);
line = toOSPath('C:\\Users\\someone\\AppData\\Local\\Temp\\_monacodata_9888\\workspaces\\mankala\\Game.ts on LINE 8, COLUMN 13');
result = OutputLinkComputer.detectLinks(line, 1, patterns, contextService);
assert.equal(result.length, 1);
assert.equal(result[0].url, contextService.toResource('/Game.ts').toString() + '#8,13');
assert.equal(result[0].range.startColumn, 1);
assert.equal(result[0].range.endColumn, 101);
assert.strictEqual(result.length, 1);
assert.strictEqual(result[0].url, contextService.toResource('/Game.ts').toString() + '#8,13');
assert.strictEqual(result[0].range.startColumn, 1);
assert.strictEqual(result[0].range.endColumn, 101);
// Example: C:\Users\someone\AppData\Local\Temp\_monacodata_9888\workspaces\express\server.js:line 8
line = toOSPath('C:\\Users\\someone\\AppData\\Local\\Temp\\_monacodata_9888\\workspaces\\mankala\\Game.ts:line 8');
result = OutputLinkComputer.detectLinks(line, 1, patterns, contextService);
assert.equal(result.length, 1);
assert.equal(result[0].url, contextService.toResource('/Game.ts').toString() + '#8');
assert.equal(result[0].range.startColumn, 1);
assert.equal(result[0].range.endColumn, 87);
assert.strictEqual(result.length, 1);
assert.strictEqual(result[0].url, contextService.toResource('/Game.ts').toString() + '#8');
assert.strictEqual(result[0].range.startColumn, 1);
assert.strictEqual(result[0].range.endColumn, 87);
// Example: at File.put (C:/Users/someone/AppData/Local/Temp/_monacodata_9888/workspaces/mankala/Game.ts)
line = toOSPath(' at File.put (C:/Users/someone/AppData/Local/Temp/_monacodata_9888/workspaces/mankala/Game.ts)');
result = OutputLinkComputer.detectLinks(line, 1, patterns, contextService);
assert.equal(result.length, 1);
assert.equal(result[0].url, contextService.toResource('/Game.ts').toString());
assert.equal(result[0].range.startColumn, 15);
assert.equal(result[0].range.endColumn, 94);
assert.strictEqual(result.length, 1);
assert.strictEqual(result[0].url, contextService.toResource('/Game.ts').toString());
assert.strictEqual(result[0].range.startColumn, 15);
assert.strictEqual(result[0].range.endColumn, 94);
// Example: at File.put (C:/Users/someone/AppData/Local/Temp/_monacodata_9888/workspaces/mankala/Game.ts:278)
line = toOSPath(' at File.put (C:/Users/someone/AppData/Local/Temp/_monacodata_9888/workspaces/mankala/Game.ts:278)');
result = OutputLinkComputer.detectLinks(line, 1, patterns, contextService);
assert.equal(result.length, 1);
assert.equal(result[0].url, contextService.toResource('/Game.ts').toString() + '#278');
assert.equal(result[0].range.startColumn, 15);
assert.equal(result[0].range.endColumn, 98);
assert.strictEqual(result.length, 1);
assert.strictEqual(result[0].url, contextService.toResource('/Game.ts').toString() + '#278');
assert.strictEqual(result[0].range.startColumn, 15);
assert.strictEqual(result[0].range.endColumn, 98);
// Example: at File.put (C:/Users/someone/AppData/Local/Temp/_monacodata_9888/workspaces/mankala/Game.ts:278:34)
line = toOSPath(' at File.put (C:/Users/someone/AppData/Local/Temp/_monacodata_9888/workspaces/mankala/Game.ts:278:34)');
result = OutputLinkComputer.detectLinks(line, 1, patterns, contextService);
assert.equal(result.length, 1);
assert.equal(result[0].url, contextService.toResource('/Game.ts').toString() + '#278,34');
assert.equal(result[0].range.startColumn, 15);
assert.equal(result[0].range.endColumn, 101);
assert.strictEqual(result.length, 1);
assert.strictEqual(result[0].url, contextService.toResource('/Game.ts').toString() + '#278,34');
assert.strictEqual(result[0].range.startColumn, 15);
assert.strictEqual(result[0].range.endColumn, 101);
line = toOSPath(' at File.put (C:/Users/someone/AppData/Local/Temp/_monacodata_9888/workspaces/mankala/Game.ts:278:34)');
result = OutputLinkComputer.detectLinks(line, 1, patterns, contextService);
assert.equal(result.length, 1);
assert.equal(result[0].url, contextService.toResource('/Game.ts').toString() + '#278,34');
assert.equal(result[0].range.startColumn, 15);
assert.equal(result[0].range.endColumn, 101);
assert.strictEqual(result.length, 1);
assert.strictEqual(result[0].url, contextService.toResource('/Game.ts').toString() + '#278,34');
assert.strictEqual(result[0].range.startColumn, 15);
assert.strictEqual(result[0].range.endColumn, 101);
// Example: C:/Users/someone/AppData/Local/Temp/_monacodata_9888/workspaces/mankala/Features.ts(45): error
line = toOSPath('C:/Users/someone/AppData/Local/Temp/_monacodata_9888/workspaces/mankala/lib/something/Features.ts(45): error');
result = OutputLinkComputer.detectLinks(line, 1, patterns, contextService);
assert.equal(result.length, 1);
assert.equal(result[0].url, contextService.toResource('/lib/something/Features.ts').toString() + '#45');
assert.equal(result[0].range.startColumn, 1);
assert.equal(result[0].range.endColumn, 102);
assert.strictEqual(result.length, 1);
assert.strictEqual(result[0].url, contextService.toResource('/lib/something/Features.ts').toString() + '#45');
assert.strictEqual(result[0].range.startColumn, 1);
assert.strictEqual(result[0].range.endColumn, 102);
// Example: C:/Users/someone/AppData/Local/Temp/_monacodata_9888/workspaces/mankala/Features.ts (45,18): error
line = toOSPath('C:/Users/someone/AppData/Local/Temp/_monacodata_9888/workspaces/mankala/lib/something/Features.ts (45): error');
result = OutputLinkComputer.detectLinks(line, 1, patterns, contextService);
assert.equal(result.length, 1);
assert.equal(result[0].url, contextService.toResource('/lib/something/Features.ts').toString() + '#45');
assert.equal(result[0].range.startColumn, 1);
assert.equal(result[0].range.endColumn, 103);
assert.strictEqual(result.length, 1);
assert.strictEqual(result[0].url, contextService.toResource('/lib/something/Features.ts').toString() + '#45');
assert.strictEqual(result[0].range.startColumn, 1);
assert.strictEqual(result[0].range.endColumn, 103);
// Example: C:/Users/someone/AppData/Local/Temp/_monacodata_9888/workspaces/mankala/Features.ts(45,18): error
line = toOSPath('C:/Users/someone/AppData/Local/Temp/_monacodata_9888/workspaces/mankala/lib/something/Features.ts(45,18): error');
result = OutputLinkComputer.detectLinks(line, 1, patterns, contextService);
assert.equal(result.length, 1);
assert.equal(result[0].url, contextService.toResource('/lib/something/Features.ts').toString() + '#45,18');
assert.equal(result[0].range.startColumn, 1);
assert.equal(result[0].range.endColumn, 105);
assert.strictEqual(result.length, 1);
assert.strictEqual(result[0].url, contextService.toResource('/lib/something/Features.ts').toString() + '#45,18');
assert.strictEqual(result[0].range.startColumn, 1);
assert.strictEqual(result[0].range.endColumn, 105);
line = toOSPath('C:/Users/someone/AppData/Local/Temp/_monacodata_9888/workspaces/mankala/lib/something/Features.ts(45,18): error');
result = OutputLinkComputer.detectLinks(line, 1, patterns, contextService);
assert.equal(result.length, 1);
assert.equal(result[0].url, contextService.toResource('/lib/something/Features.ts').toString() + '#45,18');
assert.equal(result[0].range.startColumn, 1);
assert.equal(result[0].range.endColumn, 105);
assert.strictEqual(result.length, 1);
assert.strictEqual(result[0].url, contextService.toResource('/lib/something/Features.ts').toString() + '#45,18');
assert.strictEqual(result[0].range.startColumn, 1);
assert.strictEqual(result[0].range.endColumn, 105);
// Example: C:/Users/someone/AppData/Local/Temp/_monacodata_9888/workspaces/mankala/Features.ts (45,18): error
line = toOSPath('C:/Users/someone/AppData/Local/Temp/_monacodata_9888/workspaces/mankala/lib/something/Features.ts (45,18): error');
result = OutputLinkComputer.detectLinks(line, 1, patterns, contextService);
assert.equal(result.length, 1);
assert.equal(result[0].url, contextService.toResource('/lib/something/Features.ts').toString() + '#45,18');
assert.equal(result[0].range.startColumn, 1);
assert.equal(result[0].range.endColumn, 106);
assert.strictEqual(result.length, 1);
assert.strictEqual(result[0].url, contextService.toResource('/lib/something/Features.ts').toString() + '#45,18');
assert.strictEqual(result[0].range.startColumn, 1);
assert.strictEqual(result[0].range.endColumn, 106);
line = toOSPath('C:/Users/someone/AppData/Local/Temp/_monacodata_9888/workspaces/mankala/lib/something/Features.ts (45,18): error');
result = OutputLinkComputer.detectLinks(line, 1, patterns, contextService);
assert.equal(result.length, 1);
assert.equal(result[0].url, contextService.toResource('/lib/something/Features.ts').toString() + '#45,18');
assert.equal(result[0].range.startColumn, 1);
assert.equal(result[0].range.endColumn, 106);
assert.strictEqual(result.length, 1);
assert.strictEqual(result[0].url, contextService.toResource('/lib/something/Features.ts').toString() + '#45,18');
assert.strictEqual(result[0].range.startColumn, 1);
assert.strictEqual(result[0].range.endColumn, 106);
// Example: C:/Users/someone/AppData/Local/Temp/_monacodata_9888/workspaces/mankala/Features.ts(45): error
line = toOSPath('C:\\Users\\someone\\AppData\\Local\\Temp\\_monacodata_9888\\workspaces\\mankala\\lib\\something\\Features.ts(45): error');
result = OutputLinkComputer.detectLinks(line, 1, patterns, contextService);
assert.equal(result.length, 1);
assert.equal(result[0].url, contextService.toResource('/lib/something/Features.ts').toString() + '#45');
assert.equal(result[0].range.startColumn, 1);
assert.equal(result[0].range.endColumn, 102);
assert.strictEqual(result.length, 1);
assert.strictEqual(result[0].url, contextService.toResource('/lib/something/Features.ts').toString() + '#45');
assert.strictEqual(result[0].range.startColumn, 1);
assert.strictEqual(result[0].range.endColumn, 102);
// Example: C:/Users/someone/AppData/Local/Temp/_monacodata_9888/workspaces/mankala/Features.ts (45,18): error
line = toOSPath('C:\\Users\\someone\\AppData\\Local\\Temp\\_monacodata_9888\\workspaces\\mankala\\lib\\something\\Features.ts (45): error');
result = OutputLinkComputer.detectLinks(line, 1, patterns, contextService);
assert.equal(result.length, 1);
assert.equal(result[0].url, contextService.toResource('/lib/something/Features.ts').toString() + '#45');
assert.equal(result[0].range.startColumn, 1);
assert.equal(result[0].range.endColumn, 103);
assert.strictEqual(result.length, 1);
assert.strictEqual(result[0].url, contextService.toResource('/lib/something/Features.ts').toString() + '#45');
assert.strictEqual(result[0].range.startColumn, 1);
assert.strictEqual(result[0].range.endColumn, 103);
// Example: C:/Users/someone/AppData/Local/Temp/_monacodata_9888/workspaces/mankala/Features.ts(45,18): error
line = toOSPath('C:\\Users\\someone\\AppData\\Local\\Temp\\_monacodata_9888\\workspaces\\mankala\\lib\\something\\Features.ts(45,18): error');
result = OutputLinkComputer.detectLinks(line, 1, patterns, contextService);
assert.equal(result.length, 1);
assert.equal(result[0].url, contextService.toResource('/lib/something/Features.ts').toString() + '#45,18');
assert.equal(result[0].range.startColumn, 1);
assert.equal(result[0].range.endColumn, 105);
assert.strictEqual(result.length, 1);
assert.strictEqual(result[0].url, contextService.toResource('/lib/something/Features.ts').toString() + '#45,18');
assert.strictEqual(result[0].range.startColumn, 1);
assert.strictEqual(result[0].range.endColumn, 105);
line = toOSPath('C:\\Users\\someone\\AppData\\Local\\Temp\\_monacodata_9888\\workspaces\\mankala\\lib\\something\\Features.ts(45,18): error');
result = OutputLinkComputer.detectLinks(line, 1, patterns, contextService);
assert.equal(result.length, 1);
assert.equal(result[0].url, contextService.toResource('/lib/something/Features.ts').toString() + '#45,18');
assert.equal(result[0].range.startColumn, 1);
assert.equal(result[0].range.endColumn, 105);
assert.strictEqual(result.length, 1);
assert.strictEqual(result[0].url, contextService.toResource('/lib/something/Features.ts').toString() + '#45,18');
assert.strictEqual(result[0].range.startColumn, 1);
assert.strictEqual(result[0].range.endColumn, 105);
// Example: C:/Users/someone/AppData/Local/Temp/_monacodata_9888/workspaces/mankala/Features.ts (45,18): error
line = toOSPath('C:\\Users\\someone\\AppData\\Local\\Temp\\_monacodata_9888\\workspaces\\mankala\\lib\\something\\Features.ts (45,18): error');
result = OutputLinkComputer.detectLinks(line, 1, patterns, contextService);
assert.equal(result.length, 1);
assert.equal(result[0].url, contextService.toResource('/lib/something/Features.ts').toString() + '#45,18');
assert.equal(result[0].range.startColumn, 1);
assert.equal(result[0].range.endColumn, 106);
assert.strictEqual(result.length, 1);
assert.strictEqual(result[0].url, contextService.toResource('/lib/something/Features.ts').toString() + '#45,18');
assert.strictEqual(result[0].range.startColumn, 1);
assert.strictEqual(result[0].range.endColumn, 106);
line = toOSPath('C:\\Users\\someone\\AppData\\Local\\Temp\\_monacodata_9888\\workspaces\\mankala\\lib\\something\\Features.ts (45,18): error');
result = OutputLinkComputer.detectLinks(line, 1, patterns, contextService);
assert.equal(result.length, 1);
assert.equal(result[0].url, contextService.toResource('/lib/something/Features.ts').toString() + '#45,18');
assert.equal(result[0].range.startColumn, 1);
assert.equal(result[0].range.endColumn, 106);
assert.strictEqual(result.length, 1);
assert.strictEqual(result[0].url, contextService.toResource('/lib/something/Features.ts').toString() + '#45,18');
assert.strictEqual(result[0].range.startColumn, 1);
assert.strictEqual(result[0].range.endColumn, 106);
// Example: C:\\Users\\someone\\AppData\\Local\\Temp\\_monacodata_9888\\workspaces\\mankala\\lib\\something\\Features Special.ts (45,18): error.
line = toOSPath('C:\\Users\\someone\\AppData\\Local\\Temp\\_monacodata_9888\\workspaces\\mankala\\lib\\something\\Features Special.ts (45,18): error');
result = OutputLinkComputer.detectLinks(line, 1, patterns, contextService);
assert.equal(result.length, 1);
assert.equal(result[0].url, contextService.toResource('/lib/something/Features Special.ts').toString() + '#45,18');
assert.equal(result[0].range.startColumn, 1);
assert.equal(result[0].range.endColumn, 114);
assert.strictEqual(result.length, 1);
assert.strictEqual(result[0].url, contextService.toResource('/lib/something/Features Special.ts').toString() + '#45,18');
assert.strictEqual(result[0].range.startColumn, 1);
assert.strictEqual(result[0].range.endColumn, 114);
// Example: at C:\\Users\\someone\\AppData\\Local\\Temp\\_monacodata_9888\\workspaces\\mankala\\Game.ts.
line = toOSPath(' at C:\\Users\\someone\\AppData\\Local\\Temp\\_monacodata_9888\\workspaces\\mankala\\Game.ts. in');
result = OutputLinkComputer.detectLinks(line, 1, patterns, contextService);
assert.equal(result.length, 1);
assert.equal(result[0].url, contextService.toResource('/Game.ts').toString());
assert.equal(result[0].range.startColumn, 5);
assert.equal(result[0].range.endColumn, 84);
assert.strictEqual(result.length, 1);
assert.strictEqual(result[0].url, contextService.toResource('/Game.ts').toString());
assert.strictEqual(result[0].range.startColumn, 5);
assert.strictEqual(result[0].range.endColumn, 84);
// Example: at C:\\Users\\someone\\AppData\\Local\\Temp\\_monacodata_9888\\workspaces\\mankala\\Game
line = toOSPath(' at C:\\Users\\someone\\AppData\\Local\\Temp\\_monacodata_9888\\workspaces\\mankala\\Game in');
result = OutputLinkComputer.detectLinks(line, 1, patterns, contextService);
assert.equal(result.length, 1);
assert.strictEqual(result.length, 1);
// Example: at C:\\Users\\someone\\AppData\\Local\\Temp\\_monacodata_9888\\workspaces\\mankala\\Game\\
line = toOSPath(' at C:\\Users\\someone\\AppData\\Local\\Temp\\_monacodata_9888\\workspaces\\mankala\\Game\\ in');
result = OutputLinkComputer.detectLinks(line, 1, patterns, contextService);
assert.equal(result.length, 1);
assert.strictEqual(result.length, 1);
// Example: at "C:\\Users\\someone\\AppData\\Local\\Temp\\_monacodata_9888\\workspaces\\mankala\\Game.ts"
line = toOSPath(' at "C:\\Users\\someone\\AppData\\Local\\Temp\\_monacodata_9888\\workspaces\\mankala\\Game.ts" in');
result = OutputLinkComputer.detectLinks(line, 1, patterns, contextService);
assert.equal(result.length, 1);
assert.equal(result[0].url, contextService.toResource('/Game.ts').toString());
assert.equal(result[0].range.startColumn, 6);
assert.equal(result[0].range.endColumn, 85);
assert.strictEqual(result.length, 1);
assert.strictEqual(result[0].url, contextService.toResource('/Game.ts').toString());
assert.strictEqual(result[0].range.startColumn, 6);
assert.strictEqual(result[0].range.endColumn, 85);
// Example: at 'C:\\Users\\someone\\AppData\\Local\\Temp\\_monacodata_9888\\workspaces\\mankala\\Game.ts'
line = toOSPath(' at \'C:\\Users\\someone\\AppData\\Local\\Temp\\_monacodata_9888\\workspaces\\mankala\\Game.ts\' in');
result = OutputLinkComputer.detectLinks(line, 1, patterns, contextService);
assert.equal(result.length, 1);
assert.equal(result[0].url, contextService.toResource('/Game.ts\'').toString());
assert.equal(result[0].range.startColumn, 6);
assert.equal(result[0].range.endColumn, 86);
assert.strictEqual(result.length, 1);
assert.strictEqual(result[0].url, contextService.toResource('/Game.ts\'').toString());
assert.strictEqual(result[0].range.startColumn, 6);
assert.strictEqual(result[0].range.endColumn, 86);
});
test('OutputLinkProvider - #106847', function () {
@ -291,7 +291,7 @@ suite('OutputLinkProvider', () => {
let line = toOSPath('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa C:\\Users\\bpasero\\Desktop\\test-ts\\prj.conf C:\\Users\\bpasero\\Desktop\\test-ts\\prj.conf C:\\Users\\bpasero\\Desktop\\test-ts\\prj.conf');
let result = OutputLinkComputer.detectLinks(line, 1, patterns, contextService);
assert.equal(result.length, 3);
assert.strictEqual(result.length, 3);
for (const res of result) {
assert.ok(res.range.startColumn > 0 && res.range.endColumn > 0);

View file

@ -4,12 +4,12 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import * as platform from 'vs/base/common/platform';
import * as crypto from 'crypto';
import * as os from 'os';
import * as fs from 'fs';
import * as path from 'vs/base/common/path';
import * as pfs from 'vs/base/node/pfs';
import { isWindows } from 'vs/base/common/platform';
import { createHash } from 'crypto';
import { tmpdir } from 'os';
import { existsSync, readFileSync, writeFileSync } from 'fs';
import { dirname, join } from 'vs/base/common/path';
import { mkdirp, readdirSync, rimraf, writeFile } from 'vs/base/node/pfs';
import { URI } from 'vs/base/common/uri';
import { BackupFilesModel } from 'vs/workbench/services/backup/common/backupFileService';
import { createTextBufferFactory } from 'vs/editor/common/model/textModel';
@ -121,32 +121,32 @@ suite('BackupFileService', () => {
let service: NodeTestBackupFileService;
let workspaceResource = URI.file(platform.isWindows ? 'c:\\workspace' : '/workspace');
let fooFile = URI.file(platform.isWindows ? 'c:\\Foo' : '/Foo');
let workspaceResource = URI.file(isWindows ? 'c:\\workspace' : '/workspace');
let fooFile = URI.file(isWindows ? 'c:\\Foo' : '/Foo');
let customFile = URI.parse('customScheme://some/path');
let customFileWithFragment = URI.parse('customScheme2://some/path#fragment');
let barFile = URI.file(platform.isWindows ? 'c:\\Bar' : '/Bar');
let fooBarFile = URI.file(platform.isWindows ? 'c:\\Foo Bar' : '/Foo Bar');
let barFile = URI.file(isWindows ? 'c:\\Bar' : '/Bar');
let fooBarFile = URI.file(isWindows ? 'c:\\Foo Bar' : '/Foo Bar');
let untitledFile = URI.from({ scheme: Schemas.untitled, path: 'Untitled-1' });
setup(async () => {
testDir = getRandomTestPath(os.tmpdir(), 'vsctests', 'backupfileservice');
backupHome = path.join(testDir, 'Backups');
workspacesJsonPath = path.join(backupHome, 'workspaces.json');
workspaceBackupPath = path.join(backupHome, hashPath(workspaceResource));
fooBackupPath = path.join(workspaceBackupPath, 'file', hashPath(fooFile));
barBackupPath = path.join(workspaceBackupPath, 'file', hashPath(barFile));
untitledBackupPath = path.join(workspaceBackupPath, 'untitled', hashPath(untitledFile));
testDir = getRandomTestPath(tmpdir(), 'vsctests', 'backupfileservice');
backupHome = join(testDir, 'Backups');
workspacesJsonPath = join(backupHome, 'workspaces.json');
workspaceBackupPath = join(backupHome, hashPath(workspaceResource));
fooBackupPath = join(workspaceBackupPath, 'file', hashPath(fooFile));
barBackupPath = join(workspaceBackupPath, 'file', hashPath(barFile));
untitledBackupPath = join(workspaceBackupPath, 'untitled', hashPath(untitledFile));
service = new NodeTestBackupFileService(testDir, workspaceBackupPath);
await pfs.mkdirp(backupHome);
await mkdirp(backupHome);
return pfs.writeFile(workspacesJsonPath, '');
return writeFile(workspacesJsonPath, '');
});
teardown(() => {
return pfs.rimraf(testDir);
return rimraf(testDir);
});
suite('hashPath', () => {
@ -158,19 +158,19 @@ suite('BackupFileService', () => {
const actual = hashPath(uri);
// If these hashes change people will lose their backed up files!
assert.strictEqual(actual, '13264068d108c6901b3592ea654fcd57');
assert.strictEqual(actual, crypto.createHash('md5').update(uri.fsPath).digest('hex'));
assert.strictEqual(actual, createHash('md5').update(uri.fsPath).digest('hex'));
});
test('should correctly hash the path for file scheme URIs', () => {
const uri = URI.file('/foo');
const actual = hashPath(uri);
// If these hashes change people will lose their backed up files!
if (platform.isWindows) {
if (isWindows) {
assert.strictEqual(actual, 'dec1a583f52468a020bd120c3f01d812');
} else {
assert.strictEqual(actual, '1effb2475fcfba4f9e8b8a1dbc8f3caf');
}
assert.strictEqual(actual, crypto.createHash('md5').update(uri.fsPath).digest('hex'));
assert.strictEqual(actual, createHash('md5').update(uri.fsPath).digest('hex'));
});
});
@ -180,7 +180,7 @@ suite('BackupFileService', () => {
const backupResource = fooFile;
const workspaceHash = hashPath(workspaceResource);
const filePathHash = hashPath(backupResource);
const expectedPath = URI.file(path.join(backupHome, workspaceHash, Schemas.file, filePathHash)).with({ scheme: Schemas.userData }).toString();
const expectedPath = URI.file(join(backupHome, workspaceHash, Schemas.file, filePathHash)).with({ scheme: Schemas.userData }).toString();
assert.strictEqual(service.toBackupResource(backupResource).toString(), expectedPath);
});
@ -189,7 +189,7 @@ suite('BackupFileService', () => {
const backupResource = URI.from({ scheme: Schemas.untitled, path: 'Untitled-1' });
const workspaceHash = hashPath(workspaceResource);
const filePathHash = hashPath(backupResource);
const expectedPath = URI.file(path.join(backupHome, workspaceHash, Schemas.untitled, filePathHash)).with({ scheme: Schemas.userData }).toString();
const expectedPath = URI.file(join(backupHome, workspaceHash, Schemas.untitled, filePathHash)).with({ scheme: Schemas.userData }).toString();
assert.strictEqual(service.toBackupResource(backupResource).toString(), expectedPath);
});
});
@ -197,42 +197,42 @@ suite('BackupFileService', () => {
suite('backup', () => {
test('no text', async () => {
await service.backup(fooFile);
assert.strictEqual(fs.readdirSync(path.join(workspaceBackupPath, 'file')).length, 1);
assert.strictEqual(fs.existsSync(fooBackupPath), true);
assert.strictEqual(fs.readFileSync(fooBackupPath).toString(), `${fooFile.toString()}\n`);
assert.strictEqual(readdirSync(join(workspaceBackupPath, 'file')).length, 1);
assert.strictEqual(existsSync(fooBackupPath), true);
assert.strictEqual(readFileSync(fooBackupPath).toString(), `${fooFile.toString()}\n`);
assert.ok(service.hasBackupSync(fooFile));
});
test('text file', async () => {
await service.backup(fooFile, createTextBufferFactory('test').create(DefaultEndOfLine.LF).textBuffer.createSnapshot(false));
assert.strictEqual(fs.readdirSync(path.join(workspaceBackupPath, 'file')).length, 1);
assert.strictEqual(fs.existsSync(fooBackupPath), true);
assert.strictEqual(fs.readFileSync(fooBackupPath).toString(), `${fooFile.toString()}\ntest`);
assert.strictEqual(readdirSync(join(workspaceBackupPath, 'file')).length, 1);
assert.strictEqual(existsSync(fooBackupPath), true);
assert.strictEqual(readFileSync(fooBackupPath).toString(), `${fooFile.toString()}\ntest`);
assert.ok(service.hasBackupSync(fooFile));
});
test('text file (with version)', async () => {
await service.backup(fooFile, createTextBufferFactory('test').create(DefaultEndOfLine.LF).textBuffer.createSnapshot(false), 666);
assert.strictEqual(fs.readdirSync(path.join(workspaceBackupPath, 'file')).length, 1);
assert.strictEqual(fs.existsSync(fooBackupPath), true);
assert.strictEqual(fs.readFileSync(fooBackupPath).toString(), `${fooFile.toString()}\ntest`);
assert.strictEqual(readdirSync(join(workspaceBackupPath, 'file')).length, 1);
assert.strictEqual(existsSync(fooBackupPath), true);
assert.strictEqual(readFileSync(fooBackupPath).toString(), `${fooFile.toString()}\ntest`);
assert.ok(!service.hasBackupSync(fooFile, 555));
assert.ok(service.hasBackupSync(fooFile, 666));
});
test('text file (with meta)', async () => {
await service.backup(fooFile, createTextBufferFactory('test').create(DefaultEndOfLine.LF).textBuffer.createSnapshot(false), undefined, { etag: '678', orphaned: true });
assert.strictEqual(fs.readdirSync(path.join(workspaceBackupPath, 'file')).length, 1);
assert.strictEqual(fs.existsSync(fooBackupPath), true);
assert.strictEqual(fs.readFileSync(fooBackupPath).toString(), `${fooFile.toString()} {"etag":"678","orphaned":true}\ntest`);
assert.strictEqual(readdirSync(join(workspaceBackupPath, 'file')).length, 1);
assert.strictEqual(existsSync(fooBackupPath), true);
assert.strictEqual(readFileSync(fooBackupPath).toString(), `${fooFile.toString()} {"etag":"678","orphaned":true}\ntest`);
assert.ok(service.hasBackupSync(fooFile));
});
test('untitled file', async () => {
await service.backup(untitledFile, createTextBufferFactory('test').create(DefaultEndOfLine.LF).textBuffer.createSnapshot(false));
assert.strictEqual(fs.readdirSync(path.join(workspaceBackupPath, 'untitled')).length, 1);
assert.strictEqual(fs.existsSync(untitledBackupPath), true);
assert.strictEqual(fs.readFileSync(untitledBackupPath).toString(), `${untitledFile.toString()}\ntest`);
assert.strictEqual(readdirSync(join(workspaceBackupPath, 'untitled')).length, 1);
assert.strictEqual(existsSync(untitledBackupPath), true);
assert.strictEqual(readFileSync(untitledBackupPath).toString(), `${untitledFile.toString()}\ntest`);
assert.ok(service.hasBackupSync(untitledFile));
});
@ -240,9 +240,9 @@ suite('BackupFileService', () => {
const model = createTextModel('test');
await service.backup(fooFile, model.createSnapshot());
assert.strictEqual(fs.readdirSync(path.join(workspaceBackupPath, 'file')).length, 1);
assert.strictEqual(fs.existsSync(fooBackupPath), true);
assert.strictEqual(fs.readFileSync(fooBackupPath).toString(), `${fooFile.toString()}\ntest`);
assert.strictEqual(readdirSync(join(workspaceBackupPath, 'file')).length, 1);
assert.strictEqual(existsSync(fooBackupPath), true);
assert.strictEqual(readFileSync(fooBackupPath).toString(), `${fooFile.toString()}\ntest`);
assert.ok(service.hasBackupSync(fooFile));
model.dispose();
@ -252,9 +252,9 @@ suite('BackupFileService', () => {
const model = createTextModel('test');
await service.backup(untitledFile, model.createSnapshot());
assert.strictEqual(fs.readdirSync(path.join(workspaceBackupPath, 'untitled')).length, 1);
assert.strictEqual(fs.existsSync(untitledBackupPath), true);
assert.strictEqual(fs.readFileSync(untitledBackupPath).toString(), `${untitledFile.toString()}\ntest`);
assert.strictEqual(readdirSync(join(workspaceBackupPath, 'untitled')).length, 1);
assert.strictEqual(existsSync(untitledBackupPath), true);
assert.strictEqual(readFileSync(untitledBackupPath).toString(), `${untitledFile.toString()}\ntest`);
model.dispose();
});
@ -264,9 +264,9 @@ suite('BackupFileService', () => {
const model = createTextModel(largeString);
await service.backup(fooFile, model.createSnapshot());
assert.strictEqual(fs.readdirSync(path.join(workspaceBackupPath, 'file')).length, 1);
assert.strictEqual(fs.existsSync(fooBackupPath), true);
assert.strictEqual(fs.readFileSync(fooBackupPath).toString(), `${fooFile.toString()}\n${largeString}`);
assert.strictEqual(readdirSync(join(workspaceBackupPath, 'file')).length, 1);
assert.strictEqual(existsSync(fooBackupPath), true);
assert.strictEqual(readFileSync(fooBackupPath).toString(), `${fooFile.toString()}\n${largeString}`);
assert.ok(service.hasBackupSync(fooFile));
model.dispose();
@ -277,9 +277,9 @@ suite('BackupFileService', () => {
const model = createTextModel(largeString);
await service.backup(untitledFile, model.createSnapshot());
assert.strictEqual(fs.readdirSync(path.join(workspaceBackupPath, 'untitled')).length, 1);
assert.strictEqual(fs.existsSync(untitledBackupPath), true);
assert.strictEqual(fs.readFileSync(untitledBackupPath).toString(), `${untitledFile.toString()}\n${largeString}`);
assert.strictEqual(readdirSync(join(workspaceBackupPath, 'untitled')).length, 1);
assert.strictEqual(existsSync(untitledBackupPath), true);
assert.strictEqual(readFileSync(untitledBackupPath).toString(), `${untitledFile.toString()}\n${largeString}`);
assert.ok(service.hasBackupSync(untitledFile));
model.dispose();
@ -291,7 +291,7 @@ suite('BackupFileService', () => {
cts.cancel();
await promise;
assert.strictEqual(fs.existsSync(fooBackupPath), false);
assert.strictEqual(existsSync(fooBackupPath), false);
assert.ok(!service.hasBackupSync(fooFile));
});
});
@ -299,48 +299,48 @@ suite('BackupFileService', () => {
suite('discardBackup', () => {
test('text file', async () => {
await service.backup(fooFile, createTextBufferFactory('test').create(DefaultEndOfLine.LF).textBuffer.createSnapshot(false));
assert.strictEqual(fs.readdirSync(path.join(workspaceBackupPath, 'file')).length, 1);
assert.strictEqual(readdirSync(join(workspaceBackupPath, 'file')).length, 1);
assert.ok(service.hasBackupSync(fooFile));
await service.discardBackup(fooFile);
assert.strictEqual(fs.existsSync(fooBackupPath), false);
assert.strictEqual(fs.readdirSync(path.join(workspaceBackupPath, 'file')).length, 0);
assert.strictEqual(existsSync(fooBackupPath), false);
assert.strictEqual(readdirSync(join(workspaceBackupPath, 'file')).length, 0);
assert.ok(!service.hasBackupSync(fooFile));
});
test('untitled file', async () => {
await service.backup(untitledFile, createTextBufferFactory('test').create(DefaultEndOfLine.LF).textBuffer.createSnapshot(false));
assert.strictEqual(fs.readdirSync(path.join(workspaceBackupPath, 'untitled')).length, 1);
assert.strictEqual(readdirSync(join(workspaceBackupPath, 'untitled')).length, 1);
await service.discardBackup(untitledFile);
assert.strictEqual(fs.existsSync(untitledBackupPath), false);
assert.strictEqual(fs.readdirSync(path.join(workspaceBackupPath, 'untitled')).length, 0);
assert.strictEqual(existsSync(untitledBackupPath), false);
assert.strictEqual(readdirSync(join(workspaceBackupPath, 'untitled')).length, 0);
});
});
suite('discardBackups', () => {
test('text file', async () => {
await service.backup(fooFile, createTextBufferFactory('test').create(DefaultEndOfLine.LF).textBuffer.createSnapshot(false));
assert.strictEqual(fs.readdirSync(path.join(workspaceBackupPath, 'file')).length, 1);
assert.strictEqual(readdirSync(join(workspaceBackupPath, 'file')).length, 1);
await service.backup(barFile, createTextBufferFactory('test').create(DefaultEndOfLine.LF).textBuffer.createSnapshot(false));
assert.strictEqual(fs.readdirSync(path.join(workspaceBackupPath, 'file')).length, 2);
assert.strictEqual(readdirSync(join(workspaceBackupPath, 'file')).length, 2);
await service.discardBackups();
assert.strictEqual(fs.existsSync(fooBackupPath), false);
assert.strictEqual(fs.existsSync(barBackupPath), false);
assert.strictEqual(fs.existsSync(path.join(workspaceBackupPath, 'file')), false);
assert.strictEqual(existsSync(fooBackupPath), false);
assert.strictEqual(existsSync(barBackupPath), false);
assert.strictEqual(existsSync(join(workspaceBackupPath, 'file')), false);
});
test('untitled file', async () => {
await service.backup(untitledFile, createTextBufferFactory('test').create(DefaultEndOfLine.LF).textBuffer.createSnapshot(false));
assert.strictEqual(fs.readdirSync(path.join(workspaceBackupPath, 'untitled')).length, 1);
assert.strictEqual(readdirSync(join(workspaceBackupPath, 'untitled')).length, 1);
await service.discardBackups();
assert.strictEqual(fs.existsSync(untitledBackupPath), false);
assert.strictEqual(fs.existsSync(path.join(workspaceBackupPath, 'untitled')), false);
assert.strictEqual(existsSync(untitledBackupPath), false);
assert.strictEqual(existsSync(join(workspaceBackupPath, 'untitled')), false);
});
test('can backup after discarding all', async () => {
await service.discardBackups();
await service.backup(untitledFile, createTextBufferFactory('test').create(DefaultEndOfLine.LF).textBuffer.createSnapshot(false));
assert.strictEqual(fs.existsSync(workspaceBackupPath), true);
assert.strictEqual(existsSync(workspaceBackupPath), true);
});
});
@ -474,16 +474,16 @@ suite('BackupFileService', () => {
await service.backup(fooFile, createTextBufferFactory(contents).create(DefaultEndOfLine.LF).textBuffer.createSnapshot(false), 1, meta);
const fileContents = fs.readFileSync(fooBackupPath).toString();
const fileContents = readFileSync(fooBackupPath).toString();
assert.strictEqual(fileContents.indexOf(fooFile.toString()), 0);
const metaIndex = fileContents.indexOf('{');
const newFileContents = fileContents.substring(0, metaIndex) + '{{' + fileContents.substr(metaIndex);
fs.writeFileSync(fooBackupPath, newFileContents);
writeFileSync(fooBackupPath, newFileContents);
const backup = await service.resolve(fooFile);
assert.ok(backup);
assert.strictEqual(contents, snapshotToString(backup!.value.create(platform.isWindows ? DefaultEndOfLine.CRLF : DefaultEndOfLine.LF).textBuffer.createSnapshot(true)));
assert.strictEqual(contents, snapshotToString(backup!.value.create(isWindows ? DefaultEndOfLine.CRLF : DefaultEndOfLine.LF).textBuffer.createSnapshot(true)));
assert.ok(!backup!.meta);
});
@ -572,7 +572,7 @@ suite('BackupFileService', () => {
const backup = await service.resolve<IBackupTestMetaData>(resource);
assert.ok(backup);
assert.strictEqual(contents, snapshotToString(backup!.value.create(platform.isWindows ? DefaultEndOfLine.CRLF : DefaultEndOfLine.LF).textBuffer.createSnapshot(true)));
assert.strictEqual(contents, snapshotToString(backup!.value.create(isWindows ? DefaultEndOfLine.CRLF : DefaultEndOfLine.LF).textBuffer.createSnapshot(true)));
if (expectedMeta) {
assert.strictEqual(backup!.meta!.etag, expectedMeta.etag);
@ -639,8 +639,8 @@ suite('BackupFileService', () => {
});
test('resolve', async () => {
await pfs.mkdirp(path.dirname(fooBackupPath));
fs.writeFileSync(fooBackupPath, 'foo');
await mkdirp(dirname(fooBackupPath));
writeFileSync(fooBackupPath, 'foo');
const model = new BackupFilesModel(service.fileService);
const resolvedModel = await model.resolve(URI.file(workspaceBackupPath));

View file

@ -10,27 +10,26 @@ import { GroupDirection, GroupsOrder, MergeGroupMode, GroupOrientation, GroupCha
import { EditorOptions, CloseDirection, IEditorPartOptions, EditorsOrder } from 'vs/workbench/common/editor';
import { URI } from 'vs/base/common/uri';
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { DisposableStore } from 'vs/base/common/lifecycle';
import { MockScopableContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService';
const TEST_EDITOR_ID = 'MyFileEditorForEditorGroupService';
const TEST_EDITOR_INPUT_ID = 'testEditorInputForEditorGroupService';
suite('EditorGroupsService', () => {
let disposables: IDisposable[] = [];
const TEST_EDITOR_ID = 'MyFileEditorForEditorGroupService';
const TEST_EDITOR_INPUT_ID = 'testEditorInputForEditorGroupService';
const disposables = new DisposableStore();
setup(() => {
disposables.push(registerTestEditor(TEST_EDITOR_ID, [new SyncDescriptor(TestFileEditorInput)], TEST_EDITOR_INPUT_ID));
disposables.add(registerTestEditor(TEST_EDITOR_ID, [new SyncDescriptor(TestFileEditorInput)], TEST_EDITOR_INPUT_ID));
});
teardown(() => {
dispose(disposables);
disposables = [];
disposables.clear();
});
function createPart(instantiationService = workbenchInstantiationService()): [TestEditorPart, ITestInstantiationService] {
const part = instantiationService.createInstance(TestEditorPart);
const part = disposables.add(instantiationService.createInstance(TestEditorPart));
part.create(document.createElement('div'));
part.layout(400, 300);
@ -189,8 +188,6 @@ suite('EditorGroupsService', () => {
groupAddedListener.dispose();
groupRemovedListener.dispose();
groupMovedListener.dispose();
part.dispose();
});
test('save & restore state', async function () {
@ -219,7 +216,6 @@ suite('EditorGroupsService', () => {
assert.ok(restoredPart.getGroup(downGroup.id));
restoredPart.clearState();
restoredPart.dispose();
});
test('groups index / labels', function () {
@ -276,8 +272,6 @@ suite('EditorGroupsService', () => {
labelChangeListener.dispose();
groupIndexChangedListener.dispose();
part.dispose();
});
test('copy/merge groups', async () => {
@ -315,6 +309,7 @@ suite('EditorGroupsService', () => {
part.mergeGroup(rootGroup, downGroup);
assert.strictEqual(groupRemovedCounter, 1);
assert.strictEqual(rootGroupDisposed, true);
groupAddedListener.dispose();
groupRemovedListener.dispose();
disposeListener.dispose();
@ -326,7 +321,6 @@ suite('EditorGroupsService', () => {
await part.whenRestored;
assert.ok(true);
part.dispose();
});
test('options', () => {
@ -346,8 +340,6 @@ suite('EditorGroupsService', () => {
assert.strictEqual(part.partOptions.showTabs, false);
assert.strictEqual(newOptions.showTabs, false);
assert.strictEqual(oldOptions, currentOptions);
part.dispose();
});
test('editor basics', async function () {
@ -457,7 +449,6 @@ suite('EditorGroupsService', () => {
editorWillCloseListener.dispose();
editorWillOpenListener.dispose();
editorGroupChangeListener.dispose();
part.dispose();
});
test('openEditors / closeEditors', async () => {
@ -483,7 +474,6 @@ suite('EditorGroupsService', () => {
assert.ok(inputInactive.gotDisposed);
assert.strictEqual(group.isEmpty, true);
part.dispose();
});
test('closeEditors (one, opened in multiple groups)', async () => {
@ -531,7 +521,6 @@ suite('EditorGroupsService', () => {
await group.closeEditors({ except: input2 });
assert.strictEqual(group.count, 1);
assert.strictEqual(group.getEditorByIndex(0), input2);
part.dispose();
});
test('closeEditors (except one, sticky editor)', async () => {
@ -567,7 +556,6 @@ suite('EditorGroupsService', () => {
assert.strictEqual(group.count, 1);
assert.strictEqual(group.stickyCount, 0);
assert.strictEqual(group.getEditorByIndex(0), input2);
part.dispose();
});
test('closeEditors (saved only)', async () => {
@ -592,7 +580,6 @@ suite('EditorGroupsService', () => {
await group.closeEditors({ savedOnly: true });
assert.strictEqual(group.count, 0);
part.dispose();
});
test('closeEditors (saved only, sticky editor)', async () => {
@ -624,7 +611,6 @@ suite('EditorGroupsService', () => {
await group.closeEditors({ savedOnly: true });
assert.strictEqual(group.count, 0);
part.dispose();
});
test('closeEditors (direction: right)', async () => {
@ -651,7 +637,6 @@ suite('EditorGroupsService', () => {
assert.strictEqual(group.count, 2);
assert.strictEqual(group.getEditorByIndex(0), input1);
assert.strictEqual(group.getEditorByIndex(1), input2);
part.dispose();
});
test('closeEditors (direction: right, sticky editor)', async () => {
@ -685,7 +670,6 @@ suite('EditorGroupsService', () => {
assert.strictEqual(group.count, 2);
assert.strictEqual(group.getEditorByIndex(0), input1);
assert.strictEqual(group.getEditorByIndex(1), input2);
part.dispose();
});
test('closeEditors (direction: left)', async () => {
@ -712,7 +696,6 @@ suite('EditorGroupsService', () => {
assert.strictEqual(group.count, 2);
assert.strictEqual(group.getEditorByIndex(0), input2);
assert.strictEqual(group.getEditorByIndex(1), input3);
part.dispose();
});
test('closeEditors (direction: left, sticky editor)', async () => {
@ -747,7 +730,6 @@ suite('EditorGroupsService', () => {
assert.strictEqual(group.count, 2);
assert.strictEqual(group.getEditorByIndex(0), input2);
assert.strictEqual(group.getEditorByIndex(1), input3);
part.dispose();
});
test('closeAllEditors', async () => {
@ -769,7 +751,6 @@ suite('EditorGroupsService', () => {
await group.closeAllEditors();
assert.strictEqual(group.isEmpty, true);
part.dispose();
});
test('closeAllEditors (sticky editor)', async () => {
@ -797,8 +778,6 @@ suite('EditorGroupsService', () => {
await group.closeAllEditors();
assert.strictEqual(group.isEmpty, true);
part.dispose();
});
test('moveEditor (same group)', async () => {
@ -825,8 +804,8 @@ suite('EditorGroupsService', () => {
assert.strictEqual(editorMoveCounter, 1);
assert.strictEqual(group.getEditorByIndex(0), inputInactive);
assert.strictEqual(group.getEditorByIndex(1), input);
editorGroupChangeListener.dispose();
part.dispose();
});
test('moveEditor (across groups)', async () => {
@ -848,7 +827,6 @@ suite('EditorGroupsService', () => {
assert.strictEqual(group.getEditorByIndex(0), input);
assert.strictEqual(rightGroup.count, 1);
assert.strictEqual(rightGroup.getEditorByIndex(0), inputInactive);
part.dispose();
});
test('copyEditor (across groups)', async () => {
@ -871,7 +849,6 @@ suite('EditorGroupsService', () => {
assert.strictEqual(group.getEditorByIndex(1), inputInactive);
assert.strictEqual(rightGroup.count, 1);
assert.strictEqual(rightGroup.getEditorByIndex(0), inputInactive);
part.dispose();
});
test('replaceEditors', async () => {
@ -889,7 +866,6 @@ suite('EditorGroupsService', () => {
await group.replaceEditors([{ editor: input, replacement: inputInactive }]);
assert.strictEqual(group.count, 1);
assert.strictEqual(group.getEditorByIndex(0), inputInactive);
part.dispose();
});
test('find neighbour group (left/right)', function () {
@ -899,8 +875,6 @@ suite('EditorGroupsService', () => {
assert.strictEqual(rightGroup, part.findGroup({ direction: GroupDirection.RIGHT }, rootGroup));
assert.strictEqual(rootGroup, part.findGroup({ direction: GroupDirection.LEFT }, rightGroup));
part.dispose();
});
test('find neighbour group (up/down)', function () {
@ -910,8 +884,6 @@ suite('EditorGroupsService', () => {
assert.strictEqual(downGroup, part.findGroup({ direction: GroupDirection.DOWN }, rootGroup));
assert.strictEqual(rootGroup, part.findGroup({ direction: GroupDirection.UP }, downGroup));
part.dispose();
});
test('find group by location (left/right)', function () {
@ -928,8 +900,6 @@ suite('EditorGroupsService', () => {
assert.strictEqual(downGroup, part.findGroup({ location: GroupLocation.NEXT }, rightGroup));
assert.strictEqual(rightGroup, part.findGroup({ location: GroupLocation.PREVIOUS }, downGroup));
part.dispose();
});
test('applyLayout (2x2)', function () {
@ -938,8 +908,6 @@ suite('EditorGroupsService', () => {
part.applyLayout({ groups: [{ groups: [{}, {}] }, { groups: [{}, {}] }], orientation: GroupOrientation.HORIZONTAL });
assert.strictEqual(part.groups.length, 4);
part.dispose();
});
test('centeredLayout', function () {
@ -948,8 +916,6 @@ suite('EditorGroupsService', () => {
part.centerLayout(true);
assert.strictEqual(part.isLayoutCentered(), true);
part.dispose();
});
test('sticky editors', async () => {
@ -1052,7 +1018,6 @@ suite('EditorGroupsService', () => {
assert.strictEqual(group.getIndexOfEditor(input), 2);
editorGroupChangeListener.dispose();
part.dispose();
});
test('moveEditor with context (across groups)', async () => {
@ -1078,7 +1043,6 @@ suite('EditorGroupsService', () => {
group.moveEditor(inputInactive, rightGroup, { index: 0 });
const context = await waitForEditorWillOpen;
assert.strictEqual(context, OpenEditorContext.MOVE_EDITOR);
part.dispose();
});
test('copyEditor with context (across groups)', async () => {
@ -1097,6 +1061,5 @@ suite('EditorGroupsService', () => {
group.copyEditor(inputInactive, rightGroup, { index: 0 });
const context = await waitForEditorWillOpen;
assert.strictEqual(context, OpenEditorContext.COPY_EDITOR);
part.dispose();
});
});

View file

@ -9,7 +9,7 @@ import { URI } from 'vs/base/common/uri';
import { Event } from 'vs/base/common/event';
import { EditorPane } from 'vs/workbench/browser/parts/editor/editorPane';
import { EditorInput, EditorsOrder, SideBySideEditorInput } from 'vs/workbench/common/editor';
import { workbenchInstantiationService, TestServiceAccessor, registerTestEditor, TestFileEditorInput, ITestInstantiationService } from 'vs/workbench/test/browser/workbenchTestServices';
import { workbenchInstantiationService, TestServiceAccessor, registerTestEditor, TestFileEditorInput, ITestInstantiationService, registerTestResourceEditor, registerTestSideBySideEditor } from 'vs/workbench/test/browser/workbenchTestServices';
import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput';
import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService';
import { EditorService, DelegatingEditorService } from 'vs/workbench/services/editor/browser/editorService';
@ -22,7 +22,7 @@ import { UntitledTextEditorInput } from 'vs/workbench/services/untitled/common/u
import { timeout } from 'vs/base/common/async';
import { toResource } from 'vs/base/test/common/utils';
import { IFileService, FileOperationEvent, FileOperation } from 'vs/platform/files/common/files';
import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle';
import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
import { ModesRegistry } from 'vs/editor/common/modes/modesRegistry';
import { UntitledTextEditorModel } from 'vs/workbench/services/untitled/common/untitledTextEditorModel';
import { NullFileSystemProvider } from 'vs/platform/files/test/common/nullFileSystemProvider';
@ -31,32 +31,33 @@ import { TestStorageService } from 'vs/workbench/test/common/workbenchTestServic
import { isLinux } from 'vs/base/common/platform';
import { MockScopableContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService';
const TEST_EDITOR_ID = 'MyTestEditorForEditorService';
const TEST_EDITOR_INPUT_ID = 'testEditorInputForEditorService';
class FileServiceProvider extends Disposable {
constructor(scheme: string, @IFileService fileService: IFileService) {
super();
this._register(fileService.registerProvider(scheme, new NullFileSystemProvider()));
}
}
suite('EditorService', () => {
let disposables: IDisposable[] = [];
const TEST_EDITOR_ID = 'MyTestEditorForEditorService';
const TEST_EDITOR_INPUT_ID = 'testEditorInputForEditorService';
class FileServiceProvider extends Disposable {
constructor(scheme: string, @IFileService fileService: IFileService) {
super();
this._register(fileService.registerProvider(scheme, new NullFileSystemProvider()));
}
}
const disposables = new DisposableStore();
setup(() => {
disposables.push(registerTestEditor(TEST_EDITOR_ID, [new SyncDescriptor(TestFileEditorInput)], TEST_EDITOR_INPUT_ID));
disposables.add(registerTestEditor(TEST_EDITOR_ID, [new SyncDescriptor(TestFileEditorInput)], TEST_EDITOR_INPUT_ID));
disposables.add(registerTestResourceEditor());
disposables.add(registerTestSideBySideEditor());
});
teardown(() => {
dispose(disposables);
disposables = [];
disposables.clear();
});
function createEditorService(instantiationService: ITestInstantiationService = workbenchInstantiationService()): [EditorPart, EditorService, TestServiceAccessor] {
const part = instantiationService.createInstance(EditorPart);
const part = disposables.add(instantiationService.createInstance(EditorPart));
part.create(document.createElement('div'));
part.layout(400, 300);
@ -170,8 +171,6 @@ suite('EditorService', () => {
activeEditorChangeListener.dispose();
visibleEditorChangeListener.dispose();
didCloseEditorListener.dispose();
part.dispose();
});
test('isOpen() with side by side editor', async () => {
@ -217,8 +216,6 @@ suite('EditorService', () => {
assert.strictEqual(service.isOpen(sideBySideInput), false);
assert.strictEqual(service.isOpen({ resource: input.resource }), false);
assert.strictEqual(service.isOpen({ resource: otherInput.resource }), false);
part.dispose();
});
test('openEditors() / replaceEditors()', async () => {
@ -238,8 +235,6 @@ suite('EditorService', () => {
await service.replaceEditors([{ editor: input, replacement: replaceInput }], part.activeGroup);
assert.strictEqual(part.activeGroup.count, 2);
assert.strictEqual(part.activeGroup.getIndexOfEditor(replaceInput), 0);
part.dispose();
});
test('caching', function () {
@ -444,8 +439,6 @@ suite('EditorService', () => {
await rightGroup.closeEditor(input);
assert.strictEqual(input.isDisposed(), true);
part.dispose();
});
test('open to the side', async () => {
@ -470,8 +463,6 @@ suite('EditorService', () => {
assert.strictEqual(part.activeGroup, rootGroup);
assert.strictEqual(part.count, 2);
assert.strictEqual(editor?.group, part.groups[1]);
part.dispose();
});
test('editor group activation', async () => {
@ -505,8 +496,6 @@ suite('EditorService', () => {
part.arrangeGroups(GroupsArrangement.MINIMIZE_OTHERS);
editor = await service.openEditor(input1, { pinned: true, preserveFocus: true, activation: EditorActivation.RESTORE }, rootGroup);
assert.strictEqual(part.activeGroup, sideGroup);
part.dispose();
});
test('active editor change / visible editor change events', async function () {
@ -725,8 +714,6 @@ suite('EditorService', () => {
// cleanup
activeEditorChangeListener.dispose();
visibleEditorChangeListener.dispose();
part.dispose();
});
test('two active editor change events when opening editor to the side', async function () {
@ -762,8 +749,6 @@ suite('EditorService', () => {
// cleanup
activeEditorChangeListener.dispose();
part.dispose();
});
test('activeTextEditorControl / activeTextEditorMode', async () => {
@ -777,8 +762,6 @@ suite('EditorService', () => {
assert.strictEqual(service.activeEditorPane, editor);
assert.strictEqual(service.activeTextEditorControl, editor?.getControl());
assert.strictEqual(service.activeTextEditorMode, 'plaintext');
part.dispose();
});
test('openEditor returns NULL when opening fails or is inactive', async function () {
@ -799,8 +782,6 @@ suite('EditorService', () => {
let failingEditor = await service.openEditor(failingInput);
assert.ok(!failingEditor);
part.dispose();
});
test('save, saveAll, revertAll', async function () {
@ -880,8 +861,6 @@ suite('EditorService', () => {
assert.strictEqual(sameInput1.gotSaved, false);
assert.strictEqual(sameInput1.gotSavedAs, false);
assert.strictEqual(sameInput1.gotReverted, false);
part.dispose();
});
test('saveAll, revertAll (sticky editor)', async function () {
@ -922,8 +901,6 @@ suite('EditorService', () => {
assert.strictEqual(input1.gotSaved, false);
assert.strictEqual(input2.gotSaved, true);
assert.strictEqual(sameInput1.gotSaved, true);
part.dispose();
});
test('file delete closes editor', async function () {
@ -962,8 +939,6 @@ suite('EditorService', () => {
} else {
assert.strictEqual(rootGroup.activeEditor, input1);
}
part.dispose();
}
test('file move asks input to move', async function () {
@ -994,8 +969,6 @@ suite('EditorService', () => {
await activeEditorChangePromise;
assert.strictEqual(rootGroup.activeEditor, movedInput);
part.dispose();
});
function awaitActiveEditorChange(editorService: IEditorService): Promise<void> {
@ -1020,8 +993,6 @@ suite('EditorService', () => {
await editor?.group?.closeAllEditors();
assert.strictEqual(accessor.fileService.watches.length, 0);
part.dispose();
});
test('activeEditorPane scopedContextKeyService', async function () {
@ -1038,8 +1009,6 @@ suite('EditorService', () => {
const editorContextKeyService = service.activeEditorPane?.scopedContextKeyService;
assert.ok(!!editorContextKeyService);
assert.strictEqual(editorContextKeyService, part.activeGroup.activeEditorPane?.scopedContextKeyService);
part.dispose();
});
test('overrideOpenEditor', async function () {
@ -1070,7 +1039,6 @@ suite('EditorService', () => {
assert.strictEqual(service.activeEditor, input2);
handler.dispose();
part.dispose();
});
test('whenClosed', async function () {
@ -1089,8 +1057,6 @@ suite('EditorService', () => {
editor?.group?.closeAllEditors();
await whenClosed;
part.dispose();
});
test('findEditors', async () => {
@ -1137,7 +1103,5 @@ suite('EditorService', () => {
const found = service.findEditors(input.resource, part.activeGroup);
assert.strictEqual(found.length, 0);
}
part.dispose();
});
});

View file

@ -13,33 +13,33 @@ import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { GroupDirection } from 'vs/workbench/services/editor/common/editorGroupsService';
import { EditorActivation } from 'vs/platform/editor/common/editor';
import { WillSaveStateReason } from 'vs/platform/storage/common/storage';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { DisposableStore, toDisposable } from 'vs/base/common/lifecycle';
import { EditorsObserver } from 'vs/workbench/browser/parts/editor/editorsObserver';
import { timeout } from 'vs/base/common/async';
import { TestStorageService } from 'vs/workbench/test/common/workbenchTestServices';
const TEST_EDITOR_ID = 'MyTestEditorForEditorsObserver';
const TEST_EDITOR_INPUT_ID = 'testEditorInputForEditorsObserver';
const TEST_SERIALIZABLE_EDITOR_INPUT_ID = 'testSerializableEditorInputForEditorsObserver';
suite('EditorsObserver', function () {
let disposables: IDisposable[] = [];
const TEST_EDITOR_ID = 'MyTestEditorForEditorsObserver';
const TEST_EDITOR_INPUT_ID = 'testEditorInputForEditorsObserver';
const TEST_SERIALIZABLE_EDITOR_INPUT_ID = 'testSerializableEditorInputForEditorsObserver';
const disposables = new DisposableStore();
setup(() => {
disposables.push(registerTestEditor(TEST_EDITOR_ID, [new SyncDescriptor(TestFileEditorInput)], TEST_SERIALIZABLE_EDITOR_INPUT_ID));
disposables.add(registerTestEditor(TEST_EDITOR_ID, [new SyncDescriptor(TestFileEditorInput)], TEST_SERIALIZABLE_EDITOR_INPUT_ID));
});
teardown(() => {
dispose(disposables);
disposables = [];
disposables.clear();
});
async function createPart(): Promise<TestEditorPart> {
const instantiationService = workbenchInstantiationService();
instantiationService.invokeFunction(accessor => Registry.as<IEditorInputFactoryRegistry>(EditorExtensions.EditorInputFactories).start(accessor));
const part = instantiationService.createInstance(TestEditorPart);
const part = disposables.add(instantiationService.createInstance(TestEditorPart));
disposables.add(toDisposable(() => part.clearState()));
part.create(document.createElement('div'));
part.layout(400, 300);
@ -51,7 +51,7 @@ suite('EditorsObserver', function () {
async function createEditorObserver(): Promise<[EditorPart, EditorsObserver]> {
const part = await createPart();
const observer = new EditorsObserver(part, new TestStorageService());
const observer = disposables.add(new EditorsObserver(part, new TestStorageService()));
return [part, observer];
}
@ -131,7 +131,6 @@ suite('EditorsObserver', function () {
assert.strictEqual(observer.hasEditor(input2.resource), false);
assert.strictEqual(observer.hasEditor(input3.resource), false);
part.dispose();
listener.dispose();
});
@ -200,8 +199,6 @@ suite('EditorsObserver', function () {
assert.strictEqual(currentEditorsMRU.length, 0);
assert.strictEqual(observer.hasEditor(input1.resource), false);
assert.strictEqual(observer.hasEditor(input2.resource), false);
part.dispose();
});
test('copy group', async function () {
@ -263,8 +260,6 @@ suite('EditorsObserver', function () {
assert.strictEqual(observer.hasEditor(input1.resource), false);
assert.strictEqual(observer.hasEditor(input2.resource), false);
assert.strictEqual(observer.hasEditor(input3.resource), false);
part.dispose();
});
test('initial editors are part of observer and state is persisted & restored (single group)', async () => {
@ -281,7 +276,7 @@ suite('EditorsObserver', function () {
await rootGroup.openEditor(input3, EditorOptions.create({ pinned: true }));
const storage = new TestStorageService();
const observer = new EditorsObserver(part, storage);
const observer = disposables.add(new EditorsObserver(part, storage));
await part.whenRestored;
let currentEditorsMRU = observer.editors;
@ -298,7 +293,7 @@ suite('EditorsObserver', function () {
storage.emitWillSaveState(WillSaveStateReason.SHUTDOWN);
const restoredObserver = new EditorsObserver(part, storage);
const restoredObserver = disposables.add(new EditorsObserver(part, storage));
await part.whenRestored;
currentEditorsMRU = restoredObserver.editors;
@ -312,9 +307,6 @@ suite('EditorsObserver', function () {
assert.strictEqual(observer.hasEditor(input1.resource), true);
assert.strictEqual(observer.hasEditor(input2.resource), true);
assert.strictEqual(observer.hasEditor(input3.resource), true);
part.clearState();
part.dispose();
});
test('initial editors are part of observer (multi group)', async () => {
@ -333,7 +325,7 @@ suite('EditorsObserver', function () {
await sideGroup.openEditor(input3, EditorOptions.create({ pinned: true }));
const storage = new TestStorageService();
const observer = new EditorsObserver(part, storage);
const observer = disposables.add(new EditorsObserver(part, storage));
await part.whenRestored;
let currentEditorsMRU = observer.editors;
@ -350,7 +342,7 @@ suite('EditorsObserver', function () {
storage.emitWillSaveState(WillSaveStateReason.SHUTDOWN);
const restoredObserver = new EditorsObserver(part, storage);
const restoredObserver = disposables.add(new EditorsObserver(part, storage));
await part.whenRestored;
currentEditorsMRU = restoredObserver.editors;
@ -364,9 +356,6 @@ suite('EditorsObserver', function () {
assert.strictEqual(restoredObserver.hasEditor(input1.resource), true);
assert.strictEqual(restoredObserver.hasEditor(input2.resource), true);
assert.strictEqual(restoredObserver.hasEditor(input3.resource), true);
part.clearState();
part.dispose();
});
test('observer does not restore editors that cannot be serialized', async () => {
@ -379,7 +368,7 @@ suite('EditorsObserver', function () {
await rootGroup.openEditor(input1, EditorOptions.create({ pinned: true }));
const storage = new TestStorageService();
const observer = new EditorsObserver(part, storage);
const observer = disposables.add(new EditorsObserver(part, storage));
await part.whenRestored;
let currentEditorsMRU = observer.editors;
@ -390,15 +379,12 @@ suite('EditorsObserver', function () {
storage.emitWillSaveState(WillSaveStateReason.SHUTDOWN);
const restoredObserver = new EditorsObserver(part, storage);
const restoredObserver = disposables.add(new EditorsObserver(part, storage));
await part.whenRestored;
currentEditorsMRU = restoredObserver.editors;
assert.strictEqual(currentEditorsMRU.length, 0);
assert.strictEqual(restoredObserver.hasEditor(input1.resource), false);
part.clearState();
part.dispose();
});
test('observer closes editors when limit reached (across all groups)', async () => {
@ -406,7 +392,7 @@ suite('EditorsObserver', function () {
part.enforcePartOptions({ limit: { enabled: true, value: 3 } });
const storage = new TestStorageService();
const observer = new EditorsObserver(part, storage);
const observer = disposables.add(new EditorsObserver(part, storage));
const rootGroup = part.activeGroup;
const sideGroup = part.addGroup(rootGroup, GroupDirection.RIGHT);
@ -460,9 +446,6 @@ suite('EditorsObserver', function () {
assert.strictEqual(observer.hasEditor(input3.resource), false);
assert.strictEqual(observer.hasEditor(input4.resource), false);
assert.strictEqual(observer.hasEditor(input5.resource), true);
observer.dispose();
part.dispose();
});
test('observer closes editors when limit reached (in group)', async () => {
@ -470,7 +453,7 @@ suite('EditorsObserver', function () {
part.enforcePartOptions({ limit: { enabled: true, value: 3, perEditorGroup: true } });
const storage = new TestStorageService();
const observer = new EditorsObserver(part, storage);
const observer = disposables.add(new EditorsObserver(part, storage));
const rootGroup = part.activeGroup;
const sideGroup = part.addGroup(rootGroup, GroupDirection.RIGHT);
@ -530,9 +513,6 @@ suite('EditorsObserver', function () {
assert.strictEqual(observer.hasEditor(input2.resource), false);
assert.strictEqual(observer.hasEditor(input3.resource), false);
assert.strictEqual(observer.hasEditor(input4.resource), true);
observer.dispose();
part.dispose();
});
test('observer does not close sticky', async () => {
@ -540,7 +520,7 @@ suite('EditorsObserver', function () {
part.enforcePartOptions({ limit: { enabled: true, value: 3 } });
const storage = new TestStorageService();
const observer = new EditorsObserver(part, storage);
const observer = disposables.add(new EditorsObserver(part, storage));
const rootGroup = part.activeGroup;
@ -563,8 +543,5 @@ suite('EditorsObserver', function () {
assert.strictEqual(observer.hasEditor(input2.resource), false);
assert.strictEqual(observer.hasEditor(input3.resource), true);
assert.strictEqual(observer.hasEditor(input4.resource), true);
observer.dispose();
part.dispose();
});
});

View file

@ -13,44 +13,43 @@ import { IEditorGroupsService, GroupDirection } from 'vs/workbench/services/edit
import { HistoryService } from 'vs/workbench/services/history/browser/history';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { EditorService } from 'vs/workbench/services/editor/browser/editorService';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { DisposableStore } from 'vs/base/common/lifecycle';
import { IHistoryService } from 'vs/workbench/services/history/common/history';
import { timeout } from 'vs/base/common/async';
const TEST_EDITOR_ID = 'MyTestEditorForEditorHistory';
const TEST_EDITOR_INPUT_ID = 'testEditorInputForHistoyService';
async function createServices(): Promise<[EditorPart, HistoryService, EditorService]> {
const instantiationService = workbenchInstantiationService();
const part = instantiationService.createInstance(EditorPart);
part.create(document.createElement('div'));
part.layout(400, 300);
await part.whenRestored;
instantiationService.stub(IEditorGroupsService, part);
const editorService = instantiationService.createInstance(EditorService);
instantiationService.stub(IEditorService, editorService);
const historyService = instantiationService.createInstance(HistoryService);
instantiationService.stub(IHistoryService, historyService);
return [part, historyService, editorService];
}
suite('HistoryService', function () {
let disposables: IDisposable[] = [];
const TEST_EDITOR_ID = 'MyTestEditorForEditorHistory';
const TEST_EDITOR_INPUT_ID = 'testEditorInputForHistoyService';
async function createServices(): Promise<[EditorPart, HistoryService, EditorService]> {
const instantiationService = workbenchInstantiationService();
const part = disposables.add(instantiationService.createInstance(EditorPart));
part.create(document.createElement('div'));
part.layout(400, 300);
await part.whenRestored;
instantiationService.stub(IEditorGroupsService, part);
const editorService = instantiationService.createInstance(EditorService);
instantiationService.stub(IEditorService, editorService);
const historyService = instantiationService.createInstance(HistoryService);
instantiationService.stub(IHistoryService, historyService);
return [part, historyService, editorService];
}
const disposables = new DisposableStore();
setup(() => {
disposables.push(registerTestEditor(TEST_EDITOR_ID, [new SyncDescriptor(TestFileEditorInput)]));
disposables.add(registerTestEditor(TEST_EDITOR_ID, [new SyncDescriptor(TestFileEditorInput)]));
});
teardown(() => {
dispose(disposables);
disposables = [];
disposables.clear();
});
test('back / forward', async () => {
@ -58,26 +57,24 @@ suite('HistoryService', function () {
const input1 = new TestFileEditorInput(URI.parse('foo://bar1'), TEST_EDITOR_INPUT_ID);
await part.activeGroup.openEditor(input1, EditorOptions.create({ pinned: true }));
assert.equal(part.activeGroup.activeEditor, input1);
assert.strictEqual(part.activeGroup.activeEditor, input1);
const input2 = new TestFileEditorInput(URI.parse('foo://bar2'), TEST_EDITOR_INPUT_ID);
await part.activeGroup.openEditor(input2, EditorOptions.create({ pinned: true }));
assert.equal(part.activeGroup.activeEditor, input2);
assert.strictEqual(part.activeGroup.activeEditor, input2);
historyService.back();
assert.equal(part.activeGroup.activeEditor, input1);
assert.strictEqual(part.activeGroup.activeEditor, input1);
historyService.forward();
assert.equal(part.activeGroup.activeEditor, input2);
part.dispose();
assert.strictEqual(part.activeGroup.activeEditor, input2);
});
test('getHistory', async () => {
const [part, historyService] = await createServices();
let history = historyService.getHistory();
assert.equal(history.length, 0);
assert.strictEqual(history.length, 0);
const input1 = new TestFileEditorInput(URI.parse('foo://bar1'), TEST_EDITOR_INPUT_ID);
await part.activeGroup.openEditor(input1, EditorOptions.create({ pinned: true }));
@ -86,14 +83,12 @@ suite('HistoryService', function () {
await part.activeGroup.openEditor(input2, EditorOptions.create({ pinned: true }));
history = historyService.getHistory();
assert.equal(history.length, 2);
assert.strictEqual(history.length, 2);
historyService.remove(input2);
history = historyService.getHistory();
assert.equal(history.length, 1);
assert.equal(history[0], input1);
part.dispose();
assert.strictEqual(history.length, 1);
assert.strictEqual(history[0], input1);
});
test('getLastActiveFile', async () => {
@ -104,9 +99,7 @@ suite('HistoryService', function () {
const input1 = new TestFileEditorInput(URI.parse('foo://bar1'), TEST_EDITOR_INPUT_ID);
await part.activeGroup.openEditor(input1, EditorOptions.create({ pinned: true }));
assert.equal(historyService.getLastActiveFile('foo')?.toString(), input1.resource.toString());
part.dispose();
assert.strictEqual(historyService.getLastActiveFile('foo')?.toString(), input1.resource.toString());
});
test('open next/previous recently used editor (single group)', async () => {
@ -116,24 +109,22 @@ suite('HistoryService', function () {
const input2 = new TestFileEditorInput(URI.parse('foo://bar2'), TEST_EDITOR_INPUT_ID);
await part.activeGroup.openEditor(input1, EditorOptions.create({ pinned: true }));
assert.equal(part.activeGroup.activeEditor, input1);
assert.strictEqual(part.activeGroup.activeEditor, input1);
await part.activeGroup.openEditor(input2, EditorOptions.create({ pinned: true }));
assert.equal(part.activeGroup.activeEditor, input2);
assert.strictEqual(part.activeGroup.activeEditor, input2);
historyService.openPreviouslyUsedEditor();
assert.equal(part.activeGroup.activeEditor, input1);
assert.strictEqual(part.activeGroup.activeEditor, input1);
historyService.openNextRecentlyUsedEditor();
assert.equal(part.activeGroup.activeEditor, input2);
assert.strictEqual(part.activeGroup.activeEditor, input2);
historyService.openPreviouslyUsedEditor(part.activeGroup.id);
assert.equal(part.activeGroup.activeEditor, input1);
assert.strictEqual(part.activeGroup.activeEditor, input1);
historyService.openNextRecentlyUsedEditor(part.activeGroup.id);
assert.equal(part.activeGroup.activeEditor, input2);
part.dispose();
assert.strictEqual(part.activeGroup.activeEditor, input2);
});
test('open next/previous recently used editor (multi group)', async () => {
@ -149,14 +140,12 @@ suite('HistoryService', function () {
await sideGroup.openEditor(input2, EditorOptions.create({ pinned: true }));
historyService.openPreviouslyUsedEditor();
assert.equal(part.activeGroup, rootGroup);
assert.equal(rootGroup.activeEditor, input1);
assert.strictEqual(part.activeGroup, rootGroup);
assert.strictEqual(rootGroup.activeEditor, input1);
historyService.openNextRecentlyUsedEditor();
assert.equal(part.activeGroup, sideGroup);
assert.equal(sideGroup.activeEditor, input2);
part.dispose();
assert.strictEqual(part.activeGroup, sideGroup);
assert.strictEqual(sideGroup.activeEditor, input2);
});
test('open next/previous recently is reset when other input opens', async () => {
@ -172,19 +161,15 @@ suite('HistoryService', function () {
await part.activeGroup.openEditor(input3, EditorOptions.create({ pinned: true }));
historyService.openPreviouslyUsedEditor();
assert.equal(part.activeGroup.activeEditor, input2);
assert.strictEqual(part.activeGroup.activeEditor, input2);
await timeout(0);
await part.activeGroup.openEditor(input4, EditorOptions.create({ pinned: true }));
historyService.openPreviouslyUsedEditor();
assert.equal(part.activeGroup.activeEditor, input2);
assert.strictEqual(part.activeGroup.activeEditor, input2);
historyService.openNextRecentlyUsedEditor();
assert.equal(part.activeGroup.activeEditor, input4);
part.dispose();
assert.strictEqual(part.activeGroup.activeEditor, input4);
});
});

View file

@ -17,14 +17,14 @@ import { ModesRegistry } from 'vs/editor/common/modes/modesRegistry';
import { assertIsDefined } from 'vs/base/common/types';
import { createTextBufferFactory } from 'vs/editor/common/model/textModel';
function getLastModifiedTime(model: TextFileEditorModel): number {
const stat = model.getStat();
return stat ? stat.mtime : -1;
}
suite('Files - TextFileEditorModel', () => {
function getLastModifiedTime(model: TextFileEditorModel): number {
const stat = model.getStat();
return stat ? stat.mtime : -1;
}
let instantiationService: IInstantiationService;
let accessor: TestServiceAccessor;
let content: string;

View file

@ -164,5 +164,4 @@ suite('Files - TextFileService', () => {
let suggested = accessor.textFileService.suggestFilename('plumbus2', 'Untitled-1');
assert.strictEqual(suggested, 'plumbus');
});
});

View file

@ -31,23 +31,21 @@ suite('Workbench - TextModelResolverService', () => {
});
teardown(() => {
if (model) {
model.dispose();
model = (undefined)!;
}
model?.dispose();
(<TextFileEditorModelManager>accessor.textFileService.files).dispose();
});
test('resolve resource', async () => {
const dispose = accessor.textModelResolverService.registerTextModelContentProvider('test', {
provideTextContent: function (resource: URI): Promise<ITextModel> {
const disposable = accessor.textModelResolverService.registerTextModelContentProvider('test', {
provideTextContent: async function (resource: URI): Promise<ITextModel | null> {
if (resource.scheme === 'test') {
let modelContent = 'Hello Test';
let languageSelection = accessor.modeService.create('json');
return Promise.resolve(accessor.modelService.createModel(modelContent, languageSelection, resource));
return accessor.modelService.createModel(modelContent, languageSelection, resource);
}
return Promise.resolve(null!);
return null;
}
});
@ -68,7 +66,7 @@ suite('Workbench - TextModelResolverService', () => {
await disposedPromise;
assert.strictEqual(disposed, true);
dispose.dispose();
disposable.dispose();
});
test('resolve file', async function () {

View file

@ -3,8 +3,8 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { URI } from 'vs/base/common/uri';
import * as assert from 'assert';
import { URI } from 'vs/base/common/uri';
import { join } from 'vs/base/common/path';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IUntitledTextEditorService, UntitledTextEditorService } from 'vs/workbench/services/untitled/common/untitledTextEditorService';

View file

@ -5,100 +5,101 @@
import * as assert from 'assert';
import { Part } from 'vs/workbench/browser/part';
import * as Types from 'vs/base/common/types';
import { isEmptyObject } from 'vs/base/common/types';
import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService';
import { append, $, hide } from 'vs/base/browser/dom';
import { TestLayoutService } from 'vs/workbench/test/browser/workbenchTestServices';
import { StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
import { TestStorageService } from 'vs/workbench/test/common/workbenchTestServices';
class SimplePart extends Part {
minimumWidth: number = 50;
maximumWidth: number = 50;
minimumHeight: number = 50;
maximumHeight: number = 50;
layout(width: number, height: number): void {
throw new Error('Method not implemented.');
}
toJSON(): object {
throw new Error('Method not implemented.');
}
}
class MyPart extends SimplePart {
constructor(private expectedParent: HTMLElement) {
super('myPart', { hasTitle: true }, new TestThemeService(), new TestStorageService(), new TestLayoutService());
}
createTitleArea(parent: HTMLElement): HTMLElement {
assert.strictEqual(parent, this.expectedParent);
return super.createTitleArea(parent)!;
}
createContentArea(parent: HTMLElement): HTMLElement {
assert.strictEqual(parent, this.expectedParent);
return super.createContentArea(parent)!;
}
getMemento(scope: StorageScope, target: StorageTarget) {
return super.getMemento(scope, target);
}
saveState(): void {
return super.saveState();
}
}
class MyPart2 extends SimplePart {
constructor() {
super('myPart2', { hasTitle: true }, new TestThemeService(), new TestStorageService(), new TestLayoutService());
}
createTitleArea(parent: HTMLElement): HTMLElement {
const titleContainer = append(parent, $('div'));
const titleLabel = append(titleContainer, $('span'));
titleLabel.id = 'myPart.title';
titleLabel.innerText = 'Title';
return titleContainer;
}
createContentArea(parent: HTMLElement): HTMLElement {
const contentContainer = append(parent, $('div'));
const contentSpan = append(contentContainer, $('span'));
contentSpan.id = 'myPart.content';
contentSpan.innerText = 'Content';
return contentContainer;
}
}
class MyPart3 extends SimplePart {
constructor() {
super('myPart2', { hasTitle: false }, new TestThemeService(), new TestStorageService(), new TestLayoutService());
}
createTitleArea(parent: HTMLElement): HTMLElement {
return null!;
}
createContentArea(parent: HTMLElement): HTMLElement {
const contentContainer = append(parent, $('div'));
const contentSpan = append(contentContainer, $('span'));
contentSpan.id = 'myPart.content';
contentSpan.innerText = 'Content';
return contentContainer;
}
}
suite('Workbench parts', () => {
class SimplePart extends Part {
minimumWidth: number = 50;
maximumWidth: number = 50;
minimumHeight: number = 50;
maximumHeight: number = 50;
layout(width: number, height: number): void {
throw new Error('Method not implemented.');
}
toJSON(): object {
throw new Error('Method not implemented.');
}
}
class MyPart extends SimplePart {
constructor(private expectedParent: HTMLElement) {
super('myPart', { hasTitle: true }, new TestThemeService(), new TestStorageService(), new TestLayoutService());
}
createTitleArea(parent: HTMLElement): HTMLElement {
assert.strictEqual(parent, this.expectedParent);
return super.createTitleArea(parent)!;
}
createContentArea(parent: HTMLElement): HTMLElement {
assert.strictEqual(parent, this.expectedParent);
return super.createContentArea(parent)!;
}
getMemento(scope: StorageScope, target: StorageTarget) {
return super.getMemento(scope, target);
}
saveState(): void {
return super.saveState();
}
}
class MyPart2 extends SimplePart {
constructor() {
super('myPart2', { hasTitle: true }, new TestThemeService(), new TestStorageService(), new TestLayoutService());
}
createTitleArea(parent: HTMLElement): HTMLElement {
const titleContainer = append(parent, $('div'));
const titleLabel = append(titleContainer, $('span'));
titleLabel.id = 'myPart.title';
titleLabel.innerText = 'Title';
return titleContainer;
}
createContentArea(parent: HTMLElement): HTMLElement {
const contentContainer = append(parent, $('div'));
const contentSpan = append(contentContainer, $('span'));
contentSpan.id = 'myPart.content';
contentSpan.innerText = 'Content';
return contentContainer;
}
}
class MyPart3 extends SimplePart {
constructor() {
super('myPart2', { hasTitle: false }, new TestThemeService(), new TestStorageService(), new TestLayoutService());
}
createTitleArea(parent: HTMLElement): HTMLElement {
return null!;
}
createContentArea(parent: HTMLElement): HTMLElement {
const contentContainer = append(parent, $('div'));
const contentSpan = append(contentContainer, $('span'));
contentSpan.id = 'myPart.content';
contentSpan.innerText = 'Content';
return contentContainer;
}
}
let fixture: HTMLElement;
let fixtureId = 'workbench-part-fixture';
@ -146,7 +147,7 @@ suite('Workbench parts', () => {
part = new MyPart(b);
memento = part.getMemento(StorageScope.GLOBAL, StorageTarget.MACHINE);
assert(memento);
assert.strictEqual(Types.isEmptyObject(memento), true);
assert.strictEqual(isEmptyObject(memento), true);
});
test('Part Layout with Title and Content', function () {

View file

@ -12,15 +12,15 @@ import { workbenchInstantiationService, TestServiceAccessor, TestEditorInput } f
import { Schemas } from 'vs/base/common/network';
import { UntitledTextEditorInput } from 'vs/workbench/services/untitled/common/untitledTextEditorInput';
export class TestEditorInputWithPreferredResource extends TestEditorInput implements IEditorInputWithPreferredResource {
constructor(resource: URI, public preferredResource: URI, typeId: string) {
super(resource, typeId);
}
}
suite('Workbench editor', () => {
class TestEditorInputWithPreferredResource extends TestEditorInput implements IEditorInputWithPreferredResource {
constructor(resource: URI, public preferredResource: URI, typeId: string) {
super(resource, typeId);
}
}
let instantiationService: IInstantiationService;
let accessor: TestServiceAccessor;

View file

@ -24,14 +24,15 @@ suite('Workbench editor model', () => {
test('TextDiffEditorModel', async () => {
const dispose = accessor.textModelResolverService.registerTextModelContentProvider('test', {
provideTextContent: function (resource: URI): Promise<ITextModel> {
provideTextContent: async function (resource: URI): Promise<ITextModel | null> {
if (resource.scheme === 'test') {
let modelContent = 'Hello Test';
let languageSelection = accessor.modeService.create('json');
return Promise.resolve(accessor.modelService.createModel(modelContent, languageSelection, resource));
return accessor.modelService.createModel(modelContent, languageSelection, resource);
}
return Promise.resolve(null!);
return null;
}
});

View file

@ -20,218 +20,217 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils';
import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { DisposableStore } from 'vs/base/common/lifecycle';
import { TestContextService, TestStorageService } from 'vs/workbench/test/common/workbenchTestServices';
function inst(): IInstantiationService {
let inst = new TestInstantiationService();
inst.stub(IStorageService, new TestStorageService());
inst.stub(ILifecycleService, new TestLifecycleService());
inst.stub(IWorkspaceContextService, new TestContextService());
inst.stub(ITelemetryService, NullTelemetryService);
const config = new TestConfigurationService();
config.setUserConfiguration('workbench', { editor: { openPositioning: 'right', focusRecentEditorAfterClose: true } });
inst.stub(IConfigurationService, config);
return inst;
}
function createGroup(serialized?: ISerializedEditorGroup): EditorGroup {
return inst().createInstance(EditorGroup, serialized);
}
function closeAllEditors(group: EditorGroup): void {
for (const editor of group.getEditors(EditorsOrder.SEQUENTIAL)) {
group.closeEditor(editor, false);
}
}
function closeEditors(group: EditorGroup, except: EditorInput, direction?: CloseDirection): void {
const index = group.indexOf(except);
if (index === -1) {
return; // not found
}
// Close to the left
if (direction === CloseDirection.LEFT) {
for (let i = index - 1; i >= 0; i--) {
group.closeEditor(group.getEditorByIndex(i)!);
}
}
// Close to the right
else if (direction === CloseDirection.RIGHT) {
for (let i = group.getEditors(EditorsOrder.SEQUENTIAL).length - 1; i > index; i--) {
group.closeEditor(group.getEditorByIndex(i)!);
}
}
// Both directions
else {
group.getEditors(EditorsOrder.MOST_RECENTLY_ACTIVE).filter(editor => !editor.matches(except)).forEach(editor => group.closeEditor(editor));
}
}
interface GroupEvents {
opened: EditorInput[];
activated: EditorInput[];
closed: EditorCloseEvent[];
pinned: EditorInput[];
unpinned: EditorInput[];
sticky: EditorInput[];
unsticky: EditorInput[];
moved: EditorInput[];
disposed: EditorInput[];
}
function groupListener(group: EditorGroup): GroupEvents {
const groupEvents: GroupEvents = {
opened: [],
closed: [],
activated: [],
pinned: [],
unpinned: [],
sticky: [],
unsticky: [],
moved: [],
disposed: []
};
group.onDidOpenEditor(e => groupEvents.opened.push(e));
group.onDidCloseEditor(e => groupEvents.closed.push(e));
group.onDidActivateEditor(e => groupEvents.activated.push(e));
group.onDidChangeEditorPinned(e => group.isPinned(e) ? groupEvents.pinned.push(e) : groupEvents.unpinned.push(e));
group.onDidChangeEditorSticky(e => group.isSticky(e) ? groupEvents.sticky.push(e) : groupEvents.unsticky.push(e));
group.onDidMoveEditor(e => groupEvents.moved.push(e));
group.onDidDisposeEditor(e => groupEvents.disposed.push(e));
return groupEvents;
}
let index = 0;
class TestEditorInput extends EditorInput {
readonly resource = undefined;
constructor(public id: string) {
super();
}
getTypeId() { return 'testEditorInputForGroups'; }
resolve(): Promise<IEditorModel> { return Promise.resolve(null!); }
matches(other: TestEditorInput): boolean {
return other && this.id === other.id && other instanceof TestEditorInput;
}
setDirty(): void {
this._onDidChangeDirty.fire();
}
setLabel(): void {
this._onDidChangeLabel.fire();
}
}
class NonSerializableTestEditorInput extends EditorInput {
readonly resource = undefined;
constructor(public id: string) {
super();
}
getTypeId() { return 'testEditorInputForGroups-nonSerializable'; }
resolve(): Promise<IEditorModel> { return Promise.resolve(null!); }
matches(other: NonSerializableTestEditorInput): boolean {
return other && this.id === other.id && other instanceof NonSerializableTestEditorInput;
}
}
class TestFileEditorInput extends EditorInput implements IFileEditorInput {
readonly preferredResource = this.resource;
constructor(public id: string, public resource: URI) {
super();
}
getTypeId() { return 'testFileEditorInputForGroups'; }
resolve(): Promise<IEditorModel> { return Promise.resolve(null!); }
setPreferredName(name: string): void { }
setPreferredDescription(description: string): void { }
setPreferredResource(resource: URI): void { }
setEncoding(encoding: string) { }
getEncoding() { return undefined; }
setPreferredEncoding(encoding: string) { }
setForceOpenAsBinary(): void { }
setMode(mode: string) { }
setPreferredMode(mode: string) { }
isResolved(): boolean { return false; }
matches(other: TestFileEditorInput): boolean {
return other && this.id === other.id && other instanceof TestFileEditorInput;
}
}
function input(id = String(index++), nonSerializable?: boolean, resource?: URI): EditorInput {
if (resource) {
return new TestFileEditorInput(id, resource);
}
return nonSerializable ? new NonSerializableTestEditorInput(id) : new TestEditorInput(id);
}
interface ISerializedTestInput {
id: string;
}
class TestEditorInputFactory implements IEditorInputFactory {
static disableSerialize = false;
static disableDeserialize = false;
canSerialize(editorInput: EditorInput): boolean {
return true;
}
serialize(editorInput: EditorInput): string | undefined {
if (TestEditorInputFactory.disableSerialize) {
return undefined;
}
let testEditorInput = <TestEditorInput>editorInput;
let testInput: ISerializedTestInput = {
id: testEditorInput.id
};
return JSON.stringify(testInput);
}
deserialize(instantiationService: IInstantiationService, serializedEditorInput: string): EditorInput | undefined {
if (TestEditorInputFactory.disableDeserialize) {
return undefined;
}
let testInput: ISerializedTestInput = JSON.parse(serializedEditorInput);
return new TestEditorInput(testInput.id);
}
}
suite('Workbench editor groups', () => {
let disposables: IDisposable[] = [];
function inst(): IInstantiationService {
let inst = new TestInstantiationService();
inst.stub(IStorageService, new TestStorageService());
inst.stub(ILifecycleService, new TestLifecycleService());
inst.stub(IWorkspaceContextService, new TestContextService());
inst.stub(ITelemetryService, NullTelemetryService);
const config = new TestConfigurationService();
config.setUserConfiguration('workbench', { editor: { openPositioning: 'right', focusRecentEditorAfterClose: true } });
inst.stub(IConfigurationService, config);
return inst;
}
function createGroup(serialized?: ISerializedEditorGroup): EditorGroup {
return inst().createInstance(EditorGroup, serialized);
}
function closeAllEditors(group: EditorGroup): void {
for (const editor of group.getEditors(EditorsOrder.SEQUENTIAL)) {
group.closeEditor(editor, false);
}
}
function closeEditors(group: EditorGroup, except: EditorInput, direction?: CloseDirection): void {
const index = group.indexOf(except);
if (index === -1) {
return; // not found
}
// Close to the left
if (direction === CloseDirection.LEFT) {
for (let i = index - 1; i >= 0; i--) {
group.closeEditor(group.getEditorByIndex(i)!);
}
}
// Close to the right
else if (direction === CloseDirection.RIGHT) {
for (let i = group.getEditors(EditorsOrder.SEQUENTIAL).length - 1; i > index; i--) {
group.closeEditor(group.getEditorByIndex(i)!);
}
}
// Both directions
else {
group.getEditors(EditorsOrder.MOST_RECENTLY_ACTIVE).filter(editor => !editor.matches(except)).forEach(editor => group.closeEditor(editor));
}
}
interface GroupEvents {
opened: EditorInput[];
activated: EditorInput[];
closed: EditorCloseEvent[];
pinned: EditorInput[];
unpinned: EditorInput[];
sticky: EditorInput[];
unsticky: EditorInput[];
moved: EditorInput[];
disposed: EditorInput[];
}
function groupListener(group: EditorGroup): GroupEvents {
const groupEvents: GroupEvents = {
opened: [],
closed: [],
activated: [],
pinned: [],
unpinned: [],
sticky: [],
unsticky: [],
moved: [],
disposed: []
};
group.onDidOpenEditor(e => groupEvents.opened.push(e));
group.onDidCloseEditor(e => groupEvents.closed.push(e));
group.onDidActivateEditor(e => groupEvents.activated.push(e));
group.onDidChangeEditorPinned(e => group.isPinned(e) ? groupEvents.pinned.push(e) : groupEvents.unpinned.push(e));
group.onDidChangeEditorSticky(e => group.isSticky(e) ? groupEvents.sticky.push(e) : groupEvents.unsticky.push(e));
group.onDidMoveEditor(e => groupEvents.moved.push(e));
group.onDidDisposeEditor(e => groupEvents.disposed.push(e));
return groupEvents;
}
let index = 0;
class TestEditorInput extends EditorInput {
readonly resource = undefined;
constructor(public id: string) {
super();
}
getTypeId() { return 'testEditorInputForGroups'; }
async resolve(): Promise<IEditorModel> { return null!; }
matches(other: TestEditorInput): boolean {
return other && this.id === other.id && other instanceof TestEditorInput;
}
setDirty(): void {
this._onDidChangeDirty.fire();
}
setLabel(): void {
this._onDidChangeLabel.fire();
}
}
class NonSerializableTestEditorInput extends EditorInput {
readonly resource = undefined;
constructor(public id: string) {
super();
}
getTypeId() { return 'testEditorInputForGroups-nonSerializable'; }
async resolve(): Promise<IEditorModel | null> { return null; }
matches(other: NonSerializableTestEditorInput): boolean {
return other && this.id === other.id && other instanceof NonSerializableTestEditorInput;
}
}
class TestFileEditorInput extends EditorInput implements IFileEditorInput {
readonly preferredResource = this.resource;
constructor(public id: string, public resource: URI) {
super();
}
getTypeId() { return 'testFileEditorInputForGroups'; }
async resolve(): Promise<IEditorModel | null> { return null; }
setPreferredName(name: string): void { }
setPreferredDescription(description: string): void { }
setPreferredResource(resource: URI): void { }
setEncoding(encoding: string) { }
getEncoding() { return undefined; }
setPreferredEncoding(encoding: string) { }
setForceOpenAsBinary(): void { }
setMode(mode: string) { }
setPreferredMode(mode: string) { }
isResolved(): boolean { return false; }
matches(other: TestFileEditorInput): boolean {
return other && this.id === other.id && other instanceof TestFileEditorInput;
}
}
function input(id = String(index++), nonSerializable?: boolean, resource?: URI): EditorInput {
if (resource) {
return new TestFileEditorInput(id, resource);
}
return nonSerializable ? new NonSerializableTestEditorInput(id) : new TestEditorInput(id);
}
interface ISerializedTestInput {
id: string;
}
class TestEditorInputFactory implements IEditorInputFactory {
static disableSerialize = false;
static disableDeserialize = false;
canSerialize(editorInput: EditorInput): boolean {
return true;
}
serialize(editorInput: EditorInput): string | undefined {
if (TestEditorInputFactory.disableSerialize) {
return undefined;
}
let testEditorInput = <TestEditorInput>editorInput;
let testInput: ISerializedTestInput = {
id: testEditorInput.id
};
return JSON.stringify(testInput);
}
deserialize(instantiationService: IInstantiationService, serializedEditorInput: string): EditorInput | undefined {
if (TestEditorInputFactory.disableDeserialize) {
return undefined;
}
let testInput: ISerializedTestInput = JSON.parse(serializedEditorInput);
return new TestEditorInput(testInput.id);
}
}
const disposables = new DisposableStore();
setup(() => {
TestEditorInputFactory.disableSerialize = false;
TestEditorInputFactory.disableDeserialize = false;
disposables.push(Registry.as<IEditorInputFactoryRegistry>(EditorExtensions.EditorInputFactories).registerEditorInputFactory('testEditorInputForGroups', TestEditorInputFactory));
disposables.add(Registry.as<IEditorInputFactoryRegistry>(EditorExtensions.EditorInputFactories).registerEditorInputFactory('testEditorInputForGroups', TestEditorInputFactory));
});
teardown(() => {
dispose(disposables);
disposables = [];
disposables.clear();
index = 1;
});

View file

@ -8,15 +8,15 @@ import { EditorInput } from 'vs/workbench/common/editor';
import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
import { workbenchInstantiationService } from 'vs/workbench/test/browser/workbenchTestServices';
class MyEditorInput extends EditorInput {
readonly resource = undefined;
getTypeId(): string { return ''; }
resolve(): any { return null; }
}
suite('Workbench editor input', () => {
class MyEditorInput extends EditorInput {
readonly resource = undefined;
getTypeId(): string { return ''; }
resolve(): any { return null; }
}
test('EditorInput', () => {
let counter = 0;
let input = new MyEditorInput();

View file

@ -27,19 +27,33 @@ import { TestTextResourcePropertiesService } from 'vs/workbench/test/common/work
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService';
class MyEditorModel extends EditorModel { }
class MyTextEditorModel extends BaseTextEditorModel {
createTextEditorModel(value: ITextBufferFactory, resource?: URI, preferredMode?: string) {
return super.createTextEditorModel(value, resource, preferredMode);
}
isReadonly(): boolean {
return false;
}
}
suite('Workbench editor model', () => {
class MyEditorModel extends EditorModel { }
class MyTextEditorModel extends BaseTextEditorModel {
createTextEditorModel(value: ITextBufferFactory, resource?: URI, preferredMode?: string) {
return super.createTextEditorModel(value, resource, preferredMode);
}
isReadonly(): boolean {
return false;
}
}
function stubModelService(instantiationService: TestInstantiationService): IModelService {
const dialogService = new TestDialogService();
const notificationService = new TestNotificationService();
const undoRedoService = new UndoRedoService(dialogService, notificationService);
instantiationService.stub(IConfigurationService, new TestConfigurationService());
instantiationService.stub(ITextResourcePropertiesService, new TestTextResourcePropertiesService(instantiationService.get(IConfigurationService)));
instantiationService.stub(IDialogService, dialogService);
instantiationService.stub(INotificationService, notificationService);
instantiationService.stub(IUndoRedoService, undoRedoService);
instantiationService.stub(IThemeService, new TestThemeService());
return instantiationService.createInstance(ModelServiceImpl);
}
let instantiationService: TestInstantiationService;
let modeService: IModeService;
@ -51,44 +65,31 @@ suite('Workbench editor model', () => {
test('EditorModel', async () => {
let counter = 0;
let m = new MyEditorModel();
const model = new MyEditorModel();
m.onDispose(() => {
model.onDispose(() => {
assert(true);
counter++;
});
const model = await m.load();
assert(model === m);
assert.strictEqual(model.isDisposed(), false);
assert.strictEqual(m.isResolved(), true);
m.dispose();
const resolvedModel = await model.load();
assert(resolvedModel === model);
assert.strictEqual(resolvedModel.isDisposed(), false);
assert.strictEqual(model.isResolved(), true);
model.dispose();
assert.strictEqual(counter, 1);
assert.strictEqual(model.isDisposed(), true);
assert.strictEqual(resolvedModel.isDisposed(), true);
});
test('BaseTextEditorModel', async () => {
let modelService = stubModelService(instantiationService);
let m = new MyTextEditorModel(modelService, modeService);
const model = await m.load() as MyTextEditorModel;
const model = new MyTextEditorModel(modelService, modeService);
const resolvedModel = await model.load() as MyTextEditorModel;
assert(model === m);
model.createTextEditorModel(createTextBufferFactory('foo'), null!, 'text/plain');
assert.strictEqual(m.isResolved(), true);
m.dispose();
assert(resolvedModel === model);
resolvedModel.createTextEditorModel(createTextBufferFactory('foo'), null!, 'text/plain');
assert.strictEqual(model.isResolved(), true);
model.dispose();
});
function stubModelService(instantiationService: TestInstantiationService): IModelService {
const dialogService = new TestDialogService();
const notificationService = new TestNotificationService();
const undoRedoService = new UndoRedoService(dialogService, notificationService);
instantiationService.stub(IConfigurationService, new TestConfigurationService());
instantiationService.stub(ITextResourcePropertiesService, new TestTextResourcePropertiesService(instantiationService.get(IConfigurationService)));
instantiationService.stub(IDialogService, dialogService);
instantiationService.stub(INotificationService, notificationService);
instantiationService.stub(IUndoRedoService, undoRedoService);
instantiationService.stub(IThemeService, new TestThemeService());
return instantiationService.createInstance(ModelServiceImpl);
}
});

View file

@ -7,25 +7,25 @@ import * as assert from 'assert';
import { EditorPane, EditorMemento } from 'vs/workbench/browser/parts/editor/editorPane';
import { EditorInput, EditorOptions, IEditorInputFactory, IEditorInputFactoryRegistry, Extensions as EditorExtensions } from 'vs/workbench/common/editor';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import * as Platform from 'vs/platform/registry/common/platform';
import { Registry } from 'vs/platform/registry/common/platform';
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils';
import { workbenchInstantiationService, TestEditorGroupView, TestEditorGroupsService } from 'vs/workbench/test/browser/workbenchTestServices';
import { workbenchInstantiationService, TestEditorGroupView, TestEditorGroupsService, registerTestResourceEditor } from 'vs/workbench/test/browser/workbenchTestServices';
import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput';
import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService';
import { URI } from 'vs/base/common/uri';
import { IEditorRegistry, Extensions, EditorDescriptor } from 'vs/workbench/browser/editor';
import { CancellationToken } from 'vs/base/common/cancellation';
import { IEditorModel } from 'vs/platform/editor/common/editor';
import { dispose } from 'vs/base/common/lifecycle';
import { DisposableStore, dispose } from 'vs/base/common/lifecycle';
import { TestStorageService } from 'vs/workbench/test/common/workbenchTestServices';
import { extUri } from 'vs/base/common/resources';
const NullThemeService = new TestThemeService();
let EditorRegistry: IEditorRegistry = Platform.Registry.as(Extensions.Editors);
let EditorInputRegistry: IEditorInputFactoryRegistry = Platform.Registry.as(EditorExtensions.EditorInputFactories);
let EditorRegistry: IEditorRegistry = Registry.as(Extensions.Editors);
let EditorInputRegistry: IEditorInputFactoryRegistry = Registry.as(EditorExtensions.EditorInputFactories);
export class MyEditor extends EditorPane {
@ -155,7 +155,10 @@ suite('Workbench EditorPane', () => {
test('Editor Lookup favors specific class over superclass (match on specific class)', function () {
let d1 = EditorDescriptor.create(MyEditor, 'id1', 'name');
const disposable = EditorRegistry.registerEditor(d1, [new SyncDescriptor(MyResourceEditorInput)]);
const disposables = new DisposableStore();
disposables.add(registerTestResourceEditor());
disposables.add(EditorRegistry.registerEditor(d1, [new SyncDescriptor(MyResourceEditorInput)]));
let inst = workbenchInstantiationService();
@ -165,14 +168,20 @@ suite('Workbench EditorPane', () => {
const otherEditor = EditorRegistry.getEditor(inst.createInstance(ResourceEditorInput, URI.file('/fake'), 'fake', '', undefined))!.instantiate(inst);
assert.strictEqual(otherEditor.getId(), 'workbench.editors.textResourceEditor');
disposable.dispose();
disposables.dispose();
});
test('Editor Lookup favors specific class over superclass (match on super class)', function () {
let inst = workbenchInstantiationService();
const disposables = new DisposableStore();
disposables.add(registerTestResourceEditor());
const editor = EditorRegistry.getEditor(inst.createInstance(MyResourceEditorInput, URI.file('/fake'), 'fake', '', undefined))!.instantiate(inst);
assert.strictEqual('workbench.editors.textResourceEditor', editor.getId());
disposables.dispose();
});
test('Editor Input Factory', function () {
@ -299,7 +308,7 @@ suite('Workbench EditorPane', () => {
super();
}
getTypeId() { return 'testEditorInputForMementoTest'; }
resolve(): Promise<IEditorModel> { return Promise.resolve(null!); }
async resolve(): Promise<IEditorModel | null> { return null; }
matches(other: TestEditorInput): boolean {
return other && this.id === other.id && other instanceof TestEditorInput;
@ -337,7 +346,7 @@ suite('Workbench EditorPane', () => {
super();
}
getTypeId() { return 'testEditorInputForMementoTest'; }
resolve(): Promise<IEditorModel> { return Promise.resolve(null!); }
async resolve(): Promise<IEditorModel | null> { return null; }
matches(other: TestEditorInput): boolean {
return other && this.id === other.id && other instanceof TestEditorInput;

View file

@ -4,9 +4,9 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import * as Platform from 'vs/platform/registry/common/platform';
import { Registry } from 'vs/platform/registry/common/platform';
import { ViewletDescriptor, Extensions, Viewlet, ViewletRegistry } from 'vs/workbench/browser/viewlet';
import * as Types from 'vs/base/common/types';
import { isFunction } from 'vs/base/common/types';
suite('Viewlets', () => {
@ -40,15 +40,15 @@ suite('Viewlets', () => {
});
test('Viewlet extension point and registration', function () {
assert(Types.isFunction(Platform.Registry.as<ViewletRegistry>(Extensions.Viewlets).registerViewlet));
assert(Types.isFunction(Platform.Registry.as<ViewletRegistry>(Extensions.Viewlets).getViewlet));
assert(Types.isFunction(Platform.Registry.as<ViewletRegistry>(Extensions.Viewlets).getViewlets));
assert(isFunction(Registry.as<ViewletRegistry>(Extensions.Viewlets).registerViewlet));
assert(isFunction(Registry.as<ViewletRegistry>(Extensions.Viewlets).getViewlet));
assert(isFunction(Registry.as<ViewletRegistry>(Extensions.Viewlets).getViewlets));
let oldCount = Platform.Registry.as<ViewletRegistry>(Extensions.Viewlets).getViewlets().length;
let oldCount = Registry.as<ViewletRegistry>(Extensions.Viewlets).getViewlets().length;
let d = ViewletDescriptor.create(TestViewlet, 'reg-test-id', 'name');
Platform.Registry.as<ViewletRegistry>(Extensions.Viewlets).registerViewlet(d);
Registry.as<ViewletRegistry>(Extensions.Viewlets).registerViewlet(d);
assert(d === Platform.Registry.as<ViewletRegistry>(Extensions.Viewlets).getViewlet('reg-test-id'));
assert.strictEqual(oldCount + 1, Platform.Registry.as<ViewletRegistry>(Extensions.Viewlets).getViewlets().length);
assert(d === Registry.as<ViewletRegistry>(Extensions.Viewlets).getViewlet('reg-test-id'));
assert.strictEqual(oldCount + 1, Registry.as<ViewletRegistry>(Extensions.Viewlets).getViewlets().length);
});
});

View file

@ -3,14 +3,13 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/workbench/contrib/files/browser/files.contribution'; // load our contribution into the test
import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileEditorInput';
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
import * as resources from 'vs/base/common/resources';
import { basename } from 'vs/base/common/resources';
import { URI } from 'vs/base/common/uri';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils';
import { IEditorInputWithOptions, IEditorIdentifier, IUntitledTextResourceEditorInput, IResourceDiffEditorInput, IEditorInput, IEditorPane, IEditorCloseEvent, IEditorPartOptions, IRevertOptions, GroupIdentifier, EditorInput, EditorOptions, EditorsOrder, IFileEditorInput, IEditorInputFactoryRegistry, IEditorInputFactory, Extensions as EditorExtensions, ISaveOptions, IMoveResult, ITextEditorPane, ITextDiffEditorPane, IVisibleEditorPane, IEditorOpenContext } from 'vs/workbench/common/editor';
import { IEditorInputWithOptions, IEditorIdentifier, IUntitledTextResourceEditorInput, IResourceDiffEditorInput, IEditorInput, IEditorPane, IEditorCloseEvent, IEditorPartOptions, IRevertOptions, GroupIdentifier, EditorInput, EditorOptions, EditorsOrder, IFileEditorInput, IEditorInputFactoryRegistry, IEditorInputFactory, Extensions as EditorExtensions, ISaveOptions, IMoveResult, ITextEditorPane, ITextDiffEditorPane, IVisibleEditorPane, IEditorOpenContext, SideBySideEditorInput } from 'vs/workbench/common/editor';
import { IEditorOpeningEvent, EditorServiceImpl, IEditorGroupView, IEditorGroupsAccessor, IEditorGroupTitleDimensions } from 'vs/workbench/browser/parts/editor/editor';
import { Event, Emitter } from 'vs/base/common/event';
import { IBackupFileService } from 'vs/workbench/services/backup/common/backup';
@ -97,7 +96,7 @@ import { TestDialogService } from 'vs/platform/dialogs/test/common/testDialogSer
import { CodeEditorService } from 'vs/workbench/services/editor/browser/codeEditorService';
import { EditorPart } from 'vs/workbench/browser/parts/editor/editorPart';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { IDiffEditor } from 'vs/editor/common/editorCommon';
import { IDiffEditor, IEditor } from 'vs/editor/common/editorCommon';
import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput';
import { QuickInputService } from 'vs/workbench/services/quickinput/browser/quickInputService';
import { IListService } from 'vs/platform/list/browser/listService';
@ -118,11 +117,42 @@ import { InMemoryBackupFileService } from 'vs/workbench/services/backup/common/b
import { hash } from 'vs/base/common/hash';
import { BrowserBackupFileService } from 'vs/workbench/services/backup/browser/backupFileService';
import { FileService } from 'vs/platform/files/common/fileService';
import { TextResourceEditor } from 'vs/workbench/browser/parts/editor/textResourceEditor';
import { TestCodeEditor } from 'vs/editor/test/browser/testCodeEditor';
import { TextFileEditor } from 'vs/workbench/contrib/files/browser/editors/textFileEditor';
import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput';
import { UntitledTextEditorInput } from 'vs/workbench/services/untitled/common/untitledTextEditorInput';
import { SideBySideEditor } from 'vs/workbench/browser/parts/editor/sideBySideEditor';
export function createFileEditorInput(instantiationService: IInstantiationService, resource: URI): FileEditorInput {
return instantiationService.createInstance(FileEditorInput, resource, undefined, undefined, undefined, undefined, undefined);
}
Registry.as<IEditorInputFactoryRegistry>(EditorExtensions.EditorInputFactories).registerFileEditorInputFactory({
createFileEditorInput: (resource, preferredResource, preferredName, preferredDescription, preferredEncoding, preferredMode, instantiationService): IFileEditorInput => {
return instantiationService.createInstance(FileEditorInput, resource, preferredResource, preferredName, preferredDescription, preferredEncoding, preferredMode);
},
isFileEditorInput: (obj): obj is IFileEditorInput => {
return obj instanceof FileEditorInput;
}
});
export class TestTextResourceEditor extends TextResourceEditor {
protected createEditorControl(parent: HTMLElement, configuration: any): IEditor {
return this.instantiationService.createInstance(TestCodeEditor, parent, configuration, {});
}
}
export class TestTextFileEditor extends TextFileEditor {
protected createEditorControl(parent: HTMLElement, configuration: any): IEditor {
return this.instantiationService.createInstance(TestCodeEditor, parent, configuration, {});
}
}
export interface ITestInstantiationService extends IInstantiationService {
stub<T>(service: ServiceIdentifier<T>, ctor: any): T;
}
@ -772,7 +802,7 @@ export class TestFileService implements IFileService {
isFile: true,
isDirectory: false,
isSymbolicLink: false,
name: resources.basename(resource)
name: basename(resource)
});
}
@ -794,7 +824,7 @@ export class TestFileService implements IFileService {
encoding: 'utf8',
mtime: Date.now(),
ctime: Date.now(),
name: resources.basename(resource),
name: basename(resource),
size: 1
});
}
@ -823,7 +853,7 @@ export class TestFileService implements IFileService {
mtime: Date.now(),
ctime: Date.now(),
size: 1,
name: resources.basename(resource)
name: basename(resource)
});
}
@ -845,7 +875,7 @@ export class TestFileService implements IFileService {
isFile: true,
isDirectory: false,
isSymbolicLink: false,
name: resources.basename(resource)
name: basename(resource)
});
}
@ -1216,6 +1246,56 @@ export function registerTestEditor(id: string, inputs: SyncDescriptor<EditorInpu
return disposables;
}
export function registerTestFileEditor(): IDisposable {
const disposables = new DisposableStore();
disposables.add(Registry.as<IEditorRegistry>(Extensions.Editors).registerEditor(
EditorDescriptor.create(
TestTextFileEditor,
TestTextFileEditor.ID,
'Text File Editor'
),
[new SyncDescriptor<EditorInput>(FileEditorInput)]
));
return disposables;
}
export function registerTestResourceEditor(): IDisposable {
const disposables = new DisposableStore();
disposables.add(Registry.as<IEditorRegistry>(Extensions.Editors).registerEditor(
EditorDescriptor.create(
TestTextResourceEditor,
TestTextResourceEditor.ID,
'Text Editor'
),
[
new SyncDescriptor<EditorInput>(UntitledTextEditorInput),
new SyncDescriptor<EditorInput>(ResourceEditorInput)
]
));
return disposables;
}
export function registerTestSideBySideEditor(): IDisposable {
const disposables = new DisposableStore();
disposables.add(Registry.as<IEditorRegistry>(Extensions.Editors).registerEditor(
EditorDescriptor.create(
SideBySideEditor,
SideBySideEditor.ID,
'Text Editor'
),
[
new SyncDescriptor(SideBySideEditorInput)
]
));
return disposables;
}
export class TestFileEditorInput extends EditorInput implements IFileEditorInput {
readonly preferredResource = this.resource;

View file

@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { join } from 'vs/base/common/path';
import * as resources from 'vs/base/common/resources';
import { basename, isEqual, isEqualOrParent } from 'vs/base/common/resources';
import { URI } from 'vs/base/common/uri';
import { Event, Emitter } from 'vs/base/common/event';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
@ -104,7 +104,7 @@ export class TestContextService implements IWorkspaceContextService {
isInsideWorkspace(resource: URI): boolean {
if (resource && this.workspace) {
return resources.isEqualOrParent(resource, this.workspace.folders[0].uri);
return isEqualOrParent(resource, this.workspace.folders[0].uri);
}
return false;
@ -115,7 +115,7 @@ export class TestContextService implements IWorkspaceContextService {
}
isCurrentWorkspace(workspaceIdOrFolder: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | URI): boolean {
return URI.isUri(workspaceIdOrFolder) && resources.isEqual(this.workspace.folders[0].uri, workspaceIdOrFolder);
return URI.isUri(workspaceIdOrFolder) && isEqual(this.workspace.folders[0].uri, workspaceIdOrFolder);
}
}
@ -141,7 +141,7 @@ export class TestWorkingCopy extends Disposable implements IWorkingCopy {
readonly capabilities = WorkingCopyCapabilities.None;
readonly name = resources.basename(this.resource);
readonly name = basename(this.resource);
private dirty = false;

View file

@ -40,6 +40,7 @@ import 'vs/workbench/api/browser/viewsExtensionPoint';
//#region --- workbench parts
import 'vs/workbench/browser/parts/editor/editor.contribution';
import 'vs/workbench/browser/parts/editor/editorPart';
import 'vs/workbench/browser/parts/activitybar/activitybarPart';
import 'vs/workbench/browser/parts/panel/panelPart';