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