package de.vksi.c4j.systemtest.contractclassmagic;
import static de.vksi.c4j.Condition.ignored;
import static de.vksi.c4j.Condition.postCondition;
import static de.vksi.c4j.Condition.preCondition;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import de.vksi.c4j.ClassInvariant;
import de.vksi.c4j.ContractReference;
import de.vksi.c4j.Pure;
import de.vksi.c4j.Target;
import de.vksi.c4j.systemtest.TransformerAwareRule;
public class ExceptionHandlingSystemTest {
@Rule
public TransformerAwareRule transformerAware = new TransformerAwareRule();
@Rule
public ExpectedException expectedException = ExpectedException.none();
@Test
public void testAbortOnPreconditionFailure() {
TargetClass target = new TargetClass();
target.value = 1;
expectedException.expect(AssertionError.class);
expectedException.expectMessage("method (pre-condition)");
target.method(0);
}
@Test
public void testAbortOnNestedContractFailure() {
expectedException.expect(AssertionError.class);
expectedException.expectMessage("nested (pre-condition)");
new TargetClass().method(1);
}
@Test
public void testAbortOnPostconditionFailure() {
expectedException.expect(AssertionError.class);
expectedException.expectMessage("method (post-condition)");
new TargetClass().method(2);
}
@Test
public void testAbortOnNestedException() {
expectedException.expect(RuntimeException.class);
new TargetClass().method(3);
}
@ContractReference(ContractClass.class)
private static class TargetClass {
public int value;
public int method(int arg) {
value = 1;
nestedMethod(arg);
return arg;
}
// prevents execution of class-invariant in nested method
@Pure
public void nestedMethod(int arg) {
if (arg == 3) {
throw new RuntimeException();
}
}
}
@SuppressWarnings("unused")
private static class ContractClass extends TargetClass {
@Target
private TargetClass target;
@ClassInvariant
public void invariant() {
assert target.value == 0;
}
@Override
public int method(int arg) {
if (preCondition()) {
assert arg > 0 : "method";
}
if (postCondition()) {
assert arg > 2 : "method";
}
return (Integer) ignored();
}
@Override
public void nestedMethod(int arg) {
if (preCondition()) {
assert arg > 1 : "nested";
}
}
}
}