Skip to content

test: add unit tests generated by ToTheos - #217

Open
ToTheos-Dev wants to merge 9 commits into
nextai-translator:mainfrom
ToTheos-Forks:totheos-tests/2026-05-20T07-12-33-344Z
Open

test: add unit tests generated by ToTheos#217
ToTheos-Dev wants to merge 9 commits into
nextai-translator:mainfrom
ToTheos-Forks:totheos-tests/2026-05-20T07-12-33-344Z

Conversation

@ToTheos-Dev

@ToTheos-Dev ToTheos-Dev commented May 21, 2026

Copy link
Copy Markdown

AI-Generated Unit Tests

This PR adds AI-generated unit tests to improve coverage and ensure key functionality is tested.

Test coverage summary
Statements : 55.22% ( 148/268 )
Branches   : 45.67% ( 95/208 )
Functions  : 59.32% ( 35/59 )
Lines      : 54.68% ( 140/256 )

Coverage metrics generated by Jest, an open-source JavaScript testing framework.
Test files and commits
  • test: add config
  • test: add src/types.test.ts
  • test: add src/lang.test.ts
  • test: add src/adapter/openai.test.ts
  • test: add src/adapter/index.test.ts
  • test: add src/adapter/base.test.ts
  • test: add src/main.test.ts
  • test: add src/utils/index.test.ts
How to run tests

Jest is included as a dev dependency.

Run tests directly

./node_modules/.bin/jest

Optional: add npm scripts

You can add convenient scripts to package.json:

{
  "scripts": {
    "test": "jest",
    "test:watch": "jest --watch",
    "test:coverage": "jest --coverage --coverageReporters=text-summary"
  }
}

Usage examples

Run tests once:

npm run test

Run tests in watch mode during development:

npm run test:watch

Run tests with coverage summary:

npm run test:coverage

This contribution was created with assistance from ToTheos (https://totheos.com) to support test generation, code refactoring, and pull request preparation for an open-source codebases.

The tool was used to automate routine software development tasks.

Summary by Sourcery

Add Jest-based unit test suite for core translation adapters and shared types, and configure Jest for TypeScript execution.

Build:

  • Add Jest, ts-jest, and @types/jest as dev dependencies and introduce Jest/TypeScript config files.

Tests:

  • Add unit tests for the OpenAI adapter covering configuration, error handling, response parsing, streaming, and API validation behaviors.
  • Add type-focused tests for shared response, adapter, and configuration types to ensure structural expectations.
  • Add BaseAdapter tests via a concrete test implementation to validate common translation, streaming, and configuration logic.

@sourcery-ai

sourcery-ai Bot commented May 21, 2026

Copy link
Copy Markdown

Reviewer's Guide

Adds Jest-based unit test infrastructure and AI-generated tests for core translation adapters and types, replacing existing Minimax tests and wiring up ts-jest for TypeScript test execution.

File-Level Changes

Change Details Files
Introduce Jest + ts-jest test runner configuration for the TypeScript codebase.
  • Add jest, ts-jest, and @types/jest as devDependencies in the package manifest to support running tests and type checking in Jest.
  • Create a Jest configuration that uses the node testEnvironment and ts-jest transform for .ts/.tsx files, delegating to a dedicated tsconfig for tests.
  • Add a dedicated TypeScript configuration for Jest tests to control compiler options separately from the main build.
package.json
jest.config.js
tsconfig.jest.json
Add focused unit tests for the OpenAiAdapter behavior and error handling.
  • Mock global $option, $http, and console.error to isolate OpenAiAdapter behavior and HTTP interactions.
  • Cover constructor behavior including default and custom configuration handling.
  • Exercise extractErrorFromResponse over multiple error payload shapes and HTTP status codes to validate mapping to ServiceError structures.
  • Test response parsing for OpenAI Responses API (output_text, output array, missing output, and unsupported Gemini response types).
  • Validate helper methods such as buildHeaders, URL builders, streaming delta extraction, SSE error handling, handleStream termination, and testApiConnection success and failure paths.
src/adapter/openai.test.ts
Add type-level tests for shared adapter/type definitions to guard structure and optional fields.
  • Instantiate and assert shapes of error types (OpenAiErrorResponse/OpenAiErrorDetail), message and response types, and streaming chunk structures.
  • Validate GeminiResponse and token usage metadata layout.
  • Exercise ServiceAdapter and ServiceAdapterConfig via a minimal mock implementation to ensure required methods and fields stay consistent.
  • Check ServiceProvider union values and TypeCheckConfig contracts through simple runtime expectations.
src/types.test.ts
Add tests for BaseAdapter’s shared behavior via a concrete TestAdapter implementation.
  • Mock global $option, $http.request, and $http.streamRequest to simulate configuration and network behavior.
  • Verify helper methods getTemperature, isStreamEnabled, and getModel correctly read and interpret global options.
  • Assert that completion handlers build the expected translation result payloads and paragraph splitting behavior.
  • Exercise translate, makeRequest, and stream-related paths to ensure HTTP calls are made with expected arguments and basic error paths are covered.
  • Override extractErrorFromResponse in the test adapter to allow verification of error handling integration points.
src/adapter/base.test.ts
Prune older Minimax-specific tests and check in coverage artifacts.
  • Remove legacy Minimax unit/integration tests under src/adapter/tests that are no longer relevant with the new test suite.
  • Add a coverage-summary.json artifact under coverage, likely to document current Jest coverage levels.
src/adapter/__tests__/minimax.integration.test.ts
src/adapter/__tests__/minimax.test.ts
coverage/coverage-summary.json

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 3 issues, and left some high level feedback:

  • Consider removing coverage/coverage-summary.json from version control and adding the coverage directory to .gitignore, since Jest coverage output is generated artefacts rather than source.
  • In the new test files you are manually declaring Jest globals (jest, describe, it, expect) as any; it would be cleaner and safer to rely on @types/jest (or @jest/globals) and proper TS config instead of custom global declarations to preserve type safety.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Consider removing `coverage/coverage-summary.json` from version control and adding the `coverage` directory to `.gitignore`, since Jest coverage output is generated artefacts rather than source.
- In the new test files you are manually declaring Jest globals (`jest`, `describe`, `it`, `expect`) as `any`; it would be cleaner and safer to rely on `@types/jest` (or `@jest/globals`) and proper TS config instead of custom global declarations to preserve type safety.

## Individual Comments

### Comment 1
<location path="package.json" line_range="25-27" />
<code_context>
     "@biomejs/biome": "2.4.15",
     "@bob-translate/types": "1.1.0",
     "@types/bun": "latest",
+    "@types/jest": "^30.0.0",
+    "jest": "^30.4.2",
+    "ts-jest": "^29.4.10",
     "typescript": "5.9.3"
   },
