From 2ac040c8a663f5f55e420d903352264d9eace947 Mon Sep 17 00:00:00 2001 From: Andrea Vassallo Date: Tue, 9 Mar 2021 07:27:21 +0100 Subject: [PATCH] Define the project structure Define the project structure using the atomic design pattern. Also fix the coverage and add a couple of spec. --- .eslintrc.json | 5 +- .github/workflows/suite.yml | 3 - README.md | 6 +- cypress/integration/homepage.spec.ts | 12 +++- jest.config.js | 10 ++- .../app.test.tsx.snap} | 12 ++-- src/{app/test.tsx => app.test.tsx} | 4 +- src/{app/index.tsx => app.tsx} | 4 +- src/atoms/__snapshots__/button.test.tsx.snap | 70 +++++++++++++++++++ src/atoms/button.test.tsx | 30 ++++++++ src/atoms/button.tsx | 8 +++ src/molecules/.keep | 0 src/organisms/.keep | 0 src/pages/.keep | 0 src/templates/.keep | 0 15 files changed, 144 insertions(+), 20 deletions(-) rename src/{app/__snapshots__/test.tsx.snap => __snapshots__/app.test.tsx.snap} (95%) rename src/{app/test.tsx => app.test.tsx} (71%) rename src/{app/index.tsx => app.tsx} (51%) create mode 100644 src/atoms/__snapshots__/button.test.tsx.snap create mode 100644 src/atoms/button.test.tsx create mode 100644 src/atoms/button.tsx create mode 100644 src/molecules/.keep create mode 100644 src/organisms/.keep create mode 100644 src/pages/.keep create mode 100644 src/templates/.keep diff --git a/.eslintrc.json b/.eslintrc.json index ee2f2ef..9974e38 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -6,10 +6,9 @@ }, "extends": [ "eslint:recommended", - "plugin:react/recommended", "plugin:@typescript-eslint/recommended", - "prettier", - "prettier/react" + "plugin:@typescript-eslint/recommended", + "prettier" ], "parser": "@typescript-eslint/parser", "parserOptions": { diff --git a/.github/workflows/suite.yml b/.github/workflows/suite.yml index 6cf2335..2a9399b 100644 --- a/.github/workflows/suite.yml +++ b/.github/workflows/suite.yml @@ -32,8 +32,5 @@ jobs: - name: Run Jest run: npm run test:unit - - name: Run web vitals - run: npm run test:unit - - name: Push the coverage run: npm run coverage:push -- --token=${{ secrets.CODECOV_TOKEN }} diff --git a/README.md b/README.md index 011ad44..c1614d2 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # React with TS template -[![codecov](https://codecov.io/gh/vassalloandrea/react-template/branch/master/graph/badge.svg?token=F38EP8I67R)](undefined) +[![codecov](https://codecov.io/gh/vassalloandrea/react-template/branch/main/graph/badge.svg?token=FDMIA9PIGN)](https://codecov.io/gh/vassalloandrea/react-template) This is the template that I usually use to create a new React project from scratch removing the complex boilerplate added by other tools. @@ -27,6 +27,10 @@ Each PR or push on the main branch will trigger the CI that runs: and push the Jest coverage on CodeCov. +## Basic development style + +The application uses the [Atomic Design](https://bradfrost.com/blog/post/atomic-web-design/) for the component structure. + ## Running Locally Make sure you have [Node.js](http://nodejs.org/) diff --git a/cypress/integration/homepage.spec.ts b/cypress/integration/homepage.spec.ts index 5cc2bdd..b21a922 100644 --- a/cypress/integration/homepage.spec.ts +++ b/cypress/integration/homepage.spec.ts @@ -5,7 +5,15 @@ context('Homepage', () => { cy.visit('/') }) - it('shows the hello world heading', () => { - cy.get('h1').should('have.text', 'Hello, World!') + it('shows the alert when the button is clicked', () => { + const alertStub = cy.stub() + cy.on('window:alert', alertStub) + + cy.get('button') + .contains('Click me!') + .click() + .then(() => { + expect(alertStub.getCall(0)).to.be.calledWith('Hello world!') + }) }) }) diff --git a/jest.config.js b/jest.config.js index f8f9a17..9f56b6f 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,8 +1,14 @@ module.exports = { preset: 'ts-jest', testEnvironment: 'jsdom', - roots: ['/src/'], + roots: ['/src'], collectCoverage: true, - collectCoverageFrom: ['/src'], + collectCoverageFrom: [ + '/src/atoms/*.{ts,tsx}', + '/src/molecules/*.{ts,tsx}', + '/src/organisms/*.{ts,tsx}', + '/src/templates/*.{ts,tsx}', + '/src/pages/*.{ts,tsx}', + ], coverageDirectory: '/coverage', } diff --git a/src/app/__snapshots__/test.tsx.snap b/src/__snapshots__/app.test.tsx.snap similarity index 95% rename from src/app/__snapshots__/test.tsx.snap rename to src/__snapshots__/app.test.tsx.snap index 9fabdc5..65a2062 100644 --- a/src/app/__snapshots__/test.tsx.snap +++ b/src/__snapshots__/app.test.tsx.snap @@ -8,9 +8,9 @@ Object {
-

- Hello, World! -

+
, @@ -18,9 +18,9 @@ Object {
-

- Hello, World! -

+
, "debug": [Function], diff --git a/src/app/test.tsx b/src/app.test.tsx similarity index 71% rename from src/app/test.tsx rename to src/app.test.tsx index 770a868..c969f50 100644 --- a/src/app/test.tsx +++ b/src/app.test.tsx @@ -1,7 +1,7 @@ import React from 'react' -import render from '../libs/testing-support' -import App from '.' +import render from './libs/testing-support' +import App from './app' describe('App', () => { it('renders correctly', () => { diff --git a/src/app/index.tsx b/src/app.tsx similarity index 51% rename from src/app/index.tsx rename to src/app.tsx index dd85d87..30a055e 100644 --- a/src/app/index.tsx +++ b/src/app.tsx @@ -1,8 +1,10 @@ import React from 'react' +import Button from './atoms/button' + const App: React.FC = () => (
-

Hello, World!

+
) diff --git a/src/atoms/__snapshots__/button.test.tsx.snap b/src/atoms/__snapshots__/button.test.tsx.snap new file mode 100644 index 0000000..3ca82a0 --- /dev/null +++ b/src/atoms/__snapshots__/button.test.tsx.snap @@ -0,0 +1,70 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`App renders correctly 1`] = ` +Object { + "asFragment": [Function], + "baseElement": +
+ +
+ , + "container":
+ +
, + "debug": [Function], + "findAllByAltText": [Function], + "findAllByDisplayValue": [Function], + "findAllByLabelText": [Function], + "findAllByPlaceholderText": [Function], + "findAllByRole": [Function], + "findAllByTestId": [Function], + "findAllByText": [Function], + "findAllByTitle": [Function], + "findByAltText": [Function], + "findByDisplayValue": [Function], + "findByLabelText": [Function], + "findByPlaceholderText": [Function], + "findByRole": [Function], + "findByTestId": [Function], + "findByText": [Function], + "findByTitle": [Function], + "getAllByAltText": [Function], + "getAllByDisplayValue": [Function], + "getAllByLabelText": [Function], + "getAllByPlaceholderText": [Function], + "getAllByRole": [Function], + "getAllByTestId": [Function], + "getAllByText": [Function], + "getAllByTitle": [Function], + "getByAltText": [Function], + "getByDisplayValue": [Function], + "getByLabelText": [Function], + "getByPlaceholderText": [Function], + "getByRole": [Function], + "getByTestId": [Function], + "getByText": [Function], + "getByTitle": [Function], + "queryAllByAltText": [Function], + "queryAllByDisplayValue": [Function], + "queryAllByLabelText": [Function], + "queryAllByPlaceholderText": [Function], + "queryAllByRole": [Function], + "queryAllByTestId": [Function], + "queryAllByText": [Function], + "queryAllByTitle": [Function], + "queryByAltText": [Function], + "queryByDisplayValue": [Function], + "queryByLabelText": [Function], + "queryByPlaceholderText": [Function], + "queryByRole": [Function], + "queryByTestId": [Function], + "queryByText": [Function], + "queryByTitle": [Function], + "rerender": [Function], + "unmount": [Function], +} +`; diff --git a/src/atoms/button.test.tsx b/src/atoms/button.test.tsx new file mode 100644 index 0000000..fbf6a6f --- /dev/null +++ b/src/atoms/button.test.tsx @@ -0,0 +1,30 @@ +import React from 'react' + +import { cleanup, fireEvent } from '@testing-library/react' + +import render from '../libs/testing-support' +import Button from './button' + +describe('App', () => { + afterEach(cleanup) + + it('renders correctly', () => { + const component = render() + expect(component).toMatchSnapshot() + }) + + describe('Passing the onClick prop', () => { + it('calls the onClick callback', () => { + const callback = jest.fn() + + const { getByText } = render( + , + ) + + const node = getByText('This is a button') + fireEvent.click(node) + + expect(callback).toHaveBeenCalled() + }) + }) +}) diff --git a/src/atoms/button.tsx b/src/atoms/button.tsx new file mode 100644 index 0000000..958b633 --- /dev/null +++ b/src/atoms/button.tsx @@ -0,0 +1,8 @@ +import React from 'react' + +const Button: React.FC> = ({ + onClick, + children, +}) => + +export default Button diff --git a/src/molecules/.keep b/src/molecules/.keep new file mode 100644 index 0000000..e69de29 diff --git a/src/organisms/.keep b/src/organisms/.keep new file mode 100644 index 0000000..e69de29 diff --git a/src/pages/.keep b/src/pages/.keep new file mode 100644 index 0000000..e69de29 diff --git a/src/templates/.keep b/src/templates/.keep new file mode 100644 index 0000000..e69de29