Skip to content

Commit 935945d

Browse files
Fixed the java breakpoints no line attribute error dialog regarding the
"Don't tell me again" checkbox. The value wasn't stored in the preference store due to a bug in ErrorDialogWithToggle. Added also a testcase to easily reproduce the dialog opening and checking its functionality fixes ticket https://github.com/eclipse-jdt/eclipse.jdt.ui/issues/2648
1 parent 77be489 commit 935945d

File tree

4 files changed

+182
-2
lines changed

4 files changed

+182
-2
lines changed

org.eclipse.jdt.debug.tests/META-INF/MANIFEST.MF

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ Require-Bundle: org.eclipse.ui.ide;resolution:=optional,
4949
org.eclipse.test.performance,
5050
org.eclipse.ltk.core.refactoring,
5151
org.eclipse.jdt.core.manipulation,
52-
org.eclipse.core.filesystem
52+
org.eclipse.core.filesystem,
53+
org.mockito.mockito-core;bundle-version="5.20.0"
5354
Bundle-ActivationPolicy: lazy
5455
Bundle-RequiredExecutionEnvironment: JavaSE-21
5556
Eclipse-BundleShape: dir

org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AutomatedSuite.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@
150150
import org.eclipse.jdt.debug.tests.ui.DebugViewTests;
151151
import org.eclipse.jdt.debug.tests.ui.DetailPaneManagerTests;
152152
import org.eclipse.jdt.debug.tests.ui.JavaSnippetEditorTest;
153+
import org.eclipse.jdt.debug.tests.ui.NoLineNumberAttributesStatusHandlerTest;
153154
import org.eclipse.jdt.debug.tests.ui.OpenFromClipboardTests;
154155
import org.eclipse.jdt.debug.tests.ui.ViewManagementTests;
155156
import org.eclipse.jdt.debug.tests.ui.VirtualThreadsDebugViewTests;
@@ -341,6 +342,9 @@ public AutomatedSuite() {
341342
// Scrapbook editor tests
342343
addTest(new TestSuite(JavaSnippetEditorTest.class));
343344

345+
// No Line Number Attributes Status Handler tests
346+
addTest(new TestSuite(NoLineNumberAttributesStatusHandlerTest.class));
347+
344348
// Debug hover tests
345349
addTest(new TestSuite(DebugHoverTests.class));
346350

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025 Advantest Corporation and others.
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*
11+
* Contributors:
12+
* Advantest Corporation - initial API and implementation
13+
*******************************************************************************/
14+
package org.eclipse.jdt.debug.tests.ui;
15+
16+
import static org.mockito.Mockito.mock;
17+
import static org.mockito.Mockito.when;
18+
19+
import java.lang.reflect.Method;
20+
import java.util.ArrayList;
21+
import java.util.Collections;
22+
import java.util.List;
23+
24+
import org.eclipse.core.runtime.CoreException;
25+
import org.eclipse.core.runtime.ILogListener;
26+
import org.eclipse.core.runtime.IStatus;
27+
import org.eclipse.core.runtime.Platform;
28+
import org.eclipse.core.runtime.Status;
29+
import org.eclipse.debug.core.DebugPlugin;
30+
import org.eclipse.jdi.internal.ClassTypeImpl;
31+
import org.eclipse.jdi.internal.ReferenceTypeImpl;
32+
import org.eclipse.jdt.internal.debug.ui.DebugUIMessages;
33+
import org.eclipse.jdt.internal.debug.ui.ErrorDialogWithToggle;
34+
import org.eclipse.jdt.internal.debug.ui.IJDIPreferencesConstants;
35+
import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
36+
import org.eclipse.jdt.internal.debug.ui.NoLineNumberAttributesStatusHandler;
37+
import org.eclipse.jface.dialogs.IDialogConstants;
38+
import org.eclipse.jface.preference.IPreferenceStore;
39+
import org.eclipse.osgi.util.NLS;
40+
import org.eclipse.swt.widgets.Button;
41+
import org.eclipse.swt.widgets.Display;
42+
import org.eclipse.test.OrderedTestSuite;
43+
import org.eclipse.ui.PlatformUI;
44+
import org.junit.Test;
45+
46+
/**
47+
* This test is checking the {@link NoLineNumberAttributesStatusHandler} the functionality that the ok button click is saving the state in the
48+
* preference store.
49+
*/
50+
public class NoLineNumberAttributesStatusHandlerTest extends AbstractDebugUiTests {
51+
52+
public static junit.framework.Test suite() {
53+
return new OrderedTestSuite(NoLineNumberAttributesStatusHandlerTest.class);
54+
}
55+
56+
private final class ErrorDialogWithToggleRunnable implements Runnable {
57+
58+
private final IPreferenceStore preferenceStore;
59+
private final IStatus status;
60+
private final boolean value;
61+
62+
private Exception thrownException;
63+
64+
private ErrorDialogWithToggleRunnable(IPreferenceStore preferenceStore, IStatus status, boolean value) {
65+
this.preferenceStore = preferenceStore;
66+
this.status = status;
67+
this.value = value;
68+
}
69+
70+
@Override
71+
public void run() {
72+
try {
73+
ErrorDialogWithToggle dialog = new ErrorDialogWithToggle(PlatformUI.getWorkbench().getModalDialogShellProvider().getShell(), DebugUIMessages.NoLineNumberAttributesStatusHandler_Java_Breakpoint_1, NLS.bind(DebugUIMessages.NoLineNumberAttributesStatusHandler_2, "HelloWorld"), status, IJDIPreferencesConstants.PREF_ALERT_UNABLE_TO_INSTALL_BREAKPOINT, DebugUIMessages.NoLineNumberAttributesStatusHandler_3, preferenceStore) {
74+
@Override
75+
protected org.eclipse.swt.widgets.Button getToggleButton() {
76+
Button mockedButton = mock(Button.class);
77+
when(mockedButton.getSelection()).thenReturn(value);
78+
return mockedButton;
79+
}
80+
81+
};
82+
Method buttonPressedMethod = ErrorDialogWithToggle.class.getDeclaredMethod("buttonPressed", Integer.TYPE);
83+
buttonPressedMethod.setAccessible(true);
84+
try {
85+
buttonPressedMethod.invoke(dialog, IDialogConstants.OK_ID);
86+
} finally {
87+
buttonPressedMethod.setAccessible(false);
88+
}
89+
} catch (Exception e) {
90+
this.thrownException = e;
91+
}
92+
}
93+
94+
public Exception getThrownException() {
95+
return thrownException;
96+
}
97+
}
98+
99+
private final class ListLogListener implements ILogListener {
100+
private final List<IStatus> loggedEntries;
101+
102+
private ListLogListener(List<IStatus> loggedEntries) {
103+
this.loggedEntries = loggedEntries;
104+
}
105+
106+
@Override
107+
public void logging(IStatus status, String plugin) {
108+
if (status.isMultiStatus() && status.getChildren().length == 1) {
109+
loggedEntries.add(status.getChildren()[0]);
110+
}
111+
}
112+
}
113+
114+
public NoLineNumberAttributesStatusHandlerTest(String name) {
115+
super(name);
116+
}
117+
118+
@Test
119+
public void testPreferenceSettings() throws Exception {
120+
List<IStatus> loggedEntries = new ArrayList<>();
121+
ILogListener listener = new ListLogListener(loggedEntries);
122+
123+
Platform.addLogListener(listener);
124+
try {
125+
IPreferenceStore preferenceStore = JDIDebugUIPlugin.getDefault().getPreferenceStore();
126+
127+
IStatus status = new Status(IStatus.ERROR, "org.eclipse.jdt.debug", 162, "Teststatus", null);
128+
129+
simulateErrorDialogWithToggleExecution(preferenceStore, status, true);
130+
assertFalse(preferenceStore.getBoolean(IJDIPreferencesConstants.PREF_ALERT_UNABLE_TO_INSTALL_BREAKPOINT));
131+
assertTrue(loggedEntries.isEmpty());
132+
triggerNoLineAttributesStatusHandler(status);
133+
assertEquals(0, Collections.frequency(loggedEntries, status));
134+
135+
simulateErrorDialogWithToggleExecution(preferenceStore, status, false);
136+
assertTrue(preferenceStore.getBoolean(IJDIPreferencesConstants.PREF_ALERT_UNABLE_TO_INSTALL_BREAKPOINT));
137+
assertTrue(loggedEntries.isEmpty());
138+
triggerNoLineAttributesStatusHandler(status);
139+
assertEquals(1, Collections.frequency(loggedEntries, status));
140+
loggedEntries.clear();
141+
142+
simulateErrorDialogWithToggleExecution(preferenceStore, status, true);
143+
assertFalse(preferenceStore.getBoolean(IJDIPreferencesConstants.PREF_ALERT_UNABLE_TO_INSTALL_BREAKPOINT));
144+
145+
assertTrue(loggedEntries.isEmpty());
146+
triggerNoLineAttributesStatusHandler(status);
147+
assertEquals(0, Collections.frequency(loggedEntries, status));
148+
} finally {
149+
Platform.removeLogListener(listener);
150+
}
151+
152+
}
153+
154+
private void triggerNoLineAttributesStatusHandler(IStatus status) throws CoreException {
155+
ReferenceTypeImpl referenceTypeImpl = new ClassTypeImpl(null, null);
156+
referenceTypeImpl.setName("TestRefTypeName");
157+
DebugPlugin.getDefault().getStatusHandler(status).handleStatus(status, referenceTypeImpl);
158+
}
159+
160+
private void simulateErrorDialogWithToggleExecution(IPreferenceStore preferenceStore, IStatus status, boolean value) throws Exception {
161+
ErrorDialogWithToggleRunnable runnable = new ErrorDialogWithToggleRunnable(preferenceStore, status, value);
162+
Display.getDefault().syncExec(runnable);
163+
164+
if (runnable.getThrownException() != null) {
165+
throw runnable.getThrownException();
166+
}
167+
}
168+
}

org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/ErrorDialogWithToggle.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,18 @@ protected void buttonPressed(int id, IDebugTarget target) {
105105
if (id == IDialogConstants.OK_ID) { // was the OK button pressed?
106106
storePreference(target);
107107
}
108+
buttonPressed(id);
109+
}
110+
111+
@Override
112+
protected void buttonPressed(int id) {
113+
if (id == IDialogConstants.OK_ID) { // was the OK button pressed?
114+
fStore.setValue(fPreferenceKey, !getToggleButton().getSelection());
115+
}
108116
super.buttonPressed(id);
109117
}
110118

111119
private void storePreference(IDebugTarget target) {
112-
fStore.setValue(fPreferenceKey, !getToggleButton().getSelection());
113120
if (fToggleButton2 != null) {
114121
if (target instanceof JDIDebugTarget jdiTarget) {
115122
jdiTarget.setHcrDebugErrorPref(fToggleButton2.getSelection());

0 commit comments

Comments
 (0)