diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/FeedReader.kt b/src/main/kotlin/net/thauvin/erik/mobibot/FeedReader.kt index 16c8e6b..739f45a 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/FeedReader.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/FeedReader.kt @@ -34,6 +34,7 @@ package net.thauvin.erik.mobibot import com.rometools.rome.io.FeedException import com.rometools.rome.io.SyndFeedInput import com.rometools.rome.io.XmlReader +import net.thauvin.erik.mobibot.Utils.cyan import net.thauvin.erik.mobibot.Utils.green import net.thauvin.erik.mobibot.Utils.helpFormat import net.thauvin.erik.mobibot.Utils.sendMessage @@ -83,7 +84,7 @@ class FeedReader(private val url: String, val event: GenericMessageEvent) : Runn } else { items.take(maxItems).forEach { messages.add(NoticeMessage(it.title)) - messages.add(NoticeMessage(helpFormat(green(it.link), false))) + messages.add(NoticeMessage(helpFormat(it.link.cyan(), false))) } } } diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/Utils.kt b/src/main/kotlin/net/thauvin/erik/mobibot/Utils.kt index 6f75788..0d220c8 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/Utils.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/Utils.kt @@ -75,19 +75,19 @@ object Utils { * Makes the given int bold. */ @JvmStatic - fun bold(i: Int): String = bold(i.toString()) + fun Int.bold(): String = this.toString().bold() /** * Makes the given long bold. */ @JvmStatic - fun bold(i: Long): String = bold(i.toString()) + fun Long.bold(): String = this.toString().bold() /** * Makes the given string bold. */ @JvmStatic - fun bold(s: String?): String = colorize(s, Colors.BOLD) + fun String?.bold(): String = this.colorize(Colors.BOLD) /** * Returns the [PircBotX] instance. @@ -122,15 +122,15 @@ object Utils { * Colorize a string. */ @JvmStatic - fun colorize(s: String?, color: String): String { - return if (s.isNullOrEmpty()) { + fun String?.colorize(color: String): String { + return if (this.isNullOrEmpty()) { "" } else if (color == DEFAULT_COLOR) { - s + this } else if (Colors.BOLD == color || Colors.REVERSE == color) { - color + s + color + color + this + color } else { - color + s + Colors.NORMAL + color + this + Colors.NORMAL } } @@ -138,7 +138,7 @@ object Utils { * Makes the given string cyan. */ @JvmStatic - fun cyan(s: String?): String = colorize(s, Colors.CYAN) + fun String?.cyan(): String = this.colorize(Colors.CYAN) /** * URL encodes the given string. @@ -158,7 +158,7 @@ object Utils { * Makes the given string green. */ @JvmStatic - fun green(s: String?): String = colorize(s, Colors.DARK_GREEN) + fun String?.green(): String = this.colorize(Colors.DARK_GREEN) /** * Returns a formatted help string. @@ -166,7 +166,7 @@ object Utils { @JvmStatic @JvmOverloads fun helpFormat(help: String, isBold: Boolean = true, isIndent: Boolean = true): String { - val s = if (isBold) bold(help) else help + val s = if (isBold) help.bold() else help return if (isIndent) s.prependIndent() else s } @@ -200,7 +200,7 @@ object Utils { * Makes the given string red. */ @JvmStatic - fun red(s: String?): String = colorize(s, Colors.RED) + fun String?.red(): String = this.colorize(Colors.RED) /** * Replaces all occurrences of Strings within another String. @@ -220,7 +220,7 @@ object Utils { * Makes the given string reverse color. */ @JvmStatic - fun reverseColor(s: String?): String = colorize(s, Colors.REVERSE) + fun String?.reverseColor(): String = this.colorize(Colors.REVERSE) /** * Send a formatted commands/modules, etc. list. @@ -252,11 +252,11 @@ object Utils { @JvmStatic fun GenericMessageEvent.sendMessage(channel: String, message: Message) { if (message.isNotice) { - bot().sendIRC().notice(user.nick, colorize(message.msg, message.color)) + bot().sendIRC().notice(user.nick, message.msg.colorize(message.color)) } else if (message.isPrivate || this is PrivateMessageEvent || channel.isBlank()) { - respondPrivateMessage(colorize(message.msg, message.color)) + respondPrivateMessage(message.msg.colorize(message.color)) } else { - bot().sendIRC().message(channel, colorize(message.msg, message.color)) + bot().sendIRC().message(channel, message.msg.colorize(message.color)) } } diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/commands/Ignore.kt b/src/main/kotlin/net/thauvin/erik/mobibot/commands/Ignore.kt index d1e38ce..2dc04ca 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/commands/Ignore.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/commands/Ignore.kt @@ -134,7 +134,7 @@ class Ignore : AbstractCommand() { event.sendMessage("The following nicks are ignored:") event.sendList(ignored.sorted(), 8, isIndent = true) } else { - event.sendMessage("No one is currently ${bold("ignored")}.") + event.sendMessage("No one is currently ${"ignored".bold()}.") } } diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/commands/Info.kt b/src/main/kotlin/net/thauvin/erik/mobibot/commands/Info.kt index a383756..8e54bf0 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/commands/Info.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/commands/Info.kt @@ -33,6 +33,7 @@ package net.thauvin.erik.mobibot.commands import net.thauvin.erik.mobibot.ReleaseInfo import net.thauvin.erik.mobibot.Utils.capitalise +import net.thauvin.erik.mobibot.Utils.cyan import net.thauvin.erik.mobibot.Utils.green import net.thauvin.erik.mobibot.Utils.helpFormat import net.thauvin.erik.mobibot.Utils.isChannelOp @@ -46,8 +47,8 @@ import java.lang.management.ManagementFactory class Info(private val tell: Tell) : AbstractCommand() { private val allVersions = listOf( - "${ReleaseInfo.PROJECT.capitalise()} ${ReleaseInfo.VERSION} (${green(ReleaseInfo.WEBSITE)})", - "Written by ${ReleaseInfo.AUTHOR} (${green(ReleaseInfo.AUTHOR_URL)})" + "${ReleaseInfo.PROJECT.capitalise()} ${ReleaseInfo.VERSION} (${ReleaseInfo.WEBSITE.cyan()})", + "Written by ${ReleaseInfo.AUTHOR} (${ReleaseInfo.AUTHOR_URL.green()})" ) override val name = "info" override val help = listOf("To view information about the bot:", helpFormat("%c $name")) diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/commands/links/Comment.kt b/src/main/kotlin/net/thauvin/erik/mobibot/commands/links/Comment.kt index 61143fb..02f0a3c 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/commands/links/Comment.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/commands/links/Comment.kt @@ -47,7 +47,7 @@ class Comment : AbstractCommand() { override val help = listOf( "To add a comment:", helpFormat("${Constants.LINK_CMD}1:This is a comment"), - "I will reply with a label, for example: ${bold(Constants.LINK_CMD)}1.1", + "I will reply with a label, for example: ${Constants.LINK_CMD.bold()}1.1", "To edit a comment, use its label: ", helpFormat("${Constants.LINK_CMD}1.1:This is an edited comment"), "To delete a comment, use its label and a minus sign: ", diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/commands/links/LinksMgr.kt b/src/main/kotlin/net/thauvin/erik/mobibot/commands/links/LinksMgr.kt index 7bd95b8..74be69f 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/commands/links/LinksMgr.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/commands/links/LinksMgr.kt @@ -167,7 +167,7 @@ class LinksMgr : AbstractCommand() { for (i in entries.links.indices) { if (link == entries.links[i].link) { val entry: EntryLink = entries.links[i] - event.sendMessage(bold("Duplicate") + " >> " + EntriesUtils.buildLink(i, entry)) + event.sendMessage("Duplicate".bold() + " >> " + EntriesUtils.buildLink(i, entry)) return true } } diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/commands/links/Posting.kt b/src/main/kotlin/net/thauvin/erik/mobibot/commands/links/Posting.kt index 2e7d9ec..1a43c03 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/commands/links/Posting.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/commands/links/Posting.kt @@ -49,12 +49,12 @@ class Posting : AbstractCommand() { override val help = listOf( "Post a URL, by saying it on a line on its own:", helpFormat(" [] ${Tags.COMMAND}: <+tag> [...]]"), - "I will reply with a label, for example: ${bold(Constants.LINK_CMD)}1", + "I will reply with a label, for example: ${Constants.LINK_CMD.bold()}1", "To add a title, use its label and a pipe:", helpFormat("${Constants.LINK_CMD}1:|This is the title"), "To add a comment:", helpFormat("${Constants.LINK_CMD}1:This is a comment"), - "I will reply with a label, for example: ${bold(Constants.LINK_CMD)}1.1", + "I will reply with a label, for example: ${Constants.LINK_CMD.bold()}1.1", "To edit a comment, see: ", helpFormat("%c ${Constants.HELP_CMD} ${Comment.COMMAND}") ) diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/entries/EntriesUtils.kt b/src/main/kotlin/net/thauvin/erik/mobibot/entries/EntriesUtils.kt index b577895..4c4c29c 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/entries/EntriesUtils.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/entries/EntriesUtils.kt @@ -65,9 +65,9 @@ object EntriesUtils { if (Constants.NO_TITLE == title) { buff.append(title) } else { - buff.append(bold(title)) + buff.append(title.bold()) } - buff.append(" ( ").append(green(link)).append(" )") + buff.append(" ( ").append(link.green()).append(" )") } return buff.toString() } diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/modules/Calc.kt b/src/main/kotlin/net/thauvin/erik/mobibot/modules/Calc.kt index efe87e5..25ae072 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/modules/Calc.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/modules/Calc.kt @@ -74,7 +74,7 @@ class Calc : AbstractModule() { fun calculate(query: String): String { val decimalFormat = DecimalFormat("#.##") val calc = ExpressionBuilder(query).build() - return query.replace(" ", "") + " = " + bold(decimalFormat.format(calc.evaluate())) + return query.replace(" ", "") + " = " + decimalFormat.format(calc.evaluate()).bold() } } diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/modules/CurrencyConverter.kt b/src/main/kotlin/net/thauvin/erik/mobibot/modules/CurrencyConverter.kt index ebaadb8..915aa49 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/modules/CurrencyConverter.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/modules/CurrencyConverter.kt @@ -89,7 +89,7 @@ class CurrencyConverter : ThreadedModule() { helpResponse(event) } } else if (args.contains(CURRENCY_RATES_KEYWORD)) { - event.sendMessage("The reference rates for ${bold(pubDate)} are:") + event.sendMessage("The reference rates for ${pubDate.bold()} are:") event.sendList(currencyRates(), 3, " ", isIndent = true) } else { helpResponse(event) diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/modules/Dice.kt b/src/main/kotlin/net/thauvin/erik/mobibot/modules/Dice.kt index 977a5b6..4dced28 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/modules/Dice.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/modules/Dice.kt @@ -47,11 +47,11 @@ class Dice : AbstractModule() { val total = roll.first + roll.second with(event.bot()) { event.respond( - "you rolled ${DICE_FACES[roll.first]} ${DICE_FACES[roll.second]} for a total of ${bold(total)}" + "you rolled ${DICE_FACES[roll.first]} ${DICE_FACES[roll.second]} for a total of ${total.bold()}" ) sendIRC().action( channel, - "rolled ${DICE_FACES[botRoll.first]} ${DICE_FACES[botRoll.second]} for a total of ${bold(botTotal)}" + "rolled ${DICE_FACES[botRoll.first]} ${DICE_FACES[botRoll.second]} for a total of ${botTotal.bold()}" ) when (winLoseOrTie(botTotal, total)) { Result.WIN -> sendIRC().action(channel, "wins.") diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/modules/Joke.kt b/src/main/kotlin/net/thauvin/erik/mobibot/modules/Joke.kt index 3ba5f00..26d7af3 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/modules/Joke.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/modules/Joke.kt @@ -66,7 +66,7 @@ class Joke : ThreadedModule() { override fun run(channel: String, cmd: String, args: String, event: GenericMessageEvent) { with(event.bot()) { try { - sendIRC().notice(channel, cyan(randomJoke().msg)) + sendIRC().notice(channel, randomJoke().msg.cyan()) } catch (e: ModuleException) { if (logger.isWarnEnabled) logger.warn(e.debugMessage, e) e.message?.let { diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/modules/Weather2.kt b/src/main/kotlin/net/thauvin/erik/mobibot/modules/Weather2.kt index 273c374..f5f1e16 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/modules/Weather2.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/modules/Weather2.kt @@ -240,7 +240,7 @@ class Weather2 : ThreadedModule() { add(helpFormat("%c $WEATHER_CMD <city> [, <country code>]")) add("For example:") add(helpFormat("%c $WEATHER_CMD paris, fr")) - add("The default ISO 3166 country code is ${bold("US")}. Zip codes supported in most countries.") + add("The default ISO 3166 country code is ${"US".bold()}. Zip codes supported in most countries.") } initProperties(OWM_API_KEY_PROP) } diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/modules/WorldTime.kt b/src/main/kotlin/net/thauvin/erik/mobibot/modules/WorldTime.kt index 3105d97..5d9fcde 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/modules/WorldTime.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/modules/WorldTime.kt @@ -64,7 +64,7 @@ class WorldTime : AbstractModule() { // Date/Time Format private var dtf = - DateTimeFormatter.ofPattern("'The time is ${bold("'HH:mm'")} on ${bold("'EEEE, d MMMM yyyy'")} in '") + DateTimeFormatter.ofPattern("'The time is ${"'HH:mm'".bold()} on ${"'EEEE, d MMMM yyyy'".bold()} in '") /** * Returns the current Internet (beat) Time. @@ -84,10 +84,10 @@ class WorldTime : AbstractModule() { val tz = COUNTRIES_MAP[(if (query.isNotBlank()) query.trim().uppercase() else DEFAULT_ZONE)] return if (tz != null) { if (BEATS_KEYWORD == tz) { - "The current Internet Time is ${bold(internetTime())} $BEATS_KEYWORD" + "The current Internet Time is ${internetTime().bold()} $BEATS_KEYWORD" } else { (ZonedDateTime.now().withZoneSameInstant(ZoneId.of(tz)).format(dtf) - + bold(tz.substring(tz.lastIndexOf('/') + 1).replace('_', ' '))) + + tz.substring(tz.lastIndexOf('/') + 1).replace('_', ' ').bold()) } } else { "Unsupported country/zone. Please try again." @@ -362,13 +362,8 @@ class WorldTime : AbstractModule() { zones["ZM"] = "Africa/Lusaka" zones["ZULU"] = "Zulu" zones["ZW"] = "Africa/Harare" - ZoneId.getAvailableZoneIds().stream() - .filter { tz: String -> - tz.length <= 3 && !zones.containsKey(tz) - } - .forEach { tz: String -> - zones[tz] = tz - } + ZoneId.getAvailableZoneIds().filter { it.length <= 3 && !zones.containsKey(it) } + .forEach { tz -> zones[tz] = tz } COUNTRIES_MAP = Collections.unmodifiableMap(zones) } } diff --git a/src/test/kotlin/net/thauvin/erik/mobibot/UtilsTest.kt b/src/test/kotlin/net/thauvin/erik/mobibot/UtilsTest.kt index 876bea0..92ac36f 100644 --- a/src/test/kotlin/net/thauvin/erik/mobibot/UtilsTest.kt +++ b/src/test/kotlin/net/thauvin/erik/mobibot/UtilsTest.kt @@ -97,10 +97,10 @@ class UtilsTest { @Test fun testBold() { - assertThat(bold(1), "bold(1)").isEqualTo(Colors.BOLD + "1" + Colors.BOLD) - assertThat(bold(2L), "bold(1)").isEqualTo(Colors.BOLD + "2" + Colors.BOLD) - assertThat(bold(ascii), "bold(ascii)").isEqualTo(Colors.BOLD + ascii + Colors.BOLD) - assertThat(bold("test"), "bold(test)").isEqualTo(Colors.BOLD + "test" + Colors.BOLD) + assertThat(1.bold(), "1.bold()").isEqualTo(Colors.BOLD + "1" + Colors.BOLD) + assertThat(2L.bold(), "1.bold()").isEqualTo(Colors.BOLD + "2" + Colors.BOLD) + assertThat(ascii.bold(), "ascii.bold()").isEqualTo(Colors.BOLD + ascii + Colors.BOLD) + assertThat("test".bold(), "test.bold()").isEqualTo(Colors.BOLD + "test" + Colors.BOLD) } @Test @@ -131,23 +131,23 @@ class UtilsTest { @Test fun testColorize() { - assertThat(colorize(ascii, Colors.REVERSE), "colorize(reverse)").isEqualTo( + assertThat(ascii.colorize(Colors.REVERSE), "reverse.colorize()").isEqualTo( Colors.REVERSE + ascii + Colors.REVERSE ) - assertThat(colorize(ascii, Colors.RED), "colorize(red)") + assertThat(ascii.colorize(Colors.RED), "red.colorize()") .isEqualTo(Colors.RED + ascii + Colors.NORMAL) - assertThat(colorize(ascii, Colors.BOLD), "colorized(bold)") + assertThat(ascii.colorize(Colors.BOLD), "colorized(bold)") .isEqualTo(Colors.BOLD + ascii + Colors.BOLD) - assertThat(colorize(null, Colors.RED), "colorize(null)").isEqualTo("") - assertThat(colorize("", Colors.RED), "colorize()").isEqualTo("") - assertThat(colorize(ascii, DEFAULT_COLOR), "colorize(none)").isEqualTo(ascii) - assertThat(colorize(" ", Colors.NORMAL), "colorize(blank)") + assertThat(null.colorize(Colors.RED), "null.colorize()").isEqualTo("") + assertThat("".colorize(Colors.RED), "colorize()").isEqualTo("") + assertThat(ascii.colorize(DEFAULT_COLOR), "none.colorize()").isEqualTo(ascii) + assertThat(" ".colorize(Colors.NORMAL), "blank.colorize()") .isEqualTo(Colors.NORMAL + " " + Colors.NORMAL) } @Test fun testCyan() { - assertThat(cyan(ascii)).isEqualTo(Colors.CYAN + ascii + Colors.NORMAL) + assertThat(ascii.cyan()).isEqualTo(Colors.CYAN + ascii + Colors.NORMAL) } @Test @@ -167,7 +167,7 @@ class UtilsTest { @Test fun testGreen() { - assertThat(green(ascii)).isEqualTo(Colors.DARK_GREEN + ascii + Colors.NORMAL) + assertThat(ascii.green()).isEqualTo(Colors.DARK_GREEN + ascii + Colors.NORMAL) } @Test @@ -177,7 +177,7 @@ class UtilsTest { assertThat(helpFormat(test, isBold = false, isIndent = true), "indent") .isEqualTo(test.prependIndent()) assertThat(helpFormat(test, isBold = true, isIndent = true), "bold-indent") - .isEqualTo(colorize(test, Colors.BOLD).prependIndent()) + .isEqualTo(test.colorize(Colors.BOLD).prependIndent()) } @@ -224,12 +224,12 @@ class UtilsTest { @Test fun testRed() { - assertThat(red(ascii)).isEqualTo(colorize(ascii, Colors.RED)) + assertThat(ascii.red()).isEqualTo(ascii.colorize(Colors.RED)) } @Test fun testReverseColor() { - assertThat(reverseColor(ascii)).isEqualTo(Colors.REVERSE + ascii + Colors.REVERSE) + assertThat(ascii.reverseColor()).isEqualTo(Colors.REVERSE + ascii + Colors.REVERSE) } @Test diff --git a/src/test/kotlin/net/thauvin/erik/mobibot/modules/CalcTest.kt b/src/test/kotlin/net/thauvin/erik/mobibot/modules/CalcTest.kt index 80a49b5..b37a09c 100644 --- a/src/test/kotlin/net/thauvin/erik/mobibot/modules/CalcTest.kt +++ b/src/test/kotlin/net/thauvin/erik/mobibot/modules/CalcTest.kt @@ -46,9 +46,9 @@ import org.testng.annotations.Test class CalcTest { @Test fun testCalculate() { - assertThat(calculate("1 + 1"), "calculate(1+1)").isEqualTo("1+1 = ${bold(2)}") - assertThat(calculate("1 -3"), "calculate(1 -3)").isEqualTo("1-3 = ${bold(-2)}") - assertThat(calculate("pi+π+e+φ"), "calculate(pi+π+e+φ)").isEqualTo("pi+π+e+φ = ${bold("10.62")}") + assertThat(calculate("1 + 1"), "calculate(1+1)").isEqualTo("1+1 = ${2.bold()}") + assertThat(calculate("1 -3"), "calculate(1 -3)").isEqualTo("1-3 = ${(-2).bold()}") + assertThat(calculate("pi+π+e+φ"), "calculate(pi+π+e+φ)").isEqualTo("pi+π+e+φ = ${"10.62".bold()}") assertThat { calculate("one + one") }.isFailure().isInstanceOf(UnknownFunctionOrVariableException::class.java) } } diff --git a/src/test/kotlin/net/thauvin/erik/mobibot/modules/WordTimeTest.kt b/src/test/kotlin/net/thauvin/erik/mobibot/modules/WordTimeTest.kt index ddc6e8f..abe9416 100644 --- a/src/test/kotlin/net/thauvin/erik/mobibot/modules/WordTimeTest.kt +++ b/src/test/kotlin/net/thauvin/erik/mobibot/modules/WordTimeTest.kt @@ -55,10 +55,10 @@ class WordTimeTest { "on ${Colors.BOLD}\\w+, \\d{1,2} \\w+ \\d{4}${Colors.BOLD} " + "in ${Colors.BOLD}Los Angeles${Colors.BOLD}").toRegex() ) - assertThat(time(""), "empty zone").endsWith(bold("Los Angeles")) - assertThat(time("PST"), "PST").endsWith(bold("Los Angeles")) - assertThat(time("GB"), "GB").endsWith(bold("London")) - assertThat(time("FR"), "FR").endsWith(bold("Paris")) + assertThat(time(""), "empty zone").endsWith("Los Angeles".bold()) + assertThat(time("PST"), "PST").endsWith("Los Angeles".bold()) + assertThat(time("GB"), "GB").endsWith("London".bold()) + assertThat(time("FR"), "FR").endsWith("Paris".bold()) assertThat(time("BLAH"), "BLAH").startsWith("Unsupported") assertThat(time("BEAT"), BEATS_KEYWORD).matches("[\\w ]+ .?@\\d{3}+.? .beats".toRegex()) }