/**
 * 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 YearEncoderTest {
    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 final LongEncoderBase ENCODER = EncoderFactory.YEAR;

    private final TestElement[] TEST_CASES = {
            new TestElement("0000", 0),
            new TestElement("1901", 1),
            new TestElement("1950", 50),
            new TestElement("2000", 100),
            new TestElement("2028", 128),
            new TestElement("2029", 129),
            new TestElement("2155", 255),
            new TestElement("2011", new Integer(111)),
            new TestElement("1986", new Long(86))
    };

    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("0000", ENCODER.decodeToString(0));
    }

    @Test
    public void partiallySpecified() {
        assertEquals("0002", encodeAndDecode("2"));
        assertEquals("0020", encodeAndDecode("20"));
        assertEquals("0201", encodeAndDecode("201"));
        assertEquals("2011", encodeAndDecode("2011"));
    }

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

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

@@ -790,516 +790,84 @@
 est 
-%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   
+extends LongEncoderTestBase %7B%0A%0A
     
- 
 public 
-String toString() %7B%0A            return String.format(%22(%25d, %25s, %25s)%22, asInt, asString, asObject);%0A        %7D
+YearEncoderTest() %7B
 %0A    
-%7D%0A%0A
     
-private final LongEncoderBase ENCODER = 
+super(
 Enco
@@ -885,28 +885,27 @@
 YEAR
-;%0A
+,
 %0A    
-private final
+          new
  Tes
@@ -919,23 +919,14 @@
 t%5B%5D 
-TEST_CASES = %7B%0A
+%7B%0A    
     
@@ -965,32 +965,36 @@
 0),%0A            
+    
 new TestElement(
@@ -1005,16 +1005,20 @@
 1%22, 1),%0A
+    
         
@@ -1054,32 +1054,36 @@
 0),%0A            
+    
 new TestElement(
@@ -1092,24 +1092,28 @@
 000%22, 100),%0A
+    
             
@@ -1146,32 +1146,36 @@
 8),%0A            
+   
+ 
 new TestElement(
@@ -1188,16 +1188,20 @@
 , 129),%0A
+    
         
@@ -1238,32 +1238,36 @@
 5),%0A            
+ 
+   
 new TestElement(
@@ -1297,32 +1297,36 @@
 )),%0A            
+   
+ 
 new TestElement(
@@ -1355,969 +1355,28 @@
     
-%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(%220000%22, ENCODER.decodeToString(0)
+          %7D%0A        
 );%0A 

Refactor YearEncoderTest to use LongEncoderTestbase.