Implemented seen command

This commit is contained in:
Erik C. Thauvin 2022-09-15 13:38:17 -07:00
parent d5000fa3c1
commit 3d49ebbd5f
11 changed files with 324 additions and 41 deletions

View file

@ -16,6 +16,11 @@
<option name="name" value="MavenLocal" /> <option name="name" value="MavenLocal" />
<option name="url" value="file:$MAVEN_REPOSITORY$/" /> <option name="url" value="file:$MAVEN_REPOSITORY$/" />
</remote-repository> </remote-repository>
<remote-repository>
<option name="id" value="MavenLocal" />
<option name="name" value="MavenLocal" />
<option name="url" value="file:$MAVEN_REPOSITORY$/" />
</remote-repository>
<remote-repository> <remote-repository>
<option name="id" value="maven2" /> <option name="id" value="maven2" />
<option name="name" value="maven2" /> <option name="name" value="maven2" />

3
.idea/misc.xml generated
View file

@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" /> <component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="FrameworkDetectionExcludesConfiguration">
<file type="web" url="file://$PROJECT_DIR$" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="18" project-jdk-type="JavaSDK" /> <component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="18" project-jdk-type="JavaSDK" />
</project> </project>

View file

@ -52,11 +52,13 @@
<ID>NestedBlockDepth:LinksMgr.kt$LinksMgr$override fun commandResponse(channel: String, args: String, event: GenericMessageEvent)</ID> <ID>NestedBlockDepth:LinksMgr.kt$LinksMgr$override fun commandResponse(channel: String, args: String, event: GenericMessageEvent)</ID>
<ID>NestedBlockDepth:Lookup.kt$Lookup$override fun commandResponse(channel: String, cmd: String, args: String, event: GenericMessageEvent)</ID> <ID>NestedBlockDepth:Lookup.kt$Lookup$override fun commandResponse(channel: String, cmd: String, args: String, event: GenericMessageEvent)</ID>
<ID>NestedBlockDepth:Posting.kt$Posting$override fun commandResponse(channel: String, args: String, event: GenericMessageEvent)</ID> <ID>NestedBlockDepth:Posting.kt$Posting$override fun commandResponse(channel: String, args: String, event: GenericMessageEvent)</ID>
<ID>NestedBlockDepth:Seen.kt$Seen$fun add(nick: String)</ID>
<ID>NestedBlockDepth:Seen.kt$Seen$override fun commandResponse(channel: String, args: String, event: GenericMessageEvent)</ID>
<ID>NestedBlockDepth:StockQuote.kt$StockQuote.Companion$@JvmStatic @Throws(ModuleException::class) fun getQuote(symbol: String, apiKey: String?): List&lt;Message&gt;</ID> <ID>NestedBlockDepth:StockQuote.kt$StockQuote.Companion$@JvmStatic @Throws(ModuleException::class) fun getQuote(symbol: String, apiKey: String?): List&lt;Message&gt;</ID>
<ID>NestedBlockDepth:Tell.kt$Tell$fun send(event: GenericUserEvent)</ID> <ID>NestedBlockDepth:Tell.kt$Tell$fun send(event: GenericUserEvent)</ID>
<ID>NestedBlockDepth:TellMessagesMgr.kt$TellMessagesMgr$@JvmStatic fun load(file: String): List&lt;TellMessage&gt;</ID>
<ID>NestedBlockDepth:TellMessagesMgr.kt$TellMessagesMgr$@JvmStatic fun save(file: String, messages: List&lt;TellMessage?&gt;?)</ID>
<ID>NestedBlockDepth:TwitterOAuth.kt$TwitterOAuth$@JvmStatic @Throws(TwitterException::class, IOException::class) fun main(args: Array&lt;String&gt;)</ID> <ID>NestedBlockDepth:TwitterOAuth.kt$TwitterOAuth$@JvmStatic @Throws(TwitterException::class, IOException::class) fun main(args: Array&lt;String&gt;)</ID>
<ID>NestedBlockDepth:Utils.kt$Utils$@JvmStatic fun loadData(file: String, default: Any, logger: Logger, description: String): Any</ID>
<ID>NestedBlockDepth:Utils.kt$Utils$@JvmStatic fun saveData(file: String, data: Any, logger: Logger, description: String)</ID>
<ID>NestedBlockDepth:Weather2.kt$Weather2$override fun run(channel: String, cmd: String, args: String, event: GenericMessageEvent)</ID> <ID>NestedBlockDepth:Weather2.kt$Weather2$override fun run(channel: String, cmd: String, args: String, event: GenericMessageEvent)</ID>
<ID>NestedBlockDepth:Weather2.kt$Weather2.Companion$@JvmStatic @Throws(ModuleException::class) fun getWeather(query: String, apiKey: String?): List&lt;Message&gt;</ID> <ID>NestedBlockDepth:Weather2.kt$Weather2.Companion$@JvmStatic @Throws(ModuleException::class) fun getWeather(query: String, apiKey: String?): List&lt;Message&gt;</ID>
<ID>ReturnCount:Addons.kt$Addons$fun exec(channel: String, cmd: String, args: String, event: GenericMessageEvent): Boolean</ID> <ID>ReturnCount:Addons.kt$Addons$fun exec(channel: String, cmd: String, args: String, event: GenericMessageEvent): Boolean</ID>

