/** * DataCleaner (community edition) * Copyright (C) 2014 Neopost - Customer Information Management * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU * Lesser General Public License, as published by the Free Software Foundation. * * 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 Lesser General Public License * for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this distribution; if not, write to: * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ package org.datacleaner.widgets.properties; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.metamodel.schema.ColumnType; import org.apache.metamodel.schema.MutableColumn; import org.apache.metamodel.schema.MutableTable; import org.datacleaner.api.InputColumn; import org.datacleaner.configuration.DataCleanerConfigurationImpl; import org.datacleaner.data.MutableInputColumn; import org.datacleaner.descriptors.ConfiguredPropertyDescriptor; import org.datacleaner.descriptors.Descriptors; import org.datacleaner.descriptors.TransformerDescriptor; import org.datacleaner.job.builder.AnalysisJobBuilder; import org.datacleaner.job.builder.TransformerChangeListener; import org.datacleaner.job.builder.TransformerComponentBuilder; import org.datacleaner.widgets.DCCheckBox; import org.datacleaner.widgets.SourceColumnComboBox; import cern.colt.Arrays; import junit.framework.TestCase; public class MultipleMappedColumnsPropertyWidgetTest extends TestCase { private ConfiguredPropertyDescriptor inputColumnsProperty; private ConfiguredPropertyDescriptor mappedColumnsProperty; private AnalysisJobBuilder ajb; private MultipleMappedColumnsPropertyWidget propertyWidget; private MultipleMappedColumnsPropertyWidget.MappedColumnNamesPropertyWidget mappedColumnNamesPropertyWidget; private TransformerComponentBuilder<MockMultipleMappedColumnsTransformer> tjb; private InputColumn<?> source1; private InputColumn<?> source2; private InputColumn<?> source3; private InputColumn<?> source4; private InputColumn<?> source5; @Override protected void setUp() throws Exception { super.setUp(); final TransformerDescriptor<MockMultipleMappedColumnsTransformer> descriptor = Descriptors.ofTransformer(MockMultipleMappedColumnsTransformer.class); inputColumnsProperty = descriptor.getConfiguredProperty("Input columns"); assertNotNull(inputColumnsProperty); mappedColumnsProperty = descriptor.getConfiguredProperty("Column names"); assertNotNull(mappedColumnsProperty); ajb = new AnalysisJobBuilder(new DataCleanerConfigurationImpl()); ajb.addSourceColumns(new MutableColumn("source1").setType(ColumnType.VARCHAR), new MutableColumn("source2").setType(ColumnType.INTEGER), new MutableColumn("source3").setType(ColumnType.VARCHAR), new MutableColumn("source4").setType(ColumnType.VARCHAR), new MutableColumn("source5").setType(ColumnType.VARCHAR)); source1 = ajb.getSourceColumnByName("source1"); source2 = ajb.getSourceColumnByName("source2"); source3 = ajb.getSourceColumnByName("source3"); source4 = ajb.getSourceColumnByName("source4"); source5 = ajb.getSourceColumnByName("source5"); tjb = ajb.addTransformer(MockMultipleMappedColumnsTransformer.class); propertyWidget = new MultipleMappedColumnsPropertyWidget(tjb, inputColumnsProperty, mappedColumnsProperty); mappedColumnNamesPropertyWidget = propertyWidget.getMappedColumnNamesPropertyWidget(); final PropertyWidgetCollection propertyWidgetCollection = new PropertyWidgetCollection(tjb); propertyWidgetCollection.registerWidget(inputColumnsProperty, propertyWidget); propertyWidgetCollection.registerWidget(mappedColumnsProperty, mappedColumnNamesPropertyWidget); tjb.addChangeListener(new TransformerChangeListener() { @Override public void onRequirementChanged(final TransformerComponentBuilder<?> arg0) { } @Override public void onRemove(final TransformerComponentBuilder<?> arg0) { } @Override public void onOutputChanged(final TransformerComponentBuilder<?> arg0, final List<MutableInputColumn<?>> arg1) { } @Override public void onConfigurationChanged(final TransformerComponentBuilder<?> tjb) { propertyWidgetCollection.onConfigurationChanged(); } @Override public void onAdd(final TransformerComponentBuilder<?> arg0) { } }); propertyWidget.initialize(null); mappedColumnNamesPropertyWidget.initialize(null); } public void testRemoveColumnRemovesString() throws Exception { final MutableTable table = new MutableTable(); table.addColumn(new MutableColumn("source1").setTable(table)); table.addColumn(new MutableColumn("source2").setTable(table)); table.addColumn(new MutableColumn("source3").setTable(table)); table.addColumn(new MutableColumn("source4").setTable(table)); table.addColumn(new MutableColumn("source5").setTable(table)); propertyWidget.setTable(table); propertyWidget.selectAll(); // all string columns selected now assertEquals(4, propertyWidget.getValue().length); assertEquals( "[MetaModelInputColumn[source1], MetaModelInputColumn[source3], MetaModelInputColumn[source4], " + "MetaModelInputColumn[source5]]", Arrays.toString(propertyWidget.getValue())); assertEquals("[source1, source3, source4, source5]", Arrays.toString(mappedColumnNamesPropertyWidget.getValue())); final Map<InputColumn<?>, DCCheckBox<InputColumn<?>>> checkBoxes = propertyWidget.getCheckBoxes(); // uncheck one of the columns (remove it) checkBoxes.get(source4).doClick(); assertEquals("[MetaModelInputColumn[source1], MetaModelInputColumn[source3], MetaModelInputColumn[source5]]", Arrays.toString(propertyWidget.getValue())); assertEquals("[source1, source3, source5]", Arrays.toString(mappedColumnNamesPropertyWidget.getValue())); } public void testSetTableAndThenSelectAll() throws Exception { final MutableTable table = new MutableTable(); table.addColumn(new MutableColumn("source1").setTable(table)); table.addColumn(new MutableColumn("source3").setTable(table)); table.addColumn(new MutableColumn("foo").setTable(table)); table.addColumn(new MutableColumn("bar").setTable(table)); propertyWidget.setTable(table); propertyWidget.selectAll(); final InputColumn<?>[] value = propertyWidget.getValue(); assertEquals(4, value.length); final Map<InputColumn<?>, SourceColumnComboBox> mappedColumnComboBoxes = propertyWidget.getMappedColumnComboBoxes(); for (final SourceColumnComboBox comboBox : mappedColumnComboBoxes.values()) { assertTrue(comboBox.isVisible()); } } public void testCustomMutableTable() throws Exception { final Map<InputColumn<?>, DCCheckBox<InputColumn<?>>> checkBoxes = propertyWidget.getCheckBoxes(); final Map<InputColumn<?>, SourceColumnComboBox> comboBoxes = propertyWidget.getMappedColumnComboBoxes(); // initial state should be that source1 and source3 are available, but // not checked final Set<InputColumn<?>> inputColumns = checkBoxes.keySet(); assertEquals(4, inputColumns.size()); assertTrue(inputColumns.contains(source1)); assertFalse(inputColumns.contains(source2)); assertTrue(inputColumns.contains(source3)); assertTrue(inputColumns.contains(source4)); assertTrue(inputColumns.contains(source5)); assertFalse(checkBoxes.get(source1).isSelected()); assertFalse(comboBoxes.get(source1).isVisible()); assertFalse(checkBoxes.get(source3).isSelected()); assertFalse(comboBoxes.get(source3).isVisible()); assertFalse(checkBoxes.get(source4).isSelected()); assertFalse(comboBoxes.get(source4).isVisible()); assertFalse(checkBoxes.get(source5).isSelected()); assertFalse(comboBoxes.get(source5).isVisible()); // check source3's checkbox checkBoxes.get(source3).doClick(); assertFalse(checkBoxes.get(source1).isSelected()); assertFalse(comboBoxes.get(source1).isVisible()); assertTrue(checkBoxes.get(source3).isSelected()); assertTrue(comboBoxes.get(source3).isVisible()); assertFalse(checkBoxes.get(source4).isSelected()); assertFalse(comboBoxes.get(source4).isVisible()); assertFalse(checkBoxes.get(source5).isSelected()); assertFalse(comboBoxes.get(source5).isVisible()); assertEquals(null, comboBoxes.get(source3).getSelectedItem()); assertEquals(0, comboBoxes.get(source3).getModel().getSize()); assertEquals("[MetaModelInputColumn[source3]]", Arrays.toString(propertyWidget.getValue())); // set a table on the widget propertyWidget.setTable( new MutableTable("some_table").addColumn(new MutableColumn("foo")).addColumn(new MutableColumn("bar"))); assertEquals(null, comboBoxes.get(source3).getSelectedItem()); assertEquals(3, comboBoxes.get(source3).getModel().getSize()); assertEquals(null, comboBoxes.get(source3).getModel().getElementAt(0)); assertEquals("Column[name=foo,columnNumber=0,type=null,nullable=null,nativeType=null,columnSize=null]", comboBoxes.get(source3).getModel().getElementAt(1).toString()); assertEquals("Column[name=bar,columnNumber=0,type=null,nullable=null,nativeType=null,columnSize=null]", comboBoxes.get(source3).getModel().getElementAt(2).toString()); assertEquals("[MetaModelInputColumn[source3]]", Arrays.toString(propertyWidget.getValue())); // make a combo box selection comboBoxes.get(source3).setSelectedIndex(1); assertEquals("foo", comboBoxes.get(source3).getSelectedItem().getName()); // now the values should be non-empty assertEquals(1, propertyWidget.getValue().length); assertEquals("[MetaModelInputColumn[source3]]", Arrays.toString(propertyWidget.getValue())); assertEquals("[foo]", Arrays.toString(mappedColumnNamesPropertyWidget.getValue())); // check source4's combo checkBoxes.get(source5).doClick(); assertFalse(checkBoxes.get(source1).isSelected()); assertFalse(comboBoxes.get(source1).isVisible()); assertTrue(checkBoxes.get(source3).isSelected()); assertTrue(comboBoxes.get(source3).isVisible()); assertFalse(checkBoxes.get(source4).isSelected()); assertFalse(comboBoxes.get(source4).isVisible()); assertTrue(checkBoxes.get(source5).isSelected()); assertTrue(comboBoxes.get(source5).isVisible()); assertEquals(3, comboBoxes.get(source3).getModel().getSize()); assertEquals(3, comboBoxes.get(source5).getModel().getSize()); assertEquals("[MetaModelInputColumn[source3], MetaModelInputColumn[source5]]", Arrays.toString(propertyWidget.getValue())); assertEquals("[foo, null]", Arrays.toString(mappedColumnNamesPropertyWidget.getValue())); // make a combo box selection comboBoxes.get(source5).setSelectedIndex(2); assertEquals("foo", comboBoxes.get(source3).getSelectedItem().getName()); assertEquals("bar", comboBoxes.get(source5).getSelectedItem().getName()); // now there should be 2 values assertEquals(2, propertyWidget.getValue().length); assertEquals("[MetaModelInputColumn[source3], MetaModelInputColumn[source5]]", Arrays.toString(propertyWidget.getValue())); assertEquals("[foo, bar]", Arrays.toString(mappedColumnNamesPropertyWidget.getValue())); // now select source4 - it's inbetween source3 and source5 and that // presents a special challenge to also add the "null" in mapped column // names inbetween "foo" and "bar". checkBoxes.get(source4).doClick(); assertEquals("[MetaModelInputColumn[source3], MetaModelInputColumn[source4], MetaModelInputColumn[source5]]", Arrays.toString(propertyWidget.getValue())); assertEquals("[foo, null, bar]", Arrays.toString(mappedColumnNamesPropertyWidget.getValue())); } }