blob: 85ce75ec04576a72e3c235141bd3f876fd1689a6 [file] [log] [blame]
/*******************************************************************************
* 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<String> testDescription = Observables.constantObservableValue("test-description",
String.class);
final IObservableValue<String> 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);
}
}