1
0

Mixins.spec.ts 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. import { describe, it, expect } from "vitest";
  2. import { Mixins } from "./Mixins.js";
  3. describe("Mixins", () => {
  4. //#region base
  5. it("Base resolution", () => {
  6. const mixins = new Mixins<{
  7. foo: (v: number, ctx: { a: number }) => number;
  8. }>({ autoIncrementPriority: true });
  9. mixins.add("foo", (v) => v ^ 0b0001); // 1 (prio 0)
  10. mixins.add("foo", (v) => v ^ 0b1000); // 2 (prio 1)
  11. mixins.add("foo", (v, c) => v ^ c.a); // 3 (prio 2)
  12. // input: 0b1100
  13. // 1: 0b1100 ^ 0b0001 = 0b1101
  14. // 2: 0b1101 ^ 0b1000 = 0b0101
  15. // 3: 0b0101 ^ 0b0100 = 0b0001
  16. // result: 0b0001 = 1
  17. expect(mixins.resolve("foo", 0b1100, { a: 0b0100 })).toBe(1);
  18. expect(mixins.list()).toHaveLength(3);
  19. expect(mixins.list().every(m => m.key === "foo")).toBe(true);
  20. });
  21. //#region priority
  22. it("Priority resolution", () => {
  23. const mixins = new Mixins<{
  24. foo: (v: number) => number;
  25. }>();
  26. mixins.add("foo", (v) => v / 2, 1); // 2 (prio 1)
  27. mixins.add("foo", (v) => Math.round(Math.log(v) * 10), -1); // 4 (prio -1)
  28. mixins.add("foo", (v) => Math.pow(v, 2)); // 3 (prio 0)
  29. mixins.add("foo", (v) => Math.sqrt(v), Number.MAX_SAFE_INTEGER); // 1 (prio max)
  30. // input: 100
  31. // 1: sqrt(100) = 10
  32. // 2: 10 / 2 = 5
  33. // 3: 5 ^ 2 = 25
  34. // 4: round(log(25) * 10) = round(32.188758248682006) = 32
  35. // result: 3
  36. expect(mixins.resolve("foo", 100)).toBe(32);
  37. });
  38. //#region sync/async & cleanup
  39. it("Sync/async resolution & cleanup", async () => {
  40. const acAll = new AbortController();
  41. const mixins = new Mixins<{
  42. foo: (v: number) => Promise<number>;
  43. }>({
  44. defaultSignal: acAll.signal,
  45. });
  46. const ac1 = new AbortController();
  47. mixins.add("foo", (v) => Math.sqrt(v), { signal: ac1.signal }); // 1 (prio 0, index 0)
  48. mixins.add("foo", (v) => Math.pow(v, 4)); // 2 (prio 0, index 1)
  49. const rem3 = mixins.add("foo", async (v) => { // 3 (prio 0, index 2)
  50. await new Promise((r) => setTimeout(r, 50));
  51. return v + 2;
  52. });
  53. const rem4 = mixins.add("foo", async (v) => v); // 4 (prio 0, index 3)
  54. const res1 = mixins.resolve("foo", 100);
  55. expect(res1).toBeInstanceOf(Promise);
  56. expect(await res1).toBe(10002);
  57. rem3();
  58. rem4();
  59. const res2 = mixins.resolve("foo", 100);
  60. expect(res2).not.toBeInstanceOf(Promise);
  61. expect(res2).toBe(10000);
  62. ac1.abort();
  63. const res3 = mixins.resolve("foo", 100);
  64. expect(res3).not.toBeInstanceOf(Promise);
  65. expect(res3).toBe(100000000);
  66. acAll.abort();
  67. const res4 = mixins.resolve("foo", 100);
  68. expect(res4).not.toBeInstanceOf(Promise);
  69. expect(res4).toBe(100);
  70. });
  71. });