Skip to content

Commit

Permalink
Unify sample-based tests (#2329)
Browse files Browse the repository at this point in the history
* Unify form and function test setup; allow for function tests to be in nested directories

* Enable chunking form tests be in nested directories and unify setup

* Enable CLI tests be in nested directories and unify setup

* Enable sourcemap tests to be in nested directories and unify setup

* Unify options format for function tests and fix some references to output options in warnings
  • Loading branch information
lukastaegert committed Jul 17, 2018
1 parent 4fc927b commit e093195
Show file tree
Hide file tree
Showing 17 changed files with 363 additions and 404 deletions.
2 changes: 1 addition & 1 deletion src/Chunk.ts
Expand Up @@ -77,7 +77,7 @@ function getGlobalName(
guess: module.name,
message: `No name was provided for external module '${
module.id
}' in options.globals – guessing '${module.name}'`
}' in output.globals – guessing '${module.name}'`
});
return module.name;
}
Expand Down
11 changes: 5 additions & 6 deletions src/rollup/index.ts
@@ -1,19 +1,18 @@
import Chunk from '../Chunk';
import { optimizeChunks } from '../chunk-optimization';
import Graph from '../Graph';
import { createAddons } from '../utils/addons';
import { createAssetPluginHooks, finaliseAsset } from '../utils/assetHooks';
import commondir from '../utils/commondir';
import { Deprecation } from '../utils/deprecateOptions';
import ensureArray from '../utils/ensureArray';
import error from '../utils/error';
import { writeFile } from '../utils/fs';
import getExportMode from '../utils/getExportMode';
import mergeOptions, { GenericConfigObject } from '../utils/mergeOptions';
import { basename, dirname, resolve } from '../utils/path';
import { SOURCEMAPPING_URL } from '../utils/sourceMappingURL';
import { getTimings, initialiseTimers, timeEnd, timeStart } from '../utils/timers';

