sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1454594 - in /sis/branches/JDK7/sis-utility/src: main/java/org/apache/sis/internal/converter/ test/java/org/apache/sis/internal/converter/ test/java/org/apache/sis/test/suite/
Date Fri, 08 Mar 2013 21:48:34 GMT
Author: desruisseaux
Date: Fri Mar  8 21:48:34 2013
New Revision: 1454594

URL: http://svn.apache.org/r1454594
Log:
Added FallbackConverterTest. This test needed the StringConverter provided in the previous
commit.

Added:
    sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/
    sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/FallbackConverterTest.java
  (with props)
Modified:
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/FallbackConverter.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/StringConverter.java
  (props changed)
    sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/FallbackConverter.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/FallbackConverter.java?rev=1454594&r1=1454593&r2=1454594&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/FallbackConverter.java
[UTF-8] (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/FallbackConverter.java
[UTF-8] Fri Mar  8 21:48:34 2013
@@ -327,6 +327,17 @@ final class FallbackConverter<S,T> exten
     }
 
     /**
+     * Returns the primary or fallback converter.
+     *
+     * @param asPrimary {@code true} for the primary branch, or {@code false} for the fallback
branch.
+     * @return the requested converter.
+     */
+    final ObjectConverter<S,? extends T> getConverter(final boolean asPrimary) {
+        assert Thread.holdsLock(this);
+        return asPrimary ? primary : fallback;
+    }
+
+    /**
      * Returns the base type of source objects.
      */
     @Override

Propchange: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/StringConverter.java
------------------------------------------------------------------------------
--- svn:mime-type (original)
+++ svn:mime-type Fri Mar  8 21:48:34 2013
@@ -1 +1 @@
-text/plain
+text/plain;charset=UTF-8

