Skip to content

Commit 684a949

Browse files
committed
adding tests
1 parent d4869cf commit 684a949

2 files changed

Lines changed: 76 additions & 0 deletions

File tree

src/test/repl/nativeRepl.test.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
/* eslint-disable @typescript-eslint/no-explicit-any */
66
import * as TypeMoq from 'typemoq';
77
import * as sinon from 'sinon';
8+
import { reset, when } from 'ts-mockito';
9+
import * as vscode from 'vscode';
810
import { Disposable, EventEmitter, NotebookDocument, Uri } from 'vscode';
911
import { expect } from 'chai';
1012

@@ -16,6 +18,7 @@ import * as PythonServer from '../../client/repl/pythonServer';
1618
import * as vscodeWorkspaceApis from '../../client/common/vscodeApis/workspaceApis';
1719
import * as replController from '../../client/repl/replController';
1820
import { executeCommand } from '../../client/common/vscodeApis/commandApis';
21+
import { mockedVSCodeNamespaces } from '../vscode-mock';
1922

2023
suite('REPL - Native REPL', () => {
2124
let interpreterService: TypeMoq.IMock<IInterpreterService>;
@@ -114,6 +117,66 @@ suite('REPL - Native REPL', () => {
114117
expect(createReplControllerStub.calledOnce).to.be.true;
115118
});
116119

120+
test('createReplController should publish stdout notebook output for REPL execution', async () => {
121+
const mockServer = {
122+
interrupt: sinon.stub(),
123+
execute: sinon.stub().resolves({ status: true, output: 'hello\nworld' }),
124+
dispose: sinon.stub(),
125+
} as any;
126+
const createPythonServerStub = sinon.stub(PythonServer, 'createPythonServer').returns(mockServer as any);
127+
128+
const replaceOutputStub = sinon.stub();
129+
const execStub = {
130+
start: sinon.stub(),
131+
replaceOutput: replaceOutputStub,
132+
end: sinon.stub(),
133+
} as any;
134+
135+
const createNotebookCellExecutionStub = sinon.stub().returns(execStub);
136+
const mockNotebookController = {
137+
id: 'mockController',
138+
dispose: sinon.stub(),
139+
updateNotebookAffinity: sinon.stub(),
140+
createNotebookCellExecution: createNotebookCellExecutionStub,
141+
supportedLanguages: [] as string[],
142+
description: '',
143+
interruptHandler: undefined,
144+
executeHandler: undefined,
145+
} as any as vscode.NotebookController;
146+
147+
when(mockedVSCodeNamespaces.notebooks!.createNotebookController('pythonREPL', 'jupyter-notebook', 'Python REPL')).thenReturn(
148+
mockNotebookController,
149+
);
150+
createReplControllerStub.restore();
151+
152+
const disposables: Disposable[] = [];
153+
try {
154+
const controller = replController.createReplController('python', disposables, '/cwd');
155+
156+
const mockTextDocument = { getText: sinon.stub().returns('print("hi")') } as any;
157+
const mockCell = { document: mockTextDocument } as any;
158+
await (controller.executeHandler as any)([mockCell]);
159+
160+
expect(createPythonServerStub.calledOnce).to.be.true;
161+
expect(mockServer.execute.calledOnceWithExactly('print("hi")')).to.be.true;
162+
expect(createNotebookCellExecutionStub.calledOnce).to.be.true;
163+
expect(replaceOutputStub.calledOnce).to.be.true;
164+
165+
const outputs = replaceOutputStub.firstCall.args[0] as vscode.NotebookCellOutput[];
166+
expect(outputs).to.have.lengthOf(1);
167+
const output = outputs[0];
168+
expect(output.items).to.have.lengthOf(1);
169+
expect(output.items[0].mime).to.equal('application/vnd.code.notebook.stdout');
170+
expect((output.items[0] as any).metadata).to.deep.equal({ scrollable: false });
171+
expect(output.metadata).to.deep.equal({ scrollable: false });
172+
const outputText = Buffer.from((output.items[0] as any).data).toString();
173+
expect(outputText).to.equal('hello\nworld');
174+
} finally {
175+
disposables.forEach((disposable) => disposable.dispose());
176+
reset(mockedVSCodeNamespaces.notebooks!);
177+
}
178+
});
179+
117180
test('watchNotebookClosed should clean up resources when notebook is closed', async () => {
118181
const notebookCloseEmitter = new EventEmitter<NotebookDocument>();
119182
sinon.stub(vscodeWorkspaceApis, 'onDidCloseNotebookDocument').callsFake((handler) => {

src/test/vscode-mock.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,19 @@ export function initialize() {
4242
generateMock('scm');
4343
generateMock('notebooks');
4444

45+
// Notebook output helpers used by REPL tests.
46+
(mockedVSCode as any).NotebookCellOutputItem = {
47+
stdout: (value: string) => ({ mime: 'application/vnd.code.notebook.stdout', data: Buffer.from(value) }),
48+
};
49+
(mockedVSCode as any).NotebookCellOutput = class {
50+
public items: any[];
51+
public metadata?: any;
52+
constructor(items: any[], metadata?: any) {
53+
this.items = items;
54+
this.metadata = metadata;
55+
}
56+
};
57+
4558
// Use mock clipboard fo testing purposes.
4659
const clipboard = new MockClipboard();
4760
when(mockedVSCodeNamespaces.env!.clipboard).thenReturn(clipboard);

0 commit comments

Comments
 (0)