From f2c2288fcffeec35c45b9a500ebda10580093351 Mon Sep 17 00:00:00 2001 From: Alexander Zolotov Date: Fri, 14 Nov 2025 12:54:00 +0100 Subject: [PATCH] refactoring [text-matching]: convert tests to kotlin GitOrigin-RevId: 906a9ab2cd4a2a65f7df4e02647d9e687534b5a8 --- .../matching/AllOccurrencesMatcherTest.java | 24 - .../matching/AllOccurrencesMatcherTest.kt | 20 + .../text/matching/NameUtilMatchingTest.kt | 997 +++++++++--------- .../util/text/matching/NameUtilTest.kt | 91 +- .../text/matching/PinyinMatcherDataTest.kt | 261 ++--- .../text/matching/TypoTolerantMatcherTest.kt | 91 +- 6 files changed, 742 insertions(+), 742 deletions(-) delete mode 100644 platform/util/text-matching/test/com/intellij/platform/util/text/matching/AllOccurrencesMatcherTest.java create mode 100644 platform/util/text-matching/test/com/intellij/platform/util/text/matching/AllOccurrencesMatcherTest.kt diff --git a/platform/util/text-matching/test/com/intellij/platform/util/text/matching/AllOccurrencesMatcherTest.java b/platform/util/text-matching/test/com/intellij/platform/util/text/matching/AllOccurrencesMatcherTest.java deleted file mode 100644 index 37c60937a93f..000000000000 --- a/platform/util/text-matching/test/com/intellij/platform/util/text/matching/AllOccurrencesMatcherTest.java +++ /dev/null @@ -1,24 +0,0 @@ -// 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.openapi.util.TextRange; -import com.intellij.psi.codeStyle.AllOccurrencesMatcher; -import com.intellij.psi.codeStyle.MinusculeMatcher; -import com.intellij.psi.codeStyle.NameUtil; -import org.junit.jupiter.api.Test; - -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertIterableEquals; - -class AllOccurrencesMatcherTest { - @Test - void simpleCase() { - MinusculeMatcher matcher = AllOccurrencesMatcher.create("*fooBar", NameUtil.MatchingCaseSensitivity.NONE, ""); - assertIterableEquals(matcher.matchingFragments("fooBarFooBar"), List.of(new TextRange(0, 6), new TextRange(6, 12))); - assertIterableEquals(matcher.matchingFragments("fooBarFooBuzzBar"), List.of(new TextRange(0, 6), new TextRange(6, 9), new TextRange(13, 16))); - assertIterableEquals(matcher.matchingFragments("fooBarBuzzFoo"), List.of(new TextRange(0, 6))); - assertIterableEquals(matcher.matchingFragments("fooBarBuzzFooBuzzBar"), List.of(new TextRange(0, 6), new TextRange(10, 13), new TextRange(17, 20))); - assertIterableEquals(matcher.matchingFragments("fooBuzzFooBuzzBar"), List.of(new TextRange(0, 3), new TextRange(14, 17))); - } -} \ No newline at end of file diff --git a/platform/util/text-matching/test/com/intellij/platform/util/text/matching/AllOccurrencesMatcherTest.kt b/platform/util/text-matching/test/com/intellij/platform/util/text/matching/AllOccurrencesMatcherTest.kt new file mode 100644 index 000000000000..448408b6dee1 --- /dev/null +++ b/platform/util/text-matching/test/com/intellij/platform/util/text/matching/AllOccurrencesMatcherTest.kt @@ -0,0 +1,20 @@ +// 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.openapi.util.TextRange +import com.intellij.psi.codeStyle.AllOccurrencesMatcher +import com.intellij.psi.codeStyle.NameUtil +import org.junit.jupiter.api.Test +import kotlin.test.assertEquals + +class AllOccurrencesMatcherTest { + @Test + fun simpleCase() { + val matcher = AllOccurrencesMatcher.create("*fooBar", NameUtil.MatchingCaseSensitivity.NONE, "") + assertEquals(matcher.matchingFragments("fooBarFooBar")?.toList(), listOf(TextRange(0, 6), TextRange(6, 12))); + assertEquals(matcher.matchingFragments("fooBarFooBuzzBar")?.toList(), listOf(TextRange(0, 6), TextRange(6, 9), TextRange(13, 16))); + assertEquals(matcher.matchingFragments("fooBarBuzzFoo")?.toList(), listOf(TextRange(0, 6))); + assertEquals(matcher.matchingFragments("fooBarBuzzFooBuzzBar")?.toList(), listOf(TextRange(0, 6), TextRange(10, 13), TextRange(17, 20))); + assertEquals(matcher.matchingFragments("fooBuzzFooBuzzBar")?.toList(), listOf(TextRange(0, 3), TextRange(14, 17))); + } +} \ No newline at end of file diff --git a/platform/util/text-matching/test/com/intellij/platform/util/text/matching/NameUtilMatchingTest.kt b/platform/util/text-matching/test/com/intellij/platform/util/text/matching/NameUtilMatchingTest.kt index 062703380ea0..33732b8bed9e 100644 --- a/platform/util/text-matching/test/com/intellij/platform/util/text/matching/NameUtilMatchingTest.kt +++ b/platform/util/text-matching/test/com/intellij/platform/util/text/matching/NameUtilMatchingTest.kt @@ -1,717 +1,714 @@ // 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 -package com.intellij.platform.util.text.matching; +import com.intellij.openapi.util.TextRange +import com.intellij.psi.codeStyle.AllOccurrencesMatcher.Companion.create +import com.intellij.psi.codeStyle.MinusculeMatcher +import com.intellij.psi.codeStyle.NameUtil +import com.intellij.util.text.Matcher +import org.jetbrains.annotations.NonNls +import org.junit.jupiter.api.Test +import kotlin.test.assertContentEquals +import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertTrue -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.util.text.Matcher; -import org.jetbrains.annotations.NonNls; -import org.junit.jupiter.api.Test; - -import java.util.Arrays; -import java.util.function.ToIntFunction; - -import static org.junit.jupiter.api.Assertions.*; - -public class NameUtilMatchingTest { +class NameUtilMatchingTest { @Test - public void testSimpleCases() { - assertMatches("N", "NameUtilTest"); - assertMatches("NU", "NameUtilTest"); - assertMatches("NUT", "NameUtilTest"); - assertMatches("NaUT", "NameUtilTest"); - assertDoesntMatch("NeUT", "NameUtilTest"); - assertDoesntMatch("NaUTa", "NameUtilTest"); - assertMatches("NaUtT", "NameUtilTest"); - assertMatches("NaUtT", "NameUtilTest"); - assertMatches("NaUtTe", "NameUtilTest"); - assertMatches("AACl", "AAClass"); - assertMatches("ZZZ", "ZZZZZZZZZZ"); + fun testSimpleCases() { + assertMatches("N", "NameUtilTest") + assertMatches("NU", "NameUtilTest") + assertMatches("NUT", "NameUtilTest") + assertMatches("NaUT", "NameUtilTest") + assertDoesntMatch("NeUT", "NameUtilTest") + assertDoesntMatch("NaUTa", "NameUtilTest") + assertMatches("NaUtT", "NameUtilTest") + assertMatches("NaUtT", "NameUtilTest") + assertMatches("NaUtTe", "NameUtilTest") + assertMatches("AACl", "AAClass") + assertMatches("ZZZ", "ZZZZZZZZZZ") } @Test - public void testEmptyPrefix() { - assertMatches("", ""); - assertMatches("", "asdfs"); + fun testEmptyPrefix() { + assertMatches("", "") + assertMatches("", "asdfs") } @Test - public void testSkipWords() { - assertMatches("nt", "NameUtilTest"); - assertMatches("repl map", "ReplacePathToMacroMap"); - assertMatches("replmap", "ReplacePathToMacroMap"); - assertMatches("CertificateEx", "CertificateEncodingException"); - assertDoesntMatch("ABCD", "AbstractButton.DISABLED_ICON_CHANGED_PROPERTY"); + fun testSkipWords() { + assertMatches("nt", "NameUtilTest") + assertMatches("repl map", "ReplacePathToMacroMap") + assertMatches("replmap", "ReplacePathToMacroMap") + assertMatches("CertificateEx", "CertificateEncodingException") + assertDoesntMatch("ABCD", "AbstractButton.DISABLED_ICON_CHANGED_PROPERTY") - assertMatches("templipa", "template_impl_template_list_panel"); - assertMatches("templistpa", "template_impl_template_list_panel"); + assertMatches("templipa", "template_impl_template_list_panel") + assertMatches("templistpa", "template_impl_template_list_panel") } @Test - public void testSimpleCasesWithFirstLowercased() { - assertMatches("N", "nameUtilTest"); - assertDoesntMatch("N", "anameUtilTest"); - assertMatches("NU", "nameUtilTest"); - assertDoesntMatch("NU", "anameUtilTest"); - assertMatches("NUT", "nameUtilTest"); - assertMatches("NaUT", "nameUtilTest"); - assertDoesntMatch("NeUT", "nameUtilTest"); - assertDoesntMatch("NaUTa", "nameUtilTest"); - assertMatches("NaUtT", "nameUtilTest"); - assertMatches("NaUtT", "nameUtilTest"); - assertMatches("NaUtTe", "nameUtilTest"); + fun testSimpleCasesWithFirstLowercased() { + assertMatches("N", "nameUtilTest") + assertDoesntMatch("N", "anameUtilTest") + assertMatches("NU", "nameUtilTest") + assertDoesntMatch("NU", "anameUtilTest") + assertMatches("NUT", "nameUtilTest") + assertMatches("NaUT", "nameUtilTest") + assertDoesntMatch("NeUT", "nameUtilTest") + assertDoesntMatch("NaUTa", "nameUtilTest") + assertMatches("NaUtT", "nameUtilTest") + assertMatches("NaUtT", "nameUtilTest") + assertMatches("NaUtTe", "nameUtilTest") } @Test - public void testSpaceDelimiters() { - assertMatches("Na Ut Te", "name util test"); - assertMatches("Na Ut Te", "name Util Test"); - assertDoesntMatch("Na Ut Ta", "name Util Test"); - assertMatches("na ut te", "name util test"); + fun testSpaceDelimiters() { + assertMatches("Na Ut Te", "name util test") + assertMatches("Na Ut Te", "name Util Test") + assertDoesntMatch("Na Ut Ta", "name Util Test") + assertMatches("na ut te", "name util test") - assertMatches("na ut", "name_util_test"); - assertMatches("na te", "name_util_test"); - assertDoesntMatch("na ti", "name_util_test"); + assertMatches("na ut", "name_util_test") + assertMatches("na te", "name_util_test") + assertDoesntMatch("na ti", "name_util_test") - assertDoesntMatch("alias imple", "alias simple"); - assertDoesntMatch("alias mple", "alias simple"); - assertDoesntMatch("alias nother", "alias another"); + assertDoesntMatch("alias imple", "alias simple") + assertDoesntMatch("alias mple", "alias simple") + assertDoesntMatch("alias nother", "alias another") } @Test - public void testXMLCompletion() { - assertDoesntMatch("N_T", "NameUtilTest"); - assertMatches("ORGS_ACC", "ORGS_POSITION_ACCOUNTABILITY"); - assertMatches("ORGS-ACC", "ORGS-POSITION_ACCOUNTABILITY"); - assertMatches("ORGS.ACC", "ORGS.POSITION_ACCOUNTABILITY"); + fun testXMLCompletion() { + assertDoesntMatch("N_T", "NameUtilTest") + assertMatches("ORGS_ACC", "ORGS_POSITION_ACCOUNTABILITY") + assertMatches("ORGS-ACC", "ORGS-POSITION_ACCOUNTABILITY") + assertMatches("ORGS.ACC", "ORGS.POSITION_ACCOUNTABILITY") } @Test - public void testStarFalsePositive() { - assertDoesntMatch("ar*l*p", "AbstractResponseHandler"); + fun 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"); + fun testUnderscoreStyle() { + assertMatches("N_U_T", "NAME_UTIL_TEST") + assertMatches("NUT", "NAME_UTIL_TEST") + assertDoesntMatch("NUT", "NameutilTest") } @Test - public void testAllUppercase() { - assertMatches("NOS", "NetOutputStream"); + fun testAllUppercase() { + assertMatches("NOS", "NetOutputStream") } @Test - public void testCommonFileNameConventions() { + fun testCommonFileNameConventions() { // See IDEADEV-12310 - assertMatches("BLWN", "base_layout_without_navigation.xhtml"); - assertMatches("BLWN", "base-layout-without-navigation.xhtml"); - assertMatches("FC", "faces-config.xml"); - assertMatches("ARS", "activity_report_summary.jsp"); - assertMatches("AD", "arrow_down.gif"); - assertMatches("VL", "vehicle-listings.css"); + assertMatches("BLWN", "base_layout_without_navigation.xhtml") + assertMatches("BLWN", "base-layout-without-navigation.xhtml") + assertMatches("FC", "faces-config.xml") + assertMatches("ARS", "activity_report_summary.jsp") + assertMatches("AD", "arrow_down.gif") + assertMatches("VL", "vehicle-listings.css") - assertMatches("ARS.j", "activity_report_summary.jsp"); - assertDoesntMatch("ARS.j", "activity_report_summary.xml"); - assertDoesntMatch("ARS.j", "activity_report_summary_justsometingwrong.xml"); + assertMatches("ARS.j", "activity_report_summary.jsp") + assertDoesntMatch("ARS.j", "activity_report_summary.xml") + assertDoesntMatch("ARS.j", "activity_report_summary_justsometingwrong.xml") - assertMatches("foo.goo", "foo.bar.goo"); - assertDoesntMatch("*.ico", "sm.th.iks.concierge"); + assertMatches("foo.goo", "foo.bar.goo") + assertDoesntMatch("*.ico", "sm.th.iks.concierge") } @Test - public void testSpaceForAnyWordsInBetween() { - assertMatches("fo bar", "fooBar"); - assertMatches("foo bar", "fooBar"); - assertMatches("foo bar", "fooGooBar"); - assertMatches("foo bar", "fooGoo bar"); - assertDoesntMatch(" b", "fbi"); - assertDoesntMatch(" for", "performAction"); - assertTrue(caseInsensitiveMatcher(" us").matches("getUsage")); - assertTrue(caseInsensitiveMatcher(" us").matches("getMyUsage")); + fun testSpaceForAnyWordsInBetween() { + assertMatches("fo bar", "fooBar") + assertMatches("foo bar", "fooBar") + assertMatches("foo bar", "fooGooBar") + assertMatches("foo bar", "fooGoo bar") + assertDoesntMatch(" b", "fbi") + assertDoesntMatch(" for", "performAction") + assertTrue(caseInsensitiveMatcher(" us").matches("getUsage")) + 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"); - assertMatches("Google .html", "Google Test Test.cc.html"); - assertMatches("Google Test*.html", "Google Test Test.cc.html"); - } - - private static MinusculeMatcher caseInsensitiveMatcher(String pattern) { - return NameUtil.buildMatcher(pattern, NameUtil.MatchingCaseSensitivity.NONE); + fun testFilenamesWithDotsAndSpaces() { + assertMatches("Google Test.html", "Google Test Test.cc.html") + assertMatches("Google.html", "Google Test Test.cc.html") + assertMatches("Google .html", "Google Test Test.cc.html") + assertMatches("Google Test*.html", "Google Test Test.cc.html") } @Test - public void testStartDot() { - assertMatches("A*.html", "A.html"); - assertMatches("A*.html", "Abc.html"); - assertMatches("A*.html", "after.html"); - assertDoesntMatch("A*.html", "10_after.html"); + fun testStartDot() { + assertMatches("A*.html", "A.html") + assertMatches("A*.html", "Abc.html") + assertMatches("A*.html", "after.html") + assertDoesntMatch("A*.html", "10_after.html") } @Test - public void testIDEADEV15503() { - assertMatches("AR.jsp", "add_relationship.jsp"); - assertMatches("AR.jsp", "advanced_rule.jsp"); - assertMatches("AR.jsp", "alarm_reduction.jsp"); - assertMatches("AR.jsp", "audiot_report.jsp"); - assertMatches("AR.jsp", "audiot_r.jsp"); + fun testIDEADEV15503() { + assertMatches("AR.jsp", "add_relationship.jsp") + assertMatches("AR.jsp", "advanced_rule.jsp") + assertMatches("AR.jsp", "alarm_reduction.jsp") + assertMatches("AR.jsp", "audiot_report.jsp") + assertMatches("AR.jsp", "audiot_r.jsp") - assertMatches("AR.jsp", "alarm_rule_action.jsp"); - assertMatches("AR.jsp", "alarm_rule_admin.jsp"); - assertMatches("AR.jsp", "alarm_rule_administration.jsp"); - assertMatches("AR.jsp", "alarm_rule_controller.jsp"); - assertMatches("AR.jsp", "alarm_rule_frame.jsp"); - assertMatches("AR.jsp", "alarm_rule_severity.jsp"); + assertMatches("AR.jsp", "alarm_rule_action.jsp") + assertMatches("AR.jsp", "alarm_rule_admin.jsp") + assertMatches("AR.jsp", "alarm_rule_administration.jsp") + assertMatches("AR.jsp", "alarm_rule_controller.jsp") + assertMatches("AR.jsp", "alarm_rule_frame.jsp") + assertMatches("AR.jsp", "alarm_rule_severity.jsp") - assertMatches("AR.jsp", "AddRelationship.jsp"); - assertMatches("AR.jsp", "AdvancedRule.jsp"); - assertMatches("AR.jsp", "AlarmReduction.jsp"); - assertMatches("AR.jsp", "AudiotReport.jsp"); - assertMatches("AR.jsp", "AudiotR.jsp"); + assertMatches("AR.jsp", "AddRelationship.jsp") + assertMatches("AR.jsp", "AdvancedRule.jsp") + assertMatches("AR.jsp", "AlarmReduction.jsp") + assertMatches("AR.jsp", "AudiotReport.jsp") + assertMatches("AR.jsp", "AudiotR.jsp") - assertMatches("AR.jsp", "AlarmRuleAction.jsp"); - assertMatches("AR.jsp", "AlarmRuleAdmin.jsp"); - assertMatches("AR.jsp", "AlarmRuleAdministration.jsp"); - assertMatches("AR.jsp", "AlarmRuleController.jsp"); - assertMatches("AR.jsp", "AlarmRuleFrame.jsp"); - assertMatches("AR.jsp", "AlarmRuleSeverity.jsp"); + assertMatches("AR.jsp", "AlarmRuleAction.jsp") + assertMatches("AR.jsp", "AlarmRuleAdmin.jsp") + assertMatches("AR.jsp", "AlarmRuleAdministration.jsp") + assertMatches("AR.jsp", "AlarmRuleController.jsp") + assertMatches("AR.jsp", "AlarmRuleFrame.jsp") + assertMatches("AR.jsp", "AlarmRuleSeverity.jsp") } @Test - public void testSkipDot() { - assertMatches("ja", "jquery.autocomplete.js"); - assertDoesntMatch("ja.js", "jquery.autocomplete.js"); - assertMatches("jajs", "jquery.autocomplete.js"); - assertMatches("jjs", "jquery.autocomplete.js"); - assertMatches("j.js", "jquery.autocomplete.js"); - assertDoesntMatch("j.ajs", "jquery.autocomplete.js"); - assertMatches("oracle.bnf", "oracle-11.2.bnf"); - assertMatches("*foo.*bar", "foo.b.bar"); + fun testSkipDot() { + assertMatches("ja", "jquery.autocomplete.js") + assertDoesntMatch("ja.js", "jquery.autocomplete.js") + assertMatches("jajs", "jquery.autocomplete.js") + assertMatches("jjs", "jquery.autocomplete.js") + assertMatches("j.js", "jquery.autocomplete.js") + assertDoesntMatch("j.ajs", "jquery.autocomplete.js") + assertMatches("oracle.bnf", "oracle-11.2.bnf") + assertMatches("*foo.*bar", "foo.b.bar") } @Test - public void testNoExtension() { - assertMatches("#.p", "#.php"); - assertMatches("#", "#.php"); - assertMatches("a", "a.php"); + fun testNoExtension() { + assertMatches("#.p", "#.php") + assertMatches("#", "#.php") + assertMatches("a", "a.php") } @Test - public void testIgnoreCaseWhenCompleteMatch() { - assertMatches("comboBox", "combobox"); - assertMatches("combobox", "comboBox"); + fun testIgnoreCaseWhenCompleteMatch() { + assertMatches("comboBox", "combobox") + assertMatches("combobox", "comboBox") } @Test - public void testStartsWithDot() { - assertMatches(".foo", ".foo"); + fun testStartsWithDot() { + assertMatches(".foo", ".foo") } @Test - public void testProperDotEscaping() { - assertMatches("*inspection*.pro", "InspectionsBundle.properties"); - assertDoesntMatch("*inspection*.pro", "InspectionsInProgress.png"); + fun 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"); - assertMatches("_form", "__form"); - assertTrue(firstLetterMatcher("_form").matches("__form")); + fun testLeadingUnderscore() { + assertDoesntMatch("form", "_form.html.erb") + assertMatches("_form", "_form.html.erb") + assertMatches("_form", "__form") + assertTrue(firstLetterMatcher("_form").matches("__form")) } @Test - public void testLowerCaseWords() { - assertMatches("uct", "unit_controller_test"); - assertMatches("unictest", "unit_controller_test"); - assertMatches("uc", "unit_controller_test"); - assertDoesntMatch("nc", "unit_controller_test"); - assertDoesntMatch("utc", "unit_controller_test"); + fun testLowerCaseWords() { + assertMatches("uct", "unit_controller_test") + assertMatches("unictest", "unit_controller_test") + assertMatches("uc", "unit_controller_test") + assertDoesntMatch("nc", "unit_controller_test") + assertDoesntMatch("utc", "unit_controller_test") } @Test - public void testObjectiveCCases() { - assertMatches("h*:", "h:aaa"); - assertMatches("h:", "h:aaa"); - assertMatches("text:sh", "textField:shouldChangeCharactersInRange:replacementString:"); - assertMatches("abc", "aaa:bbb:ccc"); - assertMatches("textField:sh", "textField:shouldChangeCharactersInRange:replacementString:"); - assertMatches("text*:sh", "textField:shouldChangeCharactersInRange:replacementString:"); + fun testObjectiveCCases() { + assertMatches("h*:", "h:aaa") + assertMatches("h:", "h:aaa") + assertMatches("text:sh", "textField:shouldChangeCharactersInRange:replacementString:") + assertMatches("abc", "aaa:bbb:ccc") + assertMatches("textField:sh", "textField:shouldChangeCharactersInRange:replacementString:") + assertMatches("text*:sh", "textField:shouldChangeCharactersInRange:replacementString:") } @Test - public void testMiddleMatchingMinimumTwoConsecutiveLettersInWordMiddle() { - assertMatches("*fo", "reformat"); - assertMatches("*f", "reFormat"); - assertMatches("*f", "format"); - assertMatches("*f", "Format"); - assertMatches("*Stri", "string"); - assertMatches("*f", "reformat"); - assertMatches("*f", "reformatCode"); - assertDoesntMatch("*fc", "reformatCode"); - assertDoesntMatch("*foc", "reformatCode"); - assertMatches("*forc", "reformatCode"); - assertDoesntMatch("*sTC", "LazyClassTypeConstructor"); + fun testMiddleMatchingMinimumTwoConsecutiveLettersInWordMiddle() { + assertMatches("*fo", "reformat") + assertMatches("*f", "reFormat") + assertMatches("*f", "format") + assertMatches("*f", "Format") + assertMatches("*Stri", "string") + assertMatches("*f", "reformat") + assertMatches("*f", "reformatCode") + assertDoesntMatch("*fc", "reformatCode") + assertDoesntMatch("*foc", "reformatCode") + assertMatches("*forc", "reformatCode") + assertDoesntMatch("*sTC", "LazyClassTypeConstructor") - assertDoesntMatch("*Icon", "LEADING_CONSTRUCTOR"); - assertMatches("*I", "LEADING_CONSTRUCTOR"); - assertMatches("*i", "LEADING_CONSTRUCTOR"); - assertMatches("*in", "LEADING_CONSTRUCTOR"); - assertMatches("*ing", "LEADING_CONSTRUCTOR"); - assertDoesntMatch("*inc", "LEADING_CONSTRUCTOR"); - assertDoesntMatch("*ico", "drawLinePickedOut"); - - assertMatches("*l", "AppDelegate"); - assertMatches("*le", "AppDelegate"); - assertMatches("*leg", "AppDelegate"); + assertDoesntMatch("*Icon", "LEADING_CONSTRUCTOR") + assertMatches("*I", "LEADING_CONSTRUCTOR") + assertMatches("*i", "LEADING_CONSTRUCTOR") + assertMatches("*in", "LEADING_CONSTRUCTOR") + assertMatches("*ing", "LEADING_CONSTRUCTOR") + assertDoesntMatch("*inc", "LEADING_CONSTRUCTOR") + assertDoesntMatch("*ico", "drawLinePickedOut") + assertMatches("*l", "AppDelegate") + assertMatches("*le", "AppDelegate") + assertMatches("*leg", "AppDelegate") } @Test - public void testMiddleMatchingUnderscore() { - assertMatches("*_dark", "collapseAll_dark.png"); - assertMatches("*_dark.png", "collapseAll_dark.png"); - assertMatches("**_dark.png", "collapseAll_dark.png"); - assertTrue(firstLetterMatcher("*_DARK").matches("A_DARK.png")); + fun testMiddleMatchingUnderscore() { + assertMatches("*_dark", "collapseAll_dark.png") + assertMatches("*_dark.png", "collapseAll_dark.png") + assertMatches("**_dark.png", "collapseAll_dark.png") + assertTrue(firstLetterMatcher("*_DARK").matches("A_DARK.png")) } @Test - public void testMiddleMatching() { - assertMatches("*zz*", "ListConfigzzKey"); - assertMatches("*zz", "ListConfigzzKey"); - assertTrue(caseInsensitiveMatcher("*old").matches("folder")); - assertMatches("SWU*H*7", "SWUpgradeHdlrFSPR7Test"); - assertMatches("SWU*H*R", "SWUpgradeHdlrFSPR7Test"); - assertMatches("SWU*H*R", "SWUPGRADEHDLRFSPR7TEST"); - assertMatches("*git", "GitBlaBla"); - assertMatches("*Git", "GitBlaBla"); - assertDoesntMatch("*get*A", "getClass"); - assertMatches("*git", "BlaGitBla"); - assertMatches("*Git", "BlaGitBla"); - assertTrue(firstLetterMatcher("*Git").matches("BlagitBla")); - assertMatches("*git", "BlagitBla"); - assertMatches("*Git*", "AtpGenerationItem"); - assertMatches("Collec*Util*", "CollectionUtils"); - assertMatches("Collec*Util*", "CollectionUtilsTest"); - assertTrue(caseInsensitiveMatcher("*us").matches("usage")); - assertTrue(caseInsensitiveMatcher(" us").matches("usage")); - assertTrue(caseInsensitiveMatcher(" fo. ba").matches("getFoo.getBar")); - assertMatches(" File. sepa", "File.separator"); - assertMatches(" File. sepa", "File._separator"); - assertMatches(" File. _sepa", "File._separator"); - assertMatches(" _fo", "_foo"); - assertMatches("*BComp", "BaseComponent"); + fun testMiddleMatching() { + assertMatches("*zz*", "ListConfigzzKey") + assertMatches("*zz", "ListConfigzzKey") + assertTrue(caseInsensitiveMatcher("*old").matches("folder")) + assertMatches("SWU*H*7", "SWUpgradeHdlrFSPR7Test") + assertMatches("SWU*H*R", "SWUpgradeHdlrFSPR7Test") + assertMatches("SWU*H*R", "SWUPGRADEHDLRFSPR7TEST") + assertMatches("*git", "GitBlaBla") + assertMatches("*Git", "GitBlaBla") + assertDoesntMatch("*get*A", "getClass") + assertMatches("*git", "BlaGitBla") + assertMatches("*Git", "BlaGitBla") + assertTrue(firstLetterMatcher("*Git").matches("BlagitBla")) + assertMatches("*git", "BlagitBla") + assertMatches("*Git*", "AtpGenerationItem") + assertMatches("Collec*Util*", "CollectionUtils") + assertMatches("Collec*Util*", "CollectionUtilsTest") + assertTrue(caseInsensitiveMatcher("*us").matches("usage")) + assertTrue(caseInsensitiveMatcher(" us").matches("usage")) + assertTrue(caseInsensitiveMatcher(" fo. ba").matches("getFoo.getBar")) + assertMatches(" File. sepa", "File.separator") + assertMatches(" File. sepa", "File._separator") + assertMatches(" File. _sepa", "File._separator") + assertMatches(" _fo", "_foo") + assertMatches("*BComp", "BaseComponent") } @Test - public void testUppercasePrefixWithMiddleMatching() { - assertMatches("*OS", "ios"); - assertMatches("*OS", "IOS"); - assertMatches("*OS", "osx"); - assertMatches("*OS", "OSX"); + fun testUppercasePrefixWithMiddleMatching() { + assertMatches("*OS", "ios") + assertMatches("*OS", "IOS") + assertMatches("*OS", "osx") + assertMatches("*OS", "OSX") - assertTrue(firstLetterMatcher("*I").matches("ID")); - assertFalse(firstLetterMatcher("*I").matches("id")); + assertTrue(firstLetterMatcher("*I").matches("ID")) + assertFalse(firstLetterMatcher("*I").matches("id")) } @Test - public void testAsteriskEndingInsideUppercaseWord() { - assertMatches("*LRUMap", "SLRUMap"); + fun testAsteriskEndingInsideUppercaseWord() { + assertMatches("*LRUMap", "SLRUMap") } @Test - public void testMiddleMatchingFirstLetterSensitive() { - assertTrue(firstLetterMatcher(" cl").matches("getClass")); - assertFalse(firstLetterMatcher(" EUC-").matches("x-EUC-TW")); - assertTrue(firstLetterMatcher(" a").matches("aaa")); - assertFalse(firstLetterMatcher(" a").matches("Aaa")); - assertFalse(firstLetterMatcher(" a").matches("Aaa")); - assertFalse(firstLetterMatcher(" _bl").matches("_top")); - assertFalse(firstLetterMatcher("*Ch").matches("char")); - assertTrue(firstLetterMatcher("*Codes").matches("CFLocaleCopyISOCountryCodes")); - assertFalse(firstLetterMatcher("*codes").matches("CFLocaleCopyISOCountryCodes")); - assertTrue(firstLetterMatcher("*codes").matches("getCFLocaleCopyISOCountryCodes")); - assertTrue(firstLetterMatcher("*Bcomp").matches("BaseComponent")); + fun testMiddleMatchingFirstLetterSensitive() { + assertTrue(firstLetterMatcher(" cl").matches("getClass")) + assertFalse(firstLetterMatcher(" EUC-").matches("x-EUC-TW")) + assertTrue(firstLetterMatcher(" a").matches("aaa")) + assertFalse(firstLetterMatcher(" a").matches("Aaa")) + assertFalse(firstLetterMatcher(" a").matches("Aaa")) + assertFalse(firstLetterMatcher(" _bl").matches("_top")) + assertFalse(firstLetterMatcher("*Ch").matches("char")) + assertTrue(firstLetterMatcher("*Codes").matches("CFLocaleCopyISOCountryCodes")) + assertFalse(firstLetterMatcher("*codes").matches("CFLocaleCopyISOCountryCodes")) + assertTrue(firstLetterMatcher("*codes").matches("getCFLocaleCopyISOCountryCodes")) + assertTrue(firstLetterMatcher("*Bcomp").matches("BaseComponent")) } @Test - public void testPreferCamelHumpsToAllUppers() { - assertPreference("ProVi", "PROVIDER", "ProjectView"); - } - - private static Matcher firstLetterMatcher(String pattern) { - return NameUtil.buildMatcher(pattern, NameUtil.MatchingCaseSensitivity.FIRST_LETTER); + fun testPreferCamelHumpsToAllUppers() { + assertPreference("ProVi", "PROVIDER", "ProjectView") } @Test - public void testSpaceInCompletionPrefix() { - assertTrue(caseInsensitiveMatcher("create ").matches("create module")); + fun testSpaceInCompletionPrefix() { + assertTrue(caseInsensitiveMatcher("create ").matches("create module")) } @Test - public void testLong() { + fun testLong() { assertMatches("Product.findByDateAndNameGreaterThanEqualsAndQualityGreaterThanEqual", - "Product.findByDateAndNameGreaterThanEqualsAndQualityGreaterThanEqualsIntellijIdeaRulezzz"); - } - - 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 + "!!!"); + "Product.findByDateAndNameGreaterThanEqualsAndQualityGreaterThanEqualsIntellijIdeaRulezzz") } @Test - public void testUpperCaseMatchesLowerCase() { - assertMatches("ABC_B.C", "abc_b.c"); + fun testUpperCaseMatchesLowerCase() { + assertMatches("ABC_B.C", "abc_b.c") } @Test - public void testLowerCaseHumps() { - assertMatches("foo", "foo"); - assertDoesntMatch("foo", "fxoo"); - assertMatches("foo", "fOo"); - assertMatches("foo", "fxOo"); - assertMatches("foo", "fXOo"); - assertMatches("fOo", "foo"); - assertDoesntMatch("fOo", "FaOaOaXXXX"); - assertMatches("ncdfoe", "NoClassDefFoundException"); - assertMatches("fob", "FOO_BAR"); - assertMatches("fo_b", "FOO_BAR"); - assertMatches("fob", "FOO BAR"); - assertMatches("fo b", "FOO BAR"); - assertMatches("AACl", "AAClass"); - assertMatches("ZZZ", "ZZZZZZZZZZ"); - assertMatches("em", "emptyList"); - assertMatches("bui", "BuildConfig.groovy"); - assertMatches("buico", "BuildConfig.groovy"); - assertMatches("buico.gr", "BuildConfig.groovy"); - assertMatches("bui.gr", "BuildConfig.groovy"); - assertMatches("*fz", "azzzfzzz"); + fun testLowerCaseHumps() { + assertMatches("foo", "foo") + assertDoesntMatch("foo", "fxoo") + assertMatches("foo", "fOo") + assertMatches("foo", "fxOo") + assertMatches("foo", "fXOo") + assertMatches("fOo", "foo") + assertDoesntMatch("fOo", "FaOaOaXXXX") + assertMatches("ncdfoe", "NoClassDefFoundException") + assertMatches("fob", "FOO_BAR") + assertMatches("fo_b", "FOO_BAR") + assertMatches("fob", "FOO BAR") + assertMatches("fo b", "FOO BAR") + assertMatches("AACl", "AAClass") + assertMatches("ZZZ", "ZZZZZZZZZZ") + assertMatches("em", "emptyList") + assertMatches("bui", "BuildConfig.groovy") + assertMatches("buico", "BuildConfig.groovy") + assertMatches("buico.gr", "BuildConfig.groovy") + assertMatches("bui.gr", "BuildConfig.groovy") + assertMatches("*fz", "azzzfzzz") - assertMatches("WebLogic", "Weblogic"); - assertMatches("WebLOgic", "WebLogic"); - assertMatches("WEbLogic", "WebLogic"); - assertDoesntMatch("WebLogic", "Webologic"); + assertMatches("WebLogic", "Weblogic") + assertMatches("WebLOgic", "WebLogic") + assertMatches("WEbLogic", "WebLogic") + assertDoesntMatch("WebLogic", "Webologic") - assertMatches("Wlo", "WebLogic"); + assertMatches("Wlo", "WebLogic") } @Test - public void testFinalSpace() { - assertMatches("a ", "alpha + beta"); - assertMatches("a ", "a "); - assertMatches("a ", "a"); - assertMatches("GrDebT ", "GroovyDebuggerTest"); - assertDoesntMatch("grdebT ", "GroovyDebuggerTest"); - assertDoesntMatch("grdebt ", "GroovyDebuggerTest"); - assertMatches("Foo ", "Foo"); - assertDoesntMatch("Foo ", "FooBar"); - assertDoesntMatch("Foo ", "Foox"); - assertDoesntMatch("Collections ", "CollectionSplitter"); - assertMatches("CollectionS ", "CollectionSplitter"); - assertMatches("*run ", "in Runnable.run"); + fun testFinalSpace() { + assertMatches("a ", "alpha + beta") + assertMatches("a ", "a ") + assertMatches("a ", "a") + assertMatches("GrDebT ", "GroovyDebuggerTest") + assertDoesntMatch("grdebT ", "GroovyDebuggerTest") + assertDoesntMatch("grdebt ", "GroovyDebuggerTest") + assertMatches("Foo ", "Foo") + assertDoesntMatch("Foo ", "FooBar") + assertDoesntMatch("Foo ", "Foox") + assertDoesntMatch("Collections ", "CollectionSplitter") + assertMatches("CollectionS ", "CollectionSplitter") + assertMatches("*run ", "in Runnable.run") - assertDoesntMatch("*l ", "AppDelegate"); - assertDoesntMatch("*le ", "AppDelegate"); - assertDoesntMatch("*leg ", "AppDelegate"); + assertDoesntMatch("*l ", "AppDelegate") + assertDoesntMatch("*le ", "AppDelegate") + assertDoesntMatch("*leg ", "AppDelegate") } @Test - public void testDigits() { - assertMatches("foba4", "FooBar4"); - assertMatches("foba", "Foo4Bar"); - assertMatches("*TEST-* ", "TEST-001"); - assertMatches("*TEST-0* ", "TEST-001"); - assertMatches("*v2 ", "VARCHAR2"); - assertMatches("smart8co", "SmartType18CompletionTest"); - assertMatches("smart8co", "smart18completion"); + fun testDigits() { + assertMatches("foba4", "FooBar4") + assertMatches("foba", "Foo4Bar") + assertMatches("*TEST-* ", "TEST-001") + assertMatches("*TEST-0* ", "TEST-001") + assertMatches("*v2 ", "VARCHAR2") + assertMatches("smart8co", "SmartType18CompletionTest") + assertMatches("smart8co", "smart18completion") } @Test - public void testDoNotAllowDigitsBetweenMatchingDigits() { - assertDoesntMatch("*012", "001122"); - assertMatches("012", "0a1_22"); + fun testDoNotAllowDigitsBetweenMatchingDigits() { + assertDoesntMatch("*012", "001122") + assertMatches("012", "0a1_22") } @Test - public void testSpecialSymbols() { - assertMatches("a@b", "a@bc"); - assertDoesntMatch("*@in", "a int"); + fun testSpecialSymbols() { + assertMatches("a@b", "a@bc") + assertDoesntMatch("*@in", "a int") - assertMatches("a/text", "a/Text"); - assertMatches("a/text", "a/bbbText"); + assertMatches("a/text", "a/Text") + assertMatches("a/text", "a/bbbText") } @Test - public void testMinusculeFirstLetter() { - assertTrue(firstLetterMatcher("WebLogic").matches("WebLogic")); - assertFalse(firstLetterMatcher("webLogic").matches("WebLogic")); - assertTrue(firstLetterMatcher("cL").matches("class")); - assertTrue(firstLetterMatcher("CL").matches("Class")); - assertTrue(firstLetterMatcher("Cl").matches("CoreLoader")); - assertFalse(firstLetterMatcher("abc").matches("_abc")); + fun testMinusculeFirstLetter() { + assertTrue(firstLetterMatcher("WebLogic").matches("WebLogic")) + assertFalse(firstLetterMatcher("webLogic").matches("WebLogic")) + assertTrue(firstLetterMatcher("cL").matches("class")) + assertTrue(firstLetterMatcher("CL").matches("Class")) + assertTrue(firstLetterMatcher("Cl").matches("CoreLoader")) + 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")); - assertFalse(NameUtil.buildMatcher("FOO", NameUtil.MatchingCaseSensitivity.ALL).matches("foo")); - assertFalse(NameUtil.buildMatcher("foo", NameUtil.MatchingCaseSensitivity.ALL).matches("fOO")); - assertFalse(NameUtil.buildMatcher("Wl", NameUtil.MatchingCaseSensitivity.ALL).matches("WebLogic")); - assertTrue(NameUtil.buildMatcher("WL", NameUtil.MatchingCaseSensitivity.ALL).matches("WebLogic")); - assertFalse(NameUtil.buildMatcher("WL", NameUtil.MatchingCaseSensitivity.ALL).matches("Weblogic")); - assertFalse(NameUtil.buildMatcher("WL", NameUtil.MatchingCaseSensitivity.ALL).matches("weblogic")); - assertFalse(NameUtil.buildMatcher("webLogic", NameUtil.MatchingCaseSensitivity.ALL).matches("WebLogic")); - assertFalse(NameUtil.buildMatcher("Str", NameUtil.MatchingCaseSensitivity.ALL).matches("SomeThingRidiculous")); - assertFalse(NameUtil.buildMatcher("*list*", NameUtil.MatchingCaseSensitivity.ALL).matches("List")); - assertFalse(NameUtil.buildMatcher("*list*", NameUtil.MatchingCaseSensitivity.ALL).matches("AbstractList")); - assertFalse(NameUtil.buildMatcher("java.util.list", NameUtil.MatchingCaseSensitivity.ALL).matches("java.util.List")); - assertFalse(NameUtil.buildMatcher("java.util.list", NameUtil.MatchingCaseSensitivity.ALL).matches("java.util.AbstractList")); + fun testMinusculeAllImportant() { + assertTrue(NameUtil.buildMatcher("WebLogic", NameUtil.MatchingCaseSensitivity.ALL).matches("WebLogic")) + assertFalse(NameUtil.buildMatcher("webLogic", NameUtil.MatchingCaseSensitivity.ALL).matches("weblogic")) + assertFalse(NameUtil.buildMatcher("FOO", NameUtil.MatchingCaseSensitivity.ALL).matches("foo")) + assertFalse(NameUtil.buildMatcher("foo", NameUtil.MatchingCaseSensitivity.ALL).matches("fOO")) + assertFalse(NameUtil.buildMatcher("Wl", NameUtil.MatchingCaseSensitivity.ALL).matches("WebLogic")) + assertTrue(NameUtil.buildMatcher("WL", NameUtil.MatchingCaseSensitivity.ALL).matches("WebLogic")) + assertFalse(NameUtil.buildMatcher("WL", NameUtil.MatchingCaseSensitivity.ALL).matches("Weblogic")) + assertFalse(NameUtil.buildMatcher("WL", NameUtil.MatchingCaseSensitivity.ALL).matches("weblogic")) + assertFalse(NameUtil.buildMatcher("webLogic", NameUtil.MatchingCaseSensitivity.ALL).matches("WebLogic")) + assertFalse(NameUtil.buildMatcher("Str", NameUtil.MatchingCaseSensitivity.ALL).matches("SomeThingRidiculous")) + assertFalse(NameUtil.buildMatcher("*list*", NameUtil.MatchingCaseSensitivity.ALL).matches("List")) + assertFalse(NameUtil.buildMatcher("*list*", NameUtil.MatchingCaseSensitivity.ALL).matches("AbstractList")) + assertFalse(NameUtil.buildMatcher("java.util.list", NameUtil.MatchingCaseSensitivity.ALL).matches("java.util.List")) + 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 - 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))); + fun testMatchingFragments() { + @NonNls var sample = "NoClassDefFoundException" + // 0 2 7 10 15 21 + assertContentEquals(NameUtil.buildMatcher("ncldfou*ion", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), + listOf(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"; + sample = "doGet(HttpServletRequest, HttpServletResponse):void" // 0 22 - 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))); + assertContentEquals(NameUtil.buildMatcher("d*st", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), + listOf(TextRange.from(0, 1), TextRange.from(22, 2))) + assertContentEquals(NameUtil.buildMatcher("doge*st", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), + listOf(TextRange.from(0, 4), TextRange.from(22, 2))) - sample = "_test"; - 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))); + sample = "_test" + assertContentEquals(NameUtil.buildMatcher("_", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), + listOf(TextRange.from(0, 1))) + assertContentEquals(NameUtil.buildMatcher("_t", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), + listOf(TextRange.from(0, 2))) } @Test - public void testMatchingFragmentsSorted() { - @NonNls String sample = "SWUPGRADEHDLRFSPR7TEST"; - // 0 9 12 - 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))); + fun testMatchingFragmentsSorted() { + @NonNls val sample = "SWUPGRADEHDLRFSPR7TEST" + // 0 9 12 + assertContentEquals(NameUtil.buildMatcher("SWU*H*R", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), + listOf(TextRange.from(0, 3), TextRange.from(9, 1), TextRange.from(12, 1))) } @Test - public void testPreferCapsMatching() { - String sample = "getCurrentUser"; - // 0 4 10 - assertIterableEquals(NameUtil.buildMatcher("getCU", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), - Arrays.asList(TextRange.from(0, 4), TextRange.from(10, 1))); + fun testPreferCapsMatching() { + val sample = "getCurrentUser" + // 0 4 10 + assertContentEquals(NameUtil.buildMatcher("getCU", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), + listOf(TextRange.from(0, 4), TextRange.from(10, 1))) } @Test - public void testPlusOrMinusInThePatternShouldAllowToBeSpaceSurrounded() { - assertMatches("a+b", "alpha+beta"); - assertMatches("a+b", "alpha_gamma+beta"); - assertMatches("a+b", "alpha + beta"); - assertMatches("Foo+", "Foo+Bar.txt"); - assertMatches("Foo+", "Foo + Bar.txt"); - assertMatches("a", "alpha+beta"); - assertMatches("*b", "alpha+beta"); - assertMatches("a + b", "alpha+beta"); - assertMatches("a+", "alpha+beta"); - assertDoesntMatch("a ", "alpha+beta"); - assertMatches("", "alpha+beta"); - assertMatches("*+ b", "alpha+beta"); - assertDoesntMatch("d+g", "alphaDelta+betaGamma"); - assertMatches("*d+g", "alphaDelta+betaGamma"); + fun testPlusOrMinusInThePatternShouldAllowToBeSpaceSurrounded() { + assertMatches("a+b", "alpha+beta") + assertMatches("a+b", "alpha_gamma+beta") + assertMatches("a+b", "alpha + beta") + assertMatches("Foo+", "Foo+Bar.txt") + assertMatches("Foo+", "Foo + Bar.txt") + assertMatches("a", "alpha+beta") + assertMatches("*b", "alpha+beta") + assertMatches("a + b", "alpha+beta") + assertMatches("a+", "alpha+beta") + assertDoesntMatch("a ", "alpha+beta") + assertMatches("", "alpha+beta") + assertMatches("*+ b", "alpha+beta") + assertDoesntMatch("d+g", "alphaDelta+betaGamma") + assertMatches("*d+g", "alphaDelta+betaGamma") - assertMatches("a-b", "alpha-beta"); - assertMatches("a-b", "alpha - beta"); + assertMatches("a-b", "alpha-beta") + assertMatches("a-b", "alpha - beta") } @Test - public void testMatchingDegree() { - assertPreference("jscote", "JsfCompletionTest", "JSCompletionTest", NameUtil.MatchingCaseSensitivity.NONE); - assertPreference("OCO", "OneCoolObject", "OCObject"); - assertPreference("MUp", "MavenUmlProvider", "MarkUp"); - assertPreference("MUP", "MarkUp", "MavenUmlProvider"); - assertPreference("CertificateExce", "CertificateEncodingException", "CertificateException"); - assertPreference("boo", "Boolean", "boolean", NameUtil.MatchingCaseSensitivity.NONE); - assertPreference("Boo", "boolean", "Boolean", NameUtil.MatchingCaseSensitivity.NONE); - assertPreference("getCU", "getCurrentSomething", "getCurrentUser"); - assertPreference("cL", "class", "coreLoader"); - assertPreference("cL", "class", "classLoader"); - assertPreference("inse", "InstrumentationError", "intSet", NameUtil.MatchingCaseSensitivity.NONE); - assertPreference("String", "STRING", "String", NameUtil.MatchingCaseSensitivity.NONE); - assertPreference("*String", "STRING", "String", NameUtil.MatchingCaseSensitivity.NONE); + fun testMatchingDegree() { + assertPreference("jscote", "JsfCompletionTest", "JSCompletionTest", NameUtil.MatchingCaseSensitivity.NONE) + assertPreference("OCO", "OneCoolObject", "OCObject") + assertPreference("MUp", "MavenUmlProvider", "MarkUp") + assertPreference("MUP", "MarkUp", "MavenUmlProvider") + assertPreference("CertificateExce", "CertificateEncodingException", "CertificateException") + assertPreference("boo", "Boolean", "boolean", NameUtil.MatchingCaseSensitivity.NONE) + assertPreference("Boo", "boolean", "Boolean", NameUtil.MatchingCaseSensitivity.NONE) + assertPreference("getCU", "getCurrentSomething", "getCurrentUser") + assertPreference("cL", "class", "coreLoader") + assertPreference("cL", "class", "classLoader") + assertPreference("inse", "InstrumentationError", "intSet", NameUtil.MatchingCaseSensitivity.NONE) + assertPreference("String", "STRING", "String", NameUtil.MatchingCaseSensitivity.NONE) + assertPreference("*String", "STRING", "String", NameUtil.MatchingCaseSensitivity.NONE) } @Test - public void testPreferAdjacentWords() { - assertPreference("*psfi", "PsiJavaFileBaseImpl", "PsiFileImpl", NameUtil.MatchingCaseSensitivity.NONE); + fun testPreferAdjacentWords() { + assertPreference("*psfi", "PsiJavaFileBaseImpl", "PsiFileImpl", NameUtil.MatchingCaseSensitivity.NONE) } @Test - public void testPreferMatchesToTheEnd() { - assertPreference("*e", "fileIndex", "file", NameUtil.MatchingCaseSensitivity.NONE); + fun testPreferMatchesToTheEnd() { + assertPreference("*e", "fileIndex", "file", NameUtil.MatchingCaseSensitivity.NONE) } @Test - public void testPreferences() { - assertPreference(" fb", "FooBar", "_fooBar", NameUtil.MatchingCaseSensitivity.NONE); - assertPreference("*foo", "barFoo", "foobar"); - assertPreference("*fo", "barfoo", "barFoo"); - assertPreference("*fo", "barfoo", "foo"); - assertPreference("*fo", "asdfo", "Foo", NameUtil.MatchingCaseSensitivity.NONE); - assertPreference(" sto", "StackOverflowError", "ArrayStoreException", NameUtil.MatchingCaseSensitivity.NONE); - assertPreference(" EUC-", "x-EUC-TW", "EUC-JP", NameUtil.MatchingCaseSensitivity.FIRST_LETTER); - assertPreference(" boo", "Boolean", "boolean", NameUtil.MatchingCaseSensitivity.NONE); - assertPreference(" Boo", "boolean", "Boolean", NameUtil.MatchingCaseSensitivity.NONE); - assertPreference("ob", "oci_bind_array_by_name", "obj"); - assertNoPreference("en", "ENABLED", "Enum", NameUtil.MatchingCaseSensitivity.NONE); + fun testPreferences() { + assertPreference(" fb", "FooBar", "_fooBar", NameUtil.MatchingCaseSensitivity.NONE) + assertPreference("*foo", "barFoo", "foobar") + assertPreference("*fo", "barfoo", "barFoo") + assertPreference("*fo", "barfoo", "foo") + assertPreference("*fo", "asdfo", "Foo", NameUtil.MatchingCaseSensitivity.NONE) + assertPreference(" sto", "StackOverflowError", "ArrayStoreException", NameUtil.MatchingCaseSensitivity.NONE) + assertPreference(" EUC-", "x-EUC-TW", "EUC-JP", NameUtil.MatchingCaseSensitivity.FIRST_LETTER) + assertPreference(" boo", "Boolean", "boolean", NameUtil.MatchingCaseSensitivity.NONE) + assertPreference(" Boo", "boolean", "Boolean", NameUtil.MatchingCaseSensitivity.NONE) + assertPreference("ob", "oci_bind_array_by_name", "obj") + 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); - int iMore = matcher.matchingDegree("posIdMap", true); - assertTrue(iLess < iMore); + fun testHonorFirstLetterCaseInCompletion() { + val matcher = NameUtil.buildMatcher("*pim", NameUtil.MatchingCaseSensitivity.NONE) + val iLess = matcher.matchingDegree("PImageDecoder", true) + val iMore = matcher.matchingDegree("posIdMap", true) + assertTrue(iLess < iMore) } @Test - public void testPreferWordBoundaryMatch() { - assertPreference("*ap", "add_profile", "application", NameUtil.MatchingCaseSensitivity.NONE); - assertPreference("*les", "configureByFiles", "getLookupElementStrings"); - assertPreference("*les", "configureByFiles", "getLookupElementStrings", NameUtil.MatchingCaseSensitivity.NONE); - assertPreference("*ea", "LEADING", "NORTH_EAST", NameUtil.MatchingCaseSensitivity.NONE); + fun testPreferWordBoundaryMatch() { + assertPreference("*ap", "add_profile", "application", NameUtil.MatchingCaseSensitivity.NONE) + assertPreference("*les", "configureByFiles", "getLookupElementStrings") + assertPreference("*les", "configureByFiles", "getLookupElementStrings", NameUtil.MatchingCaseSensitivity.NONE) + assertPreference("*ea", "LEADING", "NORTH_EAST", NameUtil.MatchingCaseSensitivity.NONE) - assertPreference("*Icon", "isControlKeyDown", "getErrorIcon", NameUtil.MatchingCaseSensitivity.NONE); - assertPreference("*icon", "isControlKeyDown", "getErrorIcon", NameUtil.MatchingCaseSensitivity.NONE); + assertPreference("*Icon", "isControlKeyDown", "getErrorIcon", NameUtil.MatchingCaseSensitivity.NONE) + assertPreference("*icon", "isControlKeyDown", "getErrorIcon", NameUtil.MatchingCaseSensitivity.NONE) - assertPreference("*Icon", "getInitControl", "getErrorIcon", NameUtil.MatchingCaseSensitivity.NONE); - assertPreference("*icon", "getInitControl", "getErrorIcon", NameUtil.MatchingCaseSensitivity.NONE); + assertPreference("*Icon", "getInitControl", "getErrorIcon", NameUtil.MatchingCaseSensitivity.NONE) + assertPreference("*icon", "getInitControl", "getErrorIcon", NameUtil.MatchingCaseSensitivity.NONE) } @Test - public void testPreferNoWordSkipping() { - assertPreference("CBP", "CustomProcessBP", "ComputationBatchProcess", NameUtil.MatchingCaseSensitivity.NONE); + fun testPreferNoWordSkipping() { + assertPreference("CBP", "CustomProcessBP", "ComputationBatchProcess", NameUtil.MatchingCaseSensitivity.NONE) } @Test - public void testWordLengthDoesNotMatter() { - assertNoPreference("PropComp", "PropertyComponent", "PropertiesComponent", NameUtil.MatchingCaseSensitivity.NONE); + fun testWordLengthDoesNotMatter() { + assertNoPreference("PropComp", "PropertyComponent", "PropertiesComponent", NameUtil.MatchingCaseSensitivity.NONE) } @Test - public void testMatchStartDoesntMatterForDegree() { - assertNoPreference(" path", "getAbsolutePath", "findPath", NameUtil.MatchingCaseSensitivity.FIRST_LETTER); + fun testMatchStartDoesntMatterForDegree() { + assertNoPreference(" path", "getAbsolutePath", "findPath", NameUtil.MatchingCaseSensitivity.FIRST_LETTER) } @Test - public void testPreferStartMatching() { - assertPreference("*tree", "FooTree", "Tree", NameUtil.MatchingCaseSensitivity.NONE); + fun testPreferStartMatching() { + assertPreference("*tree", "FooTree", "Tree", NameUtil.MatchingCaseSensitivity.NONE) } @Test - public void testPreferContiguousMatching() { - assertPreference("*mappablejs", "mappable-js.scope.js", "MappableJs.js", NameUtil.MatchingCaseSensitivity.NONE); + fun 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); - } - - private static void assertPreference(@NonNls String pattern, @NonNls String less, @NonNls String more) { - assertPreference(pattern, less, more, NameUtil.MatchingCaseSensitivity.FIRST_LETTER); - } - - private static void assertPreference(@NonNls String pattern, - @NonNls String less, - @NonNls String more, - NameUtil.MatchingCaseSensitivity sensitivity) { - assertPreference(NameUtil.buildMatcher(pattern, sensitivity), less, more); - } - - private static void assertPreference(MinusculeMatcher matcher, String less, String more) { - assertPreference(less, more, matcher::matchingDegree); - } - - private static void assertPreference(String less, String more, ToIntFunction matchingDegree) { - int iLess = matchingDegree.applyAsInt(less); - int iMore = matchingDegree.applyAsInt(more); - assertTrue(iLess < iMore, iLess + ">=" + iMore + "; " + less + ">=" + more); - } - - private static void assertNoPreference(@NonNls String pattern, - @NonNls String name1, - @NonNls String name2, - NameUtil.MatchingCaseSensitivity sensitivity) { - MinusculeMatcher matcher = NameUtil.buildMatcher(pattern, sensitivity); - assertEquals(matcher.matchingDegree(name1), matcher.matchingDegree(name2)); + fun testMeaningfulMatchingDegree() { + assertTrue(caseInsensitiveMatcher(" EUC-").matchingDegree("x-EUC-TW") > Int.MIN_VALUE) } @Test - public void testFilePatterns() { - assertMatches("groovy*.jar", "groovy-1.7.jar"); - assertDoesntMatch("*.ico", "a.i.c.o"); + fun 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"); + fun testCapsMayMatchNonCaps() { + assertMatches("PDFRe", "PdfRenderer") + assertMatches("*pGETPartTimePositionInfo", "dbo.pGetPartTimePositionInfo.sql") } @Test - public void testACapitalAfterAnotherCapitalMayMatchALowercaseLetterBecauseShiftWasAccidentallyHeldTooLong() { - assertMatches("USerDefa", "UserDefaults"); - assertMatches("NSUSerDefa", "NSUserDefaults"); - assertMatches("NSUSER", "NSUserDefaults"); - assertMatches("NSUSD", "NSUserDefaults"); - assertMatches("NSUserDEF", "NSUserDefaults"); + fun testACapitalAfterAnotherCapitalMayMatchALowercaseLetterBecauseShiftWasAccidentallyHeldTooLong() { + assertMatches("USerDefa", "UserDefaults") + assertMatches("NSUSerDefa", "NSUserDefaults") + assertMatches("NSUSER", "NSUserDefaults") + assertMatches("NSUSD", "NSUserDefaults") + assertMatches("NSUserDEF", "NSUserDefaults") } @Test - public void testCyrillicMatch() { - assertMatches("ыек", "String"); + fun testCyrillicMatch() { + assertMatches("ыек", "String") } @Test - public void testMatchingAllOccurrences() { - String text = "some text"; - MinusculeMatcher matcher = AllOccurrencesMatcher.create("*e", NameUtil.MatchingCaseSensitivity.NONE, ""); - assertIterableEquals(matcher.matchingFragments(text), - Arrays.asList(new TextRange(3, 4), new TextRange(6, 7))); + fun testMatchingAllOccurrences() { + val text = "some text" + val matcher = create("*e", NameUtil.MatchingCaseSensitivity.NONE, "") + assertContentEquals(matcher.matchingFragments(text), listOf(TextRange(3, 4), TextRange(6, 7))) } @Test - public void testCamelHumpWinsOverConsecutiveCaseMismatch() { - assertEquals(3, NameUtil.buildMatcher("GEN", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments("GetExtendedName").size()); + fun testCamelHumpWinsOverConsecutiveCaseMismatch() { + assertEquals(3, NameUtil.buildMatcher("GEN", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments("GetExtendedName")!!.size) - assertPreference("GEN", "GetName", "GetExtendedName"); - assertPreference("*GEN", "GetName", "GetExtendedName"); + assertPreference("GEN", "GetName", "GetExtendedName") + assertPreference("*GEN", "GetName", "GetExtendedName") } @Test - public void testLowerCaseAfterCamels() { - assertMatches("LSTMa", "LineStatusTrackerManager"); + fun testLowerCaseAfterCamels() { + assertMatches("LSTMa", "LineStatusTrackerManager") } @Test - public void testProperties() { - assertMatches("*pro", "spring.activemq.pool.configuration.reconnect-on-exception"); + fun testProperties() { + assertMatches("*pro", "spring.activemq.pool.configuration.reconnect-on-exception") + } + + companion object { + private fun caseInsensitiveMatcher(pattern: String): MinusculeMatcher { + return NameUtil.buildMatcher(pattern, NameUtil.MatchingCaseSensitivity.NONE) + } + + private fun firstLetterMatcher(pattern: String): Matcher { + return NameUtil.buildMatcher(pattern, NameUtil.MatchingCaseSensitivity.FIRST_LETTER) + } + + private fun assertMatches(@NonNls pattern: @NonNls String, @NonNls name: @NonNls String) { + assertTrue(caseInsensitiveMatcher(pattern).matches(name), "$pattern doesn't match $name!!!") + } + + private fun assertDoesntMatch(@NonNls pattern: @NonNls String, @NonNls name: @NonNls String) { + assertFalse(caseInsensitiveMatcher(pattern).matches(name), "$pattern matches $name!!!") + } + + private fun assertPreference( + @NonNls pattern: @NonNls String, + @NonNls less: @NonNls String, + @NonNls more: @NonNls String, + sensitivity: NameUtil.MatchingCaseSensitivity = NameUtil.MatchingCaseSensitivity.FIRST_LETTER, + ) { + assertPreference(NameUtil.buildMatcher(pattern, sensitivity), less, more) + } + + private fun assertPreference(matcher: MinusculeMatcher, less: String, more: String) { + assertPreference(less, more) { name -> matcher.matchingDegree(name) } + } + + private fun assertPreference(less: String, more: String, matchingDegree: (String) -> Int) { + val iLess = matchingDegree(less) + val iMore = matchingDegree(more) + assertTrue(iLess < iMore, "$iLess>=$iMore; $less>=$more") + } + + private fun assertNoPreference( + @NonNls pattern: @NonNls String, + @NonNls name1: @NonNls String, + @NonNls name2: @NonNls String, + sensitivity: NameUtil.MatchingCaseSensitivity, + ) { + val matcher = NameUtil.buildMatcher(pattern, sensitivity) + assertEquals(matcher.matchingDegree(name1), matcher.matchingDegree(name2)) + } } } diff --git a/platform/util/text-matching/test/com/intellij/platform/util/text/matching/NameUtilTest.kt b/platform/util/text-matching/test/com/intellij/platform/util/text/matching/NameUtilTest.kt index 871e01fd5068..c0c31b374aa5 100644 --- a/platform/util/text-matching/test/com/intellij/platform/util/text/matching/NameUtilTest.kt +++ b/platform/util/text-matching/test/com/intellij/platform/util/text/matching/NameUtilTest.kt @@ -1,77 +1,74 @@ // 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; +package com.intellij.platform.util.text.matching -import com.intellij.psi.codeStyle.NameUtil; -import com.intellij.util.text.NameUtilCore; -import org.jetbrains.annotations.NotNull; -import org.junit.jupiter.api.Test; +import com.intellij.psi.codeStyle.NameUtil +import com.intellij.util.text.NameUtilCore.isWordStart +import org.junit.jupiter.api.Test +import kotlin.test.assertEquals +import kotlin.test.assertTrue -import java.util.Arrays; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -public class NameUtilTest { +class NameUtilTest { @Test - public void testSplitIntoWords1() { - assertSplitEquals(new String[]{"I", "Base"}, "IBase"); + fun testSplitIntoWords1() { + assertSplitEquals(listOf("I", "Base"), "IBase") } @Test - public void testSplitIntoWords2() { - assertSplitEquals(new String[]{"Order", "Index"}, "OrderIndex"); + fun testSplitIntoWords2() { + assertSplitEquals(listOf("Order", "Index"), "OrderIndex") } @Test - public void testSplitIntoWords3() { - assertSplitEquals(new String[]{"order", "Index"}, "orderIndex"); + fun testSplitIntoWords3() { + assertSplitEquals(listOf("order", "Index"), "orderIndex") } @Test - public void testSplitIntoWords4() { - assertSplitEquals(new String[]{"Order", "Index"}, "Order_Index"); + fun testSplitIntoWords4() { + assertSplitEquals(listOf("Order", "Index"), "Order_Index") } @Test - public void testSplitIntoWords5() { - assertSplitEquals(new String[]{"ORDER", "INDEX"}, "ORDER_INDEX"); + fun testSplitIntoWords5() { + assertSplitEquals(listOf("ORDER", "INDEX"), "ORDER_INDEX") } @Test - public void testSplitIntoWords6() { - assertSplitEquals(new String[]{"gg", "J"}, "ggJ"); + fun testSplitIntoWords6() { + assertSplitEquals(listOf("gg", "J"), "ggJ") } @Test - public void testSplitIntoWordsCN() { - assertSplitEquals(new String[]{"测", "试", "打", "补", "丁", "2"}, "测试打补丁2"); + fun testSplitIntoWordsCN() { + assertSplitEquals(listOf("测", "试", "打", "补", "丁", "2"), "测试打补丁2") } @Test - public void testSplitIntoWordsJP() { + fun testSplitIntoWordsJP() { assertSplitEquals( - new String[]{"ローマ", "由", "来", "の", "アルファベット", "(", "ラテン", "文", "字", ")", "を", "用", "いて", "日", "本", "語", "を", "表", "記", "することもでき", "、", "日", "本", "では", "ローマ", "字", "と", "呼", "ばれる"}, - "ローマ由来のアルファベット(ラテン文字)を用いて日本語を表記することもでき、日本ではローマ字と呼ばれる"); - //noinspection NonAsciiCharacters - assertSplitEquals(new String[]{"近", "代", "では", "日", "本", "人", "が", "漢", "語", "を", "造", "語", "する", "例", "もあり", "、", "英", "語", "の", "philosophy", "、", "ドイツ", "語", "の", "Philosophie", "を", "指", "す", "用", "語"}, - "近代では日本人が漢語を造語する例もあり、英語のphilosophy、ドイツ語のPhilosophieを指す用語"); - } - - @Test - public void testEmoji() { - assertSplitEquals(new String[]{"\uD83E\uDD2B", " ", "\uD83D\uDD2B", "\uD83E\uDDD2"}, "\uD83E\uDD2B \uD83D\uDD2B\uD83E\uDDD2"); - } - - - @Test - public void testIsWordStart() { - assertTrue(NameUtilCore.isWordStart("测试打补丁", 0)); - assertTrue(NameUtilCore.isWordStart("测试打补丁", 2)); + listOf("ローマ", "由", "来", "の", "アルファベット", "(", "ラテン", "文", "字", ")", "を", "用", "いて", "日", "本", "語", + "を", "表", "記", "することもでき", "、", "日", "本", "では", "ローマ", "字", "と", "呼", "ばれる"), + "ローマ由来のアルファベット(ラテン文字)を用いて日本語を表記することもでき、日本ではローマ字と呼ばれる") + assertSplitEquals( + listOf("近", "代", "では", "日", "本", "人", "が", "漢", "語", "を", "造", "語", "する", "例", "もあり", "、", "英", "語", + "の", "philosophy", "、", "ドイツ", "語", "の", "Philosophie", "を", "指", "す", "用", "語"), + "近代では日本人が漢語を造語する例もあり、英語のphilosophy、ドイツ語のPhilosophieを指す用語") } - private static void assertSplitEquals(String[] expected, String name) { - final List<@NotNull String> result = NameUtil.splitNameIntoWordList(name); - assertEquals(Arrays.asList(expected), result); + @Test + fun testEmoji() { + assertSplitEquals(listOf("\uD83E\uDD2B", " ", "\uD83D\uDD2B", "\uD83E\uDDD2"), + "\uD83E\uDD2B \uD83D\uDD2B\uD83E\uDDD2") + } + + + @Test + fun testIsWordStart() { + assertTrue(isWordStart("测试打补丁", 0)) + assertTrue(isWordStart("测试打补丁", 2)) + } + + private fun assertSplitEquals(expected: List, name: String) { + assertEquals(expected, NameUtil.splitNameIntoWordList(name)) } } diff --git a/platform/util/text-matching/test/com/intellij/platform/util/text/matching/PinyinMatcherDataTest.kt b/platform/util/text-matching/test/com/intellij/platform/util/text/matching/PinyinMatcherDataTest.kt index f2136e47093f..97aa9fa94711 100644 --- a/platform/util/text-matching/test/com/intellij/platform/util/text/matching/PinyinMatcherDataTest.kt +++ b/platform/util/text-matching/test/com/intellij/platform/util/text/matching/PinyinMatcherDataTest.kt @@ -1,158 +1,161 @@ // 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; +package com.intellij.platform.util.text.matching -import com.intellij.psi.codeStyle.PinyinMatcher; -import org.jetbrains.annotations.NotNull; -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; -import java.io.InputStreamReader; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.text.Normalizer; -import java.util.*; -import java.util.function.Supplier; -import java.util.stream.Collectors; -import java.util.stream.IntStream; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; +import com.intellij.psi.codeStyle.PinyinMatcher +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test +import java.net.URL +import java.text.Normalizer +import java.util.zip.ZipInputStream +import kotlin.test.assertEquals /** - * Generates data arrays for {@link PinyinMatcher} using Unihan_Readings.txt file from unicode.org + * Generates data arrays for [PinyinMatcher] using Unihan_Readings.txt file from unicode.org * Requires Internet connection. */ @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"; - private static final String READINGS_FILE = "Unihan_Readings.txt"; - +class PinyinMatcherDataTest { @Test - public void ensurePinyinDataIsUpToDate() throws IOException { - List mappings = readMappings(); - List initials = generateInitials(mappings); - String encodingStr = String.join(",", initials); - String data = getDataString(mappings, initials); + fun ensurePinyinDataIsUpToDate() { + val mappings = readMappings() + val initials = generateInitials(mappings) + val encodingStr = initials.joinToString(",") + val data = getDataString(mappings, initials) - Supplier message = () -> - "Pinyin data mismatch. Please update constants in " + PinyinMatcher.class.getName() + " to the following:\n" + - toJavaStringLiteral("ENCODING", encodingStr) + "\n" + - toJavaStringLiteral("DATA", data) + "\n"; + val message = """Pinyin data mismatch. Please update constants in ${PinyinMatcher::class.qualifiedName} to the following: + ${toJavaStringLiteral("ENCODING", encodingStr)} + ${toJavaStringLiteral("DATA", data)} + """.trimIndent() - Assertions.assertEquals(PinyinMatcher.ENCODING, encodingStr, message); - Assertions.assertEquals(PinyinMatcher.DATA, data, message); + assertEquals(PinyinMatcher.ENCODING, encodingStr, message) + assertEquals(PinyinMatcher.DATA, data, message) } - private static String toJavaStringLiteral(String varName, String input) { - StringBuilder result = new StringBuilder(varName + " =\n\""); - int curLineLength = 0; - for (int i = 0; i < input.length(); i++) { - char ch = input.charAt(i); - String charRepresentation; - if (ch == '"' || ch == '\\') { - charRepresentation = "\\" + ch; - } - else if (ch < 127) { - charRepresentation = Character.toString(ch); - } - else { - charRepresentation = String.format("\\u%04X", (int)ch); - } - result.append(charRepresentation); - curLineLength += charRepresentation.length(); - if (curLineLength > LINE_LENGTH && i < input.length() - 1) { - curLineLength = 0; - result.append("\" +\n\""); + companion object { + private const val LINE_LENGTH = 100 + private const val DATA_SOURCE = "https://unicode.org/Public/UNIDATA/Unihan.zip" + private const val READINGS_FILE = "Unihan_Readings.txt" + + private val U4_UPPER = HexFormat { + upperCase = true + number { + minLength = 4 } } - return result.append("\";").toString(); - } - @NotNull - private static String getDataString(List mappings, List initials) { - Map encoding = initials.stream() - .collect(Collectors.toMap(s -> s, s -> (char)(PinyinMatcher.BASE_CHAR + initials.indexOf(s)))); - - Map map = mappings.stream() - .collect(Collectors.toMap(mapping -> mapping.codePoint, m -> encoding.get(m.charString()))); - int lastCodePoint = mappings.stream().mapToInt(m -> m.codePoint).max().orElseThrow(NoSuchElementException::new); - return IntStream.rangeClosed(PinyinMatcher.BASE_CODE_POINT, lastCodePoint) - .mapToObj(i -> map.getOrDefault(i, ' ').toString()).collect(Collectors.joining()); - } - - @NotNull - private static List generateInitials(List mappings) { - return mappings.stream().map(Mapping::charString).distinct() - .sorted(Comparator.comparing(String::length).thenComparing(Comparator.naturalOrder())) - .collect(Collectors.toList()); - } - - @NotNull - private static List readMappings() throws IOException { - try (ZipInputStream zis = new ZipInputStream(new URL(DATA_SOURCE).openStream())) { - while (true) { - ZipEntry entry = zis.getNextEntry(); - if (entry == null) { - throw new IllegalStateException(String.format("No %s found inside %s", READINGS_FILE, DATA_SOURCE)); + private fun toJavaStringLiteral(varName: String?, input: String): String { + val result = StringBuilder("$varName =\n\"") + var curLineLength = 0 + input.forEachIndexed { i, ch -> + val charRepresentation = when { + ch == '"' || ch == '\\' -> { + "\\" + ch + } + ch.code < 127 -> { + ch.toString() + } + else -> { + "\\u${unicodeEscapeCodePoint(ch.code)}" + } } - if (entry.getName().equals(READINGS_FILE)) { - Collection mappings = new BufferedReader(new InputStreamReader(zis, StandardCharsets.UTF_8)).lines() - .map(Mapping::parseUniHan) - .filter(Objects::nonNull) - .collect(Collectors.toMap(m -> m.codePoint, m -> m, Mapping::merge, LinkedHashMap::new)) - .values(); - return new ArrayList<>(mappings); + result.append(charRepresentation) + curLineLength += charRepresentation.length + if (curLineLength > LINE_LENGTH && i < input.length - 1) { + curLineLength = 0 + result.append("\" +\n\"") + } + } + return result.append("\";").toString() + } + + // todo + fun unicodeEscapeCodePoint(cp: Int): String { + if (cp <= 0xFFFF) return "\\u" + cp.toHexString(U4_UPPER) + val u = cp - 0x10000 + val hi = 0xD800 + (u ushr 10) + val lo = 0xDC00 + (u and 0x3FF) + return "\\u" + hi.toHexString(U4_UPPER) + "\\u" + lo.toHexString(U4_UPPER) + } + + private fun getDataString(mappings: List, initials: List): String { + val encoding = initials.associateWith { PinyinMatcher.BASE_CHAR + initials.indexOf(it) } + val map = mappings.associate { mapping -> mapping.codePoint to encoding[mapping.charString()] } + val lastCodePoint = mappings.maxOf(Mapping::codePoint) + return (PinyinMatcher.BASE_CODE_POINT..lastCodePoint).map { map[it] ?: ' ' }.joinToString("") + } + + private fun generateInitials(mappings: List): List { + return mappings.map(Mapping::charString).distinct().sortedWith(compareBy(String::length).then(naturalOrder())) + } + + private fun readMappings(): List { + ZipInputStream(URL(DATA_SOURCE).openStream()).use { zis -> + while (true) { + val entry = zis.nextEntry + requireNotNull(entry) { "No $READINGS_FILE found inside $DATA_SOURCE" } + if (entry.name == READINGS_FILE) { + return zis.bufferedReader(Charsets.UTF_8).lineSequence() + .mapNotNull(Mapping::parseUniHan) + .groupBy(Mapping::codePoint) + .map { (_, mappings) -> mappings.reduce { acc, mapping -> Mapping.merge(acc, mapping) } } + } } } } } - private record Mapping(int codePoint, long chars) { - String charString() { - return BitSet.valueOf(new long[]{chars}).stream().mapToObj(bit -> Character.toString((char)(bit + 'a'))) - .collect(Collectors.joining()); + private data class Mapping(val codePoint: Int, val chars: Long) { + fun charString(): String { + return oneBitsSequence(chars).joinToString("") { bit -> (bit + 'a'.code).toChar().toString() } } - static Mapping merge(Mapping m1, Mapping m2) { - if (m1.codePoint != m2.codePoint) throw new IllegalArgumentException(); - return new Mapping(m1.codePoint, m1.chars | m2.chars); - } - - static Mapping parseUniHan(String line) { - if (line.startsWith("#")) return null; - String[] parts = line.split("\\s+"); - if (parts.length != 3) return null; - if (!parts[0].startsWith("U+")) return null; - int codePoint = Integer.parseInt(parts[0].substring(2), 16); - if (codePoint < PinyinMatcher.BASE_CODE_POINT) return null; - // Codepoints outside BMP are not supported for now - if (codePoint > 0xA000) return null; - String[] readings; - switch (parts[1]) { - case "kMandarin" -> readings = new String[]{parts[2]}; - case "kHanyuPinyin" -> { - int colonPos = parts[2].indexOf(':'); - if (colonPos == -1) return null; - readings = parts[2].substring(colonPos + 1).split(","); - } - default -> { - return null; - } + private fun oneBitsSequence(n: Long): Sequence = sequence { + var bits = n + while (bits != 0L) { + val lsbIndex = bits.countTrailingZeroBits() + yield(lsbIndex) + bits = bits and (bits - 1) } - long encoded = 0; - for (String reading : readings) { - char initial = Normalizer.normalize(reading, Normalizer.Form.NFKD).charAt(0); - encoded |= 1L << (initial - 'a'); - } - return new Mapping(codePoint, encoded); } - @Override - public String toString() { - return String.format("%04X: %s", codePoint, charString()); + override fun toString(): String { + return "${codePoint.toHexString(U4_UPPER)}: ${charString()}" + } + + companion object { + private val whitespaceRegex = "\\s+".toRegex() + fun merge(m1: Mapping, m2: Mapping): Mapping { + require(m1.codePoint == m2.codePoint) + return Mapping(m1.codePoint, m1.chars or m2.chars) + } + + fun parseUniHan(line: String): Mapping? { + if (line.startsWith('#')) return null + val parts = line.split(whitespaceRegex) + if (parts.size != 3) return null + if (!parts.first().startsWith("U+")) return null + val codePoint = parts.first().substring(2).toInt(16) + if (codePoint < PinyinMatcher.BASE_CODE_POINT) return null + // Codepoints outside BMP are not supported for now + if (codePoint > 0xA000) return null + val readings = when (parts[1]) { + "kMandarin" -> listOf(parts[2]) + "kHanyuPinyin" -> { + val colonPos = parts[2].indexOf(':') + if (colonPos == -1) return null + parts[2].substring(colonPos + 1).split(',') + } + else -> { + return null + } + } + var encoded: Long = 0 + for (reading in readings) { + val initial = Normalizer.normalize(reading, Normalizer.Form.NFKD)[0] + encoded = encoded or (1L shl (initial.code - 'a'.code)) + } + return Mapping(codePoint, encoded) + } } } } diff --git a/platform/util/text-matching/test/com/intellij/platform/util/text/matching/TypoTolerantMatcherTest.kt b/platform/util/text-matching/test/com/intellij/platform/util/text/matching/TypoTolerantMatcherTest.kt index 941fd0fad1a7..96546fefca0f 100644 --- a/platform/util/text-matching/test/com/intellij/platform/util/text/matching/TypoTolerantMatcherTest.kt +++ b/platform/util/text-matching/test/com/intellij/platform/util/text/matching/TypoTolerantMatcherTest.kt @@ -1,55 +1,62 @@ // 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; +package com.intellij.platform.util.text.matching -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 com.intellij.psi.codeStyle.NameUtil +import com.intellij.psi.codeStyle.TypoTolerantMatcher +import org.junit.jupiter.api.Test +import kotlin.random.Random +import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertTrue -import java.util.Arrays; -import java.util.List; -import java.util.SplittableRandom; -import java.util.stream.Stream; +class TypoTolerantMatcherTest { -import static org.junit.jupiter.api.Assertions.*; - -public class TypoTolerantMatcherTest { @Test - public void testStability() { - SplittableRandom random = new SplittableRandom(1); - String[] data = - Stream.generate(() -> { - StringBuilder sb = new StringBuilder(); - random.ints(random.nextInt(5, 25), 'a', 'z') - .map(ch -> - random.nextInt(100) == 0 ? "0123456789$_@%вгдежзиклмно".charAt(ch - 'a') : - random.nextInt(6) == 0 ? Character.toUpperCase(ch) : ch) - .forEach(sb::appendCodePoint); - return sb.toString(); - }).limit(20000).toArray(String[]::new); - TypoTolerantMatcher matcher = new TypoTolerantMatcher("asd", NameUtil.MatchingCaseSensitivity.FIRST_LETTER, ""); - 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", - "adyqfdmDaryuakWicnjcj", "ahNbcEcpIsD", "aLompgtlMkDdypdxwmvvUG", "ajxoADelNmdbmvutbidrde", "nasbcDhbfXx", "aDhbEtoublcDryyh", - "pAeloeorWqXslbSDbv", "asnnWshffqbujmcOd", "adXovaMuDYjyrlexj"); - assertEquals(expected, matched); + fun testStability() { + val data = randomStrings(Random(1)).take(20000) + val matcher = TypoTolerantMatcher("asd", NameUtil.MatchingCaseSensitivity.FIRST_LETTER, "") + val matched = data.filter(matcher::matches).toList() + val expected = listOf("oaebOeSnflvteoDsqhFo", "avsdCzdi", "axFskogmnmdufynMoewjDzsU", "JazjkxFvzhdogdvSBDwq", + "amEckovsuvscwqhgoSTdznk", "aAdmRJtQggyGcbzx", "asfZPktnVioCzeWx", "ajEhAd", "aaDuhgmkapirfpEufpNYbl", + "ammimq3zszBNwCmDc", "adZOzpdakGDmhqc", "aAdbjfpbbksFvkoxzJncV", "asxQnpskleYdaUnydjy", "lAsdckUaxay", + "aafjkqrMnkmwymDhl", "RaaFSqrfuDivxNksXibx", "aDPginwvboivkJjODzTuntQ", "jaazllSrlD", "zaEgqSZroDymriOjj", + "aefqJsdfjacxfak_eoVe", "adDTvpUZAuxpX", "aRAdblxighsznpspe", "adCpMjbbtUDlkvfyakCje", "aSfygmyodrokNuwAvugkmc", + "ashzDlibpOm", "aKSDdbtlphcbInJafkP", "ajmfuYsqPYFjD", "aFyjwqdwpWDygluewSmtD", "dazpjiSdf", "ademUttrQDu", + "agupnvSxdgnukGlpwxhyLxvp", "avuvzzgdvtSdqEgFqz", "asfKryfdl", "hasfiwopqfaoghaDcGokaoq", "ssbzBsmkDv", + "aqSSykiocfzWhajmtYHkshnm", "aiyADtwtlnkdYKqhdlj", "asfcqZgtHAqeOpcpFxp", "ssmw\$dsFzenxpyx1Ff") + assertEquals(expected, matched, matched.joinToString(", ") { "\"$it\"" }) } @Test - public void testEmptyPattern() { - TypoTolerantMatcher matcher = new TypoTolerantMatcher("*", NameUtil.MatchingCaseSensitivity.NONE, ""); - String[] data = new String[]{"foo", "bar", "buzz"}; - List matched = Arrays.stream(data).filter(matcher::matches).toList(); - List expected = List.of("foo", "bar", "buzz"); - assertEquals(expected, matched); + fun testEmptyPattern() { + val matcher = TypoTolerantMatcher("*", NameUtil.MatchingCaseSensitivity.NONE, "") + val data = listOf("foo", "bar", "buzz") + val matched = data.filter(matcher::matches) + val expected = listOf("foo", "bar", "buzz") + assertEquals(expected, matched) } @Test - public void testLongPattern() { - MinusculeMatcher matcher = NameUtil.buildMatcher("MyLongTestClassName").typoTolerant().build(); - assertFalse(matcher instanceof TypoTolerantMatcher); - assertTrue(matcher.matches("MyLongTestClassName")); + fun testLongPattern() { + val matcher = NameUtil.buildMatcher("MyLongTestClassName").typoTolerant().build() + assertFalse(matcher is TypoTolerantMatcher) + assertTrue(matcher.matches("MyLongTestClassName")) + } + + private fun randomStrings(random: Random): Sequence = sequence { + while (true) { + val length = random.nextInt(5, 25) + yield(buildString(capacity = length) { + repeat(length) { + val ch = random.nextInt('a'.code, 'z'.code + 1) + val c = when { + random.nextInt(100) == 0 -> "0123456789\$_@%вгдежзиклмно"[ch - 'a'.code].code + random.nextInt(6) == 0 -> Character.toUpperCase(ch) + else -> ch + } + appendCodePoint(c) + } + }) + } } }