Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add extension module for kotest property testing #234

Merged
merged 31 commits into from
Apr 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
e8078ca
Add gradle versions catalog
serpro69 Apr 6, 2024
d61764f
Add pseudo-implementation of kotest Arb
serpro69 Apr 7, 2024
a95c1b8
Wip codegen
serpro69 Apr 7, 2024
b70f36f
Change FakerArb annotation to accept AbstractFakers
serpro69 Apr 8, 2024
80dc043
Dirty but working version
serpro69 Apr 11, 2024
5ee90c7
Add Arb.Companion extension properties for arb fakers
serpro69 Apr 11, 2024
66aaba1
Update tests
serpro69 Apr 11, 2024
d2e41ce
Add extension for randomClassInstance
serpro69 Apr 11, 2024
c475a04
Remove unused stuff
serpro69 Apr 11, 2024
ffaedf3
Split annotation and Arb extension into own module
serpro69 Apr 11, 2024
d0271e9
Add unit tests for :kotest-property
serpro69 Apr 11, 2024
e910a5f
Add some details to readmes
serpro69 Apr 11, 2024
2a9887a
Add badges for :faker modules
serpro69 Apr 11, 2024
4d1e677
Remove unused code and refactor
serpro69 Apr 13, 2024
2d7e7d1
Add docs for the extension
serpro69 Apr 14, 2024
3947ec5
Fix kotest-property-test build configuration
serpro69 Apr 14, 2024
50b6ea2
Fix kotest-property build configuration
serpro69 Apr 14, 2024
54290f4
Add api dump
serpro69 Apr 14, 2024
c8b1f7c
Configure semantic-versioning tags for :extension modules
serpro69 Apr 14, 2024
89ad483
Cleanup :extensions build.gradle files
serpro69 Apr 14, 2024
774a6f8
Add faker-ext-conventions buildSrc plugin for faker extensions
serpro69 Apr 14, 2024
4d9eb25
Add integration tests
serpro69 Apr 14, 2024
976050f
Fix wrapping of spaces in a generated function
serpro69 Apr 15, 2024
e24b69c
Exclude generation for deprecated functions with Error level
serpro69 Apr 15, 2024
a1ccfa5
Handle functions with deprecated annotations with non-Error level
serpro69 Apr 15, 2024
60b066f
Fix task dependency
serpro69 Apr 15, 2024
903e40e
Disable tasks for :extension and :faker modules
serpro69 Apr 15, 2024
1d1cac5
Disable tasks in empty modules
serpro69 Apr 15, 2024
78ad37b
Remove empty api dumps
serpro69 Apr 15, 2024
7148ade
Remove shadow plugin from ext-conventions
serpro69 Apr 15, 2024
0e9b289
Update snapshot publish workflow to include extension modules
serpro69 Apr 16, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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