refactoring [text-matching]: convert tests to kotlin

GitOrigin-RevId: 906a9ab2cd4a2a65f7df4e02647d9e687534b5a8
This commit is contained in:
Alexander Zolotov
2025-11-19 17:50:26 +00:00
committed by intellij-monorepo-bot
parent ecf232e443
commit f2c2288fcf
6 changed files with 742 additions and 742 deletions
@@ -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)));
}
}
@@ -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)));
}
}
@@ -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<String>, name: String) {
assertEquals(expected, NameUtil.splitNameIntoWordList(name))
}
}
@@ -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<Mapping> mappings = readMappings();
List<String> 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<String> 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<Mapping> mappings, List<String> initials) {
Map<String, Character> encoding = initials.stream()
.collect(Collectors.toMap(s -> s, s -> (char)(PinyinMatcher.BASE_CHAR + initials.indexOf(s))));
Map<Integer, Character> 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<String> generateInitials(List<Mapping> mappings) {
return mappings.stream().map(Mapping::charString).distinct()
.sorted(Comparator.comparing(String::length).thenComparing(Comparator.naturalOrder()))
.collect(Collectors.toList());
}
@NotNull
private static List<Mapping> 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<Mapping> 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<Mapping>, initials: List<String>): 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<Mapping>): List<String> {
return mappings.map(Mapping::charString).distinct().sortedWith(compareBy(String::length).then(naturalOrder()))
}
private fun readMappings(): List<Mapping> {
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<Int> = 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)
}
}
}
}
@@ -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<String> matched = Arrays.stream(data).filter(matcher::matches).toList();
List<String> 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<String> matched = Arrays.stream(data).filter(matcher::matches).toList();
List<String> 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<String> = 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)
}
})
}
}
}