From d61b1927b2f1180fb940c8f944e7a1c72c37b02f Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Wed, 1 Mar 2017 17:25:19 -0500 Subject: [PATCH] add development warnings for missing data properties with dev: true (#13) --- src/generators/Generator.js | 8 +++++++ src/generators/dom/index.js | 23 +++++++++++++++++-- test/generate.js | 18 +++++++++++++-- .../dev-warning-missing-data/_config.js | 7 ++++++ .../dev-warning-missing-data/main.html | 1 + 5 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 test/generator/dev-warning-missing-data/_config.js create mode 100644 test/generator/dev-warning-missing-data/main.html diff --git a/src/generators/Generator.js b/src/generators/Generator.js index 20618ee60e..7377e79461 100644 --- a/src/generators/Generator.js +++ b/src/generators/Generator.js @@ -19,6 +19,10 @@ export default class Generator { this.components = {}; this.events = {}; + // track which properties are needed, so we can provide useful info + // in dev mode + this.expectedProperties = {}; + this.elementDepth = 0; this.code = new MagicString( source ); @@ -99,6 +103,10 @@ export default class Generator { } }); + dependencies.forEach( name => { + this.expectedProperties[ name ] = true; + }); + return { dependencies, contexts: usedContexts, diff --git a/src/generators/dom/index.js b/src/generators/dom/index.js index 815d053cb3..2ade8eea93 100644 --- a/src/generators/dom/index.js +++ b/src/generators/dom/index.js @@ -291,13 +291,32 @@ export default function dom ( parsed, source, options, names ) { ` ); } - const initialState = templateProperties.data ? `Object.assign( template.data(), options.data )` : `options.data || {}`; + const stateBlock = new CodeBuilder(); + + stateBlock.addLine( + `this._state = ${templateProperties.data ? `Object.assign( template.data(), options.data )` : `options.data || {}`};` + ); + + if ( templateProperties.computed ) { + stateBlock.addLine( + `applyComputations( this._state, this._state, {}, true );` + ); + } + + if ( options.dev ) { + Object.keys( generator.expectedProperties ).forEach( prop => { + stateBlock.addLine( + `if ( !( '${prop}' in this._state ) ) throw new Error( "Component was created without expected data property 'foo'" );` + ); + }); + } builders.main.addBlock( deindent` function ${name} ( options ) { options = options || {}; ${generator.usesRefs ? `\nthis.refs = {}` : ``} - this._state = ${initialState};${templateProperties.computed ? `\napplyComputations( this._state, this._state, {}, true );` : ``} + + ${stateBlock} this._observers = { pre: Object.create( null ), diff --git a/test/generate.js b/test/generate.js index 7adba3c61d..739c93fbe3 100644 --- a/test/generate.js +++ b/test/generate.js @@ -41,6 +41,7 @@ describe( 'generate', () => { showCompiledCode = config.show; compileOptions = config.compileOptions || {}; compileOptions.shared = shared; + compileOptions.dev = config.dev; try { const source = fs.readFileSync( `test/generator/${dir}/main.html`, 'utf-8' ); @@ -79,6 +80,8 @@ describe( 'generate', () => { throw err; } + let unintendedError = null; + return env() .then( window => { // Put the constructor on window for testing @@ -91,6 +94,11 @@ describe( 'generate', () => { data: config.data }); + if ( config.error ) { + unintendedError = true; + throw new Error( 'Expected a runtime error' ); + } + if ( config.html ) { assert.htmlEqual( target.innerHTML, config.html ); } @@ -103,8 +111,14 @@ describe( 'generate', () => { } }) .catch( err => { - if ( !config.show ) console.log( addLineNumbers( code ) ); // eslint-disable-line no-console - throw err; + if ( config.error && !unintendedError ) { + config.error( assert, err ); + } + + else { + if ( !config.show ) console.log( addLineNumbers( code ) ); // eslint-disable-line no-console + throw err; + } }); }); } diff --git a/test/generator/dev-warning-missing-data/_config.js b/test/generator/dev-warning-missing-data/_config.js new file mode 100644 index 0000000000..da44c09cc1 --- /dev/null +++ b/test/generator/dev-warning-missing-data/_config.js @@ -0,0 +1,7 @@ +export default { + dev: true, + + error ( assert, err ) { + assert.equal( err.message, `Component was created without expected data property 'foo'` ); + } +}; \ No newline at end of file diff --git a/test/generator/dev-warning-missing-data/main.html b/test/generator/dev-warning-missing-data/main.html new file mode 100644 index 0000000000..083fa61785 --- /dev/null +++ b/test/generator/dev-warning-missing-data/main.html @@ -0,0 +1 @@ +

{{foo}}

\ No newline at end of file