Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add yarn test command (Jest) #67

Merged
merged 7 commits into from
Dec 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions .fixtures/test-app-ts/src/components/App.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import React from 'react'
import { observer } from 'mobx-react'
import { ReactComponent as Logo } from 'images/logo.svg'
// test packages written for newer node version
import ky from 'ky'
import mmm from 'images/mmmpiselli.jpg'
import { ReactComponent as Logo } from '../images/logo.svg'
import mmm from '../images/mmmpiselli.jpg'
import styles from './App.module.css'

export function firstDayOfYear(year: number): Date {
return new Date(Date.UTC(year, 0, 1))
}

// test decorators
@observer
export class App extends React.Component {
Expand Down
8 changes: 6 additions & 2 deletions .fixtures/test-app/src/components/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@ import { observer } from 'mobx-react'
import mapboxgl from 'mapbox-gl'
// test packages written for newer node version
import ky from 'ky'
import { ReactComponent as Logo } from 'images/logo.svg'
import mmm from 'images/mmmpiselli.jpg'
import { ReactComponent as Logo } from '../images/logo.svg'
import mmm from '../images/mmmpiselli.jpg'
import styles from './App.module.css'

export function firstDayOfYear(year) {
return new Date(Date.UTC(year, 0, 1))
}

// test decorators
@observer
export class App extends React.Component {
Expand Down
8 changes: 8 additions & 0 deletions .fixtures/test-app/src/components/App.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

import { firstDayOfYear } from './App'

describe(firstDayOfYear, () => {
it('should return Jan 1st of the year (UTC)', () => {
expect(firstDayOfYear(2019).toISOString()).toBe('2019-01-01T00:00:00.000Z')
})
})
31 changes: 29 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ but significant amounts of code were rewritten and simplified. Here are some shi
- [How do I use a service worker?](#faq)
- [I need title and meta tags for each route for SEO. How do I do it?](#faq)
- [I need to build for Electron. How do I do it?](#faq)
- [How do I configure a multi-project repo?](#faq)
- [Contributing](#contributing)

## Creating a new project
Expand Down Expand Up @@ -78,6 +79,7 @@ These are the available commands once you created a project:
- `yarn start` starts a server locally, accessible both from your browser and from another machine using your same wi-fi
- `yarn start --exposed` starts a server locally and exposes it to the internet, accessible from everyone having the link, kinda like ngrok, but works only if you have an accurat ssh key. The link created looks like `{branch}.{repo}.internal.accurat.io` if you're in a branch, or `{repo}.internal.accurat.io` if you're on master. It uses a server with an instance of [SSH-Tuna](https://github.com/accurat/ssh-tuna) to achieve this.
- `yarn build` builds the project for production, ready to be deployed from the `build/` folder
- `yarn test` runs [jest](https://jestjs.io/en/). By default (if you're not in a CI) it runs in watch mode, but you can disable watch mode by passing `--watch=false`. You can also pass any other argument you would pass to jest, for example `yarn test --updateSnapshot` updates your snapshots.
- `yarn lint` lints with eslint the `src/` folder. You can pass any [eslint options](https://eslint.org/docs/user-guide/command-line-interface#options) to the lint command, for example if you want to use eslint's fix option, you do it like this:
```json
"lint-fix": "accurapp-scripts lint --fix",
Expand Down Expand Up @@ -276,12 +278,13 @@ new Date(Number(process.env.LATEST_COMMIT_TIMESTAMP))
├── .babelrc
├── .env.example
├── .eslintrc
├── .gitignore
├── .prettierignore
├── .prettierrc
├── .gitignore
├── jest.config.js
├── netlify.toml
├── README.md
├── package.json
├── README.md
├── webpack.config.js
└── yarn.lock
```
Expand Down Expand Up @@ -736,6 +739,30 @@ Please, see [`@joshbuchea`'s head repo](https://gethead.info/).
[This guide](https://gist.github.com/matthewjberger/6f42452cb1a2253667942d333ff53404) is a good one to follow, and [here is a working example](https://github.com/nkint/accurapp-electron) of accurapp with electron. Good luck!
</details>


<details>
<summary>How do I configure a multi-project repo?</summary>

Your best bet is to use [yarn workspaces](https://yarnpkg.com/lang/en/docs/workspaces/). It will solve you a lot of headaches.

This is an example `package.json`, assuming that your multiple projects are in a subfolder called `projects`.

```json
{
"name": "main-project-name",
"private": true,
"workspaces": [
"projects/*"
]
}
```

Yarn workspaces basically puts your dependencies in just one place, at the root.

This approach allows you to require files across projects really easily. It is advised not to make a new project containing only the shared files, but rather choose a project to be the source of thruth, containing every image or UI components.

</details>

## Contributing
If you make some edits and wish to test them locally you can run `yarn test` for an end-to-end test, or `yarn create-test-app` which creates a test app using the local packages.

Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
"lint": "node node_modules/eslint/bin/eslint.js packages",
"test": "./test/e2e.sh",
"create-test-app": "./test/create-test-app.sh",
"create-test-app-build": "(yarn create-test-app && cd test-app/ && yarn build)",
"create-test-app-start": "(yarn create-test-app && cd test-app/ && BROWSER=false yarn start --exposed)",
"create-test-app-build": "(yarn create-test-app && cd test-app/ && yarn build)",
"create-test-app-test": "(yarn create-test-app && cd test-app/ && yarn test --watch=false)",
"publish": "is-git-status-clean && lerna publish --conventional-commits --message 'chore: 🚀 Publish'"
},
"husky": {
Expand Down
1 change: 1 addition & 0 deletions packages/accurapp-scripts/bin/scripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ if (!process.env.CI) {
require('../package.json'),
require('../../babel-preset-accurapp/package.json'),
require('../../eslint-config-accurapp/package.json'),
require('../../jest-config-accurapp/package.json'),
require('../../webpack-preset-accurapp/package.json'),
]

Expand Down
2 changes: 1 addition & 1 deletion packages/accurapp-scripts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
"react-dev-utils": "9.0.1",
"resolve": "1.11.0",
"semver": "6.1.1",
"ssh-tuna": "^1.0.3",
"ssh-tuna": "1.0.3",
"webpack": "4.34.0",
"webpack-dev-server": "3.2.1"
}
Expand Down
22 changes: 22 additions & 0 deletions packages/accurapp-scripts/scripts/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
require('dotenv').config() // gives precedence to the env variables already present
process.env.NODE_ENV = 'test'
process.env.PUBLIC_URL = ''

const path = require('path')
const jest = require('jest')
const { isInGitRepository } = require('../utils/git-utils')

const argv = process.argv.slice(2)

// Watch unless on CI or explicitly specified not tos
if (!process.env.CI && !argv.includes('--watch=false')) {
// --watch needs a git repository because it runs only the edited test
argv.push(isInGitRepository() ? '--watch' : '--watchAll')
}

// Load the config
const appDir = process.cwd()
const appJestConfig = path.resolve(appDir, 'jest.config.js')
argv.push('--config', JSON.stringify(appJestConfig))

jest.run(argv)
10 changes: 10 additions & 0 deletions packages/accurapp-scripts/utils/git-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,21 @@ function extractRepoName() {
}
}

function isInGitRepository() {
try {
cp.execSync('git rev-parse --is-inside-work-tree', { stdio: 'ignore' })
return true
} catch (e) {
return false
}
}

module.exports = {
extractBrowserslistString,
extractLatestCommitHash,
extractLatestCommitTimestamp,
extractLatestTag,
extractCurrentBranch,
extractRepoName,
isInGitRepository,
}
2 changes: 1 addition & 1 deletion packages/accurapp-scripts/utils/verifyTypeScriptSetup.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ function verifyTypeScriptSetup(appDir, { shouldInstall = true } = {}) {
if (shouldInstall) {
if (!appPkg.devDependencies.typescript && !appPkg.dependencies.typescript) {
log.ok(`Installing latest version of typescript`)
exec('yarn add --dev typescript @types/node @types/webpack-env', appDir)
exec('yarn add --dev typescript @types/node @types/webpack-env @types/jest', appDir)
exec('yarn add @types/react @types/react-dom @types/lodash', appDir)
}
}
Expand Down
12 changes: 10 additions & 2 deletions packages/babel-preset-accurapp/index.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
module.exports = (context, opts = {}) => {
const env = process.env.BABEL_ENV || process.env.NODE_ENV
const isDevelopment = env === 'development'
const isTest = env === 'test'
const useTypescript = opts.typescript

return {
presets: [
// Browsers are taken from the browserslist field in package.json
[
require('@babel/preset-env').default,
{
isTest ? {
targets: {
node: 'current',
},
} : {
modules: false,
useBuiltIns: 'usage',
// Enable stage 4 proposals, like array.flatMap
Expand All @@ -22,7 +27,7 @@ module.exports = (context, opts = {}) => {
{
// Adds component stack to warning messages
// Adds __self attribute to JSX which React will use for some warnings
development: isDevelopment,
development: isDevelopment || isTest,
// Will use the native built-in instead of trying to polyfill
// behavior for any plugins that require one.
useBuiltIns: true,
Expand Down Expand Up @@ -60,6 +65,9 @@ module.exports = (context, opts = {}) => {
// See discussion in https://github.com/facebook/create-react-app/issues/4263
[require('@babel/plugin-proposal-class-properties').default, { loose: true }],
require('@babel/plugin-proposal-json-strings').default,

// Transform dynamic import to require
...(isTest ? [require('babel-plugin-dynamic-import-node')] : []),
],
}
}
3 changes: 2 additions & 1 deletion packages/babel-preset-accurapp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,10 @@
"@babel/preset-env": "7.4.5",
"@babel/preset-react": "7.0.0",
"@babel/preset-typescript": "7.3.3",
"babel-plugin-dynamic-import-node": "2.3.0",
"babel-plugin-lodash": "3.3.4",
"babel-plugin-macros": "2.6.1",
"core-js": "3.0.1",
"regenerator-runtime": "^0.13.2"
"regenerator-runtime": "0.13.3"
}
}
8 changes: 5 additions & 3 deletions packages/create-accurapp/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ const packageJson = {
scripts: {
start: 'accurapp-scripts start',
build: 'accurapp-scripts build',
test: 'accurapp-scripts test',
lint: 'accurapp-scripts lint',
prettier: 'accurapp-scripts prettier',
},
Expand Down Expand Up @@ -133,10 +134,11 @@ if (shouldInstall) {

let devDependencies = [
'accurapp-scripts',
'webpack-preset-accurapp',
'eslint-config-accurapp',
'babel-preset-accurapp',
...(useTypescript ? ['typescript', '@types/node', '@types/webpack-env'] : []),
'eslint-config-accurapp',
'jest-config-accurapp',
'webpack-preset-accurapp',
...(useTypescript ? ['typescript', '@types/node', '@types/webpack-env', '@types/jest'] : []),
]

// Require local package if we're testing.
Expand Down
5 changes: 5 additions & 0 deletions packages/create-accurapp/template/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const accurappConfig = require('jest-config-accurapp')

module.exports = {
...accurappConfig,
}
1 change: 1 addition & 0 deletions packages/eslint-config-accurapp/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ module.exports = {
es6: true,
browser: true,
node: true,
jest: true,
},

globals: {
Expand Down
5 changes: 5 additions & 0 deletions packages/jest-config-accurapp/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# jest-config-accurapp

This package includes the Jest configuration used by Accurapp.

[For more info, checkout out the main documentation.](https://github.com/accurat/accurapp)
20 changes: 20 additions & 0 deletions packages/jest-config-accurapp/babelTransform.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const fs = require('fs')
const babelJest = require('babel-jest')

const appDir = process.cwd()
const useTypescript = fs.existsSync(`${appDir}/tsconfig.json`)
const babelrc = JSON.parse(fs.readFileSync(`${appDir}/.babelrc`))

// Inject the typescript option
if (useTypescript) {
babelrc.presets = [
...babelrc.presets.filter(p => p !== 'accurapp'),
['accurapp', { typescript: true }],
]
}

module.exports = babelJest.createTransformer({
...babelrc,
babelrc: false,
configFile: false,
})
38 changes: 38 additions & 0 deletions packages/jest-config-accurapp/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
module.exports = {
// Use newer version of jsdom
testEnvironment: 'jest-environment-jsdom-fifteen',

setupFiles: [
// It contains some polyfills such as the isomorphic fetch
'react-app-polyfill/jsdom',
'jest-config-accurapp/setup',
],

transform: {
// Wrapper around babel-jest
'\\.(js|jsx|ts|tsx)$': 'jest-config-accurapp/babelTransform',

// Transform simple css files in an empty object
// https://jestjs.io/docs/en/webpack.html
'\\.css$': 'react-scripts/config/jest/cssTransform',

// Transform all other files into just the filename string
'^(?!.*\\.(js|jsx|ts|tsx|css|json)$)': 'react-scripts/config/jest/fileTransform',
},

// Don't transform css modules into an empty object
transformIgnorePatterns: [
'\\.module\\.(css)$',
],

// Instead use identity-obj-proxy which outputs the classnames
moduleNameMapper: {
'\\.module\\.(css)$': 'identity-obj-proxy',
},

watchPlugins: [
// Filter your tests by file name or test name
'jest-watch-typeahead/filename',
'jest-watch-typeahead/testname',
],
}
30 changes: 30 additions & 0 deletions packages/jest-config-accurapp/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "jest-config-accurapp",
"version": "4.0.0",
"description": "Jest configuration used by Accurat",
"repository": "accurat/accurapp",
"license": "MIT",
"keywords": [
"jest",
"config",
"accurapp",
"accurat"
],
"engines": {
"node": ">=8.6",
"yarn": ">=1.2.1"
},
"files": [
"index.js"
],
"dependencies": {
"@babel/core": "7.4.5",
"babel-jest": "24.9.0",
"identity-obj-proxy": "3.0.0",
"jest": "24.9.0",
"jest-environment-jsdom-fifteen": "1.0.2",
"jest-watch-typeahead": "0.4.2",
"react-app-polyfill": "1.0.5",
"react-scripts": "3.3.0"
}
}
6 changes: 6 additions & 0 deletions packages/jest-config-accurapp/setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// TODO remove this when it will be integrated in jsdom
// https://github.com/jsdom/jsdom/issues/1721
function noop() { }
if (typeof window.URL.createObjectURL === 'undefined') {
Object.defineProperty(window.URL, 'createObjectURL', { value: noop })
}
Loading