/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2002-2011, Open Source Geospatial Foundation (OSGeo) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library 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. */ package org.geotools.data.efeature.tests.unit.conditions; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.query.conditions.Condition; import org.geotools.data.efeature.internal.EFeatureLogFormatter; import org.geotools.data.efeature.tests.unit.AbstractEFeatureTest; import org.junit.BeforeClass; import org.junit.Test; import org.opengis.filter.Filter; /** * @author kengu - 14. juni 2011 * */ public abstract class AbstractEAttributeFilterTest<E extends EObject> extends AbstractEFeatureTest { /** * Flag telling {@link Values#getValue(int)} to return all values */ public static final int ALL = Values.ALL; // ----------------------------------------------------- // Test members // ----------------------------------------------------- /** * Cached {@link Filter} instance */ private Condition eCondition; /** * Cached {@link EObject} fixture instance */ private E eFixture; // ----------------------------------------------------- // Constructors // ----------------------------------------------------- public AbstractEAttributeFilterTest(String name) { super(name); } // ----------------------------------------------------- // Test configuration methods // ----------------------------------------------------- @Override @BeforeClass protected final void setUp() throws Exception { // // Notify test start // trace("===> Begin : " + getName() + "[" + getValueCount() + " values]"); //$NON-NLS-1$ EFeatureLogFormatter.setMinimal(); // // Create fixture // eFixture = createFixture(); } @Override protected void tearDown() throws Exception { try { // // Dispose fixture and condition // eFixture = null; eCondition = null; } finally { trace("===> End : " + getName(), TIME_TOTAL); //$NON-NLS-1$ EFeatureLogFormatter.setStandard(); } } // ----------------------------------------------------- // Tests // ----------------------------------------------------- @Test public void testCondition() throws Exception { // // Initialized // int passed = 0; // // Get number of values and passes // int passes = getPassCount(); int values = getValueCount(); // // Sanity check // if(passes==0) fail("No passes defined for " + getOperationName()); if(values==0) fail("No values defined for " + getOperationName()); // // Loop over all values // for(int value=0; value<values; value++) { // // Is current value and operand of given operation? // if(isOperand(value)) { // // Assert condition given number of passes // for(int pass=0; pass<passes; pass++) { // // Update fixture // updateFixture(eFixture, value, pass); // // Create condition // eCondition = createCondition(value, pass); // // Assert condition // assertCondition(failure(value, pass), expect(pass)); // // Increment "test passed" count // passed++; } } } // // Sanity check // if(passed==0) fail("No tests defined for " + getOperationName()); } // ----------------------------------------------------- // Implementation methods // ----------------------------------------------------- protected abstract E createFixture() throws Exception; protected abstract int getPassCount(); protected abstract int getValueCount(); protected abstract String getType(int value); protected abstract String getOperationName(); protected abstract boolean isOperand(int value); protected abstract boolean expect(int pass); protected abstract Object getFilter(int value, int pass); protected abstract Object getTest(int value, int pass); protected abstract void updateFixture(E eFixture, int value, int pass) throws Exception; protected abstract Condition createCondition(int value, int pass) throws Exception; // ----------------------------------------------------- // Helper methods // ----------------------------------------------------- protected void assertCondition(String message, boolean expected) { assertEquals(message, expected, eCondition.isSatisfied(eFixture)); } protected final String failure(int value, int pass) { return "Condition [" + getType(value) + "] " + toString(getTest(value, pass)) + " " + getOperationName() + " " + toString(getFilter(value, pass)) + " not satisfied"; } protected static final String nameOf(int operation, Field[] operations) throws IllegalArgumentException { try { // // Compare values // for (Field it : operations) { // // Check value // if (Modifier.isStatic(it.getModifiers()) && int.class.isAssignableFrom(it.getType())) { // // Found? // if (it.getInt(null) == operation) { // // Found // return it.getName(); } } } // // Failure // fail("Operation " + operation + " not found"); } catch (IllegalAccessException e) { // // Failure // fail(e.getMessage()); } // // Not found // return null; } protected static final int indexOf(int operation) { String s = Integer.toBinaryString(operation); int index = s.lastIndexOf("0"); return index==-1 ? 0 : index; } protected static final String toString(Object value) { if(value instanceof Collection) { value = Arrays.toString(((Collection<?>)value).toArray()); } return String.valueOf(value); } protected static final boolean isFlag(int pattern, int flag) { return (pattern & flag) == flag; } // ----------------------------------------------------- // Helper classes // ----------------------------------------------------- protected final static class Tests { final String name; final AbstractEAttributeFilterTest.Pass[] passes; public Tests(String name, AbstractEAttributeFilterTest.Pass...passes) { this.passes = passes; this.name = name; } public Tests(String name, Tests...tests) { List<AbstractEAttributeFilterTest.Pass> passes = new ArrayList<AbstractEAttributeFilterTest.Pass>(); for(Tests it : tests) { passes.addAll(Arrays.asList(it.passes)); } this.passes = passes.toArray(new AbstractEAttributeFilterTest.Pass[]{}); this.name = name; } } protected final static class Pass { final int test; final int[] filter; final boolean success; public Pass(boolean success, int test, int... filter) { this.test = test; this.filter = filter; this.success = success; } } protected final static class Values { /** * Flag telling {@link getValue(int)} to return all values */ public static final int ALL = -1; final Class<?> type; final Object[] values; final int operations; public Values(int operations, Class<?> type, Object...values) { this.type = type; int count = values.length; this.values = new Object[count]; if(count>0) System.arraycopy(values, 0, this.values, 0, count); this.operations = operations; } public Class<?> getType() { return type; } public Object getValue(int index) { // // Return all values or value at given index only ? // return index < 0 ? Arrays.asList(values) : values[index]; } public Object getFilter(Pass pass) { // // Get filter value indices // int[] filter = pass.filter; // // Has no filter value? // if(filter.length==0) return null; // // Single value? // if(filter.length==1 || filter[0]<0) { return getValue(filter[0]); } // // Collect values from indices // List<Object> list = new ArrayList<Object>(filter.length); for(int i : filter) { list.add(getValue(i)); } // // Finished // return list; } public Object getTest(Pass pass) { return getValue(pass.test); } public boolean isOperand(int operation) { return (operations & operation) == operation; } @Override public String toString() { return type.getSimpleName() + " " + Arrays.toString(values); } } }