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();

    @Test
    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, 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));
    }

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

@@ -410,36 +410,39 @@
     
-verifyVersionParsedCorrectly
+assertEquals(Version.fromString
 (%22V0
@@ -448,18 +448,31 @@
 0.0.0ea%22
+)
 , 
+new Version(
 0, 0, 0,
@@ -469,32 +469,33 @@
 n(0, 0, 0, true)
+)
 ;%0A        verify
@@ -492,36 +492,39 @@
     
-verifyVersionParsedCorrectly
+assertEquals(Version.fromString
 (%22V3
@@ -529,18 +529,31 @@
 V3.10.2%22
+)
 , 
+new Version(
 3, 10, 2
@@ -552,32 +552,33 @@
 3, 10, 2, false)
+)
 ;%0A        verify
@@ -575,36 +575,39 @@
     
-verifyVersionParsedCorrectly
+assertEquals(Version.fromString
 (%22V1
@@ -619,18 +619,31 @@
 0.100ea%22
+)
 , 
+new Version(
 100, 100
@@ -650,24 +650,25 @@
 , 100, true)
+)
 ;%0A    %7D%0A%0A   
@@ -4628,290 +4628,6 @@
  %7D%0A%0A
-    private void verifyVersionParsedCorrectly(String versionString,%0A                                              int major, int minor, int patch, boolean isEarlyAccess) %7B%0A        assertEquals(new Version(major, minor, patch, isEarlyAccess), Version.fromString(versionString));%0A    %7D%0A
 %7D%0A

Fix VersionTest Unit Tests