math.spec.ts 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. import { describe, expect, it } from "vitest";
  2. import { bitSetHas, clamp, digitCount, mapRange, randRange, roundFixed } from "./math.js";
  3. //#region clamp
  4. describe("math/clamp", () => {
  5. it("Clamps a value between min and max", () => {
  6. expect(clamp(5, 0, 10)).toBe(5);
  7. expect(clamp(-5, 0, 10)).toBe(0);
  8. expect(clamp(15, 0, 10)).toBe(10);
  9. expect(clamp(Number.MAX_SAFE_INTEGER, 0, Infinity)).toBe(Number.MAX_SAFE_INTEGER);
  10. });
  11. it("Handles edge cases", () => {
  12. expect(clamp(0, 1, 0)).toThrow(TypeError);
  13. // @ts-expect-error
  14. expect(clamp("1", 0, 1)).toThrow(TypeError);
  15. });
  16. });
  17. //#region mapRange
  18. describe("math/mapRange", () => {
  19. it("Maps a value from one range to another", () => {
  20. expect(mapRange(2, 0, 5, 0, 10)).toBe(4);
  21. expect(mapRange(2, 5, 10, 0, 5)).toBe(-3);
  22. expect(mapRange(2, 0, 5, 0, 10)).toBe(4);
  23. expect(mapRange(3, 15, 100)).toBe(20);
  24. });
  25. it("Handles edge cases", () => {
  26. expect(mapRange(0, 0, NaN, 0, 0)).toBe(NaN);
  27. expect(mapRange(NaN, 0, 0)).toBe(NaN);
  28. expect(mapRange(0, 0, 0)).toBe(NaN);
  29. expect(mapRange(Infinity, 10, 1000)).toBe(Infinity);
  30. expect(mapRange(-Infinity, -Infinity, Infinity)).toBe(NaN);
  31. });
  32. });
  33. //#region randRange
  34. describe("math/randRange", () => {
  35. it("Returns a random number between min and max", () => {
  36. const nums: number[] = [];
  37. const startTsA = Date.now();
  38. for(let i = 0; i < 100_000; i++)
  39. nums.push(randRange(0, 10));
  40. const timeA = Date.now() - startTsA;
  41. const startTsB = Date.now();
  42. for(let i = 0; i < 100_000; i++)
  43. nums.push(randRange(10, true));
  44. const timeB = Date.now() - startTsB;
  45. expect(nums.every(n => n >= 0 && n <= 10)).toBe(true);
  46. // about a 5x speed difference
  47. expect(timeA).toBeLessThanOrEqual(75);
  48. expect(timeB).toBeGreaterThanOrEqual(150);
  49. expect(randRange(0, 0)).toBe(0);
  50. expect(randRange(0)).toBe(0);
  51. });
  52. });
  53. //#region digitCount
  54. describe("math/digitCount", () => {
  55. it("Counts the number of digits in a number", () => {
  56. expect(digitCount(0)).toBe(1);
  57. expect(digitCount(1)).toBe(1);
  58. expect(digitCount(10)).toBe(2);
  59. expect(digitCount(100_000_000.000_001)).toBe(15);
  60. expect(digitCount(100_000_000.000_001, false)).toBe(9);
  61. });
  62. it("Handles edge cases", () => {
  63. expect(digitCount(NaN)).toBe(NaN);
  64. expect(digitCount(Infinity)).toBe(Infinity);
  65. });
  66. });
  67. //#region roundFixed
  68. describe("math/roundFixed", () => {
  69. it("Rounds a number to a fixed amount of decimal places", () => {
  70. expect(roundFixed(1234.5678, -1)).toBe(1230);
  71. expect(roundFixed(1234.5678, 0)).toBe(1235);
  72. expect(roundFixed(1234.5678, 1)).toBe(1234.6);
  73. expect(roundFixed(1234.5678, 3)).toBe(1234.568);
  74. expect(roundFixed(1234.5678, 5)).toBe(1234.5678);
  75. });
  76. it("Handles edge cases", () => {
  77. expect(roundFixed(NaN, 0)).toBe(NaN);
  78. expect(roundFixed(1234.5678, NaN)).toBe(NaN);
  79. expect(roundFixed(1234.5678, Infinity)).toBe(NaN);
  80. expect(roundFixed(Infinity, 0)).toBe(Infinity);
  81. });
  82. });
  83. //#region bitSetHas
  84. describe("math/bitSetHas", () => {
  85. it("Checks if a bit is set in a number", () => {
  86. expect(bitSetHas(0b1010, 0b1000)).toBe(true);
  87. expect(bitSetHas(0b1010, 0b0100)).toBe(false);
  88. expect(bitSetHas(0b1010, 0b0010)).toBe(true);
  89. expect(bitSetHas(0b1010, 0b0001)).toBe(false);
  90. expect(bitSetHas(BigInt(0b10), BigInt(0b10))).toBe(true);
  91. expect(bitSetHas(BigInt(0b10), BigInt(0b01))).toBe(false);
  92. });
  93. it("Handles edge cases", () => {
  94. expect(bitSetHas(0, 0)).toBe(true);
  95. expect(bitSetHas(1, 0)).toBe(true);
  96. expect(bitSetHas(0, 1)).toBe(false);
  97. expect(bitSetHas(1, 1)).toBe(true);
  98. expect(bitSetHas(NaN, NaN)).toBe(false);
  99. });
  100. });