From 5ec5c3bdfdd2d5b41b3d36a711e08431938f309a Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Sun, 27 Mar 2022 13:37:18 +0600 Subject: [PATCH] Fixes in "TextSourcesList" creating in from "RawMessageEntities" --- CHANGELOG.md | 3 ++ .../types/MessageEntity/RawMessageEntity.kt | 24 +++++----- .../types/MessageEntity/EntitiesTestText.kt | 20 ++++----- .../MessageEntity/StringFormattingTests.kt | 44 +++++++++++++++++-- 4 files changed, 65 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e28150106..5d3a51db60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## 0.38.11 +* `Core`: + * Fixes in `TextSourcesList` creating in from `RawMessageEntities` + ## 0.38.10 * `API`: diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/RawMessageEntity.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/RawMessageEntity.kt index 32289a6806..6a35f4dcd5 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/RawMessageEntity.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/RawMessageEntity.kt @@ -20,11 +20,11 @@ internal data class RawMessageEntity( internal fun RawMessageEntity.asTextSource( source: String, - subParts: TextSourcesList + subParts: List> ): TextSource { val sourceSubstring: String = source.substring(range) val subPartsWithRegulars by lazy { - subParts.fillWithRegulars(sourceSubstring) + subParts.map { (it.first - offset) to it.second }.fillWithRegulars(sourceSubstring) } return when (type) { "mention" -> MentionTextSource(sourceSubstring, subPartsWithRegulars) @@ -58,16 +58,14 @@ private inline operator fun > ClosedRange.contains(other: C return start <= other.start && endInclusive >= other.endInclusive } -internal fun TextSourcesList.fillWithRegulars(source: String): TextSourcesList { +internal fun List>.fillWithRegulars(source: String): TextSourcesList { var index = 0 val result = mutableListOf() - for (i in 0 until size) { - val textSource = get(i) - val thisSourceInStart = source.startsWith(textSource.source, index) - if (!thisSourceInStart) { - val regularEndIndex = source.indexOf(textSource.source, index) - result.add(regular(source.substring(index, regularEndIndex))) - index = regularEndIndex + for (i in indices) { + val (offset, textSource) = get(i) + if (offset - index > 0) { + result.add(regular(source.substring(index, offset))) + index = offset } result.add(textSource) index += textSource.source.length @@ -83,9 +81,9 @@ internal fun TextSourcesList.fillWithRegulars(source: String): TextSourcesList { private fun createTextSources( originalFullString: String, entities: RawMessageEntities -): TextSourcesList { +): List> { val mutableEntities = entities.toMutableList().apply { sortBy { it.offset } } - val resultList = mutableListOf() + val resultList = mutableListOf>() while (mutableEntities.isNotEmpty()) { var parent = mutableEntities.removeFirst() @@ -129,7 +127,7 @@ private fun createTextSources( emptyList() } resultList.add( - parent.asTextSource( + parent.offset to parent.asTextSource( originalFullString, subtextSources ) diff --git a/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/MessageEntity/EntitiesTestText.kt b/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/MessageEntity/EntitiesTestText.kt index 7048fa4b6c..9b6a1d31f0 100644 --- a/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/MessageEntity/EntitiesTestText.kt +++ b/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/MessageEntity/EntitiesTestText.kt @@ -3,43 +3,43 @@ package dev.inmo.tgbotapi.types.MessageEntity import dev.inmo.tgbotapi.types.MessageEntity.textsources.* import kotlin.test.assertTrue -const val testText = "It is simple hello world with #tag and @mention" -const val formattedV2Text = "It *_is_ ~__simple__~* ||hello world|| with \\#tag and @mention" -const val formattedHtmlText = "It is simple hello world with #tag and @mention" +const val testText = "It (is?) is simple hello world with #tag and @mention" +const val formattedV2Text = "It \\(is?\\) *_is_ ~__simple__~* ||hello world|| with \\#tag and @mention" +const val formattedHtmlText = "It (is?) is simple hello world with #tag and @mention" internal val testTextEntities = listOf( RawMessageEntity( "bold", - 3, + 9, 9 ), RawMessageEntity( "italic", - 3, + 9, 2 ), RawMessageEntity( "strikethrough", - 6, + 12, 6 ), RawMessageEntity( "underline", - 6, + 12, 6 ), RawMessageEntity( "spoiler", - 13, + 19, 11 ), RawMessageEntity( "hashtag", - 30, + 36, 4 ), RawMessageEntity( "mention", - 39, + 45, 8 ) ) diff --git a/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/MessageEntity/StringFormattingTests.kt b/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/MessageEntity/StringFormattingTests.kt index ba11fc9d3a..6929bf6135 100644 --- a/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/MessageEntity/StringFormattingTests.kt +++ b/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/MessageEntity/StringFormattingTests.kt @@ -2,8 +2,7 @@ package dev.inmo.tgbotapi.types.MessageEntity import dev.inmo.tgbotapi.extensions.utils.formatting.* import dev.inmo.tgbotapi.types.MessageEntity.textsources.* -import kotlin.test.Test -import kotlin.test.assertEquals +import kotlin.test.* class StringFormattingTests { @Test @@ -38,7 +37,7 @@ class StringFormattingTests { @Test fun testThatCreatingOfStringWithSimpleDSLWorksCorrectly() { - val sources: TextSourcesList = regular("It ") + + val sources: TextSourcesList = regular("It (is?) ") + bold(italic("is") + " " + strikethrough(underline("simple"))) + @@ -53,4 +52,43 @@ class StringFormattingTests { assertEquals(formattedV2Text, sources.toMarkdownV2Texts().first()) assertEquals(formattedHtmlText, sources.toHtmlTexts().first()) } + + @Test + fun testForRepeatingWordsInOneSentenceWithTheSecondOneFormatted() { + val sourceText = "link link" + val messageEntities = listOf( + RawMessageEntity("bold", 5, 4), + RawMessageEntity("text_link", 6, 2, "google.com") + ) + val textSources = messageEntities.asTextSources(sourceText) + val (regular, bold) = textSources + assertTrue(regular is RegularTextSource) + assertTrue(bold is BoldTextSource) + assertTrue(regular.source == "link ") + assertTrue(bold.source == "link") + assertTrue((bold.subsources[0] as? RegularTextSource) ?.source == "l") + assertTrue((bold.subsources[1] as? TextLinkTextSource) ?.source == "in") + assertTrue((bold.subsources[1] as? TextLinkTextSource) ?.url == "google.com") + assertTrue((bold.subsources[2] as? RegularTextSource) ?.source == "k") + assertTrue(bold.subsources.size == 3) + assertTrue(textSources.size == 2) + } + + @Test + fun testForRepeatingWordsInOneSentenceWithTheSecondOneFormattedInsideOfFormatting() { + val sourceText = "text" + val messageEntities = listOf( + RawMessageEntity("bold", 0, 4), + RawMessageEntity("text_link", 3, 1, "google.com") + ) + val textSources = messageEntities.asTextSources(sourceText) + val (bold) = textSources + assertTrue(bold is BoldTextSource) + assertTrue(bold.source == "text") + assertTrue((bold.subsources[0] as? RegularTextSource) ?.source == "tex") + assertTrue((bold.subsources[1] as? TextLinkTextSource) ?.source == "t") + assertTrue((bold.subsources[1] as? TextLinkTextSource) ?.url == "google.com") + assertTrue(bold.subsources.size == 2) + assertTrue(textSources.size == 1) + } }