Skip to content

Commit

Permalink
add support for jsonUnknown support to Document codec (#1578)
Browse files Browse the repository at this point in the history
  • Loading branch information
benoitlouy authored Sep 10, 2024
1 parent 3608c82 commit d0b5cd5
Show file tree
Hide file tree
Showing 4 changed files with 382 additions and 48 deletions.
236 changes: 236 additions & 0 deletions modules/bootstrapped/test/src/smithy4s/DocumentSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import smithy.api.JsonName
import smithy.api.Default
import smithy4s.example.IntList
import alloy.Discriminated
import alloy.JsonUnknown
import munit._
import smithy4s.example.DefaultNullsOperationOutput
import alloy.Untagged
Expand Down Expand Up @@ -663,4 +664,239 @@ class DocumentSpec() extends FunSuite {
assertEquals(niceSyntaxDocument, expectedDocument)
}

case class JsonUnknownExample(
s: String,
i: Int,
others: Map[String, Document]
)

object JsonUnknownExample {
implicit val jsonUnknownExampleSchema: Schema[JsonUnknownExample] = {
val s = string.required[JsonUnknownExample]("s", _.s)
val i = int.required[JsonUnknownExample]("i", _.i)
val others = map(string, document)
.required[JsonUnknownExample]("others", _.others)
.addHints(JsonUnknown())
struct(s, i, others)(JsonUnknownExample.apply)
}
}

object JsonUnknownExampleWithDefault {
implicit val jsonUnknownExampleSchema: Schema[JsonUnknownExample] = {
val s = string.required[JsonUnknownExample]("s", _.s)
val i = int.required[JsonUnknownExample]("i", _.i)
val others = map(string, document)
.required[JsonUnknownExample]("others", _.others)
.addHints(
JsonUnknown(),
Default(Document.obj("default" -> Document.fromBoolean(true)))
)
struct(s, i, others)(JsonUnknownExample.apply)
}
}

case class JsonUnknownExampleOptional(
s: String,
i: Int,
others: Option[Map[String, Document]]
)

object JsonUnknownExampleOptional {
implicit val jsonUnknownExampleOptionalSchema
: Schema[JsonUnknownExampleOptional] = {
val s = string.required[JsonUnknownExampleOptional]("s", _.s)
val i = int.required[JsonUnknownExampleOptional]("i", _.i)
val others = map(string, document)
.optional[JsonUnknownExampleOptional]("others", _.others)
.addHints(JsonUnknown())
struct(s, i, others)(JsonUnknownExampleOptional.apply)
}
}

object JsonUnknownExampleOptionalWithDefault {
implicit val jsonUnknownExampleOptionalSchema
: Schema[JsonUnknownExampleOptional] = {
val s = string.required[JsonUnknownExampleOptional]("s", _.s)
val i = int.required[JsonUnknownExampleOptional]("i", _.i)
val others = map(string, document)
.optional[JsonUnknownExampleOptional]("others", _.others)
.addHints(
JsonUnknown(),
Default(Document.obj("default" -> Document.fromBoolean(true)))
)
struct(s, i, others)(JsonUnknownExampleOptional.apply)
}
}

test("unknown field decoding: no unknown field in payload") {
val doc = Document.obj(
"s" -> Document.fromString("foo"),
"i" -> Document.fromInt(67)
)
val expected = JsonUnknownExample("foo", 67, Map.empty)

val res = Document.Decoder
.fromSchema(JsonUnknownExample.jsonUnknownExampleSchema)
.decode(doc)

assertEquals(res, Right(expected))
}

test("unknown field decoding: no unknown field in payload with default") {
val doc = Document.obj(
"s" -> Document.fromString("foo"),
"i" -> Document.fromInt(67)
)
val expected = JsonUnknownExample(
"foo",
67,
Map("default" -> Document.fromBoolean(true))
)

val res = Document.Decoder
.fromSchema(JsonUnknownExampleWithDefault.jsonUnknownExampleSchema)
.decode(doc)

assertEquals(res, Right(expected))
}

test(
"unknown field decoding: no unknown field in payload, optional field"
) {
val doc = Document.obj(
"s" -> Document.fromString("foo"),
"i" -> Document.fromInt(67)
)
val expected = JsonUnknownExampleOptional("foo", 67, None)

val res = Document.Decoder
.fromSchema(JsonUnknownExampleOptional.jsonUnknownExampleOptionalSchema)
.decode(doc)

assertEquals(res, Right(expected))
}

test(
"unknown field decoding: no unknown field in payload, optional field with default"
) {
val doc = Document.obj(
"s" -> Document.fromString("foo"),
"i" -> Document.fromInt(67)
)
val expected = JsonUnknownExampleOptional(
"foo",
67,
Some(Map("default" -> Document.fromBoolean(true)))
)

val res = Document.Decoder
.fromSchema(
JsonUnknownExampleOptionalWithDefault.jsonUnknownExampleOptionalSchema
)
.decode(doc)

assertEquals(res, Right(expected))
}

test("unknown field decoding: with unknown fields in payload") {
val doc = Document.obj(
"s" -> Document.fromString("foo"),
"i" -> Document.fromInt(67),
"someField" -> Document.obj("a" -> Document.fromString("b")),
"someOtherField" -> Document.fromInt(75)
)
val expected = JsonUnknownExample(
"foo",
67,
Map(
"someField" -> Document.obj("a" -> Document.fromString("b")),
"someOtherField" -> Document.fromInt(75)
)
)

val res = Document.Decoder
.fromSchema(JsonUnknownExample.jsonUnknownExampleSchema)
.decode(doc)

assertEquals(res, Right(expected))
}

test(
"unknown field decoding: with unknown fields in payload, optional field"
) {
val doc = Document.obj(
"s" -> Document.fromString("foo"),
"i" -> Document.fromInt(67),
"someField" -> Document.obj("a" -> Document.fromString("b")),
"someOtherField" -> Document.fromInt(75)
)
val expected = JsonUnknownExampleOptional(
"foo",
67,
Some(
Map(
"someField" -> Document.obj("a" -> Document.fromString("b")),
"someOtherField" -> Document.fromInt(75)
)
)
)

val res = Document.Decoder
.fromSchema(JsonUnknownExampleOptional.jsonUnknownExampleOptionalSchema)
.decode(doc)

assertEquals(res, Right(expected))
}

test("unknown field decoding: with unknow field explicitely set in payload") {
val doc = Document.obj(
"s" -> Document.fromString("foo"),
"i" -> Document.fromInt(67),
"someField" -> Document.obj("a" -> Document.fromString("b")),
"someOtherField" -> Document.fromInt(75),
"others" -> Document.obj()
)
val expected = JsonUnknownExample(
"foo",
67,
Map(
"someField" -> Document.obj("a" -> Document.fromString("b")),
"someOtherField" -> Document.fromInt(75),
"others" -> Document.obj()
)
)

val res = Document.Decoder
.fromSchema(JsonUnknownExample.jsonUnknownExampleSchema)
.decode(doc)

assertEquals(res, Right(expected))
}

test("unknown field encoding") {
val in = JsonUnknownExample(
"foo",
67,
Map(
"someField" -> Document.obj("a" -> Document.fromString("b")),
"someOtherField" -> Document.fromInt(75),
"others" -> Document.obj()
)
)

val expected = Document.obj(
"s" -> Document.fromString("foo"),
"i" -> Document.fromInt(67),
"someField" -> Document.obj("a" -> Document.fromString("b")),
"someOtherField" -> Document.fromInt(75),
"others" -> Document.obj()
)

val doc = Document.Encoder
.fromSchema(JsonUnknownExample.jsonUnknownExampleSchema)
.encode(in)

assertEquals(doc, expected)
}

}
Loading

0 comments on commit d0b5cd5

Please sign in to comment.