tests: use node:test (#210)
All checks were successful
Publish latest version / build (push) Successful in 2m11s

Close #201

Tests run much faster and we don't need as much as libs

Reviewed-on: #210
Co-authored-by: Mylloon <kennel.anri@tutanota.com>
Co-committed-by: Mylloon <kennel.anri@tutanota.com>
This commit is contained in:
Mylloon 2024-12-14 11:43:09 +01:00 committed by Mylloon
parent 884d62ceed
commit a790ddf377
Signed by: Forgejo
GPG key ID: E72245C752A07631
15 changed files with 930 additions and 3581 deletions

View file

@ -293,11 +293,14 @@ Il est souhaité d'écrire des tests quand cela est possible.
```ts ```ts
import { fnReturnsTrue } from "../src/utils/file"; import { fnReturnsTrue } from "../src/utils/file";
import { describe, it } from "node:test";
import assert from "node:assert/strict";
describe("test name", () => { describe("test name", () => {
{ {
const name = "to be tested"; const name = "to be tested";
test(name, () => { it(name, () => {
expect(fnReturnsTrue() /* function to test */).toBe(true /* expected result */); assert.strictEqual(fnReturnsTrue() /* function to test */, true /* expected result */);
}); });
} }
}); });

3729
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -10,7 +10,7 @@
"lint": "npx eslint src", "lint": "npx eslint src",
"format-check": "npx prettier --check src", "format-check": "npx prettier --check src",
"format-write": "npx prettier --write src", "format-write": "npx prettier --write src",
"test": "npx jest" "test": "node --import tsx --test **/*.test.ts"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
@ -31,16 +31,11 @@
"uuid": "^11.0.3" "uuid": "^11.0.3"
}, },
"devDependencies": { "devDependencies": {
"@types/jest": "~29.5.14",
"@typescript-eslint/eslint-plugin": "~8.17.0", "@typescript-eslint/eslint-plugin": "~8.17.0",
"@typescript-eslint/parser": "~8.17.0", "@typescript-eslint/parser": "~8.17.0",
"dotenv": "~16.4.7", "dotenv": "~16.4.7",
"jest": "~29.7.0",
"prettier-eslint": "~16.3.0", "prettier-eslint": "~16.3.0",
"ts-jest": "~29.2.5", "ts-node-dev": "~2.0.0",
"ts-node-dev": "~2.0.0" "tsx": "^4.19.2"
},
"jest": {
"preset": "ts-jest"
} }
} }

View file

@ -1,34 +0,0 @@
import "../../modules/string";
describe("Capitalize", () => {
{
const name = "test";
test(name, () => {
expect(name.capitalize()).toBe("Test");
});
}
{
const name = "MACHIN";
test(name, () => {
expect(name.capitalize()).toBe("MACHIN");
});
}
{
const name = "tRUC";
test(name, () => {
expect(name.capitalize()).toBe("TRUC");
});
}
{
const name = "Super";
test(name, () => {
expect(name.capitalize()).toBe("Super");
});
}
{
const name = "";
test(name, () => {
expect(name.capitalize()).toBe("");
});
}
});

View file

@ -1,28 +0,0 @@
import { OptionReminder, splitTime } from "../../../utils/commands/reminder";
describe("Time splitter", () => {
{
const name = "";
test(name, () => {
expect(splitTime(name)).toStrictEqual({ option: OptionReminder.Nothing, time: "" });
});
}
{
const name = "2m@p";
test(name, () => {
expect(splitTime(name)).toStrictEqual({ option: OptionReminder.DirectMessage, time: "2m" });
});
}
{
const name = "41@";
test(name, () => {
expect(splitTime(name)).toStrictEqual({ option: OptionReminder.Mention, time: "41" });
});
}
{
const name = "0P";
test(name, () => {
expect(splitTime(name)).toStrictEqual({ option: OptionReminder.DirectMessage, time: "0" });
});
}
});

View file

