diff --git a/README.md b/README.md index 0d173442..575040c9 100644 --- a/README.md +++ b/README.md @@ -22,28 +22,27 @@ yarn add fusion-cli The CLI API can be most easily run through the Yarn or NPX CLI, e.g. `yarn fusion build` or `npx fusion build`. -* `fusion build [dir] [--test] [--cover] [--production] [--log-level]` +- `fusion build [dir] [--cover] [--production] [--log-level]` Builds your appplication assets This command generates transpiled javascript/source map files (aka assets, artifacts) for browser and server. By default it builds development assets, but can also build test and production assets, given the respective flags. Build artifacts are stored in the `.fusion` directory. - * `--test`: Build tests as well as application - * `--cover`: Build tests (with coverage) as well as application - * `--production`: Build production assets - * `--log-level`: Log level to output to console `[default: "info"]` + - `--cover`: Build tests (with coverage) as well as application + - `--production`: Build production assets + - `--log-level`: Log level to output to console `[default: "info"]` -* `fusion dev [dir] [--port] [--no-hmr] [--test] [--cover] [--log-level]` +- `fusion dev [dir] [--port] [--no-hmr] [--test] [--cover] [--log-level]` Builds development assets and runs the application in development mode Note that this command only builds browser artifacts in memory, and it doesn't save them to the filesystem. This allows hot module reloading to occur faster since there's no performance cost due to I/O access. - * `--port`: The port on which the application runs `[default: 3000]` - * `--no-hmr`: Run without hot modules replacement - * `--test`: Run tests as well as application - * `--cover`: Run tests (with coverage) as well as application - * `--log-level`: Log level to output to console `[default: "info"]` + - `--port`: The port on which the application runs `[default: 3000]` + - `--no-hmr`: Run without hot modules replacement + - `--test`: Run tests as well as application + - `--cover`: Run tests (with coverage) as well as application + - `--log-level`: Log level to output to console `[default: "info"]` -* `fusion start [--environment]` +- `fusion start [--environment]` Runs your application, assuming you have previously built them via `fusion build`. Note that build artifacts must be saved to disk (i.e. this command will fail if you use `fusion dev` to build artifacts instead of `fusion build`. - * `--environment`: Which environment/assets to run - defaults to first available assets among `["development", "test", "production"]` + - `--environment`: Which environment/assets to run - defaults to first available assets among `["development", "production"]` -* `fusion test [--watch] [--match] [--coverage] [--env] [--debug] [--updateSnapshot]` +- `fusion test [--watch] [--match] [--coverage] [--env] [--debug] [--updateSnapshot]` Builds test assets and runs tests Tests are run with Jest - * `--watch`: Automatically run tests when code changes. - * `--match="somestring"`: Only runs tests against files which match this string. - * `--coverage`: Collects and outputs test coverage - * `--env`: Which environments to run tests in. Defaults to "node,jsdom". You may specify only one. - * `--debug`: Allows you to debug tests using the chrome inspector (chrome://inspect). - * `--updateSnapshot`: Updates snapshots + - `--watch`: Automatically run tests when code changes. + - `--match="somestring"`: Only runs tests against files which match this string. + - `--coverage`: Collects and outputs test coverage + - `--env`: Which environments to run tests in. Defaults to "node,jsdom". You may specify only one. + - `--debug`: Allows you to debug tests using the chrome inspector (chrome://inspect). + - `--updateSnapshot`: Updates snapshots diff --git a/build/compiler.js b/build/compiler.js index a065f762..80e91511 100644 --- a/build/compiler.js +++ b/build/compiler.js @@ -34,7 +34,6 @@ const SyncChunkIdsPlugin = require('./sync-chunk-ids-plugin'); const browserSupport = require('./browser-support'); const chalk = require('chalk'); const webpackHotMiddleware = require('webpack-hot-middleware'); -const globby = require('globby'); const loadFusionRC = require('./load-fusionrc.js'); const rimraf = require('rimraf'); const {getEnv} = require('fusion-core'); @@ -47,37 +46,13 @@ function getConfig({target, env, dir, watch, cover}) { if (target !== 'node' && target !== 'web' && target !== 'webworker') { throw new Error('Invalid target: must be `node`, `web`, or `webworker`'); } - if (env !== 'production' && env !== 'development' && env !== 'test') { - throw new Error('Invalid name: must be `production`, `dev`, or `test`'); + if (env !== 'production' && env !== 'development') { + throw new Error('Invalid name: must be `production` or `dev`'); } if (!fs.existsSync(path.resolve(dir, main))) { throw new Error(`Project directory must contain a ${main} file`); } - const serverOnlyTestGlob = `${dir}/src/**/__tests__/*.node.js`; - const browserOnlyTestGlob = `${dir}/src/**/__tests__/*.browser.js`; - const universalTestGlob = `${dir}/src/**/__tests__/*.js`; - - const serverTestEntry = `__SECRET_MULTI_ENTRY_LOADER__?include[]=${universalTestGlob},include[]=${dir}/${main},exclude[]=${browserOnlyTestGlob}!`; - const browserTestEntry = `__SECRET_MULTI_ENTRY_LOADER__?include[]=${universalTestGlob},include[]=${dir}/${main},exclude[]=${serverOnlyTestGlob}!`; - - if ( - env === 'test' && - !globby.sync([universalTestGlob, `!${browserOnlyTestGlob}`]).length - ) { - throw new Error( - `Testing requires server tests in __tests__ with *.js or *.node.js extension` - ); - } - if ( - env === 'test' && - !globby.sync([universalTestGlob, `!${serverOnlyTestGlob}`]).length - ) { - throw new Error( - `Testing requires browser tests in __tests__ with *.js or *.browser.js extension` - ); - } - const fusionConfig = loadFusionRC(dir); const configPath = path.join(dir, 'package.json'); @@ -92,14 +67,8 @@ function getConfig({target, env, dir, watch, cover}) { const destination = path.resolve(dir, `.fusion/dist/${env}/${side}`); const evergreen = false; const possibleESVersions = ['es5']; - const serverEntry = - env === 'test' - ? serverTestEntry - : path.join(__dirname, `../entries/server-entry.js`); - const clientEntry = - env === 'test' - ? browserTestEntry - : path.join(__dirname, `../entries/client-entry.js`); + const serverEntry = path.join(__dirname, `../entries/server-entry.js`); + const clientEntry = path.join(__dirname, `../entries/client-entry.js`); const entry = { node: serverEntry, web: clientEntry, @@ -326,11 +295,6 @@ function getConfig({target, env, dir, watch, cover}) { ].filter(Boolean), }, externals: [ - // These externals are required to work with enzyme - // See: https://github.com/airbnb/enzyme/blob/master/docs/guides/webpack.md - env === 'test' && 'react/addons', - env === 'test' && 'react/lib/ReactContext', - env === 'test' && 'react/lib/ExecutionEnvironment', target === 'node' && ((context, request, callback) => { // bundle whitelisted packages @@ -374,14 +338,6 @@ function getConfig({target, env, dir, watch, cover}) { __FRAMEWORK_SHARED_ENTRY__: path.resolve(dir, main), __ENV__: env, }, - target === 'node' && - env === 'test' && { - __NODE_TEST_ENTRY__: serverTestEntry, - }, - target === 'web' && - env === 'test' && { - __BROWSER_TEST_ENTRY__: browserTestEntry, - }, alias ), }, @@ -685,14 +641,13 @@ function Compiler( } function getNodeConfig(target, env) { - const tapeConfig = env === 'test' && target === 'web' ? 'mock' : false; const emptyForWeb = target === 'web' ? 'empty' : false; return { // Polyfilling process involves lots of cruft. Better to explicitly inline env value statically // Tape requires process to be defined - process: tapeConfig, + process: false, // We definitely don't want automatic Buffer polyfills. This should be explicit and in userland code - Buffer: tapeConfig, + Buffer: false, // We definitely don't want automatic setImmediate polyfills. This should be explicit and in userland code setImmediate: false, // We want these to resolve to the original file source location, not the compiled location diff --git a/commands/build.js b/commands/build.js index f8d98e3b..656b884f 100644 --- a/commands/build.js +++ b/commands/build.js @@ -16,13 +16,11 @@ exports.run = async function( { dir = '.', production, - test, cover, logLevel, } /*: { dir: string, production: boolean, - test: boolean, cover: boolean, logLevel: string, }*/ @@ -38,7 +36,6 @@ exports.run = async function( const envs = []; if (production) envs.push('production'); if (envs.length === 0) envs.push('development'); - if (test) envs.push('test'); const compiler = new Compiler({envs, dir, cover, logger}); await compiler.clean(); diff --git a/commands/dev.js b/commands/dev.js index a7ac3641..60325ed3 100644 --- a/commands/dev.js +++ b/commands/dev.js @@ -26,7 +26,7 @@ exports.run = async function( logger.add(new winston.transports.Console({level: logLevel})); const compiler = new Compiler({ - envs: test ? ['development', 'test'] : ['development'], + envs: ['development'], dir, watch: hmr, cover, diff --git a/test/compiler/api.js b/test/compiler/api.js index 8e1ea7c1..3d1b8d94 100644 --- a/test/compiler/api.js +++ b/test/compiler/api.js @@ -116,96 +116,6 @@ test('development/production env globals', async t => { t.end(); }); -test('test env globals', async t => { - const envs = ['test']; - const dir = './test/fixtures/noop-test'; - - const entryPath = `.fusion/dist/${envs[0]}/server/server-main.js`; - const entry = path.resolve(dir, entryPath); - const compiler = new Compiler({envs, dir}); - await compiler.clean(); - - const watcher = await new Promise((resolve, reject) => { - const watcher = compiler.start((err, stats) => { - if (err || stats.hasErrors()) { - return reject(err || new Error('Compiler stats included errors.')); - } - - return resolve(watcher); - }); - }); - watcher.close(); - - t.ok(await exists(entry), 'Entry file gets compiled'); - t.ok(await exists(entry + '.map'), 'Source map gets compiled'); - - const clientDir = `.fusion/dist/${envs[0]}/client`; - const clientEntry = path.resolve(dir, clientDir, 'client-main.js'); - t.ok(await exists(clientEntry), 'client .js'); - t.ok(await exists(clientEntry + '.map'), 'client .map'); - - // server test bundle - const serverCommand = ` - require('${entry}'); - `; - // $FlowFixMe - let {stdout} = await run(['-e', serverCommand], { - env: Object.assign({}, process.env, { - NODE_ENV: 'production', - }), - stdio: 'pipe', - }); - t.ok( - stdout.includes('universal __BROWSER__ is false'), - 'the global, __BROWSER__, is false in universal tests' - ); - t.ok( - stdout.includes('universal __DEV__ is false'), - 'the global, __DEV__, is false in universal tests' - ); - t.ok( - stdout.includes('universal __NODE__ is true'), - 'the global, __NODE__, is true in universal tests' - ); - - // browser test bundle - // Disabled due to webpack 4 changes - // const browserCommand = `require('${clientEntry}');`; - // const {stdout: browserStdout} = await run(['-e', browserCommand], { - // env: Object.assign({}, process.env, { - // NODE_ENV: 'production', - // }), - // stdio: 'inherit', - // }); - // t.ok( - // browserStdout.includes('browser __BROWSER__ is true'), - // 'the global, __BROWSER__, is true in browser tests' - // ); - // t.ok( - // browserStdout.includes('universal __BROWSER__ is true'), - // 'the global, __BROWSER__, is true in universal tests' - // ); - // t.ok( - // browserStdout.includes('browser __NODE__ is false'), - // 'the global, __NODE__, is false in browser tests' - // ); - // t.ok( - // browserStdout.includes('universal __NODE__ is false'), - // 'the global, __NODE__, is false in universal tests' - // ); - - t.end(); -}); - -test('tests throw if no test files exist', t => { - const envs = ['test']; - const dir = './test/fixtures/noop'; - t.throws(() => { - new Compiler({envs: envs, dir}); - }); - t.end(); -}); - test('generates error if missing default export', async t => { const envs = ['development']; const dir = './test/fixtures/empty'; @@ -425,85 +335,3 @@ test('production works', async t => { }); t.end(); }); - -// TODO(#24): Is this how testing should work? -test('test works', async t => { - const envs = ['test']; - const dir = './test/fixtures/noop-test'; - const entryPath = `.fusion/dist/${envs[0]}/server/server-main.js`; - const entry = path.resolve(dir, entryPath); - - const compiler = new Compiler({envs, dir}); - await compiler.clean(); - - t.notok(await exists(entry), 'Cleans'); - - const watcher = await new Promise((resolve, reject) => { - const watcher = compiler.start((err, stats) => { - if (err || stats.hasErrors()) { - return reject(err || new Error('Compiler stats included errors.')); - } - - return resolve(watcher); - }); - }); - watcher.close(); - - t.ok(await exists(entry), 'Entry file gets compiled'); - t.ok(await exists(entry + '.map'), 'Source map gets compiled'); - - const clientDir = `.fusion/dist/${envs[0]}/client`; - const clientEntry = path.resolve(dir, clientDir, 'client-main.js'); - t.ok(await exists(clientEntry), 'client .js'); - t.ok(await exists(clientEntry + '.map'), 'client .map'); - - // server test bundle - const serverCommand = ` - require('${entry}'); - `; - // $FlowFixMe - const {stdout} = await run(['-e', serverCommand], { - env: Object.assign({}, process.env, { - NODE_ENV: 'production', - }), - stdio: 'pipe', - }); - t.ok( - stdout.includes('server test runs'), - 'server test included in server test bundle' - ); - t.ok( - !stdout.includes('client test runs'), - 'client test not included in server test bundle' - ); - t.ok( - stdout.includes('universal test runs'), - 'universal test included in browser test bundle' - ); - - // browser test bundle - // Disabled due to webpack 4 changes - // const browserCommand = ` - // require('${clientEntry}'); - // `; - // const {stdout: browserStdout} = await run(['-e', browserCommand], { - // env: Object.assign({}, process.env, { - // NODE_ENV: 'production', - // }), - // stdio: 'inherit', - // }); - // t.ok( - // !browserStdout.includes('server test runs'), - // 'server test not included in browser test bundle' - // ); - // t.ok( - // browserStdout.includes('client test runs'), - // 'client test included in browser test bundle' - // ); - // t.ok( - // browserStdout.includes('universal test runs'), - // 'universal test included in browser test bundle' - // ); - - t.end(); -}); diff --git a/test/compiler/errors.js b/test/compiler/errors.js index 9334156d..482965f2 100644 --- a/test/compiler/errors.js +++ b/test/compiler/errors.js @@ -23,7 +23,6 @@ testEnvs( function testEnvs(title, dir) { testDev(`${title} dev`, dir); testProd(`${title} prod`, dir); - testTest(`${title} test`, dir); } function testDev(title, dir) { @@ -77,35 +76,3 @@ function testProd(title, dir) { t.end(); }); } -function testTest(title, dir) { - test(title, async t => { - const envs = ['test']; - const entryPath = `.fusion/dist/${envs[0]}/server/server-main.js`; - const entry = path.resolve(dir, entryPath); - - const compiler = new Compiler({envs, dir}); - await compiler.clean(); - - const compilationError = await new Promise(resolve => { - compiler.start((err, stats) => { - if (err || stats.hasErrors()) { - return resolve(err || new Error('Compiler stats included errors.')); - } - - return resolve(false); - }); - }); - - t.assert(compilationError, 'Should produce compilation error'); - - // $FlowFixMe - t.throws(() => require(entry), 'Server test should throw'); - - const clientDir = `.fusion/dist/${envs[0]}/client`; - const clientEntry = path.resolve(clientDir, 'client-main.js'); - // $FlowFixMe - t.throws(() => require(clientEntry), 'Client test should throw'); - - t.end(); - }); -}