/* * Copyright 2012 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.junit; import com.google.gwt.junit.client.ExpectedFailure; import junit.framework.AssertionFailedError; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestResult; import java.lang.reflect.Method; /** * A {@link TestResult} that can interpret {@link ExpectedFailure} on test methods. */ class TestResultWithExpectedFailures extends ForwardingTestResult { private boolean failed; public TestResultWithExpectedFailures(TestResult delegate) { super(delegate); } @Override public void startTest(Test test) { failed = false; super.startTest(test); } @Override public void addFailure(Test test, AssertionFailedError t) { failed = true; if (isTestExpectedToFail(test)) { processException(test, t); } else { super.addFailure(test, t); } } @Override public void addError(Test test, Throwable t) { failed = true; if (isTestExpectedToFail(test)) { processException(test, t); } else { super.addError(test, t); } } @Override public void endTest(Test test) { if (!failed && isTestExpectedToFail(test)) { // Test should have failed but didn't. Report the failure by calling the super directly to // prevent any interference from overridden #addFailure. super.addFailure(test, new AssertionFailedError("Expected failure but didn't fail")); } super.endTest(test); } private boolean isTestExpectedToFail(Test test) { return getExpectedFailureAnnotation(test) != null; } private void processException(Test test, Throwable t) { ExpectedFailure annotation = getExpectedFailureAnnotation(test); try { annotation.withAsserter().newInstance().assertException(annotation, t); } catch (AssertionFailedError e) { String msg = "Assertion failed for thrown exception: " + e.getMessage() + "\n(Actual thrown exception is reported below via 'caused by')"; AssertionFailedError errorToReport = new AssertionFailedError(msg); errorToReport.initCause(t); errorToReport.setStackTrace(e.getStackTrace()); super.addFailure(test, errorToReport); } catch (Exception e) { super.addError(test, e); } } private ExpectedFailure getExpectedFailureAnnotation(Test test) { if (test instanceof TestCase) { TestCase testCase = (TestCase) test; try { Method testMethod = testCase.getClass().getMethod(testCase.getName()); return testMethod.getAnnotation(ExpectedFailure.class); } catch (NoSuchMethodException e) { throw new RuntimeException(e); } } return null; } }