package seedu.tache.commons.core;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

public class VersionTest {
    @Rule
    public ExpectedException thrown = ExpectedException.none();

    public void versionParsingAcceptableVersionStringParsedVersionCorrectly() {
        verifyVersionParsedCorrectly("V0.0.0ea", 0, 0, 0, true);
        verifyVersionParsedCorrectly("V3.10.2", 3, 10, 2, false);
        verifyVersionParsedCorrectly("V100.100.100ea", 100, 100, 100, true);
    }

    @Test
    public void versionParsingWrongVersionStringThrowIllegalArgumentException() {
        thrown.expect(IllegalArgumentException.class);
        Version.fromString("This is not a version string");
    }

    @Test
    public void versionConstructorCorrectParameterValueAsExpected() {
        Version version = new Version(19, 10, 20, true);

        assertEquals(19, version.getMajor());
        assertEquals(10, version.getMinor());
        assertEquals(20, version.getPatch());
        assertEquals(true, version.isEarlyAccess());
    }

    @Test
    public void versionToStringValidVersionCorrectStringRepresentation() {
        // boundary at 0
        Version version = new Version(0, 0, 0, true);
        assertEquals("V0.0.0ea", version.toString());

        // normal values
        version = new Version(4, 10, 5, false);
        assertEquals("V4.10.5", version.toString());

        // big numbers
        version = new Version(100, 100, 100, true);
        assertEquals("V100.100.100ea", version.toString());
    }

    @Test
    public void versionComparableValidVersionCompareToIsCorrect() {
        Version one;
        Version another;

        // Tests equality
        one = new Version(0, 0, 0, true);
        another = new  Version(0, 0, 0, true);
        assertTrue(one.compareTo(another) == 0);

        one = new Version(11, 12, 13, false);
        another = new  Version(11, 12, 13, false);
        assertTrue(one.compareTo(another) == 0);

        // Tests different patch
        one = new Version(0, 0, 5, false);
        another = new  Version(0, 0, 0, false);
        assertTrue(one.compareTo(another) > 0);

        // Tests different minor
        one = new Version(0, 0, 0, false);
        another = new  Version(0, 5, 0, false);
        assertTrue(one.compareTo(another) < 0);

        // Tests different major
        one = new Version(10, 0, 0, true);
        another = new  Version(0, 0, 0, true);
        assertTrue(one.compareTo(another) > 0);

        // Tests high major vs low minor
        one = new Version(10, 0, 0, true);
        another = new  Version(0, 1, 0, true);
        assertTrue(one.compareTo(another) > 0);

        // Tests high patch vs low minor
        one = new Version(0, 0, 10, false);
        another = new  Version(0, 1, 0, false);
        assertTrue(one.compareTo(another) < 0);

        // Tests same major minor different patch
        one = new Version(2, 15, 0, false);
        another = new  Version(2, 15, 5, false);
        assertTrue(one.compareTo(another) < 0);

        // Tests early access vs not early access on same version number
        one = new Version(2, 15, 0, true);
        another = new  Version(2, 15, 0, false);
        assertTrue(one.compareTo(another) < 0);

        // Tests early access lower version vs not early access higher version compare by version number first
        one = new Version(2, 15, 0, true);
        another = new  Version(2, 15, 5, false);
        assertTrue(one.compareTo(another) < 0);

        // Tests early access higher version vs not early access lower version compare by version number first
        one = new Version(2, 15, 0, false);
        another = new  Version(2, 15, 5, true);
        assertTrue(one.compareTo(another) < 0);
    }

    @Test
    public void versionComparableValidVersionHashCodeIsCorrect() {
        Version version = new Version(100, 100, 100, true);
        assertEquals(100100100, version.hashCode());

        version = new Version(10, 10, 10, false);
        assertEquals(1010010010, version.hashCode());
    }

    @Test
    public void versionComparableValidVersionEqualIsCorrect() {
        Version one;
        Version another;

        one = new Version(0, 0, 0, false);
        another = new  Version(0, 0, 0, false);
        assertTrue(one.equals(another));

        one = new Version(100, 191, 275, true);
        another = new  Version(100, 191, 275, true);
        assertTrue(one.equals(another));
    }

    @Test
    private void verifyVersionParsedCorrectly(String versionString,
                                              int major, int minor, int patch, boolean isEarlyAccess) {
        assertEquals(new Version(major, minor, patch, isEarlyAccess), Version.fromString(versionString));
    }
}

@@ -304,24 +304,34 @@
 on.none();%0A%0A
+    @Test%0A
     public v
@@ -348,17 +348,18 @@
 nParsing
-A
+_a
 cceptabl
@@ -372,17 +372,18 @@
 onString
-P
+_p
 arsedVer
@@ -659,9 +659,10 @@
 sing
-W
+_w
 rong
@@ -674,17 +674,18 @@
 onString
-T
+_t
 hrowIlle
@@ -875,17 +875,18 @@
 structor
-C
+_c
 orrectPa
@@ -892,17 +892,18 @@
 arameter
-V
+_v
 alueAsEx
@@ -1210,17 +1210,18 @@
 ToString
-V
+_v
 alidVers
@@ -1219,25 +1219,26 @@
 validVersion
-C
+_c
 orrectString
@@ -1694,33 +1694,34 @@
 ersionComparable
-V
+_v
 alidVersionCompa
@@ -1711,25 +1711,26 @@
 validVersion
-C
+_c
 ompareToIsCo
@@ -1758,33 +1758,17 @@
 sion one
-;%0A        Version
+,
  another
@@ -3913,33 +3913,34 @@
 ersionComparable
-V
+_v
 alidVersionHashC
@@ -3938,9 +3938,10 @@
 sion
-H
+_h
 ashC
@@ -4225,17 +4225,18 @@
 mparable
-V
+_v
 alidVers
@@ -4238,17 +4238,18 @@
 dVersion
-E
+_e
 qualIsCo
@@ -4583,34 +4583,24 @@
 r));%0A    %7D%0A%0A
-    @Test%0A
     private 

Fix junit (VersionTest initialization error)