diff --git a/.gitignore b/.gitignore index 01b9265..54710e6 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ npm-debug.log .next out build -package-lock.json \ No newline at end of file +package-lock.json +coverage \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index d33b9b1..ce173c1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,10 @@ sudo: required language: node_js node_js: node -cache: npm +cache: + npm: true + directories: + - .next/cache before_install: # Fixes an issue where the max file watch count is exceeded, triggering ENOSPC diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000..d28a831 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,23 @@ +module.exports = { + preset: 'ts-jest/presets/js-with-ts', + setupFilesAfterEnv: ['/jest/setup.ts'], + globals: { + 'ts-jest': { + tsConfig: 'jest.tsconfig.json' + } + }, + moduleNameMapper: { + '.+\\.(css|styl|less|sass|scss)$': '/jest/__mocks__/styleMock.js', + '.+\\.(jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': + '/jest/__mocks__/fileMock.js', + '\\.svg': '/jest/__mocks__/svgrMock.js' + }, + testPathIgnorePatterns: [ + '/.next', + '/node_modules', + '/build', + '/coverage' + ], + collectCoverageFrom: ['src/**/*.{ts,tsx}', '!src/@types/**/*'], + collectCoverage: true +} diff --git a/jest.tsconfig.json b/jest.tsconfig.json new file mode 100644 index 0000000..641ccdd --- /dev/null +++ b/jest.tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "jsx": "react", + "allowJs": true, + "resolveJsonModule": true, + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "noImplicitAny": true, + "sourceMap": true, + "target": "es5" + } +} diff --git a/jest/__mocks__/fileMock.js b/jest/__mocks__/fileMock.js new file mode 100644 index 0000000..0e56c5b --- /dev/null +++ b/jest/__mocks__/fileMock.js @@ -0,0 +1 @@ +module.exports = 'test-file-stub' diff --git a/jest/__mocks__/styleMock.js b/jest/__mocks__/styleMock.js new file mode 100644 index 0000000..4ba52ba --- /dev/null +++ b/jest/__mocks__/styleMock.js @@ -0,0 +1 @@ +module.exports = {} diff --git a/jest/__mocks__/svgrMock.js b/jest/__mocks__/svgrMock.js new file mode 100644 index 0000000..581ceb0 --- /dev/null +++ b/jest/__mocks__/svgrMock.js @@ -0,0 +1 @@ +module.exports = 'svg' diff --git a/jest/setup.ts b/jest/setup.ts new file mode 100644 index 0000000..264828a --- /dev/null +++ b/jest/setup.ts @@ -0,0 +1 @@ +import '@testing-library/jest-dom/extend-expect' diff --git a/package.json b/package.json index f493d1a..ac21115 100644 --- a/package.json +++ b/package.json @@ -6,8 +6,11 @@ "start": "next dev", "build": "next build", "serve": "next start", - "test": "eslint --ignore-path .gitignore '**/*.{js,jsx,ts,tsx}'", - "format": "prettier --ignore-path .gitignore '**/*.{css,yml,js,jsx,ts,tsx,json}' --write" + "test": "npm run lint && NODE_ENV=test jest", + "test:watch": "npm run lint && NODE_ENV=test jest --watch", + "lint": "eslint --ignore-path .gitignore --ext .js .", + "format": "prettier --ignore-path .gitignore '**/*.{css,yml,js,jsx,ts,tsx,json}' --write", + "analyze": "ANALYZE=true next build" }, "author": "Matthias Kretschmann ", "license": "MIT", @@ -24,6 +27,10 @@ "use-dark-mode": "^2.3.1" }, "devDependencies": { + "@next/bundle-analyzer": "^9.1.4", + "@testing-library/jest-dom": "^4.2.4", + "@testing-library/react": "^9.3.2", + "@types/jest": "^24.0.23", "@types/next-seo": "^1.10.0", "@types/node": "^12.12.14", "@types/react": "^16.9.15", @@ -35,8 +42,10 @@ "eslint-plugin-jsx-a11y": "^6.2.3", "eslint-plugin-prettier": "^3.1.1", "eslint-plugin-react": "^7.17.0", + "jest": "^24.9.0", "postcss-preset-env": "^6.7.0", "prettier": "^1.19.1", + "ts-jest": "^24.2.0", "typescript": "^3.7.3" }, "engines": { diff --git a/src/__tests__/Layout.test.tsx b/src/__tests__/Layout.test.tsx new file mode 100644 index 0000000..0702b92 --- /dev/null +++ b/src/__tests__/Layout.test.tsx @@ -0,0 +1,10 @@ +import React from 'react' +import { render } from '@testing-library/react' +import Layout from '../Layout' + +describe('Layout', () => { + it('renders without crashing', () => { + const { container } = render(Hello) + expect(container.firstChild).toBeInTheDocument() + }) +}) diff --git a/src/__tests__/Loader.test.tsx b/src/__tests__/Loader.test.tsx new file mode 100644 index 0000000..6c48f41 --- /dev/null +++ b/src/__tests__/Loader.test.tsx @@ -0,0 +1,10 @@ +import React from 'react' +import { render } from '@testing-library/react' +import Loader from '../components/Loader' + +describe('Loader', () => { + it('renders without crashing', () => { + const { container } = render() + expect(container.firstChild).toBeInTheDocument() + }) +}) diff --git a/src/__tests__/index.test.tsx b/src/__tests__/index.test.tsx new file mode 100644 index 0000000..411135e --- /dev/null +++ b/src/__tests__/index.test.tsx @@ -0,0 +1,11 @@ +import React from 'react' +import { render, wait } from '@testing-library/react' +import Home from '../pages' + +describe('Home', () => { + it('renders without crashing', async () => { + const { container } = render() + await wait() + expect(container.firstChild).toBeInTheDocument() + }) +}) diff --git a/src/components/Add.tsx b/src/components/Add.tsx index cd03e8f..e1c6a95 100644 --- a/src/components/Add.tsx +++ b/src/components/Add.tsx @@ -22,7 +22,7 @@ export default function Add() { const [message] = useState() const [error, setError] = useState() - async function handleOnDrop(acceptedFiles: FileDropzone[]) { + async function handleOnDrop(acceptedFiles: FileDropzone[]): Promise { if (!acceptedFiles) return setLoading(true)