-
Notifications
You must be signed in to change notification settings - Fork 1.5k
test: add config vite resolver coverage #1822
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| import fs from "node:fs/promises"; | ||
| import os from "node:os"; | ||
| import path from "node:path"; | ||
| import { afterEach, beforeEach, describe, expect, it } from "vitest"; | ||
| import resolver, { | ||
| clearRelativeAliasResolverCacheForTesting, | ||
| } from "./relativeAliasResolver"; | ||
|
|
||
| let tempDir: string; | ||
|
|
||
| beforeEach(async () => { | ||
| clearRelativeAliasResolverCacheForTesting(); | ||
| tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "cap-config-vite-")); | ||
| }); | ||
|
|
||
| afterEach(async () => { | ||
| await fs.rm(tempDir, { recursive: true, force: true }); | ||
| }); | ||
|
|
||
| const resolveAlias = async (source: string, importer: string) => { | ||
| const result = await resolver.customResolver?.(source, importer, {}); | ||
| if (typeof result !== "string") throw new Error("Expected string resolution"); | ||
| return result; | ||
| }; | ||
|
|
||
| describe("relativeAliasResolver", () => { | ||
| it("resolves ~/ imports from a package src directory", async () => { | ||
| const srcDir = path.join(tempDir, "pkg", "src"); | ||
| await fs.mkdir(path.join(srcDir, "components"), { recursive: true }); | ||
| await fs.writeFile(path.join(srcDir, "components", "Button.tsx"), ""); | ||
|
|
||
| await expect( | ||
| resolveAlias( | ||
| "~/components/Button", | ||
| path.join(srcDir, "pages", "index.tsx"), | ||
| ), | ||
| ).resolves.toBe(path.join(srcDir, "components", "Button.tsx")); | ||
| }); | ||
|
|
||
| it("normalizes Windows-style importers before resolving from src", async () => { | ||
| const srcDir = path.join(tempDir, "pkg", "src"); | ||
| await fs.mkdir(path.join(srcDir, "components"), { recursive: true }); | ||
| await fs.writeFile(path.join(srcDir, "components", "Card.tsx"), ""); | ||
|
|
||
| const windowsImporter = path | ||
| .join(srcDir, "pages", "index.tsx") | ||
| .replaceAll(path.sep, "\\"); | ||
|
|
||
| await expect( | ||
| resolveAlias("~/components/Card", windowsImporter), | ||
| ).resolves.toBe(path.join(srcDir, "components", "Card.tsx")); | ||
| }); | ||
|
|
||
| it("resolves ~/ imports from the nearest package root", async () => { | ||
| const pkgDir = path.join(tempDir, "pkg"); | ||
| await fs.mkdir(path.join(pkgDir, "src", "utils"), { recursive: true }); | ||
| await fs.writeFile(path.join(pkgDir, "package.json"), "{}"); | ||
| await fs.writeFile(path.join(pkgDir, "src", "utils", "index.ts"), ""); | ||
|
|
||
| await expect( | ||
| resolveAlias("~/src/utils", path.join(pkgDir, "tests", "unit.test.ts")), | ||
| ).resolves.toBe(path.join(pkgDir, "src", "utils", "index.ts")); | ||
| }); | ||
|
|
||
| it("stops at the filesystem root when no package.json can be found", async () => { | ||
| await expect( | ||
| resolveAlias("~/missing/file", path.join(tempDir, "loose", "test.ts")), | ||
| ).rejects.toThrow("Failed to resolve import path ~/missing/file"); | ||
| }); | ||
| }); | ||
|
Comment on lines
+26
to
+70
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The PR description specifically calls out "make the resolver handle Windows-style importer paths" as a fix, and the implementation adds Prompt To Fix With AIThis is a comment left during a code review.
Path: packages/config/vite/relativeAliasResolver.test.ts
Line: 23-53
Comment:
**Windows path normalization is not exercised by any test**
The PR description specifically calls out "make the resolver handle Windows-style importer paths" as a fix, and the implementation adds `importer?.replace(/\\/g, "/")`. None of the three tests pass a backslash-style path as `importer`, so the new normalization code goes untested. On Linux/macOS CI, `path.join` always produces forward slashes, meaning a backslash-containing string like `"C:\\Users\\user\\project\\src\\pages\\index.tsx"` would never be exercised. Adding one test case that uses a hardcoded Windows-style path string for the `src/` branch would lock in the intended behaviour.
How can I resolve this? If you propose a fix, please make it concise. |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| import { defineConfig } from "vitest/config"; | ||
|
|
||
| export default defineConfig({ | ||
| test: { | ||
| environment: "node", | ||
| exclude: ["**/node_modules/**", "**/dist/**"], | ||
| }, | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| import { describe, expect, it } from "vitest"; | ||
| import { | ||
| calculateStrokeDashoffset, | ||
| classNames, | ||
| getDisplayProgress, | ||
| getProgressCircleConfig, | ||
| isEmailAllowedByRestriction, | ||
| uuidFormat, | ||
| uuidParse, | ||
| } from "./helpers"; | ||
|
|
||
| describe("helpers", () => { | ||
| it("parses and formats UUIDs", () => { | ||
| const formatted = "123e4567-e89b-12d3-a456-426614174000"; | ||
| const compact = "123e4567e89b12d3a456426614174000"; | ||
|
|
||
| expect(uuidParse(formatted)).toBe(compact); | ||
| expect(uuidFormat(compact)).toBe(formatted); | ||
| }); | ||
|
|
||
| it("calculates circular progress values", () => { | ||
| const { radius, circumference } = getProgressCircleConfig(); | ||
|
|
||
| expect(radius).toBe(8); | ||
| expect(circumference).toBe(2 * Math.PI * 8); | ||
| expect(calculateStrokeDashoffset(25, 80)).toBe(60); | ||
| }); | ||
|
|
||
| it("prefers upload progress over processing progress", () => { | ||
| expect(getDisplayProgress(42, 10)).toBe(42); | ||
| expect(getDisplayProgress(undefined, 10)).toBe(10); | ||
| }); | ||
|
|
||
| it("matches email restrictions by exact address or domain", () => { | ||
| expect(isEmailAllowedByRestriction("Member@Cap.so", "member@cap.so")).toBe( | ||
| true, | ||
| ); | ||
| expect(isEmailAllowedByRestriction("hello@cap.so", "cap.so")).toBe(true); | ||
| expect(isEmailAllowedByRestriction("hello@example.com", "cap.so")).toBe( | ||
| false, | ||
| ); | ||
| expect(isEmailAllowedByRestriction("hello@example.com", "")).toBe(true); | ||
| }); | ||
|
|
||
| it("merges conditional Tailwind class names", () => { | ||
| expect(classNames("px-2", "px-4", false && "hidden")).toBe("px-4"); | ||
| }); | ||
| }); |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pkgJsonCachenot cleared between testsrelativeAliasResolver.tsstores a module-levelpkgJsonCachethat persists for the lifetime of the module instance. Within a Vitest test file, module state is shared across all test cases, so entries cached in one test remain visible to subsequent tests. The current three tests are safe (uniquemkdtemppaths prevent cross-contamination), but any future test that (1) asserts a path has nopackage.json, (2) then creates one at that path, and (3) checks again would receive a stalefalsefrom the cache. Avi.resetModules()inbeforeEach, or exporting aclearCacheForTesting()helper, would make the fixture fully isolated.Prompt To Fix With AI