/*! ****************************************************************************** * * Pentaho Data Integration * * Copyright (C) 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.ui.trans.steps.fileinput.text; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.OutputStream; import java.lang.reflect.Field; import java.util.Collections; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.reflect.FieldUtils; import org.eclipse.swt.widgets.Shell; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import org.pentaho.di.core.BlockingRowSet; import org.pentaho.di.core.KettleEnvironment; import org.pentaho.di.core.Props; import org.pentaho.di.core.RowSet; import org.pentaho.di.core.fileinput.FileInputList; import org.pentaho.di.core.playlist.FilePlayListAll; import org.pentaho.di.core.row.RowMeta; import org.pentaho.di.core.row.value.ValueMetaString; import org.pentaho.di.core.variables.Variables; import org.pentaho.di.core.vfs.KettleVFS; import org.pentaho.di.trans.TransMeta; import org.pentaho.di.trans.step.errorhandling.FileErrorHandler; import org.pentaho.di.trans.steps.StepMockUtil; import org.pentaho.di.trans.steps.fileinput.text.TextFileFilter; import org.pentaho.di.trans.steps.fileinput.text.TextFileFilterProcessor; import org.pentaho.di.trans.steps.fileinput.text.TextFileInput; import org.pentaho.di.trans.steps.fileinput.text.TextFileInputData; import org.pentaho.di.trans.steps.fileinput.BaseFileInputField; import org.pentaho.di.trans.steps.fileinput.text.TextFileInputMeta; import org.pentaho.di.ui.core.PropsUI; import org.pentaho.di.ui.core.widget.TableView; /** * Created by jadametz on 9/9/15. */ public class TextFileInputDialogTest { private static boolean changedPropsUi; @BeforeClass public static void initKettle() throws Exception { KettleEnvironment.init(); } @BeforeClass public static void hackPropsUi() throws Exception { Field props = getPropsField(); if ( props == null ) { throw new IllegalStateException( "Cannot find 'props' field in " + Props.class.getName() ); } Object value = FieldUtils.readStaticField( props, true ); if ( value == null ) { PropsUI mock = mock( PropsUI.class ); FieldUtils.writeStaticField( props, mock, true ); changedPropsUi = true; } else { changedPropsUi = false; } } @AfterClass public static void restoreNullInPropsUi() throws Exception { if ( changedPropsUi ) { Field props = getPropsField(); FieldUtils.writeStaticField( props, null, true ); } } private static Field getPropsField() { return FieldUtils.getDeclaredField( Props.class, "props", true ); } @Test public void testMinimalWidth_PDI_14253() throws Exception { final String virtualFile = "ram://pdi-14253.txt"; KettleVFS.getFileObject( virtualFile ).createFile(); final String content = "r1c1, r1c2\nr2c1 , r2c2 "; ByteArrayOutputStream bos = new ByteArrayOutputStream(); bos.write( content.getBytes() ); OutputStream os = KettleVFS.getFileObject( virtualFile ).getContent().getOutputStream(); IOUtils.copy( new ByteArrayInputStream( bos.toByteArray() ), os ); os.close(); TextFileInputMeta meta = new TextFileInputMeta(); meta.content.lineWrapped = false; meta.inputFiles.inputFields = new BaseFileInputField[]{ new BaseFileInputField( "col1", -1, -1 ), new BaseFileInputField( "col2", -1, -1 ) }; meta.content.fileCompression = "None"; meta.content.fileType = "CSV"; meta.content.header = false; meta.content.nrHeaderLines = -1; meta.content.footer = false; meta.content.nrFooterLines = -1; TextFileInputData data = new TextFileInputData(); data.files = new FileInputList(); data.files.addFile( KettleVFS.getFileObject( virtualFile ) ); data.outputRowMeta = new RowMeta(); data.outputRowMeta.addValueMeta( new ValueMetaString( "col1" ) ); data.outputRowMeta.addValueMeta( new ValueMetaString( "col2" ) ); data.dataErrorLineHandler = mock( FileErrorHandler.class ); data.fileFormatType = TextFileInputMeta.FILE_FORMAT_UNIX; data.separator = ","; data.filterProcessor = new TextFileFilterProcessor( new TextFileFilter[0], new Variables() { } ); data.filePlayList = new FilePlayListAll(); TextFileInputDialog dialog = new TextFileInputDialog( mock( Shell.class ), meta, mock( TransMeta.class ), "TFIMinimalWidthTest" ); TableView tv = mock( TableView.class ); when( tv.nrNonEmpty() ).thenReturn( 0 ); // click the Minimal width button dialog.setMinimalWidth( tv ); RowSet output = new BlockingRowSet( 5 ); TextFileInput input = StepMockUtil.getStep( TextFileInput.class, TextFileInputMeta.class, "test" ); input.setOutputRowSets( Collections.singletonList( output ) ); while ( input.processRow( meta, data ) ) { // wait until the step completes executing } Object[] row1 = output.getRowImmediate(); assertRow( row1, "r1c1", "r1c2" ); Object[] row2 = output.getRowImmediate(); assertRow( row2, "r2c1", "r2c2" ); KettleVFS.getFileObject( virtualFile ).delete(); } private static void assertRow( Object[] row, Object... values ) { assertNotNull( row ); assertTrue( String.format( "%d < %d", row.length, values.length ), row.length >= values.length ); int i = 0; while ( i < values.length ) { assertEquals( values[ i ], row[ i ] ); i++; } while ( i < row.length ) { assertNull( row[ i ] ); i++; } } }