Skip to content

Content of file GridControlRenderer_PTest.java

/*******************************************************************************
 * Copyright (c) 2011-2019 EclipseSource Muenchen GmbH and others.
 *
 * 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
 *
 * Contributors:
 * Mat Hansen - initial API and implementation
 * Christian W. Damus - bug 534829
 ******************************************************************************/
package org.eclipse.emf.ecp.view.internal.table.nebula.grid;

import static org.hamcrest.CoreMatchers.hasItem;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.eclipse.core.databinding.observable.Observables;
import org.eclipse.core.databinding.observable.list.WritableList;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.databinding.IEMFValueProperty;
import org.eclipse.emf.databinding.internal.EMFValueProperty;
import org.eclipse.emf.databinding.internal.EMFValuePropertyDecorator;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EStructuralFeature.Setting;
import org.eclipse.emf.ecp.test.common.DefaultRealm;
import org.eclipse.emf.ecp.view.spi.context.ViewModelContext;
import org.eclipse.emf.ecp.view.spi.model.LabelAlignment;
import org.eclipse.emf.ecp.view.spi.model.VDomainModelReference;
import org.eclipse.emf.ecp.view.spi.model.VFeaturePathDomainModelReference;
import org.eclipse.emf.ecp.view.spi.model.VViewFactory;
import org.eclipse.emf.ecp.view.spi.renderer.NoPropertyDescriptorFoundExeption;
import org.eclipse.emf.ecp.view.spi.renderer.NoRendererFoundException;
import org.eclipse.emf.ecp.view.spi.table.model.VTableColumnConfiguration;
import org.eclipse.emf.ecp.view.spi.table.model.VTableControl;
import org.eclipse.emf.ecp.view.spi.table.model.VTableDomainModelReference;
import org.eclipse.emf.ecp.view.spi.table.model.VTableFactory;
import org.eclipse.emf.ecp.view.spi.table.nebula.grid.GridControlSWTRenderer;
import org.eclipse.emf.ecp.view.spi.table.nebula.grid.GridTableViewerComposite;
import org.eclipse.emf.ecp.view.spi.table.nebula.grid.messages.Messages;
import org.eclipse.emf.ecp.view.spi.table.swt.action.AddRowAction;
import org.eclipse.emf.ecp.view.spi.table.swt.action.DuplicateRowAction;
import org.eclipse.emf.ecp.view.spi.table.swt.action.RemoveRowAction;
import org.eclipse.emf.ecp.view.spi.util.swt.ImageRegistryService;
import org.eclipse.emf.ecp.view.table.ui.nebula.grid.test.model.audit.AuditFactory;
import org.eclipse.emf.ecp.view.table.ui.nebula.grid.test.model.audit.AuditPackage;
import org.eclipse.emf.ecp.view.table.ui.nebula.grid.test.model.audit.Member;
import org.eclipse.emf.ecp.view.table.ui.nebula.grid.test.model.audit.Organization;
import org.eclipse.emf.ecp.view.table.ui.nebula.grid.test.model.audit.RegisteredUser;
import org.eclipse.emf.ecp.view.template.model.VTStyleProperty;
import org.eclipse.emf.ecp.view.template.model.VTViewTemplateProvider;
import org.eclipse.emf.ecp.view.template.style.keybinding.model.VTKeyBinding;
import org.eclipse.emf.ecp.view.template.style.keybinding.model.VTKeyBindings;
import org.eclipse.emf.ecp.view.template.style.keybinding.model.VTKeybindingFactory;
import org.eclipse.emf.ecp.view.test.common.swt.spi.SWTTestUtil;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emfforms.common.Optional;
import org.eclipse.emfforms.spi.common.converter.EStructuralFeatureValueConverterService;
import org.eclipse.emfforms.spi.common.report.ReportService;
import org.eclipse.emfforms.spi.core.services.databinding.DatabindingFailedException;
import org.eclipse.emfforms.spi.core.services.databinding.emf.EMFFormsDatabindingEMF;
import org.eclipse.emfforms.spi.core.services.editsupport.EMFFormsEditSupport;
import org.eclipse.emfforms.spi.core.services.label.EMFFormsLabelProvider;
import org.eclipse.emfforms.spi.core.services.label.NoLabelFoundException;
import org.eclipse.emfforms.spi.localization.EMFFormsLocalizationService;
import org.eclipse.emfforms.spi.swt.core.layout.SWTGridCell;
import org.eclipse.emfforms.spi.swt.table.AbstractTableViewerComposite;
import org.eclipse.emfforms.spi.swt.table.ColumnConfiguration;
import org.eclipse.emfforms.spi.swt.table.TableConfiguration;
import org.eclipse.emfforms.swt.common.test.AbstractControl_PTest;
import org.eclipse.nebula.widgets.grid.Grid;
import org.eclipse.nebula.widgets.grid.GridColumn;
import org.eclipse.nebula.widgets.grid.GridItem;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
import org.mockito.Matchers;
import org.mockito.Mockito;

