Skip to content

Commit

Permalink
Add extension module for kotest property testing (#234)
Browse files Browse the repository at this point in the history
  • Loading branch information
serpro69 authored Apr 17, 2024
1 parent 021b952 commit 0a048c0
Show file tree
Hide file tree
Showing 49 changed files with 1,752 additions and 90 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/publish_snapshot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,12 @@ jobs:
filters: |
core:
- '.github/workflows/**'
- 'bom/**'
- 'buildSrc/**'
- 'core/**'
- 'extension/**'
- 'faker/**'
- 'gradle/**'
- '*gradle*'
- 'set-version.sh'
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
[discrete]
=== Added

* https://github.com/serpro69/kotlin-faker/pull/234[#234] (:extension) Add extension module for kotest property testing
* https://github.com/serpro69/kotlin-faker/pull/232[#232] (:core) Add support for alternative primary key when resolving values
* https://github.com/serpro69/kotlin-faker/pull/227[#227] Add BOM to manage faker versions
* https://github.com/serpro69/kotlin-faker/issues/222[#222] (:faker:databases) Create new Databases faker module
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ See [bom/README.md](bom/README.md) for more details.

Extra fakers covering a wide range of domains are available as separate dependencies. See [faker](faker) submodules in this repo for more details about each faker.

### Third-Party Extensions

Faker provides extensions for some third-party testing libraries. See [extension](extension) submodules in this repo for more details about each extension.

## Usage

Full usage documentation for kotlin-faker is available at [serpro69.github.io/kotlin-faker/](https://serpro69.github.io/kotlin-faker/).
Expand Down
19 changes: 5 additions & 14 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,13 @@ plugins {
id("org.jetbrains.kotlinx.binary-compatibility-validator") version "0.15.0-Beta.1"
}

repositories {
mavenCentral()
}

group = "io.github.serpro69"

val lib = project.libs

subprojects {
group = rootProject.group.toString()

repositories {
mavenCentral()
}

apply {
plugin("com.github.ben-manes.versions")
}
Expand All @@ -44,12 +38,9 @@ subprojects {
val testImplementation by configurations
val testRuntimeOnly by configurations
// common-for-all dependencies go here
platform(kotlin("bom"))
implementation(kotlin("stdlib-jdk8"))
implementation(kotlin("reflect"))
testImplementation("io.kotest:kotest-runner-junit5:5.7.2")
testImplementation("io.kotest:kotest-assertions-core:5.7.2")
testImplementation("io.kotest:kotest-property-jvm:5.7.2")
implementation(platform(lib.kotlin.bom))
implementation(lib.bundles.kotlin)
testImplementation(lib.bundles.test.kotest)
}

configure<JavaPluginExtension> {
Expand Down
19 changes: 7 additions & 12 deletions buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
plugins {
`kotlin-dsl`
}

repositories {
mavenCentral()
gradlePluginPortal()
kotlin("jvm") version embeddedKotlinVersion
}

dependencies {
//https://github.com/gradle/gradle/issues/15383#issuecomment-779893192
implementation(files(libs.javaClass.superclass.protectionDomain.codeSource.location))
implementation(platform(libs.kotlin.bom))
// needed to be able to apply external plugin
// https://docs.gradle.org/current/userguide/custom_plugins.html#applying_external_plugins_in_precompiled_script_plugins
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.20")
implementation("org.jetbrains.dokka:dokka-gradle-plugin:1.9.10")
implementation("com.github.johnrengelman:shadow:8.1.1")
implementation(libs.bundles.gradle.plugins)
// used by yaml-to-json buildSrc plugin
implementation("com.fasterxml.jackson.core:jackson-databind:2.15.3")
implementation(libs.jackson.databind)
// use snakeyaml instead of jackson-dataformat-yaml to properly handle yaml anchors and write them as actual values to json
implementation("org.yaml:snakeyaml:2.2")
// NB! remember to set same version in settings.gradle.kts:13
implementation("io.github.serpro69:semantic-versioning:0.13.0")
implementation(libs.snakeyaml)
}
18 changes: 18 additions & 0 deletions buildSrc/repositories.settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// shared repository definitions for both the main project and buildSrc

@Suppress("UnstableApiUsage") // Central declaration of repositories is an incubating feature
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)

repositories {
mavenCentral()
gradlePluginPortal()
}

pluginManagement {
repositories {
gradlePluginPortal()
mavenCentral()
}
}
}
13 changes: 13 additions & 0 deletions buildSrc/settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")

rootProject.name = "buildSrc"

apply(from = "./repositories.settings.gradle.kts")

dependencyResolutionManagement {
versionCatalogs {
create("libs") {
from(files("../gradle/libs.versions.toml"))
}
}
}
190 changes: 190 additions & 0 deletions buildSrc/src/main/kotlin/faker-ext-conventions.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
import io.github.serpro69.semverkt.gradle.plugin.tasks.TagTask
import org.gradle.accessors.dm.LibrariesForLibs
import org.jetbrains.dokka.gradle.DokkaTask
import java.util.Locale

plugins {
base
kotlin("jvm")
id("org.jetbrains.dokka")
`maven-publish`
signing
}

val libs = the<LibrariesForLibs>()

/**
* For additional providers, use a combination of rootProject and subproject names for artifact name and similar things.
* i.e. kotlin-faker-books, kotlin-faker-movies, kotlin-faker-tv, ...
*
* The "core" lib retains the same name as before: kotlin-faker
*/
private val fullName: String = "${rootProject.name}-${project.name}"

val isDev = provider { version.toString().startsWith("0.0.0") }
val isSnapshot = provider {
// QUESTION do we need to check if rootProject is also set to snapshot?
// Likely not, since "isRelease" will not just check for the version, but also for the actual tag creation
// rootProject.version.toString().endsWith("SNAPSHOT") &&
version.toString().endsWith("SNAPSHOT")
}
val isRelease = provider {
val tag = project.tasks.getByName("tag", TagTask::class)
/* all fakers have their own tags, so checking if tag.didWork is enough for them,
':core' shares the tag with 'root', ':bom' and ':cli-bot' modules,
and hence the tag might already exist and didWork will return false for ':core' */
val tagCreated = if (project.name != "core") tag.didWork else tag.didWork || tag.tagExists
!isDev.get() && !isSnapshot.get() && tagCreated
}

configurations {
create("integrationImplementation") { extendsFrom(configurations.getByName("testImplementation")) }
create("integrationRuntimeOnly") {
extendsFrom(
configurations.getByName("testRuntimeOnly"),
)
}
}

// configure sourceSets as extension since it's not available here as `sourceSets` is an extension on `Project`
// https://docs.gradle.org/current/userguide/kotlin_dsl.html#project_extensions_and_conventions
configure<SourceSetContainer> {
create("integration") {
resources.srcDir("src/integration/resources")
compileClasspath += main.get().compileClasspath + test.get().compileClasspath
runtimeClasspath += main.get().runtimeClasspath + test.get().runtimeClasspath
}
main {
resources {
this.srcDir("build/generated/src/main/resources")
}
}
}

dependencies {
val implementation by configurations
implementation(libs.bundles.kotlin)
}

val integrationTest by tasks.creating(Test::class) {
testClassesDirs = sourceSets["integration"].output.classesDirs
classpath = sourceSets["integration"].runtimeClasspath
dependsOn(tasks.test)
}

tasks.withType<Jar> {
archiveBaseName.set(fullName)

manifest {
attributes(
mapOf(
"Implementation-Title" to fullName,
"Implementation-Version" to project.version,
/*
* We can't add this here because this resolves the configuration,
* after which it effectively becomes read-only and we'll get an error
* Cannot change dependencies of dependency configuration ':core:implementation' after it has been included in dependency resolution
* if we try to add more dependencies in the module's build.gradle file directly
*/
// "Class-Path" to project.configurations.compileClasspath.get().joinToString(" ") { it.name }
)
)
}

dependsOn(integrationTest)
}

val sourcesJar by tasks.creating(Jar::class) {
archiveClassifier.set("sources")
from(sourceSets.getByName("main").allSource)
from("${rootProject.rootDir.resolve("LICENSE.adoc")}") {
into("META-INF")
}
}

val dokkaJavadocJar by tasks.creating(Jar::class) {
archiveClassifier.set("javadoc")
dependsOn(tasks.dokkaJavadoc)
from(tasks.dokkaJavadoc.get().outputDirectory.orNull)
}

artifacts {
archives(sourcesJar)
archives(dokkaJavadocJar)
}

val publicationName =
"faker${project.name.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }}"

publishing {
publications {
create<MavenPublication>(publicationName) {
groupId = project.group.toString()
artifactId = fullName
version = project.version.toString()
from(components["java"])
artifact(sourcesJar)
artifact(dokkaJavadocJar) //TODO configure dokka or use defaults?

pom {
packaging = "jar"
name.set(fullName)
description.set("Generate realistically looking fake data such as names, addresses, banking details, and many more, that can be used for testing and data anonymization purposes.")
url.set("https://github.com/serpro69/kotlin-faker")
scm {
connection.set("scm:git:https://github.com/serpro69/kotlin-faker")
developerConnection.set("scm:git:https://github.com/serpro69")
url.set("https://github.com/serpro69/kotlin-faker")
}
issueManagement {
url.set("https://github.com/serpro69/kotlin-faker/issues")
}
licenses {
license {
name.set("MIT")
url.set("https://opensource.org/licenses/mit-license.php")
}
}
developers {
developer {
id.set("serpro69")
name.set("Serhii Prodan")
}
}
}
}
}
}

tasks {
assemble {
dependsOn(integrationTest)
dependsOn(jar)
}
}

signing {
sign(publishing.publications[publicationName])
}

tasks.withType<DokkaTask>().configureEach {
onlyIf("Not dev") { !isDev.get() }
onlyIf("Release or snapshot") { isRelease.get() || isSnapshot.get() }
}

tasks.withType<PublishToMavenRepository>().configureEach {
dependsOn(project.tasks.getByName("tag"))
dependsOn(project.tasks.withType(Sign::class.java))
onlyIf("Not dev") { !isDev.get() }
onlyIf("Release or snapshot") { isRelease.get() || isSnapshot.get() }
}

tasks.withType<PublishToMavenLocal>().configureEach {
onlyIf("In development") { isDev.get() || isSnapshot.get() }
}

tasks.withType<Sign>().configureEach {
dependsOn(project.tasks.getByName("tag"))
onlyIf("Not dev and snapshot") { !isDev.get() && !isSnapshot.get() }
onlyIf("Release") { isRelease.get() }
}
11 changes: 7 additions & 4 deletions buildSrc/src/main/kotlin/faker-lib-conventions.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import com.github.jengelman.gradle.plugins.shadow.ShadowExtension
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import io.github.serpro69.semverkt.gradle.plugin.tasks.TagTask
import org.gradle.accessors.dm.LibrariesForLibs
import org.jetbrains.dokka.gradle.DokkaTask
import java.util.*

plugins {
base
`java-library`
kotlin("jvm")
id("org.jetbrains.dokka")
Expand All @@ -13,6 +15,8 @@ plugins {
signing
}

val libs = the<LibrariesForLibs>()

/**
* For additional providers, use a combination of rootProject and subproject names for artifact name and similar things.
* i.e. kotlin-faker-books, kotlin-faker-movies, kotlin-faker-tv, ...
Expand Down Expand Up @@ -69,8 +73,7 @@ dependencies {
val testImplementation by configurations
val testRuntimeOnly by configurations
val integrationImplementation by configurations
shadow(kotlin("stdlib-jdk8"))
shadow(kotlin("reflect"))
shadow(libs.bundles.kotlin)
testRuntimeOnly("ch.qos.logback:logback-core:1.3.4") {
version { strictly("1.3.4") /* last stable for java 8 */ }
}
Expand All @@ -79,8 +82,8 @@ dependencies {
}
testRuntimeOnly("org.codehaus.groovy:groovy:3.0.19")
// we're shadowing these so they need to be available for test runtime
testRuntimeOnly("com.ibm.icu:icu4j:73.2")
testRuntimeOnly("com.github.mifmif:generex:1.0.2")
testRuntimeOnly(libs.icu4j)
testRuntimeOnly(libs.generex)
}

val integrationTest by tasks.creating(Test::class) {
Expand Down
Loading

0 comments on commit 0a048c0

Please sign in to comment.