This is an automated email from the ASF dual-hosted git repository.

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


The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
     new f3a5a8356e feat(Geometry): implement all tests for Empty geometry type
f3a5a8356e is described below

commit f3a5a8356e94d343a82d792713b378ad12646b38
Author: jsorel <[email protected]>
AuthorDate: Mon Sep 21 10:38:19 2026 +0200

    feat(Geometry): implement all tests for Empty geometry type
---
 .../main/org/apache/sis/geometries/Empty.java      | 149 +-----------
 .../main/org/apache/sis/geometries/Geometry.java   |  34 +--
 .../geometries/operation/GeometryProcessor.java    |  89 ++++++-
 .../test/org/apache/sis/geometries/EmptyTest.java  | 270 +++++++++------------
 .../internal/shared/DefaultEmptyTest.java          |  21 ++
 .../sis/geometries/operation/BufferTest.java       |  39 ++-
 .../sis/geometries/operation/ContainsTest.java     |  54 +----
 .../sis/geometries/operation/ConvexHullTest.java   |   6 +-
 .../sis/geometries/operation/CrossesTest.java      |   6 +-
 .../sis/geometries/operation/DifferenceTest.java   |  13 +-
 .../sis/geometries/operation/DisjointTest.java     |  14 +-
 .../sis/geometries/operation/DistanceTest.java     |  75 +++---
 .../apache/sis/geometries/operation/EqualTest.java |  14 +-
 .../sis/geometries/operation/IntersectionTest.java |  13 +-
 .../sis/geometries/operation/IntersectsTest.java   |  14 +-
 .../sis/geometries/operation/LocateAlongTest.java  |   6 +-
 .../geometries/operation/LocateBetweenTest.java    |   6 +-
 .../sis/geometries/operation/OverlapsTest.java     |   6 +-
 .../sis/geometries/operation/RelateTest.java       |   6 +-
 .../geometries/operation/SymDifferenceTest.java    |  13 +-
 .../apache/sis/geometries/operation/TestData.java  |  61 +++++
 .../sis/geometries/operation/TouchesTest.java      |   6 +-
 .../sis/geometries/operation/TransformTest.java    |   6 +-
 .../apache/sis/geometries/operation/UnionTest.java |  13 +-
 .../geometries/operation/WithinDistanceTest.java   |   6 +-
 .../sis/geometries/operation/WithinTest.java       |  14 +-
 26 files changed, 472 insertions(+), 482 deletions(-)

diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Empty.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Empty.java
index 996de45881..d7797a43f1 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Empty.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Empty.java
@@ -16,13 +16,10 @@
  */
 package org.apache.sis.geometries;
 
-import javax.measure.Quantity;
 import org.apache.sis.geometries.internal.shared.DefaultEmpty;
-import org.apache.sis.measure.Quantities;
-import org.apache.sis.measure.Units;
+import org.apache.sis.geometries.operation.GeometryProcessor;
 import static org.opengis.annotation.Specification.ISO_19107;
 import org.opengis.annotation.UML;
-import org.opengis.geometry.DirectPosition;
 
 
 /**
@@ -146,28 +143,6 @@ public sealed interface Empty extends Geometry
         return this;
     }
 
-    /**
-     * Returns {@code this}: the convex hull of the empty set is empty.
-     *
-     * @see ISO 19107:2019 - 6.4.4.10
-     */
-    @UML(identifier="convexHull", specification=ISO_19107)
-    @Override
-    default Geometry convexHull() {
-        return this;
-    }
-
-    /**
-     * Returns {@code this}: there is no position to grow a buffer around.
-     *
-     * @see ISO 19107:2019 - 6.4.4.24
-     */
-    @UML(identifier="buffer", specification=ISO_19107)
-    @Override
-    default Geometry buffer(Quantity<?> radius) {
-        return this;
-    }
-
     /**
      * Returns {@code null}: the centroid of the empty set is undefined.
      *
@@ -190,126 +165,4 @@ public sealed interface Empty extends Geometry
         return null;
     }
 
-    /**
-     * Returns an infinite distance: no position of this geometry can come 
close to another geometry.
-     * The returned quantity is dimensionless, the empty set having no 
measurement unit to report.
-     *
-     * @see ISO 19107:2019 - 6.4.4.26
-     */
-    @UML(identifier="distance", specification=ISO_19107)
-    @Override
-    default Quantity<?> distance(Geometry other) {
-        return Quantities.create(Double.POSITIVE_INFINITY, Units.UNITY);
-    }
-
-    /**
-     * Returns {@code this}: {@code ∅ ∩ A = ∅}.
-     *
-     * @see ISO 19107:2019 - 6.4.8.4
-     */
-    @UML(identifier="intersection", specification=ISO_19107)
-    @Override
-    default Geometry intersection(Geometry other) {
-        return this;
-    }
-
-    /**
-     * Returns the given geometry: {@code ∅ ∪ A = A}.
-     *
-     * @see ISO 19107:2019 - 6.4.8.7
-     */
-    @UML(identifier="union", specification=ISO_19107)
-    @Override
-    default Geometry union(Geometry other) {
-        return other;
-    }
-
-    /**
-     * Returns {@code this}: {@code ∅ − A = ∅}.
-     *
-     * @see ISO 19107:2019 - 6.4.8.5
-     */
-    @UML(identifier="difference", specification=ISO_19107)
-    @Override
-    default Geometry difference(Geometry other) {
-        return this;
-    }
-
-    /**
-     * Returns the given geometry: {@code (∅ − A) ∪ (A − ∅) = A}.
-     *
-     * @see ISO 19107:2019 - 6.4.8.6
-     */
-    @UML(identifier="symDifference", specification=ISO_19107)
-    @Override
-    default Geometry symDifference(Geometry other) {
-        return other;
-    }
-
-    /**
-     * Returns {@code false}: the empty set contains no position at all.
-     *
-     * @see ISO 19107:2019 - 6.4.2
-     */
-    @UML(identifier="contains", specification=ISO_19107)
-    @Override
-    default boolean contains(DirectPosition element) {
-        return false;
-    }
-
-    /**
-     * Returns whether the given geometry is empty: the empty set is a 
superset of itself only.
-     *
-     * @see ISO 19107:2019 - 10.8.6.3.2
-     */
-    @UML(identifier="contains", specification=ISO_19107)
-    @Override
-    default boolean contains(Geometry other) {
-        return other.isEmpty();
-    }
-
-    /**
-     * Returns {@code true}: the empty set is a subset of every geometry.
-     *
-     * @see ISO 19107:2019 - 10.8.6.3.7
-     */
-    @UML(identifier="within", specification=ISO_19107)
-    @Override
-    default boolean within(Geometry other) {
-        return true;
-    }
-
-    /**
-     * Returns whether the given geometry is empty: any two empty geometries 
are equal.
-     *
-     * @see ISO 19107:2019 - 6.4.4.27, 10.8.6.3.1
-     */
-    @UML(identifier="equals", specification=ISO_19107)
-    @Override
-    default boolean equal(Geometry other) {
-        return other.isEmpty();
-    }
-
-    /**
-     * Returns {@code true}: the empty set has no position in common with any 
geometry.
-     *
-     * @see ISO 19107:2019 - 10.8.6.3.3
-     */
-    @UML(identifier="disjoint", specification=ISO_19107)
-    @Override
-    default boolean disjoint(Geometry other) {
-        return true;
-    }
-
-    /**
-     * Returns {@code false}: the empty set has no position in common with any 
geometry.
-     *
-     * @see ISO 19107:2019 - 10.8.6.3.4
-     */
-    @UML(identifier="intersects", specification=ISO_19107)
-    @Override
-    default boolean intersects(Geometry other) {
-        return false;
-    }
-
 }
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Geometry.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Geometry.java
index 267a183d25..e5acee656d 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Geometry.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Geometry.java
@@ -67,10 +67,15 @@ import 
org.opengis.referencing.crs.CoordinateReferenceSystem;
  *
  * <p>
  * Deviation from ISO-19107 :<br>
- * A Geometry should be a sub type of TransfiniteSetOfDirectPositions (section 
6.4.2)
- * A TransfiniteSetOfDirectPositions exist to define a Geometry within the 
<b>Set theory</b>, it is a mathematical conceptual interface.
- * But the interface has only a unique subtype and provide a single additional 
method contains(DirectPosition),
- * therefor we merged TransfiniteSetOfDirectPositions in Geometry for 
simplicity state
+ * <ul>
+ *   <li>A Geometry should be a sub type of TransfiniteSetOfDirectPositions 
(section 6.4.2)
+ *   A TransfiniteSetOfDirectPositions exist to define a Geometry within the 
<b>Set theory</b>, it is a mathematical conceptual interface.
+ *   But the interface has only a unique subtype and provide a single 
additional method contains(DirectPosition),
+ *   therefor we merged TransfiniteSetOfDirectPositions in Geometry for 
simplicity state</li>
+ *   <li>We removed contains(DirectPosition) defined on TransfinitSet.
+ *   This method mimics contains(Point), to harmonize everything we keep only 
the geometric parameter method.
+ *   </li>
+ * </ul>
  *
  * @author Johann Sorel (Geomatys)
  *
@@ -584,11 +589,9 @@ public sealed interface Geometry
      * <p>Difference with ISO 19107, which takes a distance quantity:
      * see {@link #buffer(Quantity)} for the standard operation.</p>
      *
-     * @param  distance  radius of the buffer.
+     * @param  distance  radius of the buffer, in CRS unit.
      * @return buffer around this geometry.
      * @throws OperationException if the buffer cannot be computed.
-     *
-     * @see GeometryProcessor#buffer(org.apache.sis.geometries.Geometry, 
double)
      */
     default Geometry buffer(double distance) throws OperationException {
         return buffer(Quantities.create(distance, Units.UNITY));
@@ -789,23 +792,6 @@ public sealed interface Geometry
         return new GeometryProcessor().transform(this, crs, null);
     }
 