Added: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/FallbackConverterTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/FallbackConverterTest.java?rev=1454594&view=auto
==============================================================================
--- sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/FallbackConverterTest.java
(added)
+++ sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/FallbackConverterTest.java
[UTF-8] Fri Mar  8 21:48:34 2013
@@ -0,0 +1,197 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.sis.internal.converter;
+
+import java.util.EnumSet;
+import org.apache.sis.util.ObjectConverter;
+import org.apache.sis.util.UnconvertibleObjectException;
+import org.apache.sis.math.FunctionProperty;
+import org.apache.sis.test.TestCase;
+import org.junit.Test;
+
+import static org.apache.sis.test.Assert.*;
+
+
+/**
+ * Tests {@link FallbackConverter}.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.3 (derived from geotk-3.00)
+ * @version 0.3
+ * @module
+ */
+public final strictfp class FallbackConverterTest extends TestCase {
+    /**
+     * Tests a chain of fallback converters. The initial fallback will understand {@link
Short}
+     * and {@link Long} types. Later we will add other types like {@link Boolean} and {@link
Float}.
+     *
+     * @throws UnconvertibleObjectException Should never happen.
+     */
+    @Test
+    public void testChain() throws UnconvertibleObjectException {
+        @SuppressWarnings({"unchecked","rawtypes"}) // Generic array creation.
+        final ObjectConverter<String,?>[] converters = new ObjectConverter[] {
+            StringConverter.Short  .INSTANCE,
+            StringConverter.Long   .INSTANCE,
+            StringConverter.Float  .INSTANCE,
+            StringConverter.Integer.INSTANCE,
+            StringConverter.Boolean.INSTANCE,
+            StringConverter.Double .INSTANCE
+        };
+        // Index at which some kind of values are expected.
+        final int LONG    = 1;
+        final int FLOAT   = 2;
+        final int DOUBLE  = 5;
+        final int BOOLEAN = 4;
+        assertEquals(Long.class,    converters[LONG]   .getTargetClass());
+        assertEquals(Float.class,   converters[FLOAT]  .getTargetClass());
+        assertEquals(Double.class,  converters[DOUBLE] .getTargetClass());
+        assertEquals(Boolean.class, converters[BOOLEAN].getTargetClass());
+        /*
+         * Create the fallback chain and check at every steps. The source class should never
+         * change. But the target type will be relaxed more and more as we add new fallbacks.
+         * The initial target will be Short, then Number, and finally Object.
+         */
+        ObjectConverter<String,?> c = null;
+        for (int i=0; i<converters.length; i++) {
+            c = FallbackConverter.merge(c, converters[i]);
+            final ObjectConverter<String,?>[] expected;
+            final Class<?> targetClass;
+            if (i == 0) {
+                targetClass = Short.class;
+                expected    = converters;
+            } else if (i < BOOLEAN) {
+                targetClass = Number.class;
+                expected    = converters;
+            } else if (i < DOUBLE) {
+                targetClass = Object.class;
+                expected    = converters;
+            } else {
+                targetClass = Object.class;
+                expected    = converters.clone();
+                expected[BOOLEAN] = converters[DOUBLE];
+                expected[DOUBLE]  = converters[BOOLEAN];
+                // Boolean is expected to be last.
+            }
+            assertEquals(targetClass, c.getTargetClass());
+            assertEquals(String.class, c.getSourceClass());
+            assertEquals(i+1, count(c, expected, 0));
+            /*
+             * Try conversions. Parsing numbers should returns a Short, Long or Float because
+             * they were the first converters declared. Parsing a boolean should succeed
only
+             * after we registered the boolean converter.
+             */
+            assertConvert(c, "5",                      Short.valueOf((short) 5));
+            assertConvert(c, "80000", (i >= LONG)    ? Long.valueOf(80000) : null);
+            assertConvert(c, "5.0",   (i >= FLOAT)   ? Float.valueOf(5f) : null);
+            assertConvert(c, "2.5",   (i >= FLOAT)   ? Float.valueOf(2.5f) : null);
+            assertConvert(c, "1E+20", (i >= FLOAT)   ? Float.valueOf(1E+20f) : null);
+            assertConvert(c, "1E+80", (i >= FLOAT)   ? Float.POSITIVE_INFINITY : null);
+            assertConvert(c, "true",  (i >= BOOLEAN) ? Boolean.TRUE : null);
+        }
+        /*
+         * Adds a generic converter for number. It is going to change everything.
+         * This converter is expected to be registered before any other number
+         * converter. Same tests than above will return different objects.
+         */
+        @SuppressWarnings({"unchecked","rawtypes"}) // Generic array creation.
+        final ObjectConverter<String,?>[] expected = new ObjectConverter[converters.length
+ 1];
+        System.arraycopy(converters, 0, expected, 1, converters.length);
+        expected[BOOLEAN + 1] = converters[DOUBLE];
+        expected[DOUBLE  + 1] = converters[BOOLEAN];
+        c = FallbackConverter.merge(c, expected[0] = StringConverter.Number.INSTANCE);
+        assertEquals(String.class, c.getSourceClass());
+        assertEquals(Object.class, c.getTargetClass());
+        assertEquals(expected.length, count(c, expected, 0));
+        assertConvert(c, "5",     Byte.valueOf((byte) 5));
+        assertConvert(c, "80000", Integer.valueOf(80000));
+        assertConvert(c, "5.0",   Byte.valueOf((byte) 5));
+        assertConvert(c, "2.5",   Float.valueOf(2.5f));
+        assertConvert(c, "1E+20", Double.valueOf(1E+20));
+        assertConvert(c, "1E+80", Double.valueOf(1E+80));
+        assertConvert(c, "true",  Boolean.TRUE);
+        assertEquals(EnumSet.of(FunctionProperty.SURJECTIVE), c.properties());
+        /*
+         * Compares the string representations. In theory this is not needed, since the
+         * above tests performs the same check in a more programmatic way. However this
+         * is a convenient visual check and a useful debugging tool.
+         */
+        if (false) // TODO: FallbackConverter.toString() not yet implemented.
+        assertMultilinesEquals(
+                "String ⇨ Object\n" +
+                "├───String ⇨ Number\n" +
+                "│   ├───String ⇨ Number\n" +
+                "│   ├───String ⇨ Short\n" +
+                "│   ├───String ⇨ Long\n" +
+                "│   ├───String ⇨ Float\n" +
+                "│   ├───String ⇨ Integer\n" +
+                "│   └───String ⇨ Double\n" +
+                "└───String ⇨ Boolean\n", c.toString());
+    }
+
+    /**
+     * Converts the given value and compares the result with the expected one.
+     *
+     * @param converter The converter to use.
+     * @param value     The value to convert.
+     * @param expected  The expected result, or {@code null} if the conversion is expected
to
+     *                  thrown an exception.
+     *
+     * @throws UnconvertibleObjectException if an exception was not expected but occurred.
+     */
+    private static void assertConvert(final ObjectConverter<String,?> converter,
+            final String value, final Object expected) throws UnconvertibleObjectException
+    {
+        final Object result;
+        try {
+            result = converter.convert(value);
+        } catch (UnconvertibleObjectException exception) {
+            if (expected != null) {
+                throw exception;
+            }
+            return;
+        }
+        assertNotNull(result);
+        if (expected == null) {
+            fail("Expected an exception but got " + result);
+        }
+        assertEquals(expected, result);
+    }
+
+    /**
+     * Counts the number of converters, descending down in the tree if necessary.
+     *
+     * @param converter The converter for which to count underlying converters.
+     * @param expected  Expected converters while we go down the tree, or {@code null}.
+     * @param offset    The index of the first element to consider in the array.
+     */
+    private static int count(final ObjectConverter<?,?> converter,
+                             final ObjectConverter<?,?>[] expected, final int offset)
+    {
+        if (converter instanceof FallbackConverter<?,?>) {
+            final FallbackConverter<?,?> fallback = (FallbackConverter<?,?>)
converter;
+            synchronized (fallback) {
+                final int c = count(fallback.getConverter(true), expected, offset);
+                return c + count(fallback.getConverter(false), expected, offset + c);
+            }
+        }
+        if (expected != null) {
+            assertEquals(String.valueOf(offset), expected[offset], converter);
+        }
+        return 1;
+    }
+}

Propchange: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/FallbackConverterTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/FallbackConverterTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java?rev=1454594&r1=1454593&r2=1454594&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java
[UTF-8] (original)
+++ sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java
[UTF-8] Fri Mar  8 21:48:34 2013
@@ -90,6 +90,9 @@ import org.junit.runners.Suite;
     org.apache.sis.util.collection.TreeTableFormatTest.class,
     org.apache.sis.util.collection.RangeSetTest.class,
 
+    // Converters
+    org.apache.sis.internal.converter.FallbackConverterTest.class,
+
     // XML most basic types.
     org.apache.sis.xml.XLinkTest.class,
     org.apache.sis.xml.NilReasonTest.class,



Mime
View raw message