@ -1,151 +0,0 @@
import {
cleanCodeBlock,
emojiPng,
isImage,
removeExtension,
splitFilenameExtensions,
} from "../../utils/misc";
describe("Filename splitter", () => {
{
const name = "test.js";
test(name, () => {
expect(splitFilenameExtensions(name)).toStrictEqual({ file: "test", ext: "js" });
});
}
{
const name = ".env";
test(name, () => {
expect(splitFilenameExtensions(name)).toStrictEqual({ file: ".env", ext: undefined });
});
}
{
const name = ".env.test";
test(name, () => {
expect(splitFilenameExtensions(name)).toStrictEqual({
file: ".env",
ext: "test",
});
});
}
{
const name = "file.test.js";
test(name, () => {
expect(splitFilenameExtensions(name)).toStrictEqual({ file: "file.test", ext: "js" });
});
}
});
describe("Extension remover", () => {
{
const name = "test.js";
test(name, () => {
expect(removeExtension(name)).toBe("test");
});
}
{
const name = ".env";
test(name, () => {
expect(removeExtension(name)).toBe(".env");
});
}
{
const name = ".env.test";
test(name, () => {
expect(removeExtension(name)).toBe(".env");
});
}
{
const name = "file.test.js";
test(name, () => {
expect(removeExtension(name)).toBe("file.test");
});
}
});
describe("Image checker", () => {
{
const name = "image.Png";
test(name, () => {
expect(isImage(name)).toBe(true);
});
}
{
const name = "image.jpeg";
test(name, () => {
expect(isImage(name)).toBe(true);
});
}
{
const name = "image.wav";
test(name, () => {
expect(isImage(name)).toBe(false);
});
}
{
const name = "image.jpg";
test(name, () => {
expect(isImage(name)).toBe(true);
});
}
{
const name = "image.webP";
test(name, () => {
expect(isImage(name)).toBe(true);
});
}
{
const name = "image.GIF";
test(name, () => {
expect(isImage(name)).toBe(true);
});
}
});
describe("Code block cleaner", () => {
{
const name = "salut";
test(name, () => {
expect(cleanCodeBlock(name)).toBe("`salut`");
});
}
{
const name = "<@158260864623968257> ça va ?";
test(name, () => {
expect(cleanCodeBlock(name)).toBe("<@158260864623968257>` ça va ?`");
});
}
{
const name = "t'as vu la vidéo ? https://youtu.be/dQw4w9WgXcQ";
test(name, () => {
expect(cleanCodeBlock(name)).toBe("`t'as vu la vidéo ? `https://youtu.be/dQw4w9WgXcQ");
});
}
{
const name = "t'as vu la vidéo ? https://youtu.be/dQw4w9WgXcQ elle est cool en vrai tqt";
test(name, () => {
expect(cleanCodeBlock(name)).toBe(
"`t'as vu la vidéo ? `https://youtu.be/dQw4w9WgXcQ` elle est cool en vrai tqt`",
);
});
}
});
describe("Emoji to link", () => {
{
const name = "☺️";
test(name, () => {
expect(emojiPng(name)).toBe(
"https://cdn.jsdelivr.net/gh/twitter/twemoji/assets/72x72/263a.png",
);
});
}
{
const name = "🍕";
test(name, () => {
expect(emojiPng(name)).toBe(
"https://cdn.jsdelivr.net/gh/twitter/twemoji/assets/72x72/1f355.png",
);
});
}
});

View file

@ -1,26 +0,0 @@
import { RegexC, RegExpFlags } from "../../utils/regex";
describe("Regex flags", () => {
test("One parameter", () => {
const regex = RegexC("", RegExpFlags.Global);
expect(regex.global).toBeTruthy();
});
test("All parameters", () => {
const regex = RegexC(
"",
RegExpFlags.Global |
RegExpFlags.MultiLine |
RegExpFlags.Insensitive |
RegExpFlags.Sticky |
RegExpFlags.Unicode |
RegExpFlags.SingleLine,
);
expect(regex.global).toBeTruthy();
expect(regex.multiline).toBeTruthy();
expect(regex.ignoreCase).toBeTruthy();
expect(regex.sticky).toBeTruthy();
expect(regex.unicode).toBeTruthy();
expect(regex.dotAll).toBeTruthy();
});
});

View file

