/*
 * Copyright 2007 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.dev.jjs.test;

import com.google.gwt.core.client.JavaScriptException;
import com.google.gwt.junit.client.GWTTestCase;

/**
 * Tests enum functionality.
 */
public class EnumsTest extends GWTTestCase {

  enum Basic {
    A, B, C
  }

  enum Complex {
    A("X"), B("Y"), C("Z");

    String value;

    Complex(String value) {
      this.value = value;
    }

    public String value() {
      return value;
    }
  }

  enum Subclassing {
    A {
      @Override
      public String value() {
        return "X";
      }
    },
    B {
      @Override
      public String value() {
        return "Y";
      }
    },
    C {
      @Override
      public String value() {
        return "Z";
      }
    };

    public abstract String value();
  }

  public String getModuleName() {
    return "com.google.gwt.dev.jjs.CompilerSuite";
  }

  public void testCompareTo() {
    assertTrue(Basic.A.compareTo(Basic.valueOf("A")) == 0);
    assertTrue(Basic.B.compareTo(Basic.A) > 0);
    assertTrue(Basic.A.compareTo(Basic.B) < 0);

    assertTrue(Complex.A.compareTo(Complex.valueOf("A")) == 0);
    assertTrue(Complex.B.compareTo(Complex.A) > 0);
    assertTrue(Complex.A.compareTo(Complex.B) < 0);

    assertTrue(Subclassing.A.compareTo(Subclassing.valueOf("A")) == 0);
    assertTrue(Subclassing.B.compareTo(Subclassing.A) > 0);
    assertTrue(Subclassing.A.compareTo(Subclassing.B) < 0);
  }

  public void testField() {
    assertEquals("X", Complex.A.value);
    assertEquals("Y", Complex.B.value);
    assertEquals("Z", Complex.C.value);
  }

  public void testGetDeclaringClass() {
    assertEquals(Basic.class, Basic.A.getDeclaringClass());
    assertEquals(Complex.class, Complex.A.getDeclaringClass());
    assertEquals(Subclassing.class, Subclassing.A.getDeclaringClass());
  }

  public void testMethod() {
    assertEquals("X", Complex.A.value());
    assertEquals("Y", Complex.B.value());
    assertEquals("Z", Complex.C.value());

    assertEquals("X", Subclassing.A.value());
    assertEquals("Y", Subclassing.B.value());
    assertEquals("Z", Subclassing.C.value());
  }

  public void testName() {
    assertEquals("A", Basic.A.name());
    assertEquals("B", Basic.B.name());
    assertEquals("C", Basic.C.name());

    assertEquals("A", Complex.A.name());
    assertEquals("B", Complex.B.name());
    assertEquals("C", Complex.C.name());

    assertEquals("A", Subclassing.A.name());
    assertEquals("B", Subclassing.B.name());
    assertEquals("C", Subclassing.C.name());
  }

  public void testOrdinals() {
    assertEquals(0, Basic.A.ordinal());
    assertEquals(1, Basic.B.ordinal());
    assertEquals(2, Basic.C.ordinal());

    assertEquals(0, Complex.A.ordinal());
    assertEquals(1, Complex.B.ordinal());
    assertEquals(2, Complex.C.ordinal());

    assertEquals(0, Subclassing.A.ordinal());
    assertEquals(1, Subclassing.B.ordinal());
    assertEquals(2, Subclassing.C.ordinal());
  }

  public void testSwitch() {
    switch (Basic.A) {
      case A:
        break;
      case B:
        fail("Switch failed");
        break;
      case C:
        fail("Switch failed");
        break;
      default:
        fail("Switch failed");
        break;
    }
    switch (Complex.B) {
      case A:
        fail("Switch failed");
        break;
      case B:
        break;
      case C:
        fail("Switch failed");
        break;
      default:
        fail("Switch failed");
        break;
    }
    switch (Subclassing.C) {
      case A:
        fail("Switch failed");
        break;
      case B:
        fail("Switch failed");
        break;
      default:
        break;
    }
  }

  public void testValueOf() {
    assertEquals(Basic.A, Basic.valueOf("A"));
    assertEquals(Basic.B, Basic.valueOf("B"));
    assertEquals(Basic.C, Basic.valueOf("C"));
    try {
      Basic.valueOf("D");
      fail("Basic.valueOf(\"D\") -- expected IllegalArgumentException");
    } catch (IllegalArgumentException e) {
    }

    assertEquals(Complex.A, Complex.valueOf("A"));
    assertEquals(Complex.B, Complex.valueOf("B"));
    assertEquals(Complex.C, Complex.valueOf("C"));
    try {
      Complex.valueOf("D");
      fail("Complex.valueOf(\"D\") -- expected IllegalArgumentException");
    } catch (IllegalArgumentException e) {
    }

    assertEquals(Subclassing.A, Subclassing.valueOf("A"));
    assertEquals(Subclassing.B, Subclassing.valueOf("B"));
    assertEquals(Subclassing.C, Subclassing.valueOf("C"));
    try {
      Subclassing.valueOf("D");
      fail("Subclassing.valueOf(\"D\") -- expected IllegalArgumentException");
    } catch (IllegalArgumentException e) {
    }
    
    enumValuesTest(Basic.class);
    enumValuesTest(Complex.class);
    enumValuesTest(Subclassing.class);
    
    try {
      Enum.valueOf(Basic.class, "foo");
      fail("Passed an invalid enum constant name to Enum.valueOf; expected "
          + "IllegalArgumentException");
    } catch (IllegalArgumentException e) {
    }
    
    try {
      Class fakeEnumClass = String.class;
      Enum.valueOf(fakeEnumClass, "foo");
      fail("Passed a non enum class to Enum.valueOf; expected " 
              + "IllegalArgumentException");
    } catch (IllegalArgumentException e) {       
    }
     
    try {
      Class<Basic> nullEnumClass = null;
      Enum.valueOf(nullEnumClass, "foo");
      fail("Passed a null enum class to Enum.valueOf; expected "
          + "NullPointerException");
    } catch (JavaScriptException e) {
    } catch (NullPointerException e) {
    }
      
    try {
      Enum.valueOf(Basic.class, null);
      fail("Passed a null enum constant to Enum.valueOf; expected "
          + "NullPointerException");
    } catch (NullPointerException e) {
    }
  }

  public void testValues() {
    Basic[] simples = Basic.values();
    assertEquals(3, simples.length);
    assertEquals(Basic.A, simples[0]);
    assertEquals(Basic.B, simples[1]);
    assertEquals(Basic.C, simples[2]);

    Complex[] complexes = Complex.values();
    assertEquals(3, complexes.length);
    assertEquals(Complex.A, complexes[0]);
    assertEquals(Complex.B, complexes[1]);
    assertEquals(Complex.C, complexes[2]);

    Subclassing[] subs = Subclassing.values();
    assertEquals(3, subs.length);
    assertEquals(Subclassing.A, subs[0]);
    assertEquals(Subclassing.B, subs[1]);
    assertEquals(Subclassing.C, subs[2]);
  }
  
  private <T extends Enum<T>> void enumValuesTest(Class<T> enumClass) {
    T[] constants = enumClass.getEnumConstants();
    for (T constant : constants) {
      assertEquals(constant, Enum.valueOf(enumClass, constant.name()));
    }
  }
}
