From 32551d04bd0048f64c4682ceb674d162e4ee9ccc Mon Sep 17 00:00:00 2001 From: Alexander Zolotov Date: Tue, 11 Nov 2025 13:01:36 +0100 Subject: [PATCH] refactoring [text-matching]: move text-matching tests to the corresponding module GitOrigin-RevId: cef94a9c2a0f04bcc81ed08fadeeb668a17938bf --- platform/lvcs-impl/BUILD.bazel | 1 + platform/ml-impl/BUILD.bazel | 1 + platform/platform-impl/BUILD.bazel | 1 + platform/platform-tests/BUILD.bazel | 1 + .../util/MinusculeMatcherPerformanceTest.java | 22 ++- .../psi/util/SpeedSearchComparatorTest.java | 17 +++ platform/util/text-matching/BUILD.bazel | 27 +++- .../intellij.platform.util.text.matching.iml | 4 + .../text/matching}/NameUtilMatchingTest.java | 143 +++++++++++++----- .../util/text/matching}/NameUtilTest.java | 10 +- .../text/matching}/PinyinMatcherDataTest.java | 15 +- .../matching}/TypoTolerantMatcherTest.java | 17 ++- platform/xdebugger-impl/BUILD.bazel | 1 + plugins/git4idea/BUILD.bazel | 1 + .../kotlin.code-insight.k2/BUILD.bazel | 1 + 15 files changed, 198 insertions(+), 64 deletions(-) create mode 100644 platform/platform-tests/testSrc/com/intellij/psi/util/SpeedSearchComparatorTest.java rename platform/{platform-tests/testSrc/com/intellij/psi/util => util/text-matching/test/com/intellij/platform/util/text/matching}/NameUtilMatchingTest.java (89%) rename platform/{platform-tests/testSrc/com/intellij/psi => util/text-matching/test/com/intellij/platform/util/text/matching}/NameUtilTest.java (90%) rename platform/{platform-tests/testSrc/com/intellij/psi/codeStyle => util/text-matching/test/com/intellij/platform/util/text/matching}/PinyinMatcherDataTest.java (93%) rename platform/{platform-tests/testSrc/com/intellij/psi/codeStyle => util/text-matching/test/com/intellij/platform/util/text/matching}/TypoTolerantMatcherTest.java (80%) diff --git a/platform/lvcs-impl/BUILD.bazel b/platform/lvcs-impl/BUILD.bazel index 368df911f4ca..d00fc1780be5 100644 --- a/platform/lvcs-impl/BUILD.bazel +++ b/platform/lvcs-impl/BUILD.bazel @@ -70,6 +70,7 @@ jvm_library( "//libraries/fastutil", "//platform/core-ui", "//platform/util/text-matching", + "//platform/util/text-matching:text-matching_test_lib", "//platform/util/coroutines", "//platform/statistics", "//platform/statistics:statistics_test_lib", diff --git a/platform/ml-impl/BUILD.bazel b/platform/ml-impl/BUILD.bazel index 7c903c7d0da0..a422d9ff38b9 100644 --- a/platform/ml-impl/BUILD.bazel +++ b/platform/ml-impl/BUILD.bazel @@ -65,6 +65,7 @@ jvm_library( "//platform/testFramework:testFramework_test_lib", "@lib//:assert_j", "//platform/util/text-matching", + "//platform/util/text-matching:text-matching_test_lib", "@lib//:junit4", "//platform/lang-impl", "//libraries/kotlinx/serialization/core", diff --git a/platform/platform-impl/BUILD.bazel b/platform/platform-impl/BUILD.bazel index 6660c9579972..8a754ba58ff7 100644 --- a/platform/platform-impl/BUILD.bazel +++ b/platform/platform-impl/BUILD.bazel @@ -279,6 +279,7 @@ jvm_library( "//libraries/hdr-histogram", "//platform/code-style-impl:codeStyle-impl", "//platform/util/text-matching", + "//platform/util/text-matching:text-matching_test_lib", "//platform/platform-impl/rpc", "//libraries/hash4j", "//platform/util-ex", diff --git a/platform/platform-tests/BUILD.bazel b/platform/platform-tests/BUILD.bazel index 5dc2620e8a44..da9c27948656 100644 --- a/platform/platform-tests/BUILD.bazel +++ b/platform/platform-tests/BUILD.bazel @@ -118,6 +118,7 @@ jvm_library( "@lib//:hamcrest", "//libraries/hdr-histogram", "//platform/util/text-matching", + "//platform/util/text-matching:text-matching_test_lib", "//platform/lang-impl/testEntities:testEntities_test_lib", "@lib//:junit5Suites", "//platform/backend/workspace", diff --git a/platform/platform-tests/testSrc/com/intellij/psi/util/MinusculeMatcherPerformanceTest.java b/platform/platform-tests/testSrc/com/intellij/psi/util/MinusculeMatcherPerformanceTest.java index 1b49f4014a8b..696c67f759b7 100644 --- a/platform/platform-tests/testSrc/com/intellij/psi/util/MinusculeMatcherPerformanceTest.java +++ b/platform/platform-tests/testSrc/com/intellij/psi/util/MinusculeMatcherPerformanceTest.java @@ -12,8 +12,7 @@ import org.junit.Assert; import java.util.ArrayList; import java.util.List; - -import static com.intellij.psi.util.NameUtilMatchingTest.*; +import java.util.function.ToIntFunction; public class MinusculeMatcherPerformanceTest extends TestCase { public void testPerformance() { @@ -107,4 +106,23 @@ public class MinusculeMatcherPerformanceTest extends TestCase { }).runAsStressTest().start(); } + private static void assertMatches(@NonNls String pattern, @NonNls String name) { + assertTrue(pattern + " doesn't match " + name + "!!!", caseInsensitiveMatcher(pattern).matches(name)); + } + + private static void assertDoesntMatch(@NonNls String pattern, @NonNls String name) { + assertFalse(pattern + " matches " + name + "!!!", caseInsensitiveMatcher(pattern).matches(name)); + } + + private static MinusculeMatcher caseInsensitiveMatcher(String pattern) { + return NameUtil.buildMatcher(pattern, NameUtil.MatchingCaseSensitivity.NONE); + } + + static void assertPreference(@NonNls String pattern, @NonNls String less, @NonNls String more) { + MinusculeMatcher matcher = NameUtil.buildMatcher(pattern, NameUtil.MatchingCaseSensitivity.FIRST_LETTER); + ToIntFunction matchingDegree = matcher::matchingDegree; + int iLess = matchingDegree.applyAsInt(less); + int iMore = matchingDegree.applyAsInt(more); + assertTrue(iLess + ">=" + iMore + "; " + less + ">=" + more, iLess < iMore); + } } diff --git a/platform/platform-tests/testSrc/com/intellij/psi/util/SpeedSearchComparatorTest.java b/platform/platform-tests/testSrc/com/intellij/psi/util/SpeedSearchComparatorTest.java new file mode 100644 index 000000000000..f61880ac692d --- /dev/null +++ b/platform/platform-tests/testSrc/com/intellij/psi/util/SpeedSearchComparatorTest.java @@ -0,0 +1,17 @@ +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.psi.util; + +import com.intellij.ui.SpeedSearchComparator; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +public class SpeedSearchComparatorTest { + @Test + public void testSpeedSearchComparator() { + final SpeedSearchComparator c = new SpeedSearchComparator(false, true); + assertNotNull(c.matchingFragments("a", "Ant")); + assertNotNull(c.matchingFragments("an", "Changes")); + assertNotNull(c.matchingFragments("a", "Changes")); + } +} diff --git a/platform/util/text-matching/BUILD.bazel b/platform/util/text-matching/BUILD.bazel index d8cb59dcb241..fa82496aeb44 100644 --- a/platform/util/text-matching/BUILD.bazel +++ b/platform/util/text-matching/BUILD.bazel @@ -12,4 +12,29 @@ jvm_library( "//platform/util-rt", ] ) -### auto-generated section `build intellij.platform.util.text.matching` end \ No newline at end of file + +jvm_library( + name = "text-matching_test_lib", + visibility = ["//visibility:public"], + srcs = glob(["test/**/*.kt", "test/**/*.java", "test/**/*.form"], allow_empty = True), + associates = [":text-matching"], + deps = [ + "@lib//:jetbrains-annotations", + "//platform/util/base", + "//platform/util-rt", + "//platform/util-rt:util-rt_test_lib", + "@lib//:kotlin-test", + "@lib//:kotlin-test-junit", + "@lib//:junit5", + ] +) +### auto-generated section `build intellij.platform.util.text.matching` end + +### auto-generated section `test intellij.platform.util.text.matching` start +load("@community//build:tests-options.bzl", "jps_test") + +jps_test( + name = "text-matching_test", + runtime_deps = [":text-matching_test_lib"] +) +### auto-generated section `test intellij.platform.util.text.matching` end \ No newline at end of file diff --git a/platform/util/text-matching/intellij.platform.util.text.matching.iml b/platform/util/text-matching/intellij.platform.util.text.matching.iml index 150b5e2e98ae..9f51249d2926 100644 --- a/platform/util/text-matching/intellij.platform.util.text.matching.iml +++ b/platform/util/text-matching/intellij.platform.util.text.matching.iml @@ -4,11 +4,15 @@ + + + + \ No newline at end of file diff --git a/platform/platform-tests/testSrc/com/intellij/psi/util/NameUtilMatchingTest.java b/platform/util/text-matching/test/com/intellij/platform/util/text/matching/NameUtilMatchingTest.java similarity index 89% rename from platform/platform-tests/testSrc/com/intellij/psi/util/NameUtilMatchingTest.java rename to platform/util/text-matching/test/com/intellij/platform/util/text/matching/NameUtilMatchingTest.java index a04f386a038b..d9dbe36645b0 100644 --- a/platform/platform-tests/testSrc/com/intellij/psi/util/NameUtilMatchingTest.java +++ b/platform/util/text-matching/test/com/intellij/platform/util/text/matching/NameUtilMatchingTest.java @@ -1,20 +1,22 @@ -// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.psi.util; +package com.intellij.platform.util.text.matching; import com.intellij.openapi.util.TextRange; import com.intellij.psi.codeStyle.AllOccurrencesMatcher; import com.intellij.psi.codeStyle.MinusculeMatcher; import com.intellij.psi.codeStyle.NameUtil; -import com.intellij.testFramework.UsefulTestCase; -import com.intellij.ui.SpeedSearchComparator; import com.intellij.util.text.Matcher; -import junit.framework.TestCase; import org.jetbrains.annotations.NonNls; +import org.junit.jupiter.api.Test; +import java.util.Arrays; import java.util.function.ToIntFunction; -public class NameUtilMatchingTest extends TestCase { +import static org.junit.jupiter.api.Assertions.*; + +public class NameUtilMatchingTest { + @Test public void testSimpleCases() { assertMatches("N", "NameUtilTest"); assertMatches("NU", "NameUtilTest"); @@ -29,11 +31,13 @@ public class NameUtilMatchingTest extends TestCase { assertMatches("ZZZ", "ZZZZZZZZZZ"); } + @Test public void testEmptyPrefix() { assertMatches("", ""); assertMatches("", "asdfs"); } + @Test public void testSkipWords() { assertMatches("nt", "NameUtilTest"); assertMatches("repl map", "ReplacePathToMacroMap"); @@ -44,7 +48,8 @@ public class NameUtilMatchingTest extends TestCase { assertMatches("templipa", "template_impl_template_list_panel"); assertMatches("templistpa", "template_impl_template_list_panel"); } - + + @Test public void testSimpleCasesWithFirstLowercased() { assertMatches("N", "nameUtilTest"); assertDoesntMatch("N", "anameUtilTest"); @@ -58,7 +63,8 @@ public class NameUtilMatchingTest extends TestCase { assertMatches("NaUtT", "nameUtilTest"); assertMatches("NaUtTe", "nameUtilTest"); } - + + @Test public void testSpaceDelimiters() { assertMatches("Na Ut Te", "name util test"); assertMatches("Na Ut Te", "name Util Test"); @@ -73,7 +79,8 @@ public class NameUtilMatchingTest extends TestCase { assertDoesntMatch("alias mple", "alias simple"); assertDoesntMatch("alias nother", "alias another"); } - + + @Test public void testXMLCompletion() { assertDoesntMatch("N_T", "NameUtilTest"); assertMatches("ORGS_ACC", "ORGS_POSITION_ACCOUNTABILITY"); @@ -81,20 +88,24 @@ public class NameUtilMatchingTest extends TestCase { assertMatches("ORGS.ACC", "ORGS.POSITION_ACCOUNTABILITY"); } + @Test public void testStarFalsePositive() { assertDoesntMatch("ar*l*p", "AbstractResponseHandler"); } + @Test public void testUnderscoreStyle() { assertMatches("N_U_T", "NAME_UTIL_TEST"); assertMatches("NUT", "NAME_UTIL_TEST"); assertDoesntMatch("NUT", "NameutilTest"); } + @Test public void testAllUppercase() { assertMatches("NOS", "NetOutputStream"); } + @Test public void testCommonFileNameConventions() { // See IDEADEV-12310 @@ -113,6 +124,7 @@ public class NameUtilMatchingTest extends TestCase { assertDoesntMatch("*.ico", "sm.th.iks.concierge"); } + @Test public void testSpaceForAnyWordsInBetween() { assertMatches("fo bar", "fooBar"); assertMatches("foo bar", "fooBar"); @@ -124,6 +136,7 @@ public class NameUtilMatchingTest extends TestCase { assertTrue(caseInsensitiveMatcher(" us").matches("getMyUsage")); } + @Test public void testFilenamesWithDotsAndSpaces() { assertMatches("Google Test.html", "Google Test Test.cc.html"); assertMatches("Google.html", "Google Test Test.cc.html"); @@ -135,6 +148,7 @@ public class NameUtilMatchingTest extends TestCase { return NameUtil.buildMatcher(pattern, NameUtil.MatchingCaseSensitivity.NONE); } + @Test public void testStartDot() { assertMatches("A*.html", "A.html"); assertMatches("A*.html", "Abc.html"); @@ -142,6 +156,7 @@ public class NameUtilMatchingTest extends TestCase { assertDoesntMatch("A*.html", "10_after.html"); } + @Test public void testIDEADEV15503() { assertMatches("AR.jsp", "add_relationship.jsp"); assertMatches("AR.jsp", "advanced_rule.jsp"); @@ -170,6 +185,7 @@ public class NameUtilMatchingTest extends TestCase { assertMatches("AR.jsp", "AlarmRuleSeverity.jsp"); } + @Test public void testSkipDot() { assertMatches("ja", "jquery.autocomplete.js"); assertDoesntMatch("ja.js", "jquery.autocomplete.js"); @@ -181,26 +197,31 @@ public class NameUtilMatchingTest extends TestCase { assertMatches("*foo.*bar", "foo.b.bar"); } + @Test public void testNoExtension() { assertMatches("#.p", "#.php"); assertMatches("#", "#.php"); assertMatches("a", "a.php"); } + @Test public void testIgnoreCaseWhenCompleteMatch() { assertMatches("comboBox", "combobox"); assertMatches("combobox", "comboBox"); } - + + @Test public void testStartsWithDot() { assertMatches(".foo", ".foo"); } + @Test public void testProperDotEscaping() { assertMatches("*inspection*.pro", "InspectionsBundle.properties"); assertDoesntMatch("*inspection*.pro", "InspectionsInProgress.png"); } + @Test public void testLeadingUnderscore() { assertDoesntMatch("form", "_form.html.erb"); assertMatches("_form", "_form.html.erb"); @@ -208,6 +229,7 @@ public class NameUtilMatchingTest extends TestCase { assertTrue(firstLetterMatcher("_form").matches("__form")); } + @Test public void testLowerCaseWords() { assertMatches("uct", "unit_controller_test"); assertMatches("unictest", "unit_controller_test"); @@ -216,6 +238,7 @@ public class NameUtilMatchingTest extends TestCase { assertDoesntMatch("utc", "unit_controller_test"); } + @Test public void testObjectiveCCases() { assertMatches("h*:", "h:aaa"); assertMatches("h:", "h:aaa"); @@ -225,6 +248,7 @@ public class NameUtilMatchingTest extends TestCase { assertMatches("text*:sh", "textField:shouldChangeCharactersInRange:replacementString:"); } + @Test public void testMiddleMatchingMinimumTwoConsecutiveLettersInWordMiddle() { assertMatches("*fo", "reformat"); assertMatches("*f", "reFormat"); @@ -252,6 +276,7 @@ public class NameUtilMatchingTest extends TestCase { } + @Test public void testMiddleMatchingUnderscore() { assertMatches("*_dark", "collapseAll_dark.png"); assertMatches("*_dark.png", "collapseAll_dark.png"); @@ -259,6 +284,7 @@ public class NameUtilMatchingTest extends TestCase { assertTrue(firstLetterMatcher("*_DARK").matches("A_DARK.png")); } + @Test public void testMiddleMatching() { assertMatches("*zz*", "ListConfigzzKey"); assertMatches("*zz", "ListConfigzzKey"); @@ -286,6 +312,7 @@ public class NameUtilMatchingTest extends TestCase { assertMatches("*BComp", "BaseComponent"); } + @Test public void testUppercasePrefixWithMiddleMatching() { assertMatches("*OS", "ios"); assertMatches("*OS", "IOS"); @@ -296,10 +323,12 @@ public class NameUtilMatchingTest extends TestCase { assertFalse(firstLetterMatcher("*I").matches("id")); } + @Test public void testAsteriskEndingInsideUppercaseWord() { assertMatches("*LRUMap", "SLRUMap"); } + @Test public void testMiddleMatchingFirstLetterSensitive() { assertTrue(firstLetterMatcher(" cl").matches("getClass")); assertFalse(firstLetterMatcher(" EUC-").matches("x-EUC-TW")); @@ -314,6 +343,7 @@ public class NameUtilMatchingTest extends TestCase { assertTrue(firstLetterMatcher("*Bcomp").matches("BaseComponent")); } + @Test public void testPreferCamelHumpsToAllUppers() { assertPreference("ProVi", "PROVIDER", "ProjectView"); } @@ -322,26 +352,31 @@ public class NameUtilMatchingTest extends TestCase { return NameUtil.buildMatcher(pattern, NameUtil.MatchingCaseSensitivity.FIRST_LETTER); } + @Test public void testSpaceInCompletionPrefix() { assertTrue(caseInsensitiveMatcher("create ").matches("create module")); } + @Test public void testLong() { assertMatches("Product.findByDateAndNameGreaterThanEqualsAndQualityGreaterThanEqual", "Product.findByDateAndNameGreaterThanEqualsAndQualityGreaterThanEqualsIntellijIdeaRulezzz"); } - static void assertMatches(@NonNls String pattern, @NonNls String name) { - assertTrue(pattern + " doesn't match " + name + "!!!", caseInsensitiveMatcher(pattern).matches(name)); - } - static void assertDoesntMatch(@NonNls String pattern, @NonNls String name) { - assertFalse(pattern + " matches " + name + "!!!", caseInsensitiveMatcher(pattern).matches(name)); + private static void assertMatches(@NonNls String pattern, @NonNls String name) { + assertTrue(caseInsensitiveMatcher(pattern).matches(name), pattern + " doesn't match " + name + "!!!"); } + private static void assertDoesntMatch(@NonNls String pattern, @NonNls String name) { + assertFalse(caseInsensitiveMatcher(pattern).matches(name), pattern + " matches " + name + "!!!"); + } + + @Test public void testUpperCaseMatchesLowerCase() { assertMatches("ABC_B.C", "abc_b.c"); } + @Test public void testLowerCaseHumps() { assertMatches("foo", "foo"); assertDoesntMatch("foo", "fxoo"); @@ -372,6 +407,7 @@ public class NameUtilMatchingTest extends TestCase { assertMatches("Wlo", "WebLogic"); } + @Test public void testFinalSpace() { assertMatches("a ", "alpha + beta"); assertMatches("a ", "a "); @@ -391,6 +427,7 @@ public class NameUtilMatchingTest extends TestCase { assertDoesntMatch("*leg ", "AppDelegate"); } + @Test public void testDigits() { assertMatches("foba4", "FooBar4"); assertMatches("foba", "Foo4Bar"); @@ -401,11 +438,13 @@ public class NameUtilMatchingTest extends TestCase { assertMatches("smart8co", "smart18completion"); } + @Test public void testDoNotAllowDigitsBetweenMatchingDigits() { assertDoesntMatch("*012", "001122"); assertMatches("012", "0a1_22"); } + @Test public void testSpecialSymbols() { assertMatches("a@b", "a@bc"); assertDoesntMatch("*@in", "a int"); @@ -414,6 +453,7 @@ public class NameUtilMatchingTest extends TestCase { assertMatches("a/text", "a/bbbText"); } + @Test public void testMinusculeFirstLetter() { assertTrue(firstLetterMatcher("WebLogic").matches("WebLogic")); assertFalse(firstLetterMatcher("webLogic").matches("WebLogic")); @@ -423,6 +463,7 @@ public class NameUtilMatchingTest extends TestCase { assertFalse(firstLetterMatcher("abc").matches("_abc")); } + @Test public void testMinusculeAllImportant() { assertTrue(NameUtil.buildMatcher("WebLogic", NameUtil.MatchingCaseSensitivity.ALL).matches("WebLogic")); assertFalse(NameUtil.buildMatcher("webLogic", NameUtil.MatchingCaseSensitivity.ALL).matches("weblogic")); @@ -440,40 +481,45 @@ public class NameUtilMatchingTest extends TestCase { assertFalse(NameUtil.buildMatcher("java.util.list", NameUtil.MatchingCaseSensitivity.ALL).matches("java.util.AbstractList")); } + @Test public void testMatchingFragments() { @NonNls String sample = "NoClassDefFoundException"; // 0 2 7 10 15 21 - UsefulTestCase.assertOrderedEquals(NameUtil.buildMatcher("ncldfou*ion", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), - TextRange.from(0, 1), TextRange.from(2, 2), TextRange.from(7, 1), TextRange.from(10, 3), TextRange.from(21, 3)); + assertIterableEquals(NameUtil.buildMatcher("ncldfou*ion", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), + Arrays.asList(TextRange.from(0, 1), TextRange.from(2, 2), TextRange.from(7, 1), TextRange.from(10, 3), + TextRange.from(21, 3))); sample = "doGet(HttpServletRequest, HttpServletResponse):void"; // 0 22 - UsefulTestCase.assertOrderedEquals(NameUtil.buildMatcher("d*st", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), - TextRange.from(0, 1), TextRange.from(22, 2)); - UsefulTestCase.assertOrderedEquals(NameUtil.buildMatcher("doge*st", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), - TextRange.from(0, 4), TextRange.from(22, 2)); + assertIterableEquals(NameUtil.buildMatcher("d*st", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), + Arrays.asList(TextRange.from(0, 1), TextRange.from(22, 2))); + assertIterableEquals(NameUtil.buildMatcher("doge*st", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), + Arrays.asList(TextRange.from(0, 4), TextRange.from(22, 2))); sample = "_test"; - UsefulTestCase.assertOrderedEquals(NameUtil.buildMatcher("_", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), - TextRange.from(0, 1)); - UsefulTestCase.assertOrderedEquals(NameUtil.buildMatcher("_t", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), - TextRange.from(0, 2)); + assertIterableEquals(NameUtil.buildMatcher("_", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), + Arrays.asList(TextRange.from(0, 1))); + assertIterableEquals(NameUtil.buildMatcher("_t", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), + Arrays.asList(TextRange.from(0, 2))); } + @Test public void testMatchingFragmentsSorted() { @NonNls String sample = "SWUPGRADEHDLRFSPR7TEST"; // 0 9 12 - UsefulTestCase.assertOrderedEquals(NameUtil.buildMatcher("SWU*H*R", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), - TextRange.from(0, 3), TextRange.from(9, 1), TextRange.from(12, 1)); + assertIterableEquals(NameUtil.buildMatcher("SWU*H*R", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), + Arrays.asList(TextRange.from(0, 3), TextRange.from(9, 1), TextRange.from(12, 1))); } + @Test public void testPreferCapsMatching() { String sample = "getCurrentUser"; // 0 4 10 - UsefulTestCase.assertOrderedEquals(NameUtil.buildMatcher("getCU", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), - TextRange.from(0, 4), TextRange.from(10, 1)); + assertIterableEquals(NameUtil.buildMatcher("getCU", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), + Arrays.asList(TextRange.from(0, 4), TextRange.from(10, 1))); } + @Test public void testPlusOrMinusInThePatternShouldAllowToBeSpaceSurrounded() { assertMatches("a+b", "alpha+beta"); assertMatches("a+b", "alpha_gamma+beta"); @@ -494,6 +540,7 @@ public class NameUtilMatchingTest extends TestCase { assertMatches("a-b", "alpha - beta"); } + @Test public void testMatchingDegree() { assertPreference("jscote", "JsfCompletionTest", "JSCompletionTest", NameUtil.MatchingCaseSensitivity.NONE); assertPreference("OCO", "OneCoolObject", "OCObject"); @@ -510,14 +557,17 @@ public class NameUtilMatchingTest extends TestCase { assertPreference("*String", "STRING", "String", NameUtil.MatchingCaseSensitivity.NONE); } + @Test public void testPreferAdjacentWords() { assertPreference("*psfi", "PsiJavaFileBaseImpl", "PsiFileImpl", NameUtil.MatchingCaseSensitivity.NONE); } + @Test public void testPreferMatchesToTheEnd() { assertPreference("*e", "fileIndex", "file", NameUtil.MatchingCaseSensitivity.NONE); } + @Test public void testPreferences() { assertPreference(" fb", "FooBar", "_fooBar", NameUtil.MatchingCaseSensitivity.NONE); assertPreference("*foo", "barFoo", "foobar"); @@ -532,6 +582,7 @@ public class NameUtilMatchingTest extends TestCase { assertNoPreference("en", "ENABLED", "Enum", NameUtil.MatchingCaseSensitivity.NONE); } + @Test public void testHonorFirstLetterCaseInCompletion() { MinusculeMatcher matcher = NameUtil.buildMatcher("*pim", NameUtil.MatchingCaseSensitivity.NONE); int iLess = matcher.matchingDegree("PImageDecoder", true); @@ -539,6 +590,7 @@ public class NameUtilMatchingTest extends TestCase { assertTrue(iLess < iMore); } + @Test public void testPreferWordBoundaryMatch() { assertPreference("*ap", "add_profile", "application", NameUtil.MatchingCaseSensitivity.NONE); assertPreference("*les", "configureByFiles", "getLookupElementStrings"); @@ -552,31 +604,37 @@ public class NameUtilMatchingTest extends TestCase { assertPreference("*icon", "getInitControl", "getErrorIcon", NameUtil.MatchingCaseSensitivity.NONE); } + @Test public void testPreferNoWordSkipping() { assertPreference("CBP", "CustomProcessBP", "ComputationBatchProcess", NameUtil.MatchingCaseSensitivity.NONE); } + @Test public void testWordLengthDoesNotMatter() { assertNoPreference("PropComp", "PropertyComponent", "PropertiesComponent", NameUtil.MatchingCaseSensitivity.NONE); } + @Test public void testMatchStartDoesntMatterForDegree() { assertNoPreference(" path", "getAbsolutePath", "findPath", NameUtil.MatchingCaseSensitivity.FIRST_LETTER); } + @Test public void testPreferStartMatching() { assertPreference("*tree", "FooTree", "Tree", NameUtil.MatchingCaseSensitivity.NONE); } + @Test public void testPreferContiguousMatching() { assertPreference("*mappablejs", "mappable-js.scope.js", "MappableJs.js", NameUtil.MatchingCaseSensitivity.NONE); } + @Test public void testMeaningfulMatchingDegree() { assertTrue(caseInsensitiveMatcher(" EUC-").matchingDegree("x-EUC-TW") > Integer.MIN_VALUE); } - static void assertPreference(@NonNls String pattern, @NonNls String less, @NonNls String more) { + private static void assertPreference(@NonNls String pattern, @NonNls String less, @NonNls String more) { assertPreference(pattern, less, more, NameUtil.MatchingCaseSensitivity.FIRST_LETTER); } @@ -594,7 +652,7 @@ public class NameUtilMatchingTest extends TestCase { private static void assertPreference(String less, String more, ToIntFunction matchingDegree) { int iLess = matchingDegree.applyAsInt(less); int iMore = matchingDegree.applyAsInt(more); - assertTrue(iLess + ">=" + iMore + "; " + less + ">=" + more, iLess < iMore); + assertTrue(iLess < iMore, iLess + ">=" + iMore + "; " + less + ">=" + more); } private static void assertNoPreference(@NonNls String pattern, @@ -605,24 +663,19 @@ public class NameUtilMatchingTest extends TestCase { assertEquals(matcher.matchingDegree(name1), matcher.matchingDegree(name2)); } - public void testSpeedSearchComparator() { - final SpeedSearchComparator c = new SpeedSearchComparator(false, true); - - assertNotNull(c.matchingFragments("a", "Ant")); - assertNotNull(c.matchingFragments("an", "Changes")); - assertNotNull(c.matchingFragments("a", "Changes")); - } - + @Test public void testFilePatterns() { assertMatches("groovy*.jar", "groovy-1.7.jar"); assertDoesntMatch("*.ico", "a.i.c.o"); } + @Test public void testCapsMayMatchNonCaps() { assertMatches("PDFRe", "PdfRenderer"); assertMatches("*pGETPartTimePositionInfo", "dbo.pGetPartTimePositionInfo.sql"); } + @Test public void testACapitalAfterAnotherCapitalMayMatchALowercaseLetterBecauseShiftWasAccidentallyHeldTooLong() { assertMatches("USerDefa", "UserDefaults"); assertMatches("NSUSerDefa", "NSUserDefaults"); @@ -631,34 +684,40 @@ public class NameUtilMatchingTest extends TestCase { assertMatches("NSUserDEF", "NSUserDefaults"); } + @Test public void testCyrillicMatch() { assertMatches("ыек", "String"); } + @Test public void testMatchingAllOccurrences() { String text = "some text"; MinusculeMatcher matcher = AllOccurrencesMatcher.create("*e", NameUtil.MatchingCaseSensitivity.NONE, ""); - UsefulTestCase.assertOrderedEquals(matcher.matchingFragments(text), - new TextRange(3, 4), new TextRange(6, 7)); + assertIterableEquals(matcher.matchingFragments(text), + Arrays.asList(new TextRange(3, 4), new TextRange(6, 7))); } + @Test public void testCamelHumpWinsOverConsecutiveCaseMismatch() { - UsefulTestCase.assertSize(3, NameUtil.buildMatcher("GEN", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments("GetExtendedName")); + assertEquals(3, NameUtil.buildMatcher("GEN", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments("GetExtendedName").size()); assertPreference("GEN", "GetName", "GetExtendedName"); assertPreference("*GEN", "GetName", "GetExtendedName"); } + @Test public void testPrintln() { assertMatches("pl", "println"); assertMatches("pl", "printlnFoo"); assertDoesntMatch("pl", "printlnx"); } + @Test public void testLowerCaseAfterCamels() { assertMatches("LSTMa", "LineStatusTrackerManager"); } + @Test public void testProperties() { assertMatches("*pro", "spring.activemq.pool.configuration.reconnect-on-exception"); } diff --git a/platform/platform-tests/testSrc/com/intellij/psi/NameUtilTest.java b/platform/util/text-matching/test/com/intellij/platform/util/text/matching/NameUtilTest.java similarity index 90% rename from platform/platform-tests/testSrc/com/intellij/psi/NameUtilTest.java rename to platform/util/text-matching/test/com/intellij/platform/util/text/matching/NameUtilTest.java index a408588d01bf..d3d1e082bc73 100644 --- a/platform/platform-tests/testSrc/com/intellij/psi/NameUtilTest.java +++ b/platform/util/text-matching/test/com/intellij/platform/util/text/matching/NameUtilTest.java @@ -1,14 +1,14 @@ -// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.psi; +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.platform.util.text.matching; import com.intellij.psi.codeStyle.NameUtil; import com.intellij.util.text.NameUtilCore; -import org.junit.Test; +import org.junit.jupiter.api.Test; import java.util.Arrays; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; public class NameUtilTest { @Test diff --git a/platform/platform-tests/testSrc/com/intellij/psi/codeStyle/PinyinMatcherDataTest.java b/platform/util/text-matching/test/com/intellij/platform/util/text/matching/PinyinMatcherDataTest.java similarity index 93% rename from platform/platform-tests/testSrc/com/intellij/psi/codeStyle/PinyinMatcherDataTest.java rename to platform/util/text-matching/test/com/intellij/platform/util/text/matching/PinyinMatcherDataTest.java index 77f9a32e573d..f2136e47093f 100644 --- a/platform/platform-tests/testSrc/com/intellij/psi/codeStyle/PinyinMatcherDataTest.java +++ b/platform/util/text-matching/test/com/intellij/platform/util/text/matching/PinyinMatcherDataTest.java @@ -1,10 +1,11 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.psi.codeStyle; +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.platform.util.text.matching; +import com.intellij.psi.codeStyle.PinyinMatcher; import org.jetbrains.annotations.NotNull; -import org.junit.Ignore; -import org.junit.Test; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; import java.io.BufferedReader; import java.io.IOException; @@ -23,7 +24,7 @@ import java.util.zip.ZipInputStream; * Generates data arrays for {@link PinyinMatcher} using Unihan_Readings.txt file from unicode.org * Requires Internet connection. */ -@Ignore +@Disabled("It's a generator, not a real test") public class PinyinMatcherDataTest { private static final int LINE_LENGTH = 100; private static final String DATA_SOURCE = "https://unicode.org/Public/UNIDATA/Unihan.zip"; @@ -41,8 +42,8 @@ public class PinyinMatcherDataTest { toJavaStringLiteral("ENCODING", encodingStr) + "\n" + toJavaStringLiteral("DATA", data) + "\n"; - Assertions.assertEquals(encodingStr, PinyinMatcher.ENCODING, message); - Assertions.assertEquals(data, PinyinMatcher.DATA, message); + Assertions.assertEquals(PinyinMatcher.ENCODING, encodingStr, message); + Assertions.assertEquals(PinyinMatcher.DATA, data, message); } private static String toJavaStringLiteral(String varName, String input) { diff --git a/platform/platform-tests/testSrc/com/intellij/psi/codeStyle/TypoTolerantMatcherTest.java b/platform/util/text-matching/test/com/intellij/platform/util/text/matching/TypoTolerantMatcherTest.java similarity index 80% rename from platform/platform-tests/testSrc/com/intellij/psi/codeStyle/TypoTolerantMatcherTest.java rename to platform/util/text-matching/test/com/intellij/platform/util/text/matching/TypoTolerantMatcherTest.java index f1e865fe0eb3..941fd0fad1a7 100644 --- a/platform/platform-tests/testSrc/com/intellij/psi/codeStyle/TypoTolerantMatcherTest.java +++ b/platform/util/text-matching/test/com/intellij/platform/util/text/matching/TypoTolerantMatcherTest.java @@ -1,14 +1,17 @@ -// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.psi.codeStyle; +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.platform.util.text.matching; -import com.intellij.util.containers.ContainerUtil; -import org.junit.Test; +import com.intellij.psi.codeStyle.MinusculeMatcher; +import com.intellij.psi.codeStyle.NameUtil; +import com.intellij.psi.codeStyle.TypoTolerantMatcher; +import org.junit.jupiter.api.Test; +import java.util.Arrays; import java.util.List; import java.util.SplittableRandom; import java.util.stream.Stream; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.*; public class TypoTolerantMatcherTest { @Test @@ -25,7 +28,7 @@ public class TypoTolerantMatcherTest { return sb.toString(); }).limit(20000).toArray(String[]::new); TypoTolerantMatcher matcher = new TypoTolerantMatcher("asd", NameUtil.MatchingCaseSensitivity.FIRST_LETTER, ""); - List matched = ContainerUtil.filter(data, matcher::matches); + List matched = Arrays.stream(data).filter(matcher::matches).toList(); List expected = List.of("aqvQpSfmT", "arvIeSdS", "agofjgjwovuUiSmdalto", "jasridvantDr", "asvioqecqrkujxuLoiDo", "ssHDdcogvKq", "asQDqhkej", "gastDtHdqgG", "ahSDaks", "abKluwAdwxJoUyibvgeoh", "aDbsnmlGlJuBJsDi", "aamaoRrghlcD", "aadnjwforytcqwa", "adovoaqvSximVAdD", @@ -38,7 +41,7 @@ public class TypoTolerantMatcherTest { public void testEmptyPattern() { TypoTolerantMatcher matcher = new TypoTolerantMatcher("*", NameUtil.MatchingCaseSensitivity.NONE, ""); String[] data = new String[]{"foo", "bar", "buzz"}; - List matched = ContainerUtil.filter(data, matcher::matches); + List matched = Arrays.stream(data).filter(matcher::matches).toList(); List expected = List.of("foo", "bar", "buzz"); assertEquals(expected, matched); } diff --git a/platform/xdebugger-impl/BUILD.bazel b/platform/xdebugger-impl/BUILD.bazel index 5f622da3b4f7..23493ac8faae 100644 --- a/platform/xdebugger-impl/BUILD.bazel +++ b/platform/xdebugger-impl/BUILD.bazel @@ -119,6 +119,7 @@ jvm_library( "@lib//:kotlinx-coroutines-core", "//libraries/miglayout-swing", "//platform/util/text-matching", + "//platform/util/text-matching:text-matching_test_lib", "//platform/util/coroutines", "//platform/ide-core-impl", "//platform/platform-impl/rpc", diff --git a/plugins/git4idea/BUILD.bazel b/plugins/git4idea/BUILD.bazel index f3558c5b5817..dc1a7ab7b525 100644 --- a/plugins/git4idea/BUILD.bazel +++ b/plugins/git4idea/BUILD.bazel @@ -205,6 +205,7 @@ jvm_library( "//platform/collaboration-tools:collaboration-tools_test_lib", "//platform/ide-core-impl", "//platform/util/text-matching", + "//platform/util/text-matching:text-matching_test_lib", "//plugins/performanceTesting/core:performanceTesting", "//plugins/performanceTesting/core:performanceTesting_test_lib", "//platform/backend/observation", diff --git a/plugins/kotlin/code-insight/kotlin.code-insight.k2/BUILD.bazel b/plugins/kotlin/code-insight/kotlin.code-insight.k2/BUILD.bazel index 181ca627b8d1..f097c199bd7e 100644 --- a/plugins/kotlin/code-insight/kotlin.code-insight.k2/BUILD.bazel +++ b/plugins/kotlin/code-insight/kotlin.code-insight.k2/BUILD.bazel @@ -157,6 +157,7 @@ jvm_library( "//plugins/kotlin/kotlin.ide", "//libraries/velocity", "//platform/util/text-matching", + "//platform/util/text-matching:text-matching_test_lib", "//platform/util/jdom", "//plugins/kotlin/code-insight/override-implement-k2:kotlin-codeInsight-overrideImplement", "//plugins/kotlin/code-insight/override-implement-shared:kotlin-code-insight-override-implement-shared",