sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject [sis] 01/04: Add more tests.
Date Sat, 08 Dec 2018 18:01:50 GMT
This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git

commit d287b832a9e6a10a4c381abd4c2b957ba4ed06a8
Author: Martin Desruisseaux <martin.desruisseaux@geomatys.com>
AuthorDate: Sat Dec 8 11:47:44 2018 +0100

    Add more tests.
---
 .../java/org/apache/sis/coverage/Category.java     |   8 +-
 .../java/org/apache/sis/coverage/CategoryList.java |  16 ++-
 .../org/apache/sis/coverage/SampleDimension.java   |  15 +--
 .../org/apache/sis/coverage/CategoryListTest.java  |  33 +++++-
 .../java/org/apache/sis/coverage/CategoryTest.java | 112 +++++++++++++++++++--
 .../apache/sis/coverage/SampleDimensionTest.java   |  38 ++++---
 6 files changed, 172 insertions(+), 50 deletions(-)

diff --git a/core/sis-raster/src/main/java/org/apache/sis/coverage/Category.java b/core/sis-raster/src/main/java/org/apache/sis/coverage/Category.java
index d73613e..b10da34 100644
--- a/core/sis-raster/src/main/java/org/apache/sis/coverage/Category.java
+++ b/core/sis-raster/src/main/java/org/apache/sis/coverage/Category.java
@@ -200,14 +200,13 @@ public class Category implements Serializable {
      *                    The same set shall be given to all {@code Category} created for
the same sample dimension.
      *                    Content can be discarded after all categories have been created.
      */
-    protected Category(final CharSequence name, final NumberRange<?> samples, final
MathTransform1D toUnits, final Unit<?> units,
+    protected Category(final CharSequence name, NumberRange<?> samples, final MathTransform1D
toUnits, final Unit<?> units,
              final Set<Integer> padValues)
     {
         ArgumentChecks.ensureNonEmpty("name", name);
         ArgumentChecks.ensureNonNull("samples", samples);
         ArgumentChecks.ensureNonNull("padValues", padValues);
         this.name    = Types.toInternationalString(name);
-        this.range   = samples;
         this.minimum = samples.getMinDouble(true);
         this.maximum = samples.getMaxDouble(true);
         /*
@@ -227,6 +226,10 @@ public class Category implements Serializable {
                 toConverse = toUnits;
                 if (toUnits.isIdentity()) {
                     converse = this;
+                    if (!(samples instanceof MeasurementRange<?>)) {
+                        samples = new MeasurementRange<>(samples, units);   // Avoid
ClassCastException in getMeasurementRange().
+                    }
+                    range = samples;
                     return;
                 }
                 toSamples = toUnits.inverse();
@@ -265,6 +268,7 @@ search:         if (!padValues.add(ordinal)) {
                 final double value = (minimum > 0) ? minimum : (maximum <= 0) ? maximum
: 0d;
                 toSamples = (MathTransform1D) MathTransforms.linear(0, value);
             }
+            range = samples;
             converse = new ConvertedCategory(this, toSamples, toUnits != null, units);
         } catch (TransformException e) {
             throw new IllegalArgumentException(Resources.format(Resources.Keys.IllegalTransferFunction_1,
name), e);
diff --git a/core/sis-raster/src/main/java/org/apache/sis/coverage/CategoryList.java b/core/sis-raster/src/main/java/org/apache/sis/coverage/CategoryList.java
index 5e51fa2..311d8b4 100644
--- a/core/sis-raster/src/main/java/org/apache/sis/coverage/CategoryList.java
+++ b/core/sis-raster/src/main/java/org/apache/sis/coverage/CategoryList.java
@@ -256,21 +256,17 @@ final class CategoryList extends AbstractList<Category> implements
MathTransform
 
     /**
      * Returns the <cite>transfer function</cite> from sample values to real
values, including conversion
-     * of "no data" value to NaN.  Callers should ensure that there is at least one quantitative
category
+     * of "no data" values to NaNs. Callers shall ensure that there is at least one quantitative
category
      * before to invoke this method.
      *
      * @see SampleDimension#getTransferFunction()
      */
     final MathTransform1D getTransferFunction() {
-        MathTransform1D tr = null;
-        final int n = categories.length;
-        if (n != 0) {
-            tr = categories[0].toConverse;
-            for (int i=1; i<n; i++) {
-                if (!tr.equals(categories[i].toConverse)) {
-                    tr = this;
-                    break;
-                }
+        MathTransform1D tr = categories[0].toConverse;          // See condition in javadoc.
+        for (int i=categories.length; --i >= 1;) {
+            if (!tr.equals(categories[i].toConverse)) {
+                tr = this;
+                break;
             }
         }
         return tr;
diff --git a/core/sis-raster/src/main/java/org/apache/sis/coverage/SampleDimension.java b/core/sis-raster/src/main/java/org/apache/sis/coverage/SampleDimension.java
index e670901..fbe54ed 100644
--- a/core/sis-raster/src/main/java/org/apache/sis/coverage/SampleDimension.java
+++ b/core/sis-raster/src/main/java/org/apache/sis/coverage/SampleDimension.java
@@ -152,15 +152,16 @@ public class SampleDimension implements Serializable {
                 name = Vocabulary.formatInternational(Vocabulary.Keys.Untitled);
             }
         }
-        this.name       = Types.toInternationalString(name);
+        this.name = Types.toInternationalString(name);
         this.categories = list;
         if (list.range == null) {               // !hasQuantitative() inlined since we can
not yet invoke that method.
             transferFunction = null;
-            converse = this;
+            converse = null;
         } else if (list == list.converse) {
             transferFunction = Category.identity();
             converse = this;
         } else {
+            assert !list.isEmpty();             // Verified by inlined !hasQuantitative()
above.
             transferFunction = list.getTransferFunction();
             converse = new SampleDimension(this);
         }
@@ -174,7 +175,8 @@ public class SampleDimension implements Serializable {
      * @see #forConvertedValues(boolean)
      */
     private SampleDimension converted() {
-        return (converse != null && transferFunction != null && !transferFunction.isIdentity())
? converse : this;
+        // Transfer function shall never be null if 'converse' is non-null.
+        return (converse != null && !transferFunction.isIdentity()) ? converse :
this;
     }
 
     /**
@@ -374,10 +376,9 @@ public class SampleDimension implements Serializable {
      *         May be {@code this} but never {@code null}.
      */
     public SampleDimension forConvertedValues(final boolean converted) {
-        if (converse != null && transferFunction != null) {
-            if (transferFunction.isIdentity() != converted) {
-                return converse;
-            }
+        // Transfer function shall never be null if 'converse' is non-null.
+        if (converse != null && transferFunction.isIdentity() != converted) {
+            return converse;
         }
         return this;
     }
diff --git a/core/sis-raster/src/test/java/org/apache/sis/coverage/CategoryListTest.java b/core/sis-raster/src/test/java/org/apache/sis/coverage/CategoryListTest.java
index d367841..8a4d5fa 100644
--- a/core/sis-raster/src/test/java/org/apache/sis/coverage/CategoryListTest.java
+++ b/core/sis-raster/src/test/java/org/apache/sis/coverage/CategoryListTest.java
@@ -19,6 +19,7 @@ package org.apache.sis.coverage;
 import java.util.Set;
 import java.util.HashSet;
 import java.util.Arrays;
+import java.util.List;
 import java.util.Random;
 import org.opengis.referencing.operation.MathTransform1D;
 import org.opengis.referencing.operation.TransformException;
@@ -48,10 +49,11 @@ public final strictfp class CategoryListTest extends TestCase {
      * Asserts that the specified categories are sorted.
      * This method ignores {@code NaN} values.
      */
-    private static void assertSorted(final Category[] categories) {
-        for (int i=1; i<categories.length; i++) {
-            final Category current  = categories[i  ];
-            final Category previous = categories[i-1];
+    private static void assertSorted(final List<Category> categories) {
+        final int size = categories.size();
+        for (int i=1; i<size; i++) {
+            final Category current  = categories.get(i  );
+            final Category previous = categories.get(i-1);
             assertFalse( current.minimum >  current.maximum);
             assertFalse(previous.minimum > previous.maximum);
             assertFalse(Category.compare(previous.maximum, current.minimum) > 0);
@@ -92,7 +94,7 @@ public final strictfp class CategoryListTest extends TestCase {
         // Removes the wrong category. Now, construction should succeed.
         categories = Arrays.copyOf(categories, categories.length - 1);
         assertNotConverted(new CategoryList(categories, null));
-        assertSorted(categories);
+        assertSorted(Arrays.asList(categories));
     }
 
     /**
@@ -177,6 +179,7 @@ public final strictfp class CategoryListTest extends TestCase {
     @Test
     public void testRanges() {
         final CategoryList list = new CategoryList(categories(), null);
+        assertSorted(list);
         assertTrue  ("isMinIncluded",           list.range.isMinIncluded());
         assertFalse ("isMaxIncluded",           list.range.isMaxIncluded());
         assertFalse ("converse.isMinIncluded",  list.converse.range.isMinIncluded());   
 // Because computed from maxValue before conversion.
@@ -320,4 +323,24 @@ public final strictfp class CategoryListTest extends TestCase {
             assertEquals(expected, actual, CategoryTest.EPS);
         }
     }
+
+    /**
+     * Tests construction from categories that already describe real values.
+     * The constructor should have replaced {@link ConvertedCategory} instances
+     * by plain {@link Category} instances without relationship with the sample values.
+     */
+    @Test
+    public void testFromConvertedCategories() {
+        final Category[] categories = categories();
+        for (int i=0; i<categories.length; i++) {
+            categories[i] = categories[i].converse;
+        }
+        final CategoryList list = new CategoryList(categories, null);
+        assertSorted(list);
+        for (int i=list.size(); --i >= 0;) {
+            final Category category = list.get(i);
+            assertSame(category, category.converse);
+            assertTrue(category.toConverse.isIdentity());
+        }
+    }
 }
diff --git a/core/sis-raster/src/test/java/org/apache/sis/coverage/CategoryTest.java b/core/sis-raster/src/test/java/org/apache/sis/coverage/CategoryTest.java
index 9c1e2b5..b0fe445 100644
--- a/core/sis-raster/src/test/java/org/apache/sis/coverage/CategoryTest.java
+++ b/core/sis-raster/src/test/java/org/apache/sis/coverage/CategoryTest.java
@@ -68,7 +68,8 @@ public final strictfp class CategoryTest extends TestCase {
     }
 
     /**
-     * Tests that qualitative category produces the expected result.
+     * Tests that construction of qualitative category produces expected properties.
+     * This method tests also the conversions of some random sample values.
      *
      * @throws TransformException if an error occurred while transforming a value.
      */
@@ -81,9 +82,45 @@ public final strictfp class CategoryTest extends TestCase {
             final boolean  collision = padValues.contains(sample);
             final Category category  = new Category("Random", NumberRange.create(sample,
true, sample, true), null, null, padValues);
             assertTrue("Allocated NaN ordinal", padValues.contains(sample));
-            assertBoundEquals("range.minValue", sample, category.range.getMinValue());
-            assertBoundEquals("range.maxValue", sample, category.range.getMaxValue());
-            final MathTransform1D inverse = category.converse.toConverse;
+            /*
+             * Verify properties on the category that we created.
+             * The sample values are integers in our test.
+             */
+            assertEquals     ("name",           "Random",       String.valueOf(category.name));
+            assertEquals     ("name",           "Random",       String.valueOf(category.getName()));
+            assertEquals     ("minimum",        sample,         category.minimum, STRICT);
+            assertEquals     ("maximum",        sample,         category.maximum, STRICT);
+            assertBoundEquals("range.minValue", sample,         category.range.getMinValue());
+            assertBoundEquals("range.maxValue", sample,         category.range.getMaxValue());
+            assertSame       ("sampleRange",    category.range, category.getSampleRange());
+            assertFalse      ("measurementRange",               category.getMeasurementRange().isPresent());
+            assertFalse      ("toConverse.isIdentity",          category.toConverse.isIdentity());
+            assertFalse      ("transferFunction",               category.getTransferFunction().isPresent());
+            assertFalse      ("isQuantitative",                 category.isQuantitative());
+            /*
+             * Verify properties on the converse category. Values shall be NaN
+             * and the transfer function shall be absent.
+             */
+            final Category converse = category.converse;
+            assertNotSame("converse",           category, converse);
+            assertSame   ("converse.converse",  category, converse.converse);
+            assertSame   ("converted",          converse, category.converted());
+            assertSame   ("converted",          converse, converse.converted());
+            assertEquals ("name",               "Random", String.valueOf(converse.name));
+            assertEquals ("name",               "Random", String.valueOf(converse.getName()));
+            assertTrue   ("minimum",                      Double.isNaN(converse.minimum));
+            assertTrue   ("maximum",                      Double.isNaN(converse.maximum));
+            assertNull   ("range",                        converse.range);
+            assertNotNull("sampleRange",                  converse.getSampleRange());
+            assertFalse  ("measurementRange",             category.getMeasurementRange().isPresent());
+            assertFalse  ("toConverse.isIdentity",        converse.toConverse.isIdentity());
+            assertFalse  ("transferFunction",             converse.getTransferFunction().isPresent());
+            assertFalse  ("isQuantitative",               converse.isQuantitative());
+            /*
+             * Test sample values conversions. They are expected to produce NaN values and
+             * the converter shall be able to go back to original values from those NaNs.
+             */
+            final MathTransform1D inverse = converse.toConverse;
             for (int i=0; i<4; i++) {
                 final float x = 100 * random.nextFloat();
                 final float y = (float) category.toConverse.transform(x);
@@ -100,7 +137,8 @@ public final strictfp class CategoryTest extends TestCase {
     }
 
     /**
-     * Tests that quantitative category produces the expected result.
+     * Tests that construction of quantitative category produces expected properties.
+     * This method tests also the conversions of some random sample values.
      *
      * @throws TransformException if an error occurred while transforming a value.
      */
@@ -115,14 +153,39 @@ public final strictfp class CategoryTest extends TestCase {
             final Category category = new Category("Random", NumberRange.create(lower, true,
upper, true),
                     (MathTransform1D) MathTransforms.linear(scale, offset), null, Collections.emptySet());
 
-            assertBoundEquals("range.minValue",    lower,              category.range.getMinValue());
-            assertBoundEquals("range.maxValue",    upper,              category.range.getMaxValue());
-            assertBoundEquals("converse.minValue", lower*scale+offset, category.converse.range.getMinValue());
-            assertBoundEquals("converse.maxValue", upper*scale+offset, category.converse.range.getMaxValue());
-
+            final Category converse = category.converse;
+            assertNotSame    ("converse",           category, converse);
+            assertSame       ("converse.converse",  category, converse.converse);
+            assertSame       ("converted",          converse, category.converted());
+            assertSame       ("converted",          converse, converse.converted());
+            assertEquals     ("name",               "Random",            String.valueOf(category.name));
+            assertEquals     ("name",               "Random",            String.valueOf(converse.name));
+            assertEquals     ("name",               "Random",            String.valueOf(category.getName()));
+            assertEquals     ("name",               "Random",            String.valueOf(converse.getName()));
+            assertEquals     ("minimum",            lower,               category.minimum,
STRICT);
+            assertEquals     ("maximum",            upper,               category.maximum,
STRICT);
+            assertEquals     ("minimum",            lower*scale+offset,  converse.minimum,
EPS);
+            assertEquals     ("maximum",            upper*scale+offset,  converse.maximum,
EPS);
+            assertBoundEquals("range.minValue",     lower,               category.range.getMinValue());
+            assertBoundEquals("range.maxValue",     upper,               category.range.getMaxValue());
+            assertBoundEquals("range.minValue",     converse.minimum,    converse.range.getMinValue());
+            assertBoundEquals("range.maxValue",     converse.maximum,    converse.range.getMaxValue());
+            assertSame       ("sampleRange",        category.range,      category.getSampleRange());
+            assertSame       ("sampleRange",        converse.range,      converse.getSampleRange());
+            assertSame       ("measurementRange",   converse.range,      category.getMeasurementRange().get());
+            assertSame       ("measurementRange",   converse.range,      converse.getMeasurementRange().get());
+            assertSame       ("transferFunction",   category.toConverse, category.getTransferFunction().get());
+            assertNotSame    ("transferFunction",   converse.toConverse, converse.getTransferFunction().get());
+            assertTrue       ("transferFunction",                        converse.getTransferFunction().get().isIdentity());
+            assertFalse      ("toConverse.isIdentity",                   category.toConverse.isIdentity());
+            assertFalse      ("toConverse.isIdentity",                   converse.toConverse.isIdentity());
+            assertTrue       ("isQuantitative",                          category.isQuantitative());
+            assertTrue       ("isQuantitative",                          converse.isQuantitative());
+            /*
+             * Test sample values conversions.
+             */
             final MathTransform1D inverse = category.converse.toConverse;
             assertSame("inverse", inverse, category.toConverse.inverse());
-
             for (int i=0; i<20; i++) {
                 final double x = 100 * random.nextDouble();
                 final double y = x*scale + offset;
@@ -131,4 +194,31 @@ public final strictfp class CategoryTest extends TestCase {
             }
         }
     }
+
+    /**
+     * Creates a category for data that are already real values.
+     */
+    @Test
+    public void testConvertedCategory() {
+        final Random random = TestUtilities.createRandomNumberGenerator();
+        for (int pass=0; pass<3; pass++) {
+            final double lower = random.nextDouble() * 5;
+            final double upper = random.nextDouble() * 10 + lower;
+            final Category category = new Category("Random", NumberRange.create(lower, true,
upper, true),
+                    (MathTransform1D) MathTransforms.identity(1), null, Collections.emptySet());
+
+            assertSame       ("converse",           category,            category.converse);
+            assertEquals     ("name",               "Random",            String.valueOf(category.name));
+            assertEquals     ("name",               "Random",            String.valueOf(category.getName()));
+            assertEquals     ("minimum",            lower,               category.minimum,
STRICT);
+            assertEquals     ("maximum",            upper,               category.maximum,
STRICT);
+            assertBoundEquals("range.minValue",     lower,               category.range.getMinValue());
+            assertBoundEquals("range.maxValue",     upper,               category.range.getMaxValue());
+            assertSame       ("sampleRange",        category.range,      category.getSampleRange());
+            assertSame       ("measurementRange",   category.range,      category.getMeasurementRange().get());
+            assertSame       ("transferFunction",   category.toConverse, category.getTransferFunction().get());
+            assertTrue       ("toConverse.isIdentity",                   category.toConverse.isIdentity());
+            assertTrue       ("isQuantitative",                          category.isQuantitative());
+        }
+    }
 }
diff --git a/core/sis-raster/src/test/java/org/apache/sis/coverage/SampleDimensionTest.java
b/core/sis-raster/src/test/java/org/apache/sis/coverage/SampleDimensionTest.java
index bc3bf75..2ae4014 100644
--- a/core/sis-raster/src/test/java/org/apache/sis/coverage/SampleDimensionTest.java
+++ b/core/sis-raster/src/test/java/org/apache/sis/coverage/SampleDimensionTest.java
@@ -36,38 +36,46 @@ import static org.junit.Assert.*;
  */
 public final strictfp class SampleDimensionTest extends TestCase {
     /**
-     * Tests the creation of a sample dimensions using builder, then verifies the dimension
properties.
+     * Tests a sample dimension having one quantitative category and a few "no data" values.
      */
     @Test
-    public void testBuilder() {
+    public void testQuantitativeWithMissingValues() {
         final int    lower  = 10;
         final int    upper  = 200;
         final double scale  = 0.1;
         final double offset = 5.0;
-        final SampleDimension test = new SampleDimension.Builder()
+        final SampleDimension dimension = new SampleDimension.Builder()
                 .addQualitative(null,      0)           // Default to "No data" name, potentially
locale.
                 .addQualitative("Clouds",  1)
                 .addQualitative("Lands", 255)
                 .addQuantitative("Temperature", lower, upper, scale, offset, Units.CELSIUS)
                 .build();
 
-        final Set<Number> nodataValues = test.getNoDataValues();
-        assertArrayEquals(new Integer[] {0, 1, 255}, nodataValues.toArray());
+        assertEquals("name", "Temperature", String.valueOf(dimension.getName()));
 
-        final TransferFunction tr = test.getTransferFunctionFormula().get();
-        assertFalse ("identity",  test.getTransferFunction().get().isIdentity());
-        assertFalse ("identity",  tr.getTransform().isIdentity());
-        assertEquals("scale",     scale,  tr.getScale(),  STRICT);
-        assertEquals("offset",    offset, tr.getOffset(), STRICT);
+        final Set<Number> nodataValues = dimension.getNoDataValues();
+        assertArrayEquals(new Integer[] {0, 1, 255}, nodataValues.toArray());
 
-        NumberRange<?> range = test.getSampleRange().get();
-        assertEquals("minimum",   0,   range.getMinDouble(), STRICT);
-        assertEquals("maximum",   255, range.getMaxDouble(), STRICT);
+        NumberRange<?> range = dimension.getSampleRange().get();
+        assertEquals("minimum",   0, range.getMinDouble(), STRICT);
+        assertEquals("maximum", 255, range.getMaxDouble(), STRICT);
 
-        range = test.getMeasurementRange().get();
+        range = dimension.getMeasurementRange().get();
         assertEquals("minimum", lower*scale+offset, range.getMinDouble(true),  CategoryTest.EPS);
         assertEquals("maximum", upper*scale+offset, range.getMaxDouble(false), CategoryTest.EPS);
+        assertEquals("units",   Units.CELSIUS,      dimension.getUnits().get());
+
+        final TransferFunction tr = dimension.getTransferFunctionFormula().get();
+        assertFalse ("identity",  dimension.getTransferFunction().get().isIdentity());
+        assertFalse ("identity",  tr.getTransform().isIdentity());
+        assertEquals("scale",     scale,  tr.getScale(),  STRICT);
+        assertEquals("offset",    offset, tr.getOffset(), STRICT);
 
-        assertEquals("units", Units.CELSIUS, test.getUnits().get());
+        final SampleDimension converted = dimension.forConvertedValues(true);
+        assertNotSame(dimension,  converted);
+        assertSame   (dimension,  dimension.forConvertedValues(false));
+        assertSame   (dimension,  converted.forConvertedValues(false));
+        assertSame   (converted,  converted.forConvertedValues(true));
+        assertTrue   ("identity", converted.getTransferFunction().get().isIdentity());
     }
 }


Mime
View raw message