Run behavioral smoke tests with Jest, add output tests (#5150)

* Run smoke tests with Jest

* Get a unique port for smoke test

* Upgrade verdaccio across the board

* Drop unneeded step

* Try latest instead

* Boot registry in home directory

* Correct config path

* Add mutex

* Test webpack message formatting

* Strip color

* Add browserslist to default

* Disable another broken feature
This commit is contained in:
Joe Haddad
2018-09-28 06:19:29 -04:00
committed by GitHub
parent 39c73ce5e3
commit 2a7346e085
37 changed files with 485 additions and 289 deletions

View File

@@ -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"
}
}

View File

@@ -0,0 +1,5 @@
module.exports = {
testEnvironment: 'node',
testMatch: ['**/*.test.js'],
setupTestFrameworkScriptFile: './setupOutputTests.js',
};

View File

@@ -0,0 +1,6 @@
beforeAll(() => {
jest.setTimeout(1000 * 60 * 5);
});
beforeEach(() => {
jest.setTimeout(1000 * 60 * 5);
});

View File

@@ -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 | <div>
7 | <span>
> 8 | </div>
| ^
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": "",
}
`;

View File

@@ -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();
});
});

View File

@@ -0,0 +1,11 @@
{
"dependencies": {
"node-sass": "4.x",
"react": "latest",
"react-dom": "latest",
"react-scripts": "latest"
},
"browserslist": [
">0.2%"
]
}

View File

@@ -0,0 +1,9 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>React App</title>
</head>
<body>
<div id="root"></div>
</body>
</html>

View File

@@ -0,0 +1,13 @@
import React, { Component } from 'react';
class App extends Component {
render() {
return (
<div>
<span>
</div>
);
}
}
export default App;

View File

@@ -0,0 +1,3 @@
.App {
color: red;
}}

View File

@@ -0,0 +1,10 @@
import React, { Component } from 'react';
import './AppCss.css';
class App extends Component {
render() {
return <div className="App" />;
}
}
export default App;

View File

@@ -0,0 +1,13 @@
import React, { Component } from 'react';
function foo() {
const a = b;
}
class App extends Component {
render() {
return <div />;
}
}
export default App;

View File

@@ -0,0 +1,11 @@
import React, { Component } from 'react';
function foo() {}
class App extends Component {
render() {
return <div />;
}
}
export default App;

View File

@@ -0,0 +1,13 @@
import React, { Component } from 'react';
import { bar } from 'unknown-package';
class App extends Component {
componentDidMount() {
bar();
}
render() {
return <div />;
}
}
export default App;

View File

@@ -0,0 +1,13 @@
import React, { Component } from 'react';
import { bar } from './AppUnknownExport';
class App extends Component {
componentDidMount() {
bar();
}
render() {
return <div />;
}
}
export default App;

View File

@@ -0,0 +1,3 @@
export function foo() {
console.log('bar');
}

View File

@@ -0,0 +1,5 @@
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(<App />, document.getElementById('root'));

View File

@@ -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 });
});
});

View File

@@ -0,0 +1,9 @@
{
"dependencies": {
"bootstrap": "4.x",
"node-sass": "4.x",
"react": "latest",
"react-dom": "latest",
"react-scripts": "latest"
}
}

View File

@@ -0,0 +1,9 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>React App</title>
</head>
<body>
<div id="root"></div>
</body>
</html>

View File

@@ -0,0 +1,5 @@
import React from 'react';
import ReactDOM from 'react-dom';
import './index.sass';
ReactDOM.render(<div />, document.getElementById('root'));

View File

@@ -0,0 +1 @@
@import "~bootstrap/scss/bootstrap.scss";

View File

@@ -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 });
});
});

View File

@@ -0,0 +1,9 @@
{
"dependencies": {
"dva": "2.4.0",
"ky": "0.3.0",
"react": "latest",
"react-dom": "latest",
"react-scripts": "latest"
}
}

View File

@@ -0,0 +1,9 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>React App</title>
</head>
<body>
<div id="root"></div>
</body>
</html>

View File

@@ -0,0 +1,5 @@
module.exports = {
testEnvironment: 'node',
testMatch: ['**/*.test.js'],
setupTestFrameworkScriptFile: './setupSmokeTests.js',
};

View File

@@ -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);
});

75
fixtures/utils.js Normal file
View File

@@ -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,
};

View File

@@ -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"
},

View File

@@ -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 <div> (10:27)
8 | render() {
9 | return (
> 10 | <div className=\\"App\\"></p>
| ^
11 | <header className=\\"App-header\\">
12 | <img src={logo} className=\\"App-logo\\" alt=\\"logo\\" />
13 | <p>",
],
"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",
],
}
`;

View File

@@ -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 <div>\n\n 8 | render() {\n 9 | return (\n> 10 | <div className="App"></p>\n | ^\n 11 | <header className="App-header">\n 12 | <img src={logo} className="App-logo" alt="logo" />\n 13 | <p>\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 <div> (10:27)\n\n 8 | render() {\n 9 | return (\n> 10 | <div className="App"></p>\n | ^\n 11 | <header className="App-header">\n 12 | <img src={logo} className="App-logo" alt="logo" />\n 13 | <p>\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 <anonymous>\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();
});
});

View File

@@ -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

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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,
});
}
}