fileStorage: add file create option

When opening a file, sometimes we want to create it if it does not
exist and sometimes we don't.
This commit is contained in:
David Lechner
2022-04-08 18:29:05 -05:00
parent e0a6926d01
commit 8ffaf64292
5 changed files with 44 additions and 33 deletions
+1 -1
View File
@@ -82,7 +82,7 @@ describe('per-editor sagas', () => {
saga.put(editorOpenFile('test.file'));
await expect(saga.take()).resolves.toEqual(
fileStorageOpen('test.file', 'w'),
fileStorageOpen('test.file', 'w', false),
);
});
+1 -1
View File
@@ -78,7 +78,7 @@ function* handleEditorOpenFile(
let closeRequested = false;
try {
yield* put(fileStorageOpen(action.fileName, 'w'));
yield* put(fileStorageOpen(action.fileName, 'w', false));
const { didOpen, didFailToOpen } = yield* race({
didOpen: take(fileStorageDidOpen.when((a) => a.path === action.fileName)),
+9 -5
View File
@@ -81,12 +81,16 @@ export const fileStorageDidRemoveItem = createAction((file: FileMetadata) => ({
* Action that requests to open a file in storage.
* @param path The file path.
* @param mode 'r' to open for reading or 'w' to open for writing.
* @param create If true, create the file if it does not exist.
*/
export const fileStorageOpen = createAction((path: string, mode: FileOpenMode) => ({
type: 'fileStorage.action.Open',
path,
mode,
}));
export const fileStorageOpen = createAction(
(path: string, mode: FileOpenMode, create: boolean) => ({
type: 'fileStorage.action.Open',
path,
mode,
create,
}),
);
/**
* Action that indicates that {@link fileStorageOpen} succeeded.
+26 -22
View File
@@ -89,7 +89,7 @@ async function setUpTestFile(saga: AsyncSaga): Promise<[FileMetadata, string]> {
const emptyFile: FileMetadata = { ...testFile, sha256: emptyFileSha256 };
saga.put(fileStorageOpen(testFilePath, 'w'));
saga.put(fileStorageOpen(testFilePath, 'w', true));
const didOpen = await saga.take();
@@ -165,7 +165,7 @@ describe('open', () => {
});
it('should fail to open for reading if file does not exist', async () => {
saga.put(fileStorageOpen('test.file', 'r'));
saga.put(fileStorageOpen('test.file', 'r', false));
await expect(saga.take()).resolves.toEqual(
fileStorageDidFailToOpen(
@@ -177,7 +177,7 @@ describe('open', () => {
describe('should open file for writing if file does not exist', () => {
beforeEach(async () => {
saga.put(fileStorageOpen('test.file', 'w'));
saga.put(fileStorageOpen('test.file', 'w', true));
await expect(saga.take()).resolves.toEqual(
fileStorageDidOpen('test.file', 0 as FD),
@@ -194,7 +194,7 @@ describe('open', () => {
describe('should fail to open if file is already open for writing', () => {
it.each<FileOpenMode>(['r', 'w'])('mode: %o', async (mode) => {
saga.put(fileStorageOpen('test.file', mode));
saga.put(fileStorageOpen('test.file', mode, true));
await expect(saga.take()).resolves.toEqual(
fileStorageDidFailToOpen(
@@ -218,7 +218,7 @@ describe('open', () => {
});
it.each<FileOpenMode>(['r', 'w'])('mode: %o', async (mode) => {
saga.put(fileStorageOpen('test.file', mode));
saga.put(fileStorageOpen('test.file', mode, false));
await expect(saga.take()).resolves.toEqual(
fileStorageDidOpen('test.file', 1 as FD),
@@ -229,13 +229,13 @@ describe('open', () => {
it('should allow multiple readers', async () => {
await setUpTestFile(saga);
saga.put(fileStorageOpen('test.file', 'r'));
saga.put(fileStorageOpen('test.file', 'r', false));
await expect(saga.take()).resolves.toEqual(
fileStorageDidOpen('test.file', 1 as FD),
);
saga.put(fileStorageOpen('test.file', 'r'));
saga.put(fileStorageOpen('test.file', 'r', false));
await expect(saga.take()).resolves.toEqual(
fileStorageDidOpen('test.file', 2 as FD),
@@ -245,13 +245,13 @@ describe('open', () => {
it('should fail to open for writing if already open for reading', async () => {
await setUpTestFile(saga);
saga.put(fileStorageOpen('test.file', 'r'));
saga.put(fileStorageOpen('test.file', 'r', false));
await expect(saga.take()).resolves.toEqual(
fileStorageDidOpen('test.file', 1 as FD),
);
saga.put(fileStorageOpen('test.file', 'w'));
saga.put(fileStorageOpen('test.file', 'w', false));
await expect(saga.take()).resolves.toEqual(
fileStorageDidFailToOpen(
@@ -262,7 +262,7 @@ describe('open', () => {
});
it('should allow calling close multiple times', async () => {
saga.put(fileStorageOpen('test.file', 'w'));
saga.put(fileStorageOpen('test.file', 'w', true));
await expect(saga.take()).resolves.toEqual(
fileStorageDidOpen('test.file', 0 as FD),
@@ -302,7 +302,7 @@ describe('read', () => {
it.each<FileOpenMode>(['r', 'w'])('mode: %o', async (mode) => {
const [, contents] = await setUpTestFile(saga);
saga.put(fileStorageOpen('test.file', mode));
saga.put(fileStorageOpen('test.file', mode, false));
await expect(saga.take()).resolves.toEqual(
fileStorageDidOpen('test.file', 1 as FD),
@@ -320,7 +320,7 @@ describe('read', () => {
it.each<FileOpenMode>(['r', 'w'])('mode: %o', async (mode) => {
await setUpTestFile(saga);
saga.put(fileStorageOpen('test.file', mode));
saga.put(fileStorageOpen('test.file', mode, false));
await expect(saga.take()).resolves.toEqual(
fileStorageDidOpen('test.file', 1 as FD),
@@ -357,7 +357,7 @@ describe('write', () => {
it('should write a file open for writing', async () => {
await setUpTestFile(saga);
saga.put(fileStorageOpen('test.file', 'w'));
saga.put(fileStorageOpen('test.file', 'w', false));
await expect(saga.take()).resolves.toEqual(
fileStorageDidOpen('test.file', 1 as FD),
@@ -371,7 +371,7 @@ describe('write', () => {
it('should fail to write a file open for reading', async () => {
await setUpTestFile(saga);
saga.put(fileStorageOpen('test.file', 'r'));
saga.put(fileStorageOpen('test.file', 'r', false));
await expect(saga.take()).resolves.toEqual(
fileStorageDidOpen('test.file', 1 as FD),
@@ -391,7 +391,7 @@ describe('write', () => {
it.each<FileOpenMode>(['r', 'w'])('mode: %o', async (mode) => {
await setUpTestFile(saga);
saga.put(fileStorageOpen('test.file', mode));
saga.put(fileStorageOpen('test.file', mode, false));
await expect(saga.take()).resolves.toEqual(
fileStorageDidOpen('test.file', 1 as FD),
@@ -426,7 +426,9 @@ describe('readFile', () => {
saga.put(fileStorageReadFile('test.file'));
await expect(saga.take()).resolves.toEqual(fileStorageOpen('test.file', 'r'));
await expect(saga.take()).resolves.toEqual(
fileStorageOpen('test.file', 'r', false),
);
});
it('should forward open error', async () => {
@@ -491,7 +493,9 @@ describe('writeFile', () => {
saga.put(fileStorageWriteFile('test.file', contents));
await expect(saga.take()).resolves.toEqual(fileStorageOpen('test.file', 'w'));
await expect(saga.take()).resolves.toEqual(
fileStorageOpen('test.file', 'w', true),
);
});
it('should forward open error', async () => {
@@ -570,7 +574,7 @@ describe('copyFile', () => {
});
it('should fail if new file is open', async () => {
saga.put(fileStorageOpen('new.file', 'w'));
saga.put(fileStorageOpen('new.file', 'w', true));
await expect(saga.take()).resolves.toEqual(
fileStorageDidOpen('new.file', 1 as FD),
);
@@ -586,7 +590,7 @@ describe('copyFile', () => {
});
it('should fail if new file exists', async () => {
saga.put(fileStorageOpen('new.file', 'w'));
saga.put(fileStorageOpen('new.file', 'w', true));
await expect(saga.take()).resolves.toEqual(
fileStorageDidOpen('new.file', 1 as FD),
);
@@ -642,7 +646,7 @@ describe('deleteFile', () => {
});
it('should fail if file is open', async () => {
saga.put(fileStorageOpen('test.file', 'r'));
saga.put(fileStorageOpen('test.file', 'r', false));
await expect(saga.take()).resolves.toEqual(
fileStorageDidOpen('test.file', 1 as FD),
@@ -696,7 +700,7 @@ describe('renameFile', () => {
});
it('should fail if file is open', async () => {
saga.put(fileStorageOpen('test.file', 'r'));
saga.put(fileStorageOpen('test.file', 'r', false));
await expect(saga.take()).resolves.toEqual(
fileStorageDidOpen('test.file', 1 as FD),
@@ -715,7 +719,7 @@ describe('renameFile', () => {
// there are two paths here that result in the same error
// the first is if the file is open, e.g. in another tab
saga.put(fileStorageOpen(newPath, 'w'));
saga.put(fileStorageOpen(newPath, 'w', true));
await expect(saga.take()).resolves.toEqual(
fileStorageDidOpen(newPath, 1 as FD),
+7 -4
View File
@@ -233,8 +233,8 @@ function* handleOpen(
return metadata.uuid;
}
// if reading, do not create a new file
if (action.mode === 'r') {
// don't create a new file if we were not asked to
if (!action.create) {
return;
}
@@ -394,7 +394,7 @@ function* handleWrite(
*/
function* handleReadFile(action: ReturnType<typeof fileStorageReadFile>): Generator {
try {
yield* put(fileStorageOpen(action.path, 'r'));
yield* put(fileStorageOpen(action.path, 'r', false));
const { didOpen, didFailToOpen } = yield* race({
didOpen: take(fileStorageDidOpen.when((a) => a.path === action.path)),
@@ -441,11 +441,14 @@ function* handleReadFile(action: ReturnType<typeof fileStorageReadFile>): Genera
/**
* Handle open, write, close action.
*
* If the file does not exist, a new file will be created.
*
* @param action The action that triggered this saga.
*/
function* handleWriteFile(action: ReturnType<typeof fileStorageWriteFile>): Generator {
try {
yield* put(fileStorageOpen(action.path, 'w'));
yield* put(fileStorageOpen(action.path, 'w', true));
const { didOpen, didFailToOpen } = yield* race({
didOpen: take(fileStorageDidOpen.when((a) => a.path === action.path)),