mirror of
https://gitee.com/spark-store-project/spark-store
synced 2026-04-26 01:10:16 +08:00
299 lines
7.6 KiB
TypeScript
299 lines
7.6 KiB
TypeScript
import { describe, expect, it, vi } from "vitest";
|
|
|
|
import {
|
|
buildInstalledSourceMap,
|
|
mergeUpdateSources,
|
|
parseApmUpgradableOutput,
|
|
parseAptssUpgradableOutput,
|
|
parsePrintUrisOutput,
|
|
} from "../../../../electron/main/backend/update-center/query";
|
|
|
|
describe("update-center query", () => {
|
|
it("parses aptss upgradable output into normalized aptss items", () => {
|
|
const output = [
|
|
"Listing...",
|
|
"spark-weather/stable 2.0.0 amd64 [upgradable from: 1.9.0]",
|
|
"spark-same/stable 1.0.0 amd64 [upgradable from: 1.0.0]",
|
|
"",
|
|
].join("\n");
|
|
|
|
expect(parseAptssUpgradableOutput(output)).toEqual([
|
|
{
|
|
pkgname: "spark-weather",
|
|
source: "aptss",
|
|
currentVersion: "1.9.0",
|
|
nextVersion: "2.0.0",
|
|
arch: "amd64",
|
|
},
|
|
]);
|
|
});
|
|
|
|
it("parses the legacy from variant in upgradable output", () => {
|
|
const aptssOutput = "spark-clock/stable 1.2.0 amd64 [from: 1.1.0]";
|
|
const apmOutput = "spark-player/main 2.0.0 amd64 [from: 1.5.0]";
|
|
|
|
expect(parseAptssUpgradableOutput(aptssOutput)).toEqual([
|
|
{
|
|
pkgname: "spark-clock",
|
|
source: "aptss",
|
|
currentVersion: "1.1.0",
|
|
nextVersion: "1.2.0",
|
|
arch: "amd64",
|
|
},
|
|
]);
|
|
|
|
expect(parseApmUpgradableOutput(apmOutput)).toEqual([
|
|
{
|
|
pkgname: "spark-player",
|
|
source: "apm",
|
|
currentVersion: "1.5.0",
|
|
nextVersion: "2.0.0",
|
|
arch: "amd64",
|
|
},
|
|
]);
|
|
});
|
|
|
|
it("parses apt print-uris output into download metadata", () => {
|
|
const output =
|
|
"'https://example.invalid/pool/main/s/spark-weather_2.0.0_amd64.deb' spark-weather_2.0.0_amd64.deb 123456 SHA512:deadbeef";
|
|
|
|
expect(parsePrintUrisOutput(output)).toEqual({
|
|
downloadUrl:
|
|
"https://example.invalid/pool/main/s/spark-weather_2.0.0_amd64.deb",
|
|
fileName: "spark-weather_2.0.0_amd64.deb",
|
|
size: 123456,
|
|
sha512: "deadbeef",
|
|
});
|
|
});
|
|
|
|
it("marks an apm item as migration when the same package is only installed in aptss", () => {
|
|
const merged = mergeUpdateSources(
|
|
[
|
|
{
|
|
pkgname: "spark-weather",
|
|
source: "aptss",
|
|
currentVersion: "1.9.0",
|
|
nextVersion: "2.0.0",
|
|
},
|
|
],
|
|
[
|
|
{
|
|
pkgname: "spark-weather",
|
|
source: "apm",
|
|
currentVersion: "1.8.0",
|
|
nextVersion: "3.0.0",
|
|
},
|
|
],
|
|
new Map([["spark-weather", { aptss: true, apm: false }]]),
|
|
);
|
|
|
|
expect(merged).toEqual([
|
|
{
|
|
pkgname: "spark-weather",
|
|
source: "apm",
|
|
currentVersion: "1.8.0",
|
|
nextVersion: "3.0.0",
|
|
isMigration: true,
|
|
migrationSource: "aptss",
|
|
migrationTarget: "apm",
|
|
aptssVersion: "2.0.0",
|
|
},
|
|
{
|
|
pkgname: "spark-weather",
|
|
source: "aptss",
|
|
currentVersion: "1.9.0",
|
|
nextVersion: "2.0.0",
|
|
},
|
|
]);
|
|
});
|
|
|
|
it("uses Debian-style version ordering for migration decisions", () => {
|
|
const merged = mergeUpdateSources(
|
|
[
|
|
{
|
|
pkgname: "spark-browser",
|
|
source: "aptss",
|
|
currentVersion: "9.0",
|
|
nextVersion: "10.0",
|
|
},
|
|
],
|
|
[
|
|
{
|
|
pkgname: "spark-browser",
|
|
source: "apm",
|
|
currentVersion: "1:0.9",
|
|
nextVersion: "2:1.0",
|
|
},
|
|
],
|
|
new Map([["spark-browser", { aptss: true, apm: false }]]),
|
|
);
|
|
|
|
expect(merged[0]).toMatchObject({
|
|
pkgname: "spark-browser",
|
|
source: "apm",
|
|
isMigration: true,
|
|
aptssVersion: "10.0",
|
|
});
|
|
expect(merged[1]).toMatchObject({
|
|
pkgname: "spark-browser",
|
|
source: "aptss",
|
|
nextVersion: "10.0",
|
|
});
|
|
});
|
|
|
|
it("uses Debian epoch ordering in the fallback when dpkg is unavailable", async () => {
|
|
vi.resetModules();
|
|
vi.doMock("node:child_process", async (importOriginal) => {
|
|
const actual =
|
|
await importOriginal<typeof import("node:child_process")>();
|
|
|
|
return {
|
|
...actual,
|
|
default: actual,
|
|
spawnSync: vi.fn(() => ({
|
|
status: null,
|
|
error: new Error("dpkg unavailable"),
|
|
output: null,
|
|
pid: 0,
|
|
signal: null,
|
|
stdout: Buffer.alloc(0),
|
|
stderr: Buffer.alloc(0),
|
|
})),
|
|
};
|
|
});
|
|
|
|
const { mergeUpdateSources: mergeWithFallback } =
|
|
await import("../../../../electron/main/backend/update-center/query");
|
|
|
|
const merged = mergeWithFallback(
|
|
[
|
|
{
|
|
pkgname: "spark-reader",
|
|
source: "aptss",
|
|
currentVersion: "2.5.0",
|
|
nextVersion: "2.9.0",
|
|
},
|
|
],
|
|
[
|
|
{
|
|
pkgname: "spark-reader",
|
|
source: "apm",
|
|
currentVersion: "2.0.0",
|
|
nextVersion: "3.0.0",
|
|
},
|
|
],
|
|
new Map([["spark-reader", { aptss: true, apm: false }]]),
|
|
);
|
|
|
|
expect(merged[0]).toMatchObject({
|
|
pkgname: "spark-reader",
|
|
source: "apm",
|
|
isMigration: true,
|
|
aptssVersion: "2.9.0",
|
|
});
|
|
|
|
vi.doUnmock("node:child_process");
|
|
vi.resetModules();
|
|
});
|
|
|
|
it("uses Debian tilde ordering in the fallback when dpkg is unavailable", async () => {
|
|
vi.resetModules();
|
|
vi.doMock("node:child_process", async (importOriginal) => {
|
|
const actual =
|
|
await importOriginal<typeof import("node:child_process")>();
|
|
|
|
return {
|
|
...actual,
|
|
default: actual,
|
|
spawnSync: vi.fn(() => ({
|
|
status: null,
|
|
error: new Error("dpkg unavailable"),
|
|
output: null,
|
|
pid: 0,
|
|
signal: null,
|
|
stdout: Buffer.alloc(0),
|
|
stderr: Buffer.alloc(0),
|
|
})),
|
|
};
|
|
});
|
|
|
|
const { mergeUpdateSources: mergeWithFallback } =
|
|
await import("../../../../electron/main/backend/update-center/query");
|
|
|
|
const merged = mergeWithFallback(
|
|
[
|
|
{
|
|
pkgname: "spark-tilde",
|
|
source: "aptss",
|
|
currentVersion: "0.9",
|
|
nextVersion: "1.0~rc1",
|
|
},
|
|
],
|
|
[
|
|
{
|
|
pkgname: "spark-tilde",
|
|
source: "apm",
|
|
currentVersion: "0.9",
|
|
nextVersion: "1.0",
|
|
},
|
|
],
|
|
new Map([["spark-tilde", { aptss: true, apm: false }]]),
|
|
);
|
|
|
|
expect(merged[0]).toMatchObject({
|
|
pkgname: "spark-tilde",
|
|
source: "apm",
|
|
isMigration: true,
|
|
aptssVersion: "1.0~rc1",
|
|
});
|
|
|
|
vi.doUnmock("node:child_process");
|
|
vi.resetModules();
|
|
});
|
|
|
|
it("parses apm list output into normalized apm items", () => {
|
|
const output = [
|
|
"Listing...",
|
|
"spark-music/main 5.0.0 arm64 [upgradable from: 4.5.0]",
|
|
"spark-same/main 1.0.0 arm64 [upgradable from: 1.0.0]",
|
|
"",
|
|
].join("\n");
|
|
|
|
expect(parseApmUpgradableOutput(output)).toEqual([
|
|
{
|
|
pkgname: "spark-music",
|
|
source: "apm",
|
|
currentVersion: "4.5.0",
|
|
nextVersion: "5.0.0",
|
|
arch: "arm64",
|
|
},
|
|
]);
|
|
});
|
|
|
|
it("builds installed-source map from dpkg-query and apm list output", () => {
|
|
const dpkgOutput = [
|
|
"spark-weather\tinstall ok installed",
|
|
"spark-weather-data\tdeinstall ok config-files",
|
|
"spark-notes\tinstall ok installed",
|
|
"",
|
|
].join("\n");
|
|
|
|
const apmInstalledOutput = [
|
|
"Listing...",
|
|
"spark-weather/main,stable 3.0.0 amd64 [installed]",
|
|
"spark-player/main 1.0.0 amd64 [installed,automatic]",
|
|
"",
|
|
].join("\n");
|
|
|
|
expect(
|
|
Array.from(
|
|
buildInstalledSourceMap(dpkgOutput, apmInstalledOutput).entries(),
|
|
),
|
|
).toEqual([
|
|
["spark-weather", { aptss: true, apm: true }],
|
|
["spark-notes", { aptss: true, apm: false }],
|
|
["spark-player", { aptss: false, apm: true }],
|
|
]);
|
|
});
|
|
});
|