package org.testory.common; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.testory.common.Classes.canThrow; import java.lang.reflect.Method; import org.junit.Test; public class TestClassesCanThrow { @Test public void always_can_throw_error() throws Exception { assertTrue(canThrow(new Error(), method("throwNothing"))); assertTrue(canThrow(new Error(), method("throwRuntimeException"))); assertTrue(canThrow(new Error(), method("throwError"))); assertTrue(canThrow(new Error(), method("throwException"))); } @Test public void always_can_throw_runtime_exception() throws Exception { assertTrue(canThrow(new RuntimeException(), method("throwNothing"))); assertTrue(canThrow(new RuntimeException(), method("throwRuntimeException"))); assertTrue(canThrow(new RuntimeException(), method("throwError"))); assertTrue(canThrow(new RuntimeException(), method("throwException"))); } @Test public void can_throw_declared_checked_exception() throws Exception { assertTrue(canThrow(new Exception(), method("throwException"))); assertTrue(canThrow(new CheckedException(), method("throwCheckedException"))); } @Test public void cannot_throw_undeclared_checked_exception() throws Exception { assertFalse(canThrow(new CheckedException(), method("throwNothing"))); assertFalse(canThrow(new CheckedException(), method("throwOtherCheckedException"))); } @Test public void can_throw_subclass_of_legal_throwable() throws Exception { assertTrue(canThrow(new CheckedException(), method("throwException"))); assertTrue(canThrow(new UncheckedException(), method("throwNothing"))); assertTrue(canThrow(new UncheckedException(), method("throwRuntimeException"))); assertTrue(canThrow(new UncheckedError(), method("throwNothing"))); assertTrue(canThrow(new UncheckedError(), method("throwError"))); } @Test public void can_throw_anything_if_declared_throwable() throws Exception { assertTrue(canThrow(new Throwable(), method("throwThrowable"))); assertTrue(canThrow(new CheckedException(), method("throwThrowable"))); assertTrue(canThrow(new UncheckedException(), method("throwThrowable"))); assertTrue(canThrow(new UncheckedError(), method("throwThrowable"))); } @Test public void can_throw_exception_declared_at_any_position() throws Exception { assertTrue(canThrow(new CheckedException(), method("throwBothCheckedExceptions"))); assertTrue(canThrow(new OtherCheckedException(), method("throwBothCheckedExceptions"))); } @Test public void throwable_cannot_be_null() throws Exception { try { canThrow(null, method("throwNothing")); fail(); } catch (NullPointerException e) {} } @Test public void method_cannot_be_null() { try { canThrow(new Throwable(), null); fail(); } catch (NullPointerException e) {} } private static Method method(String name) throws SecurityException, NoSuchMethodException { return Methods.class.getDeclaredMethod(name); } static class Methods { // @formatter:off void throwNothing() {} void throwThrowable() throws Throwable{} void throwError() throws Error {} void throwRuntimeException() throws RuntimeException {} void throwUncheckedException() throws UncheckedException {} void throwException() throws Exception {} void throwCheckedException() throws CheckedException {} void throwOtherCheckedException() throws OtherCheckedException {} void throwBothCheckedExceptions() throws CheckedException, OtherCheckedException {} // @formatter:on } private static class UncheckedException extends RuntimeException {} private static class UncheckedError extends Error {} private static class CheckedException extends Exception {} private static class OtherCheckedException extends Exception {} }