diff --git a/fixtures/behavior/builds-with-multiple-runtimes/package.json b/fixtures/behavior/builds-with-multiple-runtimes/package.json deleted file mode 100644 index a8cfdd29cce..00000000000 --- a/fixtures/behavior/builds-with-multiple-runtimes/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "builds-with-multiple-runtimes", - "description": "Tests that a build succeeds with multiple runtime versions", - "dependencies": { - "dva": "2.4.0", - "ky": "0.3.0" - } -} diff --git a/fixtures/output/jest.config.js b/fixtures/output/jest.config.js new file mode 100644 index 00000000000..fa718fa3ea3 --- /dev/null +++ b/fixtures/output/jest.config.js @@ -0,0 +1,5 @@ +module.exports = { + testEnvironment: 'node', + testMatch: ['**/*.test.js'], + setupTestFrameworkScriptFile: './setupOutputTests.js', +}; diff --git a/fixtures/output/setupOutputTests.js b/fixtures/output/setupOutputTests.js new file mode 100644 index 00000000000..b709406980f --- /dev/null +++ b/fixtures/output/setupOutputTests.js @@ -0,0 +1,6 @@ +beforeAll(() => { + jest.setTimeout(1000 * 60 * 5); +}); +beforeEach(() => { + jest.setTimeout(1000 * 60 * 5); +}); diff --git a/fixtures/output/webpack-message-formatting/__snapshots__/index.test.js.snap b/fixtures/output/webpack-message-formatting/__snapshots__/index.test.js.snap new file mode 100644 index 00000000000..923ae734dee --- /dev/null +++ b/fixtures/output/webpack-message-formatting/__snapshots__/index.test.js.snap @@ -0,0 +1,102 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`webpack message formatting formats babel syntax error 1`] = ` +Object { + "stderr": "Creating an optimized production build... +Failed to compile. + +./src/App.js +Syntax error: Unterminated JSX contents (8:12) + + 6 |
+ 7 | +> 8 |
+ | ^ + 9 | ); + 10 | } + 11 | } + + +", + "stdout": "", +} +`; + +exports[`webpack message formatting formats css syntax error 1`] = ` +Object { + "stderr": "Creating an optimized production build... +Failed to compile. + +./src/AppCss.css +Syntax Error: (3:2) Unexpected } + +  1 | .App { +  2 |  color: red; +> 3 | }} +  |  ^ +  4 |  + + +", + "stdout": "", +} +`; + +exports[`webpack message formatting formats eslint error 1`] = ` +Object { + "stderr": "Creating an optimized production build... +Failed to compile. + +./src/App.js + Line 4: 'b' is not defined no-undef + +Search for the keywords to learn more about each error. + + +", + "stdout": "", +} +`; + +exports[`webpack message formatting formats eslint warning 1`] = ` +Object { + "stderr": "", + "stdout": "Creating an optimized production build... +Compiled with warnings. + +./src/App.js + Line 3: 'foo' is defined but never used no-unused-vars + +Search for the keywords to learn more about each warning. +To ignore, add // eslint-disable-next-line to the line before. + +", +} +`; + +exports[`webpack message formatting formats missing package 1`] = ` +Object { + "stderr": "Creating an optimized production build... +Failed to compile. + +Module not found: Error: Can't resolve 'unknown-package' in '/private/var/folders/c3/vytj6_h56b77f_g72smntm3m0000gn/T/bf26e1d3700ad14275f6eefb5e4417c1/src' + + +", + "stdout": "", +} +`; + +exports[`webpack message formatting formats unknown export 1`] = ` +Object { + "stderr": "Creating an optimized production build... +Failed to compile. + +./src/App.js +1:1677-1680 './AppUnknownExport' does not contain an export named 'bar'. + + +", + "stdout": "", +} +`; diff --git a/fixtures/output/webpack-message-formatting/index.test.js b/fixtures/output/webpack-message-formatting/index.test.js new file mode 100644 index 00000000000..26f7a3678c0 --- /dev/null +++ b/fixtures/output/webpack-message-formatting/index.test.js @@ -0,0 +1,88 @@ +const { bootstrap, getOutputProduction } = require('../../utils'); +const fs = require('fs-extra'); +const path = require('path'); +const Semaphore = require('async-sema'); +const tempy = require('tempy'); + +describe('webpack message formatting', () => { + const semaphore = new Semaphore(1, { capacity: Infinity }); + let testDirectory; + beforeAll(async () => { + testDirectory = tempy.directory(); + await bootstrap({ directory: testDirectory, template: __dirname }); + }); + beforeEach(async () => { + await semaphore.acquire(); + }); + afterEach(async () => { + fs.removeSync(path.join(testDirectory, 'src', 'App.js')); + semaphore.release(); + }); + + it('formats babel syntax error', async () => { + fs.copySync( + path.join(__dirname, 'src', 'AppBabel.js'), + path.join(testDirectory, 'src', 'App.js') + ); + + const response = await getOutputProduction({ directory: testDirectory }); + expect(response).toMatchSnapshot(); + }); + + xit('formats css syntax error', async () => { + // TODO: fix me! + fs.copySync( + path.join(__dirname, 'src', 'AppCss.js'), + path.join(testDirectory, 'src', 'App.js') + ); + + const response = await getOutputProduction({ directory: testDirectory }); + expect(response).toMatchSnapshot(); + }); + + xit('formats unknown export', async () => { + // TODO: fix me! + fs.copySync( + path.join(__dirname, 'src', 'AppUnknownExport.js'), + path.join(testDirectory, 'src', 'App.js') + ); + + const response = await getOutputProduction({ directory: testDirectory }); + expect(response).toMatchSnapshot(); + }); + + xit('formats missing package', async () => { + // TODO: fix me! + fs.copySync( + path.join(__dirname, 'src', 'AppMissingPackage.js'), + path.join(testDirectory, 'src', 'App.js') + ); + + const response = await getOutputProduction({ directory: testDirectory }); + expect(response).toMatchSnapshot(); + }); + + it('formats eslint warning', async () => { + fs.copySync( + path.join(__dirname, 'src', 'AppLintWarning.js'), + path.join(testDirectory, 'src', 'App.js') + ); + + const response = await getOutputProduction({ directory: testDirectory }); + const sizeIndex = response.stdout.indexOf('File sizes after gzip'); + if (sizeIndex !== -1) { + response.stdout = response.stdout.substring(0, sizeIndex); + } + expect(response).toMatchSnapshot(); + }); + + it('formats eslint error', async () => { + fs.copySync( + path.join(__dirname, 'src', 'AppLintError.js'), + path.join(testDirectory, 'src', 'App.js') + ); + + const response = await getOutputProduction({ directory: testDirectory }); + expect(response).toMatchSnapshot(); + }); +}); diff --git a/fixtures/output/webpack-message-formatting/package.json b/fixtures/output/webpack-message-formatting/package.json new file mode 100644 index 00000000000..5f6f0ee96a2 --- /dev/null +++ b/fixtures/output/webpack-message-formatting/package.json @@ -0,0 +1,11 @@ +{ + "dependencies": { + "node-sass": "4.x", + "react": "latest", + "react-dom": "latest", + "react-scripts": "latest" + }, + "browserslist": [ + ">0.2%" + ] +} diff --git a/fixtures/output/webpack-message-formatting/public/index.html b/fixtures/output/webpack-message-formatting/public/index.html new file mode 100644 index 00000000000..86010b24067 --- /dev/null +++ b/fixtures/output/webpack-message-formatting/public/index.html @@ -0,0 +1,9 @@ + + + + React App + + +
+ + diff --git a/fixtures/output/webpack-message-formatting/src/AppBabel.js b/fixtures/output/webpack-message-formatting/src/AppBabel.js new file mode 100644 index 00000000000..b6799d38e5f --- /dev/null +++ b/fixtures/output/webpack-message-formatting/src/AppBabel.js @@ -0,0 +1,13 @@ +import React, { Component } from 'react'; + +class App extends Component { + render() { + return ( +
+ +
+ ); + } +} + +export default App; diff --git a/fixtures/output/webpack-message-formatting/src/AppCss.css b/fixtures/output/webpack-message-formatting/src/AppCss.css new file mode 100644 index 00000000000..530380750ec --- /dev/null +++ b/fixtures/output/webpack-message-formatting/src/AppCss.css @@ -0,0 +1,3 @@ +.App { + color: red; +}} diff --git a/fixtures/output/webpack-message-formatting/src/AppCss.js b/fixtures/output/webpack-message-formatting/src/AppCss.js new file mode 100644 index 00000000000..af04f1c60b5 --- /dev/null +++ b/fixtures/output/webpack-message-formatting/src/AppCss.js @@ -0,0 +1,10 @@ +import React, { Component } from 'react'; +import './AppCss.css'; + +class App extends Component { + render() { + return
; + } +} + +export default App; diff --git a/fixtures/output/webpack-message-formatting/src/AppLintError.js b/fixtures/output/webpack-message-formatting/src/AppLintError.js new file mode 100644 index 00000000000..6015c397d47 --- /dev/null +++ b/fixtures/output/webpack-message-formatting/src/AppLintError.js @@ -0,0 +1,13 @@ +import React, { Component } from 'react'; + +function foo() { + const a = b; +} + +class App extends Component { + render() { + return
; + } +} + +export default App; diff --git a/fixtures/output/webpack-message-formatting/src/AppLintWarning.js b/fixtures/output/webpack-message-formatting/src/AppLintWarning.js new file mode 100644 index 00000000000..0918e42b739 --- /dev/null +++ b/fixtures/output/webpack-message-formatting/src/AppLintWarning.js @@ -0,0 +1,11 @@ +import React, { Component } from 'react'; + +function foo() {} + +class App extends Component { + render() { + return
; + } +} + +export default App; diff --git a/fixtures/output/webpack-message-formatting/src/AppMissingPackage.js b/fixtures/output/webpack-message-formatting/src/AppMissingPackage.js new file mode 100644 index 00000000000..5e62c967430 --- /dev/null +++ b/fixtures/output/webpack-message-formatting/src/AppMissingPackage.js @@ -0,0 +1,13 @@ +import React, { Component } from 'react'; +import { bar } from 'unknown-package'; + +class App extends Component { + componentDidMount() { + bar(); + } + render() { + return
; + } +} + +export default App; diff --git a/fixtures/output/webpack-message-formatting/src/AppUnknownExport.js b/fixtures/output/webpack-message-formatting/src/AppUnknownExport.js new file mode 100644 index 00000000000..482a545240b --- /dev/null +++ b/fixtures/output/webpack-message-formatting/src/AppUnknownExport.js @@ -0,0 +1,13 @@ +import React, { Component } from 'react'; +import { bar } from './AppUnknownExport'; + +class App extends Component { + componentDidMount() { + bar(); + } + render() { + return
; + } +} + +export default App; diff --git a/fixtures/output/webpack-message-formatting/src/FooExport.js b/fixtures/output/webpack-message-formatting/src/FooExport.js new file mode 100644 index 00000000000..acf7c881810 --- /dev/null +++ b/fixtures/output/webpack-message-formatting/src/FooExport.js @@ -0,0 +1,3 @@ +export function foo() { + console.log('bar'); +} diff --git a/fixtures/output/webpack-message-formatting/src/index.js b/fixtures/output/webpack-message-formatting/src/index.js new file mode 100644 index 00000000000..b597a44232c --- /dev/null +++ b/fixtures/output/webpack-message-formatting/src/index.js @@ -0,0 +1,5 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import App from './App'; + +ReactDOM.render(, document.getElementById('root')); diff --git a/fixtures/smoke/boostrap-sass/index.test.js b/fixtures/smoke/boostrap-sass/index.test.js new file mode 100644 index 00000000000..44f3a6c9d13 --- /dev/null +++ b/fixtures/smoke/boostrap-sass/index.test.js @@ -0,0 +1,17 @@ +const { + bootstrap, + isSuccessfulDevelopment, + isSuccessfulProduction, +} = require('../../utils'); +beforeEach(async () => { + await bootstrap({ directory: global.testDirectory, template: __dirname }); +}); + +describe('bootstrap sass', () => { + it('builds in development', async () => { + await isSuccessfulDevelopment({ directory: global.testDirectory }); + }); + it('builds in production', async () => { + await isSuccessfulProduction({ directory: global.testDirectory }); + }); +}); diff --git a/fixtures/smoke/boostrap-sass/package.json b/fixtures/smoke/boostrap-sass/package.json new file mode 100644 index 00000000000..ba85a20cecf --- /dev/null +++ b/fixtures/smoke/boostrap-sass/package.json @@ -0,0 +1,9 @@ +{ + "dependencies": { + "bootstrap": "4.x", + "node-sass": "4.x", + "react": "latest", + "react-dom": "latest", + "react-scripts": "latest" + } +} diff --git a/fixtures/smoke/boostrap-sass/public/index.html b/fixtures/smoke/boostrap-sass/public/index.html new file mode 100644 index 00000000000..86010b24067 --- /dev/null +++ b/fixtures/smoke/boostrap-sass/public/index.html @@ -0,0 +1,9 @@ + + + + React App + + +
+ + diff --git a/fixtures/smoke/boostrap-sass/src/index.js b/fixtures/smoke/boostrap-sass/src/index.js new file mode 100644 index 00000000000..44f52927b5a --- /dev/null +++ b/fixtures/smoke/boostrap-sass/src/index.js @@ -0,0 +1,5 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import './index.sass'; + +ReactDOM.render(
, document.getElementById('root')); diff --git a/fixtures/smoke/boostrap-sass/src/index.sass b/fixtures/smoke/boostrap-sass/src/index.sass new file mode 100644 index 00000000000..48fa0ce0d6e --- /dev/null +++ b/fixtures/smoke/boostrap-sass/src/index.sass @@ -0,0 +1 @@ +@import "~bootstrap/scss/bootstrap.scss"; diff --git a/fixtures/smoke/builds-with-multiple-runtimes/index.test.js b/fixtures/smoke/builds-with-multiple-runtimes/index.test.js new file mode 100644 index 00000000000..990ea7b357c --- /dev/null +++ b/fixtures/smoke/builds-with-multiple-runtimes/index.test.js @@ -0,0 +1,17 @@ +const { + bootstrap, + isSuccessfulDevelopment, + isSuccessfulProduction, +} = require('../../utils'); +beforeEach(async () => { + await bootstrap({ directory: global.testDirectory, template: __dirname }); +}); + +describe('builds-with-multiple-runtimes', () => { + it('builds in development', async () => { + await isSuccessfulDevelopment({ directory: global.testDirectory }); + }); + it('builds in production', async () => { + await isSuccessfulProduction({ directory: global.testDirectory }); + }); +}); diff --git a/fixtures/smoke/builds-with-multiple-runtimes/package.json b/fixtures/smoke/builds-with-multiple-runtimes/package.json new file mode 100644 index 00000000000..7829ebdeabd --- /dev/null +++ b/fixtures/smoke/builds-with-multiple-runtimes/package.json @@ -0,0 +1,9 @@ +{ + "dependencies": { + "dva": "2.4.0", + "ky": "0.3.0", + "react": "latest", + "react-dom": "latest", + "react-scripts": "latest" + } +} diff --git a/fixtures/smoke/builds-with-multiple-runtimes/public/index.html b/fixtures/smoke/builds-with-multiple-runtimes/public/index.html new file mode 100644 index 00000000000..86010b24067 --- /dev/null +++ b/fixtures/smoke/builds-with-multiple-runtimes/public/index.html @@ -0,0 +1,9 @@ + + + + React App + + +
+ + diff --git a/fixtures/behavior/builds-with-multiple-runtimes/src/index.js b/fixtures/smoke/builds-with-multiple-runtimes/src/index.js similarity index 100% rename from fixtures/behavior/builds-with-multiple-runtimes/src/index.js rename to fixtures/smoke/builds-with-multiple-runtimes/src/index.js diff --git a/fixtures/smoke/jest.config.js b/fixtures/smoke/jest.config.js new file mode 100644 index 00000000000..9057ec0ea71 --- /dev/null +++ b/fixtures/smoke/jest.config.js @@ -0,0 +1,5 @@ +module.exports = { + testEnvironment: 'node', + testMatch: ['**/*.test.js'], + setupTestFrameworkScriptFile: './setupSmokeTests.js', +}; diff --git a/fixtures/smoke/setupSmokeTests.js b/fixtures/smoke/setupSmokeTests.js new file mode 100644 index 00000000000..1d4038de417 --- /dev/null +++ b/fixtures/smoke/setupSmokeTests.js @@ -0,0 +1,10 @@ +const fs = require('fs-extra'); +const tempy = require('tempy'); + +beforeEach(() => { + global.testDirectory = tempy.directory(); + jest.setTimeout(1000 * 60 * 5); +}); +afterEach(() => { + fs.removeSync(global.testDirectory); +}); diff --git a/fixtures/utils.js b/fixtures/utils.js new file mode 100644 index 00000000000..e40ffba0938 --- /dev/null +++ b/fixtures/utils.js @@ -0,0 +1,75 @@ +const execa = require('execa'); +const fs = require('fs-extra'); +const getPort = require('get-port'); +const path = require('path'); +const os = require('os'); +const stripAnsi = require('strip-ansi'); + +async function bootstrap({ directory, template }) { + await Promise.all( + ['public/', 'src/', 'package.json'].map(async file => + fs.copy(path.join(template, file), path.join(directory, file)) + ) + ); + await execa('yarnpkg', ['install', '--mutex', 'network'], { cwd: directory }); +} + +async function isSuccessfulDevelopment({ directory }) { + const { stdout, stderr } = await execa( + './node_modules/.bin/react-scripts', + ['start', '--smoke-test'], + { + cwd: directory, + env: { BROWSER: 'none', PORT: await getPort() }, + } + ); + + if (!/Compiled successfully/.test(stdout)) { + throw new Error(`stdout: ${stdout}${os.EOL + os.EOL}stderr: ${stderr}`); + } +} + +async function isSuccessfulProduction({ directory }) { + const { stdout, stderr } = await execa( + './node_modules/.bin/react-scripts', + ['build'], + { + cwd: directory, + } + ); + + if (!/Compiled successfully/.test(stdout)) { + throw new Error(`stdout: ${stdout}${os.EOL + os.EOL}stderr: ${stderr}`); + } +} + +async function getOutputProduction({ directory, env = {} }) { + try { + const { stdout, stderr } = await execa( + './node_modules/.bin/react-scripts', + ['build'], + { + cwd: directory, + env: Object.assign({}, { CI: 'false', FORCE_COLOR: '0' }, env), + } + ); + return { stdout: stripAnsi(stdout), stderr: stripAnsi(stderr) }; + } catch (err) { + return { + stdout: '', + stderr: stripAnsi( + err.message + .split(os.EOL) + .slice(2) + .join(os.EOL) + ), + }; + } +} + +module.exports = { + bootstrap, + isSuccessfulDevelopment, + isSuccessfulProduction, + getOutputProduction, +}; diff --git a/package.json b/package.json index a58e2a67d06..5acfc3a2563 100644 --- a/package.json +++ b/package.json @@ -18,17 +18,20 @@ "format": "prettier --trailing-comma es5 --single-quote --write 'packages/*/*.js' 'packages/*/!(node_modules)/**/*.js'" }, "devDependencies": { - "cross-spawn": "^6.0.5", + "async-sema": "^2.1.3", "eslint": "5.6.0", "execa": "1.0.0", "fs-extra": "^7.0.0", + "get-port": "^4.0.0", "husky": "1.0.0-rc.15", + "jest": "^23.6.0", "lerna": "2.9.1", "lerna-changelog": "^0.8.0", "lint-staged": "^7.0.5", "meow": "^5.0.0", "multimatch": "^2.1.0", "prettier": "1.14.3", + "strip-ansi": "^4.0.0", "svg-term-cli": "^2.1.1", "tempy": "^0.2.1" }, diff --git a/packages/react-dev-utils/__tests__/__snapshots__/formatWebpackMessages.test.js.snap b/packages/react-dev-utils/__tests__/__snapshots__/formatWebpackMessages.test.js.snap deleted file mode 100644 index 72a346de21e..00000000000 --- a/packages/react-dev-utils/__tests__/__snapshots__/formatWebpackMessages.test.js.snap +++ /dev/null @@ -1,81 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`formats various webpack errors correctly eslint errors 1`] = ` -Object { - "errors": Array [ - "./template/src/App.js - Line 8: 'c' is not defined no-undef - -Search for the keywords to learn more about each error.", - ], - "warnings": Array [], -} -`; - -exports[`formats various webpack errors correctly eslint warning 1`] = ` -Object { - "errors": Array [], - "warnings": Array [ - "./template/src/App.js - Line 7: 'unUsed' is defined but never used no-unused-vars", - ], -} -`; - -exports[`formats various webpack errors correctly export not found 1`] = ` -Object { - "errors": Array [ - "./template/src/index.js 1:182-185 - './App' does not contain an export named 'App'.", - ], - "warnings": Array [], -} -`; - -exports[`formats various webpack errors correctly invalid css syntax 1`] = ` -Object { - "errors": Array [ - "./template/src/App.css -Syntax error: (19:1) Unexpected } - - 17 | font-size: calc(10px + 2vmin); - 18 | color: white; -> 19 | } - | ^ - 20 | - 21 | .App-link {", - ], - "warnings": Array [], -} -`; - -exports[`formats various webpack errors correctly invalid js syntax (babel) 1`] = ` -Object { - "errors": Array [ - "./template/src/App.js -Syntax error: Expected corresponding JSX closing tag for
(10:27) - - 8 | render() { - 9 | return ( -> 10 |

- | ^ - 11 |
- 12 | \\"logo\\" - 13 |

", - ], - "warnings": Array [], -} -`; - -exports[`formats various webpack errors correctly module not found 1`] = ` -Object { - "errors": Array [ - "./template/src/App.js -Module not found: Can't resolve 'blabla' in '/Users/joe/Documents/Development/OSS/create-react-app/packages/react-scripts/template/src'", - ], - "warnings": Array [ - "./template/src/App.js - Line 5: 'bla' is defined but never used no-unused-vars", - ], -} -`; diff --git a/packages/react-dev-utils/__tests__/formatWebpackMessages.test.js b/packages/react-dev-utils/__tests__/formatWebpackMessages.test.js deleted file mode 100644 index 8f19406b631..00000000000 --- a/packages/react-dev-utils/__tests__/formatWebpackMessages.test.js +++ /dev/null @@ -1,84 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -'use strict'; - -const formatWebpackMessages = require('../formatWebpackMessages'); - -// TODO: test these messages by actually running a build so we can validate -// webpack upgrades didn't break any of our massaging -// https://github.com/facebook/create-react-app/pull/5137 -describe('formats various webpack errors correctly', () => { - it('invalid js syntax (babel)', () => { - const json = { - errors: [ - './template/src/App.js\nModule Error (from /Users/joe/Documents/Development/OSS/create-react-app/node_modules/thread-loader/dist/cjs.js):\n\n Line 10: Parsing error: Expected corresponding JSX closing tag for

\n\n 8 | render() {\n 9 | return (\n> 10 |

\n | ^\n 11 |
\n 12 | logo\n 13 |

\n\n\n @ ./template/src/index.js 1:77-100 1:182-185\n @ multi ./config/polyfills.js ./template/src/index.js', - './template/src/App.js\nModule build failed (from /Users/joe/Documents/Development/OSS/create-react-app/node_modules/thread-loader/dist/cjs.js):\nThread Loader (Worker 0)\n/Users/joe/Documents/Development/OSS/create-react-app/packages/react-scripts/template/src/App.js: Expected corresponding JSX closing tag for

(10:27)\n\n 8 | render() {\n 9 | return (\n> 10 |

\n | ^\n 11 |
\n 12 | logo\n 13 |

\n\n at _class.raise (/Users/joe/Documents/Development/OSS/create-react-app/node_modules/@babel/core/node_modules/babylon/lib/index.js:779:15)\n at _class.jsxParseElementAt (/Users/joe/Documents/Development/OSS/create-react-app/node_modules/@babel/core/node_modules/babylon/lib/index.js:8111:18)\n at _class.jsxParseElement (/Users/joe/Documents/Development/OSS/create-react-app/node_modules/@babel/core/node_modules/babylon/lib/index.js:8137:19)\n at _class.parseExprAtom (/Users/joe/Documents/Development/OSS/create-react-app/node_modules/@babel/core/node_modules/babylon/lib/index.js:8144:21)\n at _class.parseExprSubscripts (/Users/joe/Documents/Development/OSS/create-react-app/node_modules/@babel/core/node_modules/babylon/lib/index.js:2758:21)\n at _class.parseMaybeUnary (/Users/joe/Documents/Development/OSS/create-react-app/node_modules/@babel/core/node_modules/babylon/lib/index.js:2737:21)\n at _class.parseExprOps (/Users/joe/Documents/Development/OSS/create-react-app/node_modules/@babel/core/node_modules/babylon/lib/index.js:2646:21)\n at _class.parseMaybeConditional (/Users/joe/Documents/Development/OSS/create-react-app/node_modules/@babel/core/node_modules/babylon/lib/index.js:2618:21)\n at _class.parseMaybeAssign (/Users/joe/Documents/Development/OSS/create-react-app/node_modules/@babel/core/node_modules/babylon/lib/index.js:2565:21)\n at _class.parseMaybeAssign (/Users/joe/Documents/Development/OSS/create-react-app/node_modules/@babel/core/node_modules/babylon/lib/index.js:7270:57)\n @ ./template/src/index.js 1:77-100 1:182-185\n @ multi ./config/polyfills.js ./template/src/index.js', - ], - warnings: [], - }; - - expect(formatWebpackMessages(json)).toMatchSnapshot(); - }); - - it('invalid css syntax', () => { - const json = { - errors: [ - './template/src/App.css\nModule build failed (from /Users/joe/Documents/Development/OSS/create-react-app/node_modules/mini-css-extract-plugin/dist/loader.js):\nModuleBuildError: Module build failed (from /Users/joe/Documents/Development/OSS/create-react-app/node_modules/postcss-loader/lib/index.js):\nSyntax Error \n\n(19:1) Unexpected }\n\n 17 | font-size: calc(10px + 2vmin);\n 18 | color: white;\n> 19 | }\n | ^\n 20 | \n 21 | .App-link {\n\n at runLoaders (/Users/joe/Documents/Development/OSS/create-react-app/node_modules/webpack/lib/NormalModule.js:286:20)\n at /Users/joe/Documents/Development/OSS/create-react-app/node_modules/loader-runner/lib/LoaderRunner.js:364:11\n at /Users/joe/Documents/Development/OSS/create-react-app/node_modules/loader-runner/lib/LoaderRunner.js:230:18\n at context.callback (/Users/joe/Documents/Development/OSS/create-react-app/node_modules/loader-runner/lib/LoaderRunner.js:111:13)\n at Promise.resolve.then.then.catch (/Users/joe/Documents/Development/OSS/create-react-app/node_modules/postcss-loader/lib/index.js:194:44)\n at \n @ ./template/src/App.js 1:1905-1923\n @ ./template/src/index.js\n @ multi ./config/polyfills.js ./template/src/index.js', - ], - warnings: [], - }; - - expect(formatWebpackMessages(json)).toMatchSnapshot(); - }); - - it('module not found', () => { - const json = { - errors: [ - "./template/src/App.js\nModule not found: Error: Can't resolve 'blabla' in '/Users/joe/Documents/Development/OSS/create-react-app/packages/react-scripts/template/src'\n @ ./template/src/App.js 5:0-25\n @ ./template/src/index.js\n @ multi ./config/polyfills.js ../react-dev-utils/webpackHotDevClient.js ./template/src/index.js", - ], - warnings: [ - "./template/src/App.js\nModule Warning (from /Users/joe/Documents/Development/OSS/create-react-app/node_modules/thread-loader/dist/cjs.js):\n\n \u001b[1mLine 5:\u001b[22m 'bla' is defined but never used \u001b[33m\u001b[4mno-unused-vars\u001b[24m\u001b[39m\n\n\n @ ./template/src/index.js 5:0-24 7:36-39\n @ multi ./config/polyfills.js ../react-dev-utils/webpackHotDevClient.js ./template/src/index.js", - ], - }; - - expect(formatWebpackMessages(json)).toMatchSnapshot(); - }); - - it('eslint errors', () => { - const json = { - errors: [ - "./template/src/App.js\nModule Error (from /Users/joe/Documents/Development/OSS/create-react-app/node_modules/thread-loader/dist/cjs.js):\n\n \u001b[1mLine 8:\u001b[22m 'c' is not defined \u001b[31m\u001b[4mno-undef\u001b[24m\u001b[39m\n\nSearch for the \u001b[4m\u001b[31mkeywords\u001b[39m\u001b[24m to learn more about each error.\n @ ./template/src/index.js 1:77-100 1:182-185\n @ multi ./config/polyfills.js ./template/src/index.js", - ], - warnings: [], - }; - - expect(formatWebpackMessages(json)).toMatchSnapshot(); - }); - - it('eslint warning', () => { - const json = { - errors: [], - warnings: [ - "./template/src/App.js\nModule Warning (from /Users/joe/Documents/Development/OSS/create-react-app/node_modules/thread-loader/dist/cjs.js):\n\n \u001b[1mLine 7:\u001b[22m 'unUsed' is defined but never used \u001b[33m\u001b[4mno-unused-vars\u001b[24m\u001b[39m\n\n\n @ ./template/src/index.js 1:77-100 1:182-185\n @ multi ./config/polyfills.js ./template/src/index.js", - ], - }; - - expect(formatWebpackMessages(json)).toMatchSnapshot(); - }); - - it('export not found', () => { - const json = { - errors: [ - "./template/src/index.js 1:182-185\n\"export 'App' was not found in './App'\n @ multi ./config/polyfills.js ./template/src/index.js", - ], - warnings: [], - }; - - expect(formatWebpackMessages(json)).toMatchSnapshot(); - }); -}); diff --git a/tasks/e2e-behavior.sh b/tasks/e2e-behavior.sh index fe34514333f..9ee3c8555d8 100755 --- a/tasks/e2e-behavior.sh +++ b/tasks/e2e-behavior.sh @@ -76,7 +76,7 @@ yarn # Start local registry tmp_registry_log=`mktemp` -nohup npx verdaccio@3.2.0 -c tasks/verdaccio.yaml &>$tmp_registry_log & +(cd && nohup npx verdaccio@3.8.2 -c "$root_path"/tasks/verdaccio.yaml &>$tmp_registry_log &) # Wait for `verdaccio` to boot grep -q 'http address' <(tail -f $tmp_registry_log) @@ -92,22 +92,14 @@ git clean -df ./tasks/publish.sh --yes --force-publish=* --skip-git --cd-version=prerelease --exact --npm-tag=latest # ****************************************************************************** -# Now that we have published them, create a clean app folder and install them. +# Now that we have published them, run all tests as if they were released. # ****************************************************************************** -# Install the app in a temporary location -cd $temp_app_path -npx create-react-app test-behavior +# Smoke tests +./node_modules/.bin/jest --config fixtures/smoke/jest.config.js -# ****************************************************************************** -# Now that we used create-react-app to create an app depending on react-scripts, -# let's run through all of our behavior tests. -# ****************************************************************************** - -# Enter the app directory -cd "$temp_app_path/test-behavior" - -node "$root_path"/tasks/test-behavior.js "$temp_app_path/test-behavior" +# Output tests +./node_modules/.bin/jest --config fixtures/output/jest.config.js # Cleanup cleanup diff --git a/tasks/e2e-installs.sh b/tasks/e2e-installs.sh index 48ab42508be..642e4f671a9 100755 --- a/tasks/e2e-installs.sh +++ b/tasks/e2e-installs.sh @@ -86,7 +86,7 @@ yarn # Start local registry tmp_registry_log=`mktemp` -nohup npx verdaccio@3.2.0 -c tasks/verdaccio.yaml &>$tmp_registry_log & +(cd && nohup npx verdaccio@3.8.2 -c "$root_path"/tasks/verdaccio.yaml &>$tmp_registry_log &) # Wait for `verdaccio` to boot grep -q 'http address' <(tail -f $tmp_registry_log) diff --git a/tasks/e2e-kitchensink-eject.sh b/tasks/e2e-kitchensink-eject.sh index 41ea1ab0d10..1640ca85ed4 100755 --- a/tasks/e2e-kitchensink-eject.sh +++ b/tasks/e2e-kitchensink-eject.sh @@ -79,7 +79,7 @@ yarn # Start local registry tmp_registry_log=`mktemp` -nohup npx verdaccio@3.2.0 -c tasks/verdaccio.yaml &>$tmp_registry_log & +(cd && nohup npx verdaccio@3.8.2 -c "$root_path"/tasks/verdaccio.yaml &>$tmp_registry_log &) # Wait for `verdaccio` to boot grep -q 'http address' <(tail -f $tmp_registry_log) diff --git a/tasks/e2e-kitchensink.sh b/tasks/e2e-kitchensink.sh index 67429fdc585..2b886a1791a 100755 --- a/tasks/e2e-kitchensink.sh +++ b/tasks/e2e-kitchensink.sh @@ -79,7 +79,7 @@ yarn # Start local registry tmp_registry_log=`mktemp` -nohup npx verdaccio@3.2.0 -c tasks/verdaccio.yaml &>$tmp_registry_log & +(cd && nohup npx verdaccio@3.8.2 -c "$root_path"/tasks/verdaccio.yaml &>$tmp_registry_log &) # Wait for `verdaccio` to boot grep -q 'http address' <(tail -f $tmp_registry_log) diff --git a/tasks/e2e-simple.sh b/tasks/e2e-simple.sh index da0d9219502..ce3324ab43f 100755 --- a/tasks/e2e-simple.sh +++ b/tasks/e2e-simple.sh @@ -86,7 +86,7 @@ yarn # Start local registry tmp_registry_log=`mktemp` -nohup npx verdaccio@3.2.0 -c tasks/verdaccio.yaml &>$tmp_registry_log & +(cd && nohup npx verdaccio@3.8.2 -c "$root_path"/tasks/verdaccio.yaml &>$tmp_registry_log &) # Wait for `verdaccio` to boot grep -q 'http address' <(tail -f $tmp_registry_log) diff --git a/tasks/test-behavior.js b/tasks/test-behavior.js deleted file mode 100644 index 46bba908a0e..00000000000 --- a/tasks/test-behavior.js +++ /dev/null @@ -1,97 +0,0 @@ -'use strict'; - -const args = process.argv.slice(2); -const fs = require('fs-extra'); -const path = require('path'); -const os = require('os'); -const spawn = require('cross-spawn'); - -const applicationPath = args.pop(); -const applicationPackageJson = path.resolve(applicationPath, 'package.json'); -const applicationSrc = path.resolve(applicationPath, 'src'); -const applicationModules = path.resolve(applicationPath, 'node_modules'); - -const fixturePath = path.resolve(__dirname, '..', 'fixtures', 'behavior'); -const fixtures = fs - .readdirSync(fixturePath) - .map(fixture => path.resolve(fixturePath, fixture)) - .filter(path => fs.lstatSync(path).isDirectory); - -const packageContents = require(applicationPackageJson); - -function install({ root }) { - spawn.sync('yarnpkg', ['--cwd', root, 'install'], { cwd: root }); -} - -function startApp({ root }) { - const output = spawn - .sync('yarnpkg', ['start', '--smoke-test'], { cwd: root }) - .output.join(''); - - if (!/Compiled successfully/.test(output)) { - throw new Error(output); - } - - console.log('\t = application started: ', output); -} - -function buildApp({ root }) { - const output = spawn - .sync('yarnpkg', ['build'], { cwd: root }) - .output.join(''); - - if (!/Compiled successfully/.test(output)) { - throw new Error(output); - } - - console.log('\t = application built: ', output); -} - -console.log(`=> checking ${fixtures.length} fixtures`); -for (const fixture of fixtures) { - const { - name, - description, - dependencies, - devDependencies, - } = require(path.resolve(fixture, 'package.json')); - console.log(`\t * checking fixture ${name}`); - console.log(`\t ... this fixture: ${description}`); - - fs.emptyDirSync(applicationSrc); - fs.emptyDirSync(applicationModules); - fs.copySync(path.resolve(fixture, 'src'), applicationSrc); - - try { - fs.writeJsonSync( - applicationPackageJson, - Object.assign({}, packageContents, { - dependencies: Object.assign( - {}, - packageContents.dependencies, - dependencies - ), - devDependencies: Object.assign( - {}, - packageContents.devDependencies, - devDependencies - ), - }), - { - spaces: 2, - EOL: os.EOL, - } - ); - install({ root: applicationPath }); - startApp({ root: applicationPath }); - buildApp({ root: applicationPath }); - } catch (e) { - console.error(`\t ! failed on ${name}:`); - throw e; - } finally { - fs.writeJsonSync(applicationPackageJson, packageContents, { - spaces: 2, - EOL: os.EOL, - }); - } -}