package pipe.controllers; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import pipe.historyActions.MultipleEdit; import pipe.historyActions.arc.AddArcPathPoint; import pipe.historyActions.arc.ArcPathPointType; import pipe.historyActions.arc.SetArcWeightAction; import pipe.historyActions.component.ChangePetriNetComponentName; import pipe.utilities.transformers.Contains; import uk.ac.imperial.pipe.models.petrinet.Arc; import uk.ac.imperial.pipe.models.petrinet.ArcPoint; import uk.ac.imperial.pipe.models.petrinet.Place; import uk.ac.imperial.pipe.models.petrinet.Transition; import uk.ac.imperial.pipe.parsers.FunctionalResults; import uk.ac.imperial.pipe.parsers.UnparsableException; import javax.swing.event.UndoableEditListener; import javax.swing.undo.UndoableEdit; import java.awt.geom.Point2D; import java.util.*; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class ArcControllerTest { @Rule public ExpectedException exception = ExpectedException.none(); @Mock Arc<Place, Transition> mockArc; @Mock PetriNetController mockPetriNetController; ArcController<Place, Transition> controller; private static final String DEFAULT_TOKEN_ID = "Default"; @Mock UndoableEditListener listener; @Before public void setUp() { controller = new ArcController<>(mockArc, mockPetriNetController, listener); FunctionalResults<Double> results = new FunctionalResults<>(1.0, new HashSet<String>()); when(mockPetriNetController.parseFunctionalExpression(anyString())).thenReturn(results); } @Test public void setWeightCreatesHistoryItem() throws UnparsableException { String oldWeight = "5"; when(mockArc.getWeightForToken(DEFAULT_TOKEN_ID)).thenReturn(oldWeight); String newWeight = "51"; controller.setWeight(DEFAULT_TOKEN_ID, newWeight); SetArcWeightAction<Place, Transition> weightAction = new SetArcWeightAction<>(mockArc, DEFAULT_TOKEN_ID, oldWeight, newWeight); verify(listener).undoableEditHappened(argThat(Contains.thisAction(weightAction))); } @Test public void setWeightUpdatesArcWeight() throws UnparsableException { String oldWeight = "5"; when(mockArc.getWeightForToken(DEFAULT_TOKEN_ID)).thenReturn(oldWeight); String newWeight = "51"; controller.setWeight(DEFAULT_TOKEN_ID, newWeight); verify(mockArc).setWeight(DEFAULT_TOKEN_ID, newWeight); } @Test public void setWeightsCreatesHistoryItem() throws UnparsableException { Map<String, String> tokenWeights = new HashMap<>(); String oldWeight = "5"; when(mockArc.getWeightForToken(DEFAULT_TOKEN_ID)).thenReturn(oldWeight); String newWeight = "51"; tokenWeights.put(DEFAULT_TOKEN_ID, newWeight); controller.setWeights(tokenWeights); UndoableEdit weightAction = new SetArcWeightAction<>(mockArc, DEFAULT_TOKEN_ID, oldWeight, newWeight); UndoableEdit edit = new MultipleEdit(Arrays.asList(weightAction)); verify(listener).undoableEditHappened(argThat(Contains.thisAction(edit))); } @Test public void setWeightsUpdatesArc() throws UnparsableException { Map<String, String> tokenWeights = new HashMap<>(); String oldWeight = "5"; when(mockArc.getWeightForToken(DEFAULT_TOKEN_ID)).thenReturn(oldWeight); String newWeight = "51"; tokenWeights.put(DEFAULT_TOKEN_ID, newWeight); controller.setWeights(tokenWeights); verify(mockArc).setWeight(DEFAULT_TOKEN_ID, newWeight); } @Test public void throwsUnparsableExceptionForNonIntegerWeight() throws UnparsableException { FunctionalResults<Double> result = new FunctionalResults<>(5.2, new HashSet<String>()); when(mockPetriNetController.parseFunctionalExpression(anyString())).thenReturn(result); exception.expect(UnparsableException.class); exception.expectMessage("Value is not an integer, please surround expression with floor or ceil"); controller.setWeight(DEFAULT_TOKEN_ID, "1.2"); } @Test public void throwsUnparsableExceptionForNonIntegerWeights() throws UnparsableException { Map<String, String> tokenWeights = new HashMap<>(); FunctionalResults<Double> result = new FunctionalResults<>(5.2, new HashSet<String>()); when(mockPetriNetController.parseFunctionalExpression(anyString())).thenReturn(result); exception.expect(UnparsableException.class); exception.expectMessage("Value is not an integer, please surround expression with floor or ceil"); tokenWeights.put(DEFAULT_TOKEN_ID, "5.2"); controller.setWeights(tokenWeights); } @Test public void throwsUnparsableExceptionForErrorInWeights() throws UnparsableException { Map<String, String> tokenWeights = new HashMap<>(); List<String> errors = new LinkedList<>(); errors.add("test error"); FunctionalResults<Double> result = new FunctionalResults<>(5.0, errors, new HashSet<String>()); when(mockPetriNetController.parseFunctionalExpression(anyString())).thenReturn(result); exception.expect(UnparsableException.class); exception.expectMessage("test error"); tokenWeights.put(DEFAULT_TOKEN_ID, "5.2"); controller.setWeights(tokenWeights); } @Test public void throwsUnparsableExceptionForErrorInWeight() throws UnparsableException { List<String> errors = new LinkedList<>(); errors.add("test error"); FunctionalResults<Double> result = new FunctionalResults<>(5.0, errors, new HashSet<String>()); when(mockPetriNetController.parseFunctionalExpression(anyString())).thenReturn(result); exception.expect(UnparsableException.class); exception.expectMessage("test error"); controller.setWeight(DEFAULT_TOKEN_ID, "5.0"); } @Test public void splittingArcPointSplitsHalfWay() { ArcPoint nextPoint = new ArcPoint(new Point2D.Double(10, 10), false); ArcPoint splitPoint = new ArcPoint(new Point2D.Double(0, 0), false); when(mockArc.getNextPoint(splitPoint)).thenReturn(nextPoint); controller.splitArcPoint(splitPoint); ArcPoint expected = new ArcPoint(new Point2D.Double(5, 5), false); verify(mockArc).addIntermediatePoint(expected); } @Test public void splittingArcPointKeepsArcUncurved() { ArcPoint nextPoint = new ArcPoint(new Point2D.Double(10, 10), false); ArcPoint splitPoint = new ArcPoint(new Point2D.Double(0, 0), false); when(mockArc.getNextPoint(splitPoint)).thenReturn(nextPoint); controller.splitArcPoint(splitPoint); ArcPoint expected = new ArcPoint(new Point2D.Double(5, 5), false); verify(mockArc).addIntermediatePoint(expected); } @Test public void splittingArcPointKeepsArcCurved() { ArcPoint nextPoint = new ArcPoint(new Point2D.Double(10, 10), false); ArcPoint splitPoint = new ArcPoint(new Point2D.Double(0, 0), true); when(mockArc.getNextPoint(splitPoint)).thenReturn(nextPoint); controller.splitArcPoint(splitPoint); ArcPoint expected = new ArcPoint(new Point2D.Double(5, 5), true); verify(mockArc).addIntermediatePoint(expected); } @Test public void splittingCreatesHistoryItem() { ArcPoint nextPoint = new ArcPoint(new Point2D.Double(10, 10), false); ArcPoint splitPoint = new ArcPoint(new Point2D.Double(0, 0), true); when(mockArc.getNextPoint(splitPoint)).thenReturn(nextPoint); controller.splitArcPoint(splitPoint); ArcPoint expected = new ArcPoint(new Point2D.Double(5, 5), true); UndoableEdit addArcPointAction = new AddArcPathPoint<>(mockArc, expected); verify(listener).undoableEditHappened(argThat(Contains.thisAction(addArcPointAction))); } @Test public void toggleCreatesHistoryItem() { ArcPoint point = new ArcPoint(new Point2D.Double(0, 0), false); controller.toggleArcPointType(point); ArcPathPointType arcPathPointType = new ArcPathPointType(point); verify(listener).undoableEditHappened(argThat(Contains.thisAction(arcPathPointType))); } @Test public void arcPointCreatesAtSpecifiedPoint() { Point2D.Double point = new Point2D.Double(4, 1); controller.addPoint(point); ArcPoint expected = new ArcPoint(point, false); verify(mockArc).addIntermediatePoint(expected); } @Test public void addPointCreatesHistoryItem() { ArcPoint point = new ArcPoint(new Point2D.Double(0, 0), false); controller.addPoint(point.getPoint()); UndoableEdit addArcPointAction = new AddArcPathPoint<>(mockArc, point); verify(listener).undoableEditHappened(argThat(Contains.thisAction(addArcPointAction))); } @Test public void setNameChangesName() { String newName = "newName"; when(mockArc.getId()).thenReturn("oldId"); controller.setId(newName); verify(mockArc).setId(newName); } @Test public void setNameCreatesUndoItem() { String oldName = "oldName"; String newName = "newName"; when(mockArc.getId()).thenReturn(oldName); controller.setId(newName); UndoableEdit nameEdit = new ChangePetriNetComponentName(mockArc, oldName, newName); verify(listener).undoableEditHappened(argThat(Contains.thisAction(nameEdit))); } }