diff --git a/src/loaders/fabric/fabric-dependency-type.ts b/src/loaders/fabric/fabric-dependency-type.ts new file mode 100644 index 0000000..904b79a --- /dev/null +++ b/src/loaders/fabric/fabric-dependency-type.ts @@ -0,0 +1,127 @@ +import { Enum, EnumOptions } from "@/utils/enum"; +import { DependencyType } from "@/dependencies"; + +/** + * Represents different Fabric dependency types. + * + * @partial + */ +enum FabricDependencyTypeValues { + /** + * For dependencies required to run. Without them, a game will crash. + */ + DEPENDS = "depends", + + /** + * For dependencies not required to run. Without them, a game will log a warning. + */ + RECOMMENDS = "recommends", + + /** + * For dependencies embedded within the project. + */ + INCLUDES = "includes", + + /** + * For dependencies not required to run. Use this as a kind of metadata. + */ + SUGGESTS = "suggests", + + /** + * For mods whose together with yours might cause a game crash. With them, a game will crash. + */ + BREAKS = "breaks", + + /** + * For mods whose together with yours cause some kind of bugs, etc. With them, a game will log a warning. + */ + CONFLICTS = "conflicts", +} + +/** + * Options for configuring the behavior of the FabricDependencyType enum. + * + * @partial + */ +const FabricDependencyTypeOptions: EnumOptions = { + /** + * The case should be ignored while parsing the dependency type. + */ + ignoreCase: true, +}; + +/** + * Converts a {@link FabricDependencyType} to a {@link DependencyType}. + * + * @param type - The {@link FabricDependencyType} to convert. + * + * @returns The corresponding {@link DependencyType}, or `undefined` if the value is invalid. + */ +function toDependencyType(type: FabricDependencyType): DependencyType | undefined { + switch (type) { + case FabricDependencyType.DEPENDS: + return DependencyType.REQUIRED; + case FabricDependencyType.RECOMMENDS: + return DependencyType.RECOMMENDED; + case FabricDependencyType.INCLUDES: + return DependencyType.EMBEDDED; + case FabricDependencyType.SUGGESTS: + return DependencyType.OPTIONAL; + case FabricDependencyType.BREAKS: + return DependencyType.INCOMPATIBLE; + case FabricDependencyType.CONFLICTS: + return DependencyType.CONFLICTING; + default: + return undefined; + } +} + +/** + * Converts a {@link DependencyType} to a {@link FabricDependencyType}. + * + * @param type - The {@link DependencyType} to convert. + * + * @returns The corresponding {@link FabricDependencyType}, or `undefined` if the value is invalid. + */ +function fromDependencyType(type: DependencyType): FabricDependencyType | undefined { + switch (type) { + case DependencyType.REQUIRED: + return FabricDependencyType.DEPENDS; + case DependencyType.RECOMMENDED: + return FabricDependencyType.RECOMMENDS; + case DependencyType.EMBEDDED: + return FabricDependencyType.INCLUDES; + case DependencyType.OPTIONAL: + return FabricDependencyType.SUGGESTS; + case DependencyType.CONFLICTING: + return FabricDependencyType.CONFLICTS; + case DependencyType.INCOMPATIBLE: + return FabricDependencyType.BREAKS; + default: + return undefined; + } +} + +/** + * A collection of methods to work with FabricDependencyType. + * + * @partial + */ +const FabricDependencyTypeMethods = { + toDependencyType, + fromDependencyType, +}; + +/** + * Represents different Fabric dependency types. + */ +export const FabricDependencyType = Enum.create( + FabricDependencyTypeValues, + FabricDependencyTypeOptions, + FabricDependencyTypeMethods, +); + +/** + * Represents different Fabric dependency types. + */ +export type FabricDependencyType = Enum; diff --git a/tests/unit/loaders/fabric/fabric-dependency-type.spec.ts b/tests/unit/loaders/fabric/fabric-dependency-type.spec.ts new file mode 100644 index 0000000..e0ff732 --- /dev/null +++ b/tests/unit/loaders/fabric/fabric-dependency-type.spec.ts @@ -0,0 +1,60 @@ +import { DependencyType } from "@/dependencies"; +import { FabricDependencyType } from "@/loaders/fabric/fabric-dependency-type"; + +describe("FabricDependencyType", () => { + describe("toDependencyType", () => { + test("returns corresponding DependencyType", () => { + expect(FabricDependencyType.toDependencyType(FabricDependencyType.BREAKS)).toBe(DependencyType.INCOMPATIBLE); + expect(FabricDependencyType.toDependencyType(FabricDependencyType.CONFLICTS)).toBe(DependencyType.CONFLICTING); + expect(FabricDependencyType.toDependencyType(FabricDependencyType.DEPENDS)).toBe(DependencyType.REQUIRED); + expect(FabricDependencyType.toDependencyType(FabricDependencyType.INCLUDES)).toBe(DependencyType.EMBEDDED); + expect(FabricDependencyType.toDependencyType(FabricDependencyType.RECOMMENDS)).toBe(DependencyType.RECOMMENDED); + expect(FabricDependencyType.toDependencyType(FabricDependencyType.SUGGESTS)).toBe(DependencyType.OPTIONAL); + }); + + test("returns undefined for unknown values", () => { + expect(FabricDependencyType.toDependencyType("" as FabricDependencyType)).toBeUndefined(); + }); + }); + + describe("fromDependencyType", () => { + test("converts DependencyType to FabricDependencyType", () => { + expect(FabricDependencyType.fromDependencyType(DependencyType.CONFLICTING)).toBe(FabricDependencyType.CONFLICTS); + expect(FabricDependencyType.fromDependencyType(DependencyType.EMBEDDED)).toBe(FabricDependencyType.INCLUDES); + expect(FabricDependencyType.fromDependencyType(DependencyType.INCOMPATIBLE)).toBe(FabricDependencyType.BREAKS); + expect(FabricDependencyType.fromDependencyType(DependencyType.OPTIONAL)).toBe(FabricDependencyType.SUGGESTS); + expect(FabricDependencyType.fromDependencyType(DependencyType.RECOMMENDED)).toBe(FabricDependencyType.RECOMMENDS); + expect(FabricDependencyType.fromDependencyType(DependencyType.REQUIRED)).toBe(FabricDependencyType.DEPENDS); + }); + + test("returns undefined for unknown values", () => { + expect(FabricDependencyType.fromDependencyType("" as DependencyType)).toBeUndefined(); + }); + }); + + describe("parse", () => { + test("parses all its own formatted values", () => { + for (const value of FabricDependencyType.values()) { + expect(FabricDependencyType.parse(FabricDependencyType.format(value))).toBe(value); + } + }); + + test("parses all friendly names of its own values", () => { + for (const value of FabricDependencyType.values()) { + expect(FabricDependencyType.parse(FabricDependencyType.friendlyNameOf(value))).toBe(value); + } + }); + + test("parses all its own formatted values in lowercase", () => { + for (const value of FabricDependencyType.values()) { + expect(FabricDependencyType.parse(FabricDependencyType.format(value).toLowerCase())).toBe(value); + } + }); + + test("parses all its own formatted values in UPPERCASE", () => { + for (const value of FabricDependencyType.values()) { + expect(FabricDependencyType.parse(FabricDependencyType.format(value).toUpperCase())).toBe(value); + } + }); + }); +});