From fe30ff311a5105e5765817199f1e9b8d93967ea7 Mon Sep 17 00:00:00 2001 From: Mark Cowlishaw Date: Thu, 21 Nov 2024 15:36:38 -0800 Subject: [PATCH] Fix #5001 OkResponse is generated as a model --- packages/http-server-csharp/src/service.ts | 7 ++- .../test/generation.test.ts | 44 ++++++++++++++++++- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/packages/http-server-csharp/src/service.ts b/packages/http-server-csharp/src/service.ts index ad7301414d..a1796912cc 100644 --- a/packages/http-server-csharp/src/service.ts +++ b/packages/http-server-csharp/src/service.ts @@ -675,7 +675,8 @@ export async function $onEmit(context: EmitContext) } for (const response of operation.responses) { - this.emitter.emitType(response.type); + if (!isEmptyResponseModel(this.emitter.getProgram(), response.type)) + this.emitter.emitType(response.type); } return builder.reduce(); @@ -1207,6 +1208,10 @@ export async function $onEmit(context: EmitContext) } } + function isEmptyResponseModel(program: Program, model: Type): boolean { + if (model.kind !== "Model") return false; + return model.properties.size === 1 && isStatusCode(program, [...model.properties.values()][0]); + } function processNameSpace(program: Program, target: Namespace, service?: Service | undefined) { if (!service) service = getService(program, target); if (service) { diff --git a/packages/http-server-csharp/test/generation.test.ts b/packages/http-server-csharp/test/generation.test.ts index 05da1472ad..aadc474d56 100644 --- a/packages/http-server-csharp/test/generation.test.ts +++ b/packages/http-server-csharp/test/generation.test.ts @@ -1,6 +1,6 @@ import { Program, Type, navigateProgram } from "@typespec/compiler"; import { BasicTestRunner } from "@typespec/compiler/testing"; -import assert from "assert"; +import assert, { deepStrictEqual } from "assert"; import { beforeEach, it } from "vitest"; import { getPropertySource, getSourceModel } from "../src/utils.js"; import { createCSharpServiceEmitterTestRunner, getStandardService } from "./test-host.js"; @@ -747,6 +747,48 @@ it("Handles void type in operations", async () => { ); }); +it("Handles empty body 2xx as void", async () => { + await compileAndValidateMultiple( + runner, + ` + using TypeSpec.Rest.Resource; + + namespace MyService { + model Toy { + @key("toyId") + id: int64; + + petId: int64; + name: string; + } + + @friendlyName("{name}ListResults", Item) + model ResponsePage { + items: Item[]; + nextLink?: string; + } + + @post @route("/foo") op foo(...Toy): OkResponse; + } + `, + [ + [ + "IMyServiceOperations.cs", + ["interface IMyServiceOperations", "Task FooAsync( long id, long petId, string name)"], + ], + [ + "MyServiceOperationsControllerBase.cs", + [ + "public abstract partial class MyServiceOperationsControllerBase: ControllerBase", + "public virtual async Task Foo(Toy body)", + ], + ], + ["Toy.cs", ["public partial class Toy"]], + ], + ); + deepStrictEqual([...runner.fs.keys()].filter((k) => k.includes("OkResponse.cs")).length, 0); +}); + it("generates appropriate types for literals", async () => { await compileAndValidateSingleModel( runner,