View file

@ -65,6 +65,7 @@ import net.thauvin.erik.mobibot.commands.links.LinksMgr
import net.thauvin.erik.mobibot.commands.links.Posting import net.thauvin.erik.mobibot.commands.links.Posting
import net.thauvin.erik.mobibot.commands.links.Tags import net.thauvin.erik.mobibot.commands.links.Tags
import net.thauvin.erik.mobibot.commands.links.View import net.thauvin.erik.mobibot.commands.links.View
import net.thauvin.erik.mobibot.commands.seen.Seen
import net.thauvin.erik.mobibot.commands.tell.Tell import net.thauvin.erik.mobibot.commands.tell.Tell
import net.thauvin.erik.mobibot.modules.Calc import net.thauvin.erik.mobibot.modules.Calc
import net.thauvin.erik.mobibot.modules.CryptoPrices import net.thauvin.erik.mobibot.modules.CryptoPrices
@ -113,7 +114,10 @@ class Mobibot(nickname: String, val channel: String, logsDirPath: String, p: Pro
// Commands and Modules // Commands and Modules
private val addons: Addons private val addons: Addons
// Tell module // Seen command
private val seen: Seen
// Tell command
private val tell: Tell private val tell: Tell
/** Logger. */ /** Logger. */
@ -231,6 +235,8 @@ class Mobibot(nickname: String, val channel: String, logsDirPath: String, p: Pro
with(event.getBot<PircBotX>()) { with(event.getBot<PircBotX>()) {
if (user.nick == nick) { if (user.nick == nick) {
LinksMgr.twitter.notification("$nick has left ${event.channel.name} on irc://$serverHostname") LinksMgr.twitter.notification("$nick has left ${event.channel.name} on irc://$serverHostname")
} else {
seen.add(user.nick)
} }
} }
} }
@ -253,7 +259,7 @@ class Mobibot(nickname: String, val channel: String, logsDirPath: String, p: Pro
Constants.PROPS_ARG, Constants.PROPS_ARG,
Constants.PROPS_ARG.substring(0, 1), Constants.PROPS_ARG.substring(0, 1),
"Use alternate properties file" "Use alternate properties file"
).default("./mobibot.properties") ).default("./${ReleaseInfo.PROJECT}.properties")
val version by parser.option( val version by parser.option(
ArgType.Boolean, ArgType.Boolean,
Constants.VERSION_ARG, Constants.VERSION_ARG,
@ -355,6 +361,7 @@ class Mobibot(nickname: String, val channel: String, logsDirPath: String, p: Pro
nickservCustomMessage = identMsg nickservCustomMessage = identMsg
} }
isAutoReconnect = true isAutoReconnect = true
//socketConnectTimeout = Constants.CONNECT_TIMEOUT //socketConnectTimeout = Constants.CONNECT_TIMEOUT
//socketTimeout = Constants.CONNECT_TIMEOUT //socketTimeout = Constants.CONNECT_TIMEOUT
//messageDelay = StaticDelay(500) //messageDelay = StaticDelay(500)
@ -388,6 +395,11 @@ class Mobibot(nickname: String, val channel: String, logsDirPath: String, p: Pro
addons.add(Posting()) addons.add(Posting())
addons.add(Recap()) addons.add(Recap())
addons.add(Say()) addons.add(Say())
// Seen command
seen = Seen("${logsDirPath}${nickname}-seen.ser")
addons.add(seen)
addons.add(Tags()) addons.add(Tags())
// Tell command // Tell command

View file

@ -38,18 +38,27 @@ import org.pircbotx.Colors
import org.pircbotx.PircBotX import org.pircbotx.PircBotX
import org.pircbotx.hooks.events.PrivateMessageEvent import org.pircbotx.hooks.events.PrivateMessageEvent
import org.pircbotx.hooks.types.GenericMessageEvent import org.pircbotx.hooks.types.GenericMessageEvent
import org.slf4j.Logger
import java.io.BufferedInputStream
import java.io.BufferedOutputStream
import java.io.BufferedReader import java.io.BufferedReader
import java.io.IOException import java.io.IOException
import java.io.InputStreamReader import java.io.InputStreamReader
import java.io.ObjectInputStream
import java.io.ObjectOutputStream
import java.net.URL import java.net.URL
import java.net.URLEncoder import java.net.URLEncoder
import java.nio.charset.StandardCharsets import java.nio.charset.StandardCharsets
import java.nio.file.Files
import java.nio.file.Paths
import java.time.LocalDateTime import java.time.LocalDateTime
import java.time.ZoneId import java.time.ZoneId
import java.time.format.DateTimeFormatter import java.time.format.DateTimeFormatter
import java.util.Date import java.util.Date
import java.util.Properties import java.util.Properties
import java.util.stream.Collectors import java.util.stream.Collectors
import kotlin.io.path.exists
import kotlin.io.path.fileSize
/** /**
* Miscellaneous utilities. * Miscellaneous utilities.
@ -188,6 +197,29 @@ object Utils {
"" ""
} }
/**
* Load data.
*/
@JvmStatic
fun loadData(file: String, default: Any, logger: Logger, description: String): Any {
val serialFile = Paths.get(file)
if (serialFile.exists() && serialFile.fileSize() > 0) {
try {
ObjectInputStream(
BufferedInputStream(Files.newInputStream(serialFile))
).use { input ->
if (logger.isDebugEnabled) logger.debug("Loading the ${description}.")
return input.readObject()
}
} catch (e: IOException) {
logger.error("An IO error occurred loading the ${description}.", e)
} catch (e: ClassNotFoundException) {
logger.error("An error occurred loading the {$description}.", e)
}
}
return default
}
/** /**
* Returns {@code true} if the list does not contain the given string. * Returns {@code true} if the list does not contain the given string.
*/ */
@ -238,6 +270,23 @@ object Utils {
@JvmStatic @JvmStatic
fun String?.reverseColor(): String = colorize(Colors.REVERSE) fun String?.reverseColor(): String = colorize(Colors.REVERSE)
/**
* Save data
*/
@JvmStatic
fun saveData(file: String, data: Any, logger: Logger, description: String) {
try {
BufferedOutputStream(Files.newOutputStream(Paths.get(file))).use { bos ->
ObjectOutputStream(bos).use { output ->
if (logger.isDebugEnabled) logger.debug("Saving the ${description}.")
output.writeObject(data)
}
}
} catch (e: IOException) {
logger.error("Unable to save the ${description}.", e)
}
}
/** /**
* Send a formatted commands/modules, etc. list. * Send a formatted commands/modules, etc. list.
*/ */

View file

@ -63,7 +63,7 @@ class Info(private val tell: Tell) : AbstractCommand() {
*/ */
@JvmStatic @JvmStatic
fun Long.toUptime(): String { fun Long.toUptime(): String {
this.toDuration(DurationUnit.MILLISECONDS).toComponents { wholeDays, hours, minutes, _, _ -> this.toDuration(DurationUnit.MILLISECONDS).toComponents { wholeDays, hours, minutes, seconds, _ ->
val years = wholeDays / 365 val years = wholeDays / 365
var days = wholeDays % 365 var days = wholeDays % 365
val months = days / 30 val months = days / 30
@ -88,7 +88,11 @@ class Info(private val tell: Tell) : AbstractCommand() {
append(hours).append(" hour".plural(hours.toLong())).append(' ') append(hours).append(" hour".plural(hours.toLong())).append(' ')
} }
if (minutes > 0) {
append(minutes).append(" minute".plural(minutes.toLong())) append(minutes).append(" minute".plural(minutes.toLong()))
} else {
append(seconds).append(" second".plural(seconds.toLong()))
}
return toString() return toString()
} }

View file

@ -0,0 +1,118 @@
/*
* Seen.kt
*
* Copyright (c) 2004-2022, Erik C. Thauvin (erik@thauvin.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of this project nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.thauvin.erik.mobibot.commands.seen
import net.thauvin.erik.mobibot.Utils.bot
import net.thauvin.erik.mobibot.Utils.helpFormat
import net.thauvin.erik.mobibot.Utils.loadData
import net.thauvin.erik.mobibot.Utils.saveData
import net.thauvin.erik.mobibot.Utils.sendMessage
import net.thauvin.erik.mobibot.commands.AbstractCommand
import net.thauvin.erik.mobibot.commands.Info.Companion.toUptime
import org.pircbotx.hooks.types.GenericMessageEvent
import org.slf4j.Logger
import org.slf4j.LoggerFactory
class Seen(private val serialObject: String) : AbstractCommand() {
private val logger: Logger = LoggerFactory.getLogger(Seen::class.java)
val seenNicks: MutableList<SeenNick> = mutableListOf()
override val name = "seen"
override val help = listOf("To view when a nickname was last seen:", helpFormat("%c $name <nick>"))
override val isOpOnly = false
override val isPublic = true
override val isVisible = true
override fun commandResponse(channel: String, args: String, event: GenericMessageEvent) {
if (isEnabled()) {
if (args.isNotBlank() && !args.contains(' ')) {
val ch = event.bot().userChannelDao.getChannel(channel)
ch.users.forEach {
if (args.equals(it.nick, true)) {
event.sendMessage("${it.nick} is on ${channel}.")
return
}
}
seenNicks.forEach {
if (it.nick.equals(args, true)) {
val lastSeen = System.currentTimeMillis() - it.last
event.sendMessage("${it.nick} was last seen on $channel ${lastSeen.toUptime()} ago.")
return
}
}
event.sendMessage("I haven't seen $args on $channel lately.")
} else {
helpResponse(channel, args, event)
}
}
}
fun add(nick: String) {
if (isEnabled()) {
seenNicks.forEach {
if (it.nick.equals(nick, true)) {
if (it.nick != nick) it.nick = nick
it.last = System.currentTimeMillis()
save()
return
}
}
seenNicks.add(SeenNick(nick))
save()
}
}
fun clear() {
seenNicks.clear()
}
fun load() {
if (isEnabled()) {
@Suppress("UNCHECKED_CAST")
seenNicks += loadData(
serialObject,
mutableListOf<SeenNick>(),
logger,
"seen nicknames"
) as MutableList<SeenNick>
}
}
fun save() {
saveData(serialObject, seenNicks, logger, "seen nicknames")
}
init {
load()
}
}

View file

@ -0,0 +1,41 @@
/*
* SeenNick.kt
*
* Copyright (c) 2004-2022, Erik C. Thauvin (erik@thauvin.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of this project nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.thauvin.erik.mobibot.commands.seen
import java.io.Serializable
data class SeenNick(var nick: String, var last: Long = System.currentTimeMillis()) : Serializable {
companion object {
private const val serialVersionUID = 1L
}
}

View file

@ -31,18 +31,12 @@
*/ */
package net.thauvin.erik.mobibot.commands.tell package net.thauvin.erik.mobibot.commands.tell
import net.thauvin.erik.mobibot.Utils.loadData
import net.thauvin.erik.mobibot.Utils.saveData
import org.slf4j.Logger import org.slf4j.Logger
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import java.io.BufferedInputStream
import java.io.BufferedOutputStream
import java.io.IOException
import java.io.ObjectInputStream
import java.io.ObjectOutputStream
import java.nio.file.Files
import java.nio.file.Paths
import java.time.Clock import java.time.Clock
import java.time.LocalDateTime import java.time.LocalDateTime
import kotlin.io.path.exists
/** /**
* The Tell Messages Manager. * The Tell Messages Manager.
@ -65,23 +59,8 @@ object TellMessagesMgr {
*/ */
@JvmStatic @JvmStatic
fun load(file: String): List<TellMessage> { fun load(file: String): List<TellMessage> {
val serialFile = Paths.get(file)
if (serialFile.exists()) {
try {
ObjectInputStream(
BufferedInputStream(Files.newInputStream(serialFile))
).use { input ->
if (logger.isDebugEnabled) logger.debug("Loading the messages.")
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
return input.readObject() as List<TellMessage> return loadData(file, emptyList<TellMessage>(), logger, "message queue") as List<TellMessage>
}
} catch (e: IOException) {
logger.error("An IO error occurred loading the messages queue.", e)
} catch (e: ClassNotFoundException) {
logger.error("An error occurred loading the messages queue.", e)
}
}
return listOf()
} }
/** /**
@ -89,15 +68,8 @@ object TellMessagesMgr {
*/ */
@JvmStatic @JvmStatic
fun save(file: String, messages: List<TellMessage?>?) { fun save(file: String, messages: List<TellMessage?>?) {
try { if (messages != null) {
BufferedOutputStream(Files.newOutputStream(Paths.get(file))).use { bos -> saveData(file, messages, logger, "messages")
ObjectOutputStream(bos).use { output ->
if (logger.isDebugEnabled) logger.debug("Saving the messages.")
output.writeObject(messages)
}
}
} catch (e: IOException) {
logger.error("Unable to save messages queue.", e)
} }
} }
} }

View file

@ -46,6 +46,8 @@ class InfoTest {
assertThat(1320300000L.toUptime(), "weeks days hours minutes").isEqualTo("2 weeks 1 day 6 hours 45 minutes") assertThat(1320300000L.toUptime(), "weeks days hours minutes").isEqualTo("2 weeks 1 day 6 hours 45 minutes")
assertThat(2700000L.toUptime(), "45 minutes").isEqualTo("45 minutes") assertThat(2700000L.toUptime(), "45 minutes").isEqualTo("45 minutes")
assertThat(60000L.toUptime(), "1 minute").isEqualTo("1 minute") assertThat(60000L.toUptime(), "1 minute").isEqualTo("1 minute")
assertThat(0L.toUptime(), "0 minute").isEqualTo("0 minute") assertThat(59000L.toUptime(), "59 seconds").isEqualTo("59 seconds")
assertThat(0L.toUptime(), "0 second").isEqualTo("0 second")
} }
} }

