-
Notifications
You must be signed in to change notification settings - Fork 0
test: add integrated test for cli #5
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
base: main
Are you sure you want to change the base?
Conversation
Coverage Report
File Coverage
|
||||||||||||||||||||||||||||||||||||||
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.
Copilot reviewed 6 out of 10 changed files in this pull request and generated 1 comment.
Files not reviewed (4)
- package.json: Language not supported
- pnpm-lock.yaml: Language not supported
- tests/fixtures/build-script/package.json: Language not supported
- tests/fixtures/test-script/package.json: Language not supported
Comments suppressed due to low confidence (2)
tests/utils/cli.ts:120
- Converting runPubmCli from an async to a synchronous function may introduce timing issues if callers rely on awaiting subprocess completion; ensure that the subprocess exit is awaited or that tests are updated accordingly.
export function runPubmCli(
src/tasks/runner.ts:38
- The revised logic for determining npmOnly is stricter than before and may not account for mixed registry configurations; please confirm that this behavior is intentional.
npmOnly: options.registries.every((registry) => registry === 'npm'),
263a7fd to
435d406
Compare
d1c1a6a to
a57fb87
Compare
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. WalkthroughThis PR introduces a comprehensive landing page ( Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes The PR spans heterogeneous changes: a full landing page with embedded interactivity, 15+ unit test files with mocked dependencies, test fixture additions, CLI/options refactoring affecting control flow, dependency version bumps, and coverage configuration. Each test file and core logic change requires separate reasoning; however, test files follow consistent patterns, reducing overall review density. Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
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. Comment |
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.
Actionable comments posted: 19
🧹 Nitpick comments (9)
docs/landing.html (2)
13-778: Consider extracting CSS to an external file.The embedded CSS is well-structured, but at 765+ lines, it affects maintainability and prevents browser caching. For production use, consider moving this to an external stylesheet.
1049-1107: Consider extracting JavaScript to an external file.Similar to the CSS, the inline JavaScript could be moved to an external file for better maintainability and browser caching. This is particularly beneficial if the landing page is frequently updated.
src/tasks/required-missing-information.ts (1)
75-81: Consider adding warning logging for distTags retrieval failures.In a previous review, you mentioned you would "make a warning" when distTags retrieval fails. However, the current implementation silently catches errors without logging. This could make debugging registry issues difficult.
🔎 Suggested implementation with warning
try { distTags = [ ...new Set( (await Promise.all([npm.distTags(), jsr.distTags()])).flat(), ), ].filter((tag) => tag !== defaultOptions.tag); -} catch {} +} catch (error) { + console.warn('Failed to retrieve dist-tags from registry:', error); +}Based on past review comments where you indicated you would add warning logging for this error case.
tests/unit/listr.test.ts (1)
1-49: Consider adding test coverage forexternalSignalHandler.The implementation in
src/utils/listr.ts(line 11) also sets theexternalSignalHandlerproperty. Consider adding a test to verify this property is correctly assigned.🔎 Suggested test addition
+ test('sets externalSignalHandler', () => { + const listr = createListr([]); + + // @ts-ignore - accessing patched property + expect(listr.externalSignalHandler).toBeDefined(); + });tests/unit/registry/npm.test.ts (1)
1-17: Import sorting issue flagged by CI.The pipeline indicates imports should be sorted. Consider reordering to satisfy the linter.
Proposed fix
-import { describe, expect, test, vi, beforeEach, afterEach } from 'vitest'; -import { NpmRegistry, npmRegistry } from '../../../src/registry/npm'; - -vi.mock('tinyexec', () => ({ - exec: vi.fn(), -})); - -vi.mock('../../../src/utils/package', () => ({ - getPackageJson: vi.fn().mockResolvedValue({ - name: 'test-package', - version: '1.0.0', - }), -})); - -import { exec } from 'tinyexec'; +import { exec } from 'tinyexec'; +import { beforeEach, afterEach, describe, expect, test, vi } from 'vitest'; + +import { NpmRegistry, npmRegistry } from '../../../src/registry/npm'; + +vi.mock('tinyexec', () => ({ + exec: vi.fn(), +})); + +vi.mock('../../../src/utils/package', () => ({ + getPackageJson: vi.fn().mockResolvedValue({ + name: 'test-package', + version: '1.0.0', + }), +}));Note: The exact ordering depends on your project's lint rules. The
vi.mockcalls must remain hoisted, but the static imports can be reordered.src/cli.ts (1)
1-12: Import sorting issue flagged by CI.The pipeline indicates imports should be sorted. The
pathimport on line 12 should be grouped with other node imports if a sorting convention is enforced.Proposed fix
+import path from 'node:path'; import cac from 'cac'; import type { OptionConfig } from 'cac/deno/Option.js'; import semver from 'semver'; import { isCI } from 'std-env'; import { consoleError } from './error.js'; import { Git } from './git.js'; import { pubm } from './index.js'; import { requiredMissingInformationTasks } from './tasks/required-missing-information.js'; import type { Options } from './types/options.js'; import { notifyNewVersion } from './utils/notify-new-version.js'; import { version } from './utils/package.js'; -import path from 'node:path';tests/unit/index.test.ts (1)
1-21: Import sorting issue flagged by CI.The pipeline indicates imports should be sorted.
Proposed fix
-import { describe, expect, test, vi, beforeEach } from 'vitest'; - -vi.mock('../../src/options', () => ({ +import { beforeEach, describe, expect, test, vi } from 'vitest'; + +import { pubm } from '../../src/index'; +import { resolveOptions } from '../../src/options'; +import { run } from '../../src/tasks/runner'; + +vi.mock('../../src/options', () => ({ resolveOptions: vi.fn((options) => ({ ...options, testScript: options.testScript ?? 'test', buildScript: options.buildScript ?? 'build', branch: options.branch ?? 'main', tag: options.tag ?? 'latest', registries: options.registries ?? ['npm', 'jsr'], })), })); vi.mock('../../src/tasks/runner', () => ({ run: vi.fn().mockResolvedValue(undefined), })); - -import { pubm } from '../../src/index'; -import { run } from '../../src/tasks/runner'; -import { resolveOptions } from '../../src/options';Note: The exact ordering depends on your project's lint configuration.
tests/unit/registry/jsr.test.ts (1)
1-24: Import sorting issue flagged by CI.The pipeline indicates imports should be sorted.
Proposed fix
-import { describe, expect, test, vi, beforeEach, afterEach } from 'vitest'; -import { JsrRegisry, JsrClient, jsrRegistry } from '../../../src/registry/jsr'; - -vi.mock('tinyexec', () => ({ - exec: vi.fn(), -})); +import { exec } from 'tinyexec'; +import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest'; + +import { JsrClient, JsrRegisry, jsrRegistry } from '../../../src/registry/jsr'; +vi.mock('tinyexec', () => ({ + exec: vi.fn(), +})); vi.mock('../../../src/utils/package', () => ({ ... })); - -import { exec } from 'tinyexec';tests/utils/cli.ts (1)
1-5: Import sorting issue flagged by CI.The pipeline indicates imports should be sorted. The
node:pathimport should be grouped with other node imports.Proposed fix
+import path from 'node:path'; import type { Readable, Writable } from 'node:stream'; import { stripVTControlCharacters } from 'node:util'; import { isCI } from 'std-env'; import { type Options, exec } from 'tinyexec'; -import path from 'node:path';
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (35)
.gitignoredocs/landing.htmlpackage.jsonsrc/cli.tssrc/options.tssrc/tasks/required-missing-information.tssrc/tasks/runner.tstests/cli.test.tstests/fixtures/both-json/jsr.jsontests/fixtures/both-json/package.jsontests/fixtures/build-script/package.jsontests/fixtures/jsr-json/jsr.jsontests/fixtures/package-json/package.jsontests/fixtures/test-script/package.jsontests/test.test.tstests/unit/db.test.tstests/unit/engine-version.test.tstests/unit/error.test.tstests/unit/git.test.tstests/unit/index.test.tstests/unit/listr.test.tstests/unit/notify-new-version.test.tstests/unit/options.test.tstests/unit/package-manager.test.tstests/unit/package-name.test.tstests/unit/package.test.tstests/unit/registry/custom-registry.test.tstests/unit/registry/index.test.tstests/unit/registry/jsr.test.tstests/unit/registry/npm.test.tstests/unit/registry/registry.test.tstests/unit/rollback.test.tstests/unit/utils-cli.test.tstests/utils/cli.tsvitest.config.mts
💤 Files with no reviewable changes (1)
- tests/test.test.ts
🧰 Additional context used
🧬 Code graph analysis (19)
tests/unit/engine-version.test.ts (2)
src/utils/package.ts (1)
getPackageJson(49-90)src/utils/engine-version.ts (1)
validateEngineVersion(5-16)
src/tasks/required-missing-information.ts (3)
src/registry/jsr.ts (2)
distTags(53-55)jsr(35-41)src/registry/npm.ts (2)
distTags(106-119)npm(14-20)src/options.ts (1)
defaultOptions(3-9)
tests/unit/utils-cli.test.ts (1)
src/utils/cli.ts (2)
warningBadge(3-3)link(5-7)
tests/unit/db.test.ts (1)
src/utils/db.ts (1)
Db(20-58)
tests/unit/listr.test.ts (1)
src/utils/listr.ts (1)
createListr(4-17)
tests/unit/package-name.test.ts (1)
src/utils/package-name.ts (4)
isScopedPackage(3-5)getScope(7-9)getScopeAndName(11-17)isValidPackageName(24-60)
tests/unit/package.test.ts (1)
src/utils/package.ts (7)
jsrJsonToPackageJson(178-204)packageJsonToJsrJson(130-176)findOutFile(24-47)patchCachedJsrJson(17-22)getPackageJson(49-90)getJsrJson(92-128)replaceVersion(223-256)
tests/unit/notify-new-version.test.ts (3)
src/utils/package.ts (3)
findOutFile(24-47)getPackageJson(49-90)getJsrJson(92-128)src/utils/package-name.ts (1)
getScopeAndName(11-17)src/utils/notify-new-version.ts (1)
notifyNewVersion(6-61)
tests/unit/index.test.ts (3)
src/index.ts (1)
pubm(15-19)src/options.ts (1)
resolveOptions(11-15)src/tasks/runner.ts (1)
run(34-246)
tests/unit/git.test.ts (1)
src/git.ts (7)
git(10-16)Git(9-343)branch(153-161)status(107-115)tags(36-48)commit(286-296)commits(117-141)
tests/utils/cli.ts (1)
src/index.ts (1)
Options(21-21)
tests/unit/registry/index.test.ts (1)
src/registry/index.ts (1)
getRegistry(12-22)
tests/unit/registry/custom-registry.test.ts (1)
src/registry/custom-registry.ts (2)
CustomRegistry(5-16)customRegistry(18-22)
tests/unit/package-manager.test.ts (2)
src/utils/package.ts (1)
findOutFile(24-47)src/utils/package-manager.ts (1)
getPackageManager(11-19)
tests/unit/error.test.ts (1)
src/error.ts (2)
AbstractError(3-12)consoleError(42-54)
tests/unit/rollback.test.ts (1)
src/utils/rollback.ts (2)
addRollback(6-11)rollback(15-27)
tests/unit/registry/npm.test.ts (2)
src/registry/npm.ts (2)
NpmRegistry(11-183)npmRegistry(185-189)src/utils/package.ts (1)
getPackageJson(49-90)
src/cli.ts (2)
src/utils/notify-new-version.ts (1)
notifyNewVersion(6-61)src/index.ts (1)
pubm(15-19)
tests/unit/registry/jsr.test.ts (2)
src/registry/jsr.ts (3)
JsrRegisry(25-123)JsrClient(125-300)jsrRegistry(302-306)src/utils/package.ts (1)
getJsrJson(92-128)
🪛 GitHub Actions: CI
tests/unit/engine-version.test.ts
Organize imports: Import statements could be sorted.
tests/unit/utils-cli.test.ts
[error] 1-1: Import statements could be sorted: current order differs from recommended.
tests/unit/db.test.ts
Organize imports: Import statements could be sorted.
tests/cli.test.ts
[error] 5-5: CLI help command shows usage timed out after 5000ms.
[error] 13-13: CLI version command shows version timed out after 5000ms.
[error] 19-19: CLI -h alias shows help timed out after 5000ms.
[error] 26-26: CLI -v alias shows version timed out after 5000ms.
tests/fixtures/both-json/package.json
[error] 1-1: Formatter would have printed the following content: - name: "@test/both-package" - version: "3.0.0"
tests/unit/index.test.ts
Organize imports: Import statements could be sorted.
tests/fixtures/package-json/package.json
[error] 1-1: Formatter would have printed the following content: - name: "@test/package" - version: "1.0.0" - description: "Test package for unit tests" - exports: { ": { import: "./dist/index.js", require: "./dist/index.cjs" }, "./utils": { import: "./dist/utils.js" } } - files: ["dist", "!dist/test", "src"] - engines: { node: ">=18" }
tests/fixtures/test-script/package.json
[error] 1-1: Formatter would have printed the following content: - name: "test-script-fixtures" - version: "0.0.1" - scripts: { test: "test" }
tests/fixtures/build-script/package.json
[error] 1-1: Formatter would have printed the following content: - name: "build-script-fixtures" - version: "0.0.1" - scripts: { build: "build" }
tests/utils/cli.ts
[error] 1-1: Import statements could be sorted: current order differs from recommended.
tests/unit/registry/index.test.ts
Organize imports: Import statements could be sorted.
tests/unit/registry/custom-registry.test.ts
[error] 43-43: lint/suspicious/noExplicitAny - Unexpected any. Specify a different type.
[error] 60-60: lint/suspicious/noExplicitAny - Unexpected any. Specify a different type.
tests/unit/error.test.ts
Organize imports: Import statements could be sorted.
tests/unit/rollback.test.ts
[error] 1-1: Import statements could be sorted: current order differs from recommended.
package.json
[error] 1-1: Formatter would have printed the following content: - name: "@test/both-package" - version: "3.0.0"
[error] 1-1: Formatter would have printed the following content: - name: "build-script-fixtures" - version: "0.0.1" - scripts: { build: "build" }
[error] 1-1: Formatter would have printed the following content: - name: "test-script-fixtures" - version: "0.0.1" - scripts: { test: "test" }
[error] 1-1: Formatter would have printed the following content: - name: "@test/package" - version: "1.0.0" - description: "Test package for unit tests" - exports: { ": { import: "./dist/index.js", require: "./dist/index.cjs" }, "./utils": { import: "./dist/utils.js" } } - files: ["dist", "!dist/test", "src"] - engines: { node: ">=18" }
tests/fixtures/both-json/jsr.json
[error] 1-1: Formatter would have printed the following content: - name: "@test/both-jsr" - version: "3.0.0" - exports: "./src/index.ts"
tests/unit/registry/npm.test.ts
[error] 1-1: Import statements could be sorted: current order differs from recommended.
src/cli.ts
[error] 1-1: Import statements could be sorted: current order differs from recommended. Suggested reordering.
[error] 1-1: Import statements could be sorted: current order differs from recommended.
tests/fixtures/jsr-json/jsr.json
[error] 1-1: Formatter would have printed the following content: - name: "@test/jsr-package" - version: "2.0.0" - exports: { ".": "./src/index.ts", "./utils": "./src/utils.ts" } - publish: { include: ["src"], exclude: ["src/test"] }
tests/unit/registry/jsr.test.ts
Organize imports: Import statements could be sorted.
🪛 GitHub Check: Coverage: node-20, ubuntu-latest
tests/cli.test.ts
[failure] 26-26: tests/cli.test.ts > CLI Basic Commands > CLI -v alias shows version
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:26:2
[failure] 19-19: tests/cli.test.ts > CLI Basic Commands > CLI -h alias shows help
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:19:2
[failure] 13-13: tests/cli.test.ts > CLI Basic Commands > CLI version command shows version
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:13:2
[failure] 5-5: tests/cli.test.ts > CLI Basic Commands > CLI help command shows usage
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:5:2
🪛 GitHub Check: Test: node-18, ubuntu-latest
tests/cli.test.ts
[failure] 26-26: tests/cli.test.ts > CLI Basic Commands > CLI -v alias shows version
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:26:2
[failure] 19-19: tests/cli.test.ts > CLI Basic Commands > CLI -h alias shows help
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:19:2
[failure] 13-13: tests/cli.test.ts > CLI Basic Commands > CLI version command shows version
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:13:2
[failure] 5-5: tests/cli.test.ts > CLI Basic Commands > CLI help command shows usage
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:5:2
🪛 GitHub Check: Test: node-20, macos-latest
tests/cli.test.ts
[failure] 26-26: tests/cli.test.ts > CLI Basic Commands > CLI -v alias shows version
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:26:2
[failure] 19-19: tests/cli.test.ts > CLI Basic Commands > CLI -h alias shows help
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:19:2
[failure] 13-13: tests/cli.test.ts > CLI Basic Commands > CLI version command shows version
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:13:2
[failure] 5-5: tests/cli.test.ts > CLI Basic Commands > CLI help command shows usage
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:5:2
🪛 GitHub Check: Test: node-20, ubuntu-latest
tests/cli.test.ts
[failure] 26-26: tests/cli.test.ts > CLI Basic Commands > CLI -v alias shows version
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:26:2
[failure] 19-19: tests/cli.test.ts > CLI Basic Commands > CLI -h alias shows help
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:19:2
[failure] 13-13: tests/cli.test.ts > CLI Basic Commands > CLI version command shows version
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:13:2
[failure] 5-5: tests/cli.test.ts > CLI Basic Commands > CLI help command shows usage
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:5:2
🪛 GitHub Check: Test: node-20, windows-latest
tests/cli.test.ts
[failure] 26-26: tests/cli.test.ts > CLI Basic Commands > CLI -v alias shows version
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:26:2
[failure] 19-19: tests/cli.test.ts > CLI Basic Commands > CLI -h alias shows help
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:19:2
[failure] 13-13: tests/cli.test.ts > CLI Basic Commands > CLI version command shows version
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:13:2
[failure] 5-5: tests/cli.test.ts > CLI Basic Commands > CLI help command shows usage
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:5:2
🪛 GitHub Check: Test: node-22, ubuntu-latest
tests/cli.test.ts
[failure] 26-26: tests/cli.test.ts > CLI Basic Commands > CLI -v alias shows version
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:26:2
[failure] 19-19: tests/cli.test.ts > CLI Basic Commands > CLI -h alias shows help
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:19:2
[failure] 13-13: tests/cli.test.ts > CLI Basic Commands > CLI version command shows version
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:13:2
[failure] 5-5: tests/cli.test.ts > CLI Basic Commands > CLI help command shows usage
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:5:2
🔇 Additional comments (48)
tests/unit/db.test.ts (1)
6-75: Excellent test coverage for the Db utility.The test suite comprehensively covers the Db class functionality including:
- Basic set/get operations
- Numeric value handling (correctly expecting string conversion)
- Null returns for non-existent keys
- Value overwrites
- Multiple key operations
- Special characters and Unicode support
The setup and teardown hooks ensure proper test isolation.
docs/landing.html (4)
1-12: LGTM! Solid HTML foundation.The document structure, metadata, and font preloading setup are correct. The preconnect hints will improve font loading performance.
797-835: LGTM! Well-structured hero section.The hero section effectively showcases the product with a simulated terminal and clear value proposition. The markup is semantic and accessible.
837-941: LGTM! Accessible and semantic markup.The features grid and comparison table use proper semantic HTML. The emoji icons are supplemented with descriptive text, maintaining accessibility.
943-1018: LGTM! Accessible quickstart section.The step-by-step guide includes proper ARIA labels on copy buttons and uses data attributes for clean JavaScript integration. Well done.
.gitignore (1)
23-24: LGTM!The additions appropriately ignore coverage reports and the
.pubmdirectory, aligning with the test infrastructure enhancements.src/tasks/runner.ts (1)
38-38: Current npmOnly logic correctly identifies npm-only registries using exact matching.The logic at line 38 (
registries.every((registry) => registry === 'npm')) correctly checks for exact matches. This is more precise than negation-based approaches, properly excluding any mixed or unknown registry configurations.tests/unit/package-manager.test.ts (1)
1-81: LGTM! Comprehensive test coverage for package manager detection.The tests properly cover all lock file scenarios (npm, pnpm, yarn) including the prioritization logic and default fallback. The mock pattern with
vi.mockbefore import andvi.mockedis correct for Vitest.tests/unit/registry/index.test.ts (1)
25-47: LGTM! Registry resolution tests are well-structured.The tests correctly verify that
getRegistryreturns the appropriate registry instance for 'npm', 'jsr', and unknown keys (falling back to custom registry).tests/unit/rollback.test.ts (1)
4-72: LGTM! Excellent use of module isolation for stateful module testing.The pattern of using
vi.resetModules()with dynamic imports correctly isolates module state between tests, which is essential for testing the rollback module'scalledflag androllbacksarray. The test cases thoroughly cover:
- Registration without immediate execution
- Execution with context passing
- Idempotency (single execution guarantee)
- No-op behavior when empty
tests/unit/notify-new-version.test.ts (1)
1-144: LGTM! Thorough test coverage for version notification.The tests comprehensively cover:
- No-op when config files are missing
- npm update notification with version comparison
- No notification when versions match
- jsr update notification with API fetch
- Graceful error handling for both npm and jsr paths
The mock setup correctly isolates external dependencies (tinyexec, fetch, package utilities).
src/options.ts (1)
11-14: LGTM! Correct fix for option merging precedence.The updated spread order
{ ...defaultOptions, ...options }correctly ensures user-provided options override defaults. The previous order would have allowed defaults to overwrite explicitly provided options, which is counterintuitive behavior.tests/unit/registry/custom-registry.test.ts (1)
22-27: Remove the manual registry assignment—the constructor properly sets it from the parameter.The
Registrybase class constructor acceptsregistryas an optional parameter and assigns it directly:public registry?: string. When you instantiatenew CustomRegistry('test-package', 'https://custom.registry.com'), the constructor setsthis.registryto the passed value, making the subsequent manual assignment line redundant.package.json (1)
52-58: Vitest 3.x is a major version upgrade with breaking changes.Upgrading from Vitest ^2.1.1 to ^3.1.2 is a major version bump with several breaking changes including: modified test hook signatures, altered spy.mockReset behavior, test files excluded from coverage by default, and browser mode configuration changes. Ensure all tests pass locally and review the Vitest 3.0 migration guide for any changes that might affect your test suite.
tests/unit/listr.test.ts (4)
5-10: LGTM!The test correctly verifies basic Listr instance creation and the presence of the
runmethod.
12-16: LGTM!The test correctly verifies that
createListroverridesisRootto always returnfalse, matching the implementation insrc/utils/listr.ts.
18-31: LGTM!The test correctly verifies that
createListraccepts task definitions with titles and task functions.
33-48: LGTM!The test correctly verifies that
createListraccepts both tasks and Listr options, matching the implementation's use of spread arguments.vitest.config.mts (1)
10-16: LGTM!The coverage configuration updates appropriately focus coverage collection on source TypeScript files while excluding type definitions, the CLI entry point, task implementations, and node_modules. This aligns well with the PR's goal of adding integrated test coverage.
tests/unit/registry/registry.test.ts (2)
32-48: LGTM!The constructor tests correctly verify both single-argument (package name only) and two-argument (package name with registry URL) initialization patterns.
50-61: LGTM!The test comprehensively verifies that all abstract methods are implemented and callable, providing good coverage of the Registry interface contract.
tests/unit/utils-cli.test.ts (1)
4-33: LGTM!The test suite provides good coverage of the CLI utility functions. The tests correctly verify the warningBadge format and the link function's OSC 8 escape sequence generation, including edge cases for empty inputs.
tests/unit/options.test.ts (1)
1-135: LGTM!Excellent test coverage for the options module. The test suite thoroughly validates default values, option merging behavior, overrides, partial options, feature flags, and various registry configurations. The tests are well-structured and cover both common use cases and edge cases.
tests/unit/engine-version.test.ts (1)
12-84: LGTM!The test suite provides comprehensive coverage of the
validateEngineVersionfunction, including satisfied/unsatisfied requirements, prerelease version handling, multiple engine types, and missing engine definitions. The mock setup and cleanup are properly implemented.tests/unit/error.test.ts (2)
4-33: LGTM!The AbstractError test suite effectively validates error construction, cause handling, inheritance chain, and stack trace generation.
35-115: LGTM!The consoleError test suite is comprehensive and well-structured. It covers string and Error instance logging, formatting behavior, nested cause chains, and edge cases with proper use of console.error spies. The @ts-ignore directives are appropriately used to test runtime edge cases.
tests/unit/package-name.test.ts (1)
1-134: LGTM!Exceptional test coverage for package name utilities. The test suite is well-organized and thoroughly validates:
- Scoped package detection and parsing
- Comprehensive package name validation including npm naming rules
- Boundary conditions (214 character limit)
- Blacklisted and builtin module names
- Special characters and formatting rules
The nested describe blocks provide excellent test organization and readability.
tests/unit/registry/npm.test.ts (5)
19-34: LGTM!Test setup is well-structured with proper mock clearing in
beforeEachand restoration inafterEach. The registry instantiation and global fetch mocking pattern is appropriate.
36-122: LGTM!Tests for
isInstalled,isPublished,userName, andisLoggedInprovide good coverage of success, failure, and edge case paths (likeENEEDAUTHhandling).
124-218: LGTM!Tests for
collaborators,hasPermission,distTags,version, andpingare well-structured. The chainedmockResolvedValueOncecalls forhasPermissioncorrectly simulate the sequentialuserName()thencollaborators()calls.
220-311: LGTM!Good coverage for
publish,publishProvenance,isPackageNameAvaliable, andinstallGlobally. The OTP parameter verification (Lines 249-253) and the invalid package name test with capital letters correctly exercise the implementation.
313-369: LGTM!Error handling tests comprehensively cover failure paths for multiple methods. The
npmRegistryfactory test correctly verifies instance creation from mocked package metadata.src/cli.ts (2)
129-143: LGTM!The
contentspath resolution usingpath.resolve(process.cwd(), options.contents)correctly canonicalizes the path to an absolute path. This ensures consistent behavior regardless of whether a relative or absolute path is provided.
159-206: LGTM!The refactored flow is cleaner:
- Options resolved once upfront
chdirto contents directory if specifiednotifyNewVersioncalled after directory change (correct context)- Single
resolvedOptionsobject used consistently throughoutThis eliminates redundant option resolution and ensures all subsequent operations use the canonicalized paths.
tests/unit/index.test.ts (1)
22-86: LGTM!Unit tests appropriately verify
pubm's delegation behavior - callingresolveOptionswith provided options and invokingrun. The test cases cover various option combinations (registries, skip flags, preview mode).tests/unit/git.test.ts (4)
1-33: LGTM!Test setup and version test are well-structured. The mock pattern for
tinyexecis consistent with other test files.
35-193: LGTM!Tests for
branch,status,userName,latestTag,tags,latestCommit,firstCommit, andrepositoryprovide comprehensive coverage. ThelatestTagnull case andtagsversion prefix stripping are correctly tested.
195-406: LGTM!Tests for staging, commit, tag, and branch operations are thorough. The chained mock pattern for
commit(Lines 259-269) correctly simulates the two-step process of committing and retrieving the hash.
533-867: LGTM!Excellent coverage of
revisionDiffsCount,dryFetch,push(including GH006 protected branch handling), and comprehensive error handling tests. The push tests correctly verify that GH006 errors returnfalserather than throwing, which aligns with protected branch workflow handling.tests/unit/registry/jsr.test.ts (3)
26-165: LGTM!
JsrRegisrytests are comprehensive, covering initialization, CLI availability checks, publishing, and permission verification. ThedistTagstest correctly expects an empty array since JSR doesn't support this feature.
167-381: LGTM!
JsrClienttests thoroughly cover API interactions including success paths, 401 unauthorized handling (returning null/empty), and network failure error propagation.
384-397: LGTM!Factory test correctly verifies
jsrRegistrycreates aJsrRegisryinstance using the package name fromgetJsrJson.tests/unit/package.test.ts (4)
1-9: LGTM!Imports are properly structured with
node:pathfollowed by vitest imports and then local imports.
11-178: LGTM!Conversion tests for
jsrJsonToPackageJsonandpackageJsonToJsrJsoncomprehensively cover:
- Simple string exports
- Object/nested exports transformation
- Publish include/exclude mapping to files array (and vice versa)
- Edge cases (missing exports, missing files/publish)
180-221: LGTM!Tests for
findOutFile,patchCachedJsrJson, andversionprovide basic coverage. ThefindOutFiletests exercise real filesystem traversal behavior.
223-382: LGTM!Mocked tests for
getPackageJson,getJsrJson, andreplaceVersionare well-structured:
- Uses
vi.doMockwithvi.resetModulesfor fresh module state- Unique
cwdpaths prevent cache interference between tests- Covers success, invalid JSON, fallback disabled, and no-files scenarios
tests/utils/cli.ts (2)
120-163: Note: Return values are captured at spawn time.The
exitCode,stdout, andstderrin the return object (Lines 158-160) capture values at subprocess spawn time. Since the process runs asynchronously:
exitCodewill typically beundefinedinitiallystdout/stderrwill be empty strings initiallyCallers should use
waitForClose()orcontroller.waitForStdout()/controller.waitForStderr()for final values. Thecontroller.stdoutandcontroller.stderrproperties update in real-time via listeners.This design is appropriate for interactive CLI testing where you need to write input and observe output incrementally.
165-167: LGTM!The exported ANSI escape sequence constants (
DOWN,UP,ENTER) are useful for simulating keyboard input in interactive CLI tests.
| <a href="#features">Features</a> | ||
| <a href="#comparison">Compare</a> | ||
| <a href="#quickstart">Quick Start</a> | ||
| <a href="https://github.com/syi0808/pubm" target="_blank" rel="noopener" class="nav-cta">GitHub</a> |
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.
Add noreferrer to external links for security.
External links use rel="noopener" but are missing rel="noreferrer". Adding noreferrer prevents referrer information leakage when users navigate to external sites.
🔎 Suggested fix
Update all external links to include both noopener and noreferrer:
- <a href="https://github.com/syi0808/pubm" target="_blank" rel="noopener" class="nav-cta">GitHub</a>
+ <a href="https://github.com/syi0808/pubm" target="_blank" rel="noopener noreferrer" class="nav-cta">GitHub</a>Apply the same pattern to lines 1024, 1027, and 1040-1043.
Also applies to: 1024-1027, 1040-1043
🤖 Prompt for AI Agents
In docs/landing.html around line 792 (and also apply to lines 1024-1027 and
1040-1043), external anchor tags currently use rel="noopener" only; update those
anchor tags to include rel="noopener noreferrer" (preserving target and other
attributes) so the links retain the noopener protection while also preventing
referrer header leakage when users follow external links.
| // Typing effect for terminal | ||
| const terminalCmd = document.querySelector('.terminal-cmd'); | ||
| const originalText = terminalCmd.textContent; | ||
| terminalCmd.textContent = ''; | ||
|
|
||
| let i = 0; | ||
| const typeWriter = () => { | ||
| if (i < originalText.length) { | ||
| terminalCmd.textContent += originalText.charAt(i); | ||
| i++; | ||
| setTimeout(typeWriter, 50); | ||
| } | ||
| }; | ||
|
|
||
| setTimeout(typeWriter, 500); |
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.
Add null check for terminal typing effect.
If the .terminal-cmd element is not found, lines 1069-1070 will throw a runtime error when trying to access textContent on null.
🔎 Suggested fix
// Typing effect for terminal
const terminalCmd = document.querySelector('.terminal-cmd');
+if (terminalCmd) {
const originalText = terminalCmd.textContent;
terminalCmd.textContent = '';
let i = 0;
const typeWriter = () => {
if (i < originalText.length) {
terminalCmd.textContent += originalText.charAt(i);
i++;
setTimeout(typeWriter, 50);
}
};
setTimeout(typeWriter, 500);
+}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // Typing effect for terminal | |
| const terminalCmd = document.querySelector('.terminal-cmd'); | |
| const originalText = terminalCmd.textContent; | |
| terminalCmd.textContent = ''; | |
| let i = 0; | |
| const typeWriter = () => { | |
| if (i < originalText.length) { | |
| terminalCmd.textContent += originalText.charAt(i); | |
| i++; | |
| setTimeout(typeWriter, 50); | |
| } | |
| }; | |
| setTimeout(typeWriter, 500); | |
| // Typing effect for terminal | |
| const terminalCmd = document.querySelector('.terminal-cmd'); | |
| if (terminalCmd) { | |
| const originalText = terminalCmd.textContent; | |
| terminalCmd.textContent = ''; | |
| let i = 0; | |
| const typeWriter = () => { | |
| if (i < originalText.length) { | |
| terminalCmd.textContent += originalText.charAt(i); | |
| i++; | |
| setTimeout(typeWriter, 50); | |
| } | |
| }; | |
| setTimeout(typeWriter, 500); | |
| } |
🤖 Prompt for AI Agents
In docs/landing.html around lines 1067 to 1081, the code assumes
document.querySelector('.terminal-cmd') always returns an element and
immediately reads .textContent, which will throw if the element is missing;
update the code to first check that terminalCmd is not null and only proceed to
read originalText, clear textContent, and start the typeWriter; if terminalCmd
is null, simply skip initializing the typing effect (or return early) to avoid
runtime errors.
| copyButtons.forEach(btn => { | ||
| btn.addEventListener('click', async () => { | ||
| const codeBlock = btn.parentElement.querySelector('.step-code'); | ||
| const textToCopy = codeBlock.getAttribute('data-copy'); | ||
|
|
||
| try { | ||
| await navigator.clipboard.writeText(textToCopy); | ||
| btn.innerHTML = checkIcon; | ||
| btn.classList.add('copied'); | ||
|
|
||
| setTimeout(() => { | ||
| btn.innerHTML = copyIcon; | ||
| btn.classList.remove('copied'); | ||
| }, 2000); | ||
| } catch (err) { | ||
| console.error('Failed to copy:', err); | ||
| } | ||
| }); | ||
| }); |
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.
Add null check in copy functionality.
The code assumes .step-code exists, but if the DOM structure changes or elements are missing, line 1091 will throw an error when accessing getAttribute on null.
🔎 Suggested fix
copyButtons.forEach(btn => {
btn.addEventListener('click', async () => {
const codeBlock = btn.parentElement.querySelector('.step-code');
+ if (!codeBlock) return;
+
const textToCopy = codeBlock.getAttribute('data-copy');
try {
await navigator.clipboard.writeText(textToCopy);
btn.innerHTML = checkIcon;
btn.classList.add('copied');
setTimeout(() => {
btn.innerHTML = copyIcon;
btn.classList.remove('copied');
}, 2000);
} catch (err) {
console.error('Failed to copy:', err);
}
});
});📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| copyButtons.forEach(btn => { | |
| btn.addEventListener('click', async () => { | |
| const codeBlock = btn.parentElement.querySelector('.step-code'); | |
| const textToCopy = codeBlock.getAttribute('data-copy'); | |
| try { | |
| await navigator.clipboard.writeText(textToCopy); | |
| btn.innerHTML = checkIcon; | |
| btn.classList.add('copied'); | |
| setTimeout(() => { | |
| btn.innerHTML = copyIcon; | |
| btn.classList.remove('copied'); | |
| }, 2000); | |
| } catch (err) { | |
| console.error('Failed to copy:', err); | |
| } | |
| }); | |
| }); | |
| copyButtons.forEach(btn => { | |
| btn.addEventListener('click', async () => { | |
| const codeBlock = btn.parentElement.querySelector('.step-code'); | |
| if (!codeBlock) return; | |
| const textToCopy = codeBlock.getAttribute('data-copy'); | |
| try { | |
| await navigator.clipboard.writeText(textToCopy); | |
| btn.innerHTML = checkIcon; | |
| btn.classList.add('copied'); | |
| setTimeout(() => { | |
| btn.innerHTML = copyIcon; | |
| btn.classList.remove('copied'); | |
| }, 2000); | |
| } catch (err) { | |
| console.error('Failed to copy:', err); | |
| } | |
| }); | |
| }); |
🤖 Prompt for AI Agents
In docs/landing.html around lines 1088 to 1106, the copy button handler assumes
btn.parentElement.querySelector('.step-code') always returns an element and
calls getAttribute on it; add a null check for codeBlock before using it and
abort/return early if missing (optionally disable the button or show a console
warning), and if you want a safe fallback use codeBlock.textContent or innerText
when data-copy attribute is absent; ensure no further operations run when
codeBlock is null so the click handler doesn't throw.
| "test": "vitest", | ||
| "coverage": "vitest --coverage", |
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.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check for CI workflow files and how they invoke tests
find .github/workflows -type f \( -name "*.yml" -o -name "*.yaml" \) 2>/dev/null | while read file; do
echo "=== File: $file ==="
cat "$file"
echo ""
doneRepository: syi0808/pubm
Length of output: 3679
Update CI configuration: test scripts now require --run flag to prevent watch mode in CI.
Removing --run from the test scripts changes the default behavior to watch mode. The CI pipeline invokes pnpm run test and pnpm run coverage without the --run flag, which will cause tests to hang waiting for interactive input. Either update the CI workflow to pass --run explicitly:
- name: 'Test'
run: pnpm run test -- --run
- name: 'Test'
run: pnpm run coverage -- --runOr revert the scripts in package.json to include --run by default.
🤖 Prompt for AI Agents
In package.json around lines 31-32, the "test" and "coverage" scripts currently
call vitest without the "--run" flag which causes watch mode in CI; fix by
either updating these scripts to include "--run" (e.g., change "test": "vitest"
to "test": "vitest --run" and "coverage": "vitest --coverage --run") or, if you
prefer to keep scripts generic, update the CI workflow to invoke the scripts
with the extra flag (e.g., use "pnpm run test -- --run" and "pnpm run coverage
-- --run"); pick one approach and apply it consistently so CI runs
non-interactively.
| test('CLI help command shows usage', async () => { | ||
| const { controller } = runPubmCli('--help'); | ||
|
|
||
| await controller.waitForStdout('pubm'); | ||
| await controller.waitForStdout('Usage:'); | ||
| await controller.waitForStdout('Options:'); | ||
| }); | ||
|
|
||
| test('CLI version command shows version', async () => { | ||
| const { controller } = runPubmCli('--version'); | ||
|
|
||
| await controller.waitForStdout('pubm'); | ||
| }); | ||
|
|
||
| test('CLI -h alias shows help', async () => { | ||
| const { controller } = runPubmCli('-h'); | ||
|
|
||
| await controller.waitForStdout('pubm'); | ||
| await controller.waitForStdout('Usage:'); | ||
| }); | ||
|
|
||
| test('CLI -v alias shows version', async () => { | ||
| const { controller } = runPubmCli('-v'); | ||
|
|
||
| await controller.waitForStdout('pubm'); | ||
| }); |
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.
🧩 Analysis chain
🏁 Script executed:
# Examine the test file and utility structure
find tests -name "*.ts" -o -name "*.js" | head -20Repository: syi0808/pubm
Length of output: 641
🏁 Script executed:
# Check the test utilities directory
ls -la tests/utils/ 2>/dev/null || echo "utils directory not found, checking alternative paths"Repository: syi0808/pubm
Length of output: 222
🏁 Script executed:
# Search for the runPubmCli function definition
rg -n "runPubmCli|waitForStdout" tests/ --type ts --type js -B 2 -A 5Repository: syi0808/pubm
Length of output: 2332
🏁 Script executed:
# Check test configuration and timeout settings
fd -e "config" -e "json" tests/
cat package.json | grep -A 10 -B 2 "jest\|vitest\|test"Repository: syi0808/pubm
Length of output: 1228
🏁 Script executed:
cat -n tests/utils/cli.tsRepository: syi0808/pubm
Length of output: 5322
🏁 Script executed:
# Also check if there's a vitest config file that might set timeout
fd . tests -name "*.config.*" -o -name "vitest.config.*" -o -name "vitest.json"Repository: syi0808/pubm
Length of output: 286
🏁 Script executed:
# Check the actual CLI entry point to understand what gets executed
fd . src -type f -name "*.ts" | head -10Repository: syi0808/pubm
Length of output: 226
🏁 Script executed:
# Find the CLI entry point
find . -path "./bin/*" -type f -name "*.js" -o -name "cli.js" | grep -E "bin|cli"Repository: syi0808/pubm
Length of output: 38
🏁 Script executed:
# Check vitest configuration in package.json or config files
cat package.json | grep -A 50 "vitest\|test"Repository: syi0808/pubm
Length of output: 1254
🏁 Script executed:
# Look for vitest config
fd . -name "vitest.config.*" -o -name "vitest.*" 2>/dev/nullRepository: syi0808/pubm
Length of output: 38
🏁 Script executed:
# Check if bin/cli.js exists
ls -la bin/ 2>/dev/null || echo "bin directory doesn't exist or is inaccessible"Repository: syi0808/pubm
Length of output: 102
🏁 Script executed:
# Get the actual structure of the repo root
ls -la | head -30Repository: syi0808/pubm
Length of output: 1308
🏁 Script executed:
cat vitest.config.mtsRepository: syi0808/pubm
Length of output: 473
🏁 Script executed:
cat tsup.config.tsRepository: syi0808/pubm
Length of output: 598
🏁 Script executed:
# Check the src directory structure
find src -type f | head -20Repository: syi0808/pubm
Length of output: 515
🏁 Script executed:
# Look for CLI entry point
rg -n "export.*main\|bin\|#!/usr" src/ --type tsRepository: syi0808/pubm
Length of output: 38
🏁 Script executed:
cat src/cli.tsRepository: syi0808/pubm
Length of output: 5560
🏁 Script executed:
# Check what happens on import - any top-level errors?
cat src/index.ts | head -30Repository: syi0808/pubm
Length of output: 665
🏁 Script executed:
# Look at package.json build scripts
grep -A 5 "build\|dist\|bin" package.jsonRepository: syi0808/pubm
Length of output: 544
🏁 Script executed:
# Check GitHub Actions workflow
find .github -type f -name "*.yml" -o -name "*.yaml"Repository: syi0808/pubm
Length of output: 111
🏁 Script executed:
# Look for any test setup files
find tests -name "setup*" -o -name "vitest.*"Repository: syi0808/pubm
Length of output: 38
🏁 Script executed:
# Check if tinyexec is imported correctly
rg -n "tinyexec" src/ tests/ --type tsRepository: syi0808/pubm
Length of output: 1140
🏁 Script executed:
# Verify the import.meta.dirname usage
rg -n "import.meta" src/cli.ts tests/utils/cli.ts --type ts -A 2 -B 2Repository: syi0808/pubm
Length of output: 513
🏁 Script executed:
cat .github/workflows/ci.yamlRepository: syi0808/pubm
Length of output: 2765
🏁 Script executed:
# Also check the release workflow
cat .github/workflows/release.ymlRepository: syi0808/pubm
Length of output: 884
🏁 Script executed:
# Check if there's a build script run before tests
grep -n "build\|test" package.jsonRepository: syi0808/pubm
Length of output: 229
Critical: CLI tests are timing out because bin/cli.js is not built before running tests.
The test utility attempts to spawn the CLI from bin/cli.js (line 139 of tests/utils/cli.ts), which is generated by tsup during the build step. The CI workflow (.github/workflows/ci.yaml) runs pnpm run test directly after pnpm install --frozen-lockfile without running pnpm run build first, causing the process spawn to fail. The controller.waitForStdout() method then times out after 4000ms (or 20000ms in CI environments) waiting for output from a process that was never started.
The tests cannot pass until a build step is added to the test job in .github/workflows/ci.yaml before running pnpm run test.
🧰 Tools
🪛 GitHub Actions: CI
[error] 5-5: CLI help command shows usage timed out after 5000ms.
[error] 13-13: CLI version command shows version timed out after 5000ms.
[error] 19-19: CLI -h alias shows help timed out after 5000ms.
[error] 26-26: CLI -v alias shows version timed out after 5000ms.
🪛 GitHub Check: Coverage: node-20, ubuntu-latest
[failure] 26-26: tests/cli.test.ts > CLI Basic Commands > CLI -v alias shows version
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:26:2
[failure] 19-19: tests/cli.test.ts > CLI Basic Commands > CLI -h alias shows help
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:19:2
[failure] 13-13: tests/cli.test.ts > CLI Basic Commands > CLI version command shows version
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:13:2
[failure] 5-5: tests/cli.test.ts > CLI Basic Commands > CLI help command shows usage
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:5:2
🪛 GitHub Check: Test: node-18, ubuntu-latest
[failure] 26-26: tests/cli.test.ts > CLI Basic Commands > CLI -v alias shows version
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:26:2
[failure] 19-19: tests/cli.test.ts > CLI Basic Commands > CLI -h alias shows help
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:19:2
[failure] 13-13: tests/cli.test.ts > CLI Basic Commands > CLI version command shows version
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:13:2
[failure] 5-5: tests/cli.test.ts > CLI Basic Commands > CLI help command shows usage
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:5:2
🪛 GitHub Check: Test: node-20, macos-latest
[failure] 26-26: tests/cli.test.ts > CLI Basic Commands > CLI -v alias shows version
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:26:2
[failure] 19-19: tests/cli.test.ts > CLI Basic Commands > CLI -h alias shows help
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:19:2
[failure] 13-13: tests/cli.test.ts > CLI Basic Commands > CLI version command shows version
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:13:2
[failure] 5-5: tests/cli.test.ts > CLI Basic Commands > CLI help command shows usage
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:5:2
🪛 GitHub Check: Test: node-20, ubuntu-latest
[failure] 26-26: tests/cli.test.ts > CLI Basic Commands > CLI -v alias shows version
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:26:2
[failure] 19-19: tests/cli.test.ts > CLI Basic Commands > CLI -h alias shows help
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:19:2
[failure] 13-13: tests/cli.test.ts > CLI Basic Commands > CLI version command shows version
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:13:2
[failure] 5-5: tests/cli.test.ts > CLI Basic Commands > CLI help command shows usage
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:5:2
🪛 GitHub Check: Test: node-20, windows-latest
[failure] 26-26: tests/cli.test.ts > CLI Basic Commands > CLI -v alias shows version
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:26:2
[failure] 19-19: tests/cli.test.ts > CLI Basic Commands > CLI -h alias shows help
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:19:2
[failure] 13-13: tests/cli.test.ts > CLI Basic Commands > CLI version command shows version
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:13:2
[failure] 5-5: tests/cli.test.ts > CLI Basic Commands > CLI help command shows usage
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:5:2
🪛 GitHub Check: Test: node-22, ubuntu-latest
[failure] 26-26: tests/cli.test.ts > CLI Basic Commands > CLI -v alias shows version
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:26:2
[failure] 19-19: tests/cli.test.ts > CLI Basic Commands > CLI -h alias shows help
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:19:2
[failure] 13-13: tests/cli.test.ts > CLI Basic Commands > CLI version command shows version
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:13:2
[failure] 5-5: tests/cli.test.ts > CLI Basic Commands > CLI help command shows usage
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ tests/cli.test.ts:5:2
| } as never); | ||
|
|
||
| // Access protected method through type casting | ||
| await (registry as any).npm(['view', 'package']); |
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.
Fix lint error: Avoid any type when accessing protected method.
The pipeline flagged lint/suspicious/noExplicitAny. Consider creating a type-safe way to test the protected method.
🔎 Suggested fix using a narrower type
- // Access protected method through type casting
- await (registry as any).npm(['view', 'package']);
+ // Access protected method through type casting
+ await (registry as unknown as { npm: (args: string[]) => Promise<string> }).npm(['view', 'package']);Alternatively, you could create a test subclass that exposes the method:
class TestableCustomRegistry extends CustomRegistry {
public async testNpm(args: string[]): Promise<string> {
return this.npm(args);
}
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| await (registry as any).npm(['view', 'package']); | |
| await (registry as unknown as { npm: (args: string[]) => Promise<string> }).npm(['view', 'package']); |
🧰 Tools
🪛 GitHub Actions: CI
[error] 43-43: lint/suspicious/noExplicitAny - Unexpected any. Specify a different type.
🤖 Prompt for AI Agents
In tests/unit/registry/custom-registry.test.ts around line 43, the test
currently uses (registry as any).npm([...]) which triggers
lint/suspicious/noExplicitAny; replace that with a type-safe approach by
creating a small TestableCustomRegistry subclass in the test that exposes the
protected npm method as a public wrapper (e.g., public async testNpm(args:
string[]): Promise<string> { return this.npm(args); }), instantiate that
subclass with the same constructor args used for CustomRegistry, and call
testNpm(['view','package']) in place of the any cast so the test remains
equivalent but avoids using any.
| exitCode: 1, | ||
| } as never); | ||
|
|
||
| await expect((registry as any).npm(['test'])).rejects.toBe('error'); |
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.
Fix lint error: Same any type issue here.
Apply the same fix pattern as suggested above.
🔎 Suggested fix
- await expect((registry as any).npm(['test'])).rejects.toBe('error');
+ await expect((registry as unknown as { npm: (args: string[]) => Promise<string> }).npm(['test'])).rejects.toBe('error');🧰 Tools
🪛 GitHub Actions: CI
[error] 60-60: lint/suspicious/noExplicitAny - Unexpected any. Specify a different type.
🤖 Prompt for AI Agents
In tests/unit/registry/custom-registry.test.ts around line 60, the test uses an
unsafe cast "(registry as any)" causing the lint error; replace the any cast
with a proper typed cast or interface for registry (e.g., cast to the registry
type or to "unknown as { npm: (args: string[]) => Promise<unknown> }") and call
.npm with that typed reference so the expect(...).rejects assertion stays
unchanged.
| @@ -0,0 +1,47 @@ | |||
| import { describe, expect, test, vi, beforeEach } from 'vitest'; | |||
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.
Address pipeline failure: Import statements need sorting.
The CI pipeline flagged that import statements could be sorted. Run the formatter to fix the import order.
🧰 Tools
🪛 GitHub Actions: CI
Organize imports: Import statements could be sorted.
🤖 Prompt for AI Agents
In tests/unit/registry/index.test.ts around line 1, the import statements are
not in the expected sorted order and the CI pipeline is failing; reorder the
imports to match the project's import/formatter rules (e.g., alphabetically and
grouped by external vs local imports) and then run the repository formatter (npm
run format or the configured prettier/eslint --fix) to apply the correct
ordering and update the file.
| @@ -0,0 +1,72 @@ | |||
| import { describe, expect, test, vi, beforeEach, afterEach } from 'vitest'; | |||
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.
Address pipeline failure: Import statements need sorting.
The CI pipeline flagged that import statements could be sorted. Run the formatter to fix the import order.
🧰 Tools
🪛 GitHub Actions: CI
[error] 1-1: Import statements could be sorted: current order differs from recommended.
🤖 Prompt for AI Agents
In tests/unit/rollback.test.ts at line 1, the import statements are not sorted
which breaks the CI pipeline; run your project's formatter or sort imports so
they follow the configured ordering (e.g., alphabetical/grouped per lint/format
rules), then save the file and re-run tests to ensure the import order warning
is resolved.
| import { describe, expect, test } from 'vitest'; | ||
| import { warningBadge, link } from '../../src/utils/cli'; |
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.
Fix import statement order.
The pipeline indicates that import statements should be sorted. Please run your linter/formatter to automatically organize the imports according to the project's conventions.
🧰 Tools
🪛 GitHub Actions: CI
[error] 1-1: Import statements could be sorted: current order differs from recommended.
🤖 Prompt for AI Agents
In tests/unit/utils-cli.test.ts lines 1-2 the import declarations are out of the
project's expected sort/order; run the project's linter/formatter (e.g., eslint
--fix or prettier, or your repo's configured import-sorting tool) or manually
reorder the imports to match the project's import sorting rules so they are
properly grouped and alphabetized (then save the file and re-run tests).
Summary by CodeRabbit
New Features
--help/-hand--version/-vflags.Bug Fixes
Tests
Chores
✏️ Tip: You can customize this high-level summary in your review settings.