Skip to content
This repository has been archived by the owner on Jan 20, 2022. It is now read-only.

Commit

Permalink
test: write tests for Table
Browse files Browse the repository at this point in the history
  • Loading branch information
justinanastos committed Jul 29, 2019
1 parent c1be211 commit 832afb1
Show file tree
Hide file tree
Showing 3 changed files with 239 additions and 5 deletions.
232 changes: 232 additions & 0 deletions src/Table.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
/**
* @jest-environment jsdom
*/
import React from "react";
import { render, cleanup } from "@testing-library/react";
import "@testing-library/jest-dom/extend-expect";
import { Table } from "./Table";

interface User {
name: string;
email: string;
image: string;
dateAdded: string;
}

const users: ReadonlyArray<User> = [
{
name: "Alice Howell",
email: "alice@starkindustries.net",
image: require("./table.story/alice-howell.png"),
dateAdded: "05/25/2019",
},
{
name: "Benjamin Lawrence",
email: "Ben@starkindustries.net",
image: require("./table.story/benjamin-lawrence.png"),
dateAdded: "05/26/2019",
},
{
name: "Cynthia Bowman",
email: "cbowman@starkindustries.net",
image: require("./table.story/cynthia-bowman.png"),
dateAdded: "05/27/2019",
},
{
name: "Jeremy Jacobs",
email: "jj@starkindustries.net",
image: require("./table.story/jeremy-jacobs.png"),
dateAdded: "05/28/2019",
},
{
name: "Jeremy Griffin",
email: "jgriffin@starkindustries.net",
image: require("./table.story/jeremy-griffin.png"),
dateAdded: "05/29/2019",
},
];

describe("Table", () => {
afterEach(cleanup);

describe("should render each density without crashing", () => {
const densities = [undefined, "standard", "condensed", "relaxed"] as const;

densities.forEach(density => {
it(`for density ${density} || \`undefined\``, () => {
expect(() => {
render(
<Table<User>
keyOn="name"
density={density}
data={users}
columns={[
{
id: 1,
render: ({ image }) => (
<img css={{ width: 32, height: 32 }} src={image} />
),
},
]}
/>
);
}).not.toThrow();
});
});
});

it("should handle `keyOn` as a function", () => {
const { container } = render(
<Table<User>
keyOn={user => user.name}
data={users}
columns={[
{
id: 1,
headerTitle: "Name",
render: ({ name }) => name,
},
]}
/>
);

expect(
(container.querySelector(
"tbody"
) as HTMLTableSectionElement).querySelectorAll("tr")
).toHaveLength(5);
});

it("should handle `keyOn` as a string", () => {
const { container } = render(
<Table<User>
keyOn="name"
data={users}
columns={[
{
id: 1,
headerTitle: "Name",
render: ({ name }) => name,
},
]}
/>
);

expect(
(container.querySelector(
"tbody"
) as HTMLTableSectionElement).querySelectorAll("tr")
).toHaveLength(5);
});

it("should handle `keyOn` as a function", () => {
const { container, getByText } = render(
<Table<User>
keyOn={user => user.name}
data={users}
columns={[
{
id: 1,
render: ({ image }) => (
<img css={{ width: 32, height: 32 }} src={image} />
),
},
{
id: 2,
headerTitle: "Name",
render: ({ name }) => name,
},
{
id: 3,
headerTitle: "Date Added",
render: ({ dateAdded }) => dateAdded,
},
]}
/>
);

expect(
(container.querySelector(
"tbody"
) as HTMLTableSectionElement).querySelectorAll("tr")
).toHaveLength(5);

expect(getByText("Date Added")).toBeInTheDocument();

// All the user names should be rendered
users.forEach(user => {
expect(getByText(user.name)).toBeInTheDocument();
});
});

it("should render a header", () => {
const { container, getByText } = render(
<Table<User>
keyOn={user => user.name}
data={users}
columns={[
{
id: 1,
render: ({ image }) => (
<img css={{ width: 32, height: 32 }} src={image} />
),
},
{
id: 2,
headerTitle: "Name",
render: ({ name }) => name,
},
{
id: 3,
headerTitle: "Date Added",
render: ({ dateAdded }) => dateAdded,
},
]}
/>
);

const thead = container.querySelector("thead") as HTMLTableSectionElement;

expect(getByText("Date Added")).toBeInTheDocument();
expect(getByText("Name")).toBeInTheDocument();

expect(thead).toBeInTheDocument();
});

it("should render content", () => {
const { getByText } = render(
<Table<User>
keyOn={user => user.name}
data={users}
columns={[
{
id: 1,
render: ({ image }) => (
<img css={{ width: 32, height: 32 }} src={image} />
),
},
{
id: 2,
headerTitle: "Name",
render: ({ name }) => name,
},
{
id: 3,
headerTitle: "Date Added",
render: ({ dateAdded }) => dateAdded,
},
]}
/>
);

// All the user names should be rendered
users.forEach(({ name }) => {
expect(getByText(name)).toBeInTheDocument();
});

// All dates should be rendered
users.forEach(({ dateAdded }) => {
expect(getByText(dateAdded)).toBeInTheDocument();
});
});
});
4 changes: 2 additions & 2 deletions src/Table.story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { jsx } from "@emotion/core";
import React from "react";
import { storiesOf } from "@storybook/react";
import { colors } from ".";
import * as colors from "./colors";
import * as typography from "./typography";
import { Table } from "./Table";
import { withKnobs, select } from "@storybook/addon-knobs/react";
Expand All @@ -14,7 +14,7 @@ interface User {
dateAdded: string;
}

const users: User[] = [
const users: ReadonlyArray<User> = [
{
name: "Alice Howell",
email: "alice@starkindustries.net",
Expand Down
8 changes: 5 additions & 3 deletions src/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ interface Props<RowShape> {
/**
* All the data for the component. Should be stored in an array of objects
*/
data: RowShape[];
data: ReadonlyArray<RowShape>;

density?: "standard" | "condensed" | "relaxed";

Expand All @@ -21,7 +21,9 @@ interface Props<RowShape> {
*/
headerTitle?: React.ReactNode | string;
/**
* an id for the column
* Unique key for each column.
*
* This'll be used as the `key` for the `<th>`
*/
id: string | number;

Expand All @@ -40,7 +42,7 @@ interface Props<RowShape> {
/**
* a field name to key rows on
*/
keyOn: keyof RowShape | ((row: RowShape) => any);
keyOn: keyof RowShape | ((row: Readonly<RowShape>) => any);
}

export function Table<RowShape>({
Expand Down

0 comments on commit 832afb1

Please sign in to comment.