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 0d2bf808bf feat(Geometry): add point geometry tests
0d2bf808bf is described below

commit 0d2bf808bffc7c7efd0318097e556287094d1fa9
Author: jsorel <[email protected]>
AuthorDate: Tue Sep 22 14:57:24 2026 +0200

    feat(Geometry): add point geometry tests
---
 .../org/apache/sis/geometries/DataPointsType.java  |  72 ++++++
 .../apache/sis/geometries/adapter/JTSAdapter.java  |   3 +
 .../internal/shared/ArrayDataPoints.java           |  19 +-
 .../geometries/internal/shared/DefaultEmpty.java   |  16 ++
 .../internal/shared/DefaultMultiPoint.java         |  16 ++
 .../geometries/operation/GeometryProcessor.java    |  77 +++++-
 .../test/org/apache/sis/geometries/PointTest.java  | 274 +++++++++++++++------
 .../internal/shared/DefaultPointTest.java          |  11 +
 .../internal/shared/IndexedPointTest.java          |  12 +
 .../sis/geometries/operation/BufferTest.java       |   8 +-
 .../sis/geometries/operation/ContainsTest.java     |  10 +-
 .../sis/geometries/operation/ConvexHullTest.java   |   6 +
 .../sis/geometries/operation/CrossesTest.java      |  17 ++
 .../sis/geometries/operation/DifferenceTest.java   |   9 +-
 .../sis/geometries/operation/DisjointTest.java     |   9 +-
 .../sis/geometries/operation/DistanceTest.java     |  14 ++
 .../apache/sis/geometries/operation/EqualTest.java |   9 +-
 .../sis/geometries/operation/IntersectionTest.java |   9 +-
 .../sis/geometries/operation/IntersectsTest.java   |   9 +-
 .../sis/geometries/operation/LocateAlongTest.java  |   8 +
 .../geometries/operation/LocateBetweenTest.java    |   8 +
 .../sis/geometries/operation/OverlapsTest.java     |  20 ++
 .../sis/geometries/operation/RelateTest.java       |  27 ++
 .../geometries/operation/SymDifferenceTest.java    |  24 +-
 .../apache/sis/geometries/operation/TestData.java  |  51 ++++
 .../apache/sis/geometries/operation/To3DTest.java  |  12 +
 .../sis/geometries/operation/TouchesTest.java      |  20 ++
 .../sis/geometries/operation/TransformTest.java    |   8 +
 .../apache/sis/geometries/operation/UnionTest.java |  22 +-
 .../geometries/operation/WithinDistanceTest.java   |  15 ++
 .../sis/geometries/operation/WithinTest.java       |  11 +-
 31 files changed, 727 insertions(+), 99 deletions(-)

diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/DataPointsType.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/DataPointsType.java
index 29e4ea1dcc..457862053a 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/DataPointsType.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/DataPointsType.java
@@ -19,8 +19,10 @@ package org.apache.sis.geometries;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import org.apache.sis.maths.DataType;
 import org.apache.sis.maths.SampleSystem;
 
@@ -105,6 +107,44 @@ public interface DataPointsType {
      */
     List<String> getAttributeNames();
 
+    static int hashCode(final DataPointsType type) {
+        int hash = 0;
+        for (final String name : type.getAttributeNames()) {
+            // Summed so that the result does not depend on the order in which 
the names are returned.
+            hash += name.hashCode()
+                  ^ Objects.hashCode(type.getAttributeSystem(name))
+                  ^ Objects.hashCode(type.getAttributeType(name));
+        }
+        return hash;
+    }
+
+    static boolean equals(final DataPointsType type, final Object obj) {
+        if (type == obj) {
+            return true;
+        }
+        if (!(obj instanceof DataPointsType other)) {
+            return false;
+        }
+        if (type instanceof DataPoints || type instanceof Geometry ||
+            obj  instanceof DataPoints || obj  instanceof Geometry)
+        {
+            // At least one operand carries the positions, not only their 
description.
+            return false;
+        }
+        final List<String> names = type.getAttributeNames();
+        final List<String> others = other.getAttributeNames();
+        if (names.size() != others.size() || !new 
HashSet<>(names).containsAll(others)) {
+            return false;
+        }
+        for (final String name : names) {
+            if (!Objects.equals(type.getAttributeSystem(name), 
other.getAttributeSystem(name)) ||
+                !Objects.equals(type.getAttributeType  (name), 
other.getAttributeType  (name)))
+            {
+                return false;
+            }
+        }
+        return true;
+    }
 
     /**
      * Empty attributes type.
@@ -124,6 +164,16 @@ public interface DataPointsType {
         public List<String> getAttributeNames() {
             return Collections.EMPTY_LIST;
         }
+
+        @Override
+        public int hashCode() {
+            return DataPointsType.hashCode(this);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            return DataPointsType.equals(this, obj);
+        }
     };
 
     /**
@@ -155,6 +205,28 @@ public interface DataPointsType {
         public List<String> getAttributeNames() {
             return new ArrayList(datatypes.keySet());
         }
+
+        /**
+         * Returns a hash code value for this description.
+         *
+         * @see DataPointsType#hashCode(DataPointsType)
+         */
+        @Override
+        public int hashCode() {
+            return DataPointsType.hashCode(this);
+        }
+
+        /**
+         * Compares this description with the given object for equality.
+         * The given object does not need to be a template: any description
+         * declaring the same attributes is equal to this one.
+         *
+         * @see DataPointsType#equals(DataPointsType, Object)
+         */
+        @Override
+        public boolean equals(Object obj) {
+            return DataPointsType.equals(this, obj);
+        }
     }
 
     /**
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/adapter/JTSAdapter.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/adapter/JTSAdapter.java
index 6bed576e46..b2c730d1cc 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/adapter/JTSAdapter.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/adapter/JTSAdapter.java
@@ -75,6 +75,9 @@ public final class JTSAdapter {
     private static Geometry fromJTS(org.locationtech.jts.geom.Geometry jts, 
CoordinateReferenceSystem crs, boolean copy) {
         if (jts == null) {
             return null;
+        } else if (jts.isEmpty()) {
+            return GeometryFactory.createEmpty(crs);
+
         } else if (jts instanceof org.locationtech.jts.geom.Point cdt) {
             return 
GeometryFactory.createPoint(toDataPoints(cdt.getCoordinateSequence(), crs, 
copy));
 
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/ArrayDataPoints.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/ArrayDataPoints.java
index d7778db474..4cc0288be8 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/ArrayDataPoints.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/ArrayDataPoints.java
@@ -123,7 +123,8 @@ public final class ArrayDataPoints implements DataPoints, 
DataPointsType {
 
     @Override
     public Tuple getAttribute(int index, String name) {
-        return attributes.get(name).get(index);
+        final Array array = attributes.get(name);
+        return (array != null) ? array.get(index) : null;
     }
 
     @Override
@@ -161,6 +162,22 @@ public final class ArrayDataPoints implements DataPoints, 
DataPointsType {
         return NDArrays.computeRange(attributes.get(name));
     }
 
+    @Override
+    public int hashCode() {
+        return 37 * attributes.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof ArrayDataPoints)) {
+            return false;
+        }
+        return attributes.equals(((ArrayDataPoints) obj).attributes);
+    }
+
     /**
      * An indexed point in the point sequence
      */
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultEmpty.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultEmpty.java
index 9ea0fed2e9..f6ac7a9a06 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultEmpty.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultEmpty.java
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.geometries.internal.shared;
 
