All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.cedarsolutions.junit.gwt.classloader.GwtResourceCreator Maven / Gradle / Ivy

There is a newer version: 5.8.4
Show newest version
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *
 *              C E D A R
 *          S O L U T I O N S       "Software done right."
 *           S O F T W A R E
 *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *
 * Copyright (c) 2013 Kenneth J. Pronovici.
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the Apache License, Version 2.0.
 * See LICENSE for more information about the licensing terms.
 *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *
 * Author   : Kenneth J. Pronovici 
 * Language : Java 6
 * Project  : Common Java Functionality
 *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
package com.cedarsolutions.junit.gwt.classloader;

import static org.mockito.Mockito.mock;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

import com.google.gwt.i18n.client.Constants;
import com.google.gwt.i18n.client.Constants.DefaultBooleanValue;
import com.google.gwt.i18n.client.Constants.DefaultDoubleValue;
import com.google.gwt.i18n.client.Constants.DefaultFloatValue;
import com.google.gwt.i18n.client.Constants.DefaultIntValue;
import com.google.gwt.i18n.client.Constants.DefaultStringArrayValue;
import com.google.gwt.i18n.client.Constants.DefaultStringMapValue;
import com.google.gwt.i18n.client.Constants.DefaultStringValue;
import com.google.gwt.i18n.client.ConstantsWithLookup;
import com.google.gwt.i18n.client.Messages;
import com.google.gwt.i18n.client.Messages.DefaultMessage;

/**
 * Creates mocked versions of objects for stubbed GWT client tests.
 *
 * 

* This class creates all of its resources as Mockito mocks. There is also * some additional logic layered on top to handle certain particular types of * interfaces and classes, like Constants or Messages. *

* *

* This class was derived in part from source code in gwt-test-utils. See * README.credits for more information. *

* *

* This whole thing has sort of a hack-ish feel. There's no simple way to * emulate GWT's behavior, and I can basically only make it work by trial- * and-error. *

* * @author Kenneth J. Pronovici */ @SuppressWarnings("unchecked") public class GwtResourceCreator { /** Create a mocked resource for a particular class. */ public static synchronized T create(Class clazz) { if (ConstantsWithLookup.class.isAssignableFrom(clazz)) { // ConstantsWithLookup extends Constants, so do this first return (T) mock(clazz, new ConstantsWithLookupAnswer(clazz)); } else if (Constants.class.isAssignableFrom(clazz)) { return (T) mock(clazz, new ConstantsAnswer()); } else if (Messages.class.isAssignableFrom(clazz)) { return (T) mock(clazz, new MessagesAnswer()); } else { return (T) mock(clazz); } } /** Uses reflection to return proper values for mocks that implement ConstantsWithLookup. */ public static class ConstantsWithLookupAnswer implements Answer { private Class clazz; // there's no other way to get the class that's actually being mocked public ConstantsWithLookupAnswer(Class clazz) { this.clazz = clazz; } @Override public Object answer(InvocationOnMock invocation) throws Throwable { return getConstantsWithLookupAnswer(clazz, invocation); } } /** Uses reflection to return proper values for mocks that implement Constants. */ public static class ConstantsAnswer implements Answer { @Override public Object answer(InvocationOnMock invocation) throws Throwable { return getConstantsAnswer(invocation, invocation.getMethod()); } } /** Uses reflection to return proper values for mocks that implement Messages. */ public static class MessagesAnswer implements Answer { @Override public Object answer(InvocationOnMock invocation) throws Throwable { return getMessagesAnswer(invocation); } } /** Generate a result for MessagesAnswer. */ private static Object getMessagesAnswer(InvocationOnMock invocation) throws Throwable { Object answer = Mockito.RETURNS_DEFAULTS.answer(invocation); for (Annotation annotation : invocation.getMethod().getDeclaredAnnotations()) { if (annotation instanceof DefaultMessage) { answer = ((DefaultMessage) annotation).value(); } } return answer; } /** Generate a result for ConstantsWithLookupAnswer, which behaves similar to Constants except with possible indirection. */ private static Object getConstantsWithLookupAnswer(Class clazz, InvocationOnMock invocation) throws NoSuchMethodException, Throwable { if ("getBoolean".equals(invocation.getMethod().getName())) { return getConstantsAnswer(invocation, clazz.getMethod((String) invocation.getArguments()[0])); } else if ("getDouble".equals(invocation.getMethod().getName())) { return getConstantsAnswer(invocation, clazz.getMethod((String) invocation.getArguments()[0])); } else if ("getFloat".equals(invocation.getMethod().getName())) { return getConstantsAnswer(invocation, clazz.getMethod((String) invocation.getArguments()[0])); } else if ("getInt".equals(invocation.getMethod().getName())) { return getConstantsAnswer(invocation, clazz.getMethod((String) invocation.getArguments()[0])); } else if ("getString".equals(invocation.getMethod().getName())) { return getConstantsAnswer(invocation, clazz.getMethod((String) invocation.getArguments()[0])); } else if ("getStringArray".equals(invocation.getMethod().getName())) { return getConstantsAnswer(invocation, clazz.getMethod((String) invocation.getArguments()[0])); } else if ("getMap".equals(invocation.getMethod().getName())) { return getConstantsAnswer(invocation, clazz.getMethod((String) invocation.getArguments()[0])); } else { return getConstantsAnswer(invocation, invocation.getMethod()); } } /** Generate a result for ConstantsAnswer. */ private static Object getConstantsAnswer(InvocationOnMock invocation, Method method) throws Throwable { Object answer = Mockito.RETURNS_DEFAULTS.answer(invocation); for (Annotation annotation : method.getDeclaredAnnotations()) { if (annotation instanceof DefaultBooleanValue) { answer = ((DefaultBooleanValue) annotation).value(); } else if (annotation instanceof DefaultDoubleValue) { answer = ((DefaultDoubleValue) annotation).value(); } else if (annotation instanceof DefaultFloatValue) { answer = ((DefaultFloatValue) annotation).value(); } else if (annotation instanceof DefaultIntValue) { answer = ((DefaultIntValue) annotation).value(); } else if (annotation instanceof DefaultStringArrayValue) { answer = ((DefaultStringArrayValue) annotation).value(); } else if (annotation instanceof DefaultStringMapValue) { answer = parseDefaultStringMapValue(((DefaultStringMapValue) annotation).value()); } else if (annotation instanceof DefaultStringValue) { answer = ((DefaultStringValue) annotation).value(); } } return answer; } /** Parse a value as from DefaultStringMapValue. */ protected static Map parseDefaultStringMapValue(String[] values) { Map map = new HashMap(); if (values != null && values.length > 0 && values.length % 2 == 0) { for (int i = 0; i < values.length; i += 2) { map.put(values[i], values[i + 1]); } } return map; } }