| /******************************************************************************* |
| * Copyright (c) 2017, 2018 École Polytechnique de Montréal |
| * |
| * All rights reserved. This program and the accompanying materials are |
| * made available under the terms of the Eclipse Public License 2.0 which |
| * accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| *******************************************************************************/ |
| |
| package org.eclipse.tracecompass.tmf.chart.ui.swtbot.tests.shared; |
| |
| import static org.junit.Assert.assertArrayEquals; |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.assertTrue; |
| |
| import java.text.Format; |
| import java.util.List; |
| import java.util.Set; |
| |
| import org.eclipse.swt.widgets.Button; |
| import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot; |
| import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable; |
| import org.eclipse.swtbot.swt.finder.matchers.AbstractMatcher; |
| import org.eclipse.swtbot.swt.finder.results.Result; |
| import org.eclipse.swtbot.swt.finder.widgets.SWTBotButton; |
| import org.eclipse.swtbot.swt.finder.widgets.SWTBotCheckBox; |
| import org.eclipse.swtbot.swt.finder.widgets.SWTBotTable; |
| import org.eclipse.tracecompass.internal.provisional.tmf.chart.core.chart.ChartType; |
| import org.eclipse.tracecompass.internal.tmf.chart.ui.data.ChartRange; |
| import org.eclipse.tracecompass.internal.tmf.chart.ui.data.ChartRangeMap; |
| import org.eclipse.tracecompass.internal.tmf.chart.ui.format.ChartDecimalUnitFormat; |
| import org.eclipse.tracecompass.internal.tmf.chart.ui.format.ChartTimeStampFormat; |
| import org.hamcrest.Description; |
| import org.hamcrest.Matcher; |
| import org.swtchart.Chart; |
| import org.swtchart.IAxis; |
| import org.swtchart.ISeries; |
| import org.swtchart.ISeriesSet; |
| |
| /** |
| * Class that provides utility methods to test custom charts with swtbot |
| * |
| * @author Geneviève Bastien |
| */ |
| public final class SWTBotCustomChartUtils { |
| |
| /** |
| * The index in the dialog for the table to select the chart type |
| */ |
| public static final int CHART_TYPE_TABLE_INDEX = 0; |
| /** |
| * The index in the dialog for the table containing the selected series |
| */ |
| public static final int SERIES_SELECTION_TABLE_INDEX = 1; |
| /** |
| * The index in the dialog for the table with the choices for the X axis |
| */ |
| public static final int X_SERIES_TABLE_INDEX = 2; |
| /** |
| * The index in the dialog for the table with the choices for the X axis |
| */ |
| public static final int Y_SERIES_TABLE_INDEX = 3; |
| |
| |
| /** |
| * An enum for the chart axis |
| */ |
| public enum AxisType { |
| /** |
| * Represents the X axis |
| */ |
| X, |
| /** |
| * Represents the Y axis |
| */ |
| Y |
| } |
| |
| private SWTBotCustomChartUtils() { |
| |
| } |
| |
| private static void ensureDialogFocus(SWTWorkbenchBot bot) { |
| bot.shell("Custom chart creation").activate(); |
| } |
| |
| /** |
| * Select the chart type from the dialog maker. |
| * |
| * The chart maker dialog must have been opened by the caller, this method |
| * will put focus on the dialog. |
| * |
| * @param bot |
| * The SWT workbench bot to use |
| * @param chartType |
| * The type of chart to select |
| */ |
| public static void selectChartType(SWTWorkbenchBot bot, ChartType chartType) { |
| ensureDialogFocus(bot); |
| int index = 0; |
| switch (chartType) { |
| case BAR_CHART: |
| index = 0; |
| break; |
| case SCATTER_CHART: |
| index = 1; |
| break; |
| case PIE_CHART: |
| default: |
| throw new IllegalStateException("Unsupported chart type: " + chartType.name()); |
| } |
| // The chart selection table is the first |
| SWTBotTable table = bot.table(CHART_TYPE_TABLE_INDEX); |
| // Click on the row corresponding to the chart type |
| table.click(index, 0); |
| } |
| |
| /** |
| * Add series to the chart. The X and Y values are the texts of the series |
| * to select. This method will fail if one of the requested series string is |
| * not available. |
| * |
| * The chart maker dialog must have been opened by the caller, this method |
| * will put focus on the dialog. |
| * |
| * @param bot |
| * The SWT workbench bot to use |
| * @param xSerie |
| * The title of the X axis series to select |
| * @param ySeries |
| * The titles of the Y axis series to select. Many Y series can |
| * be selected at the same time |
| */ |
| public static void addSeries(SWTWorkbenchBot bot, String xSerie, Set<String> ySeries) { |
| ensureDialogFocus(bot); |
| // The X and Y tables are the 3rd and 4th respectively |
| SWTBotTable xTable = bot.table(X_SERIES_TABLE_INDEX); |
| xTable.getTableItem(xSerie).click(); |
| |
| SWTBotTable yTable = bot.table(Y_SERIES_TABLE_INDEX); |
| ySeries.forEach(s -> yTable.getTableItem(s).check()); |
| |
| bot.buttonInGroup("Series Creator", 0).click(); |
| } |
| |
| /** |
| * Check logarithmic scale button for the axis. |
| * |
| * The chart maker dialog must have been opened by the caller, this method |
| * will put focus on the dialog. |
| * |
| * @param bot |
| * The SWT workbench bot to use |
| * @param axisType |
| * The axis for which to set the log scale |
| */ |
| public static void setLogScale(SWTWorkbenchBot bot, AxisType axisType) { |
| ensureDialogFocus(bot); |
| SWTBotCheckBox checkbox = bot.checkBox("Logarithmic Scale " + axisType.name()); |
| assertTrue(checkbox.isEnabled()); |
| checkbox.select(); |
| } |
| |
| /** |
| * Press the OK button of the chart maker dialog. |
| * |
| * The chart maker dialog must have been opened by the caller, this method |
| * will put focus on the dialog. |
| * |
| * @param bot |
| * The SWT workbench bot to use |
| */ |
| public static void confirmDialog(SWTWorkbenchBot bot) { |
| ensureDialogFocus(bot); |
| bot.button("OK").click(); |
| } |
| |
| /** |
| * Close the chart received in parameter. It clicks on the close button of |
| * the chart. |
| * |
| * @param bot |
| * The SWT workbench bot to use |
| * @param customChart |
| * The custom chart to close |
| */ |
| public static void closeChart(SWTWorkbenchBot bot, Chart customChart) { |
| Button closeButton = bot.widget(closeButtonForChart(customChart), 0); |
| SWTBotButton button = new SWTBotButton(closeButton); |
| button.click(); |
| } |
| |
| private static Matcher<Button> closeButtonForChart(final Chart chart) { |
| return new AbstractMatcher<Button>() { |
| |
| @Override |
| protected boolean doMatch(Object item) { |
| if (!(item instanceof Button)) { |
| return false; |
| } |
| Button button = (Button) item; |
| return (button.getParent() == chart); |
| } |
| |
| @Override |
| public void describeTo(Description description) { |
| description.appendText("delete button for custom chart"); |
| } |
| }; |
| } |
| |
| /** |
| * Verify the titles of the chart and its axis |
| * |
| * @param chart |
| * The chart to verify |
| * @param chartTitle |
| * The title of the chart |
| * @param xTitle |
| * The title of the X axis |
| * @param yTitle |
| * The title of the Y axis |
| */ |
| public static void assertTitles(Chart chart, String chartTitle, String xTitle, String yTitle) { |
| String title = UIThreadRunnable.syncExec((Result<String>) () -> { |
| return chart.getTitle().getText(); |
| }); |
| assertEquals("Title", chartTitle, title); |
| title = UIThreadRunnable.syncExec((Result<String>) () -> { |
| return chart.getAxisSet().getXAxis(0).getTitle().getText(); |
| }); |
| assertEquals("X axis title", xTitle, title); |
| title = UIThreadRunnable.syncExec((Result<String>) () -> { |
| return chart.getAxisSet().getYAxis(0).getTitle().getText(); |
| }); |
| assertEquals("Y axis title", yTitle, title); |
| } |
| |
| /** |
| * Verify that the internal range of the axis corresponds to the expected |
| * values. This method should be called on axis using numerical or time |
| * stamp formatters |
| * |
| * @param chart |
| * The chart to verify |
| * @param axisType |
| * The axis to test for |
| * @param min |
| * The minimum range value |
| * @param max |
| * The maximum range value |
| */ |
| public static void assertAxisRange(Chart chart, AxisType axisType, Number min, Number max) { |
| IAxis axis = (axisType == AxisType.X ? chart.getAxisSet().getXAxes()[0] : chart.getAxisSet().getYAxes()[0]); |
| Format format = axis.getTick().getFormat(); |
| |
| // Get the range map for the format, it has to have one |
| ChartRangeMap map = null; |
| if (format instanceof ChartTimeStampFormat) { |
| map = ((ChartTimeStampFormat) format).getRangeMap(); |
| } else if (format instanceof ChartDecimalUnitFormat) { |
| map = ((ChartDecimalUnitFormat) format).getRangeMap(); |
| } |
| assertNotNull(map); |
| |
| ChartRange inputDataRange = map.getInputDataRange(); |
| assertEquals(min.doubleValue(), inputDataRange.getMinimum().doubleValue(), 1); |
| assertEquals(max.doubleValue(), inputDataRange.getMaximum().doubleValue(), 1); |
| |
| } |
| |
| /** |
| * Verify the categories of an axis correspond to the excpected values. This |
| * method should be called on axis using discrete string values. |
| * |
| * @param chart |
| * The chart to verify |
| * @param axisType |
| * The axis to test for |
| * @param categories |
| * The expected categories |
| */ |
| public static void assertCategoriesAxis(Chart chart, AxisType axisType, String[] categories) { |
| IAxis axis = (axisType == AxisType.X ? chart.getAxisSet().getXAxes()[0] : chart.getAxisSet().getYAxes()[0]); |
| assertTrue(axis.isCategoryEnabled()); |
| String[] categorySeries = axis.getCategorySeries(); |
| assertArrayEquals(categories, categorySeries); |
| } |
| |
| /** |
| * Verify the title of the series. These titles are shown in the legend if |
| * there is more than one serie |
| * |
| * @param customChart |
| * The chart to verify |
| * @param titles |
| * The list of series titles |
| */ |
| public static void assertSeriesTitle(Chart customChart, List<String> titles) { |
| ISeriesSet seriesSet = customChart.getSeriesSet(); |
| assertNotNull(seriesSet); |
| ISeries[] series = seriesSet.getSeries(); |
| |
| assertEquals(titles.size(), series.length); |
| for (int i = 0; i < series.length; i++) { |
| assertEquals("Series title " + i, titles.get(i), series[i].getId()); |
| } |
| } |
| |
| /** |
| * Verify an axis log scale status |
| * |
| * @param chart |
| * The chart to verify |
| * @param axisType |
| * The axis to test for |
| * @param logscale |
| * <code>true</code> if this axis should be logscale, |
| * <code>false</code> otherwise |
| */ |
| public static void assertAxisLogscale(Chart chart, AxisType axisType, boolean logscale) { |
| IAxis axis = (axisType == AxisType.X ? chart.getAxisSet().getXAxes()[0] : chart.getAxisSet().getYAxes()[0]); |
| assertEquals("Log scale", logscale, axis.isLogScaleEnabled()); |
| } |
| |
| } |