Path: blob/main/src/vs/workbench/contrib/notebook/test/browser/notebookVariablesDataSource.test.ts
3296 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/4import assert from 'assert';5import { AsyncIterableObject, AsyncIterableSource } from '../../../../../base/common/async.js';6import { CancellationToken } from '../../../../../base/common/cancellation.js';7import { URI } from '../../../../../base/common/uri.js';8import { mock } from '../../../../../base/test/common/mock.js';9import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../../base/test/common/utils.js';10import { INotebookVariableElement, NotebookVariableDataSource } from '../../browser/contrib/notebookVariables/notebookVariablesDataSource.js';11import { NotebookTextModel } from '../../common/model/notebookTextModel.js';12import { INotebookKernel, INotebookKernelService, VariablesResult } from '../../common/notebookKernelService.js';131415suite('NotebookVariableDataSource', () => {16let dataSource: NotebookVariableDataSource;17const notebookModel = { uri: 'one.ipynb', languages: ['python'] } as unknown as NotebookTextModel;18let provideVariablesCalled: boolean;1920type VariablesResultWithAction = VariablesResult & { action?: () => void };21let results: VariablesResultWithAction[];2223const kernel = new class extends mock<INotebookKernel>() {24override hasVariableProvider = true;25override provideVariables(26notebookUri: URI,27parentId: number | undefined,28kind: 'named' | 'indexed',29start: number,30token: CancellationToken31): AsyncIterableObject<VariablesResult> {32provideVariablesCalled = true;33const source = new AsyncIterableSource<VariablesResult>();34for (let i = 0; i < results.length; i++) {35if (token.isCancellationRequested) {36break;37}38if (results[i].action) {39results[i].action!();40}41source.emitOne(results[i]);42}4344setTimeout(() => source.resolve(), 0);45return source.asyncIterable;46}47};4849const kernelService = new class extends mock<INotebookKernelService>() {50override getMatchingKernel(notebook: NotebookTextModel) {51return { selected: kernel, all: [], suggestions: [], hidden: [] };52}53};5455ensureNoDisposablesAreLeakedInTestSuite();5657setup(() => {58provideVariablesCalled = false;59dataSource = new NotebookVariableDataSource(kernelService);60results = [61{ id: 1, name: 'a', value: '1', hasNamedChildren: false, indexedChildrenCount: 0 },62];63});6465test('Root element should return children', async () => {66const variables = await dataSource.getChildren({ kind: 'root', notebook: notebookModel });6768assert.strictEqual(variables.length, 1);69});7071test('Get children of list element', async () => {72const parent = { kind: 'variable', notebook: notebookModel, id: '1', extHostId: 1, name: 'list', value: '[...]', hasNamedChildren: false, indexedChildrenCount: 5 } as INotebookVariableElement;73results = [74{ id: 2, name: 'first', value: '1', hasNamedChildren: false, indexedChildrenCount: 0 },75{ id: 3, name: 'second', value: '2', hasNamedChildren: false, indexedChildrenCount: 0 },76{ id: 4, name: 'third', value: '3', hasNamedChildren: false, indexedChildrenCount: 0 },77{ id: 5, name: 'fourth', value: '4', hasNamedChildren: false, indexedChildrenCount: 0 },78{ id: 6, name: 'fifth', value: '5', hasNamedChildren: false, indexedChildrenCount: 0 },79];8081const variables = await dataSource.getChildren(parent);8283assert.strictEqual(variables.length, 5);84});8586test('Get children for large list', async () => {87const parent = { kind: 'variable', notebook: notebookModel, id: '1', extHostId: 1, name: 'list', value: '[...]', hasNamedChildren: false, indexedChildrenCount: 2000 } as INotebookVariableElement;88results = [];8990const variables = await dataSource.getChildren(parent);9192assert(variables.length > 1, 'We should have results for groups of children');93assert(!provideVariablesCalled, 'provideVariables should not be called');94assert.equal(variables[0].extHostId, parent.extHostId, 'ExtHostId should match the parent since we will use it to get the real children');95});9697test('Get children for very large list', async () => {98const parent = { kind: 'variable', notebook: notebookModel, id: '1', extHostId: 1, name: 'list', value: '[...]', hasNamedChildren: false, indexedChildrenCount: 1_000_000 } as INotebookVariableElement;99results = [];100101const groups = await dataSource.getChildren(parent);102const children = await dataSource.getChildren(groups[99]);103104assert(children.length === 100, 'We should have a full page of child groups');105assert(!provideVariablesCalled, 'provideVariables should not be called');106assert.equal(children[0].extHostId, parent.extHostId, 'ExtHostId should match the parent since we will use it to get the real children');107});108109test('Cancel while enumerating through children', async () => {110const parent = { kind: 'variable', notebook: notebookModel, id: '1', extHostId: 1, name: 'list', value: '[...]', hasNamedChildren: false, indexedChildrenCount: 10 } as INotebookVariableElement;111results = [112{ id: 2, name: 'first', value: '1', hasNamedChildren: false, indexedChildrenCount: 0 },113{ id: 3, name: 'second', value: '2', hasNamedChildren: false, indexedChildrenCount: 0 },114{ id: 4, name: 'third', value: '3', hasNamedChildren: false, indexedChildrenCount: 0 },115{ id: 5, name: 'fourth', value: '4', hasNamedChildren: false, indexedChildrenCount: 0 },116{ id: 5, name: 'fifth', value: '4', hasNamedChildren: false, indexedChildrenCount: 0, action: () => dataSource.cancel() } as VariablesResult,117{ id: 7, name: 'sixth', value: '6', hasNamedChildren: false, indexedChildrenCount: 0 },118{ id: 8, name: 'seventh', value: '7', hasNamedChildren: false, indexedChildrenCount: 0 },119{ id: 9, name: 'eighth', value: '8', hasNamedChildren: false, indexedChildrenCount: 0 },120{ id: 10, name: 'ninth', value: '9', hasNamedChildren: false, indexedChildrenCount: 0 },121{ id: 11, name: 'tenth', value: '10', hasNamedChildren: false, indexedChildrenCount: 0 },122];123124const variables = await dataSource.getChildren(parent);125126assert.equal(variables.length, 5, 'Iterating should have been cancelled');127});128});129130131