Skip to content

🧪 testing improvement for getQueryTimeout config - #135

Closed
zknpr wants to merge 1 commit into
mainfrom
fix-query-timeout-config-tests-11664364936686506517
Closed

🧪 testing improvement for getQueryTimeout config#135
zknpr wants to merge 1 commit into
mainfrom
fix-query-timeout-config-tests-11664364936686506517

Conversation

@zknpr

@zknpr zknpr commented Mar 8, 2026

Copy link
Copy Markdown
Owner

🎯 What: The testing gap addressed
The user requested tests for getQueryTimeout, which retrieves the timeout from vscode configuration. A similar testable function, getMaximumFileSizeBytes also existed. The main challenge was that these functions were located in src/workerFactory.ts, which accesses import.meta.env at the top level, causing tests executed with tsx to fail when the module is imported.

📊 Coverage: What scenarios are now tested

  • The logic for both configuration retrieval functions has been separated into src/config.ts to allow isolated unit testing.
  • Test coverage has been provided for both getQueryTimeout and getMaximumFileSizeBytes.
  • Covered test scenarios for both functions include:
    1. Default values when configuration is not set.
    2. Custom configured values parsing accurately.

Result: The improvement in test coverage

  • Extracted and tested simple configuration values without invoking the complexities of worker setup.
  • Achieved robust assertions without top-level environment constraints.
  • Validated via npx tsx --tsconfig tsconfig.test.json --test tests/unit/config.test.ts.

PR created automatically by Jules for task 11664364936686506517 started by @zknpr

…ileSizeBytes and refactor into config.ts

Co-authored-by: zknpr <96851588+zknpr@users.noreply.github.com>
@google-labs-jules

Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@vercel

vercel Bot commented Mar 8, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
sq-lite-explorer Ready Ready Preview, Comment Mar 8, 2026 1:19am

@gemini-code-assist

Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly improves the testability and coverage of configuration retrieval functions within the extension. By extracting getQueryTimeout and getMaximumFileSizeBytes into a dedicated config.ts file, these functions can now be unit tested in isolation, free from environmental constraints previously encountered in workerFactory.ts. This change ensures that configuration values are correctly read and applied, enhancing the robustness of the extension's settings handling.

Highlights

  • Refactored Configuration Retrieval: Moved getQueryTimeout and getMaximumFileSizeBytes functions from src/workerFactory.ts to src/config.ts to enable isolated unit testing.
  • Enhanced Test Coverage: Introduced new unit tests for both getQueryTimeout and getMaximumFileSizeBytes, verifying default values and correct parsing of custom configurations.
  • Improved Test Environment: Addressed import.meta.env access issues during testing by polyfilling it in the vscode_mock_setup.ts file, ensuring tests run smoothly with tsx.
Changelog
  • src/config.ts
    • Added getMaximumFileSizeBytes function to retrieve the maximum file size from user configuration.
    • Added getQueryTimeout function to retrieve the query timeout from user configuration, including a default value.
    • Imported vscode module for configuration access.
  • src/databaseModel.ts
    • Updated import statement to retrieve getMaximumFileSizeBytes from src/config.ts instead of src/workerFactory.ts.
  • src/workerFactory.ts
    • Removed the getMaximumFileSizeBytes and getQueryTimeout functions.
    • Updated imports to use getMaximumFileSizeBytes and getQueryTimeout from src/config.ts.
    • Removed the ConfigurationSection import as it's no longer directly used here for configuration retrieval.
  • tests/unit/config.test.ts
    • Added a new unit test file for configuration retrieval functions.
    • Included tests for getQueryTimeout to verify default and configured values.
    • Included tests for getMaximumFileSizeBytes to verify default and configured values.
    • Implemented beforeEach and afterEach hooks to mock and restore vscode.workspace.getConfiguration.
  • tests/unit/vscode_mock_setup.ts
    • Added a mock for vscode.extensions.getExtension to provide a consistent testing environment.
    • Implemented a polyfill for import.meta.env to prevent test failures when running with tsx.
Activity
  • PR created automatically by Jules for task 11664364936686506517, initiated by @zknpr.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@coderabbitai

coderabbitai Bot commented Mar 8, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@zknpr has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 24 minutes and 41 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 0d759bab-e6d0-4b5a-8ecf-2ba2ccf567b2

