Repository: cjbooms/fabrikt
Pull request #38 (2021-04-30 10:34:48)

Issue #36: Generated class names are inconsistent for inline array objects
Issue #36: Generated class names are inconsistent for inline array objects


Patch:
diff --git a/src/main/kotlin/com/cjbooms/fabrikt/model/PropertyInfo.kt b/src/main/kotlin/com/cjbooms/fabrikt/model/PropertyInfo.kt
index a42d2b0..943799b 100644
--- a/src/main/kotlin/com/cjbooms/fabrikt/model/PropertyInfo.kt
+++ b/src/main/kotlin/com/cjbooms/fabrikt/model/PropertyInfo.kt
@@ -1,19 +1,17 @@
 package com.cjbooms.fabrikt.model
 
 import com.cjbooms.fabrikt.util.KaizenParserExtensions.getKeyIfDiscriminator
-import com.cjbooms.fabrikt.util.KaizenParserExtensions.getPolymorphicSubTypes
 import com.cjbooms.fabrikt.util.KaizenParserExtensions.hasAdditionalProperties
 import com.cjbooms.fabrikt.util.KaizenParserExtensions.isDiscriminatorProperty
 import com.cjbooms.fabrikt.util.KaizenParserExtensions.isInLinedObjectUnderAllOf
 import com.cjbooms.fabrikt.util.KaizenParserExtensions.isInlineableMapDefinition
+import com.cjbooms.fabrikt.util.KaizenParserExtensions.isInlinedArrayDefinition
 import com.cjbooms.fabrikt.util.KaizenParserExtensions.isInlinedObjectDefinition
-import com.cjbooms.fabrikt.util.KaizenParserExtensions.isPolymorphicSuperType
 import com.cjbooms.fabrikt.util.KaizenParserExtensions.isRequired
 import com.cjbooms.fabrikt.util.KaizenParserExtensions.isSchemaLess
 import com.cjbooms.fabrikt.util.KaizenParserExtensions.safeType
 import com.cjbooms.fabrikt.util.KaizenParserExtensions.toModelClassName
 import com.cjbooms.fabrikt.util.NormalisedString.camelCase
-import com.reprezen.kaizen.oasparser.model3.OpenApi3
 import com.reprezen.kaizen.oasparser.model3.Schema
 
 sealed class PropertyInfo {
@@ -60,7 +58,7 @@ sealed class PropertyInfo {
             settings: Settings,
             enclosingSchema: Schema? = null
         ): Collection<PropertyInfo> {
-            val mainProperties = properties.map { property ->
+            val mainProperties: List<PropertyInfo> = properties.map { property ->
                 when (property.value.safeType()) {
                     OasType.Array.type ->
                         ListField(
@@ -68,7 +66,8 @@ sealed class PropertyInfo {
                             property.key,
                             property.value,
                             settings.markAsInherited,
-                            this
+                            this,
+                            if (property.value.isInlinedArrayDefinition()) enclosingSchema else null
                         )
                     OasType.Object.type ->
                         if (property.value.isInlineableMapDefinition() || property.value.isSchemaLess())
@@ -115,6 +114,7 @@ sealed class PropertyInfo {
                         }
                 }
             }.filterNotNull()
+
             return if (hasAdditionalProperties())
                 mainProperties
                     .plus(
@@ -122,22 +122,6 @@ sealed class PropertyInfo {
                     )
             else mainProperties
         }
-
-        fun Schema.propertiesInPolymorphicHierarchy(api3: OpenApi3, settings: Settings): Collection<PropertyInfo> {
-            if (!isPolymorphicSuperType()) throw IllegalArgumentException("Model is not a polymorphic super type")
-            val results = emptyList<PropertyInfo>() +
-                topLevelProperties(settings.copy(markAsInherited = true)) +
-                getPolymorphicSubTypes(api3).flatMap { subType ->
-                    emptyList<PropertyInfo>() +
-                        subType.getInLinedProperties(settings) +
-                        subType.allOfSchemas
-                            .filterNot { it == this }
-                            .flatMap { it.topLevelProperties(settings.copy(markAsInherited = !it.isInLinedObjectUnderAllOf())) } +
-                        subType.oneOfSchemas.flatMap { it.topLevelProperties(settings.copy(markAllOptional = true)) } +
-                        subType.anyOfSchemas.flatMap { it.topLevelProperties(settings.copy(markAllOptional = true)) }
-                }
-            return results.toSet()
-        }
     }
 
     sealed class DiscriminatorKey(val stringValue: String) {
@@ -179,22 +163,15 @@ sealed class PropertyInfo {
         val maxItems: Int?
     }
 
-    class DummyField(
-        override val oasKey: String,
-        override val typeInfo: KotlinTypeInfo,
-        override val isRequired: Boolean = true,
-        override val minItems: Int? = null,
-        override val maxItems: Int? = null
-    ) : PropertyInfo(), CollectionValidation
-
     data class ListField(
         override val isRequired: Boolean,
         override val oasKey: String,
         val schema: Schema,
         override val isInherited: Boolean,
-        val parentSchema: Schema
+        val parentSchema: Schema,
+        val enclosingSchema: Schema?
     ) : PropertyInfo(), CollectionValidation {
-        override val typeInfo: KotlinTypeInfo = KotlinTypeInfo.from(schema, oasKey)
+        override val typeInfo: KotlinTypeInfo = KotlinTypeInfo.from(schema, oasKey, enclosingSchema?.toModelClassName() ?: "")
         override val minItems: Int? = schema.minItems
         override val maxItems: Int? = schema.maxItems
     }
diff --git a/src/main/kotlin/com/cjbooms/fabrikt/util/KaizenParserExtensions.kt b/src/main/kotlin/com/cjbooms/fabrikt/util/KaizenParserExtensions.kt
index 5f97ec9..6ba1a7e 100644
--- a/src/main/kotlin/com/cjbooms/fabrikt/util/KaizenParserExtensions.kt
+++ b/src/main/kotlin/com/cjbooms/fabrikt/util/KaizenParserExtensions.kt
@@ -44,6 +44,9 @@ object KaizenParserExtensions {
     fun Schema.isInlinedObjectDefinition() =
         isObjectType() && !isSchemaLess() && Overlay.of(this).pathFromRoot.contains("properties")
 
+    fun Schema.isInlinedArrayDefinition() =
+        isArrayType() && !isSchemaLess() && this.itemsSchema.isInlinedObjectDefinition()
+
     fun Schema.isReferenceObjectDefinition() =
         isObjectType() && !isSchemaLess() && !Overlay.of(this).pathFromRoot.contains("properties")
 
@@ -85,6 +88,8 @@ object KaizenParserExtensions {
 
     fun Schema.isObjectType() = OasType.Object.type == type
 
+    fun Schema.isArrayType() = OasType.Array.type == type
+
     fun Schema.isNotDefined() = type == null && !(hasAllOfSchemas() || hasOneOfSchemas() || hasAnyOfSchemas())
 
     fun Schema.getSchemaNameInParent(): String? = Overlay.of(this).pathInParent


Test patch:
diff --git a/src/test/resources/examples/inLinedObject/api.yaml b/src/test/resources/examples/inLinedObject/api.yaml
index 4822418..9fd61f6 100644
--- a/src/test/resources/examples/inLinedObject/api.yaml
+++ b/src/test/resources/examples/inLinedObject/api.yaml
@@ -46,3 +46,19 @@ components:
                   type: string
             direct:
               type: string
+
+    ThirdInlineObject:
+      type: object
+      properties:
+        generation:
+          type: object
+          properties:
+            urls:
+              type: array
+              items:
+                type: object
+                properties:
+                  version:
+                    type: string
+            view_name:
+              type: string
diff --git a/src/test/resources/examples/inLinedObject/models/Models.kt b/src/test/resources/examples/inLinedObject/models/Models.kt
index e082b8b..840d285 100644
--- a/src/test/resources/examples/inLinedObject/models/Models.kt
+++ b/src/test/resources/examples/inLinedObject/models/Models.kt
@@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonProperty
 import javax.validation.Valid
 import javax.validation.constraints.NotNull
 import kotlin.String
+import kotlin.collections.List
 
 data class FirstInlineObject(
     @param:JsonProperty("generation")
@@ -74,3 +75,26 @@ data class SecondInlineObjectGeneration(
     @get:JsonProperty("direct")
     val direct: String? = null
 )
+
+data class ThirdInlineObject(
+    @param:JsonProperty("generation")
+    @get:JsonProperty("generation")
+    @get:Valid
+    val generation: ThirdInlineObjectGeneration? = null
+)
+
+data class ThirdInlineObjectUrls(
+    @param:JsonProperty("version")
+    @get:JsonProperty("version")
+    val version: String? = null
+)
+
+data class ThirdInlineObjectGeneration(
+    @param:JsonProperty("urls")
+    @get:JsonProperty("urls")
+    @get:Valid
+    val urls: List<ThirdInlineObjectUrls>? = null,
+    @param:JsonProperty("view_name")
+    @get:JsonProperty("view_name")
+    val viewName: String? = null
+)