|
1 | 1 | import assert from "assert"; |
2 | | -import {EventEmitter, TreeView} from "vscode"; |
| 2 | +import {EventEmitter, TreeView, Uri, window, workspace} from "vscode"; |
3 | 3 | import {mock, instance, when} from "ts-mockito"; |
4 | 4 | import {WorkspaceFsCommands} from "./WorkspaceFsCommands"; |
5 | 5 | import {WorkspaceFsEntity} from "../sdk-extensions"; |
@@ -134,7 +134,7 @@ describe("WorkspaceFsCommands – target folder resolution", () => { |
134 | 134 | }); |
135 | 135 |
|
136 | 136 | it("no element → targets root", async () => { |
137 | | - await commands.createFile(undefined); |
| 137 | + await commands.createFile(makeEntity(ROOT_PATH)); |
138 | 138 | assert.strictEqual(capturedRootPath, ROOT_PATH); |
139 | 139 | }); |
140 | 140 |
|
@@ -243,3 +243,107 @@ describe("WorkspaceFsCommands – target folder resolution", () => { |
243 | 243 | }); |
244 | 244 | }); |
245 | 245 | }); |
| 246 | + |
| 247 | +describe("WorkspaceFsCommands – createFile content", () => { |
| 248 | + const ROOT_PATH = "/Users/me"; |
| 249 | + |
| 250 | + let commands: WorkspaceFsCommands; |
| 251 | + let capturedCreate: {path: string; content: string} | undefined; |
| 252 | + |
| 253 | + // Stubbed globals are restored after each test. |
| 254 | + let originalShowInputBox: typeof window.showInputBox; |
| 255 | + let originalShowTextDocument: typeof window.showTextDocument; |
| 256 | + let originalOpenTextDocument: typeof workspace.openTextDocument; |
| 257 | + let originalFromPath: typeof WorkspaceFsEntity.fromPath; |
| 258 | + |
| 259 | + let inputName: string; |
| 260 | + |
| 261 | + beforeEach(() => { |
| 262 | + const mockConnectionManager = mock<ConnectionManager>(); |
| 263 | + when(mockConnectionManager.workspaceClient).thenReturn({} as any); |
| 264 | + |
| 265 | + // createDirWizard reads activeProjectUri to seed the input box. |
| 266 | + const mockWorkspaceFolderManager = mock<WorkspaceFolderManager>(); |
| 267 | + when(mockWorkspaceFolderManager.activeProjectUri).thenReturn( |
| 268 | + Uri.file("/tmp/project") |
| 269 | + ); |
| 270 | + |
| 271 | + commands = new WorkspaceFsCommands( |
| 272 | + instance(mockWorkspaceFolderManager), |
| 273 | + instance(mockConnectionManager), |
| 274 | + instance(mock<WorkspaceFsDataProvider>()), |
| 275 | + instance(mock<WorkspaceFsFileSystemProvider>()), |
| 276 | + new FakeTreeView() as unknown as TreeView<WorkspaceFsEntity> |
| 277 | + ); |
| 278 | + |
| 279 | + // Fake root that captures what doCreateFile writes. |
| 280 | + capturedCreate = undefined; |
| 281 | + const fakeRoot = { |
| 282 | + path: ROOT_PATH, |
| 283 | + createFile: async (path: string, content: string) => { |
| 284 | + capturedCreate = {path, content}; |
| 285 | + }, |
| 286 | + }; |
| 287 | + (commands as any).getValidRoot = async () => fakeRoot; |
| 288 | + |
| 289 | + // createDirWizard reads the filename from showInputBox. |
| 290 | + originalShowInputBox = window.showInputBox; |
| 291 | + (window as any).showInputBox = async () => inputName; |
| 292 | + |
| 293 | + // No pre-existing file → skip the overwrite prompt. |
| 294 | + originalFromPath = WorkspaceFsEntity.fromPath; |
| 295 | + (WorkspaceFsEntity as any).fromPath = async () => undefined; |
| 296 | + |
| 297 | + // Avoid actually opening an editor after creation. |
| 298 | + originalShowTextDocument = window.showTextDocument; |
| 299 | + (window as any).showTextDocument = async () => undefined; |
| 300 | + originalOpenTextDocument = workspace.openTextDocument; |
| 301 | + (workspace as any).openTextDocument = async (uri: Uri) => uri; |
| 302 | + }); |
| 303 | + |
| 304 | + afterEach(() => { |
| 305 | + (window as any).showInputBox = originalShowInputBox; |
| 306 | + (window as any).showTextDocument = originalShowTextDocument; |
| 307 | + (workspace as any).openTextDocument = originalOpenTextDocument; |
| 308 | + (WorkspaceFsEntity as any).fromPath = originalFromPath; |
| 309 | + }); |
| 310 | + |
| 311 | + it(".ipynb file is created with valid empty notebook JSON", async () => { |
| 312 | + inputName = "notebook.ipynb"; |
| 313 | + await commands.createFile(makeEntity(ROOT_PATH)); |
| 314 | + |
| 315 | + assert.ok(capturedCreate, "createFile should have been called"); |
| 316 | + assert.strictEqual(capturedCreate!.path, "notebook.ipynb"); |
| 317 | + |
| 318 | + const parsed = JSON.parse(capturedCreate!.content); |
| 319 | + assert.deepStrictEqual(parsed.cells, []); |
| 320 | + assert.strictEqual(parsed.nbformat, 4); |
| 321 | + assert.strictEqual(parsed.nbformat_minor, 5); |
| 322 | + assert.strictEqual(parsed.metadata.language_info.name, "python"); |
| 323 | + }); |
| 324 | + |
| 325 | + it(".IPYNB extension is matched case-insensitively", async () => { |
| 326 | + inputName = "NoteBook.IPYNB"; |
| 327 | + await commands.createFile(makeEntity(ROOT_PATH)); |
| 328 | + |
| 329 | + assert.ok(capturedCreate); |
| 330 | + const parsed = JSON.parse(capturedCreate!.content); |
| 331 | + assert.strictEqual(parsed.nbformat, 4); |
| 332 | + }); |
| 333 | + |
| 334 | + it(".py file is created with empty content", async () => { |
| 335 | + inputName = "script.py"; |
| 336 | + await commands.createFile(makeEntity(ROOT_PATH)); |
| 337 | + |
| 338 | + assert.ok(capturedCreate); |
| 339 | + assert.strictEqual(capturedCreate!.content, ""); |
| 340 | + }); |
| 341 | + |
| 342 | + it("plain file is created with empty content", async () => { |
| 343 | + inputName = "notes.txt"; |
| 344 | + await commands.createFile(makeEntity(ROOT_PATH)); |
| 345 | + |
| 346 | + assert.ok(capturedCreate); |
| 347 | + assert.strictEqual(capturedCreate!.content, ""); |
| 348 | + }); |
| 349 | +}); |
0 commit comments