parent
e73053d712
commit
190a89dd1b
40
extensions/ipynb/src/test/index.ts
Normal file
40
extensions/ipynb/src/test/index.ts
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
const path = require('path');
|
||||
const testRunner = require('../../../../test/integration/electron/testrunner');
|
||||
|
||||
const options: any = {
|
||||
ui: 'tdd',
|
||||
color: true,
|
||||
timeout: 60000
|
||||
};
|
||||
|
||||
// These integration tests is being run in multiple environments (electron, web, remote)
|
||||
// so we need to set the suite name based on the environment as the suite name is used
|
||||
// for the test results file name
|
||||
let suite = '';
|
||||
if (process.env.VSCODE_BROWSER) {
|
||||
suite = `${process.env.VSCODE_BROWSER} Browser Integration .ipynb Tests`;
|
||||
} else if (process.env.REMOTE_VSCODE) {
|
||||
suite = 'Remote Integration .ipynb Tests';
|
||||
} else {
|
||||
suite = 'Integration .ipynb Tests';
|
||||
}
|
||||
|
||||
if (process.env.BUILD_ARTIFACTSTAGINGDIRECTORY) {
|
||||
options.reporter = 'mocha-multi-reporters';
|
||||
options.reporterOptions = {
|
||||
reporterEnabled: 'spec, mocha-junit-reporter',
|
||||
mochaJunitReporterReporterOptions: {
|
||||
testsuitesTitle: `${suite} ${process.platform}`,
|
||||
mochaFile: path.join(process.env.BUILD_ARTIFACTSTAGINGDIRECTORY, `test-results/${process.platform}-${process.arch}-${suite.toLowerCase().replace(/[^\w]/g, '-')}-results.xml`)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
testRunner.configure(options);
|
||||
|
||||
export = testRunner;
|
394
extensions/ipynb/src/test/serializers.test.ts
Normal file
394
extensions/ipynb/src/test/serializers.test.ts
Normal file
|
@ -0,0 +1,394 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { nbformat } from '@jupyterlab/coreutils';
|
||||
import * as assert from 'assert';
|
||||
import * as vscode from 'vscode';
|
||||
import { jupyterNotebookModelToNotebookData } from '../deserializers';
|
||||
|
||||
function deepStripProperties(obj: any, props: string[]) {
|
||||
for (let prop in obj) {
|
||||
if (obj[prop]) {
|
||||
delete obj[prop];
|
||||
} else if (typeof obj[prop] === 'object') {
|
||||
deepStripProperties(obj[prop], props);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suite('ipynb serializer', () => {
|
||||
const base64EncodedImage =
|
||||
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mOUlZL6DwAB/wFSU1jVmgAAAABJRU5ErkJggg==';
|
||||
test('Deserialize', async () => {
|
||||
const cells: nbformat.ICell[] = [
|
||||
{
|
||||
cell_type: 'code',
|
||||
execution_count: 10,
|
||||
outputs: [],
|
||||
source: 'print(1)',
|
||||
metadata: {}
|
||||
},
|
||||
{
|
||||
cell_type: 'markdown',
|
||||
source: '# HEAD',
|
||||
metadata: {}
|
||||
}
|
||||
];
|
||||
const notebook = jupyterNotebookModelToNotebookData({ cells }, 'python');
|
||||
assert.ok(notebook);
|
||||
|
||||
const expectedCodeCell = new vscode.NotebookCellData(vscode.NotebookCellKind.Code, 'print(1)', 'python');
|
||||
expectedCodeCell.outputs = [];
|
||||
expectedCodeCell.metadata = { custom: { metadata: {} } };
|
||||
expectedCodeCell.executionSummary = { executionOrder: 10 };
|
||||
|
||||
const expectedMarkdownCell = new vscode.NotebookCellData(vscode.NotebookCellKind.Markup, '# HEAD', 'markdown');
|
||||
expectedMarkdownCell.outputs = [];
|
||||
expectedMarkdownCell.metadata = {
|
||||
custom: { metadata: {} }
|
||||
};
|
||||
|
||||
assert.deepStrictEqual(notebook.cells, [expectedCodeCell, expectedMarkdownCell]);
|
||||
});
|
||||
|
||||
suite('Outputs', () => {
|
||||
function validateCellOutputTranslation(
|
||||
outputs: nbformat.IOutput[],
|
||||
expectedOutputs: vscode.NotebookCellOutput[],
|
||||
propertiesToExcludeFromComparison: string[] = []
|
||||
) {
|
||||
const cells: nbformat.ICell[] = [
|
||||
{
|
||||
cell_type: 'code',
|
||||
execution_count: 10,
|
||||
outputs,
|
||||
source: 'print(1)',
|
||||
metadata: {}
|
||||
}
|
||||
];
|
||||
const notebook = jupyterNotebookModelToNotebookData({ cells }, 'python');
|
||||
|
||||
// OutputItems contain an `id` property generated by VSC.
|
||||
// Exclude that property when comparing.
|
||||
const propertiesToExclude = propertiesToExcludeFromComparison.concat(['id']);
|
||||
const actualOuts = notebook.cells[0].outputs;
|
||||
deepStripProperties(actualOuts, propertiesToExclude);
|
||||
deepStripProperties(expectedOutputs, propertiesToExclude);
|
||||
assert.deepStrictEqual(actualOuts, expectedOutputs);
|
||||
}
|
||||
|
||||
test('Empty output', () => {
|
||||
validateCellOutputTranslation([], []);
|
||||
});
|
||||
|
||||
test('Stream output', () => {
|
||||
validateCellOutputTranslation(
|
||||
[
|
||||
{
|
||||
output_type: 'stream',
|
||||
name: 'stderr',
|
||||
text: 'Error'
|
||||
},
|
||||
{
|
||||
output_type: 'stream',
|
||||
name: 'stdout',
|
||||
text: 'NoError'
|
||||
}
|
||||
],
|
||||
[
|
||||
new vscode.NotebookCellOutput([vscode.NotebookCellOutputItem.stderr('Error')], {
|
||||
outputType: 'stream'
|
||||
}),
|
||||
new vscode.NotebookCellOutput([vscode.NotebookCellOutputItem.stdout('NoError')], {
|
||||
outputType: 'stream'
|
||||
})
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
test('Streamed text with Ansi characters', async () => {
|
||||
validateCellOutputTranslation(
|
||||
[
|
||||
{
|
||||
name: 'stderr',
|
||||
text: '\u001b[K\u001b[33m✅ \u001b[0m Loading\n',
|
||||
output_type: 'stream'
|
||||
}
|
||||
],
|
||||
[
|
||||
new vscode.NotebookCellOutput(
|
||||
[vscode.NotebookCellOutputItem.stderr('\u001b[K\u001b[33m✅ \u001b[0m Loading\n')],
|
||||
{
|
||||
outputType: 'stream'
|
||||
}
|
||||
)
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
test('Streamed text with angle bracket characters', async () => {
|
||||
validateCellOutputTranslation(
|
||||
[
|
||||
{
|
||||
name: 'stderr',
|
||||
text: '1 is < 2',
|
||||
output_type: 'stream'
|
||||
}
|
||||
],
|
||||
[
|
||||
new vscode.NotebookCellOutput([vscode.NotebookCellOutputItem.stderr('1 is < 2')], {
|
||||
outputType: 'stream'
|
||||
})
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
test('Streamed text with angle bracket characters and ansi chars', async () => {
|
||||
validateCellOutputTranslation(
|
||||
[
|
||||
{
|
||||
name: 'stderr',
|
||||
text: '1 is < 2\u001b[K\u001b[33m✅ \u001b[0m Loading\n',
|
||||
output_type: 'stream'
|
||||
}
|
||||
],
|
||||
[
|
||||
new vscode.NotebookCellOutput(
|
||||
[vscode.NotebookCellOutputItem.stderr('1 is < 2\u001b[K\u001b[33m✅ \u001b[0m Loading\n')],
|
||||
{
|
||||
outputType: 'stream'
|
||||
}
|
||||
)
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
test('Error', async () => {
|
||||
validateCellOutputTranslation(
|
||||
[
|
||||
{
|
||||
ename: 'Error Name',
|
||||
evalue: 'Error Value',
|
||||
traceback: ['stack1', 'stack2', 'stack3'],
|
||||
output_type: 'error'
|
||||
}
|
||||
],
|
||||
[
|
||||
new vscode.NotebookCellOutput(
|
||||
[
|
||||
vscode.NotebookCellOutputItem.error({
|
||||
name: 'Error Name',
|
||||
message: 'Error Value',
|
||||
stack: ['stack1', 'stack2', 'stack3'].join('\n')
|
||||
})
|
||||
],
|
||||
{
|
||||
outputType: 'error',
|
||||
originalError: {
|
||||
ename: 'Error Name',
|
||||
evalue: 'Error Value',
|
||||
traceback: ['stack1', 'stack2', 'stack3'],
|
||||
output_type: 'error'
|
||||
}
|
||||
}
|
||||
)
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
['display_data', 'execute_result'].forEach(output_type => {
|
||||
suite(`Rich output for output_type = ${output_type}`, () => {
|
||||
// Properties to exclude when comparing.
|
||||
let propertiesToExcludeFromComparison: string[] = [];
|
||||
setup(() => {
|
||||
if (output_type === 'display_data') {
|
||||
// With display_data the execution_count property will never exist in the output.
|
||||
// We can ignore that (as it will never exist).
|
||||
// But we leave it in the case of `output_type === 'execute_result'`
|
||||
propertiesToExcludeFromComparison = ['execution_count', 'executionCount'];
|
||||
}
|
||||
});
|
||||
|
||||
test('Text mimeType output', async () => {
|
||||
validateCellOutputTranslation(
|
||||
[
|
||||
{
|
||||
data: {
|
||||
'text/plain': 'Hello World!'
|
||||
},
|
||||
output_type,
|
||||
metadata: {},
|
||||
execution_count: 1
|
||||
}
|
||||
],
|
||||
[
|
||||
new vscode.NotebookCellOutput(
|
||||
[new vscode.NotebookCellOutputItem(Buffer.from('Hello World!', 'utf8'), 'text/plain')],
|
||||
{
|
||||
outputType: output_type,
|
||||
metadata: {}, // display_data & execute_result always have metadata.
|
||||
executionCount: 1
|
||||
}
|
||||
)
|
||||
],
|
||||
propertiesToExcludeFromComparison
|
||||
);
|
||||
});
|
||||
|
||||
test('png,jpeg images', async () => {
|
||||
validateCellOutputTranslation(
|
||||
[
|
||||
{
|
||||
execution_count: 1,
|
||||
data: {
|
||||
'image/png': base64EncodedImage,
|
||||
'image/jpeg': base64EncodedImage
|
||||
},
|
||||
metadata: {},
|
||||
output_type
|
||||
}
|
||||
],
|
||||
[
|
||||
new vscode.NotebookCellOutput(
|
||||
[
|
||||
new vscode.NotebookCellOutputItem(Buffer.from(base64EncodedImage, 'base64'), 'image/png'),
|
||||
new vscode.NotebookCellOutputItem(Buffer.from(base64EncodedImage, 'base64'), 'image/jpeg')
|
||||
],
|
||||
{
|
||||
executionCount: 1,
|
||||
outputType: output_type,
|
||||
metadata: {} // display_data & execute_result always have metadata.
|
||||
}
|
||||
)
|
||||
],
|
||||
propertiesToExcludeFromComparison
|
||||
);
|
||||
});
|
||||
|
||||
test('png image with a light background', async () => {
|
||||
validateCellOutputTranslation(
|
||||
[
|
||||
{
|
||||
execution_count: 1,
|
||||
data: {
|
||||
'image/png': base64EncodedImage
|
||||
},
|
||||
metadata: {
|
||||
needs_background: 'light'
|
||||
},
|
||||
output_type
|
||||
}
|
||||
],
|
||||
[
|
||||
new vscode.NotebookCellOutput(
|
||||
[new vscode.NotebookCellOutputItem(Buffer.from(base64EncodedImage, 'base64'), 'image/png')],
|
||||
{
|
||||
executionCount: 1,
|
||||
metadata: {
|
||||
needs_background: 'light'
|
||||
},
|
||||
outputType: output_type
|
||||
}
|
||||
)
|
||||
],
|
||||
propertiesToExcludeFromComparison
|
||||
);
|
||||
});
|
||||
|
||||
test('png image with a dark background', async () => {
|
||||
validateCellOutputTranslation(
|
||||
[
|
||||
{
|
||||
execution_count: 1,
|
||||
data: {
|
||||
'image/png': base64EncodedImage
|
||||
},
|
||||
metadata: {
|
||||
needs_background: 'dark'
|
||||
},
|
||||
output_type
|
||||
}
|
||||
],
|
||||
[
|
||||
new vscode.NotebookCellOutput(
|
||||
[new vscode.NotebookCellOutputItem(Buffer.from(base64EncodedImage, 'base64'), 'image/png')],
|
||||
{
|
||||
executionCount: 1,
|
||||
metadata: {
|
||||
needs_background: 'dark'
|
||||
},
|
||||
outputType: output_type
|
||||
}
|
||||
)
|
||||
],
|
||||
propertiesToExcludeFromComparison
|
||||
);
|
||||
});
|
||||
|
||||
test('png image with custom dimensions', async () => {
|
||||
validateCellOutputTranslation(
|
||||
[
|
||||
{
|
||||
execution_count: 1,
|
||||
data: {
|
||||
'image/png': base64EncodedImage
|
||||
},
|
||||
metadata: {
|
||||
'image/png': { height: '111px', width: '999px' }
|
||||
},
|
||||
output_type
|
||||
}
|
||||
],
|
||||
[
|
||||
new vscode.NotebookCellOutput(
|
||||
[new vscode.NotebookCellOutputItem(Buffer.from(base64EncodedImage, 'base64'), 'image/png')],
|
||||
{
|
||||
executionCount: 1,
|
||||
metadata: {
|
||||
'image/png': { height: '111px', width: '999px' }
|
||||
},
|
||||
outputType: output_type
|
||||
}
|
||||
)
|
||||
],
|
||||
propertiesToExcludeFromComparison
|
||||
);
|
||||
});
|
||||
|
||||
test('png allowed to scroll', async () => {
|
||||
validateCellOutputTranslation(
|
||||
[
|
||||
{
|
||||
execution_count: 1,
|
||||
data: {
|
||||
'image/png': base64EncodedImage
|
||||
},
|
||||
metadata: {
|
||||
unconfined: true,
|
||||
'image/png': { width: '999px' }
|
||||
},
|
||||
output_type
|
||||
}
|
||||
],
|
||||
[
|
||||
new vscode.NotebookCellOutput(
|
||||
[new vscode.NotebookCellOutputItem(Buffer.from(base64EncodedImage, 'base64'), 'image/png')],
|
||||
{
|
||||
executionCount: 1,
|
||||
metadata: {
|
||||
unconfined: true,
|
||||
'image/png': { width: '999px' }
|
||||
},
|
||||
outputType: output_type
|
||||
}
|
||||
)
|
||||
],
|
||||
propertiesToExcludeFromComparison
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -89,6 +89,9 @@ after_suite
|
|||
"$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_EXTRA_ARGS $(mktemp -d 2>/dev/null) --enable-proposed-api=vscode.git --extensionDevelopmentPath=$ROOT/extensions/git --extensionTestsPath=$ROOT/extensions/git/out/test $ALL_PLATFORMS_API_TESTS_EXTRA_ARGS
|
||||
after_suite
|
||||
|
||||
"$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_EXTRA_ARGS $(mktemp -d 2>/dev/null) --extensionDevelopmentPath=$ROOT/extensions/ipynb --extensionTestsPath=$ROOT/extensions/ipynb/out/test $ALL_PLATFORMS_API_TESTS_EXTRA_ARGS
|
||||
after_suite
|
||||
|
||||
|
||||
# Tests standalone (CommonJS)
|
||||
|
||||
|
|
Loading…
Reference in a new issue