/*! ******************************************************************************
*
* Pentaho Data Integration
*
* Copyright (C) 2002-2016 by Pentaho : http://www.pentaho.com
*
*******************************************************************************
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
package org.pentaho.di.trans.steps.memgroupby;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import org.pentaho.di.core.Const;
import org.pentaho.di.core.KettleEnvironment;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.core.plugins.PluginRegistry;
import org.pentaho.di.core.row.RowMeta;
import org.pentaho.di.core.row.RowMetaInterface;
import org.pentaho.di.core.row.ValueMetaInterface;
import org.pentaho.di.core.row.value.ValueMetaBigNumber;
import org.pentaho.di.core.row.value.ValueMetaBinary;
import org.pentaho.di.core.row.value.ValueMetaBoolean;
import org.pentaho.di.core.row.value.ValueMetaDate;
import org.pentaho.di.core.row.value.ValueMetaInteger;
import org.pentaho.di.core.row.value.ValueMetaInternetAddress;
import org.pentaho.di.core.row.value.ValueMetaNumber;
import org.pentaho.di.core.row.value.ValueMetaString;
import org.pentaho.di.core.row.value.ValueMetaTimestamp;
import org.pentaho.di.core.variables.Variables;
import org.pentaho.di.trans.steps.loadsave.LoadSaveTester;
import org.pentaho.di.trans.steps.loadsave.initializer.InitializerInterface;
import org.pentaho.di.trans.steps.loadsave.validator.ArrayLoadSaveValidator;
import org.pentaho.di.trans.steps.loadsave.validator.FieldLoadSaveValidator;
import org.pentaho.di.trans.steps.loadsave.validator.IntLoadSaveValidator;
import org.pentaho.di.trans.steps.loadsave.validator.PrimitiveIntArrayLoadSaveValidator;
import org.pentaho.di.trans.steps.loadsave.validator.StringLoadSaveValidator;
public class MemoryGroupByMetaTest implements InitializerInterface<MemoryGroupByMeta> {
LoadSaveTester<MemoryGroupByMeta> loadSaveTester;
Class<MemoryGroupByMeta> testMetaClass = MemoryGroupByMeta.class;
@Before
public void setUpLoadSave() throws Exception {
KettleEnvironment.init();
PluginRegistry.init( true );
List<String> attributes =
Arrays.asList( "alwaysGivingBackOneRow", "groupField", "aggregateField", "subjectField", "aggregateType", "valueField" );
FieldLoadSaveValidator<String[]> stringArrayLoadSaveValidator =
new ArrayLoadSaveValidator<String>( new StringLoadSaveValidator(), 5 );
Map<String, FieldLoadSaveValidator<?>> attrValidatorMap = new HashMap<String, FieldLoadSaveValidator<?>>();
attrValidatorMap.put( "groupField", stringArrayLoadSaveValidator );
attrValidatorMap.put( "aggregateField", stringArrayLoadSaveValidator );
attrValidatorMap.put( "subjectField", stringArrayLoadSaveValidator );
attrValidatorMap.put( "valueField", stringArrayLoadSaveValidator );
attrValidatorMap.put( "aggregateType", new PrimitiveIntArrayLoadSaveValidator(
new IntLoadSaveValidator( MemoryGroupByMeta.typeGroupCode.length ), 5 ) );
Map<String, FieldLoadSaveValidator<?>> typeValidatorMap = new HashMap<String, FieldLoadSaveValidator<?>>();
loadSaveTester =
new LoadSaveTester<MemoryGroupByMeta>( testMetaClass, attributes, new ArrayList<String>(), new ArrayList<String>(),
new HashMap<String, String>(), new HashMap<String, String>(), attrValidatorMap, typeValidatorMap, this );
}
// Call the allocate method on the LoadSaveTester meta class
@Override
public void modify( MemoryGroupByMeta someMeta ) {
someMeta.allocate( 5, 5 );
}
@Test
public void testSerialization() throws KettleException {
loadSaveTester.testSerialization();
}
private RowMetaInterface getInputRowMeta() {
RowMetaInterface rm = new RowMeta();
rm.addValueMeta( new ValueMetaString( "myGroupField2" ) );
rm.addValueMeta( new ValueMetaString( "myGroupField1" ) );
rm.addValueMeta( new ValueMetaString( "myString" ) );
rm.addValueMeta( new ValueMetaInteger( "myInteger" ) );
rm.addValueMeta( new ValueMetaNumber( "myNumber" ) );
rm.addValueMeta( new ValueMetaBigNumber( "myBigNumber" ) );
rm.addValueMeta( new ValueMetaBinary( "myBinary" ) );
rm.addValueMeta( new ValueMetaBoolean( "myBoolean" ) );
rm.addValueMeta( new ValueMetaDate( "myDate" ) );
rm.addValueMeta( new ValueMetaTimestamp( "myTimestamp" ) );
rm.addValueMeta( new ValueMetaInternetAddress( "myInternetAddress" ) );
return rm;
}
@Test
public void testGetFields() {
final String stepName = "this step name";
MemoryGroupByMeta meta = new MemoryGroupByMeta();
meta.setDefault();
meta.allocate( 1, 17 );
// Declare input fields
RowMetaInterface rm = getInputRowMeta();
String[] groupFields = new String[2];
groupFields[0] = "myGroupField1";
groupFields[1] = "myGroupField2";
String[] aggregateFields = new String[24];
String[] subjectFields = new String[24];
int[] aggregateTypes = new int[24];
String[] valueFields = new String[24];
subjectFields[0] = "myString";
aggregateTypes[0] = MemoryGroupByMeta.TYPE_GROUP_CONCAT_COMMA;
aggregateFields[0] = "ConcatComma";
valueFields[0] = null;
subjectFields[1] = "myString";
aggregateTypes[1] = MemoryGroupByMeta.TYPE_GROUP_CONCAT_STRING;
aggregateFields[1] = "ConcatString";
valueFields[1] = "|";
subjectFields[2] = "myString";
aggregateTypes[2] = MemoryGroupByMeta.TYPE_GROUP_COUNT_ALL;
aggregateFields[2] = "CountAll";
valueFields[2] = null;
subjectFields[3] = "myString";
aggregateTypes[3] = MemoryGroupByMeta.TYPE_GROUP_COUNT_ANY;
aggregateFields[3] = "CountAny";
valueFields[3] = null;
subjectFields[4] = "myString";
aggregateTypes[4] = MemoryGroupByMeta.TYPE_GROUP_COUNT_DISTINCT;
aggregateFields[4] = "CountDistinct";
valueFields[4] = null;
subjectFields[5] = "myString";
aggregateTypes[5] = MemoryGroupByMeta.TYPE_GROUP_FIRST;
aggregateFields[5] = "First(String)";
valueFields[5] = null;
subjectFields[6] = "myInteger";
aggregateTypes[6] = MemoryGroupByMeta.TYPE_GROUP_FIRST;
aggregateFields[6] = "First(Integer)";
valueFields[6] = null;
subjectFields[7] = "myNumber";
aggregateTypes[7] = MemoryGroupByMeta.TYPE_GROUP_FIRST_INCL_NULL;
aggregateFields[7] = "FirstInclNull(Number)";
valueFields[7] = null;
subjectFields[8] = "myBigNumber";
aggregateTypes[8] = MemoryGroupByMeta.TYPE_GROUP_FIRST_INCL_NULL;
aggregateFields[8] = "FirstInclNull(BigNumber)";
valueFields[8] = null;
subjectFields[9] = "myBinary";
aggregateTypes[9] = MemoryGroupByMeta.TYPE_GROUP_LAST;
aggregateFields[9] = "Last(Binary)";
valueFields[9] = null;
subjectFields[10] = "myBoolean";
aggregateTypes[10] = MemoryGroupByMeta.TYPE_GROUP_LAST;
aggregateFields[10] = "Last(Boolean)";
valueFields[10] = null;
subjectFields[11] = "myDate";
aggregateTypes[11] = MemoryGroupByMeta.TYPE_GROUP_LAST_INCL_NULL;
aggregateFields[11] = "LastInclNull(Date)";
valueFields[11] = null;
subjectFields[12] = "myTimestamp";
aggregateTypes[12] = MemoryGroupByMeta.TYPE_GROUP_LAST_INCL_NULL;
aggregateFields[12] = "LastInclNull(Timestamp)";
valueFields[12] = null;
subjectFields[13] = "myInternetAddress";
aggregateTypes[13] = MemoryGroupByMeta.TYPE_GROUP_MAX;
aggregateFields[13] = "Max(InternetAddress)";
valueFields[13] = null;
subjectFields[14] = "myString";
aggregateTypes[14] = MemoryGroupByMeta.TYPE_GROUP_MAX;
aggregateFields[14] = "Max(String)";
valueFields[14] = null;
subjectFields[15] = "myInteger";
aggregateTypes[15] = MemoryGroupByMeta.TYPE_GROUP_MEDIAN; // Always returns Number
aggregateFields[15] = "Median(Integer)";
valueFields[15] = null;
subjectFields[16] = "myNumber";
aggregateTypes[16] = MemoryGroupByMeta.TYPE_GROUP_MIN;
aggregateFields[16] = "Min(Number)";
valueFields[16] = null;
subjectFields[17] = "myBigNumber";
aggregateTypes[17] = MemoryGroupByMeta.TYPE_GROUP_MIN;
aggregateFields[17] = "Min(BigNumber)";
valueFields[17] = null;
subjectFields[18] = "myBinary";
aggregateTypes[18] = MemoryGroupByMeta.TYPE_GROUP_PERCENTILE;
aggregateFields[18] = "Percentile(Binary)";
valueFields[18] = "0.5";
subjectFields[19] = "myBoolean";
aggregateTypes[19] = MemoryGroupByMeta.TYPE_GROUP_STANDARD_DEVIATION;
aggregateFields[19] = "StandardDeviation(Boolean)";
valueFields[19] = null;
subjectFields[20] = "myDate";
aggregateTypes[20] = MemoryGroupByMeta.TYPE_GROUP_SUM;
aggregateFields[20] = "Sum(Date)";
valueFields[20] = null;
subjectFields[21] = "myInteger";
aggregateTypes[21] = MemoryGroupByMeta.TYPE_GROUP_SUM;
aggregateFields[21] = "Sum(Integer)";
valueFields[21] = null;
subjectFields[22] = "myInteger";
aggregateTypes[22] = MemoryGroupByMeta.TYPE_GROUP_AVERAGE;
aggregateFields[22] = "Average(Integer)";
valueFields[22] = null;
subjectFields[23] = "myDate";
aggregateTypes[23] = MemoryGroupByMeta.TYPE_GROUP_AVERAGE;
aggregateFields[23] = "Average(Date)";
valueFields[23] = null;
meta.setGroupField( groupFields );
meta.setSubjectField( subjectFields );
meta.setAggregateType( aggregateTypes );
meta.setAggregateField( aggregateFields );
meta.setValueField( valueFields );
Variables vars = new Variables();
meta.getFields( rm, stepName, null, null, vars, null, null );
assertNotNull( rm );
assertEquals( 26, rm.size() );
assertTrue( rm.indexOfValue( "myGroupField1" ) >= 0 );
assertEquals( ValueMetaInterface.TYPE_STRING, rm.getValueMeta( rm.indexOfValue( "myGroupField1" ) ).getType() );
assertTrue( rm.indexOfValue( "myGroupField2" ) >= 0 );
assertEquals( ValueMetaInterface.TYPE_STRING, rm.getValueMeta( rm.indexOfValue( "myGroupField2" ) ).getType() );
assertTrue( rm.indexOfValue( "myGroupField2" ) > rm.indexOfValue( "myGroupField1" ) );
assertTrue( rm.indexOfValue( "ConcatComma" ) >= 0 );
assertEquals( ValueMetaInterface.TYPE_STRING, rm.getValueMeta( rm.indexOfValue( "ConcatComma" ) ).getType() );
assertTrue( rm.indexOfValue( "ConcatString" ) >= 0 );
assertEquals( ValueMetaInterface.TYPE_STRING, rm.getValueMeta( rm.indexOfValue( "ConcatString" ) ).getType() );
assertTrue( rm.indexOfValue( "CountAll" ) >= 0 );
assertEquals( ValueMetaInterface.TYPE_INTEGER, rm.getValueMeta( rm.indexOfValue( "CountAll" ) ).getType() );
assertTrue( rm.indexOfValue( "CountAny" ) >= 0 );
assertEquals( ValueMetaInterface.TYPE_INTEGER, rm.getValueMeta( rm.indexOfValue( "CountAny" ) ).getType() );
assertTrue( rm.indexOfValue( "CountDistinct" ) >= 0 );
assertEquals( ValueMetaInterface.TYPE_INTEGER, rm.getValueMeta( rm.indexOfValue( "CountDistinct" ) ).getType() );
assertTrue( rm.indexOfValue( "First(String)" ) >= 0 );
assertEquals( ValueMetaInterface.TYPE_STRING, rm.getValueMeta( rm.indexOfValue( "First(String)" ) ).getType() );
assertTrue( rm.indexOfValue( "First(Integer)" ) >= 0 );
assertEquals( ValueMetaInterface.TYPE_INTEGER, rm.getValueMeta( rm.indexOfValue( "First(Integer)" ) ).getType() );
assertTrue( rm.indexOfValue( "FirstInclNull(Number)" ) >= 0 );
assertEquals( ValueMetaInterface.TYPE_NUMBER, rm.getValueMeta( rm.indexOfValue( "FirstInclNull(Number)" ) ).getType() );
assertTrue( rm.indexOfValue( "FirstInclNull(BigNumber)" ) >= 0 );
assertEquals( ValueMetaInterface.TYPE_BIGNUMBER, rm.getValueMeta( rm.indexOfValue( "FirstInclNull(BigNumber)" ) ).getType() );
assertTrue( rm.indexOfValue( "Last(Binary)" ) >= 0 );
assertEquals( ValueMetaInterface.TYPE_BINARY, rm.getValueMeta( rm.indexOfValue( "Last(Binary)" ) ).getType() );
assertTrue( rm.indexOfValue( "Last(Boolean)" ) >= 0 );
assertEquals( ValueMetaInterface.TYPE_BOOLEAN, rm.getValueMeta( rm.indexOfValue( "Last(Boolean)" ) ).getType() );
assertTrue( rm.indexOfValue( "LastInclNull(Date)" ) >= 0 );
assertEquals( ValueMetaInterface.TYPE_DATE, rm.getValueMeta( rm.indexOfValue( "LastInclNull(Date)" ) ).getType() );
assertTrue( rm.indexOfValue( "LastInclNull(Timestamp)" ) >= 0 );
assertEquals( ValueMetaInterface.TYPE_TIMESTAMP, rm.getValueMeta( rm.indexOfValue( "LastInclNull(Timestamp)" ) ).getType() );
assertTrue( rm.indexOfValue( "Max(InternetAddress)" ) >= 0 );
assertEquals( ValueMetaInterface.TYPE_INET, rm.getValueMeta( rm.indexOfValue( "Max(InternetAddress)" ) ).getType() );
assertTrue( rm.indexOfValue( "Max(String)" ) >= 0 );
assertEquals( ValueMetaInterface.TYPE_STRING, rm.getValueMeta( rm.indexOfValue( "Max(String)" ) ).getType() );
assertTrue( rm.indexOfValue( "Median(Integer)" ) >= 0 );
assertEquals( ValueMetaInterface.TYPE_NUMBER, rm.getValueMeta( rm.indexOfValue( "Median(Integer)" ) ).getType() );
assertTrue( rm.indexOfValue( "Min(Number)" ) >= 0 );
assertEquals( ValueMetaInterface.TYPE_NUMBER, rm.getValueMeta( rm.indexOfValue( "Min(Number)" ) ).getType() );
assertTrue( rm.indexOfValue( "Min(BigNumber)" ) >= 0 );
assertEquals( ValueMetaInterface.TYPE_BIGNUMBER, rm.getValueMeta( rm.indexOfValue( "Min(BigNumber)" ) ).getType() );
assertTrue( rm.indexOfValue( "Percentile(Binary)" ) >= 0 );
assertEquals( ValueMetaInterface.TYPE_NUMBER, rm.getValueMeta( rm.indexOfValue( "Percentile(Binary)" ) ).getType() );
assertTrue( rm.indexOfValue( "StandardDeviation(Boolean)" ) >= 0 );
assertEquals( ValueMetaInterface.TYPE_NUMBER, rm.getValueMeta( rm.indexOfValue( "StandardDeviation(Boolean)" ) ).getType() );
assertTrue( rm.indexOfValue( "Sum(Date)" ) >= 0 );
assertEquals( ValueMetaInterface.TYPE_NUMBER, rm.getValueMeta( rm.indexOfValue( "Sum(Date)" ) ).getType() ); // Force changed to Numeric
assertTrue( rm.indexOfValue( "Sum(Integer)" ) >= 0 );
assertEquals( ValueMetaInterface.TYPE_INTEGER, rm.getValueMeta( rm.indexOfValue( "Sum(Integer)" ) ).getType() );
assertTrue( rm.indexOfValue( "Average(Integer)" ) >= 0 );
assertEquals( ValueMetaInterface.TYPE_INTEGER, rm.getValueMeta( rm.indexOfValue( "Average(Integer)" ) ).getType() );
assertTrue( rm.indexOfValue( "Average(Date)" ) >= 0 );
assertEquals( ValueMetaInterface.TYPE_NUMBER, rm.getValueMeta( rm.indexOfValue( "Average(Date)" ) ).getType() );
// Test Compatibility
rm = getInputRowMeta();
vars.setVariable( Const.KETTLE_COMPATIBILITY_MEMORY_GROUP_BY_SUM_AVERAGE_RETURN_NUMBER_TYPE, "Y" );
meta.getFields( rm, stepName, null, null, vars, null, null );
assertNotNull( rm );
assertEquals( 26, rm.size() );
assertTrue( rm.indexOfValue( "Average(Integer)" ) >= 0 );
assertEquals( ValueMetaInterface.TYPE_NUMBER, rm.getValueMeta( rm.indexOfValue( "Average(Integer)" ) ).getType() );
}
}