generated from nhcarrigan/template
feat: initial prototype attempt
This commit is contained in:
@@ -0,0 +1,294 @@
|
||||
/**
|
||||
* @copyright NHCarrigan
|
||||
* @license Naomi's Public License
|
||||
* @author Naomi Carrigan
|
||||
*/
|
||||
|
||||
/* eslint-disable vitest/valid-expect -- Test expectations don't need messages */
|
||||
/* eslint-disable max-lines-per-function -- Test suites require many test cases */
|
||||
/* eslint-disable @typescript-eslint/naming-convention -- Test data uses npm package names and destructured imports */
|
||||
/* eslint-disable @typescript-eslint/consistent-type-assertions -- Required for mocking */
|
||||
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
vi.mock("@nhcarrigan/logger", () => {
|
||||
return {
|
||||
|
||||
Logger: class MockLogger {
|
||||
public error = vi.fn();
|
||||
public log = vi.fn();
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
interface MockNpmService {
|
||||
getPackageChangelog: ReturnType<typeof vi.fn>;
|
||||
getPackageInfo: ReturnType<typeof vi.fn>;
|
||||
}
|
||||
|
||||
const createMockNpmService = (): MockNpmService => {
|
||||
return {
|
||||
getPackageChangelog: vi.fn(),
|
||||
getPackageInfo: vi.fn(),
|
||||
};
|
||||
};
|
||||
|
||||
describe("dependencyAnalyzerService", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.resetAllMocks();
|
||||
});
|
||||
|
||||
it("should return empty array when no dependencies", async() => {
|
||||
expect.assertions(1);
|
||||
const mockNpmService = createMockNpmService();
|
||||
const { DependencyAnalyzerService }
|
||||
= await import("../../src/services/dependencyAnalyzerService.js");
|
||||
const analyzerService = new DependencyAnalyzerService(
|
||||
mockNpmService as Parameters<typeof DependencyAnalyzerService>[0],
|
||||
);
|
||||
const result = await analyzerService.analyzePackageJson({});
|
||||
expect(result).toStrictEqual([]);
|
||||
});
|
||||
|
||||
it("should find updates for dependencies", async() => {
|
||||
expect.assertions(2);
|
||||
const mockNpmService = createMockNpmService();
|
||||
mockNpmService.getPackageInfo.mockResolvedValue({
|
||||
"dist-tags": { latest: "2.0.0" },
|
||||
"name": "test-package",
|
||||
"versions": {},
|
||||
});
|
||||
const { DependencyAnalyzerService }
|
||||
= await import("../../src/services/dependencyAnalyzerService.js");
|
||||
const analyzerService = new DependencyAnalyzerService(
|
||||
mockNpmService as Parameters<typeof DependencyAnalyzerService>[0],
|
||||
);
|
||||
const result = await analyzerService.analyzePackageJson({
|
||||
dependencies: {
|
||||
"test-package": "1.0.0",
|
||||
},
|
||||
});
|
||||
expect(result).toHaveLength(1);
|
||||
expect(result[0]).toStrictEqual({
|
||||
currentVersion: "1.0.0",
|
||||
latestVersion: "2.0.0",
|
||||
packageName: "test-package",
|
||||
type: "dependencies",
|
||||
});
|
||||
});
|
||||
|
||||
it("should skip file: protocol dependencies", async() => {
|
||||
expect.assertions(2);
|
||||
const mockNpmService = createMockNpmService();
|
||||
const { DependencyAnalyzerService }
|
||||
= await import("../../src/services/dependencyAnalyzerService.js");
|
||||
const analyzerService = new DependencyAnalyzerService(
|
||||
mockNpmService as Parameters<typeof DependencyAnalyzerService>[0],
|
||||
);
|
||||
const result = await analyzerService.analyzePackageJson({
|
||||
dependencies: {
|
||||
"local-package": "file:../local-package",
|
||||
},
|
||||
});
|
||||
expect(result).toStrictEqual([]);
|
||||
expect(mockNpmService.getPackageInfo).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should skip git: protocol dependencies", async() => {
|
||||
expect.assertions(1);
|
||||
const mockNpmService = createMockNpmService();
|
||||
const { DependencyAnalyzerService }
|
||||
= await import("../../src/services/dependencyAnalyzerService.js");
|
||||
const analyzerService = new DependencyAnalyzerService(
|
||||
mockNpmService as Parameters<typeof DependencyAnalyzerService>[0],
|
||||
);
|
||||
const result = await analyzerService.analyzePackageJson({
|
||||
dependencies: {
|
||||
"git-package": "git:github.com/user/repo",
|
||||
},
|
||||
});
|
||||
expect(result).toStrictEqual([]);
|
||||
});
|
||||
|
||||
it("should skip http: protocol dependencies", async() => {
|
||||
expect.assertions(1);
|
||||
const mockNpmService = createMockNpmService();
|
||||
const { DependencyAnalyzerService }
|
||||
= await import("../../src/services/dependencyAnalyzerService.js");
|
||||
const analyzerService = new DependencyAnalyzerService(
|
||||
mockNpmService as Parameters<typeof DependencyAnalyzerService>[0],
|
||||
);
|
||||
const result = await analyzerService.analyzePackageJson({
|
||||
dependencies: {
|
||||
"http-package": "http://example.com/package.tgz",
|
||||
},
|
||||
});
|
||||
expect(result).toStrictEqual([]);
|
||||
});
|
||||
|
||||
it("should skip https: protocol dependencies", async() => {
|
||||
expect.assertions(1);
|
||||
const mockNpmService = createMockNpmService();
|
||||
const { DependencyAnalyzerService }
|
||||
= await import("../../src/services/dependencyAnalyzerService.js");
|
||||
const analyzerService = new DependencyAnalyzerService(
|
||||
mockNpmService as Parameters<typeof DependencyAnalyzerService>[0],
|
||||
);
|
||||
const result = await analyzerService.analyzePackageJson({
|
||||
dependencies: {
|
||||
"https-package": "https://example.com/package.tgz",
|
||||
},
|
||||
});
|
||||
expect(result).toStrictEqual([]);
|
||||
});
|
||||
|
||||
it("should skip github: shorthand dependencies", async() => {
|
||||
expect.assertions(1);
|
||||
const mockNpmService = createMockNpmService();
|
||||
const { DependencyAnalyzerService }
|
||||
= await import("../../src/services/dependencyAnalyzerService.js");
|
||||
const analyzerService = new DependencyAnalyzerService(
|
||||
mockNpmService as Parameters<typeof DependencyAnalyzerService>[0],
|
||||
);
|
||||
const result = await analyzerService.analyzePackageJson({
|
||||
dependencies: {
|
||||
"github-package": "github:user/repo",
|
||||
},
|
||||
});
|
||||
expect(result).toStrictEqual([]);
|
||||
});
|
||||
|
||||
it("should skip * version dependencies", async() => {
|
||||
expect.assertions(1);
|
||||
const mockNpmService = createMockNpmService();
|
||||
const { DependencyAnalyzerService }
|
||||
= await import("../../src/services/dependencyAnalyzerService.js");
|
||||
const analyzerService = new DependencyAnalyzerService(
|
||||
mockNpmService as Parameters<typeof DependencyAnalyzerService>[0],
|
||||
);
|
||||
const result = await analyzerService.analyzePackageJson({
|
||||
dependencies: {
|
||||
"star-package": "*",
|
||||
},
|
||||
});
|
||||
expect(result).toStrictEqual([]);
|
||||
});
|
||||
|
||||
it("should skip latest version dependencies", async() => {
|
||||
expect.assertions(1);
|
||||
const mockNpmService = createMockNpmService();
|
||||
const { DependencyAnalyzerService }
|
||||
= await import("../../src/services/dependencyAnalyzerService.js");
|
||||
const analyzerService = new DependencyAnalyzerService(
|
||||
mockNpmService as Parameters<typeof DependencyAnalyzerService>[0],
|
||||
);
|
||||
const result = await analyzerService.analyzePackageJson({
|
||||
dependencies: {
|
||||
"latest-package": "latest",
|
||||
},
|
||||
});
|
||||
expect(result).toStrictEqual([]);
|
||||
});
|
||||
|
||||
it("should not include packages that are already up-to-date", async() => {
|
||||
expect.assertions(1);
|
||||
const mockNpmService = createMockNpmService();
|
||||
mockNpmService.getPackageInfo.mockResolvedValue({
|
||||
"dist-tags": { latest: "1.0.0" },
|
||||
"name": "test-package",
|
||||
"versions": {},
|
||||
});
|
||||
const { DependencyAnalyzerService }
|
||||
= await import("../../src/services/dependencyAnalyzerService.js");
|
||||
const analyzerService = new DependencyAnalyzerService(
|
||||
mockNpmService as Parameters<typeof DependencyAnalyzerService>[0],
|
||||
);
|
||||
const result = await analyzerService.analyzePackageJson({
|
||||
dependencies: {
|
||||
"test-package": "1.0.0",
|
||||
},
|
||||
});
|
||||
expect(result).toStrictEqual([]);
|
||||
});
|
||||
|
||||
it("should handle packages not found on npm", async() => {
|
||||
expect.assertions(1);
|
||||
const mockNpmService = createMockNpmService();
|
||||
mockNpmService.getPackageInfo.mockResolvedValue(null);
|
||||
const { DependencyAnalyzerService }
|
||||
= await import("../../src/services/dependencyAnalyzerService.js");
|
||||
const analyzerService = new DependencyAnalyzerService(
|
||||
mockNpmService as Parameters<typeof DependencyAnalyzerService>[0],
|
||||
);
|
||||
const result = await analyzerService.analyzePackageJson({
|
||||
dependencies: {
|
||||
"non-existent": "1.0.0",
|
||||
},
|
||||
});
|
||||
expect(result).toStrictEqual([]);
|
||||
});
|
||||
|
||||
it("should handle version prefixes like ^", async() => {
|
||||
expect.assertions(2);
|
||||
const mockNpmService = createMockNpmService();
|
||||
mockNpmService.getPackageInfo.mockResolvedValue({
|
||||
"dist-tags": { latest: "2.0.0" },
|
||||
"name": "test-package",
|
||||
"versions": {},
|
||||
});
|
||||
const { DependencyAnalyzerService }
|
||||
= await import("../../src/services/dependencyAnalyzerService.js");
|
||||
const analyzerService = new DependencyAnalyzerService(
|
||||
mockNpmService as Parameters<typeof DependencyAnalyzerService>[0],
|
||||
);
|
||||
const result = await analyzerService.analyzePackageJson({
|
||||
dependencies: {
|
||||
"test-package": "^1.0.0",
|
||||
},
|
||||
});
|
||||
expect(result).toHaveLength(1);
|
||||
expect(result[0]?.currentVersion).toBe("^1.0.0");
|
||||
});
|
||||
|
||||
it("should handle npm errors gracefully", async() => {
|
||||
expect.assertions(1);
|
||||
const mockNpmService = createMockNpmService();
|
||||
mockNpmService.getPackageInfo.mockRejectedValue(new Error("Network error"));
|
||||
const { DependencyAnalyzerService }
|
||||
= await import("../../src/services/dependencyAnalyzerService.js");
|
||||
const analyzerService = new DependencyAnalyzerService(
|
||||
mockNpmService as Parameters<typeof DependencyAnalyzerService>[0],
|
||||
);
|
||||
const result = await analyzerService.analyzePackageJson({
|
||||
dependencies: {
|
||||
"test-package": "1.0.0",
|
||||
},
|
||||
});
|
||||
expect(result).toStrictEqual([]);
|
||||
});
|
||||
|
||||
it("should handle semver comparison errors", async() => {
|
||||
expect.assertions(1);
|
||||
const mockNpmService = createMockNpmService();
|
||||
mockNpmService.getPackageInfo.mockResolvedValue({
|
||||
"dist-tags": { latest: "invalid-version" },
|
||||
"name": "test-package",
|
||||
"versions": {},
|
||||
});
|
||||
const { DependencyAnalyzerService }
|
||||
= await import("../../src/services/dependencyAnalyzerService.js");
|
||||
const analyzerService = new DependencyAnalyzerService(
|
||||
mockNpmService as Parameters<typeof DependencyAnalyzerService>[0],
|
||||
);
|
||||
const result = await analyzerService.analyzePackageJson({
|
||||
dependencies: {
|
||||
"test-package": "also-invalid",
|
||||
},
|
||||
});
|
||||
expect(result).toStrictEqual([]);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user