mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
bookTreeView tests (#11746)
* bookTreeView tests * add types * CI failure change test * test mix up corrected * check notebook path exists * missing file error fix * error msg update * openNotebook test error alternative fix * move openNotebook test to unstable * skip instead of marking unstable
This commit is contained in:
@@ -29,8 +29,6 @@ interface BookSearchResults {
|
|||||||
export class BookTreeViewProvider implements vscode.TreeDataProvider<BookTreeItem>, azdata.nb.NavigationProvider {
|
export class BookTreeViewProvider implements vscode.TreeDataProvider<BookTreeItem>, azdata.nb.NavigationProvider {
|
||||||
private _onDidChangeTreeData: vscode.EventEmitter<BookTreeItem | undefined> = new vscode.EventEmitter<BookTreeItem | undefined>();
|
private _onDidChangeTreeData: vscode.EventEmitter<BookTreeItem | undefined> = new vscode.EventEmitter<BookTreeItem | undefined>();
|
||||||
readonly onDidChangeTreeData: vscode.Event<BookTreeItem | undefined> = this._onDidChangeTreeData.event;
|
readonly onDidChangeTreeData: vscode.Event<BookTreeItem | undefined> = this._onDidChangeTreeData.event;
|
||||||
private _throttleTimer: any;
|
|
||||||
private _resource: string;
|
|
||||||
private _extensionContext: vscode.ExtensionContext;
|
private _extensionContext: vscode.ExtensionContext;
|
||||||
private prompter: IPrompter;
|
private prompter: IPrompter;
|
||||||
private _initializeDeferred: Deferred<void> = new Deferred<void>();
|
private _initializeDeferred: Deferred<void> = new Deferred<void>();
|
||||||
@@ -231,19 +229,17 @@ export class BookTreeViewProvider implements vscode.TreeDataProvider<BookTreeIte
|
|||||||
if (this._openAsUntitled) {
|
if (this._openAsUntitled) {
|
||||||
await this.openNotebookAsUntitled(resource);
|
await this.openNotebookAsUntitled(resource);
|
||||||
} else {
|
} else {
|
||||||
|
await azdata.nb.showNotebookDocument(vscode.Uri.file(resource));
|
||||||
// let us keep a list of already visited notebooks so that we do not trust them again, potentially
|
// let us keep a list of already visited notebooks so that we do not trust them again, potentially
|
||||||
// overriding user changes
|
// overriding user changes
|
||||||
let normalizedResource = path.normalize(resource);
|
let normalizedResource = path.normalize(resource);
|
||||||
|
|
||||||
if (this._visitedNotebooks.indexOf(normalizedResource) === -1
|
if (this._visitedNotebooks.indexOf(normalizedResource) === -1
|
||||||
&& this._bookTrustManager.isNotebookTrustedByDefault(normalizedResource)) {
|
&& this._bookTrustManager.isNotebookTrustedByDefault(normalizedResource)) {
|
||||||
let openDocumentListenerUnsubscriber = azdata.nb.onDidOpenNotebookDocument((document: azdata.nb.NotebookDocument) => {
|
let document = azdata.nb.notebookDocuments.find(document => document.fileName === resource);
|
||||||
document.setTrusted(true);
|
document?.setTrusted(true);
|
||||||
this._visitedNotebooks = this._visitedNotebooks.concat([normalizedResource]);
|
this._visitedNotebooks = this._visitedNotebooks.concat([normalizedResource]);
|
||||||
openDocumentListenerUnsubscriber.dispose();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
azdata.nb.showNotebookDocument(vscode.Uri.file(resource));
|
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
vscode.window.showErrorMessage(loc.openNotebookError(resource, e instanceof Error ? e.message : e));
|
vscode.window.showErrorMessage(loc.openNotebookError(resource, e instanceof Error ? e.message : e));
|
||||||
@@ -297,26 +293,22 @@ export class BookTreeViewProvider implements vscode.TreeDataProvider<BookTreeIte
|
|||||||
}
|
}
|
||||||
|
|
||||||
openMarkdown(resource: string): void {
|
openMarkdown(resource: string): void {
|
||||||
this.runThrottledAction(resource, () => {
|
try {
|
||||||
try {
|
vscode.commands.executeCommand('markdown.showPreview', vscode.Uri.file(resource));
|
||||||
vscode.commands.executeCommand('markdown.showPreview', vscode.Uri.file(resource));
|
} catch (e) {
|
||||||
} catch (e) {
|
vscode.window.showErrorMessage(loc.openMarkdownError(resource, e instanceof Error ? e.message : e));
|
||||||
vscode.window.showErrorMessage(loc.openMarkdownError(resource, e instanceof Error ? e.message : e));
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async openNotebookAsUntitled(resource: string): Promise<void> {
|
async openNotebookAsUntitled(resource: string): Promise<void> {
|
||||||
try {
|
try {
|
||||||
await vscode.commands.executeCommand(constants.BuiltInCommands.SetContext, constants.unsavedBooksContextKey, true);
|
await vscode.commands.executeCommand(constants.BuiltInCommands.SetContext, constants.unsavedBooksContextKey, true);
|
||||||
let untitledFileName: vscode.Uri = this.getUntitledNotebookUri(resource);
|
let untitledFileName: vscode.Uri = this.getUntitledNotebookUri(resource);
|
||||||
vscode.workspace.openTextDocument(resource).then((document) => {
|
let document: vscode.TextDocument = await vscode.workspace.openTextDocument(resource);
|
||||||
let initialContent = document.getText();
|
await azdata.nb.showNotebookDocument(untitledFileName, {
|
||||||
azdata.nb.showNotebookDocument(untitledFileName, {
|
connectionProfile: null,
|
||||||
connectionProfile: null,
|
initialContent: document.getText(),
|
||||||
initialContent: initialContent,
|
initialDirtyState: false
|
||||||
initialDirtyState: false
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
vscode.window.showErrorMessage(loc.openUntitledNotebookError(resource, e instanceof Error ? e.message : e));
|
vscode.window.showErrorMessage(loc.openUntitledNotebookError(resource, e instanceof Error ? e.message : e));
|
||||||
@@ -455,35 +447,9 @@ export class BookTreeViewProvider implements vscode.TreeDataProvider<BookTreeIte
|
|||||||
return { notebookPaths: notebookPaths, bookPaths: bookPaths };
|
return { notebookPaths: notebookPaths, bookPaths: bookPaths };
|
||||||
}
|
}
|
||||||
|
|
||||||
private runThrottledAction(resource: string, action: () => void) {
|
async openExternalLink(resource: string): Promise<void> {
|
||||||
const isResourceChange = resource !== this._resource;
|
|
||||||
if (isResourceChange) {
|
|
||||||
this.clearAndResetThrottleTimer();
|
|
||||||
}
|
|
||||||
|
|
||||||
this._resource = resource;
|
|
||||||
|
|
||||||
// Schedule update if none is pending
|
|
||||||
if (!this._throttleTimer) {
|
|
||||||
if (isResourceChange) {
|
|
||||||
action();
|
|
||||||
} else {
|
|
||||||
this._throttleTimer = setTimeout(() => {
|
|
||||||
action();
|
|
||||||
this.clearAndResetThrottleTimer();
|
|
||||||
}, 300);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private clearAndResetThrottleTimer(): void {
|
|
||||||
clearTimeout(this._throttleTimer);
|
|
||||||
this._throttleTimer = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
openExternalLink(resource: string): void {
|
|
||||||
try {
|
try {
|
||||||
vscode.env.openExternal(vscode.Uri.parse(resource));
|
await vscode.env.openExternal(vscode.Uri.parse(resource));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
vscode.window.showErrorMessage(loc.openExternalLinkError(resource, e instanceof Error ? e.message : e));
|
vscode.window.showErrorMessage(loc.openExternalLinkError(resource, e instanceof Error ? e.message : e));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ describe('BooksTreeViewTests', function () {
|
|||||||
await bookTreeViewProvider.openBook(bookFolderPath, undefined, false, false);
|
await bookTreeViewProvider.openBook(bookFolderPath, undefined, false, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function(): void {
|
afterEach(function (): void {
|
||||||
sinon.restore();
|
sinon.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -276,7 +276,7 @@ describe('BooksTreeViewTests', function () {
|
|||||||
await providedbookTreeViewProvider.openBook(bookFolderPath, undefined, false, false);
|
await providedbookTreeViewProvider.openBook(bookFolderPath, undefined, false, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function(): void {
|
afterEach(function (): void {
|
||||||
sinon.restore();
|
sinon.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -505,13 +505,17 @@ describe('BooksTreeViewTests', function () {
|
|||||||
let contentFolderPath = path.join(rootFolderPath, 'content');
|
let contentFolderPath = path.join(rootFolderPath, 'content');
|
||||||
let configFile = path.join(rootFolderPath, '_config.yml');
|
let configFile = path.join(rootFolderPath, '_config.yml');
|
||||||
tableOfContentsFile = path.join(dataFolderPath, 'toc.yml');
|
tableOfContentsFile = path.join(dataFolderPath, 'toc.yml');
|
||||||
|
let notebook1File = path.join(contentFolderPath, 'notebook1.ipynb');
|
||||||
let notebook2File = path.join(contentFolderPath, 'notebook2.ipynb');
|
let notebook2File = path.join(contentFolderPath, 'notebook2.ipynb');
|
||||||
|
let markdownFile = path.join(contentFolderPath, 'readme.md');
|
||||||
await fs.mkdir(rootFolderPath);
|
await fs.mkdir(rootFolderPath);
|
||||||
await fs.mkdir(dataFolderPath);
|
await fs.mkdir(dataFolderPath);
|
||||||
await fs.mkdir(contentFolderPath);
|
await fs.mkdir(contentFolderPath);
|
||||||
await fs.writeFile(configFile, 'title: Test Book');
|
await fs.writeFile(configFile, 'title: Test Book');
|
||||||
await fs.writeFile(tableOfContentsFile, '- title: Notebook1\n url: /notebook1\n- title: Notebook2\n url: /notebook2');
|
await fs.writeFile(tableOfContentsFile, '- title: Home\n url: /readme\n- title: Notebook1\n url: /notebook1\n- title: Notebook2\n url: /notebook2');
|
||||||
|
await fs.writeFile(notebook1File, '');
|
||||||
await fs.writeFile(notebook2File, '');
|
await fs.writeFile(notebook2File, '');
|
||||||
|
await fs.writeFile(markdownFile, '');
|
||||||
|
|
||||||
const mockExtensionContext = new MockExtensionContext();
|
const mockExtensionContext = new MockExtensionContext();
|
||||||
bookTreeViewProvider = new BookTreeViewProvider([], mockExtensionContext, false, 'bookTreeView', NavigationProviders.NotebooksNavigator);
|
bookTreeViewProvider = new BookTreeViewProvider([], mockExtensionContext, false, 'bookTreeView', NavigationProviders.NotebooksNavigator);
|
||||||
@@ -519,8 +523,9 @@ describe('BooksTreeViewTests', function () {
|
|||||||
await Promise.race([bookTreeViewProvider.initialized, errorCase.then(() => { throw new Error('BookTreeViewProvider did not initialize in time'); })]);
|
await Promise.race([bookTreeViewProvider.initialized, errorCase.then(() => { throw new Error('BookTreeViewProvider did not initialize in time'); })]);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function(): void {
|
afterEach(async function (): Promise<void> {
|
||||||
sinon.restore();
|
sinon.restore();
|
||||||
|
await vscode.commands.executeCommand('workbench.action.closeAllEditors');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add book and initialize book on openBook', async () => {
|
it('should add book and initialize book on openBook', async () => {
|
||||||
@@ -533,6 +538,34 @@ describe('BooksTreeViewTests', function () {
|
|||||||
should(showPreviewSpy.notCalled).be.true('Should not call showPreviewFile when showPreview isn\' true');
|
should(showPreviewSpy.notCalled).be.true('Should not call showPreviewFile when showPreview isn\' true');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('openMarkdown should open markdown in the editor', async () => {
|
||||||
|
let executeCommandSpy = sinon.spy(vscode.commands, 'executeCommand');
|
||||||
|
let notebookPath = path.join(rootFolderPath, 'content', 'readme.md');
|
||||||
|
bookTreeViewProvider.openMarkdown(notebookPath);
|
||||||
|
should(executeCommandSpy.calledWith('markdown.showPreview')).be.true('openMarkdown should have called markdown.showPreview');
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO: Need to investigate why it's failing on linux.
|
||||||
|
it.skip('openNotebook should open notebook in the editor', async () => {
|
||||||
|
let showNotebookSpy = sinon.spy(azdata.nb, 'showNotebookDocument');
|
||||||
|
let notebookPath = path.join(rootFolderPath, 'content', 'notebook2.ipynb');
|
||||||
|
await bookTreeViewProvider.openNotebook(notebookPath);
|
||||||
|
should(showNotebookSpy.calledWith(vscode.Uri.file(notebookPath))).be.true(`Should have opened the notebook from ${notebookPath} in the editor.`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('openNotebookAsUntitled should open a notebook as untitled file in the editor', async () => {
|
||||||
|
let notebookPath = path.join(rootFolderPath, 'content', 'notebook2.ipynb');
|
||||||
|
await bookTreeViewProvider.openNotebookAsUntitled(notebookPath);
|
||||||
|
should(azdata.nb.notebookDocuments.find(doc => doc.uri.scheme === 'untitled')).not.be.undefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('openExternalLink should open link', async () => {
|
||||||
|
let executeCommandSpy = sinon.spy(vscode.commands, 'executeCommand');
|
||||||
|
let notebookPath = path.join(rootFolderPath, 'content', 'readme.md');
|
||||||
|
bookTreeViewProvider.openMarkdown(notebookPath);
|
||||||
|
should(executeCommandSpy.calledWith('markdown.showPreview')).be.true('openMarkdown should have called markdown.showPreview');
|
||||||
|
});
|
||||||
|
|
||||||
it('should call showPreviewFile on openBook when showPreview flag is set', async () => {
|
it('should call showPreviewFile on openBook when showPreview flag is set', async () => {
|
||||||
await bookTreeViewProvider.closeBook(bookTreeViewProvider.books[0].bookItems[0]);
|
await bookTreeViewProvider.closeBook(bookTreeViewProvider.books[0].bookItems[0]);
|
||||||
let showPreviewSpy = sinon.spy(bookTreeViewProvider, 'showPreviewFile');
|
let showPreviewSpy = sinon.spy(bookTreeViewProvider, 'showPreviewFile');
|
||||||
@@ -612,7 +645,7 @@ describe('BooksTreeViewTests', function () {
|
|||||||
it('should remove book on closeBook', async () => {
|
it('should remove book on closeBook', async () => {
|
||||||
let length: number = bookTreeViewProvider.books.length;
|
let length: number = bookTreeViewProvider.books.length;
|
||||||
await bookTreeViewProvider.closeBook(bookTreeViewProvider.books[0].bookItems[0]);
|
await bookTreeViewProvider.closeBook(bookTreeViewProvider.books[0].bookItems[0]);
|
||||||
should(bookTreeViewProvider.books.length).equal(length-1, 'Failed to remove the book on close');
|
should(bookTreeViewProvider.books.length).equal(length - 1, 'Failed to remove the book on close');
|
||||||
});
|
});
|
||||||
|
|
||||||
this.afterAll(async function (): Promise<void> {
|
this.afterAll(async function (): Promise<void> {
|
||||||
|
|||||||
Reference in New Issue
Block a user