From e9ea69f055ba4492c3e6e42b9afcbf0a15ef9236 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 23 Jan 2020 23:25:26 +0100 Subject: [PATCH 1/5] Add support for /rainbow and /rainbowme command (#879) --- CHANGES.md | 2 +- .../vector/riotx/features/command/Command.kt | 2 + .../riotx/features/command/CommandParser.kt | 10 +++ .../riotx/features/command/ParsedCommand.kt | 2 + .../home/room/detail/RoomDetailViewModel.kt | 21 ++++- .../composer/rainbow/RainbowGenerator.kt | 87 +++++++++++++++++++ .../room/detail/composer/rainbow/RgbColor.kt | 30 +++++++ vector/src/main/res/values/strings_riotX.xml | 3 + 8 files changed, 154 insertions(+), 3 deletions(-) create mode 100644 vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/rainbow/RainbowGenerator.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/rainbow/RgbColor.kt diff --git a/CHANGES.md b/CHANGES.md index 54dd5e5247..b8b5dd4b36 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,7 +8,7 @@ Improvements 🙌: - Sharing things to RiotX: sort list by recent room first (#771) Other changes: - - + - Add support for /rainbow and /rainbowme commands (#879) Bugfix 🐛: - diff --git a/vector/src/main/java/im/vector/riotx/features/command/Command.kt b/vector/src/main/java/im/vector/riotx/features/command/Command.kt index 8b72ffa4a6..6151ae0d66 100644 --- a/vector/src/main/java/im/vector/riotx/features/command/Command.kt +++ b/vector/src/main/java/im/vector/riotx/features/command/Command.kt @@ -37,6 +37,8 @@ enum class Command(val command: String, val parameters: String, @StringRes val d KICK_USER("/kick", " [reason]", R.string.command_description_kick_user), CHANGE_DISPLAY_NAME("/nick", "", R.string.command_description_nick), MARKDOWN("/markdown", "", R.string.command_description_markdown), + RAINBOW("/rainbow", "", R.string.command_description_rainbow), + RAINBOW_EMOTE("/rainbowme", "", R.string.command_description_rainbow_emote), CLEAR_SCALAR_TOKEN("/clear_scalar_token", "", R.string.command_description_clear_scalar_token), SPOILER("/spoiler", "", R.string.command_description_spoiler); diff --git a/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt b/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt index 359f2c1f13..58671df539 100644 --- a/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt +++ b/vector/src/main/java/im/vector/riotx/features/command/CommandParser.kt @@ -80,6 +80,16 @@ object CommandParser { ParsedCommand.SendEmote(message) } + Command.RAINBOW.command -> { + val message = textMessage.subSequence(Command.RAINBOW.command.length, textMessage.length).trim() + + ParsedCommand.SendRainbow(message) + } + Command.RAINBOW_EMOTE.command -> { + val message = textMessage.subSequence(Command.RAINBOW_EMOTE.command.length, textMessage.length).trim() + + ParsedCommand.SendRainbowEmote(message) + } Command.JOIN_ROOM.command -> { if (messageParts.size >= 2) { val roomAlias = messageParts[1] diff --git a/vector/src/main/java/im/vector/riotx/features/command/ParsedCommand.kt b/vector/src/main/java/im/vector/riotx/features/command/ParsedCommand.kt index dd7c0c7e86..c43b78d71c 100644 --- a/vector/src/main/java/im/vector/riotx/features/command/ParsedCommand.kt +++ b/vector/src/main/java/im/vector/riotx/features/command/ParsedCommand.kt @@ -34,6 +34,8 @@ sealed class ParsedCommand { // Valid commands: class SendEmote(val message: CharSequence) : ParsedCommand() + class SendRainbow(val message: CharSequence) : ParsedCommand() + class SendRainbowEmote(val message: CharSequence) : ParsedCommand() class BanUser(val userId: String, val reason: String?) : ParsedCommand() class UnbanUser(val userId: String, val reason: String?) : ParsedCommand() class SetUserPowerLevel(val userId: String, val powerLevel: Int) : ParsedCommand() diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt index 36cbdcaa75..867a382bec 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt @@ -56,6 +56,7 @@ import im.vector.matrix.android.internal.crypto.model.event.EncryptedEventConten import im.vector.matrix.rx.rx import im.vector.matrix.rx.unwrap import im.vector.riotx.R +import im.vector.riotx.core.extensions.exhaustive import im.vector.riotx.core.extensions.postLiveEvent import im.vector.riotx.core.platform.VectorViewModel import im.vector.riotx.core.resources.StringProvider @@ -64,6 +65,7 @@ import im.vector.riotx.core.utils.LiveEvent import im.vector.riotx.core.utils.subscribeLogError import im.vector.riotx.features.command.CommandParser import im.vector.riotx.features.command.ParsedCommand +import im.vector.riotx.features.home.room.detail.composer.rainbow.RainbowGenerator import im.vector.riotx.features.home.room.detail.timeline.helper.TimelineDisplayableEvents import im.vector.riotx.features.home.room.typing.TypingHelper import im.vector.riotx.features.settings.VectorPreferences @@ -83,6 +85,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro private val vectorPreferences: VectorPreferences, private val stringProvider: StringProvider, private val typingHelper: TypingHelper, + private val rainbowGenerator: RainbowGenerator, private val session: Session ) : VectorViewModel(initialState), Timeline.Listener { @@ -385,6 +388,20 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro _sendMessageResultLiveData.postLiveEvent(SendMessageResult.SlashCommandHandled()) popDraft() } + is ParsedCommand.SendRainbow -> { + slashCommandResult.message.toString().let { + room.sendFormattedTextMessage(it, rainbowGenerator.generate(it)) + } + _sendMessageResultLiveData.postLiveEvent(SendMessageResult.SlashCommandHandled()) + popDraft() + } + is ParsedCommand.SendRainbowEmote -> { + slashCommandResult.message.toString().let { + room.sendFormattedTextMessage(it, rainbowGenerator.generate(it), MessageType.MSGTYPE_EMOTE) + } + _sendMessageResultLiveData.postLiveEvent(SendMessageResult.SlashCommandHandled()) + popDraft() + } is ParsedCommand.SendSpoiler -> { room.sendFormattedTextMessage( "[${stringProvider.getString(R.string.spoiler)}](${slashCommandResult.message})", @@ -401,7 +418,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro // TODO _sendMessageResultLiveData.postLiveEvent(SendMessageResult.SlashCommandNotImplemented) } - } + }.exhaustive } is SendMode.EDIT -> { // is original event a reply? @@ -459,7 +476,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro popDraft() } } - } + }.exhaustive } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/rainbow/RainbowGenerator.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/rainbow/RainbowGenerator.kt new file mode 100644 index 0000000000..c9defac8e8 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/rainbow/RainbowGenerator.kt @@ -0,0 +1,87 @@ +/* + * Copyright 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.riotx.features.home.room.detail.composer.rainbow + +import javax.inject.Inject +import kotlin.math.abs +import kotlin.math.roundToInt + +/** + * Inspired from React-Sdk + * Ref: https://github.com/matrix-org/matrix-react-sdk/blob/develop/src/utils/colour.js + */ +class RainbowGenerator @Inject constructor() { + + fun generate(text: String): String { + val frequency = 360f / text.length + + return text + .mapIndexed { idx, letter -> + // Do better than React-Sdk: Avoid adding font color for spaces + if (letter == ' ') { + "$letter" + } else { + val dashColor = hueToRGB(idx * frequency, 1.0f, 0.5f).toDashColor() + "$letter" + } + } + .joinToString(separator = "") + } + + private fun hueToRGB(h: Float, s: Float, l: Float): RgbColor { + val c = s * (1 - abs(2 * l - 1)) + val x = c * (1 - abs((h / 60) % 2 - 1)) + val m = l - c / 2 + + var r = 0f + var g = 0f + var b = 0f + + when { + h < 60f -> { + r = c + g = x + } + h < 120f -> { + r = x + g = c + } + h < 180f -> { + g = c + b = x + } + h < 240f -> { + g = x + b = c + } + h < 300f -> { + r = x + b = c + } + else -> { + r = c + b = x + } + } + + return RgbColor( + ((r + m) * 255).roundToInt(), + ((g + m) * 255).roundToInt(), + ((b + m) * 255).roundToInt() + ) + } +} diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/rainbow/RgbColor.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/rainbow/RgbColor.kt new file mode 100644 index 0000000000..bf2e808a36 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/rainbow/RgbColor.kt @@ -0,0 +1,30 @@ +/* + * Copyright 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.riotx.features.home.room.detail.composer.rainbow + +data class RgbColor( + val r: Int, + val g: Int, + val b: Int +) + +fun RgbColor.toDashColor(): String { + return listOf(r, g, b) + .joinToString(separator = "", prefix = "#") { + it.toString(16).padStart(2, '0') + } +} diff --git a/vector/src/main/res/values/strings_riotX.xml b/vector/src/main/res/values/strings_riotX.xml index 781912fbe5..98064c0148 100644 --- a/vector/src/main/res/values/strings_riotX.xml +++ b/vector/src/main/res/values/strings_riotX.xml @@ -37,6 +37,9 @@ Recent rooms Other rooms + Sends the given message colored as a rainbow + Sends the given emote colored as a rainbow + Timeline From 6d7d4993a66f40017bc61f9636c4dfea54dfec89 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 28 Jan 2020 21:56:02 +0100 Subject: [PATCH 2/5] Add TUs for RainbowGenerator (not all passing) --- .../composer/rainbow/RainbowGeneratorTest.kt | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 vector/src/test/java/im/vector/riotx/features/home/room/detail/composer/rainbow/RainbowGeneratorTest.kt diff --git a/vector/src/test/java/im/vector/riotx/features/home/room/detail/composer/rainbow/RainbowGeneratorTest.kt b/vector/src/test/java/im/vector/riotx/features/home/room/detail/composer/rainbow/RainbowGeneratorTest.kt new file mode 100644 index 0000000000..521fb15bf2 --- /dev/null +++ b/vector/src/test/java/im/vector/riotx/features/home/room/detail/composer/rainbow/RainbowGeneratorTest.kt @@ -0,0 +1,102 @@ +/* + * Copyright 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.riotx.features.home.room.detail.composer.rainbow + +import org.junit.Assert.assertEquals +import org.junit.Test + +class RainbowGeneratorTest { + + private val rainbowGenerator = RainbowGenerator() + + @Test + fun testEmpty() { + assertEquals("", rainbowGenerator.generate("")) + } + + @Test + fun testAscii1() { + assertEquals("""a""", rainbowGenerator.generate("a")) + } + + @Test + fun testAscii2() { + val expected = + """ + T + h + i + s + + i + s + + a + + r + a + i + n + b + o + w + ! + """ + .trimIndent() + .replace("\n", "") + + assertEquals(expected, rainbowGenerator.generate("This is a rainbow!")) + } + + @Test + fun testEmoji1() { + assertEquals("""\uD83E\uDD1E""", rainbowGenerator.generate("\uD83E\uDD1E")) // 🤞 + } + + @Test + fun testEmoji2() { + assertEquals("""🤞""", rainbowGenerator.generate("🤞")) + } + + @Test + fun testEmojiMix() { + val expected = """ + T + h + i + s + + i + s + + a + + r + a + i + n + b + o + w + ! + """ + .trimIndent() + .replace("\n", "") + + assertEquals(expected, rainbowGenerator.generate("Hello 🤞 world!")) + } +} \ No newline at end of file From b2338dfcd39da4795b5923749dd4fe2731022067 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 28 Jan 2020 22:35:40 +0100 Subject: [PATCH 3/5] Make the TU passes --- .../java/im/vector/riotx/core/utils/Emoji.kt | 36 +++++++++++++++++++ .../composer/rainbow/RainbowGenerator.kt | 4 ++- .../composer/rainbow/RainbowGeneratorTest.kt | 30 +++++++--------- 3 files changed, 52 insertions(+), 18 deletions(-) diff --git a/vector/src/main/java/im/vector/riotx/core/utils/Emoji.kt b/vector/src/main/java/im/vector/riotx/core/utils/Emoji.kt index f9e5654726..e91a2896bc 100644 --- a/vector/src/main/java/im/vector/riotx/core/utils/Emoji.kt +++ b/vector/src/main/java/im/vector/riotx/core/utils/Emoji.kt @@ -113,3 +113,39 @@ fun containsOnlyEmojis(str: String?): Boolean { return res } + +/** + * Same as split, but considering emojis + */ +fun CharSequence.splitEmoji(): List { + val result = mutableListOf() + + var index = 0 + + while (index < length) { + val firstChar = get(index) + + if (firstChar.toInt() == 0x200e) { + // Left to right mark. What should I do with it? + } else if (firstChar.toInt() in 0xD800..0xDBFF && index + 1 < length) { + // We have the start of a surrogate pair + val secondChar = get(index + 1) + + if (secondChar.toInt() in 0xDC00..0xDFFF) { + // We have an emoji + result.add("$firstChar$secondChar") + index++ + } else { + // Not sure what we have here... + result.add("$firstChar") + } + } else { + // Regular char + result.add("$firstChar") + } + + index++ + } + + return result +} diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/rainbow/RainbowGenerator.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/rainbow/RainbowGenerator.kt index c9defac8e8..9662e2d372 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/rainbow/RainbowGenerator.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/rainbow/RainbowGenerator.kt @@ -16,6 +16,7 @@ package im.vector.riotx.features.home.room.detail.composer.rainbow +import im.vector.riotx.core.utils.splitEmoji import javax.inject.Inject import kotlin.math.abs import kotlin.math.roundToInt @@ -30,9 +31,10 @@ class RainbowGenerator @Inject constructor() { val frequency = 360f / text.length return text + .splitEmoji() .mapIndexed { idx, letter -> // Do better than React-Sdk: Avoid adding font color for spaces - if (letter == ' ') { + if (letter == " ") { "$letter" } else { val dashColor = hueToRGB(idx * frequency, 1.0f, 0.5f).toDashColor() diff --git a/vector/src/test/java/im/vector/riotx/features/home/room/detail/composer/rainbow/RainbowGeneratorTest.kt b/vector/src/test/java/im/vector/riotx/features/home/room/detail/composer/rainbow/RainbowGeneratorTest.kt index 521fb15bf2..6a798638f2 100644 --- a/vector/src/test/java/im/vector/riotx/features/home/room/detail/composer/rainbow/RainbowGeneratorTest.kt +++ b/vector/src/test/java/im/vector/riotx/features/home/room/detail/composer/rainbow/RainbowGeneratorTest.kt @@ -64,7 +64,7 @@ class RainbowGeneratorTest { @Test fun testEmoji1() { - assertEquals("""\uD83E\uDD1E""", rainbowGenerator.generate("\uD83E\uDD1E")) // 🤞 + assertEquals("""🤞""", rainbowGenerator.generate("\uD83E\uDD1E")) // 🤞 } @Test @@ -75,24 +75,20 @@ class RainbowGeneratorTest { @Test fun testEmojiMix() { val expected = """ - T - h - i - s + H + e + l + l + o - i - s + 🤞 - a - - r - a - i - n - b - o - w - ! + w + o + r + l + d + ! """ .trimIndent() .replace("\n", "") From 007b0cabf21323f773e63dd1e9563379466a44c5 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 28 Jan 2020 22:43:10 +0100 Subject: [PATCH 4/5] Add a few TUs --- .../composer/rainbow/RainbowGeneratorTest.kt | 50 ++++++++++++++++--- 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/vector/src/test/java/im/vector/riotx/features/home/room/detail/composer/rainbow/RainbowGeneratorTest.kt b/vector/src/test/java/im/vector/riotx/features/home/room/detail/composer/rainbow/RainbowGeneratorTest.kt index 6a798638f2..3e1092d288 100644 --- a/vector/src/test/java/im/vector/riotx/features/home/room/detail/composer/rainbow/RainbowGeneratorTest.kt +++ b/vector/src/test/java/im/vector/riotx/features/home/room/detail/composer/rainbow/RainbowGeneratorTest.kt @@ -56,8 +56,7 @@ class RainbowGeneratorTest { w ! """ - .trimIndent() - .replace("\n", "") + .trimIndentOnLine() assertEquals(expected, rainbowGenerator.generate("This is a rainbow!")) } @@ -73,7 +72,18 @@ class RainbowGeneratorTest { } @Test - fun testEmojiMix() { + fun testEmoji3() { + val expected = """ + 🤞 + 🙂 + """ + .trimIndentOnLine() + + assertEquals(expected, rainbowGenerator.generate("🤞🙂")) + } + + @Test + fun testEmojiMix1() { val expected = """ H e @@ -90,9 +100,37 @@ class RainbowGeneratorTest { d ! """ - .trimIndent() - .replace("\n", "") + .trimIndentOnLine() assertEquals(expected, rainbowGenerator.generate("Hello 🤞 world!")) } -} \ No newline at end of file + + @Test + fun testEmojiMix2() { + val expected = """ + a + 🤞 + """ + .trimIndentOnLine() + + assertEquals(expected, rainbowGenerator.generate("a🤞")) + } + + @Test + fun testEmojiMix3() { + val expected = """ + 🤞 + a + """ + .trimIndentOnLine() + + assertEquals(expected, rainbowGenerator.generate("🤞a")) + } + + @Test + fun testError1() { + assertEquals("\uD83E", rainbowGenerator.generate("\uD83E")) + } +} + +fun String.trimIndentOnLine() = trimIndent().replace("\n", "") \ No newline at end of file From 27fe4e3680193641f1ff03a9cb4b0d620ac5d4f8 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 29 Jan 2020 09:44:53 +0100 Subject: [PATCH 5/5] Fix build and add tests --- .../composer/rainbow/RainbowGenerator.kt | 6 +- .../composer/rainbow/RainbowGeneratorTest.kt | 60 ++++++++++--------- .../java/im/vector/riotx/test/Extensions.kt | 19 ++++++ 3 files changed, 54 insertions(+), 31 deletions(-) create mode 100644 vector/src/test/java/im/vector/riotx/test/Extensions.kt diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/rainbow/RainbowGenerator.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/rainbow/RainbowGenerator.kt index 9662e2d372..3868be4e2e 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/rainbow/RainbowGenerator.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/composer/rainbow/RainbowGenerator.kt @@ -28,10 +28,10 @@ import kotlin.math.roundToInt class RainbowGenerator @Inject constructor() { fun generate(text: String): String { - val frequency = 360f / text.length + val split = text.splitEmoji() + val frequency = 360f / split.size - return text - .splitEmoji() + return split .mapIndexed { idx, letter -> // Do better than React-Sdk: Avoid adding font color for spaces if (letter == " ") { diff --git a/vector/src/test/java/im/vector/riotx/features/home/room/detail/composer/rainbow/RainbowGeneratorTest.kt b/vector/src/test/java/im/vector/riotx/features/home/room/detail/composer/rainbow/RainbowGeneratorTest.kt index 3e1092d288..5a9fdc0ab7 100644 --- a/vector/src/test/java/im/vector/riotx/features/home/room/detail/composer/rainbow/RainbowGeneratorTest.kt +++ b/vector/src/test/java/im/vector/riotx/features/home/room/detail/composer/rainbow/RainbowGeneratorTest.kt @@ -16,9 +16,11 @@ package im.vector.riotx.features.home.room.detail.composer.rainbow +import im.vector.riotx.test.trimIndentOneLine import org.junit.Assert.assertEquals import org.junit.Test +@Suppress("SpellCheckingInspection") class RainbowGeneratorTest { private val rainbowGenerator = RainbowGenerator() @@ -35,8 +37,17 @@ class RainbowGeneratorTest { @Test fun testAscii2() { - val expected = - """ + val expected = """ + a + b + """.trimIndentOneLine() + + assertEquals(expected, rainbowGenerator.generate("ab")) + } + + @Test + fun testAscii3() { + val expected = """ T h i @@ -55,8 +66,7 @@ class RainbowGeneratorTest { o w ! - """ - .trimIndentOnLine() + """.trimIndentOneLine() assertEquals(expected, rainbowGenerator.generate("This is a rainbow!")) } @@ -75,9 +85,8 @@ class RainbowGeneratorTest { fun testEmoji3() { val expected = """ 🤞 - 🙂 - """ - .trimIndentOnLine() + 🙂 + """.trimIndentOneLine() assertEquals(expected, rainbowGenerator.generate("🤞🙂")) } @@ -86,21 +95,20 @@ class RainbowGeneratorTest { fun testEmojiMix1() { val expected = """ H - e - l - l - o + e + l + l + o - 🤞 + 🤞 - w - o - r - l - d - ! - """ - .trimIndentOnLine() + w + o + r + l + d + ! + """.trimIndentOneLine() assertEquals(expected, rainbowGenerator.generate("Hello 🤞 world!")) } @@ -109,9 +117,8 @@ class RainbowGeneratorTest { fun testEmojiMix2() { val expected = """ a - 🤞 - """ - .trimIndentOnLine() + 🤞 + """.trimIndentOneLine() assertEquals(expected, rainbowGenerator.generate("a🤞")) } @@ -120,9 +127,8 @@ class RainbowGeneratorTest { fun testEmojiMix3() { val expected = """ 🤞 - a - """ - .trimIndentOnLine() + a + """.trimIndentOneLine() assertEquals(expected, rainbowGenerator.generate("🤞a")) } @@ -132,5 +138,3 @@ class RainbowGeneratorTest { assertEquals("\uD83E", rainbowGenerator.generate("\uD83E")) } } - -fun String.trimIndentOnLine() = trimIndent().replace("\n", "") \ No newline at end of file diff --git a/vector/src/test/java/im/vector/riotx/test/Extensions.kt b/vector/src/test/java/im/vector/riotx/test/Extensions.kt new file mode 100644 index 0000000000..31781ce00e --- /dev/null +++ b/vector/src/test/java/im/vector/riotx/test/Extensions.kt @@ -0,0 +1,19 @@ +/* + * Copyright 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.riotx.test + +fun String.trimIndentOneLine() = trimIndent().replace("\n", "")