/**
 * Copyright (C) 2011 Akiban Technologies Inc.
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License, version 3,
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see http://www.gnu.org/licenses.
 */

package com.akiban.server.encoding;

import org.junit.Test;

import static org.junit.Assert.assertEquals;

public class TimestampEncoderTest {
    private class TestElement {
        private final int asInt;
        private final Object asObject;
        private final String asString;

        public TestElement(String str, Number num) {
            this.asInt = num.intValue();
            this.asObject = num;
            this.asString = str;
        }

        @Override
        public String toString() {
            return String.format("(%d, %s, %s)", asInt, asString, asObject);
        }
    }

    private LongEncoderBase ENCODER = EncoderFactory.TIMESTAMP;

    private final TestElement[] TEST_CASES = {
            new TestElement("0", 0),                                // 1970-01-01 00:00:00
            new TestElement("1234567890", 1234567890),              // 2009-02-13 23:31:30
            new TestElement("2147483647", 2147483647),              // 2038-01-19 03:14:07
            new TestElement("530841600", new Integer(530841600)),   // 1986-10-28 00:00:00
            new TestElement("1302460440", new Long(1302460440))     // 2011-04-10 18:34:00
    };

    private String encodeAndDecode(String dateStr) {
        final long val = ENCODER.encodeFromObject(dateStr);
        return ENCODER.decodeToString(val);
    }

    @Test
    public void encodingToInt() {
        for(TestElement t : TEST_CASES) {
            final long encodeFromNum = ENCODER.encodeFromObject(t.asObject);
            final long encodeFromStr = ENCODER.encodeFromObject(t.asString);
            assertEquals("Number->int: " + t, t.asInt, encodeFromNum);
            assertEquals("String->int: " + t, t.asInt, encodeFromStr);
        }
    }

    @Test
    public void decodingToString() {
        for(TestElement t : TEST_CASES) {
            final String decoded = ENCODER.decodeToString(t.asInt);
            assertEquals("int->String: " + t, t.asString, decoded);
        }
    }

    @Test
    public void nullIsZero() {
        assertEquals(0, ENCODER.encodeFromObject(null));
        assertEquals("0", ENCODER.decodeToString(0));
    }

    @Test(expected=IllegalArgumentException.class)
    public void invalidNumber() {
        encodeAndDecode("20111zebra");
    }

    @Test(expected=IllegalArgumentException.class)
    public void noNumbers() {
        encodeAndDecode("zebra");
    }
}

@@ -715,664 +715,186 @@
 t;%0A%0A
-import static org.junit.Assert.assertEquals;%0A%0Apublic class TimestampEncoderTest %7B%0A    private class TestElement %7B%0A        private final int asInt;%0A        private final Object asObject;%0A        private final String asString;%0A%0A        public TestElement(String str, Number num) %7B%0A            this.asInt = num.intValue();%0A            this.asObject = num;%0A            this.asString = str;%0A        %7D%0A%0A        @Override%0A        public String toString() %7B%0A            return String.format(%22(%25d, %25s, %25s)%22, asInt, asString, asObject);%0A        %7D%0A    %7D%0A%0A    private LongEncoderBase ENCODER = EncoderFactory.TIMESTAMP;%0A%0A    private final TestElement%5B%5D TEST_CASES = %7B%0A
+public class TimestampEncoderTest extends LongEncoderTestBase %7B%0A    public TimestampEncoderTest() %7B%0A        super(EncoderFactory.TIMESTAMP,%0A              new TestElement%5B%5D %7B%0A    
     
@@ -984,32 +984,36 @@
 :00%0A            
+    
 new TestElement(
@@ -1075,16 +1075,20 @@
 3:31:30%0A
+    
         
@@ -1174,32 +1174,36 @@
 :07%0A            
+   
+ 
 new TestElement(
@@ -1257,32 +1257,36 @@
 -10-28 00:00:00%0A
+    
             new 
@@ -1368,975 +1368,33 @@
     
-%7D;%0A%0A    private String encodeAndDecode(String dateStr) %7B%0A        final long val = ENCODER.encodeFromObject(dateStr);%0A        return ENCODER.decodeToString(val);%0A    %7D%0A%0A    @Test%0A    public void encodingToInt() %7B%0A        for(TestElement t : TEST_CASES) %7B%0A            final long encodeFromNum = ENCODER.encodeFromObject(t.asObject);%0A            final long encodeFromStr = ENCODER.encodeFromObject(t.asString);%0A            assertEquals(%22Number-%3Eint: %22 + t, t.asInt, encodeFromNum);%0A            assertEquals(%22String-%3Eint: %22 + t, t.asInt, encodeFromStr);%0A        %7D%0A    %7D%0A%0A    @Test%0A    public void decodingToString() %7B%0A        for(TestElement t : TEST_CASES) %7B%0A            final String decoded = ENCODER.decodeToString(t.asInt);%0A            assertEquals(%22int-%3EString: %22 + t, t.asString, decoded);%0A        %7D%0A    %7D%0A%0A    @Test%0A    public void nullIsZero() %7B%0A        assertEquals(0, ENCODER.encodeFromObject(null));%0A        assertEquals(%220%22, ENCODER.decodeToString(0));%0A    %7D%0A
+          %7D);%0A    %7D%0A%0A    
 %0A   

Refactor TimestampEncoderTest to use LongEcoderTestBase.