Skip to content

Commit

Permalink
Endpoints as list in CodeGen to avoid duplicate key elimination (#2836)…
Browse files Browse the repository at this point in the history
… (#2892)

Key is imports. And imports can be the same.
We don't need here map semantics, but just a list.
  • Loading branch information
987Nabil committed Jun 8, 2024
1 parent da5bb31 commit e28bcb3
Show file tree
Hide file tree
Showing 4 changed files with 242 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ object CodeGen {

case Code.Object(name, schema, endpoints, objects, caseClasses, enums) =>
val baseImports = if (endpoints.nonEmpty) EndpointImports else Nil
val (epImports, epContent) = endpoints.map { case (k, v) =>
val (epImports, epContent) = endpoints.toList.map { case (k, v) =>
val (kImports, kContent) = render(basePackage)(k)
val (vImports, vContent) = render(basePackage)(v)
(kImports ++ vImports, s"$kContent=$vContent")
Expand Down
18 changes: 18 additions & 0 deletions zio-http-gen/src/test/resources/EndpointsWithOverlappingPath.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package test

import test.component._

object Pets {
import zio.http._
import zio.http.endpoint._
import zio.http.codec._
val listPets = Endpoint(Method.GET / "pets")
.query(QueryCodec.queryTo[Int]("limit"))
.in[Unit]
.out[Pets](status = Status.Ok)

val createPets = Endpoint(Method.POST / "pets")
.in[Pet]
.out[Unit](status = Status.Created)

}
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,68 @@ object EndpointGenSpec extends ZIOSpecDefault {
)
assertTrue(scala.files.head == expected)
},
test("endpoints with overlapping prefix") {
val endpoint1 = Endpoint(Method.GET / "api" / "v1" / "users")
val endpoint2 = Endpoint(Method.GET / "api" / "v1" / "users" / "info")
val openAPI = OpenAPIGen.fromEndpoints(endpoint1, endpoint2)
val scala = EndpointGen.fromOpenAPI(openAPI)
val expected1 = Code.File(
List("api", "v1", "Users.scala"),
pkgPath = List("api", "v1"),
imports = List(Code.Import.FromBase(path = "component._")),
objects = List(
Code.Object(
"Users",
Map(
Code.Field("get") -> Code.EndpointCode(
Method.GET,
Code.PathPatternCode(segments =
List(Code.PathSegmentCode("api"), Code.PathSegmentCode("v1"), Code.PathSegmentCode("users")),
),
queryParamsCode = Set.empty,
headersCode = Code.HeadersCode.empty,
inCode = Code.InCode("Unit"),
outCodes = Nil,
errorsCode = Nil,
),
),
),
),
caseClasses = Nil,
enums = Nil,
)
val expected2 = Code.File(
List("api", "v1", "users", "Info.scala"),
pkgPath = List("api", "v1", "users"),
imports = List(Code.Import.FromBase(path = "component._")),
objects = List(
Code.Object(
"Info",
Map(
Code.Field("get") -> Code.EndpointCode(
Method.GET,
Code.PathPatternCode(segments =
List(
Code.PathSegmentCode("api"),
Code.PathSegmentCode("v1"),
Code.PathSegmentCode("users"),
Code.PathSegmentCode("info"),
),
),
queryParamsCode = Set.empty,
headersCode = Code.HeadersCode.empty,
inCode = Code.InCode("Unit"),
outCodes = Nil,
errorsCode = Nil,
),
),
),
),
caseClasses = Nil,
enums = Nil,
)
assertTrue(scala.files.toSet == Set(expected1, expected2))
},
),
suite("data gen spec")(
test("generates case class, companion object and schema") {
Expand Down
161 changes: 161 additions & 0 deletions zio-http-gen/src/test/scala/zio/http/gen/scala/CodeGenSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -556,5 +556,166 @@ object CodeGenSpec extends ZIOSpecDefault {
"/GeneratedUserNameArray.scala",
)
},
test("Endpoints with common prefix") {
val json = """{
| "openapi": "3.0.0",
| "info": {
| "version": "1.0.0",
| "title": "Swagger Petstore",
| "license": {
| "name": "MIT"
| }
| },
| "servers": [
| {
| "url": "http://petstore.swagger.io/v1"
| }
| ],
| "paths": {
| "/pets": {
| "get": {
| "summary": "List all pets",
| "operationId": "listPets",
| "tags": [
| "pets"
| ],
| "parameters": [
| {
| "name": "limit",
| "in": "query",
| "description": "How many items to return at one time (max 100)",
| "required": false,
| "schema": {
| "type": "integer",
| "maximum": 100,
| "format": "int32"
| }
| }
| ],
| "responses": {
| "200": {
| "description": "A paged array of pets",
| "headers": {
| "x-next": {
| "description": "A link to the next page of responses",
| "schema": {
| "type": "string"
| }
| }
| },
| "content": {
| "application/json": {
| "schema": {
| "$ref": "#/components/schemas/Pets"
| }
| }
| }
| },
| "default": {
| "description": "unexpected error",
| "content": {
| "application/json": {
| "schema": {
| "$ref": "#/components/schemas/Error"
| }
| }
| }
| }
| }
| },
| "post": {
| "summary": "Create a pet",
| "operationId": "createPets",
| "tags": [
| "pets"
| ],
| "requestBody": {
| "content": {
| "application/json": {
| "schema": {
| "$ref": "#/components/schemas/Pet"
| }
| }
| },
| "required": true
| },
| "responses": {
| "201": {
| "description": "Null response"
| },
| "default": {
| "description": "unexpected error",
| "content": {
| "application/json": {
| "schema": {
| "$ref": "#/components/schemas/Error"
| }
| }
| }
| }
| }
| }
| }
| },
| "components": {
| "schemas": {
| "Pet": {
| "type": "object",
| "required": [
| "id",
| "name"
| ],
| "properties": {
| "id": {
| "type": "integer",
| "format": "int64"
| },
| "name": {
| "type": "string",
| "minLength": 3
| },
| "tag": {
| "type": "string"
| }
| }
| },
| "Pets": {
| "type": "array",
| "maxItems": 100,
| "items": {
| "$ref": "#/components/schemas/Pet"
| }
| },
| "Error": {
| "type": "object",
| "required": [
| "code",
| "message"
| ],
| "properties": {
| "code": {
| "type": "integer",
| "format": "int32"
| },
| "message": {
| "type": "string"
| }
| }
| }
| }
| }
|}""".stripMargin
val openAPI = OpenAPI.fromJson(json).toOption.get
val code = EndpointGen.fromOpenAPI(openAPI)
val tempDir = Files.createTempDirectory("codegen")

CodeGen.writeFiles(code, java.nio.file.Paths.get(tempDir.toString, "test"), "test", Some(scalaFmtPath))

fileShouldBe(
tempDir,
"test/Pets.scala",
"/EndpointsWithOverlappingPath.scala",
)
},
) @@ java11OrNewer @@ flaky @@ blocking // Downloading scalafmt on CI is flaky
}

0 comments on commit e28bcb3

Please sign in to comment.