import Chunk from '../Chunk';
import { createAssetPluginHooks, finaliseAsset } from '../utils/assetHooks';
import getExportMode from '../utils/getExportMode';
import { Watcher } from '../watch';
import {
InputOptions,
Expand Down Expand Up @@ -56,13 +55,13 @@ function checkOutputOptions(options: OutputOptions) {

if (!options.format) {
error({
message: `You must specify options.format, which can be one of 'amd', 'cjs', 'system', 'esm', 'iife' or 'umd'`,
message: `You must specify output.format, which can be one of 'amd', 'cjs', 'system', 'esm', 'iife' or 'umd'`,
url: `https://rollupjs.org/#format-f-output-format-`
});
}

if (options.moduleId) {
if (options.amd) throw new Error('Cannot have both options.amd and options.moduleId');
if (options.amd) throw new Error('Cannot have both output.amd and output.moduleId');
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/utils/getExportMode.ts
Expand Up @@ -5,7 +5,7 @@ import error from './error';
function badExports(option: string, keys: string[]) {
error({
code: 'INVALID_EXPORT_OPTION',
message: `'${option}' was specified for options.exports, but entry module has following exports: ${keys.join(
message: `'${option}' was specified for output.exports, but entry module has following exports: ${keys.join(
', '
)}`
});
Expand Down Expand Up @@ -46,7 +46,7 @@ export default function getExportMode(
if (!/(?:default|named|none)/.test(exportMode)) {
error({
code: 'INVALID_EXPORT_OPTION',
message: `options.exports must be 'default', 'named', 'none', 'auto', or left unspecified (defaults to 'auto')`
message: `output.exports must be 'default', 'named', 'none', 'auto', or left unspecified (defaults to 'auto')`
});
}

Expand Down
2 changes: 1 addition & 1 deletion src/watch/index.ts
Expand Up @@ -137,7 +137,7 @@ export class Task {

if (chokidarOptions && !chokidar) {
throw new Error(
`options.watch.chokidar was provided, but chokidar could not be found. Have you installed it?`
`watch.chokidar was provided, but chokidar could not be found. Have you installed it?`
);
}

Expand Down
147 changes: 66 additions & 81 deletions test/chunking-form/index.js
@@ -1,95 +1,80 @@
const path = require('path');
const assert = require('assert');
const sander = require('sander');
const fixturify = require('fixturify');
const rollup = require('../../dist/rollup');
const { extend, loadConfig } = require('../utils.js');

const samples = path.resolve(__dirname, 'samples');
const { extend, runTestSuiteWithSamples } = require('../utils.js');

const FORMATS = ['es', 'cjs', 'amd', 'system'];

describe('chunking form', () => {
sander
.readdirSync(samples)
.sort()
.forEach(dir => {
if (dir[0] === '.') return; // .DS_Store...

const config = loadConfig(samples + '/' + dir + '/_config.js');

if (!config || (config.skipIfWindows && process.platform === 'win32')) return;
if (!config.options) {
config.options = {};
}

const inputOptions = extend(
{},
{
input: [samples + '/' + dir + '/main.js'],
experimentalCodeSplitting: true,
onwarn: msg => {
if (/No name was provided for/.test(msg)) return;
if (/as external dependency/.test(msg)) return;
console.error(msg);
}
},
config.options
);

(config.skip ? describe.skip : config.solo ? describe.only : describe)(dir, () => {
let promise;
const createBundle = () => promise || (promise = rollup.rollup(inputOptions));

FORMATS.forEach(format => {
it('generates ' + format, () => {
process.chdir(samples + '/' + dir);
runTestSuiteWithSamples('chunking form', path.resolve(__dirname, 'samples'), (dir, config) => {
(config.skip ? describe.skip : config.solo ? describe.only : describe)(
path.basename(dir) + ': ' + config.description,
() => {
let rollupPromise;

return createBundle().then(bundle => {
const outputOptions = extend(
{},
FORMATS.forEach(format =>
it('generates ' + format, () => {
process.chdir(dir);
return (
rollupPromise ||
(rollupPromise = rollup.rollup(
extend(
{
dir: samples + '/' + dir + '/_actual/' + format,
input: [dir + '/main.js'],
experimentalCodeSplitting: true,
onwarn: msg => {
if (/No name was provided for/.test(msg)) return;
if (/as external dependency/.test(msg)) return;
console.error(msg);
}
},
config.options || {}
)
))
).then(bundle =>
generateAndTestBundle(
bundle,
extend(
{
dir: dir + '/_actual/' + format,
format
},
inputOptions.output || {}
);

sander.rimrafSync(outputOptions.dir);
(config.options || {}).output || {}
),
dir + '/_expected/' + format,
config
)
);
})
);
}
);
});

return bundle.write(outputOptions).then(() => {
const actualFiles = fixturify.readSync(path.join(samples, dir, '_actual', format));
function generateAndTestBundle(bundle, outputOptions, expectedDir) {
return bundle.write(outputOptions).then(() => {
const actualFiles = fixturify.readSync(outputOptions.dir);

let expectedFiles;
try {
expectedFiles = fixturify.readSync(path.join(samples, dir, '_expected', format));
} catch (err) {
expectedFiles = [];
}
let expectedFiles;
try {
expectedFiles = fixturify.readSync(expectedDir);
} catch (err) {
expectedFiles = [];
}
assertFilesAreEqual(actualFiles, expectedFiles, []);
});
}

(function recurse(actualFiles, expectedFiles, dirs) {
const fileNames = Array.from(
new Set(Object.keys(actualFiles).concat(Object.keys(expectedFiles)))
);
fileNames.forEach(fileName => {
const sections = dirs.concat(fileName);
if (
typeof actualFiles[fileName] === 'object' &&
typeof expectedFiles[fileName] === 'object'
) {
return recurse(actualFiles[fileName], expectedFiles[fileName], sections);
}
assert.strictEqual(
actualFiles[fileName],
expectedFiles[fileName],
'Unexpected output for ' + sections.join('/')
);
});
})(actualFiles, expectedFiles, []);
});
});
});
});
});
});
});
function assertFilesAreEqual(actualFiles, expectedFiles, dirs) {
Object.keys(Object.assign({}, actualFiles, expectedFiles)).forEach(fileName => {
const pathSegments = dirs.concat(fileName);
if (typeof actualFiles[fileName] === 'object' && typeof expectedFiles[fileName] === 'object') {
return assertFilesAreEqual(actualFiles[fileName], expectedFiles[fileName], pathSegments);
}
assert.strictEqual(
actualFiles[fileName],
expectedFiles[fileName],
'Unexpected output for ' + pathSegments.join('/')
);
});
}
36 changes: 14 additions & 22 deletions test/cli/index.js
Expand Up @@ -3,31 +3,21 @@ const assert = require('assert');
const sander = require('sander');
const buble = require('buble');
const { exec } = require('child_process');
const { deindent, loadConfig, normaliseOutput } = require('../utils.js');

const samples = path.resolve(__dirname, 'samples');
const { deindent, normaliseOutput, runTestSuiteWithSamples } = require('../utils.js');

const cwd = process.cwd();

sander.rimrafSync(__dirname, 'node_modules');
sander.copydirSync(__dirname, 'node_modules_rename_me').to(__dirname, 'node_modules');

describe('cli', () => {
afterEach(() => {
process.chdir(cwd);
});

sander
.readdirSync(samples)
.sort()
.forEach(dir => {
if (dir[0] === '.') return; // .DS_Store...

const config = loadConfig(samples + '/' + dir + '/_config.js');
if (!config) return;

(config.skip ? it.skip : config.solo ? it.only : it)(dir, done => {
process.chdir(config.cwd || path.resolve(samples, dir));
runTestSuiteWithSamples(
'cli',
path.resolve(__dirname, 'samples'),
(dir, config) => {
(config.skip ? it.skip : config.solo ? it.only : it)(
path.basename(dir) + ': ' + config.description,
done => {
process.chdir(config.cwd || dir);

const command = 'node ' + path.resolve(__dirname, '../../bin') + path.sep + config.command;

Expand Down Expand Up @@ -121,6 +111,8 @@ describe('cli', () => {
}
}
});
});
});
});
}
);
},
() => process.chdir(cwd)
);
35 changes: 3 additions & 32 deletions test/form/index.js
Expand Up @@ -2,40 +2,11 @@ const path = require('path');
const assert = require('assert');
const sander = require('sander');
const rollup = require('../../dist/rollup');
const { extend, loadConfig, normaliseOutput, removeOldTest } = require('../utils.js');
const { extend, normaliseOutput, runTestSuiteWithSamples } = require('../utils.js');

const SAMPLES_DIR = path.resolve(__dirname, 'samples');
const FORMATS = ['amd', 'cjs', 'system', 'es', 'iife', 'umd'];

describe('form', () => {
sander
.readdirSync(SAMPLES_DIR)
.filter(name => name[0] !== '.')
.sort()
.forEach(fileName => runTestsInDir(SAMPLES_DIR + '/' + fileName));
});

function runTestsInDir(dir) {
const fileNames = sander.readdirSync(dir);

if (fileNames.indexOf('_config.js') >= 0) {
runTestCaseInDir(dir);
} else if (fileNames.indexOf('_actual') >= 0 || fileNames.indexOf('_actual.js') >= 0) {
removeOldTest(dir);
} else {
describe(path.basename(dir), () => {
fileNames
.filter(name => name[0] !== '.')
.sort()
.forEach(fileName => runTestsInDir(dir + '/' + fileName));
});
}
}

function runTestCaseInDir(dir) {
const config = loadConfig(dir + '/_config.js');
if (!config || (config.skipIfWindows && process.platform === 'win32')) return;

runTestSuiteWithSamples('form', path.resolve(__dirname, 'samples'), (dir, config) => {
const isSingleFormatTest = sander.existsSync(dir + '/_expected.js');
const itOrDescribe = isSingleFormatTest ? it : describe;
(config.skip ? itOrDescribe.skip : config.solo ? itOrDescribe.only : itOrDescribe)(
Expand Down Expand Up @@ -90,7 +61,7 @@ function runTestCaseInDir(dir) {
);
}
);
}
});

function generateAndTestBundle(bundle, outputOptions, expectedFile, { show }) {
return bundle.write(outputOptions).then(() => {
Expand Down

0 comments on commit e093195

Please sign in to comment.