diff --git a/src/utils/java/java-version.ts b/src/utils/java/java-version.ts new file mode 100644 index 0000000..944d445 --- /dev/null +++ b/src/utils/java/java-version.ts @@ -0,0 +1,91 @@ +/** + * Represents a Java version. + */ +export class JavaVersion { + /** + * The name of the Java version. + */ + private readonly _name: string; + + /** + * The version number of the Java version. + */ + private readonly _versionNumber: number; + + /** + * Creates a new {@link JavaVersion} instance. + * + * @param versionNumber - The version number of the Java version. + */ + constructor(versionNumber: number) { + this._name = `Java ${versionNumber}`; + this._versionNumber = versionNumber; + } + + /** + * Parses a Java version from a string. + * + * @param java - The string representation of the Java version. + * + * @returns A {@link JavaVersion} instance, or `undefined` if the string cannot be parsed. + */ + static parse(java: string): JavaVersion | undefined { + if (!java) { + return undefined; + } + + const match = java.match(/(\d+)\s*$/); + if (!match) { + return undefined; + } + + return new JavaVersion(+match[1]); + } + + /** + * Casts the given value to a {@link JavaVersion} instance. + * + * @param java - The string representation of the Java version, its version number, or a {@link JavaVersion} instance. + * + * @returns A {@link JavaVersion} instance, or `undefined` if the input could not be casted to such. + */ + static of(java: string | number | JavaVersion): JavaVersion | undefined { + if (java instanceof JavaVersion) { + return java; + } + + if (typeof java === "number") { + return new JavaVersion(java); + } + + return JavaVersion.parse(String(java)); + } + + /** + * Gets the name of the Java version, e.g., "Java 8". + */ + get name(): string { + return this._name; + } + + /** + * Gets the version number of the Java version, e.g., 8 for Java 8. + */ + get versionNumber(): number { + return this._versionNumber; + } + + /** + * Returns the string representation of the Java version. + */ + toString(): string { + return this._name; + } + + /** + * Returns the string representation of the Java version. + */ + toJSON(): string { + return this._name; + } +} diff --git a/tests/unit/utils/java/java-version.spec.ts b/tests/unit/utils/java/java-version.spec.ts new file mode 100644 index 0000000..11df758 --- /dev/null +++ b/tests/unit/utils/java/java-version.spec.ts @@ -0,0 +1,95 @@ +import { JavaVersion } from "@/utils/java"; + +describe("JavaVersion", () => { + describe("constructor", () => { + test("constructs a new instance with the given version number", () => { + const javaVersion = new JavaVersion(8); + + expect(javaVersion.versionNumber).toBe(8); + expect(javaVersion.name).toBe("Java 8"); + }); + }); + + describe("parse", () => { + test("returns a JavaVersion instance when given a valid string", () => { + const validInputs = ["Java 8", "Java 1.8", "java 1.8", "1.8", "8"]; + + for (const input of validInputs) { + const javaVersion = JavaVersion.parse(input); + + expect(javaVersion).toBeDefined(); + expect(javaVersion.versionNumber).toBe(8); + expect(javaVersion.name).toBe("Java 8"); + } + }); + + test("returns undefined when given an invalid string", () => { + const invalidInputs = ["Java", "1.abc", "abc"]; + + for (const input of invalidInputs) { + const javaVersion = JavaVersion.parse(input); + + expect(javaVersion).toBeUndefined(); + } + }); + + test("returns undefined when given null or undefined", () => { + expect(JavaVersion.parse(null)).toBeUndefined(); + expect(JavaVersion.parse(undefined)).toBeUndefined(); + }); + }); + + describe("of", () => { + test("returns a JavaVersion instance as is", () => { + const javaVersion1 = new JavaVersion(8); + const javaVersion2 = JavaVersion.of(javaVersion1); + + expect(javaVersion2).toBe(javaVersion1); + }); + + test("returns a JavaVersion instance when given a number", () => { + const javaVersion = JavaVersion.of(8); + + expect(javaVersion).toBeDefined(); + expect(javaVersion.versionNumber).toBe(8); + expect(javaVersion.name).toBe("Java 8"); + }); + + test("returns a JavaVersion instance when given a valid string", () => { + const javaVersion = JavaVersion.of("Java 16"); + + expect(javaVersion).toBeDefined(); + expect(javaVersion.versionNumber).toBe(16); + expect(javaVersion.name).toBe("Java 16"); + }); + + test("returns undefined when given an invalid input", () => { + const invalidInputs = ["Java", "1.abc", "abc"]; + + for (const input of invalidInputs) { + const javaVersion = JavaVersion.of(input); + + expect(javaVersion).toBeUndefined(); + } + }); + + test("returns undefined when given null or undefined", () => { + expect(JavaVersion.of(null)).toBeUndefined(); + expect(JavaVersion.of(undefined)).toBeUndefined(); + }); + }); + + describe("toString", () => { + test("returns the string representation of the Java version", () => { + const javaVersion = new JavaVersion(8); + + expect(javaVersion.toString()).toBe("Java 8"); + }); + }); + + test("should be converted to JSON as a Java version string", () => { + const javaVersion = new JavaVersion(11); + + expect(JSON.stringify(javaVersion)).toBe("\"Java 11\""); + }); +});