diff --git a/packages/react-ui/src/components/HatchifyColumn/HatchifyColumn.test.tsx b/packages/react-ui/src/components/HatchifyColumn/HatchifyColumn.test.tsx new file mode 100644 index 000000000..cb55f0d5e --- /dev/null +++ b/packages/react-ui/src/components/HatchifyColumn/HatchifyColumn.test.tsx @@ -0,0 +1,22 @@ +import "@testing-library/jest-dom" +import { render } from "@testing-library/react" +import { describe, it } from "vitest" +import { assembler, integer } from "@hatchifyjs/core" +import { HatchifyColumn } from "./HatchifyColumn.js" + +describe("components/HatchifyColumn", () => { + const partialSchemas = { + Todo: { + name: "Todo", + attributes: { + importance: integer(), + }, + }, + } + + const finalSchemas = assembler(partialSchemas) + + it("HatchifyColumn renders", async () => { + render() + }) +}) diff --git a/packages/react-ui/src/components/HatchifyDataGrid/HatchifyDataGrid.test.tsx b/packages/react-ui/src/components/HatchifyDataGrid/HatchifyDataGrid.test.tsx new file mode 100644 index 000000000..0282bf064 --- /dev/null +++ b/packages/react-ui/src/components/HatchifyDataGrid/HatchifyDataGrid.test.tsx @@ -0,0 +1,59 @@ +import "@testing-library/jest-dom" +import { render } from "@testing-library/react" +import { describe, it } from "vitest" +import { assembler, integer } from "@hatchifyjs/core" +import { default as HatchifyDataGrid } from "./HatchifyDataGrid.js" +import hatchifyReactRest from "@hatchifyjs/react-rest" + +describe("components/HatchifyDataGrid", () => { + const partialSchemas = { + Todo: { + name: "Todo", + attributes: { + importance: integer(), + }, + }, + } + + const finalSchemas = assembler(partialSchemas) + + const fakeRestClient = hatchifyReactRest({ + version: 0, + completeSchemaMap: partialSchemas, + findAll: () => + Promise.resolve([ + { + records: [ + { + id: "1", + __schema: "Todo", + attributes: { + name: "foo", + created: "2021-01-01", + important: true, + }, + }, + ], + related: [], + }, + { + unpaginatedCount: 1, + }, + ]), + findOne: () => Promise.resolve({ record: {} as any, related: [] }), + createOne: () => Promise.resolve({ record: {} as any, related: [] }), + updateOne: () => Promise.resolve({ record: {} as any, related: [] }), + deleteOne: () => Promise.resolve(), + }) + + it("HatchifyDataGrid renders", async () => { + render( + , + ) + }) +}) diff --git a/packages/react-ui/src/components/HatchifyEmpty/HatchifyEmpty.test.tsx b/packages/react-ui/src/components/HatchifyEmpty/HatchifyEmpty.test.tsx new file mode 100644 index 000000000..f14ce278a --- /dev/null +++ b/packages/react-ui/src/components/HatchifyEmpty/HatchifyEmpty.test.tsx @@ -0,0 +1,10 @@ +import "@testing-library/jest-dom" +import { render } from "@testing-library/react" +import { describe, it } from "vitest" +import { HatchifyEmpty } from "./HatchifyEmpty.js" + +describe("components/HatchifyEverything/components/HatchifyEmpty", () => { + it("'HatchifyEmpty' renders", async () => { + render( ) + }) +}) diff --git a/packages/react-ui/src/components/HatchifyEverything/HatchifyEverything.test.tsx b/packages/react-ui/src/components/HatchifyEverything/HatchifyEverything.test.tsx new file mode 100644 index 000000000..59c3973e3 --- /dev/null +++ b/packages/react-ui/src/components/HatchifyEverything/HatchifyEverything.test.tsx @@ -0,0 +1,67 @@ +import "@testing-library/jest-dom" +import { render } from "@testing-library/react" +import { describe, it } from "vitest" +import { assembler, integer } from "@hatchifyjs/core" +import { HatchifyEverything } from "./HatchifyEverything.js" +import hatchifyReactRest from "@hatchifyjs/react-rest" + +describe("components/HatchifyEverything/components/HatchifyEverything", () => { + const partialSchemas = { + Todo: { + name: "Todo", + attributes: { + importance: integer(), + }, + }, + } + + const finalSchemas = assembler(partialSchemas) + + const fakeRestClient = hatchifyReactRest({ + version: 0, + completeSchemaMap: partialSchemas, + findAll: () => + Promise.resolve([ + { + records: [ + { + id: "1", + __schema: "Todo", + attributes: { + name: "foo", + created: "2021-01-01", + important: true, + }, + }, + ], + related: [], + }, + { + unpaginatedCount: 1, + }, + ]), + findOne: () => Promise.resolve({ record: {} as any, related: [] }), + createOne: () => Promise.resolve({ record: {} as any, related: [] }), + updateOne: () => Promise.resolve({ record: {} as any, related: [] }), + deleteOne: () => Promise.resolve(), + }) + it("'HatchifyEverything' renders", async () => { + render( + , + ) + }) + + it("'HatchifyEverything' renders with no schemas", async () => { + render( + , + ) + }) +}) diff --git a/packages/react-ui/src/components/HatchifyEverything/HatchifyEverything.tsx b/packages/react-ui/src/components/HatchifyEverything/HatchifyEverything.tsx index d8f17928b..61c193359 100644 --- a/packages/react-ui/src/components/HatchifyEverything/HatchifyEverything.tsx +++ b/packages/react-ui/src/components/HatchifyEverything/HatchifyEverything.tsx @@ -26,7 +26,7 @@ export interface HatchifyEverythingProps< minimumLoadTime?: number } -function HatchifyEverything< +export function HatchifyEverything< const TSchemas extends Record, >({ finalSchemas, ...rest }: HatchifyEverythingProps): JSX.Element { return ( diff --git a/packages/react-ui/src/components/HatchifyEverything/components/NoSchemas.test.tsx b/packages/react-ui/src/components/HatchifyEverything/components/NoSchemas.test.tsx new file mode 100644 index 000000000..a4a6b7fbd --- /dev/null +++ b/packages/react-ui/src/components/HatchifyEverything/components/NoSchemas.test.tsx @@ -0,0 +1,10 @@ +import "@testing-library/jest-dom" +import { render } from "@testing-library/react" +import { describe, it } from "vitest" +import { NoSchemas } from "./NoSchemas.js" + +describe("components/HatchifyEverything/components/NoSchemas", () => { + it("'NoSchemas' renders", async () => { + render() + }) +}) diff --git a/packages/react-ui/src/components/HatchifyEverything/components/WithSchemas.test.tsx b/packages/react-ui/src/components/HatchifyEverything/components/WithSchemas.test.tsx new file mode 100644 index 000000000..cfb9607d7 --- /dev/null +++ b/packages/react-ui/src/components/HatchifyEverything/components/WithSchemas.test.tsx @@ -0,0 +1,57 @@ +import "@testing-library/jest-dom" +import { render } from "@testing-library/react" +import { describe, it } from "vitest" +import { WithSchemas } from "./WithSchemas.js" +import { assembler, integer } from "@hatchifyjs/core" +import hatchifyReactRest from "@hatchifyjs/react-rest" + +describe("components/HatchifyEverything/components/WithSchemas", () => { + const partialSchemas = { + Todo: { + name: "Todo", + attributes: { + importance: integer(), + }, + }, + } + + const finalSchemas = assembler(partialSchemas) + + const fakeRestClient = hatchifyReactRest({ + version: 0, + completeSchemaMap: partialSchemas, + findAll: () => + Promise.resolve([ + { + records: [ + { + id: "1", + __schema: "Todo", + attributes: { + name: "foo", + created: "2021-01-01", + important: true, + }, + }, + ], + related: [], + }, + { + unpaginatedCount: 1, + }, + ]), + findOne: () => Promise.resolve({ record: {} as any, related: [] }), + createOne: () => Promise.resolve({ record: {} as any, related: [] }), + updateOne: () => Promise.resolve({ record: {} as any, related: [] }), + deleteOne: () => Promise.resolve(), + }) + it("'WithSchemas' renders", async () => { + render( + , + ) + }) +}) diff --git a/packages/react-ui/src/components/HatchifyPresentationProvider/DefaultDisplayComponents/DefaultDisplayComponents.test.tsx b/packages/react-ui/src/components/HatchifyPresentationProvider/DefaultDisplayComponents/DefaultDisplayComponents.test.tsx new file mode 100644 index 000000000..a8b859673 --- /dev/null +++ b/packages/react-ui/src/components/HatchifyPresentationProvider/DefaultDisplayComponents/DefaultDisplayComponents.test.tsx @@ -0,0 +1,117 @@ +import "@testing-library/jest-dom" +import { render, screen } from "@testing-library/react" +import { describe, it, expect } from "vitest" +import { + String, + StringList, + Number, + NumberList, + Boolean, + BooleanList, + Date, + DateList, + Relationship, + RelationshipList, +} from "./DefaultDisplayComponents.js" + +describe("components/HatchifyPresentationProvider/DefaultDisplayComponents/", () => { + it("String renders", async () => { + render() + + expect(screen.getByText("Hello")) + }) + + it("StringList renders", async () => { + render() + + expect(screen.getByText("Hello, Goodbye")) + }) + + it("Number renders", async () => { + render() + + expect(screen.getByText("1,000")) + }) + + it("NumberList renders", async () => { + render() + + expect(screen.getByText("1", { exact: false })) + expect(screen.getByText("1,000", { exact: false })) + expect(screen.getByText("2", { exact: false })) + }) + + it("Boolean renders", async () => { + render() + + expect(screen.getByText("true")) + }) + + it("BooleanList renders", async () => { + render() + + expect(screen.getByText("true, true, false")) + }) + + describe("Date renders", async () => { + it("dateOnly", async () => { + render() + expect(screen.getByText("1/17/2000")) + }) + it("full date", async () => { + render() + expect(screen.getByText("1/17/2000, 12:00:00 AM")) + }) + + it("value is invalid", async () => { + render() + expect(screen.queryByText("AM")).not.toBeInTheDocument() + expect(screen.queryByText("PM")).not.toBeInTheDocument() + }) + }) + + describe("DateList renders", async () => { + it("dateOnly", async () => { + render( + , + ) + expect(screen.getByText("1/1/2000", { exact: false })) + expect(screen.getByText("2/1/2000", { exact: false })) + expect(screen.getByText("3/1/2000", { exact: false })) + }) + + it("full date", async () => { + render( + , + ) + expect(screen.getByText("1/1/2000, 12:00:00 AM", { exact: false })) + expect(screen.getByText("2/1/2000, 12:00:00 AM", { exact: false })) + expect(screen.getByText("3/1/2000, 12:00:00 AM", { exact: false })) + }) + }) + + it("Relationship renders", async () => { + render( + , + ) + expect(screen.getByText("label")) + }) + + it("RelationshipList renders", async () => { + render( + , + ) + expect(screen.getByText("label, otherLabel")) + }) +}) diff --git a/packages/react-ui/src/components/HatchifyPresentationProvider/DefaultFieldComponents/DefaultFieldComponents.test.tsx b/packages/react-ui/src/components/HatchifyPresentationProvider/DefaultFieldComponents/DefaultFieldComponents.test.tsx new file mode 100644 index 000000000..0ca1f0792 --- /dev/null +++ b/packages/react-ui/src/components/HatchifyPresentationProvider/DefaultFieldComponents/DefaultFieldComponents.test.tsx @@ -0,0 +1,54 @@ +import "@testing-library/jest-dom" +import { render, screen } from "@testing-library/react" +import { describe, it, expect, vi } from "vitest" +import { + String, + Number, + Boolean, + Date, + Relationship, +} from "./DefaultFieldComponents.js" + +describe("components/HatchifyPresentationProvider/DefaultFieldComponents/", () => { + it("String renders", async () => { + render() + expect(screen.getByRole("textbox")).toHaveValue("Test") + expect(screen.getByText("Test Label", { exact: false })) + }) + + it("Number renders", async () => { + render() + expect(screen.getByRole("spinbutton")).toHaveValue(100) + expect(screen.getByText("Test Label", { exact: false })) + }) + + it("Boolean renders", async () => { + render() + expect(screen.getByRole("checkbox")).toBeChecked() + expect(screen.getByText("Test Label", { exact: false })) + }) + + it("Date renders", async () => { + render() + expect(screen.getByText("Test Label", { exact: false })) + }) + + it("Relationship renders", async () => { + render( + , + ) + + expect(screen.getByText("Test Label", { exact: false })) + expect(screen.getByLabelText("first")) + expect(screen.getByLabelText("second")) + }) +}) diff --git a/packages/react-ui/src/hatchifyReact/hatchifyReact.test.ts b/packages/react-ui/src/hatchifyReact/hatchifyReact.test.tsx similarity index 52% rename from packages/react-ui/src/hatchifyReact/hatchifyReact.test.ts rename to packages/react-ui/src/hatchifyReact/hatchifyReact.test.tsx index fbf168e5f..e1b052da1 100644 --- a/packages/react-ui/src/hatchifyReact/hatchifyReact.test.ts +++ b/packages/react-ui/src/hatchifyReact/hatchifyReact.test.tsx @@ -1,3 +1,5 @@ +import "@testing-library/jest-dom" +import { render } from "@testing-library/react" import { describe, it, expect } from "vitest" import type { RestClient } from "@hatchifyjs/rest-client" import { hatchifyReact } from "./hatchifyReact.js" @@ -5,25 +7,27 @@ import { integer, string } from "@hatchifyjs/core" describe("react-ui/hatchifyReact", () => { it("should return objects for each schema", () => { - const fakeDataSource: RestClient = { - completeSchemaMap: { - Article: { - name: "Article", - type: "Article", - attributes: { - title: string(), - body: string(), - }, + const schemas = { + Article: { + name: "Article", + type: "Article", + attributes: { + title: string(), + body: string(), }, - Person: { - name: "Person", - type: "Person", - attributes: { - name: string(), - age: integer(), - }, + }, + Person: { + name: "Person", + type: "Person", + attributes: { + name: string(), + age: integer(), }, }, + } + + const fakeDataSource: RestClient = { + completeSchemaMap: schemas, version: 0, findAll: () => Promise.resolve([{ records: [], related: [] }, {}]), findOne: () => Promise.resolve({ record: {} as any, related: [] }), @@ -130,4 +134,116 @@ describe("react-ui/hatchifyReact", () => { state: { Feature_Article: { useDataGridState: expect.any(Function) } }, }) }) + + it("should accept schemas with namespaces", () => { + const schemas = { + Feature_Article: { + name: "Article", + type: "Article", + namespace: "Feature", + attributes: { + title: string(), + body: string(), + }, + }, + } + + const fakeDataSource: RestClient = { + completeSchemaMap: schemas, + version: 0, + findAll: () => Promise.resolve([{ records: [], related: [] }, {}]), + findOne: () => Promise.resolve({ record: {} as any, related: [] }), + createOne: () => Promise.resolve({ record: {} as any, related: [] }), + updateOne: () => Promise.resolve({ record: {} as any, related: [] }), + deleteOne: () => Promise.resolve(), + } + + const api = hatchifyReact(fakeDataSource) + + expect(api).toEqual({ + Everything: expect.any(Function), + components: { + Feature_Article: { + DataGrid: expect.any(Function), + Column: expect.any(Function), + Empty: expect.any(Function), + }, + }, + model: { + Feature_Article: { + createOne: expect.any(Function), + deleteOne: expect.any(Function), + findAll: expect.any(Function), + findOne: expect.any(Function), + updateOne: expect.any(Function), + useCreateOne: expect.any(Function), + useDeleteOne: expect.any(Function), + useAll: expect.any(Function), + useOne: expect.any(Function), + useUpdateOne: expect.any(Function), + }, + }, + state: { Feature_Article: { useDataGridState: expect.any(Function) } }, + }) + + it("should do something else", () => { + const schemas = { + Feature_Article: { + name: "Article", + type: "Article", + namespace: "Feature", + attributes: { + title: string(), + body: string(), + }, + }, + } + + const fakeDataSource: RestClient = { + completeSchemaMap: schemas, + version: 0, + findAll: () => Promise.resolve([{ records: [], related: [] }, {}]), + findOne: () => Promise.resolve({ record: {} as any, related: [] }), + createOne: () => Promise.resolve({ record: {} as any, related: [] }), + updateOne: () => Promise.resolve({ record: {} as any, related: [] }), + deleteOne: () => Promise.resolve(), + } + + const hatchedReact = hatchifyReact(fakeDataSource) + + const { state } = hatchedReact + + expect(state.Feature_Article.useDataGridState()).not.toThrowError() + }) + + it("should render everything", () => { + const schemas = { + Feature_Article: { + name: "Article", + type: "Article", + namespace: "Feature", + attributes: { + title: string(), + body: string(), + }, + }, + } + + const fakeDataSource: RestClient = { + completeSchemaMap: schemas, + version: 0, + findAll: () => Promise.resolve([{ records: [], related: [] }, {}]), + findOne: () => Promise.resolve({ record: {} as any, related: [] }), + createOne: () => Promise.resolve({ record: {} as any, related: [] }), + updateOne: () => Promise.resolve({ record: {} as any, related: [] }), + deleteOne: () => Promise.resolve(), + } + + const hatchedReact = hatchifyReact(fakeDataSource) + + const { Everything } = hatchedReact + + render() + }) + }) }) diff --git a/packages/react-ui/src/hooks/useCompoundComponents/helpers/getColumn.test.tsx b/packages/react-ui/src/hooks/useCompoundComponents/helpers/getColumn.test.tsx index 4eeb67129..f7689ba35 100644 --- a/packages/react-ui/src/hooks/useCompoundComponents/helpers/getColumn.test.tsx +++ b/packages/react-ui/src/hooks/useCompoundComponents/helpers/getColumn.test.tsx @@ -1,4 +1,4 @@ -import { describe, it, expect } from "vitest" +import { describe, it, expect, vi } from "vitest" import { assembler, belongsTo, @@ -34,7 +34,7 @@ describe("hooks/useCompoundComponents/helpers/getColumn", () => { }, }) - it("works with attribute on base schema", () => { + it("returns a column given an attribute on base schema", () => { const column = getColumn({ finalSchemas: finalSchemas, schemaName: "Todo", @@ -55,7 +55,7 @@ describe("hooks/useCompoundComponents/helpers/getColumn", () => { }) }) - it("works with compoundComponentProps", () => { + it("return a column when given compoundComponentProps", () => { const column = getColumn({ finalSchemas: finalSchemas, schemaName: "Todo", @@ -78,30 +78,144 @@ describe("hooks/useCompoundComponents/helpers/getColumn", () => { }) }) - it("correctly sets headerOverride", () => { - const column = getColumn({ - finalSchemas: finalSchemas, - schemaName: "Todo", - field: "title", - key: "title", - control: finalSchemas.Todo.attributes.created.control, - compoundComponentProps: { - renderHeaderValue: () => null, - }, - defaultValueComponents: HatchifyPresentationDefaultValueComponents, + describe("correctly sets renderDataValue", () => { + const mockDataFunction = vi + .fn() + .mockImplementation(({ args, value }) => "Data") + + const mockDataComponent = (header: string) => { + return

{header}

+ } + + it("for when 'renderData' is given", () => { + const column = getColumn({ + finalSchemas: finalSchemas, + schemaName: "Todo", + field: "title", + key: "title", + control: finalSchemas.Todo.attributes.created.control, + compoundComponentProps: { + renderData: mockDataFunction, + }, + defaultValueComponents: HatchifyPresentationDefaultValueComponents, + }) + + expect(column.renderData("string" as any)).toBe("Data") }) - expect(column).toEqual({ - headerOverride: true, - sortable: true, - key: "title", - label: "Title", - renderData: expect.any(Function), - renderHeader: expect.any(Function), + it("for when 'renderDataValue' is given", () => { + const column = getColumn({ + finalSchemas: finalSchemas, + schemaName: "Todo", + field: "title", + key: "title", + control: finalSchemas.Todo.attributes.created.control, + compoundComponentProps: { + renderDataValue: mockDataFunction, + }, + defaultValueComponents: HatchifyPresentationDefaultValueComponents, + }) + + expect( + column.renderData({ record: { title: "something" } as any } as any), + ).toBe("Data") + }) + + it("for when 'DataValueComponent' is given, renders without error", () => { + const column = getColumn({ + finalSchemas: finalSchemas, + schemaName: "Todo", + field: "title", + key: "title", + control: finalSchemas.Todo.attributes.created.control, + compoundComponentProps: { + DataValueComponent: mockDataComponent, + }, + defaultValueComponents: HatchifyPresentationDefaultValueComponents, + }) + + column.renderData({ record: { title: "something" } as any } as any) + }) + }) + describe("correctly sets headerOverride", () => { + const mockHeaderFunction = vi + .fn() + .mockImplementation((args: unknown) => "Overidden Header") + + const mockComponent = (header: string) => { + return

{header}

+ } + + it("for when renderHeaderValue is null", () => { + const column = getColumn({ + finalSchemas: finalSchemas, + schemaName: "Todo", + field: "title", + key: "title", + control: finalSchemas.Todo.attributes.created.control, + compoundComponentProps: { + renderHeaderValue: () => null, + }, + defaultValueComponents: HatchifyPresentationDefaultValueComponents, + }) + + expect(column).toEqual({ + headerOverride: true, + sortable: true, + key: "title", + label: "Title", + renderData: expect.any(Function), + renderHeader: expect.any(Function), + }) + }) + + it("for when renderHeaderValue is given render function", () => { + const column = getColumn({ + finalSchemas: finalSchemas, + schemaName: "Todo", + field: "title", + key: "title", + control: finalSchemas.Todo.attributes.created.control, + compoundComponentProps: { + renderHeaderValue: mockHeaderFunction, + }, + defaultValueComponents: HatchifyPresentationDefaultValueComponents, + }) + + column.renderHeader("string" as any) + + expect(mockHeaderFunction).toBeCalled() + + // expect(column).toEqual({ + // headerOverride: true, + // sortable: true, + // key: "title", + // label: "Title", + // renderData: expect.any(Function), + // renderHeader: () => expect.any(Function), + // }) + }) + + it("for when HeaderValueComponent is given a component", () => { + const column = getColumn({ + finalSchemas: finalSchemas, + schemaName: "Todo", + field: "title", + key: "title", + control: finalSchemas.Todo.attributes.created.control, + compoundComponentProps: { + HeaderValueComponent: mockComponent, + }, + defaultValueComponents: HatchifyPresentationDefaultValueComponents, + }) + + column.renderHeader("string" as any) + + expect(mockHeaderFunction).toBeCalled() }) }) - it("works with additional column", () => { + it("returns Column when given an additional column prop", () => { const column = getColumn({ finalSchemas: finalSchemas, schemaName: "Todo", @@ -122,7 +236,7 @@ describe("hooks/useCompoundComponents/helpers/getColumn", () => { }) }) - it("works on relationship", () => { + it("returns a column when given a relationship", () => { const column = getColumn({ finalSchemas: finalSchemas, schemaName: "Todo", @@ -146,9 +260,8 @@ describe("hooks/useCompoundComponents/helpers/getColumn", () => { }) describe("hooks/useCompoundComponents/helpers/formatFieldAsLabel", () => { - it("works", () => { - // todo: should be `Camel Case` - expect(formatFieldAsLabel("camelCase")).toBe("CamelCase") + it("returns field names as Title Case for labeling", () => { + expect(formatFieldAsLabel("camelCase")).toBe("Camel Case") expect(formatFieldAsLabel("Singluar")).toBe("Singluar") }) }) diff --git a/packages/react-ui/src/hooks/useCompoundComponents/helpers/getColumn.tsx b/packages/react-ui/src/hooks/useCompoundComponents/helpers/getColumn.tsx index 702ac62c3..094962753 100644 --- a/packages/react-ui/src/hooks/useCompoundComponents/helpers/getColumn.tsx +++ b/packages/react-ui/src/hooks/useCompoundComponents/helpers/getColumn.tsx @@ -101,13 +101,10 @@ export function getColumn< } else { column.renderHeader = () => displayName } - return column } export function formatFieldAsLabel(field: string): string { - return field - .replace(/(^\w)/g, (g) => g[0].toUpperCase()) - .replace(/([-_]\w)/g, (g) => " " + g[1].toUpperCase()) - .trim() + const result = field.replace(/([A-Z])/g, " $1") + return (result.charAt(0).toUpperCase() + result.slice(1)).trim() } diff --git a/packages/react-ui/src/hooks/useCompoundComponents/helpers/getColumns.test.ts b/packages/react-ui/src/hooks/useCompoundComponents/helpers/getColumns.test.ts index 0214dbcba..9a642444d 100644 --- a/packages/react-ui/src/hooks/useCompoundComponents/helpers/getColumns.test.ts +++ b/packages/react-ui/src/hooks/useCompoundComponents/helpers/getColumns.test.ts @@ -35,7 +35,7 @@ describe("hooks/useCompoundComponents/helpers/getColumns", () => { } const finalSchemas = assembler(partialSchemas) - it("works with no children", () => { + it("returns Columns per given schema, and given no children", () => { expect( getColumns( finalSchemas, @@ -115,4 +115,35 @@ describe("hooks/useCompoundComponents/helpers/getColumns", () => { }, ]) }) + + describe("overwrite", () => { + it("returns extra columns when overwrite is true while given an Array of JSX.elements", () => { + const childArray = [ + { + key: "Extra Details", + type: { name: "Column" }, + props: { extra: "Extra Details" }, + }, + ] as JSX.Element[] + + expect( + getColumns( + finalSchemas, + "Todo", + HatchifyPresentationDefaultValueComponents, + true, + childArray, + ), + ).toEqual([ + { + headerOverride: false, + key: "extra-0", + label: "", + renderData: expect.any(Function), + renderHeader: expect.any(Function), + sortable: false, + }, + ]) + }) + }) }) diff --git a/packages/react-ui/src/hooks/useCompoundComponents/helpers/getColumnsFromSchema.test.ts b/packages/react-ui/src/hooks/useCompoundComponents/helpers/getColumnsFromSchema.test.ts index 9a227c54a..68a281203 100644 --- a/packages/react-ui/src/hooks/useCompoundComponents/helpers/getColumnsFromSchema.test.ts +++ b/packages/react-ui/src/hooks/useCompoundComponents/helpers/getColumnsFromSchema.test.ts @@ -35,7 +35,7 @@ describe("hooks/useCompoundComponents/helpers/getColumnsFromSchema", () => { } const finalSchemas = assembler(partialSchemas) - it("works", () => { + it("'getColumnsFromSchema' returns columns based on the given schema information", () => { expect( getColumnsFromSchema( finalSchemas, diff --git a/packages/react-ui/src/hooks/useCompoundComponents/helpers/getDefaultDataRender.test.ts b/packages/react-ui/src/hooks/useCompoundComponents/helpers/getDefaultDataRender.test.ts index d25ea3833..7ceeae308 100644 --- a/packages/react-ui/src/hooks/useCompoundComponents/helpers/getDefaultDataRender.test.ts +++ b/packages/react-ui/src/hooks/useCompoundComponents/helpers/getDefaultDataRender.test.ts @@ -35,7 +35,7 @@ describe("hooks/useCompoundComponents/helpers/getDefaultDataRender", () => { }, }) - it("works for attribute", () => { + it("when given a record for a matching attribute, properly renders it in column", () => { const columnRenderFn = getDefaultDataRender({ finalSchemas, schemaName: "Todo", @@ -51,7 +51,7 @@ describe("hooks/useCompoundComponents/helpers/getDefaultDataRender", () => { expect(columnRenderFn(record).props.value).toEqual("test") }) - it("returns empty string for attribute with no value", () => { + it("when no attribute matches, renders and empty string in column", () => { const columnRenderFn = getDefaultDataRender({ finalSchemas, schemaName: "Todo", @@ -67,7 +67,7 @@ describe("hooks/useCompoundComponents/helpers/getDefaultDataRender", () => { expect(columnRenderFn(record).props.value).toEqual("") }) - it("works for boolean attribute", () => { + it("when given a boolean attribute, properly renders it in column", () => { const columnRenderFn = getDefaultDataRender({ finalSchemas, schemaName: "Todo", @@ -84,7 +84,7 @@ describe("hooks/useCompoundComponents/helpers/getDefaultDataRender", () => { ).toEqual(true) }) - it("works for dateonly attribute", () => { + it("when given a 'dateonly' attribute, properly renders it in column", () => { const columnRenderFn = getDefaultDataRender({ finalSchemas, schemaName: "Todo", @@ -100,7 +100,7 @@ describe("hooks/useCompoundComponents/helpers/getDefaultDataRender", () => { expect(columnRenderFn(record).props.value).toEqual("2023-10-27T21") }) - it("works for relationship", () => { + it("when given a 'relationship' attribute, properly renders it in column", () => { const columnRenderFn = getDefaultDataRender({ finalSchemas, schemaName: "Todo", @@ -121,7 +121,7 @@ describe("hooks/useCompoundComponents/helpers/getDefaultDataRender", () => { }) }) - it("works for relationship with label", () => { + it("when given a 'relationship value with a label', properly renders it in column", () => { const columnRenderFn = getDefaultDataRender({ finalSchemas, schemaName: "Todo", diff --git a/packages/react-ui/src/hooks/useCompoundComponents/helpers/getEmptyList.test.tsx b/packages/react-ui/src/hooks/useCompoundComponents/helpers/getEmptyList.test.tsx index 47179c85a..d1a323a88 100644 --- a/packages/react-ui/src/hooks/useCompoundComponents/helpers/getEmptyList.test.tsx +++ b/packages/react-ui/src/hooks/useCompoundComponents/helpers/getEmptyList.test.tsx @@ -9,7 +9,7 @@ describe("hooks/useCompoundComponents/helpers/getEmptyList", () => { // environment. }) - it("falls back to default EmptyList", () => { + it("when given an empty list, falls back to default EmptyList", () => { const EmptyList = getEmptyList([]) expect(EmptyList).toBeInstanceOf(Function) diff --git a/packages/react-ui/src/hooks/useCompoundComponents/useCompoundComponents.test.tsx b/packages/react-ui/src/hooks/useCompoundComponents/useCompoundComponents.test.tsx new file mode 100644 index 000000000..ba539e85c --- /dev/null +++ b/packages/react-ui/src/hooks/useCompoundComponents/useCompoundComponents.test.tsx @@ -0,0 +1,36 @@ +import "@testing-library/jest-dom" +import { renderHook } from "@testing-library/react" +import { describe, it, expect } from "vitest" +import { assembler, integer } from "@hatchifyjs/core" +import useCompoundComponents from "./useCompoundComponents.js" + +describe("hooks/useCompoundComponents", () => { + const finalSchemas = assembler({ + Todo: { + name: "Todo", + attributes: { + importance: integer(), + }, + }, + }) + + it("hook returns compoundComponents", async () => { + const { result } = renderHook(() => + useCompoundComponents(finalSchemas, "Todo", false, null), + ) + + expect(result.current).toEqual({ + Empty: expect.any(Function), + columns: [ + { + headerOverride: false, + key: "importance", + label: "Importance", + renderData: expect.any(Function), + renderHeader: expect.any(Function), + sortable: true, + }, + ], + }) + }) +}) diff --git a/packages/react-ui/src/hooks/useDataGridState.test.ts b/packages/react-ui/src/hooks/useDataGridState.test.ts index f5a36d9dc..769ae7a9e 100644 --- a/packages/react-ui/src/hooks/useDataGridState.test.ts +++ b/packages/react-ui/src/hooks/useDataGridState.test.ts @@ -41,7 +41,7 @@ const fakeRestClient = hatchifyReactRest({ }) describe("useDataGridState", () => { - it("works", async () => { + it("renders a hook result containing DatagridState", async () => { const { result } = renderHook(() => useDataGridState(finalSchemas, partialSchemas, "Todo", fakeRestClient, { defaultSelected: { all: false, ids: [] }, diff --git a/packages/react-ui/src/hooks/useFilter.test.ts b/packages/react-ui/src/hooks/useFilter.test.ts index 806bab0b7..7e0d88009 100644 --- a/packages/react-ui/src/hooks/useFilter.test.ts +++ b/packages/react-ui/src/hooks/useFilter.test.ts @@ -2,8 +2,8 @@ import { describe, expect, it } from "vitest" import { renderHook, waitFor } from "@testing-library/react" import useFilter from "./useFilter.js" -describe("usePage", () => { - it("works", async () => { +describe("useFilter", () => { + it("renders hook result, and setFilter properly sets current state", async () => { const { result } = renderHook(() => useFilter()) expect(result.current.filter).toEqual(undefined) diff --git a/packages/react-ui/src/hooks/usePage.test.ts b/packages/react-ui/src/hooks/usePage.test.ts index b3ab5ba73..5ecc3807e 100644 --- a/packages/react-ui/src/hooks/usePage.test.ts +++ b/packages/react-ui/src/hooks/usePage.test.ts @@ -3,7 +3,7 @@ import { renderHook, waitFor } from "@testing-library/react" import usePage from "./usePage.js" describe("usePage", () => { - it("works", async () => { + it("renders hook, and setPage properly sets currentState", async () => { const { result } = renderHook(() => usePage()) expect(result.current.page).toEqual({ diff --git a/packages/react-ui/src/hooks/useSelected.test.ts b/packages/react-ui/src/hooks/useSelected.test.ts index 0d98a2f00..489f1f829 100644 --- a/packages/react-ui/src/hooks/useSelected.test.ts +++ b/packages/react-ui/src/hooks/useSelected.test.ts @@ -3,7 +3,7 @@ import { renderHook, waitFor } from "@testing-library/react" import useSelected from "./useSelected.js" describe("useSelected", () => { - it("works", async () => { + it("renders hook, and setSelected properly sets currentState", async () => { const onSelectCallback = vi.fn() const { result } = renderHook(() => useSelected({ all: false, ids: [] }, onSelectCallback), diff --git a/packages/react-ui/src/hooks/useSort.test.ts b/packages/react-ui/src/hooks/useSort.test.ts index f451b27d7..a381eba6c 100644 --- a/packages/react-ui/src/hooks/useSort.test.ts +++ b/packages/react-ui/src/hooks/useSort.test.ts @@ -3,7 +3,7 @@ import { renderHook, waitFor } from "@testing-library/react" import useSort from "./useSort.js" describe("useSort", () => { - it("works", async () => { + it("renders hook, and setSort properly sets currentState", async () => { const { result } = renderHook(() => useSort()) // initial state diff --git a/packages/react-ui/vite.config.ts b/packages/react-ui/vite.config.ts index 96fd25b53..a9687ef53 100644 --- a/packages/react-ui/vite.config.ts +++ b/packages/react-ui/vite.config.ts @@ -14,7 +14,14 @@ export default defineConfig({ }, plugins: [{ ...nodeExternals(), enforce: "pre" }, dts(), react()], test: { + reporters: "verbose", globals: true, environment: "jsdom", + coverage: { + statements: 90, + branches: 90, + functions: 75, + lines: 90, + }, }, })