|
|
|
|
@@ -12,7 +12,7 @@ import { ConnectionManagementService } from 'sql/platform/connection/common/conn
|
|
|
|
|
import { CellModel } from 'sql/workbench/parts/notebook/common/models/cell';
|
|
|
|
|
import { CellTypes, NotebookChangeType } from 'sql/workbench/parts/notebook/common/models/contracts';
|
|
|
|
|
import { ModelFactory } from 'sql/workbench/parts/notebook/common/models/modelFactory';
|
|
|
|
|
import { INotebookModelOptions, NotebookContentChange } from 'sql/workbench/parts/notebook/common/models/modelInterfaces';
|
|
|
|
|
import { INotebookModelOptions, NotebookContentChange, ICellModel } from 'sql/workbench/parts/notebook/common/models/modelInterfaces';
|
|
|
|
|
import { NotebookEditorModel } from 'sql/workbench/parts/notebook/browser/models/notebookInput';
|
|
|
|
|
import { NotebookModel } from 'sql/workbench/parts/notebook/common/models/notebookModel';
|
|
|
|
|
import { NotebookService } from 'sql/workbench/services/notebook/common/notebookServiceImpl';
|
|
|
|
|
@@ -691,6 +691,170 @@ suite('Notebook Editor Model', function (): void {
|
|
|
|
|
should(notebookEditorModel.lastEditFullReplacement).equal(false);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('should not replace entire text model for content change with double quotes', async function (): Promise<void> {
|
|
|
|
|
await createNewNotebookModel();
|
|
|
|
|
let notebookEditorModel = await createTextEditorModel(this);
|
|
|
|
|
notebookEditorModel.replaceEntireTextEditorModel(notebookModel, undefined);
|
|
|
|
|
|
|
|
|
|
let newCell = notebookModel.addCell(CellTypes.Code);
|
|
|
|
|
setupTextEditorModelWithEmptyOutputs(notebookEditorModel, newCell);
|
|
|
|
|
|
|
|
|
|
addTextToBeginningOfTextEditorModel(notebookEditorModel, newCell, '"This text is in quotes"');
|
|
|
|
|
should(notebookEditorModel.editorModel.textEditorModel.getLineContent(9)).equal(' "\\"This text is in quotes\\""');
|
|
|
|
|
|
|
|
|
|
ensureStaticContentInOneLineCellIsCorrect(notebookEditorModel, newCell);
|
|
|
|
|
should(notebookEditorModel.lastEditFullReplacement).equal(false);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('should not replace entire text model for content change with many double quotes', async function (): Promise<void> {
|
|
|
|
|
await createNewNotebookModel();
|
|
|
|
|
let notebookEditorModel = await createTextEditorModel(this);
|
|
|
|
|
notebookEditorModel.replaceEntireTextEditorModel(notebookModel, undefined);
|
|
|
|
|
|
|
|
|
|
let newCell = notebookModel.addCell(CellTypes.Code);
|
|
|
|
|
setupTextEditorModelWithEmptyOutputs(notebookEditorModel, newCell);
|
|
|
|
|
|
|
|
|
|
addTextToBeginningOfTextEditorModel(notebookEditorModel, newCell, '""""""""""');
|
|
|
|
|
should(notebookEditorModel.editorModel.textEditorModel.getLineContent(9)).equal(' "\\"\\"\\"\\"\\"\\"\\"\\"\\"\\""');
|
|
|
|
|
|
|
|
|
|
ensureStaticContentInOneLineCellIsCorrect(notebookEditorModel, newCell);
|
|
|
|
|
should(notebookEditorModel.lastEditFullReplacement).equal(false);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('should not replace entire text model for content change with many backslashes', async function (): Promise<void> {
|
|
|
|
|
await createNewNotebookModel();
|
|
|
|
|
let notebookEditorModel = await createTextEditorModel(this);
|
|
|
|
|
notebookEditorModel.replaceEntireTextEditorModel(notebookModel, undefined);
|
|
|
|
|
|
|
|
|
|
let newCell = notebookModel.addCell(CellTypes.Code);
|
|
|
|
|
setupTextEditorModelWithEmptyOutputs(notebookEditorModel, newCell);
|
|
|
|
|
|
|
|
|
|
addTextToBeginningOfTextEditorModel(notebookEditorModel, newCell, '\\\\\\\\\\');
|
|
|
|
|
should(notebookEditorModel.editorModel.textEditorModel.getLineContent(9)).equal(' "\\\\\\\\\\\\\\\\\\\\\"');
|
|
|
|
|
|
|
|
|
|
ensureStaticContentInOneLineCellIsCorrect(notebookEditorModel, newCell);
|
|
|
|
|
should(notebookEditorModel.lastEditFullReplacement).equal(false);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('should not replace entire text model for content change with many backslashes and double quotes', async function (): Promise<void> {
|
|
|
|
|
await createNewNotebookModel();
|
|
|
|
|
let notebookEditorModel = await createTextEditorModel(this);
|
|
|
|
|
notebookEditorModel.replaceEntireTextEditorModel(notebookModel, undefined);
|
|
|
|
|
|
|
|
|
|
let newCell = notebookModel.addCell(CellTypes.Code);
|
|
|
|
|
setupTextEditorModelWithEmptyOutputs(notebookEditorModel, newCell);
|
|
|
|
|
|
|
|
|
|
addTextToBeginningOfTextEditorModel(notebookEditorModel, newCell, '\"\"\"\"\"\"\"\"\"\"');
|
|
|
|
|
should(notebookEditorModel.editorModel.textEditorModel.getLineContent(9)).equal(' "\\\"\\\"\\\"\\\"\\\"\\\"\\\"\\\"\\\"\\\""');
|
|
|
|
|
|
|
|
|
|
ensureStaticContentInOneLineCellIsCorrect(notebookEditorModel, newCell);
|
|
|
|
|
should(notebookEditorModel.lastEditFullReplacement).equal(false);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('should not replace entire text model for content change with no special characters', async function (): Promise<void> {
|
|
|
|
|
await createNewNotebookModel();
|
|
|
|
|
let notebookEditorModel = await createTextEditorModel(this);
|
|
|
|
|
notebookEditorModel.replaceEntireTextEditorModel(notebookModel, undefined);
|
|
|
|
|
|
|
|
|
|
let newCell = notebookModel.addCell(CellTypes.Code);
|
|
|
|
|
setupTextEditorModelWithEmptyOutputs(notebookEditorModel, newCell);
|
|
|
|
|
|
|
|
|
|
addTextToBeginningOfTextEditorModel(notebookEditorModel, newCell, 'this is a long line in a cell test. Everything should serialize correctly! # Comments here: adding more tests is fun?');
|
|
|
|
|
should(notebookEditorModel.editorModel.textEditorModel.getLineContent(9)).equal(' "this is a long line in a cell test. Everything should serialize correctly! # Comments here: adding more tests is fun?"');
|
|
|
|
|
|
|
|
|
|
ensureStaticContentInOneLineCellIsCorrect(notebookEditorModel, newCell);
|
|
|
|
|
should(notebookEditorModel.lastEditFullReplacement).equal(false);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('should not replace entire text model for content change with variety of characters', async function (): Promise<void> {
|
|
|
|
|
await createNewNotebookModel();
|
|
|
|
|
let notebookEditorModel = await createTextEditorModel(this);
|
|
|
|
|
notebookEditorModel.replaceEntireTextEditorModel(notebookModel, undefined);
|
|
|
|
|
|
|
|
|
|
let newCell = notebookModel.addCell(CellTypes.Code);
|
|
|
|
|
setupTextEditorModelWithEmptyOutputs(notebookEditorModel, newCell);
|
|
|
|
|
|
|
|
|
|
addTextToBeginningOfTextEditorModel(notebookEditorModel, newCell, '`~1!2@3#4$5%6^7&8*9(0)-_=+[{]}\\|;:",<.>/?\'');
|
|
|
|
|
should(notebookEditorModel.editorModel.textEditorModel.getLineContent(9)).equal(' "`~1!2@3#4$5%6^7&8*9(0)-_=+[{]}\\\\|;:\\",<.>/?\'"');
|
|
|
|
|
|
|
|
|
|
ensureStaticContentInOneLineCellIsCorrect(notebookEditorModel, newCell);
|
|
|
|
|
should(notebookEditorModel.lastEditFullReplacement).equal(false);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('should not replace entire text model for content change with single quotes', async function (): Promise<void> {
|
|
|
|
|
await createNewNotebookModel();
|
|
|
|
|
let notebookEditorModel = await createTextEditorModel(this);
|
|
|
|
|
notebookEditorModel.replaceEntireTextEditorModel(notebookModel, undefined);
|
|
|
|
|
|
|
|
|
|
let newCell = notebookModel.addCell(CellTypes.Code);
|
|
|
|
|
setupTextEditorModelWithEmptyOutputs(notebookEditorModel, newCell);
|
|
|
|
|
|
|
|
|
|
addTextToBeginningOfTextEditorModel(notebookEditorModel, newCell, '\'\'\'\'');
|
|
|
|
|
should(notebookEditorModel.editorModel.textEditorModel.getLineContent(9)).equal(' "\'\'\'\'"');
|
|
|
|
|
|
|
|
|
|
ensureStaticContentInOneLineCellIsCorrect(notebookEditorModel, newCell);
|
|
|
|
|
should(notebookEditorModel.lastEditFullReplacement).equal(false);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('should not replace entire text model for content change with empty content', async function (): Promise<void> {
|
|
|
|
|
await createNewNotebookModel();
|
|
|
|
|
let notebookEditorModel = await createTextEditorModel(this);
|
|
|
|
|
notebookEditorModel.replaceEntireTextEditorModel(notebookModel, undefined);
|
|
|
|
|
|
|
|
|
|
let newCell = notebookModel.addCell(CellTypes.Code);
|
|
|
|
|
setupTextEditorModelWithEmptyOutputs(notebookEditorModel, newCell);
|
|
|
|
|
|
|
|
|
|
addTextToBeginningOfTextEditorModel(notebookEditorModel, newCell, '');
|
|
|
|
|
should(notebookEditorModel.editorModel.textEditorModel.getLineContent(9)).equal(' ""');
|
|
|
|
|
|
|
|
|
|
ensureStaticContentInOneLineCellIsCorrect(notebookEditorModel, newCell);
|
|
|
|
|
should(notebookEditorModel.lastEditFullReplacement).equal(false);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('should not replace entire text model for content change with multiline content', async function (): Promise<void> {
|
|
|
|
|
await createNewNotebookModel();
|
|
|
|
|
let notebookEditorModel = await createTextEditorModel(this);
|
|
|
|
|
notebookEditorModel.replaceEntireTextEditorModel(notebookModel, undefined);
|
|
|
|
|
|
|
|
|
|
let newCell = notebookModel.addCell(CellTypes.Code);
|
|
|
|
|
setupTextEditorModelWithEmptyOutputs(notebookEditorModel, newCell);
|
|
|
|
|
|
|
|
|
|
addTextToBeginningOfTextEditorModel(notebookEditorModel, newCell, '"test"' + os.EOL + 'test""');
|
|
|
|
|
should(notebookEditorModel.editorModel.textEditorModel.getLineContent(9)).equal(' "\\"test\\"\\n",');
|
|
|
|
|
|
|
|
|
|
should(notebookEditorModel.editorModel.textEditorModel.getLineContent(8)).equal(' "source": [');
|
|
|
|
|
should(notebookEditorModel.editorModel.textEditorModel.getLineContent(10)).equal(' "test\\"\\""');
|
|
|
|
|
should(notebookEditorModel.editorModel.textEditorModel.getLineContent(11)).equal(' ],');
|
|
|
|
|
should(notebookEditorModel.editorModel.textEditorModel.getLineContent(13)).equal(' "azdata_cell_guid": "' + newCell.cellGuid + '"');
|
|
|
|
|
should(notebookEditorModel.editorModel.textEditorModel.getLineContent(15)).equal(' "outputs": [],');
|
|
|
|
|
should(notebookEditorModel.editorModel.textEditorModel.getLineContent(16)).equal(' "execution_count": 0');
|
|
|
|
|
should(notebookEditorModel.editorModel.textEditorModel.getLineContent(17)).equal(' }');
|
|
|
|
|
|
|
|
|
|
should(notebookEditorModel.lastEditFullReplacement).equal(false);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('should not replace entire text model for content change with multiline content different escaped characters', async function (): Promise<void> {
|
|
|
|
|
await createNewNotebookModel();
|
|
|
|
|
let notebookEditorModel = await createTextEditorModel(this);
|
|
|
|
|
notebookEditorModel.replaceEntireTextEditorModel(notebookModel, undefined);
|
|
|
|
|
|
|
|
|
|
let newCell = notebookModel.addCell(CellTypes.Code);
|
|
|
|
|
setupTextEditorModelWithEmptyOutputs(notebookEditorModel, newCell);
|
|
|
|
|
|
|
|
|
|
addTextToBeginningOfTextEditorModel(notebookEditorModel, newCell, '"""""test"' + os.EOL + '"""""""test\\""');
|
|
|
|
|
should(notebookEditorModel.editorModel.textEditorModel.getLineContent(9)).equal(' "\\"\\"\\"\\"\\"test\\"\\n",');
|
|
|
|
|
|
|
|
|
|
should(notebookEditorModel.editorModel.textEditorModel.getLineContent(8)).equal(' "source": [');
|
|
|
|
|
should(notebookEditorModel.editorModel.textEditorModel.getLineContent(10)).equal(' "\\"\\"\\"\\"\\"\\"\\"test\\\\\\"\\""');
|
|
|
|
|
should(notebookEditorModel.editorModel.textEditorModel.getLineContent(11)).equal(' ],');
|
|
|
|
|
should(notebookEditorModel.editorModel.textEditorModel.getLineContent(13)).equal(' "azdata_cell_guid": "' + newCell.cellGuid + '"');
|
|
|
|
|
should(notebookEditorModel.editorModel.textEditorModel.getLineContent(15)).equal(' "outputs": [],');
|
|
|
|
|
should(notebookEditorModel.editorModel.textEditorModel.getLineContent(16)).equal(' "execution_count": 0');
|
|
|
|
|
should(notebookEditorModel.editorModel.textEditorModel.getLineContent(17)).equal(' }');
|
|
|
|
|
|
|
|
|
|
should(notebookEditorModel.lastEditFullReplacement).equal(false);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
async function createNewNotebookModel() {
|
|
|
|
|
let options: INotebookModelOptions = Object.assign({}, defaultModelOptions, <Partial<INotebookModelOptions>><unknown>{
|
|
|
|
|
factory: mockModelFactory.object
|
|
|
|
|
@@ -705,4 +869,47 @@ suite('Notebook Editor Model', function (): void {
|
|
|
|
|
await textFileEditorModel.load();
|
|
|
|
|
return new NotebookEditorModel(defaultUri, textFileEditorModel, mockNotebookService.object, accessor.textFileService, testResourcePropertiesService);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function setupTextEditorModelWithEmptyOutputs(notebookEditorModel: NotebookEditorModel, newCell: ICellModel) {
|
|
|
|
|
// clear outputs
|
|
|
|
|
newCell[<any>'_outputs'] = [];
|
|
|
|
|
|
|
|
|
|
let contentChange: NotebookContentChange = {
|
|
|
|
|
changeType: NotebookChangeType.CellsModified,
|
|
|
|
|
cells: [newCell],
|
|
|
|
|
cellIndex: 0
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
notebookEditorModel.updateModel(contentChange, NotebookChangeType.CellsModified);
|
|
|
|
|
should(notebookEditorModel.lastEditFullReplacement).equal(true);
|
|
|
|
|
|
|
|
|
|
should(notebookEditorModel.editorModel.textEditorModel.getLineContent(14)).equal(' "outputs": [],');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function addTextToBeginningOfTextEditorModel(notebookEditorModel: NotebookEditorModel, newCell: ICellModel, textToAdd: string) {
|
|
|
|
|
let contentChange: NotebookContentChange = {
|
|
|
|
|
changeType: NotebookChangeType.CellSourceUpdated,
|
|
|
|
|
cells: [newCell],
|
|
|
|
|
cellIndex: 0,
|
|
|
|
|
modelContentChangedEvent: {
|
|
|
|
|
changes: [{ range: new Range(1, 1, 1, 1), rangeLength: 0, rangeOffset: 0, text: textToAdd }],
|
|
|
|
|
eol: '\n',
|
|
|
|
|
isFlush: false,
|
|
|
|
|
isRedoing: false,
|
|
|
|
|
isUndoing: false,
|
|
|
|
|
versionId: 2
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
notebookEditorModel.updateModel(contentChange, NotebookChangeType.CellSourceUpdated);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function ensureStaticContentInOneLineCellIsCorrect(notebookEditorModel: NotebookEditorModel, newCell: ICellModel) {
|
|
|
|
|
should(notebookEditorModel.editorModel.textEditorModel.getLineContent(8)).equal(' "source": [');
|
|
|
|
|
should(notebookEditorModel.editorModel.textEditorModel.getLineContent(10)).equal(' ],');
|
|
|
|
|
should(notebookEditorModel.editorModel.textEditorModel.getLineContent(12)).equal(' "azdata_cell_guid": "' + newCell.cellGuid + '"');
|
|
|
|
|
should(notebookEditorModel.editorModel.textEditorModel.getLineContent(14)).equal(' "outputs": [],');
|
|
|
|
|
should(notebookEditorModel.editorModel.textEditorModel.getLineContent(15)).equal(' "execution_count": 0');
|
|
|
|
|
should(notebookEditorModel.editorModel.textEditorModel.getLineContent(16)).equal(' }');
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|