提交 b139c10f 编写于 作者: J Johannes Rieken

add tests for notebook outline

上级 de020f04
......@@ -162,7 +162,7 @@ export class GotoSymbolQuickAccessProvider extends AbstractGotoSymbolQuickAccess
}
}));
const entries = Array.from(outline.config.quickPickDataSource.getQuickPickElements());
const entries = outline.config.quickPickDataSource.getQuickPickElements();
const items: IGotoSymbolQuickPickItem[] = entries.map((entry, idx) => {
return {
......
......@@ -237,7 +237,7 @@ class NotebookQuickPickProvider implements IQuickPickDataSource<OutlineEntry> {
@IThemeService private readonly _themeService: IThemeService
) { }
getQuickPickElements(): Iterable<IQuickPickOutlineElement<OutlineEntry>> {
getQuickPickElements(): IQuickPickOutlineElement<OutlineEntry>[] {
const bucket: OutlineEntry[] = [];
for (let entry of this._getEntries()) {
entry.asFlatList(bucket);
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { setupInstantiationService, withTestNotebook } from 'vs/workbench/contrib/notebook/test/testNotebookEditor';
import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo';
import { OutlineTarget } from 'vs/workbench/services/outline/browser/outline';
import { NotebookCellOutline } from 'vs/workbench/contrib/notebook/browser/contrib/outline/notebookOutline';
import { IFileIconTheme, IThemeService } from 'vs/platform/theme/common/themeService';
import { mock } from 'vs/base/test/common/mock';
import { Event } from 'vs/base/common/event';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IMarkerService } from 'vs/platform/markers/common/markers';
import { MarkerService } from 'vs/platform/markers/common/markerService';
import { CellKind, IOutputDto, NotebookCellMetadata } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { IActiveNotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
suite('Notebook Outline', function () {
const instantiationService = setupInstantiationService();
instantiationService.spy(IUndoRedoService, 'pushElement');
instantiationService.set(IEditorService, new class extends mock<IEditorService>() { });
instantiationService.set(IMarkerService, new MarkerService());
instantiationService.set(IThemeService, new class extends mock<IThemeService>() {
onDidFileIconThemeChange = Event.None;
getFileIconTheme(): IFileIconTheme {
return { hasFileIcons: true, hasFolderIcons: true, hidesExplorerArrows: false };
}
});
function withNotebookOutline<R = any>(cells: [source: string, lang: string, kind: CellKind, output?: IOutputDto[], metadata?: NotebookCellMetadata][], callback: (outline: NotebookCellOutline, editor: IActiveNotebookEditor) => R): R {
return withTestNotebook(instantiationService, cells, (editor) => {
if (!editor.hasModel()) {
assert.ok(false, 'MUST have active text editor');
}
const outline = instantiationService.createInstance(NotebookCellOutline, editor, OutlineTarget.OutlinePane);
return callback(outline, editor);
});
}
test('basic', function () {
withNotebookOutline([], outline => {
assert.ok(outline instanceof NotebookCellOutline);
assert.deepStrictEqual(outline.config.quickPickDataSource.getQuickPickElements(), []);
});
});
test('special characters in heading', function () {
withNotebookOutline([
['# Hellö & Hällo', 'md', CellKind.Markdown]
], outline => {
assert.ok(outline instanceof NotebookCellOutline);
assert.deepStrictEqual(outline.config.quickPickDataSource.getQuickPickElements().length, 1);
assert.deepStrictEqual(outline.config.quickPickDataSource.getQuickPickElements()[0].label, 'Hellö & Hällo');
});
});
test('First line vs heading...', function () {
return withNotebookOutline([
['foo\n # h1', 'md', CellKind.Markdown]
], outline => {
assert.ok(outline instanceof NotebookCellOutline);
assert.deepStrictEqual(outline.config.quickPickDataSource.getQuickPickElements().length, 1);
assert.deepStrictEqual(outline.config.quickPickDataSource.getQuickPickElements()[0].label, 'foo');
});
});
test('Only one entry per cell', function () {
withNotebookOutline([
['## h2 \n# h1', 'md', CellKind.Markdown]
], outline => {
assert.ok(outline instanceof NotebookCellOutline);
assert.deepStrictEqual(outline.config.quickPickDataSource.getQuickPickElements().length, 1);
assert.deepStrictEqual(outline.config.quickPickDataSource.getQuickPickElements()[0].label, 'h2');
});
withNotebookOutline([
['## h2', 'md', CellKind.Markdown],
['# h1', 'md', CellKind.Markdown]
], outline => {
assert.ok(outline instanceof NotebookCellOutline);
assert.deepStrictEqual(outline.config.quickPickDataSource.getQuickPickElements().length, 2);
assert.deepStrictEqual(outline.config.quickPickDataSource.getQuickPickElements()[0].label, 'h2');
assert.deepStrictEqual(outline.config.quickPickDataSource.getQuickPickElements()[1].label, 'h1');
});
});
});
......@@ -12,7 +12,7 @@ import { BareFontInfo } from 'vs/editor/common/config/fontInfo';
import { Range } from 'vs/editor/common/core/range';
import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo';
import { EditorModel } from 'vs/workbench/common/editor';
import { ICellViewModel, INotebookEditor, INotebookEditorContribution, INotebookEditorMouseEvent, NotebookLayoutInfo, INotebookDeltaDecoration, INotebookEditorCreationOptions, NotebookEditorOptions, ICellOutputViewModel, IInsetRenderOutput, ICommonCellInfo, IGenericCellViewModel, INotebookCellOutputLayoutInfo, CellEditState } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { ICellViewModel, INotebookEditor, INotebookEditorContribution, INotebookEditorMouseEvent, NotebookLayoutInfo, INotebookDeltaDecoration, INotebookEditorCreationOptions, NotebookEditorOptions, ICellOutputViewModel, IInsetRenderOutput, ICommonCellInfo, IGenericCellViewModel, INotebookCellOutputLayoutInfo, CellEditState, IActiveNotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { OutputRenderer } from 'vs/workbench/contrib/notebook/browser/view/output/outputRenderer';
import { NotebookEventDispatcher } from 'vs/workbench/contrib/notebook/browser/viewModel/eventDispatcher';
import { CellViewModel, IModelDecorationsChangeAccessor, NotebookViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/notebookViewModel';
......@@ -59,13 +59,10 @@ export class TestNotebookEditor implements INotebookEditor {
return this._isDisposed;
}
get viewModel() {
return undefined;
}
creationOptions: INotebookEditorCreationOptions = { isEmbedded: false };
constructor(
) { }
constructor(readonly viewModel: NotebookViewModel) { }
getSelection(): ICellRange | undefined {
throw new Error('Method not implemented.');
}
......@@ -137,7 +134,7 @@ export class TestNotebookEditor implements INotebookEditor {
uri?: URI | undefined;
textModel?: NotebookTextModel | undefined;
hasModel(): boolean {
hasModel(): this is IActiveNotebookEditor {
return true;
}
......@@ -457,7 +454,7 @@ export function setupInstantiationService() {
return instantiationService;
}
export function withTestNotebook(accessor: ServicesAccessor, cells: [string, string, CellKind, IOutputDto[], NotebookCellMetadata][], callback: (editor: TestNotebookEditor, viewModel: NotebookViewModel, textModel: NotebookTextModel) => void) {
export function withTestNotebook<R = any>(accessor: ServicesAccessor, cells: [source: string, lang: string, kind: CellKind, output?: IOutputDto[], metadata?: NotebookCellMetadata][], callback: (editor: TestNotebookEditor, viewModel: NotebookViewModel, textModel: NotebookTextModel) => R): R {
const instantiationService = accessor.get(IInstantiationService);
const undoRedoService = accessor.get(IUndoRedoService);
......@@ -465,22 +462,25 @@ export function withTestNotebook(accessor: ServicesAccessor, cells: [string, str
const bulkEditService = accessor.get(IBulkEditService);
const viewType = 'notebook';
const editor = new TestNotebookEditor();
const notebook = new NotebookTextModel(viewType, URI.parse('test'), cells.map(cell => {
return {
source: cell[0],
language: cell[1],
cellKind: cell[2],
outputs: cell[3],
outputs: cell[3] ?? [],
metadata: cell[4]
};
}), notebookDocumentMetadataDefaults, { transientMetadata: {}, transientOutputs: false }, undoRedoService, textModelService);
const model = new NotebookEditorTestModel(notebook);
const eventDispatcher = new NotebookEventDispatcher();
const viewModel = new NotebookViewModel(viewType, model.notebook, eventDispatcher, null, instantiationService, bulkEditService, undoRedoService);
const editor = new TestNotebookEditor(viewModel);
callback(editor, viewModel, notebook);
viewModel.dispose();
return;
const res = callback(editor, viewModel, notebook);
if (res instanceof Promise) {
res.finally(() => viewModel.dispose());
} else {
viewModel.dispose();
}
return res;
}
......@@ -54,7 +54,7 @@ export interface IQuickPickOutlineElement<E> {
}
export interface IQuickPickDataSource<E> {
getQuickPickElements(): Iterable<IQuickPickOutlineElement<E>>;
getQuickPickElements(): IQuickPickOutlineElement<E>[];
}
export interface IOutlineListConfig<E> {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册