From bb7f1d586b4c72b0d87dbe2fdeab04d35797e2e7 Mon Sep 17 00:00:00 2001
From: Vojtech Moravec <vojtech.moravec.st@vsb.cz>
Date: Thu, 22 Oct 2020 14:15:30 +0200
Subject: [PATCH] Add tests for basic data types and fix equals methods.

---
 pom.xml                                       |  6 ++
 .../java/cz/it4i/qcmp/cli/ParseUtils.java     |  5 +-
 .../it4i/qcmp/data/HyperStackDimensions.java  | 18 +++-
 src/main/java/cz/it4i/qcmp/data/Range.java    | 15 +++
 src/main/java/cz/it4i/qcmp/data/V2.java       |  2 +-
 src/main/java/cz/it4i/qcmp/data/V3.java       |  2 +-
 .../java/cz/it4i/qcmp/cli/ParseUtilsTest.java | 98 +++++++++++++++++++
 7 files changed, 141 insertions(+), 5 deletions(-)
 create mode 100644 src/test/java/cz/it4i/qcmp/cli/ParseUtilsTest.java

diff --git a/pom.xml b/pom.xml
index 34f7cd9..ccc76c7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -154,5 +154,11 @@
             <artifactId>commons-io</artifactId>
             <version>2.6</version>
         </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter</artifactId>
