Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/copilot/src/platform/notebook/test/node/alternativeNotebookTextDocument.spec.tsx
13405 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { afterAll, beforeEach, describe, expect, test } from 'vitest';
7
import type { NotebookDocument, NotebookDocumentContentChange, TextDocumentChangeEvent } from 'vscode';
8
import { ExtHostNotebookDocumentData } from '../../../../util/common/test/shims/notebookDocument';
9
import { DisposableStore } from '../../../../util/vs/base/common/lifecycle';
10
import { URI } from '../../../../util/vs/base/common/uri';
11
import { OffsetRange } from '../../../../util/vs/editor/common/core/ranges/offsetRange';
12
import { NotebookCellData, NotebookCellKind, NotebookData, NotebookRange, Range } from '../../../../vscodeTypes';
13
import { createAlternativeNotebookDocument, createAlternativeNotebookDocumentSnapshot, IAlternativeNotebookDocument, IAlternativeNotebookDocumentSnapshot, toAltNotebookCellChangeEdit, toAltNotebookChangeEdit } from '../../common/alternativeNotebookTextDocument';
14
15
describe('Alternative Notebook (text) Content', () => {
16
const disposables = new DisposableStore();
17
18
afterAll(() => {
19
disposables.clear();
20
});
21
22
function createNotebook(cells: NotebookCellData[], withMarkdownCells: boolean = false) {
23
const notebook = ExtHostNotebookDocumentData.fromNotebookData(URI.file('notebook.ipynb'), new NotebookData(cells), 'jupyter-notebook');
24
const altDocSnapshot = createAlternativeNotebookDocumentSnapshot(notebook.document, !withMarkdownCells);
25
const altDoc = createAlternativeNotebookDocument(notebook.document, !withMarkdownCells);
26
27
expect(altDocSnapshot.getText()).toBe(altDoc.getText());
28
return { notebookData: notebook, notebook: notebook.document, altDocSnapshot, altDoc };
29
}
30
[true, false].forEach(withMarkdownCells => {
31
describe(`Alt Content ${withMarkdownCells ? 'with' : 'without'} Markdown Cells`, () => {
32
test(`Generate Alt Content`, async () => {
33
const cells = [
34
new NotebookCellData(NotebookCellKind.Code, 'print("Hello World")', 'python'),
35
];
36
const { altDocSnapshot } = createNotebook(cells, withMarkdownCells);
37
expect(altDocSnapshot.getText()).toMatchSnapshot();
38
});
39
test(`No Content`, async () => {
40
const { altDocSnapshot } = createNotebook([], withMarkdownCells);
41
expect(altDocSnapshot.getText()).toMatchSnapshot();
42
});
43
test(`No Content without code cells`, async () => {
44
const cells = [
45
new NotebookCellData(NotebookCellKind.Markup, '# This is a sample notebook', 'markdown'),
46
];
47
const { altDocSnapshot } = createNotebook(cells, withMarkdownCells);
48
expect(altDocSnapshot.getText()).toMatchSnapshot();
49
});
50
test(`With Markdown Cells`, async () => {
51
const cells = [
52
new NotebookCellData(NotebookCellKind.Markup, '# This is a sample notebook', 'markdown'),
53
new NotebookCellData(NotebookCellKind.Markup, '## Header', 'markdown'),
54
new NotebookCellData(NotebookCellKind.Code, 'print("Hello World")', 'python'),
55
new NotebookCellData(NotebookCellKind.Markup, 'Comments', 'markdown'),
56
new NotebookCellData(NotebookCellKind.Code, 'print("Foo Bar")', 'python'),
57
];
58
const { altDocSnapshot } = createNotebook(cells, withMarkdownCells);
59
expect(altDocSnapshot.getText()).toMatchSnapshot();
60
});
61
test(`EOLs`, async () => {
62
const cells = [
63
new NotebookCellData(NotebookCellKind.Code, 'import sys\nimport os', 'python'),
64
new NotebookCellData(NotebookCellKind.Code, 'import pandas\r\nimport requests', 'python'),
65
new NotebookCellData(NotebookCellKind.Code, 'print("Hello World")\r\nprint("Foo Bar")\r\nprint("Bar Baz")', 'python'),
66
new NotebookCellData(NotebookCellKind.Code, 'print(sys.executable)\nprint(sys.version)', 'python'),
67
];
68
const { altDocSnapshot } = createNotebook(cells, withMarkdownCells);
69
70
expect(altDocSnapshot.getText()).toMatchSnapshot();
71
72
expect(altDocSnapshot.getText()).not.toContain('\r\n'); // Ensure no CRLF, only LF
73
expect(altDocSnapshot.getText()).toContain('\n'); // Ensure no CRLF, only LF
74
});
75
});
76
});
77
describe('Position Mapping', () => {
78
test(`All cells have same EOL`, async () => {
79
const cells = [
80
new NotebookCellData(NotebookCellKind.Code, 'import sys\nimport os', 'python'),
81
new NotebookCellData(NotebookCellKind.Code, 'import pandas\nimport requests', 'python'),
82
new NotebookCellData(NotebookCellKind.Code, 'print("Hello World")\nprint("Foo Bar")\nprint("Bar Baz")', 'python'),
83
new NotebookCellData(NotebookCellKind.Code, 'print(sys.executable)\nprint(sys.version)', 'python'),
84
];
85
const { notebook, altDocSnapshot } = createNotebook(cells);
86
87
expect(altDocSnapshot.getText(new OffsetRange(53, 53))).toBe('');
88
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(53, 53))).toEqual([[notebook.cellAt(0), new Range(0, 0, 0, 0)]]);
89
expect(altDocSnapshot.fromAltRange(new Range(1, 0, 1, 0))).toEqual([[notebook.cellAt(0), new Range(0, 0, 0, 0)]]);
90
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(0), [new Range(0, 0, 0, 0)])).toEqual([new OffsetRange(53, 53)]);
91
92
expect(altDocSnapshot.getText(new OffsetRange(53, 59))).toBe('import');
93
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(53, 59))).toEqual([[notebook.cellAt(0), new Range(0, 0, 0, 6)]]);
94
expect(altDocSnapshot.fromAltRange(new Range(1, 0, 1, 6))).toEqual([[notebook.cellAt(0), new Range(0, 0, 0, 6)]]);
95
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(0), [new Range(0, 0, 0, 6)])).toEqual([new OffsetRange(53, 59)]);
96
97
expect(altDocSnapshot.getText(new OffsetRange(53, 64))).toBe('import sys\n');
98
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(53, 64))).toEqual([[notebook.cellAt(0), new Range(0, 0, 1, 0)]]);
99
expect(altDocSnapshot.fromAltRange(new Range(1, 0, 2, 0))).toEqual([[notebook.cellAt(0), new Range(0, 0, 1, 0)]]);
100
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(0), [new Range(0, 0, 1, 0)])).toEqual([new OffsetRange(53, 64)]);
101
102
expect(altDocSnapshot.getText(new OffsetRange(53, 73))).toBe('import sys\nimport os');
103
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(53, 73))).toEqual([[notebook.cellAt(0), new Range(0, 0, 1, 9)]]);
104
expect(altDocSnapshot.fromAltRange(new Range(1, 0, 2, 9))).toEqual([[notebook.cellAt(0), new Range(0, 0, 1, 9)]]);
105
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(0), [new Range(0, 0, 1, 9)])).toEqual([new OffsetRange(53, 73)]);
106
107
expect(altDocSnapshot.getText(new OffsetRange(53, 74))).toBe('import sys\nimport os\n');
108
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(53, 74))).toEqual([[notebook.cellAt(0), new Range(0, 0, 1, 9)]]);
109
expect(altDocSnapshot.fromAltRange(new Range(1, 0, 3, 0))).toEqual([[notebook.cellAt(0), new Range(0, 0, 1, 9)]]);
110
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(0), [new Range(0, 0, 1, 9)])).toEqual([new OffsetRange(53, 73)]);
111
112
// Translating alt text range across cells will only return contents of one cell.
113
expect(altDocSnapshot.getText(new OffsetRange(53, 140))).toBe('import sys\nimport os\n#%% vscode.cell [id=#VSC-bdb3864a] [language=python]\nimport pandas');
114
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(53, 140))).toEqual([[notebook.cellAt(0), new Range(0, 0, 1, 9)], [notebook.cellAt(1), new Range(0, 0, 0, 13)]]);
115
expect(altDocSnapshot.fromAltRange(new Range(1, 0, 4, 13))).toEqual([[notebook.cellAt(0), new Range(0, 0, 1, 9)], [notebook.cellAt(1), new Range(0, 0, 0, 13)]]);
116
117
expect(altDocSnapshot.getText(new OffsetRange(71, 73))).toBe('os');
118
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(71, 73))).toEqual([[notebook.cellAt(0), new Range(1, 7, 1, 9)]]);
119
expect(altDocSnapshot.fromAltRange(new Range(2, 7, 2, 9))).toEqual([[notebook.cellAt(0), new Range(1, 7, 1, 9)]]);
120
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(0), [new Range(1, 7, 1, 9)])).toEqual([new OffsetRange(71, 73)]);
121
122
expect(altDocSnapshot.getText(new OffsetRange(127, 127))).toBe('');
123
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(127, 127))).toEqual([[notebook.cellAt(1), new Range(0, 0, 0, 0)]]);
124
expect(altDocSnapshot.fromAltRange(new Range(4, 0, 4, 0))).toEqual([[notebook.cellAt(1), new Range(0, 0, 0, 0)]]);
125
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(1), [new Range(0, 0, 0, 0)])).toEqual([new OffsetRange(127, 127)]);
126
127
expect(altDocSnapshot.getText(new OffsetRange(127, 133))).toBe('import');
128
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(127, 133))).toEqual([[notebook.cellAt(1), new Range(0, 0, 0, 6)]]);
129
expect(altDocSnapshot.fromAltRange(new Range(4, 0, 4, 6))).toEqual([[notebook.cellAt(1), new Range(0, 0, 0, 6)]]);
130
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(1), [new Range(0, 0, 0, 6)])).toEqual([new OffsetRange(127, 133)]);
131
132
expect(altDocSnapshot.getText(new OffsetRange(134, 258))).toBe('pandas\nimport requests\n#%% vscode.cell [id=#VSC-8862d4f3] [language=python]\nprint("Hello World")\nprint("Foo Bar")\nprint("Bar');
133
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(134, 258))).toEqual([
134
[notebook.cellAt(1), new Range(0, 7, 1, 15)],
135
[notebook.cellAt(2), new Range(0, 0, 2, 10)],
136
]);
137
expect(altDocSnapshot.fromAltRange(new Range(4, 7, 9, 10))).toEqual([
138
[notebook.cellAt(1), new Range(0, 7, 1, 15)],
139
[notebook.cellAt(2), new Range(0, 0, 2, 10)],
140
]);
141
142
expect(altDocSnapshot.getText(new OffsetRange(134, 156))).toBe('pandas\nimport requests');
143
expect(notebook.cellAt(1).document.getText(new Range(0, 7, 1, 15))).toBe('pandas\nimport requests');
144
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(1), [new Range(0, 7, 1, 15)])).toEqual([new OffsetRange(134, 156)]);
145
expect(altDocSnapshot.getText(new OffsetRange(210, 258))).toBe('print("Hello World")\nprint("Foo Bar")\nprint("Bar');
146
expect(notebook.cellAt(2).document.getText(new Range(0, 0, 2, 10))).toBe('print("Hello World")\nprint("Foo Bar")\nprint("Bar');
147
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(2), [new Range(0, 0, 2, 10)])).toEqual([new OffsetRange(210, 258)]);
148
149
expect(altDocSnapshot.getText(new OffsetRange(210, 265))).toBe('print("Hello World")\nprint("Foo Bar")\nprint("Bar Baz")\n');
150
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(210, 265))).toEqual([[notebook.cellAt(2), new Range(0, 0, 2, 16)]]);
151
expect(altDocSnapshot.fromAltRange(new Range(7, 0, 10, 0))).toEqual([[notebook.cellAt(2), new Range(0, 0, 2, 16)]]);
152
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(2), [new Range(0, 0, 2, 16)])).toEqual([new OffsetRange(210, 264)]);
153
154
expect(altDocSnapshot.getText(new OffsetRange(318, 358))).toBe('print(sys.executable)\nprint(sys.version)');
155
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(318, 358))).toEqual([[notebook.cellAt(3), new Range(0, 0, 1, 18)]]);
156
expect(altDocSnapshot.fromAltRange(new Range(11, 0, 12, 18))).toEqual([[notebook.cellAt(3), new Range(0, 0, 1, 18)]]);
157
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(3), [new Range(0, 0, 1, 18)])).toEqual([new OffsetRange(318, 358)]);
158
159
expect(altDocSnapshot.getText(new OffsetRange(60, 349))).toBe('sys\nimport os\n#%% vscode.cell [id=#VSC-bdb3864a] [language=python]\nimport pandas\nimport requests\n#%% vscode.cell [id=#VSC-8862d4f3] [language=python]\nprint("Hello World")\nprint("Foo Bar")\nprint("Bar Baz")\n#%% vscode.cell [id=#VSC-e07487cb] [language=python]\nprint(sys.executable)\nprint(sys');
160
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(60, 349))).toEqual([
161
[notebook.cellAt(0), new Range(0, 7, 1, 9)],
162
[notebook.cellAt(1), new Range(0, 0, 1, 15)],
163
[notebook.cellAt(2), new Range(0, 0, 2, 16)],
164
[notebook.cellAt(3), new Range(0, 0, 1, 9)]
165
]);
166
expect(altDocSnapshot.fromAltRange(new Range(1, 7, 12, 9))).toEqual([
167
[notebook.cellAt(0), new Range(0, 7, 1, 9)],
168
[notebook.cellAt(1), new Range(0, 0, 1, 15)],
169
[notebook.cellAt(2), new Range(0, 0, 2, 16)],
170
[notebook.cellAt(3), new Range(0, 0, 1, 9)]
171
]);
172
});
173
test(`All cells have same EOL (with MD cells excluded)`, async () => {
174
const cells = [
175
new NotebookCellData(NotebookCellKind.Markup, '# This is a sample notebook', 'markdown'),
176
new NotebookCellData(NotebookCellKind.Markup, '## Header', 'markdown'),
177
new NotebookCellData(NotebookCellKind.Code, 'import sys\nimport os', 'python'),
178
new NotebookCellData(NotebookCellKind.Markup, 'Comments', 'markdown'),
179
new NotebookCellData(NotebookCellKind.Code, 'import pandas\nimport requests', 'python'),
180
new NotebookCellData(NotebookCellKind.Code, 'print("Hello World")\nprint("Foo Bar")\nprint("Bar Baz")', 'python'),
181
new NotebookCellData(NotebookCellKind.Code, 'print(sys.executable)\nprint(sys.version)', 'python'),
182
];
183
const { notebook, altDocSnapshot } = createNotebook(cells);
184
185
expect(altDocSnapshot.getText(new OffsetRange(53, 53))).toBe('');
186
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(53, 53))).toEqual([[notebook.cellAt(2), new Range(0, 0, 0, 0)]]);
187
expect(altDocSnapshot.fromAltRange(new Range(1, 0, 1, 0))).toEqual([[notebook.cellAt(2), new Range(0, 0, 0, 0)]]);
188
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(2), [new Range(0, 0, 0, 0)])).toEqual([new OffsetRange(53, 53)]);
189
190
expect(altDocSnapshot.getText(new OffsetRange(53, 59))).toBe('import');
191
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(53, 59))).toEqual([[notebook.cellAt(2), new Range(0, 0, 0, 6)]]);
192
expect(altDocSnapshot.fromAltRange(new Range(1, 0, 1, 6))).toEqual([[notebook.cellAt(2), new Range(0, 0, 0, 6)]]);
193
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(2), [new Range(0, 0, 0, 6)])).toEqual([new OffsetRange(53, 59)]);
194
195
expect(altDocSnapshot.getText(new OffsetRange(53, 64))).toBe('import sys\n');
196
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(53, 64))).toEqual([[notebook.cellAt(2), new Range(0, 0, 1, 0)]]);
197
expect(altDocSnapshot.fromAltRange(new Range(1, 0, 2, 0))).toEqual([[notebook.cellAt(2), new Range(0, 0, 1, 0)]]);
198
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(2), [new Range(0, 0, 1, 0)])).toEqual([new OffsetRange(53, 64)]);
199
200
expect(altDocSnapshot.getText(new OffsetRange(53, 73))).toBe('import sys\nimport os');
201
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(53, 73))).toEqual([[notebook.cellAt(2), new Range(0, 0, 1, 9)]]);
202
expect(altDocSnapshot.fromAltRange(new Range(1, 0, 2, 9))).toEqual([[notebook.cellAt(2), new Range(0, 0, 1, 9)]]);
203
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(2), [new Range(0, 0, 1, 9)])).toEqual([new OffsetRange(53, 73)]);
204
205
expect(altDocSnapshot.getText(new OffsetRange(53, 74))).toBe('import sys\nimport os\n');
206
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(53, 74))).toEqual([[notebook.cellAt(2), new Range(0, 0, 1, 9)]]);
207
expect(altDocSnapshot.fromAltRange(new Range(1, 0, 3, 0))).toEqual([[notebook.cellAt(2), new Range(0, 0, 1, 9)]]);
208
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(2), [new Range(0, 0, 1, 9)])).toEqual([new OffsetRange(53, 73)]);
209
210
// Translating alt text range across cells will only return contents of one cell.
211
expect(altDocSnapshot.getText(new OffsetRange(53, 140))).toBe('import sys\nimport os\n#%% vscode.cell [id=#VSC-53ab90bb] [language=python]\nimport pandas');
212
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(53, 140))).toEqual([[notebook.cellAt(2), new Range(0, 0, 1, 9)], [notebook.cellAt(4), new Range(0, 0, 0, 13)]]);
213
expect(altDocSnapshot.fromAltRange(new Range(1, 0, 4, 13))).toEqual([[notebook.cellAt(2), new Range(0, 0, 1, 9)], [notebook.cellAt(4), new Range(0, 0, 0, 13)]]);
214
215
expect(altDocSnapshot.getText(new OffsetRange(71, 73))).toBe('os');
216
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(71, 73))).toEqual([[notebook.cellAt(2), new Range(1, 7, 1, 9)]]);
217
expect(altDocSnapshot.fromAltRange(new Range(2, 7, 2, 9))).toEqual([[notebook.cellAt(2), new Range(1, 7, 1, 9)]]);
218
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(2), [new Range(1, 7, 1, 9)])).toEqual([new OffsetRange(71, 73)]);
219
220
expect(altDocSnapshot.getText(new OffsetRange(127, 127))).toBe('');
221
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(127, 127))).toEqual([[notebook.cellAt(4), new Range(0, 0, 0, 0)]]);
222
expect(altDocSnapshot.fromAltRange(new Range(4, 0, 4, 0))).toEqual([[notebook.cellAt(4), new Range(0, 0, 0, 0)]]);
223
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(4), [new Range(0, 0, 0, 0)])).toEqual([new OffsetRange(127, 127)]);
224
225
expect(altDocSnapshot.getText(new OffsetRange(127, 133))).toBe('import');
226
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(127, 133))).toEqual([[notebook.cellAt(4), new Range(0, 0, 0, 6)]]);
227
expect(altDocSnapshot.fromAltRange(new Range(4, 0, 4, 6))).toEqual([[notebook.cellAt(4), new Range(0, 0, 0, 6)]]);
228
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(4), [new Range(0, 0, 0, 6)])).toEqual([new OffsetRange(127, 133)]);
229
230
expect(altDocSnapshot.getText(new OffsetRange(134, 258))).toBe('pandas\nimport requests\n#%% vscode.cell [id=#VSC-749a8f95] [language=python]\nprint("Hello World")\nprint("Foo Bar")\nprint("Bar');
231
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(134, 258))).toEqual([
232
[notebook.cellAt(4), new Range(0, 7, 1, 15)],
233
[notebook.cellAt(5), new Range(0, 0, 2, 10)],
234
]);
235
expect(altDocSnapshot.fromAltRange(new Range(4, 7, 9, 10))).toEqual([
236
[notebook.cellAt(4), new Range(0, 7, 1, 15)],
237
[notebook.cellAt(5), new Range(0, 0, 2, 10)],
238
]);
239
240
expect(altDocSnapshot.getText(new OffsetRange(134, 156))).toBe('pandas\nimport requests');
241
expect(notebook.cellAt(4).document.getText(new Range(0, 7, 1, 15))).toBe('pandas\nimport requests');
242
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(4), [new Range(0, 7, 1, 15)])).toEqual([new OffsetRange(134, 156)]);
243
expect(altDocSnapshot.getText(new OffsetRange(210, 258))).toBe('print("Hello World")\nprint("Foo Bar")\nprint("Bar');
244
expect(notebook.cellAt(5).document.getText(new Range(0, 0, 2, 10))).toBe('print("Hello World")\nprint("Foo Bar")\nprint("Bar');
245
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(5), [new Range(0, 0, 2, 10)])).toEqual([new OffsetRange(210, 258)]);
246
247
expect(altDocSnapshot.getText(new OffsetRange(210, 265))).toBe('print("Hello World")\nprint("Foo Bar")\nprint("Bar Baz")\n');
248
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(210, 265))).toEqual([[notebook.cellAt(5), new Range(0, 0, 2, 16)]]);
249
expect(altDocSnapshot.fromAltRange(new Range(7, 0, 10, 0))).toEqual([[notebook.cellAt(5), new Range(0, 0, 2, 16)]]);
250
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(5), [new Range(0, 0, 2, 16)])).toEqual([new OffsetRange(210, 264)]);
251
252
expect(altDocSnapshot.getText(new OffsetRange(318, 358))).toBe('print(sys.executable)\nprint(sys.version)');
253
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(318, 358))).toEqual([[notebook.cellAt(6), new Range(0, 0, 1, 18)]]);
254
expect(altDocSnapshot.fromAltRange(new Range(11, 0, 12, 18))).toEqual([[notebook.cellAt(6), new Range(0, 0, 1, 18)]]);
255
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(6), [new Range(0, 0, 1, 18)])).toEqual([new OffsetRange(318, 358)]);
256
257
expect(altDocSnapshot.getText(new OffsetRange(60, 349))).toBe('sys\nimport os\n#%% vscode.cell [id=#VSC-53ab90bb] [language=python]\nimport pandas\nimport requests\n#%% vscode.cell [id=#VSC-749a8f95] [language=python]\nprint("Hello World")\nprint("Foo Bar")\nprint("Bar Baz")\n#%% vscode.cell [id=#VSC-d2139a72] [language=python]\nprint(sys.executable)\nprint(sys');
258
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(60, 349))).toEqual([
259
[notebook.cellAt(2), new Range(0, 7, 1, 9)],
260
[notebook.cellAt(4), new Range(0, 0, 1, 15)],
261
[notebook.cellAt(5), new Range(0, 0, 2, 16)],
262
[notebook.cellAt(6), new Range(0, 0, 1, 9)]
263
]);
264
expect(altDocSnapshot.fromAltRange(new Range(1, 7, 12, 9))).toEqual([
265
[notebook.cellAt(2), new Range(0, 7, 1, 9)],
266
[notebook.cellAt(4), new Range(0, 0, 1, 15)],
267
[notebook.cellAt(5), new Range(0, 0, 2, 16)],
268
[notebook.cellAt(6), new Range(0, 0, 1, 9)]
269
]);
270
});
271
test(`All cells have same EOL (with MD cells included)`, async () => {
272
const cells = [
273
new NotebookCellData(NotebookCellKind.Markup, '# This is a sample notebook', 'markdown'),
274
new NotebookCellData(NotebookCellKind.Markup, '## Header\n### Sub Heading', 'markdown'),
275
new NotebookCellData(NotebookCellKind.Code, 'import sys\nimport os', 'python'),
276
new NotebookCellData(NotebookCellKind.Markup, 'Comments', 'markdown'),
277
new NotebookCellData(NotebookCellKind.Code, 'import pandas\nimport requests', 'python'),
278
new NotebookCellData(NotebookCellKind.Code, 'print("Hello World")\nprint("Foo Bar")\nprint("Bar Baz")', 'python'),
279
new NotebookCellData(NotebookCellKind.Code, 'print(sys.executable)\nprint(sys.version)', 'python'),
280
];
281
const { notebook, altDocSnapshot } = createNotebook(cells, true);
282
283
expect(altDocSnapshot.getText(new OffsetRange(59, 59))).toBe('');
284
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(59, 59))).toEqual([[notebook.cellAt(0), new Range(0, 0, 0, 0)]]);
285
expect(altDocSnapshot.fromAltRange(new Range(2, 0, 2, 0))).toEqual([[notebook.cellAt(0), new Range(0, 0, 0, 0)]]);
286
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(0), [new Range(0, 0, 0, 0)])).toEqual([new OffsetRange(59, 59)]);
287
288
expect(altDocSnapshot.getText(new OffsetRange(59, 65))).toBe('# This');
289
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(59, 65))).toEqual([[notebook.cellAt(0), new Range(0, 0, 0, 6)]]);
290
expect(altDocSnapshot.fromAltRange(new Range(2, 0, 2, 6))).toEqual([[notebook.cellAt(0), new Range(0, 0, 0, 6)]]);
291
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(0), [new Range(0, 0, 0, 6)])).toEqual([new OffsetRange(59, 65)]);
292
293
expect(altDocSnapshot.getText(new OffsetRange(233, 244))).toBe('import sys\n');
294
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(233, 244))).toEqual([[notebook.cellAt(2), new Range(0, 0, 1, 0)]]);
295
expect(altDocSnapshot.fromAltRange(new Range(10, 0, 11, 0))).toEqual([[notebook.cellAt(2), new Range(0, 0, 1, 0)]]);
296
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(2), [new Range(0, 0, 1, 0)])).toEqual([new OffsetRange(233, 244)]);
297
298
expect(altDocSnapshot.getText(new OffsetRange(233, 253))).toBe('import sys\nimport os');
299
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(233, 253))).toEqual([[notebook.cellAt(2), new Range(0, 0, 1, 9)]]);
300
expect(altDocSnapshot.fromAltRange(new Range(10, 0, 11, 9))).toEqual([[notebook.cellAt(2), new Range(0, 0, 1, 9)]]);
301
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(2), [new Range(0, 0, 1, 9)])).toEqual([new OffsetRange(233, 253)]);
302
303
expect(altDocSnapshot.getText(new OffsetRange(233, 254))).toBe('import sys\nimport os\n');
304
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(233, 254))).toEqual([[notebook.cellAt(2), new Range(0, 0, 1, 9)]]);
305
expect(altDocSnapshot.fromAltRange(new Range(10, 0, 12, 0))).toEqual([[notebook.cellAt(2), new Range(0, 0, 1, 9)]]);
306
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(2), [new Range(0, 0, 1, 9)])).toEqual([new OffsetRange(233, 253)]);
307
308
// Translating alt text range across cells will only return contents of one cell.
309
expect(altDocSnapshot.getText(new OffsetRange(53, 254))).toBe(']\n"""\n# This is a sample notebook\n"""\n#%% vscode.cell [id=#VSC-bdb3864a] [language=markdown]\n"""\n## Header\n### Sub Heading\n"""\n#%% vscode.cell [id=#VSC-8862d4f3] [language=python]\nimport sys\nimport os\n');
310
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(53, 254))).toEqual([
311
[notebook.cellAt(0), new Range(0, 0, 0, 27)],
312
[notebook.cellAt(1), new Range(0, 0, 1, 15)],
313
[notebook.cellAt(2), new Range(0, 0, 1, 9)]
314
]);
315
expect(altDocSnapshot.fromAltRange(new Range(1, 0, 11, 13))).toEqual([
316
[notebook.cellAt(0), new Range(0, 0, 0, 27)],
317
[notebook.cellAt(1), new Range(0, 0, 1, 15)],
318
[notebook.cellAt(2), new Range(0, 0, 1, 9)]
319
]);
320
321
expect(altDocSnapshot.getText(new OffsetRange(251, 253))).toBe('os');
322
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(251, 253))).toEqual([[notebook.cellAt(2), new Range(1, 7, 1, 9)]]);
323
expect(altDocSnapshot.fromAltRange(new Range(11, 7, 11, 9))).toEqual([[notebook.cellAt(2), new Range(1, 7, 1, 9)]]);
324
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(2), [new Range(1, 7, 1, 9)])).toEqual([new OffsetRange(251, 253)]);
325
326
expect(altDocSnapshot.getText(new OffsetRange(379, 379))).toBe('');
327
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(379, 379))).toEqual([[notebook.cellAt(4), new Range(0, 0, 0, 0)]]);
328
expect(altDocSnapshot.fromAltRange(new Range(17, 0, 17, 0))).toEqual([[notebook.cellAt(4), new Range(0, 0, 0, 0)]]);
329
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(4), [new Range(0, 0, 0, 0)])).toEqual([new OffsetRange(379, 379)]);
330
331
expect(altDocSnapshot.getText(new OffsetRange(379, 385))).toBe('import');
332
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(379, 385))).toEqual([[notebook.cellAt(4), new Range(0, 0, 0, 6)]]);
333
expect(altDocSnapshot.fromAltRange(new Range(17, 0, 17, 6))).toEqual([[notebook.cellAt(4), new Range(0, 0, 0, 6)]]);
334
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(4), [new Range(0, 0, 0, 6)])).toEqual([new OffsetRange(379, 385)]);
335
336
expect(altDocSnapshot.getText(new OffsetRange(386, 510))).toBe('pandas\nimport requests\n#%% vscode.cell [id=#VSC-749a8f95] [language=python]\nprint("Hello World")\nprint("Foo Bar")\nprint("Bar');
337
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(386, 510))).toEqual([
338
[notebook.cellAt(4), new Range(0, 7, 1, 15)],
339
[notebook.cellAt(5), new Range(0, 0, 2, 10)],
340
]);
341
expect(altDocSnapshot.fromAltRange(new Range(17, 7, 22, 10))).toEqual([
342
[notebook.cellAt(4), new Range(0, 7, 1, 15)],
343
[notebook.cellAt(5), new Range(0, 0, 2, 10)],
344
]);
345
346
expect(altDocSnapshot.getText(new OffsetRange(386, 408))).toBe('pandas\nimport requests');
347
expect(notebook.cellAt(4).document.getText(new Range(0, 7, 1, 15))).toBe('pandas\nimport requests');
348
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(4), [new Range(0, 7, 1, 15)])).toEqual([new OffsetRange(386, 408)]);
349
expect(altDocSnapshot.getText(new OffsetRange(462, 510))).toBe('print("Hello World")\nprint("Foo Bar")\nprint("Bar');
350
expect(notebook.cellAt(5).document.getText(new Range(0, 0, 2, 10))).toBe('print("Hello World")\nprint("Foo Bar")\nprint("Bar');
351
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(5), [new Range(0, 0, 2, 10)])).toEqual([new OffsetRange(462, 510)]);
352
353
expect(altDocSnapshot.getText(new OffsetRange(462, 517))).toBe('print("Hello World")\nprint("Foo Bar")\nprint("Bar Baz")\n');
354
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(462, 517))).toEqual([[notebook.cellAt(5), new Range(0, 0, 2, 16)]]);
355
expect(altDocSnapshot.fromAltRange(new Range(20, 0, 23, 0))).toEqual([[notebook.cellAt(5), new Range(0, 0, 2, 16)]]);
356
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(5), [new Range(0, 0, 2, 16)])).toEqual([new OffsetRange(462, 516)]);
357
358
expect(altDocSnapshot.getText(new OffsetRange(570, 610))).toBe('print(sys.executable)\nprint(sys.version)');
359
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(570, 610))).toEqual([[notebook.cellAt(6), new Range(0, 0, 1, 18)]]);
360
expect(altDocSnapshot.fromAltRange(new Range(24, 0, 25, 18))).toEqual([[notebook.cellAt(6), new Range(0, 0, 1, 18)]]);
361
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(6), [new Range(0, 0, 1, 18)])).toEqual([new OffsetRange(570, 610)]);
362
363
expect(altDocSnapshot.getText(new OffsetRange(240, 601))).toBe('sys\nimport os\n#%% vscode.cell [id=#VSC-e07487cb] [language=markdown]\n"""\nComments\n"""\n#%% vscode.cell [id=#VSC-53ab90bb] [language=python]\nimport pandas\nimport requests\n#%% vscode.cell [id=#VSC-749a8f95] [language=python]\nprint("Hello World")\nprint("Foo Bar")\nprint("Bar Baz")\n#%% vscode.cell [id=#VSC-d2139a72] [language=python]\nprint(sys.executable)\nprint(sys');
364
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(240, 601))).toEqual([
365
[notebook.cellAt(2), new Range(0, 7, 1, 9)],
366
[notebook.cellAt(3), new Range(0, 0, 0, 8)],
367
[notebook.cellAt(4), new Range(0, 0, 1, 15)],
368
[notebook.cellAt(5), new Range(0, 0, 2, 16)],
369
[notebook.cellAt(6), new Range(0, 0, 1, 9)]
370
]);
371
expect(altDocSnapshot.fromAltRange(new Range(10, 7, 25, 9))).toEqual([
372
[notebook.cellAt(2), new Range(0, 7, 1, 9)],
373
[notebook.cellAt(3), new Range(0, 0, 0, 8)],
374
[notebook.cellAt(4), new Range(0, 0, 1, 15)],
375
[notebook.cellAt(5), new Range(0, 0, 2, 16)],
376
[notebook.cellAt(6), new Range(0, 0, 1, 9)]
377
]);
378
379
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(106, 177))).toEqual([[notebook.cellAt(1), new Range(0, 0, 1, 15)]]);
380
expect(altDocSnapshot.fromAltRange(new Range(24, 0, 25, 18))).toEqual([[notebook.cellAt(6), new Range(0, 0, 1, 18)]]);
381
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(6), [new Range(0, 0, 1, 18)])).toEqual([new OffsetRange(570, 610)]);
382
383
});
384
test(`All Cells have different EOLs`, async () => {
385
const cells = [
386
new NotebookCellData(NotebookCellKind.Code, 'import sys\nimport os', 'python'),
387
new NotebookCellData(NotebookCellKind.Code, 'import pandas\r\nimport requests', 'python'),
388
new NotebookCellData(NotebookCellKind.Code, 'print("Hello World")\r\nprint("Foo Bar")\r\nprint("Bar Baz")', 'python'),
389
new NotebookCellData(NotebookCellKind.Code, 'print(sys.executable)\nprint(sys.version)', 'python'),
390
];
391
const { notebook, altDocSnapshot } = createNotebook(cells);
392
393
394
expect(altDocSnapshot.getText(new OffsetRange(53, 59))).toBe('import');
395
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(53, 59))).toEqual([[notebook.cellAt(0), new Range(0, 0, 0, 6)]]);
396
expect(altDocSnapshot.fromAltRange(new Range(1, 0, 1, 6))).toEqual([[notebook.cellAt(0), new Range(0, 0, 0, 6)]]);
397
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(0), [new Range(0, 0, 0, 6)])).toEqual([new OffsetRange(53, 59)]);
398
399
expect(altDocSnapshot.getText(new OffsetRange(53, 64))).toBe('import sys\n');
400
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(53, 64))).toEqual([[notebook.cellAt(0), new Range(0, 0, 1, 0)]]);
401
expect(altDocSnapshot.fromAltRange(new Range(1, 0, 2, 0))).toEqual([[notebook.cellAt(0), new Range(0, 0, 1, 0)]]);
402
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(0), [new Range(0, 0, 1, 0)])).toEqual([new OffsetRange(53, 64)]);
403
404
expect(altDocSnapshot.getText(new OffsetRange(53, 74))).toBe('import sys\nimport os\n');
405
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(53, 74))).toEqual([[notebook.cellAt(0), new Range(0, 0, 1, 9)]]);
406
expect(altDocSnapshot.fromAltRange(new Range(1, 0, 2, 9))).toEqual([[notebook.cellAt(0), new Range(0, 0, 1, 9)]]);
407
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(0), [new Range(0, 0, 1, 9)])).toEqual([new OffsetRange(53, 73)]);
408
409
// Translating alt text range across cells will only return contents of one cell.
410
expect(altDocSnapshot.getText(new OffsetRange(53, 140))).toBe('import sys\nimport os\n#%% vscode.cell [id=#VSC-bdb3864a] [language=python]\nimport pandas');
411
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(53, 140))).toEqual([[notebook.cellAt(0), new Range(0, 0, 1, 9)], [notebook.cellAt(1), new Range(0, 0, 0, 13)]]);
412
expect(altDocSnapshot.fromAltRange(new Range(0, 0, 4, 13))).toEqual([[notebook.cellAt(0), new Range(0, 0, 1, 9)], [notebook.cellAt(1), new Range(0, 0, 0, 13)]]);
413
414
expect(altDocSnapshot.getText(new OffsetRange(71, 73))).toBe('os');
415
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(71, 73))).toEqual([[notebook.cellAt(0), new Range(1, 7, 1, 9)]]);
416
expect(altDocSnapshot.fromAltRange(new Range(2, 7, 2, 9))).toEqual([[notebook.cellAt(0), new Range(1, 7, 1, 9)]]);
417
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(0), [new Range(1, 7, 1, 9)])).toEqual([new OffsetRange(71, 73)]);
418
419
expect(altDocSnapshot.getText(new OffsetRange(134, 258))).toBe('pandas\nimport requests\n#%% vscode.cell [id=#VSC-8862d4f3] [language=python]\nprint("Hello World")\nprint("Foo Bar")\nprint("Bar');
420
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(134, 258))).toEqual([
421
[notebook.cellAt(1), new Range(0, 7, 1, 15)],
422
[notebook.cellAt(2), new Range(0, 0, 2, 10)],
423
]);
424
expect(altDocSnapshot.fromAltRange(new Range(4, 7, 9, 10))).toEqual([
425
[notebook.cellAt(1), new Range(0, 7, 1, 15)],
426
[notebook.cellAt(2), new Range(0, 0, 2, 10)],
427
]);
428
429
expect(altDocSnapshot.getText(new OffsetRange(134, 156))).toBe('pandas\nimport requests');
430
expect(notebook.cellAt(1).document.getText(new Range(0, 7, 1, 15))).toBe('pandas\r\nimport requests');
431
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(1), [new Range(0, 7, 1, 15)])).toEqual([new OffsetRange(134, 156)]);
432
expect(altDocSnapshot.getText(new OffsetRange(210, 258))).toBe('print("Hello World")\nprint("Foo Bar")\nprint("Bar');
433
expect(notebook.cellAt(2).document.getText(new Range(0, 0, 2, 10))).toBe('print("Hello World")\r\nprint("Foo Bar")\r\nprint("Bar');
434
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(2), [new Range(0, 0, 2, 10)])).toEqual([new OffsetRange(210, 258)]);
435
436
expect(altDocSnapshot.getText(new OffsetRange(210, 265))).toBe('print("Hello World")\nprint("Foo Bar")\nprint("Bar Baz")\n');
437
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(210, 265))).toEqual([[notebook.cellAt(2), new Range(0, 0, 2, 16)]]);
438
expect(altDocSnapshot.fromAltRange(new Range(7, 0, 9, 16))).toEqual([[notebook.cellAt(2), new Range(0, 0, 2, 16)]]);
439
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(2), [new Range(0, 0, 2, 16)])).toEqual([new OffsetRange(210, 264)]);
440
441
expect(altDocSnapshot.getText(new OffsetRange(318, 358))).toBe('print(sys.executable)\nprint(sys.version)');
442
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(318, 358))).toEqual([[notebook.cellAt(3), new Range(0, 0, 1, 18)]]);
443
expect(altDocSnapshot.fromAltRange(new Range(11, 0, 12, 18))).toEqual([[notebook.cellAt(3), new Range(0, 0, 1, 18)]]);
444
expect(altDocSnapshot.toAltOffsetRange(notebook.cellAt(3), [new Range(0, 0, 1, 18)])).toEqual([new OffsetRange(318, 358)]);
445
446
expect(altDocSnapshot.getText(new OffsetRange(60, 349))).toBe('sys\nimport os\n#%% vscode.cell [id=#VSC-bdb3864a] [language=python]\nimport pandas\nimport requests\n#%% vscode.cell [id=#VSC-8862d4f3] [language=python]\nprint("Hello World")\nprint("Foo Bar")\nprint("Bar Baz")\n#%% vscode.cell [id=#VSC-e07487cb] [language=python]\nprint(sys.executable)\nprint(sys');
447
expect(altDocSnapshot.fromAltOffsetRange(new OffsetRange(60, 349))).toEqual([
448
[notebook.cellAt(0), new Range(0, 7, 1, 9)],
449
[notebook.cellAt(1), new Range(0, 0, 1, 15)],
450
[notebook.cellAt(2), new Range(0, 0, 2, 16)],
451
[notebook.cellAt(3), new Range(0, 0, 1, 9)]
452
]);
453
expect(altDocSnapshot.fromAltRange(new Range(1, 7, 12, 9))).toEqual([
454
[notebook.cellAt(0), new Range(0, 7, 1, 9)],
455
[notebook.cellAt(1), new Range(0, 0, 1, 15)],
456
[notebook.cellAt(2), new Range(0, 0, 2, 16)],
457
[notebook.cellAt(3), new Range(0, 0, 1, 9)]
458
]);
459
460
});
461
});
462
describe('Cell Content Changes', () => {
463
describe('Cell with 1 line', () => {
464
const cells = [
465
new NotebookCellData(NotebookCellKind.Code, 'print("Hello World")', 'python'),
466
];
467
let altDocSnapshot: IAlternativeNotebookDocumentSnapshot;
468
let altDoc: IAlternativeNotebookDocument;
469
let notebook: NotebookDocument;
470
beforeEach(() => {
471
({ altDocSnapshot, altDoc, notebook } = createNotebook(cells));
472
});
473
function getUpdatedAltText(e: TextDocumentChangeEvent): string {
474
const newDoc = altDocSnapshot.withCellChanges(e.document, e.contentChanges);
475
const edit = toAltNotebookCellChangeEdit(altDocSnapshot, e.document, e.contentChanges);
476
const updatedAltText = newDoc.getText();
477
altDoc.applyCellChanges(e.document, e.contentChanges);
478
479
// Verify the alt text is updated correctly
480
expect(updatedAltText).toBe(edit!.apply(altDocSnapshot.getText()));
481
expect(updatedAltText).toBe(altDoc.getText());
482
483
return updatedAltText;
484
}
485
test(`replace line`, async () => {
486
expect(getUpdatedAltText({
487
document: notebook.cellAt(0).document,
488
reason: undefined,
489
detailedReason: {
490
source: 'cursor',
491
metadata: {}
492
},
493
contentChanges: [{
494
range: new Range(0, 0, 0, 20),
495
rangeOffset: 0,
496
rangeLength: 20,
497
text: '# Top level imports',
498
}]
499
})).toMatchSnapshot();
500
});
501
test(`replace text with smaller text`, async () => {
502
expect(getUpdatedAltText({
503
document: notebook.cellAt(0).document,
504
reason: undefined,
505
detailedReason: {
506
source: 'cursor',
507
metadata: {}
508
},
509
contentChanges: [{
510
range: new Range(0, 7, 0, 18),
511
rangeOffset: 7,
512
rangeLength: 11,
513
text: 'Foo Bar',
514
}]
515
})).toMatchSnapshot();
516
});
517
test(`replace text with larger text`, async () => {
518
expect(getUpdatedAltText({
519
document: notebook.cellAt(0).document,
520
reason: undefined,
521
detailedReason: {
522
source: 'cursor',
523
metadata: {}
524
},
525
contentChanges: [{
526
range: new Range(0, 7, 0, 18),
527
rangeOffset: 7,
528
rangeLength: 11,
529
text: 'This is a longer piece of text',
530
}]
531
})).toMatchSnapshot();
532
});
533
test(`replace while inserting a few lines`, async () => {
534
expect(getUpdatedAltText({
535
document: notebook.cellAt(0).document,
536
reason: undefined,
537
detailedReason: {
538
source: 'cursor',
539
metadata: {}
540
},
541
contentChanges: [{
542
range: new Range(0, 7, 0, 20),
543
rangeOffset: 7,
544
rangeLength: 13,
545
text: 'Foo Bar")\nprint("Another line")\nprint("Yet another line")',
546
}]
547
})).toMatchSnapshot();
548
});
549
test(`insert a few lines`, async () => {
550
expect(getUpdatedAltText({
551
document: notebook.cellAt(0).document,
552
reason: undefined,
553
detailedReason: {
554
source: 'cursor',
555
metadata: {}
556
},
557
contentChanges: [{
558
range: new Range(0, 20, 0, 20),
559
rangeOffset: 20,
560
rangeLength: 0,
561
text: '\nprint("Another line")\nprint("Yet another line")',
562
}]
563
})).toMatchSnapshot();
564
});
565
});
566
describe('Cell with multiple line (crlf)', () => {
567
const cells = [
568
new NotebookCellData(NotebookCellKind.Code, 'print("Hello World")\r\nprint("Foo Bar")\r\nprint("Bar Baz")\r\nprint("Something Else")', 'python'),
569
];
570
let altDocSnapshot: IAlternativeNotebookDocumentSnapshot;
571
let altDoc: IAlternativeNotebookDocument;
572
let notebook: NotebookDocument;
573
beforeEach(() => {
574
({ altDocSnapshot, altDoc, notebook } = createNotebook(cells));
575
});
576
function getUpdatedAltText(e: TextDocumentChangeEvent): string {
577
const newDoc = altDocSnapshot.withCellChanges(e.document, e.contentChanges);
578
const edit = toAltNotebookCellChangeEdit(altDocSnapshot, e.document, e.contentChanges);
579
const updatedAltText = newDoc.getText();
580
altDoc.applyCellChanges(e.document, e.contentChanges);
581
582
// Verify the alt text is updated correctly
583
expect(updatedAltText).toBe(edit!.apply(altDocSnapshot.getText()));
584
expect(updatedAltText).toBe(altDoc.getText());
585
return updatedAltText;
586
}
587
test(`replace line`, async () => {
588
expect(getUpdatedAltText({
589
document: notebook.cellAt(0).document,
590
reason: undefined,
591
detailedReason: {
592
source: 'cursor',
593
metadata: {}
594
},
595
contentChanges: [{
596
range: new Range(0, 0, 0, 20),
597
rangeOffset: 0,
598
rangeLength: 20,
599
text: '# Top level imports',
600
}]
601
})).toMatchSnapshot();
602
});
603
test(`replace multiple lines`, async () => {
604
expect(getUpdatedAltText({
605
document: notebook.cellAt(0).document,
606
reason: undefined,
607
detailedReason: {
608
source: 'cursor',
609
metadata: {}
610
},
611
contentChanges: [{
612
range: new Range(1, 7, 1, 14),
613
rangeOffset: 29,
614
rangeLength: 7,
615
text: 'Say Something',
616
}, {
617
range: new Range(0, 0, 0, 20),
618
rangeOffset: 0,
619
rangeLength: 20,
620
text: '# Top level print statements',
621
}]
622
})).toMatchSnapshot();
623
});
624
test(`replace text with smaller text`, async () => {
625
expect(getUpdatedAltText({
626
document: notebook.cellAt(0).document,
627
reason: undefined,
628
detailedReason: {
629
source: 'cursor',
630
metadata: {}
631
},
632
contentChanges: [{
633
range: new Range(0, 7, 0, 18),
634
rangeOffset: 7,
635
rangeLength: 11,
636
text: 'Foo Bar',
637
}]
638
})).toMatchSnapshot();
639
});
640
test(`replace text with larger text`, async () => {
641
expect(getUpdatedAltText({
642
document: notebook.cellAt(0).document,
643
reason: undefined,
644
detailedReason: {
645
source: 'cursor',
646
metadata: {}
647
},
648
contentChanges: [{
649
range: new Range(0, 7, 0, 18),
650
rangeOffset: 7,
651
rangeLength: 11,
652
text: 'This is a longer piece of text',
653
}]
654
})).toMatchSnapshot();
655
});
656
test(`replace while inserting a few lines`, async () => {
657
expect(getUpdatedAltText({
658
document: notebook.cellAt(0).document,
659
reason: undefined,
660
detailedReason: {
661
source: 'cursor',
662
metadata: {}
663
},
664
contentChanges: [{
665
range: new Range(0, 7, 0, 20),
666
rangeOffset: 7,
667
rangeLength: 13,
668
text: 'Foo Bar")\r\nprint("Another line")\r\nprint("Yet another line")',
669
}]
670
})).toMatchSnapshot();
671
});
672
test(`insert a few lines`, async () => {
673
expect(getUpdatedAltText({
674
document: notebook.cellAt(0).document,
675
reason: undefined,
676
detailedReason: {
677
source: 'cursor',
678
metadata: {}
679
},
680
contentChanges: [{
681
range: new Range(0, 20, 0, 20),
682
rangeOffset: 20,
683
rangeLength: 0,
684
text: '\nprint("Another line")\nprint("Yet another line")',
685
}]
686
})).toMatchSnapshot();
687
});
688
test(`remove a line`, async () => {
689
expect(getUpdatedAltText({
690
document: notebook.cellAt(0).document,
691
reason: undefined,
692
detailedReason: {
693
source: 'cursor',
694
metadata: {}
695
},
696
contentChanges: [{
697
range: new Range(0, 20, 1, 16),
698
rangeOffset: 20,
699
rangeLength: 18,
700
text: '',
701
}]
702
})).toMatchSnapshot();
703
});
704
test(`remove two lines`, async () => {
705
expect(getUpdatedAltText({
706
document: notebook.cellAt(0).document,
707
reason: undefined,
708
detailedReason: {
709
source: 'cursor',
710
metadata: {}
711
},
712
contentChanges: [{
713
range: new Range(0, 20, 2, 16),
714
rangeOffset: 20,
715
rangeLength: 36,
716
text: '',
717
}]
718
})).toMatchSnapshot();
719
});
720
test(`merge two lines`, async () => {
721
expect(getUpdatedAltText({
722
document: notebook.cellAt(0).document,
723
reason: undefined,
724
detailedReason: {
725
source: 'cursor',
726
metadata: {}
727
},
728
contentChanges: [{
729
range: new Range(0, 20, 1, 0),
730
rangeOffset: 20,
731
rangeLength: 2,
732
text: '',
733
}]
734
})).toMatchSnapshot();
735
});
736
});
737
describe('Cell with multiple line (lf)', () => {
738
const cells = [
739
new NotebookCellData(NotebookCellKind.Code, 'print("Hello World")\nprint("Foo Bar")\nprint("Bar Baz")\nprint("Something Else")', 'python'),
740
];
741
let altDocSnapshot: IAlternativeNotebookDocumentSnapshot;
742
let altDoc: IAlternativeNotebookDocument;
743
let notebook: NotebookDocument;
744
beforeEach(() => {
745
({ altDocSnapshot, altDoc, notebook } = createNotebook(cells));
746
});
747
function getUpdatedAltText(e: TextDocumentChangeEvent): string {
748
const newDoc = altDocSnapshot.withCellChanges(e.document, e.contentChanges);
749
const edit = toAltNotebookCellChangeEdit(altDocSnapshot, e.document, e.contentChanges);
750
altDoc.applyCellChanges(e.document, e.contentChanges);
751
752
const updatedAltText = newDoc.getText();
753
754
// Verify the alt text is updated correctly
755
expect(updatedAltText).toBe(edit!.apply(altDocSnapshot.getText()));
756
757
return updatedAltText;
758
}
759
test(`replace line`, async () => {
760
expect(getUpdatedAltText({
761
document: notebook.cellAt(0).document,
762
reason: undefined,
763
detailedReason: {
764
source: 'cursor',
765
metadata: {}
766
},
767
contentChanges: [{
768
range: new Range(0, 0, 0, 20),
769
rangeOffset: 0,
770
rangeLength: 20,
771
text: '# Top level imports',
772
}]
773
})).toMatchSnapshot();
774
});
775
test(`replace multiple lines`, async () => {
776
expect(getUpdatedAltText({
777
document: notebook.cellAt(0).document,
778
reason: undefined,
779
detailedReason: {
780
source: 'cursor',
781
metadata: {}
782
},
783
contentChanges: [{
784
range: new Range(1, 7, 1, 14),
785
rangeOffset: 28,
786
rangeLength: 7,
787
text: 'Say Something',
788
}, {
789
range: new Range(0, 0, 0, 20),
790
rangeOffset: 0,
791
rangeLength: 20,
792
text: '# Top level print statements',
793
}]
794
})).toMatchSnapshot();
795
});
796
test(`replace text with smaller text`, async () => {
797
expect(getUpdatedAltText({
798
document: notebook.cellAt(0).document,
799
reason: undefined,
800
detailedReason: {
801
source: 'cursor',
802
metadata: {}
803
},
804
contentChanges: [{
805
range: new Range(0, 7, 0, 18),
806
rangeOffset: 7,
807
rangeLength: 11,
808
text: 'Foo Bar',
809
}]
810
})).toMatchSnapshot();
811
});
812
test(`replace text with larger text`, async () => {
813
expect(getUpdatedAltText({
814
document: notebook.cellAt(0).document,
815
reason: undefined,
816
detailedReason: {
817
source: 'cursor',
818
metadata: {}
819
},
820
contentChanges: [{
821
range: new Range(0, 7, 0, 18),
822
rangeOffset: 7,
823
rangeLength: 11,
824
text: 'This is a longer piece of text',
825
}]
826
})).toMatchSnapshot();
827
});
828
test(`replace while inserting a few lines`, async () => {
829
expect(getUpdatedAltText({
830
document: notebook.cellAt(0).document,
831
reason: undefined,
832
detailedReason: {
833
source: 'cursor',
834
metadata: {}
835
},
836
contentChanges: [{
837
range: new Range(0, 7, 0, 20),
838
rangeOffset: 7,
839
rangeLength: 13,
840
text: 'Foo Bar")\nprint("Another line")\nprint("Yet another line")',
841
}]
842
})).toMatchSnapshot();
843
});
844
test(`insert a few lines`, async () => {
845
expect(getUpdatedAltText({
846
document: notebook.cellAt(0).document,
847
reason: undefined,
848
detailedReason: {
849
source: 'cursor',
850
metadata: {}
851
},
852
contentChanges: [{
853
range: new Range(0, 20, 0, 20),
854
rangeOffset: 20,
855
rangeLength: 0,
856
text: '\nprint("Another line")\nprint("Yet another line")',
857
}]
858
})).toMatchSnapshot();
859
});
860
test(`remove a line`, async () => {
861
expect(getUpdatedAltText({
862
document: notebook.cellAt(0).document,
863
reason: undefined,
864
detailedReason: {
865
source: 'cursor',
866
metadata: {}
867
},
868
contentChanges: [{
869
range: new Range(0, 20, 1, 16),
870
rangeOffset: 20,
871
rangeLength: 17,
872
text: '',
873
}]
874
})).toMatchSnapshot();
875
});
876
test(`remove two lines`, async () => {
877
expect(getUpdatedAltText({
878
document: notebook.cellAt(0).document,
879
reason: undefined,
880
detailedReason: {
881
source: 'cursor',
882
metadata: {}
883
},
884
contentChanges: [{
885
range: new Range(0, 20, 2, 16),
886
rangeOffset: 20,
887
rangeLength: 34,
888
text: '',
889
}]
890
})).toMatchSnapshot();
891
});
892
test(`merge two lines`, async () => {
893
expect(getUpdatedAltText({
894
document: notebook.cellAt(0).document,
895
reason: undefined,
896
detailedReason: {
897
source: 'cursor',
898
metadata: {}
899
},
900
contentChanges: [{
901
range: new Range(0, 20, 1, 0),
902
rangeOffset: 20,
903
rangeLength: 1,
904
text: '',
905
}]
906
})).toMatchSnapshot();
907
});
908
});
909
describe('Cells with multiple line (lf)', () => {
910
const cells = [
911
new NotebookCellData(NotebookCellKind.Code, 'print("Foo Bar")', 'python'),
912
new NotebookCellData(NotebookCellKind.Code, 'print("Bar Baz")', 'python'),
913
new NotebookCellData(NotebookCellKind.Code, 'print("Hello World")\nprint("Foo Bar2")\nprint("Bar Baz2")\nprint("Something Else")', 'python'),
914
];
915
let altDocSnapshot: IAlternativeNotebookDocumentSnapshot;
916
let altDoc: IAlternativeNotebookDocument;
917
let notebook: NotebookDocument;
918
beforeEach(() => {
919
({ altDocSnapshot, altDoc, notebook } = createNotebook(cells));
920
});
921
function getUpdatedAltText(e: TextDocumentChangeEvent): string {
922
const newDoc = altDocSnapshot.withCellChanges(e.document, e.contentChanges);
923
const edit = toAltNotebookCellChangeEdit(altDocSnapshot, e.document, e.contentChanges);
924
const updatedAltText = newDoc.getText();
925
altDoc.applyCellChanges(e.document, e.contentChanges);
926
927
// Verify the alt text is updated correctly
928
expect(updatedAltText).toBe(edit!.apply(altDocSnapshot.getText()));
929
expect(updatedAltText).toBe(altDoc.getText());
930
931
return updatedAltText;
932
}
933
test(`replace text in last cell`, async () => {
934
expect(getUpdatedAltText({
935
document: notebook.cellAt(2).document,
936
reason: undefined,
937
detailedReason: {
938
source: 'cursor',
939
metadata: {}
940
},
941
contentChanges: [{
942
range: new Range(0, 7, 0, 18),
943
rangeOffset: 7,
944
rangeLength: 11,
945
text: 'Bye bye World',
946
}]
947
})).toMatchSnapshot();
948
});
949
// test(`replace multiple lines`, async () => {
950
// expect(getUpdatedAltText({
951
// document: notebook.cellAt(0).document,
952
// reason: undefined,
953
// detailedReason: {
954
// source: 'cursor',
955
// metadata: {}
956
// },
957
// contentChanges: [{
958
// range: new Range(1, 7, 1, 14),
959
// rangeOffset: 28,
960
// rangeLength: 7,
961
// text: 'Say Something',
962
// }, {
963
// range: new Range(0, 0, 0, 20),
964
// rangeOffset: 0,
965
// rangeLength: 20,
966
// text: '# Top level print statements',
967
// }]
968
// })).toMatchSnapshot();
969
// });
970
// test(`replace text with smaller text`, async () => {
971
// expect(getUpdatedAltText({
972
// document: notebook.cellAt(0).document,
973
// reason: undefined,
974
// detailedReason: {
975
// source: 'cursor',
976
// metadata: {}
977
// },
978
// contentChanges: [{
979
// range: new Range(0, 7, 0, 18),
980
// rangeOffset: 7,
981
// rangeLength: 11,
982
// text: 'Foo Bar',
983
// }]
984
// })).toMatchSnapshot();
985
// });
986
// test(`replace text with larger text`, async () => {
987
// expect(getUpdatedAltText({
988
// document: notebook.cellAt(0).document,
989
// reason: undefined,
990
// detailedReason: {
991
// source: 'cursor',
992
// metadata: {}
993
// },
994
// contentChanges: [{
995
// range: new Range(0, 7, 0, 18),
996
// rangeOffset: 7,
997
// rangeLength: 11,
998
// text: 'This is a longer piece of text',
999
// }]
1000
// })).toMatchSnapshot();
1001
// });
1002
// test(`replace while inserting a few lines`, async () => {
1003
// expect(getUpdatedAltText({
1004
// document: notebook.cellAt(0).document,
1005
// reason: undefined,
1006
// detailedReason: {
1007
// source: 'cursor',
1008
// metadata: {}
1009
// },
1010
// contentChanges: [{
1011
// range: new Range(0, 7, 0, 20),
1012
// rangeOffset: 7,
1013
// rangeLength: 13,
1014
// text: 'Foo Bar")\nprint("Another line")\nprint("Yet another line")',
1015
// }]
1016
// })).toMatchSnapshot();
1017
// });
1018
// test(`insert a few lines`, async () => {
1019
// expect(getUpdatedAltText({
1020
// document: notebook.cellAt(0).document,
1021
// reason: undefined,
1022
// detailedReason: {
1023
// source: 'cursor',
1024
// metadata: {}
1025
// },
1026
// contentChanges: [{
1027
// range: new Range(0, 20, 0, 20),
1028
// rangeOffset: 20,
1029
// rangeLength: 0,
1030
// text: '\nprint("Another line")\nprint("Yet another line")',
1031
// }]
1032
// })).toMatchSnapshot();
1033
// });
1034
// test(`remove a line`, async () => {
1035
// expect(getUpdatedAltText({
1036
// document: notebook.cellAt(0).document,
1037
// reason: undefined,
1038
// detailedReason: {
1039
// source: 'cursor',
1040
// metadata: {}
1041
// },
1042
// contentChanges: [{
1043
// range: new Range(0, 20, 1, 16),
1044
// rangeOffset: 20,
1045
// rangeLength: 17,
1046
// text: '',
1047
// }]
1048
// })).toMatchSnapshot();
1049
// });
1050
// test(`remove two lines`, async () => {
1051
// expect(getUpdatedAltText({
1052
// document: notebook.cellAt(0).document,
1053
// reason: undefined,
1054
// detailedReason: {
1055
// source: 'cursor',
1056
// metadata: {}
1057
// },
1058
// contentChanges: [{
1059
// range: new Range(0, 20, 2, 16),
1060
// rangeOffset: 20,
1061
// rangeLength: 34,
1062
// text: '',
1063
// }]
1064
// })).toMatchSnapshot();
1065
// });
1066
// test(`merge two lines`, async () => {
1067
// expect(getUpdatedAltText({
1068
// document: notebook.cellAt(0).document,
1069
// reason: undefined,
1070
// detailedReason: {
1071
// source: 'cursor',
1072
// metadata: {}
1073
// },
1074
// contentChanges: [{
1075
// range: new Range(0, 20, 1, 0),
1076
// rangeOffset: 20,
1077
// rangeLength: 1,
1078
// text: '',
1079
// }]
1080
// })).toMatchSnapshot();
1081
// });
1082
});
1083
});
1084
describe('Cell Add/Delete', () => {
1085
describe('Cell with 1 line', () => {
1086
const cells = [
1087
new NotebookCellData(NotebookCellKind.Code, 'print("Hello World")', 'python'),
1088
];
1089
let altDocSnapshot: IAlternativeNotebookDocumentSnapshot;
1090
let altDoc: IAlternativeNotebookDocument;
1091
let notebook: NotebookDocument;
1092
beforeEach(() => {
1093
({ altDocSnapshot, altDoc, notebook } = createNotebook(cells));
1094
});
1095
function getUpdatedAltText(e: NotebookDocumentContentChange[]): string {
1096
const originalText = altDocSnapshot.getText();
1097
const newDoc = altDocSnapshot.withNotebookChanges(e);
1098
const edit = toAltNotebookChangeEdit(altDocSnapshot, e);
1099
const updatedAltText = newDoc.getText();
1100
altDoc.applyNotebookChanges(e);
1101
if (edit) {
1102
// Verify the edit is generated correctly
1103
expect(edit.apply(originalText)).toBe(updatedAltText);
1104
}
1105
expect(altDoc.getText()).toBe(updatedAltText);
1106
return updatedAltText;
1107
}
1108
test(`remove cell`, async () => {
1109
expect(getUpdatedAltText([{
1110
addedCells: [],
1111
range: new NotebookRange(0, 1),
1112
removedCells: [notebook.cellAt(0)],
1113
}])).toMatchSnapshot();
1114
});
1115
test(`insert cell below`, async () => {
1116
const { notebook } = createNotebook(cells.concat([
1117
new NotebookCellData(NotebookCellKind.Code, 'print("Foo Bar")', 'python'),
1118
]));
1119
expect(getUpdatedAltText([{
1120
addedCells: [notebook.cellAt(1)],
1121
range: new NotebookRange(1, 1),
1122
removedCells: [],
1123
}])).toMatchSnapshot();
1124
});
1125
test(`insert a code cell and markdown cell`, async () => {
1126
const { notebook } = createNotebook(cells.concat([
1127
new NotebookCellData(NotebookCellKind.Code, 'print("Foo Bar")', 'python'),
1128
new NotebookCellData(NotebookCellKind.Markup, '# Foo Bar', 'markdown'),
1129
]));
1130
expect(getUpdatedAltText([{
1131
addedCells: [notebook.cellAt(1)],
1132
range: new NotebookRange(1, 1),
1133
removedCells: [],
1134
}])).toMatchSnapshot();
1135
});
1136
test(`insert a markdown cell`, async () => {
1137
const { notebook } = createNotebook(cells.concat([
1138
new NotebookCellData(NotebookCellKind.Markup, '# Foo Bar', 'markdown'),
1139
]));
1140
expect(getUpdatedAltText([{
1141
addedCells: [notebook.cellAt(1)],
1142
range: new NotebookRange(1, 1),
1143
removedCells: [],
1144
}])).toMatchSnapshot();
1145
});
1146
test(`insert cell above`, async () => {
1147
const { notebook } = createNotebook(cells.concat([
1148
new NotebookCellData(NotebookCellKind.Code, 'print("Foo Bar")', 'python'),
1149
]));
1150
expect(getUpdatedAltText([{
1151
addedCells: [notebook.cellAt(1)],
1152
range: new NotebookRange(0, 0),
1153
removedCells: [],
1154
}])).toMatchSnapshot();
1155
});
1156
test(`insert cells above`, async () => {
1157
const { notebook } = createNotebook(cells.concat([
1158
new NotebookCellData(NotebookCellKind.Code, 'print("Foo Bar")', 'python'),
1159
new NotebookCellData(NotebookCellKind.Code, 'print("Bar Baz")', 'python'),
1160
]));
1161
expect(getUpdatedAltText([{
1162
addedCells: [notebook.cellAt(1), notebook.cellAt(2)],
1163
range: new NotebookRange(0, 0),
1164
removedCells: [],
1165
}])).toMatchSnapshot();
1166
});
1167
test(`insert cells`, async () => {
1168
const { notebook } = createNotebook(cells.concat([
1169
new NotebookCellData(NotebookCellKind.Code, 'print("Foo Bar")', 'python'),
1170
new NotebookCellData(NotebookCellKind.Code, 'print("Bar Baz")', 'python'),
1171
]));
1172
expect(getUpdatedAltText([{
1173
addedCells: [notebook.cellAt(1), notebook.cellAt(2)],
1174
range: new NotebookRange(1, 1),
1175
removedCells: [],
1176
}])).toMatchSnapshot();
1177
});
1178
test(`remove and insert cell`, async () => {
1179
const { notebook } = createNotebook(cells.concat([
1180
new NotebookCellData(NotebookCellKind.Code, 'print("Foo Bar")', 'python'),
1181
]));
1182
expect(getUpdatedAltText([{
1183
addedCells: [notebook.cellAt(1)],
1184
range: new NotebookRange(0, 1),
1185
removedCells: [notebook.cellAt(0)],
1186
}])).toMatchSnapshot();
1187
});
1188
test(`remove and insert cells`, async () => {
1189
const { notebook } = createNotebook(cells.concat([
1190
new NotebookCellData(NotebookCellKind.Code, 'print("Foo Bar")', 'python'),
1191
new NotebookCellData(NotebookCellKind.Code, 'print("Bar Baz")', 'python'),
1192
]));
1193
expect(getUpdatedAltText([{
1194
addedCells: [notebook.cellAt(1), notebook.cellAt(2)],
1195
range: new NotebookRange(0, 1),
1196
removedCells: [notebook.cellAt(0)],
1197
}])).toMatchSnapshot();
1198
});
1199
});
1200
describe('Cell with multiple line (crlf)', () => {
1201
const cells = [
1202
new NotebookCellData(NotebookCellKind.Code, 'print("Hello World")', 'python'),
1203
new NotebookCellData(NotebookCellKind.Code, 'print("Hello World")\r\nprint("Foo Bar")\r\nprint("Bar Baz")\r\nprint("Something Else")', 'python'),
1204
];
1205
let altDocSnapshot: IAlternativeNotebookDocumentSnapshot;
1206
let altDoc: IAlternativeNotebookDocument;
1207
let notebook: NotebookDocument;
1208
beforeEach(() => {
1209
({ altDocSnapshot, altDoc, notebook } = createNotebook(cells));
1210
});
1211
function getUpdatedAltText(e: NotebookDocumentContentChange[]): string {
1212
const originalText = altDocSnapshot.getText();
1213
const newDoc = altDocSnapshot.withNotebookChanges(e);
1214
const edit = toAltNotebookChangeEdit(altDocSnapshot, e);
1215
altDoc.applyNotebookChanges(e);
1216
const updatedAltText = newDoc.getText();
1217
if (edit) {
1218
// Verify the edit is generated correctly
1219
expect(edit.apply(originalText)).toBe(updatedAltText);
1220
}
1221
expect(altDoc.getText()).toBe(updatedAltText);
1222
return updatedAltText;
1223
}
1224
test(`remove first cell`, async () => {
1225
expect(getUpdatedAltText([{
1226
addedCells: [],
1227
range: new NotebookRange(0, 1),
1228
removedCells: [notebook.cellAt(0)],
1229
}])).toMatchSnapshot();
1230
});
1231
test(`insert cell below`, async () => {
1232
const { notebook } = createNotebook(cells.concat([
1233
new NotebookCellData(NotebookCellKind.Code, 'print("Foo Bar")', 'python'),
1234
]));
1235
expect(getUpdatedAltText([{
1236
addedCells: [notebook.cellAt(2)],
1237
range: new NotebookRange(2, 2),
1238
removedCells: [],
1239
}])).toMatchSnapshot();
1240
});
1241
test(`insert cell middle`, async () => {
1242
const { notebook } = createNotebook(cells.concat([
1243
new NotebookCellData(NotebookCellKind.Code, 'print("Foo Bar")', 'python'),
1244
]));
1245
expect(getUpdatedAltText([{
1246
addedCells: [notebook.cellAt(2)],
1247
range: new NotebookRange(1, 1),
1248
removedCells: [],
1249
}])).toMatchSnapshot();
1250
});
1251
test(`insert cells middle`, async () => {
1252
const { notebook } = createNotebook(cells.concat([
1253
new NotebookCellData(NotebookCellKind.Code, 'print("Foo Bar")', 'python'),
1254
new NotebookCellData(NotebookCellKind.Code, '# Another Cell', 'python'),
1255
]));
1256
expect(getUpdatedAltText([{
1257
addedCells: [notebook.cellAt(2), notebook.cellAt(3)],
1258
range: new NotebookRange(1, 1),
1259
removedCells: [],
1260
}])).toMatchSnapshot();
1261
});
1262
test(`insert cell above`, async () => {
1263
const { notebook } = createNotebook(cells.concat([
1264
new NotebookCellData(NotebookCellKind.Code, 'print("Foo Bar")', 'python'),
1265
]));
1266
expect(getUpdatedAltText([{
1267
addedCells: [notebook.cellAt(1)],
1268
range: new NotebookRange(0, 0),
1269
removedCells: [],
1270
}])).toMatchSnapshot();
1271
});
1272
test(`insert cells above`, async () => {
1273
const { notebook } = createNotebook(cells.concat([
1274
new NotebookCellData(NotebookCellKind.Code, 'print("Foo Bar")', 'python'),
1275
new NotebookCellData(NotebookCellKind.Code, 'print("Bar Baz")', 'python'),
1276
]));
1277
expect(getUpdatedAltText([{
1278
addedCells: [notebook.cellAt(1), notebook.cellAt(2)],
1279
range: new NotebookRange(0, 0),
1280
removedCells: [],
1281
}])).toMatchSnapshot();
1282
});
1283
test(`insert cells`, async () => {
1284
const { notebook } = createNotebook(cells.concat([
1285
new NotebookCellData(NotebookCellKind.Code, 'print("Foo Bar")', 'python'),
1286
new NotebookCellData(NotebookCellKind.Code, 'print("Bar Baz")', 'python'),
1287
]));
1288
expect(getUpdatedAltText([{
1289
addedCells: [notebook.cellAt(1), notebook.cellAt(2)],
1290
range: new NotebookRange(1, 1),
1291
removedCells: [],
1292
}])).toMatchSnapshot();
1293
});
1294
test(`remove and insert cell`, async () => {
1295
const { notebook } = createNotebook(cells.concat([
1296
new NotebookCellData(NotebookCellKind.Code, 'print("Foo Bar")', 'python'),
1297
]));
1298
expect(getUpdatedAltText([{
1299
addedCells: [notebook.cellAt(1)],
1300
range: new NotebookRange(0, 1),
1301
removedCells: [notebook.cellAt(0)],
1302
}])).toMatchSnapshot();
1303
});
1304
test(`remove and insert cells`, async () => {
1305
const { notebook } = createNotebook(cells.concat([
1306
new NotebookCellData(NotebookCellKind.Code, 'print("Foo Bar")', 'python'),
1307
new NotebookCellData(NotebookCellKind.Code, 'print("Bar Baz")', 'python'),
1308
]));
1309
expect(getUpdatedAltText([{
1310
addedCells: [notebook.cellAt(1), notebook.cellAt(2)],
1311
range: new NotebookRange(0, 1),
1312
removedCells: [notebook.cellAt(0)],
1313
}])).toMatchSnapshot();
1314
});
1315
});
1316
});
1317
});
1318
1319