View file

@ -0,0 +1,75 @@
/*
* SeenTest.kt
*
* Copyright (c) 2004-2022, Erik C. Thauvin (erik@thauvin.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of this project nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.thauvin.erik.mobibot.commands.seen
import assertk.assertThat
import assertk.assertions.isEqualTo
import assertk.assertions.isGreaterThan
import assertk.assertions.isTrue
import org.testng.annotations.AfterClass
import org.testng.annotations.BeforeClass
import org.testng.annotations.Test
import kotlin.io.path.deleteIfExists
import kotlin.io.path.fileSize
class SeenTest {
private val tmpFile = kotlin.io.path.createTempFile(suffix = ".ser")
private val seen = Seen(tmpFile.toAbsolutePath().toString())
@BeforeClass
fun saveTest() {
seen.add("ErikT")
assertThat(tmpFile.fileSize(), "temporary file is empty").isGreaterThan(0)
}
@AfterClass(alwaysRun = true)
fun afterClass() {
tmpFile.deleteIfExists()
}
@Test
fun loadTest() {
val nick = seen.seenNicks[0]
seen.clear()
seen.load()
assertThat(seen.seenNicks[0] == nick, "nick is different").isTrue()
}
@Test(priority = 10)
fun clearTest() {
seen.clear()
seen.save()
seen.load()
assertThat(seen.seenNicks.size, "nicknames are not empty.").isEqualTo(0)
}
}