/******************************************************************************* * Copyright (c) 2015, 2016 itemis AG and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Matthias Wienand (itemis AG) - initial API and implementation * *******************************************************************************/ package org.eclipse.gef.mvc.tests.fx; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; import org.eclipse.gef.common.adapt.AdapterKey; import org.eclipse.gef.mvc.fx.MvcFxModule; import org.eclipse.gef.mvc.fx.behaviors.ContentBehavior; import org.eclipse.gef.mvc.fx.domain.IDomain; import org.eclipse.gef.mvc.fx.parts.IContentPart; import org.eclipse.gef.mvc.fx.parts.IContentPartFactory; import org.eclipse.gef.mvc.fx.viewer.IViewer; import org.eclipse.gef.mvc.tests.fx.rules.FXNonApplicationThreadRule; import org.eclipse.gef.mvc.tests.fx.stubs.Cell; import org.eclipse.gef.mvc.tests.fx.stubs.CellContentPartFactory; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import com.google.inject.Guice; import javafx.scene.Node; /** * Tests for the {@link ContentBehavior}. * * @author wienand * */ public class ContentSynchronizationTests { private static IDomain domain; private static IViewer viewer; @Rule public FXNonApplicationThreadRule ctx = new FXNonApplicationThreadRule(); @Before public void activate() throws Throwable { if (domain == null) { domain = Guice.createInjector(new MvcFxModule() { @Override protected void configure() { binder().bind(IContentPartFactory.class).to(CellContentPartFactory.class); super.configure(); } }).getInstance(IDomain.class); viewer = domain.getAdapter(AdapterKey.get(IViewer.class, IDomain.CONTENT_VIEWER_ROLE)); ctx.createScene(viewer.getCanvas(), 100, 100); } ctx.runAndWait(() -> { domain.activate(); }); } @After public void deactivate() throws Throwable { ctx.runAndWait(() -> { viewer.getContents().clear(); domain.deactivate(); }); } /** * This scenario tests if the synchronization works correctly, when the * contents are replaced with a previously nested content element. */ @Test public void replaceContentsWithNested() throws Throwable { // define data List<Cell> firstContents = Arrays.asList(new Cell("0", new Cell("1"))); List<Cell> secondContents = Arrays.asList(firstContents.get(0).children.get(0)); // no parts in the beginning Map<Object, IContentPart<? extends Node>> contentPartMap = viewer.getContentPartMap(); assertNull(contentPartMap.get(firstContents.get(0))); assertNull(contentPartMap.get(secondContents.get(0))); ctx.runAndWait(() -> { viewer.getContents().setAll(firstContents); }); // both parts created now assertNotNull(contentPartMap.get(firstContents.get(0))); assertNotNull(contentPartMap.get(secondContents.get(0))); ctx.runAndWait(() -> { viewer.getContents().setAll(secondContents); }); // first part removed now assertNull(contentPartMap.get(firstContents.get(0))); assertNotNull(contentPartMap.get(secondContents.get(0))); } /** * This scenario tests if the synchronization correctly identifies contents * for which parts are already created in other places of the content part * hierarchy. */ @Test public void sameContentAtDifferentPosition() throws Throwable { // create tree B Cell b = new Cell("1"); // create tree A with {left = B, right = B} List<Cell> sameContents = Arrays.asList(new Cell("0", b, b)); AtomicReference<IllegalStateException> exceptionRef = new AtomicReference<>(); ctx.runAndWait(() -> { try { viewer.getContents().setAll(sameContents); } catch (IllegalStateException e) { exceptionRef.set(e); } }); // check if the exception is thrown when the contents are set assertNotNull(exceptionRef.get()); assertEquals( "Located a ContentPart which controls the same (or an equal) content element but is already bound to a parent. A content element may only be controlled by a single ContentPart.", exceptionRef.get().getMessage()); } }