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

erans pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-geometry.git

commit fd09ed0eb7f3dd61fc5377d455707c2ecc8108d5
Author: Matt Juntunen <matt.juntu...@hotmail.com>
AuthorDate: Fri Dec 13 00:26:56 2019 -0500

    miscellaneous cleanup and code coverage improvements
---
 .../geometry/core/internal/SimpleTupleFormat.java  |  56 ++++---
 .../AbstractEmbeddingSubHyperplane.java            |   3 +-
 .../bsp/AbstractBSPTreeMergeOperator.java          |  11 --
 .../partitioning/bsp/AbstractRegionBSPTree.java    | 165 ++++++++++-----------
 .../core/internal/GeometryInternalErrorTest.java   |  36 +++++
 .../AbstractConvexHyperplaneBoundedRegionTest.java |   2 -
 .../AbstractEmbeddingSubHyperplaneTest.java        |  44 ++++--
 .../core/partitioning/AbstractHyperplaneTest.java  |   2 -
 .../core/partitioning/bsp/AbstractBSPTreeTest.java |  20 +++
 .../core/precision/DoublePrecisionContextTest.java |   2 -
 .../euclidean/AbstractAffineTransformMatrix.java   |  19 +--
 .../geometry/euclidean/threed/SubPlaneTest.java    |   2 -
 .../twod/AbstractSegmentConnectorTest.java         |  43 +++++-
 13 files changed, 246 insertions(+), 159 deletions(-)

diff --git 
a/commons-geometry-core/src/main/java/org/apache/commons/geometry/core/internal/SimpleTupleFormat.java
 
b/commons-geometry-core/src/main/java/org/apache/commons/geometry/core/internal/SimpleTupleFormat.java
index ce0c9ac..d13e6e8 100644
--- 
a/commons-geometry-core/src/main/java/org/apache/commons/geometry/core/internal/SimpleTupleFormat.java
+++ 
b/commons-geometry-core/src/main/java/org/apache/commons/geometry/core/internal/SimpleTupleFormat.java
@@ -299,8 +299,7 @@ public class SimpleTupleFormat {
 
             return value;
         } catch (NumberFormatException exc) {
-            fail(String.format("unable to parse number from string \"%s\"", 
substr), str, pos, exc);
-            return 0.0; // for the compiler
+            throw parseFailure(String.format("unable to parse number from 
string \"%s\"", substr), str, pos, exc);
         }
     }
 
@@ -328,7 +327,7 @@ public class SimpleTupleFormat {
     private void endParse(String str, ParsePosition pos) {
         consumeWhitespace(str, pos);
         if (pos.getIndex() != str.length()) {
-            fail("unexpected content", str, pos);
+            throw parseFailure("unexpected content", str, pos);
         }
     }
 
@@ -395,35 +394,10 @@ public class SimpleTupleFormat {
             final int idx = pos.getIndex();
             final String actualSeq = str.substring(idx, Math.min(str.length(), 
idx + seq.length()));
 
-            fail(String.format("expected \"%s\" but found \"%s\"", seq, 
actualSeq), str, pos);
+            throw parseFailure(String.format("expected \"%s\" but found 
\"%s\"", seq, actualSeq), str, pos);
         }
     }
 
