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

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

View File

@@ -0,0 +1,107 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { TPromise } from 'vs/base/common/winjs.base';
import { isParent } from 'vs/platform/files/common/files';
import { localize } from 'vs/nls';
import { basename, dirname, join } from 'vs/base/common/paths';
import { isLinux } from 'vs/base/common/platform';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import Event from 'vs/base/common/event';
import { tildify, getPathLabel } from 'vs/base/common/labels';
export const IWorkspacesMainService = createDecorator<IWorkspacesMainService>('workspacesMainService');
export const IWorkspacesService = createDecorator<IWorkspacesService>('workspacesService');
export const WORKSPACE_EXTENSION = 'code-workspace';
export const WORKSPACE_FILTER = [{ name: localize('codeWorkspace', "Code Workspace"), extensions: [WORKSPACE_EXTENSION] }];
export const UNTITLED_WORKSPACE_NAME = 'workspace.json';
/**
* A single folder workspace identifier is just the path to the folder.
*/
export type ISingleFolderWorkspaceIdentifier = string;
export interface IWorkspaceIdentifier {
id: string;
configPath: string;
}
export interface IStoredWorkspaceFolder {
path: string;
}
export interface IStoredWorkspace {
folders: IStoredWorkspaceFolder[];
}
export interface IResolvedWorkspace extends IWorkspaceIdentifier, IStoredWorkspace { }
export interface IWorkspaceSavedEvent {
workspace: IWorkspaceIdentifier;
oldConfigPath: string;
}
export interface IWorkspacesMainService extends IWorkspacesService {
_serviceBrand: any;
onWorkspaceSaved: Event<IWorkspaceSavedEvent>;
onUntitledWorkspaceDeleted: Event<IWorkspaceIdentifier>;
saveWorkspace(workspace: IWorkspaceIdentifier, target: string): TPromise<IWorkspaceIdentifier>;
createWorkspaceSync(folders?: string[]): IWorkspaceIdentifier;
resolveWorkspace(path: string): TPromise<IResolvedWorkspace>;
resolveWorkspaceSync(path: string): IResolvedWorkspace;
isUntitledWorkspace(workspace: IWorkspaceIdentifier): boolean;
deleteUntitledWorkspaceSync(workspace: IWorkspaceIdentifier): void;
getUntitledWorkspacesSync(): IWorkspaceIdentifier[];
getWorkspaceId(workspacePath: string): string;
}
export interface IWorkspacesService {
_serviceBrand: any;
createWorkspace(folders?: string[]): TPromise<IWorkspaceIdentifier>;
}
export function getWorkspaceLabel(workspace: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier), environmentService: IEnvironmentService, options?: { verbose: boolean }): string {
// Workspace: Single Folder
if (isSingleFolderWorkspaceIdentifier(workspace)) {
return tildify(workspace, environmentService.userHome);
}
// Workspace: Untitled
if (isParent(workspace.configPath, environmentService.workspacesHome, !isLinux /* ignore case */)) {
return localize('untitledWorkspace', "Untitled (Workspace)");
}
// Workspace: Saved
const filename = basename(workspace.configPath);
const workspaceName = filename.substr(0, filename.length - WORKSPACE_EXTENSION.length - 1);
if (options && options.verbose) {
return localize('workspaceNameVerbose', "{0} (Workspace)", getPathLabel(join(dirname(workspace.configPath), workspaceName), null, environmentService));
}
return localize('workspaceName', "{0} (Workspace)", workspaceName);
}
export function isSingleFolderWorkspaceIdentifier(obj: any): obj is ISingleFolderWorkspaceIdentifier {
return typeof obj === 'string';
}
export function isWorkspaceIdentifier(obj: any): obj is IWorkspaceIdentifier {
const workspaceIdentifier = obj as IWorkspaceIdentifier;
return workspaceIdentifier && typeof workspaceIdentifier.id === 'string' && typeof workspaceIdentifier.configPath === 'string';
}

View File

