From 0dbe64775aa106cd0f077bc1336126e2781902b4 Mon Sep 17 00:00:00 2001 From: kzc Date: Sat, 6 Feb 2021 17:52:09 -0500 Subject: [PATCH 1/5] implement `validate` output option and `--validate` CLI option * optionally verifies the generated output by parsing it with acorn * disabled by default * enable the validate option in the majority of tests * increase mocha test timeout due to circleci node-v14-latest --- cli/help.md | 1 + src/Bundle.ts | 12 +++++++++++ src/rollup/types.d.ts | 2 ++ src/utils/options/mergeOptions.ts | 6 ++++-- src/utils/options/normalizeOutputOptions.ts | 4 +++- test/chunking-form/index.js | 3 ++- test/cli/samples/validate/_config.js | 11 ++++++++++ test/cli/samples/validate/main.js | 1 + test/form/index.js | 3 ++- test/function/index.js | 3 ++- .../samples/output-options-hook/_config.js | 6 ++++-- test/misc/misc.js | 21 ++++++++++++++++++- test/misc/optionList.js | 4 ++-- test/test.js | 2 +- 14 files changed, 67 insertions(+), 12 deletions(-) create mode 100644 test/cli/samples/validate/_config.js create mode 100644 test/cli/samples/validate/main.js diff --git a/cli/help.md b/cli/help.md index 17ffc652150..bf1ee92a553 100644 --- a/cli/help.md +++ b/cli/help.md @@ -72,6 +72,7 @@ Basic options: --watch.skipWrite Do not write files to disk when watching --watch.exclude Exclude files from being watched --watch.include Limit watching to specified files +--validate Validate output (default false) Examples: diff --git a/src/Bundle.ts b/src/Bundle.ts index 1d161350104..62ad496588b 100644 --- a/src/Bundle.ts +++ b/src/Bundle.ts @@ -17,6 +17,7 @@ import commondir from './utils/commondir'; import { errCannotAssignModuleToChunk, error, warnDeprecation } from './utils/error'; import { sortByExecutionOrder } from './utils/executionOrder'; import { FILE_PLACEHOLDER } from './utils/FileEmitter'; +import getCodeFrame from './utils/getCodeFrame'; import { basename, isAbsolute } from './utils/path'; import { PluginDriver } from './utils/PluginDriver'; import { timeEnd, timeStart } from './utils/timers'; @@ -174,6 +175,17 @@ export default class Bundle { ); file.type = 'asset'; } + if (this.outputOptions.validate && typeof file.code == 'string') { + try { + this.graph.contextParse(file.code, { + allowHashBang: true, + ecmaVersion: 'latest' + }); + } catch (ex) { + const frame = getCodeFrame(file.code, ex.loc.line, ex.loc.column); + throw new Error(`validate failed for output '${key}': ${ex}\n${frame}`); + } + } } this.pluginDriver.finaliseAssets(); } diff --git a/src/rollup/types.d.ts b/src/rollup/types.d.ts index a185e66f80a..88f957a7a6d 100644 --- a/src/rollup/types.d.ts +++ b/src/rollup/types.d.ts @@ -653,6 +653,7 @@ export interface OutputOptions { sourcemapPathTransform?: SourcemapPathTransformOption; strict?: boolean; systemNullSetters?: boolean; + validate?: boolean; } export interface NormalizedOutputOptions { @@ -696,6 +697,7 @@ export interface NormalizedOutputOptions { sourcemapPathTransform: SourcemapPathTransformOption | undefined; strict: boolean; systemNullSetters: boolean; + validate?: boolean; } export type WarningHandlerWithDefault = ( diff --git a/src/utils/options/mergeOptions.ts b/src/utils/options/mergeOptions.ts index cb6cd097027..53ddb946a3c 100644 --- a/src/utils/options/mergeOptions.ts +++ b/src/utils/options/mergeOptions.ts @@ -55,7 +55,8 @@ export function mergeOptions( 'silent', 'failAfterWarnings', 'stdin', - 'waitForBundleInput' + 'waitForBundleInput', + 'validate' ), 'CLI flags', warn, @@ -227,7 +228,8 @@ function mergeOutputOptions( sourcemapFile: getOption('sourcemapFile'), sourcemapPathTransform: getOption('sourcemapPathTransform'), strict: getOption('strict'), - systemNullSetters: getOption('systemNullSetters') + systemNullSetters: getOption('systemNullSetters'), + validate: getOption('validate') }; warnUnknownOptions(config, Object.keys(outputOptions), 'output options', warn); diff --git a/src/utils/options/normalizeOutputOptions.ts b/src/utils/options/normalizeOutputOptions.ts index 8fc9c9e99df..5b034acda52 100644 --- a/src/utils/options/normalizeOutputOptions.ts +++ b/src/utils/options/normalizeOutputOptions.ts @@ -26,6 +26,7 @@ export function normalizeOutputOptions( const unsetOptions = new Set(unsetInputOptions); const compact = (config.compact as boolean | undefined) || false; + const validate = (config.validate as boolean | undefined) || false; const format = getFormat(config); const inlineDynamicImports = getInlineDynamicImports(config, inputOptions); const preserveModules = getPreserveModules(config, inlineDynamicImports, inputOptions); @@ -73,7 +74,8 @@ export function normalizeOutputOptions( | SourcemapPathTransformOption | undefined, strict: (config.strict as boolean | undefined) ?? true, - systemNullSetters: (config.systemNullSetters as boolean | undefined) || false + systemNullSetters: (config.systemNullSetters as boolean | undefined) || false, + validate }; warnUnknownOptions(config, Object.keys(outputOptions), 'output options', inputOptions.onwarn); diff --git a/test/chunking-form/index.js b/test/chunking-form/index.js index 4e34c6b9f41..509be3cbe44 100644 --- a/test/chunking-form/index.js +++ b/test/chunking-form/index.js @@ -44,7 +44,8 @@ runTestSuiteWithSamples('chunking form', path.resolve(__dirname, 'samples'), (di dir: `${dir}/_actual/${format}`, exports: 'auto', format, - chunkFileNames: 'generated-[name].js' + chunkFileNames: 'generated-[name].js', + validate: true }, (config.options || {}).output || {} ), diff --git a/test/cli/samples/validate/_config.js b/test/cli/samples/validate/_config.js new file mode 100644 index 00000000000..6a8c7bf1b47 --- /dev/null +++ b/test/cli/samples/validate/_config.js @@ -0,0 +1,11 @@ +const { assertIncludes } = require('../../../utils.js'); + +module.exports = { + description: 'use CLI --validate to test whether output is well formed', + skipIfWindows: true, + command: `rollup main.js --silent --outro 'console.log("end"); /*' -o _actual/out.js --validate`, + error(err) { + assertIncludes(err.message, `validate failed for output 'out.js'`); + assertIncludes(err.message, 'SyntaxError: Unterminated comment (3:20)'); + } +}; diff --git a/test/cli/samples/validate/main.js b/test/cli/samples/validate/main.js new file mode 100644 index 00000000000..8b068518106 --- /dev/null +++ b/test/cli/samples/validate/main.js @@ -0,0 +1 @@ +console.log(1 ? 2 : 3); diff --git a/test/form/index.js b/test/form/index.js index 4e329c42987..dc5b34e9e7b 100644 --- a/test/form/index.js +++ b/test/form/index.js @@ -47,7 +47,8 @@ runTestSuiteWithSamples('form', path.resolve(__dirname, 'samples'), (dir, config { exports: 'auto', file: inputFile, - format: defaultFormat + format: defaultFormat, + // validate: true // add when systemjs bugs fixed }, (config.options || {}).output || {} ), diff --git a/test/function/index.js b/test/function/index.js index 0f2a85d63a5..5c9c8b3d421 100644 --- a/test/function/index.js +++ b/test/function/index.js @@ -82,7 +82,8 @@ runTestSuiteWithSamples('function', path.resolve(__dirname, 'samples'), (dir, co Object.assign( { exports: 'auto', - format: 'cjs' + format: 'cjs', + validate: true }, (config.options || {}).output || {} ) diff --git a/test/function/samples/output-options-hook/_config.js b/test/function/samples/output-options-hook/_config.js index b6855ab3c91..24dab923b19 100644 --- a/test/function/samples/output-options-hook/_config.js +++ b/test/function/samples/output-options-hook/_config.js @@ -45,7 +45,8 @@ module.exports = { sourcemap: false, sourcemapExcludeSources: false, strict: true, - systemNullSetters: false + systemNullSetters: false, + validate: true }); assert.strictEqual(options.banner(), 'exports.bar = 43;'); assert.ok(/^\d+\.\d+\.\d+/.test(this.meta.rollupVersion)); @@ -55,7 +56,8 @@ module.exports = { assert.deepStrictEqual(JSON.parse(JSON.stringify(options)), { banner: "throw new Error('unused')", exports: 'auto', - format: 'cjs' + format: 'cjs', + validate: true }); assert.ok(/^\d+\.\d+\.\d+/.test(this.meta.rollupVersion)); assert.strictEqual(this.meta.watchMode, false); diff --git a/test/misc/misc.js b/test/misc/misc.js index 2840e429307..44614217494 100644 --- a/test/misc/misc.js +++ b/test/misc/misc.js @@ -1,6 +1,6 @@ const assert = require('assert'); const rollup = require('../../dist/rollup'); -const { loader } = require('../utils.js'); +const { assertIncludes, loader } = require('../utils.js'); describe('misc', () => { it('avoids modification of options or their properties', () => { @@ -242,4 +242,23 @@ console.log(x); assert.strictEqual(subfeature.fileName, 'base/main/feature/sub'); assert.ok(subfeature.code.startsWith("import { fn } from '../../main'")); }); + + it('handles validate failure', () => { + return rollup + .rollup({ + input: 'x', + plugins: [loader({ x: `console.log(1 ? 2 : 3);` })] + }) + .then(bundle => bundle.generate({ + format: 'es', + outro: '/*', // introduce bad syntax in output + validate: true + }) + .then(generated => should_not_be_reached) + .catch(error => { + assertIncludes(error.message, `validate failed for output 'x.js'`); + assertIncludes(error.message, 'SyntaxError: Unterminated comment (3:0)'); + }) + ); + }); }); diff --git a/test/misc/optionList.js b/test/misc/optionList.js index 3d013653035..05392922320 100644 --- a/test/misc/optionList.js +++ b/test/misc/optionList.js @@ -1,6 +1,6 @@ exports.input = 'acorn, acornInjectPlugins, cache, context, experimentalCacheExpiry, external, inlineDynamicImports, input, manualChunks, moduleContext, onwarn, perf, plugins, preserveEntrySignatures, preserveModules, preserveSymlinks, shimMissingExports, strictDeprecations, treeshake, watch'; exports.flags = - 'acorn, acornInjectPlugins, amd, assetFileNames, banner, c, cache, chunkFileNames, compact, config, context, d, dir, dynamicImportFunction, e, entryFileNames, environment, esModule, experimentalCacheExpiry, exports, extend, external, externalLiveBindings, f, failAfterWarnings, file, footer, format, freeze, g, globals, h, hoistTransitiveImports, i, indent, inlineDynamicImports, input, interop, intro, m, manualChunks, minifyInternalExports, moduleContext, n, name, namespaceToStringTag, noConflict, o, onwarn, outro, p, paths, perf, plugin, plugins, preferConst, preserveEntrySignatures, preserveModules, preserveModulesRoot, preserveSymlinks, shimMissingExports, silent, sourcemap, sourcemapExcludeSources, sourcemapFile, stdin, strict, strictDeprecations, systemNullSetters, treeshake, v, w, waitForBundleInput, watch'; + 'acorn, acornInjectPlugins, amd, assetFileNames, banner, c, cache, chunkFileNames, compact, config, context, d, dir, dynamicImportFunction, e, entryFileNames, environment, esModule, experimentalCacheExpiry, exports, extend, external, externalLiveBindings, f, failAfterWarnings, file, footer, format, freeze, g, globals, h, hoistTransitiveImports, i, indent, inlineDynamicImports, input, interop, intro, m, manualChunks, minifyInternalExports, moduleContext, n, name, namespaceToStringTag, noConflict, o, onwarn, outro, p, paths, perf, plugin, plugins, preferConst, preserveEntrySignatures, preserveModules, preserveModulesRoot, preserveSymlinks, shimMissingExports, silent, sourcemap, sourcemapExcludeSources, sourcemapFile, stdin, strict, strictDeprecations, systemNullSetters, treeshake, v, validate, w, waitForBundleInput, watch'; exports.output = - 'amd, assetFileNames, banner, chunkFileNames, compact, dir, dynamicImportFunction, entryFileNames, esModule, exports, extend, externalLiveBindings, file, footer, format, freeze, globals, hoistTransitiveImports, indent, inlineDynamicImports, interop, intro, manualChunks, minifyInternalExports, name, namespaceToStringTag, noConflict, outro, paths, plugins, preferConst, preserveModules, preserveModulesRoot, sourcemap, sourcemapExcludeSources, sourcemapFile, sourcemapPathTransform, strict, systemNullSetters'; + 'amd, assetFileNames, banner, chunkFileNames, compact, dir, dynamicImportFunction, entryFileNames, esModule, exports, extend, externalLiveBindings, file, footer, format, freeze, globals, hoistTransitiveImports, indent, inlineDynamicImports, interop, intro, manualChunks, minifyInternalExports, name, namespaceToStringTag, noConflict, outro, paths, plugins, preferConst, preserveModules, preserveModulesRoot, sourcemap, sourcemapExcludeSources, sourcemapFile, sourcemapPathTransform, strict, systemNullSetters, validate'; diff --git a/test/test.js b/test/test.js index 699c48846de..119b13391e1 100644 --- a/test/test.js +++ b/test/test.js @@ -1,7 +1,7 @@ require('source-map-support').install(); describe('rollup', function () { - this.timeout(15000); + this.timeout(30000); require('./misc/index.js'); require('./function/index.js'); require('./form/index.js'); From 535a1f8a839edf15e2999d9a5626e9bc4d9be62b Mon Sep 17 00:00:00 2001 From: Lukas Taegert-Atkinson Date: Fri, 12 Feb 2021 06:54:09 +0100 Subject: [PATCH 2/5] Add missing documentation --- cli/help.md | 2 +- docs/01-command-line-reference.md | 2 ++ docs/02-javascript-api.md | 1 + docs/999-big-list-of-options.md | 7 +++++++ 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/cli/help.md b/cli/help.md index bf1ee92a553..b6b853dc50b 100644 --- a/cli/help.md +++ b/cli/help.md @@ -72,7 +72,7 @@ Basic options: --watch.skipWrite Do not write files to disk when watching --watch.exclude Exclude files from being watched --watch.include Limit watching to specified files ---validate Validate output (default false) +--validate Validate output Examples: diff --git a/docs/01-command-line-reference.md b/docs/01-command-line-reference.md index 099903738de..f3438bf71c1 100755 --- a/docs/01-command-line-reference.md +++ b/docs/01-command-line-reference.md @@ -83,6 +83,7 @@ export default { // can be an array (for multiple inputs) sourcemapExcludeSources, sourcemapFile, sourcemapPathTransform, + validate, // danger zone amd, @@ -330,6 +331,7 @@ Many options have command line equivalents. In those cases, any arguments passed --watch.skipWrite Do not write files to disk when watching --watch.exclude Exclude files from being watched --watch.include Limit watching to specified files +--validate Validate output ``` The flags listed below are only available via the command line interface. All other flags correspond to and override their config file equivalents, see the [big list of options](guide/en/#big-list-of-options) for details. diff --git a/docs/02-javascript-api.md b/docs/02-javascript-api.md index cfa9429466d..cf10af2ae1b 100755 --- a/docs/02-javascript-api.md +++ b/docs/02-javascript-api.md @@ -148,6 +148,7 @@ const outputOptions = { sourcemapExcludeSources, sourcemapFile, sourcemapPathTransform, + validate, // danger zone amd, diff --git a/docs/999-big-list-of-options.md b/docs/999-big-list-of-options.md index c8edd7274ab..d70ca194b8e 100755 --- a/docs/999-big-list-of-options.md +++ b/docs/999-big-list-of-options.md @@ -924,6 +924,13 @@ export default ({ }); ``` +#### output.validate +Type: `boolean`
+CLI: `--validate`/`--no-validate`
+Default: `false` + +Re-parses each generated chunk to detect if the generated code is valid JavaScript. This can be useful to debug output generated by plugins that use the [`renderChunk`](guide/en/#renderchunk) hook to transform code. + #### preserveEntrySignatures Type: `"strict" | "allow-extension" | "exports-only" | false`
CLI: `--preserveEntrySignatures `/`--no-preserveEntrySignatures`
From 16a839e2ef254e22d200a5de1c8796a7fea8a79d Mon Sep 17 00:00:00 2001 From: Lukas Taegert-Atkinson Date: Fri, 12 Feb 2021 07:33:32 +0100 Subject: [PATCH 3/5] Refine error output and tests --- src/Bundle.ts | 13 +++++++---- src/utils/error.ts | 13 +++++++++++ src/utils/options/mergeOptions.ts | 3 +-- src/utils/options/normalizeOutputOptions.ts | 3 +-- test/cli/samples/validate/_config.js | 16 +++++++++---- test/function/index.js | 3 +-- .../samples/output-options-hook/_config.js | 5 ++-- .../samples/validate-output/_config.js | 23 +++++++++++++++++++ test/function/samples/validate-output/main.js | 1 + test/misc/misc.js | 19 --------------- 10 files changed, 61 insertions(+), 38 deletions(-) create mode 100644 test/function/samples/validate-output/_config.js create mode 100644 test/function/samples/validate-output/main.js diff --git a/src/Bundle.ts b/src/Bundle.ts index 62ad496588b..21afff03c38 100644 --- a/src/Bundle.ts +++ b/src/Bundle.ts @@ -14,10 +14,14 @@ import { import { Addons, createAddons } from './utils/addons'; import { getChunkAssignments } from './utils/chunkAssignment'; import commondir from './utils/commondir'; -import { errCannotAssignModuleToChunk, error, warnDeprecation } from './utils/error'; +import { + errCannotAssignModuleToChunk, + errChunkInvalid, + error, + warnDeprecation +} from './utils/error'; import { sortByExecutionOrder } from './utils/executionOrder'; import { FILE_PLACEHOLDER } from './utils/FileEmitter'; -import getCodeFrame from './utils/getCodeFrame'; import { basename, isAbsolute } from './utils/path'; import { PluginDriver } from './utils/PluginDriver'; import { timeEnd, timeStart } from './utils/timers'; @@ -181,9 +185,8 @@ export default class Bundle { allowHashBang: true, ecmaVersion: 'latest' }); - } catch (ex) { - const frame = getCodeFrame(file.code, ex.loc.line, ex.loc.column); - throw new Error(`validate failed for output '${key}': ${ex}\n${frame}`); + } catch (exception) { + return error(errChunkInvalid(file, exception)); } } } diff --git a/src/utils/error.ts b/src/utils/error.ts index f4066823a61..176a8fc3312 100644 --- a/src/utils/error.ts +++ b/src/utils/error.ts @@ -45,6 +45,7 @@ export const enum Errors { BAD_LOADER = 'BAD_LOADER', CANNOT_EMIT_FROM_OPTIONS_HOOK = 'CANNOT_EMIT_FROM_OPTIONS_HOOK', CHUNK_NOT_GENERATED = 'CHUNK_NOT_GENERATED', + CHUNK_INVALID = 'CHUNK_INVALID', CIRCULAR_REEXPORT = 'CIRCULAR_REEXPORT', CYCLIC_CROSS_CHUNK_REEXPORT = 'CYCLIC_CROSS_CHUNK_REEXPORT', DEPRECATED_FEATURE = 'DEPRECATED_FEATURE', @@ -93,6 +94,18 @@ export function errChunkNotGeneratedForFileName(name: string) { }; } +export function errChunkInvalid( + { fileName, code }: { code: string; fileName: string }, + exception: { loc: { column: number; line: number }; message: string } +) { + const errorProps = { + code: Errors.CHUNK_INVALID, + message: `Chunk "${fileName}" is not valid JavaScript: ${exception.message}.` + }; + augmentCodeLocation(errorProps, exception.loc, code, fileName); + return errorProps; +} + export function errCircularReexport(exportName: string, importedModule: string) { return { code: Errors.CIRCULAR_REEXPORT, diff --git a/src/utils/options/mergeOptions.ts b/src/utils/options/mergeOptions.ts index 53ddb946a3c..843109df900 100644 --- a/src/utils/options/mergeOptions.ts +++ b/src/utils/options/mergeOptions.ts @@ -55,8 +55,7 @@ export function mergeOptions( 'silent', 'failAfterWarnings', 'stdin', - 'waitForBundleInput', - 'validate' + 'waitForBundleInput' ), 'CLI flags', warn, diff --git a/src/utils/options/normalizeOutputOptions.ts b/src/utils/options/normalizeOutputOptions.ts index 5b034acda52..5cf14024e29 100644 --- a/src/utils/options/normalizeOutputOptions.ts +++ b/src/utils/options/normalizeOutputOptions.ts @@ -26,7 +26,6 @@ export function normalizeOutputOptions( const unsetOptions = new Set(unsetInputOptions); const compact = (config.compact as boolean | undefined) || false; - const validate = (config.validate as boolean | undefined) || false; const format = getFormat(config); const inlineDynamicImports = getInlineDynamicImports(config, inputOptions); const preserveModules = getPreserveModules(config, inlineDynamicImports, inputOptions); @@ -75,7 +74,7 @@ export function normalizeOutputOptions( | undefined, strict: (config.strict as boolean | undefined) ?? true, systemNullSetters: (config.systemNullSetters as boolean | undefined) || false, - validate + validate: (config.validate as boolean | undefined) || false }; warnUnknownOptions(config, Object.keys(outputOptions), 'output options', inputOptions.onwarn); diff --git a/test/cli/samples/validate/_config.js b/test/cli/samples/validate/_config.js index 6a8c7bf1b47..586758d8eab 100644 --- a/test/cli/samples/validate/_config.js +++ b/test/cli/samples/validate/_config.js @@ -2,10 +2,16 @@ const { assertIncludes } = require('../../../utils.js'); module.exports = { description: 'use CLI --validate to test whether output is well formed', - skipIfWindows: true, command: `rollup main.js --silent --outro 'console.log("end"); /*' -o _actual/out.js --validate`, - error(err) { - assertIncludes(err.message, `validate failed for output 'out.js'`); - assertIncludes(err.message, 'SyntaxError: Unterminated comment (3:20)'); - } + error: () => true, + stderr: stderr => + assertIncludes( + stderr, + `[!] Error: Chunk "out.js" is not valid JavaScript: Unterminated comment (3:20). +out.js (3:20) +1: console.log(2 ); +2: +3: console.log("end"); /* + ^` + ) }; diff --git a/test/function/index.js b/test/function/index.js index 5c9c8b3d421..0f2a85d63a5 100644 --- a/test/function/index.js +++ b/test/function/index.js @@ -82,8 +82,7 @@ runTestSuiteWithSamples('function', path.resolve(__dirname, 'samples'), (dir, co Object.assign( { exports: 'auto', - format: 'cjs', - validate: true + format: 'cjs' }, (config.options || {}).output || {} ) diff --git a/test/function/samples/output-options-hook/_config.js b/test/function/samples/output-options-hook/_config.js index 24dab923b19..904cf55577e 100644 --- a/test/function/samples/output-options-hook/_config.js +++ b/test/function/samples/output-options-hook/_config.js @@ -46,7 +46,7 @@ module.exports = { sourcemapExcludeSources: false, strict: true, systemNullSetters: false, - validate: true + validate: false }); assert.strictEqual(options.banner(), 'exports.bar = 43;'); assert.ok(/^\d+\.\d+\.\d+/.test(this.meta.rollupVersion)); @@ -56,8 +56,7 @@ module.exports = { assert.deepStrictEqual(JSON.parse(JSON.stringify(options)), { banner: "throw new Error('unused')", exports: 'auto', - format: 'cjs', - validate: true + format: 'cjs' }); assert.ok(/^\d+\.\d+\.\d+/.test(this.meta.rollupVersion)); assert.strictEqual(this.meta.watchMode, false); diff --git a/test/function/samples/validate-output/_config.js b/test/function/samples/validate-output/_config.js new file mode 100644 index 00000000000..9850e118ef0 --- /dev/null +++ b/test/function/samples/validate-output/_config.js @@ -0,0 +1,23 @@ +module.exports = { + description: 'handles validate failure', + options: { + output: { + outro: '/*', + validate: true + } + }, + generateError: { + code: 'CHUNK_INVALID', + message: 'Chunk "main.js" is not valid JavaScript: Unterminated comment (5:0).', + frame: ` +3: throw new Error('Not executed'); +4: +5: /* + ^`, + loc: { + column: 0, + file: 'main.js', + line: 5 + } + } +}; diff --git a/test/function/samples/validate-output/main.js b/test/function/samples/validate-output/main.js new file mode 100644 index 00000000000..a9244a453fb --- /dev/null +++ b/test/function/samples/validate-output/main.js @@ -0,0 +1 @@ +throw new Error('Not executed'); diff --git a/test/misc/misc.js b/test/misc/misc.js index 44614217494..347cd46f3f5 100644 --- a/test/misc/misc.js +++ b/test/misc/misc.js @@ -242,23 +242,4 @@ console.log(x); assert.strictEqual(subfeature.fileName, 'base/main/feature/sub'); assert.ok(subfeature.code.startsWith("import { fn } from '../../main'")); }); - - it('handles validate failure', () => { - return rollup - .rollup({ - input: 'x', - plugins: [loader({ x: `console.log(1 ? 2 : 3);` })] - }) - .then(bundle => bundle.generate({ - format: 'es', - outro: '/*', // introduce bad syntax in output - validate: true - }) - .then(generated => should_not_be_reached) - .catch(error => { - assertIncludes(error.message, `validate failed for output 'x.js'`); - assertIncludes(error.message, 'SyntaxError: Unterminated comment (3:0)'); - }) - ); - }); }); From ea58fdd0f0a62b7f72bb7af78429b7ce243d6e6b Mon Sep 17 00:00:00 2001 From: Lukas Taegert-Atkinson Date: Fri, 12 Feb 2021 07:37:24 +0100 Subject: [PATCH 4/5] Normalized options should be normalized --- src/rollup/types.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rollup/types.d.ts b/src/rollup/types.d.ts index 88f957a7a6d..b12911dc00c 100644 --- a/src/rollup/types.d.ts +++ b/src/rollup/types.d.ts @@ -697,7 +697,7 @@ export interface NormalizedOutputOptions { sourcemapPathTransform: SourcemapPathTransformOption | undefined; strict: boolean; systemNullSetters: boolean; - validate?: boolean; + validate: boolean; } export type WarningHandlerWithDefault = ( From 808134262a50403d95d8da00e7b0275b853d4aa3 Mon Sep 17 00:00:00 2001 From: Lukas Taegert-Atkinson Date: Fri, 12 Feb 2021 08:34:52 +0100 Subject: [PATCH 5/5] Skip test on windows --- test/cli/samples/validate/_config.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/cli/samples/validate/_config.js b/test/cli/samples/validate/_config.js index 586758d8eab..934ca67c2a5 100644 --- a/test/cli/samples/validate/_config.js +++ b/test/cli/samples/validate/_config.js @@ -2,6 +2,7 @@ const { assertIncludes } = require('../../../utils.js'); module.exports = { description: 'use CLI --validate to test whether output is well formed', + skipIfWindows: true, command: `rollup main.js --silent --outro 'console.log("end"); /*' -o _actual/out.js --validate`, error: () => true, stderr: stderr =>