mirror of
https://github.com/Kir-Antipov/mc-publish.git
synced 2024-11-26 10:20:58 -05:00
Covered ModMetadataReader with tests
This commit is contained in:
parent
ac79549091
commit
7cc4b5d26f
5 changed files with 321 additions and 1 deletions
24
package-lock.json
generated
24
package-lock.json
generated
|
@ -1788,6 +1788,15 @@
|
||||||
"integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==",
|
"integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"@types/yazl": {
|
||||||
|
"version": "2.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/yazl/-/yazl-2.4.2.tgz",
|
||||||
|
"integrity": "sha512-T+9JH8O2guEjXNxqmybzQ92mJUh2oCwDDMSSimZSe1P+pceZiFROZLYmcbqkzV5EUwz6VwcKXCO2S2yUpra6XQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@types/node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@typescript-eslint/eslint-plugin": {
|
"@typescript-eslint/eslint-plugin": {
|
||||||
"version": "4.32.0",
|
"version": "4.32.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.32.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.32.0.tgz",
|
||||||
|
@ -2201,6 +2210,12 @@
|
||||||
"node-int64": "^0.4.0"
|
"node-int64": "^0.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"buffer-crc32": {
|
||||||
|
"version": "0.2.13",
|
||||||
|
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
|
||||||
|
"integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"buffer-from": {
|
"buffer-from": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
||||||
|
@ -5165,6 +5180,15 @@
|
||||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
|
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
|
||||||
"integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
|
"integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
|
||||||
"dev": true
|
"dev": true
|
||||||
|
},
|
||||||
|
"yazl": {
|
||||||
|
"version": "2.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz",
|
||||||
|
"integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"buffer-crc32": "~0.2.3"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,13 +30,15 @@
|
||||||
"@babel/preset-env": "^7.15.6",
|
"@babel/preset-env": "^7.15.6",
|
||||||
"@babel/preset-typescript": "^7.15.0",
|
"@babel/preset-typescript": "^7.15.0",
|
||||||
"@types/node": "^16.10.2",
|
"@types/node": "^16.10.2",
|
||||||
|
"@types/yazl": "^2.4.2",
|
||||||
"@typescript-eslint/eslint-plugin": "^4.32.0",
|
"@typescript-eslint/eslint-plugin": "^4.32.0",
|
||||||
"@typescript-eslint/parser": "^4.32.0",
|
"@typescript-eslint/parser": "^4.32.0",
|
||||||
"@vercel/ncc": "^0.31.1",
|
"@vercel/ncc": "^0.31.1",
|
||||||
"babel-jest": "^27.2.4",
|
"babel-jest": "^27.2.4",
|
||||||
"eslint": "^7.32.0",
|
"eslint": "^7.32.0",
|
||||||
"jest": "^27.2.4",
|
"jest": "^27.2.4",
|
||||||
"typescript": "^4.4.3"
|
"typescript": "^4.4.3",
|
||||||
|
"yazl": "^2.5.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^1.6.0",
|
"@actions/core": "^1.6.0",
|
||||||
|
|
73
test/content/fabric.mod.json
Normal file
73
test/content/fabric.mod.json
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
{
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"id": "example-mod",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"name": "Example Mod",
|
||||||
|
"description": "Description",
|
||||||
|
"authors": [
|
||||||
|
"Author"
|
||||||
|
],
|
||||||
|
"contact": {
|
||||||
|
"homepage": "https://github.com/",
|
||||||
|
"sources": "https://github.com/"
|
||||||
|
},
|
||||||
|
"license": "MIT",
|
||||||
|
"icon": "assets/example-mod/icon.png",
|
||||||
|
"environment": "*",
|
||||||
|
"entrypoints": {
|
||||||
|
"main": [
|
||||||
|
"example.ExampleMod"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"mixins": [
|
||||||
|
"example-mod.mixins.json"
|
||||||
|
],
|
||||||
|
|
||||||
|
"projects": {
|
||||||
|
"modrinth": "AANobbMI"
|
||||||
|
},
|
||||||
|
"custom": {
|
||||||
|
"projects": {
|
||||||
|
"curseforge": 394468
|
||||||
|
},
|
||||||
|
"mc-publish": {
|
||||||
|
"github": "mc1.18-0.4.0-alpha5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"depends": {
|
||||||
|
"fabricloader": ">=0.11.3",
|
||||||
|
"fabric": "*",
|
||||||
|
"minecraft": "1.17.x",
|
||||||
|
"java": ">=16"
|
||||||
|
},
|
||||||
|
"recommends": {
|
||||||
|
"recommended-mod": {
|
||||||
|
"version": "0.2.0",
|
||||||
|
"projects": {
|
||||||
|
"modrinth": "AAAA"
|
||||||
|
},
|
||||||
|
"custom": {
|
||||||
|
"projects": {
|
||||||
|
"curseforge": 42
|
||||||
|
},
|
||||||
|
"mc-publish": {
|
||||||
|
"github": "v0.2.0",
|
||||||
|
"ignore": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"includes": {
|
||||||
|
"included-mod": "*"
|
||||||
|
},
|
||||||
|
"suggests": {
|
||||||
|
"suggested-mod": "*"
|
||||||
|
},
|
||||||
|
"conflicts": {
|
||||||
|
"conflicting-mod": "*"
|
||||||
|
},
|
||||||
|
"breaks": {
|
||||||
|
"breaking-mod": "*"
|
||||||
|
}
|
||||||
|
}
|
65
test/content/mods.toml
Normal file
65
test/content/mods.toml
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
modLoader="javafml"
|
||||||
|
loaderVersion="[34,)"
|
||||||
|
issueTrackerURL="https://github.com/"
|
||||||
|
displayURL="https://github.com/"
|
||||||
|
authors="Author"
|
||||||
|
license="MIT"
|
||||||
|
|
||||||
|
[[mods]]
|
||||||
|
modId="example-mod"
|
||||||
|
version="0.1.0"
|
||||||
|
displayName="Example Mod"
|
||||||
|
description='''
|
||||||
|
Example mod
|
||||||
|
'''
|
||||||
|
|
||||||
|
[projects]
|
||||||
|
modrinth="AANobbMI"
|
||||||
|
[custom.projects]
|
||||||
|
curseforge=394468
|
||||||
|
[custom.mc-publish]
|
||||||
|
github="mc1.18-0.4.0-alpha5"
|
||||||
|
|
||||||
|
[[dependencies.example-mod]]
|
||||||
|
modId="minecraft"
|
||||||
|
mandatory=true
|
||||||
|
versionRange="[1.17, 1.18)"
|
||||||
|
side="BOTH"
|
||||||
|
|
||||||
|
[[dependencies.example-mod]]
|
||||||
|
modId="forge"
|
||||||
|
mandatory=true
|
||||||
|
versionRange="[34,)"
|
||||||
|
ordering="NONE"
|
||||||
|
side="BOTH"
|
||||||
|
|
||||||
|
[[dependencies.example-mod]]
|
||||||
|
modId="recommended-mod"
|
||||||
|
mandatory=false
|
||||||
|
versionRange="0.2.0"
|
||||||
|
ordering="NONE"
|
||||||
|
side="BOTH"
|
||||||
|
[dependencies.example-mod.projects]
|
||||||
|
modrinth="AAAA"
|
||||||
|
[dependencies.example-mod.custom.projects]
|
||||||
|
curseforge=42
|
||||||
|
[dependencies.example-mod.custom.mc-publish]
|
||||||
|
github="v0.2.0"
|
||||||
|
ignore=true
|
||||||
|
|
||||||
|
|
||||||
|
[[dependencies.example-mod]]
|
||||||
|
modId="included-mod"
|
||||||
|
mandatory=false
|
||||||
|
embedded=true
|
||||||
|
versionRange="*"
|
||||||
|
ordering="NONE"
|
||||||
|
side="BOTH"
|
||||||
|
|
||||||
|
[[dependencies.example-mod]]
|
||||||
|
modId="breaking-mod"
|
||||||
|
mandatory=false
|
||||||
|
incompatible=true
|
||||||
|
versionRange="*"
|
||||||
|
ordering="NONE"
|
||||||
|
side="BOTH"
|
156
test/mod-metadata-reader.test.ts
Normal file
156
test/mod-metadata-reader.test.ts
Normal file
|
@ -0,0 +1,156 @@
|
||||||
|
import { describe, test, expect, beforeAll, afterAll } from "@jest/globals";
|
||||||
|
import Dependency from "../src/metadata/dependency";
|
||||||
|
import DependencyKind from "../src/metadata/dependency-kind";
|
||||||
|
import ModMetadataReader from "../src/metadata/mod-metadata-reader";
|
||||||
|
import PublisherTarget from "../src/publishing/publisher-target";
|
||||||
|
import { ZipFile } from "yazl";
|
||||||
|
import fs from "fs";
|
||||||
|
|
||||||
|
describe("ModMetadataReader.readMetadata", () => {
|
||||||
|
describe("Fabric", () => {
|
||||||
|
beforeAll(() => new Promise(resolve => {
|
||||||
|
const zip = new ZipFile();
|
||||||
|
zip.addFile("./test/content/fabric.mod.json", "fabric.mod.json");
|
||||||
|
zip.end();
|
||||||
|
zip.outputStream.pipe(fs.createWriteStream("example-mod.fabric.jar")).on("close", resolve);
|
||||||
|
}));
|
||||||
|
|
||||||
|
afterAll(() => new Promise(resolve => fs.unlink("example-mod.fabric.jar", resolve)));
|
||||||
|
|
||||||
|
test("the format can be read", async () => {
|
||||||
|
const metadata = await ModMetadataReader.readMetadata("example-mod.fabric.jar");
|
||||||
|
expect(metadata).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("mod info can be read", async () => {
|
||||||
|
const metadata = await ModMetadataReader.readMetadata("example-mod.fabric.jar");
|
||||||
|
expect(metadata.id).toBe("example-mod");
|
||||||
|
expect(metadata.name).toBe("Example Mod");
|
||||||
|
expect(metadata.version).toBe("0.1.0");
|
||||||
|
expect(metadata.loaders).toMatchObject(["fabric"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("project ids can be specified in the config file", async () => {
|
||||||
|
const metadata = await ModMetadataReader.readMetadata("example-mod.fabric.jar");
|
||||||
|
expect(metadata.getProjectId(PublisherTarget.Modrinth)).toBe("AANobbMI");
|
||||||
|
expect(metadata.getProjectId(PublisherTarget.CurseForge)).toBe("394468");
|
||||||
|
expect(metadata.getProjectId(PublisherTarget.GitHub)).toBe("mc1.18-0.4.0-alpha5");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("all dependencies are read", async () => {
|
||||||
|
const metadata = await ModMetadataReader.readMetadata("example-mod.fabric.jar");
|
||||||
|
expect(metadata.dependencies).toHaveLength(9);
|
||||||
|
const dependencies = metadata.dependencies.reduce((agg, x) => { agg[x.id] = x; return agg; }, <Record<string, Dependency>>{});
|
||||||
|
expect(dependencies["fabricloader"]?.kind).toBe(DependencyKind.Depends);
|
||||||
|
expect(dependencies["fabric"]?.kind).toBe(DependencyKind.Depends);
|
||||||
|
expect(dependencies["minecraft"]?.kind).toBe(DependencyKind.Depends);
|
||||||
|
expect(dependencies["java"]?.kind).toBe(DependencyKind.Depends);
|
||||||
|
expect(dependencies["recommended-mod"]?.kind).toBe(DependencyKind.Recommends);
|
||||||
|
expect(dependencies["included-mod"]?.kind).toBe(DependencyKind.Includes);
|
||||||
|
expect(dependencies["suggested-mod"]?.kind).toBe(DependencyKind.Suggests);
|
||||||
|
expect(dependencies["conflicting-mod"]?.kind).toBe(DependencyKind.Conflicts);
|
||||||
|
expect(dependencies["breaking-mod"]?.kind).toBe(DependencyKind.Breaks);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("dependency info can be read", async () => {
|
||||||
|
const metadata = await ModMetadataReader.readMetadata("example-mod.fabric.jar");
|
||||||
|
const minecraft = metadata.dependencies.find(x => x.id === "minecraft");
|
||||||
|
expect(minecraft).toBeTruthy();
|
||||||
|
expect(minecraft.id).toBe("minecraft");
|
||||||
|
expect(minecraft.kind).toBe(DependencyKind.Depends);
|
||||||
|
expect(minecraft.version).toBe("1.17.x");
|
||||||
|
expect(minecraft.ignore).toBe(false);
|
||||||
|
for (const project of PublisherTarget.getValues()) {
|
||||||
|
expect(minecraft.getProjectSlug(project)).toBe(minecraft.id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test("custom metadata can be attached to dependency entry", async () => {
|
||||||
|
const metadata = await ModMetadataReader.readMetadata("example-mod.fabric.jar");
|
||||||
|
const recommended = metadata.dependencies.find(x => x.id === "recommended-mod");
|
||||||
|
expect(recommended).toBeTruthy();
|
||||||
|
expect(recommended.id).toBe("recommended-mod");
|
||||||
|
expect(recommended.kind).toBe(DependencyKind.Recommends);
|
||||||
|
expect(recommended.version).toBe("0.2.0");
|
||||||
|
expect(recommended.ignore).toBe(true);
|
||||||
|
expect(recommended.getProjectSlug(PublisherTarget.Modrinth)).toBe("AAAA");
|
||||||
|
expect(recommended.getProjectSlug(PublisherTarget.CurseForge)).toBe("42");
|
||||||
|
expect(recommended.getProjectSlug(PublisherTarget.GitHub)).toBe("v0.2.0");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("Forge", () => {
|
||||||
|
beforeAll(() => new Promise(resolve => {
|
||||||
|
const zip = new ZipFile();
|
||||||
|
zip.addFile("./test/content/mods.toml", "META-INF/mods.toml");
|
||||||
|
zip.end();
|
||||||
|
zip.outputStream.pipe(fs.createWriteStream("example-mod.forge.jar")).on("close", resolve);
|
||||||
|
}));
|
||||||
|
|
||||||
|
afterAll(() => new Promise(resolve => fs.unlink("example-mod.forge.jar", resolve)));
|
||||||
|
|
||||||
|
test("the format can be read", async () => {
|
||||||
|
const metadata = await ModMetadataReader.readMetadata("example-mod.forge.jar");
|
||||||
|
expect(metadata).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("mod info can be read", async () => {
|
||||||
|
const metadata = await ModMetadataReader.readMetadata("example-mod.forge.jar");
|
||||||
|
expect(metadata.id).toBe("example-mod");
|
||||||
|
expect(metadata.name).toBe("Example Mod");
|
||||||
|
expect(metadata.version).toBe("0.1.0");
|
||||||
|
expect(metadata.loaders).toMatchObject(["forge"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("project ids can be specified in the config file", async () => {
|
||||||
|
const metadata = await ModMetadataReader.readMetadata("example-mod.forge.jar");
|
||||||
|
expect(metadata.getProjectId(PublisherTarget.Modrinth)).toBe("AANobbMI");
|
||||||
|
expect(metadata.getProjectId(PublisherTarget.CurseForge)).toBe("394468");
|
||||||
|
expect(metadata.getProjectId(PublisherTarget.GitHub)).toBe("mc1.18-0.4.0-alpha5");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("all dependencies are read", async () => {
|
||||||
|
const metadata = await ModMetadataReader.readMetadata("example-mod.forge.jar");
|
||||||
|
expect(metadata.dependencies).toHaveLength(5);
|
||||||
|
const dependencies = metadata.dependencies.reduce((agg, x) => { agg[x.id] = x; return agg; }, <Record<string, Dependency>>{});
|
||||||
|
expect(dependencies["forge"]?.kind).toBe(DependencyKind.Depends);
|
||||||
|
expect(dependencies["minecraft"]?.kind).toBe(DependencyKind.Depends);
|
||||||
|
expect(dependencies["recommended-mod"]?.kind).toBe(DependencyKind.Recommends);
|
||||||
|
expect(dependencies["included-mod"]?.kind).toBe(DependencyKind.Includes);
|
||||||
|
expect(dependencies["breaking-mod"]?.kind).toBe(DependencyKind.Breaks);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("dependency info can be read", async () => {
|
||||||
|
const metadata = await ModMetadataReader.readMetadata("example-mod.forge.jar");
|
||||||
|
const minecraft = metadata.dependencies.find(x => x.id === "minecraft");
|
||||||
|
expect(minecraft).toBeTruthy();
|
||||||
|
expect(minecraft.id).toBe("minecraft");
|
||||||
|
expect(minecraft.kind).toBe(DependencyKind.Depends);
|
||||||
|
expect(minecraft.version).toBe("[1.17, 1.18)");
|
||||||
|
expect(minecraft.ignore).toBe(false);
|
||||||
|
for (const project of PublisherTarget.getValues()) {
|
||||||
|
expect(minecraft.getProjectSlug(project)).toBe(minecraft.id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test("custom metadata can be attached to dependency entry", async () => {
|
||||||
|
const metadata = await ModMetadataReader.readMetadata("example-mod.forge.jar");
|
||||||
|
const recommended = metadata.dependencies.find(x => x.id === "recommended-mod");
|
||||||
|
expect(recommended).toBeTruthy();
|
||||||
|
expect(recommended.id).toBe("recommended-mod");
|
||||||
|
expect(recommended.kind).toBe(DependencyKind.Recommends);
|
||||||
|
expect(recommended.version).toBe("0.2.0");
|
||||||
|
expect(recommended.ignore).toBe(true);
|
||||||
|
expect(recommended.getProjectSlug(PublisherTarget.Modrinth)).toBe("AAAA");
|
||||||
|
expect(recommended.getProjectSlug(PublisherTarget.CurseForge)).toBe("42");
|
||||||
|
expect(recommended.getProjectSlug(PublisherTarget.GitHub)).toBe("v0.2.0");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("unsupported mod formats", () => {
|
||||||
|
test("null is returned when the format is not supported or specified file does not exist", async () => {
|
||||||
|
const metadata = await ModMetadataReader.readMetadata("example-mod.unknown.jar");
|
||||||
|
expect(metadata).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in a new issue