package de.vksi.c4j.systemtest.classinvariant;
import static de.vksi.c4j.Condition.unchanged;
import org.junit.Rule;
import org.junit.Test;
import de.vksi.c4j.ClassInvariant;
import de.vksi.c4j.ContractReference;
import de.vksi.c4j.Target;
import de.vksi.c4j.systemtest.MutableString;
import de.vksi.c4j.systemtest.TransformerAwareRule;
public class UnchangedInClassInvariantSystemTest {
@Rule
public TransformerAwareRule transformerAware = new TransformerAwareRule();
@Test
public void testUnchangedInClassInvariant() {
new TargetClass().leavePrimitiveValueUnchanged();
}
@Test(expected = AssertionError.class)
public void testUnchangedInClassInvariantFailing() {
new TargetClass().changePrimitiveValue();
}
@Test
public void testUnchangedInClassInvariantForReference() {
new TargetClass().leaveReferenceValueUnchanged();
}
@Test(expected = AssertionError.class)
public void testUnchangedInClassInvariantForReferenceFailing() {
new TargetClass().changeReferenceValue();
}
@Test(expected = AssertionError.class)
public void testUnchangedInClassInvariantForReferenceReassign() {
new TargetClass().reassignReferenceValue();
}
@ContractReference(ContractClass.class)
private static class TargetClass {
protected int primitiveValue;
protected MutableString referenceValue;
public TargetClass() {
primitiveValue = 1;
referenceValue = new MutableString("constructor");
}
public void leavePrimitiveValueUnchanged() {
}
public void changePrimitiveValue() {
primitiveValue--;
}
public void leaveReferenceValueUnchanged() {
}
public void changeReferenceValue() {
referenceValue.setValue("new value");
}
public void reassignReferenceValue() {
referenceValue = new MutableString("new value");
}
}
@SuppressWarnings("unused")
private static class ContractClass {
@Target
private TargetClass target;
@ClassInvariant
public void invariant() {
assert unchanged(target.primitiveValue);
assert unchanged(target.referenceValue);
}
}
}