@ -1,120 +0,0 @@
import {
nextTimeUnit,
showDate,
strToSeconds,
timeDeltaToString,
TimeSecond,
} from "../../utils/time";
describe("Date with correct timezone", () => {
const map = new Map([["u_time_at", "@"]]);
const date = new Date(1727434767686);
{
const name = "fr";
test(name, () => {
expect(showDate(name, map, date)).toBe("27/09/2024 @ 12:59:27");
});
}
{
const name = "en-US";
test(name, () => {
expect(showDate(name, map, date)).toBe("9/27/24, @ 1:59:27");
});
}
{
const name = "unknown";
// Depends on the system
// The important is that the date is in the correct timezone (UTC)
test(name, () => {
expect(["27/09/2024 @ 10:59:27", "9/27/24, @ 10:59:27"]).toContain(showDate(name, map, date));
});
}
{
const name = "zh-CN";
test(name, () => {
expect(showDate(name, map, date)).toBe("2024/9/27 @ 18:59:27");
});
}
});
describe("String time to seconds", () => {
{
const name = "10m30";
test(name, () => {
expect(strToSeconds(name)).toBe(630);
});
}
{
const name = "12h30";
test(name, () => {
expect(strToSeconds(name)).toBe(45000);
});
}
{
const name = "12s30";
test(name, () => {
expect(strToSeconds(name)).toBe(42);
});
}
{
const name = "1w30h20";
test(name, () => {
expect(strToSeconds(name)).toBe(714000);
});
}
});
describe("Next time unit", () => {
{
const name = TimeSecond.Minute;
test(name.toString(), () => {
expect(nextTimeUnit(name)).toBe(TimeSecond.Second);
});
}
{
const name = TimeSecond.Hour;
test(name.toString(), () => {
expect(nextTimeUnit(name)).toBe(TimeSecond.Minute);
});
}
{
const name = TimeSecond.Second;
test(name.toString(), () => {
expect(nextTimeUnit(name)).toBe(TimeSecond.Second);
});
}
{
const name = TimeSecond.Year;
test(name.toString(), () => {
expect(nextTimeUnit(name)).toBe(TimeSecond.Week);
});
}
});
describe("Relative time", () => {
// Thoses tests are based on time, we have 10s of acceptance.
{
const name = Date.now() + (10 * TimeSecond.Minute + 30) * 1000;
test(name.toString(), () => {
expect(timeDeltaToString(name)).toMatch(/10m 30s|10m 2\ds/);
});
}
{
const name = Date.now() + (12 * TimeSecond.Hour + 30 * TimeSecond.Minute) * 1000;
test(name.toString(), () => {
expect(timeDeltaToString(name)).toMatch(/12h 30m|12h 29m 5\ds/);
});
}
{
const name = Date.now() + (TimeSecond.Week + TimeSecond.Day + 6 * TimeSecond.Hour) * 1000;
test(name.toString(), () => {
expect(timeDeltaToString(name)).toMatch(/1w 1d 6h|1w 1d 5h 59m 5\ds/);
});
}
{
const name = Date.now();
test(name.toString(), () => {
expect(timeDeltaToString(name)).toMatch(/\ds/);
});
}
});

View file

@ -0,0 +1,36 @@
import "../../src/modules/string";
import { describe, it } from "node:test";
import assert from "node:assert/strict";
describe("Capitalize", () => {
{
const name = "test";
it(name, () => {
assert.strictEqual(name.capitalize(), "Test");
});
}
{
const name = "MACHIN";
it(name, () => {
assert.strictEqual(name.capitalize(), "MACHIN");
});
}
{
const name = "tRUC";
it(name, () => {
assert.strictEqual(name.capitalize(), "TRUC");
});
}
{
const name = "Super";
it(name, () => {
assert.strictEqual(name.capitalize(), "Super");
});
}
{
it("Empty string", () => {
assert.strictEqual("".capitalize(), "");
});
}
});

View file

@ -0,0 +1,30 @@
import { OptionReminder, splitTime } from "../../../src/utils/commands/reminder";
import { describe, it } from "node:test";
import assert from "node:assert/strict";
describe("Time splitter", () => {
{
it("Empty String", () => {
assert.deepStrictEqual(splitTime(""), { option: OptionReminder.Nothing, time: "" });
});
}
{
const name = "2m@p";
it(name, () => {
assert.deepStrictEqual(splitTime(name), { option: OptionReminder.DirectMessage, time: "2m" });
});
}
{
const name = "41@";
it(name, () => {
assert.deepStrictEqual(splitTime(name), { option: OptionReminder.Mention, time: "41" });
});
}
{
const name = "0P";
it(name, () => {
assert.deepStrictEqual(splitTime(name), { option: OptionReminder.DirectMessage, time: "0" });
});
}
});

