time.test.ts 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. import { describe, expect, it } from "vitest";
  2. import { ContentRegistry, TimeSystem, World, WorldEventBus, type TimeDef } from "../src/index.js";
  3. function setup() {
  4. const registry = new ContentRegistry();
  5. const world = new World();
  6. const events = new WorldEventBus();
  7. const timeDef: TimeDef = {
  8. id: "default",
  9. dayLengthTicks: 4,
  10. seasons: [
  11. { name: "spring", dayCount: 3 },
  12. { name: "summer", dayCount: 3 },
  13. ],
  14. start: { day: 1, season: "spring" },
  15. };
  16. registry.register("time", timeDef);
  17. const ts = new TimeSystem();
  18. ts.init({ world, registry, events });
  19. return { ts, events };
  20. }
  21. describe("TimeSystem", () => {
  22. it("starts from the TimeDef start state", () => {
  23. const { ts } = setup();
  24. expect(ts.get()).toEqual({ day: 1, season: "spring", tickInDay: 0 });
  25. });
  26. it("advance across a day boundary emits day-start", () => {
  27. const { ts, events } = setup();
  28. const seen: unknown[] = [];
  29. events.on("day-start", (p) => seen.push(p));
  30. ts.advance(3);
  31. expect(seen).toHaveLength(0);
  32. expect(ts.get()).toEqual({ day: 1, season: "spring", tickInDay: 3 });
  33. ts.advance(1);
  34. expect(seen).toHaveLength(1);
  35. expect(seen[0]).toEqual({ day: 2, season: "spring" });
  36. expect(ts.get()).toEqual({ day: 2, season: "spring", tickInDay: 0 });
  37. });
  38. it("advance across a season boundary emits season-change", () => {
  39. const { ts, events } = setup();
  40. const seen: unknown[] = [];
  41. events.on("season-change", (p) => seen.push(p));
  42. ts.advance(4 * 3);
  43. expect(seen).toHaveLength(1);
  44. expect(seen[0]).toEqual({ day: 1, season: "summer" });
  45. expect(ts.get()).toEqual({ day: 1, season: "summer", tickInDay: 0 });
  46. });
  47. it("advance across a season boundary also emits day-start for the new day", () => {
  48. const { ts, events } = setup();
  49. const days: unknown[] = [];
  50. const seasons: unknown[] = [];
  51. events.on("day-start", (p) => days.push(p));
  52. events.on("season-change", (p) => seasons.push(p));
  53. ts.advance(4 * 3);
  54. expect(seasons).toHaveLength(1);
  55. expect(days).toHaveLength(3);
  56. expect(days[2]).toEqual({ day: 1, season: "summer" });
  57. });
  58. it("set jumps directly without emitting", () => {
  59. const { ts, events } = setup();
  60. const seen: unknown[] = [];
  61. events.on("day-start", (p) => seen.push(p));
  62. events.on("season-change", (p) => seen.push(p));
  63. ts.set(10, "winter");
  64. expect(ts.get()).toEqual({ day: 10, season: "winter", tickInDay: 0 });
  65. expect(seen).toHaveLength(0);
  66. });
  67. });