mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI.git
synced 2024-11-22 16:23:48 +00:00
commit
ba145d3ff8
12
CHANGELOG.md
12
CHANGELOG.md
@ -20,6 +20,18 @@
|
|||||||
* `Game` now is not serializable and have no additional trash, related to serialization
|
* `Game` now is not serializable and have no additional trash, related to serialization
|
||||||
* `TelegramFile` was removed
|
* `TelegramFile` was removed
|
||||||
|
|
||||||
|
### 0.18.1 Libraries update
|
||||||
|
|
||||||
|
* Update libraries:
|
||||||
|
* `kotlin`: 1.3.41 -> 1.3.61
|
||||||
|
* `kotlin coroutines`: 1.2.2 -> 1.3.2
|
||||||
|
* `kotlin serialization`: 0.11.1 -> 0.14.0
|
||||||
|
* `joda time`: 2.10.3 -> 2.10.5
|
||||||
|
* `ktor`: 1.2.3 -> 1.2.6
|
||||||
|
* `BotAction` now will be deserialized in a little bit other way
|
||||||
|
* `BotActionSerializer` now is internal
|
||||||
|
* Most part of serializers now are objects (instead of classes as was previously)
|
||||||
|
|
||||||
## 0.17.0 July 29, 2019 API Update
|
## 0.17.0 July 29, 2019 API Update
|
||||||
|
|
||||||
Libraries updates:
|
Libraries updates:
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
project.version = "0.18.0"
|
project.version = "0.18.1"
|
||||||
project.group = "com.github.insanusmokrassar"
|
project.group = "com.github.insanusmokrassar"
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
@ -39,6 +39,8 @@ dependencies {
|
|||||||
|
|
||||||
api "io.ktor:ktor-server:$ktor_version"
|
api "io.ktor:ktor-server:$ktor_version"
|
||||||
api "io.ktor:ktor-server-host-common:$ktor_version"
|
api "io.ktor:ktor-server-host-common:$ktor_version"
|
||||||
|
|
||||||
|
testImplementation "org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version"
|
||||||
}
|
}
|
||||||
|
|
||||||
compileKotlin {
|
compileKotlin {
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
kotlin.code.style=official
|
kotlin.code.style=official
|
||||||
kotlin_version=1.3.41
|
kotlin_version=1.3.61
|
||||||
kotlin_coroutines_version=1.2.2
|
kotlin_coroutines_version=1.3.2
|
||||||
kotlin_serialisation_runtime_version=0.11.1
|
kotlin_serialisation_runtime_version=0.14.0
|
||||||
joda_time_version=2.10.3
|
joda_time_version=2.10.5
|
||||||
ktor_version=1.2.3
|
ktor_version=1.2.6
|
||||||
|
|
||||||
gradle_bintray_plugin_version=1.8.4
|
gradle_bintray_plugin_version=1.8.4
|
||||||
|
|
||||||
|
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,6 +1,6 @@
|
|||||||
#Thu Feb 21 12:05:40 HKT 2019
|
#Fri Nov 29 12:11:00 HKT 2019
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.2.1-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-6.0.1-all.zip
|
||||||
|
@ -1,18 +1 @@
|
|||||||
/*
|
|
||||||
* This settings file was generated by the Gradle 'init' task.
|
|
||||||
*
|
|
||||||
* The settings file is used to specify which projects to include in your build.
|
|
||||||
* In a single project build this file can be empty or even removed.
|
|
||||||
*
|
|
||||||
* Detailed information about configuring a multi-project build in Gradle can be found
|
|
||||||
* in the user guide at https://docs.gradle.org/3.4.1/userguide/multi_project_builds.html
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
// To declare projects as part of a multi-project build use the 'include' method
|
|
||||||
include 'shared'
|
|
||||||
include 'api'
|
|
||||||
include 'services:webservice'
|
|
||||||
*/
|
|
||||||
|
|
||||||
rootProject.name = 'TelegramBotAPI'
|
rootProject.name = 'TelegramBotAPI'
|
||||||
|
@ -37,7 +37,7 @@ data class Username(
|
|||||||
fun String.toUsername(): Username = Username(this)
|
fun String.toUsername(): Username = Username(this)
|
||||||
|
|
||||||
@Serializer(ChatIdentifier::class)
|
@Serializer(ChatIdentifier::class)
|
||||||
internal class ChatIdentifierSerializer: KSerializer<ChatIdentifier> {
|
internal object ChatIdentifierSerializer : KSerializer<ChatIdentifier> {
|
||||||
override fun deserialize(decoder: Decoder): ChatIdentifier {
|
override fun deserialize(decoder: Decoder): ChatIdentifier {
|
||||||
val id = decoder.decodeString()
|
val id = decoder.decodeString()
|
||||||
return id.toLongOrNull() ?.let {
|
return id.toLongOrNull() ?.let {
|
||||||
@ -51,7 +51,7 @@ internal class ChatIdentifierSerializer: KSerializer<ChatIdentifier> {
|
|||||||
|
|
||||||
override fun serialize(encoder: Encoder, obj: ChatIdentifier) {
|
override fun serialize(encoder: Encoder, obj: ChatIdentifier) {
|
||||||
when (obj) {
|
when (obj) {
|
||||||
is ChatId -> encoder.encodeString(obj.chatId.toString())
|
is ChatId -> encoder.encodeLong(obj.chatId)
|
||||||
is Username -> encoder.encodeString(obj.username)
|
is Username -> encoder.encodeString(obj.username)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,10 +27,9 @@ typealias Markdown = MarkdownParseMode
|
|||||||
typealias HTML = HTMLParseMode
|
typealias HTML = HTMLParseMode
|
||||||
|
|
||||||
@Serializer(ParseMode::class)
|
@Serializer(ParseMode::class)
|
||||||
internal class ParseModeSerializerObject: KSerializer<ParseMode> {
|
internal object ParseModeSerializerObject : KSerializer<ParseMode> {
|
||||||
override fun deserialize(decoder: Decoder): ParseMode {
|
override fun deserialize(decoder: Decoder): ParseMode {
|
||||||
val mode = decoder.decodeString()
|
return when (decoder.decodeString()) {
|
||||||
return when (mode) {
|
|
||||||
MarkdownParseMode.parseModeName -> MarkdownParseMode
|
MarkdownParseMode.parseModeName -> MarkdownParseMode
|
||||||
HTMLParseMode.parseModeName -> HTMLParseMode
|
HTMLParseMode.parseModeName -> HTMLParseMode
|
||||||
else -> throw IllegalArgumentException("Unknown parse mode")
|
else -> throw IllegalArgumentException("Unknown parse mode")
|
||||||
|
@ -5,7 +5,10 @@ import org.joda.time.DateTime
|
|||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
@Serializable(TelegramDateSerializer::class)
|
@Serializable(TelegramDateSerializer::class)
|
||||||
class TelegramDate(
|
data class TelegramDate(
|
||||||
|
/**
|
||||||
|
* Contains UNIX time (seconds)
|
||||||
|
*/
|
||||||
private val date: Long
|
private val date: Long
|
||||||
) {
|
) {
|
||||||
constructor(dateTime: DateTime) : this(
|
constructor(dateTime: DateTime) : this(
|
||||||
@ -21,7 +24,7 @@ class TelegramDate(
|
|||||||
fun DateTime.toTelegramDate(): TelegramDate = TelegramDate(this)
|
fun DateTime.toTelegramDate(): TelegramDate = TelegramDate(this)
|
||||||
|
|
||||||
@Serializer(TelegramDate::class)
|
@Serializer(TelegramDate::class)
|
||||||
internal class TelegramDateSerializer: KSerializer<TelegramDate> {
|
internal object TelegramDateSerializer : KSerializer<TelegramDate> {
|
||||||
override fun serialize(encoder: Encoder, obj: TelegramDate) {
|
override fun serialize(encoder: Encoder, obj: TelegramDate) {
|
||||||
encoder.encodeLong(
|
encoder.encodeLong(
|
||||||
TimeUnit.MILLISECONDS.toSeconds(obj.asDate.millis)
|
TimeUnit.MILLISECONDS.toSeconds(obj.asDate.millis)
|
||||||
|
@ -2,31 +2,29 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.actions
|
|||||||
|
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
private val actions = listOf(
|
|
||||||
TypingAction,
|
|
||||||
UploadPhotoAction,
|
|
||||||
RecordVideoAction,
|
|
||||||
UploadVideoAction,
|
|
||||||
RecordAudioAction,
|
|
||||||
UploadAudioAction,
|
|
||||||
UploadDocumentAction,
|
|
||||||
FindLocationAction
|
|
||||||
)
|
|
||||||
|
|
||||||
@Serializable(BotActionSerializer::class)
|
@Serializable(BotActionSerializer::class)
|
||||||
sealed class BotAction {
|
sealed class BotAction {
|
||||||
abstract val actionName: String
|
abstract val actionName: String
|
||||||
}
|
}
|
||||||
|
|
||||||
@Serializer(BotAction::class)
|
@Serializer(BotAction::class)
|
||||||
class BotActionSerializer: KSerializer<BotAction> {
|
internal object BotActionSerializer: KSerializer<BotAction> {
|
||||||
override fun serialize(encoder: Encoder, obj: BotAction) {
|
override fun serialize(encoder: Encoder, obj: BotAction) {
|
||||||
encoder.encodeString(obj.actionName)
|
encoder.encodeString(obj.actionName)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun deserialize(decoder: Decoder): BotAction {
|
override fun deserialize(decoder: Decoder): BotAction {
|
||||||
val actionName = decoder.decodeString()
|
return when (val actionName = decoder.decodeString()) {
|
||||||
return actions.firstOrNull { it.actionName == actionName } ?: throw IllegalStateException("Unknown action type: $actionName")
|
TypingAction.actionName -> TypingAction
|
||||||
|
UploadPhotoAction.actionName -> UploadPhotoAction
|
||||||
|
RecordVideoAction.actionName -> RecordVideoAction
|
||||||
|
UploadVideoAction.actionName -> UploadVideoAction
|
||||||
|
RecordAudioAction.actionName -> RecordAudioAction
|
||||||
|
UploadAudioAction.actionName -> UploadAudioAction
|
||||||
|
UploadDocumentAction.actionName -> UploadDocumentAction
|
||||||
|
FindLocationAction.actionName -> FindLocationAction
|
||||||
|
else -> throw IllegalStateException("Unknown action type: $actionName")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,60 @@
|
|||||||
|
package com.github.insanusmokrassar.TelegramBotAPI.types
|
||||||
|
|
||||||
|
import com.github.insanusmokrassar.TelegramBotAPI.types.actions.*
|
||||||
|
import kotlinx.serialization.ImplicitReflectionSerializer
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
@ImplicitReflectionSerializer
|
||||||
|
class BotActionTests {
|
||||||
|
@Serializable
|
||||||
|
data class Example(
|
||||||
|
val botAction: BotAction
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun checkBotAction(example: Example, sourceAction: BotAction) {
|
||||||
|
assertEquals(
|
||||||
|
sourceAction.actionName,
|
||||||
|
when (example.botAction) {
|
||||||
|
TypingAction -> example.botAction.actionName
|
||||||
|
UploadPhotoAction -> example.botAction.actionName
|
||||||
|
RecordVideoAction -> example.botAction.actionName
|
||||||
|
UploadVideoAction -> example.botAction.actionName
|
||||||
|
RecordAudioAction -> example.botAction.actionName
|
||||||
|
UploadAudioAction -> example.botAction.actionName
|
||||||
|
UploadDocumentAction -> example.botAction.actionName
|
||||||
|
FindLocationAction -> example.botAction.actionName
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkBotActionSerializeDeserialize(example: Example) {
|
||||||
|
val stringified = Json.plain.stringify(Example.serializer(), example)
|
||||||
|
assertEquals("{\"botAction\":\"${example.botAction.actionName}\"}", stringified)
|
||||||
|
|
||||||
|
val deserialized = Json.plain.parse(Example.serializer(), stringified)
|
||||||
|
|
||||||
|
assertEquals(example, deserialized)
|
||||||
|
|
||||||
|
checkBotAction(deserialized, example.botAction)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `BotAction correctly serialized and deserialized`() {
|
||||||
|
fun BotAction.example() = Example(this)
|
||||||
|
listOf(
|
||||||
|
TypingAction.example(),
|
||||||
|
UploadPhotoAction.example(),
|
||||||
|
RecordVideoAction.example(),
|
||||||
|
UploadVideoAction.example(),
|
||||||
|
RecordAudioAction.example(),
|
||||||
|
UploadAudioAction.example(),
|
||||||
|
UploadDocumentAction.example(),
|
||||||
|
FindLocationAction.example()
|
||||||
|
).forEach {
|
||||||
|
checkBotActionSerializeDeserialize(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,79 @@
|
|||||||
|
package com.github.insanusmokrassar.TelegramBotAPI.types
|
||||||
|
|
||||||
|
import kotlinx.serialization.ImplicitReflectionSerializer
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import kotlin.test.*
|
||||||
|
|
||||||
|
@ImplicitReflectionSerializer
|
||||||
|
private const val chatIdentifierChatId: Identifier = 123L
|
||||||
|
@ImplicitReflectionSerializer
|
||||||
|
private const val chatIdentifierLink = "tg://user?id=$chatIdentifierChatId"
|
||||||
|
@ImplicitReflectionSerializer
|
||||||
|
private const val testUsername = "@Example"
|
||||||
|
|
||||||
|
@ImplicitReflectionSerializer
|
||||||
|
class ChatIdentifierTests {
|
||||||
|
@Test
|
||||||
|
fun `Cast from Int to ChatId is working correctly`() {
|
||||||
|
val chatId = chatIdentifierChatId.toInt().toChatId()
|
||||||
|
assertEquals(chatIdentifierChatId, chatId.chatId)
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
fun `Cast from Byte to ChatId is working correctly`() {
|
||||||
|
val chatId = chatIdentifierChatId.toByte().toChatId()
|
||||||
|
assertEquals(chatIdentifierChatId, chatId.chatId)
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
fun `Cast from Identifier to ChatId is working correctly`() {
|
||||||
|
val chatId = chatIdentifierChatId.toChatId()
|
||||||
|
assertEquals(chatIdentifierChatId, chatId.chatId)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `Creating link from ChatId is correct`() {
|
||||||
|
val chatId = chatIdentifierChatId.toChatId()
|
||||||
|
assertEquals(chatIdentifierLink, chatId.link)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `Cast from String to Username is working correctly`() {
|
||||||
|
assertEquals(testUsername, testUsername.toUsername().username)
|
||||||
|
|
||||||
|
assertFails("Username creating must fail when trying to create from string which is not starting from @ symbol") {
|
||||||
|
testUsername.replace("@", "").toUsername().username
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `Deserializing from String must work correctly`() {
|
||||||
|
@Serializable
|
||||||
|
data class Example(
|
||||||
|
val identifier: ChatIdentifier
|
||||||
|
)
|
||||||
|
|
||||||
|
Example(chatIdentifierChatId.toChatId()).let { withChatId ->
|
||||||
|
val stringified = Json.plain.stringify(Example.serializer(), withChatId)
|
||||||
|
assertEquals(stringified, "{\"identifier\":$chatIdentifierChatId}")
|
||||||
|
val deserialized = Json.plain.parse(Example.serializer(), stringified)
|
||||||
|
assertEquals(withChatId, deserialized)
|
||||||
|
}
|
||||||
|
|
||||||
|
Example(testUsername.toUsername()).let { withUsername ->
|
||||||
|
val stringified = Json.plain.stringify(Example.serializer(), withUsername)
|
||||||
|
assertEquals(stringified, "{\"identifier\":\"$testUsername\"}")
|
||||||
|
val deserialized = Json.plain.parse(Example.serializer(), stringified)
|
||||||
|
assertEquals(withUsername, deserialized)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace @ by empty string, because from time to time we can retrieve from Telegram system
|
||||||
|
// username without starting @ symbol
|
||||||
|
Example(testUsername.toUsername()).let { withUsername ->
|
||||||
|
val stringified = Json.plain.stringify(Example.serializer(), withUsername).replace("@", "")
|
||||||
|
assertEquals("{\"identifier\":\"${testUsername.replace("@", "")}\"}", stringified)
|
||||||
|
val deserialized = Json.plain.parse(Example.serializer(), stringified)
|
||||||
|
assertEquals(withUsername, deserialized)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package com.github.insanusmokrassar.TelegramBotAPI.types
|
||||||
|
|
||||||
|
import com.github.insanusmokrassar.TelegramBotAPI.types.ParseMode.*
|
||||||
|
import kotlinx.serialization.ImplicitReflectionSerializer
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
@ImplicitReflectionSerializer
|
||||||
|
class ParseModeTests {
|
||||||
|
@Serializable
|
||||||
|
data class Example(
|
||||||
|
val mode: ParseMode
|
||||||
|
)
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `Markdown parse mode correctly serializing and deserializing`() {
|
||||||
|
val example = Example(Markdown)
|
||||||
|
|
||||||
|
val stringified = Json.plain.stringify(Example.serializer(), example)
|
||||||
|
assertEquals("{\"mode\":\"Markdown\"}", stringified)
|
||||||
|
|
||||||
|
val deserialized = Json.plain.parse(Example.serializer(), stringified)
|
||||||
|
assertEquals(example, deserialized)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `HTML parse mode correctly serializing and deserializing`() {
|
||||||
|
val example = Example(HTML)
|
||||||
|
|
||||||
|
val stringified = Json.plain.stringify(Example.serializer(), example)
|
||||||
|
assertEquals("{\"mode\":\"HTML\"}", stringified)
|
||||||
|
|
||||||
|
val deserialized = Json.plain.parse(Example.serializer(), stringified)
|
||||||
|
assertEquals(example, deserialized)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package com.github.insanusmokrassar.TelegramBotAPI.types
|
||||||
|
|
||||||
|
import kotlinx.serialization.ImplicitReflectionSerializer
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import org.joda.time.DateTime
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
private val dateTimeMillis = System.currentTimeMillis()
|
||||||
|
private val dateTimeUnix = TimeUnit.MILLISECONDS.toSeconds(dateTimeMillis)
|
||||||
|
private val dateTime = DateTime(TimeUnit.SECONDS.toMillis(dateTimeUnix))
|
||||||
|
|
||||||
|
@ImplicitReflectionSerializer
|
||||||
|
class TelegramDateTests {
|
||||||
|
@Serializable
|
||||||
|
data class Example(
|
||||||
|
val dateTime: TelegramDate
|
||||||
|
)
|
||||||
|
@Test
|
||||||
|
fun `Serializtion of TelegramDate is working correctly`() {
|
||||||
|
val example = Example(TelegramDate(dateTimeUnix))
|
||||||
|
|
||||||
|
val stringified = Json.plain.stringify(Example.serializer(), example)
|
||||||
|
assertEquals("{\"dateTime\":$dateTimeUnix}", stringified)
|
||||||
|
|
||||||
|
val deserialized = Json.plain.parse(Example.serializer(), stringified)
|
||||||
|
assertEquals(example, deserialized)
|
||||||
|
|
||||||
|
assertEquals(dateTime, deserialized.dateTime.asDate)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user