blob: e44a87b0a0b8497ee01b95a0dec7615fa004a215 [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:
* Lucas Koehler - initial API and implementation
******************************************************************************/
package org.eclipse.emf.ecp.view.spi.table.swt;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import java.util.Arrays;
import java.util.Random;
import java.util.function.Consumer;
import org.eclipse.emf.common.command.BasicCommandStack;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EcoreFactory;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecp.test.common.PerformanceClock;
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.VTableControl;
import org.eclipse.emf.ecp.view.spi.table.model.VTableDomainModelReference;
import org.eclipse.emf.ecp.view.table.test.common.TableTestUtil;
import org.eclipse.emf.ecp.view.test.common.swt.spi.DatabindingClassRunner;
import org.eclipse.emf.ecp.view.test.common.swt.spi.SWTTestUtil;
import org.eclipse.emf.ecp.view.test.common.swt.spi.SWTViewTestHelper;
import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.provider.ReflectiveItemProviderAdapterFactory;
import org.eclipse.emfforms.spi.swt.core.EMFFormsNoRendererException;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
/**
* Performance tests for the {@link TableControlSWTRenderer}.
*
* @author Lucas Koehler
*
*/
@RunWith(DatabindingClassRunner.class)
public class TableControlSWTRendererPerformance_PTest {
private static final int SMALL_SCALE = 50;
private static final int LARGE_SCALE = 2000;
// sorting takes O(n*log n)
private static final int ITERATIONS = 8;
private static final double WORST_CASE_MULTIPLIER = 20.0;
private Shell shell;
private ComposedAdapterFactory adapterFactory;
private Resource smallResource;
private Resource largeResource;
@Before
public void init() {
shell = SWTViewTestHelper.createShell();
// Add domain element to resource with editing domain
final ResourceSetImpl rs = new ResourceSetImpl();
adapterFactory = new ComposedAdapterFactory(new AdapterFactory[] {
new ReflectiveItemProviderAdapterFactory(),
new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE) });
final AdapterFactoryEditingDomain editingDomain = new AdapterFactoryEditingDomain(
adapterFactory, new BasicCommandStack(), rs);
rs.eAdapters().add(new AdapterFactoryEditingDomain.EditingDomainProvider(editingDomain));
smallResource = rs.createResource(URI.createURI("VIRTUAL_SMALL"));
largeResource = rs.createResource(URI.createURI("VIRTUAL_BIG"));
}
@After
public void after() {
adapterFactory.dispose();
if (shell != null && !shell.isDisposed()) {
shell.dispose();
}
}
@Test
public void tableSorting_autoSortOnEdit()
throws EMFFormsNoRendererException, NoRendererFoundException, NoPropertyDescriptorFoundExeption {
// table control
final VTableControl tableControl = TableTestUtil.createTableControl();
final VTableDomainModelReference tableDMR = (VTableDomainModelReference) tableControl.getDomainModelReference();
tableDMR.setDomainModelEFeature(EcorePackage.eINSTANCE.getEClass_EAttributes());
tableDMR.getColumnDomainModelReferences().add(createDMR(EcorePackage.eINSTANCE.getENamedElement_Name()));
// render
shell.open();
test(domain -> {
Control control = null;
try {
control = SWTViewTestHelper.render(tableControl, domain, shell);
} catch (NoRendererFoundException | NoPropertyDescriptorFoundExeption | EMFFormsNoRendererException ex) {
fail("An exception occurred while rendering the table: " + ex.getMessage());
}
if (control == null) {
fail("No control was rendered");
}
final Table table = SWTTestUtil.findControl(control, 0, Table.class);
// column 0 is validation column
// select column 1 (name) and ascending sorting
SWTTestUtil.selectWidget(table.getColumns()[1]);
SWTTestUtil.waitForUIThread();
assertEquals(SWT.DOWN, table.getSortDirection()); // SWT.DOWN := ascending sorting
final EAttribute start = (EAttribute) table.getItem(0).getData();
start.setName("zzz");
final EAttribute middle = (EAttribute) table.getItem(table.getItemCount() / 2).getData();
middle.setName("aaa");
});
}
private void test(Consumer<EClass> experiment) {
final EClass smallInput = generateInput(SMALL_SCALE);
smallResource.getContents().clear();
smallResource.getContents().add(smallInput);
final EClass largeInput = generateInput(LARGE_SCALE);
largeResource.getContents().clear();
largeResource.getContents().add(largeInput);
PerformanceClock.test(ITERATIONS, WORST_CASE_MULTIPLIER, () -> smallInput, () -> largeInput, experiment);
}
private static EClass generateInput(int childCount) {
final EClass eClass = EcoreFactory.eINSTANCE.createEClass();
final Random random = new Random(System.nanoTime());
final int nameLength = 10;
for (int i = 0; i < childCount; i++) {
final char[] result = new char[nameLength];
for (int j = 0; j < nameLength; j++) {
result[j] = (char) (random.nextInt('z' - 'A') + 'A');
}
final EAttribute attribute = EcoreFactory.eINSTANCE.createEAttribute();
attribute.setEType(EcorePackage.Literals.ESTRING);
attribute.setName(new String(result));
eClass.getEStructuralFeatures().add(attribute);
}
return eClass;
}
private static VFeaturePathDomainModelReference createDMR(EAttribute attribute, EReference... refs) {
final VFeaturePathDomainModelReference dmr = VViewFactory.eINSTANCE.createFeaturePathDomainModelReference();
dmr.setDomainModelEFeature(attribute);
dmr.getDomainModelEReferencePath().addAll(Arrays.asList(refs));
return dmr;
}
}