|
| 1 | +/** |
| 2 | + * Regression tests for GitHub issue #18 |
| 3 | + * https://github.com/calidy-com/dayjs-calendarsystems/issues/18 |
| 4 | + * |
| 5 | + * Verifies that calling toCalendarSystem() on an instance does NOT |
| 6 | + * mutate global state or affect other dayjs instances. |
| 7 | + */ |
| 8 | +import dayjs from "dayjs"; |
| 9 | +import "dayjs/locale/ar"; |
| 10 | +import calendarSystems from "../src/index"; |
| 11 | +import GregoryCalendarSystem from "../src/calendarSystems/GregoryCalendarSystem"; |
| 12 | +import PersianCalendarSystem from "../src/calendarSystems/PersianCalendarSystem"; |
| 13 | +import HijriCalendarSystem from "../src/calendarSystems/HijriCalendarSystem"; |
| 14 | +import HebrewCalendarSystem from "../src/calendarSystems/HebrewCalendarSystem"; |
| 15 | + |
| 16 | +describe("Instance isolation - GitHub issue #18", () => { |
| 17 | + beforeAll(() => { |
| 18 | + dayjs.extend(calendarSystems); |
| 19 | + dayjs.registerCalendarSystem("gregory", new GregoryCalendarSystem()); |
| 20 | + dayjs.registerCalendarSystem("persian", new PersianCalendarSystem()); |
| 21 | + dayjs.registerCalendarSystem("islamic", new HijriCalendarSystem()); |
| 22 | + dayjs.registerCalendarSystem("hebrew", new HebrewCalendarSystem()); |
| 23 | + }); |
| 24 | + |
| 25 | + test("toCalendarSystem on instance should NOT affect new instances", () => { |
| 26 | + // Create a Gregorian date |
| 27 | + const gregorianDate = dayjs("2023-05-14"); |
| 28 | + expect(gregorianDate.format("MMMM")).toEqual("May"); |
| 29 | + expect(gregorianDate.$C).toBeUndefined(); |
| 30 | + |
| 31 | + // Convert to Islamic calendar |
| 32 | + const islamicDate = gregorianDate.toCalendarSystem("islamic"); |
| 33 | + expect(islamicDate.$C).toEqual("islamic"); |
| 34 | + expect(islamicDate.format("MMMM")).toEqual("Shawwal"); |
| 35 | + |
| 36 | + // Create a NEW dayjs instance - it should still be Gregorian |
| 37 | + const newGregorianDate = dayjs("2023-05-14"); |
| 38 | + expect(newGregorianDate.$C).toBeUndefined(); |
| 39 | + expect(newGregorianDate.format("MMMM")).toEqual("May"); |
| 40 | + }); |
| 41 | + |
| 42 | + test("multiple calendar conversions should not interfere with each other", () => { |
| 43 | + const baseDate = dayjs("2023-05-14"); |
| 44 | + |
| 45 | + // Convert to different calendars |
| 46 | + const persian = baseDate.toCalendarSystem("persian"); |
| 47 | + const islamic = baseDate.toCalendarSystem("islamic"); |
| 48 | + const hebrew = baseDate.toCalendarSystem("hebrew"); |
| 49 | + |
| 50 | + // Each should have its own calendar system |
| 51 | + expect(persian.$C).toEqual("persian"); |
| 52 | + expect(islamic.$C).toEqual("islamic"); |
| 53 | + expect(hebrew.$C).toEqual("hebrew"); |
| 54 | + |
| 55 | + // Each should format with its own month names |
| 56 | + expect(persian.format("MMMM")).toEqual("Ordibehesht"); |
| 57 | + expect(islamic.format("MMMM")).toEqual("Shawwal"); |
| 58 | + expect(hebrew.format("MMMM")).toEqual("Iyar"); |
| 59 | + |
| 60 | + // Original should still be Gregorian |
| 61 | + expect(baseDate.$C).toBeUndefined(); |
| 62 | + expect(baseDate.format("MMMM")).toEqual("May"); |
| 63 | + }); |
| 64 | + |
| 65 | + test("new instances after calendar conversion should be Gregorian", () => { |
| 66 | + // Convert an instance to Islamic |
| 67 | + dayjs("2023-01-15").toCalendarSystem("islamic"); |
| 68 | + |
| 69 | + // Create multiple new instances - all should be Gregorian |
| 70 | + const dates = [ |
| 71 | + dayjs("2023-01-15"), |
| 72 | + dayjs("2023-06-20"), |
| 73 | + dayjs("2023-12-25"), |
| 74 | + ]; |
| 75 | + |
| 76 | + dates.forEach((date) => { |
| 77 | + expect(date.$C).toBeUndefined(); |
| 78 | + expect(date.format("MMMM")).toMatch( |
| 79 | + /^(January|February|March|April|May|June|July|August|September|October|November|December)$/ |
| 80 | + ); |
| 81 | + }); |
| 82 | + }); |
| 83 | + |
| 84 | + test("calendar instance should preserve locale when cloned", () => { |
| 85 | + const islamicDate = dayjs("2023-05-14").toCalendarSystem("islamic"); |
| 86 | + const cloned = islamicDate.clone(); |
| 87 | + |
| 88 | + expect(cloned.$C).toEqual("islamic"); |
| 89 | + expect(cloned.format("MMMM")).toEqual("Shawwal"); |
| 90 | + }); |
| 91 | + |
| 92 | + test("changing locale on calendar instance should update month names", () => { |
| 93 | + const islamicDate = dayjs("2023-04-10").toCalendarSystem("islamic"); |
| 94 | + expect(islamicDate.format("MMMM")).toEqual("Ramadan"); |
| 95 | + |
| 96 | + // Change to Arabic locale |
| 97 | + const arabicIslamicDate = islamicDate.locale("ar"); |
| 98 | + expect(arabicIslamicDate.format("MMMM")).toEqual("رمضان"); |
| 99 | + |
| 100 | + // Original should still have English month names |
| 101 | + expect(islamicDate.format("MMMM")).toEqual("Ramadan"); |
| 102 | + }); |
| 103 | + |
| 104 | + test("factory method vs instance method distinction", () => { |
| 105 | + // Instance method should only affect that instance |
| 106 | + const instance1 = dayjs("2023-05-14"); |
| 107 | + const islamicInstance = instance1.toCalendarSystem("islamic"); |
| 108 | + |
| 109 | + expect(islamicInstance.$C).toEqual("islamic"); |
| 110 | + expect(instance1.$C).toBeUndefined(); |
| 111 | + |
| 112 | + // New instances should still default to Gregorian |
| 113 | + const instance2 = dayjs("2023-05-14"); |
| 114 | + expect(instance2.$C).toBeUndefined(); |
| 115 | + expect(instance2.format("MMMM")).toEqual("May"); |
| 116 | + }); |
| 117 | +}); |
0 commit comments