This commit is contained in:
Jonathan Cook
2019-10-23 15:01:44 +02:00
parent db85c8f275
commit 684ec0d2e3
20486 changed files with 1642483 additions and 0 deletions
+14
View File
@@ -0,0 +1,14 @@
/bin/
#ignore gradle
.gradle/
#ignore build and generated files
build/
node/
out/
#ignore installed node modules and package lock file
node_modules/
package-lock.json
+15
View File
@@ -0,0 +1,15 @@
## Core Kotlin
This module contains articles about core Kotlin.
### Relevant articles:
- [Void Type in Kotlin](https://www.baeldung.com/kotlin-void-type)
- [How to use Kotlin Range Expressions](https://www.baeldung.com/kotlin-ranges)
- [Creating a Kotlin Range Iterator on a Custom Object](https://www.baeldung.com/kotlin-custom-range-iterator)
- [Kotlin Scope Functions](https://www.baeldung.com/kotlin-scope-functions)
- [Kotlin Annotations](https://www.baeldung.com/kotlin-annotations)
- [Split a List into Parts in Kotlin](https://www.baeldung.com/kotlin-split-list-into-parts)
- [String Comparison in Kotlin](https://www.baeldung.com/kotlin-string-comparison)
- [Guide to JVM Platform Annotations in Kotlin](https://www.baeldung.com/kotlin-jvm-annotations)
- More articles: [[<-- prev]](/core-kotlin)
+58
View File
@@ -0,0 +1,58 @@
group 'com.baeldung.ktor'
version '1.0-SNAPSHOT'
buildscript {
ext.kotlin_version = '1.3.30'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: 'java'
apply plugin: 'kotlin'
apply plugin: 'application'
mainClassName = 'APIServer.kt'
sourceCompatibility = 1.8
compileKotlin { kotlinOptions.jvmTarget = "1.8" }
compileTestKotlin { kotlinOptions.jvmTarget = "1.8" }
repositories {
mavenCentral()
jcenter()
maven { url "https://dl.bintray.com/kotlin/ktor" }
}
sourceSets {
main{
kotlin{
srcDirs 'com/baeldung/ktor'
}
}
}
test {
useJUnitPlatform()
testLogging {
events "passed", "skipped", "failed"
}
}
dependencies {
implementation "ch.qos.logback:logback-classic:1.2.1"
implementation "org.jetbrains.kotlin:kotlin-stdlib:${kotlin_version}"
testImplementation 'org.junit.jupiter:junit-jupiter:5.4.2'
testImplementation 'junit:junit:4.12'
testImplementation 'org.assertj:assertj-core:3.12.2'
testImplementation 'org.mockito:mockito-core:2.27.0'
testImplementation "org.jetbrains.kotlin:kotlin-test:${kotlin_version}"
testImplementation "org.jetbrains.kotlin:kotlin-test-junit5:${kotlin_version}"
}
Binary file not shown.
@@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
+188
View File
@@ -0,0 +1,188 @@
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# 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.
#
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"
+100
View File
@@ -0,0 +1,100 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem http://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
+97
View File
@@ -0,0 +1,97 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>core-kotlin-2</artifactId>
<name>core-kotlin-2</name>
<packaging>jar</packaging>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-kotlin</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../parent-kotlin</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
<version>${kotlin.version}</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${junit.jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
<version>${byte-buddy.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-test</artifactId>
<version>${kotlin.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-test-junit5</artifactId>
<version>${kotlin.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
<configuration>
<jvmTarget>1.8</jvmTarget>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<kotlin.version>1.3.30</kotlin.version>
<junit.jupiter.version>5.4.2</junit.jupiter.version>
<mockito.version>2.27.0</mockito.version>
<byte-buddy.version>1.9.12</byte-buddy.version>
<assertj.version>3.10.0</assertj.version>
</properties>
</project>
+11
View File
@@ -0,0 +1,11 @@
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
+2
View File
@@ -0,0 +1,2 @@
rootProject.name = 'KtorWithKotlin'
@@ -0,0 +1,7 @@
package com.baeldung.annotations
@Target(AnnotationTarget.FIELD)
annotation class Positive
@Target(AnnotationTarget.FIELD)
annotation class AllowedNames(val names: Array<String>)
@@ -0,0 +1,3 @@
package com.baeldung.annotations
class Item(@Positive val amount: Float, @AllowedNames(["Alice", "Bob"]) val name: String)
@@ -0,0 +1,7 @@
package com.baeldung.annotations
fun main(args: Array<String>) {
val item = Item(amount = 1.0f, name = "Bob")
val validator = Validator()
println("Is instance valid? ${validator.isValid(item)}")
}
@@ -0,0 +1,38 @@
package com.baeldung.annotations
/**
* Naive annotation-based validator.
* @author A.Shcherbakov
*/
class Validator() {
/**
* Return true if every item's property annotated with @Positive is positive and if
* every item's property annotated with @AllowedNames has a value specified in that annotation.
*/
fun isValid(item: Item): Boolean {
val fields = item::class.java.declaredFields
for (field in fields) {
field.isAccessible = true
for (annotation in field.annotations) {
val value = field.get(item)
if (field.isAnnotationPresent(Positive::class.java)) {
val amount = value as Float
if (amount < 0) {
return false
}
}
if (field.isAnnotationPresent(AllowedNames::class.java)) {
val allowedNames = field.getAnnotation(AllowedNames::class.java)?.names
val name = value as String
allowedNames?.let {
if (!it.contains(name)) {
return false
}
}
}
}
}
return true
}
}
@@ -0,0 +1,11 @@
package com.baeldung.jvmannotations
import java.util.*
interface Document {
@JvmDefault
fun getTypeDefault() = "document"
fun getType() = "document"
}
@@ -0,0 +1,9 @@
package com.baeldung.jvmannotations;
public class HtmlDocument implements Document {
@Override
public String getType() {
return "HTML";
}
}
@@ -0,0 +1,66 @@
@file:JvmName("MessageHelper")
@file:JvmMultifileClass //used
package com.baeldung.jvmannotations
import java.util.*
@JvmName("getMyUsername")
fun getMyName() : String {
return "myUserId"
}
object MessageBroker {
@JvmStatic
var totalMessagesSent = 0
const val maxMessageLength = 0
@JvmStatic
fun clearAllMessages() {
}
@JvmStatic
@JvmOverloads
@Throws(Exception::class)
fun findMessages(sender : String, type : String = "text", maxResults : Int = 10) : List<Message> {
if(sender.isEmpty()) {
throw Exception()
}
return ArrayList()
}
}
class Message {
// this would cause a compilation error since sender is immutable
// @set:JvmName("setSender")
val sender = "myself"
// this works as name is overridden
@JvmName("getSenderName")
fun getSender() : String = "from:$sender"
@get:JvmName("getReceiverName")
@set:JvmName("setReceiverName")
var receiver : String = ""
@get:JvmName("getContent")
@set:JvmName("setContent")
var text = ""
// generates a warning
@get:JvmName("getId")
private val id = 0
@get:JvmName("hasAttachment")
var hasAttachment = true
var isEncrypted = true
fun setReceivers(receiverNames : List<String>) {
}
@JvmName("setReceiverIds")
fun setReceivers(receiverNames : List<Int>) {
}
}
@@ -0,0 +1,6 @@
@file:JvmMultifileClass
@file:JvmName("MessageHelper") //applies to all top level functions / variables / constants
package com.baeldung.jvmannotations
fun convert(message: Message) {
}
@@ -0,0 +1,16 @@
package com.baeldung.jvmannotations
import java.util.*
class TextDocument : Document {
override fun getType() = "text"
fun transformList(list : List<Number>) : List<Number> {
return list.filter { n -> n.toInt() > 1 }
}
fun transformListInverseWildcards(list : List<@JvmSuppressWildcards Number>) : List<@JvmWildcard Number> {
return list.filter { n -> n.toInt() > 1 }
}
var list : List<@JvmWildcard Any> = ArrayList()
}
@@ -0,0 +1,5 @@
package com.baeldung.jvmannotations
import java.util.*
class XmlDocument(d : Document) : Document by d
@@ -0,0 +1,13 @@
package com.baeldung.range
fun main(args: Array<String>) {
for (ch in 'a'..'f') {
print(ch)
}
println()
for (ch in 'f' downTo 'a') {
print(ch)
}
}
@@ -0,0 +1,21 @@
package com.baeldung.range
enum class Color(val rgb: Int) {
BLUE(0x0000FF),
GREEN(0x008000),
RED(0xFF0000),
MAGENTA(0xFF00FF),
YELLOW(0xFFFF00);
}
fun main(args: Array<String>) {
println(Color.values().toList());
val red = Color.RED
val yellow = Color.YELLOW
val range = red..yellow
println(range.contains(Color.MAGENTA))
println(range.contains(Color.BLUE))
println(range.contains(Color.GREEN))
}
@@ -0,0 +1,56 @@
package com.baeldung.range
import java.lang.IllegalStateException
class CustomColor(val rgb: Int): Comparable<CustomColor> {
override fun compareTo(other: CustomColor): Int {
return this.rgb.compareTo(other.rgb)
}
operator fun rangeTo(that: CustomColor) = ColorRange(this,that)
operator fun inc(): CustomColor {
return CustomColor(rgb + 1)
}
init {
if(rgb < 0x000000 || rgb > 0xFFFFFF){
throw IllegalStateException("RGB must be between 0 and 16777215")
}
}
override fun toString(): String {
return "CustomColor(rgb=$rgb)"
}
}
class ColorRange(override val start: CustomColor,
override val endInclusive: CustomColor) : ClosedRange<CustomColor>, Iterable<CustomColor>{
override fun iterator(): Iterator<CustomColor> {
return ColorIterator(start, endInclusive)
}
}
class ColorIterator(val start: CustomColor, val endInclusive: CustomColor) : Iterator<CustomColor> {
var initValue = start
override fun hasNext(): Boolean {
return initValue <= endInclusive
}
override fun next(): CustomColor {
return initValue++
}
}
fun main(args: Array<String>) {
val a = CustomColor(0xABCDEF)
val b = CustomColor(-1)
val c = CustomColor(0xABCDFF)
for(color in a..c){
println(color)
}
}
@@ -0,0 +1,18 @@
package com.baeldung.range
fun main(args: Array<String>) {
val r = 1..10
//Apply filter
val f = r.filter { it -> it % 2 == 0 }
println(f)
//Map
val m = r.map { it -> it * it }
println(m)
//Reduce
val rdc = r.reduce { a, b -> a + b }
println(rdc)
}
@@ -0,0 +1,8 @@
package com.baeldung.range
fun main(args: Array<String>) {
println((1..9).first)
println((1..9 step 2).step)
println((3..9).reversed().last)
}
@@ -0,0 +1,14 @@
package com.baeldung.range
fun main(args: Array<String>) {
val r = 1..20
println(r.min())
println(r.max())
println(r.sum())
println(r.average())
println(r.count())
val repeated = listOf(1, 1, 2, 4, 4, 6, 10)
println(repeated.distinct())
}
@@ -0,0 +1,28 @@
package com.baeldung.range
fun main(args: Array<String>) {
for (i in 1..9) {
print(i)
}
println()
for (i in 9 downTo 1) {
print(i)
}
println()
for (i in 1.rangeTo(9)) {
print(i)
}
println()
for (i in 9.downTo(1)) {
print(i)
}
println()
for (i in 1 until 9) {
print(i)
}
}
@@ -0,0 +1,14 @@
package com.baeldung.range
fun main(args: Array<String>) {
(1..9).reversed().forEach {
print(it)
}
println()
(1..9).reversed().step(3).forEach {
print(it)
}
}
@@ -0,0 +1,15 @@
package com.baeldung.range
fun main(args: Array<String>) {
for(i in 1..9 step 2){
print(i)
}
println()
for (i in 9 downTo 1 step 2){
print(i)
}
}
@@ -0,0 +1,8 @@
package com.baeldung.range
fun main(args: Array<String>) {
for (i in 1 until 9) {
print(i)
}
}
@@ -0,0 +1,25 @@
package com.baeldung.scope
data class Student(var studentId: String = "", var name: String = "", var surname: String = "") {
}
data class Teacher(var teacherId: Int = 0, var name: String = "", var surname: String = "") {
fun setId(anId: Int): Teacher = apply { teacherId = anId }
fun setName(aName: String): Teacher = apply { name = aName }
fun setSurname(aSurname: String): Teacher = apply { surname = aSurname }
}
data class Headers(val headerInfo: String)
data class Response(val headers: Headers)
data class RestClient(val url: String) {
fun getResponse() = Response(Headers("some header info"))
}
data class BankAccount(val id: Int) {
fun checkAuthorization(username: String) = Unit
fun addPayee(payee: String) = Unit
fun makePayment(paymentDetails: String) = Unit
}
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</configuration>
@@ -0,0 +1,41 @@
package com.baeldung.annotations
import org.junit.Test
import kotlin.test.assertTrue
import kotlin.test.assertFalse
class ValidationTest {
@Test
fun whenAmountIsOneAndNameIsAlice_thenTrue() {
assertTrue(Validator().isValid(Item(1f, "Alice")))
}
@Test
fun whenAmountIsOneAndNameIsBob_thenTrue() {
assertTrue(Validator().isValid(Item(1f, "Bob")))
}
@Test
fun whenAmountIsMinusOneAndNameIsAlice_thenFalse() {
assertFalse(Validator().isValid(Item(-1f, "Alice")))
}
@Test
fun whenAmountIsMinusOneAndNameIsBob_thenFalse() {
assertFalse(Validator().isValid(Item(-1f, "Bob")))
}
@Test
fun whenAmountIsOneAndNameIsTom_thenFalse() {
assertFalse(Validator().isValid(Item(1f, "Tom")))
}
@Test
fun whenAmountIsMinusOneAndNameIsTom_thenFalse() {
assertFalse(Validator().isValid(Item(-1f, "Tom")))
}
}
@@ -0,0 +1,34 @@
package com.baeldung.lists
import org.junit.jupiter.api.Test
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertTrue
class ListsUnitTest {
var batmans: List<String> = listOf("Christian Bale", "Michael Keaton", "Ben Affleck", "George Clooney")
@Test
fun whenFindASpecificItem_thenItemIsReturned() {
//Returns the first element matching the given predicate, or null if no such element was found.
val theFirstBatman = batmans.find { actor -> "Michael Keaton".equals(actor) }
assertEquals(theFirstBatman, "Michael Keaton")
}
@Test
fun whenFilterWithPredicate_thenMatchingItemsAreReturned() {
//Returns a list containing only elements matching the given predicate.
val theCoolestBatmans = batmans.filter { actor -> actor.contains("a") }
assertTrue(theCoolestBatmans.contains("Christian Bale") && theCoolestBatmans.contains("Michael Keaton"))
}
@Test
fun whenFilterNotWithPredicate_thenMatchingItemsAreReturned() {
//Returns a list containing only elements not matching the given predicate.
val theMehBatmans = batmans.filterNot { actor -> actor.contains("a") }
assertFalse(theMehBatmans.contains("Christian Bale") && theMehBatmans.contains("Michael Keaton"))
assertTrue(theMehBatmans.contains("Ben Affleck") && theMehBatmans.contains("George Clooney"))
}
}
@@ -0,0 +1,17 @@
package com.baeldung.range
import org.junit.Test
import kotlin.test.assertEquals
class CharRangeTest {
@Test
fun testCharRange() {
assertEquals(listOf('a', 'b', 'c'), ('a'..'c').toList())
}
@Test
fun testCharDownRange() {
assertEquals(listOf('c', 'b', 'a'), ('c'.downTo('a')).toList())
}
}
@@ -0,0 +1,20 @@
package com.baeldung.range
import org.junit.Test
import kotlin.test.assertFalse
import kotlin.test.assertTrue
class ColorTest {
@Test
fun testEnumRange() {
println(Color.values().toList());
val red = Color.RED
val yellow = Color.YELLOW
val range = red..yellow
assertTrue { range.contains(Color.MAGENTA) }
assertFalse { range.contains(Color.BLUE) }
}
}
@@ -0,0 +1,41 @@
package com.baeldung.range
import org.junit.Test
import java.lang.IllegalStateException
import kotlin.test.assertFailsWith
import kotlin.test.assertTrue
class CustomColorTest {
@Test
fun testInvalidConstructor(){
assertFailsWith(IllegalStateException::class){
CustomColor(-1)
}
}
@Test
fun assertHas10Colors(){
assertTrue {
val a = CustomColor(1)
val b = CustomColor(10)
val range = a..b
for(cc in range){
println(cc)
}
range.toList().size == 10
}
}
@Test
fun assertContains0xCCCCCC(){
assertTrue {
val a = CustomColor(0xBBBBBB)
val b = CustomColor(0xDDDDDD)
val range = a..b
range.contains(CustomColor(0xCCCCCC))
}
}
}
@@ -0,0 +1,20 @@
package com.baeldung.range
import org.junit.Test
import kotlin.test.assertEquals
import com.baeldung.jvmannotations.*;
class DocumentTest {
@Test
fun testDefaultMethod() {
val myDocument = TextDocument()
val myTextDocument = XmlDocument(myDocument)
assertEquals("text", myDocument.getType())
assertEquals("text", myTextDocument.getType())
assertEquals("document", myTextDocument.getTypeDefault())
}
}
@@ -0,0 +1,24 @@
package com.baeldung.range
import org.junit.Test
import kotlin.test.assertEquals
class FilterTest {
val r = 1..10
@Test
fun filterTest() {
assertEquals(listOf(2, 4, 6, 8, 10), r.filter { it -> it % 2 == 0 }.toList())
}
@Test
fun mapTest() {
assertEquals(listOf(1, 4, 9, 16, 25, 36, 49, 64, 81, 100), r.map { it -> it * it }.toList())
}
@Test
fun reduceTest() {
assertEquals(55, r.reduce { a, b -> a + b })
}
}
@@ -0,0 +1,22 @@
package com.baeldung.range
import org.junit.Test
import kotlin.test.assertEquals
class FirstLastTest {
@Test
fun testFirst() {
assertEquals(1, (1..9).first)
}
@Test
fun testLast() {
assertEquals(9, (1..9).last)
}
@Test
fun testStep() {
assertEquals(2, (1..9 step 2).step)
}
}
@@ -0,0 +1,40 @@
package com.baeldung.range
import org.junit.Test
import kotlin.test.assertEquals
class OtherRangeFunctionsTest {
val r = 1..20
val repeated = listOf(1, 1, 2, 4, 4, 6, 10)
@Test
fun testMin() {
assertEquals(1, r.min())
}
@Test
fun testMax() {
assertEquals(20, r.max())
}
@Test
fun testSum() {
assertEquals(210, r.sum())
}
@Test
fun testAverage() {
assertEquals(10.5, r.average())
}
@Test
fun testCount() {
assertEquals(20, r.count())
}
@Test
fun testDistinct() {
assertEquals(listOf(1, 2, 4, 6, 10), repeated.distinct())
}
}
@@ -0,0 +1,22 @@
package com.baeldung.range
import org.junit.Test
import kotlin.test.assertEquals
class RangeTest {
@Test
fun testRange() {
assertEquals(listOf(1,2,3), (1.rangeTo(3).toList()))
}
@Test
fun testDownTo(){
assertEquals(listOf(3,2,1), (3.downTo(1).toList()))
}
@Test
fun testUntil(){
assertEquals(listOf(1,2), (1.until(3).toList()))
}
}
@@ -0,0 +1,12 @@
package com.baeldung.range
import org.junit.Test
import kotlin.test.assertEquals
class ReverseRangeTest {
@Test
fun reversedTest() {
assertEquals(listOf(9, 6, 3), (1..9).reversed().step(3).toList())
}
}
@@ -0,0 +1,17 @@
package com.baeldung.range
import org.junit.Test
import kotlin.test.assertEquals
class StepTest {
@Test
fun testStep() {
assertEquals(listOf(1, 3, 5, 7, 9), (1..9 step 2).toList())
}
@Test
fun testStepDown() {
assertEquals(listOf(9, 7, 5, 3, 1), (9 downTo 1 step 2).toList())
}
}
@@ -0,0 +1,12 @@
package com.baeldung.range
import org.junit.Test
import kotlin.test.assertEquals
class UntilRangeTest {
@Test
fun testUntil() {
assertEquals(listOf(1, 2, 3, 4), (1 until 5).toList())
}
}
@@ -0,0 +1,143 @@
package com.baeldung.scope
import org.junit.Test
import kotlin.test.assertTrue
class ScopeFunctionsUnitTest {
class Logger {
var called : Boolean = false
fun info(message: String) {
called = true
}
fun wasCalled() = called
}
@Test
fun shouldTransformWhenLetFunctionUsed() {
val stringBuider = StringBuilder()
val numberOfCharacters = stringBuider.let {
it.append("This is a transformation function.")
it.append("It takes a StringBuilder instance and returns the number of characters in the generated String")
it.length
}
assertTrue {
numberOfCharacters == 128
}
}
@Test
fun shouldHandleNullabilityWhenLetFunctionUsed() {
val message: String? = "hello there!"
val charactersInMessage = message?.let {
"At this point is safe to reference the variable. Let's print the message: $it"
} ?: "default value"
assertTrue {
charactersInMessage.equals("At this point is safe to reference the variable. Let's print the message: hello there!")
}
val aNullMessage = null
val thisIsNull = aNullMessage?.let {
"At this point it would be safe to reference the variable. But it will not really happen because it is null. Let's reference: $it"
} ?: "default value"
assertTrue {
thisIsNull.equals("default value")
}
}
@Test
fun shouldInitializeObjectWhenUsingApply() {
val aStudent = Student().apply {
studentId = "1234567"
name = "Mary"
surname = "Smith"
}
assertTrue {
aStudent.name.equals("Mary")
}
}
@Test
fun shouldAllowBuilderStyleObjectDesignWhenApplyUsedInClassMethods() {
val teacher = Teacher()
.setId(1000)
.setName("Martha")
.setSurname("Spector")
assertTrue {
teacher.surname.equals("Spector")
}
}
@Test
fun shouldAllowSideEffectWhenUsingAlso() {
val restClient = RestClient("http://www.someurl.com")
val logger = Logger()
val headers = restClient
.getResponse()
.also { logger.info(it.toString()) }
.headers
assertTrue {
logger.wasCalled() && headers.headerInfo.equals("some header info")
}
}
@Test
fun shouldInitializeFieldWhenAlsoUsed() {
val aStudent = Student().also { it.name = "John"}
assertTrue {
aStudent.name.equals("John")
}
}
@Test
fun shouldLogicallyGroupObjectCallsWhenUsingWith() {
val bankAccount = BankAccount(1000)
with (bankAccount) {
checkAuthorization("someone")
addPayee("some payee")
makePayment("payment information")
}
}
@Test
fun shouldConvertObjectWhenRunUsed() {
val stringBuider = StringBuilder()
val numberOfCharacters = stringBuider.run {
append("This is a transformation function.")
append("It takes a StringBuilder instance and returns the number of characters in the generated String")
length
}
assertTrue {
numberOfCharacters == 128
}
}
@Test
fun shouldHandleNullabilityWhenRunIsUsed() {
val message: String? = "hello there!"
val charactersInMessage = message?.run {
"At this point is safe to reference the variable. Let's print the message: $this"
} ?: "default value"
assertTrue {
charactersInMessage.equals("At this point is safe to reference the variable. Let's print the message: hello there!")
}
}
}
@@ -0,0 +1,99 @@
package com.baeldung.lambda
import org.junit.jupiter.api.Test
import kotlin.test.assertEquals
class SplittingTest {
private val evenList = listOf(0, "a", 1, "b", 2, "c");
private val unevenList = listOf(0, "a", 1, "b", 2, "c", 3);
private fun verifyList(resultList: List<List<Any>>) {
assertEquals("[[0, a], [1, b], [2, c]]", resultList.toString())
}
private fun verifyPartialList(resultList: List<List<Any>>) {
assertEquals("[[0, a], [1, b], [2, c], [3]]", resultList.toString())
}
@Test
fun whenChunked_thenListIsSplit() {
val resultList = evenList.chunked(2)
verifyList(resultList)
}
@Test
fun whenUnevenChunked_thenListIsSplit() {
val resultList = unevenList.chunked(2)
verifyPartialList(resultList)
}
@Test
fun whenWindowed_thenListIsSplit() {
val resultList = evenList.windowed(2, 2)
verifyList(resultList)
}
@Test
fun whenUnevenPartialWindowed_thenListIsSplit() {
val resultList = unevenList.windowed(2, 2, partialWindows = true)
verifyPartialList(resultList)
}
@Test
fun whenUnevenWindowed_thenListIsSplit() {
val resultList = unevenList.windowed(2, 2, partialWindows = false)
verifyList(resultList)
}
@Test
fun whenGroupByWithAscendingNumbers_thenListIsSplit() {
val numberList = listOf(1, 2, 3, 4, 5, 6);
val resultList = numberList.groupBy { (it + 1) / 2 }
assertEquals("[[1, 2], [3, 4], [5, 6]]", resultList.values.toString())
assertEquals("[1, 2, 3]", resultList.keys.toString())
}
@Test
fun whenGroupByWithAscendingNumbersUneven_thenListIsSplit() {
val numberList = listOf(1, 2, 3, 4, 5, 6, 7);
val resultList = numberList.groupBy { (it + 1) / 2 }.values
assertEquals("[[1, 2], [3, 4], [5, 6], [7]]", resultList.toString())
}
@Test
fun whenGroupByWithRandomNumbers_thenListIsSplitInWrongWay() {
val numberList = listOf(1, 3, 8, 20, 23, 30);
val resultList = numberList.groupBy { (it + 1) / 2 }
assertEquals("[[1], [3], [8], [20], [23], [30]]", resultList.values.toString())
assertEquals("[1, 2, 4, 10, 12, 15]", resultList.keys.toString())
}
@Test
fun whenWithIndexGroupBy_thenListIsSplit() {
val resultList = evenList.withIndex()
.groupBy { it.index / 2 }
.map { it.value.map { it.value } }
verifyList(resultList)
}
@Test
fun whenWithIndexGroupByUneven_thenListIsSplit() {
val resultList = unevenList.withIndex()
.groupBy { it.index / 2 }
.map { it.value.map { it.value } }
verifyPartialList(resultList)
}
@Test
fun whenFoldIndexed_thenListIsSplit() {
val resultList = evenList.foldIndexed(ArrayList<ArrayList<Any>>(evenList.size / 2)) { index, acc, item ->
if (index % 2 == 0) {
acc.add(ArrayList(2))
}
acc.last().add(item)
acc
}
verifyList(resultList)
}
}
@@ -0,0 +1,47 @@
package stringcomparison
import org.junit.Test
import kotlin.test.assertFalse
import kotlin.test.assertTrue
class StringComparisonUnitTest {
@Test
fun `compare using equals operator`() {
val first = "kotlin"
val second = "kotlin"
val firstCapitalized = "KOTLIN"
assertTrue { first == second }
assertFalse { first == firstCapitalized }
}
@Test
fun `compare using referential equals operator`() {
val first = "kotlin"
val second = "kotlin"
val copyOfFirst = buildString { "kotlin" }
assertTrue { first === second }
assertFalse { first === copyOfFirst }
}
@Test
fun `compare using equals method`() {
val first = "kotlin"
val second = "kotlin"
val firstCapitalized = "KOTLIN"
assertTrue { first.equals(second) }
assertFalse { first.equals(firstCapitalized) }
assertTrue { first.equals(firstCapitalized, true) }
}
@Test
fun `compare using compare method`() {
val first = "kotlin"
val second = "kotlin"
val firstCapitalized = "KOTLIN"
assertTrue { first.compareTo(second) == 0 }
assertTrue { first.compareTo(firstCapitalized) == 32 }
assertTrue { firstCapitalized.compareTo(first) == -32 }
assertTrue { first.compareTo(firstCapitalized, true) == 0 }
}
}
@@ -0,0 +1,63 @@
package com.baeldung.voidtypes
import org.junit.jupiter.api.Test
import kotlin.test.assertNull
import kotlin.test.assertTrue
class VoidTypesUnitTest {
// Un-commenting below methods will result into compilation error
// as the syntax used is incorrect and is used for explanation in tutorial.
// fun returnTypeAsVoidAttempt1(): Void {
// println("Trying with Void as return type")
// }
// fun returnTypeAsVoidAttempt2(): Void {
// println("Trying with Void as return type")
// return null
// }
fun returnTypeAsVoidSuccess(): Void? {
println("Function can have Void as return type")
return null
}
fun unitReturnTypeForNonMeaningfulReturns(): Unit {
println("No meaningful return")
}
fun unitReturnTypeIsImplicit() {
println("Unit Return type is implicit")
}
fun alwaysThrowException(): Nothing {
throw IllegalArgumentException()
}
fun invokeANothingOnlyFunction() {
alwaysThrowException()
var name = "Tom"
}
@Test
fun givenJavaVoidFunction_thenMappedToKotlinUnit() {
assertTrue(System.out.println() is Unit)
}
@Test
fun givenVoidReturnType_thenReturnsNullOnly() {
assertNull(returnTypeAsVoidSuccess())
}
@Test
fun givenUnitReturnTypeDeclared_thenReturnsOfTypeUnit() {
assertTrue(unitReturnTypeForNonMeaningfulReturns() is Unit)
}
@Test
fun givenUnitReturnTypeNotDeclared_thenReturnsOfTypeUnit() {
assertTrue(unitReturnTypeIsImplicit() is Unit)
}
}
@@ -0,0 +1,5 @@
Hello to Kotlin. Its:
1. Concise
2. Safe
3. Interoperable
4. Tool-friendly
@@ -0,0 +1,2 @@
Kotlin
Concise, Safe, Interoperable, Tool-friendly