Skip to content

chore(tests): switch to vitest MCP-65 #363

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Jul 15, 2025
Merged

chore(tests): switch to vitest MCP-65 #363

merged 12 commits into from
Jul 15, 2025

Conversation

gagik
Copy link
Collaborator

@gagik gagik commented Jul 14, 2025

This is a proposal to switch to vitest in light of continued issues with ESM modules and jest. Jest support for ESM modules is still experimental and it will likely require constant patching to keep it working as we end up adopting more ESM-based modules. This also applies to extra TypeScript processing.

vitest is tried and tested now and is essentially a drop-in replacement for jest (minus our minor usage of jest-extended, which is replaceable).

Pros of vitest

  • Native TypeScript, ESM module support means little to no configuration and extra work required compared to configurating jest or chai/mocha/sinon.
  • All in one package compared to chai/mocha/sinon.
  • It has better typed helper methods such as vi.mocked.
  • It has an official VSCode extension that just works without any extra setup 💘
  • There's potential to add type testing which is quite cool.
  • Its performance is similar, maybe even a bit faster? vitest vs jest.

Cons of vitest

  • As it is a more recent project, there's not much usage of it in the mongodb-js organization outside of small projects. I do believe that this is largely because of older age of most other codebases. That said, it is being adopted in other places: vitest is used by the https://github.com/mongodb/chatbot for example.

Possible alternatives:

  • Configuring jest: Probably would take even more effort than this switching to vitest right now and we may run into future issues as its support is experimental.
  • Using chai/mocha/sinon: We may have better time with this and would align with other mongodb-js codebases if that matters. Would likely again require a lot more extra setup than the built-in vitest work but be less experimental than jest.
  • Give up on ESM: this may be a good argument in light of VSCode only supporting CommonJS right now. However, I think it's odd to downgrade to an older standard when it's clear from perspective of future of ECMAScript that ESM is what new libraries should use. I found this thread useful in learning more about ESM pros.

In my opinion minimal configuration is preferable and vitest is mature enough and well worth being adopted.

@Copilot Copilot AI review requested due to automatic review settings July 14, 2025 17:59
@gagik gagik requested a review from a team as a code owner July 14, 2025 17:59
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR replaces Jest with Vitest as the test runner to simplify ESM/TypeScript support and reduce configuration overhead.

  • Adds a vitest.config.ts for Vitest setup
  • Updates TS config and package dependencies to reference Vitest types and remove Jest
  • Rewrites all tests to use Vitest APIs (vi, expect, describe, etc.)

Reviewed Changes

Copilot reviewed 43 out of 46 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
vitest.config.ts New Vitest configuration
tsconfig.jest.json Switched "types" from Jest to Vitest
package.json Removed Jest deps, added vitest
jest.config.cjs Deleted (old Jest config)
eslint.config.js Updated ESLint to include vitest.config.ts
tests/unit//*.test.ts, tests/integration/ Replaced Jest imports, mocks, and assertions with Vitest

import logger, { LogId } from "../../src/common/logger.js";
import { createHmac } from "crypto";
import type { MockedFunction } from "vitest";
Copy link
Preview

Copilot AI Jul 14, 2025

Choose a reason for hiding this comment

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

[nitpick] The manual as unknown as typeof mockApiClient casting is complex. You can simplify typing by using const mockApiClient = vi.mocked(ApiClient, { shallow: true }); to get strongly typed mocks without workarounds.

Copilot uses AI. Check for mistakes.

@coveralls
Copy link
Collaborator

Pull Request Test Coverage Report for Build 16275099623

Details

  • 0 of 26 (0.0%) changed or added relevant lines in 2 files are covered.
  • 291 unchanged lines in 26 files lost coverage.
  • Overall coverage increased (+2.3%) to 77.524%

