From cae67c041e5f3589f5ed106324e1973aa25b7e89 Mon Sep 17 00:00:00 2001 From: Patryk Date: Sun, 5 Aug 2018 00:51:01 +0200 Subject: [PATCH] BAEL-1704: Non-Trivial Work in Kotlin vs Java (#4861) * BAEL-1704: Non-Trivial Work in Kotlin vs Java * BAEL-1704: Non-Trivial Work in Kotlin vs Java Renaming one test class --- .../kotlinvsjava/CompanionObjectTest.kt | 21 ++++++ .../baeldung/kotlinvsjava/ConstructorTest.kt | 18 +++++ .../baeldung/kotlinvsjava/DataClassTest.kt | 33 +++++++++ .../baeldung/kotlinvsjava/DelegationTest.kt | 27 +++++++ .../baeldung/kotlinvsjava/ExceptionsTest.kt | 34 +++++++++ .../kotlinvsjava/ExtensionFunctionsTest.kt | 30 ++++++++ .../baeldung/kotlinvsjava/FunctionsTest.kt | 70 +++++++++++++++++++ .../baeldung/kotlinvsjava/IsOperatorTest.kt | 36 ++++++++++ .../baeldung/kotlinvsjava/NullSafetyTest.kt | 67 ++++++++++++++++++ .../kotlinvsjava/OperatorsOverloadingTest.kt | 61 ++++++++++++++++ .../baeldung/kotlinvsjava/PropertiesTest.kt | 32 +++++++++ 11 files changed, 429 insertions(+) create mode 100644 core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/CompanionObjectTest.kt create mode 100644 core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/ConstructorTest.kt create mode 100644 core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/DataClassTest.kt create mode 100644 core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/DelegationTest.kt create mode 100644 core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/ExceptionsTest.kt create mode 100644 core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/ExtensionFunctionsTest.kt create mode 100644 core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/FunctionsTest.kt create mode 100644 core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/IsOperatorTest.kt create mode 100644 core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/NullSafetyTest.kt create mode 100644 core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/OperatorsOverloadingTest.kt create mode 100644 core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/PropertiesTest.kt diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/CompanionObjectTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/CompanionObjectTest.kt new file mode 100644 index 0000000000..69573fb75b --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/CompanionObjectTest.kt @@ -0,0 +1,21 @@ +package com.baeldung.kotlinvsjava + +import org.junit.Test +import kotlin.test.assertEquals + +class CompanionObjectTest { + + @Test + fun givenAClassWithCompanionObject_whenCallingMethodTheSameAsStaticOne_thenWeGetAResult() { + assertEquals("A", A.returnClassName()) + } + +} + +class A { + companion object { + fun returnClassName(): String { + return "A" + } + } +} \ No newline at end of file diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/ConstructorTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/ConstructorTest.kt new file mode 100644 index 0000000000..fdb5d05db5 --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/ConstructorTest.kt @@ -0,0 +1,18 @@ +package com.baeldung.kotlinvsjava + +import org.junit.Test +import kotlin.test.assertEquals + +class ConstructorTests { + + @Test + fun givenAClassWithPrimaryConstructor_whenCreatingAnInstance_thenWeGetObject() { + var example = Example(1, "Example") + + assertEquals(1, example.id) + assertEquals("Example", example.name) + } + +} + +class Example constructor(val id: Int, var name: String) \ No newline at end of file diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/DataClassTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/DataClassTest.kt new file mode 100644 index 0000000000..ad79538d3c --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/DataClassTest.kt @@ -0,0 +1,33 @@ +package com.baeldung.kotlinvsjava + +import org.junit.Test +import kotlin.test.assertEquals +import kotlin.test.assertFalse + +class DataClassTest { + + @Test + fun givenASampleDataClass_whenCallingToStringMethod_thenItReturnsAllProperties() { + val student = Student(1, "John", "Smith") + + assertEquals(1, student.id) + assertEquals("John", student.name) + assertEquals("Smith", student.lastName) + assertEquals("Student(id=1, name=John, lastName=Smith)", student.toString()) + } + + @Test + fun givenASampleDataClass_whenCreatingACopyWithGeneratedFunction_thenItReturnsACopyWithRequestedChanges() { + val student = Student(1, "John", "Smith") + val student2 = student.copy(id = 2, name = "Anne") + + assertEquals(2, student2.id) + assertEquals("Anne", student2.name) + assertEquals("Smith", student2.lastName) + assertEquals("Student(id=2, name=Anne, lastName=Smith)", student2.toString()) + assertFalse(student.equals(student2)) + } + +} + +data class Student(val id: Int, val name: String, val lastName: String) \ No newline at end of file diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/DelegationTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/DelegationTest.kt new file mode 100644 index 0000000000..2da824c2db --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/DelegationTest.kt @@ -0,0 +1,27 @@ +package com.baeldung.kotlinvsjava + +import org.junit.Test +import kotlin.test.assertEquals + +class DelegationTest { + + @Test + fun givenAClassWithDelegation_whenCallDelegatedMethod_thenWeGetAResultDefinedInPassedObject() { + val car = Car(V6Engine()) + + assertEquals("Vroom", car.makeSound()) + } + +} + +interface Engine { + fun makeSound(): String +} + +class V6Engine: Engine { + override fun makeSound(): String { + return "Vroom" + } +} + +class Car(e: Engine) : Engine by e \ No newline at end of file diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/ExceptionsTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/ExceptionsTest.kt new file mode 100644 index 0000000000..d1b3390544 --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/ExceptionsTest.kt @@ -0,0 +1,34 @@ +package com.baeldung.kotlinvsjava + +import java.io.IOException +import kotlin.test.Test +import kotlin.test.assertEquals + +class ExceptionsTest { + + @Test + fun givenATryExpression_whenReturning5InLastExpressionOfTryBlock_thenWeGet5() { + val value: Int = try { 5 } catch (e: IOException) { 6 } + + assertEquals(5, value) + } + + @Test + fun givenATryExpression_whenReturning6InLastExpressionOfCatchBlock_thenWeGet6() { + val value: Int = try { funThrowingException() } catch (e: IOException) { 6 } + + assertEquals(6, value) + } + + @org.junit.Test(expected = IllegalArgumentException::class) + fun givenANullString_whenUsingElvisOperator_thenExceptionIsThrown() { + val sampleString: String? = null + + val length: Int = sampleString?.length ?: throw IllegalArgumentException("String must not be null") + } + + private fun funThrowingException(): Nothing { + throw IOException() + } + +} \ No newline at end of file diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/ExtensionFunctionsTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/ExtensionFunctionsTest.kt new file mode 100644 index 0000000000..3db73b6d2d --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/ExtensionFunctionsTest.kt @@ -0,0 +1,30 @@ +package com.baeldung.kotlinvsjava + +import org.junit.Test +import kotlin.test.assertEquals + +class ExtensionFunctionsTest { + + @Test + fun givenAStringWithAnExtensionFunction_whenCallingThatFunction_thenItConcatenatesStrings() { + val sampleString = "ABC" + val concatenatedString = sampleString.appendString("DEF") + + assertEquals("ABCDEF", concatenatedString) + } + + @Test + fun givenAStringWithAnExtensionProperty_whenReadingProperty_thenItReturnsLengthOfString() { + val sampleString = "ABC" + + assertEquals(3, sampleString.size) + } + + fun String.appendString(str : String): String { + return plus(str) + } + + val String.size: Int + get() = length + +} \ No newline at end of file diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/FunctionsTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/FunctionsTest.kt new file mode 100644 index 0000000000..6176478dfe --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/FunctionsTest.kt @@ -0,0 +1,70 @@ +package com.baeldung.kotlinvsjava + +import org.junit.Test +import kotlin.test.assertEquals + +class FunctionsTest { + + @Test + fun givenALambdaExpressionConcatenatingString_whenUsingTheFunctionWithAAndBString_thenWeGetAB() { + val concat: (String, String) -> String = { a, b -> a + b } + + assertEquals("AB", concat("A","B")) + } + + @Test + fun givenAnAnonymousFunctionConcatenatingString_whenUsingTheFunctionWithAAndBString_thenWeGetAB() { + val concat: (String, String) -> String = fun(a: String, b: String): String { return a + b } + + assertEquals("AB", concat("A","B")) + } + + @Test + fun givenAnPlusMethodOfString_whenUsingTheFunctionWithAAndBString_thenWeGetAB() { + val concat = String::plus + + assertEquals("AB", concat("A","B")) + } + + @Test + fun givenAStringConstractorAssignedToFunction_whenUsingFunctionReference_thenWeGetNewString() { + val concat = ::String + + assertEquals("A", concat().plus("A")) + } + + @Test + fun givenAClassImplementingAFunctionType_whenUsingTheFunctionWithAAndBString_thenWeGetAB() { + val concat = StringConcatenation() + + assertEquals("AB", concat("A", "B")) + } + + @Test + fun givenALambdaExpressionWithReceiver_whenUsingTheFunctionWithReceiver_thenWeGetABC() { + val concat: String.(String, String) -> String = { a, b -> plus(a).plus(b) } + + assertEquals("ABC", "A".concat("B", "C")) + } + + @Test + fun givenALambdaExpressionWithinLambdaExpression_whenUsingTheFunction_thenWeGetAB() { + val concat: (String) -> ((String) -> String) = { a -> {b -> a + b} } + + assertEquals("AB", (concat("A")("B"))) + } + + @Test + fun given3NestedLambdaExpression_whenUsingTheFunction_thenWeGetABC() { + val concat: (String) -> (String) -> (String) -> String = { a -> {b -> { c -> a + b + c} } } + + assertEquals("ABC", concat("A")("B")("C")) + } + +} + +class StringConcatenation: (String, String) -> String { + override fun invoke(p1: String, p2: String): String { + return p1 + p2 + } +} \ No newline at end of file diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/IsOperatorTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/IsOperatorTest.kt new file mode 100644 index 0000000000..1817602cdf --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/IsOperatorTest.kt @@ -0,0 +1,36 @@ +package com.baeldung.kotlinvsjava + +import org.junit.Test +import kotlin.math.absoluteValue +import kotlin.test.assertEquals +import kotlin.test.assertTrue + +class IsOperatorTest { + + @Test + fun givenSampleValue_whenUsingIsOperatorInIfStatement_thenItCastsAutomaticallyToString() { + val value: Any = "string" + + if(value is String) { + assertEquals(6, value.length) + } + } + + @Test + fun givenSampleValue_whenUsingIsOperatorWithAndOperator_thenItCastsAutomaticallyToString() { + val value: Any = "string" + + assertTrue(value is String && value.length == 6) + } + + @Test + fun givenSampleValue_whenUsingWithWhenOperator_thenItCastsAutomaticallyToString() { + val value: Any = "string" + + when(value) { + is String -> assertEquals(6, value.length) + is Int -> assertEquals(6, value.absoluteValue) + } + } + +} \ No newline at end of file diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/NullSafetyTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/NullSafetyTest.kt new file mode 100644 index 0000000000..8cb3cbc761 --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/NullSafetyTest.kt @@ -0,0 +1,67 @@ +package com.baeldung.kotlinvsjava + +import kotlin.test.Test +import java.lang.NullPointerException +import kotlin.test.assertEquals +import kotlin.test.assertNotNull +import kotlin.test.assertNull + +class NullSafetyTest { + + @Test + fun givenStringAndNull_whenUsingSafeCallOperatorWithLengthMethod_thenReturnsLengthForStringAndNullForNull() { + val stringValue: String? = "string" + val nullValue: String? = null + + assertNotNull(stringValue?.length) + assertNull(nullValue?.length) + } + + @Test(expected = NullPointerException::class) + fun givenNullReference_whenUsingTheNotNullAssertionOperator_thenItThrowsNullPointerException() { + val stringValue: String? = "string" + val nullValue: String? = null + + assertNotNull(stringValue!!.length) + nullValue!!.length + } + + @Test + fun givenStringAndNull_whenUsingElvisOperator_thenItTestsAgainstNullAndReturnsTheProperValue() { + val stringValue: String? = "string" + val nullValue: String? = null + + val shouldBeLength: Int = stringValue?.length ?: -1 + val souldBeMinusOne: Int = nullValue?.length ?: -1 + + assertEquals(6, shouldBeLength) + assertEquals(-1, souldBeMinusOne) + } + + @Test + fun givenString_whenCastingToInt_thenItReturnsNull() { + val stringValue: String? = "string" + + val intValue: Int? = stringValue as? Int + + assertNull(intValue) + } + + @Test + fun givenCollectionWithNulls_whenFilterNonNull_thenItReturnsCollectionWithoutNulls() { + val list: List = listOf("a", "b", null) + val nonNullList = list.filterNotNull() + + assertEquals(2, nonNullList.size) + assertEquals(nonNullList, listOf("a", "b")) + } + + @Test + fun givenCollectionWithNulls_whenLetWithSafeCallOperator_thenItOmitsNulls() { + val list: List = listOf("a", "b", null) + for(elem in list) { + elem?.let { assertNotNull(it) } + } + } + +} \ No newline at end of file diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/OperatorsOverloadingTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/OperatorsOverloadingTest.kt new file mode 100644 index 0000000000..a28008da20 --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/OperatorsOverloadingTest.kt @@ -0,0 +1,61 @@ +package com.baeldung.kotlinvsjava + +import org.junit.Test +import kotlin.test.assertEquals +import kotlin.test.assertTrue + +class OperatorsOverloadingTest { + + @Test + fun givenThePlaneClassWithOverloadedIncrementationOperator_whenCallingTheOperator_thenItIncreasesSpeed(){ + var plane = Plane(0.0) + + plane++ + assertEquals(50.0, plane.currentSpeed) + } + + @Test + fun givenThePlaneClassWithOverloadedMinusOperator_whenCallingTheOperator_thenItDecreaseSpeed(){ + var plane = Plane(1000.0) + + plane - 500.0 + assertEquals(500.0, plane.currentSpeed) + } + + @Test + fun givenThePlaneClassWithOverloadedInvokeOperator_whenCallingTheOperator_thenItSetSpeed(){ + var plane = Plane(0.0) + + plane(150.0) + assertEquals(150.0, plane.currentSpeed) + } + + @Test + fun given2PlaneObjectWithOverloadedComparisonOperator_whenCallingTheOperator_thenItComparesSpeedValues(){ + var plane = Plane(0.0) + var plane2 = Plane(150.0) + + assertTrue(plane < (plane2)) + } + +} + +class Plane(var currentSpeed: Double) { + + operator fun inc(): Plane { + currentSpeed += 50.0 + return this + } + + operator fun minus(number: Double) { + currentSpeed = if(currentSpeed < number) 0.0 else currentSpeed - number + } + + operator fun invoke(speed: Double) { + currentSpeed = speed + } + + operator fun compareTo(plane: Plane): Int { + return currentSpeed.compareTo(plane.currentSpeed) + } +} \ No newline at end of file diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/PropertiesTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/PropertiesTest.kt new file mode 100644 index 0000000000..95abcd68a2 --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/PropertiesTest.kt @@ -0,0 +1,32 @@ +package com.baeldung.kotlinvsjava + +import org.junit.Test +import java.math.BigDecimal +import kotlin.test.assertEquals + +class PropertiesTest { + + @Test + fun givenASampleClassWithValAndVarProperties_whenSettingPrice_thenWeGetZeroOrOne() { + val product = Product() + product.price = BigDecimal(10) + + val product2 = Product() + product2.price = null + + assertEquals("empty", product.id) + assertEquals("empty", product2.id) + assertEquals(BigDecimal(10), product.price) + assertEquals(BigDecimal(1), product2.price) + } + +} + +class Product { + + val id: String? = "empty" + + var price: BigDecimal? = BigDecimal.ZERO + set(value) = if(value == null) { field = BigDecimal.ONE} else { field = value } + +} \ No newline at end of file