diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ac303b..3aac6cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,34 @@ This document serves as the change log for the ONIXLabs Kotlin Core API. +## Version 2.0.0 + +#### TypeConverter (abstract class) + +Represents the base class for implementing type converters. Type converters represent a mechanism to convert from one type to another, using type-safe convensions. + +The following type converters are implemented: + +- BigDecimalTypeConverter +- BigIntegerTypeConverter +- BooleanTypeConverter +- ByteTypeConverter +- CharTypeConverter +- DoubleTypeConverter +- FloatTypeConverter +- IntTypeConverter +- LongTypeConverter +- ShortTypeConverter +- StringTypeConverter +- UUIDTypeConverter + +### Extensions + +#### KType Extensions + +- Renamed `name` to `formattedSimpleName`. +- Renamed `fullName` to `formattedQualifiedName`. + ## Version 1.0.0 #### ConsoleColor (enum) diff --git a/build.gradle b/build.gradle index 18cc356..109048a 100644 --- a/build.gradle +++ b/build.gradle @@ -19,7 +19,7 @@ buildscript { } group 'io.onixlabs' -version '1.0.0' +version '2.0.0' allprojects { repositories { diff --git a/src/main/kotlin/io/onixlabs/kotlin/core/reflection/Extensions.KType.kt b/src/main/kotlin/io/onixlabs/kotlin/core/reflection/Extensions.KType.kt index 6e8521e..ba6e53f 100644 --- a/src/main/kotlin/io/onixlabs/kotlin/core/reflection/Extensions.KType.kt +++ b/src/main/kotlin/io/onixlabs/kotlin/core/reflection/Extensions.KType.kt @@ -25,17 +25,20 @@ import kotlin.reflect.jvm.jvmErasure /** * Gets the formatted simple name of the type, including any generic type arguments. */ -val KType.name: String get() = "${jvmErasure.simpleName}${getFormattedArguments(false)}$nullableToken" +val KType.formattedSimpleName: String + get() = "${jvmErasure.simpleName}${getFormattedArguments(false)}$nullableToken" /** * Gets the formatted qualified name of the type, including any generic type arguments. */ -val KType.fullName: String get() = "${jvmErasure.qualifiedName}${getFormattedArguments(true)}$nullableToken" +val KType.formattedQualifiedName: String + get() = "${jvmErasure.qualifiedName}${getFormattedArguments(true)}$nullableToken" /** * Gets a nullable token for the specified string, or an empty string if the type is non-nullable. */ -private val KType.nullableToken: String get() = if (isMarkedNullable) "?" else String.EMPTY +private val KType.nullableToken: String + get() = if (isMarkedNullable) "?" else String.EMPTY /** * Gets a formatted list of generic type argument names. diff --git a/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/BigDecimalTypeConverter.kt b/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/BigDecimalTypeConverter.kt new file mode 100644 index 0000000..2f4979b --- /dev/null +++ b/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/BigDecimalTypeConverter.kt @@ -0,0 +1,47 @@ +/** + * Copyright 2020 Matthew Layton + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.onixlabs.kotlin.core.typeconverters + +import io.onixlabs.kotlin.core.reflection.kotlinClass +import java.math.BigDecimal +import java.math.BigInteger + +/** + * Provides a mechanism to safely convert the specified value value to the [BigDecimal] type. + */ +class BigDecimalTypeConverter : TypeConverter() { + + /** + * Converts the specified value to the [BigDecimal] type. + * + * @param value The value to convert. + * @return Returns a [BigDecimal] representation of the specified value. + */ + override fun convert(value: Any): BigDecimal = when (value) { + is Boolean -> if (value) BigDecimal.ONE else BigDecimal.ZERO + is Byte -> BigDecimal.valueOf(value.toLong()) + is Short -> BigDecimal.valueOf(value.toLong()) + is Int -> BigDecimal.valueOf(value.toLong()) + is Long -> BigDecimal.valueOf(value) + is BigInteger -> BigDecimal(value) + is Double -> value.toBigDecimal() + is BigDecimal -> value + is String -> value.toBigDecimal().stripTrailingZeros() + is Char -> BigDecimal.valueOf(value.toLong()) + else -> throw IllegalTypeConversionException(value.kotlinClass, BigDecimal::class) + } +} diff --git a/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/BigIntegerTypeConverter.kt b/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/BigIntegerTypeConverter.kt new file mode 100644 index 0000000..227a316 --- /dev/null +++ b/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/BigIntegerTypeConverter.kt @@ -0,0 +1,84 @@ +/** + * Copyright 2020 Matthew Layton + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.onixlabs.kotlin.core.typeconverters + +import io.onixlabs.kotlin.core.isInteger +import io.onixlabs.kotlin.core.math.isInteger +import io.onixlabs.kotlin.core.reflection.kotlinClass +import io.onixlabs.kotlin.core.typeconverters.IllegalTypeConversionException.Companion.NUMERIC_LOSS_OF_PRECISION +import java.math.BigDecimal +import java.math.BigInteger + +/** + * Provides a mechanism to safely convert the specified value value to the [BigInteger] type. + */ +class BigIntegerTypeConverter : TypeConverter() { + + /** + * Converts the specified value to the [BigInteger] type. + * + * @param value The value to convert. + * @return Returns an [BigInteger] representation of the specified value. + */ + override fun convert(value: Any): BigInteger = when (value) { + is Boolean -> if (value) BigInteger.ONE else BigInteger.ZERO + is Byte -> BigInteger.valueOf(value.toLong()) + is Short -> BigInteger.valueOf(value.toLong()) + is Int -> BigInteger.valueOf(value.toLong()) + is Long -> BigInteger.valueOf(value) + is BigInteger -> value + is Float -> value.toBigIntegerChecked() + is Double -> value.toBigIntegerChecked() + is BigDecimal -> value.toBigIntegerChecked() + is String -> value.toBigInteger() + is Char -> BigInteger.valueOf(value.toLong()) + else -> throw IllegalTypeConversionException(value.kotlinClass, BigInteger::class) + } + + /** + * Performs a checked conversion from [Float] to [BigInteger]. + * + * @return Returns a [BigInteger] representation of the specified [Float]. + * @throws IllegalTypeConversionException if the value cannot be safely converted to [BigInteger]. + */ + private fun Float.toBigIntegerChecked(): BigInteger = when { + isInteger() -> BigInteger.valueOf(toLong()) + else -> throw NUMERIC_LOSS_OF_PRECISION + } + + /** + * Performs a checked conversion from [Double] to [BigInteger]. + * + * @return Returns a [BigInteger] representation of the specified [Double]. + * @throws IllegalTypeConversionException if the value cannot be safely converted to [BigInteger]. + */ + private fun Double.toBigIntegerChecked(): BigInteger = when { + isInteger() -> BigInteger.valueOf(toLong()) + else -> throw NUMERIC_LOSS_OF_PRECISION + } + + /** + * Performs a checked conversion from [BigDecimal] to [BigInteger]. + * + * @return Returns a [BigInteger] representation of the specified [BigDecimal]. + * @throws IllegalTypeConversionException if the value cannot be safely converted to [BigInteger]. + */ + private fun BigDecimal.toBigIntegerChecked(): BigInteger = when { + isInteger() -> toBigInteger() + else -> throw NUMERIC_LOSS_OF_PRECISION + } +} diff --git a/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/BooleanTypeConverter.kt b/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/BooleanTypeConverter.kt new file mode 100644 index 0000000..142208d --- /dev/null +++ b/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/BooleanTypeConverter.kt @@ -0,0 +1,81 @@ +/** + * Copyright 2020 Matthew Layton + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.onixlabs.kotlin.core.typeconverters + +import io.onixlabs.kotlin.core.reflection.kotlinClass + +/** + * Provides a mechanism to safely convert the specified value value to the [Boolean] type. + */ +class BooleanTypeConverter : TypeConverter() { + + private companion object { + const val EX_NUM_TO_BOOL = "Illegal type conversion. Numeric value cannot be converted to Boolean." + const val EX_STR_TO_BOOL = "Illegal type conversion. String value cannot be converted to Boolean." + const val EX_CHR_TO_BOOL = "Illegal type conversion. Char value cannot be converted to Boolean." + } + + /** + * Converts the specified value to the [Boolean] type. + * + * @param value The value to convert. + * @return Returns a [Boolean] representation of the specified value. + */ + override fun convert(value: Any): Boolean = when (value) { + is Boolean -> value + is Number -> value.toBooleanChecked() + is String -> value.toBooleanChecked() + is Char -> value.toBooleanChecked() + else -> throw IllegalTypeConversionException(value.kotlinClass, Boolean::class) + } + + /** + * Performs a checked conversion from [Number] to [Boolean]. + * + * @return Returns a [Boolean] representation of the specified [Number]. + * @throws IllegalTypeConversionException if the value cannot be safely converted to [Boolean]. + */ + private fun Number.toBooleanChecked(): Boolean = when (this) { + 1 -> true + 0 -> false + else -> throw IllegalTypeConversionException(EX_NUM_TO_BOOL) + } + + /** + * Performs a checked conversion from [String] to [Boolean]. + * + * @return Returns a [Boolean] representation of the specified [String]. + * @throws IllegalTypeConversionException if the value cannot be safely converted to [Boolean]. + */ + private fun String.toBooleanChecked(): Boolean = when (this.toLowerCase()) { + "true", "yes", "y", "1" -> true + "false", "no", "n", "0" -> false + else -> throw IllegalTypeConversionException(EX_STR_TO_BOOL) + } + + /** + * Performs a checked conversion from [Char] to [Boolean]. + * + * @return Returns a [Boolean] representation of the specified [Char]. + * @throws IllegalTypeConversionException if the value cannot be safely converted to [Boolean]. + */ + private fun Char.toBooleanChecked(): Boolean = when (this.toLowerCase()) { + 'y', '1' -> true + 'n', '0' -> false + else -> throw IllegalTypeConversionException(EX_CHR_TO_BOOL) + } +} diff --git a/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/ByteTypeConverter.kt b/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/ByteTypeConverter.kt new file mode 100644 index 0000000..02d2a9f --- /dev/null +++ b/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/ByteTypeConverter.kt @@ -0,0 +1,143 @@ +/** + * Copyright 2020 Matthew Layton + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.onixlabs.kotlin.core.typeconverters + +import io.onixlabs.kotlin.core.* +import io.onixlabs.kotlin.core.math.isInteger +import io.onixlabs.kotlin.core.reflection.kotlinClass +import io.onixlabs.kotlin.core.typeconverters.IllegalTypeConversionException.Companion.NUMERIC_LOSS_OF_PRECISION +import io.onixlabs.kotlin.core.typeconverters.IllegalTypeConversionException.Companion.NUMERIC_OVERFLOW +import java.math.BigDecimal +import java.math.BigInteger + +/** + * Provides a mechanism to safely convert the specified value value to the [Byte] type. + */ +class ByteTypeConverter : TypeConverter() { + + /** + * Converts the specified value to the [Byte] type. + * + * @param value The value to convert. + * @return Returns a [Byte] representation of the specified value. + */ + override fun convert(value: Any): Byte = when (value) { + is Boolean -> if (value) Byte.ONE else Byte.ZERO + is Byte -> value + is Short -> value.toByteChecked() + is Int -> value.toByteChecked() + is Long -> value.toByteChecked() + is BigInteger -> value.toByteChecked() + is Float -> value.toByteChecked() + is Double -> value.toByteChecked() + is BigDecimal -> value.toByteChecked() + is String -> value.toByte() + is Char -> value.toByteChecked() + else -> throw IllegalTypeConversionException(value.kotlinClass, Byte::class) + } + + /** + * Performs a checked conversion from [Short] to [Byte]. + * + * @return Returns a [Byte] representation of the specified [Short]. + * @throws IllegalTypeConversionException if the value cannot be safely converted to [Byte]. + */ + private fun Short.toByteChecked(): Byte = when (this) { + in Byte.MIN_VALUE..Byte.MAX_VALUE -> toByte() + else -> throw NUMERIC_OVERFLOW + } + + /** + * Performs a checked conversion from [Int] to [Byte]. + * + * @return Returns a [Byte] representation of the specified [Int]. + * @throws IllegalTypeConversionException if the value cannot be safely converted to [Byte]. + */ + private fun Int.toByteChecked(): Byte = when (this) { + in Byte.MIN_VALUE..Byte.MAX_VALUE -> toByte() + else -> throw NUMERIC_OVERFLOW + } + + /** + * Performs a checked conversion from [Long] to [Byte]. + * + * @return Returns a [Byte] representation of the specified [Long]. + * @throws IllegalTypeConversionException if the value cannot be safely converted to [Byte]. + */ + private fun Long.toByteChecked(): Byte = when (this) { + in Byte.MIN_VALUE..Byte.MAX_VALUE -> toByte() + else -> throw NUMERIC_OVERFLOW + } + + /** + * Performs a checked conversion from [BigInteger] to [Boolean]. + * + * @return Returns a [Boolean] representation of the specified [BigInteger]. + * @throws IllegalTypeConversionException if the value cannot be safely converted to [Boolean]. + */ + private fun BigInteger.toByteChecked(): Byte = when (this) { + in Byte.MIN_VALUE.toBigInteger()..Byte.MAX_VALUE.toBigInteger() -> toByte() + else -> throw NUMERIC_OVERFLOW + } + + /** + * Performs a checked conversion from [Float] to [Byte]. + * + * @return Returns a [Byte] representation of the specified [Float]. + * @throws IllegalTypeConversionException if the value cannot be safely converted to [Byte]. + */ + private fun Float.toByteChecked(): Byte = when { + !isInteger() -> throw NUMERIC_LOSS_OF_PRECISION + this in Byte.MIN_VALUE.toFloat()..Byte.MAX_VALUE.toFloat() -> toInt().toByte() + else -> throw NUMERIC_OVERFLOW + } + + /** + * Performs a checked conversion from [Double] to [Byte]. + * + * @return Returns a [Byte] representation of the specified [Double]. + * @throws IllegalTypeConversionException if the value cannot be safely converted to [Byte]. + */ + private fun Double.toByteChecked(): Byte = when { + !isInteger() -> throw NUMERIC_LOSS_OF_PRECISION + this in Byte.MIN_VALUE.toDouble()..Byte.MAX_VALUE.toDouble() -> toInt().toByte() + else -> throw NUMERIC_OVERFLOW + } + + /** + * Performs a checked conversion from [BigDecimal] to [Byte]. + * + * @return Returns a [Byte] representation of the specified [BigDecimal]. + * @throws IllegalTypeConversionException if the value cannot be safely converted to [Byte]. + */ + private fun BigDecimal.toByteChecked(): Byte = when { + !isInteger() -> throw NUMERIC_LOSS_OF_PRECISION + this in Byte.MIN_VALUE.toBigDecimal()..Byte.MAX_VALUE.toBigDecimal() -> toByte() + else -> throw NUMERIC_OVERFLOW + } + + /** + * Performs a checked conversion from [Char] to [Byte]. + * + * @return Returns a [Byte] representation of the specified [Char]. + * @throws IllegalTypeConversionException if the value cannot be safely converted to [Byte]. + */ + private fun Char.toByteChecked(): Byte = when { + toShort() in Byte.MIN_VALUE..Byte.MAX_VALUE -> toByte() + else -> throw NUMERIC_OVERFLOW + } +} diff --git a/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/CharTypeConverter.kt b/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/CharTypeConverter.kt new file mode 100644 index 0000000..35afd73 --- /dev/null +++ b/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/CharTypeConverter.kt @@ -0,0 +1,135 @@ +/** + * Copyright 2020 Matthew Layton + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.onixlabs.kotlin.core.typeconverters + +import io.onixlabs.kotlin.core.isInteger +import io.onixlabs.kotlin.core.math.isInteger +import io.onixlabs.kotlin.core.reflection.kotlinClass +import io.onixlabs.kotlin.core.toBigDecimal +import io.onixlabs.kotlin.core.toBigInteger +import io.onixlabs.kotlin.core.typeconverters.IllegalTypeConversionException.Companion.NUMERIC_LOSS_OF_PRECISION +import io.onixlabs.kotlin.core.typeconverters.IllegalTypeConversionException.Companion.NUMERIC_OVERFLOW +import java.math.BigDecimal +import java.math.BigInteger + +/** + * Provides a mechanism to safely convert the specified value value to the [Char] type. + */ +class CharTypeConverter : TypeConverter() { + + private companion object { + const val EX_STR_TO_CHR = "Illegal type conversion. String value cannot be converted to Char." + } + + /** + * Converts the specified value to the [Char] type. + * + * @param value The value to convert. + * @return Returns a [Char] representation of the specified value. + */ + override fun convert(value: Any): Char = when (value) { + is Boolean -> if (value) '1' else '0' + is Byte -> value.toChar() + is Short -> value.toChar() + is Int -> value.toCharChecked() + is Long -> value.toCharChecked() + is BigInteger -> value.toCharChecked() + is Float -> value.toCharChecked() + is Double -> value.toCharChecked() + is BigDecimal -> value.toCharChecked() + is String -> value.toCharChecked() + is Char -> value + else -> throw IllegalTypeConversionException(value.kotlinClass, Char::class) + } + + /** + * Performs a checked conversion from [Int] to [Char]. + * + * @return Returns a [Char] representation of the specified [Int]. + * @throws IllegalTypeConversionException if the value cannot be safely converted to [Char]. + */ + private fun Int.toCharChecked(): Char = when (this) { + in Short.MIN_VALUE..Short.MAX_VALUE -> toChar() + else -> throw NUMERIC_OVERFLOW + } + + /** + * Performs a checked conversion from [Long] to [Char]. + * + * @return Returns a [Char] representation of the specified [Long]. + * @throws IllegalTypeConversionException if the value cannot be safely converted to [Char]. + */ + private fun Long.toCharChecked(): Char = when (this) { + in Short.MIN_VALUE..Short.MAX_VALUE -> toChar() + else -> throw NUMERIC_OVERFLOW + } + + /** + * Performs a checked conversion from [BigInteger] to [Char]. + * + * @return Returns a [Char] representation of the specified [BigInteger]. + * @throws IllegalTypeConversionException if the value cannot be safely converted to [Char]. + */ + private fun BigInteger.toCharChecked(): Char = when (this) { + in Short.MIN_VALUE.toBigInteger()..Short.MAX_VALUE.toBigInteger() -> toShort().toChar() + else -> throw NUMERIC_OVERFLOW + } + + /** + * Performs a checked conversion from [Float] to [Char]. + * + * @return Returns a [Char] representation of the specified [Float]. + * @throws IllegalTypeConversionException if the value cannot be safely converted to [Char]. + */ + private fun Float.toCharChecked(): Char = when { + !isInteger() -> throw NUMERIC_LOSS_OF_PRECISION + this in Short.MIN_VALUE.toFloat()..Short.MAX_VALUE.toFloat() -> toChar() + else -> throw NUMERIC_OVERFLOW + } + + /** + * Performs a checked conversion from [Double] to [Char]. + * + * @return Returns a [Char] representation of the specified [Double]. + * @throws IllegalTypeConversionException if the value cannot be safely converted to [Char]. + */ + private fun Double.toCharChecked(): Char = when { + !isInteger() -> throw NUMERIC_LOSS_OF_PRECISION + this in Short.MIN_VALUE.toDouble()..Short.MAX_VALUE.toDouble() -> toChar() + else -> throw NUMERIC_OVERFLOW + } + + /** + * Performs a checked conversion from [BigDecimal] to [Char]. + * + * @return Returns a [Char] representation of the specified [BigDecimal]. + * @throws IllegalTypeConversionException if the value cannot be safely converted to [Char]. + */ + private fun BigDecimal.toCharChecked(): Char = when { + !isInteger() -> throw NUMERIC_LOSS_OF_PRECISION + this in Short.MIN_VALUE.toBigDecimal()..Short.MAX_VALUE.toBigDecimal() -> toShort().toChar() + else -> throw NUMERIC_OVERFLOW + } + + /** + * Performs a checked conversion from [String] to [Char]. + * + * @return Returns a [Char] representation of the specified [BigInteger]. + * @throws IllegalTypeConversionException if the value cannot be safely converted to [String]. + */ + private fun String.toCharChecked(): Char = singleOrNull() ?: throw IllegalTypeConversionException(EX_STR_TO_CHR) +} diff --git a/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/DoubleTypeConverter.kt b/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/DoubleTypeConverter.kt new file mode 100644 index 0000000..eb30433 --- /dev/null +++ b/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/DoubleTypeConverter.kt @@ -0,0 +1,60 @@ +/** + * Copyright 2020 Matthew Layton + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.onixlabs.kotlin.core.typeconverters + +import io.onixlabs.kotlin.core.ONE +import io.onixlabs.kotlin.core.ZERO +import io.onixlabs.kotlin.core.reflection.kotlinClass +import io.onixlabs.kotlin.core.toBigInteger +import io.onixlabs.kotlin.core.typeconverters.IllegalTypeConversionException.Companion.NUMERIC_OVERFLOW +import java.math.BigInteger + +/** + * Provides a mechanism to safely convert the specified value value to the [Double] type. + */ +class DoubleTypeConverter : TypeConverter() { + + /** + * Converts the specified value to the [Double] type. + * + * @param value The value to convert. + * @return Returns a [Double] representation of the specified value. + */ + override fun convert(value: Any): Double = when (value) { + is Boolean -> if (value) Double.ONE else Double.ZERO + is Byte -> value.toDouble() + is Short -> value.toDouble() + is Int -> value.toDouble() + is Long -> value.toDouble() + is BigInteger -> value.toDoubleChecked() + is Double -> value + is String -> value.toDouble() + is Char -> value.toDouble() + else -> throw IllegalTypeConversionException(value.kotlinClass, Double::class) + } + + /** + * Performs a checked conversion from [BigInteger] to [Double]. + * + * @return Returns a [Double] representation of the specified [BigInteger]. + * @throws IllegalTypeConversionException if the value cannot be safely converted to [Double]. + */ + private fun BigInteger.toDoubleChecked(): Double = when (this) { + in Double.MIN_VALUE.toBigInteger()..Double.MAX_VALUE.toBigInteger() -> toDouble() + else -> throw NUMERIC_OVERFLOW + } +} diff --git a/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/FloatTypeConverter.kt b/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/FloatTypeConverter.kt new file mode 100644 index 0000000..5ed0a6c --- /dev/null +++ b/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/FloatTypeConverter.kt @@ -0,0 +1,44 @@ +/** + * Copyright 2020 Matthew Layton + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.onixlabs.kotlin.core.typeconverters + +import io.onixlabs.kotlin.core.ONE +import io.onixlabs.kotlin.core.ZERO +import io.onixlabs.kotlin.core.reflection.kotlinClass + +/** + * Provides a mechanism to safely convert the specified value value to the [Float] type. + */ +class FloatTypeConverter : TypeConverter() { + + /** + * Converts an object from the input type to the output type. + * + * @param value The value to convert. + * @return Returns an instance of the output type. + */ + override fun convert(value: Any): Float = when (value) { + is Boolean -> if (value) Float.ONE else Float.ZERO + is Byte -> value.toFloat() + is Short -> value.toFloat() + is Int -> value.toFloat() + is Float -> value + is String -> value.toFloat() + is Char -> value.toFloat() + else -> throw IllegalTypeConversionException(value.kotlinClass, Float::class) + } +} diff --git a/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/IllegalTypeConversionException.kt b/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/IllegalTypeConversionException.kt new file mode 100644 index 0000000..71b659c --- /dev/null +++ b/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/IllegalTypeConversionException.kt @@ -0,0 +1,52 @@ +/** + * Copyright 2020 Matthew Layton + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.onixlabs.kotlin.core.typeconverters + +import kotlin.reflect.KClass + +/** + * Represents the exception that is thrown when a type converter is unable to convert the specified value. + * + * @param message A message detailing the type conversion exception. + * @param cause An underlying cause of the type conversion exception. + */ +class IllegalTypeConversionException(message: String, cause: Throwable? = null) : Exception(message, cause) { + + internal companion object { + + /** + * An [IllegalTypeConversionException] that is thrown when a numeric value overflows. + */ + val NUMERIC_OVERFLOW = IllegalTypeConversionException("Illegal type conversion. Numeric overflow.") + + /** + * An [IllegalTypeConversionException] that is thrown when a floating point value loses precision. + */ + val NUMERIC_LOSS_OF_PRECISION = IllegalTypeConversionException("Illegal type conversion. Loss of precision.") + } + + /** + * Creates an [IllegalTypeConversionException] from the specified input and output classes. + * This exception details that the input class cannot be mapped to the output class. + * + * @param inputClass The input class. + * @param outputClass The output class. + */ + constructor(inputClass: KClass<*>, outputClass: KClass<*>) : this( + "Illegal type conversion. Cannot convert from '${inputClass.qualifiedName}' to '${outputClass.qualifiedName}'." + ) +} diff --git a/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/IntTypeConverter.kt b/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/IntTypeConverter.kt new file mode 100644 index 0000000..b5c7a17 --- /dev/null +++ b/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/IntTypeConverter.kt @@ -0,0 +1,112 @@ +/** + * Copyright 2020 Matthew Layton + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.onixlabs.kotlin.core.typeconverters + +import io.onixlabs.kotlin.core.ONE +import io.onixlabs.kotlin.core.ZERO +import io.onixlabs.kotlin.core.isInteger +import io.onixlabs.kotlin.core.math.isInteger +import io.onixlabs.kotlin.core.reflection.kotlinClass +import io.onixlabs.kotlin.core.typeconverters.IllegalTypeConversionException.Companion.NUMERIC_LOSS_OF_PRECISION +import io.onixlabs.kotlin.core.typeconverters.IllegalTypeConversionException.Companion.NUMERIC_OVERFLOW +import java.math.BigDecimal +import java.math.BigInteger + +/** + * Provides a mechanism to safely convert the specified value value to the [Int] type. + */ +class IntTypeConverter : TypeConverter() { + + /** + * Converts the specified value to the [Int] type. + * + * @param value The value to convert. + * @return Returns an [Int] representation of the specified value. + */ + override fun convert(value: Any): Int = when (value) { + is Boolean -> if (value) Int.ONE else Int.ZERO + is Byte -> value.toInt() + is Short -> value.toInt() + is Int -> value + is Long -> value.toIntChecked() + is BigInteger -> value.toIntChecked() + is Float -> value.toIntChecked() + is Double -> value.toIntChecked() + is BigDecimal -> value.toIntChecked() + is String -> value.toInt() + is Char -> value.toInt() + else -> throw IllegalTypeConversionException(value.kotlinClass, Int::class) + } + + /** + * Performs a checked conversion from [Long] to [Int]. + * + * @return Returns an [Int] representation of the specified [Long]. + * @throws IllegalTypeConversionException if the value cannot be safely converted to [Int]. + */ + private fun Long.toIntChecked(): Int = when (this) { + in Int.MIN_VALUE..Int.MAX_VALUE -> toInt() + else -> throw NUMERIC_OVERFLOW + } + + /** + * Performs a checked conversion from [BigInteger] to [Int]. + * + * @return Returns an [Int] representation of the specified [BigInteger]. + * @throws IllegalTypeConversionException if the value cannot be safely converted to [Int]. + */ + private fun BigInteger.toIntChecked(): Int = when (this) { + in Int.MIN_VALUE.toBigInteger()..Int.MAX_VALUE.toBigInteger() -> toInt() + else -> throw NUMERIC_OVERFLOW + } + + /** + * Performs a checked conversion from [Float] to [Int]. + * + * @return Returns an [Int] representation of the specified [Float]. + * @throws IllegalTypeConversionException if the value cannot be safely converted to [Int]. + */ + private fun Float.toIntChecked(): Int = when { + !isInteger() -> throw NUMERIC_LOSS_OF_PRECISION + this in Int.MIN_VALUE.toFloat()..Int.MAX_VALUE.toFloat() -> toInt() + else -> throw NUMERIC_OVERFLOW + } + + /** + * Performs a checked conversion from [Double] to [Int]. + * + * @return Returns an [Int] representation of the specified [Double]. + * @throws IllegalTypeConversionException if the value cannot be safely converted to [Int]. + */ + private fun Double.toIntChecked(): Int = when { + !isInteger() -> throw NUMERIC_LOSS_OF_PRECISION + this in Int.MIN_VALUE.toDouble()..Int.MAX_VALUE.toDouble() -> toInt() + else -> throw NUMERIC_OVERFLOW + } + + /** + * Performs a checked conversion from [BigDecimal] to [Int]. + * + * @return Returns an [Int] representation of the specified [BigDecimal]. + * @throws IllegalTypeConversionException if the value cannot be safely converted to [Int]. + */ + private fun BigDecimal.toIntChecked(): Int = when { + !isInteger() -> throw NUMERIC_LOSS_OF_PRECISION + this in Int.MIN_VALUE.toBigDecimal()..Int.MAX_VALUE.toBigDecimal() -> toInt() + else -> throw NUMERIC_OVERFLOW + } +} diff --git a/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/LongTypeConverter.kt b/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/LongTypeConverter.kt new file mode 100644 index 0000000..a5d4994 --- /dev/null +++ b/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/LongTypeConverter.kt @@ -0,0 +1,101 @@ +/** + * Copyright 2020 Matthew Layton + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.onixlabs.kotlin.core.typeconverters + +import io.onixlabs.kotlin.core.ONE +import io.onixlabs.kotlin.core.ZERO +import io.onixlabs.kotlin.core.isInteger +import io.onixlabs.kotlin.core.math.isInteger +import io.onixlabs.kotlin.core.reflection.kotlinClass +import io.onixlabs.kotlin.core.typeconverters.IllegalTypeConversionException.Companion.NUMERIC_LOSS_OF_PRECISION +import io.onixlabs.kotlin.core.typeconverters.IllegalTypeConversionException.Companion.NUMERIC_OVERFLOW +import java.math.BigDecimal +import java.math.BigInteger + +/** + * Provides a mechanism to safely convert the specified value value to the [Long] type. + */ +class LongTypeConverter : TypeConverter() { + + /** + * Converts the specified value to the [Long] type. + * + * @param value The value to convert. + * @return Returns a [Long] representation of the specified value. + */ + override fun convert(value: Any): Long = when (value) { + is Boolean -> if (value) Long.ONE else Long.ZERO + is Byte -> value.toLong() + is Short -> value.toLong() + is Int -> value.toLong() + is Long -> value + is BigInteger -> value.toLongChecked() + is Float -> value.toLongChecked() + is Double -> value.toLongChecked() + is BigDecimal -> value.toLongChecked() + is String -> value.toLong() + is Char -> value.toLong() + else -> throw IllegalTypeConversionException(value.kotlinClass, Long::class) + } + + /** + * Performs a checked conversion from [BigInteger] to [Long]. + * + * @return Returns a [Long] representation of the specified [BigInteger]. + * @throws IllegalTypeConversionException if the value cannot be safely converted to [Long]. + */ + private fun BigInteger.toLongChecked(): Long = when (this) { + in Long.MIN_VALUE.toBigInteger()..Long.MAX_VALUE.toBigInteger() -> toLong() + else -> throw NUMERIC_OVERFLOW + } + + /** + * Performs a checked conversion from [Float] to [Long]. + * + * @return Returns a [Long] representation of the specified [Float]. + * @throws IllegalTypeConversionException if the value cannot be safely converted to [Long]. + */ + private fun Float.toLongChecked(): Long = when { + !isInteger() -> throw NUMERIC_LOSS_OF_PRECISION + this in Long.MIN_VALUE.toFloat()..Long.MAX_VALUE.toFloat() -> toLong() + else -> throw NUMERIC_OVERFLOW + } + + /** + * Performs a checked conversion from [Double] to [Long]. + * + * @return Returns a [Long] representation of the specified [Double]. + * @throws IllegalTypeConversionException if the value cannot be safely converted to [Long]. + */ + private fun Double.toLongChecked(): Long = when { + !isInteger() -> throw NUMERIC_LOSS_OF_PRECISION + this in Long.MIN_VALUE.toDouble()..Long.MAX_VALUE.toDouble() -> toLong() + else -> throw NUMERIC_OVERFLOW + } + + /** + * Performs a checked conversion from [BigDecimal] to [Long]. + * + * @return Returns a [Long] representation of the specified [BigDecimal]. + * @throws IllegalTypeConversionException if the value cannot be safely converted to [Long]. + */ + private fun BigDecimal.toLongChecked(): Long = when { + !isInteger() -> throw NUMERIC_LOSS_OF_PRECISION + this in Long.MIN_VALUE.toBigDecimal()..Long.MAX_VALUE.toBigDecimal() -> toLong() + else -> throw NUMERIC_OVERFLOW + } +} diff --git a/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/ShortTypeConverter.kt b/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/ShortTypeConverter.kt new file mode 100644 index 0000000..ab996df --- /dev/null +++ b/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/ShortTypeConverter.kt @@ -0,0 +1,121 @@ +/** + * Copyright 2020 Matthew Layton + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.onixlabs.kotlin.core.typeconverters + +import io.onixlabs.kotlin.core.* +import io.onixlabs.kotlin.core.math.isInteger +import io.onixlabs.kotlin.core.reflection.kotlinClass +import io.onixlabs.kotlin.core.typeconverters.IllegalTypeConversionException.Companion.NUMERIC_LOSS_OF_PRECISION +import io.onixlabs.kotlin.core.typeconverters.IllegalTypeConversionException.Companion.NUMERIC_OVERFLOW +import java.math.BigDecimal +import java.math.BigInteger + +/** + * Provides a mechanism to safely convert the specified value value to the [Short] type. + */ +class ShortTypeConverter : TypeConverter() { + + /** + * Converts the specified value to the [Short] type. + * + * @param value The value to convert. + * @return Returns a [Short] representation of the specified value. + */ + override fun convert(value: Any): Short = when (value) { + is Boolean -> if (value) Short.ONE else Short.ZERO + is Byte -> value.toShort() + is Short -> value + is Int -> value.toShortChecked() + is Long -> value.toShortChecked() + is BigInteger -> value.toShortChecked() + is Float -> value.toShortChecked() + is Double -> value.toShortChecked() + is BigDecimal -> value.toShortChecked() + is String -> value.toShort() + is Char -> value.toShort() + else -> throw IllegalTypeConversionException(value.kotlinClass, Short::class) + } + + /** + * Performs a checked conversion from [Int] to [Short]. + * + * @return Returns a [Short] representation of the specified [Int]. + * @throws IllegalTypeConversionException if the value cannot be safely converted to [Short]. + */ + private fun Int.toShortChecked(): Short = when (this) { + in Short.MIN_VALUE..Short.MAX_VALUE -> toShort() + else -> throw NUMERIC_OVERFLOW + } + + /** + * Performs a checked conversion from [Long] to [Short]. + * + * @return Returns a [Short] representation of the specified [Long]. + * @throws IllegalTypeConversionException if the value cannot be safely converted to [Short]. + */ + private fun Long.toShortChecked(): Short = when (this) { + in Short.MIN_VALUE..Short.MAX_VALUE -> toShort() + else -> throw NUMERIC_OVERFLOW + } + + /** + * Performs a checked conversion from [BigInteger] to [Short]. + * + * @return Returns a [Short] representation of the specified [BigInteger]. + * @throws IllegalTypeConversionException if the value cannot be safely converted to [Short]. + */ + private fun BigInteger.toShortChecked(): Short = when (this) { + in Short.MIN_VALUE.toBigInteger()..Short.MAX_VALUE.toBigInteger() -> toShort() + else -> throw NUMERIC_OVERFLOW + } + + /** + * Performs a checked conversion from [Float] to [Short]. + * + * @return Returns a [Short] representation of the specified [Float]. + * @throws IllegalTypeConversionException if the value cannot be safely converted to [Short]. + */ + private fun Float.toShortChecked(): Short = when { + !isInteger() -> throw NUMERIC_LOSS_OF_PRECISION + this in Short.MIN_VALUE.toFloat()..Short.MAX_VALUE.toFloat() -> toInt().toShort() + else -> throw NUMERIC_OVERFLOW + } + + /** + * Performs a checked conversion from [Double] to [Short]. + * + * @return Returns a [Short] representation of the specified [Double]. + * @throws IllegalTypeConversionException if the value cannot be safely converted to [Short]. + */ + private fun Double.toShortChecked(): Short = when { + !isInteger() -> throw NUMERIC_LOSS_OF_PRECISION + this in Short.MIN_VALUE.toDouble()..Short.MAX_VALUE.toDouble() -> toInt().toShort() + else -> throw NUMERIC_OVERFLOW + } + + /** + * Performs a checked conversion from [BigDecimal] to [Short]. + * + * @return Returns a [Short] representation of the specified [BigDecimal]. + * @throws IllegalTypeConversionException if the value cannot be safely converted to [Short]. + */ + private fun BigDecimal.toShortChecked(): Short = when { + !isInteger() -> throw NUMERIC_LOSS_OF_PRECISION + this in Short.MIN_VALUE.toBigDecimal()..Short.MAX_VALUE.toBigDecimal() -> toShort() + else -> throw NUMERIC_OVERFLOW + } +} diff --git a/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/StringTypeConverter.kt b/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/StringTypeConverter.kt new file mode 100644 index 0000000..db1a9a2 --- /dev/null +++ b/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/StringTypeConverter.kt @@ -0,0 +1,35 @@ +/** + * Copyright 2020 Matthew Layton + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.onixlabs.kotlin.core.typeconverters + +/** + * Provides a mechanism to safely convert the specified value value to the [String] type. + */ +class StringTypeConverter : TypeConverter() { + + /** + * Converts the specified value to the [String] type. + * + * @param value The value to convert. + * @return Returns a [String] representation of the specified value. + */ + override fun convert(value: Any): String = when (value) { + // TODO : [Kotlin 1.3] Push values to TRUE_STRING and FALSE_STRING in Boolean.Companion + is Boolean -> if (value) "True" else "False" + else -> value.toString() + } +} diff --git a/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/TypeConverter.kt b/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/TypeConverter.kt new file mode 100644 index 0000000..10e45fb --- /dev/null +++ b/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/TypeConverter.kt @@ -0,0 +1,33 @@ +/** + * Copyright 2020 Matthew Layton + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.onixlabs.kotlin.core.typeconverters + +/** + * Represents the base class for implementing type converters. + * + * @param T The underlying type that the type converter will convert to. + */ +abstract class TypeConverter { + + /** + * Converts the specified value to the [T] type. + * + * @param value The value to convert. + * @return Returns a [T] representation of the specified value. + */ + abstract fun convert(value: Any): T +} diff --git a/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/UUIDTypeConverter.kt b/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/UUIDTypeConverter.kt new file mode 100644 index 0000000..66257bf --- /dev/null +++ b/src/main/kotlin/io/onixlabs/kotlin/core/typeconverters/UUIDTypeConverter.kt @@ -0,0 +1,50 @@ +/** + * Copyright 2020 Matthew Layton + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.onixlabs.kotlin.core.typeconverters + +import io.onixlabs.kotlin.core.reflection.kotlinClass +import java.util.* + +/** + * Provides a mechanism to safely convert the specified value value to the [UUID] type. + */ +class UUIDTypeConverter : TypeConverter() { + + /** + * Converts the specified value to the [UUID] type. + * + * @param value The value to convert. + * @return Returns a [UUID] representation of the specified value. + */ + override fun convert(value: Any): UUID = when (value) { + is String -> value.toUUIDChecked() + is UUID -> value + else -> throw IllegalTypeConversionException(value.kotlinClass, UUID::class) + } + + /** + * Performs a checked conversion from [String] to [UUID]. + * + * @return Returns a [UUID] representation of the specified [String]. + * @throws IllegalTypeConversionException if the value cannot be safely converted to [UUID]. + */ + private fun String.toUUIDChecked(): UUID = try { + UUID.fromString(this) + } catch (ex: IllegalArgumentException) { + throw IllegalTypeConversionException("Illegal type conversion. ${ex.message}.") + } +} diff --git a/src/test/kotlin/io/onixlabs/kotlin/core/reflection/KTypeExtensionTests.kt b/src/test/kotlin/io/onixlabs/kotlin/core/reflection/KTypeExtensionTests.kt index ee70320..95485d9 100644 --- a/src/test/kotlin/io/onixlabs/kotlin/core/reflection/KTypeExtensionTests.kt +++ b/src/test/kotlin/io/onixlabs/kotlin/core/reflection/KTypeExtensionTests.kt @@ -32,7 +32,7 @@ class KTypeExtensionTests { val type = UUID::class.createType(nullable = false) // Act - val name = type.name + val name = type.formattedSimpleName // Assert assertEquals("UUID", name) @@ -45,7 +45,7 @@ class KTypeExtensionTests { val type = UUID::class.createType(nullable = true) // Act - val name = type.name + val name = type.formattedSimpleName // Assert assertEquals("UUID?", name) @@ -59,7 +59,7 @@ class KTypeExtensionTests { val type = ArrayList::class.createType(arguments = arguments, nullable = false) // Act - val name = type.name + val name = type.formattedSimpleName // Assert assertEquals("ArrayList", name) @@ -73,7 +73,7 @@ class KTypeExtensionTests { val type = ArrayList::class.createType(arguments = arguments, nullable = false) // Act - val name = type.name + val name = type.formattedSimpleName // Assert assertEquals("ArrayList", name) @@ -87,7 +87,7 @@ class KTypeExtensionTests { val type = ArrayList::class.createType(arguments = arguments, nullable = true) // Act - val name = type.name + val name = type.formattedSimpleName // Assert assertEquals("ArrayList?", name) @@ -101,7 +101,7 @@ class KTypeExtensionTests { val type = ArrayList::class.createType(arguments = arguments, nullable = true) // Act - val name = type.name + val name = type.formattedSimpleName // Assert assertEquals("ArrayList?", name) @@ -119,7 +119,7 @@ class KTypeExtensionTests { val type = Map::class.createType(arguments = arguments, nullable = false) // Act - val name = type.name + val name = type.formattedSimpleName // Assert assertEquals("Map", name) @@ -137,7 +137,7 @@ class KTypeExtensionTests { val type = Map::class.createType(arguments = arguments, nullable = false) // Act - val name = type.name + val name = type.formattedSimpleName // Assert assertEquals("Map", name) @@ -155,7 +155,7 @@ class KTypeExtensionTests { val type = Map::class.createType(arguments = arguments, nullable = true) // Act - val name = type.name + val name = type.formattedSimpleName // Assert assertEquals("Map?", name) @@ -173,7 +173,7 @@ class KTypeExtensionTests { val type = Map::class.createType(arguments = arguments, nullable = true) // Act - val name = type.name + val name = type.formattedSimpleName // Assert assertEquals("Map?", name) @@ -187,7 +187,7 @@ class KTypeExtensionTests { val type = ArrayList::class.createType(arguments = arguments, nullable = false) // Act - val name = type.name + val name = type.formattedSimpleName // Assert //fail(type.arguments.joinToString()) @@ -202,7 +202,7 @@ class KTypeExtensionTests { val type = ArrayList::class.createType(arguments = arguments, nullable = true) // Act - val name = type.name + val name = type.formattedSimpleName // Assert //fail(type.arguments.joinToString()) @@ -216,7 +216,7 @@ class KTypeExtensionTests { val type = UUID::class.createType(nullable = false) // Act - val name = type.fullName + val name = type.formattedQualifiedName // Assert assertEquals("java.util.UUID", name) @@ -229,7 +229,7 @@ class KTypeExtensionTests { val type = UUID::class.createType(nullable = true) // Act - val name = type.fullName + val name = type.formattedQualifiedName // Assert assertEquals("java.util.UUID?", name) @@ -243,7 +243,7 @@ class KTypeExtensionTests { val type = ArrayList::class.createType(arguments = arguments, nullable = false) // Act - val name = type.fullName + val name = type.formattedQualifiedName // Assert assertEquals("java.util.ArrayList", name) @@ -257,7 +257,7 @@ class KTypeExtensionTests { val type = ArrayList::class.createType(arguments = arguments, nullable = false) // Act - val name = type.fullName + val name = type.formattedQualifiedName // Assert assertEquals("java.util.ArrayList", name) @@ -271,7 +271,7 @@ class KTypeExtensionTests { val type = ArrayList::class.createType(arguments = arguments, nullable = true) // Act - val name = type.fullName + val name = type.formattedQualifiedName // Assert assertEquals("java.util.ArrayList?", name) @@ -285,7 +285,7 @@ class KTypeExtensionTests { val type = ArrayList::class.createType(arguments = arguments, nullable = true) // Act - val name = type.fullName + val name = type.formattedQualifiedName // Assert assertEquals("java.util.ArrayList?", name) @@ -303,7 +303,7 @@ class KTypeExtensionTests { val type = Map::class.createType(arguments = arguments, nullable = false) // Act - val name = type.fullName + val name = type.formattedQualifiedName // Assert assertEquals("kotlin.collections.Map", name) @@ -321,7 +321,7 @@ class KTypeExtensionTests { val type = Map::class.createType(arguments = arguments, nullable = false) // Act - val name = type.fullName + val name = type.formattedQualifiedName // Assert assertEquals("kotlin.collections.Map", name) @@ -339,7 +339,7 @@ class KTypeExtensionTests { val type = Map::class.createType(arguments = arguments, nullable = true) // Act - val name = type.fullName + val name = type.formattedQualifiedName // Assert assertEquals("kotlin.collections.Map?", name) @@ -357,7 +357,7 @@ class KTypeExtensionTests { val type = Map::class.createType(arguments = arguments, nullable = true) // Act - val name = type.fullName + val name = type.formattedQualifiedName // Assert assertEquals("kotlin.collections.Map?", name) @@ -371,7 +371,7 @@ class KTypeExtensionTests { val type = ArrayList::class.createType(arguments = arguments, nullable = false) // Act - val name = type.fullName + val name = type.formattedQualifiedName // Assert assertEquals("java.util.ArrayList<*>", name) @@ -385,7 +385,7 @@ class KTypeExtensionTests { val type = ArrayList::class.createType(arguments = arguments, nullable = true) // Act - val name = type.fullName + val name = type.formattedQualifiedName // Assert assertEquals("java.util.ArrayList<*>?", name) diff --git a/src/test/kotlin/io/onixlabs/kotlin/core/typeconverters/BigDecimalTypeConverterTests.kt b/src/test/kotlin/io/onixlabs/kotlin/core/typeconverters/BigDecimalTypeConverterTests.kt new file mode 100644 index 0000000..b4daf7e --- /dev/null +++ b/src/test/kotlin/io/onixlabs/kotlin/core/typeconverters/BigDecimalTypeConverterTests.kt @@ -0,0 +1,185 @@ +package io.onixlabs.kotlin.core.typeconverters + +import io.onixlabs.kotlin.core.ONE +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import java.math.BigDecimal +import java.math.BigInteger +import java.util.* + +class BigDecimalTypeConverterTests { + + @Test + fun `BigDecimalTypeConverter should return ONE when Boolean is true`() { + + // Arrange + val value = true + val converter = BigDecimalTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(BigDecimal.ONE, result) + } + + @Test + fun `BigDecimalTypeConverter should return ZERO when Boolean is false`() { + + // Arrange + val value = false + val converter = BigDecimalTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(BigDecimal.ZERO, result) + } + + @Test + fun `BigDecimalTypeConverter should return the expected value for a Byte`() { + + // Arrange + val value = Byte.ONE + val converter = BigDecimalTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(BigDecimal.ONE, result) + } + + @Test + fun `BigDecimalTypeConverter should return the expected value for a Short`() { + + // Arrange + val value = Short.ONE + val converter = BigDecimalTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(BigDecimal.ONE, result) + } + + @Test + fun `BigDecimalTypeConverter should return the expected value for an Int`() { + + // Arrange + val value = Int.ONE + val converter = BigDecimalTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(BigDecimal.ONE, result) + } + + @Test + fun `BigDecimalTypeConverter should return the expected value for a Long`() { + + // Arrange + val value = Long.ONE + val converter = BigDecimalTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(BigDecimal.ONE, result) + } + + @Test + fun `BigDecimalTypeConverter should return the expected value for a BigInteger`() { + + // Arrange + val value = BigInteger.ONE + val converter = BigDecimalTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(BigDecimal.ONE, result) + } + + @Test + fun `BigDecimalTypeConverter should return the expected value for a Double`() { + + // Arrange + val value = Double.ONE + val converter = BigDecimalTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Double.ONE.toBigDecimal(), result) + } + + @Test + fun `BigDecimalTypeConverter should return the expected value for a BigDecimal`() { + + // Arrange + val value = BigDecimal.ONE + val converter = BigDecimalTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(BigDecimal.ONE, result) + } + + @Test + fun `BigDecimalTypeConverter should return the expected value for a String`() { + + // Arrange + val value = "123.456" + val converter = BigDecimalTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals((123.456).toBigDecimal(), result) + } + + @Test + fun `BigDecimalTypeConverter should return the expected value for a Char`() { + + // Arrange + val value = ' ' + val converter = BigDecimalTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(32.toBigDecimal(), result) + } + + @Test + fun `BigDecimalTypeConverter should throw an exception for an unsupported type`() { + + // Arrange + val value = UUID.randomUUID() + val converter = BigDecimalTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals( + "Illegal type conversion. Cannot convert from 'java.util.UUID' to 'java.math.BigDecimal'.", + result.message + ) + } +} diff --git a/src/test/kotlin/io/onixlabs/kotlin/core/typeconverters/BigIntegerTypeConverterTests.kt b/src/test/kotlin/io/onixlabs/kotlin/core/typeconverters/BigIntegerTypeConverterTests.kt new file mode 100644 index 0000000..7f433cc --- /dev/null +++ b/src/test/kotlin/io/onixlabs/kotlin/core/typeconverters/BigIntegerTypeConverterTests.kt @@ -0,0 +1,247 @@ +package io.onixlabs.kotlin.core.typeconverters + +import io.onixlabs.kotlin.core.ONE +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import java.math.BigDecimal +import java.math.BigInteger +import java.util.* + +class BigIntegerTypeConverterTests { + + @Test + fun `BigIntegerTypeConverter should return ONE when Boolean is true`() { + + // Arrange + val value = true + val converter = BigIntegerTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(BigInteger.ONE, result) + } + + @Test + fun `BigIntegerTypeConverter should return ZERO when Boolean is false`() { + + // Arrange + val value = false + val converter = BigIntegerTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(BigInteger.ZERO, result) + } + + @Test + fun `BigIntegerTypeConverter should return the expected value for a Byte`() { + + // Arrange + val value = Byte.ONE + val converter = BigIntegerTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(BigInteger.ONE, result) + } + + @Test + fun `BigIntegerTypeConverter should return the expected value for a Short`() { + + // Arrange + val value = Short.ONE + val converter = BigIntegerTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(BigInteger.ONE, result) + } + + @Test + fun `BigIntegerTypeConverter should return the expected value for an Int`() { + + // Arrange + val value = Int.ONE + val converter = BigIntegerTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(BigInteger.ONE, result) + } + + @Test + fun `BigIntegerTypeConverter should return the expected value for a Long`() { + + // Arrange + val value = Long.ONE + val converter = BigIntegerTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(BigInteger.ONE, result) + } + + @Test + fun `BigIntegerTypeConverter should return the expected value for a BigInteger`() { + + // Arrange + val value = BigInteger.ONE + val converter = BigIntegerTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(BigInteger.ONE, result) + } + + @Test + fun `BigIntegerTypeConverter should return the expected value for a Float`() { + + // Arrange + val value = Float.ONE + val converter = BigIntegerTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(BigInteger.ONE, result) + } + + @Test + fun `BigIntegerTypeConverter should throw an exception when a Float loses precision`() { + + // Arrange + val value = 123.456F + val converter = BigIntegerTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Loss of precision.", result.message) + } + + @Test + fun `BigIntegerTypeConverter should return the expected value for a Double`() { + + // Arrange + val value = Double.ONE + val converter = BigIntegerTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(BigInteger.ONE, result) + } + + @Test + fun `BigIntegerTypeConverter should throw an exception when a Double loses precision`() { + + // Arrange + val value = 123.456 + val converter = BigIntegerTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Loss of precision.", result.message) + } + + @Test + fun `BigIntegerTypeConverter should return the expected value for a BigDecimal`() { + + // Arrange + val value = BigDecimal.ONE + val converter = BigIntegerTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(BigInteger.ONE, result) + } + + @Test + fun `BigIntegerTypeConverter should throw an exception when a BigDecimal loses precision`() { + + // Arrange + val value = (123.456).toBigDecimal() + val converter = BigIntegerTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Loss of precision.", result.message) + } + + @Test + fun `BigIntegerTypeConverter should return the expected value for a String`() { + + // Arrange + val value = "1" + val converter = BigIntegerTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(BigInteger.ONE, result) + } + + @Test + fun `BigIntegerTypeConverter should return the expected value for a Char`() { + + // Arrange + val value = ' ' + val converter = BigIntegerTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(32.toBigInteger(), result) + } + + @Test + fun `BigIntegerTypeConverter should throw an exception for an unsupported type`() { + + // Arrange + val value = UUID.randomUUID() + val converter = BigIntegerTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals( + "Illegal type conversion. Cannot convert from 'java.util.UUID' to 'java.math.BigInteger'.", + result.message + ) + } +} diff --git a/src/test/kotlin/io/onixlabs/kotlin/core/typeconverters/BooleanTypeConverterTests.kt b/src/test/kotlin/io/onixlabs/kotlin/core/typeconverters/BooleanTypeConverterTests.kt new file mode 100644 index 0000000..526e6db --- /dev/null +++ b/src/test/kotlin/io/onixlabs/kotlin/core/typeconverters/BooleanTypeConverterTests.kt @@ -0,0 +1,142 @@ +package io.onixlabs.kotlin.core.typeconverters + +import io.onixlabs.kotlin.core.ONE +import io.onixlabs.kotlin.core.ZERO +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import java.util.* + +class BooleanTypeConverterTests { + + @Test + fun `BooleanTypeConverter should return the expected value for a Boolean value true`() { + + // Arrange + val value = true + val converter = BooleanTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertTrue(result) + } + + @Test + fun `BooleanTypeConverter should return the expected value for a Boolean value false`() { + + // Arrange + val value = false + val converter = BooleanTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertFalse(result) + } + + @Test + fun `BooleanTypeConverter should return the expected value for a Numeric value ONE`() { + + // Arrange + val value = Int.ONE + val converter = BooleanTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertTrue(result) + } + + @Test + fun `BooleanTypeConverter should return the expected value for a Numeric value ZERO`() { + + // Arrange + val value = Int.ZERO + val converter = BooleanTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertFalse(result) + } + + @Test + fun `BooleanTypeConverter should return the expected value for a String value true`() { + + // Arrange + val value = "true" + val converter = BooleanTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertTrue(result) + } + + @Test + fun `BooleanTypeConverter should return the expected value for a String value false`() { + + // Arrange + val value = "false" + val converter = BooleanTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertFalse(result) + } + + @Test + fun `BooleanTypeConverter should return the expected value for a Char value Y`() { + + // Arrange + val value = 'Y' + val converter = BooleanTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertTrue(result) + } + + @Test + fun `BooleanTypeConverter should return the expected value for a Char value N`() { + + // Arrange + val value = 'N' + val converter = BooleanTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertFalse(result) + } + + @Test + fun `BooleanTypeConverter should throw an exception for an unsupported type`() { + + // Arrange + val value = UUID.randomUUID() + val converter = BooleanTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals( + "Illegal type conversion. Cannot convert from 'java.util.UUID' to 'kotlin.Boolean'.", + result.message + ) + } +} diff --git a/src/test/kotlin/io/onixlabs/kotlin/core/typeconverters/ByteTypeConverterTests.kt b/src/test/kotlin/io/onixlabs/kotlin/core/typeconverters/ByteTypeConverterTests.kt new file mode 100644 index 0000000..808d2f0 --- /dev/null +++ b/src/test/kotlin/io/onixlabs/kotlin/core/typeconverters/ByteTypeConverterTests.kt @@ -0,0 +1,373 @@ +package io.onixlabs.kotlin.core.typeconverters + +import io.onixlabs.kotlin.core.ONE +import io.onixlabs.kotlin.core.ZERO +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import java.math.BigDecimal +import java.math.BigInteger +import java.util.* + +class ByteTypeConverterTests { + + @Test + fun `ByteTypeConverter should return ONE when Boolean is true`() { + + // Arrange + val value = true + val converter = ByteTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Byte.ONE, result) + } + + @Test + fun `ByteTypeConverter should return ZERO when Boolean is false`() { + + // Arrange + val value = false + val converter = ByteTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Byte.ZERO, result) + } + + @Test + fun `ByteTypeConverter should return the expected value for a Byte`() { + + // Arrange + val value = Byte.ONE + val converter = ByteTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Byte.ONE, result) + } + + @Test + fun `ByteTypeConverter should return the expected value for a Short`() { + + // Arrange + val value = Short.ONE + val converter = ByteTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Byte.ONE, result) + } + + @Test + fun `ByteTypeConverter should throw an exception when a Short overflows`() { + + // Arrange + val value = Short.MAX_VALUE + val converter = ByteTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Numeric overflow.", result.message) + } + + @Test + fun `ByteTypeConverter should return the expected value for an Int`() { + + // Arrange + val value = Int.ONE + val converter = ByteTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Byte.ONE, result) + } + + @Test + fun `ByteTypeConverter should throw an exception when an Int overflows`() { + + // Arrange + val value = Int.MAX_VALUE + val converter = ByteTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Numeric overflow.", result.message) + } + + @Test + fun `ByteTypeConverter should return the expected value for a Long`() { + + // Arrange + val value = Long.ONE + val converter = ByteTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Byte.ONE, result) + } + + @Test + fun `ByteTypeConverter should throw an exception when a Long overflows`() { + + // Arrange + val value = Long.MAX_VALUE + val converter = ByteTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Numeric overflow.", result.message) + } + + @Test + fun `ByteTypeConverter should return the expected value for a BigInteger`() { + + // Arrange + val value = BigInteger.ONE + val converter = ByteTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Byte.ONE, result) + } + + @Test + fun `ByteTypeConverter should throw an exception when a BigInteger overflows`() { + + // Arrange + val value = Long.MAX_VALUE.toBigInteger() + val converter = ByteTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Numeric overflow.", result.message) + } + + @Test + fun `ByteTypeConverter should return the expected value for a Float`() { + + // Arrange + val value = Float.ONE + val converter = ByteTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Byte.ONE, result) + } + + @Test + fun `ByteTypeConverter should throw an exception when a Float overflows`() { + + // Arrange + val value = Int.MAX_VALUE.toFloat() + val converter = ByteTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Numeric overflow.", result.message) + } + + @Test + fun `ByteTypeConverter should throw an exception when a Float loses precision`() { + + // Arrange + val value = 123.456F + val converter = ByteTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Loss of precision.", result.message) + } + + @Test + fun `ByteTypeConverter should return the expected value for a Double`() { + + // Arrange + val value = Double.ONE + val converter = ByteTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Byte.ONE, result) + } + + @Test + fun `ByteTypeConverter should throw an exception when a Double overflows`() { + + // Arrange + val value = Double.MAX_VALUE + val converter = ByteTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Numeric overflow.", result.message) + } + + @Test + fun `ByteTypeConverter should throw an exception when a Double loses precision`() { + + // Arrange + val value = 123.456 + val converter = ByteTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Loss of precision.", result.message) + } + + @Test + fun `ByteTypeConverter should return the expected value for a BigDecimal`() { + + // Arrange + val value = BigDecimal.ONE + val converter = ByteTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Byte.ONE, result) + } + + @Test + fun `ByteTypeConverter should throw an exception when a BigDecimal overflows`() { + + // Arrange + val value = Long.MAX_VALUE.toBigDecimal() + val converter = ByteTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Numeric overflow.", result.message) + } + + @Test + fun `ByteTypeConverter should throw an exception when a BigDecimal loses precision`() { + + // Arrange + val value = (123.456).toBigDecimal() + val converter = ByteTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Loss of precision.", result.message) + } + + @Test + fun `ByteTypeConverter should return the expected value for a String`() { + + // Arrange + val value = "1" + val converter = ByteTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Byte.ONE, result) + } + + @Test + fun `ByteTypeConverter should return the expected value for a Char`() { + + // Arrange + val value = ' ' + val converter = ByteTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(32.toByte(), result) + } + + @Test + fun `ByteTypeConverter should throw an exception when a Char overflows`() { + + // Arrange + val value = '\u1255' + val converter = ByteTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Numeric overflow.", result.message) + } + + @Test + fun `ByteTypeConverter should throw an exception for an unsupported type`() { + + // Arrange + val value = UUID.randomUUID() + val converter = ByteTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Cannot convert from 'java.util.UUID' to 'kotlin.Byte'.", result.message) + } +} diff --git a/src/test/kotlin/io/onixlabs/kotlin/core/typeconverters/CharTypeConverterTests.kt b/src/test/kotlin/io/onixlabs/kotlin/core/typeconverters/CharTypeConverterTests.kt new file mode 100644 index 0000000..bc283a1 --- /dev/null +++ b/src/test/kotlin/io/onixlabs/kotlin/core/typeconverters/CharTypeConverterTests.kt @@ -0,0 +1,353 @@ +package io.onixlabs.kotlin.core.typeconverters + +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import java.util.* + +class CharTypeConverterTests { + + @Test + fun `CharTypeConverter should return ONE when Boolean is true`() { + + // Arrange + val value = true + val converter = CharTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals('1', result) + } + + @Test + fun `CharTypeConverter should return ZERO when Boolean is false`() { + + // Arrange + val value = false + val converter = CharTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals('0', result) + } + + @Test + fun `CharTypeConverter should return the expected value for a Byte`() { + + // Arrange + val value = 32.toByte() + val converter = CharTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(' ', result) + } + + @Test + fun `CharTypeConverter should return the expected value for a Short`() { + + // Arrange + val value = 32.toShort() + val converter = CharTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(' ', result) + } + + @Test + fun `CharTypeConverter should return the expected value for an Int`() { + + // Arrange + val value = 32 + val converter = CharTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(' ', result) + } + + @Test + fun `CharTypeConverter should throw an exception when an Int overflows`() { + + // Arrange + val value = Int.MAX_VALUE + val converter = CharTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Numeric overflow.", result.message) + } + + @Test + fun `CharTypeConverter should return the expected value for a Long`() { + + // Arrange + val value = 32.toLong() + val converter = CharTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(' ', result) + } + + @Test + fun `CharTypeConverter should throw an exception when an Long overflows`() { + + // Arrange + val value = Long.MAX_VALUE + val converter = CharTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Numeric overflow.", result.message) + } + + @Test + fun `CharTypeConverter should return the expected value for a BigInteger`() { + + // Arrange + val value = 32.toBigInteger() + val converter = CharTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(' ', result) + } + + @Test + fun `CharTypeConverter should throw an exception when a BigInteger overflows`() { + + // Arrange + val value = Long.MAX_VALUE.toBigInteger() + val converter = CharTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Numeric overflow.", result.message) + } + + @Test + fun `CharTypeConverter should return the expected value for a Float`() { + + // Arrange + val value = 32.toFloat() + val converter = CharTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(' ', result) + } + + @Test + fun `CharTypeConverter should throw an exception when a Float overflows`() { + + // Arrange + val value = Float.MAX_VALUE + val converter = CharTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Numeric overflow.", result.message) + } + + @Test + fun `CharTypeConverter should throw an exception when a Float loses precision`() { + + // Arrange + val value = 123.456F + val converter = CharTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Loss of precision.", result.message) + } + + @Test + fun `CharTypeConverter should return the expected value for a Double`() { + + // Arrange + val value = 32.toDouble() + val converter = CharTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(' ', result) + } + + @Test + fun `CharTypeConverter should throw an exception when a Double overflows`() { + + // Arrange + val value = Double.MAX_VALUE + val converter = CharTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Numeric overflow.", result.message) + } + + @Test + fun `CharTypeConverter should throw an exception when a Double loses precision`() { + + // Arrange + val value = 123.456 + val converter = CharTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Loss of precision.", result.message) + } + + @Test + fun `CharTypeConverter should return the expected value for a BigDecimal`() { + + // Arrange + val value = 32.toBigDecimal() + val converter = CharTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(' ', result) + } + + @Test + fun `CharTypeConverter should throw an exception when a BigDecimal overflows`() { + + // Arrange + val value = Double.MAX_VALUE.toBigDecimal() + val converter = CharTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Numeric overflow.", result.message) + } + + @Test + fun `CharTypeConverter should throw an exception when a BigDecimal loses precision`() { + + // Arrange + val value = (123.456).toBigDecimal() + val converter = CharTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Loss of precision.", result.message) + } + + @Test + fun `CharTypeConverter should return the expected value for a String`() { + + // Arrange + val value = " " + val converter = CharTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(' ', result) + } + + @Test + fun `CharTypeConverter should throw an exception when a String contains more than a single Char`() { + + // Arrange + val value = "ab" + val converter = CharTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. String value cannot be converted to Char.", result.message) + } + + @Test + fun `CharTypeConverter should return the expected value for a Char`() { + + // Arrange + val value = ' ' + val converter = CharTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(' ', result) + } + + @Test + fun `CharTypeConverter should throw an exception for an unsupported type`() { + + // Arrange + val value = UUID.randomUUID() + val converter = CharTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Cannot convert from 'java.util.UUID' to 'kotlin.Char'.", result.message) + } +} diff --git a/src/test/kotlin/io/onixlabs/kotlin/core/typeconverters/DoubleTypeConverterTests.kt b/src/test/kotlin/io/onixlabs/kotlin/core/typeconverters/DoubleTypeConverterTests.kt new file mode 100644 index 0000000..5c21aea --- /dev/null +++ b/src/test/kotlin/io/onixlabs/kotlin/core/typeconverters/DoubleTypeConverterTests.kt @@ -0,0 +1,187 @@ +package io.onixlabs.kotlin.core.typeconverters + +import io.onixlabs.kotlin.core.ONE +import io.onixlabs.kotlin.core.ZERO +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import java.math.BigInteger +import java.util.* + +class DoubleTypeConverterTests { + + @Test + fun `DoubleTypeConverter should return ONE when Boolean is true`() { + + // Arrange + val value = true + val converter = DoubleTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Double.ONE, result) + } + + @Test + fun `DoubleTypeConverter should return ZERO when Boolean is false`() { + + // Arrange + val value = false + val converter = DoubleTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Double.ZERO, result) + } + + @Test + fun `DoubleTypeConverter should return the expected value for a Byte`() { + + // Arrange + val value = Byte.ONE + val converter = DoubleTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Double.ONE, result) + } + + @Test + fun `DoubleTypeConverter should return the expected value for a Short`() { + + // Arrange + val value = Short.ONE + val converter = DoubleTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Double.ONE, result) + } + + @Test + fun `DoubleTypeConverter should return the expected value for an Int`() { + + // Arrange + val value = Int.ONE + val converter = DoubleTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Double.ONE, result) + } + + @Test + fun `DoubleTypeConverter should return the expected value for a Long`() { + + // Arrange + val value = Long.ONE + val converter = DoubleTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Double.ONE, result) + } + + @Test + fun `DoubleTypeConverter should return the expected value for a BigInteger`() { + + // Arrange + val value = BigInteger.ONE + val converter = DoubleTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Double.ONE, result) + } + + @Test + fun `DoubleTypeConverter should throw an exception when a BigInteger overflows`() { + + // Arrange + val value = Long.MAX_VALUE.toBigInteger().pow(2) + val converter = DoubleTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Numeric overflow.", result.message) + } + + @Test + fun `DoubleTypeConverter should return the expected value for a Double`() { + + // Arrange + val value = Double.ONE + val converter = DoubleTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Double.ONE, result) + } + + @Test + fun `DoubleTypeConverter should return the expected value for a String`() { + + // Arrange + val value = "1" + val converter = DoubleTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Double.ONE, result) + } + + @Test + fun `DoubleTypeConverter should return the expected value for a Char`() { + + // Arrange + val value = ' ' + val converter = DoubleTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(32.0, result) + } + + @Test + fun `DoubleTypeConverter should throw an exception for an unsupported type`() { + + // Arrange + val value = UUID.randomUUID() + val converter = DoubleTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals( + "Illegal type conversion. Cannot convert from 'java.util.UUID' to 'kotlin.Double'.", + result.message + ) + } +} diff --git a/src/test/kotlin/io/onixlabs/kotlin/core/typeconverters/FloatTypeConverterTests.kt b/src/test/kotlin/io/onixlabs/kotlin/core/typeconverters/FloatTypeConverterTests.kt new file mode 100644 index 0000000..d4da152 --- /dev/null +++ b/src/test/kotlin/io/onixlabs/kotlin/core/typeconverters/FloatTypeConverterTests.kt @@ -0,0 +1,139 @@ +package io.onixlabs.kotlin.core.typeconverters + +import io.onixlabs.kotlin.core.ONE +import io.onixlabs.kotlin.core.ZERO +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import java.util.* + +class FloatTypeConverterTests { + + @Test + fun `FloatTypeConverter should return ONE when Boolean is true`() { + + // Arrange + val value = true + val converter = FloatTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Float.ONE, result) + } + + @Test + fun `FloatTypeConverter should return ZERO when Boolean is false`() { + + // Arrange + val value = false + val converter = FloatTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Float.ZERO, result) + } + + @Test + fun `FloatTypeConverter should return the expected value for a Byte`() { + + // Arrange + val value = Byte.ONE + val converter = FloatTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Float.ONE, result) + } + + @Test + fun `FloatTypeConverter should return the expected value for a Short`() { + + // Arrange + val value = Short.ONE + val converter = FloatTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Float.ONE, result) + } + + @Test + fun `FloatTypeConverter should return the expected value for an Int`() { + + // Arrange + val value = Int.ONE + val converter = FloatTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Float.ONE, result) + } + + @Test + fun `FloatTypeConverter should return the expected value for a Float`() { + + // Arrange + val value = Float.ONE + val converter = FloatTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Float.ONE, result) + } + + @Test + fun `FloatTypeConverter should return the expected value for a String`() { + + // Arrange + val value = "1" + val converter = FloatTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Float.ONE, result) + } + + @Test + fun `FloatTypeConverter should return the expected value for a Char`() { + + // Arrange + val value = ' ' + val converter = FloatTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(32.0F, result) + } + + @Test + fun `FloatTypeConverter should throw an exception for an unsupported type`() { + + // Arrange + val value = UUID.randomUUID() + val converter = FloatTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Cannot convert from 'java.util.UUID' to 'kotlin.Float'.", result.message) + } +} diff --git a/src/test/kotlin/io/onixlabs/kotlin/core/typeconverters/IntTypeConverterTests.kt b/src/test/kotlin/io/onixlabs/kotlin/core/typeconverters/IntTypeConverterTests.kt new file mode 100644 index 0000000..46fdbd4 --- /dev/null +++ b/src/test/kotlin/io/onixlabs/kotlin/core/typeconverters/IntTypeConverterTests.kt @@ -0,0 +1,325 @@ +package io.onixlabs.kotlin.core.typeconverters + +import io.onixlabs.kotlin.core.ONE +import io.onixlabs.kotlin.core.ZERO +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import java.math.BigDecimal +import java.math.BigInteger +import java.util.* + +class IntTypeConverterTests { + + @Test + fun `IntTypeConverter should return ONE when Boolean is true`() { + + // Arrange + val value = true + val converter = IntTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Int.ONE, result) + } + + @Test + fun `IntTypeConverter should return ZERO when Boolean is false`() { + + // Arrange + val value = false + val converter = IntTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Int.ZERO, result) + } + + @Test + fun `IntTypeConverter should return the expected value for a Byte`() { + + // Arrange + val value = Byte.ONE + val converter = IntTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Int.ONE, result) + } + + @Test + fun `IntTypeConverter should return the expected value for a Short`() { + + // Arrange + val value = Short.ONE + val converter = IntTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Int.ONE, result) + } + + @Test + fun `IntTypeConverter should return the expected value for an Int`() { + + // Arrange + val value = Int.ONE + val converter = IntTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Int.ONE, result) + } + + @Test + fun `IntTypeConverter should return the expected value for a Long`() { + + // Arrange + val value = Long.ONE + val converter = IntTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Int.ONE, result) + } + + @Test + fun `IntTypeConverter should throw an exception when a Long overflows`() { + + // Arrange + val value = Long.MAX_VALUE + val converter = IntTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Numeric overflow.", result.message) + } + + @Test + fun `IntTypeConverter should return the expected value for a BigInteger`() { + + // Arrange + val value = BigInteger.ONE + val converter = IntTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Int.ONE, result) + } + + @Test + fun `IntTypeConverter should throw an exception when a BigInteger overflows`() { + + // Arrange + val value = Long.MAX_VALUE.toBigInteger() + val converter = IntTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Numeric overflow.", result.message) + } + + @Test + fun `IntTypeConverter should return the expected value for a Float`() { + + // Arrange + val value = Float.ONE + val converter = IntTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Int.ONE, result) + } + + @Test + fun `IntTypeConverter should throw an exception when a Float overflows`() { + + // Arrange + val value = Float.MAX_VALUE + val converter = IntTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Numeric overflow.", result.message) + } + + @Test + fun `IntTypeConverter should throw an exception when a Float loses precision`() { + + // Arrange + val value = 123.456F + val converter = IntTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Loss of precision.", result.message) + } + + @Test + fun `IntTypeConverter should return the expected value for a Double`() { + + // Arrange + val value = Double.ONE + val converter = IntTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Int.ONE, result) + } + + @Test + fun `IntTypeConverter should throw an exception when a Double overflows`() { + + // Arrange + val value = Long.MAX_VALUE.toDouble() + val converter = IntTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Numeric overflow.", result.message) + } + + @Test + fun `IntTypeConverter should throw an exception when a Double loses precision`() { + + // Arrange + val value = 123.456 + val converter = IntTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Loss of precision.", result.message) + } + + @Test + fun `IntTypeConverter should return the expected value for a BigDecimal`() { + + // Arrange + val value = BigDecimal.ONE + val converter = IntTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Int.ONE, result) + } + + @Test + fun `IntTypeConverter should throw an exception when a BigDecimal overflows`() { + + // Arrange + val value = Long.MAX_VALUE.toBigDecimal() + val converter = IntTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Numeric overflow.", result.message) + } + + @Test + fun `IntTypeConverter should throw an exception when a BigDecimal loses precision`() { + + // Arrange + val value = (123.456).toBigDecimal() + val converter = IntTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Loss of precision.", result.message) + } + + @Test + fun `IntTypeConverter should return the expected value for a String`() { + + // Arrange + val value = "1" + val converter = IntTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Int.ONE, result) + } + + @Test + fun `IntTypeConverter should return the expected value for a Char`() { + + // Arrange + val value = ' ' + val converter = IntTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(32, result) + } + + @Test + fun `IntTypeConverter should throw an exception for an unsupported type`() { + + // Arrange + val value = UUID.randomUUID() + val converter = IntTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Cannot convert from 'java.util.UUID' to 'kotlin.Int'.", result.message) + } +} diff --git a/src/test/kotlin/io/onixlabs/kotlin/core/typeconverters/LongTypeConverterTests.kt b/src/test/kotlin/io/onixlabs/kotlin/core/typeconverters/LongTypeConverterTests.kt new file mode 100644 index 0000000..cfddcd6 --- /dev/null +++ b/src/test/kotlin/io/onixlabs/kotlin/core/typeconverters/LongTypeConverterTests.kt @@ -0,0 +1,293 @@ +package io.onixlabs.kotlin.core.typeconverters + +import io.onixlabs.kotlin.core.ONE +import io.onixlabs.kotlin.core.ZERO +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import java.math.BigDecimal +import java.math.BigInteger +import java.util.* + +class LongTypeConverterTests { + + @Test + fun `LongTypeConverter should return ONE when Boolean is true`() { + + // Arrange + val value = true + val converter = LongTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Long.ONE, result) + } + + @Test + fun `LongTypeConverter should return ZERO when Boolean is false`() { + + // Arrange + val value = false + val converter = LongTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Long.ZERO, result) + } + + @Test + fun `LongTypeConverter should return the expected value for a Byte`() { + + // Arrange + val value = Byte.ONE + val converter = LongTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Long.ONE, result) + } + + @Test + fun `LongTypeConverter should return the expected value for a Short`() { + + // Arrange + val value = Short.ONE + val converter = LongTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Long.ONE, result) + } + + @Test + fun `LongTypeConverter should return the expected value for an Int`() { + + // Arrange + val value = Int.ONE + val converter = LongTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Long.ONE, result) + } + + @Test + fun `LongTypeConverter should return the expected value for a Long`() { + + // Arrange + val value = Long.ONE + val converter = LongTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Long.ONE, result) + } + + @Test + fun `LongTypeConverter should return the expected value for a BigInteger`() { + + // Arrange + val value = BigInteger.ONE + val converter = LongTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Long.ONE, result) + } + + @Test + fun `LongTypeConverter should throw an exception when a BigInteger overflows`() { + + // Arrange + val value = Long.MAX_VALUE.toBigInteger().pow(2) + val converter = LongTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Numeric overflow.", result.message) + } + + @Test + fun `LongTypeConverter should return the expected value for a Float`() { + + // Arrange + val value = Float.ONE + val converter = LongTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Long.ONE, result) + } + + @Test + fun `LongTypeConverter should throw an exception when a Float loses precision`() { + + // Arrange + val value = 123.456F + val converter = LongTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Loss of precision.", result.message) + } + + @Test + fun `LongTypeConverter should return the expected value for a Double`() { + + // Arrange + val value = Double.ONE + val converter = LongTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Long.ONE, result) + } + + @Test + fun `LongTypeConverter should throw an exception when a Double overflows`() { + + // Arrange + val value = Double.MAX_VALUE + val converter = LongTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Numeric overflow.", result.message) + } + + @Test + fun `LongTypeConverter should throw an exception when a Double loses precision`() { + + // Arrange + val value = 123.456 + val converter = LongTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Loss of precision.", result.message) + } + + @Test + fun `LongTypeConverter should return the expected value for a BigDecimal`() { + + // Arrange + val value = BigDecimal.ONE + val converter = LongTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Long.ONE, result) + } + + @Test + fun `LongTypeConverter should throw an exception when a BigDecimal overflows`() { + + // Arrange + val value = Long.MAX_VALUE.toBigDecimal().pow(2) + val converter = LongTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Numeric overflow.", result.message) + } + + @Test + fun `LongTypeConverter should throw an exception when a BigDecimal loses precision`() { + + // Arrange + val value = (123.456).toBigDecimal() + val converter = LongTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Loss of precision.", result.message) + } + + @Test + fun `LongTypeConverter should return the expected value for a String`() { + + // Arrange + val value = "1" + val converter = LongTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Long.ONE, result) + } + + @Test + fun `LongTypeConverter should return the expected value for a Char`() { + + // Arrange + val value = ' ' + val converter = LongTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(32, result) + } + + @Test + fun `LongTypeConverter should throw an exception for an unsupported type`() { + + // Arrange + val value = UUID.randomUUID() + val converter = LongTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Cannot convert from 'java.util.UUID' to 'kotlin.Long'.", result.message) + } +} diff --git a/src/test/kotlin/io/onixlabs/kotlin/core/typeconverters/ShortTypeConverterTests.kt b/src/test/kotlin/io/onixlabs/kotlin/core/typeconverters/ShortTypeConverterTests.kt new file mode 100644 index 0000000..1f84a97 --- /dev/null +++ b/src/test/kotlin/io/onixlabs/kotlin/core/typeconverters/ShortTypeConverterTests.kt @@ -0,0 +1,341 @@ +package io.onixlabs.kotlin.core.typeconverters + +import io.onixlabs.kotlin.core.ONE +import io.onixlabs.kotlin.core.ZERO +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import java.math.BigDecimal +import java.math.BigInteger +import java.util.* + +class ShortTypeConverterTests { + + @Test + fun `ShortTypeConverter should return ONE when Boolean is true`() { + + // Arrange + val value = true + val converter = ShortTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Short.ONE, result) + } + + @Test + fun `ShortTypeConverter should return ZERO when Boolean is false`() { + + // Arrange + val value = false + val converter = ShortTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Short.ZERO, result) + } + + @Test + fun `ShortTypeConverter should return the expected value for a Byte`() { + + // Arrange + val value = Byte.ONE + val converter = ShortTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Short.ONE, result) + } + + @Test + fun `ShortTypeConverter should return the expected value for a Short`() { + + // Arrange + val value = Short.ONE + val converter = ShortTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Short.ONE, result) + } + + @Test + fun `ShortTypeConverter should return the expected value for an Int`() { + + // Arrange + val value = Int.ONE + val converter = ShortTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Short.ONE, result) + } + + @Test + fun `ShortTypeConverter should throw an exception when an Int overflows`() { + + // Arrange + val value = Int.MAX_VALUE + val converter = ShortTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Numeric overflow.", result.message) + } + + @Test + fun `ShortTypeConverter should return the expected value for a Long`() { + + // Arrange + val value = Long.ONE + val converter = ShortTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Short.ONE, result) + } + + @Test + fun `ShortTypeConverter should throw an exception when a Long overflows`() { + + // Arrange + val value = Long.MAX_VALUE + val converter = ShortTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Numeric overflow.", result.message) + } + + @Test + fun `ShortTypeConverter should return the expected value for a BigInteger`() { + + // Arrange + val value = BigInteger.ONE + val converter = ShortTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Short.ONE, result) + } + + @Test + fun `ShortTypeConverter should throw an exception when a BigInteger overflows`() { + + // Arrange + val value = Long.MAX_VALUE.toBigInteger() + val converter = ShortTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Numeric overflow.", result.message) + } + + @Test + fun `ShortTypeConverter should return the expected value for a Float`() { + + // Arrange + val value = Float.ONE + val converter = ShortTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Short.ONE, result) + } + + @Test + fun `ShortTypeConverter should throw an exception when a Float overflows`() { + + // Arrange + val value = Int.MAX_VALUE.toFloat() + val converter = ShortTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Numeric overflow.", result.message) + } + + @Test + fun `ShortTypeConverter should throw an exception when a Float loses precision`() { + + // Arrange + val value = 123.456F + val converter = ShortTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Loss of precision.", result.message) + } + + @Test + fun `ShortTypeConverter should return the expected value for a Double`() { + + // Arrange + val value = Double.ONE + val converter = ShortTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Short.ONE, result) + } + + @Test + fun `ShortTypeConverter should throw an exception when a Double overflows`() { + + // Arrange + val value = Int.MAX_VALUE.toDouble() + val converter = ShortTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Numeric overflow.", result.message) + } + + @Test + fun `ShortTypeConverter should throw an exception when a Double loses precision`() { + + // Arrange + val value = 123.456 + val converter = ShortTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Loss of precision.", result.message) + } + + @Test + fun `ShortTypeConverter should return the expected value for a BigDecimal`() { + + // Arrange + val value = BigDecimal.ONE + val converter = ShortTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Short.ONE, result) + } + + @Test + fun `ShortTypeConverter should throw an exception when a BigDecimal overflows`() { + + // Arrange + val value = Int.MAX_VALUE.toBigDecimal() + val converter = ShortTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Numeric overflow.", result.message) + } + + @Test + fun `ShortTypeConverter should throw an exception when a BigDecimal loses precision`() { + + // Arrange + val value = (123.456).toBigDecimal() + val converter = ShortTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Loss of precision.", result.message) + } + + @Test + fun `ShortTypeConverter should return the expected value for a String`() { + + // Arrange + val value = "1" + val converter = ShortTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(Short.ONE, result) + } + + @Test + fun `ShortTypeConverter should return the expected value for a Char`() { + + // Arrange + val value = ' ' + val converter = ShortTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(32.toShort(), result) + } + + @Test + fun `ShortTypeConverter should throw an exception for an unsupported type`() { + + // Arrange + val value = UUID.randomUUID() + val converter = ShortTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Cannot convert from 'java.util.UUID' to 'kotlin.Short'.", result.message) + } +} diff --git a/src/test/kotlin/io/onixlabs/kotlin/core/typeconverters/StringTypeConverterTests.kt b/src/test/kotlin/io/onixlabs/kotlin/core/typeconverters/StringTypeConverterTests.kt new file mode 100644 index 0000000..d57cee1 --- /dev/null +++ b/src/test/kotlin/io/onixlabs/kotlin/core/typeconverters/StringTypeConverterTests.kt @@ -0,0 +1,49 @@ +package io.onixlabs.kotlin.core.typeconverters + +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test + +class StringTypeConverterTests { + + @Test + fun `StringTypeConverter should return the expected value for a Boolean value true`() { + + // Arrange + val value = true + val converter = StringTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals("True", result) + } + + @Test + fun `StringTypeConverter should return the expected value for a Boolean value false`() { + + // Arrange + val value = false + val converter = StringTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals("False", result) + } + + @Test + fun `StringTypeConverter should return the string representation of all types other than Boolean`() { + + // Arrange + val value = 123456 + val converter = StringTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals("123456", result) + } +} diff --git a/src/test/kotlin/io/onixlabs/kotlin/core/typeconverters/UUIDTypeConverterTests.kt b/src/test/kotlin/io/onixlabs/kotlin/core/typeconverters/UUIDTypeConverterTests.kt new file mode 100644 index 0000000..d202040 --- /dev/null +++ b/src/test/kotlin/io/onixlabs/kotlin/core/typeconverters/UUIDTypeConverterTests.kt @@ -0,0 +1,54 @@ +package io.onixlabs.kotlin.core.typeconverters + +import io.onixlabs.kotlin.core.ONE +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import java.util.* + +class UUIDTypeConverterTests { + + @Test + fun `UUIDTypeConverter should return the expected value for a String`() { + + // Arrange + val value = "3ab57c8d-ab84-4db0-be2b-db9551dd4af6" + val converter = UUIDTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(4, result.version()) + } + + @Test + fun `UUIDTypeConverter should return the expected value for a UUID`() { + + // Arrange + val value = UUID.fromString("3ab57c8d-ab84-4db0-be2b-db9551dd4af6") + val converter = UUIDTypeConverter() + + // Act + val result = converter.convert(value) + + // Assert + assertEquals(value, result) + } + + @Test + fun `UUIDTypeConverter should throw an exception for an unsupported type`() { + + // Arrange + val value = Int.ONE + val converter = UUIDTypeConverter() + + // Act + val result = assertThrows { + converter.convert(value) + } + + // Assert + assertEquals("Illegal type conversion. Cannot convert from 'kotlin.Int' to 'java.util.UUID'.", result.message) + } +}