/*
 * Copyright 2008 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.core.ext.typeinfo;

import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.test.GenericClassWithDependentTypeBounds;
import com.google.gwt.core.ext.typeinfo.test.GenericClassWithTypeBound;
import com.google.gwt.dev.util.log.PrintWriterTreeLogger;

import junit.framework.TestCase;

import java.io.Serializable;

/**
 * Tests for {@link JAbstractMethod}.
 */
public class JAbstractMethodTest extends TestCase {
  private final boolean logToConsole = false;
  private final ModuleContext moduleContext = new ModuleContext(logToConsole
      ? new PrintWriterTreeLogger() : TreeLogger.NULL,
      "com.google.gwt.core.ext.typeinfo.TypeOracleTest");

  public JAbstractMethodTest() throws UnableToCompleteException {
  }

  /**
   * Test method for {@link
   * com.google.gwt.core.ext.typeinfo.JAbstractMethod#getTypeParameters()}. This
   * test is similar in nature to
   * {@link com.google.gwt.core.ext.typeinfo.JGenericTypeTest#testGetDependentTypeParameters()},
   * except that it is verifying the type parameters on a method declaration,
   * as opposed to a class declaration.
   *
   * NOTE: The test types used are:
   * {@link GenericClassWithDependentTypeBounds}
   * {@link GenericClassWithTypeBound}
   *
   * @throws NotFoundException
   */
  public void testGenericMethodWithDependentTypeParameters()
      throws NotFoundException {

    TypeOracle oracle = moduleContext.getOracle();

    // Get the type.

    JClassType type = oracle.getType(
        GenericClassWithDependentTypeBounds.class.getName());

    // Get its methods (not constructors). There should be only one method.

    JMethod [] methods = type.getMethods();
    assertEquals(1, methods.length);

    // Make sure this method is a generic method by checking its type
    // parameters. The method should have two type parameters.

    JMethod method = methods[0];
    JTypeParameter [] typeParameters = method.getTypeParameters();
    assertEquals(2, typeParameters.length);
    
    // Examine the first type parameter. Its name should be 'Q'.

    JTypeParameter typeParameter = typeParameters[0];
    assertEquals("Q", typeParameter.getName());

    // Check the bound of the first type parameter. It should be a single
    // upper bound.
    JClassType [] genericTypeBounds = typeParameter.getBounds();
    assertEquals(1, genericTypeBounds.length);

    // Check to see that the upper bound is a parameterized type.

    JClassType upperBoundType = genericTypeBounds[0];
    JParameterizedType upperBoundParameterizedType =
        upperBoundType.isParameterized();
    assertNotNull(upperBoundParameterizedType);

    // Examine the parameterized type. Its name should be
    // 'GenericClassWithTypeBound'. The base type of the parameterized type
    // should be a reference to the class 'GenericClassWithTypeBound'.

    assertEquals("GenericClassWithTypeBound", upperBoundParameterizedType.getName());
    assertEquals(upperBoundParameterizedType.getBaseType(),
        oracle.getType(GenericClassWithTypeBound.class.getName()));

    // Check the type arguments for the parameterized type. There should be a
    // single type argument.

    JClassType [] typeArgs = upperBoundParameterizedType.getTypeArgs();
    assertEquals(1, typeArgs.length);

    // Examine the first type argument. It should be a type parameter.

    JClassType typeArg = typeArgs[0];
    JTypeParameter typeArgTypeParameter = typeArg.isTypeParameter();
    assertNotNull(typeArgTypeParameter);

    // Check the name of the type parameter. It should be 'P'.

    assertEquals("P", typeArgTypeParameter.getName());

    // Check the bound of the type parameter. It should have a single upper
    // bound.
    JClassType [] typeArgBounds = typeArgTypeParameter.getBounds();
    assertEquals(1, typeArgBounds.length);

    // Verify that the bound type is actually a reference to java.io.Serializable.

    JClassType typeArgUpperBoundType = typeArgBounds[0];
    assertEquals(typeArgUpperBoundType, oracle.getType(Serializable.class.getName()));

    // Now look at the second type parameter on the generic method. It should
    // be  identical to the type argument of the the first type parameter
    // (remember, the first type parameter was a paramaterized type).

    JTypeParameter secondTypeParameter =  typeParameters[1];
    assertEquals(secondTypeParameter, typeArgTypeParameter);
  }
}
