// 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
//
//     https://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.
//
// ** This file is automatically generated by gapic-generator-typescript. **
// ** https://github.com/googleapis/gapic-generator-typescript **
// ** All changes to this file may be overwritten. **

import * as protos from '../protos/protos';
import * as assert from 'assert';
import * as sinon from 'sinon';
import {SinonStub} from 'sinon';
import {describe, it} from 'mocha';
import * as spannerexecutorproxyModule from '../src';

import {PassThrough} from 'stream';

import {protobuf} from 'google-gax';

// Dynamically loaded proto JSON is needed to get the type information
// to fill in default values for request objects
const root = protobuf.Root.fromJSON(
  require('../protos/protos.json'),
).resolveAll();

// eslint-disable-next-line @typescript-eslint/no-unused-vars
function getTypeDefaultValue(typeName: string, fields: string[]) {
  let type = root.lookupType(typeName) as protobuf.Type;
  for (const field of fields.slice(0, -1)) {
    type = type.fields[field]?.resolvedType as protobuf.Type;
  }
  return type.fields[fields[fields.length - 1]]?.defaultValue;
}

function generateSampleMessage<T extends object>(instance: T) {
  const filledObject = (
    instance.constructor as typeof protobuf.Message
  ).toObject(instance as protobuf.Message<T>, {defaults: true});
  return (instance.constructor as typeof protobuf.Message).fromObject(
    filledObject,
  ) as T;
}

function stubBidiStreamingCall<ResponseType>(
  response?: ResponseType,
  error?: Error,
) {
  const transformStub = error
    ? sinon.stub().callsArgWith(2, error)
    : sinon.stub().callsArgWith(2, null, response);
  const mockStream = new PassThrough({
    objectMode: true,
    transform: transformStub,
  });
  return sinon.stub().returns(mockStream);
}

