Skip to content

Commit

Permalink
Call the "activated" method of the default tab in a Launch Config Dialog
Browse files Browse the repository at this point in the history
Also add a new test bundle that contains the proper regression test.

Bundle: org.eclipse.debug.ui.tests
Class: LaunchConfigurationTabGroupViewerTest

This class also contains a regression test for
#766

Fixes: #859
  • Loading branch information
fedejeanne committed Nov 29, 2023
1 parent 81042f5 commit c910372
Show file tree
Hide file tree
Showing 8 changed files with 354 additions and 11 deletions.
1 change: 1 addition & 0 deletions debug/org.eclipse.debug.tests/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,6 @@ Export-Package: org.eclipse.debug.tests,
org.eclipse.debug.tests.ui,
org.eclipse.debug.tests.view.memory,
org.eclipse.debug.tests.viewer.model
Import-Package: org.assertj.core.api;version="3.24.2"
Eclipse-BundleShape: dir
Automatic-Module-Name: org.eclipse.debug.tests
3 changes: 2 additions & 1 deletion debug/org.eclipse.debug.tests/plugin.properties
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ launchConfigurationType.name = Test Launch Type
extension.name = Debug File System
launchConfigurationType.name.0 = Cancelling Launch Type
launchConfigurationType.name.1 = Throwing Launch Type
testBreakpoint.name = Test Breakpoint
testBreakpoint.name = Test Breakpoint
launchConfigurationType.name.2 = Example launch
16 changes: 16 additions & 0 deletions debug/org.eclipse.debug.tests/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -163,4 +163,20 @@
priority="-1"
class="org.eclipse.debug.tests.ui.TestVariableValueEditor3"/>
</extension>
<extension point="org.eclipse.debug.core.launchConfigurationTypes">
<launchConfigurationType
name="%launchConfigurationType.name.2"
modes="run, debug"
id="org.eclipse.debug.ui.tests.launchConfigurationType1">
</launchConfigurationType>
</extension>

<extension
point="org.eclipse.debug.ui.launchConfigurationTabGroups">
<launchConfigurationTabGroup
class="org.eclipse.debug.tests.ui.SpyTabGroup"
id="org.eclipse.debug.ui.tests.launchConfigurationTabGroup"
type="org.eclipse.debug.ui.tests.launchConfigurationType1">
</launchConfigurationTabGroup>
</extension>
</plugin>
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import org.eclipse.debug.tests.sourcelookup.SourceLookupFacilityTests;
import org.eclipse.debug.tests.statushandlers.StatusHandlerTests;
import org.eclipse.debug.tests.stepfilters.StepFiltersTests;
import org.eclipse.debug.tests.ui.LaunchConfigurationTabGroupViewerTest;
import org.eclipse.debug.tests.ui.VariableValueEditorManagerTests;
import org.eclipse.debug.tests.view.memory.MemoryRenderingTests;
import org.eclipse.debug.tests.view.memory.TableRenderingTests;
Expand Down Expand Up @@ -131,6 +132,7 @@

// Launch Groups
LaunchGroupTests.class,
LaunchConfigurationTabGroupViewerTest.class,

// Logical structure
LogicalStructureCacheTest.class,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
/*******************************************************************************
* Copyright (c) 2018, 2019 SAP SE and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* SAP SE - initial version
*******************************************************************************/

package org.eclipse.debug.tests.ui;

import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;

import java.util.Arrays;
import java.util.concurrent.atomic.AtomicReference;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationPresentationManager;
import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationsDialog;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.debug.ui.ILaunchConfigurationDialog;
import org.eclipse.debug.ui.ILaunchConfigurationTab;
import org.eclipse.debug.ui.ILaunchConfigurationTabGroup;
import org.eclipse.swt.widgets.Display;
import org.junit.Before;
import org.junit.Test;

