Skip to content

Commit

Permalink
refactor 1
Browse files Browse the repository at this point in the history
  • Loading branch information
MartijnR committed Jul 31, 2020
1 parent 273a4fa commit 0f8df9d
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 47 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"main": "src/validator.js",
"bin": "./validate",
"scripts": {
"test": "nyc mocha test/spec/*.spec.js --exit && npm run style-check && node update-readme-with-shield-badge.js",
"test": "nyc mocha test/spec/*.spec.js --exit --timeout 5000 && npm run style-check && node update-readme-with-shield-badge.js",
"build-docs": "rimraf docs && ./node_modules/.bin/jsdoc -c jsdoc.config.js",
"prepublish": "rollup --config && rollup --config rollup.utils.config.js",
"style-fix": "eslint *.js src/**/*.js test/**/*.js --fix",
Expand Down
82 changes: 38 additions & 44 deletions src/validator.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const { version } = require( '../package' );
* @param {ValidationOptions} [options] - Validation options.
* @return {ValidateResult} validation results.
*/
const validate = ( xformStr, options = {} ) => {
const validate = async( xformStr, options = {} ) => {
let warnings = [];
let errors = [];
let xform;
Expand All @@ -56,61 +56,55 @@ const validate = ( xformStr, options = {} ) => {
xform.checkOpenClinicaRules( warnings, errors );
}

return xform.parseModel()
.then( () => {
const tasks = [];
// Find binds
xform.binds.forEach( ( bind, index ) => {
const path = bind.getAttribute( 'nodeset' );

if ( !path ) {
warnings.push( `Found bind (index: ${index}) without nodeset attribute.` );

return;
}
try{
await xform.parseModel();
} catch ( e ) {
let ers = Array.isArray( e ) ? e : [ e ];
errors = errors.concat( ers );
}

const nodeName = path.substring( path.lastIndexOf( '/' ) + 1 );
// Find binds

// Note: using enketoEvaluate here, would be much slower.
tasks.push( xform.nodeExists( path )
.then( nodeExists => {
if ( !nodeExists ) {
warnings.push( `Found bind for "${nodeName}" that does not exist in the model.` );
for( const bind of xform.binds ){
const path = bind.getAttribute( 'nodeset' );

return;
}
if ( !path ) {
warnings.push( 'Found bind without nodeset attribute.' );

const subTasks = [ 'calculate', 'constraint', 'relevant', 'required' ].map( logicName => {
const logicExpr = bind.getAttribute( logicName );
const calculation = logicName === 'calculate';
continue;
}

if ( logicExpr ) {
const friendlyLogicName = calculation ? 'Calculation' : logicName[ 0 ].toUpperCase() + logicName.substring( 1 );
const nodeName = path.substring( path.lastIndexOf( '/' ) + 1 );
// Note: using enketoEvaluate here, would be much slower
const nodeExists = await xform.nodeExists( path );

if ( !nodeExists ) {
warnings.push( `Found bind for "${nodeName}" that does not exist in the model.` );

return xform.enketoEvaluate( logicExpr, ( calculation ? 'string' : 'boolean' ), path )
.catch( e => {
errors.push( `${friendlyLogicName} formula for "${nodeName}": ${e}` );
} );
// TODO: check for cyclic dependencies within single expression and between calculations, e.g. triangular calculation dependencies
}
} );
continue;
}

return Promise.all( subTasks );
} ) );
for ( const logicName of [ 'calculate', 'constraint', 'relevant', 'required' ] ){
const logicExpr = bind.getAttribute( logicName );
const calculation = logicName === 'calculate';

} );
if ( logicExpr ) {
const friendlyLogicName = calculation ? 'Calculation' : logicName[ 0 ].toUpperCase() + logicName.substring( 1 );

return Promise.all( tasks );
} )
.catch( e => {
let ers = Array.isArray( e ) ? e : [ e ];
errors = errors.concat( ers );
} )
.then( () => xform.exit() )
.then( () => ( { warnings, errors, version } ) );
try {
await xform.enketoEvaluate( logicExpr, ( calculation ? 'string' : 'boolean' ), path );
}
catch( e ){
errors.push( `${friendlyLogicName} formula for "${nodeName}": ${e}` );
}
// TODO: check for cyclic dependencies within single expression and between calculations, e.g. triangular calculation dependencies
}
}
}

await xform.exit();

return { warnings, errors, version };
};

module.exports = { validate, version };
4 changes: 2 additions & 2 deletions test/spec/xform.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const arrContains = ( arr, reg ) => arr.some( item => item.search( reg ) !== -1

describe( 'XForm', () => {

describe( 'with bind that has no matching primary instance node', () => {
describe( 'with bind that has no matching primary instance node (b)', () => {
const xf = loadXForm( 'bind-not-binding.xml' );

it( 'should return a warning', async() => {
Expand All @@ -20,7 +20,7 @@ describe( 'XForm', () => {
} );
} );

describe( 'with bind that has no matching primary instance node', () => {
describe( 'with bind that has no matching primary instance node (instanceID)', () => {
const xf = loadXForm( 'missing-instanceID.xml' );
it( 'should return a error', async() => {
const result = await validator.validate( xf );
Expand Down

0 comments on commit 0f8df9d

Please sign in to comment.