Repository: serpro69/kotlin-faker (kotlin)

Issue:
Prohibit invoking 'io.github.serpro69.kfaker.fakerConfig' inside 'faker' DSL
Would be nice to prohibit invoking `fakerConfig` inside the `faker` function to make the api more clearer.
Not sure if it's possible though.

```
fun main() {
    val faker1 = faker {
        fakerConfig {
            randomSeed = 42
            locale = "uk"
        }
    }

    val config = fakerConfig {
        randomSeed = 42
        locale = "uk"
    }
    val faker2 = Faker(config)

    println(faker1.separator.separator()) // &
    println(faker2.separator.separator()) // та
}
```

Pull request description:
Closes #80

Patch:
diff --git a/core/src/main/kotlin/io/github/serpro69/kfaker/Faker.kt b/core/src/main/kotlin/io/github/serpro69/kfaker/Faker.kt
index b8f4eb73c6..9fc15b925a 100644
--- a/core/src/main/kotlin/io/github/serpro69/kfaker/Faker.kt
+++ b/core/src/main/kotlin/io/github/serpro69/kfaker/Faker.kt
@@ -9,15 +9,20 @@ import io.github.serpro69.kfaker.provider.unique.GlobalUniqueDataDataProvider
  * Provides access to fake data generators.
  *
  * Each category (generator) from this [Faker] is represented by a property that has the same name as the `.yml` file.
+ *
+ * @property random provides public access to functions of [RandomService].
+ * @property randomProvider provides additional functionality that is not covered by other data providers
+ * such as [address], [name], [internet], and so on. See [RandomProvider] for more details.
+ * @property unique global provider for generation of unique values.
  */
