package de.vksi.c4j.acceptancetest.s2; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import org.junit.Rule; import org.junit.Test; import org.junit.matchers.JUnitMatchers; import org.junit.rules.ExpectedException; import de.vksi.c4j.Pure; import de.vksi.c4j.acceptancetest.floatingwindow.Vector; import de.vksi.c4j.acceptancetest.point.Color; import de.vksi.c4j.systemtest.TransformerAwareRule; public class NNPureS2Test { @Rule public TransformerAwareRule transformerAware = new TransformerAwareRule(); @Rule public ExpectedException thrown = ExpectedException.none(); @Test public void testIncorrectPureUsage_IllegalMethodAccessOnBoxedField() { thrown.expect(AssertionError.class); thrown.expectMessage(JUnitMatchers.containsString("illegal access on unpure object")); FloatingWindow window = new FloatingWindow(new Vector(0, 0)); window.move(new Vector(5, 10)); } @Test public void testIncorrectPureUsage_IllegalFieldWriteAccess() { thrown.expect(AssertionError.class); thrown.expectMessage(JUnitMatchers.containsString("illegal write access on field")); FloatingWindow window = new FloatingWindow(new Vector(0, 0)); window.setStyleColor(Color.GREEN); } @Test public void testCorrectPureUsage_ChangesOnLocalVariablesAllowed() { FloatingWindow window = new FloatingWindow(new Vector(1, 3)); assertEquals("UpperLeftCorner: 1, 3\nColor: INDIGO", window.toString()); } @Test public void testCorrectPureUsage_ReferenceCopySetToNullDoesNotChangeObject() { FloatingWindow window = new FloatingWindow(new Vector(1, 3)); window.destroyUpperLeftCorner(); assertNotNull(window.upperLeftCorner); } @Test public void testIncorrectPureUsage_FieldModifiedInPureMethodOfAnotherType() { thrown.expect(AssertionError.class); thrown.expectMessage(JUnitMatchers.containsString("illegal access on unpure object")); FloatingWindow window = new FloatingWindow(new Vector(1, 3)); window.resetUpperLeftCorner(); } @Test public void testIncorrectPureUsage_IllegalFieldModification() { thrown.expect(AssertionError.class); thrown.expectMessage(JUnitMatchers.containsString("illegal write access on field")); FloatingWindow window = new FloatingWindow(new Vector(1, 3)); window.reallyDestroyUpperLeftCorner(); } private class FloatingWindow { public Vector upperLeftCorner; public WindowStyle style; private VectorDestroyer destroyer; public FloatingWindow(Vector upperLeftCorner) { this.upperLeftCorner = upperLeftCorner; style = new WindowStyle(); destroyer = new VectorDestroyer(); } @Pure //method does nothing public void destroyUpperLeftCorner() { destroyer.destroyVector(upperLeftCorner); } @Pure //method does nothing public void reallyDestroyUpperLeftCorner() { upperLeftCorner = null; } @Pure //Incorrect use of pure public void resetUpperLeftCorner() { destroyer.resetVector(upperLeftCorner); } @Pure //Incorrect use of pure public void move(Vector vector) { VectorBox upperLeftCornerBoxed = new VectorBox(upperLeftCorner); upperLeftCornerBoxed.add(vector); } @Pure //Incorrect use of pure public void setStyleColor(Color color) { style.color = color; } @Pure @Override public String toString() { StringBuffer buffer = new StringBuffer(); buffer.append("UpperLeftCorner: " + upperLeftCorner.getX() + ", " + upperLeftCorner.getY() + "\n"); buffer.append("Color: " + style.color); return buffer.toString(); } } private class VectorDestroyer { @Pure public void destroyVector(Vector vector) { vector = null; } @Pure public void resetVector(Vector vector) { vector.setX(0); vector.setY(0); } } private class VectorBox { Vector vector; public VectorBox(Vector vector) { this.vector = vector; } public void add(Vector vectorToAdd) { vector.add(vectorToAdd); } } private class WindowStyle { public Color color = Color.INDIGO; } }