forked from DonJayamanne/pythonVSCode
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add command to create a python terminal (#625)
Fixes #622
- Loading branch information
1 parent
2876e19
commit 5a1dc67
Showing
9 changed files
with
224 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
import { Disposable, Uri } from 'vscode'; | ||
import { ICommandManager, IDocumentManager, IWorkspaceService } from '../common/application/types'; | ||
import { Commands } from '../common/constants'; | ||
import { ITerminalServiceFactory } from '../common/terminal/types'; | ||
import { IServiceContainer } from '../ioc/types'; | ||
|
||
export class TerminalProvider implements Disposable { | ||
private disposables: Disposable[] = []; | ||
constructor(private serviceContainer: IServiceContainer) { | ||
this.registerCommands(); | ||
} | ||
public dispose() { | ||
this.disposables.forEach(disposable => disposable.dispose()); | ||
} | ||
private registerCommands() { | ||
const commandManager = this.serviceContainer.get<ICommandManager>(ICommandManager); | ||
const disposable = commandManager.registerCommand(Commands.Create_Terminal, this.onCreateTerminal, this); | ||
|
||
this.disposables.push(disposable); | ||
} | ||
private async onCreateTerminal() { | ||
const terminalService = this.serviceContainer.get<ITerminalServiceFactory>(ITerminalServiceFactory); | ||
const activeResource = this.getActiveResource(); | ||
await terminalService.createTerminalService(activeResource, 'Python').show(); | ||
} | ||
private getActiveResource(): Uri | undefined { | ||
const documentManager = this.serviceContainer.get<IDocumentManager>(IDocumentManager); | ||
if (documentManager.activeTextEditor && !documentManager.activeTextEditor.document.isUntitled) { | ||
return documentManager.activeTextEditor.document.uri; | ||
} | ||
const workspace = this.serviceContainer.get<IWorkspaceService>(IWorkspaceService); | ||
return Array.isArray(workspace.workspaceFolders) && workspace.workspaceFolders.length > 0 ? workspace.workspaceFolders[0].uri : undefined; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
import { expect } from 'chai'; | ||
import * as TypeMoq from 'typemoq'; | ||
import { Disposable, TextDocument, TextEditor, Uri, WorkspaceFolder } from 'vscode'; | ||
import { ICommandManager, IDocumentManager, IWorkspaceService } from '../../client/common/application/types'; | ||
import { Commands } from '../../client/common/constants'; | ||
import { TerminalService } from '../../client/common/terminal/service'; | ||
import { ITerminalServiceFactory } from '../../client/common/terminal/types'; | ||
import { IServiceContainer } from '../../client/ioc/types'; | ||
import { TerminalProvider } from '../../client/providers/terminalProvider'; | ||
|
||
// tslint:disable-next-line:max-func-body-length | ||
suite('Terminal Provider', () => { | ||
let serviceContainer: TypeMoq.IMock<IServiceContainer>; | ||
let commandManager: TypeMoq.IMock<ICommandManager>; | ||
let workspace: TypeMoq.IMock<IWorkspaceService>; | ||
let documentManager: TypeMoq.IMock<IDocumentManager>; | ||
let terminalProvider: TerminalProvider; | ||
setup(() => { | ||
serviceContainer = TypeMoq.Mock.ofType<IServiceContainer>(); | ||
commandManager = TypeMoq.Mock.ofType<ICommandManager>(); | ||
workspace = TypeMoq.Mock.ofType<IWorkspaceService>(); | ||
documentManager = TypeMoq.Mock.ofType<IDocumentManager>(); | ||
serviceContainer.setup(c => c.get(ICommandManager)).returns(() => commandManager.object); | ||
serviceContainer.setup(c => c.get(IWorkspaceService)).returns(() => workspace.object); | ||
serviceContainer.setup(c => c.get(IDocumentManager)).returns(() => documentManager.object); | ||
}); | ||
teardown(() => { | ||
try { | ||
terminalProvider.dispose(); | ||
// tslint:disable-next-line:no-empty | ||
} catch { } | ||
}); | ||
|
||
test('Ensure command is registered', () => { | ||
terminalProvider = new TerminalProvider(serviceContainer.object); | ||
commandManager.verify(c => c.registerCommand(TypeMoq.It.isValue(Commands.Create_Terminal), TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once()); | ||
}); | ||
|
||
test('Ensure command handler is disposed', () => { | ||
const disposable = TypeMoq.Mock.ofType<Disposable>(); | ||
commandManager.setup(c => c.registerCommand(TypeMoq.It.isValue(Commands.Create_Terminal), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => disposable.object); | ||
|
||
terminalProvider = new TerminalProvider(serviceContainer.object); | ||
terminalProvider.dispose(); | ||
|
||
disposable.verify(d => d.dispose(), TypeMoq.Times.once()); | ||
}); | ||
|
||
test('Ensure terminal is created and displayed when command is invoked', () => { | ||
const disposable = TypeMoq.Mock.ofType<Disposable>(); | ||
let commandHandler: undefined | (() => void); | ||
commandManager.setup(c => c.registerCommand(TypeMoq.It.isValue(Commands.Create_Terminal), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns((_cmd, callback) => { | ||
commandHandler = callback; | ||
return disposable.object; | ||
}); | ||
documentManager.setup(d => d.activeTextEditor).returns(() => undefined); | ||
workspace.setup(w => w.workspaceFolders).returns(() => undefined); | ||
|
||
terminalProvider = new TerminalProvider(serviceContainer.object); | ||
expect(commandHandler).not.to.be.equal(undefined, 'Handler not set'); | ||
|
||
const terminalServiceFactory = TypeMoq.Mock.ofType<ITerminalServiceFactory>(); | ||
serviceContainer.setup(c => c.get(TypeMoq.It.isValue(ITerminalServiceFactory))).returns(() => terminalServiceFactory.object); | ||
const terminalService = TypeMoq.Mock.ofType<TerminalService>(); | ||
terminalServiceFactory.setup(t => t.createTerminalService(TypeMoq.It.isValue(undefined), TypeMoq.It.isValue('Python'))).returns(() => terminalService.object); | ||
|
||
commandHandler!.call(terminalProvider); | ||
terminalService.verify(t => t.show(), TypeMoq.Times.once()); | ||
}); | ||
|
||
test('Ensure terminal creation does not use uri of the active documents which is untitled', () => { | ||
const disposable = TypeMoq.Mock.ofType<Disposable>(); | ||
let commandHandler: undefined | (() => void); | ||
commandManager.setup(c => c.registerCommand(TypeMoq.It.isValue(Commands.Create_Terminal), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns((_cmd, callback) => { | ||
commandHandler = callback; | ||
return disposable.object; | ||
}); | ||
const editor = TypeMoq.Mock.ofType<TextEditor>(); | ||
documentManager.setup(d => d.activeTextEditor).returns(() => editor.object); | ||
const document = TypeMoq.Mock.ofType<TextDocument>(); | ||
document.setup(d => d.isUntitled).returns(() => true); | ||
editor.setup(e => e.document).returns(() => document.object); | ||
workspace.setup(w => w.workspaceFolders).returns(() => undefined); | ||
|
||
terminalProvider = new TerminalProvider(serviceContainer.object); | ||
expect(commandHandler).not.to.be.equal(undefined, 'Handler not set'); | ||
|
||
const terminalServiceFactory = TypeMoq.Mock.ofType<ITerminalServiceFactory>(); | ||
serviceContainer.setup(c => c.get(TypeMoq.It.isValue(ITerminalServiceFactory))).returns(() => terminalServiceFactory.object); | ||
const terminalService = TypeMoq.Mock.ofType<TerminalService>(); | ||
terminalServiceFactory.setup(t => t.createTerminalService(TypeMoq.It.isValue(undefined), TypeMoq.It.isValue('Python'))).returns(() => terminalService.object); | ||
|
||
commandHandler!.call(terminalProvider); | ||
terminalService.verify(t => t.show(), TypeMoq.Times.once()); | ||
}); | ||
|
||
test('Ensure terminal creation uses uri of active document', () => { | ||
const disposable = TypeMoq.Mock.ofType<Disposable>(); | ||
let commandHandler: undefined | (() => void); | ||
commandManager.setup(c => c.registerCommand(TypeMoq.It.isValue(Commands.Create_Terminal), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns((_cmd, callback) => { | ||
commandHandler = callback; | ||
return disposable.object; | ||
}); | ||
const editor = TypeMoq.Mock.ofType<TextEditor>(); | ||
documentManager.setup(d => d.activeTextEditor).returns(() => editor.object); | ||
const document = TypeMoq.Mock.ofType<TextDocument>(); | ||
const documentUri = Uri.file('a'); | ||
document.setup(d => d.isUntitled).returns(() => false); | ||
document.setup(d => d.uri).returns(() => documentUri); | ||
editor.setup(e => e.document).returns(() => document.object); | ||
workspace.setup(w => w.workspaceFolders).returns(() => undefined); | ||
|
||
terminalProvider = new TerminalProvider(serviceContainer.object); | ||
expect(commandHandler).not.to.be.equal(undefined, 'Handler not set'); | ||
|
||
const terminalServiceFactory = TypeMoq.Mock.ofType<ITerminalServiceFactory>(); | ||
serviceContainer.setup(c => c.get(TypeMoq.It.isValue(ITerminalServiceFactory))).returns(() => terminalServiceFactory.object); | ||
const terminalService = TypeMoq.Mock.ofType<TerminalService>(); | ||
terminalServiceFactory.setup(t => t.createTerminalService(TypeMoq.It.isValue(documentUri), TypeMoq.It.isValue('Python'))).returns(() => terminalService.object); | ||
|
||
commandHandler!.call(terminalProvider); | ||
terminalService.verify(t => t.show(), TypeMoq.Times.once()); | ||
}); | ||
|
||
test('Ensure terminal creation uses uri of active workspace', () => { | ||
const disposable = TypeMoq.Mock.ofType<Disposable>(); | ||
let commandHandler: undefined | (() => void); | ||
commandManager.setup(c => c.registerCommand(TypeMoq.It.isValue(Commands.Create_Terminal), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns((_cmd, callback) => { | ||
commandHandler = callback; | ||
return disposable.object; | ||
}); | ||
documentManager.setup(d => d.activeTextEditor).returns(() => undefined); | ||
const workspaceUri = Uri.file('a'); | ||
const workspaceFolder = TypeMoq.Mock.ofType<WorkspaceFolder>(); | ||
workspaceFolder.setup(w => w.uri).returns(() => workspaceUri); | ||
workspace.setup(w => w.workspaceFolders).returns(() => [workspaceFolder.object]); | ||
|
||
terminalProvider = new TerminalProvider(serviceContainer.object); | ||
expect(commandHandler).not.to.be.equal(undefined, 'Handler not set'); | ||
|
||
const terminalServiceFactory = TypeMoq.Mock.ofType<ITerminalServiceFactory>(); | ||
serviceContainer.setup(c => c.get(TypeMoq.It.isValue(ITerminalServiceFactory))).returns(() => terminalServiceFactory.object); | ||
const terminalService = TypeMoq.Mock.ofType<TerminalService>(); | ||
terminalServiceFactory.setup(t => t.createTerminalService(TypeMoq.It.isValue(workspaceUri), TypeMoq.It.isValue('Python'))).returns(() => terminalService.object); | ||
|
||
commandHandler!.call(terminalProvider); | ||
terminalService.verify(t => t.show(), TypeMoq.Times.once()); | ||
}); | ||
}); |