From f624710451b5955ee6d96fcc2fdf351dc491cc82 Mon Sep 17 00:00:00 2001 From: Mike Gerwitz Date: Wed, 20 Apr 2016 12:11:17 -0400 Subject: [PATCH] Consider field failure cause when checking fixes This maintains BC with the old string-based system. * src/validate/ValidStateMonitor.js (_getCause): Added. (detectFixes): Consider failure cause if available when checking for fixes. --- src/validate/ValidStateMonitor.js | 58 +++++++++++++++++++------ test/validate/ValidStateMonitorTest.js | 60 ++++++++++++++++++++++++++ 2 files changed, 106 insertions(+), 12 deletions(-) diff --git a/src/validate/ValidStateMonitor.js b/src/validate/ValidStateMonitor.js index cc79c93..d32b7f1 100644 --- a/src/validate/ValidStateMonitor.js +++ b/src/validate/ValidStateMonitor.js @@ -20,7 +20,8 @@ */ var Class = require( 'easejs' ).Class, - EventEmitter = require( 'events' ).EventEmitter; + EventEmitter = require( 'events' ).EventEmitter, + Failure = require( './Failure' ); /** @@ -182,15 +183,7 @@ module.exports = Class( 'ValidStateMonitor' ) for ( var name in past ) { - // we're only interested in detecting fixes on the data that has - // been set - if ( !( data[ name ] ) ) - { - continue; - } - - var field = data[ name ], - past_fail = past[ name ], + var past_fail = past[ name ], fail = failures[ name ]; // we must check each individual index because it is possible that @@ -198,17 +191,29 @@ module.exports = Class( 'ValidStateMonitor' ) // this because this is treated as a hash table, not an array) for ( var i in past_fail ) { + var cause = this._getCause( name, i, past_fail ), + cause_name = cause[ 0 ], + cause_index = cause[ 1 ], + field = data[ cause_name ]; + + // if datum is unchanged, ignore it + if ( field === undefined ) + { + continue; + } + // to be marked as fixed, there must both me no failure and // there must be data for this index for the field in question // (if the field wasn't touched, then of course there's no // failure!) if ( ( fail === undefined ) - || ( !( fail[ i ] ) && ( field[ i ] !== undefined ) ) + || ( !( fail[ cause_index ] ) + && ( field[ cause_index ] !== undefined ) ) ) { // looks like it has been resolved ( fixed[ name ] = fixed[ name ] || [] )[ i ] = - data[ name ][ i ]; + field[ cause_index ] has_fixed = true; @@ -220,5 +225,34 @@ module.exports = Class( 'ValidStateMonitor' ) return ( has_fixed ) ? fixed : null; + }, + + + /** + * Produces name and index of the field causing a failure, or NAME + * and INDEX if unavailable + * + * This maintains backwards-compatibility for the old string-based + * system. + * + * @param {string} name field name + * @param {number} index field index + * + * @param {Array.} past_fail previous failure + * + * @return {Array} name/index tuple of cause field + */ + 'private _getCause': function( name, index, past_fail ) + { + var failure = past_fail[ index ]; + + if ( Class.isA( Failure, failure ) ) + { + var cause = failure.getCause(); + + return [ cause.getName(), cause.getIndex() ]; + } + + return [ name, index ]; } } ); diff --git a/test/validate/ValidStateMonitorTest.js b/test/validate/ValidStateMonitorTest.js index 6ce9dcd..084adf7 100644 --- a/test/validate/ValidStateMonitorTest.js +++ b/test/validate/ValidStateMonitorTest.js @@ -204,6 +204,66 @@ describe( 'ValidStateMonitor', function() expect( called ).to.equal( 1 ); } ); + + + describe( 'given a cause', function() + { + it( 'considers when recognizing fix', function( done ) + { + // same index + var data = { cause: [ 'bar' ] }, + field = Field( 'foo', 0 ), + cause = Field( 'cause', 0 ), + fail = Failure( field, 'reason', cause ); + + Sut() + .on( 'fix', function( fixed ) + { + expect( fixed ) + .to.deep.equal( { foo: [ 'bar' ] } ); + + done(); + } ) + .update( data, { foo: [ fail ] } ) + .update( data, {} ); + } ); + + + it( 'considers different cause index', function( done ) + { + // different index + var data = { cause: [ undefined, 'bar' ] }, + field = Field( 'foo', 0 ), + cause = Field( 'cause', 1 ), + fail = Failure( field, 'reason', cause ); + + Sut() + .on( 'fix', function( fixed ) + { + expect( fixed ) + .to.deep.equal( { foo: [ 'bar' ] } ); + + done(); + } ) + .update( data, { foo: [ fail ] } ) + .update( data, {} ); + } ); + + + it( 'recognizes non-fix', function() + { + // no cause data + var data = { noncause: [ undefined, 'bar' ] }, + field = Field( 'foo', 0 ), + cause = Field( 'cause', 1 ), + fail = Failure( field, 'reason', cause ); + + Sut() + .on( 'fix', nocall ) + .update( data, { foo: [ fail ] } ) + .update( data, {} ); + } ); + } ); } );