Skip to content

Content of file TreeRevealProvider_PTest.java

/*******************************************************************************
 * Copyright (c) 2019 Christian W. Damus 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:
 * Christian W. Damus - initial API and implementation
 ******************************************************************************/
package org.eclipse.emf.ecp.view.treemasterdetail.ui.swt.internal;

import static org.eclipse.emf.ecp.view.test.common.spi.EMFMocking.eMock;
import static org.eclipse.emf.ecp.view.test.common.spi.EMFMocking.withESettings;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyVararg;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.util.Arrays;

import org.eclipse.emf.common.command.BasicCommandStack;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.ETypedElement;
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.ResourceImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecp.test.common.DefaultRealm;
import org.eclipse.emf.ecp.view.spi.context.ViewModelContext;
import org.eclipse.emf.ecp.view.spi.context.ViewModelService;
import org.eclipse.emf.ecp.view.spi.model.VElement;
import org.eclipse.emf.ecp.view.spi.model.VView;
import org.eclipse.emf.ecp.view.spi.model.VViewFactory;
import org.eclipse.emf.ecp.view.spi.swt.services.DefaultSelectionProviderService;
import org.eclipse.emf.ecp.view.spi.swt.services.ECPSelectionProviderService;
import org.eclipse.emf.ecp.view.test.common.spi.EMFFormsRevealServiceFixture;
import org.eclipse.emf.ecp.view.test.common.spi.EMFFormsViewContextFixture.DomainModel;
import org.eclipse.emf.ecp.view.test.common.spi.EMFFormsViewContextFixture.ViewModel;
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.ecp.view.treemasterdetail.model.VTreeMasterDetail;
import org.eclipse.emf.ecp.view.treemasterdetail.model.VTreeMasterDetailFactory;
import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
import org.eclipse.emf.edit.provider.ReflectiveItemProviderAdapterFactory;
import org.eclipse.emfforms.bazaar.Bid;
import org.eclipse.emfforms.bazaar.Create;
import org.eclipse.emfforms.spi.core.services.reveal.EMFFormsRevealProvider;
import org.eclipse.emfforms.spi.core.services.reveal.Reveal;
import org.eclipse.emfforms.spi.core.services.reveal.RevealHelper;
import org.eclipse.emfforms.spi.core.services.reveal.RevealStep;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;

/**
 * Tests covering the {@link TreeRevealProvider} class.
 */
@SuppressWarnings("nls")
public class TreeRevealProvider_PTest {

	@ViewModel
	private final VView viewModel = VViewFactory.eINSTANCE.createView();

	@DomainModel
	private EObject rootObject;

	private EObject class1;
	private EObject class2;

	private EObject att1;
	private EObject att2;

	private EObject detailObj;

