mirror of
https://github.com/pybricks/pybricks-code.git
synced 2026-09-12 09:36:27 +00:00
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:
@@ -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
@@ -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)),
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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)),
|
||||
|
||||
Reference in New Issue
Block a user