Changes Missing Coverage Covered Lines Changed/Added Lines %
eslint.config.js 0 13 0.0%
vitest.config.ts 0 13 0.0%
Files with Coverage Reduction New Missed Lines %
src/helpers/EJsonTransport.ts 1 86.11%
src/helpers/indexCheck.ts 1 96.0%
src/tools/atlas/create/createAccessList.ts 1 90.54%
src/tools/atlas/read/inspectAccessList.ts 1 90.0%
src/tools/atlas/read/listOrgs.ts 1 88.89%
src/tools/mongodb/metadata/collectionStorageSize.ts 1 95.65%
src/common/atlas/apiClientError.ts 2 85.9%
src/helpers/container.ts 2 73.17%
src/telemetry/telemetry.ts 2 91.85%
src/telemetry/eventCache.ts 3 80.56%
Totals Coverage Status
Change from base Build 16220557964: 2.3%
Covered Lines: 2833
Relevant Lines: 3610

💛 - Coveralls

@@ -8,6 +8,7 @@ import {
expectDefined,
} from "../../../helpers.js";
import { IndexDirection } from "mongodb";
import { expect, it } from "vitest";
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

these imports can actually be avoided by opting in to use globals which would make this PR look less scary. However I'm not a fan of globals in general as they're a bit too magical and hide real dependencies.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think using globals in this particular situation is kind of fine, but not a strong opinion.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

yeah another thing with globals was that every time it required eslint/typescript/etc. configuration to make it apply to some files but not others so this ended up being quicker

Copy link
Collaborator

@nirinchev nirinchev left a comment

Choose a reason for hiding this comment

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

Looks reasonable - no strong feelings on vi vs the rest. Looks like the coverage reporter is slightly different though and will now report 2 lines for each missed line (now seems to be counting the closing curly brace). Probably not a blocking issue.

@@ -8,6 +8,7 @@ import {
expectDefined,
} from "../../../helpers.js";
import { IndexDirection } from "mongodb";
import { expect, it } from "vitest";
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think using globals in this particular situation is kind of fine, but not a strong opinion.

Comment on lines 58 to 61
expect(items2).toHaveLength(2);
expect(items2.map((item) => item.text)).toIncludeSameMembers([
'Name: "collection-1"',
'Name: "collection-2"',
]);
expect(items2.map((item) => item.text)).toEqual(
expect.arrayContaining(['Name: "collection-1"', 'Name: "collection-2"'])
);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can this be .strictEqual(...)?

Copy link
Collaborator Author

@gagik gagik Jul 15, 2025

Choose a reason for hiding this comment

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

a lot of these toIncludeSameMembers tests are not order-sensitive but toStrictEqual is so generally no

Copy link
Collaborator

Choose a reason for hiding this comment

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

Ah, true. Kind of annoying there's no built-in matcher for arrays ignoring the order.

Copy link
Collaborator Author

@gagik gagik Jul 15, 2025

Choose a reason for hiding this comment

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

we can add custom matcher; honestly will be great to use that kind of stuff more, will add it now

@@ -20,7 +21,7 @@ describeWithMongoDB("aggregate tool", (integration) => {
validateThrowsForInvalidArguments(integration, "aggregate", [
{},
{ database: "test", collection: "foo" },
{ database: test, pipeline: [] },
Copy link
Collaborator Author

@gagik gagik Jul 15, 2025

Choose a reason for hiding this comment

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

this is actually best argument against globals, we had an accidental usage of jest's test global here.... I'm actually surprised the test was passing...

Copy link
Collaborator

@nirinchev nirinchev left a comment

Choose a reason for hiding this comment

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

LGTM once eslint is happy. Also, if there's an easy fix for the coverage reports being akward, we should apply it, otherwise we'll have to live with it

@gagik gagik enabled auto-merge (squash) July 15, 2025 12:09
@gagik gagik merged commit b12db06 into main Jul 15, 2025
17 checks passed
@gagik gagik deleted the gagik/vitest branch July 15, 2025 12:11
@gagik gagik changed the title chore(tests): switch to vitest chore(tests): switch to vitest MCP-65 Jul 15, 2025
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.

3 participants