	private VTreeMasterDetail treeMD;
@Rule public final TestRule realm = DefaultRealm.rule(); @Rule public final EMFFormsRevealServiceFixture<ViewModelContext> fixture = EMFFormsRevealServiceFixture.create( ViewModelContext.class, this); private Shell shell; /** * Initializes me. */ public TreeRevealProvider_PTest() { super(); createDomainModel(); } /** * Test revealing an object that is presented and selectable in the tree. */ @Test public void revealInTree() { final Runnable reveal = mock(Runnable.class); fixture.addRevealProvider(new ViewRevealer(reveal)); render(); fixture.reveal(att1); SWTTestUtil.waitForUIThread(); verify(reveal).run(); final Tree tree = SWTTestUtil.findControl(shell, 0, Tree.class); final TreeItem[] selection = tree.getSelection(); assertThat("No tree selection", selection.length, is(1)); assertThat("Tree selection incorrect", selection[0].getData(), is(att1)); } /** * Test revealing an object that is presented only in the detail view of an object * that is selectable in the tree. */ @Test public void revealInDetail() { final Runnable reveal = mock(Runnable.class); fixture.addRevealProvider(new ViewRevealer(mock(Runnable.class))); fixture.addRevealProvider(new DetailRevealer(reveal)); render(); fixture.reveal(detailObj); SWTTestUtil.waitForUIThread(); verify(reveal).run(); final Tree tree = SWTTestUtil.findControl(shell, 0, Tree.class); final TreeItem[] selection = tree.getSelection(); assertThat("No tree selection", selection.length, is(1)); assertThat("Tree selection incorrect", selection[0].getData(), is(att2)); } // // Test framework // @Before public void createViewModel() { treeMD = VTreeMasterDetailFactory.eINSTANCE.createTreeMasterDetail(); viewModel.getChildren().add(treeMD); // The renderer needs this fixture.putService(ECPSelectionProviderService.class, new DefaultSelectionProviderService()); } private void createDomainModel() { // Tiny dynamic schema to make sure that we get a generated view model // for the details (for predictability) final EPackage pkg = EcoreFactory.eINSTANCE.createEPackage(); pkg.setName("pkg"); pkg.setNsPrefix("pkg"); pkg.setNsURI("fake:pkg"); final EClass namedElement = EcoreFactory.eINSTANCE.createEClass(); namedElement.setName("NamedElement"); pkg.getEClassifiers().add(namedElement); final EAttribute name = EcoreFactory.eINSTANCE.createEAttribute(); name.setName("name"); name.setEType(EcorePackage.Literals.ESTRING); namedElement.getEStructuralFeatures().add(name); final EReference children = EcoreFactory.eINSTANCE.createEReference(); children.setName("children"); children.setEType(namedElement); children.setContainment(true); children.setLowerBound(0); children.setUpperBound(ETypedElement.UNBOUNDED_MULTIPLICITY); namedElement.getEStructuralFeatures().add(children); // Create the model that will show in the tree rootObject = EcoreUtil.create(namedElement); rootObject.eSet(name, "pkg"); class1 = EcoreUtil.create(namedElement); class1.eSet(name, "Class1"); class2 = EcoreUtil.create(namedElement); class2.eSet(name, "Class2"); rootObject.eSet(children, Arrays.asList(class1, class2)); att1 = EcoreUtil.create(namedElement); att1.eSet(name, "att1"); att2 = EcoreUtil.create(namedElement); att2.eSet(name, "att2"); class2.eSet(children, Arrays.asList(att1, att2)); // An object that isn't presented in the tree but as a detail // of an object that is in the tree detailObj = eMock(EObject.class, withESettings().eContainer(att2)); // The detail rendeering for featurees wants to find types in the resource set final Resource res = new ResourceImpl(URI.createURI("fake:resource")); res.getContents().add(rootObject); new AdapterFactoryEditingDomain(new ReflectiveItemProviderAdapterFactory(), new BasicCommandStack()).getResourceSet().getResources().add(res); } @Before public void createShell() { shell = new Shell(); } @Before public void mockChildContexts() { when(fixture.getViewContext().getChildContext(any(), any(), any(), (ViewModelService[]) anyVararg())) .then(invocation -> { final ViewModelContext result = fixture.createChildContext((VElement) invocation.getArguments()[1], "child", (VView) invocation.getArguments()[2], (EObject) invocation.getArguments()[0]); when(result.getParentContext()).thenReturn((ViewModelContext) invocation.getMock()); return result; }); } @After public void destroyShell() { shell.dispose(); shell = null; } void render() { SWTViewTestHelper.render(fixture.getViewContext(), shell); } // // Nested types // /** * A high-bidding reveal provider to make sure that we drill into the view * to find the tree, regardless of other possible contributions in the * current configuration. */ private final class ViewRevealer implements EMFFormsRevealProvider { private final Runnable reveal; ViewRevealer(Runnable reveal) { super(); this.reveal = reveal; } @Bid public Double bid(VView view) { return view == viewModel ? Double.MAX_VALUE : null; } @Create public RevealStep create(VView view, EObject model, RevealHelper helper) { return view == viewModel ? helper.drillDown(this) : RevealStep.fail(); } @Reveal private RevealStep drillDown(VView view, EObject model) { return RevealStep.reveal(view, model, reveal); } } /** * A high-bidding reveal provider to mock revealing the detail object * that is not presented in the tree. */ private final class DetailRevealer implements EMFFormsRevealProvider { private final Runnable reveal; DetailRevealer(Runnable reveal) { super(); this.reveal = reveal; } @Bid public Double bid(VView view, EObject object) { // The detail is a generated view return view != viewModel && object == detailObj ? Double.MAX_VALUE : null; } @Create public RevealStep create(VView view, EObject model) { return RevealStep.reveal(view, model, reveal); } } }