@@ -0,0 +1,39 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { TPromise } from 'vs/base/common/winjs.base';
import { IChannel } from 'vs/base/parts/ipc/common/ipc';
import { IWorkspacesService, IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
export interface IWorkspacesChannel extends IChannel {
call(command: 'createWorkspace', arg: [string[]]): TPromise<string>;
call(command: string, arg?: any): TPromise<any>;
}
export class WorkspacesChannel implements IWorkspacesChannel {
constructor(private service: IWorkspacesService) { }
call(command: string, arg?: any): TPromise<any> {
switch (command) {
case 'createWorkspace': return this.service.createWorkspace(arg);
}
return void 0;
}
}
export class WorkspacesChannelClient implements IWorkspacesService {
_serviceBrand: any;
constructor(private channel: IWorkspacesChannel) { }
createWorkspace(folders?: string[]): TPromise<IWorkspaceIdentifier> {
return this.channel.call('createWorkspace', folders);
}
}

View File

@@ -0,0 +1,277 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { IWorkspacesMainService, IWorkspaceIdentifier, IStoredWorkspace, WORKSPACE_EXTENSION, IWorkspaceSavedEvent, UNTITLED_WORKSPACE_NAME, IResolvedWorkspace } from 'vs/platform/workspaces/common/workspaces';
import { TPromise } from 'vs/base/common/winjs.base';
import { isParent } from 'vs/platform/files/common/files';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { extname, join, dirname, isAbsolute, resolve, relative } from 'path';
import { mkdirp, writeFile, readFile } from 'vs/base/node/pfs';
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
import { isLinux } from 'vs/base/common/platform';
import { delSync, readdirSync } from 'vs/base/node/extfs';
import Event, { Emitter } from 'vs/base/common/event';
import { ILogService } from 'vs/platform/log/common/log';
import { isEqual, isEqualOrParent } from 'vs/base/common/paths';
import { coalesce } from 'vs/base/common/arrays';
import { createHash } from 'crypto';
import URI from 'vs/base/common/uri';
import * as json from 'vs/base/common/json';
// TODO@Ben migration
export interface ILegacyStoredWorkspace {
id: string;
folders: string[];
}
export class WorkspacesMainService implements IWorkspacesMainService {
public _serviceBrand: any;
protected workspacesHome: string;
private _onWorkspaceSaved: Emitter<IWorkspaceSavedEvent>;
private _onUntitledWorkspaceDeleted: Emitter<IWorkspaceIdentifier>;
constructor(
@IEnvironmentService private environmentService: IEnvironmentService,
@ILogService private logService: ILogService
) {
this.workspacesHome = environmentService.workspacesHome;
this._onWorkspaceSaved = new Emitter<IWorkspaceSavedEvent>();
this._onUntitledWorkspaceDeleted = new Emitter<IWorkspaceIdentifier>();
}
public get onWorkspaceSaved(): Event<IWorkspaceSavedEvent> {
return this._onWorkspaceSaved.event;
}
public get onUntitledWorkspaceDeleted(): Event<IWorkspaceIdentifier> {
return this._onUntitledWorkspaceDeleted.event;
}
public resolveWorkspace(path: string): TPromise<IResolvedWorkspace> {
if (!this.isWorkspacePath(path)) {
return TPromise.as(null); // does not look like a valid workspace config file
}
return readFile(path).then(contents => this.doResolveWorkspace(path, contents.toString()));
}
public resolveWorkspaceSync(path: string): IResolvedWorkspace {
if (!this.isWorkspacePath(path)) {
return null; // does not look like a valid workspace config file
}
return this.doResolveWorkspace(path, readFileSync(path, 'utf8'));
}
private isWorkspacePath(path: string): boolean {
return this.isInsideWorkspacesHome(path) || extname(path) === `.${WORKSPACE_EXTENSION}`;
}
private doResolveWorkspace(path: string, contents: string): IResolvedWorkspace {
try {
const workspace = this.doParseStoredWorkspace(path, contents);
// relative paths get resolved against the workspace location
workspace.folders.forEach(folder => {
if (!isAbsolute(folder.path)) {
folder.path = resolve(dirname(path), folder.path);
}
});
return {
id: this.getWorkspaceId(path),
configPath: path,
folders: workspace.folders
};
} catch (error) {
this.logService.log(error.toString());
}
return null;
}
private doParseStoredWorkspace(path: string, contents: string): IStoredWorkspace {
// Parse workspace file
let storedWorkspace: IStoredWorkspace;
try {
storedWorkspace = json.parse(contents); // use fault tolerant parser
} catch (error) {
throw new Error(`${path} cannot be parsed as JSON file (${error}).`);
}
// TODO@Ben migration
const legacyStoredWorkspace = (<any>storedWorkspace) as ILegacyStoredWorkspace;
if (legacyStoredWorkspace.folders.some(folder => typeof folder === 'string')) {
storedWorkspace.folders = legacyStoredWorkspace.folders.map(folder => ({ path: URI.parse(folder).fsPath }));
writeFileSync(path, JSON.stringify(storedWorkspace, null, '\t'));
}
// Filter out folders which do not have a path set
if (Array.isArray(storedWorkspace.folders)) {
storedWorkspace.folders = storedWorkspace.folders.filter(folder => !!folder.path);
}
// Validate
if (!Array.isArray(storedWorkspace.folders) || storedWorkspace.folders.length === 0) {
throw new Error(`${path} looks like an invalid workspace file.`);
}
return storedWorkspace;
}
private isInsideWorkspacesHome(path: string): boolean {
return isParent(path, this.environmentService.workspacesHome, !isLinux /* ignore case */);
}
public createWorkspace(folders: string[]): TPromise<IWorkspaceIdentifier> {
const { workspace, configParent, storedWorkspace } = this.createUntitledWorkspace(folders);
return mkdirp(configParent).then(() => {
return writeFile(workspace.configPath, JSON.stringify(storedWorkspace, null, '\t')).then(() => workspace);
});
}
public createWorkspaceSync(folders: string[]): IWorkspaceIdentifier {
const { workspace, configParent, storedWorkspace } = this.createUntitledWorkspace(folders);
if (!existsSync(this.workspacesHome)) {
mkdirSync(this.workspacesHome);
}
mkdirSync(configParent);
writeFileSync(workspace.configPath, JSON.stringify(storedWorkspace, null, '\t'));
return workspace;
}
private createUntitledWorkspace(folders: string[]): { workspace: IWorkspaceIdentifier, configParent: string, storedWorkspace: IStoredWorkspace } {
const randomId = (Date.now() + Math.round(Math.random() * 1000)).toString();
const untitledWorkspaceConfigFolder = join(this.workspacesHome, randomId);
const untitledWorkspaceConfigPath = join(untitledWorkspaceConfigFolder, UNTITLED_WORKSPACE_NAME);
const storedWorkspace: IStoredWorkspace = {
folders: folders.map(folder => ({
path: folder
}))
};
return {
workspace: {
id: this.getWorkspaceId(untitledWorkspaceConfigPath),
configPath: untitledWorkspaceConfigPath
},
configParent: untitledWorkspaceConfigFolder,
storedWorkspace
};
}
public getWorkspaceId(workspaceConfigPath: string): string {
if (!isLinux) {
workspaceConfigPath = workspaceConfigPath.toLowerCase(); // sanitize for platform file system
}
return createHash('md5').update(workspaceConfigPath).digest('hex');
}
public isUntitledWorkspace(workspace: IWorkspaceIdentifier): boolean {
return this.isInsideWorkspacesHome(workspace.configPath);
}
public saveWorkspace(workspace: IWorkspaceIdentifier, targetConfigPath: string): TPromise<IWorkspaceIdentifier> {
// Return early if target is same as source
if (isEqual(workspace.configPath, targetConfigPath, !isLinux)) {
return TPromise.as(workspace);
}
// Read the contents of the workspace file and resolve it
return readFile(workspace.configPath).then(rawWorkspaceContents => {
let storedWorkspace: IStoredWorkspace;
try {
storedWorkspace = this.doParseStoredWorkspace(workspace.configPath, rawWorkspaceContents.toString());
} catch (error) {
return TPromise.wrapError(error);
}
const sourceConfigFolder = dirname(workspace.configPath);
const targetConfigFolder = dirname(targetConfigPath);
// Rewrite absolute paths to relative paths if the target workspace folder
// is a parent of the location of the workspace file itself. Otherwise keep
// using absolute paths.
storedWorkspace.folders.forEach(folder => {
if (!isAbsolute(folder.path)) {
folder.path = resolve(sourceConfigFolder, folder.path); // relative paths get resolved against the workspace location
}
if (isEqualOrParent(folder.path, targetConfigFolder, !isLinux)) {
folder.path = relative(targetConfigFolder, folder.path) || '.'; // absolute paths get converted to relative ones to workspace location if possible
}
});
return writeFile(targetConfigPath, JSON.stringify(storedWorkspace, null, '\t')).then(() => {
const savedWorkspaceIdentifier = { id: this.getWorkspaceId(targetConfigPath), configPath: targetConfigPath };
// Event
this._onWorkspaceSaved.fire({ workspace: savedWorkspaceIdentifier, oldConfigPath: workspace.configPath });
// Delete untitled workspace
this.deleteUntitledWorkspaceSync(workspace);
return savedWorkspaceIdentifier;
});
});
}
public deleteUntitledWorkspaceSync(workspace: IWorkspaceIdentifier): void {
if (!this.isUntitledWorkspace(workspace)) {
return; // only supported for untitled workspaces
}
// Delete from disk
this.doDeleteUntitledWorkspaceSync(workspace.configPath);
// Event
this._onUntitledWorkspaceDeleted.fire(workspace);
}
private doDeleteUntitledWorkspaceSync(configPath: string): void {
try {
delSync(dirname(configPath));
} catch (error) {
this.logService.log(`Unable to delete untitled workspace ${configPath} (${error}).`);
}
}
public getUntitledWorkspacesSync(): IWorkspaceIdentifier[] {
let untitledWorkspacePaths: string[] = [];
try {
untitledWorkspacePaths = readdirSync(this.workspacesHome).map(folder => join(this.workspacesHome, folder, UNTITLED_WORKSPACE_NAME));
} catch (error) {
this.logService.log(`Unable to read folders in ${this.workspacesHome} (${error}).`);
}
const untitledWorkspaces: IWorkspaceIdentifier[] = coalesce(untitledWorkspacePaths.map(untitledWorkspacePath => {
const workspace = this.resolveWorkspaceSync(untitledWorkspacePath);
if (!workspace) {
this.doDeleteUntitledWorkspaceSync(untitledWorkspacePath);
return null; // invalid workspace
}
return { id: workspace.id, configPath: untitledWorkspacePath };
}));
return untitledWorkspaces;
}
}

View File

@@ -0,0 +1,301 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import fs = require('fs');
import os = require('os');
import path = require('path');
import extfs = require('vs/base/node/extfs');
import pfs = require('vs/base/node/pfs');
import { EnvironmentService } from 'vs/platform/environment/node/environmentService';
import { parseArgs } from 'vs/platform/environment/node/argv';
import { WorkspacesMainService } from 'vs/platform/workspaces/electron-main/workspacesMainService';
import { IStoredWorkspace, WORKSPACE_EXTENSION, IWorkspaceSavedEvent, IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { LogMainService } from 'vs/platform/log/common/log';
import URI from 'vs/base/common/uri';
suite('WorkspacesMainService', () => {
const parentDir = path.join(os.tmpdir(), 'vsctests', 'service');
const workspacesHome = path.join(parentDir, 'Workspaces');
class TestEnvironmentService extends EnvironmentService {
get workspacesHome(): string {
return workspacesHome;
}
}
class TestWorkspacesMainService extends WorkspacesMainService {
public deleteWorkspaceCall: IWorkspaceIdentifier;
public deleteUntitledWorkspaceSync(workspace: IWorkspaceIdentifier): void {
this.deleteWorkspaceCall = workspace;
super.deleteUntitledWorkspaceSync(workspace);
}
}
const environmentService = new TestEnvironmentService(parseArgs(process.argv), process.execPath);
const logService = new LogMainService(environmentService);
let service: TestWorkspacesMainService;
setup(done => {
service = new TestWorkspacesMainService(environmentService, logService);
// Delete any existing backups completely and then re-create it.
extfs.del(workspacesHome, os.tmpdir(), () => {
pfs.mkdirp(workspacesHome).then(() => {
done();
});
});
});
teardown(done => {
extfs.del(workspacesHome, os.tmpdir(), done);
});
test('createWorkspace (folders)', done => {
return service.createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => {
assert.ok(workspace);
assert.ok(fs.existsSync(workspace.configPath));
assert.ok(service.isUntitledWorkspace(workspace));
const ws = JSON.parse(fs.readFileSync(workspace.configPath).toString()) as IStoredWorkspace;
assert.equal(ws.folders.length, 2); //
assert.equal(ws.folders[0].path, process.cwd());
assert.equal(ws.folders[1].path, os.tmpdir());
done();
});
});
test('createWorkspaceSync (folders)', () => {
const workspace = service.createWorkspaceSync([process.cwd(), os.tmpdir()]);
assert.ok(workspace);
assert.ok(fs.existsSync(workspace.configPath));
assert.ok(service.isUntitledWorkspace(workspace));
const ws = JSON.parse(fs.readFileSync(workspace.configPath).toString()) as IStoredWorkspace;
assert.equal(ws.folders.length, 2); //
assert.equal(ws.folders[0].path, process.cwd());
assert.equal(ws.folders[1].path, os.tmpdir());
});
test('resolveWorkspaceSync', done => {
return service.createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => {
assert.ok(service.resolveWorkspaceSync(workspace.configPath));
// make it a valid workspace path
const newPath = path.join(path.dirname(workspace.configPath), `workspace.${WORKSPACE_EXTENSION}`);
fs.renameSync(workspace.configPath, newPath);
workspace.configPath = newPath;
const resolved = service.resolveWorkspaceSync(workspace.configPath);
assert.equal(2, resolved.folders.length);
assert.equal(resolved.configPath, workspace.configPath);
assert.ok(resolved.id);
fs.writeFileSync(workspace.configPath, JSON.stringify({ something: 'something' })); // invalid workspace
const resolvedInvalid = service.resolveWorkspaceSync(workspace.configPath);
assert.ok(!resolvedInvalid);
done();
});
});
test('resolveWorkspace', done => {
return service.createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => {
return service.resolveWorkspace(workspace.configPath).then(ws => {
assert.ok(ws);
// make it a valid workspace path
const newPath = path.join(path.dirname(workspace.configPath), `workspace.${WORKSPACE_EXTENSION}`);
fs.renameSync(workspace.configPath, newPath);
workspace.configPath = newPath;
return service.resolveWorkspace(workspace.configPath).then(resolved => {
assert.equal(2, resolved.folders.length);
assert.equal(resolved.configPath, workspace.configPath);
assert.ok(resolved.id);
fs.writeFileSync(workspace.configPath, JSON.stringify({ something: 'something' })); // invalid workspace
return service.resolveWorkspace(workspace.configPath).then(resolvedInvalid => {
assert.ok(!resolvedInvalid);
done();
});
});
});
});
});
test('resolveWorkspaceSync (support relative paths)', done => {
return service.createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => {
fs.writeFileSync(workspace.configPath, JSON.stringify({ folders: [{ path: './ticino-playground/lib' }] }));
const resolved = service.resolveWorkspaceSync(workspace.configPath);
assert.equal(URI.file(resolved.folders[0].path).fsPath, URI.file(path.join(path.dirname(workspace.configPath), 'ticino-playground', 'lib')).fsPath);
done();
});
});
test('resolveWorkspaceSync (support relative paths #2)', done => {
return service.createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => {
fs.writeFileSync(workspace.configPath, JSON.stringify({ folders: [{ path: './ticino-playground/lib/../other' }] }));
const resolved = service.resolveWorkspaceSync(workspace.configPath);
assert.equal(URI.file(resolved.folders[0].path).fsPath, URI.file(path.join(path.dirname(workspace.configPath), 'ticino-playground', 'other')).fsPath);
done();
});
});
test('resolveWorkspaceSync (support relative paths #3)', done => {
return service.createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => {
fs.writeFileSync(workspace.configPath, JSON.stringify({ folders: [{ path: 'ticino-playground/lib' }] }));
const resolved = service.resolveWorkspaceSync(workspace.configPath);
assert.equal(URI.file(resolved.folders[0].path).fsPath, URI.file(path.join(path.dirname(workspace.configPath), 'ticino-playground', 'lib')).fsPath);
done();
});
});
test('resolveWorkspaceSync (support invalid JSON via fault tolerant parsing)', done => {
return service.createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => {
fs.writeFileSync(workspace.configPath, '{ "folders": [ { "path": "./ticino-playground/lib" } , ] }'); // trailing comma
const resolved = service.resolveWorkspaceSync(workspace.configPath);
assert.equal(URI.file(resolved.folders[0].path).fsPath, URI.file(path.join(path.dirname(workspace.configPath), 'ticino-playground', 'lib')).fsPath);
done();
});
});
test('saveWorkspace (untitled)', done => {
let savedEvent: IWorkspaceSavedEvent;
const listener = service.onWorkspaceSaved(e => {
savedEvent = e;
});
let deletedEvent: IWorkspaceIdentifier;
const listener2 = service.onUntitledWorkspaceDeleted(e => {
deletedEvent = e;
});
return service.createWorkspace([process.cwd(), os.tmpdir(), path.join(os.tmpdir(), 'somefolder')]).then(workspace => {
const workspaceConfigPath = path.join(os.tmpdir(), `myworkspace.${Date.now()}.${WORKSPACE_EXTENSION}`);
return service.saveWorkspace(workspace, workspaceConfigPath).then(savedWorkspace => {
assert.ok(savedWorkspace.id);
assert.notEqual(savedWorkspace.id, workspace.id);
assert.equal(savedWorkspace.configPath, workspaceConfigPath);
assert.equal(service.deleteWorkspaceCall, workspace);
const ws = JSON.parse(fs.readFileSync(savedWorkspace.configPath).toString()) as IStoredWorkspace;
assert.equal(ws.folders.length, 3);
assert.equal(ws.folders[0].path, process.cwd()); // absolute
assert.equal(ws.folders[1].path, '.'); // relative
assert.equal(ws.folders[2].path, path.relative(path.dirname(workspaceConfigPath), path.join(os.tmpdir(), 'somefolder'))); // relative
assert.equal(savedWorkspace, savedEvent.workspace);
assert.equal(workspace.configPath, savedEvent.oldConfigPath);
assert.deepEqual(deletedEvent, workspace);
listener.dispose();
listener2.dispose();
extfs.delSync(workspaceConfigPath);
done();
});
});
});
test('saveWorkspace (saved workspace)', done => {
return service.createWorkspace([process.cwd(), os.tmpdir(), path.join(os.tmpdir(), 'somefolder')]).then(workspace => {
const workspaceConfigPath = path.join(os.tmpdir(), `myworkspace.${Date.now()}.${WORKSPACE_EXTENSION}`);
const newWorkspaceConfigPath = path.join(os.tmpdir(), `mySavedWorkspace.${Date.now()}.${WORKSPACE_EXTENSION}`);
return service.saveWorkspace(workspace, workspaceConfigPath).then(savedWorkspace => {
return service.saveWorkspace(savedWorkspace, newWorkspaceConfigPath).then(newSavedWorkspace => {
assert.ok(newSavedWorkspace.id);
assert.notEqual(newSavedWorkspace.id, workspace.id);
assert.equal(newSavedWorkspace.configPath, newWorkspaceConfigPath);
const ws = JSON.parse(fs.readFileSync(newSavedWorkspace.configPath).toString()) as IStoredWorkspace;
assert.equal(ws.folders.length, 3);
assert.equal(ws.folders[0].path, process.cwd()); // absolute path because outside of tmpdir
assert.equal(ws.folders[1].path, '.'); // relative path because inside of tmpdir
assert.equal(ws.folders[2].path, path.relative(path.dirname(workspaceConfigPath), path.join(os.tmpdir(), 'somefolder'))); // relative
extfs.delSync(workspaceConfigPath);
extfs.delSync(newWorkspaceConfigPath);
done();
});
});
});
});
test('deleteUntitledWorkspaceSync (untitled)', done => {
return service.createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => {
assert.ok(fs.existsSync(workspace.configPath));
service.deleteUntitledWorkspaceSync(workspace);
assert.ok(!fs.existsSync(workspace.configPath));
done();
});
});
test('deleteUntitledWorkspaceSync (saved)', done => {
return service.createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => {
const workspaceConfigPath = path.join(os.tmpdir(), `myworkspace.${Date.now()}.${WORKSPACE_EXTENSION}`);
return service.saveWorkspace(workspace, workspaceConfigPath).then(savedWorkspace => {
assert.ok(fs.existsSync(savedWorkspace.configPath));
service.deleteUntitledWorkspaceSync(savedWorkspace);
assert.ok(fs.existsSync(savedWorkspace.configPath));
done();
});
});
});
test('getUntitledWorkspaceSync', done => {
let untitled = service.getUntitledWorkspacesSync();
assert.equal(0, untitled.length);
return service.createWorkspace([process.cwd(), os.tmpdir()]).then(untitledOne => {
untitled = service.getUntitledWorkspacesSync();
assert.equal(1, untitled.length);
assert.equal(untitledOne.id, untitled[0].id);
return service.createWorkspace([process.cwd(), os.tmpdir()]).then(untitledTwo => {
untitled = service.getUntitledWorkspacesSync();
assert.equal(2, untitled.length);
service.deleteUntitledWorkspaceSync(untitledOne);
service.deleteUntitledWorkspaceSync(untitledTwo);
untitled = service.getUntitledWorkspacesSync();
assert.equal(0, untitled.length);
done();
});
});
});
});