diff --git a/packages/data-sources/file-jsonl/test/index.test.ts b/packages/data-sources/file-jsonl/test/index.test.ts index eaff939..185c9f0 100644 --- a/packages/data-sources/file-jsonl/test/index.test.ts +++ b/packages/data-sources/file-jsonl/test/index.test.ts @@ -20,6 +20,8 @@ describe('prepareResource', () => { }); }); +const toJsonl = (dummyItems: unknown[]) => dummyItems.map((i) => JSON.stringify(i)).join('\n') + describe('methods', () => { const dummyItems = [ { @@ -39,7 +41,7 @@ describe('methods', () => { name: v.string(), }); let ds: DataSource>; - let mockGenerationStrategy; + let mockGenerationStrategy: Mock; beforeEach(() => { mockGenerationStrategy = vi.fn(); const r = resource(schema) @@ -55,9 +57,13 @@ describe('methods', () => { beforeEach(() => { const mockReadFile = readFile as Mock; - mockReadFile.mockReturnValueOnce( - dummyItems.map((i) => JSON.stringify(i)).join('\n') - ); + mockReadFile.mockReturnValueOnce(toJsonl(dummyItems)); + }); + + let mockWriteFile: Mock; + beforeEach(() => { + mockWriteFile = writeFile as Mock; + mockWriteFile.mockImplementationOnce(() => { /* noop */ }); }); describe('initialize', () => { @@ -94,7 +100,7 @@ describe('methods', () => { describe('getById', () => { it('works', async () => { - const item = await ds.getById('2'); + const item = await ds.getById('2'); // ID is always a string because it originates from URLs const expected = dummyItems.find((i) => i.id === 2); expect(item).toEqual(expected); }); @@ -103,6 +109,7 @@ describe('methods', () => { describe('getSingle', () => { it('works', async () => { if (typeof ds.getSingle !== 'function') { + // skip if data source doesn't offer this return; } const item = await ds.getSingle(); @@ -111,10 +118,83 @@ describe('methods', () => { }); }); - describe.todo('create'); - describe.todo('delete'); - describe.todo('emplace'); - describe.todo('patch'); + describe('create', () => { + it('works', async () => { + const data = { + // notice we don't have IDs here, as it is expected to be generated by newId() + name: 'foo' + }; + const newItem = await ds.create(data); + + expect(mockWriteFile).toBeCalledWith( + expect.any(String), + toJsonl([ + ...dummyItems, + data + ]) + ); + expect(newItem).toEqual(data); + }); + }); + + describe('delete', () => { + it('works', async () => { + await ds.delete('1'); + expect(mockWriteFile).toBeCalledWith( + expect.any(String), + toJsonl(dummyItems.filter((d) => d.id !== 1)), + ); + }); + }); + + describe('emplace', () => { + it('works', async () => { + const data = { + id: 2, + name: 'foo', + }; + const { id, ...etcData } = data; + const newItem = await ds.emplace( + id.toString(), + etcData, + ); + + expect(mockWriteFile).toBeCalledWith( + expect.any(String), + toJsonl(dummyItems.map((d) => + d.id === 2 + // ID will be defined last, since we are just writing to file, we need strict ordering + ? { ...etcData, id } + : d + )), + ); + expect(newItem).toEqual([data, false]); + }); + }); + + describe('patch', () => { + it('works', async () => { + const data = { + id: 2, + name: 'foo', + }; + const { id, ...etcData } = data; + const newItem = await ds.emplace( + id.toString(), + etcData, + ); + + expect(mockWriteFile).toBeCalledWith( + expect.any(String), + toJsonl(dummyItems.map((d) => + d.id === 2 + ? { ...etcData, id } + : d + )), + ); + expect(newItem).toBeDefined(); + }); + }); describe('newId', () => { it('works', async () => {