From e3cda93cd6e6f7a9b375af2c468113173f342b5b Mon Sep 17 00:00:00 2001 From: Shivanee Persaud Date: Fri, 31 Jul 2026 13:25:11 -0700 Subject: [PATCH 1/6] feat(generator): add enable_telemetry_tracing option and client interface field --- .../gapic-generator-typescript/typescript/src/generator.ts | 7 +++++++ .../typescript/src/schema/api.ts | 2 ++ .../typescript/src/schema/naming.ts | 1 + 3 files changed, 10 insertions(+) diff --git a/core/generator/gapic-generator-typescript/typescript/src/generator.ts b/core/generator/gapic-generator-typescript/typescript/src/generator.ts index 84a8e818781f..c6cbf042839e 100644 --- a/core/generator/gapic-generator-typescript/typescript/src/generator.ts +++ b/core/generator/gapic-generator-typescript/typescript/src/generator.ts @@ -86,6 +86,7 @@ export class Generator { restNumericEnums?: boolean; mixinsOverride?: string[]; format?: string | string[]; + enableTelemetryTracing?: boolean; private root: protobuf.Root; @@ -227,6 +228,10 @@ export class Generator { } } + private readEnableTelemetryTracing() { + this.enableTelemetryTracing = this.paramMap['enable_telemetry_tracing'] === 'true'; + } + private readLegacyProtoLoad() { if (this.paramMap['legacy-proto-load'] === 'true') { this.legacyProtoLoad = true; @@ -274,6 +279,7 @@ export class Generator { this.readLegacyProtoLoad(); this.readRestNumericEnums(); this.readFormat(); + this.readEnableTelemetryTracing(); } } @@ -334,6 +340,7 @@ export class Generator { legacyProtoLoad: this.legacyProtoLoad, restNumericEnums: this.restNumericEnums, mixinsOverridden: this.mixinsOverride !== undefined, + enableTelemetryTracing: this.enableTelemetryTracing, }); return api; } diff --git a/core/generator/gapic-generator-typescript/typescript/src/schema/api.ts b/core/generator/gapic-generator-typescript/typescript/src/schema/api.ts index a49572f920f2..2e8c02aadc69 100644 --- a/core/generator/gapic-generator-typescript/typescript/src/schema/api.ts +++ b/core/generator/gapic-generator-typescript/typescript/src/schema/api.ts @@ -45,6 +45,7 @@ export class API { restNumericEnums: boolean; documentationUri: any; newIssueUri: string; + enableTelemetryTracing?: boolean; title?: string; static isIgnoredService( @@ -112,6 +113,7 @@ export class API { this.documentationUri = options.serviceYaml?.publishing?.documentation_uri ?? ''; this.newIssueUri = options.serviceYaml?.publishing?.new_issue_uri ?? ''; + this.enableTelemetryTracing = options.enableTelemetryTracing ?? false; this.title = options.serviceYaml?.title; const [allResourceDatabase, resourceDatabase] = diff --git a/core/generator/gapic-generator-typescript/typescript/src/schema/naming.ts b/core/generator/gapic-generator-typescript/typescript/src/schema/naming.ts index 0d95f68a732c..49c90c9f1b63 100644 --- a/core/generator/gapic-generator-typescript/typescript/src/schema/naming.ts +++ b/core/generator/gapic-generator-typescript/typescript/src/schema/naming.ts @@ -30,6 +30,7 @@ export interface Options { legacyProtoLoad?: boolean; restNumericEnums?: boolean; mixinsOverridden?: boolean; + enableTelemetryTracing?: boolean; } export class Naming { From 7879f5af89b16c6a7ff3a79ec5d4a73ca6bba17e Mon Sep 17 00:00:00 2001 From: Shivanee Persaud Date: Fri, 31 Jul 2026 13:27:07 -0700 Subject: [PATCH 2/6] test(generator): add unit tests for enableTelemetryTracing option --- .../typescript/test/unit/api.ts | 21 +++++++++++++++++++ .../typescript/test/unit/naming.ts | 13 ++++++++++++ 2 files changed, 34 insertions(+) diff --git a/core/generator/gapic-generator-typescript/typescript/test/unit/api.ts b/core/generator/gapic-generator-typescript/typescript/test/unit/api.ts index 4be052b5bccc..0fddfb7f3e71 100644 --- a/core/generator/gapic-generator-typescript/typescript/test/unit/api.ts +++ b/core/generator/gapic-generator-typescript/typescript/test/unit/api.ts @@ -325,4 +325,25 @@ describe('src/schema/api.ts', () => { assert('.google.cloud.example.v1.MessageB' in secondCallMessages); }); }); + + it('should set enableTelemetryTracing option', () => { + const fd = {} as protos.google.protobuf.FileDescriptorProto; + fd.name = 'google/cloud/test/v1/test.proto'; + fd.package = 'google.cloud.test.v1'; + fd.service = [{} as protos.google.protobuf.ServiceDescriptorProto]; + fd.service[0].name = 'ZService'; + fd.service[0].options = { + '.google.api.defaultHost': 'hostname.example.com:443', + }; + const apiWithTracing = new API([fd], 'google.cloud.test.v1', { + grpcServiceConfig: {} as protos.grpc.service_config.ServiceConfig, + enableTelemetryTracing: true, + }); + assert.strictEqual(apiWithTracing.enableTelemetryTracing, true); + + const apiWithoutTracing = new API([fd], 'google.cloud.test.v1', { + grpcServiceConfig: {} as protos.grpc.service_config.ServiceConfig, + }); + assert.strictEqual(apiWithoutTracing.enableTelemetryTracing, false); + }); }); diff --git a/core/generator/gapic-generator-typescript/typescript/test/unit/naming.ts b/core/generator/gapic-generator-typescript/typescript/test/unit/naming.ts index 2aec137f42ec..8ab6e94db8ff 100644 --- a/core/generator/gapic-generator-typescript/typescript/test/unit/naming.ts +++ b/core/generator/gapic-generator-typescript/typescript/test/unit/naming.ts @@ -218,4 +218,17 @@ describe('src/schema/naming.ts', () => { assert(naming); }); }); + + it('supports enableTelemetryTracing option', () => { + const descriptor = {} as protos.google.protobuf.FileDescriptorProto; + descriptor.package = 'google.namespace.service.v1beta1'; + descriptor.service = [{} as protos.google.protobuf.ServiceDescriptorProto]; + const options: Options = { + grpcServiceConfig: {} as protos.grpc.service_config.ServiceConfig, + enableTelemetryTracing: true, + }; + const naming = new Naming([descriptor], options); + assert(naming); + assert.strictEqual(naming.name, 'Service'); + }); }); From 4159976a488314a2dc443dba7866af7ec4d7fcee Mon Sep 17 00:00:00 2001 From: Shivanee Persaud Date: Mon, 3 Aug 2026 20:14:50 -0700 Subject: [PATCH 3/6] fix: update readEnableTelemetryTracing to read enable-telemetry-tracing option --- .../gapic-generator-typescript/typescript/src/generator.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/generator/gapic-generator-typescript/typescript/src/generator.ts b/core/generator/gapic-generator-typescript/typescript/src/generator.ts index c6cbf042839e..b66849bed378 100644 --- a/core/generator/gapic-generator-typescript/typescript/src/generator.ts +++ b/core/generator/gapic-generator-typescript/typescript/src/generator.ts @@ -229,7 +229,9 @@ export class Generator { } private readEnableTelemetryTracing() { - this.enableTelemetryTracing = this.paramMap['enable_telemetry_tracing'] === 'true'; + if (this.paramMap['enable-telemetry-tracing'] === 'true') { + this.enableTelemetryTracing = true; + } } private readLegacyProtoLoad() { From 58025e6031b33f2c265f66a2393a719505cea022 Mon Sep 17 00:00:00 2001 From: Shivanee Persaud Date: Mon, 3 Aug 2026 20:57:12 -0700 Subject: [PATCH 4/6] test: add unit tests for Generator class in gapic-generator-typescript --- .../typescript/test/unit/generator.ts | 399 ++++++++++++++++++ 1 file changed, 399 insertions(+) create mode 100644 core/generator/gapic-generator-typescript/typescript/test/unit/generator.ts diff --git a/core/generator/gapic-generator-typescript/typescript/test/unit/generator.ts b/core/generator/gapic-generator-typescript/typescript/test/unit/generator.ts new file mode 100644 index 000000000000..f74665455511 --- /dev/null +++ b/core/generator/gapic-generator-typescript/typescript/test/unit/generator.ts @@ -0,0 +1,399 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import assert from 'assert'; +import {describe, it, beforeEach, afterEach} from 'mocha'; +import {Generator} from '../../src/generator.js'; +import type {API} from '../../src/schema/api.js'; +import type * as protos from '../../../protos/index.js'; +import * as fs from 'fs'; +import * as path from 'path'; +import * as os from 'os'; + +interface TestGenerator { + getParamMap(parameter: string): void; + readGrpcServiceConfig(): Promise; + readBundleConfig(): void; + readServiceYaml(): void; + readPublishPackageName(): void; + readMainServiceName(): void; + readTemplates(): void; + readRest(): void; + readDiregapic(): void; + readHandwrittenLayer(): void; + readFormat(): void; + readEnableTelemetryTracing(): void; + readLegacyProtoLoad(): void; + readRestNumericEnums(): void; + readMixins(): void; + addProtosToResponse(): void; + buildAPIObject(): API; +} + +describe('src/generator.ts', () => { + let generator: Generator; + + beforeEach(() => { + generator = new Generator(); + }); + + function getPrivate(gen: Generator): TestGenerator { + return gen as unknown as TestGenerator; + } + + it('should initialize with default values', () => { + assert.deepStrictEqual(generator.request, {}); + assert.deepStrictEqual(generator.response, {}); + assert.deepStrictEqual(generator.grpcServiceConfig, {}); + assert.deepStrictEqual(generator.paramMap, {}); + assert.deepStrictEqual(generator.templates, [ + 'typescript_gapic', + 'typescript_packing_test', + 'typescript_samples', + ]); + }); + + describe('parameter parsing', () => { + it('should parse parameter options string', () => { + getPrivate(generator).getParamMap( + 'package-name=@google-cloud/test,transport=rest,diregapic=true', + ); + assert.strictEqual( + generator.paramMap['package-name'], + '@google-cloud/test', + ); + assert.strictEqual(generator.paramMap['transport'], 'rest'); + assert.strictEqual(generator.paramMap['diregapic'], 'true'); + }); + + it('should handle parameter without explicit value', () => { + getPrivate(generator).getParamMap('handwritten-layer'); + assert.strictEqual(generator.paramMap['handwritten-layer'], 'true'); + }); + + it('should handle quoted parameters', () => { + getPrivate(generator).getParamMap('"main-service=TestService"'); + assert.strictEqual(generator.paramMap['main-service'], 'TestService'); + }); + + it('should convert parameter keys to kebab-case', () => { + getPrivate(generator).getParamMap( + 'main_service=TestService,legacy_proto_load=true', + ); + assert.strictEqual(generator.paramMap['main-service'], 'TestService'); + assert.strictEqual(generator.paramMap['legacy-proto-load'], 'true'); + }); + }); + + describe('option readers', () => { + it('should read publish package name', () => { + generator.paramMap['package-name'] = '@google-cloud/speech'; + getPrivate(generator).readPublishPackageName(); + assert.strictEqual(generator.publishName, '@google-cloud/speech'); + }); + + it('should read main service name', () => { + generator.paramMap['main-service'] = 'Speech'; + getPrivate(generator).readMainServiceName(); + assert.strictEqual(generator.mainServiceName, 'Speech'); + }); + + it('should read custom templates and metadata flag', () => { + generator.paramMap['template'] = 'custom_template_1;custom_template_2'; + generator.paramMap['metadata'] = 'true'; + getPrivate(generator).readTemplates(); + assert.deepStrictEqual(generator.templates, [ + 'custom_template_1', + 'custom_template_2', + 'typescript_gapic_metadata', + ]); + }); + + it('should read transport rest option', () => { + generator.paramMap['transport'] = 'rest'; + getPrivate(generator).readRest(); + assert.strictEqual(generator.rest, true); + }); + + it('should read diregapic option', () => { + generator.paramMap['diregapic'] = 'true'; + getPrivate(generator).readDiregapic(); + assert.strictEqual(generator.diregapic, true); + assert.strictEqual(generator.rest, true); + }); + + it('should read handwritten-layer option', () => { + generator.paramMap['handwritten-layer'] = 'true'; + getPrivate(generator).readHandwrittenLayer(); + assert.strictEqual(generator.handwrittenLayer, true); + }); + + it('should read format option', () => { + generator.paramMap['format'] = 'esm;cjs'; + getPrivate(generator).readFormat(); + assert.deepStrictEqual(generator.format, ['esm', 'cjs']); + }); + + it('should read telemetry tracing option', () => { + generator.paramMap['enable-telemetry-tracing'] = 'true'; + getPrivate(generator).readEnableTelemetryTracing(); + assert.strictEqual(generator.enableTelemetryTracing, true); + }); + + it('should read legacy proto load option', () => { + generator.paramMap['legacy-proto-load'] = 'true'; + getPrivate(generator).readLegacyProtoLoad(); + assert.strictEqual(generator.legacyProtoLoad, true); + }); + + it('should read rest numeric enums option', () => { + generator.paramMap['rest-numeric-enums'] = 'true'; + getPrivate(generator).readRestNumericEnums(); + assert.strictEqual(generator.restNumericEnums, true); + }); + + it('should read mixins option', () => { + generator.paramMap['mixins'] = + 'google.iam.v1.IAMPolicy;google.longrunning.Operations'; + getPrivate(generator).readMixins(); + assert.deepStrictEqual(generator.mixinsOverride, [ + 'google.iam.v1.IAMPolicy', + 'google.longrunning.Operations', + ]); + }); + }); + + describe('file configurations', () => { + const tmpDir = path.join(os.tmpdir(), 'generator-test-' + Date.now()); + + beforeEach(() => { + fs.mkdirSync(tmpDir, {recursive: true}); + }); + + afterEach(() => { + fs.rmSync(tmpDir, {recursive: true, force: true}); + }); + + it('should throw when gRPC service config file does not exist', async () => { + generator.paramMap['grpc-service-config'] = path.join( + tmpDir, + 'nonexistent.json', + ); + await assert.rejects(async () => { + await getPrivate(generator).readGrpcServiceConfig(); + }, /ERROR: File .* cannot be opened\./); + }); + + it('should read valid gRPC service config file', async () => { + const grpcConfigPath = path.join(tmpDir, 'grpc_service_config.json'); + fs.writeFileSync( + grpcConfigPath, + JSON.stringify({ + methodConfig: [ + { + name: [{service: 'google.test.v1.TestService'}], + timeout: '60s', + }, + ], + }), + ); + generator.paramMap['grpc-service-config'] = grpcConfigPath; + await getPrivate(generator).readGrpcServiceConfig(); + assert.ok(generator.grpcServiceConfig.methodConfig); + assert.strictEqual(generator.grpcServiceConfig.methodConfig.length, 1); + }); + + it('should throw when bundle config file does not exist', () => { + generator.paramMap['bundle-config'] = path.join( + tmpDir, + 'nonexistent.yaml', + ); + assert.throws(() => { + getPrivate(generator).readBundleConfig(); + }, /ERROR: File .* cannot be opened\./); + }); + + it('should throw when service yaml file does not exist', () => { + generator.paramMap['service-yaml'] = path.join( + tmpDir, + 'nonexistent.yaml', + ); + assert.throws(() => { + getPrivate(generator).readServiceYaml(); + }, /ERROR: File .* cannot be opened\./); + }); + + it('should read valid service yaml file', () => { + const serviceYamlPath = path.join(tmpDir, 'service.yaml'); + fs.writeFileSync( + serviceYamlPath, + `title: Test Service +apis: + - name: google.iam.v1.IAMPolicy + - name: google.longrunning.Operations +`, + ); + generator.paramMap['service-yaml'] = serviceYamlPath; + getPrivate(generator).readServiceYaml(); + assert.strictEqual(generator.serviceYaml?.title, 'Test Service'); + assert.deepStrictEqual(generator.serviceYaml?.apis, [ + 'google.iam.v1.IAMPolicy', + 'google.longrunning.Operations', + ]); + }); + + it('should override mixins when mixinsOverride is set', () => { + generator.mixinsOverride = ['google.iam.v1.IAMPolicy']; + getPrivate(generator).readServiceYaml(); + assert.deepStrictEqual(generator.serviceYaml?.apis, [ + 'google.iam.v1.IAMPolicy', + ]); + + generator.mixinsOverride = ['none']; + getPrivate(generator).readServiceYaml(); + assert.deepStrictEqual(generator.serviceYaml?.apis, []); + }); + + it('should read valid bundle config file', () => { + const bundleConfigPath = path.join(tmpDir, 'bundle.yaml'); + fs.writeFileSync( + bundleConfigPath, + `interfaces: + - name: google.test.v1.TestService + methods: + - name: ListItems + batching: + thresholds: + element_count_threshold: 10 + request_byte_threshold: 100 + delay_threshold_millis: 1000 + batch_descriptor: + batched_field: items + discriminator_fields: + - parent + subresponse_field: items +`, + ); + generator.paramMap['bundle-config'] = bundleConfigPath; + getPrivate(generator).readBundleConfig(); + assert.strictEqual(generator.bundleConfigs.length, 1); + assert.strictEqual(generator.bundleConfigs[0].serviceName, 'TestService'); + assert.strictEqual(generator.bundleConfigs[0].methodName, 'ListItems'); + }); + }); + + describe('addProtosToResponse', () => { + it('should populate response with proto.list file', () => { + generator.request = { + protoFile: [ + {name: 'google/cloud/test/v1/test.proto'}, + {name: 'google/cloud/test/v1/other.proto'}, + ], + } as protos.google.protobuf.compiler.CodeGeneratorRequest; + generator.response = { + file: [], + } as protos.google.protobuf.compiler.CodeGeneratorResponse; + + getPrivate(generator).addProtosToResponse(); + + assert.strictEqual(generator.response.file?.length, 1); + assert.strictEqual(generator.response.file?.[0].name, 'proto.list'); + assert.strictEqual( + generator.response.file?.[0].content, + 'google/cloud/test/v1/test.proto\ngoogle/cloud/test/v1/other.proto\n', + ); + }); + }); + + describe('buildAPIObject', () => { + it('should throw error if protos define no services', () => { + generator.request = { + protoFile: [ + { + name: 'google/cloud/test/v1/test.proto', + package: 'google.cloud.test.v1', + }, + ], + fileToGenerate: ['google/cloud/test/v1/test.proto'], + } as protos.google.protobuf.compiler.CodeGeneratorRequest; + + assert.throws(() => { + getPrivate(generator).buildAPIObject(); + }, /ERROR: Protos do not define any service/); + }); + + it('should create API object when services are defined', () => { + generator.request = { + protoFile: [ + { + name: 'google/cloud/test/v1/test.proto', + package: 'google.cloud.test.v1', + service: [ + { + name: 'TestService', + options: { + '.google.api.defaultHost': 'test.googleapis.com', + }, + }, + ], + }, + ], + fileToGenerate: ['google/cloud/test/v1/test.proto'], + } as protos.google.protobuf.compiler.CodeGeneratorRequest; + + const api = getPrivate(generator).buildAPIObject(); + assert.ok(api); + assert.strictEqual(api.packageName, 'google.cloud.test.v1'); + }); + }); + + describe('processTemplates', () => { + it('should throw error if template location does not exist', async () => { + generator.templates = ['nonexistent_template_dir']; + const api = {} as API; + + await assert.rejects(async () => { + await generator.processTemplates(api); + }, /Template directory .* does not exist\./); + }); + }); + + describe('generate', () => { + it('should capture error message in response on failure', async () => { + const originalStdoutWrite = process.stdout.write; + let writtenBuffer: Buffer | null = null; + + process.stdout.write = (chunk: Uint8Array | string) => { + writtenBuffer = Buffer.from(chunk); + return true; + }; + + try { + generator.request = { + protoFile: [], + } as protos.google.protobuf.compiler.CodeGeneratorRequest; + + await generator.generate(); + + assert.strictEqual( + generator.response.error, + 'ERROR: Protos do not define any service, client library cannot be generated.', + ); + assert.ok(writtenBuffer); + } finally { + process.stdout.write = originalStdoutWrite; + } + }); + }); +}); From fbe04320d62fc18e4c40d1e65eb302f183f50964 Mon Sep 17 00:00:00 2001 From: Shivanee Persaud Date: Mon, 3 Aug 2026 21:00:31 -0700 Subject: [PATCH 5/6] refactor: rename helper to getTestGenerator in generator unit tests --- .../typescript/test/unit/generator.ts | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/core/generator/gapic-generator-typescript/typescript/test/unit/generator.ts b/core/generator/gapic-generator-typescript/typescript/test/unit/generator.ts index f74665455511..73b82e1e931f 100644 --- a/core/generator/gapic-generator-typescript/typescript/test/unit/generator.ts +++ b/core/generator/gapic-generator-typescript/typescript/test/unit/generator.ts @@ -48,7 +48,7 @@ describe('src/generator.ts', () => { generator = new Generator(); }); - function getPrivate(gen: Generator): TestGenerator { + function getTestGenerator(gen: Generator): TestGenerator { return gen as unknown as TestGenerator; } @@ -66,7 +66,7 @@ describe('src/generator.ts', () => { describe('parameter parsing', () => { it('should parse parameter options string', () => { - getPrivate(generator).getParamMap( + getTestGenerator(generator).getParamMap( 'package-name=@google-cloud/test,transport=rest,diregapic=true', ); assert.strictEqual( @@ -78,17 +78,17 @@ describe('src/generator.ts', () => { }); it('should handle parameter without explicit value', () => { - getPrivate(generator).getParamMap('handwritten-layer'); + getTestGenerator(generator).getParamMap('handwritten-layer'); assert.strictEqual(generator.paramMap['handwritten-layer'], 'true'); }); it('should handle quoted parameters', () => { - getPrivate(generator).getParamMap('"main-service=TestService"'); + getTestGenerator(generator).getParamMap('"main-service=TestService"'); assert.strictEqual(generator.paramMap['main-service'], 'TestService'); }); it('should convert parameter keys to kebab-case', () => { - getPrivate(generator).getParamMap( + getTestGenerator(generator).getParamMap( 'main_service=TestService,legacy_proto_load=true', ); assert.strictEqual(generator.paramMap['main-service'], 'TestService'); @@ -99,20 +99,20 @@ describe('src/generator.ts', () => { describe('option readers', () => { it('should read publish package name', () => { generator.paramMap['package-name'] = '@google-cloud/speech'; - getPrivate(generator).readPublishPackageName(); + getTestGenerator(generator).readPublishPackageName(); assert.strictEqual(generator.publishName, '@google-cloud/speech'); }); it('should read main service name', () => { generator.paramMap['main-service'] = 'Speech'; - getPrivate(generator).readMainServiceName(); + getTestGenerator(generator).readMainServiceName(); assert.strictEqual(generator.mainServiceName, 'Speech'); }); it('should read custom templates and metadata flag', () => { generator.paramMap['template'] = 'custom_template_1;custom_template_2'; generator.paramMap['metadata'] = 'true'; - getPrivate(generator).readTemplates(); + getTestGenerator(generator).readTemplates(); assert.deepStrictEqual(generator.templates, [ 'custom_template_1', 'custom_template_2', @@ -122,51 +122,51 @@ describe('src/generator.ts', () => { it('should read transport rest option', () => { generator.paramMap['transport'] = 'rest'; - getPrivate(generator).readRest(); + getTestGenerator(generator).readRest(); assert.strictEqual(generator.rest, true); }); it('should read diregapic option', () => { generator.paramMap['diregapic'] = 'true'; - getPrivate(generator).readDiregapic(); + getTestGenerator(generator).readDiregapic(); assert.strictEqual(generator.diregapic, true); assert.strictEqual(generator.rest, true); }); it('should read handwritten-layer option', () => { generator.paramMap['handwritten-layer'] = 'true'; - getPrivate(generator).readHandwrittenLayer(); + getTestGenerator(generator).readHandwrittenLayer(); assert.strictEqual(generator.handwrittenLayer, true); }); it('should read format option', () => { generator.paramMap['format'] = 'esm;cjs'; - getPrivate(generator).readFormat(); + getTestGenerator(generator).readFormat(); assert.deepStrictEqual(generator.format, ['esm', 'cjs']); }); it('should read telemetry tracing option', () => { generator.paramMap['enable-telemetry-tracing'] = 'true'; - getPrivate(generator).readEnableTelemetryTracing(); + getTestGenerator(generator).readEnableTelemetryTracing(); assert.strictEqual(generator.enableTelemetryTracing, true); }); it('should read legacy proto load option', () => { generator.paramMap['legacy-proto-load'] = 'true'; - getPrivate(generator).readLegacyProtoLoad(); + getTestGenerator(generator).readLegacyProtoLoad(); assert.strictEqual(generator.legacyProtoLoad, true); }); it('should read rest numeric enums option', () => { generator.paramMap['rest-numeric-enums'] = 'true'; - getPrivate(generator).readRestNumericEnums(); + getTestGenerator(generator).readRestNumericEnums(); assert.strictEqual(generator.restNumericEnums, true); }); it('should read mixins option', () => { generator.paramMap['mixins'] = 'google.iam.v1.IAMPolicy;google.longrunning.Operations'; - getPrivate(generator).readMixins(); + getTestGenerator(generator).readMixins(); assert.deepStrictEqual(generator.mixinsOverride, [ 'google.iam.v1.IAMPolicy', 'google.longrunning.Operations', @@ -191,7 +191,7 @@ describe('src/generator.ts', () => { 'nonexistent.json', ); await assert.rejects(async () => { - await getPrivate(generator).readGrpcServiceConfig(); + await getTestGenerator(generator).readGrpcServiceConfig(); }, /ERROR: File .* cannot be opened\./); }); @@ -209,7 +209,7 @@ describe('src/generator.ts', () => { }), ); generator.paramMap['grpc-service-config'] = grpcConfigPath; - await getPrivate(generator).readGrpcServiceConfig(); + await getTestGenerator(generator).readGrpcServiceConfig(); assert.ok(generator.grpcServiceConfig.methodConfig); assert.strictEqual(generator.grpcServiceConfig.methodConfig.length, 1); }); @@ -220,7 +220,7 @@ describe('src/generator.ts', () => { 'nonexistent.yaml', ); assert.throws(() => { - getPrivate(generator).readBundleConfig(); + getTestGenerator(generator).readBundleConfig(); }, /ERROR: File .* cannot be opened\./); }); @@ -230,7 +230,7 @@ describe('src/generator.ts', () => { 'nonexistent.yaml', ); assert.throws(() => { - getPrivate(generator).readServiceYaml(); + getTestGenerator(generator).readServiceYaml(); }, /ERROR: File .* cannot be opened\./); }); @@ -245,7 +245,7 @@ apis: `, ); generator.paramMap['service-yaml'] = serviceYamlPath; - getPrivate(generator).readServiceYaml(); + getTestGenerator(generator).readServiceYaml(); assert.strictEqual(generator.serviceYaml?.title, 'Test Service'); assert.deepStrictEqual(generator.serviceYaml?.apis, [ 'google.iam.v1.IAMPolicy', @@ -255,13 +255,13 @@ apis: it('should override mixins when mixinsOverride is set', () => { generator.mixinsOverride = ['google.iam.v1.IAMPolicy']; - getPrivate(generator).readServiceYaml(); + getTestGenerator(generator).readServiceYaml(); assert.deepStrictEqual(generator.serviceYaml?.apis, [ 'google.iam.v1.IAMPolicy', ]); generator.mixinsOverride = ['none']; - getPrivate(generator).readServiceYaml(); + getTestGenerator(generator).readServiceYaml(); assert.deepStrictEqual(generator.serviceYaml?.apis, []); }); @@ -286,7 +286,7 @@ apis: `, ); generator.paramMap['bundle-config'] = bundleConfigPath; - getPrivate(generator).readBundleConfig(); + getTestGenerator(generator).readBundleConfig(); assert.strictEqual(generator.bundleConfigs.length, 1); assert.strictEqual(generator.bundleConfigs[0].serviceName, 'TestService'); assert.strictEqual(generator.bundleConfigs[0].methodName, 'ListItems'); @@ -305,7 +305,7 @@ apis: file: [], } as protos.google.protobuf.compiler.CodeGeneratorResponse; - getPrivate(generator).addProtosToResponse(); + getTestGenerator(generator).addProtosToResponse(); assert.strictEqual(generator.response.file?.length, 1); assert.strictEqual(generator.response.file?.[0].name, 'proto.list'); @@ -329,7 +329,7 @@ apis: } as protos.google.protobuf.compiler.CodeGeneratorRequest; assert.throws(() => { - getPrivate(generator).buildAPIObject(); + getTestGenerator(generator).buildAPIObject(); }, /ERROR: Protos do not define any service/); }); @@ -352,7 +352,7 @@ apis: fileToGenerate: ['google/cloud/test/v1/test.proto'], } as protos.google.protobuf.compiler.CodeGeneratorRequest; - const api = getPrivate(generator).buildAPIObject(); + const api = getTestGenerator(generator).buildAPIObject(); assert.ok(api); assert.strictEqual(api.packageName, 'google.cloud.test.v1'); }); From 77b4eaf5e0522c792c598e808773219c4a54874c Mon Sep 17 00:00:00 2001 From: Shivanee Persaud Date: Mon, 3 Aug 2026 21:10:56 -0700 Subject: [PATCH 6/6] refactor: update type assertions in generator unit tests --- .../typescript/test/unit/generator.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/generator/gapic-generator-typescript/typescript/test/unit/generator.ts b/core/generator/gapic-generator-typescript/typescript/test/unit/generator.ts index 73b82e1e931f..5ec3b3e1b8a1 100644 --- a/core/generator/gapic-generator-typescript/typescript/test/unit/generator.ts +++ b/core/generator/gapic-generator-typescript/typescript/test/unit/generator.ts @@ -300,10 +300,10 @@ apis: {name: 'google/cloud/test/v1/test.proto'}, {name: 'google/cloud/test/v1/other.proto'}, ], - } as protos.google.protobuf.compiler.CodeGeneratorRequest; + } as unknown as protos.google.protobuf.compiler.CodeGeneratorRequest; generator.response = { file: [], - } as protos.google.protobuf.compiler.CodeGeneratorResponse; + } as unknown as protos.google.protobuf.compiler.CodeGeneratorResponse; getTestGenerator(generator).addProtosToResponse(); @@ -382,7 +382,7 @@ apis: try { generator.request = { protoFile: [], - } as protos.google.protobuf.compiler.CodeGeneratorRequest; + } as unknown as protos.google.protobuf.compiler.CodeGeneratorRequest; await generator.generate();