describe('v1.SpannerExecutorProxyClient', () => {
  describe('Common methods', () => {
    it('has apiEndpoint', () => {
      const client =
        new spannerexecutorproxyModule.v1.SpannerExecutorProxyClient();
      const apiEndpoint = client.apiEndpoint;
      assert.strictEqual(apiEndpoint, 'spanner-cloud-executor.googleapis.com');
    });

    it('has universeDomain', () => {
      const client =
        new spannerexecutorproxyModule.v1.SpannerExecutorProxyClient();
      const universeDomain = client.universeDomain;
      assert.strictEqual(universeDomain, 'googleapis.com');
    });

    if (
      typeof process === 'object' &&
      typeof process.emitWarning === 'function'
    ) {
      it('throws DeprecationWarning if static servicePath is used', () => {
        const stub = sinon.stub(process, 'emitWarning');
        const servicePath =
          spannerexecutorproxyModule.v1.SpannerExecutorProxyClient.servicePath;
        assert.strictEqual(
          servicePath,
          'spanner-cloud-executor.googleapis.com',
        );
        assert(stub.called);
        stub.restore();
      });

      it('throws DeprecationWarning if static apiEndpoint is used', () => {
        const stub = sinon.stub(process, 'emitWarning');
        const apiEndpoint =
          spannerexecutorproxyModule.v1.SpannerExecutorProxyClient.apiEndpoint;
        assert.strictEqual(
          apiEndpoint,
          'spanner-cloud-executor.googleapis.com',
        );
        assert(stub.called);
        stub.restore();
      });
    }
    it('sets apiEndpoint according to universe domain camelCase', () => {
      const client =
        new spannerexecutorproxyModule.v1.SpannerExecutorProxyClient({
          universeDomain: 'example.com',
        });
      const servicePath = client.apiEndpoint;
      assert.strictEqual(servicePath, 'spanner-cloud-executor.example.com');
    });

    it('sets apiEndpoint according to universe domain snakeCase', () => {
      const client =
        new spannerexecutorproxyModule.v1.SpannerExecutorProxyClient({
          universe_domain: 'example.com',
        });
      const servicePath = client.apiEndpoint;
      assert.strictEqual(servicePath, 'spanner-cloud-executor.example.com');
    });

    if (typeof process === 'object' && 'env' in process) {
      describe('GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variable', () => {
        it('sets apiEndpoint from environment variable', () => {
          const saved = process.env['GOOGLE_CLOUD_UNIVERSE_DOMAIN'];
          process.env['GOOGLE_CLOUD_UNIVERSE_DOMAIN'] = 'example.com';
          const client =
            new spannerexecutorproxyModule.v1.SpannerExecutorProxyClient();
          const servicePath = client.apiEndpoint;
          assert.strictEqual(servicePath, 'spanner-cloud-executor.example.com');
          if (saved) {
            process.env['GOOGLE_CLOUD_UNIVERSE_DOMAIN'] = saved;
          } else {
            delete process.env['GOOGLE_CLOUD_UNIVERSE_DOMAIN'];
          }
        });

        it('value configured in code has priority over environment variable', () => {
          const saved = process.env['GOOGLE_CLOUD_UNIVERSE_DOMAIN'];
          process.env['GOOGLE_CLOUD_UNIVERSE_DOMAIN'] = 'example.com';
          const client =
            new spannerexecutorproxyModule.v1.SpannerExecutorProxyClient({
              universeDomain: 'configured.example.com',
            });
          const servicePath = client.apiEndpoint;
          assert.strictEqual(
            servicePath,
            'spanner-cloud-executor.configured.example.com',
          );
          if (saved) {
            process.env['GOOGLE_CLOUD_UNIVERSE_DOMAIN'] = saved;
          } else {
            delete process.env['GOOGLE_CLOUD_UNIVERSE_DOMAIN'];
          }
        });
      });
    }
    it('does not allow setting both universeDomain and universe_domain', () => {
      assert.throws(() => {
        new spannerexecutorproxyModule.v1.SpannerExecutorProxyClient({
          universe_domain: 'example.com',
          universeDomain: 'example.net',
        });
      });
    });

    it('has port', () => {
      const port =
        spannerexecutorproxyModule.v1.SpannerExecutorProxyClient.port;
      assert(port);
      assert(typeof port === 'number');
    });

    it('should create a client with no option', () => {
      const client =
        new spannerexecutorproxyModule.v1.SpannerExecutorProxyClient();
      assert(client);
    });

    it('should create a client with gRPC fallback', () => {
      const client =
        new spannerexecutorproxyModule.v1.SpannerExecutorProxyClient({
          fallback: true,
        });
      assert(client);
    });

    it('has initialize method and supports deferred initialization', async () => {
      const client =
        new spannerexecutorproxyModule.v1.SpannerExecutorProxyClient({
          credentials: {client_email: 'bogus', private_key: 'bogus'},
          projectId: 'bogus',
        });
      assert.strictEqual(client.spannerExecutorProxyStub, undefined);
      await client.initialize();
      assert(client.spannerExecutorProxyStub);
    });

    it('has close method for the initialized client', done => {
      const client =
        new spannerexecutorproxyModule.v1.SpannerExecutorProxyClient({
          credentials: {client_email: 'bogus', private_key: 'bogus'},
          projectId: 'bogus',
        });
      client.initialize().catch(err => {
        throw err;
      });
      assert(client.spannerExecutorProxyStub);
      client
        .close()
        .then(() => {
          done();
        })
        .catch(err => {
          throw err;
        });
    });

    it('has close method for the non-initialized client', done => {
      const client =
        new spannerexecutorproxyModule.v1.SpannerExecutorProxyClient({
          credentials: {client_email: 'bogus', private_key: 'bogus'},
          projectId: 'bogus',
        });
      assert.strictEqual(client.spannerExecutorProxyStub, undefined);
      client
        .close()
        .then(() => {
          done();
        })
        .catch(err => {
          throw err;
        });
    });

    it('has getProjectId method', async () => {
      const fakeProjectId = 'fake-project-id';
      const client =
        new spannerexecutorproxyModule.v1.SpannerExecutorProxyClient({
          credentials: {client_email: 'bogus', private_key: 'bogus'},
          projectId: 'bogus',
        });
      client.auth.getProjectId = sinon.stub().resolves(fakeProjectId);
      const result = await client.getProjectId();
      assert.strictEqual(result, fakeProjectId);
      assert((client.auth.getProjectId as SinonStub).calledWithExactly());
    });

    it('has getProjectId method with callback', async () => {
      const fakeProjectId = 'fake-project-id';
      const client =
        new spannerexecutorproxyModule.v1.SpannerExecutorProxyClient({
          credentials: {client_email: 'bogus', private_key: 'bogus'},
          projectId: 'bogus',
        });
      client.auth.getProjectId = sinon
        .stub()
        .callsArgWith(0, null, fakeProjectId);
      const promise = new Promise((resolve, reject) => {
        client.getProjectId((err?: Error | null, projectId?: string | null) => {
          if (err) {
            reject(err);
          } else {
            resolve(projectId);
          }
        });
      });
      const result = await promise;
      assert.strictEqual(result, fakeProjectId);
    });
  });

  describe('executeActionAsync', () => {
    it('invokes executeActionAsync without error', async () => {
      const client =
        new spannerexecutorproxyModule.v1.SpannerExecutorProxyClient({
          credentials: {client_email: 'bogus', private_key: 'bogus'},
          projectId: 'bogus',
        });
      await client.initialize();
      const request = generateSampleMessage(
        new protos.google.spanner.executor.v1.SpannerAsyncActionRequest(),
      );

      const expectedResponse = generateSampleMessage(
        new protos.google.spanner.executor.v1.SpannerAsyncActionResponse(),
      );
      client.innerApiCalls.executeActionAsync =
        stubBidiStreamingCall(expectedResponse);
      const stream = client.executeActionAsync();
      const promise = new Promise((resolve, reject) => {
        stream.on(
          'data',
          (
            response: protos.google.spanner.executor.v1.SpannerAsyncActionResponse,
          ) => {
            resolve(response);
          },
        );
        stream.on('error', (err: Error) => {
          reject(err);
        });
        stream.write(request);
        stream.end();
      });
      const response = await promise;
      assert.deepStrictEqual(response, expectedResponse);
      assert(
        (client.innerApiCalls.executeActionAsync as SinonStub)
          .getCall(0)
          .calledWith(null),
      );
      assert.deepStrictEqual(
        ((stream as unknown as PassThrough)._transform as SinonStub).getCall(0)
          .args[0],
        request,
      );
    });

    it('invokes executeActionAsync with error', async () => {
      const client =
        new spannerexecutorproxyModule.v1.SpannerExecutorProxyClient({
          credentials: {client_email: 'bogus', private_key: 'bogus'},
          projectId: 'bogus',
        });
      await client.initialize();
      const request = generateSampleMessage(
        new protos.google.spanner.executor.v1.SpannerAsyncActionRequest(),
      );
      const expectedError = new Error('expected');
      client.innerApiCalls.executeActionAsync = stubBidiStreamingCall(
        undefined,
        expectedError,
      );
      const stream = client.executeActionAsync();
      const promise = new Promise((resolve, reject) => {
        stream.on(
          'data',
          (
            response: protos.google.spanner.executor.v1.SpannerAsyncActionResponse,
          ) => {
            resolve(response);
          },
        );
        stream.on('error', (err: Error) => {
          reject(err);
        });
        stream.write(request);
        stream.end();
      });
      await assert.rejects(promise, expectedError);
      assert(
        (client.innerApiCalls.executeActionAsync as SinonStub)
          .getCall(0)
          .calledWith(null),
      );
      assert.deepStrictEqual(
        ((stream as unknown as PassThrough)._transform as SinonStub).getCall(0)
          .args[0],
        request,
      );
    });
  });

  describe('Path templates', () => {
    describe('backup', async () => {
      const fakePath = '/rendered/path/backup';
      const expectedParameters = {
        project: 'projectValue',
        instance: 'instanceValue',
        backup: 'backupValue',
      };
      const client =
        new spannerexecutorproxyModule.v1.SpannerExecutorProxyClient({
          credentials: {client_email: 'bogus', private_key: 'bogus'},
          projectId: 'bogus',
        });
      await client.initialize();
      client.pathTemplates.backupPathTemplate.render = sinon
        .stub()
        .returns(fakePath);
      client.pathTemplates.backupPathTemplate.match = sinon
        .stub()
        .returns(expectedParameters);

      it('backupPath', () => {
        const result = client.backupPath(
          'projectValue',
          'instanceValue',
          'backupValue',
        );
        assert.strictEqual(result, fakePath);
        assert(
          (client.pathTemplates.backupPathTemplate.render as SinonStub)
            .getCall(-1)
            .calledWith(expectedParameters),
        );
      });

      it('matchProjectFromBackupName', () => {
        const result = client.matchProjectFromBackupName(fakePath);
        assert.strictEqual(result, 'projectValue');
        assert(
          (client.pathTemplates.backupPathTemplate.match as SinonStub)
            .getCall(-1)
            .calledWith(fakePath),
        );
      });

      it('matchInstanceFromBackupName', () => {
        const result = client.matchInstanceFromBackupName(fakePath);
        assert.strictEqual(result, 'instanceValue');
        assert(
          (client.pathTemplates.backupPathTemplate.match as SinonStub)
            .getCall(-1)
            .calledWith(fakePath),
        );
      });

      it('matchBackupFromBackupName', () => {
        const result = client.matchBackupFromBackupName(fakePath);
        assert.strictEqual(result, 'backupValue');
        assert(
          (client.pathTemplates.backupPathTemplate.match as SinonStub)
            .getCall(-1)
            .calledWith(fakePath),
        );
      });
    });

    describe('backupSchedule', async () => {
      const fakePath = '/rendered/path/backupSchedule';
      const expectedParameters = {
        project: 'projectValue',
        instance: 'instanceValue',
        database: 'databaseValue',
        schedule: 'scheduleValue',
      };
      const client =
        new spannerexecutorproxyModule.v1.SpannerExecutorProxyClient({
          credentials: {client_email: 'bogus', private_key: 'bogus'},
          projectId: 'bogus',
        });
      await client.initialize();
      client.pathTemplates.backupSchedulePathTemplate.render = sinon
        .stub()
        .returns(fakePath);
      client.pathTemplates.backupSchedulePathTemplate.match = sinon
        .stub()
        .returns(expectedParameters);

      it('backupSchedulePath', () => {
        const result = client.backupSchedulePath(
          'projectValue',
          'instanceValue',
          'databaseValue',
          'scheduleValue',
        );
        assert.strictEqual(result, fakePath);
        assert(
          (client.pathTemplates.backupSchedulePathTemplate.render as SinonStub)
            .getCall(-1)
            .calledWith(expectedParameters),
        );
      });

      it('matchProjectFromBackupScheduleName', () => {
        const result = client.matchProjectFromBackupScheduleName(fakePath);
        assert.strictEqual(result, 'projectValue');
        assert(
          (client.pathTemplates.backupSchedulePathTemplate.match as SinonStub)
            .getCall(-1)
            .calledWith(fakePath),
        );
      });

      it('matchInstanceFromBackupScheduleName', () => {
        const result = client.matchInstanceFromBackupScheduleName(fakePath);
        assert.strictEqual(result, 'instanceValue');
        assert(
          (client.pathTemplates.backupSchedulePathTemplate.match as SinonStub)
            .getCall(-1)
            .calledWith(fakePath),
        );
      });

      it('matchDatabaseFromBackupScheduleName', () => {
        const result = client.matchDatabaseFromBackupScheduleName(fakePath);
        assert.strictEqual(result, 'databaseValue');
        assert(
          (client.pathTemplates.backupSchedulePathTemplate.match as SinonStub)
            .getCall(-1)
            .calledWith(fakePath),
        );
      });

      it('matchScheduleFromBackupScheduleName', () => {
        const result = client.matchScheduleFromBackupScheduleName(fakePath);
        assert.strictEqual(result, 'scheduleValue');
        assert(
          (client.pathTemplates.backupSchedulePathTemplate.match as SinonStub)
            .getCall(-1)
            .calledWith(fakePath),
        );
      });
    });

    describe('database', async () => {
      const fakePath = '/rendered/path/database';
      const expectedParameters = {
        project: 'projectValue',
        instance: 'instanceValue',
        database: 'databaseValue',
      };
      const client =
        new spannerexecutorproxyModule.v1.SpannerExecutorProxyClient({
          credentials: {client_email: 'bogus', private_key: 'bogus'},
          projectId: 'bogus',
        });
      await client.initialize();
      client.pathTemplates.databasePathTemplate.render = sinon
        .stub()
        .returns(fakePath);
      client.pathTemplates.databasePathTemplate.match = sinon
        .stub()
        .returns(expectedParameters);

      it('databasePath', () => {
        const result = client.databasePath(
          'projectValue',
          'instanceValue',
          'databaseValue',
        );
        assert.strictEqual(result, fakePath);
        assert(
          (client.pathTemplates.databasePathTemplate.render as SinonStub)
            .getCall(-1)
            .calledWith(expectedParameters),
        );
      });

      it('matchProjectFromDatabaseName', () => {
        const result = client.matchProjectFromDatabaseName(fakePath);
        assert.strictEqual(result, 'projectValue');
        assert(
          (client.pathTemplates.databasePathTemplate.match as SinonStub)
            .getCall(-1)
            .calledWith(fakePath),
        );
      });

      it('matchInstanceFromDatabaseName', () => {
        const result = client.matchInstanceFromDatabaseName(fakePath);
        assert.strictEqual(result, 'instanceValue');
        assert(
          (client.pathTemplates.databasePathTemplate.match as SinonStub)
            .getCall(-1)
            .calledWith(fakePath),
        );
      });

      it('matchDatabaseFromDatabaseName', () => {
        const result = client.matchDatabaseFromDatabaseName(fakePath);
        assert.strictEqual(result, 'databaseValue');
        assert(
          (client.pathTemplates.databasePathTemplate.match as SinonStub)
            .getCall(-1)
            .calledWith(fakePath),
        );
      });
    });

    describe('databaseRole', async () => {
      const fakePath = '/rendered/path/databaseRole';
      const expectedParameters = {
        project: 'projectValue',
        instance: 'instanceValue',
        database: 'databaseValue',
        role: 'roleValue',
      };
      const client =
        new spannerexecutorproxyModule.v1.SpannerExecutorProxyClient({
          credentials: {client_email: 'bogus', private_key: 'bogus'},
          projectId: 'bogus',
        });
      await client.initialize();
      client.pathTemplates.databaseRolePathTemplate.render = sinon
        .stub()
        .returns(fakePath);
      client.pathTemplates.databaseRolePathTemplate.match = sinon
        .stub()
        .returns(expectedParameters);

      it('databaseRolePath', () => {
        const result = client.databaseRolePath(
          'projectValue',
          'instanceValue',
          'databaseValue',
          'roleValue',
        );
        assert.strictEqual(result, fakePath);
        assert(
          (client.pathTemplates.databaseRolePathTemplate.render as SinonStub)
            .getCall(-1)
            .calledWith(expectedParameters),
        );
      });

      it('matchProjectFromDatabaseRoleName', () => {
        const result = client.matchProjectFromDatabaseRoleName(fakePath);
        assert.strictEqual(result, 'projectValue');
        assert(
          (client.pathTemplates.databaseRolePathTemplate.match as SinonStub)
            .getCall(-1)
            .calledWith(fakePath),
        );
      });

      it('matchInstanceFromDatabaseRoleName', () => {
        const result = client.matchInstanceFromDatabaseRoleName(fakePath);
        assert.strictEqual(result, 'instanceValue');
        assert(
          (client.pathTemplates.databaseRolePathTemplate.match as SinonStub)
            .getCall(-1)
            .calledWith(fakePath),
        );
      });

      it('matchDatabaseFromDatabaseRoleName', () => {
        const result = client.matchDatabaseFromDatabaseRoleName(fakePath);
        assert.strictEqual(result, 'databaseValue');
        assert(
          (client.pathTemplates.databaseRolePathTemplate.match as SinonStub)
            .getCall(-1)
            .calledWith(fakePath),
        );
      });

      it('matchRoleFromDatabaseRoleName', () => {
        const result = client.matchRoleFromDatabaseRoleName(fakePath);
        assert.strictEqual(result, 'roleValue');
        assert(
          (client.pathTemplates.databaseRolePathTemplate.match as SinonStub)
            .getCall(-1)
            .calledWith(fakePath),
        );
      });
    });

    describe('instance', async () => {
      const fakePath = '/rendered/path/instance';
      const expectedParameters = {
        project: 'projectValue',
        instance: 'instanceValue',
      };
      const client =
        new spannerexecutorproxyModule.v1.SpannerExecutorProxyClient({
          credentials: {client_email: 'bogus', private_key: 'bogus'},
          projectId: 'bogus',
        });
      await client.initialize();
      client.pathTemplates.instancePathTemplate.render = sinon
        .stub()
        .returns(fakePath);
      client.pathTemplates.instancePathTemplate.match = sinon
        .stub()
        .returns(expectedParameters);

      it('instancePath', () => {
        const result = client.instancePath('projectValue', 'instanceValue');
        assert.strictEqual(result, fakePath);
        assert(
          (client.pathTemplates.instancePathTemplate.render as SinonStub)
            .getCall(-1)
            .calledWith(expectedParameters),
        );
      });

      it('matchProjectFromInstanceName', () => {
        const result = client.matchProjectFromInstanceName(fakePath);
        assert.strictEqual(result, 'projectValue');
        assert(
          (client.pathTemplates.instancePathTemplate.match as SinonStub)
            .getCall(-1)
            .calledWith(fakePath),
        );
      });

      it('matchInstanceFromInstanceName', () => {
        const result = client.matchInstanceFromInstanceName(fakePath);
        assert.strictEqual(result, 'instanceValue');
        assert(
          (client.pathTemplates.instancePathTemplate.match as SinonStub)
            .getCall(-1)
            .calledWith(fakePath),
        );
      });
    });

    describe('instanceConfig', async () => {
      const fakePath = '/rendered/path/instanceConfig';
      const expectedParameters = {
        project: 'projectValue',
        instance_config: 'instanceConfigValue',
      };
      const client =
        new spannerexecutorproxyModule.v1.SpannerExecutorProxyClient({
          credentials: {client_email: 'bogus', private_key: 'bogus'},
          projectId: 'bogus',
        });
      await client.initialize();
      client.pathTemplates.instanceConfigPathTemplate.render = sinon
        .stub()
        .returns(fakePath);
      client.pathTemplates.instanceConfigPathTemplate.match = sinon
        .stub()
        .returns(expectedParameters);

      it('instanceConfigPath', () => {
        const result = client.instanceConfigPath(
          'projectValue',
          'instanceConfigValue',
        );
        assert.strictEqual(result, fakePath);
        assert(
          (client.pathTemplates.instanceConfigPathTemplate.render as SinonStub)
            .getCall(-1)
            .calledWith(expectedParameters),
        );
      });

      it('matchProjectFromInstanceConfigName', () => {
        const result = client.matchProjectFromInstanceConfigName(fakePath);
        assert.strictEqual(result, 'projectValue');
        assert(
          (client.pathTemplates.instanceConfigPathTemplate.match as SinonStub)
            .getCall(-1)
            .calledWith(fakePath),
        );
      });

      it('matchInstanceConfigFromInstanceConfigName', () => {
        const result =
          client.matchInstanceConfigFromInstanceConfigName(fakePath);
        assert.strictEqual(result, 'instanceConfigValue');
        assert(
          (client.pathTemplates.instanceConfigPathTemplate.match as SinonStub)
            .getCall(-1)
            .calledWith(fakePath),
        );
      });
    });

    describe('instancePartition', async () => {
      const fakePath = '/rendered/path/instancePartition';
      const expectedParameters = {
        project: 'projectValue',
        instance: 'instanceValue',
        instance_partition: 'instancePartitionValue',
      };
      const client =
        new spannerexecutorproxyModule.v1.SpannerExecutorProxyClient({
          credentials: {client_email: 'bogus', private_key: 'bogus'},
          projectId: 'bogus',
        });
      await client.initialize();
      client.pathTemplates.instancePartitionPathTemplate.render = sinon
        .stub()
        .returns(fakePath);
      client.pathTemplates.instancePartitionPathTemplate.match = sinon
        .stub()
        .returns(expectedParameters);

      it('instancePartitionPath', () => {
        const result = client.instancePartitionPath(
          'projectValue',
          'instanceValue',
          'instancePartitionValue',
        );
        assert.strictEqual(result, fakePath);
        assert(
          (
            client.pathTemplates.instancePartitionPathTemplate
              .render as SinonStub
          )
            .getCall(-1)
            .calledWith(expectedParameters),
        );
      });

      it('matchProjectFromInstancePartitionName', () => {
        const result = client.matchProjectFromInstancePartitionName(fakePath);
        assert.strictEqual(result, 'projectValue');
        assert(
          (
            client.pathTemplates.instancePartitionPathTemplate
              .match as SinonStub
          )
            .getCall(-1)
            .calledWith(fakePath),
        );
      });

      it('matchInstanceFromInstancePartitionName', () => {
        const result = client.matchInstanceFromInstancePartitionName(fakePath);
        assert.strictEqual(result, 'instanceValue');
        assert(
          (
            client.pathTemplates.instancePartitionPathTemplate
              .match as SinonStub
          )
            .getCall(-1)
            .calledWith(fakePath),
        );
      });

      it('matchInstancePartitionFromInstancePartitionName', () => {
        const result =
          client.matchInstancePartitionFromInstancePartitionName(fakePath);
        assert.strictEqual(result, 'instancePartitionValue');
        assert(
          (
            client.pathTemplates.instancePartitionPathTemplate
              .match as SinonStub
          )
            .getCall(-1)
            .calledWith(fakePath),
        );
      });
    });

    describe('session', async () => {
      const fakePath = '/rendered/path/session';
      const expectedParameters = {
        project: 'projectValue',
        instance: 'instanceValue',
        database: 'databaseValue',
        session: 'sessionValue',
      };
      const client =
        new spannerexecutorproxyModule.v1.SpannerExecutorProxyClient({
          credentials: {client_email: 'bogus', private_key: 'bogus'},
          projectId: 'bogus',
        });
      await client.initialize();
      client.pathTemplates.sessionPathTemplate.render = sinon
        .stub()
        .returns(fakePath);
      client.pathTemplates.sessionPathTemplate.match = sinon
        .stub()
        .returns(expectedParameters);

      it('sessionPath', () => {
        const result = client.sessionPath(
          'projectValue',
          'instanceValue',
          'databaseValue',
          'sessionValue',
        );
        assert.strictEqual(result, fakePath);
        assert(
          (client.pathTemplates.sessionPathTemplate.render as SinonStub)
            .getCall(-1)
            .calledWith(expectedParameters),
        );
      });

      it('matchProjectFromSessionName', () => {
        const result = client.matchProjectFromSessionName(fakePath);
        assert.strictEqual(result, 'projectValue');
        assert(
          (client.pathTemplates.sessionPathTemplate.match as SinonStub)
            .getCall(-1)
            .calledWith(fakePath),
        );
      });

      it('matchInstanceFromSessionName', () => {
        const result = client.matchInstanceFromSessionName(fakePath);
        assert.strictEqual(result, 'instanceValue');
        assert(
          (client.pathTemplates.sessionPathTemplate.match as SinonStub)
            .getCall(-1)
            .calledWith(fakePath),
        );
      });

      it('matchDatabaseFromSessionName', () => {
        const result = client.matchDatabaseFromSessionName(fakePath);
        assert.strictEqual(result, 'databaseValue');
        assert(
          (client.pathTemplates.sessionPathTemplate.match as SinonStub)
            .getCall(-1)
            .calledWith(fakePath),
        );
      });

      it('matchSessionFromSessionName', () => {
        const result = client.matchSessionFromSessionName(fakePath);
        assert.strictEqual(result, 'sessionValue');
        assert(
          (client.pathTemplates.sessionPathTemplate.match as SinonStub)
            .getCall(-1)
            .calledWith(fakePath),
        );
      });
    });
  });
});
