diff --git a/README.md b/README.md index fa5fda8d..c9d0f628 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ Here is the highlights of **Muscle and Fitness Server**: 1. Each microservice is organized by [Domain Driven Design](https://en.wikipedia.org/wiki/Domain-driven_design) (DDD) structure. -1. Based on Java - [![](https://img.shields.io/badge/OpenJDK-Temurin%2017.0.3+7-informational?style=flat&logo=java&logoColor=white&color=2bbc8a)](https://github.com/adoptium/temurin17-binaries/releases/tag/jdk-17.0.3%2B7) and Kotlin - [![](https://img.shields.io/badge/Kotlin-1.6.21-informational?style=flat&logo=kotlin&logoColor=white&color=2bbc8a)](https://github.com/JetBrains/kotlin/releases/tag/v1.6.21), built by Gradle multi-module management [![](https://img.shields.io/badge/Gradle-7.5.1-informational?style=flat&logo=gradle&logoColor=white&color=2bbc8a)](https://github.com/gradle/gradle/releases/tag/v7.5.1). Inherited from the most modern and newest Spring frameworks: +1. Based on Java - [![](https://img.shields.io/badge/OpenJDK-Temurin%2017.0.4+8-informational?style=flat&logo=java&logoColor=white&color=2bbc8a)](https://github.com/adoptium/temurin17-binaries/releases/tag/jdk-17.0.4%2B8) and Kotlin - [![](https://img.shields.io/badge/Kotlin-1.6.21-informational?style=flat&logo=kotlin&logoColor=white&color=2bbc8a)](https://github.com/JetBrains/kotlin/releases/tag/v1.6.21), built by Gradle multi-module management [![](https://img.shields.io/badge/Gradle-7.5.1-informational?style=flat&logo=gradle&logoColor=white&color=2bbc8a)](https://github.com/gradle/gradle/releases/tag/v7.5.1). Inherited from the most modern and newest Spring frameworks: `org.springframework.boot:spring-boot-starter-parent` - [![Spring Boot](https://maven-badges.herokuapp.com/maven-central/org.springframework.boot/spring-boot-starter-parent/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.springframework.boot/spring-boot-starter-parent/) `org.springframework.cloud:spring-cloud-dependencies` - [![Spring Cloud](https://maven-badges.herokuapp.com/maven-central/org.springframework.cloud/spring-cloud-dependencies/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.springframework.cloud/spring-cloud-dependencies/) @@ -186,6 +186,13 @@ Here is the highlights of **Muscle and Fitness Server**: 1. Require the expression to be true, otherwise throws an exception (if provided). + ```kotlin + import com.jmsoftware.maf.springcloudstarter.function.* + + requireTrue(1 != 1) { anotherBoolean: Boolean? -> log.info("aBoolean = $anotherBoolean") } + .orElseThrow { IllegalArgumentException("aBoolean is expected to be true") } + ``` + ```java import static com.jmsoftware.maf.springcloudstarter.function.BooleanCheck.requireTrue; @@ -195,6 +202,21 @@ Here is the highlights of **Muscle and Fitness Server**: 2. Make Function have cache ability. + ```kotlin + val cacheMap = mutableMapOf("key1" to "1", "key2" to "2") + val stringProcess = Function { input: String -> + log.info("No cache return value found. input: $input Re-calculating…") + StrUtil.subSuf(input, 3) + } + val result1 = cacheFunction(stringProcess, "key1", cacheMap) + val result2 = cacheFunction(stringProcess, "key2", cacheMap) + val result3 = cacheFunction(stringProcess, "key3", cacheMap) + assertEquals("1", result1) + assertEquals("2", result2) + assertEquals("3", result3) + assertEquals(3, cacheMap.size) + ``` + ```java val cacheMap = Maps.newHashMap(); cacheMap.put("key1", "1"); @@ -206,6 +228,10 @@ Here is the highlights of **Muscle and Fitness Server**: val result1 = cacheFunction(stringProcess, "key1", cacheMap); val result2 = cacheFunction(stringProcess, "key2", cacheMap); val result3 = cacheFunction(stringProcess, "key3", cacheMap); + assertEquals("1", result1); + assertEquals("2", result2); + assertEquals("3", result3); + assertEquals(3, cacheMap.size); ``` diff --git a/spring-cloud-starter/src/test/kotlin/com/jmsoftware/maf/springcloudstarter/FunctionTests.kt b/spring-cloud-starter/src/test/kotlin/com/jmsoftware/maf/springcloudstarter/FunctionTests.kt index 5beecae5..79205456 100644 --- a/spring-cloud-starter/src/test/kotlin/com/jmsoftware/maf/springcloudstarter/FunctionTests.kt +++ b/spring-cloud-starter/src/test/kotlin/com/jmsoftware/maf/springcloudstarter/FunctionTests.kt @@ -3,12 +3,10 @@ package com.jmsoftware.maf.springcloudstarter import cn.hutool.core.util.StrUtil import com.google.common.cache.CacheBuilder import com.google.common.cache.RemovalNotification -import com.google.common.collect.Maps import com.jmsoftware.maf.common.util.logger import com.jmsoftware.maf.springcloudstarter.function.* import fj.Show -import org.junit.jupiter.api.Assertions -import org.junit.jupiter.api.Assertions.assertThrows +import org.junit.jupiter.api.Assertions.* import org.junit.jupiter.api.Test import org.junit.jupiter.api.parallel.Execution import org.junit.jupiter.api.parallel.ExecutionMode @@ -35,9 +33,8 @@ internal class FunctionTests { fun testRequireTrue() { assertThrows( IllegalArgumentException::class.java, { - requireTrue(false) { anotherBoolean: Boolean? -> - log.info("aBoolean = $anotherBoolean") - }.orElseThrow { IllegalArgumentException("aBoolean is expected to be true") } + requireTrue(false) { anotherBoolean: Boolean? -> log.info("aBoolean = $anotherBoolean") } + .orElseThrow { IllegalArgumentException("aBoolean is expected to be true") } }, "requireTrue doesn't throws exception" ) @@ -55,40 +52,37 @@ internal class FunctionTests { */ @Test fun testCacheFunction() { - val cacheMap = Maps.newHashMap() - cacheMap["key1"] = "1" - cacheMap["key2"] = "2" + val cacheMap = mutableMapOf("key1" to "1", "key2" to "2") val stringProcess = Function { input: String -> log.info("No cache return value found. input: $input Re-calculating…") StrUtil.subSuf(input, 3) } - val result1 = cacheFunction(stringProcess, "key1", cacheMap) - val result2 = cacheFunction(stringProcess, "key2", cacheMap) - val result3 = cacheFunction(stringProcess, "key3", cacheMap) - Assertions.assertEquals("1", result1) - Assertions.assertEquals("2", result2) - Assertions.assertEquals("3", result3) - Assertions.assertEquals(3, cacheMap.size) + val result1 = cacheFunction(stringProcess, "key1", cacheMap) + val result2 = cacheFunction(stringProcess, "key2", cacheMap) + val result3 = cacheFunction(stringProcess, "key3", cacheMap) + assertEquals("1", result1) + assertEquals("2", result2) + assertEquals("3", result3) + assertEquals(3, cacheMap.size) val guavaCache = CacheBuilder .newBuilder() .maximumSize(2) .expireAfterWrite(Duration.ofSeconds(3)) .removalListener { notification: RemovalNotification? -> log.info("Removed cache: $notification") - } - .build() + }.build() guavaCache.put("key4", "4") guavaCache.put("key5", "5") - val result4 = cacheFunction(stringProcess, "key4", guavaCache) - val result5 = cacheFunction(stringProcess, "key5", guavaCache) - val result6 = cacheFunction(stringProcess, "key6", guavaCache) + val result4 = cacheFunction(stringProcess, "key4", guavaCache) + val result5 = cacheFunction(stringProcess, "key5", guavaCache) + val result6 = cacheFunction(stringProcess, "key6", guavaCache) Show.anyShow().print("Before cache invalidated: ") Show.anyShow().println(guavaCache.asMap().entries) - Assertions.assertEquals("4", result4) - Assertions.assertEquals("5", result5) - Assertions.assertEquals("6", result6) + assertEquals("4", result4) + assertEquals("5", result5) + assertEquals("6", result6) Thread.sleep(Duration.ofSeconds(4).toMillis()) - Assertions.assertNull(guavaCache.getIfPresent("key5"), "The value of Guava cache map is supposed to be null") + assertNull(guavaCache.getIfPresent("key5"), "The value of Guava cache map is supposed to be null") Show.anyShow().print("After cache invalidated: ") Show.anyShow().println(guavaCache.asMap().entries) } @@ -103,7 +97,7 @@ internal class FunctionTests { val result1 = computeAndHandleException(compute, 1, handleException) val result2 = computeAndHandleException(compute, 0, handleException) log.info("result1 = $result1, result2 = $result2") - Assertions.assertEquals(0.0, result2) + assertEquals(0.0, result2) } @Test @@ -111,7 +105,7 @@ internal class FunctionTests { val compute = ThrowExceptionFunction { value: Int? -> (1 / value!!).toDouble() } val result = computeOrGetDefault(compute, null, 0.0) log.info("computeOrGetDefault result = $result") - Assertions.assertEquals(0.0, result) + assertEquals(0.0, result) } @Test @@ -137,7 +131,7 @@ internal class FunctionTests { assertThrows(RuntimeException::class.java) { retryFunction(compute, 5) } val compute2 = Function { value: Int -> 1 + value } val result = retryFunction(compute2, -1, { integer: Int -> integer == 0 }, 3) - Assertions.assertEquals(0, result) + assertEquals(0, result) assertThrows( IllegalStateException::class.java ) { retryFunction(compute2, 1, Predicate { integer: Int -> integer == 0 }, 3) }