-    /**
-     * Returns whether the given position belongs to this geometry.
-     * This is the membership test which stands for this geometry being a 
possibly infinite
-     * set of positions.
-     *
-     * @param  element  the position to test.
-     * @return {@code true} if the given position is on this geometry.
-     * @throws OperationException if the test cannot be performed.
-     *
-     * @see GeometryProcessor#contains(org.apache.sis.geometries.Geometry, 
org.opengis.geometry.DirectPosition)
-     * @see ISO 19107:2019 - contains & 3Dcontains - 6.4.2, 6.4.4.30, 6.4.9
-     */
-    @UML(identifier="contains", specification=ISO_19107)
-    default boolean contains(DirectPosition element) throws OperationException 
{
-        return new GeometryProcessor().contains(this, element);
-    }
-
     /**
      * Returns whether the given geometry is a subset of this geometry, that 
is whether no position
      * of the given geometry lies in the exterior of this geometry.
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/operation/GeometryProcessor.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/operation/GeometryProcessor.java
index 5ec4d75fe8..748669dcfb 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/operation/GeometryProcessor.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/operation/GeometryProcessor.java
@@ -24,6 +24,7 @@ import java.util.Map.Entry;
 import java.util.function.Consumer;
 import java.util.function.Function;
 import javax.measure.Quantity;
+import javax.measure.Unit;
 import org.apache.sis.geometries.AttributesType;
 import org.apache.sis.geometries.DE9IM;
 import org.apache.sis.geometries.Geometries;
@@ -49,7 +50,6 @@ import org.apache.sis.measure.Units;
 import org.apache.sis.util.ArgumentChecks;
 import static org.opengis.annotation.Specification.ISO_19107;
 import org.opengis.annotation.UML;
-import org.opengis.geometry.DirectPosition;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.opengis.referencing.operation.MathTransform;
 
@@ -76,6 +76,10 @@ public final class GeometryProcessor {
     @UML(identifier="buffer", specification=ISO_19107) // section 6.4.4.24 and 
6.4.8.3
     //@UML(identifier="3Dbuffer", specification=ISO_19107) // section 6.4.9
     public Geometry buffer(Geometry geom, Quantity<?> radius) throws 
OperationException {
+        if (geom.isEmpty()) {
+            // There is no position to grow a buffer around, whatever the 
radius.
+            return geom;
+        }
         throw new UnsupportedOperationException();
     }
 
@@ -86,6 +90,10 @@ public final class GeometryProcessor {
      */
     //@UML(identifier="3DconvexHull", specification=ISO_19107) // section 6.4.9
     public Geometry convexHull(Geometry geom) throws OperationException {
+        if (geom.isEmpty()) {
+            // The convex hull of the empty set is empty.
+            return geom;
+        }
 
         //TODO : fallback on JTS until implemented, this loss the attributes !
         return Geometries.fromJTS(jts(geom).convexHull(), true);
@@ -97,6 +105,10 @@ public final class GeometryProcessor {
     @UML(identifier="difference", specification=ISO_19107) // section 6.4.4.30 
and 6.4.8.5
     //@UML(identifier="3Ddifference", specification=ISO_19107) // section 6.4.9
     public Geometry difference(Geometry geom1, Geometry geom2) throws 
OperationException {
+        if (geom1.isEmpty() || geom2.isEmpty()) {
+            // ∅ − A = ∅ and A − ∅ = A, which are both the first operand.
+            return geom1;
+        }
 
         //TODO : fallback on JTS until implemented, this loss the attributes !
         return Geometries.fromJTS(jts(geom1).difference(jts(geom2)), true);
@@ -120,9 +132,16 @@ public final class GeometryProcessor {
     @UML(identifier="distance", specification=ISO_19107) // section 6.4.4.26 
and 6.4.8.2
     //@UML(identifier="3Ddistance", specification=ISO_19107) // section 6.4.9
     public Quantity<?> distance(Geometry geom1, Geometry geom2) throws 
OperationException {
+        if (geom1.isEmpty() || geom2.isEmpty()) {
+            /*
+             * No position of an empty geometry can come close to another 
geometry.
+             * The returned quantity is dimensionless, the empty set having no 
measurement unit to report.
+             */
+            return Quantities.create(Double.POSITIVE_INFINITY, Units.UNITY);
+        }
         if (geom1 instanceof Point pt1) {
             if (geom2 instanceof Point pt2) {
-                return Quantities.create(Distance.distance(pt1, pt2), 
Units.METRE);
+                return Quantities.create(Distance.distance(pt1, pt2), 
getUnit(pt1));
             }
         }
 
@@ -135,6 +154,13 @@ public final class GeometryProcessor {
     @UML(identifier="intersection", specification=ISO_19107) // section 
6.4.4.30 and 6.4.8.4
     //@UML(identifier="3Dintersection", specification=ISO_19107) // section 
6.4.9
     public Geometry intersection(Geometry geom1, Geometry geom2) throws 
OperationException {
+        // ∅ ∩ A = ∅ and A ∩ ∅ = ∅, the result being the operand which is 
already empty.
+        if (geom1.isEmpty()) {
+            return geom1;
+        }
+        if (geom2.isEmpty()) {
+            return geom2;
+        }
 
         if (geom1 instanceof MeshPrimitive.Triangles g1) {
             if (geom2 instanceof MeshPrimitive.Points g2) {
@@ -155,6 +181,13 @@ public final class GeometryProcessor {
     @UML(identifier="symDifference", specification=ISO_19107) // section 
6.4.4.30 and 6.4.8.6
     //@UML(identifier="3DsymDifference", specification=ISO_19107) // section 
6.4.9
     public Geometry symDifference(Geometry geom1, Geometry geom2) throws 
OperationException {
+        // (∅ − A) ∪ (A − ∅) = A, the result being the operand which is not 
empty.
+        if (geom1.isEmpty()) {
+            return geom2;
+        }
+        if (geom2.isEmpty()) {
+            return geom1;
+        }
 
         //TODO : fallback on JTS until implemented, this loss the attributes !
         return Geometries.fromJTS(jts(geom1).symDifference(jts(geom2)), true);
@@ -166,22 +199,31 @@ public final class GeometryProcessor {
     @UML(identifier="union", specification=ISO_19107) // section 6.4.4.30 and 
6.4.8.7
     //@UML(identifier="3Dunion", specification=ISO_19107) // section 6.4.9
     public Geometry union(Geometry geom1, Geometry geom2) throws 
OperationException {
+        // ∅ ∪ A = A and A ∪ ∅ = A, the result being the operand which is not 
empty.
+        if (geom1.isEmpty()) {
+            return geom2;
+        }
+        if (geom2.isEmpty()) {
+            return geom1;
+        }
 
         //TODO : fallback on JTS until implemented, this loss the attributes !
         return Geometries.fromJTS(jts(geom1).union(jts(geom2)), true);
     }
 
-    @UML(identifier="contains", specification=ISO_19107) // section 6.4.4.30 ?
-    //@UML(identifier="3Dcontains", specification=ISO_19107) // section 6.4.9
-    public boolean contains(Geometry geom1, DirectPosition element) throws 
OperationException {
-        throw new UnsupportedOperationException();
-    }
-
     /**
      * Returns TRUE if this geometric object “spatially contains” 
anotherGeometry.
      */
     @UML(identifier="contains", specification=ISO_19107) // section 6.4.8.8, 
6.4.4.2
     public boolean contains(Geometry geom1, Geometry geom2) throws 
OperationException {
+        if (geom1.isEmpty()) {
+            // The empty set is a superset of itself only.
+            return geom2.isEmpty();
+        }
+        if (geom2.isEmpty()) {
+            // The empty set is a subset of every geometry.
+            return true;
+        }
         if (geom1 instanceof Polygon polygon) {
             if (geom2 instanceof Point pt) {
                 return Contains.contains(polygon, pt);
@@ -208,6 +250,11 @@ public final class GeometryProcessor {
     @UML(identifier="disjoint", specification=ISO_19107) // section 6.4.8.8
     //@UML(identifier="3Ddisjoint", specification=ISO_19107) // section 6.4.9
     public boolean disjoint(Geometry geom1, Geometry geom2) throws 
OperationException {
+        if (geom1.isEmpty() || geom2.isEmpty()) {
+            // The empty set has no position in common with any geometry.
+            return true;
+        }
+
         //TODO : fallback on JTS until implemented
         return jts(geom1).disjoint(jts(geom2));
     }
@@ -218,6 +265,11 @@ public final class GeometryProcessor {
     @UML(identifier="equals", specification=ISO_19107) // section 6.4.8.8, 
6.4.4.30
     //@UML(identifier="3Dequals", specification=ISO_19107) // section 6.4.9
     public boolean equal(Geometry geom1, Geometry geom2) throws 
OperationException {
+        if (geom1.isEmpty() || geom2.isEmpty()) {
+            // The empty set being unique, any two empty geometries are equal 
and nothing else is.
+            return geom1.isEmpty() == geom2.isEmpty();
+        }
+
         //TODO : fallback on JTS until implemented
         return jts(geom1).equals(jts(geom2));
     }
@@ -228,6 +280,11 @@ public final class GeometryProcessor {
     @UML(identifier="intersects", specification=ISO_19107) // section 6.4.8.8, 
6.4.4.30
     //@UML(identifier="3Dintersects", specification=ISO_19107) // section 6.4.9
     public boolean intersects(Geometry geom1, Geometry geom2) throws 
OperationException {
+        if (geom1.isEmpty() || geom2.isEmpty()) {
+            // Negation of `disjoint(Geometry, Geometry)`.
+            return false;
+        }
+
         //TODO : fallback on JTS until implemented
         return jts(geom1).intersects(jts(geom2));
     }
@@ -299,6 +356,14 @@ public final class GeometryProcessor {
     @UML(identifier="within", specification=ISO_19107) // section 6.4.8.8
     //@UML(identifier="3Dwithin", specification=ISO_19107) // section 6.4.9
     public boolean within(Geometry geom1, Geometry geom2) throws 
OperationException {
+        if (geom1.isEmpty()) {
+            // The empty set is a subset of every geometry.
+            return true;
+        }
+        if (geom2.isEmpty()) {
+            // Converse of `contains(Geometry, Geometry)`: only the empty set 
is within the empty set.
+            return false;
+        }
 
         //TODO : fallback on JTS until implemented
         return jts(geom1).within(jts(geom2));
@@ -491,4 +556,12 @@ public final class GeometryProcessor {
     private static org.locationtech.jts.geom.Geometry jts(Geometry geom) {
         return Geometries.asJTS(geom, false, null);
     }
+
+    private static Unit getUnit(Geometry geometry) {
+        return getUnit(geometry.getCoordinateReferenceSystem());
+    }
+
+    private static Unit getUnit(CoordinateReferenceSystem crs) {
+        return crs.getCoordinateSystem().getAxis(0).getUnit();
+    }
 }
diff --git 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/EmptyTest.java
 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/EmptyTest.java
index 126ccd4703..4c16281527 100644
--- 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/EmptyTest.java
+++ 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/EmptyTest.java
@@ -16,310 +16,278 @@
  */
 package org.apache.sis.geometries;
 
+import java.util.Map;
+import org.apache.sis.geometry.AbstractEnvelope;
+import org.apache.sis.geometry.GeneralDirectPosition;
+import org.apache.sis.referencing.CommonCRS;
+import org.opengis.geometry.DirectPosition;
+import org.opengis.geometry.Envelope;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
 // Test dependencies
-import org.junit.jupiter.api.Disabled;
+import static org.junit.jupiter.api.Assertions.*;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Disabled;
 
 
 /**
  * Tests {@link Empty}.
  *
+ * <p>This class tests the behavior mandated by {@link Empty} on any 
implementation.
+ * Subclasses provide the implementation to test by implementing
+ * {@link #createEmpty(CoordinateReferenceSystem)}.</p>
+ *
  * @author Johann Sorel (Geomatys)
  */
-public class EmptyTest {
+public abstract class EmptyTest {
+    /**
+     * An arbitrary two-dimensional coordinate reference system used by the 
tests.
+     */
+    protected static final CoordinateReferenceSystem CRS_2D = 
CommonCRS.WGS84.normalizedGeographic();
+
+    /**
+     * An arbitrary three-dimensional coordinate reference system used by the 
tests.
+     */
+    protected static final CoordinateReferenceSystem CRS_3D = 
CommonCRS.WGS84.geographic3D();
+
+    /**
+     * Creates a new test case.
+     */
+    protected EmptyTest() {
+    }
+
+    /**
+     * Creates an empty geometry using the given coordinate reference system.
+     * The returned geometry shall report the given system as its
+     * {@linkplain Geometry#getCoordinateReferenceSystem() coordinate 
reference system}.
+     *
+     * @param  crs  the coordinate reference system of the geometry to create, 
not null.
+     * @return a new empty geometry, never null.
+     */
+    protected abstract Empty createEmpty(CoordinateReferenceSystem crs);
+
     /**
      * Test of {@code isEmpty()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
     public void testIsEmpty() {
+        assertTrue(createEmpty(CRS_2D).isEmpty());
     }
 
     /**
      * Test of {@code getGeometryType()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
     public void testGetGeometryType() {
+        assertEquals("EMPTY", createEmpty(CRS_2D).getGeometryType());
     }
 
     /**
      * Test of {@code getTopologicDimension()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
     public void testGetTopologicDimension() {
+        assertEquals(-1, createEmpty(CRS_2D).getTopologicDimension());
+        assertEquals(-1, createEmpty(CRS_3D).getTopologicDimension());
     }
 
     /**
      * Test of {@code isCycle()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
     public void testIsCycle() {
+        assertTrue(createEmpty(CRS_2D).isCycle(), "The boundary of the empty 
set is empty.");
     }
 
     /**
      * Test of {@code isSimple()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
     public void testIsSimple() {
+        assertTrue(createEmpty(CRS_2D).isSimple(), "The empty set has no 
anomalous position.");
     }
 
     /**
      * Test of {@code isValid()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
     public void testIsValid() {
+        assertTrue(createEmpty(CRS_2D).isValid());
     }
 
     /**
      * Test of {@code boundary()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
     public void testBoundary() {
+        final Empty empty = createEmpty(CRS_2D);
+        final Geometry boundary = empty.boundary();
+        assertSame(empty, boundary);
+        assertTrue(boundary.isEmpty());
     }
 
     /**
      * Test of {@code getClosure()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
     public void testGetClosure() {
+        final Empty empty = createEmpty(CRS_2D);
+        final Geometry closure = empty.getClosure();
+        assertSame(empty, closure);
+        assertTrue(closure.isEmpty());
     }
 
     /**
      * Test of {@code convexHull()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
     public void testConvexHull() {
-    }
-
-    /**
-     * Test of {@code buffer(double)}.
-     */
-    @Test
-    @Disabled("Not implemented yet.")
-    public void testBuffer_double() {
-    }
-
-    /**
-     * Test of {@code buffer(Length)}.
-     */
-    @Test
-    @Disabled("Not implemented yet.")
-    public void testBuffer_Length() {
+        final Empty empty = createEmpty(CRS_2D);
+        final Geometry hull = empty.convexHull();
+        assertSame(empty, hull);
+        assertTrue(hull.isEmpty());
     }
 
     /**
      * Test of {@code getCentroid()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
     public void testGetCentroid() {
+        assertNull(createEmpty(CRS_2D).getCentroid(), "The centroid of the 
empty set is undefined.");
     }
 
     /**
      * Test of {@code getRepresentativePoint()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
     public void testGetRepresentativePoint() {
-    }
-
-    /**
-     * Test of {@code distance(Geometry)}.
-     */
-    @Test
-    @Disabled("Not implemented yet.")
-    public void testDistance() {
-    }
-
-    /**
-     * Test of {@code intersection(Geometry)}.
-     */
-    @Test
-    @Disabled("Not implemented yet.")
-    public void testIntersection() {
-    }
-
-    /**
-     * Test of {@code union(Geometry)}.
-     */
-    @Test
-    @Disabled("Not implemented yet.")
-    public void testUnion() {
-    }
-
-    /**
-     * Test of {@code difference(Geometry)}.
-     */
-    @Test
-    @Disabled("Not implemented yet.")
-    public void testDifference() {
-    }
-
-    /**
-     * Test of {@code symDifference(Geometry)}.
-     */
-    @Test
-    @Disabled("Not implemented yet.")
-    public void testSymDifference() {
-    }
-
-    /**
-     * Test of {@code contains(DirectPosition)}.
-     */
-    @Test
-    @Disabled("Not implemented yet.")
-    public void testContains_DirectPosition() {
-    }
-
-    /**
-     * Test of {@code contains(Geometry)}.
-     */
-    @Test
-    @Disabled("Not implemented yet.")
-    public void testContains_Geometry() {
-    }
-
-    /**
-     * Test of {@code within(Geometry)}.
-     */
-    @Test
-    @Disabled("Not implemented yet.")
-    public void testWithin() {
-    }
-
-    /**
-     * Test of {@code equal(Geometry)}.
-     */
-    @Test
-    @Disabled("Not implemented yet.")
-    public void testEqual() {
-    }
-
-    /**
-     * Test of {@code disjoint(Geometry)}.
-     */
-    @Test
-    @Disabled("Not implemented yet.")
-    public void testDisjoint() {
-    }
-
-    /**
-     * Test of {@code intersects(Geometry)}.
-     */
-    @Test
-    @Disabled("Not implemented yet.")
-    public void testIntersects() {
+        assertNull(createEmpty(CRS_2D).getRepresentativePoint(), "The empty 
set has no interior position.");
     }
 
     /**
      * Test of {@code getCoordinateReferenceSystem()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
     public void testGetCoordinateReferenceSystem() {
+        assertEquals(CRS_2D, 
createEmpty(CRS_2D).getCoordinateReferenceSystem());
+        assertEquals(CRS_3D, 
createEmpty(CRS_3D).getCoordinateReferenceSystem());
     }
 
     /**
      * Test of {@code setCoordinateReferenceSystem(CoordinateReferenceSystem)}.
      */
     @Test
-    @Disabled("Not implemented yet.")
     public void testSetCoordinateReferenceSystem() {
-    }
-
-    /**
-     * Test of {@code getMetadata()}.
-     */
-    @Test
-    @Disabled("Not implemented yet.")
-    public void testGetMetadata() {
+        final Empty empty = createEmpty(CRS_2D);
+        try {
+            empty.setCoordinateReferenceSystem(CRS_3D);
+        } catch (UnsupportedOperationException e) {
+            // Immutable implementation. The geometry shall then be left 
unchanged.
+            assertEquals(CRS_2D, empty.getCoordinateReferenceSystem());
+            return;
+        }
+        assertEquals(CRS_3D, empty.getCoordinateReferenceSystem());
     }
 
     /**
      * Test of {@code getAttributesType()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
     public void testGetAttributesType() {
+        final Empty empty = createEmpty(CRS_2D);
+        final AttributesType type = empty.getAttributesType();
+        assertNotNull(type);
+        assertNotNull(type.getAttributeNames());
+        /*
+         * The positions of a geometry use the coordinate reference system of 
that geometry,
+         * as stated in the constraints of the `Geometry` interface.
+         */
+        assertEquals(CRS_2D, 
type.getAttributeSystem(AttributesType.ATT_POSITION).getCoordinateReferenceSystem());
     }
 
     /**
      * Test of {@code getDimension()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
     public void testGetDimension() {
+        assertEquals(2, createEmpty(CRS_2D).getDimension());
+        assertEquals(3, createEmpty(CRS_3D).getDimension());
     }
 
     /**
      * Test of {@code getDimension(DirectPosition)}.
      */
     @Test
-    @Disabled("Not implemented yet.")
     public void testGetDimension_DirectPosition() {
+        final Empty empty = createEmpty(CRS_2D);
+        assertEquals(-1, empty.getDimension(null), "Dimension of the whole 
geometry.");
+        /*
+         * TODO: the empty set has no interior position, therefore no position 
where the dimension
+         * is unambiguous. Replace this check if a value is defined for that 
case.
+         */
+        final DirectPosition position = new GeneralDirectPosition(CRS_2D);
+        assertThrows(UnsupportedOperationException.class, () -> 
empty.getDimension(position));
     }
 
     /**
      * Test of {@code is3D()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
     public void testIs3D() {
+        assertFalse(createEmpty(CRS_2D).is3D());
+        assertTrue (createEmpty(CRS_3D).is3D());
     }
 
     /**
      * Test of {@code getSpatialDimension()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
     public void testGetSpatialDimension() {
+        assertEquals(2, createEmpty(CRS_2D).getSpatialDimension());
+        assertEquals(3, createEmpty(CRS_3D).getSpatialDimension());
     }
 
     /**
      * Test of {@code getBoundaryType()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
+    @Disabled
     public void testGetBoundaryType() {
-    }
-
-    /**
-     * Test of {@code getGeometryType2()}.
-     */
-    @Test
-    @Disabled("Not implemented yet.")
-    public void testGetGeometryType2() {
+        final Empty empty = createEmpty(CRS_2D);
+        /*
+         * TODO: `Geometry.getBoundaryType()` is not implemented yet. The 
empty geometry has no
+         * element, therefore no ambiguous position: every rule gives the same 
empty boundary.
+         */
+        assertThrows(UnsupportedOperationException.class, () -> 
empty.getBoundaryType());
     }
 
     /**
      * Test of {@code getEnvelope()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
     public void testGetEnvelope() {
-    }
-
-    /**
-     * Test of {@code getMaximalComplex()}.
-     */
-    @Test
-    @Disabled("Not implemented yet.")
-    public void testGetMaximalComplex() {
+        final Empty empty = createEmpty(CRS_2D);
+        final Envelope envelope = empty.getEnvelope();
+        assertNotNull(envelope);
+        assertEquals(CRS_2D, envelope.getCoordinateReferenceSystem());
+        assertEquals(2, envelope.getDimension());
+        assertTrue(AbstractEnvelope.castOrCopy(envelope).isEmpty(),
+                   "The envelope of an empty geometry contains no position.");
     }
 
     /**
      * Test of {@code userProperties()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
     public void testUserProperties() {
+        final Empty empty = createEmpty(CRS_2D);
+        final Map<String,Object> properties = empty.userProperties();
+        if (properties == null) {
+            // Allowed by the contract: the geometry cannot store additional 
information.
+            return;
+        }
+        assertTrue(properties.isEmpty(), "A new geometry shall have no user 
property.");
+        properties.put("A key", "A value");
+        assertEquals("A value", empty.userProperties().get("A key"));
     }
 }
diff --git 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/internal/shared/DefaultEmptyTest.java
 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/internal/shared/DefaultEmptyTest.java
index 1cc5a85e67..582942f5e6 100644
--- 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/internal/shared/DefaultEmptyTest.java
+++ 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/internal/shared/DefaultEmptyTest.java
@@ -16,6 +16,12 @@
  */
 package org.apache.sis.geometries.internal.shared;
 
+import org.apache.sis.geometries.AttributesType;
+import org.apache.sis.geometries.Empty;
+import org.apache.sis.maths.DataType;
+import org.apache.sis.maths.SampleSystem;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
 // Test dependencies
 import org.apache.sis.geometries.EmptyTest;
 
@@ -26,4 +32,19 @@ import org.apache.sis.geometries.EmptyTest;
  * @author Johann Sorel (Geomatys)
  */
 public class DefaultEmptyTest extends EmptyTest {
+    /**
+     * Creates a new test case.
+     */
+    public DefaultEmptyTest() {
+    }
+
+    /**
+     * Creates an empty geometry whose positions use the given coordinate 
reference system.
+     */
+    @Override
+    protected Empty createEmpty(final CoordinateReferenceSystem crs) {
+        final AttributesType.Template attType = new AttributesType.Template();
+        attType.addOrReplaceAttribute(AttributesType.ATT_POSITION, 
SampleSystem.of(crs), DataType.DOUBLE);
+        return new DefaultEmpty(attType);
+    }
 }
diff --git 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/BufferTest.java
 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/BufferTest.java
index 0a8ce8ff11..3d191952c6 100644
--- 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/BufferTest.java
+++ 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/BufferTest.java
@@ -18,8 +18,11 @@ package org.apache.sis.geometries.operation;
 
 import javax.measure.Quantity;
 import org.apache.sis.geometries.Geometry;
+import org.apache.sis.measure.Quantities;
+import org.apache.sis.measure.Units;
 
 // Test dependencies
+import static org.apache.sis.geometries.operation.TestData.EMPTY_1;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import org.junit.jupiter.api.Test;
@@ -31,27 +34,6 @@ import org.junit.jupiter.api.Test;
  * @author Johann Sorel (Geomatys)
  */
 public class BufferTest {
-    /**
-     * The inputs and expected result of a single test of {@code 
buffer(Geometry, double)}.
-     *
-     * @param input    the geometry on which the operation is invoked.
-     * @param distance the buffer distance.
-     * @param expected the expected result, or {@code null} if an exception is 
expected.
-     * @param error    the type of the expected exception, or {@code null} if 
the operation should succeed.
-     */
-    private record Entry(Geometry input,
-                         double distance,
-                         Geometry expected,
-                         Class<? extends Exception> error)
-    {
-    }
-
-    /**
-     * All test cases of {@code buffer(Geometry, double)}.
-     */
-    private static final Entry[] ENTRIES = {
-    };
-
     /**
      * The inputs and expected result of a single test of {@code 
buffer(Geometry, Quantity)}.
      *
@@ -60,7 +42,7 @@ public class BufferTest {
      * @param expected the expected result, or {@code null} if an exception is 
expected.
      * @param error    the type of the expected exception, or {@code null} if 
the operation should succeed.
      */
-    private record RadiusEntry(Geometry input,
+    private record TestCase(Geometry input,
                                Quantity<?> radius,
                                Geometry expected,
                                Class<? extends Exception> error)
@@ -70,7 +52,16 @@ public class BufferTest {
     /**
      * All test cases of {@code buffer(Geometry, Quantity)}.
      */
-    private static final RadiusEntry[] RADIUS_ENTRIES = {
+    private static final TestCase[] RADIUS_ENTRIES = {
+        /*
+         * There is no position to grow a buffer around, therefore the buffer 
of an empty geometry
+         * is the empty geometry. This holds for a negative radius, which 
shrinks a geometry, and
+         * for a dimensionless radius, which is interpreted in the units of 
the coordinate system.
+         */
+        new TestCase(EMPTY_1, Quantities.create( 10, Units.METRE), EMPTY_1, 
null),
+        new TestCase(EMPTY_1, Quantities.create(  0, Units.METRE), EMPTY_1, 
null),
+        new TestCase(EMPTY_1, Quantities.create(-10, Units.METRE), EMPTY_1, 
null),
+        new TestCase(EMPTY_1, Quantities.create( 10, Units.UNITY), EMPTY_1, 
null)
     };
 
     /**
@@ -78,7 +69,7 @@ public class BufferTest {
      */
     @Test
     public void testBufferByRadius() {
-        for (final RadiusEntry entry : RADIUS_ENTRIES) {
+        for (final TestCase entry : RADIUS_ENTRIES) {
             try {
                 final Geometry result = new 
GeometryProcessor().buffer(entry.input(), entry.radius());
                 assertNull(entry.error(), "An exception was expected.");
diff --git 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/ContainsTest.java
 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/ContainsTest.java
index b96ff21b4d..4b9195e711 100644
--- 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/ContainsTest.java
+++ 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/ContainsTest.java
@@ -17,9 +17,11 @@
 package org.apache.sis.geometries.operation;
 
 import org.apache.sis.geometries.Geometry;
-import org.opengis.geometry.DirectPosition;
 
 // Test dependencies
+import static org.apache.sis.geometries.operation.TestData.EMPTY_1;
+import static org.apache.sis.geometries.operation.TestData.EMPTY_2;
+import static org.apache.sis.geometries.operation.TestData.NON_EMPTY;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import org.junit.jupiter.api.Test;
@@ -31,45 +33,6 @@ import org.junit.jupiter.api.Test;
  * @author Johann Sorel (Geomatys)
  */
 public class ContainsTest {
-    /**
-     * The inputs and expected result of a single test of {@code 
contains(Geometry, DirectPosition)}.
-     *
-     * @param input    the geometry on which the operation is invoked.
-     * @param element  the position to test for inclusion.
-     * @param expected the expected result, or {@code null} if an exception is 
expected.
-     * @param error    the type of the expected exception, or {@code null} if 
the operation should succeed.
-     */
-    private record PositionEntry(Geometry input,
-                                 DirectPosition element,
-                                 Boolean expected,
-                                 Class<? extends Exception> error)
-    {
-    }
-
-    /**
-     * All test cases of {@code contains(Geometry, DirectPosition)}.
-     */
-    private static final PositionEntry[] POSITION_ENTRIES = {
-    };
-
-    /**
-     * Tests {@code contains(Geometry, DirectPosition)} on all declared test 
cases.
-     */
-    @Test
-    public void testContainsPosition() {
-        for (final PositionEntry entry : POSITION_ENTRIES) {
-            try {
-                final boolean result = new 
GeometryProcessor().contains(entry.input(), entry.element());
-                assertNull(entry.error(), "An exception was expected.");
-                assertEquals(entry.expected(), result);
-            } catch (Exception ex) {
-                if (entry.error() == null || !entry.error().isInstance(ex)) {
-                    throw new AssertionError("Unexpected exception for " + 
entry, ex);
-                }
-            }
-        }
-    }
-
     /**
      * The inputs and expected result of a single test of {@code 
contains(Geometry, Geometry)}.
      *
@@ -78,7 +41,7 @@ public class ContainsTest {
      * @param expected the expected result, or {@code null} if an exception is 
expected.
      * @param error    the type of the expected exception, or {@code null} if 
the operation should succeed.
      */
-    private record Entry(Geometry input,
+    private record TestCase(Geometry input,
                          Geometry other,
                          Boolean expected,
                          Class<? extends Exception> error)
@@ -88,7 +51,12 @@ public class ContainsTest {
     /**
      * All test cases of {@code contains(Geometry, Geometry)}.
      */
-    private static final Entry[] ENTRIES = {
+    private static final TestCase[] ENTRIES = {
+        // The empty set is a superset of itself only, and a subset of every 
geometry.
+        new TestCase(EMPTY_1,   EMPTY_1,   true,  null),
+        new TestCase(EMPTY_1,   EMPTY_2,   true,  null),
+        new TestCase(EMPTY_1,   NON_EMPTY, false, null),
+        new TestCase(NON_EMPTY, EMPTY_1,   true,  null)
     };
 
     /**
@@ -96,7 +64,7 @@ public class ContainsTest {
      */
     @Test
     public void testContains() {
-        for (final Entry entry : ENTRIES) {
+        for (final TestCase entry : ENTRIES) {
             try {
                 final boolean result = new 
GeometryProcessor().contains(entry.input(), entry.other());
                 assertNull(entry.error(), "An exception was expected.");
diff --git 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/ConvexHullTest.java
 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/ConvexHullTest.java
index d016a3df9b..17b5051d5b 100644
--- 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/ConvexHullTest.java
+++ 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/ConvexHullTest.java
@@ -37,7 +37,7 @@ public class ConvexHullTest {
      * @param expected the expected result, or {@code null} if an exception is 
expected.
      * @param error    the type of the expected exception, or {@code null} if 
the operation should succeed.
      */
-    private record Entry(Geometry input,
+    private record TestCase(Geometry input,
                          Geometry expected,
                          Class<? extends Exception> error)
     {
@@ -46,7 +46,7 @@ public class ConvexHullTest {
     /**
      * All test cases of {@code convexHull(Geometry)}.
      */
-    private static final Entry[] ENTRIES = {
+    private static final TestCase[] ENTRIES = {
     };
 
     /**
@@ -54,7 +54,7 @@ public class ConvexHullTest {
      */
     @Test
     public void testConvexHull() {
-        for (final Entry entry : ENTRIES) {
+        for (final TestCase entry : ENTRIES) {
             try {
                 final Geometry result = new 
GeometryProcessor().convexHull(entry.input());
                 assertNull(entry.error(), "An exception was expected.");
diff --git 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/CrossesTest.java
 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/CrossesTest.java
index f23a3d68f1..65f8e9ffc8 100644
--- 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/CrossesTest.java
+++ 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/CrossesTest.java
@@ -38,7 +38,7 @@ public class CrossesTest {
      * @param expected the expected result, or {@code null} if an exception is 
expected.
      * @param error    the type of the expected exception, or {@code null} if 
the operation should succeed.
      */
-    private record Entry(Geometry input,
+    private record TestCase(Geometry input,
                          Geometry other,
                          Boolean expected,
                          Class<? extends Exception> error)
@@ -48,7 +48,7 @@ public class CrossesTest {
     /**
      * All test cases of {@code crosses(Geometry, Geometry)}.
      */
-    private static final Entry[] ENTRIES = {
+    private static final TestCase[] ENTRIES = {
     };
 
     /**
@@ -56,7 +56,7 @@ public class CrossesTest {
      */
     @Test
     public void testCrosses() {
-        for (final Entry entry : ENTRIES) {
+        for (final TestCase entry : ENTRIES) {
             try {
                 final boolean result = new 
GeometryProcessor().crosses(entry.input(), entry.other());
                 assertNull(entry.error(), "An exception was expected.");
diff --git 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/DifferenceTest.java
 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/DifferenceTest.java
index 98f87b1072..c75014f99d 100644
--- 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/DifferenceTest.java
+++ 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/DifferenceTest.java
@@ -19,6 +19,9 @@ package org.apache.sis.geometries.operation;
 import org.apache.sis.geometries.Geometry;
 
 // Test dependencies
+import static org.apache.sis.geometries.operation.TestData.EMPTY_1;
+import static org.apache.sis.geometries.operation.TestData.EMPTY_2;
+import static org.apache.sis.geometries.operation.TestData.NON_EMPTY;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import org.junit.jupiter.api.Test;
@@ -38,7 +41,7 @@ public class DifferenceTest {
      * @param expected the expected result, or {@code null} if an exception is 
expected.
      * @param error    the type of the expected exception, or {@code null} if 
the operation should succeed.
      */
-    private record Entry(Geometry input,
+    private record TestCase(Geometry input,
                          Geometry other,
                          Geometry expected,
                          Class<? extends Exception> error)
@@ -48,7 +51,11 @@ public class DifferenceTest {
     /**
      * All test cases of {@code difference(Geometry, Geometry)}.
      */
-    private static final Entry[] ENTRIES = {
+    private static final TestCase[] ENTRIES = {
+        // ∅ − A = ∅ and A − ∅ = A, which are both the first operand.
+        new TestCase(EMPTY_1,   NON_EMPTY, EMPTY_1,   null),
+        new TestCase(NON_EMPTY, EMPTY_1,   NON_EMPTY, null),
+        new TestCase(EMPTY_1,   EMPTY_2,   EMPTY_1,   null)
     };
 
     /**
@@ -56,7 +63,7 @@ public class DifferenceTest {
      */
     @Test
     public void testDifference() {
-        for (final Entry entry : ENTRIES) {
+        for (final TestCase entry : ENTRIES) {
             try {
                 final Geometry result = new 
GeometryProcessor().difference(entry.input(), entry.other());
                 assertNull(entry.error(), "An exception was expected.");
diff --git 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/DisjointTest.java
 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/DisjointTest.java
index 115210352d..0f77c511dc 100644
--- 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/DisjointTest.java
+++ 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/DisjointTest.java
@@ -19,6 +19,9 @@ package org.apache.sis.geometries.operation;
 import org.apache.sis.geometries.Geometry;
 
 // Test dependencies
+import static org.apache.sis.geometries.operation.TestData.EMPTY_1;
+import static org.apache.sis.geometries.operation.TestData.EMPTY_2;
+import static org.apache.sis.geometries.operation.TestData.NON_EMPTY;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import org.junit.jupiter.api.Test;
@@ -38,7 +41,7 @@ public class DisjointTest {
      * @param expected the expected result, or {@code null} if an exception is 
expected.
      * @param error    the type of the expected exception, or {@code null} if 
the operation should succeed.
      */
-    private record Entry(Geometry input,
+    private record TestCase(Geometry input,
                          Geometry other,
                          Boolean expected,
                          Class<? extends Exception> error)
@@ -48,7 +51,12 @@ public class DisjointTest {
     /**
      * All test cases of {@code disjoint(Geometry, Geometry)}.
      */
-    private static final Entry[] ENTRIES = {
+    private static final TestCase[] ENTRIES = {
+        // The empty set has no position in common with any geometry.
+        new TestCase(EMPTY_1,   NON_EMPTY, true, null),
+        new TestCase(NON_EMPTY, EMPTY_1,   true, null),
+        new TestCase(EMPTY_1,   EMPTY_1,   true, null),
+        new TestCase(EMPTY_1,   EMPTY_2,   true, null)
     };
 
     /**
@@ -56,7 +64,7 @@ public class DisjointTest {
      */
     @Test
     public void testDisjoint() {
-        for (final Entry entry : ENTRIES) {
+        for (final TestCase entry : ENTRIES) {
             try {
                 final boolean result = new 
GeometryProcessor().disjoint(entry.input(), entry.other());
                 assertNull(entry.error(), "An exception was expected.");
diff --git 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/DistanceTest.java
 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/DistanceTest.java
index 516ffe675f..0961b48c82 100644
--- 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/DistanceTest.java
+++ 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/DistanceTest.java
@@ -21,11 +21,14 @@ import org.apache.sis.geometries.Geometry;
 import org.apache.sis.geometries.GeometryFactory;
 import org.apache.sis.geometries.Point;
 import org.apache.sis.maths.SampleSystem;
+import org.apache.sis.measure.Quantities;
 import org.apache.sis.measure.Units;
 import org.apache.sis.referencing.CommonCRS;
+import static org.apache.sis.geometries.operation.TestData.EMPTY_1;
+import static org.apache.sis.geometries.operation.TestData.EMPTY_2;
+import static org.apache.sis.geometries.operation.TestData.NON_EMPTY;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNull;
-import static org.junit.jupiter.api.Assertions.fail;
 import org.junit.jupiter.api.Test;
 
 /**
@@ -37,38 +40,23 @@ public class DistanceTest {
     private static final SampleSystem CRS2D = 
SampleSystem.of(CommonCRS.WGS84.geographic());
 
     /**
-     * Test point to point distance.
+     * Two points at the same position, and a third one at a distance of 1 
along the second axis.
      */
-    @Test
-    public void PointPoint() {
-
-        { //different CRS
-            final Point point1 = 
GeometryFactory.createPoint(CommonCRS.WGS84.geographic());
-            final Point point2 = 
GeometryFactory.createPoint(CommonCRS.WGS84.normalizedGeographic());
-            try {
-                new GeometryProcessor().distance(point1, point2);
-                fail("evaluation should fail");
-            } catch (OperationException ex) {
-                //ok
-            }
-        }
+    private static final Point POINT_10_5     = 
GeometryFactory.createPoint(CRS2D, 10.0, 5.0);
+    private static final Point POINT_10_5_BIS = 
GeometryFactory.createPoint(CRS2D, 10.0, 5.0);
+    private static final Point POINT_10_6     = 
GeometryFactory.createPoint(CRS2D, 10.0, 6.0);
 
-        { //at same position
-            final Point point1 = GeometryFactory.createPoint(CRS2D, 10.0, 5.0);
-            final Point point2 = GeometryFactory.createPoint(CRS2D, 10.0, 5.0);
-            final Quantity<?> distance = new 
GeometryProcessor().distance(point1, point2);
-            assertEquals(Units.METRE, distance.getUnit());
-            assertEquals(0.0, distance.getValue().doubleValue(), 0.0);
-        }
+    /**
+     * Two points using coordinate reference systems which differ by their 
axis order.
+     */
+    private static final Point POINT_GEOGRAPHIC = 
GeometryFactory.createPoint(CommonCRS.WGS84.geographic());
+    private static final Point POINT_NORMALIZED = 
GeometryFactory.createPoint(CommonCRS.WGS84.normalizedGeographic());
 
-        { //at 1.0 of distance
-            final Point point1 = GeometryFactory.createPoint(CRS2D, 10, 5);
-            final Point point2 = GeometryFactory.createPoint(CRS2D, 10, 6);
-            final Quantity<?> distance = new 
GeometryProcessor().distance(point1, point2);
-            assertEquals(Units.METRE, distance.getUnit());
-            assertEquals(1.0, distance.getValue().doubleValue(), 0.0);
-        }
-    }
+    /**
+     * The distance from an empty geometry to any geometry, including itself, 
is infinite.
+     * The quantity is dimensionless, the empty set having no measurement unit 
to report.
+     */
+    private static final Quantity<?> INFINITY = 
Quantities.create(Double.POSITIVE_INFINITY, Units.UNITY);
 
     /**
      * The inputs and expected result of a single test of {@code 
distance(Geometry, Geometry)}.
@@ -78,7 +66,7 @@ public class DistanceTest {
      * @param expected the expected result, or {@code null} if an exception is 
expected.
      * @param error    the type of the expected exception, or {@code null} if 
the operation should succeed.
      */
-    private record Entry(Geometry input,
+    private record TestCase(Geometry input,
                          Geometry other,
                          Quantity<?> expected,
                          Class<? extends Exception> error)
@@ -88,7 +76,28 @@ public class DistanceTest {
     /**
      * All test cases of {@code distance(Geometry, Geometry)}.
      */
-    private static final Entry[] ENTRIES = {
+    private static final TestCase[] ENTRIES = {
+        /*
+         * Point to point. The distance is zero when the two points are at the 
same position, and is
+         * otherwise the Pythagorean distance computed in the units of the 
coordinate system axes.
+         * The unit reported is metre in both cases; see the limitation 
documented on
+         * `GeometryProcessor.distance(Geometry, Geometry)`.
+         */
+        new TestCase(POINT_10_5, POINT_10_5_BIS, Quantities.create(0.0, 
Units.DEGREE), null),
+        new TestCase(POINT_10_5, POINT_10_6,     Quantities.create(1.0, 
Units.DEGREE), null),
+        new TestCase(POINT_10_6, POINT_10_5,     Quantities.create(1.0, 
Units.DEGREE), null),
+        /*
+         * The operation computes in the coordinate reference system of the 
first geometry,
+         * and does not transform the second one.
+         */
+        new TestCase(POINT_GEOGRAPHIC, POINT_NORMALIZED, null, 
OperationException.class),
+        /*
+         * The distance from an empty geometry to any geometry, including 
itself, is infinite.
+         */
+        new TestCase(EMPTY_1,   NON_EMPTY, INFINITY, null),
+        new TestCase(NON_EMPTY, EMPTY_1,   INFINITY, null),
+        new TestCase(EMPTY_1,   EMPTY_1,   INFINITY, null),
+        new TestCase(EMPTY_1,   EMPTY_2,   INFINITY, null)
     };
 
     /**
@@ -96,7 +105,7 @@ public class DistanceTest {
      */
     @Test
     public void testDistance() {
-        for (final Entry entry : ENTRIES) {
+        for (final TestCase entry : ENTRIES) {
             try {
                 final Quantity<?> result = new 
GeometryProcessor().distance(entry.input(), entry.other());
                 assertNull(entry.error(), "An exception was expected.");
diff --git 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/EqualTest.java
 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/EqualTest.java
index b5adee4450..23e6730cbd 100644
--- 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/EqualTest.java
+++ 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/EqualTest.java
@@ -19,6 +19,9 @@ package org.apache.sis.geometries.operation;
 import org.apache.sis.geometries.Geometry;
 
 // Test dependencies
+import static org.apache.sis.geometries.operation.TestData.EMPTY_1;
+import static org.apache.sis.geometries.operation.TestData.EMPTY_2;
+import static org.apache.sis.geometries.operation.TestData.NON_EMPTY;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import org.junit.jupiter.api.Test;
@@ -38,7 +41,7 @@ public class EqualTest {
      * @param expected the expected result, or {@code null} if an exception is 
expected.
      * @param error    the type of the expected exception, or {@code null} if 
the operation should succeed.
      */
-    private record Entry(Geometry input,
+    private record TestCase(Geometry input,
                          Geometry other,
                          Boolean expected,
                          Class<? extends Exception> error)
@@ -48,7 +51,12 @@ public class EqualTest {
     /**
      * All test cases of {@code equal(Geometry, Geometry)}.
      */
-    private static final Entry[] ENTRIES = {
+    private static final TestCase[] ENTRIES = {
+        // The empty set being unique, any two empty geometries are equal and 
nothing else is.
+        new TestCase(EMPTY_1,   EMPTY_1,   true,  null),
+        new TestCase(EMPTY_1,   EMPTY_2,   true,  null),
+        new TestCase(EMPTY_1,   NON_EMPTY, false, null),
+        new TestCase(NON_EMPTY, EMPTY_1,   false, null)
     };
 
     /**
@@ -56,7 +64,7 @@ public class EqualTest {
      */
     @Test
     public void testEqual() {
-        for (final Entry entry : ENTRIES) {
+        for (final TestCase entry : ENTRIES) {
             try {
                 final boolean result = new 
GeometryProcessor().equal(entry.input(), entry.other());
                 assertNull(entry.error(), "An exception was expected.");
diff --git 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/IntersectionTest.java
 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/IntersectionTest.java
index 1043f79123..122f0759e2 100644
--- 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/IntersectionTest.java
+++ 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/IntersectionTest.java
@@ -22,6 +22,9 @@ import org.apache.sis.maths.NDArrays;
 import org.apache.sis.maths.SampleSystem;
 import org.apache.sis.geometries.mesh.MeshPrimitive;
 import org.apache.sis.referencing.CommonCRS;
+import static org.apache.sis.geometries.operation.TestData.EMPTY_1;
+import static org.apache.sis.geometries.operation.TestData.EMPTY_2;
+import static org.apache.sis.geometries.operation.TestData.NON_EMPTY;
 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNull;
@@ -150,7 +153,7 @@ public class IntersectionTest {
      * @param expected the expected result, or {@code null} if an exception is 
expected.
      * @param error    the type of the expected exception, or {@code null} if 
the operation should succeed.
      */
-    private record Entry(Geometry input,
+    private record TestCase(Geometry input,
                          Geometry other,
                          Geometry expected,
                          Class<? extends Exception> error)
@@ -160,7 +163,11 @@ public class IntersectionTest {
     /**
      * All test cases of {@code intersection(Geometry, Geometry)}.
      */
-    private static final Entry[] ENTRIES = {
+    private static final TestCase[] ENTRIES = {
+        // ∅ ∩ A = ∅ and A ∩ ∅ = ∅: the result is the operand which is already 
empty.
+        new TestCase(EMPTY_1,   NON_EMPTY, EMPTY_1, null),
+        new TestCase(NON_EMPTY, EMPTY_1,   EMPTY_1, null),
+        new TestCase(EMPTY_1,   EMPTY_2,   EMPTY_1, null)
     };
 
     /**
@@ -168,7 +175,7 @@ public class IntersectionTest {
      */
     @Test
     public void testIntersection() {
-        for (final Entry entry : ENTRIES) {
+        for (final TestCase entry : ENTRIES) {
             try {
                 final Geometry result = new 
GeometryProcessor().intersection(entry.input(), entry.other());
                 assertNull(entry.error(), "An exception was expected.");
diff --git 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/IntersectsTest.java
 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/IntersectsTest.java
index 76f2979ecd..4a58e76211 100644
--- 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/IntersectsTest.java
+++ 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/IntersectsTest.java
@@ -19,6 +19,9 @@ package org.apache.sis.geometries.operation;
 import org.apache.sis.geometries.Geometry;
 
 // Test dependencies
+import static org.apache.sis.geometries.operation.TestData.EMPTY_1;
+import static org.apache.sis.geometries.operation.TestData.EMPTY_2;
+import static org.apache.sis.geometries.operation.TestData.NON_EMPTY;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import org.junit.jupiter.api.Test;
@@ -38,7 +41,7 @@ public class IntersectsTest {
      * @param expected the expected result, or {@code null} if an exception is 
expected.
      * @param error    the type of the expected exception, or {@code null} if 
the operation should succeed.
      */
-    private record Entry(Geometry input,
+    private record TestCase(Geometry input,
                          Geometry other,
                          Boolean expected,
                          Class<? extends Exception> error)
@@ -48,7 +51,12 @@ public class IntersectsTest {
     /**
      * All test cases of {@code intersects(Geometry, Geometry)}.
      */
-    private static final Entry[] ENTRIES = {
+    private static final TestCase[] ENTRIES = {
+        // Negation of `disjoint(Geometry, Geometry)`.
+        new TestCase(EMPTY_1,   NON_EMPTY, false, null),
+        new TestCase(NON_EMPTY, EMPTY_1,   false, null),
+        new TestCase(EMPTY_1,   EMPTY_1,   false, null),
+        new TestCase(EMPTY_1,   EMPTY_2,   false, null)
     };
 
     /**
@@ -56,7 +64,7 @@ public class IntersectsTest {
      */
     @Test
     public void testIntersects() {
-        for (final Entry entry : ENTRIES) {
+        for (final TestCase entry : ENTRIES) {
             try {
                 final boolean result = new 
GeometryProcessor().intersects(entry.input(), entry.other());
                 assertNull(entry.error(), "An exception was expected.");
diff --git 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/LocateAlongTest.java
 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/LocateAlongTest.java
index b0520f2011..029c98ccc9 100644
--- 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/LocateAlongTest.java
+++ 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/LocateAlongTest.java
@@ -38,7 +38,7 @@ public class LocateAlongTest {
      * @param expected the expected result, or {@code null} if an exception is 
expected.
      * @param error    the type of the expected exception, or {@code null} if 
the operation should succeed.
      */
-    private record Entry(Geometry input,
+    private record TestCase(Geometry input,
                          String attName,
                          double mValue,
                          Geometry expected,
@@ -49,7 +49,7 @@ public class LocateAlongTest {
     /**
      * All test cases of {@code locateAlong(Geometry, double)}.
      */
-    private static final Entry[] ENTRIES = {
+    private static final TestCase[] ENTRIES = {
     };
 
     /**
@@ -57,7 +57,7 @@ public class LocateAlongTest {
      */
     @Test
     public void testLocateAlong() {
-        for (final Entry entry : ENTRIES) {
+        for (final TestCase entry : ENTRIES) {
             try {
                 final Geometry result = new 
GeometryProcessor().locateAlong(entry.input(), entry.attName(), entry.mValue());
                 assertNull(entry.error(), "An exception was expected.");
diff --git 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/LocateBetweenTest.java
 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/LocateBetweenTest.java
index e423d2dff2..8497705722 100644
--- 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/LocateBetweenTest.java
+++ 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/LocateBetweenTest.java
@@ -39,7 +39,7 @@ public class LocateBetweenTest {
      * @param expected the expected result, or {@code null} if an exception is 
expected.
      * @param error    the type of the expected exception, or {@code null} if 
the operation should succeed.
      */
-    private record Entry(Geometry input,
+    private record TestCase(Geometry input,
                          String attName,
                          double mStart,
                          double mEnd,
@@ -51,7 +51,7 @@ public class LocateBetweenTest {
     /**
      * All test cases of {@code locateBetween(Geometry, double, double)}.
      */
-    private static final Entry[] ENTRIES = {
+    private static final TestCase[] ENTRIES = {
     };
 
     /**
@@ -59,7 +59,7 @@ public class LocateBetweenTest {
      */
     @Test
     public void testLocateBetween() {
-        for (final Entry entry : ENTRIES) {
+        for (final TestCase entry : ENTRIES) {
             try {
                 final Geometry result = new 
GeometryProcessor().locateBetween(entry.input(), entry.attName(), 
entry.mStart(), entry.mEnd());
                 assertNull(entry.error(), "An exception was expected.");
diff --git 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/OverlapsTest.java
 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/OverlapsTest.java
index 396c7eaee7..8425ecce2c 100644
--- 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/OverlapsTest.java
+++ 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/OverlapsTest.java
@@ -38,7 +38,7 @@ public class OverlapsTest {
      * @param expected the expected result, or {@code null} if an exception is 
expected.
      * @param error    the type of the expected exception, or {@code null} if 
the operation should succeed.
      */
-    private record Entry(Geometry input,
+    private record TestCase(Geometry input,
                          Geometry other,
                          Boolean expected,
                          Class<? extends Exception> error)
@@ -48,7 +48,7 @@ public class OverlapsTest {
     /**
      * All test cases of {@code overlaps(Geometry, Geometry)}.
      */
-    private static final Entry[] ENTRIES = {
+    private static final TestCase[] ENTRIES = {
     };
 
     /**
@@ -56,7 +56,7 @@ public class OverlapsTest {
      */
     @Test
     public void testOverlaps() {
-        for (final Entry entry : ENTRIES) {
+        for (final TestCase entry : ENTRIES) {
             try {
                 final boolean result = new 
GeometryProcessor().overlaps(entry.input(), entry.other());
                 assertNull(entry.error(), "An exception was expected.");
diff --git 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/RelateTest.java
 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/RelateTest.java
index bd60e8df0c..e777cbd224 100644
--- 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/RelateTest.java
+++ 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/RelateTest.java
@@ -40,7 +40,7 @@ public class RelateTest {
      * @param expected the expected result, or {@code null} if an exception is 
expected.
      * @param error    the type of the expected exception, or {@code null} if 
the operation should succeed.
      */
-    private record Entry(Geometry input,
+    private record TestCase(Geometry input,
                          Geometry other,
                          DE9IM matrix,
                          Boolean expected,
@@ -51,7 +51,7 @@ public class RelateTest {
     /**
      * All test cases of {@code relate(Geometry, Geometry, DE9IM)}.
      */
-    private static final Entry[] ENTRIES = {
+    private static final TestCase[] ENTRIES = {
     };
 
     /**
@@ -59,7 +59,7 @@ public class RelateTest {
      */
     @Test
     public void testRelate() {
-        for (final Entry entry : ENTRIES) {
+        for (final TestCase entry : ENTRIES) {
             try {
                 final boolean result = new 
GeometryProcessor().relate(entry.input(), entry.other(), entry.matrix());
                 assertNull(entry.error(), "An exception was expected.");
diff --git 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/SymDifferenceTest.java
 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/SymDifferenceTest.java
index c4b91aa9d5..ba56d98c1f 100644
--- 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/SymDifferenceTest.java
+++ 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/SymDifferenceTest.java
@@ -19,6 +19,9 @@ package org.apache.sis.geometries.operation;
 import org.apache.sis.geometries.Geometry;
 
 // Test dependencies
+import static org.apache.sis.geometries.operation.TestData.EMPTY_1;
+import static org.apache.sis.geometries.operation.TestData.EMPTY_2;
+import static org.apache.sis.geometries.operation.TestData.NON_EMPTY;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import org.junit.jupiter.api.Test;
@@ -38,7 +41,7 @@ public class SymDifferenceTest {
      * @param expected the expected result, or {@code null} if an exception is 
expected.
      * @param error    the type of the expected exception, or {@code null} if 
the operation should succeed.
      */
-    private record Entry(Geometry input,
+    private record TestCase(Geometry input,
                          Geometry other,
                          Geometry expected,
                          Class<? extends Exception> error)
@@ -48,7 +51,11 @@ public class SymDifferenceTest {
     /**
      * All test cases of {@code symDifference(Geometry, Geometry)}.
      */
-    private static final Entry[] ENTRIES = {
+    private static final TestCase[] ENTRIES = {
+        // (∅ − A) ∪ (A − ∅) = A: the result is the operand which is not empty.
+        new TestCase(EMPTY_1,   NON_EMPTY, NON_EMPTY, null),
+        new TestCase(NON_EMPTY, EMPTY_1,   NON_EMPTY, null),
+        new TestCase(EMPTY_1,   EMPTY_2,   EMPTY_2,   null)
     };
 
     /**
@@ -56,7 +63,7 @@ public class SymDifferenceTest {
      */
     @Test
     public void testSymDifference() {
-        for (final Entry entry : ENTRIES) {
+        for (final TestCase entry : ENTRIES) {
             try {
                 final Geometry result = new 
GeometryProcessor().symDifference(entry.input(), entry.other());
                 assertNull(entry.error(), "An exception was expected.");
diff --git 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/TestData.java
 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/TestData.java
new file mode 100644
index 0000000000..63e95356bd
--- /dev/null
+++ 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/TestData.java
@@ -0,0 +1,61 @@
+/*
+ * 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.geometries.operation;
+
+import org.apache.sis.geometries.Empty;
+import org.apache.sis.geometries.GeometryFactory;
+import org.apache.sis.geometries.Point;
+import org.apache.sis.referencing.CommonCRS;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
+
+/**
+ * Geometries shared by the test cases of the {@link GeometryProcessor} 
operations.
+ * They are immutable, which allows the test classes to declare them once and 
to
+ * reuse the same instances in every test case.
+ *
+ * @author Johann Sorel (Geomatys)
+ */
+public final class TestData {
+    /**
+     * The coordinate reference system of all the geometries declared in this 
class.
+     */
+    public static final CoordinateReferenceSystem CRS_2D = 
CommonCRS.WGS84.geographic();
+
+    /**
+     * An empty geometry. Together with {@link #EMPTY_2}, it allows to verify 
that the result of an
+     * operation on the empty set depends on the emptiness of the operands, 
not on their identity.
+     */
+    public static final Empty EMPTY_1 = GeometryFactory.createEmpty(CRS_2D);
+
+    /**
+     * Another empty geometry, distinct from {@link #EMPTY_1} but equal to it 
as a set of positions.
+     */
+    public static final Empty EMPTY_2 = GeometryFactory.createEmpty(CRS_2D);
+
+    /**
+     * An arbitrary geometry which is not empty, used as the other operand of 
the operations
+     * tested against the empty set.
+     */
+    public static final Point NON_EMPTY = GeometryFactory.createPoint(CRS_2D, 
10.0, 5.0);
+
+    /**
+     * Do not allow instantiation of this class.
+     */
+    private TestData() {
+    }
+}
diff --git 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/TouchesTest.java
 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/TouchesTest.java
index aeb1d64921..24770cfea4 100644
--- 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/TouchesTest.java
+++ 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/TouchesTest.java
@@ -38,7 +38,7 @@ public class TouchesTest {
      * @param expected the expected result, or {@code null} if an exception is 
expected.
      * @param error    the type of the expected exception, or {@code null} if 
the operation should succeed.
      */
-    private record Entry(Geometry input,
+    private record TestCase(Geometry input,
                          Geometry other,
                          Boolean expected,
                          Class<? extends Exception> error)
@@ -48,7 +48,7 @@ public class TouchesTest {
     /**
      * All test cases of {@code touches(Geometry, Geometry)}.
      */
-    private static final Entry[] ENTRIES = {
+    private static final TestCase[] ENTRIES = {
     };
 
     /**
@@ -56,7 +56,7 @@ public class TouchesTest {
      */
     @Test
     public void testTouches() {
-        for (final Entry entry : ENTRIES) {
+        for (final TestCase entry : ENTRIES) {
             try {
                 final boolean result = new 
GeometryProcessor().touches(entry.input(), entry.other());
                 assertNull(entry.error(), "An exception was expected.");
diff --git 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/TransformTest.java
 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/TransformTest.java
index 09eaec4a4c..cfbe376d7c 100644
--- 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/TransformTest.java
+++ 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/TransformTest.java
@@ -137,7 +137,7 @@ public class TransformTest {
      * @param expected the expected result, or {@code null} if an exception is 
expected.
      * @param error    the type of the expected exception, or {@code null} if 
the operation should succeed.
      */
-    private record Entry(Geometry input,
+    private record TestCase(Geometry input,
                          CoordinateReferenceSystem crs,
                          Geometry expected,
                          Class<? extends Exception> error)
@@ -147,7 +147,7 @@ public class TransformTest {
     /**
      * All test cases of {@code transform(Geometry, CoordinateReferenceSystem, 
MathTransform)}.
      */
-    private static final Entry[] ENTRIES = {
+    private static final TestCase[] ENTRIES = {
     };
 
     /**
@@ -155,7 +155,7 @@ public class TransformTest {
      */
     @Test
     public void testTransform() {
-        for (final Entry entry : ENTRIES) {
+        for (final TestCase entry : ENTRIES) {
             try {
                 final Geometry result = new 
GeometryProcessor().transform(entry.input(), entry.crs(), null);
                 assertNull(entry.error(), "An exception was expected.");
diff --git 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/UnionTest.java
 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/UnionTest.java
index 97652efed0..2465d5ae4c 100644
--- 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/UnionTest.java
+++ 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/UnionTest.java
@@ -19,6 +19,9 @@ package org.apache.sis.geometries.operation;
 import org.apache.sis.geometries.Geometry;
 
 // Test dependencies
+import static org.apache.sis.geometries.operation.TestData.EMPTY_1;
+import static org.apache.sis.geometries.operation.TestData.EMPTY_2;
+import static org.apache.sis.geometries.operation.TestData.NON_EMPTY;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import org.junit.jupiter.api.Test;
@@ -38,7 +41,7 @@ public class UnionTest {
      * @param expected the expected result, or {@code null} if an exception is 
expected.
      * @param error    the type of the expected exception, or {@code null} if 
the operation should succeed.
      */
-    private record Entry(Geometry input,
+    private record TestCase(Geometry input,
                          Geometry other,
                          Geometry expected,
                          Class<? extends Exception> error)
@@ -48,7 +51,11 @@ public class UnionTest {
     /**
      * All test cases of {@code union(Geometry, Geometry)}.
      */
-    private static final Entry[] ENTRIES = {
+    private static final TestCase[] ENTRIES = {
+        // ∅ ∪ A = A and A ∪ ∅ = A: the result is the operand which is not 
empty.
+        new TestCase(EMPTY_1,   NON_EMPTY, NON_EMPTY, null),
+        new TestCase(NON_EMPTY, EMPTY_1,   NON_EMPTY, null),
+        new TestCase(EMPTY_1,   EMPTY_2,   EMPTY_2,   null)
     };
 
     /**
@@ -56,7 +63,7 @@ public class UnionTest {
      */
     @Test
     public void testUnion() {
-        for (final Entry entry : ENTRIES) {
+        for (final TestCase entry : ENTRIES) {
             try {
                 final Geometry result = new 
GeometryProcessor().union(entry.input(), entry.other());
                 assertNull(entry.error(), "An exception was expected.");
diff --git 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/WithinDistanceTest.java
 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/WithinDistanceTest.java
index 5de7a80cb2..6125f59057 100644
--- 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/WithinDistanceTest.java
+++ 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/WithinDistanceTest.java
@@ -40,7 +40,7 @@ public class WithinDistanceTest {
      * @param expected the expected result, or {@code null} if an exception is 
expected.
      * @param error    the type of the expected exception, or {@code null} if 
the operation should succeed.
      */
-    private record Entry(Geometry input,
+    private record TestCase(Geometry input,
                          Geometry other,
                          Quantity<?> distance,
                          Boolean expected,
@@ -51,7 +51,7 @@ public class WithinDistanceTest {
     /**
      * All test cases of {@code withinDistance(Geometry, Geometry, Quantity)}.
      */
-    private static final Entry[] ENTRIES = {
+    private static final TestCase[] ENTRIES = {
     };
 
     /**
@@ -59,7 +59,7 @@ public class WithinDistanceTest {
      */
     @Test
     public void testWithinDistance() {
-        for (final Entry entry : ENTRIES) {
+        for (final TestCase entry : ENTRIES) {
             try {
                 final boolean result = new 
GeometryProcessor().withinDistance(entry.input(), entry.other(), 
entry.distance());
                 assertNull(entry.error(), "An exception was expected.");
diff --git 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/WithinTest.java
 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/WithinTest.java
index 3b125cfde4..cb1b4ae902 100644
--- 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/WithinTest.java
+++ 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/WithinTest.java
@@ -19,6 +19,9 @@ package org.apache.sis.geometries.operation;
 import org.apache.sis.geometries.Geometry;
 
 // Test dependencies
+import static org.apache.sis.geometries.operation.TestData.EMPTY_1;
+import static org.apache.sis.geometries.operation.TestData.EMPTY_2;
+import static org.apache.sis.geometries.operation.TestData.NON_EMPTY;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import org.junit.jupiter.api.Test;
@@ -38,7 +41,7 @@ public class WithinTest {
      * @param expected the expected result, or {@code null} if an exception is 
expected.
      * @param error    the type of the expected exception, or {@code null} if 
the operation should succeed.
      */
-    private record Entry(Geometry input,
+    private record TestCase(Geometry input,
                          Geometry other,
                          Boolean expected,
                          Class<? extends Exception> error)
@@ -48,7 +51,12 @@ public class WithinTest {
     /**
      * All test cases of {@code within(Geometry, Geometry)}.
      */
-    private static final Entry[] ENTRIES = {
+    private static final TestCase[] ENTRIES = {
+        // The empty set is a subset of every geometry. Converse of 
`contains(Geometry, Geometry)`.
+        new TestCase(EMPTY_1,   NON_EMPTY, true,  null),
+        new TestCase(EMPTY_1,   EMPTY_1,   true,  null),
+        new TestCase(EMPTY_1,   EMPTY_2,   true,  null),
+        new TestCase(NON_EMPTY, EMPTY_1,   false, null)
     };
 
     /**
@@ -56,7 +64,7 @@ public class WithinTest {
      */
     @Test
     public void testWithin() {
-        for (final Entry entry : ENTRIES) {
+        for (final TestCase entry : ENTRIES) {
             try {
                 final boolean result = new 
GeometryProcessor().within(entry.input(), entry.other());
                 assertNull(entry.error(), "An exception was expected.");

Reply via email to