Deleted old test suites

This commit is contained in:
Kir_Antipov 2022-11-30 09:09:15 +00:00
parent fc1a2a044b
commit 9ad1412834
20 changed files with 0 additions and 1604 deletions

View file

@ -1,72 +0,0 @@
{
"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"
],
"custom": {
"modmanager": {
"modrinth": "AANobbMI"
},
"projects": {
"curseforge": 394468
},
"mc-publish": {
"github": "mc1.18-0.4.0-alpha5"
}
},
"depends": {
"fabricloader": ">=0.11.3",
"fabric": ">=0.40.0",
"minecraft": [
"1.17",
"1.17.1"
],
"java": ">=16"
},
"recommends": {
"recommended-mod": {
"version": "0.2.0",
"custom": {
"mc-publish": {
"modrinth": "AAAA",
"curseforge": 42,
"github": "v0.2.0",
"ignore": true
}
}
}
},
"includes": {
"included-mod": "*"
},
"suggests": {
"suggested-mod": "*"
},
"conflicts": {
"conflicting-mod": "<0.40.0"
},
"breaks": {
"breaking-mod": "*"
}
}

View file

@ -1,71 +0,0 @@
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
'''
[mc-publish]
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="java"
mandatory=true
versionRange="[16,)"
ordering="NONE"
side="BOTH"
[[dependencies.example-mod]]
modId="recommended-mod"
mandatory=false
versionRange="0.2.0"
ordering="NONE"
side="BOTH"
[dependencies.example-mod.mc-publish]
modrinth="AAAA"
curseforge=42
ignore=true
[dependencies.example-mod.custom.mc-publish]
github="v0.2.0"
[[dependencies.example-mod]]
modId="included-mod"
mandatory=false
embedded=true
versionRange="[0.40.0, )"
ordering="NONE"
side="BOTH"
[[dependencies.example-mod]]
modId="breaking-mod"
mandatory=false
incompatible=true
versionRange="*"
ordering="NONE"
side="BOTH"

View file

@ -1,82 +0,0 @@
{
"schema_version": 1,
"quilt_loader": {
"group": "com.example",
"id": "example-mod",
"version": "0.1.0",
"name": "Example Mod",
"description": "Description",
"authors": [
"Author"
],
"contact": {
"homepage": "https://github.com/",
"sources": "https://github.com/",
"issues": "https://github.com/",
"wiki": "https://github.com/"
},
"license": "MIT",
"icon": "icon.jpg",
"intermediate_mappings": "net.fabricmc:intermediary",
"environment": "*",
"entrypoints": {
"main": [
"example.ExampleMod"
]
},
"depends": [
{
"id": "quilt_loader",
"versions": ">=0.11.3"
},
{
"id": "quilt_base",
"versions": ">=0.40.0"
},
{
"id": "minecraft",
"versions": [
"1.17",
"1.17.1"
]
},
{
"id": "java",
"versions": ">=16"
},
{
"id": "recommended-mod",
"versions": "0.2.0",
"optional": true,
"mc-publish": {
"curseforge": 42,
"github": "v0.2.0",
"modrinth": "AAAA",
"ignore": true
}
}
],
"provides": [
"included:included-mod"
],
"breaks": [
"breaking-mod",
{
"id": "conflicting:conflicting-mod",
"versions": "<0.40.0",
"unless": "fix-conflicting-mod"
}
]
},
"mc-publish": {
"github": "mc1.18-0.4.0-alpha5",
"modrinth": "AANobbMI"
},
"projects": {
"curseforge": 394468
},
"mixins": [
"example-mod.mixins.json"
],
"access_widener": "example.accesswidener"
}

View file

@ -1,34 +0,0 @@
import { describe, test, expect } from "@jest/globals";
import DependencyKind from "../../../src/metadata/dependency-kind";
describe("DependencyKind.getValues", () => {
test("all DependencyKind values are returned", () => {
const kinds = DependencyKind.getValues();
expect(kinds).toHaveLength(6);
expect(kinds).toContain(DependencyKind.Depends);
expect(kinds).toContain(DependencyKind.Recommends);
expect(kinds).toContain(DependencyKind.Includes);
expect(kinds).toContain(DependencyKind.Suggests);
expect(kinds).toContain(DependencyKind.Conflicts);
expect(kinds).toContain(DependencyKind.Breaks);
});
});
describe("DependencyKind.parse", () => {
test("every DependencyKind can be parsed", () => {
for (const kind of DependencyKind.getValues()) {
expect(DependencyKind.parse(DependencyKind.toString(kind))).toStrictEqual(kind);
}
});
test("DependencyKind's name is case-insensitive", () => {
for (const kind of DependencyKind.getValues()) {
expect(DependencyKind.parse(DependencyKind.toString(kind).toLowerCase())).toStrictEqual(kind);
expect(DependencyKind.parse(DependencyKind.toString(kind).toUpperCase())).toStrictEqual(kind);
}
});
test("undefined is returned when the value cannot be parsed", () => {
expect(DependencyKind.parse("There's no such dependency kind")).toBeUndefined();
});
});

View file

@ -1,18 +0,0 @@
import { describe, test, expect } from "@jest/globals";
import ModLoaderType from "../../../src/metadata/mod-loader-type";
import ModMetadataReaderFactory from "../../../src/metadata/mod-metadata-reader-factory";
describe("ModMetadataReaderFactory.create", () => {
test("factory can create metadata reader for every ModLoaderType value", () => {
const factory = new ModMetadataReaderFactory();
for (const target of ModLoaderType.getValues()) {
const reader = factory.create(target);
expect(reader).toHaveProperty("readMetadata");
}
});
test("the method throws on invalid ModLoaderType value", () => {
const factory = new ModMetadataReaderFactory();
expect(() => factory.create(-1)).toThrow();
});
});

View file

@ -1,277 +0,0 @@
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/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"] as any);
});
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 conflicting = metadata.dependencies.find(x => x.id === "conflicting-mod")!;
expect(conflicting).toBeTruthy();
expect(conflicting.id).toBe("conflicting-mod");
expect(conflicting.kind).toBe(DependencyKind.Conflicts);
expect(conflicting.version).toBe("<0.40.0");
expect(conflicting.ignore).toBe(false);
for (const project of PublisherTarget.getValues()) {
expect(conflicting.getProjectSlug(project)).toBe(conflicting.id);
}
});
test("version array is supported", async () => {
const metadata = (await ModMetadataReader.readMetadata("example-mod.fabric.jar"))!;
const minecraft = metadata.dependencies.find(x => x.id === "minecraft");
expect(minecraft.version).toStrictEqual("1.17 || 1.17.1");
});
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");
});
test("special case dependencies (minecraft, java and fabricloader) are ignored by default", async () => {
const metadata = (await ModMetadataReader.readMetadata("example-mod.fabric.jar"))!;
expect(metadata.dependencies.find(x => x.id === "minecraft")!.ignore).toBe(true);
expect(metadata.dependencies.find(x => x.id === "java")!.ignore).toBe(true);
expect(metadata.dependencies.find(x => x.id === "fabricloader")!.ignore).toBe(true);
});
test("special case dependencies (fabric) are replaced with their aliases", async() => {
const metadata = (await ModMetadataReader.readMetadata("example-mod.fabric.jar"))!;
const fabric = metadata.dependencies.find(x => x.id === "fabric")!;
for (const target of PublisherTarget.getValues()) {
expect(fabric.getProjectSlug(target) === "fabric-api");
}
});
});
describe("Forge", () => {
beforeAll(() => new Promise(resolve => {
const zip = new ZipFile();
zip.addFile("./test/content/forge/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"] as any);
});
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(6);
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["java"]?.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 included = metadata.dependencies.find(x => x.id === "included-mod")!;
expect(included).toBeTruthy();
expect(included.id).toBe("included-mod");
expect(included.kind).toBe(DependencyKind.Includes);
expect(included.version).toBe("[0.40.0, )");
expect(included.ignore).toBe(false);
for (const project of PublisherTarget.getValues()) {
expect(included.getProjectSlug(project)).toBe(included.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");
});
test("special case dependencies (minecraft, java and forge) are ignored by default", async () => {
const metadata = (await ModMetadataReader.readMetadata("example-mod.forge.jar"))!;
expect(metadata.dependencies.find(x => x.id === "minecraft")!.ignore).toBe(true);
expect(metadata.dependencies.find(x => x.id === "java")!.ignore).toBe(true);
expect(metadata.dependencies.find(x => x.id === "forge")!.ignore).toBe(true);
});
});
describe("Quilt", () => {
beforeAll(() => new Promise(resolve => {
const zip = new ZipFile();
zip.addFile("./test/content/quilt/quilt.mod.json", "quilt.mod.json");
zip.end();
zip.outputStream.pipe(fs.createWriteStream("example-mod.quilt.jar")).on("close", resolve);
}));
afterAll(() => new Promise(resolve => fs.unlink("example-mod.quilt.jar", resolve)));
test("the format can be read", async () => {
const metadata = await ModMetadataReader.readMetadata("example-mod.quilt.jar");
expect(metadata).toBeTruthy();
});
test("mod info can be read", async () => {
const metadata = (await ModMetadataReader.readMetadata("example-mod.quilt.jar"))!;
expect(metadata.id).toBe("example-mod");
expect(metadata.name).toBe("Example Mod");
expect(metadata.version).toBe("0.1.0");
expect(metadata.loaders).toMatchObject(["quilt"] as any);
});
test("project ids can be specified in the config file", async () => {
const metadata = (await ModMetadataReader.readMetadata("example-mod.quilt.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.quilt.jar"))!;
expect(metadata.dependencies).toHaveLength(8);
const dependencies = metadata.dependencies.reduce((agg, x) => { agg[x.id] = x; return agg; }, <Record<string, Dependency>>{});
expect(dependencies["quilt_loader"]?.kind).toBe(DependencyKind.Depends);
expect(dependencies["quilt_base"]?.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["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.quilt.jar"))!;
const conflicting = metadata.dependencies.find(x => x.id === "conflicting-mod")!;
expect(conflicting).toBeTruthy();
expect(conflicting.id).toBe("conflicting-mod");
expect(conflicting.kind).toBe(DependencyKind.Conflicts);
expect(conflicting.version).toBe("<0.40.0");
expect(conflicting.ignore).toBe(false);
for (const project of PublisherTarget.getValues()) {
expect(conflicting.getProjectSlug(project)).toBe(conflicting.id);
}
});
test("version array is supported", async () => {
const metadata = (await ModMetadataReader.readMetadata("example-mod.quilt.jar"))!;
const minecraft = metadata.dependencies.find(x => x.id === "minecraft");
expect(minecraft.version).toStrictEqual("1.17 || 1.17.1");
});
test("custom metadata can be attached to dependency entry", async () => {
const metadata = (await ModMetadataReader.readMetadata("example-mod.quilt.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");
});
test("special case dependencies (minecraft, java and quilt_loader) are ignored by default", async () => {
const metadata = (await ModMetadataReader.readMetadata("example-mod.quilt.jar"))!;
expect(metadata.dependencies.find(x => x.id === "minecraft")!.ignore).toBe(true);
expect(metadata.dependencies.find(x => x.id === "java")!.ignore).toBe(true);
expect(metadata.dependencies.find(x => x.id === "quilt_loader")!.ignore).toBe(true);
});
test("special case dependencies (quilted_quilt_api) are replaced with their aliases", async() => {
const metadata = (await ModMetadataReader.readMetadata("example-mod.quilt.jar"))!;
const quilt = metadata.dependencies.find(x => x.id === "quilt_base")!;
for (const target of PublisherTarget.getValues()) {
expect(quilt.getProjectSlug(target) === "qsl");
}
});
});
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();
});
});
});

View file

@ -1,30 +0,0 @@
import { describe, test, expect } from "@jest/globals";
import PublisherFactory from "../../../src/publishing/publisher-factory";
import PublisherTarget from "../../../src/publishing/publisher-target";
import { getConsoleLogger } from "../../../src/utils/logging/logger";
describe("PublisherFactory.create", () => {
test("factory can create publisher for every PublisherTarget value", () => {
const factory = new PublisherFactory();
for (const target of PublisherTarget.getValues()) {
const logger = getConsoleLogger();
const publisher = factory.create(target, logger);
expect(publisher.target).toStrictEqual(target);
expect((publisher as any).logger).toStrictEqual(logger);
}
});
test("every publisher has logger object", () => {
const factory = new PublisherFactory();
for (const target of PublisherTarget.getValues()) {
const publisher = factory.create(target);
expect(publisher.target).toStrictEqual(target);
expect((publisher as any).logger).toBeTruthy();
}
});
test("the method throws on invalid PublisherTarget value", () => {
const factory = new PublisherFactory();
expect(() => factory.create(-1)).toThrow();
});
});

View file

@ -1,253 +0,0 @@
import { describe, test, expect, beforeAll, afterAll } from "@jest/globals";
import { setupInput, unsetInput } from "../../../utils/input-utils";
import { getInputAsObject, mapStringInput, mapObjectInput, mapNumberInput, mapBooleanInput, mapEnumInput } from "../../../../src/utils/actions/input";
const defaultInput = {
"boolean": true,
"object": { foo: "bar" },
"number": 1,
"array": ["foo", "bar"],
"undefined": "${undefined}",
"files-primary": "primaryPath",
"files-secondary": "secondaryPath",
"files-secondary-inner": "innerSecondaryPath",
"files": "path",
"modrinth-id": 42,
"modrinth-token": "1234",
"modrinth-files-primary": "primaryPath",
"modrinth-files-secondary": "secondaryPath",
"This is a Very--Long_Name!": "foo"
};
describe("getInputAsObject", () => {
beforeAll(() => setupInput(defaultInput));
afterAll(() => unsetInput());
test("input object contains only strings", () => {
const input = getInputAsObject();
expect(input).toHaveProperty("boolean", "true");
expect(input).toHaveProperty("object", {}.toString());
expect(input).not.toHaveProperty("object.foo");
expect(input).toHaveProperty("number", "1");
expect(input).toHaveProperty("array", ["foo", "bar"].toString());
});
test("property names are converted to paths inside of the input object (a-b -> a.b and aB)", () => {
const input = getInputAsObject();
expect(input).toHaveProperty("modrinth.id", "42");
expect(input).toHaveProperty("modrinthId", "42");
expect(input).toHaveProperty("modrinth.token", "1234");
expect(input).toHaveProperty("modrinthToken", "1234");
expect(input).toHaveProperty("modrinth.files.primary", "primaryPath");
expect(input).toHaveProperty("modrinth.filesPrimary", "primaryPath");
expect(input).toHaveProperty("modrinthFilesPrimary", "primaryPath");
expect(input).toHaveProperty("modrinth.files.secondary", "secondaryPath");
expect(input).toHaveProperty("modrinth.filesSecondary", "secondaryPath");
expect(input).toHaveProperty("modrinthFilesSecondary", "secondaryPath");
});
test("string values do not have additional properties", () => {
const input = getInputAsObject();
expect(input).toHaveProperty("files", "path");
expect(input).toHaveProperty("filesPrimary", "primaryPath");
expect(input).toHaveProperty("filesSecondary", "secondaryPath");
expect(input).toHaveProperty("filesSecondaryInner", "innerSecondaryPath");
expect(input).not.toHaveProperty("files.primary");
expect(input).not.toHaveProperty("files.secondary");
});
test("input object does not have empty property names", () => {
const input = getInputAsObject();
expect(input).toHaveProperty("this.is.a.very.long.name", "foo");
expect(input).toHaveProperty("thisIsAVeryLongName", "foo");
});
test("special case for GitHub Actions: ${undefined} transforms into undefined", () => {
const input = getInputAsObject();
expect(input.undefined).toBeUndefined();
});
});
describe("mapStringInput", () => {
beforeAll(() => setupInput(defaultInput));
afterAll(() => unsetInput());
test("returns default value if input is not a string", () => {
const input = getInputAsObject();
expect(input["undefined"]).toBeUndefined();
expect(mapStringInput(input["undefined"], "42")).toBe("42");
});
test("maps strings to string", () => {
const input = getInputAsObject();
expect(mapStringInput(input["boolean"], "")).toBe("true");
expect(mapStringInput(input["number"], "")).toBe("1");
expect(mapStringInput(input["object"])).toBe({}.toString());
});
});
describe("mapObjectInput", () => {
beforeAll(() => setupInput(defaultInput));
afterAll(() => unsetInput());
test("returns default value if input is not an object", () => {
const input = getInputAsObject();
expect(input["boolean"]).not.toBeUndefined();
expect(mapObjectInput(input["boolean"], null!)).toBeNull();
expect(input["number"]).not.toBeUndefined();
expect(mapObjectInput(input["number"], null!)).toBeNull()
expect(input["array"]).not.toBeUndefined();
expect(mapObjectInput(input["array"])).toBeNull()
expect(input["undefined"]).toBeUndefined();
expect(mapObjectInput(input["undefined"], { answer: 42 })).toStrictEqual({ answer: 42 });
});
test("maps object values to object", () => {
const input = getInputAsObject();
expect(mapObjectInput(input["modrinth"], null!)).toStrictEqual({ id: "42", token: "1234", filesPrimary: "primaryPath", filesSecondary: "secondaryPath", files: { primary: "primaryPath", secondary: "secondaryPath" } });
});
});
describe("mapNumberInput", () => {
beforeAll(() => setupInput({
...defaultInput,
numberOne: 1,
numberOneString: "1",
numberOneStringWithWhitespace: " 1 ",
}));
afterAll(() => unsetInput());
test("returns default value if input is not number or number-like", () => {
const input = getInputAsObject();
expect(input["boolean"]).not.toBeUndefined();
expect(mapNumberInput(input["boolean"], 0)).toBe(0);
expect(input["object"]).not.toBeUndefined();
expect(mapNumberInput(input["object"], 0)).toBe(0);
expect(input["array"]).not.toBeUndefined();
expect(mapNumberInput(input["array"], 0)).toBe(0);
expect(input["undefined"]).toBeUndefined();
expect(mapNumberInput(input["undefined"], 1)).toBe(1);
});
test("maps number and number-like values to number", () => {
const input = getInputAsObject();
expect(mapNumberInput(input["numberone"], 0)).toBe(1);
expect(mapNumberInput(input["numberonestring"], 0)).toBe(1);
expect(mapNumberInput(input["numberonestringwithwhitespace"])).toBe(1);
});
});
describe("mapBooleanInput", () => {
beforeAll(() => setupInput({
...defaultInput,
booleanTrue: true,
booleanTrueStringLowerCase: "true",
booleanTrueStringUpperCase: "TRUE",
booleanTrueStringUpperCaseWithWhitespace: " TRUE ",
booleanFalse: false,
booleanFalseStringLowerCase: "false",
booleanFalseStringUpperCase: "FALSE",
booleanFalseStringUpperCaseWithWhitespace: " FALSE ",
}));
afterAll(() => unsetInput());
test("returns default value if input is not boolean or boolean-like", () => {
const input = getInputAsObject();
expect(input["object"]).not.toBeUndefined();
expect(mapBooleanInput(input["object"], false)).toBe(false);
expect(input["number"]).not.toBeUndefined();
expect(mapBooleanInput(input["number"], false)).toBe(false);
expect(input["array"]).not.toBeUndefined();
expect(mapBooleanInput(input["array"], false)).toBe(false);
expect(input["undefined"]).toBeUndefined();
expect(mapBooleanInput(input["undefined"], true)).toBe(true);
});
test("maps boolean and boolean-like values to boolean", () => {
const input = getInputAsObject();
expect(mapBooleanInput(input["booleantrue"], false)).toBe(true);
expect(mapBooleanInput(input["booleantruestringlowercase"], false)).toBe(true);
expect(mapBooleanInput(input["booleantruestringuppercase"], false)).toBe(true);
expect(mapBooleanInput(input["booleantruestringuppercasewithwhitespace"])).toBe(true);
expect(mapBooleanInput(input["booleanfalse"], true)).toBe(false);
expect(mapBooleanInput(input["booleanfalsestringlowercase"], true)).toBe(false);
expect(mapBooleanInput(input["booleanfalsestringuppercase"], true)).toBe(false);
expect(mapBooleanInput(input["booleanfalsestringuppercasewithwhitespace"], true)).toBe(false);
});
});
describe("mapEnumInput", () => {
enum TestEnum {
None = 0,
A = 1,
B = 2,
C = 4,
A_B = 1 | 2,
A_C = 1 | 4,
B_C = 2 | 4,
A_B_C = 1 | 2 | 4,
}
beforeAll(() => setupInput({
...defaultInput,
enumAB: TestEnum.A_B,
enumABStringUpperCase: "A_B",
enumABStringLowerCase: "a_b",
enumABStringLowerCaseWithWhitespace: " a_b ",
enumABStringLowerCaseWithWhitespaceAndDifferentSeparator: " a-b ",
enumABStringLowerCaseWithWhitespaceBitwise: " a | b ",
enumABCStringLowerCaseWithWhitespaceBitwise: " c | b | b | a ",
}));
afterAll(() => unsetInput());
test("returns default value if input cannot be casted to the given enum", () => {
const input = getInputAsObject();
expect(input["object"]).not.toBeUndefined();
expect(mapEnumInput(input["object"], TestEnum)).toBeNull();
expect(input["boolean"]).not.toBeUndefined();
expect(mapEnumInput(input["boolean"], TestEnum)).toBeNull();
expect(input["array"]).not.toBeUndefined();
expect(mapEnumInput(input["array"], TestEnum)).toBeNull();
expect(input["undefined"]).toBeUndefined();
expect(mapEnumInput(input["undefined"], TestEnum, TestEnum.A_B_C)).toBe(TestEnum.A_B_C);
});
test("maps values to the given enum", () => {
const input = getInputAsObject();
expect(mapEnumInput(input["enumab"], TestEnum)).toBe(TestEnum.A_B);
expect(mapEnumInput(input["enumabstringuppercase"], TestEnum)).toBe(TestEnum.A_B);
expect(mapEnumInput(input["enumabstringlowercase"], TestEnum)).toBe(TestEnum.A_B);
expect(mapEnumInput(input["enumabstringlowercasewithwhitespace"], TestEnum)).toBe(TestEnum.A_B);
expect(mapEnumInput(input["enumabstringlowercasewithwhitespaceanddifferentseparator"], TestEnum)).toBe(TestEnum.A_B);
expect(mapEnumInput(input["enumabstringlowercasewithwhitespacebitwise"], TestEnum)).toBe(TestEnum.A_B);
expect(mapEnumInput(input["enumabcstringlowercasewithwhitespacebitwise"], TestEnum, TestEnum.A_B)).toBe(TestEnum.A_B_C);
});
});

View file

@ -1,105 +0,0 @@
import process from "process";
import { describe, test, expect } from "@jest/globals";
import { unifyGameVersion, unifyJava, convertToCurseForgeVersions } from "../../../../src/utils/curseforge";
describe("unifyGameVersion", () => {
test("versions in the unified format are not changed", async () => {
const validVersions = ["1.7.10", "1.12", "1.17-Snapshot", "1.17"];
for (const version of validVersions) {
expect(await unifyGameVersion(version)).toStrictEqual(version);
}
});
test("snapshot versions are converted to the unified format (\\d+\\.\\d+(\\.\\d+)?-Snapshot)", async () => {
expect(await unifyGameVersion("21w37a")).toStrictEqual("1.18-Snapshot");
expect(await unifyGameVersion("1.17.1-pre1")).toStrictEqual("1.17.1-Snapshot");
expect(await unifyGameVersion("1.17.1-pre2")).toStrictEqual("1.17.1-Snapshot");
expect(await unifyGameVersion("1.17.1-pre3")).toStrictEqual("1.17.1-Snapshot");
expect(await unifyGameVersion("1.17.1-rc1")).toStrictEqual("1.17.1-Snapshot");
expect(await unifyGameVersion("1.17.1-rc2")).toStrictEqual("1.17.1-Snapshot");
expect(await unifyGameVersion("1.17-rc2")).toStrictEqual("1.17-Snapshot");
expect(await unifyGameVersion("1.16-snapshot")).toStrictEqual("1.16-Snapshot");
});
test("unnecessary punctuation marks and whitespace symbols do not break the function", async () => {
expect(await unifyGameVersion(" 21w37a ")).toStrictEqual("1.18-Snapshot");
expect(await unifyGameVersion("1.17.1 pre1")).toStrictEqual("1.17.1-Snapshot");
expect(await unifyGameVersion(" 1.17.1-pre2 ")).toStrictEqual("1.17.1-Snapshot");
expect(await unifyGameVersion(" 1.17.1_pre2 ")).toStrictEqual("1.17.1-Snapshot");
expect(await unifyGameVersion(" 1 17 1 pre3 ")).toStrictEqual("1.17.1-Snapshot");
expect(await unifyGameVersion("1-17-1-rc1")).toStrictEqual("1.17.1-Snapshot");
expect(await unifyGameVersion("1.17.1.rc2")).toStrictEqual("1.17.1-Snapshot");
expect(await unifyGameVersion("1..17--rc2")).toStrictEqual("1.17-Snapshot");
expect(await unifyGameVersion("\t1-16.snapshot\t")).toStrictEqual("1.16-Snapshot");
});
});
describe("unifyJava", () => {
test("versions in the unified format are not changed", () => {
const validVersions = ["Java 8", "Java 9", "Java 10", "Java 11", "Java 1234"];
for (const version of validVersions) {
expect(unifyJava(version)).toStrictEqual(version);
}
});
test("java versions are converted to the unified format (Java \\d+)", () => {
expect(unifyJava("Java 1.8")).toStrictEqual("Java 8");
expect(unifyJava("Java 1.9")).toStrictEqual("Java 9");
expect(unifyJava("Java 1.10")).toStrictEqual("Java 10");
expect(unifyJava("Java 1.11")).toStrictEqual("Java 11");
expect(unifyJava("1.1234")).toStrictEqual("Java 1234");
});
test("unnecessary punctuation marks and whitespace symbols do not break the function", () => {
expect(unifyJava("1.8")).toStrictEqual("Java 8");
expect(unifyJava("9")).toStrictEqual("Java 9");
expect(unifyJava(" Java 10 ")).toStrictEqual("Java 10");
expect(unifyJava(" Java 1.11 ")).toStrictEqual("Java 11");
expect(unifyJava("\t\t\tjava 1 12\n")).toStrictEqual("Java 12");
expect(unifyJava(" 1.1234 ")).toStrictEqual("Java 1234");
});
});
describe("convertToCurseForgeVersions", () => {
// This test can only be executed in the GitHub Actions' environment,
// because CurseForge is a little bitch.
if (!process.env.CI) {
return;
}
test("versions are converted to CurseForge ids", async () => {
const versions = {
gameVersions: {
"1.18-Snapshot": 8633,
"21w37a": 8633,
"1.18 (snapshot)": 8633,
"1.18-rc1": 8633,
"1.17-pre3": 8282,
"1.17.1": 8516,
},
loaders: {
fabric: 7499,
forge: 7498,
quilt: 9153,
rift: 7500
},
java: {
"Java 8": 4458,
"Java 1.8": 4458,
"1.8": 4458,
"8": 4458,
"Java 1.7": 4457,
"java 1.16": 8325,
"17": 8326,
}
};
const curseForgeVersions = await convertToCurseForgeVersions(Object.keys(versions.gameVersions), Object.keys(versions.loaders), Object.keys(versions.java), process.env.CURSEFORGE_TOKEN as string);
const expectedIds = new Set([...Object.values<number>(versions.gameVersions), ...Object.values(versions.loaders), ...Object.values(versions.java)]);
expect(curseForgeVersions).toHaveLength(expectedIds.size);
for (const expectedId of expectedIds) {
expect(curseForgeVersions).toContain(expectedId);
}
});
});

View file

@ -1,59 +0,0 @@
import { describe, test, expect } from "@jest/globals";
import sleep from "../../../../src/utils/sleep";
import Stopwatch from "../../../../src/utils/diagnostics/stopwatch";
describe("Stopwatch", () => {
test("base functionality of Stopwatch works", async () => {
const stopwatch = new Stopwatch();
expect(stopwatch.isRunning).toBe(false);
expect(stopwatch.elapsedMilliseconds).toBe(0);
expect(stopwatch.start()).toBe(true);
await sleep(100);
expect(stopwatch.start()).toBe(false);
expect(stopwatch.stop()).toBe(true);
expect(stopwatch.stop()).toBe(false);
expect(stopwatch.elapsedMilliseconds).toBeGreaterThan(50);
expect(stopwatch.elapsedMilliseconds).toBeLessThan(200);
stopwatch.reset();
expect(stopwatch.elapsedMilliseconds).toBe(0);
});
test("Stopwatch executes callbacks on start and end", async () => {
let started = 0;
let stopped = 0;
let ms = 0;
const stopwatch = new Stopwatch(() => ++started, elapsedMilliseconds => {
++stopped;
ms = elapsedMilliseconds;
});
expect(stopwatch.isRunning).toBe(false);
expect(stopwatch.elapsedMilliseconds).toBe(0);
expect(stopwatch.start()).toBe(true);
expect(started).toBe(1);
expect(stopped).toBe(0);
await sleep(100);
expect(stopwatch.start()).toBe(false);
expect(started).toBe(1);
expect(stopped).toBe(0);
expect(stopwatch.stop()).toBe(true);
expect(started).toBe(1);
expect(stopped).toBe(1);
expect(stopwatch.stop()).toBe(false);
expect(started).toBe(1);
expect(stopped).toBe(1);
expect(stopwatch.elapsedMilliseconds).toBeGreaterThan(50);
expect(stopwatch.elapsedMilliseconds).toBeLessThan(200);
expect(stopwatch.elapsedMilliseconds).toBe(ms);
stopwatch.reset();
expect(stopwatch.elapsedMilliseconds).toBe(0);
});
});

View file

@ -1,30 +0,0 @@
import { describe, test, expect } from "@jest/globals";
import File from "../../../../src/utils/io/file";
describe("File", () => {
describe("getFiles", () => {
test("all files matching the given pattern are returned", async () => {
expect(await File.getFiles("(README|LICENSE|FOO).md")).toHaveLength(2);
});
test("files matching the primary pattern are returned first", async () => {
const files = await File.getFiles({ primary: "README.md", secondary: "(README|LICENSE|FOO).md" });
expect(files).toHaveLength(2);
expect(files[0]).toHaveProperty("name", "README.md");
const inversedFiles = await File.getFiles({ primary: "LICENSE.md", secondary: "(README|LICENSE|FOO).md" });
expect(inversedFiles).toHaveLength(2);
expect(inversedFiles[0]).toHaveProperty("name", "LICENSE.md");
});
});
describe("getRequiredFiles", () => {
test("all files matching the given pattern are returned", async () => {
expect(await File.getRequiredFiles("(README|LICENSE|FOO).md")).toHaveLength(2);
});
test("an error is thrown if no files are found", async () => {
await expect(File.getRequiredFiles("FOO.md")).rejects.toBeInstanceOf(Error);
});
});
});

View file

@ -1,81 +0,0 @@
import { describe, test, expect } from "@jest/globals";
import sleep from "../../../../src/utils/sleep";
import Logger from "../../../../src/utils/logging/logger";
import LogginStopwatch from "../../../../src/utils/logging/logging-stopwatch";
function createLogger(info?: (msg: string) => void): Logger {
const notImplementedLogger = () => {
throw new Error("Not implemented and should never be called");
};
return {
fatal: notImplementedLogger,
error: notImplementedLogger,
warn: notImplementedLogger,
debug: notImplementedLogger,
info: info ?? notImplementedLogger
};
}
describe("LogginStopwatch", () => {
test("base functionality of LogginStopwatch works", async () => {
const stopwatch = new LogginStopwatch(createLogger());
expect(stopwatch.isRunning).toBe(false);
expect(stopwatch.elapsedMilliseconds).toBe(0);
expect(stopwatch.start()).toBe(true);
await sleep(100);
expect(stopwatch.start()).toBe(false);
expect(stopwatch.stop()).toBe(true);
expect(stopwatch.stop()).toBe(false);
expect(stopwatch.elapsedMilliseconds).toBeGreaterThan(50);
expect(stopwatch.elapsedMilliseconds).toBeLessThan(200);
stopwatch.reset();
expect(stopwatch.elapsedMilliseconds).toBe(0);
});
test("LogginStopwatch executes callbacks on start and end", async () => {
let started = 0;
let stopped = 0;
let ms = 0;
const logger = createLogger(msg => {
if (msg.startsWith("start")) {
++started;
} else if (msg.startsWith("stop")) {
++stopped;
ms = +msg.split(" ")[1];
} else {
throw new Error("Unrecognized message");
}
});
const stopwatch = new LogginStopwatch(logger, "start", ms => `stop ${ms}`);
expect(stopwatch.isRunning).toBe(false);
expect(stopwatch.elapsedMilliseconds).toBe(0);
expect(stopwatch.start()).toBe(true);
expect(started).toBe(1);
expect(stopped).toBe(0);
await sleep(100);
expect(stopwatch.start()).toBe(false);
expect(started).toBe(1);
expect(stopped).toBe(0);
expect(stopwatch.stop()).toBe(true);
expect(started).toBe(1);
expect(stopped).toBe(1);
expect(stopwatch.stop()).toBe(false);
expect(started).toBe(1);
expect(stopped).toBe(1);
expect(stopwatch.elapsedMilliseconds).toBeGreaterThan(50);
expect(stopwatch.elapsedMilliseconds).toBeLessThan(200);
expect(stopwatch.elapsedMilliseconds).toBe(ms);
stopwatch.reset();
expect(stopwatch.elapsedMilliseconds).toBe(0);
});
});

View file

@ -1,168 +0,0 @@
import { describe, test, expect } from "@jest/globals";
import { getVersionById, findVersionByName, isSnapshot, parseVersionName, parseVersionNameFromFileVersion, getVersions, getLatestRelease, getCompatibleBuilds } from "../../../../src/utils/minecraft";
import Version from "../../../../src/utils/versioning/version";
describe("getVersionById", () => {
test("returned versions have the same id as the given one", async () => {
const existingVersionIds = ["20w45a", "1.14.4-pre4", "3D Shareware v1.34", "20w14infinite", "1.14.2 Pre-Release 4", "1.7.10", "1.12.2"];
for (const versionId of existingVersionIds) {
expect(await getVersionById(versionId)).toHaveProperty("id", versionId);
}
});
test("the method returns null if version with the given id does not exist", async () => {
const nonExistingVersionIds = ["", "0.0.0", "1.16.6", "18w100c", "1.7.10-rc1"];
for (const versionId of nonExistingVersionIds) {
expect(await getVersionById(versionId)).toBeNull();
}
});
test("returned versions have expected names", async () => {
const versions = {
"21w37a": "1.18",
"1.17.1": "1.17.1",
"1.17.1-pre3": "1.17.1",
"1.14.2 Pre-Release 4": "1.14.2",
"1.7.10": "1.7.10",
};
for (const [id, name] of Object.entries(versions)) {
expect (await getVersionById(id)).toHaveProperty("name", name);
}
});
});
describe("findVersionByName", () => {
test("if the given name is an identifier, id of the found version should match it", async () => {
const ids = ["21w37a", "1.17.1-pre3", "1.16.5", "3D Shareware v1.34", "20w14infinite", "1.14.2 Pre-Release 4"];
for (const id of ids) {
expect(await findVersionByName(id)).toHaveProperty("id", id);
}
});
test("if version with the given name does not exist, the most similar is returned", async () => {
const versions = {
"1.17.1-Snapshot": "1.17.1-rc2",
"1.17.1-rc3": "1.17.1-rc2",
"1.17.1 (snapshot)": "1.17.1-rc2",
"1.15.2 Pre-Release": "1.15.2-pre2",
};
for (const [name, id] of Object.entries(versions)) {
expect(await findVersionByName(name)).toHaveProperty("id", id);
}
});
});
describe("isSnapshot", () => {
test("the method returns true if provided version is a snapshot; otherwise, false", () => {
const versions = {
"1.7.10": false,
"1.7.10-pre4": true,
"1.6.3-rc1": true,
"21w37a": true,
"1.14.2 Pre-Release 3": true,
"1.6.1": false,
"1.6": true,
"1.5": true,
"14w34c": true,
"1.RV-Pre1": true,
"20w14infinite": true,
"1.12.2": false,
"1.17-Snapshot": true,
};
for (const [name, snapshot] of Object.entries(versions)) {
expect(isSnapshot(name)).toStrictEqual(snapshot);
}
});
});
describe("parseVersionName", () => {
test("Minecraft versions are parsed correctly", () => {
expect(parseVersionName("1.17.1")).toStrictEqual("1.17.1");
expect(parseVersionName("1.16.3")).toStrictEqual("1.16.3");
expect(parseVersionName("1.17")).toStrictEqual("1.17");
expect(parseVersionName("1.16")).toStrictEqual("1.16");
});
test("weird formats that contain Minecraft version are parsed correctly", () => {
expect(parseVersionName("1.17-5.0.1-beta+build.29")).toStrictEqual("1.17");
expect(parseVersionName("[1.16.5, 1.17)")).toStrictEqual("1.16.5");
expect(parseVersionName(">=1.17")).toStrictEqual("1.17");
});
test("null is returned if version string does not contain Minecraft version", () => {
expect(parseVersionName("5.0.8-beta+build.111")).toBeNull();
expect(parseVersionName("5.3.3-BETA+ec3b0e5d")).toBeNull();
expect(parseVersionName("2.0.12")).toBeNull();
});
});
describe("parseVersionNameFromFileVersion", () => {
test("Sodium-like versions are parsed correctly", () => {
expect(parseVersionNameFromFileVersion("mc1.17.1-0.3.2+build.7")).toStrictEqual("1.17.1");
expect(parseVersionNameFromFileVersion("mc1.16.3-0.1.0")).toStrictEqual("1.16.3");
expect(parseVersionNameFromFileVersion("mc1.17.x-1.2")).toStrictEqual("1.17");
expect(parseVersionNameFromFileVersion("mc1.16.*-1.2")).toStrictEqual("1.16");
});
test("Fabric-like versions are parsed correctly", () => {
expect(parseVersionNameFromFileVersion("0.40.1+1.18_experimental")).toStrictEqual("1.18");
expect(parseVersionNameFromFileVersion("0.5+1.17")).toStrictEqual("1.17");
expect(parseVersionNameFromFileVersion("1.17.1+1.19")).toStrictEqual("1.19");
expect(parseVersionNameFromFileVersion("1.19+1.17.1")).toStrictEqual("1.17.1");
});
test("weird formats that contain obvious Minecraft version are parsed correctly", () => {
expect(parseVersionNameFromFileVersion("1.17-5.0.1-beta+build.29")).toStrictEqual("1.17");
});
test("null is returned if version string does not contain obvious Minecraft version", () => {
expect(parseVersionNameFromFileVersion("5.0.8-beta+build.111")).toBeNull();
expect(parseVersionNameFromFileVersion("5.3.3-BETA+ec3b0e5d")).toBeNull();
expect(parseVersionNameFromFileVersion("2.0.12")).toBeNull();
expect(parseVersionNameFromFileVersion("1.17")).toBeNull();
});
});
describe("getLatestRelease", () => {
test("the latest release is returned", async () => {
const latestRelease = (await getVersions()).filter(x => x.isRelease).sort((a, b) => b.releaseTime.getTime() - a.releaseTime.getTime())[0];
expect(await getLatestRelease()).toHaveProperty("id", latestRelease.id);
});
});
describe("getCompatibleBuilds", () => {
test("empty array is returned if no versions were found", async () => {
expect(await getCompatibleBuilds("42.0.0")).toHaveLength(0);
});
test("all versions of the given minor are returned", async () => {
const builds = (await getCompatibleBuilds("1.16")).map(x => x.id);
expect(builds).toHaveLength(54);
expect(builds).toContain("1.16");
expect(builds).toContain("1.16.1");
expect(builds).toContain("1.16.2");
expect(builds).toContain("1.16.3");
expect(builds).toContain("1.16.4");
expect(builds).toContain("1.16.5");
expect(builds).toContain("20w06a");
expect(builds).toContain("20w14infinite");
expect(builds).not.toContain("1.17");
expect(builds).not.toContain("1.15");
});
test("all versions of the given minor starting with the given build are returned", async () => {
const builds = (await getCompatibleBuilds(new Version(1, 17, 1))).map(x => x.id);
expect(builds).toHaveLength(6);
expect(builds).toContain("1.17.1");
expect(builds).toContain("1.17.1-pre1");
expect(builds).toContain("1.17.1-pre2");
expect(builds).toContain("1.17.1-pre3");
expect(builds).toContain("1.17.1-rc1");
expect(builds).toContain("1.17.1-rc2");
expect(builds).not.toContain("1.18");
expect(builds).not.toContain("1.17");
});
});

View file

@ -1,115 +0,0 @@
import { describe, test, expect } from "@jest/globals";
import MinecraftVersionResolver from "../../../../src/utils/minecraft/minecraft-version-resolver";
describe("MinecraftVersionResolver.byName", () => {
test("every predefined MinecraftVersionResolver can be resolved", () => {
for (const [key, value] of Object.entries(MinecraftVersionResolver).filter(([_, x]) => x instanceof MinecraftVersionResolver)) {
expect(MinecraftVersionResolver.byName(key)).toStrictEqual(value);
}
});
test("null is returned if MinecraftVersionResolver with the given name doesn't exist", () => {
expect(MinecraftVersionResolver.byName("non-existing-resolver")).toBeNull();
});
test("name of MinecraftVersionResolver is case insensitive", () => {
expect(MinecraftVersionResolver.byName("latest")).toStrictEqual(MinecraftVersionResolver.latest);
expect(MinecraftVersionResolver.byName("Latest")).toStrictEqual(MinecraftVersionResolver.latest);
expect(MinecraftVersionResolver.byName("LATEST")).toStrictEqual(MinecraftVersionResolver.latest);
expect(MinecraftVersionResolver.byName("LatesT")).toStrictEqual(MinecraftVersionResolver.latest);
});
});
describe("MinecraftVersionResolver.exact", () => {
test("the exact version is returned", async () => {
const _1_17 = (await MinecraftVersionResolver.exact.resolve("1.17")).map(x => x.id);
expect(_1_17).toHaveLength(1);
expect(_1_17).toContain("1.17");
const _1_17_1 = (await MinecraftVersionResolver.exact.resolve("1.17.1")).map(x => x.id);
expect(_1_17_1).toHaveLength(1);
expect(_1_17_1).toContain("1.17.1");
});
test("empty array is returned if no versions were found", async () => {
expect(await MinecraftVersionResolver.exact.resolve("42.0")).toHaveLength(0);
});
});
describe("MinecraftVersionResolver.latest", () => {
test("the latest version of the given minor is returned", async () => {
const versions = (await MinecraftVersionResolver.latest.resolve("1.17")).map(x => x.id);
expect(versions).toHaveLength(1);
expect(versions).toContain("1.17.1");
});
test("empty array is returned if no versions were found", async () => {
expect(await MinecraftVersionResolver.latest.resolve("42.0")).toHaveLength(0);
});
});
describe("MinecraftVersionResolver.all", () => {
test("all versions of the given minor are returned", async () => {
const versions = (await MinecraftVersionResolver.all.resolve("1.17")).map(x => x.id);
expect(versions).toHaveLength(31);
expect(versions).toContain("1.17");
expect(versions).toContain("1.17.1");
expect(versions).toContain("1.17.1-rc2");
expect(versions).toContain("1.17.1-rc1");
expect(versions).toContain("1.17.1-pre3");
expect(versions).toContain("1.17.1-pre2");
expect(versions).toContain("1.17.1-pre1");
expect(versions).toContain("21w03a");
});
test("all versions of the given minor starting with the given build are returned", async () => {
const versions = (await MinecraftVersionResolver.all.resolve("1.17.1")).map(x => x.id);
expect(versions).toHaveLength(6);
expect(versions).toContain("1.17.1");
expect(versions).toContain("1.17.1-rc2");
expect(versions).toContain("1.17.1-rc1");
expect(versions).toContain("1.17.1-pre3");
expect(versions).toContain("1.17.1-pre2");
expect(versions).toContain("1.17.1-pre1");
});
test("empty array is returned if no versions were found", async () => {
expect(await MinecraftVersionResolver.all.resolve("42.0")).toHaveLength(0);
});
});
describe("MinecraftVersionResolver.releases", () => {
test("all releases of the given minor are returned", async () => {
const versions = (await MinecraftVersionResolver.releases.resolve("1.17")).map(x => x.id);
expect(versions).toHaveLength(2);
expect(versions).toContain("1.17");
expect(versions).toContain("1.17.1");
});
test("all releases of the given minor starting with the given build are returned", async () => {
const versions = (await MinecraftVersionResolver.releases.resolve("1.16.1")).map(x => x.id);
expect(versions).toHaveLength(5);
expect(versions).toContain("1.16.1");
expect(versions).toContain("1.16.2");
expect(versions).toContain("1.16.3");
expect(versions).toContain("1.16.4");
expect(versions).toContain("1.16.5");
});
test("an empty array is returned if no versions were found", async () => {
expect(await MinecraftVersionResolver.releases.resolve("42.0")).toHaveLength(0);
});
});
describe("MinecraftVersionResolver.releasesIfAny", () => {
test("all releases of the given minor are returned", async () => {
const versions = (await MinecraftVersionResolver.releasesIfAny.resolve("1.17")).map(x => x.id);
expect(versions).toHaveLength(2);
expect(versions).toContain("1.17");
expect(versions).toContain("1.17.1");
});
test("empty array is returned if no versions were found", async () => {
expect(await MinecraftVersionResolver.releasesIfAny.resolve("42.0")).toHaveLength(0);
});
});

View file

@ -1,75 +0,0 @@
import { describe, test, expect } from "@jest/globals";
import { getProject, getVersions } from "../../../../src/utils/modrinth";
const timeout = 15000;
describe("getProject", () => {
test("returned versions have expected ids", async () => {
const projects = {
"sodium": "AANobbMI",
"fabric-api": "P7dR8mSH",
"sync-fabric": "OrJTMhHF",
"nether-chest": "okOUGirG",
"ebe": "OVuFYfre",
};
for (const [slug, id] of Object.entries(projects)) {
const project = await getProject(slug);
expect(project).toHaveProperty("id", id);
}
}, timeout);
test("the method returns null if project with the given slug does not exist", async () => {
const nonExistentProjects = [
"Na-11",
"api-fabric",
"sync-forge",
"ever-chest",
"beb",
"i-swear-to-god-if-someone-registers-these-mods"
];
for (const slug of nonExistentProjects) {
const project = await getProject(slug);
expect(project).toBeNull();
}
}, timeout);
});
describe("getVersions", () => {
test("returns unfiltered versions if no parameters were passed", async () => {
const versions = await getVersions("terra");
expect(versions.find(x => x.featured)).toBeTruthy();
expect(versions.find(x => !x.featured)).toBeTruthy();
expect(versions.find(x => x.loaders.includes("fabric"))).toBeTruthy();
expect(versions.find(x => x.loaders.includes("forge"))).toBeTruthy();
expect(versions.find(x => x.game_versions.includes("1.18.2"))).toBeTruthy();
expect(versions.find(x => x.game_versions.includes("1.16.5"))).toBeTruthy();
}, timeout);
test("returns only featured versions with featured === true", async () => {
const versions = await getVersions("terra", null!, null!, true);
expect(versions.every(x => x.featured)).toBe(true);
}, timeout);
test("returns only unfeatured versions with featured === false", async () => {
const versions = await getVersions("terra", null!, null!, false);
expect(versions.every(x => !x.featured)).toBe(true);
}, timeout);
test("returns only versions that support given modloaders", async () => {
const fabricVersions = await getVersions("terra", ["fabric"]);
expect(fabricVersions.every(x => x.loaders.includes("fabric"))).toBe(true);
const forgeVersions = await getVersions("terra", ["forge"]);
expect(forgeVersions.every(x => x.loaders.includes("forge"))).toBe(true);
}, timeout);
test("returns only versions that support given mc versions", async () => {
const versions_1_18_2 = await getVersions("terra", null!, ["1.18.2"]);
expect(versions_1_18_2.every(x => x.game_versions.includes("1.18.2"))).toBe(true);
const versions_1_16_5 = await getVersions("terra", null!, ["1.16.5"]);
expect(versions_1_16_5.every(x => x.game_versions.includes("1.16.5"))).toBe(true);
}, timeout);
});

View file

@ -1,70 +0,0 @@
import { describe, test, expect } from "@jest/globals";
import retry from "../../../src/utils/retry";
import SoftError from "../../../src/utils/soft-error";
function createThrowingFunc(attempts: number): () => true {
let counter = 0;
return () => {
if (++counter !== attempts) {
throw new SoftError(true);
}
return true;
};
}
function createAsyncThrowingFunc(attempts: number): () => Promise<true> {
const func = createThrowingFunc(attempts);
return async () => func();
}
describe("retry", () => {
test("function resolves after several attempts", async () => {
expect(await retry({ func: createThrowingFunc(5), maxAttempts: 5 })).toBe(true);
});
test("delay is applied between the attempts", async () => {
const start = new Date();
expect(await retry({ func: createThrowingFunc(2), maxAttempts: 2, delay: 100 })).toBe(true);
const end = new Date();
const duration = end.getTime() - start.getTime();
expect(duration > 50 && duration < 200).toBe(true);
});
test("the original error is thrown if retry function didn't succeed", async () => {
await expect(retry({ func: createThrowingFunc(5), maxAttempts: 1 })).rejects.toThrow(<any>SoftError);
});
test("softErrorPredicate is used to determine whether the error is soft or not", async () => {
await expect(retry({ func: createThrowingFunc(5), maxAttempts: 5, softErrorPredicate: _ => false })).rejects.toThrow(<any>SoftError);
});
test("errorCallback is called whenever an error occurs", async () => {
await expect(retry({ func: createThrowingFunc(5), maxAttempts: 5, errorCallback: e => { throw e; } })).rejects.toThrow(<any>SoftError);
});
});
describe("retry (async)", () => {
test("function resolves after several attempts", async () => {
expect(await retry({ func: createAsyncThrowingFunc(5), maxAttempts: 5 })).toBe(true);
});
test("delay is applied between the attempts", async () => {
const start = new Date();
expect(await retry({ func: createAsyncThrowingFunc(2), maxAttempts: 2, delay: 100 })).toBe(true);
const end = new Date();
const duration = end.getTime() - start.getTime();
expect(duration > 50 && duration < 200).toBe(true);
});
test("the original error is thrown if retry function didn't succeed", async () => {
await expect(retry({ func: createAsyncThrowingFunc(5), maxAttempts: 1 })).rejects.toThrow(<any>SoftError);
});
test("softErrorPredicate is used to determine whether the error is soft or not", async () => {
await expect(retry({ func: createAsyncThrowingFunc(5), maxAttempts: 5, softErrorPredicate: _ => false })).rejects.toThrow(<any>SoftError);
});
test("errorCallback is called whenever an error occurs", async () => {
await expect(retry({ func: createAsyncThrowingFunc(5), maxAttempts: 5, errorCallback: e => { throw e; } })).rejects.toThrow(<any>SoftError);
});
});

View file

@ -1,14 +0,0 @@
import { describe, test, expect } from "@jest/globals";
import sleep from "../../../src/utils/sleep";
describe("sleep", () => {
test("execution continues after the specified delay", async () => {
const start = new Date();
await sleep(100);
const end = new Date();
const duration = end.getTime() - start.getTime();
expect(duration).toBeGreaterThan(50);
expect(duration).toBeLessThan(200);
});
});

View file

@ -1,18 +0,0 @@
import { describe, test, expect } from "@jest/globals";
import VersionType from "../../../../src/utils/versioning/version-type";
describe("VersionType", () => {
describe("fromName", () => {
test("version type is correctly extracted from the filename", () => {
expect(VersionType.fromName("sodium-fabric-mc1.17.1-0.3.2+build.7")).toStrictEqual("release");
expect(VersionType.fromName("fabric-api-0.40.1+1.18_experimental")).toStrictEqual("release");
expect(VersionType.fromName("TechReborn-5.0.8-beta+build.111")).toStrictEqual("beta");
expect(VersionType.fromName("TechReborn-1.17-5.0.1-beta+build.29")).toStrictEqual("beta");
expect(VersionType.fromName("Terra-forge-5.3.3-BETA+ec3b0e5d")).toStrictEqual("beta");
expect(VersionType.fromName("Terra-forge-5.3.3-alpha+ec3b0e5d")).toStrictEqual("alpha");
expect(VersionType.fromName("modmenu-2.0.12")).toStrictEqual("release");
expect(VersionType.fromName("enhancedblockentities-0.5+1.17")).toStrictEqual("release");
expect(VersionType.fromName("sync-mc1.17.x-1.2")).toStrictEqual("release");
});
});
});

View file

@ -1,17 +0,0 @@
import { describe, test, expect } from "@jest/globals";
import Version from "../../../../src/utils/versioning/version";
describe("Version", () => {
describe("fromName", () => {
test("file version is correctly extracted from the filename", () => {
expect(Version.fromName("sodium-fabric-mc1.17.1-0.3.2+build.7")).toStrictEqual("mc1.17.1-0.3.2+build.7");
expect(Version.fromName("fabric-api-0.40.1+1.18_experimental")).toStrictEqual("0.40.1+1.18_experimental");
expect(Version.fromName("TechReborn-5.0.8-beta+build.111")).toStrictEqual("5.0.8-beta+build.111");
expect(Version.fromName("TechReborn-1.17-5.0.1-beta+build.29")).toStrictEqual("1.17-5.0.1-beta+build.29");
expect(Version.fromName("Terra-forge-5.3.3-BETA+ec3b0e5d")).toStrictEqual("5.3.3-BETA+ec3b0e5d");
expect(Version.fromName("modmenu-2.0.12")).toStrictEqual("2.0.12");
expect(Version.fromName("enhancedblockentities-0.5+1.17")).toStrictEqual("0.5+1.17");
expect(Version.fromName("sync-mc1.17.x-1.2")).toStrictEqual("mc1.17.x-1.2");
});
});
});

View file

@ -1,15 +0,0 @@
import process from "process";
export function setupInput(input: Record<string, any>): void {
for (const [key, value] of Object.entries(input)) {
process.env[`INPUT_${key.replace(/ /g, "_").toUpperCase()}`] = value.toString();
}
}
export function unsetInput(): void {
for (const key of Object.keys(process.env)) {
if (key.startsWith("INPUT_")) {
delete process.env[key];
}
}
}