Code examples for lotharschulz.info - How to: Nulls and Exceptions in Kotlin from github.com/lotharschulz/kotlin-null
fun reciprocal(i: Int): Double =
when(i == 0){
true -> throw IllegalArgumentException("Can not take reciprocal of 0.")
false -> 1.0 / i
}
@Test(expected = IllegalArgumentException::class)
fun testReciprocalException() {
ExceptionStyle.reciprocal(ZERO_INT)
}
fun parse(): Nothing = throw IllegalArgumentException("Can not parse anything.")
fun reciprocal(): Nothing = throw IllegalArgumentException("Can not take reciprocal of anything.")
@Test(expected = IllegalArgumentException::class)
fun testParse(){
NothingStyle.parse()
}
@Test(expected = IllegalArgumentException::class)
fun testReciprocal(){
NothingStyle.reciprocal()
}
fun callFunction(function: (Int) -> Unit): Unit = (1..2).forEach(function)
fun reciprocal(){}
private val printNumber = { x: Number -> println("Number: $x") }
@Test
fun testCallFunction(){
assertEquals(UnitStyle.callFunction(printNumber), Unit)
}
@Test
fun testReciprocal(){
assertEquals(UnitStyle.reciprocal(), Unit)
}
fun parse(s: String): Any =
when(s.matches(Regex("-?[0-9]+"))){
true -> s.toInt()
false -> NumberFormatException("$s is not a valid integer.")
}
@Test
fun testParse(){
assertEquals(AnyStyle.parse("42"), 42, "42 expected")
assertEquals(
AnyStyle.parse("some string").toString(),
NumberFormatException("some string is not a valid integer.").toString(),
"some string can not be parsed"
)
}
fun parse(s: String): Int? =
when(s.matches(Regex("-?[0-9]+"))){
true -> s.toInt()
false -> null
}
// https://kotlinlang.org/docs/reference/null-safety.html#elvis-operator
@Test
fun testParseElvisOperator(){
val parseResult = NullableStyle.parse("some string") ?: -1
assertEquals(parseResult, -1, "Elvis operator turns it into -1")
}
// https://kotlinlang.org/docs/reference/null-safety.html#the--operator !! - operator
@Test
fun testParseDoubleExclamationOperator(){
val parseResultForSureNotNull = NullableStyle.parse("42")!!.div(42)
assertEquals(parseResultForSureNotNull, 1, "42/42 must be one")
}
data class MyInt(val value: Int)
private lateinit var toBeDefinedInt : MyInt
fun parse(s: String): Int =
when (s.matches(Regex("-?[0-9]+"))) {
true -> s.toInt()
false -> when (this::toBeDefinedInt.isInitialized) {
true -> toBeDefinedInt.value
false -> 79
}
}
@Test
fun testParse() {
assertEquals(LateInitStyle.parse("42"), 42, "42 expected")
assertEquals(LateInitStyle.parse("some string"), 79, "some string shall be parsed to 79.")
}
var toBeDefinedInt : Int by Delegates.notNull()
fun parse(s: String): Int {
toBeDefinedInt = 79
return when(s.matches(Regex("-?[0-9]+"))){
true -> s.toInt()
false -> toBeDefinedInt
}
}
@Test
fun testParse() {
assertEquals(NotNullDelegateStyle.parse("42"), 42, "42 expected")
assertEquals(NotNullDelegateStyle.parse("some string"), 79, "some string shall be parsed to 79.")
}
sealed class ParseResult {
data class IntResult(val value: Int): ParseResult()
data class Exception(val error: String): ParseResult()
}
fun parse(s: String): ParseResult =
when(s.matches(Regex("-?[0-9]+"))){
true -> ParseResult.IntResult(s.toInt())
false -> ParseResult.Exception(NumberFormatException("$s is not a valid integer.").message.toString())
}
@Test
fun testParse(){
assertEquals(SealedStyle.parse("42"), ParseResult.IntResult(42), "42 expected")
assertEquals(SealedStyle.parse("some string"), ParseResult.Exception("some string is not a valid integer."),
"some string can not be parsed")
when(val r = SealedStyle.parse("42")) {
is ParseResult.IntResult -> assertEquals(r.value, 42)
is ParseResult.Exception -> fail(r.error)
}
}
@Nullable
fun parse(s: String): Int? =
when(s.matches(Regex("-?[0-9]+"))){
true -> s.toInt()
false -> null
}
@Test
fun testParse() {
assertEquals(NullableAnnotationStyle.parse("42"), 42, "42 expected")
assertEquals(NullableAnnotationStyle.parse("some string"), null, "some string can not be parsed")
}
fun parse(s: String): Option<Int> =
when(s.matches(Regex("-?[0-9]+"))){
true -> Some(s.toInt())
false -> None
}
fun testParseWithOption() {
assertTrue(OptionStyle.parse("42").isDefined(), "some expceted")
assertEquals(OptionStyle.parse("42"), Some(42), "some containing 42 expceted")
assertTrue(OptionStyle.parse("some string").isEmpty(), "none expected")
assertEquals(OptionStyle.parse("some string"), None, "none expected")
}
fun parse(s: String): Either<NumberFormatException, Int> =
when(s.matches(Regex("-?[0-9]+"))){
true -> Either.Right(s.toInt())
false -> Either.Left(NumberFormatException("$s is not a valid integer."))
}
@Test
fun testParse() {
assertTrue(EitherStyle.parse("42").isRight(), "42 is expected")
// consider ShouldSpec as in https://github.com/BTheunissen/toy-robot-kotlin/blob/master/src/test/kotlin/robot/DirectionSpec.kt @ 2020 09 21
EitherStyle.parse("42").right().shouldBeRight(Right(42))
assertTrue(EitherStyle.parse("some string").isLeft(), "some string can not be parsed")
EitherStyle.parse("some string").left().shouldBeLeft()
}