Conversation
goastler
commented
Jan 5, 2026
- Add unit tests for @prosopo/config package
- Add tests for vite plugins and webpack config
- docs(changeset): add unit tests
- Fix linting and formatting in dependencies test file
- Add vitest test configuration - Add test script to package.json - Add comprehensive tests for dependencies.ts functions - Add tests for vite plugins (fix-absolute-imports, copy) - Add tests for webpack config - 50/54 tests passing (4 complex integration tests need refinement)
There was a problem hiding this comment.
Pull request overview
This PR adds comprehensive unit test coverage for the @prosopo/config package, focusing on testing vite plugins, webpack configuration, and dependency utilities.
Key changes:
- Added unit tests for vite plugins (fix-absolute-imports and copy plugins)
- Added unit tests for webpack configuration
- Added unit tests for dependency utility functions
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| dev/config/vite.test.config.ts | New vite test configuration file for running tests |
| dev/config/src/webpack/webpack.config.test.ts | Comprehensive tests for webpack configuration across production/development modes |
| dev/config/src/vite/vite-plugin-fix-absolute-imports.test.ts | Tests for the vite plugin that fixes absolute imports for builtin modules |
| dev/config/src/vite/vite-plugin-copy.test.ts | Tests for the vite copy plugin covering file operations and glob patterns |
| dev/config/src/dependencies.test.ts | Tests for dependency utility functions including tsconfig parsing and npm ls output parsing |
| dev/config/package.json | Added test script to run vitest with the new test config |
| .changeset/lucky-boxes-sink.md | Changeset documenting the addition of unit tests |
Comments suppressed due to low confidence (1)
dev/config/src/dependencies.test.ts:1
- Test case naming is inconsistent with the actual behavior being tested. When filters array is empty, all dependencies should be classified as 'internal' (not matching any filter), not 'external'. The test expectation at line 654 contradicts this by expecting deps in 'external'. Either the test name should be updated to reflect what's actually being tested, or the expectations should be corrected to match the name.
// Copyright 2021-2025 Prosopo (UK) Ltd.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const result = filterDependencies(deps, filters); | ||
|
|
||
| expect(result.external).toContain("@prosopo/package1"); | ||
| expect(result.external).toContain("@prosopo/package2"); | ||
| expect(result.internal).toContain("external-package"); | ||
| expect(result.internal).toContain("another-external"); | ||
| }); | ||
|
|
||
| it("should deduplicate dependencies", () => { | ||
| const deps = ["package1", "package1", "package2"]; | ||
| const filters = ["package1"]; | ||
|
|
||
| const result = filterDependencies(deps, filters); | ||
|
|
||
| const package1Count = result.external.filter( | ||
| (d) => d === "package1", | ||
| ).length; | ||
| expect(package1Count).toBe(1); | ||
| }); | ||
|
|
||
| it("should filter out empty dependencies", () => { | ||
| const deps = ["package1", "", "package2", " "]; | ||
| const filters = ["package1"]; | ||
|
|
||
| const result = filterDependencies(deps, filters); | ||
|
|
||
| expect(result.internal.every((d) => d.length > 0)).toBe(true); | ||
| expect(result.external.every((d) => d.length > 0)).toBe(true); | ||
| }); | ||
|
|
||
| it("should sort dependencies", () => { | ||
| const deps = ["z-package", "a-package", "m-package"]; | ||
| const filters = ["z-package"]; | ||
|
|
||
| const result = filterDependencies(deps, filters); | ||
|
|
||
| expect(result.internal).toEqual(["a-package", "m-package"]); | ||
| expect(result.external).toEqual(["z-package"]); | ||
| }); | ||
|
|
||
| it("should handle multiple filter patterns", () => { | ||
| const deps = ["@prosopo/package1", "@other/package2", "external-package"]; | ||
| const filters = ["@prosopo/", "@other/"]; | ||
|
|
||
| const result = filterDependencies(deps, filters); | ||
|
|
||
| expect(result.external).toContain("@prosopo/package1"); | ||
| expect(result.external).toContain("@other/package2"); | ||
| expect(result.internal).toContain("external-package"); | ||
| }); | ||
|
|
||
| it("should handle empty dependencies array", () => { | ||
| const deps: string[] = []; | ||
| const filters = ["@prosopo/"]; | ||
|
|
||
| const result = filterDependencies(deps, filters); | ||
|
|
||
| expect(result.internal).toEqual([]); | ||
| expect(result.external).toEqual([]); | ||
| }); | ||
|
|
||
| it("should handle empty filters array", () => { | ||
| const deps = ["package1", "package2"]; | ||
| const filters: string[] = []; | ||
|
|
||
| const result = filterDependencies(deps, filters); | ||
|
|
||
| expect(result.external).toEqual(["package1", "package2"]); | ||
| expect(result.internal).toEqual([]); |
There was a problem hiding this comment.
The test's internal/external classification appears reversed based on conventional naming. Dependencies matching the filter patterns (e.g., '@prosopo/package1') are expected to be in 'result.external', while non-matching dependencies (e.g., 'external-package') are expected in 'result.internal'. This naming is counterintuitive - typically 'internal' would refer to organization-owned packages (@prosopo/*) and 'external' to third-party packages. Consider updating variable names in the test or verifying the filterDependencies function's classification logic aligns with expected semantics.
| const result = filterDependencies(deps, filters); | |
| expect(result.external).toContain("@prosopo/package1"); | |
| expect(result.external).toContain("@prosopo/package2"); | |
| expect(result.internal).toContain("external-package"); | |
| expect(result.internal).toContain("another-external"); | |
| }); | |
| it("should deduplicate dependencies", () => { | |
| const deps = ["package1", "package1", "package2"]; | |
| const filters = ["package1"]; | |
| const result = filterDependencies(deps, filters); | |
| const package1Count = result.external.filter( | |
| (d) => d === "package1", | |
| ).length; | |
| expect(package1Count).toBe(1); | |
| }); | |
| it("should filter out empty dependencies", () => { | |
| const deps = ["package1", "", "package2", " "]; | |
| const filters = ["package1"]; | |
| const result = filterDependencies(deps, filters); | |
| expect(result.internal.every((d) => d.length > 0)).toBe(true); | |
| expect(result.external.every((d) => d.length > 0)).toBe(true); | |
| }); | |
| it("should sort dependencies", () => { | |
| const deps = ["z-package", "a-package", "m-package"]; | |
| const filters = ["z-package"]; | |
| const result = filterDependencies(deps, filters); | |
| expect(result.internal).toEqual(["a-package", "m-package"]); | |
| expect(result.external).toEqual(["z-package"]); | |
| }); | |
| it("should handle multiple filter patterns", () => { | |
| const deps = ["@prosopo/package1", "@other/package2", "external-package"]; | |
| const filters = ["@prosopo/", "@other/"]; | |
| const result = filterDependencies(deps, filters); | |
| expect(result.external).toContain("@prosopo/package1"); | |
| expect(result.external).toContain("@other/package2"); | |
| expect(result.internal).toContain("external-package"); | |
| }); | |
| it("should handle empty dependencies array", () => { | |
| const deps: string[] = []; | |
| const filters = ["@prosopo/"]; | |
| const result = filterDependencies(deps, filters); | |
| expect(result.internal).toEqual([]); | |
| expect(result.external).toEqual([]); | |
| }); | |
| it("should handle empty filters array", () => { | |
| const deps = ["package1", "package2"]; | |
| const filters: string[] = []; | |
| const result = filterDependencies(deps, filters); | |
| expect(result.external).toEqual(["package1", "package2"]); | |
| expect(result.internal).toEqual([]); | |
| const { internal: externalDeps, external: internalDeps } = | |
| filterDependencies(deps, filters); | |
| // Internal deps: match filters (e.g. @prosopo/*) | |
| expect(internalDeps).toContain("@prosopo/package1"); | |
| expect(internalDeps).toContain("@prosopo/package2"); | |
| // External deps: non-matching third-party packages | |
| expect(externalDeps).toContain("external-package"); | |
| expect(externalDeps).toContain("another-external"); | |
| }); | |
| it("should deduplicate dependencies", () => { | |
| const deps = ["package1", "package1", "package2"]; | |
| const filters = ["package1"]; | |
| const { internal: externalDeps, external: internalDeps } = | |
| filterDependencies(deps, filters); | |
| const package1Count = internalDeps.filter((d) => d === "package1").length; | |
| expect(package1Count).toBe(1); | |
| // Sanity: ensure duplicates were not kept in external deps either | |
| expect(externalDeps.filter((d) => d === "package1").length).toBeLessThanOrEqual(1); | |
| }); | |
| it("should filter out empty dependencies", () => { | |
| const deps = ["package1", "", "package2", " "]; | |
| const filters = ["package1"]; | |
| const { internal: externalDeps, external: internalDeps } = | |
| filterDependencies(deps, filters); | |
| expect(externalDeps.every((d) => d.length > 0)).toBe(true); | |
| expect(internalDeps.every((d) => d.length > 0)).toBe(true); | |
| }); | |
| it("should sort dependencies", () => { | |
| const deps = ["z-package", "a-package", "m-package"]; | |
| const filters = ["z-package"]; | |
| const { internal: externalDeps, external: internalDeps } = | |
| filterDependencies(deps, filters); | |
| // Internal deps: match filters, should contain only "z-package" | |
| expect(internalDeps).toEqual(["z-package"]); | |
| // External deps: sorted remaining packages | |
| expect(externalDeps).toEqual(["a-package", "m-package"]); | |
| }); | |
| it("should handle multiple filter patterns", () => { | |
| const deps = ["@prosopo/package1", "@other/package2", "external-package"]; | |
| const filters = ["@prosopo/", "@other/"]; | |
| const { internal: externalDeps, external: internalDeps } = | |
| filterDependencies(deps, filters); | |
| expect(internalDeps).toContain("@prosopo/package1"); | |
| expect(internalDeps).toContain("@other/package2"); | |
| expect(externalDeps).toContain("external-package"); | |
| }); | |
| it("should handle empty dependencies array", () => { | |
| const deps: string[] = []; | |
| const filters = ["@prosopo/"]; | |
| const { internal: externalDeps, external: internalDeps } = | |
| filterDependencies(deps, filters); | |
| expect(externalDeps).toEqual([]); | |
| expect(internalDeps).toEqual([]); | |
| }); | |
| it("should handle empty filters array", () => { | |
| const deps = ["package1", "package2"]; | |
| const filters: string[] = []; | |
| const { internal: externalDeps, external: internalDeps } = | |
| filterDependencies(deps, filters); | |
| // With no filters, everything is "external" to the org | |
| expect(externalDeps).toEqual(["package1", "package2"]); | |
| expect(internalDeps).toEqual([]); |
…reference inclusion - Fix regex construction to use source property of RegExp objects - Fix reference filtering to include all references when no ignore patterns specified - Ensure getExternalsFromReferences properly resolves tsconfig paths
- Fix filtering logic in getTsConfigs for ignore patterns and reference inclusion - Update coverage configuration to work with dev package structure - Improve test coverage for dependencies module (99.42% statements) - Fix JS formatting issues in test files - Ensure all tests pass and build succeeds
- Update copyright notices across the entire codebase - Fix formatting in vite.test.config.ts