/******************************************************************************* * Copyright (c) 2012-2017 Codenvy, S.A. * 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: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.eclipse.che.ide.part.editor; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwtmockito.GwtMockitoTestRunner; import com.google.inject.Provider; import com.google.web.bindery.event.shared.Event; import com.google.web.bindery.event.shared.EventBus; import com.google.web.bindery.event.shared.HandlerRegistration; import org.eclipse.che.api.workspace.shared.dto.ProjectConfigDto; import org.eclipse.che.ide.actions.EditorActions; import org.eclipse.che.ide.api.action.Action; import org.eclipse.che.ide.api.action.ActionManager; import org.eclipse.che.ide.api.action.Presentation; import org.eclipse.che.ide.api.editor.AbstractEditorPresenter; import org.eclipse.che.ide.api.editor.EditorAgent; import org.eclipse.che.ide.api.editor.EditorInput; import org.eclipse.che.ide.api.editor.EditorPartPresenter; import org.eclipse.che.ide.api.editor.EditorWithErrors; import org.eclipse.che.ide.api.parts.EditorTab; import org.eclipse.che.ide.api.parts.PartPresenter; import org.eclipse.che.ide.api.parts.PartStackView.TabItem; import org.eclipse.che.ide.api.parts.PropertyListener; import org.eclipse.che.ide.api.resources.VirtualFile; import org.eclipse.che.ide.menu.PartMenu; import org.eclipse.che.ide.part.PartStackPresenter.PartStackEventHandler; import org.eclipse.che.ide.part.PartsComparator; import org.eclipse.che.ide.part.editor.actions.CloseAllTabsPaneAction; import org.eclipse.che.ide.part.editor.actions.ClosePaneAction; import org.eclipse.che.ide.part.editor.actions.SplitHorizontallyAction; import org.eclipse.che.ide.part.editor.actions.SplitVerticallyAction; import org.eclipse.che.ide.part.widgets.TabItemFactory; import org.eclipse.che.ide.part.widgets.panemenu.EditorPaneMenu; import org.eclipse.che.ide.part.widgets.panemenu.EditorPaneMenuItem; import org.eclipse.che.ide.part.widgets.panemenu.EditorPaneMenuItemFactory; import org.eclipse.che.ide.part.widgets.panemenu.PaneMenuActionItemWidget; import org.eclipse.che.ide.resource.Path; import org.eclipse.che.ide.ui.toolbar.PresentationFactory; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Matchers; import org.mockito.Mock; import org.vectomatic.dom.svg.ui.SVGResource; import static org.eclipse.che.ide.part.editor.actions.EditorAbstractAction.CURRENT_FILE_PROP; import static org.eclipse.che.ide.part.editor.actions.EditorAbstractAction.CURRENT_PANE_PROP; import static org.eclipse.che.ide.part.editor.actions.EditorAbstractAction.CURRENT_TAB_PROP; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.nullValue; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyObject; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; /** * @author Dmitry Shnurenko */ @RunWith(GwtMockitoTestRunner.class) public class EditorPartStackPresenterTest { private static final String SOME_TEXT = "someText"; //constructor mocks @Mock private EditorPartStackView view; @Mock private PartMenu partMenu; @Mock private PartsComparator partsComparator; @Mock private EventBus eventBus; @Mock private TabItemFactory tabItemFactory; @Mock private PartStackEventHandler partStackEventHandler; @Mock private EditorPaneMenu editorPaneMenu; @Mock private Provider<EditorAgent> editorAgentProvider; @Mock private PresentationFactory presentationFactory; @Mock private ActionManager actionManager; @Mock private ClosePaneAction closePaneAction; @Mock private CloseAllTabsPaneAction closeAllTabsPaneAction; @Mock private EditorPaneMenuItemFactory editorPaneMenuItemFactory; @Mock private EditorAgent editorAgent; //additional mocks @Mock private SplitHorizontallyAction splitHorizontallyAction; @Mock private SplitVerticallyAction splitVerticallyAction; @Mock private Presentation presentation; @Mock private EditorTab editorTab1; @Mock private EditorTab editorTab2; @Mock private EditorTab editorTab3; @Mock private EditorWithErrors withErrorsPart; @Mock private AbstractEditorPresenter partPresenter1; @Mock private AbstractEditorPresenter partPresenter2; @Mock private AbstractEditorPresenter partPresenter3; @Mock private EditorPaneMenuItem<Action> editorPaneActionMenuItem; @Mock private EditorPaneMenuItem<TabItem> editorPaneTabMenuItem; @Mock private SVGResource resource1; @Mock private SVGResource resource2; @Mock private ProjectConfigDto descriptor; @Mock private EditorPartPresenter editorPartPresenter; @Mock private EditorInput editorInput1; @Mock private EditorInput editorInput2; @Mock private EditorInput editorInput3; @Mock private VirtualFile file1; @Mock private VirtualFile file2; @Mock private VirtualFile file3; @Mock private HandlerRegistration handlerRegistration; @Captor private ArgumentCaptor<EditorPaneMenuItem> itemCaptor; @Captor private ArgumentCaptor<AsyncCallback<Void>> argumentCaptor; private EditorPartStackPresenter presenter; @Before public void setUp() { when(partPresenter1.getTitle()).thenReturn(SOME_TEXT); when(partPresenter1.getTitleImage()).thenReturn(resource1); when(partPresenter2.getTitle()).thenReturn(SOME_TEXT); when(partPresenter2.getTitleImage()).thenReturn(resource2); when(partPresenter1.getEditorInput()).thenReturn(editorInput1); when(editorInput1.getFile()).thenReturn(file1); when(partPresenter2.getEditorInput()).thenReturn(editorInput2); when(editorInput2.getFile()).thenReturn(file2); when(partPresenter3.getEditorInput()).thenReturn(editorInput3); when(editorInput3.getFile()).thenReturn(file3); when(presentationFactory.getPresentation((Action)anyObject())).thenReturn(presentation); when(eventBus.addHandler((Event.Type<Object>)anyObject(), anyObject())).thenReturn(handlerRegistration); when(actionManager.getAction(EditorActions.SPLIT_HORIZONTALLY)).thenReturn(splitHorizontallyAction); when(actionManager.getAction(EditorActions.SPLIT_VERTICALLY)).thenReturn(splitVerticallyAction); when(closePaneAction.getTemplatePresentation()).thenReturn(presentation); when(closeAllTabsPaneAction.getTemplatePresentation()).thenReturn(presentation); when(splitHorizontallyAction.getTemplatePresentation()).thenReturn(presentation); when(splitVerticallyAction.getTemplatePresentation()).thenReturn(presentation); when(editorPaneMenuItemFactory.createMenuItem((Action)anyObject())).thenReturn(editorPaneActionMenuItem); when(editorPaneMenuItemFactory.createMenuItem((TabItem)anyObject())).thenReturn(editorPaneTabMenuItem); presenter = new EditorPartStackPresenter(view, partMenu, partsComparator, editorPaneMenuItemFactory, presentationFactory, eventBus, tabItemFactory, partStackEventHandler, editorPaneMenu, actionManager, closePaneAction, closeAllTabsPaneAction, editorAgent); when(tabItemFactory.createEditorPartButton(partPresenter1, presenter)).thenReturn(editorTab1); when(tabItemFactory.createEditorPartButton(partPresenter2, presenter)).thenReturn(editorTab2); when(tabItemFactory.createEditorPartButton(partPresenter3, presenter)).thenReturn(editorTab3); when(editorTab1.getFile()).thenReturn(file1); } @Test public void constructorShouldBeVerified() { verify(view, times(2)).setDelegate(presenter); verify(view).addPaneMenuButton(editorPaneMenu); verify(editorPaneMenuItemFactory, times(4)).createMenuItem(Matchers.<Action>anyObject()); verify(editorPaneMenu).addItem(Matchers.<PaneMenuActionItemWidget>anyObject(), eq(true)); verify(editorPaneMenu, times(3)).addItem(Matchers.<PaneMenuActionItemWidget>anyObject()); } @Test public void focusShouldBeSet() { presenter.setFocus(true); verify(view).setFocus(true); } @Test public void partShouldBeAdded() { presenter.addPart(partPresenter1); verify(partPresenter1, times(2)).addPropertyListener(Matchers.<PropertyListener>anyObject()); verify(tabItemFactory).createEditorPartButton(partPresenter1, presenter); verify(editorTab1).setDelegate(presenter); verify(view).addTab(editorTab1, partPresenter1); verify(view).selectTab(partPresenter1); } @Test public void partShouldNotBeAddedWhenItExist() { presenter.addPart(partPresenter1); reset(view); presenter.addPart(partPresenter1); verify(view, never()).addTab(editorTab1, partPresenter1); verify(view).selectTab(partPresenter1); } @Test public void activePartShouldBeReturned() { presenter.setActivePart(partPresenter1); assertEquals(presenter.getActivePart(), partPresenter1); } @Test public void onTabShouldBeClicked() { presenter.addPart(partPresenter1); reset(view); presenter.onTabClicked(editorTab1); verify(view).selectTab(partPresenter1); } @Test public void tabShouldBeClosed() { presenter.addPart(partPresenter1); presenter.removePart(partPresenter1); presenter.onTabClose(editorTab1); verify(view).removeTab(partPresenter1); } @Test public void activePartShouldBeChangedWhenWeClickOnTab() { presenter.addPart(partPresenter1); presenter.addPart(partPresenter2); presenter.onTabClicked(editorTab1); assertEquals(presenter.getActivePart(), partPresenter1); presenter.onTabClicked(editorTab2); assertEquals(presenter.getActivePart(), partPresenter2); } @Test public void previousTabSelectedWhenWeRemovePart() { presenter.addPart(partPresenter1); presenter.addPart(partPresenter2); presenter.onTabClicked(editorTab2); presenter.removePart(partPresenter2); presenter.onTabClose(editorTab2); assertEquals(presenter.getActivePart(), partPresenter1); } @Test public void activePartShouldBeNullWhenWeCloseAllParts() { presenter.addPart(partPresenter1); presenter.onTabClose(editorTab1); assertThat(presenter.getActivePart(), is(nullValue())); } @Test public void shouldReturnNextPart() { presenter.addPart(partPresenter1); presenter.addPart(partPresenter2); presenter.addPart(partPresenter3); EditorPartPresenter result = presenter.getNextFor(partPresenter2); assertNotNull(result); assertEquals(partPresenter3, result); } @Test public void shouldReturnFirstPart() { presenter.addPart(partPresenter1); presenter.addPart(partPresenter2); presenter.addPart(partPresenter3); EditorPartPresenter result = presenter.getNextFor(partPresenter3); assertNotNull(result); assertEquals(partPresenter1, result); } @Test public void shouldReturnPreviousPart() { presenter.addPart(partPresenter1); presenter.addPart(partPresenter2); presenter.addPart(partPresenter3); EditorPartPresenter result = presenter.getPreviousFor(partPresenter2); assertNotNull(result); assertEquals(partPresenter1, result); } @Test public void shouldReturnLastPart() { presenter.addPart(partPresenter1); presenter.addPart(partPresenter2); presenter.addPart(partPresenter3); EditorPartPresenter result = presenter.getPreviousFor(partPresenter1); assertNotNull(result); assertEquals(partPresenter3, result); } @Test public void tabShouldBeReturnedByPath() throws Exception { Path path = new Path(SOME_TEXT); when(editorTab1.getFile()).thenReturn(file1); when(file1.getLocation()).thenReturn(path); presenter.addPart(partPresenter1); assertEquals(editorTab1, presenter.getTabByPath(path)); } @Test public void shouldAddHandlers() throws Exception { presenter.addPart(partPresenter1); verify(eventBus, times(2)).addHandler((Event.Type<EditorPartStackPresenter>)anyObject(), eq(presenter)); } @Test public void shouldNotAddHandlersWhenHandlersAlreadyExist() throws Exception { presenter.addPart(partPresenter1); reset(eventBus); presenter.addPart(partPresenter2); verify(eventBus, never()).addHandler((Event.Type<EditorPartStackPresenter>)anyObject(), eq(presenter)); } @Test public void shouldRemoveHandlersWhenPartsIsAbsent() throws Exception { presenter.addPart(partPresenter1); reset(handlerRegistration); presenter.removePart(partPresenter1); verify(handlerRegistration, times(2)).removeHandler(); } @Test public void shouldAvoidNPEWhenHandlersAlreadyRemoved() throws Exception { presenter.addPart(partPresenter1); presenter.removePart(partPresenter1); reset(handlerRegistration); presenter.removePart(partPresenter2); verify(handlerRegistration, never()).removeHandler(); } @Test public void openPreviousActivePartTest() { presenter.addPart(partPresenter1); presenter.openPreviousActivePart(); verify(view).selectTab(eq(partPresenter1)); } @Test public void onTabItemClickedTest() { TabItem tabItem = mock(TabItem.class); when(editorPaneTabMenuItem.getData()).thenReturn(tabItem); presenter.paneMenuTabItemHandler.onItemClicked(editorPaneTabMenuItem); verify(view).selectTab((PartPresenter)anyObject()); } @Test public void onActionClickedTest() { Action action = mock(Action.class); when(editorPaneActionMenuItem.getData()).thenReturn(action); presenter.addPart(partPresenter1); presenter.setActivePart(partPresenter1); presenter.paneMenuActionItemHandler.onItemClicked(editorPaneActionMenuItem); verify(presentation).putClientProperty(eq(CURRENT_PANE_PROP), eq(presenter)); verify(presentation).putClientProperty(eq(CURRENT_TAB_PROP), eq(editorTab1)); verify(presentation).putClientProperty(eq(CURRENT_FILE_PROP), eq(file1)); } @Test public void onItemCloseTest() { when(editorPaneTabMenuItem.getData()).thenReturn(editorTab1); presenter.paneMenuTabItemHandler.onCloseButtonClicked(editorPaneTabMenuItem); verify(editorAgent).closeEditor(any(EditorPartPresenter.class)); } }