/* * Copyright Red Hat Inc. and/or its affiliates and other contributors * as indicated by the authors tag. All rights reserved. * * This copyrighted material is made available to anyone wishing to use, * modify, copy, or redistribute it subject to the terms and conditions * of the GNU General Public License version 2. * * This particular file is subject to the "Classpath" exception as provided in the * LICENSE file that accompanied this code. * * This program is distributed in the hope that it will be useful, but WITHOUT A * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. See the GNU General Public License for more details. * You should have received a copy of the GNU General Public License, * along with this distribution; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ package com.redhat.ceylon.compiler.java.test; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import org.junit.ComparisonFailure; import org.junit.runner.Description; import org.junit.runner.notification.Failure; import org.junit.runner.notification.RunNotifier; import org.junit.runners.ParentRunner; import org.junit.runners.model.InitializationError; public class CeylonTestRunner extends ParentRunner<Method> { private Class<?> testClass; private LinkedHashMap<Method, Description> children = new LinkedHashMap<Method, Description>(); private Method failureCountGetter; public CeylonTestRunner(Class<?> testClass, Method failureCountGetter, List<String> list) throws InitializationError { super(testClass); this.testClass = testClass; this.failureCountGetter = failureCountGetter; for (String method : list) { Method m; try { m = testClass.getMethod(method); } catch (Exception e) { throw new RuntimeException(e); } Description description = Description.createTestDescription(testClass, method); children.put(m, description); } } @Override protected Description describeChild(Method child) { return children.get(child); } @Override protected List<Method> getChildren() { return new ArrayList<Method>(this.children.keySet()); } @Override protected void runChild(Method method, RunNotifier notifier) { Description description = describeChild(method); notifier.fireTestStarted(description); Failure failure = null; try { failure = executeTest(method, description); } finally { if (failure != null) { notifier.fireTestFailure(failure); } } notifier.fireTestFinished(description); } private Failure executeTest(Method child, Description description) { Failure failure = null; try { Object instance; if (Modifier.isStatic(child.getModifiers())) { instance = null; } else { instance = testClass.newInstance(); } Long previousCount = null; if(failureCountGetter != null) previousCount = (Long) failureCountGetter.invoke(null); child.invoke(instance); if(failureCountGetter != null){ Long newCount = (Long) failureCountGetter.invoke(null); if(!newCount.equals(previousCount)) failure = new Failure(description, new AssertionError("check() failed: "+(newCount - previousCount)+" errors")); } } catch (InvocationTargetException e) { Throwable cause = e.getCause(); StackTraceElement[] st = cause.getStackTrace(); if ("ceylon.language.AssertionError".equals(cause.getClass().getName())) { AssertionError error = new AssertionError(cause.getMessage()); error.setStackTrace(cause.getStackTrace()); failure = new Failure(description, error); } else if ("com.redhat.ceylon.compiler.java.test.runtime.AssertionFailed".equals(cause.getClass().getName())) { AssertionError error = new AssertionError(cause.getMessage()); error.setStackTrace(cause.getStackTrace()); failure = new Failure(description, error); } else if ("com.redhat.ceylon.compiler.java.test.runtime.ComparisonFailed".equals(cause.getClass().getName())) { Object expected = get(cause, "getExpected"); Object got = get(cause, "getGot"); ComparisonFailure error = new ComparisonFailure(cause.getMessage(), String.valueOf(expected), String.valueOf(got)); error.setStackTrace(cause.getStackTrace()); failure = new Failure(description, error); } else { failure = new Failure(description, e); } } catch (Exception e) { failure = new Failure(description, e); } catch (AssertionError e) { failure = new Failure(description, e); } return failure; } private Object get(Throwable cause, String getter) { try { Method method = cause.getClass().getMethod(getter); Object expected = method.invoke(cause); return expected; } catch (Exception e) { throw new RuntimeException(); } } public int testCount() { return this.children.size(); } }