+import java.util.Objects;
 import org.apache.sis.geometries.Empty;
 import org.apache.sis.geometry.GeneralEnvelope;
 import org.opengis.geometry.Envelope;
@@ -56,4 +57,19 @@ public non-sealed class DefaultEmpty extends 
AbstractGeometry implements Empty {
         return env;
     }
 
+    @Override
+    public int hashCode() {
+        return 11 * Objects.hashCode(attType);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null || getClass() != obj.getClass()) {
+            return false;
+        }
+        return Objects.equals(attType, ((DefaultEmpty) obj).attType);
+    }
 }
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultMultiPoint.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultMultiPoint.java
index a18894e842..e9c6b92d09 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultMultiPoint.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultMultiPoint.java
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.geometries.internal.shared;
 
+import java.util.Objects;
 import org.apache.sis.geometries.DataPoints;
 import org.apache.sis.geometries.Point;
 import org.apache.sis.geometries.point.MultiPoint;
@@ -71,4 +72,19 @@ public non-sealed class DefaultMultiPoint extends 
AbstractGeometry implements Mu
         return points;
     }
 
+    @Override
+    public int hashCode() {
+        return 13 * Objects.hashCode(points);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null || getClass() != obj.getClass()) {
+            return false;
+        }
+        return Objects.equals(points, ((DefaultMultiPoint) obj).points);
+    }
 }
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 aca397cf84..d4302976bd 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
@@ -17,6 +17,7 @@
 package org.apache.sis.geometries.operation;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -96,7 +97,7 @@ public final class GeometryProcessor {
         }
 
         //TODO : fallback on JTS until implemented, this loss the attributes !
-        return Geometries.fromJTS(jts(geom).convexHull(), true);
+        return fromJTS(jts(geom).convexHull(), geom);
     }
 
     /**
@@ -111,7 +112,7 @@ public final class GeometryProcessor {
         }
 
         //TODO : fallback on JTS until implemented, this loss the attributes !
-        return Geometries.fromJTS(jts(geom1).difference(jts(geom2)), true);
+        return fromJTS(jts(geom1).difference(jts(geom2)), geom1);
     }
 
     /**
@@ -171,7 +172,7 @@ public final class GeometryProcessor {
         }
 
         //TODO : fallback on JTS until implemented, this loss the attributes !
-        return Geometries.fromJTS(jts(geom1).intersection(jts(geom2)), true);
+        return fromJTS(jts(geom1).intersection(jts(geom2)), geom1);
     }
 
     /**
@@ -190,7 +191,7 @@ public final class GeometryProcessor {
         }
 
         //TODO : fallback on JTS until implemented, this loss the attributes !
-        return Geometries.fromJTS(jts(geom1).symDifference(jts(geom2)), true);
+        return fromJTS(jts(geom1).symDifference(jts(geom2)), geom1);
     }
 
     /**
@@ -208,7 +209,7 @@ public final class GeometryProcessor {
         }
 
         //TODO : fallback on JTS until implemented, this loss the attributes !
-        return Geometries.fromJTS(jts(geom1).union(jts(geom2)), true);
+        return fromJTS(jts(geom1).union(jts(geom2)), geom1);
     }
 
     /**
@@ -240,6 +241,10 @@ public final class GeometryProcessor {
     @UML(identifier="crosses", specification=ISO_19107) // section 6.4.8.8
     //@UML(identifier="3Dcrosses", specification=ISO_19107) // section 6.4.9
     public boolean crosses(Geometry geom1, Geometry geom2) throws 
OperationException {
+        if (geom1.isEmpty() || geom2.isEmpty()) {
+            return false;
+        }
+
         //TODO : fallback on JTS until implemented
         return jts(geom1).crosses(jts(geom2));
     }
@@ -311,6 +316,10 @@ public final class GeometryProcessor {
     @UML(identifier="overlaps", specification=ISO_19107) // section 6.4.8.8
     //@UML(identifier="3Doverlaps", specification=ISO_19107) // section 6.4.9
     public boolean overlaps(Geometry geom1, Geometry geom2) throws 
OperationException {
+        if (geom1.isEmpty() || geom2.isEmpty()) {
+            return false;
+        }
+
         //TODO : fallback on JTS until implemented
         return jts(geom1).overlaps(jts(geom2));
     }
@@ -331,11 +340,36 @@ public final class GeometryProcessor {
     //@UML(identifier="3Drelate", specification=ISO_19107) // section 6.4.9
     public boolean relate(Geometry geom1, Geometry geom2, DE9IM matrix) throws 
OperationException {
         ArgumentChecks.ensureNonNull("matrix", matrix);
-        //TODO : fallback on JTS until implemented
-        final org.locationtech.jts.geom.IntersectionMatrix computed = 
jts(geom1).relate(jts(geom2));
         final int[] dimensions = new int[9];
-        for (int i=0; i<dimensions.length; i++) {
-            dimensions[i] = computed.get(i / 3, i % 3);
+        if (geom1.isEmpty() || geom2.isEmpty()) {
+            /*
+             * The interior and the boundary of the empty set meet nothing, 
while its exterior is the
+             * whole space. The row and the column of an empty operand are 
therefore empty, except the
+             * cells where its exterior meets the interior or the boundary of 
the other operand.
+             */
+            Arrays.fill(dimensions, -1);
+            dimensions[8] = 2;                      // Both exteriors cover 
the whole plane.
+            if (geom1.isEmpty() != geom2.isEmpty()) {
+                /*
+                 * The dimensions of the other operand are those of its 
interior and of its boundary.
+                 */
+                final Geometry other = geom1.isEmpty() ? geom2 : geom1;
+                final int interior = other.getTopologicDimension();
+                final int boundary = other.boundary().getTopologicDimension();
+                if (geom1.isEmpty()) {
+                    dimensions[6] = interior;       // Exterior of geom1 ∩ 
interior of geom2.
+                    dimensions[7] = boundary;       // Exterior of geom1 ∩ 
boundary of geom2.
+                } else {
+                    dimensions[2] = interior;       // Interior of geom1 ∩ 
exterior of geom2.
+                    dimensions[5] = boundary;       // Boundary of geom1 ∩ 
exterior of geom2.
+                }
+            }
+        } else {
+            //TODO : fallback on JTS until implemented
+            final org.locationtech.jts.geom.IntersectionMatrix computed = 
jts(geom1).relate(jts(geom2));
+            for (int i=0; i<dimensions.length; i++) {
+                dimensions[i] = computed.get(i / 3, i % 3);
+            }
         }
         return matrix.matches(dimensions);
     }