/**
 * Plugin Test for Grid Table.
 *
 * Uses two different data sets:
 * 1) SimpleDataSet, consist of three members of the same type (RegisteredUser)
 * * which have three fields each: name, isActive, joinDate
 * 2) ComplexDataSet, consist of different member types (RegisteredUser, AdminUser, Bot)
 * * which have one unique field each: login, executionInterval, createdBy
 *
 * @author Mat Hansen <mhansen@eclipsesource.com>
 *
 */
@SuppressWarnings("restriction")
@RunWith(Parameterized.class)
public class GridControlRenderer_PTest extends AbstractControl_PTest<VTableControl> {

	private DefaultRealm realm;

	private static final String MEMBER1_NAME = "Kliver Oahn";
	private static final String MEMBER2_NAME = "Branz Feckenbauer";
	private static final String MEMBER3_NAME = "Vudi Roeller";

	private static final Map<String, EClass> MEMBERS;
	static {

		final Map<String, EClass> tmp = new LinkedHashMap<String, EClass>();
		tmp.put(MEMBER1_NAME, AuditPackage.eINSTANCE.getRegisteredUser());
		tmp.put(MEMBER2_NAME, AuditPackage.eINSTANCE.getAdminUser());
		tmp.put(MEMBER3_NAME, AuditPackage.eINSTANCE.getBot());
		MEMBERS = Collections.unmodifiableMap(tmp);
	}

	private int expectedRows = -1;
	private int expectedColumns = -1;

	public enum DataSet {
		Simple, Complex
	}

	// BEGIN COMPLEX CODE
	// Field must be public for JUnit's @Parameter to work: https://github.com/junit-team/junit4/pull/737
	@Parameter
	public DataSet dataset;
	// END COMPLEX CODE

	@Parameters(name = "{0}")
	public static DataSet[] data() {
		return DataSet.values();
	}

	@Before
	public void before() throws DatabindingFailedException {
		realm = new DefaultRealm();
		final ReportService reportService = mock(ReportService.class);

		setDatabindingService(mock(EMFFormsDatabindingEMF.class));
		setLabelProvider(mock(EMFFormsLabelProvider.class));
		setTemplateProvider(mock(VTViewTemplateProvider.class));

		final EMFFormsEditSupport editSupport = mock(EMFFormsEditSupport.class);
		final EStructuralFeatureValueConverterService converterService = mock(
			EStructuralFeatureValueConverterService.class);
		final ImageRegistryService imageRegistryService = mock(ImageRegistryService.class);
		final EMFFormsLocalizationService localizationService = mock(EMFFormsLocalizationService.class);

		setup();

		setRenderer(new GridControlSWTRenderer(
			getvControl(), getContext(), reportService,
			(EMFFormsDatabindingEMF) getDatabindingService(),
			getLabelProvider(), getTemplateProvider(), imageRegistryService, editSupport, converterService,
			localizationService));

		getRenderer().init();
	}

	@After
	public void testTearDown() {
		realm.dispose();
		dispose();
	}

