|
|
@@ -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<v.Output<typeof schema>>; |
|
|
|
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 () => { |
|
|
|