From 5ce106710ecd8d13a27314f8b4d0871a5f53dbc2 Mon Sep 17 00:00:00 2001 From: Mike Gerwitz Date: Tue, 28 Jun 2016 08:58:20 -0400 Subject: [PATCH] Add MultiDimension formatter * src/validate/formatter/MultiDimension.js: Added * test/validate/formatter/MultiDimensionTest.js: Added --- src/validate/formatter/MultiDimension.js | 116 ++++++++++++++++++ test/validate/formatter/MultiDimensionTest.js | 109 ++++++++++++++++ 2 files changed, 225 insertions(+) create mode 100644 src/validate/formatter/MultiDimension.js create mode 100644 test/validate/formatter/MultiDimensionTest.js diff --git a/src/validate/formatter/MultiDimension.js b/src/validate/formatter/MultiDimension.js new file mode 100644 index 0000000..e3d2f5c --- /dev/null +++ b/src/validate/formatter/MultiDimension.js @@ -0,0 +1,116 @@ +/** + * Multi-dimensional array formatting + * + * Copyright (C) 2016 LoVullo Associates, Inc. + * + * This file is part of liza. + * + * liza is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +var Trait = require( 'easejs' ).Trait, + ValidatorFormatter = require( '../ValidatorFormatter' ); + + +/** + * Applies supertype for each item in a vector + */ +module.exports = Trait( 'MultiDimension' ) + .implement( ValidatorFormatter ) + .extend( +{ + /** + * Delimiter to combine values + * @type {string} + */ + 'private _delim': '', + + + /** + * Initialize delimiter for parsing and retrieval + * + * DELIM will be used to split during parsing, and will be used to + * join formatted strings during retrieval. + * + * @param {string} delim delimiter + */ + __mixin: function( delim ) + { + this._delim = ''+delim; + }, + + + /** + * Parse each item into a vector + * + * @param {string} data data to parse + * + * @return {Array} vector of data formatted for storage + */ + 'virtual abstract override public parse': function( data ) + { + var split = data.split( this._delim ); + + // maintain ES3 compatibility (no map) + for ( var i = 0; i < split.length; i++ ) + { + split[ i ] = this.__super( split[ i ] ); + } + + return split; + }, + + + /** + * Join formatted vector elements into a delimited string + * + * If DATA is not a vector, it will be treated as though it were a + * vector with a single element `[DATA]'. + * + * If all elements of DATA are the same value, then only that + * value will be returned; there will be no delimiters. This + * might be problematic if #parse is subsequently used, since that + * would change the number of elements in the vector. + * + * @param {Array|string} data vector to parse + * + * @return {string} delimited string + */ + 'virtual abstract override public retrieve': function( data ) + { + // pretend non-arrays are single-element vectors + if ( Object.prototype.toString.call( data ) !== '[object Array]' ) + { + return this.__super( data ); + } + + var parsed = [], + same = true; + + // must maintain ES3 support; no forEach + for ( var i = 0; i < data.length; i++ ) + { + parsed[ i ] = this.__super( data[ i ] ); + + same = same && ( + ( i === 0 ) + || ( parsed[ i - 1 ] === parsed[ i ] ) + ); + } + + return ( same ) + ? parsed[ 0 ] + : parsed.join( this._delim ); + } +} ); diff --git a/test/validate/formatter/MultiDimensionTest.js b/test/validate/formatter/MultiDimensionTest.js new file mode 100644 index 0000000..0f700ac --- /dev/null +++ b/test/validate/formatter/MultiDimensionTest.js @@ -0,0 +1,109 @@ +/** + * Multi-dimensional array formatting test + * + * Copyright (C) 2016 LoVullo Associates, Inc. + * + * This file is part of liza. + * + * liza is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +var Class = require( 'easejs' ).Class, + liza = require( '../../../' ), + formatter = liza.validate.formatter, + Sut = formatter.MultiDimension, + EchoFormatter = formatter.EchoFormatter, + ValidatorFormatter = liza.validate.ValidatorFormatter, + common = require( './common' ), + expect = require( 'chai' ).expect; + +var DummyFormatter = Class.implement( ValidatorFormatter ) + .extend( +{ + 'virtual parse': function( data ) + { + return '+' + data; + }, + + 'virtual retrieve': function( data ) + { + return '-' + data; + }, +} ); + + +describe( 'validate.formatter.MultiDimension', function() +{ + describe( '#parse', function() + { + it( 'splits on delimiter into vector', function() + { + expect( + DummyFormatter.use( Sut( '||' ) )() + .parse( 'foo||bar||baz' ) + ).to.deep.equal( [ '+foo', '+bar', '+baz' ] ); + } ); + + + it( 'produces vector for non-delimited strings', function() + { + expect( + DummyFormatter.use( Sut( '||' ) )() + .parse( 'foo' ) + ).to.deep.equal( [ '+foo' ] ); + } ); + } ); + + + describe( '#retrieve', function() + { + it( 'applies formatting to each element in vector', function() + { + expect( + DummyFormatter.use( Sut( '||' ) )() + .retrieve( [ 'one', 'two', 'three' ] ) + ).to.equal( '-one||-two||-three' ); + } ); + + + it( 'treats scalars as single-element vectors', function() + { + expect( + DummyFormatter.use( Sut( '||' ) )() + .retrieve( 'one' ) + ).to.equal( '-one' ); + } ); + + + describe( 'given identical elements', function() + { + it( 'combines if all elements are identical', function() + { + expect( + DummyFormatter.use( Sut( '||' ) )() + .retrieve( [ 'foo', 'foo', 'foo' ] ) + ).to.equal( '-foo' ); + } ); + + + it( 'does not combine if not all are identical', function() + { + expect( + DummyFormatter.use( Sut( '||' ) )() + .retrieve( [ 'foo', 'foo', 'bar' ] ) + ).to.equal( '-foo||-foo||-bar' ); + } ); + } ); + } ); +} );