diff --git a/js/checkNamespaces.js b/js/checkNamespaces.js index 7e952627..009c6881 100644 --- a/js/checkNamespaces.js +++ b/js/checkNamespaces.js @@ -13,6 +13,7 @@ define( function() { 'use strict'; return function() { + // Skip everything if we don't have assertions on, since that's the point of this function. if ( !assert ) { return; @@ -22,41 +23,61 @@ define( function() { // information yet in the optimizer (with almond) and with require.js, so we have a fall-back set up. var defined = window.requirejs._defined || window.require.s.contexts._.defined; - for ( var moduleName in defined ) { - // Skip strings, images, or anything imported with a plugin. Could be added later if needed - if ( moduleName.indexOf( '!' ) >= 0 ) { - continue; - } + /** + * This function iterates over all defined AMD modules and reports to a problemHandler any problems. + * @param {function} problemHandler, a function that is called when an error occurs, with an {string} argument that + * describes the problem + */ + var visit = function( problemHandler ) { + for ( var moduleName in defined ) { + // Skip strings, images, or anything imported with a plugin. Could be added later if needed + if ( moduleName.indexOf( '!' ) >= 0 ) { + continue; + } - // Skip anything without a slash (the plugins themselves, and the main/config files) - if ( moduleName.indexOf( '/' ) < 0 ) { - continue; - } + // Skip anything without a slash (the plugins themselves, and the main/config files) + if ( moduleName.indexOf( '/' ) < 0 ) { + continue; + } - // Skip anything with '..' in the path (chipper imports some things where we can't get the repository prefix) - if ( moduleName.indexOf( '..' ) >= 0 ) { - continue; - } + // Skip anything with '..' in the path (chipper imports some things where we can't get the repository prefix) + if ( moduleName.indexOf( '..' ) >= 0 ) { + continue; + } - var prefix = moduleName.slice( 0, moduleName.indexOf( '/' ) ); // e.g. 'SCENERY_PHET' - var name = moduleName.slice( moduleName.lastIndexOf( '/' ) + 1 ); // e.g. 'ArrowButton' + var prefix = moduleName.slice( 0, moduleName.indexOf( '/' ) ); // e.g. 'SCENERY_PHET' + var name = moduleName.slice( moduleName.lastIndexOf( '/' ) + 1 ); // e.g. 'ArrowButton' - // Convert to camel-case, e.g. 'SCENERY_PHET' to 'sceneryPhet' - var prefixTokens = prefix.toLowerCase().split( '_' ); - var namespace = [ prefixTokens[ 0 ] ].concat( prefixTokens.slice( 1 ).map( function( token ) { - return token.charAt( 0 ).toUpperCase() + token.slice( 1 ); - } ) ).join( '' ); + // Convert to camel-case, e.g. 'SCENERY_PHET' to 'sceneryPhet' + var prefixTokens = prefix.toLowerCase().split( '_' ); + var namespace = [ prefixTokens[ 0 ] ].concat( prefixTokens.slice( 1 ).map( function( token ) { + return token.charAt( 0 ).toUpperCase() + token.slice( 1 ); + } ) ).join( '' ); - // Skip things with the same name as the namespace, as this is most likely a namespace object (e.g. scenery.js) - if ( namespace === name ) { - continue; + // Skip things with the same name as the namespace, as this is most likely a namespace object (e.g. scenery.js) + if ( namespace === name ) { + continue; + } + + var namespacedObject = phet[ namespace ] && phet[ namespace ][ name ]; + + if ( !namespacedObject ) { + problemHandler( 'not namespaced: ' + namespace + '.' + name ); + } + if ( namespacedObject && namespacedObject !== defined[ moduleName ] ) { + problemHandler( namespace + '.' + name + ' is different than the expected namespaced object' ); + } } + }; - var namespacedObject = phet[ namespace ] && phet[ namespace ][ name ]; + // First pass prints out all issues, to assist developers as we are adding the namespace register calls + visit( function( errorMessage ) { + console.log( errorMessage ); + } ); - assert && assert( namespacedObject, 'not namespaced: ' + namespace + '.' + name ); - assert && assert( namespacedObject === defined[ moduleName ], - namespace + '.' + name + ' is different than the expected namespaced object' ); - } + // Second pass fails with an assertion error. + visit( function( errorMessage ) { + assert && assert( false, errorMessage ); + } ); }; } );