Instantly share code, notes, and snippets.
Last active
October 5, 2020 04:04
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save createdbymahmood/0344bde8d182c679a5eaf3fb2cc5bd0f to your computer and use it in GitHub Desktop.
This is how I'm testing a button component
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from "react"; | |
import { | |
cleanup, | |
fireEvent, | |
render, | |
RenderResult, | |
} from "@testing-library/react"; | |
import { Button, ButtonProps } from "./Button"; | |
describe("<DangerButton />", () => { | |
let wrapper: RenderResult; | |
const onClickHandler = jest.fn(); | |
const buttonText = "button"; | |
const buttonProps: ButtonProps = { | |
onClick: onClickHandler, | |
type: "danger", | |
size: "lg", | |
}; | |
beforeEach(() => { | |
wrapper = render(<Button {...buttonProps}>{buttonText}</Button>); | |
}); | |
afterAll(cleanup); | |
it("Should render the button correctly", () => { | |
const { getByTestId } = wrapper; | |
const button = getByTestId("btn"); | |
expect(button).toBeInTheDocument(); | |
}); | |
it("Should fire the onClickHandler on click ", () => { | |
const { getByTestId } = wrapper; | |
const button = getByTestId("btn"); | |
fireEvent.click(button); | |
/* to have beed called */ | |
expect(onClickHandler).toHaveBeenCalled(); | |
/* to have beed called only one time */ | |
expect(onClickHandler).toHaveBeenCalledTimes(1); | |
}); | |
it("Should have the lg specified classnames", () => { | |
const { queryByText } = wrapper; | |
const button = queryByText("button") as HTMLButtonElement; | |
expect(button.className).toContain("p-8 py-4 text-lg"); | |
}); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from "react"; | |
import classnames from "classnames"; | |
// * these are the base custom button props | |
type ButtonSizeType = "xs" | "sm" | "md" | "lg" | "xl"; | |
type ButtonTypeType = | |
| "primary" | |
| "info" | |
| "light-info" | |
| "warning" | |
| "danger" | |
| "success" | |
| "dark-info" | |
| "default"; | |
type ButtonExtraProps = { | |
size: ButtonSizeType; | |
type: ButtonTypeType; | |
block: boolean; | |
rounded: boolean; | |
}; | |
// * integrate HTML button props with our custom props | |
export type ButtonProps = Omit< | |
React.HtmlHTMLAttributes<HTMLButtonElement>, | |
keyof ButtonExtraProps | |
> & | |
Partial<ButtonExtraProps>; | |
const defaultProps: ButtonProps = { | |
size: "sm", | |
type: "default", | |
block: false, | |
rounded: true, | |
}; | |
export const Button: React.FC<ButtonProps> = props => { | |
// * destruct needed props | |
const { | |
size, | |
type, | |
block, | |
rounded, | |
className: nativeClassName, | |
...restProps | |
} = props; | |
// * switch on the types and make suitable size & types | |
let sizeClassname = makeSize(size); | |
let typeClassname = makeType(type); | |
// * check if our button is fullwidth or rounded | |
let blockClassname = block ? "w-full" : ""; | |
let roundedClassname = rounded ? "rounded-full" : ""; | |
const classNames = [ | |
nativeClassName, | |
sizeClassname, | |
typeClassname, | |
blockClassname, | |
roundedClassname, | |
]; | |
// * render the button 🔥 | |
return ( | |
<button | |
data-testid="btn" | |
className={classnames(classNames)} | |
{...restProps} | |
/> | |
); | |
}; | |
function makeSize(size: ButtonSizeType) { | |
switch (size) { | |
case "xs": | |
return ["px-2", "py-1", "text-xs"]; | |
case "sm": | |
return ["p-4", "py-2", "text-sm"]; | |
case "md": | |
return ["p-6", "py-3", "text-md"]; | |
case "lg": | |
return ["p-8", "py-4", "text-lg"]; | |
case "xl": | |
return ["p-10", "py-5", "text-xl"]; | |
// sm by default | |
default: | |
return ["p-4", "py-2", "text-sm"]; | |
} | |
} | |
function makeType(type: ButtonTypeType) { | |
switch (type) { | |
case "default": | |
return ["bg-white", "text-black"]; | |
case "danger": | |
return ["text-white", "bg-red"]; | |
case "info": | |
return ["text-white", "bg-blue-700"]; | |
case "light-info": | |
return ["text-black", "bg-light-blue"]; | |
case "primary": | |
return ["text-white", "bg-blue"]; | |
case "success": | |
return ["text-white", "bg-green"]; | |
case "warning": | |
return ["text-white", "bg-orange"]; | |
case "dark-info": | |
return ["text-white", "bg-dark-blue"]; | |
// default button type, the most simple 🎈 | |
default: | |
return ["bg-white", "text-black"]; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment