package com.googlecode.gentyref;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.List;

import junit.framework.TestCase;

/**
 * Simple samples of what gentyref does, in the form of tests.
 * See http://code.google.com/p/gentyref/wiki/ExampleUsage
 * 
 * @author Wouter Coekaerts <wouter@coekaerts.be>
 */
public class SamplesTest extends TestCase {
	interface Processor<T> {
		void process(T t);
	}
	
	class StringProcessor implements Processor<String> {
		public void process(String s) {
			System.out.println("processing " + s);
		}
	}
	
	class IntegerProcessor implements Processor<Integer> {
		public void process(Integer i) {
			System.out.println("processing " + i);
		}
	}
	
	/*
	 * Returns true if processorClass extends Processor<String>
	 */
	public boolean isStringProcessor(Class<? extends Processor<?>> processorClass) {
		// Use TypeToken to get an instanceof a specific Type
		Type type = new TypeToken<Processor<String>>(){}.getType();
		// Use GenericTypeReflector.isSuperType to check if a type is a supertype of another
		return GenericTypeReflector.isSuperType(type, processorClass);
	}
	
	public void testProsessor() {
		assertTrue(isStringProcessor(StringProcessor.class));
		assertFalse(isStringProcessor(IntegerProcessor.class));
	}
	
	abstract class Lister<T> {
		public List<T> list() {
			return null;
		}
	}
	
	class StringLister extends Lister<String> {
	}
	
	public void testFooBar() throws NoSuchMethodException {
		Method listMethod = StringLister.class.getMethod("list");
		
		// java returns List<T>
		Type returnType = listMethod.getGenericReturnType();
		assertTrue(returnType instanceof ParameterizedType);
		assertTrue(((ParameterizedType)returnType).getActualTypeArguments()[0] instanceof TypeVariable);
		
		// we get List<String>
		Type exactReturnType = GenericTypeReflector.getExactReturnType(listMethod, StringLister.class);
		assertEquals(new TypeToken<List<String>>(){}.getType(), exactReturnType);
	}
}

@@ -1386,21 +1386,24 @@
 t class 
-Liste
+Collecto
 r%3CT%3E %7B%0A%09
@@ -1443,24 +1443,56 @@
 n null;%0A%09%09%7D%0A
+%09%09public void add(T item) %7B%0A%09%09%7D%0A
 %09%7D%0A%09%0A%09class 
@@ -1497,21 +1497,24 @@
 s String
-Liste
+Collecto
 r extend
@@ -1515,21 +1515,24 @@
 extends 
-Liste
+Collecto
 r%3CString
@@ -1561,14 +1561,21 @@
 test
-FooBar
+CollectorList
 () t
@@ -1628,29 +1628,32 @@
 hod = String
-Liste
+Collecto
 r.class.getM
@@ -1902,16 +1902,19 @@
 Variable
+%3C?%3E
 );%0A%09%09%0A%09%09
@@ -2023,13 +2023,16 @@
 ring
-Liste
+Collecto
 r.cl
@@ -2116,10 +2116,575 @@
 pe);%0A%09%7D%0A
+%09%0A%09public void testCollectorAdd() throws NoSuchMethodException %7B%0A%09%09Method addMethod = StringCollector.class.getMethod(%22add%22, Object.class);%0A%09%09%0A%09%09// java returns T%0A%09%09Type%5B%5D parameterTypes = addMethod.getGenericParameterTypes();%0A%09%09assertEquals(1, parameterTypes.length);%0A%09%09assertTrue(parameterTypes%5B0%5D instanceof TypeVariable%3C?%3E);%0A%09%09%0A%09%09// we get String%0A%09%09Type%5B%5D exactParameterTypes = GenericTypeReflector.getExactParameterTypes(addMethod, StringCollector.class);%0A%09%09assertEquals(1, exactParameterTypes.length);%0A%09%09assertEquals(String.class, exactParameterTypes%5B0%5D);%0A%09%7D%0A
 %7D%0A

Add getExactParameterTypes sample