-class Faker @JvmOverloads constructor(internal val fakerConfig: FakerConfig = fakerConfig {  }) {
-    private val fakerService: FakerService = FakerService(this, fakerConfig.locale, fakerConfig.random)
+class Faker @JvmOverloads constructor(internal val config: FakerConfig = fakerConfig { }) {
+    private val fakerService: FakerService = FakerService(this, config.locale, config.random)
 
-    val random = RandomService(fakerConfig.random)
+    val random = RandomService(config.random)
 
     val unique = GlobalUniqueDataDataProvider()
 
-    val randomProvider: RandomProvider = RandomProvider(fakerConfig.random)
+    val randomProvider: RandomProvider = RandomProvider(config.random)
 
     val separator: Separator = Separator(fakerService)
     val currencySymbol: CurrencySymbol = CurrencySymbol(fakerService)
@@ -193,10 +198,19 @@ class Faker @JvmOverloads constructor(internal val fakerConfig: FakerConfig = fa
 
     @FakerDsl
     class Builder internal constructor(){
-        private var config = fakerConfig { }
+        private var config = io.github.serpro69.kfaker.fakerConfig { }
 
+        @Deprecated(
+            message = "This API is unstable and might change in the final 1.8.0 release.",
+            level = DeprecationLevel.WARNING,
+            replaceWith = ReplaceWith(expression = "fakerConfig{ }")
+        )
         fun config(block: FakerConfig.Builder.() -> Unit) {
-            this.config = fakerConfig(block)
+            config = io.github.serpro69.kfaker.fakerConfig(block)
+        }
+
+        fun fakerConfig(block: FakerConfig.Builder.() -> Unit) {
+            config = io.github.serpro69.kfaker.fakerConfig(block)
         }
 
         internal fun build() = Faker(config)
diff --git a/core/src/main/kotlin/io/github/serpro69/kfaker/RandomService.kt b/core/src/main/kotlin/io/github/serpro69/kfaker/RandomService.kt
index 7e618541cb..32049c6a07 100644
--- a/core/src/main/kotlin/io/github/serpro69/kfaker/RandomService.kt
+++ b/core/src/main/kotlin/io/github/serpro69/kfaker/RandomService.kt
@@ -5,7 +5,15 @@ import kotlin.experimental.and
 import kotlin.experimental.or
 
 /**
- * Wrapper around [Random] that contains some extra helper functions.
+ * Wrapper around [Random] that also contains some additional functions not covered by [Random].
+ *
+ * If two instances of this [RandomService] are created with the same seed,
+ * and the same sequence of method calls is made for each,
+ * then they will generate and return identical sequences of values.
+ *
+ * Instances of [RandomService] are not cryptographically secure by default.
+ * Consider passing [java.security.SecureRandom] to the constructor of this [RandomService]
+ * to get a cryptographically secure pseudo-random generator.
  */
 class RandomService internal constructor(private val random: Random) {
     private val alphabeticSource = "abcdefghijklmnopqrstuvwxyz"
diff --git a/core/src/main/kotlin/io/github/serpro69/kfaker/provider/AbstractFakeDataProvider.kt b/core/src/main/kotlin/io/github/serpro69/kfaker/provider/AbstractFakeDataProvider.kt
index 97618352c4..aced3d0cba 100644
--- a/core/src/main/kotlin/io/github/serpro69/kfaker/provider/AbstractFakeDataProvider.kt
+++ b/core/src/main/kotlin/io/github/serpro69/kfaker/provider/AbstractFakeDataProvider.kt
@@ -120,7 +120,7 @@ abstract class AbstractFakeDataProvider<T : FakeDataProvider> internal construct
         }
 
         val globalUniqueProvider = fakerService.faker.unique
-        val fakerConfig = fakerService.faker.fakerConfig
+        val fakerConfig = fakerService.faker.config
 
         val key = listOfNotNull(primaryKey, secondaryKey, thirdKey).joinToString("$")
 


Test patch:
diff --git a/core/src/test/kotlin/io/github/serpro69/kfaker/FakerConfigTest.kt b/core/src/test/kotlin/io/github/serpro69/kfaker/FakerConfigTest.kt
index 68ce36a2ad..9cdc25c8a5 100644
--- a/core/src/test/kotlin/io/github/serpro69/kfaker/FakerConfigTest.kt
+++ b/core/src/test/kotlin/io/github/serpro69/kfaker/FakerConfigTest.kt
@@ -54,7 +54,7 @@ class FakerConfigTest : DescribeSpec() {
         }
 
         describe("randomSeed is set through FakerConfig") {
-            val fakerConfig = fakerConfig { random = Random(42) }
+            val fakerConfig = fakerConfig { randomSeed = 42 }
 
             val faker = Faker(fakerConfig)
 
@@ -62,7 +62,7 @@ class FakerConfigTest : DescribeSpec() {
             val name1 = faker.name.name()
 
             context("another randomSeed is set with the same value") {
-                val otherFakerConfig = fakerConfig { random = Random(42) }
+                val otherFakerConfig = fakerConfig { randomSeed = 42 }
                 val otherFaker = Faker(otherFakerConfig)
 
                 it("the output of repeated function calls should be the same") {
@@ -91,5 +91,14 @@ class FakerConfigTest : DescribeSpec() {
                 }
             }
         }
+
+        it("random is should be ignored if set in same config as randomSeed") {
+            val fakerConfig = fakerConfig {
+                random = Random(1234567890)
+                randomSeed = 42
+            }
+
+            fakerConfig.random.nextInt() shouldBe Random(42).nextInt()
+        }
     }
 }
diff --git a/core/src/test/kotlin/io/github/serpro69/kfaker/FakerIT.kt b/core/src/test/kotlin/io/github/serpro69/kfaker/FakerIT.kt
index a49fa56622..c0597c6655 100644
--- a/core/src/test/kotlin/io/github/serpro69/kfaker/FakerIT.kt
+++ b/core/src/test/kotlin/io/github/serpro69/kfaker/FakerIT.kt
@@ -8,6 +8,7 @@ import io.kotest.matchers.shouldBe
 import io.kotest.matchers.shouldNotBe
 import org.junit.jupiter.api.assertDoesNotThrow
 import java.io.File
+import java.util.*
 import kotlin.reflect.KProperty
 import kotlin.reflect.KVisibility
 import kotlin.reflect.full.declaredMemberFunctions
@@ -161,6 +162,32 @@ class FakerIT : DescribeSpec({
             }
         }
     }
+
+    describe("faker{} DSL") {
+        it("should have default config if not explicitly configured") {
+            val faker = faker { }
+            assertSoftly {
+                faker.config.locale shouldBe "en"
+                faker.config.uniqueGeneratorRetryLimit shouldBe 100
+            }
+        }
+
+        it("should be able to provide custom configuration") {
+            val r = Random(42)
+            val faker = faker {
+                fakerConfig {
+                    locale = "uk"
+                    uniqueGeneratorRetryLimit = 42
+                    random = r
+                }
+            }
+            assertSoftly {
+                faker.config.locale shouldBe "uk"
+                faker.config.uniqueGeneratorRetryLimit shouldBe 42
+                faker.config.random shouldBe r
+            }
+        }
+    }
 })
 
 private fun List<String>.odds() = this.mapIndexedNotNull { index, s ->