Skip to content

Commit

Permalink
add development warnings for missing data properties with dev: true (#13
Browse files Browse the repository at this point in the history
)
  • Loading branch information
Rich-Harris committed Mar 1, 2017
1 parent 62c8ef4 commit d61b192
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 4 deletions.
8 changes: 8 additions & 0 deletions src/generators/Generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
Expand Down Expand Up @@ -99,6 +103,10 @@ export default class Generator {
}
});

dependencies.forEach( name => {
this.expectedProperties[ name ] = true;
});

return {
dependencies,
contexts: usedContexts,
Expand Down
23 changes: 21 additions & 2 deletions src/generators/dom/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 ),
Expand Down
18 changes: 16 additions & 2 deletions test/generate.js
Original file line number Diff line number Diff line change
Expand Up @@ -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' );
Expand Down Expand Up @@ -79,6 +80,8 @@ describe( 'generate', () => {
throw err;
}

let unintendedError = null;

return env()
.then( window => {
// Put the constructor on window for testing
Expand All @@ -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 );
}
Expand All @@ -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;
}
});
});
}
Expand Down
7 changes: 7 additions & 0 deletions test/generator/dev-warning-missing-data/_config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default {
dev: true,

error ( assert, err ) {
assert.equal( err.message, `Component was created without expected data property 'foo'` );
}
};
1 change: 1 addition & 0 deletions test/generator/dev-warning-missing-data/main.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<p>{{foo}}</p>

0 comments on commit d61b192

Please sign in to comment.