+            <version>RELEASE</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 </project>
\ No newline at end of file
diff --git a/src/main/java/cz/it4i/qcmp/cli/ParseUtils.java b/src/main/java/cz/it4i/qcmp/cli/ParseUtils.java
index aa261af..46c3760 100644
--- a/src/main/java/cz/it4i/qcmp/cli/ParseUtils.java
+++ b/src/main/java/cz/it4i/qcmp/cli/ParseUtils.java
@@ -147,13 +147,14 @@ public abstract class ParseUtils {
         y = maybeY.get();
 
         if (indexes.length > 1) {
-            final Optional<Integer> maybeZ = tryParseInt(string.substring(indexes[1], indexes.length > 2 ? indexes[2] : string.length()));
+            final Optional<Integer> maybeZ = tryParseInt(string.substring(indexes[1] + 1,
+                                                                          indexes.length > 2 ? indexes[2] : string.length()));
             if (!maybeZ.isPresent())
                 return Optional.empty();
             z = maybeZ.get();
 
             if (indexes.length > 2) {
-                final Optional<Integer> maybeT = tryParseInt(string.substring(indexes[2]));
+                final Optional<Integer> maybeT = tryParseInt(string.substring(indexes[2] + 1));
                 if (!maybeT.isPresent())
                     return Optional.empty();
                 t = maybeT.get();
diff --git a/src/main/java/cz/it4i/qcmp/data/HyperStackDimensions.java b/src/main/java/cz/it4i/qcmp/data/HyperStackDimensions.java
index 140eee7..78a71be 100644
--- a/src/main/java/cz/it4i/qcmp/data/HyperStackDimensions.java
+++ b/src/main/java/cz/it4i/qcmp/data/HyperStackDimensions.java
@@ -1,5 +1,7 @@
 package cz.it4i.qcmp.data;
 
+import java.util.Objects;
+
 /**
  * Class representing dimensions of the Stack or Hyperstack.
  * This terminology is taken from the ImageJ.
@@ -10,7 +12,6 @@ public class HyperStackDimensions {
     private final int sliceCount;
     private final int numberOfTimepoints;
 
-
     /**
      * Create HyperStackDimensions.
      *
@@ -87,4 +88,19 @@ public class HyperStackDimensions {
     public String toString() {
         return String.format("X=%d;Y=%d;Z=%d;T=%d", width, height, sliceCount, numberOfTimepoints);
     }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(width, height, sliceCount, numberOfTimepoints);
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (obj instanceof HyperStackDimensions) {
+            final HyperStackDimensions other = (HyperStackDimensions) obj;
+            return (width == other.width && height == other.height &&
+                    sliceCount == other.sliceCount && numberOfTimepoints == other.numberOfTimepoints);
+        }
+        return super.equals(obj);
+    }
 }
diff --git a/src/main/java/cz/it4i/qcmp/data/Range.java b/src/main/java/cz/it4i/qcmp/data/Range.java
index c309cd4..07bfa34 100644
--- a/src/main/java/cz/it4i/qcmp/data/Range.java
+++ b/src/main/java/cz/it4i/qcmp/data/Range.java
@@ -1,5 +1,7 @@
 package cz.it4i.qcmp.data;
 
+import java.util.Objects;
+
 public final class Range<T extends Comparable<T>> {
     /**
      * Start of the interval.
@@ -44,4 +46,17 @@ public final class Range<T extends Comparable<T>> {
     public String toString() {
         return "Range: [" + from + " - " + to + "]";
     }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(from, to);
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (obj instanceof Range<?>) {
+            return hashCode() == obj.hashCode();
+        }
+        return super.equals(obj);
+    }
 }
diff --git a/src/main/java/cz/it4i/qcmp/data/V2.java b/src/main/java/cz/it4i/qcmp/data/V2.java
index 50dd462..f0da93c 100644
--- a/src/main/java/cz/it4i/qcmp/data/V2.java
+++ b/src/main/java/cz/it4i/qcmp/data/V2.java
@@ -74,7 +74,7 @@ public class V2<T> {
     public boolean equals(final Object obj) {
         if (obj instanceof V2<?>) {
             final V2<?> other = (V2<?>) obj;
-            return ((x == other.x) && (y == other.y));
+            return (x.equals(other.x) && y.equals(other.y));
         } else {
             return super.equals(obj);
         }
diff --git a/src/main/java/cz/it4i/qcmp/data/V3.java b/src/main/java/cz/it4i/qcmp/data/V3.java
index 973bd9d..a3f5b9b 100644
--- a/src/main/java/cz/it4i/qcmp/data/V3.java
+++ b/src/main/java/cz/it4i/qcmp/data/V3.java
@@ -52,7 +52,7 @@ public class V3<T> extends V2<T> {
     public boolean equals(final Object obj) {
         if (obj instanceof V3<?>) {
             final V3<?> other = (V3<?>) obj;
-            return ((getX() == other.getX()) && (getY() == other.getY()) && (z == other.z));
+            return (getX().equals(other.getX()) && getY().equals(other.getY()) && z.equals(other.z));
         } else {
             return super.equals(obj);
         }
diff --git a/src/test/java/cz/it4i/qcmp/cli/ParseUtilsTest.java b/src/test/java/cz/it4i/qcmp/cli/ParseUtilsTest.java
new file mode 100644
index 0000000..811149a
--- /dev/null
+++ b/src/test/java/cz/it4i/qcmp/cli/ParseUtilsTest.java
@@ -0,0 +1,98 @@
+package cz.it4i.qcmp.cli;
+
+import cz.it4i.qcmp.data.HyperStackDimensions;
+import cz.it4i.qcmp.data.Range;
+import cz.it4i.qcmp.data.V2i;
+import cz.it4i.qcmp.data.V3i;
+import org.junit.jupiter.api.Test;
+
+import java.util.Optional;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class ParseUtilsTest {
+
+    private void tryParseHyperStackDimensionsHelper(final String string,
+                                                    final boolean shouldSucceed,
+                                                    final HyperStackDimensions expectedResult) {
+        final Optional<HyperStackDimensions> parseResult = ParseUtils.tryParseHyperStackDimensions(string, 'x');
+        assertEquals(shouldSucceed, parseResult.isPresent());
+
+        //noinspection OptionalIsPresent
+        if (parseResult.isPresent()) {
+            assertEquals(parseResult.get(), expectedResult);
+        }
+    }
+
+
+    @Test
+    void tryParseHyperStackDimensions() {
+        tryParseHyperStackDimensionsHelper("100x100", true, new HyperStackDimensions(100, 100));
+        tryParseHyperStackDimensionsHelper("100x200x300", true, new HyperStackDimensions(100, 200, 300));
+        tryParseHyperStackDimensionsHelper("100x200x300x400", true, new HyperStackDimensions(100, 200, 300, 400));
+        tryParseHyperStackDimensionsHelper("100", false, null);
+        tryParseHyperStackDimensionsHelper("100x", false, null);
+        tryParseHyperStackDimensionsHelper("x50", false, null);
+        tryParseHyperStackDimensionsHelper("100x100x", false, null);
+        tryParseHyperStackDimensionsHelper("100xx", false, null);
+        tryParseHyperStackDimensionsHelper("100x100x100x", false, null);
+    }
+
+    @Test
+    void tryParseInt() {
+        assertTrue(ParseUtils.tryParseInt("10").isPresent());
+        assertFalse(ParseUtils.tryParseInt("q10").isPresent());
+        assertEquals(ParseUtils.tryParseInt("10").get(), 10);
+    }
+
+    @Test
+    void tryParseRange() {
+        final Optional<Range<Integer>> t1 = ParseUtils.tryParseRange("10-20", '-');
+        assertTrue(t1.isPresent());
+        assertEquals(t1.get(), new Range<>(10, 20));
+
+        final Optional<Range<Integer>> t2 = ParseUtils.tryParseRange("999x10045", 'x');
+        assertTrue(t2.isPresent());
+        assertEquals(t2.get(), new Range<>(999, 10045));
+
+        assertFalse(ParseUtils.tryParseRange("999x10045", '-').isPresent());
+        assertFalse(ParseUtils.tryParseRange("99910045", 'x').isPresent());
+    }
+
+    @Test
+    void tryParseV2i() {
+        final Optional<V2i> c1 = ParseUtils.tryParseV2i("10x20", 'x');
+        assertTrue(c1.isPresent());
+        assertEquals(c1.get(), new V2i(10, 20));
+
+        final Optional<V2i> c2 = ParseUtils.tryParseV2i("-20x-89", 'x');
+        assertTrue(c2.isPresent());
+        assertEquals(c2.get(), new V2i(-20, -89));
+
+        final Optional<V2i> i1 = ParseUtils.tryParseV2i("10x20", '-');
+        assertFalse(i1.isPresent());
+
+        final Optional<V2i> i2 = ParseUtils.tryParseV2i("15", 'x');
+        assertFalse(i2.isPresent());
+    }
+
+    @Test
+    void tryParseV3i() {
+        final Optional<V3i> c1 = ParseUtils.tryParseV3i("10x20x30", 'x');
+        assertTrue(c1.isPresent());
+        assertEquals(c1.get(), new V3i(10, 20, 30));
+
+        final Optional<V3i> c2 = ParseUtils.tryParseV3i("-20x-89x999", 'x');
+        assertTrue(c2.isPresent());
+        assertEquals(c2.get(), new V3i(-20, -89, 999));
+
+        final Optional<V3i> i1 = ParseUtils.tryParseV3i("10x20", 'x');
+        assertFalse(i1.isPresent());
+
+        final Optional<V3i> i2 = ParseUtils.tryParseV3i("15", 'x');
+        assertFalse(i2.isPresent());
+
+        final Optional<V3i> i3 = ParseUtils.tryParseV3i("10x20x", 'x');
+        assertFalse(i3.isPresent());
+    }
+}
\ No newline at end of file
-- 
GitLab