| /******************************************************************************* |
| * Copyright (c) 2009, 2010 IBM Corporation 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: |
| * IBM Corporation - initial API and implementation |
| ******************************************************************************/ |
| |
| package org.eclipse.e4.core.services.internal.context; |
| |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.List; |
| import junit.framework.TestCase; |
| import org.eclipse.e4.core.services.IDisposable; |
| import org.eclipse.e4.core.services.context.ContextChangeEvent; |
| import org.eclipse.e4.core.services.context.EclipseContextFactory; |
| import org.eclipse.e4.core.services.context.IEclipseContext; |
| import org.eclipse.e4.core.services.context.IRunAndTrack; |
| import org.eclipse.e4.core.services.context.spi.ContextFunction; |
| import org.eclipse.e4.core.services.context.spi.IContextConstants; |
| import org.eclipse.e4.core.tests.services.TestActivator; |
| |
| /** |
| * Tests for {@link org.eclipse.e4.core.services.context.IRunAndTrack}. |
| */ |
| public class RunAndTrackTest extends TestCase { |
| |
| private class ActivePartLookupFunction extends ContextFunction { |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.e4.core.services.context.spi.ContextFunction#compute( |
| * org.eclipse.e4.core.services.context.IEclipseContext, java.lang.Object[]) |
| */ |
| public Object compute(IEclipseContext context, Object[] arguments) { |
| IEclipseContext childContext = (IEclipseContext) context.getLocal(ACTIVE_CHILD); |
| if (childContext != null) { |
| return childContext.get(ACTIVE_PART); |
| } |
| return context.get(INTERNAL_LOCAL_PART); |
| } |
| |
| } |
| |
| static final String ACTIVE_CHILD = "activeChild"; |
| |
| static final String ACTIVE_PART = "activePart"; |
| |
| static final String ACTIVE_PART_ID = "activePartId"; |
| |
| static final String INTERNAL_LOCAL_PART = "localPart"; |
| |
| private List createdContexts = new ArrayList(); |
| |
| private IEclipseContext createContext(IEclipseContext parentContext, String level) { |
| IEclipseContext childContext = EclipseContextFactory.create(parentContext, null); |
| createdContexts.add(childContext); |
| childContext.set(IContextConstants.DEBUG_STRING, level); |
| return childContext; |
| } |
| |
| private IEclipseContext getGlobalContext() { |
| IEclipseContext serviceContext = EclipseContextFactory |
| .getServiceContext(TestActivator.bundleContext); |
| // global initialization and setup, usually done by workbench |
| IEclipseContext appContext = createContext(serviceContext, "globalContext"); |
| |
| appContext.set("globalContext", appContext); |
| |
| return appContext; |
| } |
| |
| private IEclipseContext[] createNextLevel(IEclipseContext parent, String prefix, int num) { |
| assertTrue(num > 0); |
| IEclipseContext[] contexts = new IEclipseContext[num]; |
| for (int i = 0; i < num; i++) { |
| contexts[i] = createContext(parent, prefix + i); |
| contexts[i].set(INTERNAL_LOCAL_PART, prefix + i); |
| } |
| parent.set(ACTIVE_CHILD, contexts[0]); |
| return contexts; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see junit.framework.TestCase#tearDown() |
| */ |
| protected void tearDown() throws Exception { |
| for (Iterator i = createdContexts.iterator(); i.hasNext();) { |
| IDisposable context = (IDisposable) i.next(); |
| context.dispose(); |
| } |
| createdContexts.clear(); |
| super.tearDown(); |
| } |
| |
| public void testActiveChain() throws Exception { |
| final IEclipseContext workbenchContext = getGlobalContext(); |
| workbenchContext.set("activePart", new ActivePartLookupFunction()); |
| final IEclipseContext[] windows = createNextLevel(workbenchContext, "window", 1); |
| createNextLevel(windows[0], "part", 2); |
| assertEquals("part0", workbenchContext.get(ACTIVE_PART)); |
| } |
| |
| public void testActiveChange() throws Exception { |
| final IEclipseContext workbenchContext = getGlobalContext(); |
| workbenchContext.set("activePart", new ActivePartLookupFunction()); |
| final IEclipseContext[] windows = createNextLevel(workbenchContext, "window", 1); |
| final IEclipseContext[] parts = createNextLevel(windows[0], "part", 2); |
| assertEquals("part0", workbenchContext.get(ACTIVE_PART)); |
| |
| windows[0].set(ACTIVE_CHILD, parts[1]); |
| assertEquals("part1", workbenchContext.get(ACTIVE_PART)); |
| } |
| |
| /** |
| * Tests that {@link org.eclipse.e4.core.services.context.ContextChangeEvent#getOldValue()} |
| * returns the correct value for various change types. |
| */ |
| public void testContextEventOldValue() { |
| final String NAME = "Name"; |
| class ContextListener implements IRunAndTrack { |
| public Object newValue; |
| public Object oldValue; |
| |
| public boolean notify(ContextChangeEvent event) { |
| oldValue = event.getOldValue(); |
| IEclipseContext eventsContext = event.getContext(); |
| newValue = eventsContext.get(NAME); |
| return true; |
| } |
| } |
| IEclipseContext context = EclipseContextFactory.create(); |
| context.set(NAME, "Value"); |
| ContextListener listener = new ContextListener(); |
| context.runAndTrack(listener, null); |
| assertEquals("Value", listener.newValue); |
| assertNull(listener.oldValue); |
| |
| // simple value change |
| context.set(NAME, "NewValue"); |
| assertEquals("Value", listener.oldValue); |
| assertEquals("NewValue", listener.newValue); |
| |
| // set value to null |
| context.set(NAME, null); |
| assertEquals("NewValue", listener.oldValue); |
| assertEquals(null, listener.newValue); |
| |
| // set from null to non-null |
| context.set(NAME, "Value"); |
| assertEquals(null, listener.oldValue); |
| assertEquals("Value", listener.newValue); |
| |
| // remove |
| context.remove(NAME); |
| assertEquals("Value", listener.oldValue); |
| assertEquals(null, listener.newValue); |
| |
| } |
| |
| /** |
| * Tests that {@link org.eclipse.e4.core.services.context.ContextChangeEvent#getOldValue()} |
| * returns the correct value for various change types. |
| */ |
| public void testContextEventType() { |
| final String NAME = "Name"; |
| class ContextListener implements IRunAndTrack { |
| int eventType; |
| |
| public boolean notify(ContextChangeEvent event) { |
| // must get a value so we aren't removed |
| eventType = event.getEventType(); |
| IEclipseContext eventsContext = event.getContext(); |
| eventsContext.get(NAME); |
| return true; |
| } |
| } |
| IEclipseContext context = EclipseContextFactory.create(); |
| ContextListener listener = new ContextListener(); |
| context.runAndTrack(listener, null); |
| assertEquals(ContextChangeEvent.INITIAL, listener.eventType); |
| |
| // add a new value |
| context.set(NAME, "Value"); |
| assertEquals(ContextChangeEvent.ADDED, listener.eventType); |
| |
| // simple value change |
| context.set(NAME, "NewValue"); |
| assertEquals(ContextChangeEvent.ADDED, listener.eventType); |
| |
| // set value to null |
| context.set(NAME, null); |
| assertEquals(ContextChangeEvent.ADDED, listener.eventType); |
| |
| // set from null to non-null |
| context.set(NAME, "Value"); |
| assertEquals(ContextChangeEvent.ADDED, listener.eventType); |
| |
| // remove |
| context.remove(NAME); |
| assertEquals(ContextChangeEvent.REMOVED, listener.eventType); |
| |
| // dispose context |
| ((IDisposable) context).dispose(); |
| assertEquals(ContextChangeEvent.DISPOSE, listener.eventType); |
| |
| } |
| |
| /** |
| * There was a failing scenario in the legacy workbench support. This captures the hierarchy and |
| * function (without any workbench level references). It should be updated when we figure out |
| * the failing scenario :-) |
| * |
| * @throws Exception |
| */ |
| public void testRunAndTrackComplex() throws Exception { |
| final IEclipseContext workbenchContext = getGlobalContext(); |
| workbenchContext.set("activePart", new ActivePartLookupFunction()); |
| final IEclipseContext[] windows = createNextLevel(workbenchContext, "window", 1); |
| windows[0].runAndTrack(new IRunAndTrack() { |
| public boolean notify(ContextChangeEvent event) { |
| final Object part = windows[0].get(ACTIVE_PART); |
| windows[0].set(ACTIVE_PART_ID, part); |
| return true; |
| } |
| |
| public String toString() { |
| return ACTIVE_PART_ID; |
| } |
| }, null); |
| |
| final IEclipseContext[] mainSashes = createNextLevel(windows[0], "mainSash", 2); |
| createNextLevel(mainSashes[1], "editorArea", 1); |
| final IEclipseContext[] viewSashes = createNextLevel(mainSashes[0], "viewSashes", 2); |
| |
| // create package explorer stack |
| final IEclipseContext[] packageStack = createNextLevel(viewSashes[0], "packageStack", 1); |
| final IEclipseContext[] packageViews = createNextLevel(packageStack[0], "packageViews", 3); |
| assertNotNull(packageViews); |
| assertEquals("packageViews0", windows[0].get(ACTIVE_PART)); |
| assertEquals("packageViews0", windows[0].get(ACTIVE_PART_ID)); |
| |
| // create problems stack |
| final IEclipseContext[] problemsStack = createNextLevel(viewSashes[1], "problemsStack", 1); |
| final IEclipseContext[] problemsViews = createNextLevel(problemsStack[0], "problemViews", 5); |
| assertNotNull(problemsViews); |
| assertEquals("packageViews0", windows[0].get(ACTIVE_PART)); |
| assertEquals("packageViews0", windows[0].get(ACTIVE_PART_ID)); |
| |
| assertEquals("problemViews0", problemsStack[0].get(ACTIVE_PART)); |
| // this won't change since it is a "runAndTrack" at the window context |
| // level |
| assertEquals("packageViews0", problemsStack[0].get(ACTIVE_PART_ID)); |
| |
| // set the "problems view" active, propagating the information up |
| // the active chain. |
| problemsStack[0].set(ACTIVE_CHILD, problemsViews[0]); |
| viewSashes[1].set(ACTIVE_CHILD, problemsStack[0]); |
| mainSashes[0].set(ACTIVE_CHILD, viewSashes[1]); |
| windows[0].set(ACTIVE_CHILD, mainSashes[0]); |
| workbenchContext.set(ACTIVE_CHILD, windows[0]); |
| |
| assertEquals("problemViews0", windows[0].get(ACTIVE_PART)); |
| assertEquals("problemViews0", windows[0].get(ACTIVE_PART_ID)); |
| |
| assertEquals("packageViews0", packageStack[0].get(ACTIVE_PART)); |
| assertEquals("problemViews0", packageStack[0].get(ACTIVE_PART_ID)); |
| } |
| |
| public void testRunAndTrackSimple() throws Exception { |
| final IEclipseContext workbenchContext = getGlobalContext(); |
| workbenchContext.set("activePart", new ActivePartLookupFunction()); |
| final IEclipseContext[] windows = createNextLevel(workbenchContext, "window", 1); |
| windows[0].runAndTrack(new IRunAndTrack() { |
| public boolean notify(ContextChangeEvent event) { |
| final Object part = windows[0].get(ACTIVE_PART); |
| windows[0].set(ACTIVE_PART_ID, part); |
| return true; |
| } |
| |
| public String toString() { |
| return ACTIVE_PART_ID; |
| } |
| }, null); |
| |
| final IEclipseContext[] parts = createNextLevel(windows[0], "part", 2); |
| assertEquals("part0", workbenchContext.get(ACTIVE_PART)); |
| assertEquals("part0", windows[0].get(ACTIVE_PART_ID)); |
| |
| windows[0].set(ACTIVE_CHILD, parts[1]); |
| assertEquals("part1", windows[0].get(ACTIVE_PART)); |
| assertEquals("part1", windows[0].get(ACTIVE_PART_ID)); |
| } |
| } |