Skip to content

Commit

Permalink
Adding test cases for folding (#1960)
Browse files Browse the repository at this point in the history
  • Loading branch information
jakub-suliga authored Jan 24, 2025
1 parent 744f119 commit b9e7119
Show file tree
Hide file tree
Showing 3 changed files with 363 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.eclipse.jdt.text.tests.codemining.CodeMiningTriggerTest;
import org.eclipse.jdt.text.tests.codemining.ParameterNamesCodeMiningTest;
import org.eclipse.jdt.text.tests.contentassist.ContentAssistTestSuite;
import org.eclipse.jdt.text.tests.folding.FoldingTest;
import org.eclipse.jdt.text.tests.semantictokens.SemanticTokensProviderTest;
import org.eclipse.jdt.text.tests.spelling.SpellCheckEngineTestCase;
import org.eclipse.jdt.text.tests.templates.TemplatesTestSuite;
Expand Down Expand Up @@ -70,6 +71,7 @@
JavaElementPrefixPatternMatcherTest.class,
CodeMiningTriggerTest.class,
ParameterNamesCodeMiningTest.class,
FoldingTest.class,
})
public class JdtTextTestSuite {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,260 @@
/*******************************************************************************
* Copyright (c) 2025 Vector Informatik GmbH and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Vector Informatik GmbH - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.text.tests.folding;

import java.util.List;

import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;

import org.eclipse.jdt.testplugin.JavaProjectHelper;

import org.eclipse.core.runtime.CoreException;

import org.eclipse.jface.text.IRegion;

import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;

import org.eclipse.jdt.ui.tests.core.rules.ProjectTestSetup;

public class FoldingTest {
@Rule
public ProjectTestSetup projectSetup= new ProjectTestSetup();

private IJavaProject jProject;

private IPackageFragmentRoot sourceFolder;

private IPackageFragment packageFragment;

@Before
public void setUp() throws CoreException {
jProject= projectSetup.getProject();
sourceFolder= jProject.findPackageFragmentRoot(jProject.getResource().getFullPath().append("src"));
if (sourceFolder == null) {
sourceFolder= JavaProjectHelper.addSourceContainer(jProject, "src");
}
packageFragment= sourceFolder.createPackageFragment("org.example.test", false, null);
}

@After
public void tearDown() throws CoreException {
JavaProjectHelper.delete(jProject);
}

@Test
public void testCompilationUnitFolding() throws Exception {
String str= """
package org.example.test;
public class A { //here should not be an annotation
}
""";
FoldingTestUtils.assertCodeHasRegions(packageFragment, "TestFolding.java", str, 0);
}

@Test
public void testClassWithJavadocAsHeaderComment() throws Exception {
String str= """
package org.example.test;
/** //here should be an annotation
* Javadoc
*/
public class HeaderCommentTest {
}
""";
FoldingTestUtils.assertCodeHasRegions(packageFragment, "TestFolding.java", str, 1);

List<IRegion> regions= FoldingTestUtils.getProjectionRangesOfFile(packageFragment, "TestFolding.java", str);
FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(regions, str, 1, 3); // Javadoc
}

@Test
public void testImportsFolding() throws Exception {
String str= """
package org.example.test;
import java.util.List; //here should be an annotation
import java.util.ArrayList;
public class ImportsTest {
}
""";
FoldingTestUtils.assertCodeHasRegions(packageFragment, "TestFolding.java", str, 1);

List<IRegion> regions= FoldingTestUtils.getProjectionRangesOfFile(packageFragment, "TestFolding.java", str);
FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(regions, str, 2, 3); // Imports
}

@Test
public void testSingleMethodWithJavadoc() throws Exception {
String str= """
package org.example.test;
public class SingleMethodTest {
/** //here should be an annotation
* Javadoc
*/
public void foo() { //here should be an annotation
System.out.println("Hello");
}
}
""";
FoldingTestUtils.assertCodeHasRegions(packageFragment, "TestFolding.java", str, 2);

List<IRegion> regions= FoldingTestUtils.getProjectionRangesOfFile(packageFragment, "TestFolding.java", str);
FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(regions, str, 2, 4); // Javadoc
FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(regions, str, 5, 7); // foo Methode
}

@Test
public void testMultipleMethodsWithoutComments() throws Exception {
String str= """
package org.example.test;
public class MultipleMethodTest {
public void foo() { //here should be an annotation
}
public void bar() { //here should be an annotation
}
}
""";
FoldingTestUtils.assertCodeHasRegions(packageFragment, "TestFolding.java", str, 2);

List<IRegion> regions= FoldingTestUtils.getProjectionRangesOfFile(packageFragment, "TestFolding.java", str);
FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(regions, str, 2, 4); // foo Methode
FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(regions, str, 5, 7); // bar Methode
}

@Test
public void testInnerClassFolding() throws Exception {
String str= """
package org.example.test;
public class OuterClass {
class InnerClass { //here should be an annotation
void bar() { //here should be an annotation
}
}
}
""";
FoldingTestUtils.assertCodeHasRegions(packageFragment, "TestFolding.java", str, 2);

List<IRegion> regions= FoldingTestUtils.getProjectionRangesOfFile(packageFragment, "TestFolding.java", str);
FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(regions, str, 2, 6); // InnerClass
FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(regions, str, 3, 5); // bar Methode
}

@Test
public void testInnerClassWithJavadoc() throws Exception {
String str= """
package org.example.test;
public class OuterWithDocs {
/** //here should be an annotation
* Javadoc
*/
class InnerWithDocs { //here should be an annotation
/** //here should be an annotation
* Javadoc
*/
void bar() { //here should be an annotation
}
}
}
""";
FoldingTestUtils.assertCodeHasRegions(packageFragment, "TestFolding.java", str, 4);

List<IRegion> regions= FoldingTestUtils.getProjectionRangesOfFile(packageFragment, "TestFolding.java", str);
FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(regions, str, 2, 4); // OuterWithDocs Javadoc
FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(regions, str, 5, 12); // InnerWithDocs Klasse
FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(regions, str, 6, 8); // InnerWithDocs Javadoc
FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(regions, str, 9, 11); // bar Methode
}

@Test
public void testJavadocs() throws Exception {
String str= """
package org.example.test;
/** //here should be an annotation
* Javadoc
*/
/** //here should be an annotation
* Another Javadoc
*/
/** //here should be an annotation
* Yet another Javadoc
*/
public class Example {}
""";
FoldingTestUtils.assertCodeHasRegions(packageFragment, "TestFolding.java", str, 3);

List<IRegion> regions= FoldingTestUtils.getProjectionRangesOfFile(packageFragment, "TestFolding.java", str);
FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(regions, str, 1, 3); // 1. Javadoc
FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(regions, str, 4, 6); // 2. Javadoc
FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(regions, str, 7, 9); // 3. Javadoc
}

@Test
public void testCommentBlocks() throws Exception {
String str= """
package org.example.test;
/* //here should be an annotation
*
*/
/* //here should be an annotation
*
*/
/* //here should be an annotation
*
*/
class h {
/* //here should be an annotation
*
*/
void b() { //here should be an annotation
/* //here should NOT be an annotation
*
*/
int a;
}
}
""";
FoldingTestUtils.assertCodeHasRegions(packageFragment, "TestFolding.java", str, 5);

List<IRegion> regions= FoldingTestUtils.getProjectionRangesOfFile(packageFragment, "TestFolding.java", str);
FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(regions, str, 1, 3); // 1. Javadoc
FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(regions, str, 4, 6); // 2. Javadoc
FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(regions, str, 7, 9); // 3. Javadoc
FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(regions, str, 12, 14); // 4. Javadoc
FoldingTestUtils.assertContainsRegionUsingStartAndEndLine(regions, str, 15, 20); // Methode b()
}

@Test
public void testCopyrightHeader() throws Exception {
String str= """
/** //here should be an annotation
* This is some copyright header
*/
package org.example.test;
class SomeClass {}
""";
FoldingTestUtils.assertCodeHasRegions(packageFragment, "TestFolding.java", str, 1);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*******************************************************************************
* Copyright (c) 2025 Vector Informatik GmbH and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Vector Informatik GmbH - initial API and implementation
* Daniel Schmid - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.text.tests.folding;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.projection.ProjectionAnnotation;
import org.eclipse.jface.text.source.projection.ProjectionAnnotationModel;

import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IPackageFragment;

import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility;
import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;

public final class FoldingTestUtils {

private FoldingTestUtils() {
}

public static List<IRegion> getProjectionRangesOfFile(IPackageFragment packageFragment, String fileName, String code) throws Exception {
ICompilationUnit cu= packageFragment.createCompilationUnit(fileName, code, true, null);
JavaEditor editor= (JavaEditor) EditorUtility.openInEditor(cu);
ProjectionAnnotationModel model= editor.getAdapter(ProjectionAnnotationModel.class);

List<IRegion> regions= new ArrayList<>();
Iterator<Annotation> it= model.getAnnotationIterator();
while (it.hasNext()) {
Annotation a= it.next();
if (a instanceof ProjectionAnnotation) {
Position p= model.getPosition(a);
regions.add(new Region(p.getOffset(), p.getLength()));
}
}
return regions;
}

public static void assertCodeHasRegions(IPackageFragment packageFragment, String fileName, String code, int regionsCount) throws Exception {
List<IRegion> regions= FoldingTestUtils.getProjectionRangesOfFile(packageFragment, fileName, code);
assertEquals(regionsCount, regions.size(), String.format("Expected %d regions but saw %d.", regionsCount, regions.size()));
}

public static void assertContainsRegionUsingStartAndEndLine(List<IRegion> projectionRanges, String input, int startLine, int endLine) {
assertTrue(startLine <= endLine, "start line must be smaller or equal to end line");
int startLineBegin= findLineStartIndex(input, startLine);
int endLineBegin= findLineStartIndex(input, endLine);
int endLineEnd= findNextLineStart(input, endLineBegin);
endLineEnd= getLengthIfNotFound(input, endLineEnd);
for (IRegion region : projectionRanges) {
if (region.getOffset() == startLineBegin + 1 && region.getOffset() + region.getLength() == endLineEnd + 1) {
return;
}
}
fail(
"missing region from line " + startLine + " (index " + (startLineBegin + 1) + ") " +
"to line " + endLine + " (index " + (endLineEnd + 1) + ")" +
", actual regions: " + projectionRanges
);
}
private static int getLengthIfNotFound(String input, int startLineEnd) {
if (startLineEnd == -1) {
startLineEnd= input.length();
}
return startLineEnd;
}
private static int findLineStartIndex(String input, int lineNumber) {
int currentInputIndex= 0;
for (int i= 0; i < lineNumber; i++) {
currentInputIndex= findNextLineStart(input, currentInputIndex);
if (currentInputIndex == -1) {
fail("line number is greater than the total number of lines");
}
}
return currentInputIndex;
}
private static int findNextLineStart(String input, int currentInputIndex) {
return input.indexOf('\n', currentInputIndex + 1);
}
}

0 comments on commit b9e7119

Please sign in to comment.