diff --git a/bunfig.toml b/bunfig.toml index 67811e5..08c06e2 100644 --- a/bunfig.toml +++ b/bunfig.toml @@ -1,5 +1,6 @@ [test] coverage = true +coverageSkipTestFiles = true coverageReporter = ['text', 'lcov'] coverageDir = './.coverage' preload = "./test.config.ts" diff --git a/src/components/table/dataset.spec.ts b/src/components/table/dataset.spec.ts new file mode 100644 index 0000000..e2fade5 --- /dev/null +++ b/src/components/table/dataset.spec.ts @@ -0,0 +1,133 @@ +import { describe, expect, it } from "bun:test"; +import { createDataSet } from "./dataset"; + +interface DataEntry { + id: string; + name: string; + amount: number; +}; +const defaultData: DataEntry[] = [ + { id: '1', name: 'a first name', amount: 30 }, + { id: '2', name: 'a second name', amount: 20 }, + { id: '3', name: 'a third name', amount: 10 }, +]; + +describe('dataset', () => { + describe('createDataset', () => { + it('can create an instance', async () => { + // Arrange + + // Act + const actual = createDataSet(defaultData); + + // Assert + expect(actual).toMatchObject({ data: defaultData }) + }); + + it('can sort by a property', async () => { + // Arrange + + // Act + const actual = createDataSet(defaultData, { sort: { by: 'amount', reversed: false } }); + + // Assert + expect(actual.nodes()).toEqual([ + expect.objectContaining({ key: 2 }), + expect.objectContaining({ key: 1 }), + expect.objectContaining({ key: 0 }), + ]) + }); + + it('can group by a property', async () => { + // Arrange + + // Act + const actual = createDataSet(defaultData, { group: { by: 'name' } }); + + // Assert + expect(actual).toEqual(expect.objectContaining({ data: defaultData })) + }); + + describe('mutate', () => { + it('mutates the value', async () => { + // Arrange + const dataset = createDataSet(defaultData); + + // Act + dataset.mutate(0, 'amount', 100); + + // Assert + expect(dataset.value[0]!.amount).toBe(100); + }); + }); + + describe('mutateEach', () => { + it('mutates all the entries', async () => { + // Arrange + const dataset = createDataSet(defaultData); + + // Act + dataset.mutateEach(entry => ({ ...entry, amount: entry.amount + 5 })); + + // Assert + expect(dataset.value).toEqual([ + expect.objectContaining({ amount: 35 }), + expect.objectContaining({ amount: 25 }), + expect.objectContaining({ amount: 15 }), + ]); + }); + }); + + describe('remove', () => { + it('removes the 2nd entry', async () => { + // Arrange + const dataset = createDataSet(defaultData); + + // Act + dataset.remove([1]); + + // Assert + expect(dataset.value[1]).toBeUndefined(); + }); + }); + + describe('insert', () => { + it('adds an entry to the dataset', async () => { + // Arrange + const dataset = createDataSet(defaultData); + + // Act + dataset.insert({ id: '4', name: 'name', amount: 100 }); + + // Assert + expect(dataset.value[3]).toEqual({ id: '4', name: 'name', amount: 100 }); + }); + }); + + describe('sort', () => { + it('can set the sorting', async () => { + // Arrange + const dataset = createDataSet(defaultData); + + // Act + dataset.sort({ by: 'id', reversed: true }); + + // Assert + expect(dataset.sorting).toEqual({ by: 'id', reversed: true }); + }); + }); + + describe('group', () => { + it('can set the grouping', async () => { + // Arrange + const dataset = createDataSet(defaultData); + + // Act + dataset.group({ by: 'id' }); + + // Assert + expect(dataset.grouping).toEqual({ by: 'id' }); + }); + }); + }); +}); \ No newline at end of file diff --git a/src/components/table/dataset.ts b/src/components/table/dataset.ts index 10dbba0..86082b6 100644 --- a/src/components/table/dataset.ts +++ b/src/components/table/dataset.ts @@ -39,10 +39,10 @@ export type Setter = export interface DataSet> { data: T[]; nodes: Accessor[]>; - value: Accessor<(T | undefined)[]>; mutations: Accessor; - sorting: Accessor | undefined>; - grouping: Accessor | undefined>; + readonly value: (T | undefined)[]; + readonly sorting: SortOptions | undefined; + readonly grouping: GroupOptions | undefined; mutate(index: number, prop: K, value: T[K]): void; mutateEach(setter: (value: T) => T): void; @@ -107,10 +107,16 @@ export const createDataSet = >(data: T[], initialO const set: DataSet = { data, nodes, - value: createMemo(() => state.value), + get value() { + return state.value; + }, mutations, - sorting, - grouping, + get sorting() { + return state.sorting; + }, + get grouping() { + return state.grouping; + }, mutate(index, prop, value) { setState('value', index, prop as any, value); diff --git a/src/components/table/table.spec.tsx b/src/components/table/table.spec.tsx new file mode 100644 index 0000000..24fe041 --- /dev/null +++ b/src/components/table/table.spec.tsx @@ -0,0 +1,15 @@ +import { describe, it, expect } from 'bun:test'; +import { render } from "@solidjs/testing-library" +import { Table } from './table'; +import { createDataSet } from './dataset'; + +type TableItem = {}; + +// describe('', () => { +// it('should render', async () => { +// const dataset = createDataSet([]); +// const result = render(() =>
); + +// expect(true).toBe(true); +// }); +// }); \ No newline at end of file diff --git a/src/components/table/table.tsx b/src/components/table/table.tsx index ff6b21f..4a35881 100644 --- a/src/components/table/table.tsx +++ b/src/components/table/table.tsx @@ -166,7 +166,7 @@ function Head(props: {}) { { ({ id, label, sortable }) => { - const sort = createMemo(() => table.rows().sorting()); + const sort = createMemo(() => table.rows().sorting); const by = String(id); const onPointerDown = (e: PointerEvent) => { diff --git a/src/features/file/grid.tsx b/src/features/file/grid.tsx index 43f933b..a6e5e0c 100644 --- a/src/features/file/grid.tsx +++ b/src/features/file/grid.tsx @@ -40,7 +40,7 @@ export function Grid(props: { class?: string, rows: Entry[], locales: string[], id: lang, label: lang, renderer: ({ row, column, value, mutate }) => { - const entry = rows().value()[row]!; + const entry = rows().value[row]!; return