diff --git a/package.json b/package.json index f80d830d..52623e68 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "dev:cp-frontend": "lerna run start --scope joyent-cp-frontend", "dev:gql-mock-server": "lerna run dev --scope joyent-cp-gql-mock-server", "commitmsg": "conventional-changelog-lint -e", - "precommit": "redrun -s lint-staged format-staged test-staged", + "precommit": "cross-env CI=1 redrun -s lint-staged format-staged test-staged", "prepare": "redrun -s clean bootstrap" }, "devDependencies": { @@ -46,6 +46,7 @@ "conventional-changelog-lint": "^1.1.9", "conventional-changelog-lint-config-angular": "^0.4.1", "conventional-changelog-lint-config-lerna-scopes": "^1.0.0", + "cross-env": "^5.0.0", "dotenv": "^4.0.0", "eslint": "^3.19.0", "eslint-config-prettier": "^2.1.1", diff --git a/packages/cp-frontend/package.json b/packages/cp-frontend/package.json index 1489467e..072d42dd 100644 --- a/packages/cp-frontend/package.json +++ b/packages/cp-frontend/package.json @@ -14,8 +14,8 @@ "lint-ci:css": "echo 0", "lint-ci:js": "eslint . --format junit --output-file $CIRCLE_TEST_REPORTS/lint/cp-frontend.xml", "lint-ci": "redrun -p lint-ci:*", - "test": "echo 0", - "test-ci": "echo 0", + "test": "NODE_ENV=test ./test/run --env=jsdom", + "test-ci": "NODE_ENV=test JEST_JUNIT_OUTPUT=$CIRCLE_TEST_REPORTS/test/cp-frontend.xml ./test/run --env=jsdom --coverage --coverageDirectory=$CIRCLE_ARTIFACTS/cp-frontend --testResultsProcessor='./node_modules/jest-junit'", "postinstall": "node scripts/postinstall" }, "dependencies": { @@ -53,11 +53,14 @@ "cross-env": "^5.0.0", "eslint": "^3.19.0", "eslint-config-joyent-portal": "1.0.0", - "jest": "^20.0.3", + "jest": "^20.0.4", + "jest-alias-preprocessor": "^1.1.0", + "jest-cli": "^20.0.4", "jest-diff": "^20.0.3", + "jest-junit": "^1.5.1", "jest-matcher-utils": "^20.0.3", "jest-snapshot": "^20.0.3", - "jest-styled-components": "^2.0.0", + "jest-styled-components": "^3.0.0-2", "mz": "^2.6.0", "react-scripts": "^1.0.0", "react-test-renderer": "^15.5.4", diff --git a/packages/cp-frontend/src/state/store.js b/packages/cp-frontend/src/state/store.js index 01778ee3..9d3149fa 100644 --- a/packages/cp-frontend/src/state/store.js +++ b/packages/cp-frontend/src/state/store.js @@ -4,8 +4,15 @@ import { ApolloClient, createNetworkInterface } from 'react-apollo'; import state from './state'; import { ui } from './reducers'; -const GQL_HOSTNAME = - process.env.REACT_APP_GQL_HOSTNAME || window.location.hostname; +const GLOBAL = typeof window === 'object' + ? window + : { + location: { + hostname: 'http://0.0.0.0' + } + }; + +const GQL_HOSTNAME = process.env.REACT_APP_GQL_HOSTNAME || GLOBAL; export const client = new ApolloClient({ dataIdFromObject: o => { @@ -35,8 +42,8 @@ export const store = createStore( applyMiddleware(client.middleware()), // If you are using the devToolsExtension, you can add it here also // eslint-disable-next-line no-negated-condition - typeof window.__REDUX_DEVTOOLS_EXTENSION__ !== 'undefined' - ? window.__REDUX_DEVTOOLS_EXTENSION__() + typeof GLOBAL.__REDUX_DEVTOOLS_EXTENSION__ !== 'undefined' + ? GLOBAL.__REDUX_DEVTOOLS_EXTENSION__() : f => f ) ); diff --git a/packages/cp-frontend/test/file-mock.js b/packages/cp-frontend/test/file-mock.js new file mode 100644 index 00000000..d906d5b4 --- /dev/null +++ b/packages/cp-frontend/test/file-mock.js @@ -0,0 +1 @@ +module.exports = 'test-file-mock'; diff --git a/packages/cp-frontend/test/run b/packages/cp-frontend/test/run new file mode 100755 index 00000000..209c3690 --- /dev/null +++ b/packages/cp-frontend/test/run @@ -0,0 +1,51 @@ +#!/usr/bin/env node + +// Do this as the first thing so that any code reading it knows the right env. +process.env.BABEL_ENV = 'test'; +process.env.NODE_ENV = 'test'; +process.env.PUBLIC_URL = ''; + +// Makes the script crash on unhandled rejections instead of silently +// ignoring them. In the future, promise rejections that are not handled will +// terminate the Node.js process with a non-zero exit code. +process.on('unhandledRejection', err => { + throw err; +}); + +// Ensure environment variables are read. +require('react-scripts/config/env'); + +const jest = require('jest'); +const argv = process.argv.slice(2); + +// Watch unless on CI or in coverage mode +if (!process.env.CI && argv.indexOf('--coverage') < 0) { + argv.push('--watch'); +} + +// This is not necessary after eject because we embed config into package.json. +const createJestConfig = require('react-scripts/scripts/utils/createJestConfig'); +const path = require('path'); +const paths = require('react-scripts/config/paths'); + +const config = createJestConfig( + relativePath => + path.resolve(__dirname, '../node_modules/react-scripts', relativePath), + path.resolve(__dirname, '..'), + false +); + +// patch +config.testEnvironment = 'node'; +config.testMatch = ['/test/(unit|integration)/*.js']; +config.moduleNameMapper = Object.assign({}, config.moduleNameMapper, { + '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': '/test/file-mock.js', + '^root/(.*)$': '/src/$1', + '^@components/(.*)$': '/src/components/$1', + '^@assets/(.*)$': '/src/assets/$1', + '^@state/(.*)$': '/src/state/$1' +}); + +argv.push('--config', JSON.stringify(config)); + +jest.run(argv); diff --git a/packages/cp-frontend/test/unit/__snapshots__/header.js.snap b/packages/cp-frontend/test/unit/__snapshots__/header.js.snap new file mode 100644 index 00000000..ce823761 --- /dev/null +++ b/packages/cp-frontend/test/unit/__snapshots__/header.js.snap @@ -0,0 +1,147 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renders
without throwing 1`] = ` +.FqmtD { + box-sizing: border-box; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-flex: 0 1 auto; + -ms-flex: 0 1 auto; + flex: 0 1 auto; + -webkit-flex-direction: row; + -ms-flex-direction: row; + flex-direction: row; + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + margin-right: -0.5rem; + margin-left: -0.5rem; +} + +.bpmDrC { + box-sizing: border-box; + -webkit-flex: 0 0 auto; + -ms-flex: 0 0 auto; + flex: 0 0 auto; + padding-right: 0.5rem; + padding-left: 0.5rem; +} + +.dPgIpY { + box-sizing: border-box; + -webkit-flex: 0 0 auto; + -ms-flex: 0 0 auto; + flex: 0 0 auto; + padding-right: 0.5rem; + padding-left: 0.5rem; +} + +.eBVNKv { + background-color: ; + padding: 0.9375rem 1.125rem 0.75rem 1.125rem; +} + +.ejNIBm { + color: ; + font-weight: 600; + margin: 0.1875rem 0 0 0; +} + +@media only screen and (min-width: 0em) { + .bpmDrC { + -webkit-flex-basis: 50%; + -ms-flex-basis: 50%; + flex-basis: 50%; + max-width: 50%; + display: block; + } +} + +@media only screen and (min-width: 48em) { + .bpmDrC { + -webkit-flex-basis: 66.66666666666667%; + -ms-flex-basis: 66.66666666666667%; + flex-basis: 66.66666666666667%; + max-width: 66.66666666666667%; + display: block; + } +} + +@media only screen and (min-width: 64em) { + .bpmDrC { + -webkit-flex-basis: 83.33333333333334%; + -ms-flex-basis: 83.33333333333334%; + flex-basis: 83.33333333333334%; + max-width: 83.33333333333334%; + display: block; + } +} + +@media only screen and (min-width: 0em) { + .dPgIpY { + -webkit-flex-basis: 25%; + -ms-flex-basis: 25%; + flex-basis: 25%; + max-width: 25%; + display: block; + } +} + +@media only screen and (min-width: 48em) { + .dPgIpY { + -webkit-flex-basis: 16.666666666666668%; + -ms-flex-basis: 16.666666666666668%; + flex-basis: 16.666666666666668%; + max-width: 16.666666666666668%; + display: block; + } +} + +@media only screen and (min-width: 64em) { + .dPgIpY { + -webkit-flex-basis: 8.333333333333334%; + -ms-flex-basis: 8.333333333333334%; + flex-basis: 8.333333333333334%; + max-width: 8.333333333333334%; + display: block; + } +} + +
+
+
+ + + +
+
+

+

+
+

+

+
+
+`; diff --git a/packages/cp-frontend/test/unit/header.js b/packages/cp-frontend/test/unit/header.js new file mode 100644 index 00000000..51ef2b1f --- /dev/null +++ b/packages/cp-frontend/test/unit/header.js @@ -0,0 +1,15 @@ +/** + * @jest-environment node + */ + +import 'jest-styled-components'; + +import React from 'react'; +import renderer from 'react-test-renderer'; +import Header from '@components/navigation/header'; +import { Router } from './mocks'; + +it('renders
without throwing', () => { + const tree = renderer.create(
).toJSON(); + expect(tree).toMatchStyledComponentsSnapshot(); +}); diff --git a/packages/cp-frontend/test/unit/mocks/index.js b/packages/cp-frontend/test/unit/mocks/index.js new file mode 100644 index 00000000..cf9bab85 --- /dev/null +++ b/packages/cp-frontend/test/unit/mocks/index.js @@ -0,0 +1,3 @@ +export { default as Router } from './router'; +export { default as Store } from './store'; +export { default as Theme } from './theme'; diff --git a/packages/cp-frontend/test/unit/mocks/router.js b/packages/cp-frontend/test/unit/mocks/router.js new file mode 100644 index 00000000..47dbba36 --- /dev/null +++ b/packages/cp-frontend/test/unit/mocks/router.js @@ -0,0 +1,4 @@ +import React from 'react'; +import { MemoryRouter } from 'react-router-dom'; + +export default ({ children }) => {children}; diff --git a/packages/cp-frontend/test/unit/mocks/store.js b/packages/cp-frontend/test/unit/mocks/store.js new file mode 100644 index 00000000..e125d5c0 --- /dev/null +++ b/packages/cp-frontend/test/unit/mocks/store.js @@ -0,0 +1,7 @@ +import React from 'react'; +import { client, store } from '@state/store'; +import { ApolloProvider } from 'react-apollo'; + +export default ({ children }) => ( + {children} +); diff --git a/packages/cp-frontend/test/unit/mocks/theme.js b/packages/cp-frontend/test/unit/mocks/theme.js new file mode 100644 index 00000000..5b1a2a45 --- /dev/null +++ b/packages/cp-frontend/test/unit/mocks/theme.js @@ -0,0 +1,7 @@ +import React from 'react'; +import { ThemeProvider } from 'styled-components'; +import { theme } from 'joyent-ui-toolkit'; + +export default ({ children }) => ( + {children} +); diff --git a/packages/cp-frontend/yarn.lock b/packages/cp-frontend/yarn.lock index d2111e40..cb751ffe 100644 --- a/packages/cp-frontend/yarn.lock +++ b/packages/cp-frontend/yarn.lock @@ -55,12 +55,26 @@ acorn-globals@^3.1.0: dependencies: acorn "^4.0.4" +acorn-jsx@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-2.0.1.tgz#0edf9878a5866bca625f52955a1ed9e7d8c5117e" + dependencies: + acorn "^2.0.1" + acorn-jsx@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" dependencies: acorn "^3.0.4" +acorn@^1.0.3: + version "1.2.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-1.2.2.tgz#c8ce27de0acc76d896d2b1fad3df588d9e82f014" + +acorn@^2.0.1: + version "2.7.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-2.7.0.tgz#ab6e7d9d886aaca8b085bc3312b79a198433f0e7" + acorn@^3.0.4: version "3.3.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" @@ -2376,6 +2390,10 @@ eslint-plugin-import@2.2.0: minimatch "^3.0.3" pkg-up "^1.0.0" +eslint-plugin-jest@^20.0.3: + version "20.0.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-20.0.3.tgz#ec15eba6ac0ab44a67ebf6e02672ca9d7e7cba29" + eslint-plugin-jsx-a11y@5.0.3: version "5.0.3" resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-5.0.3.tgz#4a939f76ec125010528823331bf948cc573380b6" @@ -2607,6 +2625,15 @@ facet@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/facet/-/facet-0.3.0.tgz#1bf949d8a112e2045dda84259407def3deb62c1b" +falafel@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/falafel/-/falafel-1.2.0.tgz#c18d24ef5091174a497f318cd24b026a25cddab4" + dependencies: + acorn "^1.0.3" + foreach "^2.0.5" + isarray "0.0.1" + object-keys "^1.0.6" + fast-levenshtein@~2.0.4: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" @@ -3661,6 +3688,13 @@ jessy@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/jessy/-/jessy-2.0.1.tgz#2114b42a51caa40dd48caa8689cc8ffca25abe47" +jest-alias-preprocessor@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/jest-alias-preprocessor/-/jest-alias-preprocessor-1.1.0.tgz#a1b0ff7a370cb5aabc5d6257a34dd1e527247eb8" + dependencies: + lodash.flatten "^4.4.0" + transform-jest-deps "^2.2.0" + jest-changed-files@^20.0.3: version "20.0.3" resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-20.0.3.tgz#9394d5cc65c438406149bef1bf4d52b68e03e3f8" @@ -3768,6 +3802,13 @@ jest-jasmine2@^20.0.4: once "^1.4.0" p-map "^1.1.1" +jest-junit@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/jest-junit/-/jest-junit-1.5.1.tgz#f6e48203e691f827530f21fb509f8c0da75ca15b" + dependencies: + mkdirp "^0.5.1" + xml "^1.0.1" + jest-matcher-utils@^20.0.3: version "20.0.3" resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-20.0.3.tgz#b3a6b8e37ca577803b0832a98b164f44b7815612" @@ -3845,7 +3886,7 @@ jest-snapshot@^20.0.3: natural-compare "^1.4.0" pretty-format "^20.0.3" -jest-styled-components@^2.0.0: +jest-styled-components@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/jest-styled-components/-/jest-styled-components-2.2.0.tgz#7c0748c07979b090ede10220ffa67ab9057b4e8e" dependencies: @@ -3878,7 +3919,7 @@ jest@20.0.3: dependencies: jest-cli "^20.0.3" -jest@^20.0.3: +jest@^20.0.4: version "20.0.4" resolved "https://registry.yarnpkg.com/jest/-/jest-20.0.4.tgz#3dd260c2989d6dad678b1e9cc4d91944f6d602ac" dependencies: @@ -4143,7 +4184,7 @@ lodash.defaults@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" -lodash.flatten@^4.2.0: +lodash.flatten@^4.2.0, lodash.flatten@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" @@ -4208,6 +4249,10 @@ lodash.uniq@^4.5.0: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" +lodash@^3.10.1: + version "3.10.1" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" + log-symbols@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18" @@ -4592,7 +4637,7 @@ object-hash@^1.1.4: version "1.1.8" resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.1.8.tgz#28a659cf987d96a4dabe7860289f3b5326c4a03c" -object-keys@^1.0.8: +object-keys@^1.0.6, object-keys@^1.0.8: version "1.0.11" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d" @@ -6676,6 +6721,14 @@ tr46@~0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" +transform-jest-deps@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/transform-jest-deps/-/transform-jest-deps-2.2.1.tgz#8acbd3eba514dc17700c8fb6db7114f2f72a3e74" + dependencies: + acorn-jsx "^2.0.0" + falafel "^1.2.0" + lodash "^3.10.1" + trim-newlines@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" @@ -7142,6 +7195,10 @@ xml-name-validator@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-2.0.1.tgz#4d8b8f1eccd3419aa362061becef515e1e559635" +xml@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5" + "xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" diff --git a/packages/normalized-styled-components/package.json b/packages/normalized-styled-components/package.json index a6b45342..3cdf3c0d 100644 --- a/packages/normalized-styled-components/package.json +++ b/packages/normalized-styled-components/package.json @@ -24,8 +24,8 @@ "lint-ci:js": "eslint . --format junit --output-file $CIRCLE_TEST_REPORTS/lint/normalized-styled-components.xml", "lint": "redrun -s lint:*", "lint-ci": "redrun -p lint-ci:*", - "test": "bup && cross-env NODE_ENV=test jest --coverage", - "test-ci": "cross-env NODE_ENV=test JEST_JUNIT_OUTPUT=$CIRCLE_TEST_REPORTS/test/normalized-styled-components.xml jest --coverage --coverageDirectory=$CIRCLE_ARTIFACTS/normalized-styled-components --testResultsProcessor='./node_modules/jest-junit'", + "test": "bup && NODE_ENV=test jest --coverage", + "test-ci": "NODE_ENV=test JEST_JUNIT_OUTPUT=$CIRCLE_TEST_REPORTS/test/normalized-styled-components.xml jest --coverage --coverageDirectory=$CIRCLE_ARTIFACTS/normalized-styled-components --testResultsProcessor='./node_modules/jest-junit'", "build": "bup", "prepublish": "redrun build" }, @@ -37,7 +37,6 @@ "babel-preset-react-app": "^3.0.0", "bup": "^1.0.7", "chalk": "^1.1.3", - "cross-env": "^5.0.0", "eslint": "^3.19.0", "eslint-config-joyent-portal": "1.0.0", "jest": "^20.0.4", diff --git a/packages/ui-toolkit/package.json b/packages/ui-toolkit/package.json index 848d4b76..c9724346 100644 --- a/packages/ui-toolkit/package.json +++ b/packages/ui-toolkit/package.json @@ -4,8 +4,9 @@ "private": true, "license": "MPL-2.0", "repository": "github:yldio/joyent-portal", - "main": "dist/index.js", - "module": "dist/index.js", + "main": "dist/umd/index.js", + "jsnext:main": "dist/es/index.js", + "module": "dist/es/index.js", "scripts": { "lint:css": "echo 0", "lint-ci:css": "echo 0", @@ -15,12 +16,16 @@ "lint-ci": "redrun -s lint-ci:*", "test": "echo 0", "test-ci": "echo 0", - "copy-fonts": "rm -rf dist; mkdir -p dist/typography; cp -r src/typography/libre-franklin dist/typography", - "compile": "babel src --out-dir dist --source-maps inline", - "watch": "cross-env NODE_ENV=development redrun -s -c copy-fonts \"compile --watch\"", + "copy-fonts": "rm -rf dist; mkdir -p dist/es/typography; mkdir -p dist/umd/typography; cp -r src/typography/libre-franklin dist/es/typography; cp -r src/typography/libre-franklin dist/umd/typography", + "compile-watch:es": "NODE_ENV=development babel src --out-dir dist/es --source-maps inline --watch", + "compile:es": "NODE_ENV=development babel src --out-dir dist/es --source-maps inline", + "compile:umd": "cross-env NODE_ENV=test babel src --out-dir dist/umd --source-maps inline", + "compile-watch:umd": "cross-env NODE_ENV=test babel src --out-dir dist/umd --source-maps inline --watch", + "compile": "redrun -p compile:*", + "watch": "redrun copy-fonts && redrun -p compile-watch:*", "styleguide:build": "cross-env NODE_ENV=production styleguidist build", "styleguide": "cross-env NODE_ENV=development styleguidist server", - "postinstall": "cross-env NODE_ENV=production redrun -s copy-fonts compile" + "postinstall": "redrun -s copy-fonts compile" }, "dependencies": { "camel-case": "^3.0.0",