Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • api-redesign
  • main
  • 0.10.0
  • 0.10.1
  • 0.10.2
  • 0.7.0
  • 0.8.0
  • 0.8.1
  • 0.9.0
  • 0.9.1
  • 0.9.2
11 results

Target

Select target project
  • justJanne/libquassel
1 result
Select Git revision
  • api-redesign
  • main
  • 0.10.0
  • 0.10.1
  • 0.10.2
  • 0.7.0
  • 0.8.0
  • 0.8.1
  • 0.9.0
  • 0.9.1
  • 0.9.2
11 results
Show changes
Showing
with 988 additions and 976 deletions
/* /*
* libquassel * libquassel
* Copyright (c) 2021 Janne Mareike Koschinski * Copyright (c) 2024 Janne Mareike Koschinski
* *
* This Source Code Form is subject to the terms of the Mozilla Public License, * This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can * v. 2.0. If a copy of the MPL was not distributed with this file, You can
......
/* /*
* libquassel * libquassel
* Copyright (c) 2021 Janne Mareike Koschinski * Copyright (c) 2024 Janne Mareike Koschinski
* *
* This Source Code Form is subject to the terms of the Mozilla Public License, * This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can * v. 2.0. If a copy of the MPL was not distributed with this file, You can
......
/*
* libquassel
* Copyright (c) 2021 Janne Mareike Koschinski
*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at https://mozilla.org/MPL/2.0/.
*/
package de.justjanne.libquassel.protocol.util.collections
fun <T> List<T>.remove(value: T): List<T> = this.filter { it != value }
fun <T> List<T>.removeAt(index: Int): List<T> {
if (index < 0 || index >= size) return this
val before = subList(0, index)
val after = subList(index + 1, size)
if (before.isEmpty()) return after
if (after.isEmpty()) return before
return before + after
}
...@@ -22,7 +22,7 @@ sealed class Expansion { ...@@ -22,7 +22,7 @@ sealed class Expansion {
/** /**
* Text to insert * Text to insert
*/ */
override val source: String override val source: String,
) : Expansion() ) : Expansion()
/** /**
...@@ -41,7 +41,7 @@ sealed class Expansion { ...@@ -41,7 +41,7 @@ sealed class Expansion {
/** /**
* Original value that was parsed and replaced * Original value that was parsed and replaced
*/ */
override val source: String override val source: String,
) : Expansion() ) : Expansion()
/** /**
...@@ -66,7 +66,7 @@ sealed class Expansion { ...@@ -66,7 +66,7 @@ sealed class Expansion {
/** /**
* Original value that was parsed and replaced * Original value that was parsed and replaced
*/ */
override val source: String override val source: String,
) : Expansion() ) : Expansion()
/** /**
...@@ -80,7 +80,7 @@ sealed class Expansion { ...@@ -80,7 +80,7 @@ sealed class Expansion {
/** /**
* Original value that was parsed and replaced * Original value that was parsed and replaced
*/ */
override val source: String override val source: String,
) : Expansion() ) : Expansion()
/** /**
...@@ -115,7 +115,7 @@ sealed class Expansion { ...@@ -115,7 +115,7 @@ sealed class Expansion {
* given context, or "*" if the user is not found or the hostname could not * given context, or "*" if the user is not found or the hostname could not
* be determined. * be determined.
*/ */
ACCOUNT ACCOUNT,
} }
/** /**
...@@ -136,14 +136,13 @@ sealed class Expansion { ...@@ -136,14 +136,13 @@ sealed class Expansion {
/** /**
* Name of the network this alias is invoked on * Name of the network this alias is invoked on
*/ */
NETWORK NETWORK,
} }
companion object { companion object {
/** /**
* Parse a list of expansions from a given expansion string * Parse a list of expansions from a given expansion string
*/ */
fun parse(text: String): List<Expansion> = fun parse(text: String): List<Expansion> = ExpansionParsingContext(text).parse()
ExpansionParsingContext(text).parse()
} }
} }
...@@ -13,9 +13,10 @@ import de.justjanne.libquassel.protocol.util.ParsingContext ...@@ -13,9 +13,10 @@ import de.justjanne.libquassel.protocol.util.ParsingContext
import java.util.function.Supplier import java.util.function.Supplier
internal class ExpansionParsingContext( internal class ExpansionParsingContext(
text: String text: String,
) : ParsingContext<Expansion>(text) { ) : ParsingContext<Expansion>(text) {
override val matchers: List<Supplier<Expansion?>> = listOf( override val matchers: List<Supplier<Expansion?>> =
listOf(
match("\$channelname", "\$channel") { source -> match("\$channelname", "\$channel") { source ->
Expansion.Constant(Expansion.ConstantField.CHANNEL, source) Expansion.Constant(Expansion.ConstantField.CHANNEL, source)
}, },
...@@ -50,9 +51,13 @@ internal class ExpansionParsingContext( ...@@ -50,9 +51,13 @@ internal class ExpansionParsingContext(
Expansion.Parameter(value.toInt(), null, source) Expansion.Parameter(value.toInt(), null, source)
}, },
Supplier { Supplier {
val end = text.indexOf('$', startIndex = position).let { val end =
if (it >= 0) it text.indexOf('$', startIndex = position).let {
else text.length if (it >= 0) {
it
} else {
text.length
}
} }
if (position < end) { if (position < end) {
val start = position val start = position
...@@ -61,6 +66,6 @@ internal class ExpansionParsingContext( ...@@ -61,6 +66,6 @@ internal class ExpansionParsingContext(
return@Supplier Expansion.Text(value) return@Supplier Expansion.Text(value)
} }
return@Supplier null return@Supplier null
} },
) )
} }
...@@ -19,21 +19,22 @@ package de.justjanne.libquassel.protocol.util.expression ...@@ -19,21 +19,22 @@ package de.justjanne.libquassel.protocol.util.expression
data class ExpressionMatch( data class ExpressionMatch(
val expression: String, val expression: String,
val mode: MatchMode, val mode: MatchMode,
val caseSensitive: Boolean val caseSensitive: Boolean,
) { ) {
enum class MatchMode { enum class MatchMode {
MatchPhrase, MatchPhrase,
MatchMultiPhrase, MatchMultiPhrase,
MatchWildcard, MatchWildcard,
MatchMultiWildcard, MatchMultiWildcard,
MatchRegEx MatchRegEx,
} }
internal val positiveRegex: Regex? internal val positiveRegex: Regex?
internal val negativeRegex: Regex? internal val negativeRegex: Regex?
init { init {
val (positive, negative) = when (mode) { val (positive, negative) =
when (mode) {
MatchMode.MatchPhrase -> parsePhrase(expression) MatchMode.MatchPhrase -> parsePhrase(expression)
MatchMode.MatchMultiPhrase -> parseMultiPhrase(expression) MatchMode.MatchMultiPhrase -> parseMultiPhrase(expression)
MatchMode.MatchWildcard -> parseWildcard(expression) MatchMode.MatchWildcard -> parseWildcard(expression)
...@@ -47,7 +48,10 @@ data class ExpressionMatch( ...@@ -47,7 +48,10 @@ data class ExpressionMatch(
fun isEmpty() = positiveRegex == null && negativeRegex == null fun isEmpty() = positiveRegex == null && negativeRegex == null
fun match(content: String, matchEmpty: Boolean = false): Boolean { fun match(
content: String,
matchEmpty: Boolean = false,
): Boolean {
if (isEmpty()) { if (isEmpty()) {
return matchEmpty return matchEmpty
} }
...@@ -64,7 +68,11 @@ data class ExpressionMatch( ...@@ -64,7 +68,11 @@ data class ExpressionMatch(
} }
companion object { companion object {
private fun regex(expression: String, caseSensitive: Boolean): Regex? = try { private fun regex(
expression: String,
caseSensitive: Boolean,
): Regex? =
try {
when { when {
expression.isBlank() -> null expression.isBlank() -> null
caseSensitive -> expression.toRegex() caseSensitive -> expression.toRegex()
...@@ -154,7 +162,8 @@ data class ExpressionMatch( ...@@ -154,7 +162,8 @@ data class ExpressionMatch(
} }
private fun parseMultiPhrase(expression: String): Pair<String, String> { private fun parseMultiPhrase(expression: String): Pair<String, String> {
val components = expression.split('\n') val components =
expression.split('\n')
.filter(String::isNotEmpty) .filter(String::isNotEmpty)
.map(::escape) .map(::escape)
...@@ -170,14 +179,16 @@ data class ExpressionMatch( ...@@ -170,14 +179,16 @@ data class ExpressionMatch(
var escaped = false var escaped = false
for (char in expression) { for (char in expression) {
when (char) { when (char) {
'\\' -> if (escaped) { '\\' ->
if (escaped) {
result.append('\\') result.append('\\')
result.append(char) result.append(char)
escaped = false escaped = false
} else { } else {
escaped = true escaped = true
} }
'?' -> if (escaped) { '?' ->
if (escaped) {
result.append('\\') result.append('\\')
result.append(char) result.append(char)
escaped = false escaped = false
...@@ -185,7 +196,8 @@ data class ExpressionMatch( ...@@ -185,7 +196,8 @@ data class ExpressionMatch(
result.append('.') result.append('.')
escaped = false escaped = false
} }
'*' -> if (escaped) { '*' ->
if (escaped) {
result.append('\\') result.append('\\')
result.append(char) result.append(char)
escaped = false escaped = false
...@@ -211,14 +223,18 @@ data class ExpressionMatch( ...@@ -211,14 +223,18 @@ data class ExpressionMatch(
val (inverted, phrase) = parseInverted(expression) val (inverted, phrase) = parseInverted(expression)
val result = "^${parseWildcardInternal(phrase)}$" val result = "^${parseWildcardInternal(phrase)}$"
return if (inverted) Pair("", result) return if (inverted) {
else Pair(result, "") Pair("", result)
} else {
Pair(result, "")
}
} }
private fun parseMultiWildcard(expression: String): Pair<String, String> { private fun parseMultiWildcard(expression: String): Pair<String, String> {
val components = splitWithEscaping(expression) val components = splitWithEscaping(expression)
val positive = components val positive =
components
.asSequence() .asSequence()
.map(::parseInverted) .map(::parseInverted)
.filterNot(Pair<Boolean, String>::first) .filterNot(Pair<Boolean, String>::first)
...@@ -228,7 +244,8 @@ data class ExpressionMatch( ...@@ -228,7 +244,8 @@ data class ExpressionMatch(
.filter(String::isNotEmpty) .filter(String::isNotEmpty)
.toList() .toList()
val negative = components val negative =
components
.asSequence() .asSequence()
.map(::parseInverted) .map(::parseInverted)
.filter(Pair<Boolean, String>::first) .filter(Pair<Boolean, String>::first)
...@@ -239,10 +256,16 @@ data class ExpressionMatch( ...@@ -239,10 +256,16 @@ data class ExpressionMatch(
.toList() .toList()
return Pair( return Pair(
if (positive.isEmpty()) "" if (positive.isEmpty()) {
else positive.joinToString("|", prefix = "^(?:", postfix = ")$"), ""
if (negative.isEmpty()) "" } else {
else negative.joinToString("|", prefix = "^(?:", postfix = ")$") positive.joinToString("|", prefix = "^(?:", postfix = ")$")
},
if (negative.isEmpty()) {
""
} else {
negative.joinToString("|", prefix = "^(?:", postfix = ")$")
},
) )
} }
......
...@@ -9,5 +9,4 @@ ...@@ -9,5 +9,4 @@
package de.justjanne.libquassel.protocol.util.reflect package de.justjanne.libquassel.protocol.util.reflect
internal infix fun <T> Any?.instanceof(other: Class<T>?): Boolean = internal infix fun <T> Any?.instanceof(other: Class<T>?): Boolean = other?.isInstance(this) != false
other?.isInstance(this) != false
/*
* libquassel
* Copyright (c) 2021 Janne Mareike Koschinski
*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at https://mozilla.org/MPL/2.0/.
*/
package de.justjanne.libquassel.protocol.util.reflect
inline fun <reified T> objectByName(name: String): T {
val clazz = try {
Class.forName(name)
} catch (t: Throwable) {
throw IllegalArgumentException("Could not load class $name", t)
}
val element = clazz.getDeclaredField("INSTANCE").get(null)
require(element != null) {
"No object found for $name"
}
require(element is T) {
"Object of wrong type found for $name:" +
"expected ${T::class.java.canonicalName}, " +
"got ${element::class.java.canonicalName}"
}
return element
}
...@@ -35,7 +35,6 @@ data class TlsInfo( ...@@ -35,7 +35,6 @@ data class TlsInfo(
*/ */
val certificateChain: List<X509Certificate>, val certificateChain: List<X509Certificate>,
) { ) {
override fun toString(): String { override fun toString(): String {
return "TlsInfo(protocol='$protocol', cipherSuite='$cipherSuite', keyExchangeMechanism=$keyExchangeMechanism)" return "TlsInfo(protocol='$protocol', cipherSuite='$cipherSuite', keyExchangeMechanism=$keyExchangeMechanism)"
} }
...@@ -45,11 +44,18 @@ data class TlsInfo( ...@@ -45,11 +44,18 @@ data class TlsInfo(
private val cipherSuiteRegex12 = "TLS_(.*)_WITH_(.*)".toRegex() private val cipherSuiteRegex12 = "TLS_(.*)_WITH_(.*)".toRegex()
private fun cipherSuiteRegex(protocol: String): Regex = private fun cipherSuiteRegex(protocol: String): Regex =
if (protocol == "TLSv1.3") cipherSuiteRegex13 if (protocol == "TLSv1.3") {
else cipherSuiteRegex12 cipherSuiteRegex13
} else {
cipherSuiteRegex12
}
private fun parseCipherSuite(protocol: String, cipherSuite: String): Pair<String, String?>? { private fun parseCipherSuite(
val match = cipherSuiteRegex(protocol) protocol: String,
cipherSuite: String,
): Pair<String, String?>? {
val match =
cipherSuiteRegex(protocol)
.matchEntire(cipherSuite) .matchEntire(cipherSuite)
?: return null ?: return null
...@@ -64,7 +70,8 @@ data class TlsInfo( ...@@ -64,7 +70,8 @@ data class TlsInfo(
* Obtain the TLS metadata of an existing [SSLSession] * Obtain the TLS metadata of an existing [SSLSession]
*/ */
fun ofSession(session: SSLSession): TlsInfo? { fun ofSession(session: SSLSession): TlsInfo? {
val (cipherSuite, keyExchangeMechanism) = parseCipherSuite( val (cipherSuite, keyExchangeMechanism) =
parseCipherSuite(
session.protocol, session.protocol,
session.cipherSuite, session.cipherSuite,
) ?: return null ) ?: return null
...@@ -73,7 +80,7 @@ data class TlsInfo( ...@@ -73,7 +80,7 @@ data class TlsInfo(
session.protocol, session.protocol,
cipherSuite, cipherSuite,
keyExchangeMechanism, keyExchangeMechanism,
session.peerCertificates.map(Certificate::toX509) session.peerCertificates.map(Certificate::toX509),
) )
} }
} }
......
...@@ -35,17 +35,20 @@ sealed class QVariant<T> { ...@@ -35,17 +35,20 @@ sealed class QVariant<T> {
* Serializer for the contained data * Serializer for the contained data
*/ */
abstract val serializer: PrimitiveSerializer<T> abstract val serializer: PrimitiveSerializer<T>
@PublishedApi @PublishedApi
internal abstract fun <U> withType(type: Class<U>): QVariant<U>? internal abstract fun <U> withType(type: Class<U>): QVariant<U>?
/** /**
* QVariant of a predefined qt type * QVariant of a predefined qt type
*/ */
data class Typed<T> @PublishedApi internal constructor( data class Typed<T>
@PublishedApi
internal constructor(
override val data: T, override val data: T,
@PublishedApi @PublishedApi
internal val type: QtType, internal val type: QtType,
override val serializer: PrimitiveSerializer<T> override val serializer: PrimitiveSerializer<T>,
) : QVariant<T>() { ) : QVariant<T>() {
override fun <U> withType(type: Class<U>): QVariant<U>? { override fun <U> withType(type: Class<U>): QVariant<U>? {
return if ( return if (
...@@ -58,7 +61,9 @@ sealed class QVariant<T> { ...@@ -58,7 +61,9 @@ sealed class QVariant<T> {
null null
} }
} }
override fun toString() = data.let {
override fun toString() =
data.let {
when (it) { when (it) {
is ByteBuffer -> is ByteBuffer ->
"QVariant(${type.name}, ${it.contentToString()})" "QVariant(${type.name}, ${it.contentToString()})"
...@@ -73,11 +78,13 @@ sealed class QVariant<T> { ...@@ -73,11 +78,13 @@ sealed class QVariant<T> {
* *
* Serialized as [QtType.UserType] with the custom type name serialized as ASCII string * Serialized as [QtType.UserType] with the custom type name serialized as ASCII string
*/ */
data class Custom<T> @PublishedApi internal constructor( data class Custom<T>
@PublishedApi
internal constructor(
override val data: T, override val data: T,
@PublishedApi @PublishedApi
internal val type: QuasselType, internal val type: QuasselType,
override val serializer: PrimitiveSerializer<T> override val serializer: PrimitiveSerializer<T>,
) : QVariant<T>() { ) : QVariant<T>() {
override fun <U> withType(type: Class<U>): QVariant<U>? { override fun <U> withType(type: Class<U>): QVariant<U>? {
return if ( return if (
...@@ -91,7 +98,8 @@ sealed class QVariant<T> { ...@@ -91,7 +98,8 @@ sealed class QVariant<T> {
} }
} }
override fun toString() = data.let { override fun toString() =
data.let {
when (it) { when (it) {
is ByteBuffer -> is ByteBuffer ->
"QVariant(${type.name}, ${it.contentToString()})" "QVariant(${type.name}, ${it.contentToString()})"
...@@ -103,33 +111,37 @@ sealed class QVariant<T> { ...@@ -103,33 +111,37 @@ sealed class QVariant<T> {
@PublishedApi @PublishedApi
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
internal inline fun <reified U> withType(): QVariant<U>? = internal inline fun <reified U> withType(): QVariant<U>? = withType(U::class.java)
withType(U::class.java)
fun type(): Class<*>? = data?.let { it::class.java } fun type(): Class<*>? = data?.let { it::class.java }
internal fun serialize(buffer: ChainedByteBuffer, featureSet: FeatureSet) = internal fun serialize(
serializer.serialize(buffer, data, featureSet) buffer: ChainedByteBuffer,
featureSet: FeatureSet,
) = serializer.serialize(buffer, data, featureSet)
} }
/** /**
* Construct a QVariant from data and type * Construct a QVariant from data and type
*/ */
inline fun <reified T> qVariant(data: T, type: QtType): QVariant<T> = inline fun <reified T> qVariant(
QVariant.Typed(data, type, type.serializer()) data: T,
type: QtType,
): QVariant<T> = QVariant.Typed(data, type, type.serializer())
/** /**
* Construct a QVariant from data and type * Construct a QVariant from data and type
*/ */
inline fun <reified T> qVariant(data: T, type: QuasselType): QVariant<T> = inline fun <reified T> qVariant(
QVariant.Custom(data, type, type.serializer()) data: T,
type: QuasselType,
): QVariant<T> = QVariant.Custom(data, type, type.serializer())
/** /**
* Extract the content of a QVariant in a type-safe manner * Extract the content of a QVariant in a type-safe manner
* @return value of the QVariant or null * @return value of the QVariant or null
*/ */
inline fun <reified T> QVariant_?.into(): T? = inline fun <reified T> QVariant_?.into(): T? = this?.withType<T>()?.data
this?.withType<T>()?.data
/** /**
* Extract the content of a QVariant in a type-safe manner * Extract the content of a QVariant in a type-safe manner
...@@ -139,7 +151,7 @@ inline fun <reified T> QVariant_?.into(): T? = ...@@ -139,7 +151,7 @@ inline fun <reified T> QVariant_?.into(): T? =
inline fun <reified T> QVariant_?.intoOrThrow(): T = inline fun <reified T> QVariant_?.intoOrThrow(): T =
this?.withType<T>()?.data ?: throw WrongVariantTypeException( this?.withType<T>()?.data ?: throw WrongVariantTypeException(
T::class.java.canonicalName, T::class.java.canonicalName,
this?.type()?.canonicalName ?: "null" this?.type()?.canonicalName ?: "null",
) )
/** /**
...@@ -147,5 +159,4 @@ inline fun <reified T> QVariant_?.intoOrThrow(): T = ...@@ -147,5 +159,4 @@ inline fun <reified T> QVariant_?.intoOrThrow(): T =
* @param defValue default value if the type does not match or no value is found * @param defValue default value if the type does not match or no value is found
* @return value of the QVariant or defValue * @return value of the QVariant or defValue
*/ */
inline fun <reified T> QVariant_?.into(defValue: T): T = inline fun <reified T> QVariant_?.into(defValue: T): T = this?.withType<T>()?.data ?: defValue
this?.withType<T>()?.data ?: defValue
...@@ -11,5 +11,5 @@ package de.justjanne.libquassel.protocol.variant ...@@ -11,5 +11,5 @@ package de.justjanne.libquassel.protocol.variant
data class WrongVariantTypeException( data class WrongVariantTypeException(
val expected: String, val expected: String,
val actual: String? val actual: String?,
) : Exception("Could not coerce QVariant of type $actual into $expected") ) : Exception("Could not coerce QVariant of type $actual into $expected")
/*
* libquassel
* Copyright (c) 2021 Janne Mareike Koschinski
*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at https://mozilla.org/MPL/2.0/.
*/
package de.justjanne.libquassel.protocol.variant
@Suppress("NOTHING_TO_INLINE")
internal inline fun QVariant_?.indexed(index: Int?) = this?.let {
index?.let { i ->
it.into<QVariantList>()?.get(i)
} ?: it
}
...@@ -16,35 +16,47 @@ import org.junit.jupiter.api.Test ...@@ -16,35 +16,47 @@ import org.junit.jupiter.api.Test
class ClientHeaderSerializerTest { class ClientHeaderSerializerTest {
@Test @Test
fun testQuasseldroid() = serializerTest( fun testQuasseldroid() =
serializerTest(
ClientHeaderSerializer, ClientHeaderSerializer,
ClientHeader( ClientHeader(
features = ProtocolFeature.of( features =
ProtocolFeature.of(
ProtocolFeature.TLS, ProtocolFeature.TLS,
ProtocolFeature.Compression, ProtocolFeature.Compression,
), ),
versions = listOf( versions =
listOf(
ProtocolMeta( ProtocolMeta(
version = ProtocolVersion.Datastream, version = ProtocolVersion.Datastream,
data = 0x0000u, data = 0x0000u,
) ),
) ),
), ),
byteBufferOf( byteBufferOf(
0x42u, 0xb3u, 0x3fu, 0x03u, 0x42u,
0x80u, 0x00u, 0x00u, 0x02u 0xb3u,
) 0x3fu,
0x03u,
0x80u,
0x00u,
0x00u,
0x02u,
),
) )
@Test @Test
fun testQuasselClient() = serializerTest( fun testQuasselClient() =
serializerTest(
ClientHeaderSerializer, ClientHeaderSerializer,
ClientHeader( ClientHeader(
features = ProtocolFeature.of( features =
ProtocolFeature.of(
ProtocolFeature.TLS, ProtocolFeature.TLS,
ProtocolFeature.Compression, ProtocolFeature.Compression,
), ),
versions = listOf( versions =
listOf(
ProtocolMeta( ProtocolMeta(
version = ProtocolVersion.Legacy, version = ProtocolVersion.Legacy,
data = 0x0000u, data = 0x0000u,
...@@ -52,22 +64,24 @@ class ClientHeaderSerializerTest { ...@@ -52,22 +64,24 @@ class ClientHeaderSerializerTest {
ProtocolMeta( ProtocolMeta(
version = ProtocolVersion.Datastream, version = ProtocolVersion.Datastream,
data = 0x0000u, data = 0x0000u,
) ),
) ),
), ),
byteBufferOf( byteBufferOf(
0x42u, 0xb3u, 0x3fu, 0x03u, 0x42u, 0xb3u, 0x3fu, 0x03u,
0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x01u,
0x80u, 0x00u, 0x00u, 0x02u 0x80u, 0x00u, 0x00u, 0x02u,
) ),
) )
@Test @Test
fun testDebugClient() = serializerTest( fun testDebugClient() =
serializerTest(
ClientHeaderSerializer, ClientHeaderSerializer,
ClientHeader( ClientHeader(
features = ProtocolFeature.of(), features = ProtocolFeature.of(),
versions = listOf( versions =
listOf(
ProtocolMeta( ProtocolMeta(
version = ProtocolVersion.Legacy, version = ProtocolVersion.Legacy,
data = 0x0000u, data = 0x0000u,
...@@ -75,13 +89,13 @@ class ClientHeaderSerializerTest { ...@@ -75,13 +89,13 @@ class ClientHeaderSerializerTest {
ProtocolMeta( ProtocolMeta(
version = ProtocolVersion.Datastream, version = ProtocolVersion.Datastream,
data = 0x0000u, data = 0x0000u,
) ),
) ),
), ),
byteBufferOf( byteBufferOf(
0x42u, 0xb3u, 0x3fu, 0x00u, 0x42u, 0xb3u, 0x3fu, 0x00u,
0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x01u,
0x80u, 0x00u, 0x00u, 0x02u 0x80u, 0x00u, 0x00u, 0x02u,
) ),
) )
} }
...@@ -21,25 +21,25 @@ class FeatureSetTest { ...@@ -21,25 +21,25 @@ class FeatureSetTest {
emptyList<QuasselFeatureName>(), emptyList<QuasselFeatureName>(),
FeatureSet.build( FeatureSet.build(
LegacyFeature.none(), LegacyFeature.none(),
emptyList() emptyList(),
).featureList() ).featureList(),
) )
assertEquals( assertEquals(
listOf( listOf(
QuasselFeature.SynchronizedMarkerLine.feature, QuasselFeature.SynchronizedMarkerLine.feature,
QuasselFeature.ExtendedFeatures.feature, QuasselFeature.ExtendedFeatures.feature,
QuasselFeatureName("_unknownFeature") QuasselFeatureName("_unknownFeature"),
), ),
FeatureSet.build( FeatureSet.build(
LegacyFeature.of( LegacyFeature.of(
LegacyFeature.SynchronizedMarkerLine LegacyFeature.SynchronizedMarkerLine,
), ),
listOf( listOf(
QuasselFeature.ExtendedFeatures.feature, QuasselFeature.ExtendedFeatures.feature,
QuasselFeatureName("_unknownFeature") QuasselFeatureName("_unknownFeature"),
) ),
).featureList() ).featureList(),
) )
} }
...@@ -47,20 +47,20 @@ class FeatureSetTest { ...@@ -47,20 +47,20 @@ class FeatureSetTest {
fun testBuild() { fun testBuild() {
assertEquals( assertEquals(
emptyList<QuasselFeatureName>(), emptyList<QuasselFeatureName>(),
FeatureSet.build(emptySet()).featureList() FeatureSet.build(emptySet()).featureList(),
) )
assertEquals( assertEquals(
listOf( listOf(
QuasselFeature.SynchronizedMarkerLine.feature, QuasselFeature.SynchronizedMarkerLine.feature,
QuasselFeature.ExtendedFeatures.feature QuasselFeature.ExtendedFeatures.feature,
), ),
FeatureSet.build( FeatureSet.build(
setOf( setOf(
QuasselFeature.SynchronizedMarkerLine, QuasselFeature.SynchronizedMarkerLine,
QuasselFeature.ExtendedFeatures QuasselFeature.ExtendedFeatures,
) ),
).featureList() ).featureList(),
) )
} }
} }
...@@ -17,8 +17,7 @@ import org.junit.jupiter.api.Test ...@@ -17,8 +17,7 @@ import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertThrows import org.junit.jupiter.api.assertThrows
import java.nio.ByteBuffer import java.nio.ByteBuffer
class ChainedByteBufferTest { class ChainedByteBufferModelTest {
@Test @Test
fun testPutArray() { fun testPutArray() {
validateArray(byteArrayOf()) validateArray(byteArrayOf())
...@@ -35,7 +34,7 @@ class ChainedByteBufferTest { ...@@ -35,7 +34,7 @@ class ChainedByteBufferTest {
0x00, 0x01, -0x01, 0x00, 0x00, 0x01, -0x01, 0x00, 0x00, 0x01, -0x01, 0x00, 0x00, 0x01, -0x01, 0x00,
0x00, 0x01, -0x01, 0x00, 0x00, 0x01, -0x01, 0x00, 0x00, 0x01, -0x01, 0x00, 0x00, 0x01, -0x01, 0x00,
0x00, 0x01, -0x01, 0x00, 0x00, 0x01, -0x01, 0x00, 0x00, 0x01, -0x01, 0x00, 0x00, 0x01, -0x01, 0x00,
) ),
) )
validateArray(ByteArray(3000, Int::toByte)) validateArray(ByteArray(3000, Int::toByte))
} }
...@@ -43,7 +42,7 @@ class ChainedByteBufferTest { ...@@ -43,7 +42,7 @@ class ChainedByteBufferTest {
@Test @Test
fun testLimit() { fun testLimit() {
assertThrows<IllegalArgumentException>( assertThrows<IllegalArgumentException>(
"Can not allocate 10 bytes, currently at 50, limit is 50" "Can not allocate 10 bytes, currently at 50, limit is 50",
) { ) {
ChainedByteBuffer(chunkSize = 10, limit = 50) ChainedByteBuffer(chunkSize = 10, limit = 50)
.put(ByteArray(70, Int::toByte)) .put(ByteArray(70, Int::toByte))
...@@ -81,7 +80,10 @@ class ChainedByteBufferTest { ...@@ -81,7 +80,10 @@ class ChainedByteBufferTest {
} }
private fun validateArray(array: ByteArray) { private fun validateArray(array: ByteArray) {
fun validateArrayInternal(array: ByteArray, direct: Boolean) { fun validateArrayInternal(
array: ByteArray,
direct: Boolean,
) {
val bufferSize = 1024 val bufferSize = 1024
val chained = ChainedByteBuffer(chunkSize = bufferSize, direct = direct, limit = 16384) val chained = ChainedByteBuffer(chunkSize = bufferSize, direct = direct, limit = 16384)
chained.put(array) chained.put(array)
......
...@@ -25,15 +25,15 @@ class StringEncoderTest { ...@@ -25,15 +25,15 @@ class StringEncoderTest {
fun testNullString() { fun testNullString() {
assertThat( assertThat(
ascii.encode(null), ascii.encode(null),
ByteBufferMatcher(ByteBuffer.allocate(0)) ByteBufferMatcher(ByteBuffer.allocate(0)),
) )
assertThat( assertThat(
utf8.encode(null), utf8.encode(null),
ByteBufferMatcher(ByteBuffer.allocate(0)) ByteBufferMatcher(ByteBuffer.allocate(0)),
) )
assertThat( assertThat(
utf16.encode(null), utf16.encode(null),
ByteBufferMatcher(ByteBuffer.allocate(0)) ByteBufferMatcher(ByteBuffer.allocate(0)),
) )
} }
...@@ -41,11 +41,11 @@ class StringEncoderTest { ...@@ -41,11 +41,11 @@ class StringEncoderTest {
fun testUnencodableString() { fun testUnencodableString() {
assertEquals( assertEquals(
0, 0,
ascii.encode("\uFFFF").remaining() ascii.encode("\uFFFF").remaining(),
) )
assertThat( assertThat(
ascii.encode("\uFFFF"), ascii.encode("\uFFFF"),
ByteBufferMatcher(byteBufferOf()) ByteBufferMatcher(byteBufferOf()),
) )
} }
...@@ -53,21 +53,21 @@ class StringEncoderTest { ...@@ -53,21 +53,21 @@ class StringEncoderTest {
fun testNullChar() { fun testNullChar() {
assertEquals( assertEquals(
1, 1,
ascii.encodeChar(null).remaining() ascii.encodeChar(null).remaining(),
) )
assertThat( assertThat(
ascii.encodeChar(null), ascii.encodeChar(null),
ByteBufferMatcher(byteBufferOf(0)) ByteBufferMatcher(byteBufferOf(0)),
) )
assertThat( assertThat(
utf8.encodeChar(null), utf8.encodeChar(null),
ByteBufferMatcher(byteBufferOf(0xEFu, 0xBFu, 0xBDu)) ByteBufferMatcher(byteBufferOf(0xEFu, 0xBFu, 0xBDu)),
) )
assertEquals( assertEquals(
2, 2,
utf16.encodeChar(null).remaining() utf16.encodeChar(null).remaining(),
) )
assertThat( assertThat(
utf16.encodeChar(null), utf16.encodeChar(null),
...@@ -79,11 +79,11 @@ class StringEncoderTest { ...@@ -79,11 +79,11 @@ class StringEncoderTest {
fun testUnencodableChar() { fun testUnencodableChar() {
assertEquals( assertEquals(
1, 1,
ascii.encodeChar('\uFFFF').remaining() ascii.encodeChar('\uFFFF').remaining(),
) )
assertThat( assertThat(
ascii.encodeChar('\uFFFF'), ascii.encodeChar('\uFFFF'),
ByteBufferMatcher(byteBufferOf(0)) ByteBufferMatcher(byteBufferOf(0)),
) )
} }
} }
...@@ -22,12 +22,13 @@ import org.junit.jupiter.api.Test ...@@ -22,12 +22,13 @@ import org.junit.jupiter.api.Test
@Tag("HandshakeSerializerTest") @Tag("HandshakeSerializerTest")
class ClientInitAckSerializerTest { class ClientInitAckSerializerTest {
@Test @Test
fun testEmptyMap() = handshakeSerializerTest( fun testEmptyMap() =
handshakeSerializerTest(
HandshakeMessage.ClientInitAck( HandshakeMessage.ClientInitAck(
coreConfigured = null, coreConfigured = null,
backendInfo = emptyList(), backendInfo = emptyList(),
authenticatorInfo = emptyList(), authenticatorInfo = emptyList(),
featureSet = FeatureSet.none() featureSet = FeatureSet.none(),
), ),
byteBufferOf( byteBufferOf(
// 4 elements // 4 elements
...@@ -49,16 +50,17 @@ class ClientInitAckSerializerTest { ...@@ -49,16 +50,17 @@ class ClientInitAckSerializerTest {
0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x41u, 0x00u, 0x63u, 0x00u, 0x6Bu, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x41u, 0x00u, 0x63u, 0x00u, 0x6Bu,
), ),
featureSets = emptyList(), featureSets = emptyList(),
serializeFeatureSet = null serializeFeatureSet = null,
) )
@Test @Test
fun testSimple() = handshakeSerializerTest( fun testSimple() =
handshakeSerializerTest(
HandshakeMessage.ClientInitAck( HandshakeMessage.ClientInitAck(
coreConfigured = false, coreConfigured = false,
backendInfo = emptyList(), backendInfo = emptyList(),
authenticatorInfo = emptyList(), authenticatorInfo = emptyList(),
featureSet = FeatureSet.none() featureSet = FeatureSet.none(),
), ),
byteBufferOf( byteBufferOf(
0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
...@@ -74,71 +76,78 @@ class ClientInitAckSerializerTest { ...@@ -74,71 +76,78 @@ class ClientInitAckSerializerTest {
0x6Eu, 0x66u, 0x69u, 0x67u, 0x75u, 0x72u, 0x65u, 0x64u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x6Eu, 0x66u, 0x69u, 0x67u, 0x75u, 0x72u, 0x65u, 0x64u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u,
0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Bu, 0x46u, 0x65u, 0x61u, 0x74u, 0x75u, 0x72u, 0x65u, 0x4Cu, 0x69u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Bu, 0x46u, 0x65u, 0x61u, 0x74u, 0x75u, 0x72u, 0x65u, 0x4Cu, 0x69u,
0x73u, 0x74u, 0x00u, 0x00u, 0x00u, 0x0Bu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x73u, 0x74u, 0x00u, 0x00u, 0x00u, 0x0Bu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
) ),
) )
@Test @Test
fun testRealistic() = handshakeSerializerTest( fun testRealistic() =
handshakeSerializerTest(
HandshakeMessage.ClientInitAck( HandshakeMessage.ClientInitAck(
coreConfigured = false, coreConfigured = false,
backendInfo = listOf( backendInfo =
listOf(
BackendInfo( BackendInfo(
entries = emptyList(), entries = emptyList(),
isDefault = true, isDefault = true,
displayName = "SQLite", displayName = "SQLite",
description = "SQLite is a file-based database engine that does not " + description =
"SQLite is a file-based database engine that does not " +
"require any setup. It is suitable for small and medium-sized " + "require any setup. It is suitable for small and medium-sized " +
"databases that do not require access via network. Use SQLite if " + "databases that do not require access via network. Use SQLite if " +
"your Quassel Core should store its data on the same machine it is " + "your Quassel Core should store its data on the same machine it is " +
"running on, and if you only expect a few users to use your core.", "running on, and if you only expect a few users to use your core.",
backendId = "SQLite" backendId = "SQLite",
), ),
BackendInfo( BackendInfo(
entries = listOf( entries =
listOf(
SetupEntry( SetupEntry(
"Username", "Username",
"Username", "Username",
qVariant("quassel", QtType.QString) qVariant("quassel", QtType.QString),
), ),
SetupEntry( SetupEntry(
"Password", "Password",
"Password", "Password",
qVariant<String?>(null, QtType.QString) qVariant<String?>(null, QtType.QString),
), ),
SetupEntry( SetupEntry(
"Hostname", "Hostname",
"Hostname", "Hostname",
qVariant("localhost", QtType.QString) qVariant("localhost", QtType.QString),
), ),
SetupEntry( SetupEntry(
"Port", "Port",
"Port", "Port",
qVariant(5432, QtType.Int) qVariant(5432, QtType.Int),
), ),
SetupEntry( SetupEntry(
"Database", "Database",
"Database", "Database",
qVariant("quassel", QtType.QString) qVariant("quassel", QtType.QString),
) ),
), ),
isDefault = false, isDefault = false,
displayName = "PostgreSQL", displayName = "PostgreSQL",
description = "PostgreSQL Turbo Bomber HD!", description = "PostgreSQL Turbo Bomber HD!",
backendId = "PostgreSQL" backendId = "PostgreSQL",
) ),
), ),
authenticatorInfo = listOf( authenticatorInfo =
listOf(
BackendInfo( BackendInfo(
entries = emptyList(), entries = emptyList(),
isDefault = true, isDefault = true,
displayName = "Database", displayName = "Database",
description = "Do not authenticate against any remote service, but " + description =
"Do not authenticate against any remote service, but " +
"instead save a hashed and salted password in the database " + "instead save a hashed and salted password in the database " +
"selected in the next step.", "selected in the next step.",
backendId = "Database" backendId = "Database",
), ),
BackendInfo( BackendInfo(
entries = listOf( entries =
listOf(
SetupEntry( SetupEntry(
"Hostname", "Hostname",
"Hostname", "Hostname",
...@@ -173,15 +182,15 @@ class ClientInitAckSerializerTest { ...@@ -173,15 +182,15 @@ class ClientInitAckSerializerTest {
"UidAttribute", "UidAttribute",
"UID Attribute", "UID Attribute",
qVariant("uid", QtType.QString), qVariant("uid", QtType.QString),
) ),
), ),
isDefault = false, isDefault = false,
displayName = "LDAP", displayName = "LDAP",
description = "Authenticate users using an LDAP server.", description = "Authenticate users using an LDAP server.",
backendId = "LDAP" backendId = "LDAP",
)
), ),
featureSet = FeatureSet.none() ),
featureSet = FeatureSet.none(),
), ),
byteBufferOf( byteBufferOf(
0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
...@@ -417,6 +426,6 @@ class ClientInitAckSerializerTest { ...@@ -417,6 +426,6 @@ class ClientInitAckSerializerTest {
0x65u, 0x64u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x65u, 0x64u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u,
0x0Bu, 0x46u, 0x65u, 0x61u, 0x74u, 0x75u, 0x72u, 0x65u, 0x4Cu, 0x69u, 0x73u, 0x74u, 0x00u, 0x00u, 0x00u, 0x0Bu, 0x0Bu, 0x46u, 0x65u, 0x61u, 0x74u, 0x75u, 0x72u, 0x65u, 0x4Cu, 0x69u, 0x73u, 0x74u, 0x00u, 0x00u, 0x00u, 0x0Bu,
0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
) ),
) )
} }
...@@ -17,9 +17,10 @@ import org.junit.jupiter.api.Test ...@@ -17,9 +17,10 @@ import org.junit.jupiter.api.Test
@Tag("HandshakeSerializerTest") @Tag("HandshakeSerializerTest")
class ClientInitRejectSerializerTest { class ClientInitRejectSerializerTest {
@Test @Test
fun testEmptyMap() = handshakeSerializerTest( fun testEmptyMap() =
handshakeSerializerTest(
HandshakeMessage.ClientInitReject( HandshakeMessage.ClientInitReject(
errorString = null errorString = null,
), ),
byteBufferOf( byteBufferOf(
// 4 elements // 4 elements
...@@ -41,13 +42,14 @@ class ClientInitRejectSerializerTest { ...@@ -41,13 +42,14 @@ class ClientInitRejectSerializerTest {
0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x6Au, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x6Au, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x74u,
), ),
featureSets = emptyList(), featureSets = emptyList(),
serializeFeatureSet = null serializeFeatureSet = null,
) )
@Test @Test
fun testEmpty() = handshakeSerializerTest( fun testEmpty() =
handshakeSerializerTest(
HandshakeMessage.ClientInitReject( HandshakeMessage.ClientInitReject(
errorString = null errorString = null,
), ),
byteBufferOf( byteBufferOf(
0x00u, 0x00u, 0x00u, 0x04u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u, 0x00u, 0x00u, 0x00u, 0x04u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
...@@ -56,14 +58,16 @@ class ClientInitRejectSerializerTest { ...@@ -56,14 +58,16 @@ class ClientInitRejectSerializerTest {
0x74u, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x6Au, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x74u, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x6Au, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u,
0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x05u, 0x45u, 0x72u, 0x72u, 0x6Fu, 0x72u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x05u, 0x45u, 0x72u, 0x72u, 0x6Fu, 0x72u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u,
0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu,
) ),
) )
@Test @Test
fun testSimple() = handshakeSerializerTest( fun testSimple() =
handshakeSerializerTest(
HandshakeMessage.ClientInitReject( HandshakeMessage.ClientInitReject(
errorString = "hm. I've lost a machine.. literally _lost_. it responds to ping, it works completely, I just " + errorString =
"can't figure out where in my apartment it is." "hm. I've lost a machine.. literally _lost_. it responds to ping, it works completely, I just " +
"can't figure out where in my apartment it is.",
), ),
byteBufferOf( byteBufferOf(
0x00u, 0x00u, 0x00u, 0x04u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u, 0x00u, 0x00u, 0x00u, 0x04u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
...@@ -89,6 +93,6 @@ class ClientInitRejectSerializerTest { ...@@ -89,6 +93,6 @@ class ClientInitRejectSerializerTest {
0x00u, 0x20u, 0x00u, 0x6Du, 0x00u, 0x79u, 0x00u, 0x20u, 0x00u, 0x61u, 0x00u, 0x70u, 0x00u, 0x61u, 0x00u, 0x72u, 0x00u, 0x20u, 0x00u, 0x6Du, 0x00u, 0x79u, 0x00u, 0x20u, 0x00u, 0x61u, 0x00u, 0x70u, 0x00u, 0x61u, 0x00u, 0x72u,
0x00u, 0x74u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x74u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x74u,
0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x73u, 0x00u, 0x2Eu, 0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x73u, 0x00u, 0x2Eu,
) ),
) )
} }
...@@ -19,11 +19,12 @@ import org.junit.jupiter.api.Test ...@@ -19,11 +19,12 @@ import org.junit.jupiter.api.Test
@Tag("HandshakeSerializerTest") @Tag("HandshakeSerializerTest")
class ClientInitSerializerTest { class ClientInitSerializerTest {
@Test @Test
fun testEmptyMap() = handshakeSerializerTest( fun testEmptyMap() =
handshakeSerializerTest(
HandshakeMessage.ClientInit( HandshakeMessage.ClientInit(
clientVersion = null, clientVersion = null,
buildDate = null, buildDate = null,
featureSet = FeatureSet.none() featureSet = FeatureSet.none(),
), ),
byteBufferOf( byteBufferOf(
// 4 elements // 4 elements
...@@ -44,15 +45,16 @@ class ClientInitSerializerTest { ...@@ -44,15 +45,16 @@ class ClientInitSerializerTest {
0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x74u,
), ),
featureSets = emptyList(), featureSets = emptyList(),
serializeFeatureSet = null serializeFeatureSet = null,
) )
@Test @Test
fun testSimple() = handshakeSerializerTest( fun testSimple() =
handshakeSerializerTest(
HandshakeMessage.ClientInit( HandshakeMessage.ClientInit(
clientVersion = "Quasseldroid test", clientVersion = "Quasseldroid test",
buildDate = "Never", buildDate = "Never",
featureSet = FeatureSet.none() featureSet = FeatureSet.none(),
), ),
byteBufferOf( byteBufferOf(
0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x0Cu,
...@@ -80,17 +82,20 @@ class ClientInitSerializerTest { ...@@ -80,17 +82,20 @@ class ClientInitSerializerTest {
0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u,
0x00u, 0x00u, 0x0Bu, 0x46u, 0x65u, 0x61u, 0x74u, 0x75u, 0x00u, 0x00u, 0x0Bu, 0x46u, 0x65u, 0x61u, 0x74u, 0x75u,
0x72u, 0x65u, 0x4Cu, 0x69u, 0x73u, 0x74u, 0x00u, 0x00u, 0x72u, 0x65u, 0x4Cu, 0x69u, 0x73u, 0x74u, 0x00u, 0x00u,
0x00u, 0x0Bu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u 0x00u, 0x0Bu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
) ),
) )
@Test @Test
fun testRealistic() = handshakeSerializerTest( fun testRealistic() =
handshakeSerializerTest(
HandshakeMessage.ClientInit( HandshakeMessage.ClientInit(
clientVersion = "Quasseldroid <a href=\"https://git.kuschku.de/justJanne/QuasselDroid-ng/commit/" + clientVersion =
"Quasseldroid <a href=\"https://git.kuschku.de/justJanne/QuasselDroid-ng/commit/" +
"b622ad63056b6054b06e09f8e1f1ef2b0c3aaf9a\">v1.3.3</a>", "b622ad63056b6054b06e09f8e1f1ef2b0c3aaf9a\">v1.3.3</a>",
buildDate = "2020-04-27T22:21:17Z", buildDate = "2020-04-27T22:21:17Z",
featureSet = FeatureSet.build( featureSet =
FeatureSet.build(
QuasselFeature.SynchronizedMarkerLine, QuasselFeature.SynchronizedMarkerLine,
QuasselFeature.SaslAuthentication, QuasselFeature.SaslAuthentication,
QuasselFeature.SaslExternal, QuasselFeature.SaslExternal,
...@@ -113,7 +118,7 @@ class ClientInitSerializerTest { ...@@ -113,7 +118,7 @@ class ClientInitSerializerTest {
QuasselFeature.EcdsaCertfpKeys, QuasselFeature.EcdsaCertfpKeys,
QuasselFeature.LongMessageId, QuasselFeature.LongMessageId,
QuasselFeature.SyncedCoreInfo, QuasselFeature.SyncedCoreInfo,
) ),
), ),
byteBufferOf( byteBufferOf(
0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
...@@ -192,7 +197,7 @@ class ClientInitSerializerTest { ...@@ -192,7 +197,7 @@ class ClientInitSerializerTest {
0x73u, 0x00u, 0x00u, 0x00u, 0x1Au, 0x00u, 0x4Cu, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x67u, 0x00u, 0x4Du, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x1Au, 0x00u, 0x4Cu, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x67u, 0x00u, 0x4Du, 0x00u,
0x65u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x61u, 0x00u, 0x67u, 0x00u, 0x65u, 0x00u, 0x49u, 0x00u, 0x64u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x61u, 0x00u, 0x67u, 0x00u, 0x65u, 0x00u, 0x49u, 0x00u, 0x64u, 0x00u,
0x00u, 0x00u, 0x1Cu, 0x00u, 0x53u, 0x00u, 0x79u, 0x00u, 0x6Eu, 0x00u, 0x63u, 0x00u, 0x65u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x1Cu, 0x00u, 0x53u, 0x00u, 0x79u, 0x00u, 0x6Eu, 0x00u, 0x63u, 0x00u, 0x65u, 0x00u, 0x64u, 0x00u,
0x43u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x49u, 0x00u, 0x6Eu, 0x00u, 0x66u, 0x00u, 0x6Fu 0x43u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x49u, 0x00u, 0x6Eu, 0x00u, 0x66u, 0x00u, 0x6Fu,
) ),
) )
} }