/*
 * This file is part of Sponge, licensed under the MIT License (MIT).
 *
 * Copyright (c) SpongePowered.org <http://www.spongepowered.org>
 * Copyright (c) contributors
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package org.spongepowered.api.event;

import org.junit.Test;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

import static org.mockito.Mockito.mock;

public class SpongeEventFactoryTest {

    @Test
    public void testCreate() throws InvocationTargetException, IllegalAccessException {
        for (Method method : SpongeEventFactory.class.getMethods()) {
            if (method.getName().startsWith("create") && Modifier.isStatic(method.getModifiers())) {
                Class<?>[] paramTypes = method.getParameterTypes();
                Object[] params = new Object[paramTypes.length];
                for (int i = 0; i < paramTypes.length; i++) {
                    params[i] = mockParam(paramTypes[i]);
                }
                method.invoke(null, params);
            }
        }
    }

    private Object mockParam(Class<?> paramType) {
        if (paramType == byte.class) {
            return (byte) 0;
        } else if (paramType == short.class) {
            return (short) 0;
        } else if (paramType == int.class) {
            return (int) 0;
        } else if (paramType == long.class) {
            return (long) 0;
        } else if (paramType == float.class) {
            return (float) 0;
        } else if (paramType == double.class) {
            return (double) 0;
        } else if (paramType == char.class) {
            return (char) 0;
        } else if (paramType == boolean.class) {
            return false;
        } else if (paramType == String.class) {
            return "Cupcakes";
        } else if (Enum.class.isAssignableFrom(paramType)) {
            return paramType.getEnumConstants()[0];
        } else {
            return mock(paramType);
        }
    }
}
@@ -1305,16 +1305,78 @@
 it.Test;
+%0Aimport org.spongepowered.api.util.event.factory.EventFactory;
 %0A%0Aimport
@@ -1835,24 +1835,50 @@
 fiers())) %7B%0A
+                try %7B%0A    
             
@@ -1949,16 +1949,20 @@
         
+    
 Object%5B%5D
@@ -2014,24 +2014,28 @@
             
+   
+ 
 for (int i =
@@ -2088,16 +2088,20 @@
         
+    
 params%5Bi
@@ -2138,34 +2138,43 @@
                 
+   
+ 
 %7D%0A
+%0A    
                 
@@ -2202,16 +2202,2038 @@
 arams);%0A
+                %7D catch (Exception e) %7B%0A                    throw new RuntimeException(%0A                            %22Runtime creation of the '%22 + method.getReturnType().getName() + %22' event failed%5Cn%5Cn%22 +%0A                            %22(To avoid the need to create numerous boilerplate concrete classes for Sponge's many event %22 +%0A                             %22interfaces, the %22 + SpongeEventFactory.class.getSimpleName() + %22 class dynamically creates concrete classes at %22 +%0A                            %22runtime. However, as this means that errors may only become known at runtime, this test ensures that problems %22 +%0A                            %22are caught during development.)%5Cn%5Cn%22 +%0A                            %22The failure of this test is in regards to creation of the '%22 + method.getReturnType().getName() + %22' event.%5Cn%5Cn%22 +%0A                            %22Reasons for failure include:%5Cn%22 +%0A                            %22(1) The event was changed and there are new, removed, or modified properties (most likely)%5Cn%22 +%0A                            %22%5CtSolution: Make appropriate changes to %22 + SpongeEventFactory.class.getName() + %22.%22 + method.getName() + %22(). %22 +%0A                            %22See the wrapped exception for more details.%5Cn%22 +%0A                            %22(2) A bug in the class generator was found%5Cn%22 +%0A                            %22%5CtSolution: Look into %22 + EventFactory.class.getName() + %22 and its implementations.%5Cn%22 +%0A                            %22(3) A method that does not follow getter/setter semantics (getProp(), isBool(), setProp()) was added (i.e. blockList())%5Cn%22 +%0A                            %22%5CtSolution: Revisit %22 + method.getReturnType().getName() + %22 and its supertypes. If the method in question %22 +%0A                            %22must exist, then the event factory is capable of accepting a base class to build the %22 +%0A                            %22runtime concrete class upon (i.e. %22 + AbstractEvent.class.getName() + %22 is the supertype of all generated event classes).%5Cn%22, e);%0A                %7D%0A
         

Improve the test failure message for SpongeEventFactoryTest.