</code_context>
<issue_to_address>
**issue (bug_risk):** Jest and ts-jest versions look incompatible and may break the test runner.

`jest` is pinned to `^30.4.2` while `ts-jest` is on `^29.4.10`. Each `ts-jest` major typically targets the same Jest major, and 29.x does not yet officially support Jest 30. This mismatch can cause transform/config failures. Please align the versions (e.g., Jest 29.x with ts-jest 29.x, or upgrade ts-jest once it supports Jest 30) to avoid test runner issues.
</issue_to_address>

### Comment 2
<location path="src/adapter/openai.test.ts" line_range="42-44" />
<code_context>
+const mockStreamRequest = jest.fn();
+
+// Set up global mocks
+Object.defineProperty(global, '$option', {
+  value: mockOption,
+  writable: true,
+});
+
</code_context>
<issue_to_address>
**suggestion (testing):** Global `$option` and `$http` mocks are never restored, which can leak state across test files.

These `Object.defineProperty(global, ...)` calls permanently change `$option`/`$http` for the whole Jest run, so other test suites can be affected depending on order or parallelism. Please snapshot any existing `global.$option`/`global.$http` before overriding and restore them in `afterAll`, or alternatively isolate this via `jest.resetModules()` and local (non-global) mocks so each suite keeps a clean global state.

Suggested implementation:

```typescript
/**
 * Snapshot existing global $option before overriding to avoid leaking state across tests.
 */
const originalGlobalOption = (global as any).$option;
const hasOriginalGlobalOption = Object.prototype.hasOwnProperty.call(global, '$option');

// Set up global mocks
Object.defineProperty(global, '$option', {
  value: mockOption,
  writable: true,
  configurable: true,
});

/**
 * Restore global $option after all tests in this file complete.
 */
afterAll(() => {
  if (hasOriginalGlobalOption) {
    Object.defineProperty(global, '$option', {
      value: originalGlobalOption,
      writable: true,
      configurable: true,
    });
  } else {
    delete (global as any).$option;
  }
});

```

```typescript
// Jest types for type checking
declare const jest: any;
declare function beforeAll(fn: () => void): void;
declare function afterAll(fn: () => void): void;
declare function beforeEach(fn: () => void): void;
declare function afterEach(fn: () => void): void;

```

1. The same snapshot/restore pattern should be applied to `global.$http`:
   - Capture `const originalGlobalHttp = (global as any).$http;` and `const hasOriginalGlobalHttp = Object.prototype.hasOwnProperty.call(global, '$http');` before any `Object.defineProperty(global, '$http', ...)`.
   - After overriding with your `$http` mock, add logic in `afterAll` (or a separate `afterAll`) to restore `global.$http` when `hasOriginalGlobalHttp` is `true` and delete it otherwise.
2. Integrate the `$http` restore logic into the same `afterAll` used for `$option` to avoid multiple hooks fighting over the same globals.
3. Ensure any new `$http`-related code you add follows the same `configurable: true` pattern so the properties can be redefined or deleted safely.
</issue_to_address>

