diff --git a/.editorconfig b/.editorconfig index 6fc7e1c..eb5f18f 100644 --- a/.editorconfig +++ b/.editorconfig @@ -27,3 +27,4 @@ indent_size = 4 max_line_length = 100 ij_kotlin_name_count_to_use_star_import = 999 ij_kotlin_name_count_to_use_star_import_for_members = 999 +ktlint_function_naming_ignore_when_annotated_with = "Test" diff --git a/.idea/externalDependencies.xml b/.idea/externalDependencies.xml index 9d0a9c4..e9f3987 100644 --- a/.idea/externalDependencies.xml +++ b/.idea/externalDependencies.xml @@ -4,5 +4,6 @@ - + + diff --git a/.mvn/maven.config b/.mvn/maven.config index 02f6928..d3c0da1 100644 --- a/.mvn/maven.config +++ b/.mvn/maven.config @@ -1,2 +1,3 @@ -Dkotlin.compiler.incremental=true +-Dmaven.install.skip=true -T12C diff --git a/Makefile b/Makefile index df04911..b2948d6 100644 --- a/Makefile +++ b/Makefile @@ -1,2 +1,5 @@ build: mvn clean verify site +lint: + # brew install ktlint + ktlint --format diff --git a/README.md b/README.md index 1eccbfb..7e3c540 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,13 @@ -# awesome-kotlin-maven-template +# Finchly +## Helper utilities for integration testing -[![Kotlin CI with Maven](https://github.com/kpavlov/awesome-kotlin-maven-template/actions/workflows/maven.yml/badge.svg?branch=main)](https://github.com/kpavlov/awesome-kotlin-maven-template/actions/workflows/maven.yml) -[![Codacy Badge](https://app.codacy.com/project/badge/Grade/644f664ad05a4a009b299bc24c8be4b8)](https://app.codacy.com/gh/kpavlov/langchain4j-kotlin/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade) -[![Codacy Coverage](https://app.codacy.com/project/badge/Coverage/644f664ad05a4a009b299bc24c8be4b8)](https://app.codacy.com/gh/kpavlov/langchain4j-kotlin/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_coverage) +[![Kotlin CI with Maven](https://github.com/kpavlov/finchly/actions/workflows/maven.yml/badge.svg?branch=main)](https://github.com/kpavlov/finchly/actions/workflows/maven.yml) +[![Codacy Badge](https://app.codacy.com/project/badge/Grade/3aa0b5847e70494d9795ff98aa14b386)](https://app.codacy.com/gh/kpavlov/langchain4j-kotlin/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade) +[![Codacy Coverage](https://app.codacy.com/project/badge/Coverage/3aa0b5847e70494d9795ff98aa14b386)](https://app.codacy.com/gh/kpavlov/langchain4j-kotlin/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_coverage) +![logo](docs/finchly-logo.webp) -## How to run - -Create `.env` file in root directory and add your API keys: - -```dotenv -OPENAI_API_KEY=sk-xxxxx -``` +## How to build Building project locally: ```shell @@ -22,8 +18,3 @@ or make build ``` -## Acknowledgements - -Training data from Project Gutenberg: - -- [CAPTAIN BLOOD By Rafael Sabatini](https://www.gutenberg.org/cache/epub/1965/pg1965.txt) diff --git a/bom/pom.xml b/bom/pom.xml index ea95c3f..68e58a8 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -4,23 +4,23 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - me.kpavlov.project - project-aggregator + me.kpavlov.finchly + aggregator 1.0-SNAPSHOT bom pom - Project :: BOM - Bill of Materials POM for getting full, complete set of compatible versions of LangChain4j modules + Finchly :: BOM + Bill of Materials POM for getting full, complete set of compatible versions of Finchly modules me.kpavlov.project - core + wiremock ${project.parent.version} diff --git a/detekt.yml b/detekt.yml new file mode 100644 index 0000000..60edf25 --- /dev/null +++ b/detekt.yml @@ -0,0 +1,8 @@ +style: + active: true + MethodName: + active: true + ignoreOverriddenFunctions: true + excludeAnnotatedMethodsOrClasses: + - "org.junit.jupiter.api.Test" + ignoreTestFiles: true diff --git a/docs/finchly-logo.webp b/docs/finchly-logo.webp new file mode 100644 index 0000000..d3d0945 Binary files /dev/null and b/docs/finchly-logo.webp differ diff --git a/parent/pom.xml b/parent/pom.xml index f6803a5..1c0555e 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -4,14 +4,14 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - me.kpavlov.project + me.kpavlov.finchly parent 1.0-SNAPSHOT pom Project :: Parent POM Parent POM for Project modules - https://github.com/kpavlov/awesome-kotlin-maven-template + https://github.com/kpavlov/finchly UTF-8 @@ -22,10 +22,12 @@ ${java.version} + 0.28.1 1.9.0 5.11.3 4.2.2 6.4.2 + 3.9.2 @@ -36,6 +38,8 @@ + ${project.basedir}/src/main/kotlin + ${project.basedir}/src/test/kotlin @@ -46,7 +50,6 @@ -Xjsr305=strict - -Werror @@ -156,24 +159,38 @@ ${kotlinx.version} test + + com.willowtreeapps.assertk + assertk-jvm + ${assertk.version} + test + + + com.willowtreeapps.assertk + assertk-coroutines-jvm + ${assertk.version} + test + org.jetbrains.kotlin - kotlin-test-junit5 - test + kotlin-stdlib + ${kotlin.version} + org.junit.jupiter - junit-jupiter-params + junit-jupiter-api ${junit.version} test - org.jetbrains.kotlin - kotlin-stdlib - ${kotlin.version} + com.willowtreeapps.assertk + assertk-jvm + ${assertk.versopn} + test diff --git a/pom.xml b/pom.xml index 3499bd8..e5b597b 100644 --- a/pom.xml +++ b/pom.xml @@ -4,8 +4,8 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - me.kpavlov.project - project-aggregator + me.kpavlov.finchly + aggregator 1.0-SNAPSHOT pom Project :: Aggregator @@ -13,11 +13,20 @@ parent bom - core + wiremock reports + + + + org.apache.maven.plugins + maven-site-plugin + 3.21.0 + + + org.apache.maven.plugins diff --git a/renovate.json5 b/renovate.json5 index c5e3fe6..63b8d2e 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -8,7 +8,7 @@ "packageRules": [ { "matchPackageNames": [ - "me.kpavlov.project" + "me.kpavlov.finchly" ], "enabled": false }, diff --git a/reports/pom.xml b/reports/pom.xml index 365d9b5..934343b 100644 --- a/reports/pom.xml +++ b/reports/pom.xml @@ -4,15 +4,15 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - me.kpavlov.project - project-aggregator + me.kpavlov.finchly + aggregator 1.0-SNAPSHOT ../pom.xml reports pom - Project :: Reports + Finchly :: Reports true @@ -20,8 +20,8 @@ - me.kpavlov.project - core + me.kpavlov.finchly + wiremock ${project.parent.version} diff --git a/wiremock/pom.xml b/wiremock/pom.xml new file mode 100644 index 0000000..be4a59c --- /dev/null +++ b/wiremock/pom.xml @@ -0,0 +1,26 @@ + + + 4.0.0 + + me.kpavlov.finchly + parent + 1.0-SNAPSHOT + ../parent/pom.xml + + + wiremock + Finchly :: Wiremock + + + + + org.wiremock + wiremock-standalone + ${wiremock.version} + compile + + + + diff --git a/wiremock/src/main/kotlin/me/kpavlov/finchly/wiremock/BaseWiremock.kt b/wiremock/src/main/kotlin/me/kpavlov/finchly/wiremock/BaseWiremock.kt new file mode 100644 index 0000000..bd7f73a --- /dev/null +++ b/wiremock/src/main/kotlin/me/kpavlov/finchly/wiremock/BaseWiremock.kt @@ -0,0 +1,69 @@ +package me.kpavlov.finchly.wiremock + +import com.github.tomakehurst.wiremock.WireMockServer +import com.github.tomakehurst.wiremock.client.VerificationException + +/** + * Base class for managing a WireMock server instance. + * + * The server is started upon initialization. + * Provides utility methods for managing stub mappings and verifying unmatched requests. + * + * @param mock The WireMock server instance to manage. + */ +public abstract class BaseWiremock( + protected val mock: WireMockServer, +) { + init { + mock.start() + } + + /** + * Retrieves the port number on which the WireMock server instance is running. + * + * @return the port number on which the WireMock server instance is listening. + */ + public fun port(): Int = mock.port() + + /** + * Removes a specific stub mapping from the WireMock server. + * + * @param mapping The stub mapping to remove. + */ + public fun resetStub(mapping: com.github.tomakehurst.wiremock.stubbing.StubMapping) { + mock.removeStub(mapping) + } + + /** + * Resets all the stub mappings in the WireMock server instance. + * + * This function clears all the stub mappings that have been set up in the WireMock server. + * After calling this method, the server will no longer have any of the previously configured stubs. + */ + public fun resetAllStubs() { + mock.resetAll() + } + + /** + * Verifies that there are no unmatched requests for the WireMock server. + * + * This function checks the WireMock server for any requests that were not matched against + * any stub mappings. If there are unmatched requests, it will find near misses and throw an + * appropriate `VerificationException`. + * + * @throws VerificationException if there are unmatched requests or near misses. + */ + public fun verifyNoUnmatchedRequests() { + val unmatchedRequests = mock.findAllUnmatchedRequests() + if (unmatchedRequests.isEmpty()) { + return + } + println("Unmatched requests: $unmatchedRequests") + val nearMisses = mock.findNearMissesForAllUnmatchedRequests() + if (nearMisses.isEmpty()) { + throw VerificationException.forUnmatchedRequests(unmatchedRequests) + } else { + throw VerificationException.forUnmatchedNearMisses(nearMisses) + } + } +} diff --git a/wiremock/src/test/kotlin/me/kpavlov/finchly/wiremock/BaseWiremockTest.kt b/wiremock/src/test/kotlin/me/kpavlov/finchly/wiremock/BaseWiremockTest.kt new file mode 100644 index 0000000..0c90ed1 --- /dev/null +++ b/wiremock/src/test/kotlin/me/kpavlov/finchly/wiremock/BaseWiremockTest.kt @@ -0,0 +1,51 @@ +package me.kpavlov.finchly.wiremock + +import assertk.assertThat +import assertk.assertions.isEqualTo +import com.github.tomakehurst.wiremock.WireMockServer +import com.github.tomakehurst.wiremock.client.WireMock +import com.github.tomakehurst.wiremock.core.WireMockConfiguration +import org.junit.jupiter.api.Test +import java.net.URI +import java.net.http.HttpClient +import java.net.http.HttpRequest +import java.net.http.HttpResponse + +class BaseWiremockTest { + private val mock = + object : BaseWiremock( + WireMockServer( + WireMockConfiguration.wireMockConfig().dynamicPort(), + ), + ) { + fun shouldSayHello() { + mock.stubFor( + WireMock + .get("/hello") + .willReturn( + WireMock.ok("Hello"), + ), + ) + } + } + + private val client = HttpClient.newHttpClient() + private val port = mock.port() + + @Test + fun `Should mock method`() { + // given + mock.shouldSayHello() + // when + val request = + HttpRequest + .newBuilder() + .uri(URI.create("http://localhost:$port/hello")) + .build() + + val response = client.send(request, HttpResponse.BodyHandlers.ofString()) + + // then + assertThat(response.body()).isEqualTo("Hello") + } +}