diff --git a/src/loaders/neoforge/neoforge-dependency-type.ts b/src/loaders/neoforge/neoforge-dependency-type.ts new file mode 100644 index 0000000..c3ee824 --- /dev/null +++ b/src/loaders/neoforge/neoforge-dependency-type.ts @@ -0,0 +1,119 @@ +import { Enum, EnumOptions } from "@/utils/enum"; +import { DependencyType } from "@/dependencies"; + +/** + * Represents different NeoForge dependency types. + * + * @partial + */ +enum NeoForgeDependencyTypeValues { + /** + * For dependencies required to run. Without them, a game will crash. + */ + REQUIRED = "required", + + /** + * For dependencies not required to run. Without them, a game will log a warning. + */ + OPTIONAL = "optional", + + /** + * For dependencies embedded within the project. + */ + EMBEDDED = "embedded", + + /** + * For mods whose together with yours might cause a game crash. With them, a game will crash. + */ + INCOMPATIBLE = "incompatible", + + /** + * For mods whose together with yours cause some kind of bugs, etc. With them, a game will log a warning. + */ + DISCOURAGED = "discouraged", +} + +/** + * Options for configuring the behavior of the NeoForgeDependencyType enum. + * + * @partial + */ +const NeoForgeDependencyTypeOptions: EnumOptions = { + /** + * The case should be ignored while parsing the dependency type. + */ + ignoreCase: true, +}; + +/** + * Converts a {@link NeoForgeDependencyType} to a {@link DependencyType}. + * + * @param type - The {@link NeoForgeDependencyType} to convert. + * + * @returns The corresponding {@link DependencyType}, or `undefined` if the value is invalid. + */ +function toDependencyType(type: NeoForgeDependencyType): DependencyType | undefined { + switch (type) { + case NeoForgeDependencyType.REQUIRED: + return DependencyType.REQUIRED; + case NeoForgeDependencyType.OPTIONAL: + return DependencyType.OPTIONAL; + case NeoForgeDependencyType.EMBEDDED: + return DependencyType.EMBEDDED; + case NeoForgeDependencyType.INCOMPATIBLE: + return DependencyType.INCOMPATIBLE; + case NeoForgeDependencyType.DISCOURAGED: + return DependencyType.CONFLICTING; + default: + return undefined; + } +} + +/** + * Converts a {@link DependencyType} to a {@link NeoForgeDependencyType}. + * + * @param type - The {@link DependencyType} to convert. + * + * @returns The corresponding {@link NeoForgeDependencyType}, or `undefined` if the value is invalid. + */ +function fromDependencyType(type: DependencyType): NeoForgeDependencyType | undefined { + switch (type) { + case DependencyType.REQUIRED: + return NeoForgeDependencyType.REQUIRED; + case DependencyType.OPTIONAL: + case DependencyType.RECOMMENDED: + return NeoForgeDependencyType.OPTIONAL; + case DependencyType.EMBEDDED: + return NeoForgeDependencyType.EMBEDDED; + case DependencyType.CONFLICTING: + return NeoForgeDependencyType.DISCOURAGED; + case DependencyType.INCOMPATIBLE: + return NeoForgeDependencyType.INCOMPATIBLE; + default: + return undefined; + } +} + +/** + * A collection of methods to work with NeoForgeDependencyType. + * + * @partial + */ +const NeoForgeDependencyTypeMethods = { + toDependencyType, + fromDependencyType, +}; + +/** + * Represents different NeoForge dependency types. + */ +export const NeoForgeDependencyType = Enum.create( + NeoForgeDependencyTypeValues, + NeoForgeDependencyTypeOptions, + NeoForgeDependencyTypeMethods, +); + +/** + * Represents different NeoForge dependency types. + */ +export type NeoForgeDependencyType = Enum; diff --git a/tests/unit/loaders/neoforge/neoforge-dependency-type.spec.ts b/tests/unit/loaders/neoforge/neoforge-dependency-type.spec.ts new file mode 100644 index 0000000..8d10f93 --- /dev/null +++ b/tests/unit/loaders/neoforge/neoforge-dependency-type.spec.ts @@ -0,0 +1,59 @@ +import { DependencyType } from "@/dependencies/dependency-type"; +import { NeoForgeDependencyType } from "@/loaders/neoforge/neoforge-dependency-type"; + +describe("NeoForgeDependencyType", () => { + describe("toDependencyType", () => { + test("returns corresponding DependencyType", () => { + expect(NeoForgeDependencyType.toDependencyType(NeoForgeDependencyType.INCOMPATIBLE)).toBe(DependencyType.INCOMPATIBLE); + expect(NeoForgeDependencyType.toDependencyType(NeoForgeDependencyType.DISCOURAGED)).toBe(DependencyType.CONFLICTING); + expect(NeoForgeDependencyType.toDependencyType(NeoForgeDependencyType.REQUIRED)).toBe(DependencyType.REQUIRED); + expect(NeoForgeDependencyType.toDependencyType(NeoForgeDependencyType.EMBEDDED)).toBe(DependencyType.EMBEDDED); + expect(NeoForgeDependencyType.toDependencyType(NeoForgeDependencyType.OPTIONAL)).toBe(DependencyType.OPTIONAL); + }); + + test("returns undefined for unknown values", () => { + expect(NeoForgeDependencyType.toDependencyType("" as NeoForgeDependencyType)).toBeUndefined(); + }); + }); + + describe("fromDependencyType", () => { + test("converts DependencyType to NeoForgeDependencyType", () => { + expect(NeoForgeDependencyType.fromDependencyType(DependencyType.CONFLICTING)).toBe(NeoForgeDependencyType.DISCOURAGED); + expect(NeoForgeDependencyType.fromDependencyType(DependencyType.EMBEDDED)).toBe(NeoForgeDependencyType.EMBEDDED); + expect(NeoForgeDependencyType.fromDependencyType(DependencyType.INCOMPATIBLE)).toBe(NeoForgeDependencyType.INCOMPATIBLE); + expect(NeoForgeDependencyType.fromDependencyType(DependencyType.OPTIONAL)).toBe(NeoForgeDependencyType.OPTIONAL); + expect(NeoForgeDependencyType.fromDependencyType(DependencyType.RECOMMENDED)).toBe(NeoForgeDependencyType.OPTIONAL); + expect(NeoForgeDependencyType.fromDependencyType(DependencyType.REQUIRED)).toBe(NeoForgeDependencyType.REQUIRED); + }); + + test("returns undefined for unknown values", () => { + expect(NeoForgeDependencyType.fromDependencyType("" as DependencyType)).toBeUndefined(); + }); + }); + + describe("parse", () => { + test("parses all its own formatted values", () => { + for (const value of NeoForgeDependencyType.values()) { + expect(NeoForgeDependencyType.parse(NeoForgeDependencyType.format(value))).toBe(value); + } + }); + + test("parses all friendly names of its own values", () => { + for (const value of NeoForgeDependencyType.values()) { + expect(NeoForgeDependencyType.parse(NeoForgeDependencyType.friendlyNameOf(value))).toBe(value); + } + }); + + test("parses all its own formatted values in lowercase", () => { + for (const value of NeoForgeDependencyType.values()) { + expect(NeoForgeDependencyType.parse(NeoForgeDependencyType.format(value).toLowerCase())).toBe(value); + } + }); + + test("parses all its own formatted values in UPPERCASE", () => { + for (const value of NeoForgeDependencyType.values()) { + expect(NeoForgeDependencyType.parse(NeoForgeDependencyType.format(value).toUpperCase())).toBe(value); + } + }); + }); +});