	@Override
	protected void setup() throws DatabindingFailedException {
		setvControl(Mockito.mock(VTableControl.class));
		mockControl();
		setContext(Mockito.mock(ViewModelContext.class));
		when(getContext().getDomainModel()).thenReturn(mock(EObject.class));
		setShell(new Shell(Display.getDefault(), SWT.NONE));

		final IObservableValue testDescription = Observables.constantObservableValue("test-description", String.class);
		final IObservableValue testDisplayName = Observables.constantObservableValue("test-displayname", String.class);
try { when(getLabelProvider().getDisplayName(any(VDomainModelReference.class), any(EObject.class))).thenReturn( Observables.constantObservableValue("antiException", String.class)); setMockLabelAlignment(LabelAlignment.LEFT); when(getLabelProvider().getDescription(any(VDomainModelReference.class), any(EObject.class))).thenReturn( testDescription); when(getLabelProvider().getDescription(any(VDomainModelReference.class), any(EClass.class))).thenReturn( testDescription); when(getLabelProvider().getDisplayName(any(VDomainModelReference.class), any(EObject.class))).thenReturn( testDisplayName); when(getLabelProvider().getDisplayName(any(VDomainModelReference.class), any(EClass.class))).thenReturn( testDisplayName); } catch (final NoLabelFoundException ex) { Assert.fail(ex.getMessage()); } when(getvControl().getColumnConfigurations()) .thenReturn(new BasicEList<VTableColumnConfiguration>()); } @Override protected void mockControl() throws DatabindingFailedException { final TestObservableValue mockedObservableValue = mock(TestObservableValue.class); when(mockedObservableValue.getRealm()).thenReturn(realm); final EObject mockedEObject = mock(EObject.class); when(mockedEObject.eIsSet(any(EStructuralFeature.class))).thenReturn(true); when(mockedObservableValue.getObserved()).thenReturn(mockedEObject); final EStructuralFeature mockedEStructuralFeature = mock(EStructuralFeature.class); when(mockedEStructuralFeature.isUnsettable()).thenReturn(false); when(mockedObservableValue.getValueType()).thenReturn(mockedEStructuralFeature); when(getDatabindingService().getObservableValue(any(VDomainModelReference.class), any(EObject.class))) .thenReturn( mockedObservableValue); final EStructuralFeature structuralFeature = mock(EStructuralFeature.class); when(structuralFeature.isChangeable()).thenReturn(true); final IEMFValueProperty valueProperty = mock(IEMFValueProperty.class); when(valueProperty.getValueType()).thenReturn(structuralFeature); when(getDatabindingService().getValueProperty(any(VDomainModelReference.class), any(EObject.class))).thenReturn( valueProperty); when(getvControl().getColumnConfigurations()) .thenReturn(new BasicEList<VTableColumnConfiguration>()); } private void mockDataset() throws DatabindingFailedException { switch (dataset) { case Simple: mockDataSetSimple(); break; case Complex: mockDataSetComplex(); break; default: throw new IllegalArgumentException("Unsupported dataset"); } } /** * Provide a simple data set which has no abstract types. */ protected void mockDataSetSimple() throws DatabindingFailedException { final Organization org = AuditFactory.eINSTANCE.createOrganization(); // add members for (final String memberName : MEMBERS.keySet()) { final Member member = AuditFactory.eINSTANCE.createRegisteredUser(); member.setName(memberName); org.getMembers().add(member); mockSetting(mock(Setting.class), member, AuditPackage.eINSTANCE.getMember_Name()); } final WritableList<Member> memberList = new WritableList<Member>(org.getMembers(), AuditPackage.eINSTANCE.getOrganization_Members()); when(getDatabindingService().getObservableList(any(VDomainModelReference.class), any(EObject.class))) .thenReturn( memberList); final Setting memberSetting = mock(Setting.class); mockSetting(memberSetting, org, AuditPackage.eINSTANCE.getOrganization_Members()); final VTableDomainModelReference tableDomainModelReference = VTableFactory.eINSTANCE .createTableDomainModelReference(); tableDomainModelReference.setDomainModelEFeature(AuditPackage.eINSTANCE.getOrganization_Members()); // add three columns for (final EStructuralFeature eStructuralFeature : Arrays.asList( AuditPackage.eINSTANCE.getMember_Name(), AuditPackage.eINSTANCE.getMember_IsActive(), AuditPackage.eINSTANCE.getMember_JoinDate() // )) { final VFeaturePathDomainModelReference dmr = // VViewFactory.eINSTANCE.createFeaturePathDomainModelReference(); dmr.setDomainModelEFeature(eStructuralFeature); tableDomainModelReference.getColumnDomainModelReferences().add(dmr); mockColumnFeature(dmr); } when(((EMFFormsDatabindingEMF) getDatabindingService()) .getSetting(any(VDomainModelReference.class), any(EObject.class))) .thenReturn(memberSetting); when(getvControl().getDomainModelReference()).thenReturn( tableDomainModelReference); expectedRows = MEMBERS.size(); expectedColumns = 3; } protected void mockDataSetComplex() throws DatabindingFailedException { final Organization org = AuditFactory.eINSTANCE.createOrganization(); // add three players for (final Entry<String, EClass> m : MEMBERS.entrySet()) { final String name = m.getKey(); final Member member = (Member) AuditFactory.eINSTANCE.create(m.getValue()); member.setName(name); if (RegisteredUser.class.isInstance(member)) { // will include MEMBER1 and MEMBER2, as MEMBER3 is a Bot final RegisteredUser user = RegisteredUser.class.cast(member); user.setLogin(name.toLowerCase().replaceAll(" ", "")); } org.getMembers().add(member); mockSetting(mock(Setting.class), member, AuditPackage.eINSTANCE.getMember_Name()); } final WritableList<Member> memberList = new WritableList<Member>(org.getMembers(), AuditPackage.eINSTANCE.getOrganization_Members()); when(getDatabindingService().getObservableList(any(VDomainModelReference.class), any(EObject.class))) .thenReturn( memberList); final Setting memberSetting = mock(Setting.class); mockSetting(memberSetting, org, AuditPackage.eINSTANCE.getOrganization_Members()); final VTableDomainModelReference tableDomainModelReference = VTableFactory.eINSTANCE .createTableDomainModelReference(); tableDomainModelReference.setDomainModelEFeature(AuditPackage.eINSTANCE.getOrganization_Members()); // add three columns for (final EStructuralFeature eStructuralFeature : Arrays.asList( AuditPackage.eINSTANCE.getMember_Name(), AuditPackage.eINSTANCE.getMember_IsActive(), AuditPackage.eINSTANCE.getMember_JoinDate() // )) { final VFeaturePathDomainModelReference dmr = // VViewFactory.eINSTANCE.createFeaturePathDomainModelReference(); dmr.setDomainModelEFeature(eStructuralFeature); tableDomainModelReference.getColumnDomainModelReferences().add(dmr); mockColumnFeature(dmr); } for (final EStructuralFeature eStructuralFeature : Arrays.asList( AuditPackage.eINSTANCE.getRegisteredUser_Login(), AuditPackage.eINSTANCE.getBot_ExecutionIntervalSeconds(), AuditPackage.eINSTANCE.getAdminUser_CreatedBy() // )) { final VFeaturePathDomainModelReference dmr = // VViewFactory.eINSTANCE.createFeaturePathDomainModelReference(); dmr.setDomainModelEFeature(eStructuralFeature); tableDomainModelReference.getColumnDomainModelReferences().add(dmr); mockColumnFeature(dmr); } when(((EMFFormsDatabindingEMF) getDatabindingService()) .getSetting(any(VDomainModelReference.class), any(EObject.class))) .thenReturn(memberSetting); when(getvControl().getDomainModelReference()).thenReturn( tableDomainModelReference); expectedRows = MEMBERS.size(); expectedColumns = 6; } /** * @param dmr * @throws DatabindingFailedException */ private void mockColumnFeature(final VFeaturePathDomainModelReference dmr) throws DatabindingFailedException { when(EMFFormsDatabindingEMF.class.cast(getDatabindingService()) .getValueProperty(Matchers.argThat(new BaseMatcher<VDomainModelReference>() { @Override public boolean matches(Object item) { if (item == null) { return false; } final VFeaturePathDomainModelReference cast = VFeaturePathDomainModelReference.class.cast(item); return cast.getDomainModelEFeature() == dmr.getDomainModelEFeature(); } @Override public void describeTo(Description description) { } }), any(EClass.class), any(EditingDomain.class))) .thenReturn(new EMFValuePropertyDecorator( new EMFValueProperty(dmr.getDomainModelEFeature()), dmr.getDomainModelEFeature())); } /** * @param setting * @param player_Name * @throws DatabindingFailedException */ private void mockSetting(final Setting setting, final EObject eObject, final EStructuralFeature eStructuralFeature) throws DatabindingFailedException { when(setting.getEObject()).thenReturn(eObject); when(setting.getEStructuralFeature()).thenReturn(eStructuralFeature); } private void assertControl(Control tableViewerComposite) { assertTrue(AbstractTableViewerComposite.class.isInstance(tableViewerComposite)); final Control gridComposite = Composite.class.cast(tableViewerComposite).getChildren()[0]; final Control grid = Composite.class.cast(Composite.class.cast(gridComposite).getChildren()[1]) .getChildren()[0]; assertTrue(Grid.class.isInstance(grid)); } private Grid getGrid(Control tableViewerComposite) { final Control gridComposite = Composite.class.cast(tableViewerComposite).getChildren()[0]; return (Grid) Composite.class.cast(Composite.class.cast(gridComposite).getChildren()[1]) .getChildren()[0]; } private ColumnConfiguration extractGridColumnConfigByIndex(Grid grid, int i) { final GridColumn colum = grid.getColumn(i); final Object data = colum.getData(ColumnConfiguration.ID); assertTrue(ColumnConfiguration.class.isInstance(data)); final ColumnConfiguration columnConfiguration = ColumnConfiguration.class.cast(data); return columnConfiguration; } @Test public void testColumnHideShow() throws DatabindingFailedException, NoRendererFoundException, NoPropertyDescriptorFoundExeption { mockDataset(); final Control rendered = renderControl(new SWTGridCell(0, 2, getRenderer())); assertControl(rendered); final GridTableViewerComposite tableViewerComposite = (GridTableViewerComposite) rendered; assertTrue(tableViewerComposite.getEnabledFeatures().contains(TableConfiguration.FEATURE_COLUMN_HIDE_SHOW)); final Grid grid = getGrid(rendered); assertEquals(expectedColumns + 1, grid.getColumns().length); // columns defined by mockDataset() // +1 for validation column final GridColumn nameColumn = grid.getColumn(1); assertTrue(nameColumn.isVisible()); final Object data = nameColumn.getData(ColumnConfiguration.ID); assertTrue(ColumnConfiguration.class.isInstance(data)); final ColumnConfiguration columnConfiguration = extractGridColumnConfigByIndex(grid, 1); // name column assertTrue("Feature not enabled/supported. Check ColumnConfiguration.FEATURES?", columnConfiguration.getEnabledFeatures() .contains(ColumnConfiguration.FEATURE_COLUMN_HIDE_SHOW)); columnConfiguration.visible().setValue(Boolean.FALSE); assertFalse(nameColumn.isVisible()); columnConfiguration.visible().resetToDefault(); assertTrue(nameColumn.isVisible()); // TODO: check context menu items } @Test public void testColumnFilter() throws DatabindingFailedException, NoRendererFoundException, NoPropertyDescriptorFoundExeption { mockDataset(); final Control rendered = renderControl(new SWTGridCell(0, 2, getRenderer())); assertControl(rendered); final GridTableViewerComposite tableViewerComposite = (GridTableViewerComposite) rendered; assertTrue(tableViewerComposite.getEnabledFeatures().contains(TableConfiguration.FEATURE_COLUMN_FILTER)); final Grid grid = getGrid(rendered); final ColumnConfiguration columnConfiguration = extractGridColumnConfigByIndex(grid, DataSet.Simple.equals(dataset) ? 1 : 4); // name or login column assertTrue("Feature not enabled/supported. Check ColumnConfiguration.FEATURES?", columnConfiguration.getEnabledFeatures() .contains(ColumnConfiguration.FEATURE_COLUMN_FILTER)); assertEquals(expectedRows, countItems(grid)); // 3 players/rows defined in mockSampleDataSet() /* * test filtering */ assertFilterMenuChecked(tableViewerComposite, null); tableViewerComposite.setFilteringMode(TableConfiguration.FEATURE_COLUMN_FILTER); assertThat("Filter control not showing", columnConfiguration.showFilterControl().getValue(), is(true)); assertFilterMenuChecked(tableViewerComposite, Messages.GridTableViewerComposite_toggleFilterControlsAction); columnConfiguration.matchFilter().setValue("er"); switch (dataset) { case Simple: assertEquals(3, countVisible(grid)); break; default: // complex case, has only two logins (a bot doesn't have one) assertEquals(2, countVisible(grid)); } columnConfiguration.matchFilter().setValue("foo"); assertEquals(0, countVisible(grid)); // double check, that extending a filter which lead to an empty result still created an empty result columnConfiguration.matchFilter().setValue("foo2"); assertEquals(0, countVisible(grid)); columnConfiguration.matchFilter().resetToDefault(); assertEquals(expectedRows, countVisible(grid)); columnConfiguration.matchFilter().setValue("Kliver"); assertEquals(1, countVisible(grid)); columnConfiguration.matchFilter().resetToDefault(); columnConfiguration.matchFilter().setValue("branzfeckenbauer"); switch (dataset) { case Simple: assertEquals(0, countVisible(grid)); break; default: // complex case, there is exactly one matching login assertEquals(1, countVisible(grid)); } /* * test clearing of filter */ tableViewerComposite.setFilteringMode(null); assertThat("Filter control still showing", columnConfiguration.showFilterControl().getValue(), is(false)); assertFilterMenuChecked(tableViewerComposite, null); assertEquals(3, countItems(grid)); assertEquals(3, countVisible(grid)); } /** * Assert that the indicated filtering item in the context menu is checked and no other. * * @param composite the grid composite * @param label the label of the menu item that should be checked, or {@code null} if * in fact no filtering item should be checked */ void assertFilterMenuChecked(GridTableViewerComposite composite, String label) { final Control grid = composite.getTableViewer().getControl(); final Menu menu = grid.getMenu(); final Event event = new Event(); // Some menu actions are not defined if the mouse is not over a grid cell final Rectangle cell = allItems(composite.getTableViewer().getGrid())[0].getBounds(1); event.type = SWT.MouseMove; event.x = cell.x + cell.width / 2; event.y = cell.y + cell.height / 2; grid.notifyListeners(SWT.MouseMove, event); event.type = SWT.Show; event.widget = menu; menu.notifyListeners(SWT.Show, event); boolean asserted = false; try { for (final MenuItem next : menu.getItems()) { if (next.getText().contains("filter")) { assertThat("Wrong check state", next.getSelection(), is(label != null && label.equals(next.getText()))); asserted = true; } } } finally { event.type = SWT.Hide; menu.notifyListeners(SWT.Hide, event); } assertThat("No context-menu items found to assert their check state", asserted, is(true)); } @Test public void testColumnFilterWithColumnHideShow() throws DatabindingFailedException, NoRendererFoundException, NoPropertyDescriptorFoundExeption { mockDataset(); final Control rendered = renderControl(new SWTGridCell(0, 2, getRenderer())); final Grid grid = getGrid(rendered); final GridColumn nameColumn = grid.getColumn(1); // name column final Object data = nameColumn.getData(ColumnConfiguration.ID); final ColumnConfiguration columnConfiguration = ColumnConfiguration.class.cast(data); assertTrue("Feature not enabled/supported. Check ColumnConfiguration.FEATURES?", columnConfiguration.getEnabledFeatures() .contains(ColumnConfiguration.FEATURE_COLUMN_HIDE_SHOW)); assertTrue("Feature not enabled/supported. Check ColumnConfiguration.FEATURES?", columnConfiguration.getEnabledFeatures() .contains(ColumnConfiguration.FEATURE_COLUMN_FILTER)); /* * test clearing of filter */ final GridTableViewerComposite tableViewerComposite = (GridTableViewerComposite) rendered; tableViewerComposite.setFilteringMode(TableConfiguration.FEATURE_COLUMN_FILTER); assertThat("Filter control not showing", columnConfiguration.showFilterControl().getValue(), is(true)); columnConfiguration.matchFilter().setValue("foo"); assertEquals(0, countVisible(grid)); tableViewerComposite.setFilteringMode(null); columnConfiguration.visible().setValue(Boolean.FALSE); assertEquals(expectedRows, countVisible(grid)); /* * test for Gerrit #110529 (filter again after filters have been hidden) */ tableViewerComposite.setFilteringMode(TableConfiguration.FEATURE_COLUMN_FILTER); columnConfiguration.visible().setValue(Boolean.TRUE); assertThat("Filter control not showing", columnConfiguration.showFilterControl().getValue(), is(true)); columnConfiguration.matchFilter().setValue("bar"); assertEquals(0, countVisible(grid)); columnConfiguration.matchFilter().resetToDefault(); tableViewerComposite.setFilteringMode(null); assertThat("Filter control still showing", columnConfiguration.showFilterControl().getValue(), is(false)); // will result in a NPE without Gerrit #110529 columnConfiguration.visible().setValue(Boolean.FALSE); assertEquals(expectedRows, countVisible(grid)); } @Test public void testColumnRegexFilter() throws DatabindingFailedException, NoRendererFoundException, NoPropertyDescriptorFoundExeption { mockDataset(); final Control rendered = renderControl(new SWTGridCell(0, 2, getRenderer())); assertControl(rendered); final GridTableViewerComposite tableViewerComposite = (GridTableViewerComposite) rendered; assertThat("Bad table features configuration", tableViewerComposite.getEnabledFeatures(), hasItem(TableConfiguration.FEATURE_COLUMN_REGEX_FILTER)); final Grid grid = getGrid(rendered); final ColumnConfiguration columnConfiguration = extractGridColumnConfigByIndex(grid, DataSet.Simple.equals(dataset) ? 1 : 4); // name or login column assertThat("Feature not enabled/supported. Check ColumnConfiguration.FEATURES?", columnConfiguration.getEnabledFeatures(), hasItem(ColumnConfiguration.FEATURE_COLUMN_REGEX_FILTER)); assertThat("Wrong number of rows filtered", countItems(grid), is(expectedRows)); // 3 players/rows defined in mockSampleDataSet() /* * test filtering */ tableViewerComposite.setFilteringMode(TableConfiguration.FEATURE_COLUMN_REGEX_FILTER); assertFilterMenuChecked(tableViewerComposite, Messages.GridTableViewerComposite_toggleRegexFilterControlsAction); columnConfiguration.matchFilter().setValue("er"); switch (dataset) { case Simple: assertThat("No rows should be filtered", countVisible(grid), is(3)); break; default: // complex case, has only two logins (a bot doesn't have one) assertThat("One row should be filtered", countVisible(grid), is(2)); } // Match only 'er' at the end of the string columnConfiguration.matchFilter().setValue("er$"); switch (dataset) { case Simple: assertThat("One row should be filtered", countVisible(grid), is(2)); break; default: // complex case, has only two logins (a bot doesn't have one) assertThat("Two rows should be filtered", countVisible(grid), is(1)); } columnConfiguration.matchFilter().setValue("foo"); assertThat("All rows should be filtered", countVisible(grid), is(0)); // double check, that extending a filter which lead to an empty result still created an empty result columnConfiguration.matchFilter().setValue("foo2"); assertThat("All rows should be filtered", countVisible(grid), is(0)); // but an invalid regex doesn't filter anything (user should see examples in the grid to // be guides in formulating the regex) columnConfiguration.matchFilter().setValue("([a].*\\1"); assertThat("No rows should be filtered", countVisible(grid), is(expectedRows)); columnConfiguration.matchFilter().setValue("([a]).*\\1"); switch (dataset) { case Simple: assertThat("Two rows should be filtered", countVisible(grid), is(1)); break; default: // complex case, where the bot hasn't a login assertThat("Two rows should be filtered", countVisible(grid), is(1)); } columnConfiguration.matchFilter().setValue("([ae]).*\\1"); switch (dataset) { case Simple: assertThat("One row should be filtered", countVisible(grid), is(2)); break; default: // complex case, where the bot hasn't a login assertThat("Two rows should be filtered", countVisible(grid), is(1)); } columnConfiguration.matchFilter().resetToDefault(); assertThat("No rows should be filtered", countVisible(grid), is(expectedRows)); columnConfiguration.matchFilter().setValue("branzfeckenbauer"); switch (dataset) { case Simple: assertThat("All rows should be filtered", countVisible(grid), is(0)); break; default: // complex case, there is exactly one matching login assertThat("Two rows should be filtered", countVisible(grid), is(1)); } /* * test clearing of filter */ tableViewerComposite.setFilteringMode(null); assertFilterMenuChecked(tableViewerComposite, null); assertThat("Filter control still showing", columnConfiguration.showFilterControl().getValue(), is(false)); assertThat("Wrong number of items in the grid", countItems(grid), is(3)); assertThat("No rows should be filtered", countVisible(grid), is(3)); } private GridItem[] filterVisible(Grid grid) { final List<GridItem> visibleItems = new ArrayList<GridItem>(); for (final GridItem item : allItems(grid)) { if (!item.isVisible()) { continue; } visibleItems.add(item); } return visibleItems.toArray(new GridItem[] {}); } private GridItem[] allItems(Grid grid) { SWTTestUtil.waitForUIThread(); // The table refresh is asynchronous return grid.getItems(); } private int countItems(Grid grid) { return allItems(grid).length; } private int countVisible(Grid grid) { return filterVisible(grid).length; } @Override public void renderValidationIconLabelAlignmentLeft() throws NoRendererFoundException, NoPropertyDescriptorFoundExeption { } @Override public void renderValidationIconLabelAlignmentNone() throws NoRendererFoundException, NoPropertyDescriptorFoundExeption { } @Override public void testGridDescriptionLabelAlignmentLeft() { } @Override public void testGridDescriptionLabelAlignmentNone() { } @Test public void testEffectivelyReadOnlyHidesAddRemoveButtons() throws DatabindingFailedException, NoRendererFoundException, NoPropertyDescriptorFoundExeption { mockDataset(); when(getvControl().isAddRemoveDisabled()).thenReturn(false); when(getvControl().isEffectivelyEnabled()).thenReturn(true); when(getvControl().isEffectivelyReadonly()).thenReturn(true); when(getvControl().isVisible()).thenReturn(true); getShell().open(); final Control rendered = renderControl(new SWTGridCell(0, 2, getRenderer())); getRenderer().finalizeRendering(getShell()); assertControl(rendered); final GridTableViewerComposite tableViewerComposite = (GridTableViewerComposite) rendered; final Composite gridComposite = Composite.class.cast(tableViewerComposite.getChildren()[0]); final Composite buttonComposite = (Composite) Composite.class.cast(gridComposite.getChildren()[0]) .getChildren()[2]; // there should be no buttons in case the table is read-only assertEquals(0, buttonComposite.getChildren().length); final GridControlSWTRenderer swtRenderer = GridControlSWTRenderer.class.cast(getRenderer()); final Optional<Control> addRowButton = swtRenderer.getControlForAction(AddRowAction.ACTION_ID); final Optional<Control> removeRowButton = swtRenderer.getControlForAction(RemoveRowAction.ACTION_ID); final Optional<Control> duplicateRowButton = swtRenderer.getControlForAction(DuplicateRowAction.ACTION_ID); assertFalse(addRowButton.isPresent()); assertFalse(removeRowButton.isPresent()); assertFalse(duplicateRowButton.isPresent()); } @Test public void testActionKeyBindings() throws DatabindingFailedException, NoRendererFoundException, NoPropertyDescriptorFoundExeption { mockDataset(); final Set<VTStyleProperty> properties = new LinkedHashSet<VTStyleProperty>(); final VTKeyBindings keyBindings = VTKeybindingFactory.eINSTANCE.createKeyBindings(); addKeyBinding(keyBindings, AddRowAction.ACTION_ID, "M1+e"); properties.add(keyBindings); final VTViewTemplateProvider viewTemplateProvider = mock(VTViewTemplateProvider.class); when(viewTemplateProvider.getStyleProperties(getvControl(), getContext())) .thenReturn(properties); setTemplateProvider(viewTemplateProvider); getShell().open(); final Control rendered = renderControl(new SWTGridCell(0, 2, getRenderer())); getRenderer().finalizeRendering(getShell()); assertControl(rendered); final GridTableViewerComposite tableViewerComposite = (GridTableViewerComposite) rendered; final Composite gridComposite = Composite.class.cast(tableViewerComposite.getChildren()[0]); final Composite buttonComposite = (Composite) Composite.class.cast(gridComposite.getChildren()[0]) .getChildren()[2]; final GridControlSWTRenderer swtRenderer = GridControlSWTRenderer.class.cast(getRenderer()); } private void addKeyBinding(VTKeyBindings bindings, String actionId, String sequence) { final VTKeyBinding binding = VTKeybindingFactory.eINSTANCE.createKeyBinding(); binding.setId(actionId); binding.setKeySequence(sequence); bindings.getBindings().add(binding); } }