2021-09-25 08:44:49 -04:00
|
|
|
import { describe, test, expect, beforeAll, afterAll } from "@jest/globals";
|
|
|
|
import { setupInput, unsetInput } from "./utils/input-utils";
|
2022-06-07 08:58:13 -04:00
|
|
|
import { getInputAsObject, mapStringInput, mapObjectInput, mapNumberInput, mapBooleanInput, mapEnumInput } from "../src/utils/input-utils";
|
2022-06-06 11:09:45 -04:00
|
|
|
|
|
|
|
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"
|
|
|
|
};
|
2021-09-25 08:44:49 -04:00
|
|
|
|
|
|
|
describe("getInputAsObject", () => {
|
2022-06-06 11:09:45 -04:00
|
|
|
beforeAll(() => setupInput(defaultInput));
|
2021-09-25 08:44:49 -04:00
|
|
|
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");
|
|
|
|
});
|
2021-12-11 07:21:24 -05:00
|
|
|
|
|
|
|
test("special case for GitHub Actions: ${undefined} transforms into undefined", () => {
|
|
|
|
const input = getInputAsObject();
|
|
|
|
expect(input.undefined).toBeUndefined();
|
|
|
|
});
|
2021-09-25 08:44:49 -04:00
|
|
|
});
|
2022-06-06 11:09:45 -04:00
|
|
|
|
|
|
|
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);
|
|
|
|
});
|
|
|
|
});
|
2022-06-07 08:58:13 -04:00
|
|
|
|
|
|
|
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);
|
|
|
|
});
|
|
|
|
});
|