/******************************************************************************* * Mission Control Technologies, Copyright (c) 2009-2012, United States Government * as represented by the Administrator of the National Aeronautics and Space * Administration. All rights reserved. * * The MCT platform is licensed under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0. * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. * * MCT includes source code licensed under additional open source licenses. See * the MCT Open Source Licenses file included with this distribution or the About * MCT Licenses dialog available at runtime from the MCT Help menu for additional * information. *******************************************************************************/ package gov.nasa.arc.mct.fastplot.bridge; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import gov.nasa.arc.mct.fastplot.bridge.PlotConstants.AxisOrientationSetting; import gov.nasa.arc.mct.fastplot.bridge.PlotConstants.PlotLineConnectionType; import gov.nasa.arc.mct.fastplot.bridge.PlotConstants.PlotLineDrawingFlags; import gov.nasa.arc.mct.fastplot.bridge.PlotConstants.TimeAxisSubsequentBoundsSetting; import gov.nasa.arc.mct.fastplot.bridge.PlotConstants.XAxisMaximumLocationSetting; import gov.nasa.arc.mct.fastplot.bridge.PlotConstants.YAxisMaximumLocationSetting; import gov.nasa.arc.mct.fastplot.settings.PlotSettings; import gov.nasa.arc.mct.fastplot.utils.AbbreviatingPlotLabelingAlgorithm; import gov.nasa.arc.mct.fastplot.view.Axis; import gov.nasa.arc.mct.fastplot.view.PinSupport; import gov.nasa.arc.mct.fastplot.view.PlotViewManifestation; import java.awt.Color; import java.awt.Font; import java.awt.Rectangle; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.GregorianCalendar; import java.util.List; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JPanel; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.testng.Assert; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; public class TestPlotTimeSyncLine { @Mock private PlotAbstraction plotView; @Mock private PlotViewManifestation mockPlotViewManifestation; private List<AbstractPlottingPackage> plots = new ArrayList<AbstractPlottingPackage>(); private AbbreviatingPlotLabelingAlgorithm plotLabelingAlgorithm = new AbbreviatingPlotLabelingAlgorithm(); @BeforeMethod public void setup() { long now = new GregorianCalendar().getTimeInMillis(); MockitoAnnotations.initMocks(this); Mockito.when(mockPlotViewManifestation.getCurrentMCTTime()).thenReturn(now); Mockito.when(plotView.getCurrentMCTTime()).thenReturn(now); Mockito.when(plotView.getTimeAxis()).thenReturn(new Axis()); Mockito.when(plotView.getTimeAxisUserPin()).thenReturn(new PinSupport().createPin()); Mockito.when(plotView.getSubPlots()).thenReturn(plots); Mockito.when(plotView.getMinTime()).thenReturn(now - 360000); Mockito.when(plotView.getMaxTime()).thenReturn(now + 360000); Mockito.when(plotView.getXAxisMaximumLocation()).thenReturn(XAxisMaximumLocationSetting.MAXIMUM_AT_RIGHT); Mockito.when(plotView.getYAxisMaximumLocation()).thenReturn(YAxisMaximumLocationSetting.MAXIMUM_AT_TOP); Mockito.when(plotView.getPlotLineDraw()).thenReturn(PlotConstants.DEFAULT_PLOT_LINE_DRAW); } @Test public void testUserMouseClickEstablishSyncLineXAsTime() { /* * Plan: Simulate a user by moving the mouse into the plot area. Click on * the time axis. Release shift and click. Check that sync line appears and is removed. * Then try some clicks outside the target area or within without pressed * and test that a sync line does not appear. */ Mockito.when(plotView.getAxisOrientationSetting()).thenReturn(AxisOrientationSetting.X_AXIS_AS_TIME); final PlotterPlot plot = new PlotterPlot(); plot.createChart( new Font("Arial", Font.PLAIN, 12), 1, Color.gray, Color.black, 0, Color.white, Color.white, Color.white, "dd", Color.black, Color.black, 1, false, true, true, plotView, plotLabelingAlgorithm); plots.add(plot); Mockito.doAnswer(new Answer<Object>() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { plot.showTimeSyncLine((GregorianCalendar) invocation.getArguments()[0]); return null; } }).when(plotView).showTimeSyncLine(Mockito.<GregorianCalendar>any()); Mockito.doAnswer(new Answer<Object>() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { plot.removeTimeSyncLine(); return null; } }).when(plotView).removeTimeSyncLine(); Mockito.doAnswer(new Answer<Object>() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { plot.removeTimeSyncLine(); return null; } }).when(plotView).notifyGlobalTimeSyncFinished(); JFrame frame = new JFrame(); frame.add(plot.getPlotComponent()); frame.pack(); // put data onto the plot so that it is initialized plot.addDataSet("DataSet1", Color.red); GregorianCalendar now = new GregorianCalendar(); // Add in limit value plot.addData("DataSet1", now.getTimeInMillis(), 10.0); // Plot should have a time sync line. Assert.assertNotNull(plot.timeSyncLine); plot.refreshDisplay(); // User moves mouse into the general area. Rectangle contentRect = plot.getPlotView().getContents().getBounds(); plot.timeSyncLine.mouseEntered(new MouseEvent(plot.getPlotComponent(), 1, 0, 0, (int) contentRect.getMinX() + 1, (int) contentRect.getMaxY(), 0, false)); // User clicks outside of the plot time axis area. MouseEvent outsideMouseEvent = new MouseEvent(plot.getPlotComponent(), 1, 0, 0, (int) contentRect.getMaxX() -1, (int) contentRect.getMaxY() -1, 0, false); plot.timeSyncLine.mousePressed(outsideMouseEvent); Assert.assertFalse(plot.timeSyncLine.timeSyncLineVisible()); plot.timeSyncLine.mouseReleased(outsideMouseEvent); Assert.assertFalse(plot.timeSyncLine.timeSyncLineVisible()); // User clicks inside of the plot time axis area. MouseEvent insideMouseEvent = new MouseEvent(plot.getPlotComponent(), 1, 0, 0, (int) contentRect.getMinX() + 1, (int) contentRect.getMaxY(), 0, false); plot.timeSyncLine.mousePressed(insideMouseEvent); Assert.assertTrue(plot.timeSyncLine.timeSyncLineVisible()); MouseEvent insideDragEvent = new MouseEvent(plot.getPlotComponent(), 1, 0, 0, (int) contentRect.getMinX() + 20, (int) contentRect.getMaxY(), 0, false); plot.timeSyncLine.mouseDragged(insideDragEvent); Assert.assertTrue(plot.timeSyncLine.timeSyncLineVisible()); Assert.assertTrue(plot.timeSyncLine.inTimeSyncMode()); } @Test public void testMouseExit() { Mockito.when(plotView.getAxisOrientationSetting()).thenReturn(AxisOrientationSetting.X_AXIS_AS_TIME); final PlotterPlot plot = new PlotterPlot(); plot.createChart( new Font("Arial", Font.PLAIN, 12), 1, Color.gray, Color.black, 0, Color.white, Color.white, Color.white, "dd", Color.black, Color.black, 1, false, true, true, plotView, plotLabelingAlgorithm); plots.add(plot); Mockito.doAnswer(new Answer<Object>() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { plot.showTimeSyncLine((GregorianCalendar) invocation.getArguments()[0]); return null; } }).when(plotView).showTimeSyncLine(Mockito.<GregorianCalendar>any()); JFrame frame = new JFrame(); frame.add(plot.getPlotComponent()); frame.pack(); // put data onto the plot so that it is initialized plot.addDataSet("DataSet1", Color.red); GregorianCalendar now = new GregorianCalendar(); // Add in limit value plot.addData("DataSet1", now.getTimeInMillis(), 10.0); // Plot should have a time sync line. Assert.assertNotNull(plot.timeSyncLine); plot.refreshDisplay(); Rectangle contentRect = plot.getPlotView().getContents().getBounds(); MouseEvent pressEvent = new MouseEvent(plot.getPlotComponent(), 1, 0, 0, (int) contentRect.getMinX() + 20, (int) contentRect.getMaxY(), 0, false, MouseEvent.BUTTON1); plot.timeSyncLine.mousePressed(pressEvent); Assert.assertTrue(plot.timeSyncLine.timeSyncLineVisible()); Assert.assertTrue(plot.timeSyncLine.inTimeSyncMode()); // Move mouse MouseEvent insideDragEvent = new MouseEvent(plot.getPlotComponent(), 1, 0, 0, (int) contentRect.getMinX() + 20, (int) contentRect.getMaxY(), 0, false); plot.timeSyncLine.mouseDragged(insideDragEvent); Assert.assertTrue(plot.timeSyncLine.timeSyncLineVisible()); Assert.assertTrue(plot.timeSyncLine.inTimeSyncMode()); // Move mouse outside. MouseEvent mouseExit = new MouseEvent(new JPanel(), 1, 0, 0, 0, 0, 0, false); plot.timeSyncLine.mouseExited(mouseExit); verify(plotView, never()).notifyGlobalTimeSyncFinished(); } @Test public void testUserMouseClickEstablishSyncLineYAsTime() { /* * Plan: Simulate a user by moving the mouse into the plot area. Click on * the time axis. Release shift and click. Check that sync line appears and is removed. * Then try some clicks outside the target area or within without pressed * and test that a sync line does not appear. */ Mockito.when(plotView.getAxisOrientationSetting()).thenReturn(AxisOrientationSetting.Y_AXIS_AS_TIME); PlotterPlot plot = new PlotterPlot(); plot.createChart( new Font("Arial", Font.PLAIN, 12), 1, Color.gray, Color.black, 0, Color.white, Color.white, Color.white, "dd", Color.black, Color.black, 1, false, true, true, plotView, plotLabelingAlgorithm); plots.add(plot); // put data onto the plot so that it is initialized plot.addDataSet("DataSet1", Color.red); GregorianCalendar now = new GregorianCalendar(); // Add in limit value plot.addData("DataSet1", now.getTimeInMillis(), 10.0); // Plot should have a time sync line. Assert.assertNotNull(plot.timeSyncLine); Rectangle plotRectangle = plot.getPlotView().getContents().getBounds(); // User moves mouse into the general area. plot.timeSyncLine.mouseEntered(new MouseEvent(plot.getPlotComponent(), 1, 0, 0, (int) plotRectangle.getMinX() - 1, (int) plotRectangle.getMaxY() -1, 0, false)); // User clicks outside of the plot time axis area. MouseEvent outsideMouseEvent = new MouseEvent(plot.getPlotComponent(), 1, 0, 0, (int) plotRectangle.getMinX() +1, (int) plotRectangle.getMaxY() -1, 0, false); plot.timeSyncLine.mousePressed(outsideMouseEvent); Assert.assertFalse(plot.timeSyncLine.timeSyncLineVisible()); plot.timeSyncLine.mouseReleased(outsideMouseEvent); Assert.assertFalse(plot.timeSyncLine.timeSyncLineVisible()); // Move the mouse below the timeline axis. outsideMouseEvent = new MouseEvent(plot.getPlotComponent(), 1, 0, 0, (int) plotRectangle.getMinX() + 1, (int) plotRectangle.getMaxY() + plot.getPlotView().getXAxis().getHeight()+ 1, 0, false); plot.timeSyncLine.mousePressed(outsideMouseEvent); Assert.assertFalse(plot.timeSyncLine.timeSyncLineVisible()); plot.timeSyncLine.mouseReleased(outsideMouseEvent); } @Test public void testProgramaticRequestsEstablishSyncLine() { /* * Plan: Request and remove the sync line using the plot's API. */ PlotView testPlot = new PlotView.Builder(PlotterPlot.class).build(); testPlot.setManifestation(mockPlotViewManifestation); testPlot.addDataSet("Foo"); testPlot.addData("Foo", System.currentTimeMillis(), 10); Assert.assertFalse(testPlot.isTimeSyncLineVisible()); testPlot.showTimeSyncLine(new GregorianCalendar()); Assert.assertTrue(testPlot.isTimeSyncLineVisible()); testPlot.removeTimeSyncLine(); Assert.assertFalse(testPlot.isTimeSyncLineVisible()); PlotSettings settings = new PlotSettings(); settings.setAxisOrientationSetting(AxisOrientationSetting.Y_AXIS_AS_TIME); testPlot = new PlotView.Builder(PlotterPlot.class).plotSettings(settings).build(); testPlot.setManifestation(mockPlotViewManifestation); testPlot.addDataSet("Foo"); testPlot.addData("Foo", System.currentTimeMillis(), 10); Assert.assertFalse(testPlot.isTimeSyncLineVisible()); testPlot.showTimeSyncLine(new GregorianCalendar()); Assert.assertTrue(testPlot.isTimeSyncLineVisible()); testPlot.removeTimeSyncLine(); Assert.assertFalse(testPlot.isTimeSyncLineVisible()); } @Test public void testShiftAfterClick() { // Click and hold mouse button to start vertical line, then press shift to enter time sync mode. Mockito.when(plotView.getAxisOrientationSetting()).thenReturn(AxisOrientationSetting.X_AXIS_AS_TIME); final PlotterPlot plot = new PlotterPlot(); plot.createChart( new Font("Arial", Font.PLAIN, 12), 1, Color.gray, Color.black, 0, Color.white, Color.white, Color.white, "dd", Color.black, Color.black, 1, false, true, true, plotView, plotLabelingAlgorithm); plots.add(plot); Mockito.doAnswer(new Answer<Object>() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { plot.showTimeSyncLine((GregorianCalendar) invocation.getArguments()[0]); return null; } }).when(plotView).showTimeSyncLine(Mockito.<GregorianCalendar> any()); Mockito.doAnswer(new Answer<Object>() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { plot.removeTimeSyncLine(); return null; } }).when(plotView).removeTimeSyncLine(); Mockito.doAnswer(new Answer<Object>() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { plot.removeTimeSyncLine(); return null; } }).when(plotView).notifyGlobalTimeSyncFinished(); JFrame frame = new JFrame(); JComponent panel = plot.getPlotComponent(); frame.add(panel); frame.pack(); // put data onto the plot so that it is initialized plot.addDataSet("DataSet1", Color.red); GregorianCalendar now = new GregorianCalendar(); // Add in limit value plot.addData("DataSet1", now.getTimeInMillis(), 10.0); // Plot should have a time sync line. Assert.assertNotNull(plot.timeSyncLine); Assert.assertFalse(plot.timeSyncLine.timeSyncLineVisible()); plot.refreshDisplay(); // User clicks inside of the plot time axis area. Rectangle contentRect = plot.getPlotView().getContents().getBounds(); MouseEvent pressEvent = new MouseEvent(panel, 1, 0, 0, (int) contentRect.getMinX() + 1, (int) contentRect.getMaxY(), 0, false); plot.timeSyncLine.mousePressed(pressEvent); Assert.assertTrue(plot.timeSyncLine.timeSyncLineVisible()); Mockito.verify(plotView, Mockito.never()).initiateGlobalTimeSync(Mockito.<GregorianCalendar> any()); plot.timeSyncLine.informShiftKeyState(true); Assert.assertTrue(plot.timeSyncLine.timeSyncLineVisible()); Mockito.verify(plotView).initiateGlobalTimeSync(Mockito.<GregorianCalendar> any()); MouseEvent releaseEvent = new MouseEvent(panel, MouseEvent.MOUSE_RELEASED, System.currentTimeMillis(), 0, (int) contentRect.getMinX() + 1, (int) contentRect.getMaxY(), 0, false); plot.timeSyncLine.mouseReleased(releaseEvent); Assert.assertFalse(plot.timeSyncLine.timeSyncLineVisible()); plot.timeSyncLine.informShiftKeyState(false); Assert.assertFalse(plot.timeSyncLine.timeSyncLineVisible()); } }