/*! ****************************************************************************** * * Pentaho Data Integration * * Copyright (C) 2002-2013 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.scriptvalues_mod; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.junit.Test; import org.pentaho.di.core.CheckResultInterface; import org.pentaho.di.core.KettleEnvironment; import org.pentaho.di.core.RowMetaAndData; import org.pentaho.di.core.exception.KettleException; import org.pentaho.di.core.plugins.PluginRegistry; import org.pentaho.di.core.plugins.StepPluginType; import org.pentaho.di.core.row.ValueMetaInterface; import org.pentaho.di.trans.TransHopMeta; import org.pentaho.di.trans.TransMeta; import org.pentaho.di.trans.step.StepMeta; import org.pentaho.di.trans.steps.dummytrans.DummyTransMeta; import org.pentaho.di.trans.steps.injector.InjectorMeta; /** * Tests setting the optimization level of ScriptValuesMetaMod. This unit test will call the ScriptValuesMetaMod.check() * to test the setting. * * This class depends on JavaScriptSpecialTest for the creation of test data. * * The java script optimization is described here: https://developer.mozilla.org/en/Rhino_Optimization * * If Rhino's error message is changed in future releases then this unit test will break. In that case * RANGE_ERROR_MESSAGE_PREFIX will have to be modified accordingly. * * @author sflatley */ public class OptimizationLevelTest { /** * The error message that Rhino will give when an out or range optimization level is set will start with this. * * If we update Ketle with a version of Rhino */ private static final String RANGE_ERROR_MESSAGE_PREFIX = "Optimization level outside [-1..9]"; /** * Returns a true of the list of CheckResultInterface contains a message that starts with RANGE_ERROR_MESSAGE_PREFIX. * * @param checkResultInterfaces * @param thisString * @return boolean */ private boolean containsErrorMessage( List<CheckResultInterface> checkResultInterfaces ) { for ( CheckResultInterface checkResultInterface : checkResultInterfaces ) { if ( checkResultInterface.getText().startsWith( RANGE_ERROR_MESSAGE_PREFIX ) ) { return true; } } return false; } /** * Runs a test for valid values a a few invalid ones. */ @Test public void testOptimizationLevelminus1Through9() { // positive tests test( "-1", false ); test( "0", false ); test( "1", false ); test( "2", false ); test( "3", false ); test( "4", false ); test( "5", false ); test( "6", false ); test( "7", false ); test( "8", false ); test( "9", false ); // negative tests test( "-9", true ); test( "10", true ); } /** * Performs the JUnit assertEquals for the passed optimization level. The return value of testOptimizationLevel is * asserted with containsErrorMessage. * * @param optimizationLevel * the optimization level to test * @param containsErrorMessage * True if the check contains the error message, false if not. */ private void test( String optimizationLevel, boolean containsErrorMessage ) { try { List<CheckResultInterface> remarks = testOptimizationLevel( optimizationLevel ); assertEquals( containsErrorMessage( remarks ), containsErrorMessage ); } catch ( KettleException ke ) { ke.printStackTrace(); fail( ke.getMessage() ); } } /** * Creates the transformation needed to test the java script step with an optimization level set. * * @param optimizationLevel * @return * @throws KettleException */ private List<CheckResultInterface> testOptimizationLevel( String optimizationLevel ) throws KettleException { KettleEnvironment.init(); // Create a new transformation... TransMeta transMeta = new TransMeta(); transMeta.setName( "Test optimization level exception handling" ); PluginRegistry registry = PluginRegistry.getInstance(); // create an injector step.../ String injectorStepname = "injector step"; InjectorMeta im = new InjectorMeta(); // Set the information of the injector. String injectorPid = registry.getPluginId( StepPluginType.class, im ); StepMeta injectorStep = new StepMeta( injectorPid, injectorStepname, im ); transMeta.addStep( injectorStep ); // Create a javascript step String javaScriptStepname = "javascript step"; // Create the meta and populate ScriptValuesMetaMod scriptValuesMetaMod = new ScriptValuesMetaMod(); ScriptValuesScript[] js = new ScriptValuesScript[] { new ScriptValuesScript( ScriptValuesScript.TRANSFORM_SCRIPT, "script", "var str = string;\n" + "var bool = LuhnCheck(str);" ) }; scriptValuesMetaMod.setJSScripts( js ); scriptValuesMetaMod.setFieldname( new String[] { "bool" } ); scriptValuesMetaMod.setRename( new String[] { "" } ); scriptValuesMetaMod.setType( new int[] { ValueMetaInterface.TYPE_BOOLEAN } ); scriptValuesMetaMod.setLength( new int[] { -1 } ); scriptValuesMetaMod.setPrecision( new int[] { -1 } ); scriptValuesMetaMod.setReplace( new boolean[] { false } ); scriptValuesMetaMod.setCompatible( false ); scriptValuesMetaMod.setOptimizationLevel( optimizationLevel ); // Create the step meta String javaScriptStepPid = registry.getPluginId( StepPluginType.class, scriptValuesMetaMod ); StepMeta javaScriptStep = new StepMeta( javaScriptStepPid, javaScriptStepname, scriptValuesMetaMod ); // Create a dummy step String dummyStepname = "dummy step"; DummyTransMeta dm = new DummyTransMeta(); String dummyPid = registry.getPluginId( StepPluginType.class, dm ); StepMeta dummyStep = new StepMeta( dummyPid, dummyStepname, dm ); transMeta.addStep( dummyStep ); // hop the steps that were created TransHopMeta hi2 = new TransHopMeta( javaScriptStep, dummyStep ); transMeta.addTransHop( hi2 ); // We use an existing test that creates data: we'll use that data here JavaScriptSpecialTest javaScriptSpecialTest = new JavaScriptSpecialTest(); List<RowMetaAndData> inputList = javaScriptSpecialTest.createData1(); // RowMetaInterface rowMetaInterface = null; // This is the collection of error messages that may be generated // and other things that the check method will need List<CheckResultInterface> remarks = new ArrayList<CheckResultInterface>(); String[] input = new String[] { injectorStepname }; String[] output = new String[] {}; // We get the row meta and data.... Iterator<RowMetaAndData> it = inputList.iterator(); if ( it.hasNext() ) { RowMetaAndData rowMetaAndData = it.next(); // .... and then call the scriptValuesMetaMod's check method scriptValuesMetaMod.check( remarks, transMeta, javaScriptStep, rowMetaAndData.getRowMeta(), input, output, null, transMeta, null, null ); } else { fail( "No data in the inputList" ); } // we then return the remarks made by scriptValuesMetaMod.check(....); return remarks; } }