/******************************************************************************* * Copyright (c) 2014, 2015 Obeo 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: * Obeo - initial API and implementation * Michael Borkowski - extraction of nested classes, TreeItem creation *******************************************************************************/ package org.eclipse.emf.compare.ide.ui.tests.structuremergeviewer; import static org.mockito.Matchers.any; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import java.util.HashMap; import java.util.Map; import org.eclipse.emf.common.notify.Adapter; import org.eclipse.emf.common.notify.AdapterFactory; import org.eclipse.emf.compare.Diff; import org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.EMFCompareStructureMergeViewerContentProvider; import org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.EMFCompareStructureMergeViewerContentProvider.CallbackType; import org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.Navigatable; import org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.WrappableTreeViewer; import org.eclipse.emf.edit.tree.TreeNode; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeItem; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; /** * Utils class used for creating the {@link Tree} and the {@link WrappableTreeViewer}. * * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a> */ final class TestContext { /** * Number of elements in the testContext. */ private int counter = 0; private Tree swtTree; private Map<Integer, TreeItem> itemRetreiver; private WrappableTreeViewer viewer; private final Shell currentShell; private Object[] currentSelection; public TestContext(Shell shell) { super(); currentShell = shell; this.itemRetreiver = new HashMap<Integer, TreeItem>(); } private Integer increment() { return new Integer(counter++); } public Tree getTree() { return swtTree; } public TreeItem getItem(int id) { return itemRetreiver.get(Integer.valueOf(id)); } public int getNumberOfNodes() { return counter - 1; } /** * Builds a {@link Tree} (convenience method for calling {@link #buildTree(int, int, boolean)} with * useString = <code>true</code>) * * @param depth * of the testContext * @param numberOfChildren * number of chidlren by item. * @return {@link Navigatable} */ public TestNavigatable buildTree(int depth, int numberOfChildren) { return buildTree(depth, numberOfChildren, true); } /** * Builds a {@link Tree}. * * @param depth * of the testContext * @param numberOfChildren * number of children by item. * @param useStrings * whether to use {@link String} data instead of {@link Adapter} data elements. * @return {@link Navigatable} */ public TestNavigatable buildTree(int depth, int numberOfChildren, boolean useStrings) { if (swtTree == null) { swtTree = new Tree(currentShell, SWT.NONE); swtTree.setData("root"); //$NON-NLS-1$ createSubNodes(swtTree, numberOfChildren, depth, useStrings); viewer = spy(new WrappableTreeViewer(swtTree)); doAnswer(selectionChanged()).when(viewer).setSelection(any(ISelection.class)); AdapterFactory adapterFactory = mock(AdapterFactory.class); EMFCompareStructureMergeViewerContentProvider contentProvider = new EMFCompareStructureMergeViewerContentProvider( adapterFactory, viewer); // mock(EMFCompareStructureMergeViewerContentProvider.class); return new TestNavigatable(viewer, contentProvider); } else { throw new AssertionError("The tree can only be built once"); //$NON-NLS-1$ } } private Answer<Void> selectionChanged() { return new Answer<Void>() { public Void answer(InvocationOnMock invocation) throws Throwable { ISelection selection = (ISelection)invocation.getArguments()[0]; if (selection instanceof StructuredSelection) { currentSelection = ((StructuredSelection)selection).toArray(); } invocation.callRealMethod(); return null; } }; } private void createSubNodes(Object parent, int numberOfChild, int depth, boolean useStrings) { if (depth > 0) { for (int childIndex = 0; childIndex < numberOfChild; childIndex++) { final TreeItem item; if (parent instanceof Tree) { item = new TreeItem((Tree)parent, SWT.NONE); } else { item = new TreeItem((TreeItem)parent, SWT.NONE); } Integer increment = increment(); String name = String.valueOf(increment); item.setText(name); if (useStrings) { item.setData(name); } else { Adapter adapter = mock(Adapter.class); TreeNode notifier = mock(TreeNode.class); Diff diff = mock(Diff.class); when(adapter.getTarget()).thenReturn(notifier); when(notifier.getData()).thenReturn(diff); item.setData(adapter); } itemRetreiver.put(increment, item); createSubNodes(item, numberOfChild, depth - 1, useStrings); } } } /** * The purpose of this class is to make protected members of {@link Navigatable} visible to tests. * * @author Michael Borkowski <mborkowski@eclipsesource.com> */ public class TestNavigatable extends Navigatable { public TestNavigatable(WrappableTreeViewer viewer, EMFCompareStructureMergeViewerContentProvider contentProvider) { super(viewer, contentProvider); uiSyncCallbackType = CallbackType.IN_CURRENT_THREAD; } @Override public TreeItem getNextItem(TreeItem previousItem) { return super.getNextItem(previousItem); } @Override public TreeItem getPreviousItem(TreeItem previousItem) { return super.getPreviousItem(previousItem); } } /** * Returns the current tree selection * * @return */ public Object[] getCurrentSelection() { return currentSelection; } }