-    /** Abort the current parsing operation by throwing an {@link 
IllegalArgumentException} with an informative
-     * error message.
-     * @param msg the error message
-     * @param str the string being parsed
-     * @param pos the current parse position
-     * @throws IllegalArgumentException the exception signaling a parse failure
-     */
-    private void fail(String msg, String str, ParsePosition pos) {
-        fail(msg, str, pos, null);
-    }
-
-    /** Abort the current parsing operation by throwing an {@link 
IllegalArgumentException} with an informative
-     * error message.
-     * @param msg the error message
-     * @param str the string being parsed
-     * @param pos the current parse position
-     * @param cause the original cause of the error
-     * @throws IllegalArgumentException the exception signaling a parse failure
-     */
-    private void fail(String msg, String str, ParsePosition pos, Throwable 
cause) {
-        final String fullMsg = String.format("Failed to parse string \"%s\" at 
index %d: %s", str, pos.getIndex(), msg);
-
-        throw new TupleParseException(fullMsg, cause);
-    }
-
     /** Return an instance configured with default values. Tuples in this 
format
      * are enclosed by parentheses and separated by commas.
      *
@@ -439,6 +413,30 @@ public class SimpleTupleFormat {
         return DEFAULT_INSTANCE;
     }
 
+    /** Return an {@link IllegalArgumentException} representing a parsing 
failure.
+     * @param msg the error message
+     * @param str the string being parsed
+     * @param pos the current parse position
+     * @return an exception signaling a parse failure
+     */
+    private static IllegalArgumentException parseFailure(String msg, String 
str, ParsePosition pos) {
+        return parseFailure(msg, str, pos, null);
+    }
+
+    /** Return an {@link IllegalArgumentException} representing a parsing 
failure.
+     * @param msg the error message
+     * @param str the string being parsed
+     * @param pos the current parse position
+     * @param cause the original cause of the error
+     * @return an exception signaling a parse failure
+     */
+    private static IllegalArgumentException parseFailure(String msg, String 
str, ParsePosition pos, Throwable cause) {
+        final String fullMsg = String.format("Failed to parse string \"%s\" at 
index %d: %s",
+                str, pos.getIndex(), msg);
+
+        return new TupleParseException(fullMsg, cause);
+    }
+
     /** Exception class for errors occurring during tuple parsing.
      */
     private static class TupleParseException extends IllegalArgumentException {
diff --git 
a/commons-geometry-core/src/main/java/org/apache/commons/geometry/core/partitioning/AbstractEmbeddingSubHyperplane.java
 
b/commons-geometry-core/src/main/java/org/apache/commons/geometry/core/partitioning/AbstractEmbeddingSubHyperplane.java
index 7f9a43c..acbce9c 100644
--- 
a/commons-geometry-core/src/main/java/org/apache/commons/geometry/core/partitioning/AbstractEmbeddingSubHyperplane.java
+++ 
b/commons-geometry-core/src/main/java/org/apache/commons/geometry/core/partitioning/AbstractEmbeddingSubHyperplane.java
@@ -30,6 +30,7 @@ public abstract class AbstractEmbeddingSubHyperplane<
     P extends Point<P>,
     S extends Point<S>,
     H extends EmbeddingHyperplane<P, S>> implements SubHyperplane<P> {
+
     /** {@inheritDoc} */
     @Override
     public boolean isFull() {
@@ -51,7 +52,7 @@ public abstract class AbstractEmbeddingSubHyperplane<
     /** {@inheritDoc} */
     @Override
     public boolean isFinite() {
-        return !isInfinite();
+        return Double.isFinite(getSize());
     }
 
     /** {@inheritDoc} */
diff --git 
a/commons-geometry-core/src/main/java/org/apache/commons/geometry/core/partitioning/bsp/AbstractBSPTreeMergeOperator.java
 
b/commons-geometry-core/src/main/java/org/apache/commons/geometry/core/partitioning/bsp/AbstractBSPTreeMergeOperator.java
index 8cfaa46..ae84255 100644
--- 
a/commons-geometry-core/src/main/java/org/apache/commons/geometry/core/partitioning/bsp/AbstractBSPTreeMergeOperator.java
+++ 
b/commons-geometry-core/src/main/java/org/apache/commons/geometry/core/partitioning/bsp/AbstractBSPTreeMergeOperator.java
@@ -112,17 +112,6 @@ public abstract class AbstractBSPTreeMergeOperator<P 
extends Point<P>, N extends
         return outputTree.createNode();
     }
 
-    /** Create a new node in the output tree with the same non-structural 
properties as the given
-     * node. Non-structural properties are properties other than parent, 
children, or cut. The
-     * returned node is associated with the output tree but is not attached to 
a parent node.
-     * Note that this method only copies the given node and 
<strong>not</strong> any of its children.
-     * @param node the input node to copy properties from
-     * @return a new node in the output tree
-     */
-    protected N outputNode(final N node) {
-        return outputTree.copyNode(node);
-    }
-
     /** Place the subtree rooted at the given input node into the output tree. 
The subtree
      * is copied if needed.
      * @param node the root of the subtree to copy
diff --git 
a/commons-geometry-core/src/main/java/org/apache/commons/geometry/core/partitioning/bsp/AbstractRegionBSPTree.java
 
b/commons-geometry-core/src/main/java/org/apache/commons/geometry/core/partitioning/bsp/AbstractRegionBSPTree.java
index 8500396..89b5569 100644
--- 
a/commons-geometry-core/src/main/java/org/apache/commons/geometry/core/partitioning/bsp/AbstractRegionBSPTree.java
+++ 
b/commons-geometry-core/src/main/java/org/apache/commons/geometry/core/partitioning/bsp/AbstractRegionBSPTree.java
@@ -446,91 +446,6 @@ public abstract class AbstractRegionBSPTree<
         dst.setLocation(src.getLocationValue());
     }
 
-    /** Compute the portion of the node's cut subhyperplane that lies on the 
boundary of
-     * the region.
-     * @param node the node to compute the cut subhyperplane boundary of
-     * @return object representing the portions of the node's cut 
subhyperplane that lie
-     *      on the region's boundary
-     */
-    private RegionCutBoundary<P> computeBoundary(final N node) {
-        if (node.isLeaf()) {
-            // no boundary for leaf nodes; they are either entirely in or
-            // entirely out
-            return null;
-        }
-
-        ConvexSubHyperplane<P> sub = node.getCut();
-
-        // find the portions of the node cut sub-hyperplane that touch inside 
and
-        // outside cells in the minus sub-tree
-        SubHyperplane.Builder<P> minusInBuilder = sub.builder();
-        SubHyperplane.Builder<P> minusOutBuilder = sub.builder();
-
-        characterizeSubHyperplane(sub, node.getMinus(), minusInBuilder, 
minusOutBuilder);
-
-        List<? extends ConvexSubHyperplane<P>> minusIn = 
minusInBuilder.build().toConvex();
-        List<? extends ConvexSubHyperplane<P>> minusOut = 
minusOutBuilder.build().toConvex();
-
-        // create the result boundary builders
-        SubHyperplane.Builder<P> insideFacing = sub.builder();
-        SubHyperplane.Builder<P> outsideFacing = sub.builder();
-
-        if (!minusIn.isEmpty()) {
-            // Add to the boundary anything that touches an inside cell in the 
minus sub-tree
-            // and an outside cell in the plus sub-tree. These portions are 
oriented with their
-            // plus side pointing to the outside of the region.
-            for (ConvexSubHyperplane<P> minusInFragment : minusIn) {
-                characterizeSubHyperplane(minusInFragment, node.getPlus(), 
null, outsideFacing);
-            }
-        }
-
-        if (!minusOut.isEmpty()) {
-            // Add to the boundary anything that touches an outside cell in 
the minus sub-tree
-            // and an inside cell in the plus sub-tree. These portions are 
oriented with their
-            // plus side pointing to the inside of the region.
-            for (ConvexSubHyperplane<P> minusOutFragment : minusOut) {
-                characterizeSubHyperplane(minusOutFragment, node.getPlus(), 
insideFacing, null);
-            }
-        }
-
-        return new RegionCutBoundary<>(insideFacing.build(), 
outsideFacing.build());
-    }
-
-    /** Recursive method to characterize a convex subhyperplane with respect 
to the region's
-     * boundaries.
-     * @param sub the subhyperplane to characterize
-     * @param node the node to characterize the subhyperplane against
-     * @param in the builder that will receive the portions of the 
subhyperplane that lie in the inside
-     *      of the region; may be null
-     * @param out the builder that will receive the portions of the 
subhyperplane that lie on the outside
-     *      of the region; may be null
-     */
-    private void characterizeSubHyperplane(final ConvexSubHyperplane<P> sub, 
final AbstractRegionNode<P, N> node,
-            final SubHyperplane.Builder<P> in, final SubHyperplane.Builder<P> 
out) {
-
-        if (sub != null) {
-            if (node.isLeaf()) {
-                if (node.isInside() && in != null) {
-                    in.add(sub);
-                } else if (node.isOutside() && out != null) {
-                    out.add(sub);
-                }
-            } else {
-                final Split<? extends ConvexSubHyperplane<P>> split = 
sub.split(node.getCutHyperplane());
-
-                // Continue further on down the subtree with the same 
subhyperplane if the
-                // subhyperplane lies directly on the current node's cut
-                if (split.getLocation() == SplitLocation.NEITHER) {
-                    characterizeSubHyperplane(sub, node.getPlus(), in, out);
-                    characterizeSubHyperplane(sub, node.getMinus(), in, out);
-                } else {
-                    characterizeSubHyperplane(split.getPlus(), node.getPlus(), 
in, out);
-                    characterizeSubHyperplane(split.getMinus(), 
node.getMinus(), in, out);
-                }
-            }
-        }
-    }
-
     /** {@inheritDoc} */
     @Override
     protected void initChildNode(final N parent, final N child, final boolean 
isPlus) {
@@ -611,13 +526,91 @@ public abstract class AbstractRegionBSPTree<
                 checkValid();
 
                 if (cutBoundary == null) {
-                    cutBoundary = getTree().computeBoundary(getSelf());
+                    cutBoundary = computeBoundary();
                 }
             }
 
             return cutBoundary;
         }
 
+        /** Compute the portion of the node's cut subhyperplane that lies on 
the boundary of
+         * the region. This method must only be called on internal nodes.
+         * @return object representing the portions of the node's cut 
subhyperplane that lie
+         *      on the region's boundary
+         */
+        private RegionCutBoundary<P> computeBoundary() {
+            ConvexSubHyperplane<P> sub = getCut();
+
+            // find the portions of the node cut sub-hyperplane that touch 
inside and
+            // outside cells in the minus sub-tree
+            SubHyperplane.Builder<P> minusInBuilder = sub.builder();
+            SubHyperplane.Builder<P> minusOutBuilder = sub.builder();
+
+            characterizeSubHyperplane(sub, getMinus(), minusInBuilder, 
minusOutBuilder);
+
+            List<? extends ConvexSubHyperplane<P>> minusIn = 
minusInBuilder.build().toConvex();
+            List<? extends ConvexSubHyperplane<P>> minusOut = 
minusOutBuilder.build().toConvex();
+
+            // create the result boundary builders
+            SubHyperplane.Builder<P> insideFacing = sub.builder();
+            SubHyperplane.Builder<P> outsideFacing = sub.builder();
+
+            if (!minusIn.isEmpty()) {
+                // Add to the boundary anything that touches an inside cell in 
the minus sub-tree
+                // and an outside cell in the plus sub-tree. These portions 
are oriented with their
+                // plus side pointing to the outside of the region.
+                for (ConvexSubHyperplane<P> minusInFragment : minusIn) {
+                    characterizeSubHyperplane(minusInFragment, getPlus(), 
null, outsideFacing);
+                }
+            }
+
+            if (!minusOut.isEmpty()) {
+                // Add to the boundary anything that touches an outside cell 
in the minus sub-tree
+                // and an inside cell in the plus sub-tree. These portions are 
oriented with their
+                // plus side pointing to the inside of the region.
+                for (ConvexSubHyperplane<P> minusOutFragment : minusOut) {
+                    characterizeSubHyperplane(minusOutFragment, getPlus(), 
insideFacing, null);
+                }
+            }
+
+            return new RegionCutBoundary<>(insideFacing.build(), 
outsideFacing.build());
+        }
+
+        /** Recursive method to characterize a convex subhyperplane with 
respect to the region's
+         * boundaries.
+         * @param sub the subhyperplane to characterize
+         * @param node the node to characterize the subhyperplane against
+         * @param in the builder that will receive the portions of the 
subhyperplane that lie in the inside
+         *      of the region; may be null
+         * @param out the builder that will receive the portions of the 
subhyperplane that lie on the outside
+         *      of the region; may be null
+         */
+        private void characterizeSubHyperplane(final ConvexSubHyperplane<P> 
sub, final AbstractRegionNode<P, N> node,
+                final SubHyperplane.Builder<P> in, final 
SubHyperplane.Builder<P> out) {
+
+            if (sub != null) {
+                if (node.isLeaf()) {
+                    if (node.isInside() && in != null) {
+                        in.add(sub);
+                    } else if (node.isOutside() && out != null) {
+                        out.add(sub);
+                    }
+                } else {
+                    final Split<? extends ConvexSubHyperplane<P>> split = 
sub.split(node.getCutHyperplane());
+
+                    // Continue further on down the subtree with the same 
subhyperplane if the
+                    // subhyperplane lies directly on the current node's cut
+                    if (split.getLocation() == SplitLocation.NEITHER) {
+                        characterizeSubHyperplane(sub, node.getPlus(), in, 
out);
+                        characterizeSubHyperplane(sub, node.getMinus(), in, 
out);
+                    } else {
+                        characterizeSubHyperplane(split.getPlus(), 
node.getPlus(), in, out);
+                        characterizeSubHyperplane(split.getMinus(), 
node.getMinus(), in, out);
+                    }
+                }
+            }
+        }
+
         /** {@inheritDoc} */
         @Override
         public String toString() {
diff --git 
a/commons-geometry-core/src/test/java/org/apache/commons/geometry/core/internal/GeometryInternalErrorTest.java
 
b/commons-geometry-core/src/test/java/org/apache/commons/geometry/core/internal/GeometryInternalErrorTest.java
new file mode 100644
index 0000000..e01bd47
--- /dev/null
+++ 
b/commons-geometry-core/src/test/java/org/apache/commons/geometry/core/internal/GeometryInternalErrorTest.java
@@ -0,0 +1,36 @@
+/*
+ * 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.commons.geometry.core.internal;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class GeometryInternalErrorTest {
+
+    @Test
+    public void testMessage() {
+        // act
+        GeometryInternalError err = new GeometryInternalError();
+
+        // assert
+        String msg = "An internal geometry error occurred. This most often 
indicates an " +
+                "error in the algorithm implementation than in the calling 
code or data. Please file a bug report " +
+                "with the developers.";
+
+        Assert.assertEquals(msg, err.getMessage());
+    }
+}
diff --git 
a/commons-geometry-core/src/test/java/org/apache/commons/geometry/core/partitioning/AbstractConvexHyperplaneBoundedRegionTest.java
 
b/commons-geometry-core/src/test/java/org/apache/commons/geometry/core/partitioning/AbstractConvexHyperplaneBoundedRegionTest.java
index a33ce68..8b25791 100644
--- 
a/commons-geometry-core/src/test/java/org/apache/commons/geometry/core/partitioning/AbstractConvexHyperplaneBoundedRegionTest.java
+++ 
b/commons-geometry-core/src/test/java/org/apache/commons/geometry/core/partitioning/AbstractConvexHyperplaneBoundedRegionTest.java
@@ -505,8 +505,6 @@ public class AbstractConvexHyperplaneBoundedRegionTest {
 
     private static final class StubRegion extends 
AbstractConvexHyperplaneBoundedRegion<TestPoint2D, TestLineSegment>{
 
-        private static final long serialVersionUID = 1L;
-
         private static final StubRegion FULL = new 
StubRegion(Collections.emptyList());
 
         StubRegion(List<TestLineSegment> boundaries) {
diff --git 
a/commons-geometry-core/src/test/java/org/apache/commons/geometry/core/partitioning/AbstractEmbeddingSubHyperplaneTest.java
 
b/commons-geometry-core/src/test/java/org/apache/commons/geometry/core/partitioning/AbstractEmbeddingSubHyperplaneTest.java
index a5c6ef2..6b75c0a 100644
--- 
a/commons-geometry-core/src/test/java/org/apache/commons/geometry/core/partitioning/AbstractEmbeddingSubHyperplaneTest.java
+++ 
b/commons-geometry-core/src/test/java/org/apache/commons/geometry/core/partitioning/AbstractEmbeddingSubHyperplaneTest.java
@@ -32,12 +32,33 @@ public class AbstractEmbeddingSubHyperplaneTest {
     @Test
     public void testSimpleProperties() {
         // arrange
-        StubSubHyperplane sub = new StubSubHyperplane();
+        StubSubHyperplane sub = new StubSubHyperplane(1.0);
 
         // act/assert
         Assert.assertTrue(sub.isFull());
         Assert.assertTrue(sub.isEmpty());
         Assert.assertEquals(1.0, sub.getSize(), PartitionTestUtils.EPS);
+
+        Assert.assertTrue(sub.isFinite());
+        Assert.assertFalse(sub.isInfinite());
+    }
+
+    @Test
+    public void testFiniteAndInfinite() {
+        // arrange
+        StubSubHyperplane finite = new StubSubHyperplane(1.0);
+        StubSubHyperplane inf = new 
StubSubHyperplane(Double.POSITIVE_INFINITY);
+        StubSubHyperplane nan = new StubSubHyperplane(Double.NaN);
+
+        // act/assert
+        Assert.assertTrue(finite.isFinite());
+        Assert.assertFalse(finite.isInfinite());
+
+        Assert.assertFalse(inf.isFinite());
+        Assert.assertTrue(inf.isInfinite());
+
+        Assert.assertFalse(nan.isFinite());
+        Assert.assertFalse(nan.isInfinite());
     }
 
     @Test
@@ -82,16 +103,15 @@ public class AbstractEmbeddingSubHyperplaneTest {
     }
 
     private static class StubSubHyperplane extends 
AbstractEmbeddingSubHyperplane<TestPoint2D, TestPoint1D, TestLine> {
-        private StubRegion1D region = new StubRegion1D();
 
-        @Override
-        public boolean isInfinite() {
-            return false;
+        private final StubRegion1D region;
+
+        public StubSubHyperplane() {
+            this(0);
         }
 
-        @Override
-        public boolean isFinite() {
-            return true;
+        public StubSubHyperplane(final double size) {
+            this.region = new StubRegion1D(size);
         }
 
         @Override
@@ -132,6 +152,12 @@ public class AbstractEmbeddingSubHyperplaneTest {
 
         private TestPoint1D projected = new TestPoint1D(0);
 
+        private final double size;
+
+        public StubRegion1D(final double size) {
+            this.size = size;
+        }
+
         @Override
         public boolean isFull() {
             return true;
@@ -144,7 +170,7 @@ public class AbstractEmbeddingSubHyperplaneTest {
 
         @Override
         public double getSize() {
-            return 1;
+            return size;
         }
 
         @Override
diff --git 
a/commons-geometry-core/src/test/java/org/apache/commons/geometry/core/partitioning/AbstractHyperplaneTest.java
 
b/commons-geometry-core/src/test/java/org/apache/commons/geometry/core/partitioning/AbstractHyperplaneTest.java
index 5855448..89e677c 100644
--- 
a/commons-geometry-core/src/test/java/org/apache/commons/geometry/core/partitioning/AbstractHyperplaneTest.java
+++ 
b/commons-geometry-core/src/test/java/org/apache/commons/geometry/core/partitioning/AbstractHyperplaneTest.java
@@ -74,8 +74,6 @@ public class AbstractHyperplaneTest {
 
     public static class StubHyperplane extends AbstractHyperplane<TestPoint2D> 
{
 
-        private static final long serialVersionUID = 1L;
-
         public StubHyperplane(DoublePrecisionContext precision) {
             super(precision);
         }
diff --git 
a/commons-geometry-core/src/test/java/org/apache/commons/geometry/core/partitioning/bsp/AbstractBSPTreeTest.java
 
b/commons-geometry-core/src/test/java/org/apache/commons/geometry/core/partitioning/bsp/AbstractBSPTreeTest.java
index 50a9781..b3077bc 100644
--- 
a/commons-geometry-core/src/test/java/org/apache/commons/geometry/core/partitioning/bsp/AbstractBSPTreeTest.java
+++ 
b/commons-geometry-core/src/test/java/org/apache/commons/geometry/core/partitioning/bsp/AbstractBSPTreeTest.java
@@ -19,8 +19,10 @@ package org.apache.commons.geometry.core.partitioning.bsp;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.NoSuchElementException;
 import java.util.stream.Collectors;
 
 import org.apache.commons.geometry.core.Transform;
@@ -1129,6 +1131,24 @@ public class AbstractBSPTreeTest {
         Assert.assertSame(root.getPlus().getPlus(), nodes.get(6));
     }
 
+
+    @Test
+    public void testIterable_iteratorThrowsNoSuchElementExceptionAtEnd() {
+        // arrange
+        TestBSPTree tree = new TestBSPTree();
+
+        Iterator<TestNode> it = tree.iterator();
+        it.next();
+
+        // act
+        try {
+            it.next();
+            Assert.fail("Operation should have thrown an exception");
+        } catch (NoSuchElementException exc) {
+            // expected
+        }
+    }
+
     @Test
     public void testStream_emptyTree() {
         // arrange
diff --git 
a/commons-geometry-core/src/test/java/org/apache/commons/geometry/core/precision/DoublePrecisionContextTest.java
 
b/commons-geometry-core/src/test/java/org/apache/commons/geometry/core/precision/DoublePrecisionContextTest.java
index 17a95a1..5a6616d 100644
--- 
a/commons-geometry-core/src/test/java/org/apache/commons/geometry/core/precision/DoublePrecisionContextTest.java
+++ 
b/commons-geometry-core/src/test/java/org/apache/commons/geometry/core/precision/DoublePrecisionContextTest.java
@@ -132,8 +132,6 @@ public class DoublePrecisionContextTest {
 
     private static class StubContext extends DoublePrecisionContext {
 
-        private static final long serialVersionUID = 1L;
-
         @Override
         public double getMaxZero() {
             return 0.0;
diff --git 
a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/AbstractAffineTransformMatrix.java
 
b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/AbstractAffineTransformMatrix.java
index 7418b6a..476d11a 100644
--- 
a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/AbstractAffineTransformMatrix.java
+++ 
b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/AbstractAffineTransformMatrix.java
@@ -60,7 +60,7 @@ public abstract class AbstractAffineTransformMatrix<V extends 
EuclideanVector<V>
     protected double getDeterminantForInverse() {
         final double det = determinant();
         if (!Vectors.isRealNonZero(det)) {
-            nonInvertibleTransform("matrix determinant is " + det);
+            throw nonInvertibleTransform("matrix determinant is " + det);
         }
         return det;
     }
@@ -73,23 +73,16 @@ public abstract class AbstractAffineTransformMatrix<V 
extends EuclideanVector<V>
      */
     protected void validateElementForInverse(final double element) {
         if (!Double.isFinite(element)) {
-            nonInvertibleTransform("invalid matrix element: " + element);
+            throw nonInvertibleTransform("invalid matrix element: " + element);
         }
     }
 
-    /** Create an exception indicating that a transform matrix is not able
-     * to be inverted.
-     * @param msg message containing specific information for the failure
-     * @return an exception indicating that a transform matrix is not able
-     *      to be inverted
-     */
-
-    /** Throw an exception indicating that the instance is not able to be 
inverted.
+    /** Create an exception indicating that the instance is not able to be 
inverted.
      * @param msg message containing the specific reason that the matrix cannot
      *      be inverted
-     * @throws IllegalStateException containing the given error message
+     * @return IllegalStateException containing the given error message
      */
-    protected void nonInvertibleTransform(final String msg) {
-        throw new IllegalStateException("Transform is not invertible; " + msg);
+    protected IllegalStateException nonInvertibleTransform(final String msg) {
+        return new IllegalStateException("Transform is not invertible; " + 
msg);
     }
 }
diff --git 
a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/SubPlaneTest.java
 
b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/SubPlaneTest.java
index 285d063..b50bf51 100644
--- 
a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/SubPlaneTest.java
+++ 
b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/SubPlaneTest.java
@@ -479,8 +479,6 @@ public class SubPlaneTest {
 
     private static class StubSubPlane extends 
AbstractSubPlane<RegionBSPTree2D> implements SubHyperplane<Vector3D> {
 
-        private static final long serialVersionUID = 1L;
-
         StubSubPlane(Plane plane) {
             super(plane);
         }
diff --git 
a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/twod/AbstractSegmentConnectorTest.java
 
b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/twod/AbstractSegmentConnectorTest.java
index 8113ba2..9a9681c 100644
--- 
a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/twod/AbstractSegmentConnectorTest.java
+++ 
b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/twod/AbstractSegmentConnectorTest.java
@@ -26,6 +26,7 @@ import org.apache.commons.numbers.angle.PlaneAngleRadians;
 import org.apache.commons.geometry.core.precision.DoublePrecisionContext;
 import 
org.apache.commons.geometry.core.precision.EpsilonDoublePrecisionContext;
 import org.apache.commons.geometry.euclidean.EuclideanTestUtils;
+import 
org.apache.commons.geometry.euclidean.twod.AbstractSegmentConnector.ConnectableSegment;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -482,6 +483,46 @@ public class AbstractSegmentConnectorTest {
         assertFinitePath(paths.get(1), Vector2D.Unit.PLUS_X, Vector2D.of(2, 
0));
     }
 
+    @Test
+    public void testConnectableSegment_hashCode() {
+        // arrange
+        Segment segA = Segment.fromPoints(Vector2D.ZERO, Vector2D.Unit.PLUS_X, 
TEST_PRECISION);
+        Segment segB = Segment.fromPoints(Vector2D.Unit.PLUS_X, Vector2D.of(1, 
1), TEST_PRECISION);
+
+        ConnectableSegment a = new ConnectableSegment(segA);
+
+        // act
+        int hash = a.hashCode();
+
+        // assert
+        Assert.assertEquals(hash, a.hashCode());
+
+        Assert.assertNotEquals(hash, new ConnectableSegment(segB).hashCode());
+        Assert.assertNotEquals(hash, new 
ConnectableSegment(Vector2D.Unit.PLUS_X).hashCode());
+
+        Assert.assertEquals(hash, new ConnectableSegment(segA).hashCode());
+    }
+
+    @Test
+    public void testConnectableSegment_equals() {
+        // arrange
+        Segment segA = Segment.fromPoints(Vector2D.ZERO, Vector2D.Unit.PLUS_X, 
TEST_PRECISION);
+        Segment segB = Segment.fromPoints(Vector2D.Unit.PLUS_X, Vector2D.of(1, 
1), TEST_PRECISION);
+
+        ConnectableSegment a = new ConnectableSegment(segA);
+
+        // act/assert
+        Assert.assertTrue(a.equals(a));
+
+        Assert.assertFalse(a.equals(null));
+        Assert.assertFalse(a.equals(new Object()));
+
+        Assert.assertFalse(a.equals(new ConnectableSegment(segB)));
+        Assert.assertFalse(a.equals(new 
ConnectableSegment(Vector2D.Unit.PLUS_X)));
+
+        Assert.assertTrue(a.equals(new ConnectableSegment(segA)));
+    }
+
     private static List<Segment> shuffle(final List<Segment> segments) {
         return shuffle(segments, 1);
     }
@@ -514,8 +555,6 @@ public class AbstractSegmentConnectorTest {
 
     private static class TestConnector extends AbstractSegmentConnector {
 
-        private static final long serialVersionUID = 1L;
-
         @Override
         protected ConnectableSegment selectConnection(ConnectableSegment 
incoming, List<ConnectableSegment> outgoing) {
             // just choose the first element

Reply via email to