mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-26 09:35:38 -05:00
Add tests for Open Notebook Folder functionality. (#10056)
This commit is contained in:
@@ -79,15 +79,10 @@ export class BookTreeViewProvider implements vscode.TreeDataProvider<BookTreeIte
|
||||
|
||||
trustBook(bookTreeItem?: BookTreeItem): void {
|
||||
let bookPathToTrust = bookTreeItem ? bookTreeItem.root : this.currentBook?.bookPath;
|
||||
|
||||
if (bookPathToTrust) {
|
||||
|
||||
let trustChanged = this._bookTrustManager.setBookAsTrusted(bookPathToTrust);
|
||||
|
||||
if (trustChanged) {
|
||||
|
||||
let notebookDocuments = this._apiWrapper.getNotebookDocuments();
|
||||
|
||||
if (notebookDocuments) {
|
||||
// update trust state of opened items
|
||||
notebookDocuments.forEach(document => {
|
||||
@@ -114,7 +109,7 @@ export class BookTreeViewProvider implements vscode.TreeDataProvider<BookTreeIte
|
||||
if (existingBook?.bookItems.length > 0) {
|
||||
this.currentBook = existingBook;
|
||||
} else {
|
||||
await this.createAndAddBookModel(bookPath, isNotebook);
|
||||
await this.createAndAddBookModel(bookPath, !!isNotebook);
|
||||
let bookViewer = vscode.window.createTreeView(this.viewId, { showCollapseAll: true, treeDataProvider: this });
|
||||
this.currentBook = this.books.find(book => book.bookPath === bookPath);
|
||||
bookViewer.reveal(this.currentBook.bookItems[0], { expand: vscode.TreeItemCollapsibleState.Expanded, focus: true, select: true });
|
||||
@@ -370,7 +365,7 @@ export class BookTreeViewProvider implements vscode.TreeDataProvider<BookTreeIte
|
||||
}
|
||||
}
|
||||
|
||||
private async loadNotebooksInFolder(folderPath: string) {
|
||||
public async loadNotebooksInFolder(folderPath: string) {
|
||||
let bookCollection = await this.getNotebooksInTree(folderPath);
|
||||
for (let i = 0; i < bookCollection.bookPaths.length; i++) {
|
||||
await this.openBook(bookCollection.bookPaths[i], undefined, false);
|
||||
@@ -456,7 +451,6 @@ export class BookTreeViewProvider implements vscode.TreeDataProvider<BookTreeIte
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
getParent(element?: BookTreeItem): vscode.ProviderResult<BookTreeItem> {
|
||||
if (element) {
|
||||
let parentPath;
|
||||
@@ -488,7 +482,6 @@ export class BookTreeViewProvider implements vscode.TreeDataProvider<BookTreeIte
|
||||
return untitledFileName;
|
||||
}
|
||||
|
||||
|
||||
//Confirmation message dialog
|
||||
private async confirmReplace(): Promise<boolean> {
|
||||
return await this.prompter.promptSingle<boolean>(<IQuestion>{
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as fs from 'fs-extra';
|
||||
import * as nls from 'vscode-nls';
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
import * as constants from '../common/constants';
|
||||
|
||||
export enum SettingType {
|
||||
String,
|
||||
Number,
|
||||
Boolean,
|
||||
Set
|
||||
}
|
||||
export class ISetting {
|
||||
key: string;
|
||||
value: string | number | boolean;
|
||||
type: SettingType;
|
||||
}
|
||||
|
||||
export class JupyterSettingWriter {
|
||||
private settings: ISetting[] = [];
|
||||
|
||||
constructor(private baseFile: string) {
|
||||
}
|
||||
|
||||
public addSetting(setting: ISetting): void {
|
||||
this.settings.push(setting);
|
||||
}
|
||||
|
||||
public async writeSettings(targetFile: string): Promise<void> {
|
||||
let settings = await this.printSettings();
|
||||
await fs.writeFile(targetFile, settings);
|
||||
}
|
||||
|
||||
public async printSettings(): Promise<string> {
|
||||
let content = '';
|
||||
let newLine = process.platform === constants.winPlatform ? '\r\n' : '\n';
|
||||
if (this.baseFile) {
|
||||
let sourceContents = await fs.readFile(this.baseFile);
|
||||
content += sourceContents.toString();
|
||||
}
|
||||
|
||||
for (let setting of this.settings) {
|
||||
content += newLine;
|
||||
content += this.printSetting(setting);
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
private printSetting(setting: ISetting): string {
|
||||
let value: string;
|
||||
switch (setting.type) {
|
||||
case SettingType.Boolean:
|
||||
value = setting.value ? 'True' : 'False';
|
||||
break;
|
||||
case SettingType.String:
|
||||
value = `'${setting.value}'`;
|
||||
break;
|
||||
case SettingType.Number:
|
||||
value = `${setting.value}`;
|
||||
break;
|
||||
case SettingType.Set:
|
||||
value = `set([${setting.value}])`;
|
||||
break;
|
||||
default:
|
||||
throw new Error(localize('UnexpectedSettingType', "Unexpected setting type {0}", setting.type));
|
||||
}
|
||||
return `c.${setting.key} = ${value}`;
|
||||
}
|
||||
}
|
||||
@@ -12,12 +12,13 @@ import * as rimraf from 'rimraf';
|
||||
import * as os from 'os';
|
||||
import * as uuid from 'uuid';
|
||||
import { BookTreeViewProvider } from '../../book/bookTreeView';
|
||||
import { BookTreeItem } from '../../book/bookTreeItem';
|
||||
import { BookTreeItem, BookTreeItemType } from '../../book/bookTreeItem';
|
||||
import { promisify } from 'util';
|
||||
import { MockExtensionContext } from '../common/stubs';
|
||||
import { exists } from '../../common/utils';
|
||||
import { AppContext } from '../../common/appContext';
|
||||
import { ApiWrapper } from '../../common/apiWrapper';
|
||||
import { BookModel } from '../../book/bookModel';
|
||||
import { BookTrustManager } from '../../book/bookTrustManager';
|
||||
|
||||
export interface IExpectedBookItem {
|
||||
@@ -43,7 +44,6 @@ export function equalBookItems(book: BookTreeItem, expectedBook: IExpectedBookIt
|
||||
}
|
||||
|
||||
describe('BookTreeViewProviderTests', function () {
|
||||
|
||||
describe('BookTreeViewProvider', () => {
|
||||
|
||||
let mockExtensionContext: vscode.ExtensionContext;
|
||||
@@ -449,4 +449,110 @@ describe('BookTreeViewProviderTests', function () {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('BookTreeViewProvider.openNotebookFolder', function (): void {
|
||||
let rootFolderPath: string;
|
||||
let bookFolderPath: string;
|
||||
let bookTitle: string;
|
||||
let notebookFolderPath: string;
|
||||
let tableOfContentsFile: string;
|
||||
let standaloneNotebookTitle: string;
|
||||
let standaloneNotebookFile: string;
|
||||
let bookTreeViewProvider: BookTreeViewProvider;
|
||||
let appContext: AppContext;
|
||||
|
||||
this.beforeAll(async () => {
|
||||
rootFolderPath = path.join(os.tmpdir(), `BookFolderTest_${uuid.v4()}`);
|
||||
bookFolderPath = path.join(rootFolderPath, 'BookTestData');
|
||||
let dataFolderPath = path.join(bookFolderPath, '_data');
|
||||
let contentFolderPath = path.join(bookFolderPath, 'content');
|
||||
let configFile = path.join(bookFolderPath, '_config.yml');
|
||||
tableOfContentsFile = path.join(dataFolderPath, 'toc.yml');
|
||||
let bookNotebookFile = path.join(contentFolderPath, 'notebook1.ipynb');
|
||||
notebookFolderPath = path.join(rootFolderPath, 'NotebookTestData');
|
||||
standaloneNotebookTitle = 'notebook2';
|
||||
standaloneNotebookFile = path.join(notebookFolderPath, `${standaloneNotebookTitle}.ipynb`);
|
||||
await fs.mkdir(rootFolderPath);
|
||||
await fs.mkdir(bookFolderPath);
|
||||
await fs.mkdir(dataFolderPath);
|
||||
await fs.mkdir(contentFolderPath);
|
||||
await fs.mkdir(notebookFolderPath);
|
||||
bookTitle = 'Test Book';
|
||||
await fs.writeFile(configFile, `title: ${bookTitle}`);
|
||||
await fs.writeFile(tableOfContentsFile, '- title: Notebook1\n url: /notebook1');
|
||||
await fs.writeFile(bookNotebookFile, '');
|
||||
await fs.writeFile(standaloneNotebookFile, '');
|
||||
|
||||
const mockExtensionContext = new MockExtensionContext();
|
||||
appContext = new AppContext(mockExtensionContext, new ApiWrapper());
|
||||
bookTreeViewProvider = new BookTreeViewProvider(appContext.apiWrapper, [], mockExtensionContext, false, 'bookTreeView');
|
||||
let errorCase = new Promise((resolve, reject) => setTimeout(() => resolve(), 5000));
|
||||
await Promise.race([bookTreeViewProvider.initialized, errorCase.then(() => { throw new Error('BookTreeViewProvider did not initialize in time'); })]);
|
||||
appContext = new AppContext(undefined, new ApiWrapper());
|
||||
});
|
||||
|
||||
it('should include books and notebooks when opening parent folder', async () => {
|
||||
await bookTreeViewProvider.loadNotebooksInFolder(rootFolderPath);
|
||||
should(bookTreeViewProvider.books.length).equal(2, 'Should have loaded a book and a notebook');
|
||||
|
||||
validateIsBook(bookTreeViewProvider.books[0]);
|
||||
validateIsNotebook(bookTreeViewProvider.books[1]);
|
||||
});
|
||||
|
||||
it('should include only books when opening books folder', async () => {
|
||||
await bookTreeViewProvider.loadNotebooksInFolder(bookFolderPath);
|
||||
should(bookTreeViewProvider.books.length).equal(1, 'Should have loaded only one book');
|
||||
|
||||
validateIsBook(bookTreeViewProvider.books[0]);
|
||||
});
|
||||
|
||||
it('should include only notebooks when opening notebooks folder', async () => {
|
||||
await bookTreeViewProvider.loadNotebooksInFolder(notebookFolderPath);
|
||||
should(bookTreeViewProvider.books.length).equal(1, 'Should have loaded only one notebook');
|
||||
|
||||
validateIsNotebook(bookTreeViewProvider.books[0]);
|
||||
});
|
||||
|
||||
this.afterEach(async function (): Promise<void> {
|
||||
let bookItems = await bookTreeViewProvider.getChildren();
|
||||
await Promise.all(bookItems.map(bookItem => bookTreeViewProvider.closeBook(bookItem)));
|
||||
});
|
||||
|
||||
this.afterAll(async function (): Promise<void> {
|
||||
if (await exists(rootFolderPath)) {
|
||||
await promisify(rimraf)(rootFolderPath);
|
||||
}
|
||||
});
|
||||
|
||||
let validateIsBook = (book: BookModel) => {
|
||||
should(book.isNotebook).be.false();
|
||||
should(book.bookItems.length).equal(1);
|
||||
|
||||
let bookItem = book.bookItems[0];
|
||||
|
||||
let bookDetails = bookItem.book;
|
||||
should(bookDetails.type).equal(BookTreeItemType.Book);
|
||||
should(bookDetails.title).equal(bookTitle);
|
||||
should(bookDetails.contentPath).equal(tableOfContentsFile.replace(/\\/g, '/'));
|
||||
should(bookDetails.root).equal(bookFolderPath.replace(/\\/g, '/'));
|
||||
should(bookDetails.tableOfContents.sections).not.equal(undefined);
|
||||
should(bookDetails.page).not.equal(undefined);
|
||||
};
|
||||
|
||||
let validateIsNotebook = (book: BookModel) => {
|
||||
should(book.isNotebook).be.true();
|
||||
should(book.bookItems.length).equal(1);
|
||||
|
||||
let bookItem = book.bookItems[0];
|
||||
should(book.getAllNotebooks().get(vscode.Uri.file(standaloneNotebookFile).fsPath)).equal(bookItem);
|
||||
|
||||
let bookDetails = bookItem.book;
|
||||
should(bookDetails.type).equal(BookTreeItemType.Notebook);
|
||||
should(bookDetails.title).equal(standaloneNotebookTitle);
|
||||
should(bookDetails.contentPath).equal(standaloneNotebookFile.replace(/\\/g, '/'));
|
||||
should(bookDetails.root).equal(notebookFolderPath.replace(/\\/g, '/'));
|
||||
should(bookDetails.tableOfContents.sections).equal(undefined);
|
||||
should(bookDetails.page.sections).equal(undefined);
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user