diff --git a/src/program/ProgramInit.js b/src/program/ProgramInit.js index e363c9f..9d76a69 100644 --- a/src/program/ProgramInit.js +++ b/src/program/ProgramInit.js @@ -56,14 +56,49 @@ module.exports = Class( 'ProgramInit', { const defaults = program.defaults || {}; - // initialize to an array with a single element of the default value - return Promise.resolve( - Object.keys( defaults ).reduce( - ( data, key ) => ( data[ key ] === undefined ) - ? ( data[ key ] = [ defaults[ key ] ], data ) - : data, - doc_data || {} - ) - ); + var data = {}, + groups = program.meta.groups; + + Object.keys( program.groupExclusiveFields ).forEach( function( group, index ) + { + var length = program.groupExclusiveFields[ group ].length; + + while ( length-- ) + { + var field = program.groupExclusiveFields[ group ][ length ], + defaultValue; + + if ( defaults.hasOwnProperty(field) ) + { + defaultValue = defaults[ field ]; + // Initialize with existing document data if any + data[ field ] = doc_data[ field ] ? doc_data[ field ] : []; + + // If no document data, initialize with default value + if ( !doc_data[ field ] ) + { + data[ field ][ 0 ] = defaultValue; + } + + // If min rows on the group is greater than the data + // currently in the bucket, then populate the rest + // of the data with the default data until the + // arrays are the same length + if ( groups.hasOwnProperty( group ) && + data[ field ].length < groups[ group ].min ) + { + var index = data[ field ].length; + + while ( index < groups[ group ].min ) + { + data[ field ][ index ] = defaultValue; + index++; + } + } + } + } + }); + + return Promise.resolve( data ); }, } ); diff --git a/test/program/ProgramInitTest.js b/test/program/ProgramInitTest.js index 581a5c4..fe65914 100644 --- a/test/program/ProgramInitTest.js +++ b/test/program/ProgramInitTest.js @@ -34,6 +34,12 @@ describe( 'ProgramInit', () => { label: "initializes defaults", defaults: { a: "one", b: "two" }, + meta: { + groups: {} + }, + groupExclusiveFields: { + Something: [ "a", "b" ] + }, doc_data: {}, expected: { a: [ "one" ], @@ -43,18 +49,33 @@ describe( 'ProgramInit', () => { label: "does nothing with no data or defaults", defaults: {}, + meta: { + groups: {} + }, + groupExclusiveFields: {}, doc_data: {}, expected: {}, }, { label: "produces empty object given undefined data", defaults: {}, + meta: { + groups: {} + }, + groupExclusiveFields: {}, doc_data: undefined, expected: {}, }, { label: "keeps existing data with defaults", defaults: { foo: "init" }, + meta: { + groups: {} + }, + groupExclusiveFields: { + Something: [ "foo" ], + SomethingElse: [ "bar" ] + }, doc_data: { bar: [ "baz" ] }, expected: { foo: [ "init" ], @@ -64,6 +85,12 @@ describe( 'ProgramInit', () => { label: "keeps existing doc data with no defaults", defaults: {}, + meta: { + groups: {} + }, + groupExclusiveFields: { + Something: [ "foo" ], + }, doc_data: { foo: [ "bar" ] }, expected: { foo: [ "bar" ], @@ -72,12 +99,74 @@ describe( 'ProgramInit', () => { label: "does not overwrite existing data with defaults", defaults: { foo: "init" }, + meta: { + groups: {} + }, + groupExclusiveFields: { + Something: [ "foo" ] + }, doc_data: { foo: [ "bar" ] }, expected: { foo: [ "bar" ], }, }, - ].forEach( ({ label, doc_data, id, defaults, expected }) => + { + label: "does not overwrite existing data with defaults and multiple rows", + defaults: { foo: "init" }, + meta: { + groups: { + Something: { + min: 3 + } + } + }, + groupExclusiveFields: { + Something: [ "foo" ] + }, + doc_data: { foo: [ "bar", "baz", "test" ] }, + expected: { + foo: [ "bar", "baz", "test" ], + }, + }, + { + label: "initializes with default bucket data", + defaults: { foo: "init" }, + meta: { + groups: { + Something: { + min: 5 + } + } + }, + groupExclusiveFields: { + Something: [ "foo" ] + }, + doc_data: {}, + expected: { + foo: [ "init", "init", "init", "init", "init" ], + }, + }, + { + label: "fix missing bucket data values", + defaults: { foo: "init" }, + meta: { + groups: { + Something: { + min: 5 + } + } + }, + groupExclusiveFields: { + Something: [ "foo" ] + }, + doc_data: { + foo: [ "1", "2", "3", "4" ], + }, + expected: { + foo: [ "1", "2", "3", "4", "init" ], + }, + }, + ].forEach( ({ label, doc_data, id, defaults, meta, groupExclusiveFields, expected }) => { it( label, () => { @@ -86,6 +175,8 @@ describe( 'ProgramInit', () => const program = { id: "foo", defaults: defaults, + meta: meta, + groupExclusiveFields : groupExclusiveFields }; return expect( sut.init( program, doc_data ) )