Repository: serpro69/kotlin-faker (kotlin)

Issue:
Add support for sealed classes in randomClassInstance
- check if base class is sealed
- return a random boxedClass
- profit

```kotlin
if (!base.isSealed) {
  base
} else {
  base.nestedClasses.random().boxedClass as KClass<T>
}
```

> Suggested by @timrijckaert

Pull request description:
Closes #264

Patch:
diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc
index d86234f82e..d2cafe189c 100644
--- a/CHANGELOG.adoc
+++ b/CHANGELOG.adoc
@@ -11,6 +11,7 @@
 [discrete]
 === Added
 
+* https://github.com/serpro69/kotlin-faker/pull/267[#267] (:core) Add support for sealed classes in randomClassInstance
 * https://github.com/serpro69/kotlin-faker/pull/266[#266] (:core) Add support for internal constructors in randomClassInstance
 * https://github.com/serpro69/kotlin-faker/pull/260[#260] (:core) Add config strategy for default values of RandomClass instances
 * https://github.com/serpro69/kotlin-faker/pull/258[#258] (:core) Add RandomClassProvider::randomClassInstance fun with KClass input
diff --git a/core/src/main/kotlin/io/github/serpro69/kfaker/provider/misc/RandomClassProvider.kt b/core/src/main/kotlin/io/github/serpro69/kfaker/provider/misc/RandomClassProvider.kt
index 55eecad6a0..2bbf6fc749 100644
--- a/core/src/main/kotlin/io/github/serpro69/kfaker/provider/misc/RandomClassProvider.kt
+++ b/core/src/main/kotlin/io/github/serpro69/kfaker/provider/misc/RandomClassProvider.kt
@@ -168,6 +168,7 @@ class RandomClassProvider {
         // Handle cases where "constructor-less" type is not a direct parameter of the generated class,
         // but is a collection type, for example
         // https://github.com/serpro69/kotlin-faker/issues/204
+        if (this.isSealed) return randomSealedClassOrNull(config) as T
         if (this.java.isEnum) return randomEnumOrNull() as T
         if (this.java.isPrimitive) return randomPrimitiveOrNull() as T
 
diff --git a/docs/src/orchid/resources/wiki/extras.md b/docs/src/orchid/resources/wiki/extras.md
index 3ad4876db3..a14e931d75 100644
--- a/docs/src/orchid/resources/wiki/extras.md
+++ b/docs/src/orchid/resources/wiki/extras.md
@@ -11,7 +11,7 @@
   * [Random Class Instance Configuration](#random-class-instance-configuration)
   * [Pre-configuring type generation](#pre-configuring-type-generation)
     * [Predefined types for constructor parameters](#predefined-types-for-constructor-parameters)
-    * [Pre-defined instance for classes with no public constructors](#pre-defined-instance-for-classes-with-no-public-constructors)
+    * [Pre-defined instance for classes with no public constructors](#pre-defined-instance-for-classes-with-no-public-or-internal-constructors)
     * [Predefined collection element types](#predefined-collection-element-types)
   * [Deterministic constructor selection](#deterministic-constructor-selection)
   * [Default constructor values selection](#default-values-selection)
@@ -31,8 +31,8 @@ It is possible to create a random instance of (almost) any class.
 
 There are some rules to keep in mind:
 
+- A class must have a public or internal constructor
 - By default, a constructor with the least number of arguments is used (This can be configured - read on.)
-  - Both publicly- and internally-visible constructors are supported
 - `kolin.Array` type in the constructor is not supported at the moment
 - Inner classes (either direct generation or as class parameter type) are not supported at the moment
 


Test patch:
diff --git a/core/src/test/kotlin/io/github/serpro69/kfaker/provider/misc/RandomClassProviderTest.kt b/core/src/test/kotlin/io/github/serpro69/kfaker/provider/misc/RandomClassProviderTest.kt
index 7bee37936e..24fa1b69ce 100644
--- a/core/src/test/kotlin/io/github/serpro69/kfaker/provider/misc/RandomClassProviderTest.kt
+++ b/core/src/test/kotlin/io/github/serpro69/kfaker/provider/misc/RandomClassProviderTest.kt
@@ -651,6 +651,32 @@ class RandomClassProviderTest : DescribeSpec({
         }
     }
 
+    describe("a sealed class") {
+        it("should return a random sealed class implementation") {
+            val cls = randomProvider.randomClassInstance<TestSealedCls>()
+            cls shouldBe instanceOf<TestSealedCls>()
+        }
+        context("with constructor parameters") {
+            it("should return a random sealed class implementation") {
+                val cls = randomProvider.randomClassInstance<TestSealedClsWithParams>()
+                cls shouldBe instanceOf<TestSealedClsWithParams>()
+            }
+        }
+    }
+
+    describe("an enum class") {
+        it("should return a random enum implementation") {
+            val cls = randomProvider.randomClassInstance<TestEnum>()
+            cls shouldBe instanceOf<TestEnum>()
+        }
+        context("with constructor parameters") {
+            it("should return a random sealed class implementation") {
+                val cls = randomProvider.randomClassInstance<TestEnumWithParams>()
+                cls shouldBe instanceOf<TestEnumWithParams>()
+            }
+        }
+    }
+
     describe("RandomClassProvider configuration") {
         class Foo(val int: Int)
         class Bar(val foo: Foo)
@@ -908,6 +934,12 @@ class RandomClassProviderTest : DescribeSpec({
     }
 })
 
+enum class TestEnumWithParams(val id: Int) {
+    THREE(3),
+    SIX(6),
+    FORTY_TWO(42),
+}
+
 @Suppress("unused")
 enum class TestEnum {
     KOTLIN,
@@ -915,10 +947,19 @@ enum class TestEnum {
     GO
 }
 
+sealed class TestSealedClsWithParams(val id: Int) {
+    data object Three : TestSealedClsWithParams(3)
+    class Six : TestSealedClsWithParams(6)
+    object Nine : TestSealedClsWithParams(9)
+    class Cls(private val ownId: Int) : TestSealedClsWithParams(ownId)
+    data class Data(private val ownId: Int) : TestSealedClsWithParams(ownId)
+}
+
 @Suppress("CanSealedSubClassBeObject", "unused")
 sealed class TestSealedCls {
     data object Kotlin : TestSealedCls()
     class Java : TestSealedCls()
+    object JS : TestSealedCls()
 }
 
 @Suppress("unused")