mirror of
https://github.com/zhigang1992/create-react-app.git
synced 2026-01-12 22:46:30 +08:00
Clean up the behavior tests (#5365)
* Speed up installs with pnp * Move to a better relative path test * Continue work on new test organization * Move mjs test to new enhanced tests * Move over last legacy test * Update behavior e2e script * Add first iteration of instructions to test readme * Add some more bad instructions * Split test command into multiple lines * Use two workers (do not run in band) * Bump install timeout * No global pollution * Fix PnP support via standard run mechanism * Prevent circular serve command * Silent yarn execs * Fix common commands by using a shell * Run with npx instead of Yarn * Remove unused scripts * Wait for localhost and fix script booting with PnP * Don't pnp locally because links will cause module resolution to whine * lint-staged is annoying * Strip Yarn out of execa runs * Set default license if none specified * Don't impose worker limit * Disable pnp for webpack messages * Add missing dependency * Disable timeout and rely on Jest * Only use 2 jest workers * Add missing dependency
This commit is contained in:
@@ -1,5 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`graphql with mjs entrypoint correctly bundles files in development 1`] = `"Pikachu"`;
|
||||
|
||||
exports[`graphql with mjs entrypoint correctly bundles files in production 1`] = `"Pikachu"`;
|
||||
@@ -1,56 +0,0 @@
|
||||
const {
|
||||
bootstrap,
|
||||
startDevelopmentServer,
|
||||
startProductionServer,
|
||||
} = require('../../utils');
|
||||
const puppeteer = require('puppeteer');
|
||||
|
||||
beforeEach(async () => {
|
||||
await bootstrap({ directory: global.testDirectory, template: __dirname });
|
||||
global.appDevPort = await startDevelopmentServer({
|
||||
directory: global.testDirectory,
|
||||
});
|
||||
global.appProdPort = await startProductionServer({
|
||||
directory: global.testDirectory,
|
||||
});
|
||||
// Wait for serve to boot up
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
});
|
||||
|
||||
// https://github.com/facebook/create-react-app/issues/5234
|
||||
// https://github.com/facebook/create-react-app/pull/5258
|
||||
describe('graphql with mjs entrypoint', () => {
|
||||
it('correctly bundles files in development', async () => {
|
||||
const browser = await puppeteer.launch({ headless: true });
|
||||
try {
|
||||
const page = await browser.newPage();
|
||||
await page.goto(`http://localhost:${global.appDevPort}/`);
|
||||
await page.waitForSelector('.Pokemon-Name-Data');
|
||||
const output = await page.evaluate(() => {
|
||||
return Array.from(
|
||||
document.getElementsByClassName('Pokemon-Name-Data')
|
||||
).pop().innerHTML;
|
||||
});
|
||||
expect(output).toMatchSnapshot();
|
||||
} finally {
|
||||
browser.close();
|
||||
}
|
||||
});
|
||||
|
||||
it('correctly bundles files in production', async () => {
|
||||
const browser = await puppeteer.launch({ headless: true });
|
||||
try {
|
||||
const page = await browser.newPage();
|
||||
await page.goto(`http://localhost:${global.appProdPort}/`);
|
||||
await page.waitForSelector('.Pokemon-Name-Data');
|
||||
const output = await page.evaluate(() => {
|
||||
return Array.from(
|
||||
document.getElementsByClassName('Pokemon-Name-Data')
|
||||
).pop().innerHTML;
|
||||
});
|
||||
expect(output).toMatchSnapshot();
|
||||
} finally {
|
||||
browser.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -1,7 +0,0 @@
|
||||
module.exports = {
|
||||
testEnvironment: 'node',
|
||||
testMatch: ['**/*.test.js'],
|
||||
testPathIgnorePatterns: ['/src/', 'node_modules'],
|
||||
setupTestFrameworkScriptFile: './setupBrowserTests.js',
|
||||
forceExit: true,
|
||||
};
|
||||
@@ -1,9 +0,0 @@
|
||||
const fs = require('fs-extra');
|
||||
const tempy = require('tempy');
|
||||
beforeEach(() => {
|
||||
global.testDirectory = tempy.directory();
|
||||
jest.setTimeout(1000 * 60 * 5);
|
||||
});
|
||||
afterEach(() => {
|
||||
fs.removeSync(global.testDirectory);
|
||||
});
|
||||
@@ -1,5 +0,0 @@
|
||||
module.exports = {
|
||||
testEnvironment: 'node',
|
||||
testMatch: ['**/*.test.js'],
|
||||
setupTestFrameworkScriptFile: './setupOutputTests.js',
|
||||
};
|
||||
@@ -1,6 +0,0 @@
|
||||
beforeAll(() => {
|
||||
jest.setTimeout(1000 * 60 * 5);
|
||||
});
|
||||
beforeEach(() => {
|
||||
jest.setTimeout(1000 * 60 * 5);
|
||||
});
|
||||
@@ -1,157 +0,0 @@
|
||||
const {
|
||||
bootstrap,
|
||||
getOutputDevelopment,
|
||||
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();
|
||||
});
|
||||
|
||||
it('formats css syntax error', async () => {
|
||||
fs.copySync(
|
||||
path.join(__dirname, 'src', 'AppCss.js'),
|
||||
path.join(testDirectory, 'src', 'App.js')
|
||||
);
|
||||
|
||||
const response = await getOutputProduction({ directory: testDirectory });
|
||||
expect(response).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('formats unknown export', async () => {
|
||||
fs.copySync(
|
||||
path.join(__dirname, 'src', 'AppUnknownExport.js'),
|
||||
path.join(testDirectory, 'src', 'App.js')
|
||||
);
|
||||
|
||||
const response = await getOutputProduction({ directory: testDirectory });
|
||||
expect(response).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('formats aliased unknown export', async () => {
|
||||
fs.copySync(
|
||||
path.join(__dirname, 'src', 'AppAliasUnknownExport.js'),
|
||||
path.join(testDirectory, 'src', 'App.js')
|
||||
);
|
||||
|
||||
const response = await getOutputProduction({ directory: testDirectory });
|
||||
expect(response).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('formats no default export', async () => {
|
||||
fs.copySync(
|
||||
path.join(__dirname, 'src', 'AppNoDefault.js'),
|
||||
path.join(testDirectory, 'src', 'App.js')
|
||||
);
|
||||
|
||||
const response = await getOutputProduction({ directory: testDirectory });
|
||||
expect(response).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('formats missing package', async () => {
|
||||
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();
|
||||
});
|
||||
|
||||
it('helps when users tries to use sass', async () => {
|
||||
fs.copySync(
|
||||
path.join(__dirname, 'src', 'AppSass.js'),
|
||||
path.join(testDirectory, 'src', 'App.js')
|
||||
);
|
||||
|
||||
const response = await getOutputProduction({ directory: testDirectory });
|
||||
expect(response).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('formats file not found error', async () => {
|
||||
fs.copySync(
|
||||
path.join(__dirname, 'src', 'AppUnknownFile.js'),
|
||||
path.join(testDirectory, 'src', 'App.js')
|
||||
);
|
||||
|
||||
const response = await getOutputProduction({ directory: testDirectory });
|
||||
expect(response).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('formats case sensitive path error', async () => {
|
||||
fs.copySync(
|
||||
path.join(__dirname, 'src', 'AppIncorrectCase.js'),
|
||||
path.join(testDirectory, 'src', 'App.js')
|
||||
);
|
||||
|
||||
const response = await getOutputDevelopment({ directory: testDirectory });
|
||||
if (process.platform === 'darwin') {
|
||||
expect(response.stderr).toMatch(
|
||||
`Cannot find file: 'export5.js' does not match the corresponding name on disk: './src/Export5.js'.`
|
||||
);
|
||||
} else {
|
||||
expect(response.stderr).not.toEqual(''); // TODO: figure out how we can test this on Linux/Windows
|
||||
// I believe getting this working requires we tap into enhanced-resolve
|
||||
// pipeline, which is debt we don't want to take on right now.
|
||||
}
|
||||
});
|
||||
|
||||
it('formats out of scope error', async () => {
|
||||
fs.copySync(
|
||||
path.join(__dirname, 'src', 'AppOutOfScopeImport.js'),
|
||||
path.join(testDirectory, 'src', 'App.js')
|
||||
);
|
||||
|
||||
const response = await getOutputProduction({ directory: testDirectory });
|
||||
expect(response).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
@@ -1,9 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>React App</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,17 +0,0 @@
|
||||
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 });
|
||||
});
|
||||
});
|
||||
@@ -1,9 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>React App</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,17 +0,0 @@
|
||||
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 });
|
||||
});
|
||||
});
|
||||
@@ -1,9 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>React App</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,13 +0,0 @@
|
||||
const { bootstrap, isSuccessfulTest } = require('../../utils');
|
||||
beforeEach(async () => {
|
||||
await bootstrap({ directory: global.testDirectory, template: __dirname });
|
||||
});
|
||||
|
||||
describe('issue #5176 (flow class properties interaction)', () => {
|
||||
it('passes tests', async () => {
|
||||
await isSuccessfulTest({
|
||||
directory: global.testDirectory,
|
||||
jestEnvironment: 'node',
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,9 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>React App</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,37 +0,0 @@
|
||||
const fs = require('fs-extra');
|
||||
const globby = require('globby');
|
||||
const path = require('path');
|
||||
const {
|
||||
bootstrap,
|
||||
isSuccessfulDevelopment,
|
||||
isSuccessfulProduction,
|
||||
} = require('../../utils');
|
||||
beforeEach(async () => {
|
||||
await bootstrap({ directory: global.testDirectory, template: __dirname });
|
||||
});
|
||||
|
||||
describe('relative paths', () => {
|
||||
// TODO: enable when development relative paths are supported
|
||||
xit('builds in development', async () => {
|
||||
await isSuccessfulDevelopment({ directory: global.testDirectory });
|
||||
});
|
||||
it('builds in production', async () => {
|
||||
await isSuccessfulProduction({ directory: global.testDirectory });
|
||||
|
||||
const buildDir = path.join(global.testDirectory, 'build');
|
||||
const cssFile = path.join(
|
||||
buildDir,
|
||||
globby.sync('**/*.css', { cwd: buildDir }).pop()
|
||||
);
|
||||
const svgFile = path.join(
|
||||
buildDir,
|
||||
globby.sync('**/*.svg', { cwd: buildDir }).pop()
|
||||
);
|
||||
const desiredPath = /url\((.+?)\)/
|
||||
.exec(fs.readFileSync(cssFile, 'utf8'))
|
||||
.pop();
|
||||
expect(path.resolve(path.join(path.dirname(cssFile), desiredPath))).toBe(
|
||||
path.resolve(svgFile)
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -1,9 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>React App</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,10 +0,0 @@
|
||||
const fs = require('fs-extra');
|
||||
const tempy = require('tempy');
|
||||
|
||||
beforeEach(() => {
|
||||
global.testDirectory = tempy.directory();
|
||||
jest.setTimeout(1000 * 60 * 5);
|
||||
});
|
||||
afterEach(() => {
|
||||
fs.removeSync(global.testDirectory);
|
||||
});
|
||||
@@ -1,177 +0,0 @@
|
||||
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 }) {
|
||||
const shouldInstallScripts = process.env.CI && process.env.CI !== 'false';
|
||||
await Promise.all(
|
||||
['public/', 'src/', 'package.json'].map(async file =>
|
||||
fs.copy(path.join(template, file), path.join(directory, file))
|
||||
)
|
||||
);
|
||||
if (shouldInstallScripts) {
|
||||
const packageJson = fs.readJsonSync(path.join(directory, 'package.json'));
|
||||
packageJson.dependencies = Object.assign({}, packageJson.dependencies, {
|
||||
'react-scripts': 'latest',
|
||||
});
|
||||
fs.writeJsonSync(path.join(directory, 'package.json'), packageJson);
|
||||
}
|
||||
await execa('yarnpkg', ['install', '--mutex', 'network'], { cwd: directory });
|
||||
if (!shouldInstallScripts) {
|
||||
fs.ensureSymlinkSync(
|
||||
path.resolve(
|
||||
path.join(
|
||||
__dirname,
|
||||
'..',
|
||||
'packages',
|
||||
'react-scripts',
|
||||
'bin',
|
||||
'react-scripts.js'
|
||||
)
|
||||
),
|
||||
path.join(directory, 'node_modules', '.bin', 'react-scripts')
|
||||
);
|
||||
await execa('yarnpkg', ['link', 'react-scripts'], { 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 isSuccessfulTest({ directory, jestEnvironment = 'jsdom' }) {
|
||||
await execa(
|
||||
'./node_modules/.bin/react-scripts',
|
||||
['test', '--env', jestEnvironment, '--ci'],
|
||||
{
|
||||
cwd: directory,
|
||||
env: { CI: 'true' },
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
async function getOutputDevelopment({ directory, env = {} }) {
|
||||
try {
|
||||
const { stdout, stderr } = await execa(
|
||||
'./node_modules/.bin/react-scripts',
|
||||
['start', '--smoke-test'],
|
||||
{
|
||||
cwd: directory,
|
||||
env: Object.assign(
|
||||
{},
|
||||
{
|
||||
BROWSER: 'none',
|
||||
PORT: await getPort(),
|
||||
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)
|
||||
),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
async function startDevelopmentServer({ directory, env = {} }) {
|
||||
const port = await getPort();
|
||||
execa('./node_modules/.bin/react-scripts', ['start'], {
|
||||
cwd: directory,
|
||||
env: Object.assign(
|
||||
{},
|
||||
{
|
||||
BROWSER: 'none',
|
||||
PORT: port,
|
||||
CI: 'false',
|
||||
FORCE_COLOR: '0',
|
||||
},
|
||||
env
|
||||
),
|
||||
});
|
||||
return port;
|
||||
}
|
||||
|
||||
async function startProductionServer({ directory, env = {} }) {
|
||||
const port = await getPort();
|
||||
await execa('./node_modules/.bin/react-scripts', ['build'], {
|
||||
cwd: directory,
|
||||
env: Object.assign({}, { CI: 'false' }, env),
|
||||
});
|
||||
execa('./node_modules/.bin/serve', ['-s', 'build', '-p', port], {
|
||||
cwd: directory,
|
||||
});
|
||||
return port;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
bootstrap,
|
||||
isSuccessfulDevelopment,
|
||||
isSuccessfulProduction,
|
||||
isSuccessfulTest,
|
||||
getOutputDevelopment,
|
||||
getOutputProduction,
|
||||
startDevelopmentServer,
|
||||
startProductionServer,
|
||||
};
|
||||
@@ -19,7 +19,6 @@
|
||||
"compile:lockfile": "node tasks/compile-lockfile.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"async-sema": "^2.1.3",
|
||||
"eslint": "5.6.0",
|
||||
"execa": "1.0.0",
|
||||
"fs-extra": "^7.0.0",
|
||||
@@ -36,7 +35,8 @@
|
||||
"puppeteer": "^1.8.0",
|
||||
"strip-ansi": "^4.0.0",
|
||||
"svg-term-cli": "^2.1.1",
|
||||
"tempy": "^0.2.1"
|
||||
"tempy": "^0.2.1",
|
||||
"wait-for-localhost": "2.0.1"
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
|
||||
@@ -95,14 +95,9 @@ git clean -df
|
||||
# Now that we have published them, run all tests as if they were released.
|
||||
# ******************************************************************************
|
||||
|
||||
# Browser tests
|
||||
CI=true ./node_modules/.bin/jest --config fixtures/browser/jest.config.js
|
||||
|
||||
# Smoke tests
|
||||
CI=true ./node_modules/.bin/jest --config fixtures/smoke/jest.config.js
|
||||
|
||||
# Output tests
|
||||
CI=true ./node_modules/.bin/jest --config fixtures/output/jest.config.js
|
||||
# Run all tests
|
||||
cd test/
|
||||
CI=true ../node_modules/.bin/jest -w 2
|
||||
|
||||
# Cleanup
|
||||
cleanup
|
||||
|
||||
45
test/README.md
Normal file
45
test/README.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# Create React App End-to-End Tests
|
||||
|
||||
## Usage
|
||||
|
||||
These tests ensure various functionality contracts are upheld across dependency upgrades.
|
||||
|
||||
To get started locally, run `cd packages/react-scripts/ && yarn link; cd ../../test/ && ../node_modules/.bin/jest --watchAll`.
|
||||
|
||||
It's suggested that you filter down tests to avoid re-running everything. The most common tests will be the webpack messages.<br>
|
||||
To only run the webpack messages, type `p` followed by `webpack-message` and press `[enter]`.
|
||||
|
||||
## How do these work?
|
||||
|
||||
### `fixtures/`
|
||||
|
||||
Each `fixture/` gets spun up in a temporary directory and has its dependencies installed with Yarn PnP (for speed).<br>
|
||||
To opt-out of PnP, create a `.disable-pnp` file in the specific fixture directory.
|
||||
|
||||
A global (`testSetup`) is created which has a few interesting properties:
|
||||
|
||||
- `testSetup.testDirectory`: the directory containing the test application
|
||||
- `testSetup.scripts`: an object allowing you to invoke `react-scripts` commands and friends
|
||||
|
||||
All tests for each `fixture/` are then ran.
|
||||
|
||||
#### `testSetup.scripts`
|
||||
|
||||
##### `start`
|
||||
|
||||
This will run the `start` command, it can be ran asynchronously or blocking if `{ smoke: true }` is used.<br>
|
||||
If ran asynchronously, it will return the `port` and a `done` function to clean up the process.
|
||||
If ran blocking, it will return the `stdout` and `stderr` of the process.
|
||||
|
||||
##### `build`
|
||||
|
||||
This will run the `build` command and return the `stdout` and `stderr` of the process.
|
||||
|
||||
##### `test`
|
||||
|
||||
This will run the `test` command and return the `stdout` and `stderr` of the process.
|
||||
|
||||
##### `serve`
|
||||
|
||||
This will run serve the application.
|
||||
It will return the `port` and a `done` function to clean up the process.
|
||||
21
test/fixtures/__shared__/test-setup.js
vendored
Normal file
21
test/fixtures/__shared__/test-setup.js
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
const path = require('path');
|
||||
const fs = require('fs-extra');
|
||||
const TestSetup = require('./util/setup');
|
||||
|
||||
const fixturePath = path.dirname(module.parent.filename);
|
||||
const fixtureName = path.basename(fixturePath);
|
||||
const disablePnp = fs.existsSync(path.resolve(fixturePath, '.disable-pnp'));
|
||||
const testSetup = new TestSetup(fixtureName, fixturePath, {
|
||||
pnp: !disablePnp,
|
||||
});
|
||||
|
||||
beforeAll(async () => {
|
||||
await testSetup.setup();
|
||||
}, 1000 * 60 * 5);
|
||||
afterAll(async () => {
|
||||
await testSetup.teardown();
|
||||
});
|
||||
|
||||
beforeEach(() => jest.setTimeout(1000 * 60 * 5));
|
||||
|
||||
module.exports = testSetup;
|
||||
113
test/fixtures/__shared__/util/scripts.js
vendored
Normal file
113
test/fixtures/__shared__/util/scripts.js
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
const execa = require('execa');
|
||||
const getPort = require('get-port');
|
||||
const os = require('os');
|
||||
const stripAnsi = require('strip-ansi');
|
||||
const waitForLocalhost = require('wait-for-localhost');
|
||||
|
||||
function stripYarn(output) {
|
||||
let lines = output.split('\n');
|
||||
|
||||
let runIndex = lines.findIndex(line => line.match(/^yarn run/));
|
||||
if (runIndex !== -1) {
|
||||
lines.splice(0, runIndex + 2);
|
||||
lines = lines.filter(line => !line.match(/^info Visit.*yarnpkg/));
|
||||
}
|
||||
|
||||
return lines.join('\n');
|
||||
}
|
||||
|
||||
function execaSafe(...args) {
|
||||
return execa(...args)
|
||||
.then(({ stdout, stderr, ...rest }) => ({
|
||||
fulfilled: true,
|
||||
rejected: false,
|
||||
stdout: stripYarn(stripAnsi(stdout)),
|
||||
stderr: stripYarn(stripAnsi(stderr)),
|
||||
...rest,
|
||||
}))
|
||||
.catch(err => ({
|
||||
fulfilled: false,
|
||||
rejected: true,
|
||||
reason: err,
|
||||
stdout: '',
|
||||
stderr: stripYarn(
|
||||
stripAnsi(
|
||||
err.message
|
||||
.split(os.EOL)
|
||||
.slice(2)
|
||||
.join(os.EOL)
|
||||
)
|
||||
),
|
||||
}));
|
||||
}
|
||||
|
||||
module.exports = class ReactScripts {
|
||||
constructor(root) {
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
async start({ smoke = false, env = {} } = {}) {
|
||||
const port = await getPort();
|
||||
const options = {
|
||||
cwd: this.root,
|
||||
env: Object.assign(
|
||||
{},
|
||||
{
|
||||
CI: 'false',
|
||||
FORCE_COLOR: '0',
|
||||
BROWSER: 'none',
|
||||
PORT: port,
|
||||
},
|
||||
env
|
||||
),
|
||||
};
|
||||
|
||||
if (smoke) {
|
||||
return await execaSafe('yarnpkg', ['start', '--smoke-test'], options);
|
||||
}
|
||||
const startProcess = execa('yarnpkg', ['start'], options);
|
||||
await waitForLocalhost(port);
|
||||
return {
|
||||
port,
|
||||
done() {
|
||||
startProcess.kill('SIGKILL');
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
async build({ env = {} } = {}) {
|
||||
return await execaSafe('yarnpkg', ['build'], {
|
||||
cwd: this.root,
|
||||
env: Object.assign({}, { CI: 'false', FORCE_COLOR: '0' }, env),
|
||||
});
|
||||
}
|
||||
|
||||
async serve() {
|
||||
const port = await getPort();
|
||||
const serveProcess = execa(
|
||||
'yarnpkg',
|
||||
['serve', '--', '-p', port, '-s', 'build/'],
|
||||
{
|
||||
cwd: this.root,
|
||||
}
|
||||
);
|
||||
await waitForLocalhost(port);
|
||||
return {
|
||||
port,
|
||||
done() {
|
||||
serveProcess.kill('SIGKILL');
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
async test({ jestEnvironment = 'jsdom', env = {} } = {}) {
|
||||
return await execaSafe(
|
||||
'yarnpkg',
|
||||
['test', '--env', jestEnvironment, '--ci'],
|
||||
{
|
||||
cwd: this.root,
|
||||
env: Object.assign({}, { CI: 'true' }, env),
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
104
test/fixtures/__shared__/util/setup.js
vendored
Normal file
104
test/fixtures/__shared__/util/setup.js
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
const execa = require('execa');
|
||||
const fs = require('fs-extra');
|
||||
const path = require('path');
|
||||
const tempy = require('tempy');
|
||||
const ReactScripts = require('./scripts');
|
||||
|
||||
module.exports = class TestSetup {
|
||||
constructor(fixtureName, templateDirectory, { pnp = true } = {}) {
|
||||
this.fixtureName = fixtureName;
|
||||
|
||||
this.templateDirectory = templateDirectory;
|
||||
this.testDirectory = null;
|
||||
this._scripts = null;
|
||||
|
||||
this.setup = this.setup.bind(this);
|
||||
this.teardown = this.teardown.bind(this);
|
||||
|
||||
this.isLocal = !(process.env.CI && process.env.CI !== 'false');
|
||||
this.settings = { pnp: pnp && !this.isLocal };
|
||||
}
|
||||
|
||||
async setup() {
|
||||
await this.teardown();
|
||||
this.testDirectory = tempy.directory();
|
||||
await fs.copy(
|
||||
path.resolve(__dirname, '..', 'template'),
|
||||
this.testDirectory
|
||||
);
|
||||
await fs.copy(this.templateDirectory, this.testDirectory);
|
||||
await fs.remove(path.resolve(this.testDirectory, 'test.partial.js'));
|
||||
await fs.remove(path.resolve(this.testDirectory, '.disable-pnp'));
|
||||
|
||||
const packageJson = await fs.readJson(
|
||||
path.resolve(this.testDirectory, 'package.json')
|
||||
);
|
||||
|
||||
const shouldInstallScripts = !this.isLocal;
|
||||
if (shouldInstallScripts) {
|
||||
packageJson.dependencies = Object.assign({}, packageJson.dependencies, {
|
||||
'react-scripts': 'latest',
|
||||
});
|
||||
}
|
||||
packageJson.scripts = Object.assign({}, packageJson.scripts, {
|
||||
start: 'react-scripts start',
|
||||
build: 'react-scripts build',
|
||||
test: 'react-scripts test',
|
||||
});
|
||||
packageJson.license = packageJson.license || 'UNLICENSED';
|
||||
await fs.writeJson(
|
||||
path.resolve(this.testDirectory, 'package.json'),
|
||||
packageJson
|
||||
);
|
||||
|
||||
await execa(
|
||||
'yarnpkg',
|
||||
[
|
||||
'install',
|
||||
this.settings.pnp ? '--enable-pnp' : null,
|
||||
'--mutex',
|
||||
'network',
|
||||
].filter(Boolean),
|
||||
{
|
||||
cwd: this.testDirectory,
|
||||
}
|
||||
);
|
||||
|
||||
if (!shouldInstallScripts) {
|
||||
await fs.ensureSymlink(
|
||||
path.resolve(
|
||||
path.resolve(
|
||||
__dirname,
|
||||
'../../../..',
|
||||
'packages',
|
||||
'react-scripts',
|
||||
'bin',
|
||||
'react-scripts.js'
|
||||
)
|
||||
),
|
||||
path.join(this.testDirectory, 'node_modules', '.bin', 'react-scripts')
|
||||
);
|
||||
await execa('yarnpkg', ['link', 'react-scripts'], {
|
||||
cwd: this.testDirectory,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
get scripts() {
|
||||
if (this.testDirectory == null) {
|
||||
return null;
|
||||
}
|
||||
if (this._scripts == null) {
|
||||
this._scripts = new ReactScripts(this.testDirectory);
|
||||
}
|
||||
return this._scripts;
|
||||
}
|
||||
|
||||
async teardown() {
|
||||
if (this.testDirectory != null) {
|
||||
await fs.remove(this.testDirectory);
|
||||
this.testDirectory = null;
|
||||
this._scripts = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
0
test/fixtures/boostrap-sass/.disable-pnp
vendored
Normal file
0
test/fixtures/boostrap-sass/.disable-pnp
vendored
Normal file
16
test/fixtures/boostrap-sass/index.test.js
vendored
Normal file
16
test/fixtures/boostrap-sass/index.test.js
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
const testSetup = require('../__shared__/test-setup');
|
||||
|
||||
if (testSetup.isLocal) {
|
||||
// TODO: make this work locally
|
||||
test('skipped locally', () => {});
|
||||
} else {
|
||||
test('builds in development', async () => {
|
||||
const { fulfilled } = await testSetup.scripts.start({ smoke: true });
|
||||
expect(fulfilled).toBe(true);
|
||||
});
|
||||
|
||||
test('builds in production', async () => {
|
||||
const { fulfilled } = await testSetup.scripts.build();
|
||||
expect(fulfilled).toBe(true);
|
||||
});
|
||||
}
|
||||
10
test/fixtures/builds-with-multiple-runtimes/index.test.js
vendored
Normal file
10
test/fixtures/builds-with-multiple-runtimes/index.test.js
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
const testSetup = require('../__shared__/test-setup');
|
||||
|
||||
test('builds in development', async () => {
|
||||
const { fulfilled } = await testSetup.scripts.start({ smoke: true });
|
||||
expect(fulfilled).toBe(true);
|
||||
});
|
||||
test('builds in production', async () => {
|
||||
const { fulfilled } = await testSetup.scripts.build();
|
||||
expect(fulfilled).toBe(true);
|
||||
});
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"dva": "2.4.0",
|
||||
"history": "4.7.2",
|
||||
"ky": "0.3.0",
|
||||
"react": "latest",
|
||||
"react-dom": "latest"
|
||||
8
test/fixtures/issue-5176-flow-class-properties/index.test.js
vendored
Normal file
8
test/fixtures/issue-5176-flow-class-properties/index.test.js
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
const testSetup = require('../__shared__/test-setup');
|
||||
|
||||
test('passes tests', async () => {
|
||||
const { fulfilled } = await testSetup.scripts.test({
|
||||
jestEnvironment: 'node',
|
||||
});
|
||||
expect(fulfilled).toBe(true);
|
||||
});
|
||||
5
test/fixtures/mjs-support/__snapshots__/index.test.js.snap
vendored
Normal file
5
test/fixtures/mjs-support/__snapshots__/index.test.js.snap
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`can use mjs library in development 1`] = `"Pikachu"`;
|
||||
|
||||
exports[`can use mjs library in production 1`] = `"Pikachu"`;
|
||||
43
test/fixtures/mjs-support/index.test.js
vendored
Normal file
43
test/fixtures/mjs-support/index.test.js
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
const testSetup = require('../__shared__/test-setup');
|
||||
|
||||
const puppeteer = require('puppeteer');
|
||||
|
||||
test('can use mjs library in development', async () => {
|
||||
const { port, done } = await testSetup.scripts.start();
|
||||
|
||||
const browser = await puppeteer.launch({ headless: true });
|
||||
try {
|
||||
const page = await browser.newPage();
|
||||
await page.goto(`http://localhost:${port}/`);
|
||||
await page.waitForSelector('.Pokemon-Name-Data', { timeout: 0 });
|
||||
const output = await page.evaluate(() => {
|
||||
return Array.from(
|
||||
document.getElementsByClassName('Pokemon-Name-Data')
|
||||
).pop().innerHTML;
|
||||
});
|
||||
expect(output).toMatchSnapshot();
|
||||
} finally {
|
||||
browser.close();
|
||||
done();
|
||||
}
|
||||
});
|
||||
test('can use mjs library in production', async () => {
|
||||
await testSetup.scripts.build();
|
||||
const { port, done } = await testSetup.scripts.serve();
|
||||
|
||||
const browser = await puppeteer.launch({ headless: true });
|
||||
try {
|
||||
const page = await browser.newPage();
|
||||
await page.goto(`http://localhost:${port}/`);
|
||||
await page.waitForSelector('.Pokemon-Name-Data', { timeout: 0 });
|
||||
const output = await page.evaluate(() => {
|
||||
return Array.from(
|
||||
document.getElementsByClassName('Pokemon-Name-Data')
|
||||
).pop().innerHTML;
|
||||
});
|
||||
expect(output).toMatchSnapshot();
|
||||
} finally {
|
||||
browser.close();
|
||||
done();
|
||||
}
|
||||
});
|
||||
@@ -3,6 +3,7 @@
|
||||
"apollo-boost": "0.1.16",
|
||||
"graphql": "14.0.2",
|
||||
"react-apollo": "2.2.1",
|
||||
"apollo-client": "2.4.2",
|
||||
"react": "latest",
|
||||
"react-dom": "latest",
|
||||
"serve": "10.0.2"
|
||||
25
test/fixtures/relative-paths/index.test.js
vendored
Normal file
25
test/fixtures/relative-paths/index.test.js
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
const testSetup = require('../__shared__/test-setup');
|
||||
|
||||
const fs = require('fs-extra');
|
||||
const globby = require('globby');
|
||||
const path = require('path');
|
||||
|
||||
test('contains a relative path in production build', async () => {
|
||||
await testSetup.scripts.build();
|
||||
|
||||
const buildDir = path.join(testSetup.testDirectory, 'build');
|
||||
const cssFile = path.join(
|
||||
buildDir,
|
||||
globby.sync('**/*.css', { cwd: buildDir }).pop()
|
||||
);
|
||||
const svgFile = path.join(
|
||||
buildDir,
|
||||
globby.sync('**/*.svg', { cwd: buildDir }).pop()
|
||||
);
|
||||
const desiredPath = /url\((.+?)\)/
|
||||
.exec(fs.readFileSync(cssFile, 'utf8'))
|
||||
.pop();
|
||||
expect(path.resolve(path.join(path.dirname(cssFile), desiredPath))).toBe(
|
||||
path.resolve(svgFile)
|
||||
);
|
||||
});
|
||||
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
0
test/fixtures/webpack-message-formatting/.disable-pnp
vendored
Normal file
0
test/fixtures/webpack-message-formatting/.disable-pnp
vendored
Normal file
@@ -1,6 +1,6 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`webpack message formatting formats aliased unknown export 1`] = `
|
||||
exports[`formats aliased unknown export 1`] = `
|
||||
Object {
|
||||
"stderr": "Creating an optimized production build...
|
||||
Failed to compile.
|
||||
@@ -14,7 +14,7 @@ Attempted import error: 'bar' is not exported from './AppUnknownExport' (importe
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`webpack message formatting formats babel syntax error 1`] = `
|
||||
exports[`formats babel syntax error 1`] = `
|
||||
Object {
|
||||
"stderr": "Creating an optimized production build...
|
||||
Failed to compile.
|
||||
@@ -36,7 +36,7 @@ Syntax error: Unterminated JSX contents (8:13)
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`webpack message formatting formats css syntax error 1`] = `
|
||||
exports[`formats css syntax error 1`] = `
|
||||
Object {
|
||||
"stderr": "Creating an optimized production build...
|
||||
Failed to compile.
|
||||
@@ -56,7 +56,7 @@ Syntax error: Unexpected } (3:2)
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`webpack message formatting formats eslint error 1`] = `
|
||||
exports[`formats eslint error 1`] = `
|
||||
Object {
|
||||
"stderr": "Creating an optimized production build...
|
||||
Failed to compile.
|
||||
@@ -72,7 +72,7 @@ Search for the keywords to learn more about each error.
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`webpack message formatting formats eslint warning 1`] = `
|
||||
exports[`formats eslint warning 1`] = `
|
||||
Object {
|
||||
"stderr": "",
|
||||
"stdout": "Creating an optimized production build...
|
||||
@@ -88,7 +88,7 @@ To ignore, add // eslint-disable-next-line to the line before.
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`webpack message formatting formats file not found error 1`] = `
|
||||
exports[`formats file not found error 1`] = `
|
||||
Object {
|
||||
"stderr": "Creating an optimized production build...
|
||||
Failed to compile.
|
||||
@@ -102,7 +102,7 @@ Cannot find file './ThisFileSouldNotExist' in './src'.
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`webpack message formatting formats missing package 1`] = `
|
||||
exports[`formats missing package 1`] = `
|
||||
Object {
|
||||
"stderr": "Creating an optimized production build...
|
||||
Failed to compile.
|
||||
@@ -118,7 +118,7 @@ You can install this package by running: yarn add unknown-package.
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`webpack message formatting formats no default export 1`] = `
|
||||
exports[`formats no default export 1`] = `
|
||||
Object {
|
||||
"stderr": "Creating an optimized production build...
|
||||
Failed to compile.
|
||||
@@ -132,7 +132,7 @@ Attempted import error: './ExportNoDefault' does not contain a default export (i
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`webpack message formatting formats out of scope error 1`] = `
|
||||
exports[`formats out of scope error 1`] = `
|
||||
Object {
|
||||
"stderr": "Creating an optimized production build...
|
||||
Failed to compile.
|
||||
@@ -147,7 +147,7 @@ You can either move it inside src/, or add a symlink to it from project's node_m
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`webpack message formatting formats unknown export 1`] = `
|
||||
exports[`formats unknown export 1`] = `
|
||||
Object {
|
||||
"stderr": "Creating an optimized production build...
|
||||
Failed to compile.
|
||||
@@ -161,7 +161,7 @@ Attempted import error: 'bar' is not exported from './AppUnknownExport'.
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`webpack message formatting helps when users tries to use sass 1`] = `
|
||||
exports[`helps when users tries to use sass 1`] = `
|
||||
Object {
|
||||
"stderr": "Creating an optimized production build...
|
||||
Failed to compile.
|
||||
136
test/fixtures/webpack-message-formatting/index.test.js
vendored
Normal file
136
test/fixtures/webpack-message-formatting/index.test.js
vendored
Normal file
@@ -0,0 +1,136 @@
|
||||
const testSetup = require('../__shared__/test-setup');
|
||||
|
||||
const fs = require('fs-extra');
|
||||
const path = require('path');
|
||||
|
||||
test('formats babel syntax error', async () => {
|
||||
fs.copySync(
|
||||
path.join(__dirname, 'src', 'AppBabel.js'),
|
||||
path.join(testSetup.testDirectory, 'src', 'App.js')
|
||||
);
|
||||
|
||||
const { stdout, stderr } = await testSetup.scripts.build();
|
||||
expect({ stdout, stderr }).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('formats css syntax error', async () => {
|
||||
fs.copySync(
|
||||
path.join(__dirname, 'src', 'AppCss.js'),
|
||||
path.join(testSetup.testDirectory, 'src', 'App.js')
|
||||
);
|
||||
|
||||
const { stdout, stderr } = await testSetup.scripts.build();
|
||||
expect({ stdout, stderr }).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('formats unknown export', async () => {
|
||||
fs.copySync(
|
||||
path.join(__dirname, 'src', 'AppUnknownExport.js'),
|
||||
path.join(testSetup.testDirectory, 'src', 'App.js')
|
||||
);
|
||||
|
||||
const { stdout, stderr } = await testSetup.scripts.build();
|
||||
expect({ stdout, stderr }).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('formats aliased unknown export', async () => {
|
||||
fs.copySync(
|
||||
path.join(__dirname, 'src', 'AppAliasUnknownExport.js'),
|
||||
path.join(testSetup.testDirectory, 'src', 'App.js')
|
||||
);
|
||||
|
||||
const { stdout, stderr } = await testSetup.scripts.build();
|
||||
expect({ stdout, stderr }).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('formats no default export', async () => {
|
||||
fs.copySync(
|
||||
path.join(__dirname, 'src', 'AppNoDefault.js'),
|
||||
path.join(testSetup.testDirectory, 'src', 'App.js')
|
||||
);
|
||||
|
||||
const { stdout, stderr } = await testSetup.scripts.build();
|
||||
expect({ stdout, stderr }).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('formats missing package', async () => {
|
||||
fs.copySync(
|
||||
path.join(__dirname, 'src', 'AppMissingPackage.js'),
|
||||
path.join(testSetup.testDirectory, 'src', 'App.js')
|
||||
);
|
||||
|
||||
const { stdout, stderr } = await testSetup.scripts.build();
|
||||
expect({ stdout, stderr }).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('formats eslint warning', async () => {
|
||||
fs.copySync(
|
||||
path.join(__dirname, 'src', 'AppLintWarning.js'),
|
||||
path.join(testSetup.testDirectory, 'src', 'App.js')
|
||||
);
|
||||
|
||||
let { stdout, stderr } = await testSetup.scripts.build();
|
||||
const sizeIndex = stdout.indexOf('File sizes after gzip');
|
||||
if (sizeIndex !== -1) {
|
||||
stdout = stdout.substring(0, sizeIndex);
|
||||
}
|
||||
expect({ stdout, stderr }).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('formats eslint error', async () => {
|
||||
fs.copySync(
|
||||
path.join(__dirname, 'src', 'AppLintError.js'),
|
||||
path.join(testSetup.testDirectory, 'src', 'App.js')
|
||||
);
|
||||
|
||||
const { stdout, stderr } = await testSetup.scripts.build();
|
||||
expect({ stdout, stderr }).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('helps when users tries to use sass', async () => {
|
||||
fs.copySync(
|
||||
path.join(__dirname, 'src', 'AppSass.js'),
|
||||
path.join(testSetup.testDirectory, 'src', 'App.js')
|
||||
);
|
||||
|
||||
const { stdout, stderr } = await testSetup.scripts.build();
|
||||
expect({ stdout, stderr }).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('formats file not found error', async () => {
|
||||
fs.copySync(
|
||||
path.join(__dirname, 'src', 'AppUnknownFile.js'),
|
||||
path.join(testSetup.testDirectory, 'src', 'App.js')
|
||||
);
|
||||
|
||||
const { stdout, stderr } = await testSetup.scripts.build();
|
||||
expect({ stdout, stderr }).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('formats case sensitive path error', async () => {
|
||||
fs.copySync(
|
||||
path.join(__dirname, 'src', 'AppIncorrectCase.js'),
|
||||
path.join(testSetup.testDirectory, 'src', 'App.js')
|
||||
);
|
||||
|
||||
const { stdout, stderr } = await testSetup.scripts.start({ smoke: true });
|
||||
if (process.platform === 'darwin') {
|
||||
expect(stderr).toMatch(
|
||||
`Cannot find file: 'export5.js' does not match the corresponding name on disk: './src/Export5.js'.`
|
||||
);
|
||||
} else {
|
||||
expect(stderr).not.toEqual(''); // TODO: figure out how we can test this on Linux/Windows
|
||||
// I believe getting this working requires we tap into enhanced-resolve
|
||||
// pipeline, which is debt we don't want to take on right now.
|
||||
}
|
||||
});
|
||||
|
||||
test('formats out of scope error', async () => {
|
||||
fs.copySync(
|
||||
path.join(__dirname, 'src', 'AppOutOfScopeImport.js'),
|
||||
path.join(testSetup.testDirectory, 'src', 'App.js')
|
||||
);
|
||||
|
||||
const { stdout, stderr } = await testSetup.scripts.build();
|
||||
expect({ stdout, stderr }).toMatchSnapshot();
|
||||
});
|
||||
@@ -1,6 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
testEnvironment: 'node',
|
||||
testMatch: ['**/*.test.js'],
|
||||
testMatch: ['<rootDir>/**/*.test.js'],
|
||||
testPathIgnorePatterns: ['/src/', 'node_modules'],
|
||||
setupTestFrameworkScriptFile: './setupSmokeTests.js',
|
||||
};
|
||||
Reference in New Issue
Block a user