Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ interface Error {
}

export function getAllOutputsText(notebook: NotebookTextModel, viewCell: ICellViewModel): string {
let outputContent = '';
const outputText: string[] = [];
for (let i = 0; i < viewCell.outputsViewModels.length; i++) {
const outputViewModel = viewCell.outputsViewModels[i];
const outputTextModel = viewCell.model.outputs[i];
Expand All @@ -36,16 +36,25 @@ export function getAllOutputsText(notebook: NotebookTextModel, viewCell: ICellVi
if (isTextStreamMime(mimeType)) {
const { text: stream, count } = getOutputStreamText(outputViewModel);
text = stream;
i = i + count;
if (count > 1) {
i += count - 1;
}
} else {
text = getOutputText(mimeType, buffer);
}

const index = viewCell.outputsViewModels.length > 1
? `Cell output ${i + 1} of ${viewCell.outputsViewModels.length}\n`
: '';
outputContent = outputContent.concat(`${index}${text}\n`);
outputText.push(text);
}

let outputContent: string;
if (outputText.length > 1) {
outputContent = outputText.map((output, i) => {
return `Cell output ${i + 1} of ${outputText.length}\n${output}`;
}).join('\n');
} else {
outputContent = outputText[0] ?? '';
}

return outputContent.trim();
}

Expand Down
72 changes: 70 additions & 2 deletions src/vs/workbench/contrib/notebook/test/browser/cellOutput.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { mock } from '../../../../../base/test/common/mock.js';
import { IMenu, IMenuService } from '../../../../../platform/actions/common/actions.js';
import { Event } from '../../../../../base/common/event.js';
import { TestInstantiationService } from '../../../../../platform/instantiation/test/common/instantiationServiceMock.js';
import { getAllOutputsText } from '../../browser/viewModel/cellOutputTextHelper.js';

suite('CellOutput', () => {
const store = ensureNoDisposablesAreLeakedInTestSuite();
Expand All @@ -28,7 +29,7 @@ suite('CellOutput', () => {
outputMenus = [];
instantiationService = setupInstantiationService(store);
instantiationService.stub(INotebookService, new class extends mock<INotebookService>() {
override getOutputMimeTypeInfo() {
override getOutputMimeTypeInfo(_textModel: any, _kernelProvides: readonly string[] | undefined, output: IOutputDto) {
return [{
rendererId: 'plainTextRendererId',
mimeType: 'text/plain',
Expand All @@ -37,7 +38,20 @@ suite('CellOutput', () => {
rendererId: 'htmlRendererId',
mimeType: 'text/html',
isTrusted: true
}];
}, {
rendererId: 'errorRendererId',
mimeType: 'application/vnd.code.notebook.error',
isTrusted: true
}, {
rendererId: 'stderrRendererId',
mimeType: 'application/vnd.code.notebook.stderr',
isTrusted: true
}, {
rendererId: 'stdoutRendererId',
mimeType: 'application/vnd.code.notebook.stdout',
isTrusted: true
}]
.filter(info => output.outputs.some(output => output.mime === info.mimeType));
}
override getRendererInfo(): INotebookRendererInfo {
return {
Expand Down Expand Up @@ -116,6 +130,60 @@ suite('CellOutput', () => {
);
});

test('get all adjacent stream outputs', async () => {
const stdout = { data: VSBuffer.fromString('stdout'), mime: 'application/vnd.code.notebook.stdout' };
const stderr = { data: VSBuffer.fromString('stderr'), mime: 'application/vnd.code.notebook.stderr' };
const output1: IOutputDto = { outputId: 'abc', outputs: [stdout] };
const output2: IOutputDto = { outputId: 'abc', outputs: [stderr] };

await withTestNotebook(
[
['print(output content)', 'python', CellKind.Code, [output1, output2], {}],
],
(_editor, viewModel) => {
const cell = viewModel.viewCells[0];
const notebook = viewModel.notebookDocument;
const result = getAllOutputsText(notebook, cell);

assert.strictEqual(result, 'stdoutstderr');
},
instantiationService
);
});

test('get all mixed outputs of cell', async () => {
const stdout = { data: VSBuffer.fromString('stdout'), mime: 'application/vnd.code.notebook.stdout' };
const stderr = { data: VSBuffer.fromString('stderr'), mime: 'application/vnd.code.notebook.stderr' };
const plainText = { data: VSBuffer.fromString('output content'), mime: 'text/plain' };
const error = { data: VSBuffer.fromString(`{"name":"Error Name","message":"error message","stack":"error stack"}`), mime: 'application/vnd.code.notebook.error' };
const output1: IOutputDto = { outputId: 'abc', outputs: [stdout] };
const output2: IOutputDto = { outputId: 'abc', outputs: [stderr] };
const output3: IOutputDto = { outputId: 'abc', outputs: [plainText] };
const output4: IOutputDto = { outputId: 'abc', outputs: [error] };

await withTestNotebook(
[
['print(output content)', 'python', CellKind.Code, [output1, output2, output3, output4], {}],
],
(_editor, viewModel) => {
const cell = viewModel.viewCells[0];
const notebook = viewModel.notebookDocument;
const result = getAllOutputsText(notebook, cell);

assert.strictEqual(result,
'Cell output 1 of 3\n' +
'stdoutstderr\n' +
'Cell output 2 of 3\n' +
'output content\n' +
'Cell output 3 of 3\n' +
'error stack'
);
},
instantiationService
);

});


});

Expand Down