Skip to content

Commit 6511313

Browse files
test(vfs): comprehensive writeFile + delete/rename/stat/watch coverage (#365)
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
1 parent f6ee4a2 commit 6511313

1 file changed

Lines changed: 137 additions & 0 deletions

File tree

tests/unit/virtualFileSystem.test.ts

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,4 +176,141 @@ describe('SQLiteFileSystemProvider', () => {
176176
}, /FileNotFound/);
177177
});
178178
});
179+
describe('writeFile', () => {
180+
const provider = new SQLiteFileSystemProvider();
181+
const docKey = 'test-doc';
182+
183+
it('should throw NoPermissions if writing to __create__.sql', async () => {
184+
setupMockDocument(docKey, {});
185+
const uri = vscode.Uri.parse(`vscode-sqlite://${docKey}/users/group/__create__.sql/create.sql`);
186+
await assert.rejects(async () => {
187+
await provider.writeFile(uri, new Uint8Array(), { create: false, overwrite: true });
188+
}, (err: any) => err.message.includes('Cannot edit CREATE statement directly'));
189+
});
190+
191+
it('should throw Unavailable for invalid row ID', async () => {
192+
setupMockDocument(docKey, {});
193+
const uri = vscode.Uri.parse(`vscode-sqlite://${docKey}/users/group/invalid-id/col.txt`);
194+
await assert.rejects(async () => {
195+
await provider.writeFile(uri, new Uint8Array(), { create: false, overwrite: true });
196+
}, (err: any) => err.message.includes('Invalid Row ID'));
197+
});
198+
199+
it('should map string error to Unavailable', async () => {
200+
const dbOps = {
201+
updateCell: mock.fn(async () => {
202+
throw 'Database write string error';
203+
})
204+
};
205+
setupMockDocument(docKey, dbOps);
206+
207+
const uri = vscode.Uri.parse(`vscode-sqlite://${docKey}/users/group/1/col.txt`);
208+
209+
await assert.rejects(async () => {
210+
await provider.writeFile(uri, new Uint8Array(), { create: false, overwrite: true });
211+
}, (err: any) => err.message.includes('Database write string error'));
212+
});
213+
214+
it('should map Error object to Unavailable', async () => {
215+
const dbOps = {
216+
updateCell: mock.fn(async () => {
217+
throw new Error('Database write error');
218+
})
219+
};
220+
setupMockDocument(docKey, dbOps);
221+
222+
const uri = vscode.Uri.parse(`vscode-sqlite://${docKey}/users/group/1/col.txt`);
223+
224+
await assert.rejects(async () => {
225+
await provider.writeFile(uri, new Uint8Array(), { create: false, overwrite: true });
226+
}, (err: any) => err.message.includes('Database write error'));
227+
});
228+
229+
it('should write text content correctly', async () => {
230+
const dbOps = {
231+
updateCell: mock.fn(async () => {})
232+
};
233+
const doc = setupMockDocument(docKey, dbOps);
234+
235+
const uri = vscode.Uri.parse(`vscode-sqlite://${docKey}/users/group/1/col.txt`);
236+
const content = new TextEncoder().encode('Hello World');
237+
await provider.writeFile(uri, content, { create: false, overwrite: true });
238+
239+
assert.strictEqual(dbOps.updateCell.mock.callCount(), 1);
240+
assert.deepStrictEqual(dbOps.updateCell.mock.calls[0].arguments, ['users', 1, 'col', 'Hello World']);
241+
assert.strictEqual(doc.recordExternalModification.mock.callCount(), 1);
242+
});
243+
244+
it('should write binary content if not valid UTF-8', async () => {
245+
const dbOps = {
246+
updateCell: mock.fn(async () => {})
247+
};
248+
const doc = setupMockDocument(docKey, dbOps);
249+
250+
const uri = vscode.Uri.parse(`vscode-sqlite://${docKey}/users/group/1/col.txt`);
251+
const content = new Uint8Array([0xff, 0xff, 0xff]); // Invalid UTF-8
252+
await provider.writeFile(uri, content, { create: false, overwrite: true });
253+
254+
assert.strictEqual(dbOps.updateCell.mock.callCount(), 1);
255+
assert.deepStrictEqual(dbOps.updateCell.mock.calls[0].arguments, ['users', 1, 'col', content]);
256+
assert.strictEqual(doc.recordExternalModification.mock.callCount(), 1);
257+
});
258+
});
259+
260+
describe('delete / rename / stat / watch', () => {
261+
const provider = new SQLiteFileSystemProvider();
262+
const docKey = 'test-doc';
263+
264+
it('should throw NoPermissions for createDirectory', async () => {
265+
const uri = vscode.Uri.parse(`vscode-sqlite://${docKey}/users/group`);
266+
await assert.rejects(async () => {
267+
await provider.createDirectory(uri);
268+
}, (err: any) => err.message.includes('NoPermissions'));
269+
});
270+
271+
it('should return empty array for readDirectory', async () => {
272+
const uri = vscode.Uri.parse(`vscode-sqlite://${docKey}/users/group`);
273+
const res = await provider.readDirectory(uri);
274+
assert.deepStrictEqual(res, []);
275+
});
276+
277+
it('stat should return generic file stat for normal cell', async () => {
278+
const uri = vscode.Uri.parse(`vscode-sqlite://${docKey}/users/group/1/col.txt`);
279+
setupMockDocument(docKey, {});
280+
const s = await provider.stat(uri);
281+
assert.strictEqual(s.type, vscode.FileType.File);
282+
assert.strictEqual(s.size, 0);
283+
assert.strictEqual(s.permissions, undefined);
284+
});
285+
286+
it('stat should return generic file stat with Readonly for __create__.sql', async () => {
287+
const uri = vscode.Uri.parse(`vscode-sqlite://${docKey}/users/group/__create__.sql/create.sql`);
288+
setupMockDocument(docKey, {});
289+
const s = await provider.stat(uri);
290+
assert.strictEqual(s.type, vscode.FileType.File);
291+
assert.strictEqual(s.size, 0);
292+
assert.strictEqual(s.permissions, vscode.FilePermission.Readonly);
293+
});
294+
295+
it('watch should return a generic Disposable', async () => {
296+
const uri = vscode.Uri.parse(`vscode-sqlite://${docKey}/users/group/1/col.txt`);
297+
const disposable = provider.watch(uri, { recursive: false, excludes: [] });
298+
assert.ok(disposable.dispose);
299+
});
300+
301+
it('should throw NoPermissions for delete', async () => {
302+
const uri = vscode.Uri.parse(`vscode-sqlite://${docKey}/users/group/1/col.txt`);
303+
await assert.rejects(async () => {
304+
await provider.delete(uri, { recursive: false });
305+
}, (err: any) => err.message.includes('NoPermissions'));
306+
});
307+
308+
it('should throw NoPermissions for rename', async () => {
309+
const uri1 = vscode.Uri.parse(`vscode-sqlite://${docKey}/users/group/1/col.txt`);
310+
const uri2 = vscode.Uri.parse(`vscode-sqlite://${docKey}/users/group/1/col2.txt`);
311+
await assert.rejects(async () => {
312+
await provider.rename(uri1, uri2, { overwrite: true });
313+
}, (err: any) => err.message.includes('NoPermissions'));
314+
});
315+
});
179316
});

0 commit comments

Comments
 (0)