@@ -346,6 +380,10 @@ public final class GeometryProcessor {
     @UML(identifier="touches", specification=ISO_19107) // section 6.4.8.8
     //@UML(identifier="3Dtouches", specification=ISO_19107) // section 6.4.9
     public boolean touches(Geometry geom1, Geometry geom2) throws 
OperationException {
+        if (geom1.isEmpty() || geom2.isEmpty()) {
+            return false;
+        }
+
         //TODO : fallback on JTS until implemented
         return jts(geom1).touches(jts(geom2));
     }
@@ -376,7 +414,12 @@ public final class GeometryProcessor {
     @UML(identifier="withinDistance", specification=ISO_19107) // section 
6.4.8.8
     //@UML(identifier="3DwithinDistance", specification=ISO_19107) // section 
6.4.9
     public boolean withinDistance(Geometry geom1, Geometry geom2, Quantity<?> 
distance) throws OperationException {
-        throw new UnsupportedOperationException();
+        if (geom1.isEmpty() || geom2.isEmpty()) {
+            return false;
+        }
+
+        //TODO : fallback on JTS until implemented
+        return jts(geom1).isWithinDistance(jts(geom2), 
distance.getValue().doubleValue());
     }
 
     // ////////////////////////////////////////////////////////////////////////
@@ -557,6 +600,20 @@ public final class GeometryProcessor {
         return Geometries.asJTS(geom, false, null);
     }
 
+    /**
+     * Converts back to a geometry of this package the result of an operation 
delegated to JTS.
+     * The JTS geometries produced by an overlay operation carry no reference 
system, therefore
+     * the system of the geometry on which the operation was invoked is 
assigned to the result.
+     *
+     * @param  result  the geometry computed by JTS.
+     * @param  source  the geometry which provided the coordinate reference 
system of the operation.
+     * @return the result as a geometry of this package.
+     */
+    private static Geometry fromJTS(org.locationtech.jts.geom.Geometry result, 
Geometry source) {
+        result.setUserData(source.getCoordinateReferenceSystem());
+        return Geometries.fromJTS(result, true);
+    }
+
     private static Unit getUnit(Geometry geometry) {
         return getUnit(geometry.getCoordinateReferenceSystem());
     }
diff --git 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/PointTest.java
 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/PointTest.java
index 151e3c0dd1..6477757c86 100644
--- 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/PointTest.java
+++ 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/PointTest.java
@@ -16,262 +16,380 @@
  */
 package org.apache.sis.geometries;
 
+import java.util.List;
+import java.util.Map;
+import org.apache.sis.geometry.GeneralDirectPosition;
+import org.apache.sis.maths.DataType;
+import org.apache.sis.maths.SampleSystem;
+import org.apache.sis.maths.Tuple;
+import org.apache.sis.maths.Vector;
+import org.apache.sis.maths.Vectors;
+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 Point}.
  *
+ * <p>This class tests the behavior mandated by {@link Point} on any 
implementation.
+ * Subclasses provide the implementation to test by implementing
+ * {@link #createPoint(CoordinateReferenceSystem, double[])}.</p>
+ *
  * @author Johann Sorel (Geomatys)
  */
-public class PointTest {
+public abstract class PointTest {
+
+    protected static final CoordinateReferenceSystem CRS_2D = 
CommonCRS.WGS84.normalizedGeographic();
+    protected static final CoordinateReferenceSystem CRS_3D = 
CommonCRS.WGS84.geographic3D();
+
+    private static final double[] POSITION_2D = {10, 5};
+    private static final double[] POSITION_3D = {10, 5, 100};
+
+    protected PointTest() {
+    }
+
+    /**
+     * Creates a point at the given location in the given coordinate reference 
system.
+     *
+     * @param  crs          the coordinate reference system of the point to 
create, not null.
+     * @param  coordinates  the coordinates of the point, in the axis order of 
the given system.
+     * @return a new point at the given location, never null.
+     */
+    protected abstract Point createPoint(CoordinateReferenceSystem crs, 
double... coordinates);
+
+    /**
+     * Creates a point at {@link #POSITION_2D} in {@link #CRS_2D}.
+     */
+    private Point createPoint2D() {
+        return createPoint(CRS_2D, POSITION_2D.clone());
+    }
+
+    /**
+     * Creates a point at {@link #POSITION_3D} in {@link #CRS_3D}.
+     */
+    private Point createPoint3D() {
+        return createPoint(CRS_3D, POSITION_3D.clone());
+    }
+
     /**
      * Test of {@code getPosition()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
     public void testGetPosition() {
+        final Tuple<?> position = createPoint2D().getPosition();
+        assertNotNull(position);
+        assertEquals(2, position.getDimension());
+        assertArrayEquals(POSITION_2D, position.toArrayDouble());
+        assertArrayEquals(POSITION_3D, 
createPoint3D().getPosition().toArrayDouble());
     }
 
     /**
      * Test of {@code getAttribute(String)}.
      */
     @Test
-    @Disabled("Not implemented yet.")
     public void testGetAttribute() {
+        final Point point = createPoint2D();
+        final Tuple<?> position = 
point.getAttribute(DataPointsType.ATT_POSITION);
+        assertNotNull(position, "The coordinates are always carried by the 
positions attribute.");
+        assertArrayEquals(POSITION_2D, position.toArrayDouble());
+        assertNull(point.getAttribute("Not an attribute of this point."));
     }
 
     /**
      * Test of {@code setAttribute(String, Tuple)}.
      */
     @Test
-    @Disabled("Not implemented yet.")
     public void testSetAttribute() {
+        final Point point = createPoint2D();
+        final Tuple<?> moved = point.getPosition().copy();
+        moved.set(new double[] {20, 15});
+        point.setAttribute(DataPointsType.ATT_POSITION, moved);
+        assertArrayEquals(new double[] {20, 15}, 
point.getPosition().toArrayDouble(),
+                          "Setting the positions attribute shall move the 
point.");
     }
 
     /**
      * Test of {@code asDataPoint()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
     public void testAsDataPoint() {
+        final Point point = createPoint2D();
+        final DataPoints points = point.asDataPoint();
+        assertNotNull(points);
+        assertEquals(1, points.size(), "A point is a sequence of a single 
position.");
+        assertFalse(points.isEmpty());
+        assertArrayEquals(POSITION_2D, points.getPosition(0).toArrayDouble());
+        assertArrayEquals(POSITION_2D, 
points.getPoint(0).getPosition().toArrayDouble());
+        assertEquals(CRS_2D, points.getCoordinateReferenceSystem());
+        assertNotNull(points.getType());
     }
 
     /**
      * Test of {@code getGeometryType()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
     public void testGetGeometryType() {
+        assertEquals(GeometryType.POINT, createPoint2D().getGeometryType());
     }
 
     /**
      * Test of {@code getTopologicDimension()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
     public void testGetTopologicDimension() {
+        assertEquals(0, createPoint2D().getTopologicDimension());
+        assertEquals(0, createPoint3D().getTopologicDimension());
     }
 
     /**
      * Test of {@code getSegments()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
     public void testGetSegments() {
+        final List<Primitive> segments = createPoint2D().getSegments();
+        assertNotNull(segments);
+        assertTrue(segments.isEmpty(), "A point cannot be decomposed.");
     }
 
     /**
      * Test of {@code isCycle()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
     public void testIsCycle() {
+        assertTrue(createPoint2D().isCycle(), "The boundary of a point is 
empty.");
     }
 
     /**
      * Test of {@code isSimple()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
     public void testIsSimple() {
+        assertTrue(createPoint2D().isSimple(), "A single location can neither 
self-intersect nor self-tangent.");
     }
 
     /**
      * Test of {@code isValid()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
     public void testIsValid() {
+        assertTrue(createPoint2D().isValid());
     }
 
     /**
-     * Test of {@code boundary()}.
-     */
-    @Test
-    @Disabled("Not implemented yet.")
-    public void testBoundary() {
-    }
-
-    /**
-     * Test of {@code getCentroid()}.
-     */
-    @Test
-    @Disabled("Not implemented yet.")
-    public void testGetCentroid() {
-    }
-
-    /**
-     * Test of {@code getRepresentativePoint()}.
+     * Test of {@code isEmpty()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
-    public void testGetRepresentativePoint() {
+    public void testIsEmpty() {
+        assertFalse(createPoint2D().isEmpty(), "A point always has a 
location.");
     }
 
     /**
-     * Test of {@code getEnvelope()}.
+     * Test of {@code boundary()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
-    public void testGetEnvelope() {
+    public void testBoundary() {
+        final Point point = createPoint2D();
+        final Geometry boundary = point.boundary();
+        assertNotNull(boundary);
+        assertTrue(boundary.isEmpty(), "The boundary of a point is the empty 
set.");
+        assertEquals(GeometryType.EMPTY, boundary.getGeometryType());
+        assertEquals(CRS_2D, boundary.getCoordinateReferenceSystem());
     }
 
     /**
-     * Test of {@code vectorToPoint(DirectPosition)}.
+     * Test of {@code getClosure()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
-    public void testVectorToPoint() {
+    public void testGetClosure() {
+        final Point point = createPoint2D();
+        assertSame(point, point.getClosure(), "A point contains its empty 
boundary, therefore it is its own closure.");
     }
 
     /**
-     * Test of {@code bearing(DirectPosition)}.
+     * Test of {@code getCentroid()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
-    public void testBearing() {
+    public void testGetCentroid() {
+        final Point point = createPoint2D();
+        assertSame(point, point.getCentroid(), "A point is its own centroid.");
     }
 
     /**
-     * Test of {@code pointAtDistance(Vector)}.
+     * Test of {@code getRepresentativePoint()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
-    public void testPointAtDistance() {
+    public void testGetRepresentativePoint() {
+        final Point point = createPoint2D();
+        assertSame(point, point.getRepresentativePoint(), "A point is interior 
to itself.");
     }
 
     /**
-     * Test of {@code getBoundaryType()}.
+     * Test of {@code getMaximalComplex()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
-    public void testGetBoundaryType() {
+    @Disabled
+    public void testGetMaximalComplex() {
+        // todo
     }
 
     /**
-     * Test of {@code getDimension(DirectPosition)}.
+     * Test of {@code getMetadata()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
-    public void testGetDimension() {
+    @Disabled
+    public void testGetMetadata() {
+        // todo
     }
 
     /**
      * Test of {@code getCoordinateReferenceSystem()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
     public void testGetCoordinateReferenceSystem() {
+        assertEquals(CRS_2D, createPoint2D().getCoordinateReferenceSystem());
+        assertEquals(CRS_3D, createPoint3D().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 Point point = createPoint2D();
+        final CoordinateReferenceSystem other = CommonCRS.WGS84.geographic();
+        try {
+            point.setCoordinateReferenceSystem(other);
+        } catch (UnsupportedOperationException e) {
+            // Immutable implementation. The geometry shall then be left 
unchanged.
+            assertEquals(CRS_2D, point.getCoordinateReferenceSystem());
+            return;
+        }
+        assertEquals(other, point.getCoordinateReferenceSystem());
+        assertArrayEquals(POSITION_2D, point.getPosition().toArrayDouble(),
+                          "Changing the reference system shall not move the 
coordinates.");
     }
 
     /**
      * Test of {@code getAttributesType()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
     public void testGetAttributesType() {
+        final Point point = createPoint2D();
+        final DataPointsType type = point.getDataPointsType();
+        assertNotNull(type);
+        
assertTrue(type.getAttributeNames().contains(DataPointsType.ATT_POSITION),
+                   "The coordinates are always carried by the positions 
attribute.");
+        /*
+         * 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(DataPointsType.ATT_POSITION).getCoordinateReferenceSystem());
     }
 
     /**
-     * Test of {@code getDimension(DirectPosition)}.
+     * Test of {@code getDimension()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
-    public void testGetDimension_DirectPosition() {
+    public void testGetDimension() {
+        assertEquals(2, createPoint2D().getDimension());
+        assertEquals(3, createPoint3D().getDimension());
     }
 
     /**
      * Test of {@code is3D()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
     public void testIs3D() {
+        assertFalse(createPoint2D().is3D());
+        assertTrue (createPoint3D().is3D());
     }
 
     /**
      * Test of {@code getSpatialDimension()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
     public void testGetSpatialDimension() {
+        assertEquals(2, createPoint2D().getSpatialDimension());
+        assertEquals(3, createPoint3D().getSpatialDimension());
     }
 
     /**
-     * Test of {@code getGeometryType2()}.
+     * Test of {@code getBoundaryType()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
-    public void testGetGeometryType2() {
+    @Disabled
+    public void testGetBoundaryType() {
+        final Point point = createPoint2D();
+        /*
+         * TODO
+         */
+        assertThrows(UnsupportedOperationException.class, () -> 
point.getBoundaryType());
     }
 
     /**
-     * Test of {@code getClosure()}.
+     * Test of {@code getEnvelope()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
-    public void testGetClosure() {
+    public void testGetEnvelope() {
+        final Point point = createPoint2D();
+        final Envelope envelope = point.getEnvelope();
+        assertNotNull(envelope);
+        assertEquals(CRS_2D, envelope.getCoordinateReferenceSystem());
+        assertEquals(2, envelope.getDimension());
+
+        for (int i = 0; i < POSITION_2D.length; i++) {
+            assertEquals(POSITION_2D[i], envelope.getMinimum(i));
+            assertEquals(POSITION_2D[i], envelope.getMaximum(i));
+        }
     }
 
     /**
-     * Test of {@code getMaximalComplex()}.
+     * Test of {@code vectorToPoint(DirectPosition)}.
      */
     @Test
-    @Disabled("Not implemented yet.")
-    public void testGetMaximalComplex() {
+    @Disabled
+    public void testVectorToPoint() {
+        // TODO
     }
 
     /**
-     * Test of {@code isEmpty()}.
+     * Test of {@code bearing(DirectPosition)}.
      */
     @Test
-    @Disabled("Not implemented yet.")
-    public void testIsEmpty() {
+    @Disabled
+    public void testBearing() {
+        // TODO
+    }
+
+    /**
+     * Test of {@code pointAtDistance(Vector)}.
+     */
+    @Test
+    @Disabled
+    public void testPointAtDistance() {
+        // TODO
     }
 
     /**
      * Test of {@code userProperties()}.
      */
     @Test
-    @Disabled("Not implemented yet.")
     public void testUserProperties() {
+        final Point point = createPoint2D();
+        final Map<String,Object> properties = point.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", point.userProperties().get("A key"));
     }
 }
diff --git 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/internal/shared/DefaultPointTest.java
 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/internal/shared/DefaultPointTest.java
index c06b7a42f3..687fdbc2cf 100644
--- 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/internal/shared/DefaultPointTest.java
+++ 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/internal/shared/DefaultPointTest.java
@@ -16,6 +16,9 @@
  */
 package org.apache.sis.geometries.internal.shared;
 
+import org.apache.sis.geometries.Point;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
 // Test dependencies
 import org.apache.sis.geometries.PointTest;
 
@@ -26,4 +29,12 @@ import org.apache.sis.geometries.PointTest;
  * @author Johann Sorel (Geomatys)
  */
 public class DefaultPointTest extends PointTest {
+
+    public DefaultPointTest() {
+    }
+
+    @Override
+    protected Point createPoint(final CoordinateReferenceSystem crs, final 
double... coordinates) {
+        return new DefaultPoint(crs, coordinates);
+    }
 }
diff --git 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/internal/shared/IndexedPointTest.java
 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/internal/shared/IndexedPointTest.java
index 08dcfa045c..0f93476066 100644
--- 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/internal/shared/IndexedPointTest.java
+++ 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/internal/shared/IndexedPointTest.java
@@ -16,6 +16,10 @@
  */
 package org.apache.sis.geometries.internal.shared;
 
+import org.apache.sis.geometries.Point;
+import org.apache.sis.maths.NDArrays;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
 // Test dependencies
 import org.apache.sis.geometries.PointTest;
 
@@ -26,4 +30,12 @@ import org.apache.sis.geometries.PointTest;
  * @author Johann Sorel (Geomatys)
  */
 public class IndexedPointTest extends PointTest {
+
+    public IndexedPointTest() {
+    }
+
+    @Override
+    protected Point createPoint(final CoordinateReferenceSystem crs, final 
double... coordinates) {
+        return new IndexedPoint(new ArrayDataPoints(NDArrays.of(crs, 
coordinates)), 0);
+    }
 }
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 3d191952c6..19400298b0 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
@@ -23,6 +23,7 @@ import org.apache.sis.measure.Units;
 
 // Test dependencies
 import static org.apache.sis.geometries.operation.TestData.EMPTY_1;
+import static org.apache.sis.geometries.operation.TestData.POINT_A;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import org.junit.jupiter.api.Test;
@@ -61,7 +62,12 @@ public class BufferTest {
         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)
+        new TestCase(EMPTY_1, Quantities.create( 10, Units.UNITY), EMPTY_1, 
null),
+        /*
+         * TODO
+         */
+        new TestCase(POINT_A, Quantities.create( 10, Units.METRE), null, 
UnsupportedOperationException.class),
+        new TestCase(POINT_A, Quantities.create(  0, Units.METRE), null, 
UnsupportedOperationException.class)
     };
 
     /**
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 4b9195e711..810687a9be 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
@@ -22,6 +22,9 @@ import org.apache.sis.geometries.Geometry;
 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.apache.sis.geometries.operation.TestData.POINT_A;
+import static org.apache.sis.geometries.operation.TestData.POINT_A_BIS;
+import static org.apache.sis.geometries.operation.TestData.POINT_B;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import org.junit.jupiter.api.Test;
@@ -56,7 +59,12 @@ public class ContainsTest {
         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)
+        new TestCase(NON_EMPTY, EMPTY_1,   true,  null),
+       // points
+        new TestCase(POINT_A, POINT_A,     true,  null),
+        new TestCase(POINT_A, POINT_A_BIS, true,  null),
+        new TestCase(POINT_A, POINT_B,     false, null),
+        new TestCase(POINT_B, POINT_A,     false, null)
     };
 
     /**
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 17b5051d5b..895e5c4643 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
@@ -19,6 +19,8 @@ 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.POINT_A;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import org.junit.jupiter.api.Test;
@@ -47,6 +49,10 @@ public class ConvexHullTest {
      * All test cases of {@code convexHull(Geometry)}.
      */
     private static final TestCase[] ENTRIES = {
+        // The convex hull of the empty set is empty.
+        new TestCase(EMPTY_1, EMPTY_1, null),
+        // points
+        new TestCase(POINT_A, POINT_A, null)
     };
 
     /**
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 65f8e9ffc8..2e20f3f267 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
@@ -19,6 +19,12 @@ 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.apache.sis.geometries.operation.TestData.POINT_A;
+import static org.apache.sis.geometries.operation.TestData.POINT_A_BIS;
+import static org.apache.sis.geometries.operation.TestData.POINT_B;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import org.junit.jupiter.api.Test;
@@ -49,6 +55,17 @@ public class CrossesTest {
      * All test cases of {@code crosses(Geometry, Geometry)}.
      */
     private static final TestCase[] ENTRIES = {
+        /*
+         * Crossing requires the two interiors to share a position while 
neither geometry
+         * contains the other. The empty set has no interior, therefore it 
crosses nothing.
+         */
+        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),
+       // points
+        new TestCase(POINT_A, POINT_A_BIS, false, null),
+        new TestCase(POINT_A, POINT_B,     false, null)
     };
 
     /**
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 c75014f99d..ae2254beed 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
@@ -21,7 +21,11 @@ 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.EMPTY_RESULT;
 import static org.apache.sis.geometries.operation.TestData.NON_EMPTY;
+import static org.apache.sis.geometries.operation.TestData.POINT_A;
+import static org.apache.sis.geometries.operation.TestData.POINT_A_BIS;
+import static org.apache.sis.geometries.operation.TestData.POINT_B;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import org.junit.jupiter.api.Test;
@@ -55,7 +59,10 @@ public class DifferenceTest {
         // ∅ − 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)
+        new TestCase(EMPTY_1,   EMPTY_2,   EMPTY_1,   null),
+        // points
+        new TestCase(POINT_A, POINT_B,     POINT_A,      null),
+        new TestCase(POINT_A, POINT_A_BIS, EMPTY_RESULT, null)
     };
 
     /**
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 0f77c511dc..1f02c77d8a 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
@@ -22,6 +22,9 @@ import org.apache.sis.geometries.Geometry;
 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.apache.sis.geometries.operation.TestData.POINT_A;
+import static org.apache.sis.geometries.operation.TestData.POINT_A_BIS;
+import static org.apache.sis.geometries.operation.TestData.POINT_B;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import org.junit.jupiter.api.Test;
@@ -56,7 +59,11 @@ public class DisjointTest {
         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)
+        new TestCase(EMPTY_1,   EMPTY_2,   true, null),
+        // points
+        new TestCase(POINT_A, POINT_A_BIS, false, null),
+        new TestCase(POINT_A, POINT_B,     true,  null),
+        new TestCase(POINT_B, POINT_A,     true,  null)
     };
 
     /**
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 0961b48c82..4e5cdbc650 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
@@ -46,6 +46,14 @@ public class DistanceTest {
     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);
 
+    /**
+     * Two points in a three-dimensional coordinate reference system, at the 
same horizontal
+     * position but at different heights.
+     */
+    private static final SampleSystem CRS3D = 
SampleSystem.of(CommonCRS.WGS84.geographic3D());
+    private static final Point POINT_3D_LOW  = 
GeometryFactory.createPoint(CRS3D, 10.0, 5.0,   0.0);
+    private static final Point POINT_3D_HIGH = 
GeometryFactory.createPoint(CRS3D, 10.0, 5.0, 100.0);
+
     /**
      * Two points using coordinate reference systems which differ by their 
axis order.
      */
@@ -86,6 +94,12 @@ public class DistanceTest {
         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),
+        /*
+         * TODO / Limitation: only the first two axes are taken in account, 
therefore two points
+         * at the same horizontal position are reported at a distance of zero 
whatever the
+         * difference of their heights.
+         */
+        new TestCase(POINT_3D_LOW, POINT_3D_HIGH, Quantities.create(0.0, 
Units.DEGREE), null),
         /*
          * The operation computes in the coordinate reference system of the 
first geometry,
          * and does not transform the second one.
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 23e6730cbd..f951eb1b35 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
@@ -22,6 +22,9 @@ import org.apache.sis.geometries.Geometry;
 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.apache.sis.geometries.operation.TestData.POINT_A;
+import static org.apache.sis.geometries.operation.TestData.POINT_A_BIS;
+import static org.apache.sis.geometries.operation.TestData.POINT_B;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import org.junit.jupiter.api.Test;
@@ -56,7 +59,11 @@ public class EqualTest {
         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)
+        new TestCase(NON_EMPTY, EMPTY_1,   false, null),
+        // points
+        new TestCase(POINT_A, POINT_A,     true,  null),
+        new TestCase(POINT_A, POINT_A_BIS, true,  null),
+        new TestCase(POINT_A, POINT_B,     false, null)
     };
 
     /**
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 122f0759e2..d3d15b13f6 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
@@ -24,7 +24,11 @@ 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.EMPTY_RESULT;
 import static org.apache.sis.geometries.operation.TestData.NON_EMPTY;
+import static org.apache.sis.geometries.operation.TestData.POINT_A;
+import static org.apache.sis.geometries.operation.TestData.POINT_A_BIS;
+import static org.apache.sis.geometries.operation.TestData.POINT_B;
 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNull;
@@ -167,7 +171,10 @@ public class IntersectionTest {
         // ∅ ∩ 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)
+        new TestCase(EMPTY_1,   EMPTY_2,   EMPTY_1, null),
+        // points
+        new TestCase(POINT_A, POINT_A_BIS, POINT_A,      null),
+        new TestCase(POINT_A, POINT_B,     EMPTY_RESULT, null)
     };
 
     /**
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 4a58e76211..e910dc5195 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
@@ -22,6 +22,9 @@ import org.apache.sis.geometries.Geometry;
 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.apache.sis.geometries.operation.TestData.POINT_A;
+import static org.apache.sis.geometries.operation.TestData.POINT_A_BIS;
+import static org.apache.sis.geometries.operation.TestData.POINT_B;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import org.junit.jupiter.api.Test;
@@ -56,7 +59,11 @@ public class IntersectsTest {
         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)
+        new TestCase(EMPTY_1,   EMPTY_2,   false, null),
+        //points
+        new TestCase(POINT_A, POINT_A_BIS, true,  null),
+        new TestCase(POINT_A, POINT_B,     false, null),
+        new TestCase(POINT_B, POINT_A,     false, null)
     };
 
     /**
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 029c98ccc9..38f940607f 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
@@ -17,8 +17,11 @@
 package org.apache.sis.geometries.operation;
 
 import org.apache.sis.geometries.Geometry;
+import org.apache.sis.geometries.DataPointsType;
 
 // Test dependencies
+import static org.apache.sis.geometries.operation.TestData.EMPTY_1;
+import static org.apache.sis.geometries.operation.TestData.POINT_A;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import org.junit.jupiter.api.Test;
@@ -50,6 +53,11 @@ public class LocateAlongTest {
      * All test cases of {@code locateAlong(Geometry, double)}.
      */
     private static final TestCase[] ENTRIES = {
+        /*
+         * TODO
+         */
+        new TestCase(EMPTY_1, DataPointsType.ATT_M, 1, null, 
UnsupportedOperationException.class),
+        new TestCase(POINT_A, DataPointsType.ATT_M, 1, null, 
UnsupportedOperationException.class)
     };
 
     /**
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 8497705722..b7e134f146 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
@@ -17,8 +17,11 @@
 package org.apache.sis.geometries.operation;
 
 import org.apache.sis.geometries.Geometry;
+import org.apache.sis.geometries.DataPointsType;
 
 // Test dependencies
+import static org.apache.sis.geometries.operation.TestData.EMPTY_1;
+import static org.apache.sis.geometries.operation.TestData.POINT_A;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import org.junit.jupiter.api.Test;
@@ -52,6 +55,11 @@ public class LocateBetweenTest {
      * All test cases of {@code locateBetween(Geometry, double, double)}.
      */
     private static final TestCase[] ENTRIES = {
+        /*
+         * TODO
+         */
+        new TestCase(EMPTY_1, DataPointsType.ATT_M, 1, 2, null, 
UnsupportedOperationException.class),
+        new TestCase(POINT_A, DataPointsType.ATT_M, 1, 2, null, 
UnsupportedOperationException.class)
     };
 
     /**
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 8425ecce2c..cce8c0b17f 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
@@ -19,6 +19,12 @@ 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.apache.sis.geometries.operation.TestData.POINT_A;
+import static org.apache.sis.geometries.operation.TestData.POINT_A_BIS;
+import static org.apache.sis.geometries.operation.TestData.POINT_B;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import org.junit.jupiter.api.Test;
@@ -49,6 +55,20 @@ public class OverlapsTest {
      * All test cases of {@code overlaps(Geometry, Geometry)}.
      */
     private static final TestCase[] ENTRIES = {
+        /*
+         * Overlapping requires the two interiors to share a position while 
neither geometry
+         * contains the other. The empty set has no interior, therefore it 
overlaps nothing.
+         */
+        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),
+        /*
+         * Two points cannot overlap: either they are at the same position, 
and then each one
+         * contains the other, or they share no position at all.
+         */
+        new TestCase(POINT_A, POINT_A_BIS, false, null),
+        new TestCase(POINT_A, POINT_B,     false, null)
     };
 
     /**
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 e777cbd224..d778376f8e 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
@@ -20,6 +20,12 @@ import org.apache.sis.geometries.DE9IM;
 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.apache.sis.geometries.operation.TestData.POINT_A;
+import static org.apache.sis.geometries.operation.TestData.POINT_A_BIS;
+import static org.apache.sis.geometries.operation.TestData.POINT_B;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import org.junit.jupiter.api.Test;
@@ -52,6 +58,27 @@ public class RelateTest {
      * All test cases of {@code relate(Geometry, Geometry, DE9IM)}.
      */
     private static final TestCase[] ENTRIES = {
+        /*
+         * The interior and the boundary of the empty set meet nothing, while 
its exterior is the
+         * whole space. Two empty geometries therefore meet only by their 
exteriors.
+         */
+        new TestCase(EMPTY_1, EMPTY_2, DE9IM.valueOf("FFFFFFFF2"), true, null),
+        /*
+         * Between the empty set and a point, the only non-empty intersections 
are those of the
+         * exterior of the empty set with the point, which is a position, and 
with the exterior
+         * of the point, which is the rest of the plane. The boundary of a 
point being empty,
+         * the boundary row and the boundary column stay empty in both cases.
+         */
+        new TestCase(EMPTY_1,   NON_EMPTY, DE9IM.valueOf("FFFFFF0F2"), true, 
null),
+        new TestCase(NON_EMPTY, EMPTY_1,   DE9IM.valueOf("FF0FFFFF2"), true, 
null),
+        /*
+         * Two points at the same position have their interiors in common and 
nothing else.
+         * Two points at different positions have no position in common, each 
one lying in
+         * the exterior of the other.
+         */
+        new TestCase(POINT_A, POINT_A_BIS, DE9IM.valueOf("0FFFFFFF2"), true,  
null),
+        new TestCase(POINT_A, POINT_B,     DE9IM.valueOf("FF0FFF0F2"), true,  
null),
+        new TestCase(POINT_A, POINT_B,     DE9IM.valueOf("0FFFFFFF2"), false, 
null)
     };
 
     /**
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 ba56d98c1f..e926964cd1 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
@@ -17,12 +17,18 @@
 package org.apache.sis.geometries.operation;
 
 import org.apache.sis.geometries.Geometry;
+import org.apache.sis.geometries.point.MultiPoint;
 
 // 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.EMPTY_RESULT;
 import static org.apache.sis.geometries.operation.TestData.NON_EMPTY;
+import static org.apache.sis.geometries.operation.TestData.POINT_A;
+import static org.apache.sis.geometries.operation.TestData.POINT_A_BIS;
+import static org.apache.sis.geometries.operation.TestData.POINT_B;
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import org.junit.jupiter.api.Test;
 
@@ -55,7 +61,8 @@ public class SymDifferenceTest {
         // (∅ − 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)
+        new TestCase(EMPTY_1,   EMPTY_2,   EMPTY_2,   null),
+        new TestCase(POINT_A, POINT_A_BIS, EMPTY_RESULT, null)
     };
 
     /**
@@ -75,4 +82,19 @@ public class SymDifferenceTest {
             }
         }
     }
+
+    /**
+     * Tests {@code symDifference(Geometry, Geometry)} on two points at 
different positions.
+     * No position belongs to both points, therefore the result shall contain 
both of them,
+     * in an unspecified order.
+     */
+    @Test
+    public void testDistinctPoints() {
+        final Geometry result = new GeometryProcessor().symDifference(POINT_A, 
POINT_B);
+        assertInstanceOf(MultiPoint.class, result, "No position is shared by 
the two points.");
+        final MultiPoint<?> points = (MultiPoint<?>) result;
+        assertEquals(TestData.CRS_2D, points.getCoordinateReferenceSystem());
+        assertEquals(2, points.getNumGeometries());
+        TestData.assertPositionsEqual(points, POINT_A, POINT_B);
+    }
 }
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
index 63e95356bd..b078c54fb6 100644
--- 
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
@@ -16,12 +16,19 @@
  */
 package org.apache.sis.geometries.operation;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
 import org.apache.sis.geometries.Empty;
 import org.apache.sis.geometries.GeometryFactory;
 import org.apache.sis.geometries.Point;
+import org.apache.sis.geometries.point.MultiPoint;
 import org.apache.sis.referencing.CommonCRS;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 
+// Test dependencies
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
 
 /**
  * Geometries shared by the test cases of the {@link GeometryProcessor} 
operations.
@@ -53,9 +60,53 @@ public final class TestData {
      */
     public static final Point NON_EMPTY = GeometryFactory.createPoint(CRS_2D, 
10.0, 5.0);
 
+    /**
+     * An arbitrary point. Together with {@link #POINT_A_BIS}, it allows to 
verify that the result
+     * of an operation on two points depends on their positions, not on their 
identity.
+     */
+    public static final Point POINT_A = GeometryFactory.createPoint(CRS_2D, 
10.0, 5.0);
+
+    /**
+     * Another point, distinct from {@link #POINT_A} but at the same position.
+     */
+    public static final Point POINT_A_BIS = 
GeometryFactory.createPoint(CRS_2D, 10.0, 5.0);
+
+    /**
+     * A point at a position different than {@link #POINT_A}.
+     */
+    public static final Point POINT_B = GeometryFactory.createPoint(CRS_2D, 
20.0, 15.0);
+
+    /**
+     * The empty geometry expected as the result of an operation which found 
no position,
+     * for example the intersection of {@link #POINT_A} with {@link #POINT_B}.
+     * It is a distinct instance from {@link #EMPTY_1} on purpose: an 
operation builds its
+     * result rather than returning an operand when neither operand is empty.
+     */
+    public static final Empty EMPTY_RESULT = 
GeometryFactory.createEmpty(CRS_2D);
+
     /**
      * Do not allow instantiation of this class.
      */
     private TestData() {
     }
+
+    /**
+     * Asserts that the given collection contains exactly the positions of the 
given points,
+     * in any order. This is used for the results of the operations which are 
specified as a
+     * set of positions, the order of which is left to the implementation.
+     *
+     * @param  actual    the collection of points to verify.
+     * @param  expected  the points which shall be in the given collection, in 
any order.
+     */
+    public static void assertPositionsEqual(final MultiPoint<?> actual, final 
Point... expected) {
+        final List<String> remaining = new ArrayList<>(expected.length);
+        for (final Point point : expected) {
+            
remaining.add(Arrays.toString(point.getPosition().toArrayDouble()));
+        }
+        for (int i = 0; i < actual.getNumGeometries(); i++) {
+            final String position = 
Arrays.toString(actual.getGeometryN(i).getPosition().toArrayDouble());
+            assertTrue(remaining.remove(position), () -> "Unexpected position 
" + position + '.');
+        }
+        assertTrue(remaining.isEmpty(), () -> "Missing positions " + remaining 
+ '.');
+    }
 }
diff --git 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/To3DTest.java
 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/To3DTest.java
index f8558d72d5..acc0f6d0f9 100644
--- 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/To3DTest.java
+++ 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/To3DTest.java
@@ -19,6 +19,8 @@ package org.apache.sis.geometries.operation;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.opengis.util.FactoryException;
 import org.apache.sis.geometries.Geometry;
+import org.apache.sis.geometries.GeometryFactory;
+import org.apache.sis.geometries.Point;
 import org.apache.sis.geometries.mesh.MeshPrimitive;
 import org.apache.sis.maths.Tuple;
 import org.apache.sis.maths.NDArrays;
@@ -48,6 +50,16 @@ public class To3DTest {
         }
     }
 
+    @Test
+    public void testPoint() {
+        final Point point = GeometryFactory.createPoint(CRS2D, 10.0, 5.0);
+        final Geometry result = new GeometryProcessor().to3D(point, CRS2DZ, 
(Tuple t) -> t.set(2, 15));
+        assertInstanceOf(Point.class, result);
+        assertEquals(CRS2DZ, result.getCoordinateReferenceSystem());
+        assertArrayEquals(new double[] {10.0, 5.0, 15.0},
+                          ((Point) result).getPosition().toArrayDouble(), 0.0);
+    }
+
     @Test
     public void testPrimitive() {
 
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 24770cfea4..77cbb32834 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
@@ -19,6 +19,12 @@ 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.apache.sis.geometries.operation.TestData.POINT_A;
+import static org.apache.sis.geometries.operation.TestData.POINT_A_BIS;
+import static org.apache.sis.geometries.operation.TestData.POINT_B;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import org.junit.jupiter.api.Test;
@@ -49,6 +55,20 @@ public class TouchesTest {
      * All test cases of {@code touches(Geometry, Geometry)}.
      */
     private static final TestCase[] ENTRIES = {
+        /*
+         * Touching requires a shared position which is in the boundary of at 
least one of the
+         * two geometries. The empty set has no boundary, therefore it touches 
nothing.
+         */
+        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),
+        /*
+         * Two points cannot touch: the boundary of a point is empty, 
therefore the only
+         * position they may share is interior to both of them.
+         */
+        new TestCase(POINT_A, POINT_A_BIS, false, null),
+        new TestCase(POINT_A, POINT_B,     false, null)
     };
 
     /**
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 cfbe376d7c..e4003d186b 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
@@ -148,6 +148,14 @@ public class TransformTest {
      * All test cases of {@code transform(Geometry, CoordinateReferenceSystem, 
MathTransform)}.
      */
     private static final TestCase[] ENTRIES = {
+        /*
+         * TODO: `GeometryProcessor.transform(...)` handles only the mesh 
primitives and the
+         * surfaces built on linear rings. The transform of an empty geometry 
should be that
+         * geometry in the target reference system, and the transform of a 
point should be its
+         * position converted to that system.
+         */
+        new TestCase(TestData.EMPTY_1, CRS_TARGET, null, 
UnsupportedOperationException.class),
+        new TestCase(TestData.POINT_A, CRS_TARGET, null, 
UnsupportedOperationException.class)
     };
 
     /**
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 2465d5ae4c..c1578fa325 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
@@ -17,12 +17,17 @@
 package org.apache.sis.geometries.operation;
 
 import org.apache.sis.geometries.Geometry;
+import org.apache.sis.geometries.point.MultiPoint;
 
 // 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.apache.sis.geometries.operation.TestData.POINT_A;
+import static org.apache.sis.geometries.operation.TestData.POINT_A_BIS;
+import static org.apache.sis.geometries.operation.TestData.POINT_B;
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import org.junit.jupiter.api.Test;
 
@@ -55,7 +60,8 @@ public class UnionTest {
         // ∅ ∪ 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)
+        new TestCase(EMPTY_1,   EMPTY_2,   EMPTY_2,   null),
+        new TestCase(POINT_A, POINT_A_BIS, POINT_A, null)
     };
 
     /**
@@ -75,4 +81,18 @@ public class UnionTest {
             }
         }
     }
+
+    /**
+     * Tests {@code union(Geometry, Geometry)} on two points at different 
positions.
+     * The result shall contain both positions, in an unspecified order.
+     */
+    @Test
+    public void testDistinctPoints() {
+        final Geometry result = new GeometryProcessor().union(POINT_A, 
POINT_B);
+        assertInstanceOf(MultiPoint.class, result, "The union of two distinct 
points is a set of two points.");
+        final MultiPoint<?> points = (MultiPoint<?>) result;
+        assertEquals(TestData.CRS_2D, points.getCoordinateReferenceSystem());
+        assertEquals(2, points.getNumGeometries());
+        TestData.assertPositionsEqual(points, POINT_A, POINT_B);
+    }
 }
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 6125f59057..1465215369 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
@@ -18,8 +18,14 @@ 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.apache.sis.geometries.operation.TestData.POINT_A;
+import static org.apache.sis.geometries.operation.TestData.POINT_A_BIS;
+import static org.apache.sis.geometries.operation.TestData.POINT_B;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import org.junit.jupiter.api.Test;
@@ -31,6 +37,11 @@ import org.junit.jupiter.api.Test;
  * @author Johann Sorel (Geomatys)
  */
 public class WithinDistanceTest {
+    /**
+     * An arbitrary radius, smaller than the distance between the two points 
of the test cases.
+     */
+    private static final Quantity<?> RADIUS = Quantities.create(1, 
Units.DEGREE);
+
     /**
      * The inputs and expected result of a single test of {@code 
withinDistance(Geometry, Geometry, Length)}.
      *
@@ -52,6 +63,10 @@ public class WithinDistanceTest {
      * All test cases of {@code withinDistance(Geometry, Geometry, Quantity)}.
      */
     private static final TestCase[] ENTRIES = {
+        new TestCase(EMPTY_1, POINT_A,     RADIUS, false, null),
+        new TestCase(POINT_A, EMPTY_1,     RADIUS, false, null),
+        new TestCase(POINT_A, POINT_A_BIS, RADIUS, true, null),
+        new TestCase(POINT_A, POINT_B,     RADIUS, false, null)
     };
 
     /**
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 cb1b4ae902..57fe254c95 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
@@ -22,6 +22,9 @@ import org.apache.sis.geometries.Geometry;
 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.apache.sis.geometries.operation.TestData.POINT_A;
+import static org.apache.sis.geometries.operation.TestData.POINT_A_BIS;
+import static org.apache.sis.geometries.operation.TestData.POINT_B;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import org.junit.jupiter.api.Test;
@@ -56,7 +59,13 @@ public class WithinTest {
         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)
+        new TestCase(NON_EMPTY, EMPTY_1,   false, null),
+        /*
+         * A point is a subset of another point only when the two are at the 
same position.
+         */
+        new TestCase(POINT_A, POINT_A_BIS, true,  null),
+        new TestCase(POINT_A, POINT_B,     false, null),
+        new TestCase(POINT_B, POINT_A,     false, null)
     };
 
     /**

Reply via email to