📥 Commits

Reviewing files that changed from the base of the PR and between 0573573 and 375af20.

📒 Files selected for processing (5)
  • src/config.ts
  • src/databaseModel.ts
  • src/workerFactory.ts
  • tests/unit/config.test.ts
  • tests/unit/vscode_mock_setup.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix-query-timeout-config-tests-11664364936686506517

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request effectively refactors the configuration retrieval functions getQueryTimeout and getMaximumFileSizeBytes into src/config.ts, which is a great improvement for testability. The newly added unit tests in tests/unit/config.test.ts provide good coverage for these functions.

My review includes a couple of suggestions to enhance the maintainability of the new test code. One suggestion is to refactor the test setup to reduce code duplication. Another one is to clean up the import.meta.env polyfill to reduce the usage of @ts-ignore.

Overall, this is a solid contribution that improves the project's test coverage and structure.

Comment thread tests/unit/config.test.ts
Comment on lines +18 to +50
describe('getQueryTimeout', () => {
test('should return default timeout (30000ms) when not configured', () => {
vscode.workspace.getConfiguration = (section) => {
assert.strictEqual(section, 'sqliteExplorer');
return {
get: (key: string, defaultValue: any) => {
assert.strictEqual(key, 'queryTimeout');
return defaultValue;
},
update: () => Promise.resolve()
} as any;
};

const timeout = getQueryTimeout();
assert.strictEqual(timeout, 30000);
});

test('should return configured timeout when defined', () => {
vscode.workspace.getConfiguration = (section) => {
assert.strictEqual(section, 'sqliteExplorer');
return {
get: (key: string, defaultValue: any) => {
assert.strictEqual(key, 'queryTimeout');
return 15000;
},
update: () => Promise.resolve()
} as any;
};

const timeout = getQueryTimeout();
assert.strictEqual(timeout, 15000);
});
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The test setup for getQueryTimeout is duplicated across the two test cases. To improve maintainability and reduce repetition, you can extract the mock setup into a helper function within the describe block. This pattern can then be applied to the getMaximumFileSizeBytes tests as well.

    describe('getQueryTimeout', () => {
        const setupMock = (returnValue: any) => {
            vscode.workspace.getConfiguration = (section) => {
                assert.strictEqual(section, 'sqliteExplorer');
                return {
                    get: (key: string, defaultValue: any) => {
                        assert.strictEqual(key, 'queryTimeout');
                        if (returnValue === 'use_default') {
                            return defaultValue;
                        }
                        return returnValue;
                    },
                    update: () => Promise.resolve()
                } as any;
            };
        };

        test('should return default timeout (30000ms) when not configured', () => {
            setupMock('use_default');
            const timeout = getQueryTimeout();
            assert.strictEqual(timeout, 30000);
        });

        test('should return configured timeout when defined', () => {
            setupMock(15000);
            const timeout = getQueryTimeout();
            assert.strictEqual(timeout, 15000);
        });
    });

Comment on lines +22 to +29
if (typeof process !== 'undefined') {
// @ts-ignore
globalThis.import = globalThis.import || {};
// @ts-ignore
globalThis.import.meta = globalThis.import.meta || {};
// @ts-ignore
globalThis.import.meta.env = globalThis.import.meta.env || { VSCODE_BROWSER_EXT: false };
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

To improve code clarity and reduce the number of @ts-ignore directives, you can cast globalThis to any once and then perform the property assignments. This makes the polyfill logic a bit cleaner.

if (typeof process !== 'undefined') {
  const g = globalThis as any;
  g.import = g.import || {};
  g.import.meta = g.import.meta || {};
  g.import.meta.env = g.import.meta.env || { VSCODE_BROWSER_EXT: false };
}

@greptile-apps

greptile-apps Bot commented Mar 8, 2026

Copy link
Copy Markdown

Greptile Summary

This PR improves test coverage by extracting the getQueryTimeout and getMaximumFileSizeBytes configuration helper functions from src/workerFactory.ts — which could not be imported in tests due to a top-level import.meta.env access — into the side-effect-free src/config.ts, and then adding unit tests for both functions.

  • src/config.ts: The two config functions and DEFAULT_QUERY_TIMEOUT_MS are added here. The vscode import is placed at the bottom of the file rather than the top (after all the existing constants), which is non-standard and should be moved to the top.
  • src/workerFactory.ts / src/databaseModel.ts: Import sources updated to ./config; no logic changes.
  • tests/unit/config.test.ts: New tests cover the default and custom-value cases for both functions, but are missing a test for maxFileSize: 0 (the documented "unlimited" case), which could regress if ?? were ever changed to ||.
  • tests/unit/vscode_mock_setup.ts: Adds an import.meta.env polyfill that is fundamentally ineffective — assigning to globalThis.import.meta.env does not affect import.meta resolution inside ES modules. The tests pass only because src/config.ts never references import.meta.env directly; future contributors might rely on this polyfill mistakenly when writing tests for modules that do.

Confidence Score: 4/5

  • Safe to merge — the refactor is a clean extraction with no logic changes; issues found are minor style and test-quality concerns.
  • The production-code change is a pure refactor (moving two functions and updating two import statements) with no behavioral difference. The test additions are correct and add meaningful coverage. The deductions are for: the misplaced import at the bottom of config.ts, an ineffective import.meta.env polyfill that could mislead future test authors, and a missing edge-case test for the maxFileSize: 0 unlimited scenario.
  • tests/unit/vscode_mock_setup.ts — the import.meta.env polyfill is non-functional and should be removed or replaced with an explanatory comment.

Important Files Changed

Filename Overview
src/config.ts Moved getMaximumFileSizeBytes and getQueryTimeout from workerFactory.ts into this centralized config module to enable isolated unit testing. The vscode import is placed at the bottom of the file rather than the top, which is non-standard.
src/workerFactory.ts Removed the two config retrieval functions and now imports them from src/config.ts. No logic changes; straightforward refactor.
src/databaseModel.ts Import source for getMaximumFileSizeBytes updated from ./workerFactory to ./config. Single-line import change with no logic impact.
tests/unit/config.test.ts New unit tests for getQueryTimeout and getMaximumFileSizeBytes using a manual mock for vscode.workspace.getConfiguration. Tests cover default and custom values but are missing an edge-case test for maxFileSize: 0 (unlimited).
tests/unit/vscode_mock_setup.ts Added extensions.getExtension mock and an import.meta.env polyfill. The polyfill is ineffective — setting globalThis.import.meta.env does not affect ES module import.meta resolution — and could mislead future contributors.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[src/config.ts] -->|exports getMaximumFileSizeBytes| B[src/workerFactory.ts]
    A -->|exports getQueryTimeout| B
    A -->|exports getMaximumFileSizeBytes| C[src/databaseModel.ts]
    B -->|uses getMaximumFileSizeBytes| D[establishConnection]
    B -->|uses getQueryTimeout| D
    C -->|uses getMaximumFileSizeBytes| E[open database file]

    subgraph Tests
        F[tests/unit/vscode_mock_setup.ts] -->|sets up vscode mock| G[tests/unit/config.test.ts]
        G -->|imports & tests| A
    end

    style A fill:#d4edda,stroke:#28a745
    style G fill:#d4edda,stroke:#28a745
    style F fill:#fff3cd,stroke:#ffc107
Loading

Last reviewed commit: 375af20

Comment thread src/config.ts
// Copilot integration
export const CopilotChatId = 'github.copilot-chat';

import * as vsc from 'vscode';

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Import placed at the bottom of the file

The import * as vsc from 'vscode' statement is placed after all the constant exports, which is unconventional and inconsistent with standard TypeScript/JavaScript practice. Imports should always be at the top of the file before any module-level declarations. While ES module import statements are hoisted and technically work regardless of position, this layout makes the file harder to read and the dependency on vscode less obvious.

Suggested change
import * as vsc from 'vscode';
import * as vsc from 'vscode';
/**
* Extension Constants
*

Move the import to the very top of the file.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Comment on lines +21 to +29
// @ts-ignore
if (typeof process !== 'undefined') {
// @ts-ignore
globalThis.import = globalThis.import || {};
// @ts-ignore
globalThis.import.meta = globalThis.import.meta || {};
// @ts-ignore
globalThis.import.meta.env = globalThis.import.meta.env || { VSCODE_BROWSER_EXT: false };
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

import.meta.env polyfill is ineffective

This polyfill attempts to simulate import.meta.env by setting globalThis.import.meta.env, but this does not actually affect how import.meta is resolved in ES module files. import.meta is a host-defined meta-property resolved statically by the module system at parse/link time — it is not a runtime property lookup on globalThis. Setting globalThis.import has no effect on module-internal import.meta references.

In practice, the current tests pass only because src/config.ts (the module under test) does not contain any import.meta.env references. If a future test were to import src/workerFactory.ts directly (which does use import.meta.env), this polyfill would not prevent it from throwing. It could mislead contributors into believing they are covered.

The PR description correctly identifies that the architectural fix (moving the config functions into config.ts) is what avoids the import.meta.env problem — the polyfill is both unnecessary and non-functional. Consider removing it or replacing it with a comment explaining why workerFactory.ts should not be imported in unit tests.

Comment thread tests/unit/config.test.ts
Comment on lines +52 to +84
describe('getMaximumFileSizeBytes', () => {
test('should return default size (200MB) when not configured', () => {
vscode.workspace.getConfiguration = (section) => {
assert.strictEqual(section, 'sqliteExplorer');
return {
get: (key: string, defaultValue: any) => {
assert.strictEqual(key, 'maxFileSize');
return undefined; // Not configured
},
update: () => Promise.resolve()
} as any;
};

const size = getMaximumFileSizeBytes();
assert.strictEqual(size, 200 * (2 ** 20));
});

test('should return configured size in bytes', () => {
vscode.workspace.getConfiguration = (section) => {
assert.strictEqual(section, 'sqliteExplorer');
return {
get: (key: string, defaultValue: any) => {
assert.strictEqual(key, 'maxFileSize');
return 50; // 50MB
},
update: () => Promise.resolve()
} as any;
};

const size = getMaximumFileSizeBytes();
assert.strictEqual(size, 50 * (2 ** 20));
});
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Missing edge-case test for maxFileSize: 0 (unlimited)

The docstring on getMaximumFileSizeBytes (and the callers in workerFactory.ts) explicitly document that 0 means "unlimited". The tests cover the default (undefined → 200 MB) and a positive custom value, but do not exercise the 0 case. When a user sets maxFileSize: 0, config.get<number>('maxFileSize') ?? 200 evaluates to 0 (since 0 is not nullish), so the function correctly returns 0 * (2 ** 20) === 0. Adding a test for this would protect against a future regression where someone accidentally changes ?? to ||:

test('should return 0 (unlimited) when maxFileSize is configured as 0', () => {
    vscode.workspace.getConfiguration = (_section) => ({
        get: (_key: string, _defaultValue: any) => 0,
        update: () => Promise.resolve()
    } as any);

    const size = getMaximumFileSizeBytes();
    assert.strictEqual(size, 0);
});

@zknpr

zknpr commented Mar 8, 2026

Copy link
Copy Markdown
Owner Author

Implemented manually on main. Extracted getMaximumFileSizeBytes and getQueryTimeout to src/config.ts with proper import placement. Added unit tests with configurable mock store. Updated databaseModel.ts import path.

@zknpr zknpr closed this Mar 8, 2026
@google-labs-jules

Copy link
Copy Markdown
Contributor

Implemented manually on main. Extracted getMaximumFileSizeBytes and getQueryTimeout to src/config.ts with proper import placement. Added unit tests with configurable mock store. Updated databaseModel.ts import path.

Understood. Acknowledging that this work was implemented manually on main. Stopping work on this task.

zknpr added a commit that referenced this pull request Mar 8, 2026
…d code, bump sql.js

- Replace `as any` casts in HostBridge toast methods with shared `showToast`
  helper that properly maps DialogConfig→MessageOptions and
  DialogButton→MessageItem (PR #132)
- Extract getMaximumFileSizeBytes and getQueryTimeout from workerFactory.ts
  to config.ts for testability without import.meta.env (PR #135)
- Remove dead rowIds filtering code in tableExporter non-rowid branch (PR #137)
- Bump sql.js from 1.13.0 to 1.14.0 (PR #112)
- Add configurable mock store to vscode test mock for workspace.getConfiguration
- Add unit tests for getMaximumFileSizeBytes and getQueryTimeout

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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