Skip to content

Commit

Permalink
Merge pull request #3235 from eanea/3234/fix_markOptionsAsNullable_fo…
Browse files Browse the repository at this point in the history
…r_reference_types

3234: use markOptionsAsNullable for Option reference types
  • Loading branch information
adamw authored Oct 13, 2023
2 parents 3c94f6d + e95728e commit 29f62fc
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,12 @@ private[schema] class TSchemaToASchema(toSchemaReference: ToSchemaReference, mar
case TSchemaType.SArray(nested @ TSchema(_, Some(name), _, _, _, _, _, _, _, _, _)) =>
ASchema(SchemaType.Array).copy(items = Some(toSchemaReference.map(nested, name)))
case TSchemaType.SArray(el) => ASchema(SchemaType.Array).copy(items = Some(apply(el)))
case TSchemaType.SOption(nested @ TSchema(_, Some(name), _, _, _, _, _, _, _, _, _)) => toSchemaReference.map(nested, name)
case TSchemaType.SOption(el) => apply(el, isOptionElement = true)
case TSchemaType.SOption(nested @ TSchema(_, Some(name), _, _, _, _, _, _, _, _, _)) => {
val ref = toSchemaReference.map(nested, name)
if (!markOptionsAsNullable) ref
else ASchema.oneOf(List(ref, ASchema(SchemaType.Null)), None)
}
case TSchemaType.SOption(el) => apply(el, isOptionElement = true)
case TSchemaType.SBinary() => ASchema(SchemaType.String).copy(format = SchemaFormat.Binary)
case TSchemaType.SDate() => ASchema(SchemaType.String).copy(format = SchemaFormat.Date)
case TSchemaType.SDateTime() => ASchema(SchemaType.String).copy(format = SchemaFormat.DateTime)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
openapi: 3.1.0
info:
title: ClassWithOptionClassField
version: '1.0'
paths:
/:
post:
operationId: postRoot
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/ClassWithOptionClassField'
required: true
responses:
'200':
description: ''
content:
text/plain:
schema:
type: string
'400':
description: 'Invalid value for: body'
content:
text/plain:
schema:
type: string
components:
schemas:
Bar:
required:
- bar
type: object
properties:
bar:
type: integer
format: int32
ClassWithOptionClassField:
required:
- requiredStringField
type: object
properties:
optionalObjField:
oneOf:
- $ref: '#/components/schemas/Bar'
- type: 'null'
requiredStringField:
type: string
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,20 @@ class VerifyYamlTest extends AnyFunSuite with Matchers {
actualYamlNoIndent shouldBe expectedYaml
}

test("should mark optional class fields as nullable when configured to do so") {
case class Bar(bar: Int)
case class ClassWithOptionClassField(optionalObjField: Option[Bar], requiredStringField: String)

val e = endpoint.in(jsonBody[ClassWithOptionClassField]).out(stringBody).post
val expectedYaml = load("expected_nullable_option_class_field.yml")

val options = OpenAPIDocsOptions.default.copy(markOptionsAsNullable = true)

val actualYaml = OpenAPIDocsInterpreter(options).toOpenAPI(e, Info("ClassWithOptionClassField", "1.0")).toYaml
val actualYamlNoIndent = noIndentation(actualYaml)
actualYamlNoIndent shouldBe expectedYaml
}

test("should generate default and example values for nested optional fields") {
case class Nested(nestedValue: String)
case class ClassWithNestedOptionalField(
Expand Down

0 comments on commit 29f62fc

Please sign in to comment.