public class LaunchConfigurationTabGroupViewerTest {

private static interface ThrowingRunnable<T extends Exception> {
void run() throws T;
}

private static final String LAUNCH_CONFIG_TYPE_ID = "org.eclipse.debug.ui.tests.launchConfigurationType1";
private static final String LAUNCH_CONFIG_MODE = ILaunchManager.RUN_MODE;
private ILaunchConfigurationType fLaunchConfigurationType;
private LaunchConfigurationsDialog fLaunchConfigurationsDialog;

@Before
public void createDialog() throws CoreException {
fLaunchConfigurationType = getLaunchManager().getLaunchConfigurationType(LAUNCH_CONFIG_TYPE_ID);
ILaunchConfigurationTabGroup tabGroup = getLaunchConfigurationTabGroup(fLaunchConfigurationType);

fLaunchConfigurationsDialog = (LaunchConfigurationsDialog) createLaunchConfigurationDialog();
tabGroup.createTabs(fLaunchConfigurationsDialog, ILaunchManager.RUN_MODE);

ILaunchConfigurationTab[] tabs = tabGroup.getTabs();

assertThat(tabs).hasSizeGreaterThanOrEqualTo(2);
assertThat(tabs).allMatch(SpyTab.class::isInstance, "Use only SpyTabs in the group");
long typesOfTabs = Arrays.stream(tabs).map(Object::getClass).distinct().count();
assertThat("There are tabs of the exact same type in the group", tabs.length == typesOfTabs);
}

@Test
public void testAllTabsAreInitializedByDefault() {
// Create a launch configuration with a unique name
ThrowingRunnable<CoreException> createAndSelect1LaunchConfig = () -> {
fLaunchConfigurationsDialog.getTabViewer().setInput(createLaunchConfigurationInstance());
};

final ILaunchConfigurationTab[] tabs = runOnDialog(createAndSelect1LaunchConfig);

for (int i = 0; i < tabs.length; i++) {
assertThat("Tab " + i + " was not initialized", ((SpyTab) tabs[i]).isInitialized());
}
}

@Test
public void testFirstTabIsActivatedByDefault() {
// Create a launch configuration with a unique name
ThrowingRunnable<CoreException> createAndSelect1LaunchConfig = () -> {
fLaunchConfigurationsDialog.getTabViewer().setInput(createLaunchConfigurationInstance());
};

final ILaunchConfigurationTab[] tabs = runOnDialog(createAndSelect1LaunchConfig);
assertThat("The 1st tab was not activated", ((SpyTab) tabs[0]).isActivated());
}

@Test
public void testOtherTabInOtherConfigIsActivated() {
int secondTabIndex = 1;

ThrowingRunnable<CoreException> setActiveTab = () -> {
// Create and select launch config
fLaunchConfigurationsDialog.getTabViewer().setInput(createLaunchConfigurationInstance());

// Select another tab
fLaunchConfigurationsDialog.getTabViewer().setActiveTab(secondTabIndex);

// Create a new launch config. This one should activate the same tab
// by default.
fLaunchConfigurationsDialog.getTabViewer().setInput(createLaunchConfigurationInstance());
};

final ILaunchConfigurationTab[] tabs = runOnDialog(setActiveTab);

assertThat("The 1st tab of the other launch configuration shouldn't have been activated", not(((SpyTab) tabs[0]).isActivated()));
assertThat("The tab was not activated", ((SpyTab) tabs[secondTabIndex]).isActivated());
}

@Test
public void testOnlyDefaultTabInOtherConfigIsActivated() {
int overflowTabIndex = Integer.MAX_VALUE;

ThrowingRunnable<CoreException> setActiveTab = () -> {
// Create and select launch config
fLaunchConfigurationsDialog.getTabViewer().setInput(createLaunchConfigurationInstance());

// Select another tab
fLaunchConfigurationsDialog.getTabViewer().setActiveTab(overflowTabIndex);

// Create a new launch config. This one should activate the same tab
// by default.
fLaunchConfigurationsDialog.getTabViewer().setInput(createLaunchConfigurationInstance());
};

final ILaunchConfigurationTab[] tabs = runOnDialog(setActiveTab);

assertThat("The 1st tab of the other launch configuration should have been activated", ((SpyTab) tabs[0]).isActivated());

// All other tabs should not have been initialized
for (int i = 1; i < tabs.length; i++) {
assertThat("Tab " + i + " should not have been initialized", not(((SpyTab) tabs[i]).isInitialized()));
}
}

@Test
public void testOtherTabIsActivated() {
int secondTabIndex = 1;

ThrowingRunnable<CoreException> setActiveTab = () -> {
// Create and select launch config
fLaunchConfigurationsDialog.getTabViewer().setInput(createLaunchConfigurationInstance());

// Select another tab
fLaunchConfigurationsDialog.getTabViewer().setActiveTab(secondTabIndex);
};

final ILaunchConfigurationTab[] tabs = runOnDialog(setActiveTab);

assertThat("The tab was not activated", ((SpyTab) tabs[secondTabIndex]).isActivated());
}

private ILaunchConfigurationWorkingCopy createLaunchConfigurationInstance() throws CoreException {
return fLaunchConfigurationType.newInstance(null, "MyLaunchConfiguration_" + System.currentTimeMillis());
}

private <T extends Exception> ILaunchConfigurationTab[] runOnDialog(ThrowingRunnable<T> runnable) {
AtomicReference<ILaunchConfigurationTab[]> tabsRef = new AtomicReference<>();
AtomicReference<Throwable> throwableRef = new AtomicReference<>();

Display.getCurrent().asyncExec(() -> {
try {

runnable.run();

// I need to store the tabs here because the tab viewer (and all
// its tabs) are
// gone as soon as the dialog is closed
tabsRef.set(fLaunchConfigurationsDialog.getTabs());

} catch (Throwable e) {
// neither calling "fail" not throwing an exception will let the
// test fail so I
// need to store this and check it outside of the runnable
throwableRef.set(e);
// DebugPlugin.log(e);
} finally {
fLaunchConfigurationsDialog.close();
}
});

fLaunchConfigurationsDialog.open();

if (throwableRef.get() != null) {
throw new AssertionError("An exception occurred while executing the runnable.", throwableRef.get());
}

return tabsRef.get();
}

protected ILaunchConfigurationTabGroup getLaunchConfigurationTabGroup(ILaunchConfigurationType launchConfigurationType) throws CoreException {
return LaunchConfigurationPresentationManager.getDefault().getTabGroup(launchConfigurationType, LAUNCH_CONFIG_MODE);
}

protected ILaunchConfigurationDialog createLaunchConfigurationDialog() {
return new LaunchConfigurationsDialog(null, DebugUIPlugin.getDefault().getLaunchConfigurationManager().getLaunchGroup(IDebugUIConstants.ID_DEBUG_LAUNCH_GROUP));
}

protected ILaunchManager getLaunchManager() {
return DebugPlugin.getDefault().getLaunchManager();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*******************************************************************************
* Copyright (c) 2018, 2019 SAP SE and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* SAP SE - initial version
*******************************************************************************/

package org.eclipse.debug.tests.ui;

import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
import org.eclipse.swt.widgets.Composite;

/**
* A Tab whose sole purpose is to say if it was initialized and activated
* properly
*/
public abstract class SpyTab extends AbstractLaunchConfigurationTab {

private boolean initialized;
private boolean activated;

@Override
public void createControl(Composite parent) {
}

@Override
public String getName() {
return getClass().getSimpleName();
}

@Override
public void initializeFrom(ILaunchConfiguration configuration) {
initialized = true;
}

@Override
public void activated(ILaunchConfigurationWorkingCopy workingCopy) {
activated = true;
}

@Override
public void performApply(ILaunchConfigurationWorkingCopy configuration) {
}

@Override
public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
}

public boolean isInitialized() {
return initialized;
}

public boolean isActivated() {
return activated;
}

// These are necessary because I need several tabs in the launch config and
// using always the same kind (class) of tab produces incorrect results
public static class SpyTabA extends SpyTab {
}

public static class SpyTabB extends SpyTab {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*******************************************************************************
* Copyright (c) 2018, 2019 SAP SE and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* SAP SE - initial version
*******************************************************************************/

package org.eclipse.debug.tests.ui;

import org.eclipse.debug.tests.ui.SpyTab.SpyTabA;
import org.eclipse.debug.tests.ui.SpyTab.SpyTabB;
import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup;
import org.eclipse.debug.ui.ILaunchConfigurationDialog;
import org.eclipse.debug.ui.ILaunchConfigurationTab;

public class SpyTabGroup extends AbstractLaunchConfigurationTabGroup {

@Override
public void createTabs(ILaunchConfigurationDialog dialog, String mode) {
setTabs(new ILaunchConfigurationTab[] { new SpyTabA(), new SpyTabB() });
}

}
Loading

0 comments on commit c910372

Please sign in to comment.