Skip to content

Commit

Permalink
Define the project structure
Browse files Browse the repository at this point in the history
Define the project structure using the atomic design pattern.
Also fix the coverage and add a couple of spec.
  • Loading branch information
vassalloandrea committed Mar 9, 2021
1 parent 1024cb3 commit 2ac040c
Show file tree
Hide file tree
Showing 15 changed files with 144 additions and 20 deletions.
5 changes: 2 additions & 3 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
3 changes: 0 additions & 3 deletions .github/workflows/suite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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/)
Expand Down
12 changes: 10 additions & 2 deletions cypress/integration/homepage.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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!')
})
})
})
10 changes: 8 additions & 2 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
module.exports = {
preset: 'ts-jest',
testEnvironment: 'jsdom',
roots: ['<rootDir>/src/'],
roots: ['<rootDir>/src'],
collectCoverage: true,
collectCoverageFrom: ['<rootDir>/src'],
collectCoverageFrom: [
'<rootDir>/src/atoms/*.{ts,tsx}',
'<rootDir>/src/molecules/*.{ts,tsx}',
'<rootDir>/src/organisms/*.{ts,tsx}',
'<rootDir>/src/templates/*.{ts,tsx}',
'<rootDir>/src/pages/*.{ts,tsx}',
],
coverageDirectory: '<rootDir>/coverage',
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,19 @@ Object {
<div
class="App"
>
<h1>
Hello, World!
</h1>
<button>
Click me!
</button>
</div>
</div>
</body>,
"container": <div>
<div
class="App"
>
<h1>
Hello, World!
</h1>
<button>
Click me!
</button>
</div>
</div>,
"debug": [Function],
Expand Down
4 changes: 2 additions & 2 deletions src/app/test.tsx → src/app.test.tsx
Original file line number Diff line number Diff line change
@@ -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', () => {
Expand Down
4 changes: 3 additions & 1 deletion src/app/index.tsx → src/app.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import React from 'react'

import Button from './atoms/button'

const App: React.FC = () => (
<div className="App">
<h1>Hello, World!</h1>
<Button onClick={() => alert('Hello world!')}>Click me!</Button>
</div>
)

Expand Down
70 changes: 70 additions & 0 deletions src/atoms/__snapshots__/button.test.tsx.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`App renders correctly 1`] = `
Object {
"asFragment": [Function],
"baseElement": <body>
<div>
<button>
This is a button
</button>
</div>
</body>,
"container": <div>
<button>
This is a button
</button>
</div>,
"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],
}
`;
30 changes: 30 additions & 0 deletions src/atoms/button.test.tsx
Original file line number Diff line number Diff line change
@@ -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(<Button>This is a button</Button>)
expect(component).toMatchSnapshot()
})

describe('Passing the onClick prop', () => {
it('calls the onClick callback', () => {
const callback = jest.fn()

const { getByText } = render(
<Button onClick={callback}>This is a button</Button>,
)

const node = getByText('This is a button')
fireEvent.click(node)

expect(callback).toHaveBeenCalled()
})
})
})
8 changes: 8 additions & 0 deletions src/atoms/button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import React from 'react'

const Button: React.FC<React.HTMLProps<HTMLButtonElement>> = ({
onClick,
children,
}) => <button onClick={onClick}>{children}</button>

export default Button
Empty file added src/molecules/.keep
Empty file.
Empty file added src/organisms/.keep
Empty file.
Empty file added src/pages/.keep
Empty file.
Empty file added src/templates/.keep
Empty file.

0 comments on commit 2ac040c

Please sign in to comment.