View file

@ -1,5 +1,8 @@
import { Attachment, Collection, EmbedBuilder } from "discord.js"; import { Attachment, Collection, EmbedBuilder } from "discord.js";
import { handleAttachments } from "../../../utils/events/citation"; import { handleAttachments } from "../../../src/utils/events/citation";
import { describe, it } from "node:test";
import assert from "node:assert/strict";
/** /**
* Generate a new random string * Generate a new random string
@ -17,7 +20,7 @@ describe("Attachements Handler", () => {
const max_field = Array.from({ length: max }, () => "[f](url)").join(", "); const max_field = Array.from({ length: max }, () => "[f](url)").join(", ");
{ {
const name = "One image"; const name = "One image";
test(name, () => { it(name, () => {
const embedExpected = new EmbedBuilder(); const embedExpected = new EmbedBuilder();
embedExpected.setImage("http://url"); embedExpected.setImage("http://url");
@ -28,12 +31,12 @@ describe("Attachements Handler", () => {
new Collection([[newKey(), { name: "image.png", url: "http://url" } as Attachment]]), new Collection([[newKey(), { name: "image.png", url: "http://url" } as Attachment]]),
); );
expect(embedTest).toStrictEqual(embedExpected); assert.deepStrictEqual(embedTest, embedExpected);
}); });
} }
{ {
const name = "Two images"; const name = "Two images";
test(name, () => { it(name, () => {
const embedExpected = new EmbedBuilder(); const embedExpected = new EmbedBuilder();
embedExpected.addFields({ embedExpected.addFields({
name: "yes_s", name: "yes_s",
@ -50,12 +53,12 @@ describe("Attachements Handler", () => {
]), ]),
); );
expect(embedTest).toStrictEqual(embedExpected); assert.deepStrictEqual(embedTest, embedExpected);
}); });
} }
{ {
const name = "One link"; const name = "One link";
test(name, () => { it(name, () => {
const embedExpected = new EmbedBuilder(); const embedExpected = new EmbedBuilder();
embedExpected.addFields({ name: "no_s", value: "[f](url)" }); embedExpected.addFields({ name: "no_s", value: "[f](url)" });
@ -66,12 +69,12 @@ describe("Attachements Handler", () => {
new Collection([[newKey(), { name: "f", url: "url" } as Attachment]]), new Collection([[newKey(), { name: "f", url: "url" } as Attachment]]),
); );
expect(embedTest).toStrictEqual(embedExpected); assert.deepStrictEqual(embedTest, embedExpected);
}); });
} }
{ {
const name = "Two files"; const name = "Two files";
test(name, () => { it(name, () => {
const embedExpected = new EmbedBuilder(); const embedExpected = new EmbedBuilder();
embedExpected.addFields({ name: "yes_s", value: "[f](url), [f](url)" }); embedExpected.addFields({ name: "yes_s", value: "[f](url), [f](url)" });
@ -85,12 +88,12 @@ describe("Attachements Handler", () => {
]), ]),
); );
expect(embedTest).toStrictEqual(embedExpected); assert.deepStrictEqual(embedTest, embedExpected);
}); });
} }
{ {
const name = "Two fields with multiples files each"; const name = "Two fields with multiples files each";
test(name, () => { it(name, () => {
const total = 150; const total = 150;
const embedExpected = new EmbedBuilder(); const embedExpected = new EmbedBuilder();
@ -114,12 +117,12 @@ describe("Attachements Handler", () => {
), ),
); );
expect(embedTest).toStrictEqual(embedExpected); assert.deepStrictEqual(embedTest, embedExpected);
}); });
} }
{ {
const name = "Two fields with one field with one element"; const name = "Two fields with one field with one element";
test(name, () => { it(name, () => {
const total = 103; const total = 103;
const embedExpected = new EmbedBuilder(); const embedExpected = new EmbedBuilder();
@ -143,7 +146,7 @@ describe("Attachements Handler", () => {
), ),
); );
expect(embedTest).toStrictEqual(embedExpected); assert.deepStrictEqual(embedTest, embedExpected);
}); });
} }
}); });

154
tests/utils/misc.test.ts Normal file
View file

@ -0,0 +1,154 @@
import {
cleanCodeBlock,
emojiPng,
isImage,
removeExtension,
splitFilenameExtensions,
} from "../../src/utils/misc";
import { describe, it } from "node:test";
import assert from "node:assert/strict";
describe("Filename splitter", () => {
{
const name = "test.js";
it(name, () => {
assert.deepStrictEqual(splitFilenameExtensions(name), { file: "test", ext: "js" });
});
}
{
const name = ".env";
it(name, () => {
assert.deepStrictEqual(splitFilenameExtensions(name), { file: ".env", ext: undefined });
});
}
{
const name = ".env.test";
it(name, () => {
assert.deepStrictEqual(splitFilenameExtensions(name), { file: ".env", ext: "test" });
});
}
{
const name = "file.test.js";
it(name, () => {
assert.deepStrictEqual(splitFilenameExtensions(name), { file: "file.test", ext: "js" });
});
}
});
describe("Extension remover", () => {
{
const name = "test.js";
it(name, () => {
assert.strictEqual(removeExtension(name), "test");
});
}
{
const name = ".env";
it(name, () => {
assert.strictEqual(removeExtension(name), ".env");
});
}
{
const name = ".env.test";
it(name, () => {
assert.strictEqual(removeExtension(name), ".env");
});
}
{
const name = "file.test.js";
it(name, () => {
assert.strictEqual(removeExtension(name), "file.test");
});
}
});
describe("Image checker", () => {
{
const name = "image.Png";
it(name, () => {
assert.strictEqual(isImage(name), true);
});
}
{
const name = "image.jpeg";
it(name, () => {
assert.strictEqual(isImage(name), true);
});
}
{
const name = "image.wav";
it(name, () => {
assert.strictEqual(isImage(name), false);
});
}
{
const name = "image.jpg";
it(name, () => {
assert.strictEqual(isImage(name), true);
});
}
{
const name = "image.webP";
it(name, () => {
assert.strictEqual(isImage(name), true);
});
}
{
const name = "image.GIF";
it(name, () => {
assert.strictEqual(isImage(name), true);
});
}
});
describe("Code block cleaner", () => {
{
const name = "salut";
it(name, () => {
assert.strictEqual(cleanCodeBlock(name), "`salut`");
});
}
{
const name = "<@158260864623968257> ça va ?";
it(name, () => {
assert.strictEqual(cleanCodeBlock(name), "<@158260864623968257>` ça va ?`");
});
}
{
const name = "t'as vu la vidéo ? https://youtu.be/dQw4w9WgXcQ";
it(name, () => {
assert.strictEqual(cleanCodeBlock(name), "`t'as vu la vidéo ? `https://youtu.be/dQw4w9WgXcQ");
});
}
{
const name = "t'as vu la vidéo ? https://youtu.be/dQw4w9WgXcQ elle est cool en vrai tqt";
it(name, () => {
assert.strictEqual(
cleanCodeBlock(name),
"`t'as vu la vidéo ? `https://youtu.be/dQw4w9WgXcQ` elle est cool en vrai tqt`",
);
});
}
});
describe("Emoji to link", () => {
{
const name = "☺️";
it(name, () => {
assert.strictEqual(
emojiPng(name),
"https://cdn.jsdelivr.net/gh/twitter/twemoji/assets/72x72/263a.png",
);
});
}
{
const name = "🍕";
it(name, () => {
assert.strictEqual(
emojiPng(name),
"https://cdn.jsdelivr.net/gh/twitter/twemoji/assets/72x72/1f355.png",
);
});
}
});

29
tests/utils/regex.test.ts Normal file
View file

@ -0,0 +1,29 @@
import { RegexC, RegExpFlags } from "../../src/utils/regex";
import { describe, it } from "node:test";
import assert from "node:assert/strict";
describe("Regex flags", () => {
it("One parameter", () => {
const regex = RegexC("", RegExpFlags.Global);
assert.strictEqual(regex.global, true);
});
it("All parameters", () => {
const regex = RegexC(
"",
RegExpFlags.Global |
RegExpFlags.MultiLine |
RegExpFlags.Insensitive |
RegExpFlags.Sticky |
RegExpFlags.Unicode |
RegExpFlags.SingleLine,
);
assert.strictEqual(regex.global, true);
assert.strictEqual(regex.multiline, true);
assert.strictEqual(regex.ignoreCase, true);
assert.strictEqual(regex.sticky, true);
assert.strictEqual(regex.unicode, true);
assert.strictEqual(regex.dotAll, true);
});
});

125
tests/utils/time.test.ts Normal file
View file

@ -0,0 +1,125 @@
import {
nextTimeUnit,
showDate,
strToSeconds,
timeDeltaToString,
TimeSecond,
} from "../../src/utils/time";
import { describe, it } from "node:test";
import assert from "node:assert/strict";
describe("Date with correct timezone", () => {
const map = new Map([["u_time_at", "@"]]);
const date = new Date(1727434767686);
{
const name = "fr";
it(name, () => {
assert.strictEqual(showDate(name, map, date), "27/09/2024 @ 12:59:27");
});
}
{
const name = "en-US";
it(name, () => {
assert.strictEqual(showDate(name, map, date), "9/27/24, @ 1:59:27");
});
}
{
const name = "unknown";
// Depends on the system
// The important is that the date is in the correct timezone (UTC)
it(name, () => {
assert.ok(
["27/09/2024 @ 10:59:27", "9/27/24, @ 10:59:27"].includes(showDate(name, map, date)),
);
});
}
{
const name = "zh-CN";
it(name, () => {
assert.strictEqual(showDate(name, map, date), "2024/9/27 @ 18:59:27");
});
}
});
describe("String time to seconds", () => {
{
const name = "10m30";
it(name, () => {
assert.strictEqual(strToSeconds(name), 630);
});
}
{
const name = "12h30";
it(name, () => {
assert.strictEqual(strToSeconds(name), 45000);
});
}
{
const name = "12s30";
it(name, () => {
assert.strictEqual(strToSeconds(name), 42);
});
}
{
const name = "1w30h20";
it(name, () => {
assert.strictEqual(strToSeconds(name), 714000);
});
}
});
describe("Next time unit", () => {
{
const name = TimeSecond.Minute;
it(name.toString(), () => {
assert.strictEqual(nextTimeUnit(name), TimeSecond.Second);
});
}
{
const name = TimeSecond.Hour;
it(name.toString(), () => {
assert.strictEqual(nextTimeUnit(name), TimeSecond.Minute);
});
}
{
const name = TimeSecond.Second;
it(name.toString(), () => {
assert.strictEqual(nextTimeUnit(name), TimeSecond.Second);
});
}
{
const name = TimeSecond.Year;
it(name.toString(), () => {
assert.strictEqual(nextTimeUnit(name), TimeSecond.Week);
});
}
});
describe("Relative time", () => {
// Thoses its are based on time, we have 10s of acceptance.
{
const name = Date.now() + (10 * TimeSecond.Minute + 30) * 1000;
it(name.toString(), () => {
assert.match(timeDeltaToString(name), /10m 30s|10m 2\ds/);
});
}
{
const name = Date.now() + (12 * TimeSecond.Hour + 30 * TimeSecond.Minute) * 1000;
it(name.toString(), () => {
assert.match(timeDeltaToString(name), /12h 30m|12h 29m 5\ds/);
});
}
{
const name = Date.now() + (TimeSecond.Week + TimeSecond.Day + 6 * TimeSecond.Hour) * 1000;
it(name.toString(), () => {
assert.match(timeDeltaToString(name), /1w 1d 6h|1w 1d 5h 59m 5\ds/);
});
}
{
const name = Date.now();
it(name.toString(), () => {
assert.match(timeDeltaToString(name), /\ds/);
});
}
});

View file

@ -103,5 +103,5 @@
"skipLibCheck": true /* Skip type checking all .d.ts files. */ "skipLibCheck": true /* Skip type checking all .d.ts files. */
}, },
"include": ["./**/*.ts", "./src/locales/*.json"], "include": ["./**/*.ts", "./src/locales/*.json"],
"exclude": ["./src/tests"] "exclude": ["tests"]
} }