Skip to content

Commit

Permalink
chore: Convert tests to TS and update dev dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
jschrader-nr committed Sep 9, 2022
1 parent 2cbfce2 commit b63ed10
Show file tree
Hide file tree
Showing 9 changed files with 4,230 additions and 3,969 deletions.
4 changes: 4 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
{
"extends": [
"airbnb",
"airbnb-typescript",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended"
],
"parserOptions": {
"project": "./tsconfig.eslint.json"
},
"parser": "@typescript-eslint/parser",
"plugins": [
"@typescript-eslint",
Expand Down
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v15.14.0
v16.17.0
55 changes: 0 additions & 55 deletions .yarn/releases/yarn-2.4.2.cjs

This file was deleted.

783 changes: 783 additions & 0 deletions .yarn/releases/yarn-3.2.3.cjs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion .yarnrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ plugins:
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
spec: "@yarnpkg/plugin-interactive-tools"

yarnPath: .yarn/releases/yarn-2.4.2.cjs
yarnPath: .yarn/releases/yarn-3.2.3.cjs
67 changes: 34 additions & 33 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,50 +15,51 @@
},
"scripts": {
"prepublishOnly": "yarn build && pinst --disable",
"build": "rollup -c && yarn types",
"build": "rollup -c && yarn type-declarations",
"test": "jest",
"test-build": "sh ./scripts/test-build.sh",
"types": "tsc -p tsconfig.json --declaration --emitDeclarationOnly",
"types": "tsc -p tsconfig.json --noEmit",
"type-declarations": "tsc -p tsconfig.json --declaration --emitDeclarationOnly --excludeFiles ./src/index.test.tsx",
"lint": "eslint ./src/**",
"postpublish": "pinst --enable",
"prepare": "husky install"
},
"devDependencies": {
"@babel/cli": "^7.17.6",
"@babel/core": "^7.17.9",
"@babel/plugin-transform-runtime": "^7.17.0",
"@babel/preset-env": "^7.16.11",
"@babel/preset-react": "^7.16.7",
"@babel/preset-typescript": "^7.16.7",
"@commitlint/cli": "^12.1.4",
"@commitlint/config-conventional": "^12.1.4",
"@rollup/plugin-babel": "^5.3.0",
"@rollup/plugin-typescript": "^8.2.1",
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^13.0.1",
"@types/react": "^17.0.11",
"@types/react-dom": "^17.0.7",
"@typescript-eslint/eslint-plugin": "^4.26.1",
"@typescript-eslint/parser": "^4.26.1",
"babel-eslint": "^10.1.0",
"eslint": "^7.28.0",
"eslint-config-airbnb": "^18.2.1",
"eslint-plugin-import": "^2.23.4",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-react": "^7.24.0",
"eslint-plugin-react-hooks": "^4.2.0",
"husky": "^6.0.0",
"jest": "^27.0.4",
"@babel/cli": "^7.18.10",
"@babel/core": "^7.19.0",
"@babel/plugin-transform-runtime": "^7.18.10",
"@babel/preset-env": "^7.19.0",
"@babel/preset-react": "^7.18.6",
"@babel/preset-typescript": "^7.18.6",
"@commitlint/cli": "^17.1.2",
"@commitlint/config-conventional": "^17.1.0",
"@rollup/plugin-babel": "^5.3.1",
"@rollup/plugin-typescript": "^8.5.0",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@types/react": "^18.0.18",
"@types/react-dom": "^18.0.6",
"@typescript-eslint/eslint-plugin": "^5.36.2",
"@typescript-eslint/parser": "^5.36.2",
"eslint": "^8.23.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-airbnb-typescript": "^17.0.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jsx-a11y": "^6.6.1",
"eslint-plugin-react": "^7.31.8",
"eslint-plugin-react-hooks": "^4.6.0",
"husky": "^8.0.1",
"jest": "^29.0.2",
"jsdom": "^20.0.0",
"jsdom-global": "^3.0.2",
"pinst": "^2.1.6",
"prop-types": "^15.7.2",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"pinst": "^3.0.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router": "^6.3.0",
"rollup": "^2.51.1",
"rollup": "^2.79.0",
"rollup-plugin-size": "^0.2.2",
"rollup-plugin-terser": "^7.0.2",
"typescript": "^4.3.2"
"typescript": "^4.8.3"
},
"keywords": [
"react",
Expand Down
160 changes: 57 additions & 103 deletions src/index.test.js → src/index.test.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
/* eslint-disable react/require-default-props */
/* eslint-disable react/no-array-index-key */
/* eslint-disable react/jsx-filename-extension */
import '@testing-library/jest-dom';
import React from 'react';
import PropTypes from 'prop-types';
import { render, screen } from '@testing-library/react';
import { MemoryRouter as Router, Route, useLocation } from 'react-router';
import useBreadcrumbs, { getBreadcrumbs, createRoutesFromChildren } from './index.tsx';
import { MemoryRouter as Router, useLocation } from 'react-router';
import useBreadcrumbs, { getBreadcrumbs, createRoutesFromChildren, BreadcrumbsRoute, Route, Options } from './index';

// imports to test compiled builds
import useBreadcrumbsCompiledES, {
getBreadcrumbs as getBreadcrumbsCompiledES,
} from '../dist/es/index';
import useBreadcrumbsCompiledUMD, {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
getBreadcrumbs as getBreadcrumbsCompiledUMD,
} from '../dist/umd/index';
import useBreadcrumbsCompiledCJS, {
Expand All @@ -24,6 +25,10 @@ const components = {
options,
routes,
...forwardedProps
}: {
useBreadcrumbs: (r?: BreadcrumbsRoute[], o?: Options) => []
options?: Options
routes?: BreadcrumbsRoute[]
}) => {
const breadcrumbs = useBreadcrumbsHook(routes, options);
const location = useLocation();
Expand All @@ -34,8 +39,10 @@ const components = {
<div data-test-id="forwarded-props">
{forwardedProps
&& Object.values(forwardedProps)
.filter((v) => typeof v === 'string')
.map((value) => <span key={value}>{value}</span>)}
.filter((v: unknown) => typeof v === 'string')
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
.map((value: string) => <span key={value}>{value}</span>)}
</div>
<div className="breadcrumbs-container">
{breadcrumbs.map(({ breadcrumb, key }, index) => (
Expand All @@ -48,28 +55,44 @@ const components = {
</h1>
);
},
BreadcrumbMatchTest: ({ match }) => <span>{match.params.number}</span>,
BreadcrumbRouteTest: ({ match }) => <span>{match.route?.arbitraryProp}</span>,
BreadcrumbNavLinkTest: ({ match }) => <a role="link" to={match.pathname}>Link</a>,
BreadcrumbMatchTest: (
{ match }: { match?: { params?: { number?: number } } },
) => <span>{match?.params?.number}</span>,

BreadcrumbRouteTest: (
{ match }: { match: { route?: { arbitraryProp: string } } },
) => <span>{match.route?.arbitraryProp}</span>,

BreadcrumbNavLinkTest: (
{ match }: { match: { pathname: string } },
) => <a href={match.pathname}>Link</a>,

BreadcrumbLocationTest: ({
location: {
state: { isLocationTest },
},
}) => <span>{isLocationTest ? 'pass' : 'fail'}</span>,
BreadcrumbExtraPropsTest: ({ foo, bar }) => (
location,
}: {
location?: {
state?: { isLocationTest?: boolean }
}
}) => <span>{location?.state?.isLocationTest ? 'pass' : 'fail'}</span>,

BreadcrumbExtraPropsTest: ({ foo, bar }: { foo: string, bar: string }) => (
<span>
{foo}
{bar}
</span>
),

BreadcrumbMemoized: React.memo(() => <span>Memoized</span>),

// eslint-disable-next-line react/prefer-stateless-function
BreadcrumbClass: class BreadcrumbClass extends React.PureComponent {
render() {
return <span>Class</span>;
}
},
Layout: React.memo(({ children }) => <div>{children}</div>),

// eslint-disable-next-line react/require-default-props
Layout: React.memo(({ children }: { children?: React.ReactNode }) => <div>{children}</div>),
};

const getHOC = () => {
Expand Down Expand Up @@ -98,13 +121,24 @@ const getMethod = () => {
}
};

const renderer = ({ options, pathname, routes, state, props }) => {
const renderer = (
{ options, pathname, routes, state, props }:
{
options?: Options
pathname: string
routes?: BreadcrumbsRoute<string>[]
state?: { isLocationTest: boolean }
props?: { [x: string]: unknown }
},
) => {
const useBreadcrumbsHook = getHOC();
const { Breadcrumbs } = components;

const wrapper = render(
<Router initialIndex={0} initialEntries={[{ pathname, state }]}>
<Breadcrumbs
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
useBreadcrumbs={useBreadcrumbsHook}
options={options}
routes={routes}
Expand All @@ -118,88 +152,8 @@ const renderer = ({ options, pathname, routes, state, props }) => {
};
};

const matchShape = {
params: PropTypes.shape().isRequired,
pathname: PropTypes.string.isRequired,
pattern: PropTypes.object.isRequired,
};

components.Breadcrumbs.propTypes = {
useBreadcrumbs: PropTypes.func.isRequired,
options: PropTypes.shape({
excludePaths: PropTypes.arrayOf(PropTypes.string),
disableDefaults: PropTypes.bool,
}),
routes: PropTypes.arrayOf(
PropTypes.oneOfType([
PropTypes.shape({
path: PropTypes.string,
breadcrumb: PropTypes.oneOfType([
PropTypes.node,
PropTypes.func,
PropTypes.object,
]),
}),
PropTypes.shape({
index: PropTypes.bool,
breadcrumb: PropTypes.oneOfType([
PropTypes.node,
PropTypes.func,
PropTypes.object,
]),
}),
PropTypes.shape({
children: PropTypes.arrayOf(PropTypes.shape()).isRequired,
breadcrumb: PropTypes.oneOfType([
PropTypes.node,
PropTypes.func,
PropTypes.object,
]),
}),
]),
),
};

components.Breadcrumbs.defaultProps = {
routes: null,
options: null,
};

components.BreadcrumbMatchTest.propTypes = {
match: PropTypes.shape(matchShape).isRequired,
};

components.BreadcrumbRouteTest.propTypes = {
match: PropTypes.shape(matchShape).isRequired,
};

components.BreadcrumbNavLinkTest.propTypes = {
match: PropTypes.shape(matchShape).isRequired,
};

components.BreadcrumbLocationTest.propTypes = {
location: PropTypes.shape({
state: PropTypes.shape({
isLocationTest: PropTypes.bool.isRequired,
}).isRequired,
}).isRequired,
};

components.BreadcrumbExtraPropsTest.propTypes = {
foo: PropTypes.string.isRequired,
bar: PropTypes.string.isRequired,
};

components.Layout.propTypes = {
children: PropTypes.node,
};

components.Layout.defaultProps = {
children: null,
};

const getByTextContent = (text) => screen.getByText((content, element) => {
const hasText = (ele) => ele.textContent === text;
const getByTextContent = (text: string) => screen.getByText((content, element) => {
const hasText = (ele: Element | null) => ele?.textContent === text;
const elementHasText = hasText(element);
const childrenDontHaveText = (element?.children ? Array.from(element.children) : [])
.every((child) => !hasText(child));
Expand All @@ -210,15 +164,16 @@ const getByTextContent = (text) => screen.getByText((content, element) => {
describe('use-react-router-breadcrumbs', () => {
describe('Valid routes', () => {
it('Should render breadcrumb components as expected', () => {
const routes = [
const { BreadcrumbMatchTest } = components;
const routes: BreadcrumbsRoute[] = [
// test home route
{ path: '/', breadcrumb: 'Home' },
// test breadcrumb passed as string
{ path: '/1', breadcrumb: 'One' },
// test simple breadcrumb component
{ path: '/1/2', breadcrumb: () => <span>TWO</span> },
// test advanced breadcrumb component (user can use `match` however they wish)
{ path: '/1/2/:number', breadcrumb: components.BreadcrumbMatchTest },
{ path: '/1/2/:number', breadcrumb: BreadcrumbMatchTest },
// test NavLink wrapped breadcrumb
{
path: '/1/2/:number/4',
Expand All @@ -232,7 +187,7 @@ describe('use-react-router-breadcrumbs', () => {
routes,
});
expect(getByTextContent('Home / One / TWO / 3 / Link / Any')).toBeTruthy();
expect(screen.getByRole('link')).toHaveAttribute('to', '/1/2/3/4');
expect(screen.getByRole('link')).toHaveAttribute('href', '/1/2/3/4');
});
});

Expand Down Expand Up @@ -536,7 +491,6 @@ describe('use-react-router-breadcrumbs', () => {
it('Should be able to set options without defining a routes array', () => {
renderer({
pathname: '/one/two',
routes: null,
options: { excludePaths: ['/', '/one'] },
});
expect(getByTextContent('Two')).toBeTruthy();
Expand Down Expand Up @@ -569,7 +523,7 @@ describe('use-react-router-breadcrumbs', () => {
renderer({
pathname: '/one/two/three_four',
routes,
options: { defaultFormatter: (breadcrumb) => breadcrumb.replace(/two/g, 'changed') },
options: { defaultFormatter: (breadcrumb: string) => breadcrumb.replace(/two/g, 'changed') },
});

expect(getByTextContent('Home / One / changed / three_four')).toBeTruthy();
Expand Down
4 changes: 4 additions & 0 deletions tsconfig.eslint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"extends": "./tsconfig.json",
"include": ["src/index.test.tsx"]
}
Loading

0 comments on commit b63ed10

Please sign in to comment.