diff --git a/.chronus/changes/fix_override-2024-10-13-15-32-53.md b/.chronus/changes/fix_override-2024-10-13-15-32-53.md new file mode 100644 index 0000000000..6d38ef673e --- /dev/null +++ b/.chronus/changes/fix_override-2024-10-13-15-32-53.md @@ -0,0 +1,7 @@ +--- +changeKind: fix +packages: + - "@azure-tools/typespec-client-generator-core" +--- + +do not replace operation with `@override` when `listOperationsInOperationGroup` \ No newline at end of file diff --git a/.chronus/changes/fix_override-2024-10-15-14-8-26.md b/.chronus/changes/fix_override-2024-10-15-14-8-26.md new file mode 100644 index 0000000000..d0c0ff837d --- /dev/null +++ b/.chronus/changes/fix_override-2024-10-15-14-8-26.md @@ -0,0 +1,7 @@ +--- +changeKind: feature +packages: + - "@azure-tools/typespec-client-generator-core" +--- + +add `isOverride` flag to `SdkServiceMethod`. \ No newline at end of file diff --git a/packages/typespec-client-generator-core/src/decorators.ts b/packages/typespec-client-generator-core/src/decorators.ts index 31842b5204..414a564c07 100644 --- a/packages/typespec-client-generator-core/src/decorators.ts +++ b/packages/typespec-client-generator-core/src/decorators.ts @@ -584,9 +584,12 @@ export function listOperationsInOperationGroup( } for (const op of current.operations.values()) { - // Skip templated operations - if (!isTemplateDeclarationOrInstance(op)) { - operations.push(getOverriddenClientMethod(context, op) ?? op); + // Skip templated operations and omit operations + if ( + !isTemplateDeclarationOrInstance(op) && + !context.program.stateMap(omitOperation).get(op) + ) { + operations.push(op); } } @@ -898,6 +901,7 @@ export function getClientNameOverride( } const overrideKey = createStateSymbol("override"); +const omitOperation = createStateSymbol("omitOperation"); // Recursive function to collect parameter names function collectParams( @@ -946,6 +950,9 @@ export const $override = ( override: Operation, scope?: LanguageScopes, ) => { + // omit all override operation + context.program.stateMap(omitOperation).set(override, true); + // Extract and sort parameter names const originalParams = collectParams(original.parameters.properties).sort((a, b) => a.name.localeCompare(b.name), diff --git a/packages/typespec-client-generator-core/src/interfaces.ts b/packages/typespec-client-generator-core/src/interfaces.ts index a233d6d11c..c1025281fa 100644 --- a/packages/typespec-client-generator-core/src/interfaces.ts +++ b/packages/typespec-client-generator-core/src/interfaces.ts @@ -586,6 +586,7 @@ interface SdkServiceMethodBase exception?: SdkMethodResponse; generateConvenient: boolean; generateProtocol: boolean; + isOverride: boolean; } export interface SdkBasicServiceMethod diff --git a/packages/typespec-client-generator-core/src/package.ts b/packages/typespec-client-generator-core/src/package.ts index 6a19169854..57b7bc2704 100644 --- a/packages/typespec-client-generator-core/src/package.ts +++ b/packages/typespec-client-generator-core/src/package.ts @@ -383,6 +383,7 @@ function getSdkBasicServiceMethod decorators: diagnostics.pipe(getTypeDecorators(context, operation)), generateConvenient: shouldGenerateConvenient(context, operation), generateProtocol: shouldGenerateProtocol(context, operation), + isOverride: override !== undefined, }); } diff --git a/packages/typespec-client-generator-core/test/decorators.test.ts b/packages/typespec-client-generator-core/test/decorators.test.ts index 511d1cab8a..5b7c8bf516 100644 --- a/packages/typespec-client-generator-core/test/decorators.test.ts +++ b/packages/typespec-client-generator-core/test/decorators.test.ts @@ -1,4 +1,3 @@ -import { AzureCoreTestLibrary } from "@azure-tools/typespec-azure-core/testing"; import { Interface, Model, Operation } from "@typespec/compiler"; import { expectDiagnostics } from "@typespec/compiler/testing"; import { deepStrictEqual, ok, strictEqual } from "assert"; @@ -2229,310 +2228,6 @@ describe("typespec-client-generator-core: decorators", () => { }); }); - describe("@override", () => { - it("basic", async () => { - await runner.compileWithCustomization( - ` - @service - namespace MyService; - model Params { - foo: string; - bar: string; - } - - op func(...Params): void; - `, - ` - namespace MyCustomizations; - - op func(params: MyService.Params): void; - - @@override(MyService.func, MyCustomizations.func); - `, - ); - const sdkPackage = runner.context.sdkPackage; - - const paramsModel = sdkPackage.models.find((x) => x.name === "Params"); - ok(paramsModel); - - const client = sdkPackage.clients[0]; - strictEqual(client.methods.length, 1); - const method = client.methods[0]; - - strictEqual(method.kind, "basic"); - strictEqual(method.name, "func"); - strictEqual(method.parameters.length, 2); - const contentTypeParam = method.parameters.find((x) => x.name === "contentType"); - ok(contentTypeParam); - const paramsParam = method.parameters.find((x) => x.name === "params"); - ok(paramsParam); - strictEqual(paramsModel, paramsParam.type); - - ok(method.operation.bodyParam); - strictEqual(method.operation.bodyParam.correspondingMethodParams.length, 1); - strictEqual(method.operation.bodyParam.correspondingMethodParams[0], paramsParam); - }); - - it("basic with scope", async () => { - const mainCode = ` - @service - namespace MyService; - model Params { - foo: string; - bar: string; - } - - op func(...Params): void; - `; - - const customizationCode = ` - namespace MyCustomizations; - - op func(params: MyService.Params): void; - - @@override(MyService.func, MyCustomizations.func, "csharp"); - `; - await runner.compileWithCustomization(mainCode, customizationCode); - // runner has python scope, so shouldn't be overridden - - ok(runner.context.sdkPackage.models.find((x) => x.name === "Params")); - const sdkPackage = runner.context.sdkPackage; - const client = sdkPackage.clients[0]; - strictEqual(client.methods.length, 1); - const method = client.methods[0]; - strictEqual(method.kind, "basic"); - strictEqual(method.name, "func"); - strictEqual(method.parameters.length, 3); - - const contentTypeParam = method.parameters.find((x) => x.name === "contentType"); - ok(contentTypeParam); - - const fooParam = method.parameters.find((x) => x.name === "foo"); - ok(fooParam); - - const barParam = method.parameters.find((x) => x.name === "bar"); - ok(barParam); - - const httpOp = method.operation; - strictEqual(httpOp.parameters.length, 1); - strictEqual(httpOp.parameters[0].correspondingMethodParams[0], contentTypeParam); - - ok(httpOp.bodyParam); - strictEqual(httpOp.bodyParam.correspondingMethodParams.length, 2); - strictEqual(httpOp.bodyParam.correspondingMethodParams[0], fooParam); - strictEqual(httpOp.bodyParam.correspondingMethodParams[1], barParam); - - const runnerWithCsharp = await createSdkTestRunner({ - emitterName: "@azure-tools/typespec-csharp", - }); - await runnerWithCsharp.compileWithCustomization(mainCode, customizationCode); - ok(runnerWithCsharp.context.sdkPackage.models.find((x) => x.name === "Params")); - - const sdkPackageWithCsharp = runnerWithCsharp.context.sdkPackage; - strictEqual(sdkPackageWithCsharp.clients.length, 1); - - strictEqual(sdkPackageWithCsharp.clients[0].methods.length, 1); - const methodWithCsharp = sdkPackageWithCsharp.clients[0].methods[0]; - strictEqual(methodWithCsharp.kind, "basic"); - strictEqual(methodWithCsharp.name, "func"); - strictEqual(methodWithCsharp.parameters.length, 2); - const contentTypeParamWithCsharp = methodWithCsharp.parameters.find( - (x) => x.name === "contentType", - ); - ok(contentTypeParamWithCsharp); - - const paramsParamWithCsharp = methodWithCsharp.parameters.find((x) => x.name === "params"); - ok(paramsParamWithCsharp); - strictEqual( - sdkPackageWithCsharp.models.find((x) => x.name === "Params"), - paramsParamWithCsharp.type, - ); - - const httpOpWithCsharp = methodWithCsharp.operation; - strictEqual(httpOpWithCsharp.parameters.length, 1); - strictEqual( - httpOpWithCsharp.parameters[0].correspondingMethodParams[0], - contentTypeParamWithCsharp, - ); - ok(httpOpWithCsharp.bodyParam); - strictEqual(httpOpWithCsharp.bodyParam.correspondingMethodParams.length, 1); - strictEqual(httpOpWithCsharp.bodyParam.correspondingMethodParams[0], paramsParamWithCsharp); - }); - - it("regrouping", async () => { - const mainCode = ` - @service - namespace MyService; - model Params { - foo: string; - bar: string; - fooBar: string; - } - - op func(...Params): void; - `; - - const customizationCode = ` - namespace MyCustomizations; - - model ParamsCustomized { - ...PickProperties; - } - - op func(params: MyCustomizations.ParamsCustomized, ...PickProperties): void; - - @@override(MyService.func, MyCustomizations.func); - `; - await runner.compileWithCustomization(mainCode, customizationCode); - // runner has python scope, so shouldn't be overridden - - ok(!runner.context.sdkPackage.models.find((x) => x.name === "Params")); - const sdkPackage = runner.context.sdkPackage; - const client = sdkPackage.clients[0]; - strictEqual(client.methods.length, 1); - const method = client.methods[0]; - strictEqual(method.kind, "basic"); - strictEqual(method.name, "func"); - strictEqual(method.parameters.length, 3); - - const contentTypeParam = method.parameters.find((x) => x.name === "contentType"); - ok(contentTypeParam); - - const paramsParam = method.parameters.find((x) => x.name === "params"); - ok(paramsParam); - - const fooBarParam = method.parameters.find((x) => x.name === "fooBar"); - ok(fooBarParam); - - const httpOp = method.operation; - strictEqual(httpOp.parameters.length, 1); - strictEqual(httpOp.parameters[0].correspondingMethodParams[0], contentTypeParam); - - ok(httpOp.bodyParam); - strictEqual(httpOp.bodyParam.correspondingMethodParams.length, 2); - strictEqual(httpOp.bodyParam.correspondingMethodParams[0], paramsParam); - strictEqual(httpOp.bodyParam.correspondingMethodParams[1], fooBarParam); - }); - - it("params mismatch", async () => { - const mainCode = ` - @service - namespace MyService; - model Params { - foo: string; - bar: string; - } - - op func(...Params): void; - `; - - const customizationCode = ` - namespace MyCustomizations; - - model ParamsCustomized { - foo: string; - bar: string; - } - - op func(params: MyCustomizations.ParamsCustomized): void; - - @@override(MyService.func, MyCustomizations.func); - `; - const diagnostics = ( - await runner.compileAndDiagnoseWithCustomization(mainCode, customizationCode) - )[1]; - expectDiagnostics(diagnostics, { - code: "@azure-tools/typespec-client-generator-core/override-method-parameters-mismatch", - }); - }); - - it("recursive params", async () => { - await runner.compileWithCustomization( - ` - @service - namespace MyService; - model Params { - foo: string; - params: Params[]; - } - - op func(...Params): void; - `, - ` - namespace MyCustomizations; - - op func(input: MyService.Params): void; - - @@override(MyService.func, MyCustomizations.func); - `, - ); - const sdkPackage = runner.context.sdkPackage; - - const paramsModel = sdkPackage.models.find((x) => x.name === "Params"); - ok(paramsModel); - - const client = sdkPackage.clients[0]; - strictEqual(client.methods.length, 1); - const method = client.methods[0]; - - strictEqual(method.kind, "basic"); - strictEqual(method.name, "func"); - strictEqual(method.parameters.length, 2); - const contentTypeParam = method.parameters.find((x) => x.name === "contentType"); - ok(contentTypeParam); - const inputParam = method.parameters.find((x) => x.name === "input"); - ok(inputParam); - strictEqual(paramsModel, inputParam.type); - - ok(method.operation.bodyParam); - strictEqual(method.operation.bodyParam.correspondingMethodParams.length, 1); - strictEqual(method.operation.bodyParam.correspondingMethodParams[0], inputParam); - }); - - it("core template", async () => { - const runnerWithCore = await createSdkTestRunner({ - librariesToAdd: [AzureCoreTestLibrary], - autoUsings: ["Azure.Core"], - emitterName: "@azure-tools/typespec-java", - }); - await runnerWithCore.compileWithCustomization( - ` - @useDependency(Versions.v1_0_Preview_2) - @server("http://localhost:3000", "endpoint") - @service() - namespace My.Service; - - model Params { - foo: string; - params: Params[]; - } - - @route("/template") - op templateOp is Azure.Core.RpcOperation< - Params, - Params - >; - `, - ` - namespace My.Customizations; - - op templateOp(params: My.Service.Params): My.Service.Params; - - @@override(My.Service.templateOp, My.Customizations.templateOp); - `, - ); - const sdkPackage = runnerWithCore.context.sdkPackage; - const method = sdkPackage.clients[0].methods[0]; - strictEqual(method.parameters.length, 3); - ok(method.parameters.find((x) => x.name === "contentType")); - ok(method.parameters.find((x) => x.name === "accept")); - - const paramsParam = method.parameters.find((x) => x.name === "params"); - ok(paramsParam); - strictEqual(paramsParam.type.kind, "model"); - strictEqual(paramsParam.type.name, "Params"); - }); - }); describe("@clientInitialization", () => { it("main client", async () => { await runner.compileWithCustomization( diff --git a/packages/typespec-client-generator-core/test/decorators/override.test.ts b/packages/typespec-client-generator-core/test/decorators/override.test.ts new file mode 100644 index 0000000000..37edf0a88b --- /dev/null +++ b/packages/typespec-client-generator-core/test/decorators/override.test.ts @@ -0,0 +1,326 @@ +import { AzureCoreTestLibrary } from "@azure-tools/typespec-azure-core/testing"; +import { expectDiagnostics } from "@typespec/compiler/testing"; +import { ok, strictEqual } from "assert"; +import { beforeEach, describe, it } from "vitest"; +import { UsageFlags } from "../../src/interfaces.js"; +import { createSdkTestRunner, SdkTestRunner } from "../test-host.js"; + +describe("typespec-client-generator-core: @override", () => { + let runner: SdkTestRunner; + + beforeEach(async () => { + runner = await createSdkTestRunner({ emitterName: "@azure-tools/typespec-python" }); + }); + + it("basic", async () => { + await runner.compileWithCustomization( + ` + @service + namespace MyService; + model Params { + foo: string; + bar: string; + } + + op func(...Params): void; + `, + ` + namespace MyCustomizations; + + op func(params: MyService.Params): void; + + @@override(MyService.func, MyCustomizations.func); + `, + ); + const sdkPackage = runner.context.sdkPackage; + + const paramsModel = sdkPackage.models.find((x) => x.name === "Params"); + ok(paramsModel); + + const client = sdkPackage.clients[0]; + strictEqual(client.methods.length, 1); + const method = client.methods[0]; + + strictEqual(method.kind, "basic"); + strictEqual(method.name, "func"); + strictEqual(method.parameters.length, 2); + const contentTypeParam = method.parameters.find((x) => x.name === "contentType"); + ok(contentTypeParam); + const paramsParam = method.parameters.find((x) => x.name === "params"); + ok(paramsParam); + strictEqual(paramsModel, paramsParam.type); + + ok(method.operation.bodyParam); + strictEqual(method.operation.bodyParam.correspondingMethodParams.length, 2); + strictEqual(method.operation.bodyParam.correspondingMethodParams[0], paramsModel.properties[0]); + strictEqual(method.operation.bodyParam.correspondingMethodParams[1], paramsModel.properties[1]); + }); + + it("basic with scope", async () => { + const mainCode = ` + @service + namespace MyService; + model Params { + foo: string; + bar: string; + } + + op func(...Params): void; + `; + + const customizationCode = ` + namespace MyCustomizations; + + op func(params: MyService.Params): void; + + @@override(MyService.func, MyCustomizations.func, "csharp"); + `; + await runner.compileWithCustomization(mainCode, customizationCode); + // runner has python scope, so shouldn't be overridden + + ok(runner.context.sdkPackage.models.find((x) => x.name === "Params")); + const sdkPackage = runner.context.sdkPackage; + const client = sdkPackage.clients[0]; + strictEqual(client.methods.length, 1); + const method = client.methods[0]; + strictEqual(method.kind, "basic"); + strictEqual(method.name, "func"); + strictEqual(method.parameters.length, 3); + + const contentTypeParam = method.parameters.find((x) => x.name === "contentType"); + ok(contentTypeParam); + + const fooParam = method.parameters.find((x) => x.name === "foo"); + ok(fooParam); + + const barParam = method.parameters.find((x) => x.name === "bar"); + ok(barParam); + + const httpOp = method.operation; + strictEqual(httpOp.parameters.length, 1); + strictEqual(httpOp.parameters[0].correspondingMethodParams[0], contentTypeParam); + + ok(httpOp.bodyParam); + strictEqual(httpOp.bodyParam.correspondingMethodParams.length, 2); + strictEqual(httpOp.bodyParam.correspondingMethodParams[0], fooParam); + strictEqual(httpOp.bodyParam.correspondingMethodParams[1], barParam); + + const runnerWithCsharp = await createSdkTestRunner({ + emitterName: "@azure-tools/typespec-csharp", + }); + await runnerWithCsharp.compileWithCustomization(mainCode, customizationCode); + const paramModel = runnerWithCsharp.context.sdkPackage.models.find((x) => x.name === "Params"); + ok(paramModel); + + const sdkPackageWithCsharp = runnerWithCsharp.context.sdkPackage; + strictEqual(sdkPackageWithCsharp.clients.length, 1); + + strictEqual(sdkPackageWithCsharp.clients[0].methods.length, 1); + const methodWithCsharp = sdkPackageWithCsharp.clients[0].methods[0]; + strictEqual(methodWithCsharp.kind, "basic"); + strictEqual(methodWithCsharp.name, "func"); + strictEqual(methodWithCsharp.parameters.length, 2); + const contentTypeParamWithCsharp = methodWithCsharp.parameters.find( + (x) => x.name === "contentType", + ); + ok(contentTypeParamWithCsharp); + + const paramsParamWithCsharp = methodWithCsharp.parameters.find((x) => x.name === "params"); + ok(paramsParamWithCsharp); + strictEqual(paramModel, paramsParamWithCsharp.type); + + const httpOpWithCsharp = methodWithCsharp.operation; + strictEqual(httpOpWithCsharp.parameters.length, 1); + strictEqual( + httpOpWithCsharp.parameters[0].correspondingMethodParams[0], + contentTypeParamWithCsharp, + ); + ok(httpOpWithCsharp.bodyParam); + strictEqual(httpOpWithCsharp.bodyParam.correspondingMethodParams.length, 2); + strictEqual(httpOpWithCsharp.bodyParam.correspondingMethodParams[0], paramModel.properties[0]); + strictEqual(httpOpWithCsharp.bodyParam.correspondingMethodParams[1], paramModel.properties[1]); + }); + + it("regrouping", async () => { + const mainCode = ` + @service + namespace MyService; + model Params { + foo: string; + bar: string; + fooBar: string; + } + + op func(...Params): void; + `; + + const customizationCode = ` + namespace MyCustomizations; + + model ParamsCustomized { + ...PickProperties; + } + + op func(params: MyCustomizations.ParamsCustomized, ...PickProperties): void; + + @@override(MyService.func, MyCustomizations.func); + `; + await runner.compileWithCustomization(mainCode, customizationCode); + // runner has python scope, so shouldn't be overridden + + const sdkPackage = runner.context.sdkPackage; + const client = sdkPackage.clients[0]; + strictEqual(client.methods.length, 1); + const method = client.methods[0]; + strictEqual(method.kind, "basic"); + strictEqual(method.name, "func"); + strictEqual(method.parameters.length, 3); + + const contentTypeParam = method.parameters.find((x) => x.name === "contentType"); + ok(contentTypeParam); + + const paramsParam = method.parameters.find((x) => x.name === "params"); + ok(paramsParam); + + const fooBarParam = method.parameters.find((x) => x.name === "fooBar"); + ok(fooBarParam); + + const httpOp = method.operation; + strictEqual(httpOp.parameters.length, 1); + strictEqual(httpOp.parameters[0].correspondingMethodParams[0], contentTypeParam); + + strictEqual(sdkPackage.models.length, 2); + const paramsModel = sdkPackage.models.find((x) => x.name === "Params"); + ok(paramsModel); + strictEqual(paramsModel.usage, UsageFlags.Spread | UsageFlags.Json); + const paramsCustomizedModel = sdkPackage.models.find((x) => x.name === "ParamsCustomized"); + ok(paramsCustomizedModel); + strictEqual(paramsCustomizedModel.usage, UsageFlags.Input); + + ok(httpOp.bodyParam); + strictEqual(httpOp.bodyParam.correspondingMethodParams.length, 3); + strictEqual(httpOp.bodyParam.correspondingMethodParams[0], paramsCustomizedModel.properties[0]); + strictEqual(httpOp.bodyParam.correspondingMethodParams[1], paramsCustomizedModel.properties[1]); + strictEqual(httpOp.bodyParam.correspondingMethodParams[2], fooBarParam); + }); + + it("params mismatch", async () => { + const mainCode = ` + @service + namespace MyService; + model Params { + foo: string; + bar: string; + } + + op func(...Params): void; + `; + + const customizationCode = ` + namespace MyCustomizations; + + model ParamsCustomized { + foo: string; + bar: string; + } + + op func(params: MyCustomizations.ParamsCustomized): void; + + @@override(MyService.func, MyCustomizations.func); + `; + const diagnostics = ( + await runner.compileAndDiagnoseWithCustomization(mainCode, customizationCode) + )[1]; + expectDiagnostics(diagnostics, { + code: "@azure-tools/typespec-client-generator-core/override-method-parameters-mismatch", + }); + }); + + it("recursive params", async () => { + await runner.compileWithCustomization( + ` + @service + namespace MyService; + model Params { + foo: string; + params: Params[]; + } + + op func(...Params): void; + `, + ` + namespace MyCustomizations; + + op func(input: MyService.Params): void; + + @@override(MyService.func, MyCustomizations.func); + `, + ); + const sdkPackage = runner.context.sdkPackage; + + const paramsModel = sdkPackage.models.find((x) => x.name === "Params"); + ok(paramsModel); + + const client = sdkPackage.clients[0]; + strictEqual(client.methods.length, 1); + const method = client.methods[0]; + + strictEqual(method.kind, "basic"); + strictEqual(method.name, "func"); + strictEqual(method.parameters.length, 2); + const contentTypeParam = method.parameters.find((x) => x.name === "contentType"); + ok(contentTypeParam); + const inputParam = method.parameters.find((x) => x.name === "input"); + ok(inputParam); + strictEqual(paramsModel, inputParam.type); + + ok(method.operation.bodyParam); + strictEqual(method.operation.bodyParam.correspondingMethodParams.length, 2); + strictEqual(method.operation.bodyParam.correspondingMethodParams[0], paramsModel.properties[0]); + strictEqual(method.operation.bodyParam.correspondingMethodParams[1], paramsModel.properties[1]); + }); + + it("core template", async () => { + const runnerWithCore = await createSdkTestRunner({ + librariesToAdd: [AzureCoreTestLibrary], + autoUsings: ["Azure.Core"], + emitterName: "@azure-tools/typespec-java", + }); + await runnerWithCore.compileWithCustomization( + ` + @useDependency(Versions.v1_0_Preview_2) + @server("http://localhost:3000", "endpoint") + @service() + namespace My.Service; + + model Params { + foo: string; + params: Params[]; + } + + @route("/template") + op templateOp is Azure.Core.RpcOperation< + Params, + Params + >; + `, + ` + namespace My.Customizations; + + op templateOp(params: My.Service.Params): My.Service.Params; + + @@override(My.Service.templateOp, My.Customizations.templateOp); + `, + ); + const sdkPackage = runnerWithCore.context.sdkPackage; + const method = sdkPackage.clients[0].methods[0]; + strictEqual(method.parameters.length, 3); + ok(method.parameters.find((x) => x.name === "contentType")); + ok(method.parameters.find((x) => x.name === "accept")); + + const paramsParam = method.parameters.find((x) => x.name === "params"); + ok(paramsParam); + strictEqual(paramsParam.type.kind, "model"); + strictEqual(paramsParam.type.name, "Params"); + }); +}); diff --git a/packages/typespec-client-generator-core/test/packages/client.test.ts b/packages/typespec-client-generator-core/test/packages/client.test.ts index a87c529d10..55d88b07e2 100644 --- a/packages/typespec-client-generator-core/test/packages/client.test.ts +++ b/packages/typespec-client-generator-core/test/packages/client.test.ts @@ -12,7 +12,7 @@ import { } from "../../src/interfaces.js"; import { SdkTestRunner, createSdkTestRunner } from "../test-host.js"; -describe("typespec-client-generator-core: package", () => { +describe("typespec-client-generator-core: client", () => { let runner: SdkTestRunner; beforeEach(async () => { diff --git a/packages/typespec-client-generator-core/test/packages/methods.test.ts b/packages/typespec-client-generator-core/test/packages/methods.test.ts new file mode 100644 index 0000000000..61cfebffbc --- /dev/null +++ b/packages/typespec-client-generator-core/test/packages/methods.test.ts @@ -0,0 +1,39 @@ +import { strictEqual } from "assert"; +import { beforeEach, describe, it } from "vitest"; +import { SdkTestRunner, createSdkTestRunner } from "../test-host.js"; +import { getServiceMethodOfClient } from "./utils.js"; + +describe("typespec-client-generator-core: parameters", () => { + let runner: SdkTestRunner; + + beforeEach(async () => { + runner = await createSdkTestRunner({ emitterName: "@azure-tools/typespec-python" }); + }); + + it("isOverride false", async () => { + await runner.compileWithBuiltInService(` + op test(): void; + `); + const sdkPackage = runner.context.sdkPackage; + const method = getServiceMethodOfClient(sdkPackage); + strictEqual(method.isOverride, false); + }); + + it("isOverride true", async () => { + await runner.compileWithBuiltInService(` + model TestOptions { + @query a: string; + @query b: string; + } + + op test(...TestOptions): void; + + op testOverride(options: TestOptions): void; + + @@override(test, testOverride); + `); + const sdkPackage = runner.context.sdkPackage; + const method = getServiceMethodOfClient(sdkPackage); + strictEqual(method.isOverride, true); + }); +}); diff --git a/packages/typespec-client-generator-core/test/packages/responses.test.ts b/packages/typespec-client-generator-core/test/packages/responses.test.ts index 1551880dcb..f08b89706f 100644 --- a/packages/typespec-client-generator-core/test/packages/responses.test.ts +++ b/packages/typespec-client-generator-core/test/packages/responses.test.ts @@ -3,7 +3,7 @@ import { beforeEach, describe, it } from "vitest"; import { SdkTestRunner, createSdkTestRunner } from "../test-host.js"; import { getServiceMethodOfClient } from "./utils.js"; -describe("typespec-client-generator-core: package", () => { +describe("typespec-client-generator-core: responses", () => { let runner: SdkTestRunner; beforeEach(async () => {