diff --git a/bundles/org.eclipse.cdt.lsp.test/src/org/eclipse/cdt/lsp/test/TestUtils.java b/bundles/org.eclipse.cdt.lsp.test/src/org/eclipse/cdt/lsp/test/TestUtils.java index fce8de3e..07038de4 100644 --- a/bundles/org.eclipse.cdt.lsp.test/src/org/eclipse/cdt/lsp/test/TestUtils.java +++ b/bundles/org.eclipse.cdt.lsp.test/src/org/eclipse/cdt/lsp/test/TestUtils.java @@ -26,12 +26,14 @@ import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.ServiceCaller; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.WorkbenchException; import org.eclipse.ui.ide.IDE; import org.junit.jupiter.api.TestInfo; @@ -83,6 +85,12 @@ public static IEditorPart openInEditor(IFile file) throws PartInitException { return part; } + public static IEditorPart openInEditorInNewWindow(URI uri, String editorID) throws PartInitException { + IEditorPart part = IDE.openEditor(getNewWorkbenchWindowPage(), uri, editorID, true); + part.setFocus(); + return part; + } + public static boolean closeEditor(IEditorPart editor, boolean save) { IWorkbenchWindow workbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); IWorkbenchPage page = workbenchWindow.getActivePage(); @@ -100,4 +108,13 @@ private static IWorkbenchPage getWorkbenchPage() { return PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); } + private static IWorkbenchPage getNewWorkbenchWindowPage() { + try { + return PlatformUI.getWorkbench().openWorkbenchWindow(null).getActivePage(); + } catch (WorkbenchException e) { + Platform.getLog(TestUtils.class).error(e.getMessage(), e); + } + return null; + } + } diff --git a/bundles/org.eclipse.cdt.lsp.test/src/org/eclipse/cdt/lsp/test/internal/server/CLanguageServerEnableCacheTest.java b/bundles/org.eclipse.cdt.lsp.test/src/org/eclipse/cdt/lsp/test/internal/server/CLanguageServerEnableCacheTest.java new file mode 100644 index 00000000..7474048e --- /dev/null +++ b/bundles/org.eclipse.cdt.lsp.test/src/org/eclipse/cdt/lsp/test/internal/server/CLanguageServerEnableCacheTest.java @@ -0,0 +1,106 @@ +/******************************************************************************* + * Copyright (c) 2025 Contributors to the Eclipse Foundation. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * See git history + *******************************************************************************/ + +package org.eclipse.cdt.lsp.test.internal.server; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.File; +import java.io.IOException; + +import org.eclipse.cdt.lsp.internal.server.CLanguageServerEnableCache; +import org.eclipse.cdt.lsp.plugin.LspPlugin; +import org.eclipse.cdt.lsp.test.TestUtils; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.ui.IEditorPart; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; +import org.junit.jupiter.api.io.TempDir; + +class CLanguageServerEnableCacheTest { + private static final String EXTERNAL_HEADER_HPP = "ExternalHeader.hpp"; + private IProject project; + private File externalFile; + private IEditorPart editor; + private IEditorPart editor2; + private CLanguageServerEnableCache cache = CLanguageServerEnableCache.getInstance(); + + @TempDir + private static File TEMP_DIR; + + @BeforeEach + public void setUp(TestInfo testInfo) throws CoreException, IOException { + project = TestUtils.createCProject(TestUtils.getName(testInfo)); + externalFile = new File(TEMP_DIR, EXTERNAL_HEADER_HPP); + externalFile.createNewFile(); + } + + @AfterEach + public void cleanUp() throws CoreException { + TestUtils.deleteProject(project); + if (externalFile != null) { + externalFile.delete(); + } + if (editor != null) { + TestUtils.closeEditor(editor, false); + } + if (editor2 != null) { + TestUtils.closeEditor(editor2, false); + } + } + + @Test + public void testCacheRemovedAfterFileGetsClosed() throws CoreException, IOException { + // GIVEN is an opened file in the LSP based C/C++ editor: + var uri = externalFile.toURI(); + editor = TestUtils.openInEditor(uri, LspPlugin.LSP_C_EDITOR_ID); + // WHEN accessing the cached enable value: + var cachedUri = cache.get(uri); + // THEN the cache for the given URI is present: + assertTrue(cachedUri != null); + // AND the cache returns TRUE for the given file URI: + assertTrue(cachedUri.booleanValue()); + // WHEN when the file gets closed: + TestUtils.closeEditor(editor, false); + // THEN the cached URI has been removed: + assertNull(cache.get(uri)); + } + + @Test + public void testCacheNotRemovedUntilAllOpenedEditorsHasBeenClosed() throws CoreException, IOException { + // GIVEN two opened files in the LSP based C/C++ editor in two workbench windows: + var uri = externalFile.toURI(); + editor = TestUtils.openInEditor(uri, LspPlugin.LSP_C_EDITOR_ID); + editor2 = TestUtils.openInEditorInNewWindow(uri, LspPlugin.LSP_C_EDITOR_ID); + // WHEN accessing the cached enable value: + var cachedUri = cache.get(uri); + // THEN the cache for the given URI is present: + assertTrue(cachedUri != null); + // AND the cache returns TRUE for the given file URI: + assertTrue(cachedUri.booleanValue()); + // WHEN when the file gets closed in the first window: + TestUtils.closeEditor(editor, false); + // THEN the cached URI has NOT been removed: + assertNotNull(cache.get(uri)); + assertTrue(cache.get(uri).booleanValue()); + // WHEN the file gets closed in the second window: + TestUtils.closeEditor(editor2, false); + // THEN the cached URI has been removed: + assertNull(cache.get(uri)); + } + +}