### Comment 3
<location path="src/types.test.ts" line_range="15-18" />
<code_context>
+} from './types';
+
+// Add Jest global types
+declare global {
+  const describe: any;
+  const it: any;
+  const expect: any;
+}
+
</code_context>
<issue_to_address>
**suggestion:** Redefining Jest globals as `any` weakens type checking now that `@types/jest` is installed.

These `declare global` stubs override Jest’s real typings and turn `describe`/`it`/`expect` into `any`, negating the benefit of `@types/jest`. Please remove this block and instead rely on Jest’s types (e.g. via `"types": ["jest"]` in tsconfig or a shared `setupTests.d.ts`).

Suggested implementation:

```typescript
  TypeCheckConfig,
} from './types';

// Test OpenAiErrorResponse type
describe('OpenAiErrorResponse', () => {

```

To make sure Jest types are available without these `declare global` stubs, confirm one of the following is configured in your project:
1. In `tsconfig.json`, include `"types": ["jest"]` (possibly alongside other type packages) or
2. Have a global declaration file (e.g. `src/setupTests.d.ts` or `types/jest.d.ts`) that contains `/// <reference types="jest" />` or `import '@types/jest';`.

No further changes to `src/types.test.ts` are required once the Jest types are correctly configured.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread package.json
Comment on lines +25 to +27
"@types/jest": "^30.0.0",
"jest": "^30.4.2",
"ts-jest": "^29.4.10",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Jest and ts-jest versions look incompatible and may break the test runner.

jest is pinned to ^30.4.2 while ts-jest is on ^29.4.10. Each ts-jest major typically targets the same Jest major, and 29.x does not yet officially support Jest 30. This mismatch can cause transform/config failures. Please align the versions (e.g., Jest 29.x with ts-jest 29.x, or upgrade ts-jest once it supports Jest 30) to avoid test runner issues.

Comment on lines +42 to +44
Object.defineProperty(global, '$option', {
value: mockOption,
writable: true,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (testing): Global $option and $http mocks are never restored, which can leak state across test files.

These Object.defineProperty(global, ...) calls permanently change $option/$http for the whole Jest run, so other test suites can be affected depending on order or parallelism. Please snapshot any existing global.$option/global.$http before overriding and restore them in afterAll, or alternatively isolate this via jest.resetModules() and local (non-global) mocks so each suite keeps a clean global state.

Suggested implementation:

/**
 * Snapshot existing global $option before overriding to avoid leaking state across tests.
 */
const originalGlobalOption = (global as any).$option;
const hasOriginalGlobalOption = Object.prototype.hasOwnProperty.call(global, '$option');

// Set up global mocks
Object.defineProperty(global, '$option', {
  value: mockOption,
  writable: true,
  configurable: true,
});

/**
 * Restore global $option after all tests in this file complete.
 */
afterAll(() => {
  if (hasOriginalGlobalOption) {
    Object.defineProperty(global, '$option', {
      value: originalGlobalOption,
      writable: true,
      configurable: true,
    });
  } else {
    delete (global as any).$option;
  }
});
// Jest types for type checking
declare const jest: any;
declare function beforeAll(fn: () => void): void;
declare function afterAll(fn: () => void): void;
declare function beforeEach(fn: () => void): void;
declare function afterEach(fn: () => void): void;
  1. The same snapshot/restore pattern should be applied to global.$http:
    • Capture const originalGlobalHttp = (global as any).$http; and const hasOriginalGlobalHttp = Object.prototype.hasOwnProperty.call(global, '$http'); before any Object.defineProperty(global, '$http', ...).
    • After overriding with your $http mock, add logic in afterAll (or a separate afterAll) to restore global.$http when hasOriginalGlobalHttp is true and delete it otherwise.
  2. Integrate the $http restore logic into the same afterAll used for $option to avoid multiple hooks fighting over the same globals.
  3. Ensure any new $http-related code you add follows the same configurable: true pattern so the properties can be redefined or deleted safely.

Comment thread src/types.test.ts
Comment on lines +15 to +18
declare global {
const describe: any;
const it: any;
const expect: any;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Redefining Jest globals as any weakens type checking now that @types/jest is installed.

These declare global stubs override Jest’s real typings and turn describe/it/expect into any, negating the benefit of @types/jest. Please remove this block and instead rely on Jest’s types (e.g. via "types": ["jest"] in tsconfig or a shared setupTests.d.ts).

Suggested implementation:

  TypeCheckConfig,
} from './types';

// Test OpenAiErrorResponse type
describe('OpenAiErrorResponse', () => {

To make sure Jest types are available without these declare global stubs, confirm one of the following is configured in your project:

  1. In tsconfig.json, include "types": ["jest"] (possibly alongside other type packages) or
  2. Have a global declaration file (e.g. src/setupTests.d.ts or types/jest.d.ts) that contains /// <reference types="jest" /> or import '@types/jest';.

No further changes to src/types.test.ts are required once the Jest types are correctly configured.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant