X-Git-Url: https://git.ladys.computer/Sutra/blobdiff_plain/86748e0641f8c4d833cf2cca4873925a6f6c64e8..8ead025fe221239c198ca31a1d4e03e0318dd54f:/xsd/functions.test.js diff --git a/xsd/functions.test.js b/xsd/functions.test.js new file mode 100644 index 0000000..8692c33 --- /dev/null +++ b/xsd/functions.test.js @@ -0,0 +1,3463 @@ +// ♓️🪡 सूत्र ∷ xsd/functions.test.js +// ==================================================================== +// +// Copyright © 2023 Lady [@ Lady’s Computer]. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at . + +import { + assertAlmostEquals, + assertEquals, + assertObjectMatch, + assertStrictEquals, + assertThrows, + describe, + it, +} from "../dev-deps.js"; +import { + booleanCanonicalMap, + booleanLexicalMap, + dateCanonicalMap, + dateLexicalMap, + dateTimeCanonicalMap, + dateTimeLexicalMap, + dateTimePlusDuration, + dayCanonicalFragmentMap, + dayFragValue, + daysInMonth, + dayTimeDurationCanonicalMap, + dayTimeDurationMap, + decimalCanonicalMap, + decimalLexicalMap, + decimalPtCanonicalMap, + decimalPtMap, + doubleCanonicalMap, + doubleLexicalMap, + durationCanonicalMap, + durationMap, + floatCanonicalMap, + floatLexicalMap, + gDayCanonicalMap, + gDayLexicalMap, + gMonthCanonicalMap, + gMonthDayCanonicalMap, + gMonthDayLexicalMap, + gMonthLexicalMap, + gYearCanonicalMap, + gYearLexicalMap, + gYearMonthCanonicalMap, + gYearMonthLexicalMap, + hexBinaryCanonical, + hexBinaryMap, + hourCanonicalFragmentMap, + hourFragValue, + minuteCanonicalFragmentMap, + minuteFragValue, + monthCanonicalFragmentMap, + monthFragValue, + newDateTime, + noDecimalMap, + noDecimalPtCanonicalMap, + scientificCanonicalMap, + scientificMap, + secondCanonicalFragmentMap, + secondFragValue, + specialRepCanonicalMap, + specialRepValue, + stringCanonicalMap, + stringLexicalMap, + timeCanonicalMap, + timeLexicalMap, + timeOnTimeline, + timezoneCanonicalFragmentMap, + timezoneFragValue, + unsignedDecimalPtCanonicalMap, + unsignedDecimalPtMap, + unsignedNoDecimalMap, + unsignedNoDecimalPtCanonicalMap, + unsignedScientificCanonicalMap, + yearCanonicalFragmentMap, + yearFragValue, + yearMonthDurationCanonicalMap, + yearMonthDurationMap, +} from "./functions.js"; + +describe("unsignedNoDecimalMap", () => { + it("maps the value", () => { + assertStrictEquals(unsignedNoDecimalMap("231"), 231); + }); + + it("throws an error if the value has a decimal point", () => { + assertThrows(() => { + unsignedNoDecimalMap("231."); + }); + assertThrows(() => { + unsignedNoDecimalMap(".231"); + }); + assertThrows(() => { + unsignedNoDecimalMap("23.1"); + }); + }); + + it("throws an error if the value has a sign", () => { + assertThrows(() => { + unsignedNoDecimalMap("+231"); + }); + assertThrows(() => { + unsignedNoDecimalMap("-231"); + }); + }); + + it("throws an error if the value is not a string", () => { + assertThrows(() => { + unsignedNoDecimalMap(231); + }); + }); +}); + +describe("noDecimalMap", () => { + it("maps the value", () => { + assertStrictEquals(noDecimalMap("231"), 231); + assertStrictEquals(noDecimalMap("-69"), -69); + assertStrictEquals(noDecimalMap("+72"), +72); + assertStrictEquals(noDecimalMap("0"), 0); + assertStrictEquals(noDecimalMap("-0"), 0); + }); + + it("throws an error if the value has a decimal point", () => { + assertThrows(() => { + noDecimalMap("231."); + }); + assertThrows(() => { + noDecimalMap(".231"); + }); + assertThrows(() => { + noDecimalMap("23.1"); + }); + }); + + it("throws an error if the value is not a string", () => { + assertThrows(() => { + noDecimalMap(231); + }); + }); +}); + +describe("unsignedDecimalPtMap", () => { + it("maps the value", () => { + assertStrictEquals(unsignedDecimalPtMap("231."), 231); + assertStrictEquals(unsignedDecimalPtMap(".231"), .231); + assertStrictEquals(unsignedDecimalPtMap("23.1"), 23.1); + }); + + it("throws an error if the value has no decimal point", () => { + assertThrows(() => { + unsignedDecimalPtMap("231"); + }); + }); + + it("throws an error if the value has a sign", () => { + assertThrows(() => { + unsignedDecimalPtMap("+231."); + }); + assertThrows(() => { + unsignedDecimalPtMap("-231."); + }); + }); + + it("throws an error if the value is not a string", () => { + assertThrows(() => { + unsignedDecimalPtMap(231); + }); + }); +}); + +describe("decimalPtMap", () => { + it("maps the value", () => { + assertStrictEquals(decimalPtMap("231."), 231); + assertStrictEquals(decimalPtMap("+.231"), .231); + assertStrictEquals(decimalPtMap("-23.1"), -23.1); + assertStrictEquals(decimalPtMap("0.0"), 0); + assertStrictEquals(decimalPtMap("-0.0"), 0); + }); + + it("throws an error if the value has no decimal point", () => { + assertThrows(() => { + decimalPtMap("231"); + }); + }); + + it("throws an error if the value is not a string", () => { + assertThrows(() => { + decimalPtMap(231); + }); + }); +}); + +describe("scientificMap", () => { + it("maps the value", () => { + assertStrictEquals(scientificMap("23E1"), 230); + assertStrictEquals(scientificMap("+2.3E-1"), .23); + assertStrictEquals(scientificMap("-.23E1"), -2.3); + assertStrictEquals(scientificMap("0.0E0"), 0); + assertStrictEquals(scientificMap("-0.0E-0"), 0); + }); + + it("throws an error if the value has no E", () => { + assertThrows(() => { + scientificMap("231"); + }); + }); + + it("throws an error if the value is not a string", () => { + assertThrows(() => { + decimalPtMap(231); + }); + }); +}); + +describe("unsignedNoDecimalPtCanonicalMap", () => { + it("maps the value", () => { + assertStrictEquals(unsignedNoDecimalPtCanonicalMap(231), "231"); + assertStrictEquals( + unsignedNoDecimalPtCanonicalMap(1e23), + "100000000000000000000000", + ); + assertStrictEquals(unsignedNoDecimalPtCanonicalMap(0), "0"); + assertStrictEquals(unsignedNoDecimalPtCanonicalMap(-0), "0"); + }); + + it("throws an error if the value has a fractional part", () => { + assertThrows(() => { + unsignedNoDecimalPtCanonicalMap(23.1); + }); + }); + + it("throws an error if the value is negative", () => { + assertThrows(() => { + unsignedNoDecimalPtCanonicalMap(-231); + }); + }); + + it("throws an error if the value is not a number", () => { + assertThrows(() => { + unsignedNoDecimalPtCanonicalMap("231"); + }); + }); +}); + +describe("noDecimalPtCanonicalMap", () => { + it("maps the value", () => { + assertStrictEquals(noDecimalPtCanonicalMap(231), "231"); + assertStrictEquals(noDecimalPtCanonicalMap(-231), "-231"); + assertStrictEquals(noDecimalPtCanonicalMap(0), "0"); + assertStrictEquals(noDecimalPtCanonicalMap(-0), "0"); + }); + + it("throws an error if the value has a fractional part", () => { + assertThrows(() => { + noDecimalPtCanonicalMap(23.1); + }); + }); + + it("throws an error if the value is not a number", () => { + assertThrows(() => { + noDecimalPtCanonicalMap("231"); + }); + }); +}); + +describe("unsignedDecimalPtCanonicalMap", () => { + it("maps the value", () => { + assertStrictEquals(unsignedDecimalPtCanonicalMap(4), "4.0"); + assertStrictEquals(unsignedDecimalPtCanonicalMap(231), "231.0"); + assertStrictEquals(unsignedDecimalPtCanonicalMap(23.1), "23.1"); + assertStrictEquals(unsignedDecimalPtCanonicalMap(.24), "0.24"); + assertStrictEquals( + unsignedDecimalPtCanonicalMap(10 ** 21.5), + "3162277660168379400000.0", + ); + assertStrictEquals(unsignedDecimalPtCanonicalMap(.0085), "0.0085"); + assertStrictEquals( + unsignedDecimalPtCanonicalMap(10 ** -6.5), + "0.0000003162277660168379", + ); + assertStrictEquals(unsignedDecimalPtCanonicalMap(0), "0.0"); + assertStrictEquals(unsignedDecimalPtCanonicalMap(-0), "0.0"); + }); + + it("throws an error if the value is negative", () => { + assertThrows(() => { + unsignedDecimalPtCanonicalMap(-231); + }); + }); + + it("throws an error if the value is not a number", () => { + assertThrows(() => { + unsignedDecimalPtCanonicalMap("231.0"); + }); + }); +}); + +describe("decimalPtCanonicalMap", () => { + it("maps the value", () => { + assertStrictEquals(decimalPtCanonicalMap(231), "231.0"); + assertStrictEquals(decimalPtCanonicalMap(-23.1), "-23.1"); + assertStrictEquals(decimalPtCanonicalMap(0), "0.0"); + assertStrictEquals(decimalPtCanonicalMap(-0), "0.0"); + }); + + it("throws an error if the value is not a number", () => { + assertThrows(() => { + decimalPtCanonicalMap("231.0"); + }); + }); +}); + +describe("unsignedScientificCanonicalMap", () => { + it("maps the value", () => { + assertStrictEquals(unsignedScientificCanonicalMap(4), "4.0E0"); + assertStrictEquals(unsignedScientificCanonicalMap(231), "2.31E2"); + assertStrictEquals(unsignedScientificCanonicalMap(23), "2.3E1"); + assertStrictEquals(unsignedScientificCanonicalMap(.24), "2.4E-1"); + assertStrictEquals( + unsignedScientificCanonicalMap(10 ** 21.5), + "3.1622776601683794E21", + ); + assertStrictEquals( + unsignedScientificCanonicalMap(.0085), + "8.5E-3", + ); + assertStrictEquals( + unsignedScientificCanonicalMap(10 ** -6.5), + "3.162277660168379E-7", + ); + assertStrictEquals(unsignedScientificCanonicalMap(0), "0.0E0"); + assertStrictEquals(unsignedScientificCanonicalMap(-0), "0.0E0"); + }); + + it("throws an error if the value is negative", () => { + assertThrows(() => { + unsignedScientificCanonicalMap(-231); + }); + }); + + it("throws an error if the value is not a number", () => { + assertThrows(() => { + unsignedScientificCanonicalMap("2.31E2"); + }); + }); +}); + +describe("scientificCanonicalMap", () => { + it("maps the value", () => { + assertStrictEquals(scientificCanonicalMap(231), "2.31E2"); + assertStrictEquals(scientificCanonicalMap(-.231), "-2.31E-1"); + assertStrictEquals(scientificCanonicalMap(0), "0.0E0"); + assertStrictEquals(scientificCanonicalMap(-0), "0.0E0"); + }); + + it("throws an error if the value is not a number", () => { + assertThrows(() => { + scientificCanonicalMap("2.31E2"); + }); + }); +}); + +describe("specialRepValue", () => { + it("maps the value", () => { + assertStrictEquals(specialRepValue("INF"), Infinity); + assertStrictEquals(specialRepValue("+INF"), Infinity); + assertStrictEquals(specialRepValue("-INF"), -Infinity); + assertStrictEquals(specialRepValue("NaN"), NaN); + }); + + it("throws an error if the value is not a special represention", () => { + assertThrows(() => { + specialRepValue("231"); + }); + }); + + it("throws an error if the value is not a string", () => { + assertThrows(() => { + specialRepValue(Infinity); + }); + }); +}); + +describe("specialRepCanonicalMap", () => { + it("maps the value", () => { + assertStrictEquals(specialRepCanonicalMap(Infinity), "INF"); + assertStrictEquals(specialRepCanonicalMap(-Infinity), "-INF"); + assertStrictEquals(specialRepCanonicalMap(NaN), "NaN"); + }); + + it("throws an error if the value is not a special value", () => { + assertThrows(() => { + specialRepCanonicalMap(231); + }); + }); + + it("throws an error if the value is not a number", () => { + assertThrows(() => { + specialRepCanonicalMap("NaN"); + }); + }); +}); + +describe("decimalLexicalMap", () => { + it("maps the value", () => { + assertStrictEquals(decimalLexicalMap("4.0"), 4); + assertStrictEquals(decimalLexicalMap("-231"), -231); + assertStrictEquals(decimalLexicalMap("+23.1"), 23.1); + assertStrictEquals(decimalLexicalMap("-0.24"), -0.24); + assertStrictEquals(decimalLexicalMap(".008500"), 0.0085); + assertStrictEquals(decimalLexicalMap("0"), 0); + assertStrictEquals(decimalLexicalMap("-0"), 0); + }); + + it("throws an error if the value is in exponential notation", () => { + assertThrows(() => { + decimalLexicalMap("23E1"); + }); + }); + + it("throws an error if the value is not a string", () => { + assertThrows(() => { + decimalLexicalMap(231); + }); + }); +}); + +describe("decimalCanonicalMap", () => { + it("maps the value", () => { + assertStrictEquals(decimalCanonicalMap(4), "4"); + assertStrictEquals(decimalCanonicalMap(-231), "-231"); + assertStrictEquals(decimalCanonicalMap(23.1), "23.1"); + assertStrictEquals(decimalCanonicalMap(-.24), "-0.24"); + assertStrictEquals( + decimalCanonicalMap(10 ** 21.5), + "3162277660168379400000", + ); + assertStrictEquals(decimalCanonicalMap(.0085), "0.0085"); + assertStrictEquals( + decimalCanonicalMap(10 ** -6.5), + "0.0000003162277660168379", + ); + assertStrictEquals(decimalCanonicalMap(0), "0"); + assertStrictEquals(decimalCanonicalMap(-0), "0"); + }); + + it("throws an error if the value is not a number", () => { + assertThrows(() => { + decimalCanonicalMap("231"); + }); + }); +}); + +describe("floatLexicalMap", () => { + it("maps the value", () => { + assertStrictEquals(floatLexicalMap("4.0"), Math.fround(4)); + assertStrictEquals(floatLexicalMap("-231"), Math.fround(-231)); + assertStrictEquals(floatLexicalMap("+23.1"), Math.fround(23.1)); + assertStrictEquals(floatLexicalMap("-0.24"), Math.fround(-0.24)); + assertStrictEquals( + floatLexicalMap(".008500"), + Math.fround(0.0085), + ); + assertStrictEquals(floatLexicalMap("23E1"), Math.fround(230)); + assertStrictEquals(floatLexicalMap("4E-20"), Math.fround(4e-20)); + assertStrictEquals(doubleLexicalMap("+0"), 0); + assertStrictEquals(doubleLexicalMap("-0"), -0); + assertStrictEquals(doubleLexicalMap("INF"), Infinity); + assertStrictEquals(doubleLexicalMap("+INF"), Infinity); + assertStrictEquals(doubleLexicalMap("-INF"), -Infinity); + assertStrictEquals(doubleLexicalMap("NaN"), NaN); + }); + + it("throws an error if the value is not a string", () => { + assertThrows(() => { + floatLexicalMap(231); + }); + }); +}); + +describe("doubleLexicalMap", () => { + it("maps the value", () => { + assertStrictEquals(doubleLexicalMap("4.0"), 4); + assertStrictEquals(doubleLexicalMap("-231"), -231); + assertStrictEquals(doubleLexicalMap("+23.1"), 23.1); + assertStrictEquals(doubleLexicalMap("-0.24"), -0.24); + assertStrictEquals(doubleLexicalMap(".008500"), 0.0085); + assertStrictEquals(doubleLexicalMap("23E1"), 230); + assertStrictEquals(doubleLexicalMap("4E-20"), 4e-20); + assertStrictEquals(doubleLexicalMap("+0"), 0); + assertStrictEquals(doubleLexicalMap("-0"), -0); + assertStrictEquals(doubleLexicalMap("INF"), Infinity); + assertStrictEquals(doubleLexicalMap("+INF"), Infinity); + assertStrictEquals(doubleLexicalMap("-INF"), -Infinity); + assertStrictEquals(doubleLexicalMap("NaN"), NaN); + }); + + it("throws an error if the value is not a string", () => { + assertThrows(() => { + doubleLexicalMap(231); + }); + }); +}); + +describe("floatCanonicalMap", () => { + it("maps the value", () => { + assertStrictEquals(floatCanonicalMap(4), "4.0E0"); + assertStrictEquals(floatCanonicalMap(-231), "-2.31E2"); + assertStrictEquals( + floatCanonicalMap(23.100000381469727), + "2.3100000381469727E1", + ); + assertStrictEquals( + floatCanonicalMap(-0.23999999463558197), + "-2.3999999463558197E-1", + ); + assertStrictEquals( + floatCanonicalMap(0.008500000461935997), + "8.500000461935997E-3", + ); + assertStrictEquals( + floatCanonicalMap(3.1622776321769755e21), + "3.1622776321769755E21", + ); + assertStrictEquals( + floatCanonicalMap(3.1622775509276835e-7), + "3.1622775509276835E-7", + ); + assertStrictEquals(floatCanonicalMap(0), "0.0E0"); + assertStrictEquals(floatCanonicalMap(-0), "-0.0E0"); + assertStrictEquals(floatCanonicalMap(Infinity), "INF"); + assertStrictEquals(floatCanonicalMap(-Infinity), "-INF"); + assertStrictEquals(floatCanonicalMap(NaN), "NaN"); + }); + + it("throws an error if the value is not a float", () => { + assertThrows(() => { + floatCanonicalMap(23.1); + }); + }); + + it("throws an error if the value is not a number", () => { + assertThrows(() => { + floatCanonicalMap("231"); + }); + }); +}); + +describe("doubleCanonicalMap", () => { + it("maps the value", () => { + assertStrictEquals(doubleCanonicalMap(4), "4.0E0"); + assertStrictEquals(doubleCanonicalMap(-231), "-2.31E2"); + assertStrictEquals(doubleCanonicalMap(23.1), "2.31E1"); + assertStrictEquals(doubleCanonicalMap(-0.24), "-2.4E-1"); + assertStrictEquals(doubleCanonicalMap(.0085), "8.5E-3"); + assertStrictEquals( + doubleCanonicalMap(10 ** 21.5), + "3.1622776601683794E21", + ); + assertStrictEquals( + doubleCanonicalMap(10 ** -6.5), + "3.162277660168379E-7", + ); + assertStrictEquals(doubleCanonicalMap(0), "0.0E0"); + assertStrictEquals(doubleCanonicalMap(-0), "-0.0E0"); + assertStrictEquals(doubleCanonicalMap(Infinity), "INF"); + assertStrictEquals(doubleCanonicalMap(-Infinity), "-INF"); + assertStrictEquals(doubleCanonicalMap(NaN), "NaN"); + }); + + it("throws an error if the value is not a number", () => { + assertThrows(() => { + doubleCanonicalMap("231"); + }); + }); +}); + +describe("durationMap", () => { + it("maps the value", () => { + assertEquals(durationMap("P0Y0M0DT0H0M0.0S"), { + months: 0, + seconds: 0, + }); + assertStrictEquals(durationMap("-P0Y0M0DT0H0M0.0S").months, 0); + assertStrictEquals(durationMap("-P0Y0M0DT0H0M0.0S").seconds, 0); + assertEquals(durationMap("-P1Y2M"), { months: -14, seconds: 0 }); + assertStrictEquals(durationMap("-P1Y2M").seconds, 0); + assertEquals(durationMap("-P3DT5H7M11S"), { + months: 0, + seconds: -277631, + }); + assertStrictEquals(durationMap("-P3DT5H7M11S").months, 0); + assertEquals(durationMap("-P1Y2M3DT5H7M11.13S"), { + months: -14, + seconds: -277631.13, + }); + }); + + it("throws an error if the value is not a string", () => { + assertThrows(() => { + durationMap(0); + }); + assertThrows(() => { + durationMap({ months: 0, seconds: 0 }); + }); + }); + + it("throws an error if the value has no fields", () => { + assertThrows(() => { + durationMap("P"); + }); + }); + + it("throws an error if the value has a T but no time", () => { + assertThrows(() => { + durationMap("P0Y0M0DT"); + }); + }); +}); + +describe("yearMonthDurationMap", () => { + it("maps the value", () => { + assertEquals(yearMonthDurationMap("P0Y0M"), { + months: 0, + seconds: 0, + }); + assertStrictEquals(yearMonthDurationMap("-P0Y0M").months, 0); + assertStrictEquals(yearMonthDurationMap("-P0Y0M").seconds, 0); + assertEquals(yearMonthDurationMap("-P1Y2M"), { + months: -14, + seconds: 0, + }); + assertStrictEquals(yearMonthDurationMap("-P1Y2M").seconds, 0); + }); + + it("throws an error if the value is not a string", () => { + assertThrows(() => { + yearMonthDurationMap(0); + }); + assertThrows(() => { + yearMonthDurationMap({ months: 0, seconds: 0 }); + }); + }); + + it("throws an error if the value has no fields", () => { + assertThrows(() => { + yearMonthDurationMap("P"); + }); + }); +}); + +describe("dayTimeDurationMap", () => { + it("maps the value", () => { + assertEquals(dayTimeDurationMap("P0DT0H0M0.0S"), { + months: 0, + seconds: 0, + }); + assertStrictEquals(dayTimeDurationMap("-P0DT0H0M0.0S").months, 0); + assertStrictEquals(dayTimeDurationMap("-P0DT0H0M0.0S").seconds, 0); + assertEquals(dayTimeDurationMap("-P3DT5H7M11.13S"), { + months: 0, + seconds: -277631.13, + }); + assertStrictEquals( + dayTimeDurationMap("-P3DT5H7M11.13S").months, + 0, + ); + }); + + it("throws an error if the value is not a string", () => { + assertThrows(() => { + dayTimeDurationMap(0); + }); + assertThrows(() => { + dayTimeDurationMap({ months: 0, seconds: 0 }); + }); + }); + + it("throws an error if the value has no fields", () => { + assertThrows(() => { + dayTimeDurationMap("P"); + }); + }); + + it("throws an error if the value has a T but no time", () => { + assertThrows(() => { + dayTimeDurationMap("P0DT"); + }); + }); +}); + +describe("durationCanonicalMap", () => { + it("maps the value", () => { + assertStrictEquals( + durationCanonicalMap({ months: 0, seconds: 0 }), + "PT0S", + ); + assertStrictEquals( + durationCanonicalMap({ months: -0, seconds: -0 }), + "PT0S", + ); + assertStrictEquals( + durationCanonicalMap({ months: 23, seconds: 1234.5 }), + "P1Y11MT20M34.5S", + ); + assertStrictEquals( + durationCanonicalMap({ months: -14, seconds: -277631 }), + "-P1Y2M3DT5H7M11S", + ); + }); + + it("throws an error if the value is not a duration", () => { + assertThrows(() => { + durationCanonicalMap("PT0S"); + }); + assertThrows(() => { + durationCanonicalMap({}); + }); + assertThrows(() => { + durationCanonicalMap(0); + }); + }); + + it("throws an error if the signs of the terms do not match", () => { + assertThrows(() => { + durationCanonicalMap({ months: 1, seconds: -1 }); + }); + }); +}); + +describe("yearMonthDurationCanonicalMap", () => { + it("maps the value", () => { + assertStrictEquals( + yearMonthDurationCanonicalMap({ months: 0, seconds: 0 }), + "P0M", + ); + assertStrictEquals( + yearMonthDurationCanonicalMap({ months: -0, seconds: -0 }), + "P0M", + ); + assertStrictEquals( + yearMonthDurationCanonicalMap({ months: 23, seconds: 0 }), + "P1Y11M", + ); + assertStrictEquals( + yearMonthDurationCanonicalMap({ months: -14, seconds: 0 }), + "-P1Y2M", + ); + }); + + it("throws an error if the value is not a duration", () => { + assertThrows(() => { + yearMonthDurationCanonicalMap("P0M"); + }); + assertThrows(() => { + yearMonthDurationCanonicalMap({}); + }); + assertThrows(() => { + yearMonthDurationCanonicalMap(0); + }); + }); + + it("throws an error if the value of seconds is not zero", () => { + assertThrows(() => { + yearMonthDurationCanonicalMap({ months: 1, seconds: 1 }); + }); + }); +}); + +describe("dayTimeDurationCanonicalMap", () => { + it("maps the value", () => { + assertStrictEquals( + dayTimeDurationCanonicalMap({ months: 0, seconds: 0 }), + "PT0S", + ); + assertStrictEquals( + dayTimeDurationCanonicalMap({ months: -0, seconds: -0 }), + "PT0S", + ); + assertStrictEquals( + dayTimeDurationCanonicalMap({ months: 0, seconds: 1234.5 }), + "PT20M34.5S", + ); + assertStrictEquals( + dayTimeDurationCanonicalMap({ months: 0, seconds: -277631 }), + "-P3DT5H7M11S", + ); + }); + + it("throws an error if the value is not a duration", () => { + assertThrows(() => { + dayTimeDurationCanonicalMap("PT0S"); + }); + assertThrows(() => { + dayTimeDurationCanonicalMap({}); + }); + assertThrows(() => { + dayTimeDurationCanonicalMap(0); + }); + }); + + it("throws an error if the value of months is not zero", () => { + assertThrows(() => { + dayTimeDurationCanonicalMap({ months: 1, seconds: 1 }); + }); + }); +}); + +describe("daysInMonth", () => { + it("returns the correct value when no year is supplied", () => { + assertStrictEquals(daysInMonth(undefined, 1), 31); + assertStrictEquals(daysInMonth(undefined, 2), 28); + assertStrictEquals(daysInMonth(undefined, 3), 31); + assertStrictEquals(daysInMonth(undefined, 4), 30); + assertStrictEquals(daysInMonth(undefined, 5), 31); + assertStrictEquals(daysInMonth(undefined, 6), 30); + assertStrictEquals(daysInMonth(undefined, 7), 31); + assertStrictEquals(daysInMonth(undefined, 8), 31); + assertStrictEquals(daysInMonth(undefined, 9), 30); + assertStrictEquals(daysInMonth(undefined, 10), 31); + assertStrictEquals(daysInMonth(undefined, 11), 30); + assertStrictEquals(daysInMonth(undefined, 12), 31); + }); + + it("returns the correct value when a year is supplied", () => { + assertStrictEquals(daysInMonth(1972, 12), 31); + assertStrictEquals(daysInMonth(1972, 2), 29); + assertStrictEquals(daysInMonth(1970, 2), 28); + assertStrictEquals(daysInMonth(2000, 2), 29); + assertStrictEquals(daysInMonth(1000, 2), 28); + assertStrictEquals(daysInMonth(800, 2), 29); + assertStrictEquals(daysInMonth(100, 2), 28); + assertStrictEquals(daysInMonth(0, 2), 29); + }); + + it("throws an error if the month is not an integer between 1 and 12", () => { + assertThrows(() => { + daysInMonth(undefined, 0); + }); + assertThrows(() => { + daysInMonth(undefined, 13); + }); + assertThrows(() => { + daysInMonth(undefined, "1"); + }); + }); + + it("throws an error if the year is not undefined or an integer", () => { + assertThrows(() => { + daysInMonth(null, 1); + }); + assertThrows(() => { + daysInMonth(2.31, 1); + }); + assertThrows(() => { + daysInMonth("undefined", 1); + }); + assertThrows(() => { + daysInMonth("1", 1); + }); + }); +}); + +describe("newDateTime", () => { + it("returns a new datetime object", () => { + assertEquals(newDateTime(1, 1, 1, 0, 0, 0, 0), { + year: 1, + month: 1, + day: 1, + hour: 0, + minute: 0, + second: 0, + timezoneOffset: 0, + }); + assertEquals(newDateTime(-1, 12, 31, 23, 59, 59.99, -840), { + year: -1, + month: 12, + day: 31, + hour: 23, + minute: 59, + second: 59.99, + timezoneOffset: -840, + }); + }); + + it("fills absent values with undefined", () => { + assertEquals(newDateTime(), { + year: undefined, + month: undefined, + day: undefined, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: undefined, + }); + }); + + it("normalizes the date", () => { + assertEquals(newDateTime(1, 2, 31, 24), { + year: 1, + month: 3, + day: 4, + hour: 0, + minute: undefined, + second: undefined, + timezoneOffset: undefined, + }); + assertEquals(newDateTime(1, undefined, 31, 24), { + year: 1, + month: undefined, + day: 1, + hour: 0, + minute: undefined, + second: undefined, + timezoneOffset: undefined, + }); + }); + + it("forbids out‐of‐range values", () => { + assertThrows(() => { + newDateTime(undefined, 0); + }); + assertThrows(() => { + newDateTime(undefined, 13); + }); + assertThrows(() => { + newDateTime(undefined, undefined, 0); + }); + assertThrows(() => { + newDateTime(undefined, undefined, 32); + }); + assertThrows(() => { + newDateTime(undefined, undefined, undefined, -1); + }); + assertThrows(() => { + newDateTime(undefined, undefined, undefined, 25); + }); + assertThrows(() => { + newDateTime(undefined, undefined, undefined, undefined, -1); + }); + assertThrows(() => { + newDateTime(undefined, undefined, undefined, undefined, 61); + }); + assertThrows(() => { + newDateTime( + undefined, + undefined, + undefined, + undefined, + undefined, + -1, + ); + }); + assertThrows(() => { + newDateTime( + undefined, + undefined, + undefined, + undefined, + undefined, + 61, + ); + }); + assertThrows(() => { + newDateTime( + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + -841, + ); + }); + assertThrows(() => { + newDateTime( + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + 841, + ); + }); + }); + + it("forbids values of the incorrect type", () => { + assertThrows(() => { + newDateTime(1.23); + }); + assertThrows(() => { + newDateTime("1"); + }); + assertThrows(() => { + newDateTime(undefined, 1.23); + }); + assertThrows(() => { + newDateTime(undefined, "1"); + }); + assertThrows(() => { + newDateTime(undefined, undefined, 1.23); + }); + assertThrows(() => { + newDateTime(undefined, undefined, "1"); + }); + assertThrows(() => { + newDateTime(undefined, undefined, undefined, 1.23); + }); + assertThrows(() => { + newDateTime(undefined, undefined, undefined, "1"); + }); + assertThrows(() => { + newDateTime(undefined, undefined, undefined, undefined, 1.23); + }); + assertThrows(() => { + newDateTime(undefined, undefined, undefined, undefined, "1"); + }); + assertThrows(() => { + newDateTime( + undefined, + undefined, + undefined, + undefined, + undefined, + "1", + ); + }); + assertThrows(() => { + newDateTime( + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + 1.23, + ); + }); + assertThrows(() => { + newDateTime( + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + "1", + ); + }); + }); +}); + +describe("dateTimePlusDuration", () => { + it("fills absent values with undefined", () => { + assertEquals(dateTimePlusDuration({ months: 0, seconds: 0 }, {}), { + year: undefined, + month: undefined, + day: undefined, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: undefined, + }); + }); + + it("correctly adds the duration to the datetime", () => { + // These examples are taken from the X·S·D spec. + const fuzzyResult = dateTimePlusDuration({ + months: 15, + seconds: 457803.3, + }, { + year: 2000, + month: 1, + day: 12, + hour: 12, + minute: 13, + second: 14, + timezoneOffset: 0, + }); + assertObjectMatch(fuzzyResult, { + year: 2001, + month: 4, + day: 17, + hour: 19, + minute: 23, + // seconds must be matched fuzzily + timezoneOffset: 0, + }); + assertAlmostEquals(fuzzyResult.second, 17.3); + assertEquals( + dateTimePlusDuration({ months: -3, seconds: 0 }, { + year: 2000, + month: 1, + }), + { + year: 1999, + month: 10, + day: undefined, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: undefined, + }, + ); + assertEquals( + dateTimePlusDuration({ months: 0, seconds: 118800 }, { + year: 2000, + month: 1, + day: 12, + }), + { + year: 2000, + month: 1, + day: 13, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: undefined, + }, + ); + assertEquals( + dateTimePlusDuration( + { months: 1, seconds: 0 }, + dateTimePlusDuration({ months: 0, seconds: 86400 }, { + year: 2000, + month: 3, + day: 30, + }), + ), + { + year: 2000, + month: 4, + day: 30, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: undefined, + }, + ); + assertEquals( + dateTimePlusDuration( + { months: 0, seconds: 86400 }, + dateTimePlusDuration({ months: 1, seconds: 0 }, { + year: 2000, + month: 3, + day: 30, + }), + ), + { + year: 2000, + month: 5, + day: 1, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: undefined, + }, + ); + }); + + it("follows 28 February with 01 March", () => { + assertEquals( + dateTimePlusDuration({ months: 0, seconds: 86400 }, { + month: 2, + day: 28, + }), + { + year: undefined, + month: 3, + day: 1, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: undefined, + }, + ); + }); + + it("allows 29 February without a year", () => { + assertEquals( + dateTimePlusDuration({ months: 0, seconds: 1 }, { + month: 2, + day: 29, + }), + { + year: undefined, + month: 2, + day: 29, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: undefined, + }, + ); + }); + + it("follows 29 February with 01 March", () => { + assertEquals( + dateTimePlusDuration({ months: 0, seconds: 86400 }, { + month: 2, + day: 29, + }), + { + year: undefined, + month: 3, + day: 1, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: undefined, + }, + ); + }); + + it("throws if not provided with a valid duration", () => { + assertThrows(() => { + dateTimePlusDuration({ months: 0 }, {}); + }); + assertThrows(() => { + dateTimePlusDuration({ seconds: 0 }, {}); + }); + assertThrows(() => { + dateTimePlusDuration({}, {}); + }); + assertThrows(() => { + dateTimePlusDuration(0, {}); + }); + assertThrows(() => { + dateTimePlusDuration("PT0S", {}); + }); + }); + + it("throws if not provided with a valid date·time", () => { + assertThrows(() => { + dateTimePlusDuration({ months: 0, seconds: 0 }, 0); + }); + assertThrows(() => { + dateTimePlusDuration({ seconds: 0 }, "2000-01-12T12:13:14Z"); + }); + }); +}); + +describe("timeOnTimeline", () => { + it("gets the time", () => { + assertStrictEquals( + timeOnTimeline({ + year: 1, + month: 1, + day: 1, + hour: 0, + minute: 0, + second: 0, + timezoneOffset: 0, + }), + 0, + ); + assertStrictEquals( + timeOnTimeline({ + year: 1, + month: 1, + day: 1, + hour: 0, + minute: 0, + second: 0, + timezoneOffset: 840, + }), + -50400, + ); + assertStrictEquals(timeOnTimeline({}), 62230204800); + assertStrictEquals(timeOnTimeline({ year: 0 }), -86400); + }); + + it("throws if not provided with a valid date·time", () => { + assertThrows(() => { + timeOnTimeline(0); + }); + assertThrows(() => { + timeOnTimeline("2000-01-12T12:13:14Z"); + }); + }); +}); + +describe("yearFragValue", () => { + it("maps the value", () => { + assertStrictEquals(yearFragValue("0001"), 1); + assertStrictEquals(yearFragValue("-0000"), 0); + assertStrictEquals(yearFragValue("-10000"), -10000); + assertStrictEquals(yearFragValue("99999"), 99999); + }); + + it("throws an error if the value is not a string", () => { + assertThrows(() => { + yearFragValue(1); + }); + }); + + it("throws an error if the value is not a valid yearFrag", () => { + assertThrows(() => { + yearFragValue(""); + }); + assertThrows(() => { + yearFragValue("1"); + }); + assertThrows(() => { + yearFragValue("01000"); + }); + }); +}); + +describe("monthFragValue", () => { + it("maps the value", () => { + assertStrictEquals(monthFragValue("01"), 1); + assertStrictEquals(monthFragValue("10"), 10); + assertStrictEquals(monthFragValue("12"), 12); + }); + + it("throws an error if the value is not a string", () => { + assertThrows(() => { + monthFragValue(1); + }); + }); + + it("throws an error if the value is not a valid monthFrag", () => { + assertThrows(() => { + monthFragValue(""); + }); + assertThrows(() => { + monthFragValue("1"); + }); + assertThrows(() => { + monthFragValue("-1"); + }); + assertThrows(() => { + monthFragValue("-01"); + }); + assertThrows(() => { + monthFragValue("00"); + }); + assertThrows(() => { + monthFragValue("13"); + }); + assertThrows(() => { + monthFragValue("20"); + }); + }); +}); + +describe("dayFragValue", () => { + it("maps the value", () => { + assertStrictEquals(dayFragValue("01"), 1); + assertStrictEquals(dayFragValue("10"), 10); + assertStrictEquals(dayFragValue("19"), 19); + assertStrictEquals(dayFragValue("20"), 20); + assertStrictEquals(dayFragValue("29"), 29); + assertStrictEquals(dayFragValue("30"), 30); + assertStrictEquals(dayFragValue("31"), 31); + }); + + it("throws an error if the value is not a string", () => { + assertThrows(() => { + dayFragValue(1); + }); + }); + + it("throws an error if the value is not a valid dayFrag", () => { + assertThrows(() => { + dayFragValue(""); + }); + assertThrows(() => { + dayFragValue("1"); + }); + assertThrows(() => { + dayFragValue("-1"); + }); + assertThrows(() => { + dayFragValue("-01"); + }); + assertThrows(() => { + dayFragValue("00"); + }); + assertThrows(() => { + dayFragValue("32"); + }); + assertThrows(() => { + dayFragValue("40"); + }); + }); +}); + +describe("hourFragValue", () => { + it("maps the value", () => { + assertStrictEquals(hourFragValue("00"), 0); + assertStrictEquals(hourFragValue("01"), 1); + assertStrictEquals(hourFragValue("10"), 10); + assertStrictEquals(hourFragValue("19"), 19); + assertStrictEquals(hourFragValue("20"), 20); + assertStrictEquals(hourFragValue("23"), 23); + }); + + it("throws an error if the value is not a string", () => { + assertThrows(() => { + hourFragValue(0); + }); + }); + + it("throws an error if the value is not a valid hourFrag", () => { + assertThrows(() => { + hourFragValue(""); + }); + assertThrows(() => { + hourFragValue("1"); + }); + assertThrows(() => { + hourFragValue("-1"); + }); + assertThrows(() => { + hourFragValue("-01"); + }); + assertThrows(() => { + hourFragValue("24"); + }); + assertThrows(() => { + hourFragValue("30"); + }); + assertThrows(() => { + hourFragValue("01.23"); + }); + }); +}); + +describe("minuteFragValue", () => { + it("maps the value", () => { + assertStrictEquals(minuteFragValue("00"), 0); + assertStrictEquals(minuteFragValue("01"), 1); + assertStrictEquals(minuteFragValue("10"), 10); + assertStrictEquals(minuteFragValue("19"), 19); + assertStrictEquals(minuteFragValue("50"), 50); + assertStrictEquals(minuteFragValue("59"), 59); + }); + + it("throws an error if the value is not a string", () => { + assertThrows(() => { + minuteFragValue(0); + }); + }); + + it("throws an error if the value is not a valid minuteFrag", () => { + assertThrows(() => { + minuteFragValue(""); + }); + assertThrows(() => { + minuteFragValue("1"); + }); + assertThrows(() => { + minuteFragValue("-1"); + }); + assertThrows(() => { + minuteFragValue("-01"); + }); + assertThrows(() => { + minuteFragValue("60"); + }); + assertThrows(() => { + minuteFragValue("01.23"); + }); + }); +}); + +describe("secondFragValue", () => { + it("maps the value", () => { + assertStrictEquals(secondFragValue("00"), 0); + assertStrictEquals(secondFragValue("00.00000"), 0); + assertStrictEquals(secondFragValue("01"), 1); + assertStrictEquals(secondFragValue("10"), 10); + assertStrictEquals(secondFragValue("19"), 19); + assertStrictEquals(secondFragValue("50"), 50); + assertStrictEquals(secondFragValue("59"), 59); + assertStrictEquals(secondFragValue("59.99"), 59.99); + }); + + it("throws an error if the value is not a string", () => { + assertThrows(() => { + secondFragValue(0); + }); + }); + + it("throws an error if the value is not a valid secondFrag", () => { + assertThrows(() => { + secondFragValue(""); + }); + assertThrows(() => { + secondFragValue("1"); + }); + assertThrows(() => { + secondFragValue("-1"); + }); + assertThrows(() => { + secondFragValue("-01"); + }); + assertThrows(() => { + secondFragValue("60"); + }); + }); +}); + +describe("timezoneFragValue", () => { + it("maps the value", () => { + assertStrictEquals(timezoneFragValue("Z"), 0); + assertStrictEquals(timezoneFragValue("+00:00"), 0); + assertStrictEquals(timezoneFragValue("-00:00"), 0); + assertStrictEquals(timezoneFragValue("+00:01"), 1); + assertStrictEquals(timezoneFragValue("+00:59"), 59); + assertStrictEquals(timezoneFragValue("+01:23"), 83); + assertStrictEquals(timezoneFragValue("-09:23"), -563); + assertStrictEquals(timezoneFragValue("-10:23"), -623); + assertStrictEquals(timezoneFragValue("+13:59"), 839); + assertStrictEquals(timezoneFragValue("+14:00"), 840); + assertStrictEquals(timezoneFragValue("-14:00"), -840); + }); + + it("throws an error if the value is not a string", () => { + assertThrows(() => { + timezoneFragValue(0); + }); + }); + + it("throws an error if the value is not a valid timezoneFrag", () => { + assertThrows(() => { + timezoneFragValue(""); + }); + assertThrows(() => { + timezoneFragValue("0"); + }); + assertThrows(() => { + timezoneFragValue("+Z"); + }); + assertThrows(() => { + timezoneFragValue("-Z"); + }); + assertThrows(() => { + timezoneFragValue("Z+00:00"); + }); + assertThrows(() => { + timezoneFragValue("00:00"); + }); + assertThrows(() => { + timezoneFragValue("0000"); + }); + assertThrows(() => { + timezoneFragValue("+0000"); + }); + assertThrows(() => { + timezoneFragValue("840"); + }); + assertThrows(() => { + timezoneFragValue("+840"); + }); + assertThrows(() => { + timezoneFragValue("+-00:00"); + }); + assertThrows(() => { + timezoneFragValue("-+00:00"); + }); + assertThrows(() => { + timezoneFragValue("+14:01"); + }); + assertThrows(() => { + timezoneFragValue("+15:00"); + }); + }); +}); + +describe("dateTimeLexicalMap", () => { + it("maps the value", () => { + assertEquals(dateTimeLexicalMap("0001-01-01T00:00:00.00Z"), { + year: 1, + month: 1, + day: 1, + hour: 0, + minute: 0, + second: 0, + timezoneOffset: 0, + }); + assertEquals(dateTimeLexicalMap("-0001-12-31T24:00:00Z"), { + year: 0, + month: 1, + day: 1, + hour: 0, + minute: 0, + second: 0, + timezoneOffset: 0, + }); + assertEquals(dateTimeLexicalMap("-0000-01-01T00:00:00-00:00"), { + year: 0, + month: 1, + day: 1, + hour: 0, + minute: 0, + second: 0, + timezoneOffset: 0, + }); + assertEquals(dateTimeLexicalMap("0001-01-01T00:00:00.00"), { + year: 1, + month: 1, + day: 1, + hour: 0, + minute: 0, + second: 0, + timezoneOffset: undefined, + }); + assertEquals(dateTimeLexicalMap("99999-12-31T23:59:59.99+14:00"), { + year: 99999, + month: 12, + day: 31, + hour: 23, + minute: 59, + second: 59.99, + timezoneOffset: 840, + }); + assertEquals(dateTimeLexicalMap("1972-02-29T00:00:00"), { + year: 1972, + month: 2, + day: 29, + hour: 0, + minute: 0, + second: 0, + timezoneOffset: undefined, + }); + }); + + it("throws an error if the value is not a string", () => { + assertThrows(() => { + dateTimeLexicalMap(0); + }); + }); + + it("throws an error if the value is not a valid dateTime", () => { + assertThrows(() => { + dateTimeLexicalMap(""); + }); + assertThrows(() => { + dateTimeLexicalMap("1"); + }); + assertThrows(() => { + dateTimeLexicalMap("10-10-10T00:00:00"); + }); + assertThrows(() => { + dateTimeLexicalMap("2345-67-89T01:23:45"); + }); + assertThrows(() => { + dateTimeLexicalMap("01000-10-10T10:10:10"); + }); + assertThrows(() => { + dateTimeLexicalMap("0001-01-01T00:00:00.00+0000"); + }); + assertThrows(() => { + dateTimeLexicalMap("0001-01-01T00:00:00.00+14:01"); + }); + assertThrows(() => { + dateTimeLexicalMap("1970-02-29T00:00:00.00"); + }); + }); +}); + +describe("timeLexicalMap", () => { + it("maps the value", () => { + assertEquals(timeLexicalMap("00:00:00.00Z"), { + year: undefined, + month: undefined, + day: undefined, + hour: 0, + minute: 0, + second: 0, + timezoneOffset: 0, + }); + assertEquals(timeLexicalMap("24:00:00Z"), { + year: undefined, + month: undefined, + day: undefined, + hour: 0, + minute: 0, + second: 0, + timezoneOffset: 0, + }); + assertEquals(timeLexicalMap("23:59:59.99+14:00"), { + year: undefined, + month: undefined, + day: undefined, + hour: 23, + minute: 59, + second: 59.99, + timezoneOffset: 840, + }); + }); + + it("throws an error if the value is not a string", () => { + assertThrows(() => { + timeLexicalMap(0); + }); + }); + + it("throws an error if the value is not a valid time", () => { + assertThrows(() => { + timeLexicalMap(""); + }); + assertThrows(() => { + timeLexicalMap("1"); + }); + assertThrows(() => { + timeLexicalMap("00:00"); + }); + assertThrows(() => { + timeLexicalMap("23:45:67"); + }); + assertThrows(() => { + timeLexicalMap("-10:10:10"); + }); + assertThrows(() => { + timeLexicalMap("00:00:00.00+0000"); + }); + assertThrows(() => { + timeLexicalMap("00:00:00.00+14:01"); + }); + assertThrows(() => { + timeLexicalMap("T00:00:00"); + }); + }); +}); + +describe("dateLexicalMap", () => { + it("maps the value", () => { + assertEquals(dateLexicalMap("0001-01-01Z"), { + year: 1, + month: 1, + day: 1, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: 0, + }); + assertEquals(dateLexicalMap("-0001-12-31Z"), { + year: -1, + month: 12, + day: 31, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: 0, + }); + assertEquals(dateLexicalMap("-0000-01-01-00:00"), { + year: 0, + month: 1, + day: 1, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: 0, + }); + assertEquals(dateLexicalMap("0001-01-01"), { + year: 1, + month: 1, + day: 1, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: undefined, + }); + assertEquals(dateLexicalMap("99999-12-31+14:00"), { + year: 99999, + month: 12, + day: 31, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: 840, + }); + assertEquals(dateLexicalMap("1972-02-29"), { + year: 1972, + month: 2, + day: 29, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: undefined, + }); + }); + + it("throws an error if the value is not a string", () => { + assertThrows(() => { + dateLexicalMap(0); + }); + }); + + it("throws an error if the value is not a valid date", () => { + assertThrows(() => { + dateLexicalMap(""); + }); + assertThrows(() => { + dateLexicalMap("1"); + }); + assertThrows(() => { + dateLexicalMap("10-10-10"); + }); + assertThrows(() => { + dateLexicalMap("2345-67-89"); + }); + assertThrows(() => { + dateLexicalMap("01000-10-10"); + }); + assertThrows(() => { + dateLexicalMap("0001-01-01+0000"); + }); + assertThrows(() => { + dateLexicalMap("0001-01-01+14:01"); + }); + assertThrows(() => { + dateLexicalMap("1970-02-29"); + }); + assertThrows(() => { + dateLexicalMap("1972-02-29T00:00:00"); + }); + }); +}); + +describe("gYearMonthLexicalMap", () => { + it("maps the value", () => { + assertEquals(gYearMonthLexicalMap("0001-01Z"), { + year: 1, + month: 1, + day: undefined, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: 0, + }); + assertEquals(gYearMonthLexicalMap("-0001-12Z"), { + year: -1, + month: 12, + day: undefined, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: 0, + }); + assertEquals(gYearMonthLexicalMap("-0000-01-00:00"), { + year: 0, + month: 1, + day: undefined, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: 0, + }); + assertEquals(gYearMonthLexicalMap("0001-01"), { + year: 1, + month: 1, + day: undefined, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: undefined, + }); + assertEquals(gYearMonthLexicalMap("99999-12+14:00"), { + year: 99999, + month: 12, + day: undefined, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: 840, + }); + assertEquals(gYearMonthLexicalMap("1972-02"), { + year: 1972, + month: 2, + day: undefined, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: undefined, + }); + }); + + it("throws an error if the value is not a string", () => { + assertThrows(() => { + gYearMonthLexicalMap(0); + }); + }); + + it("throws an error if the value is not a valid gYearMonth", () => { + assertThrows(() => { + gYearMonthLexicalMap(""); + }); + assertThrows(() => { + gYearMonthLexicalMap("1"); + }); + assertThrows(() => { + gYearMonthLexicalMap("10-10"); + }); + assertThrows(() => { + gYearMonthLexicalMap("2345-67"); + }); + assertThrows(() => { + gYearMonthLexicalMap("01000-10"); + }); + assertThrows(() => { + gYearMonthLexicalMap("0001-01+0000"); + }); + assertThrows(() => { + gYearMonthLexicalMap("0001-01+14:01"); + }); + assertThrows(() => { + gYearMonthLexicalMap("1970-01-01"); + }); + assertThrows(() => { + gYearMonthLexicalMap("1972-02T00:00:00"); + }); + }); +}); + +describe("gYearLexicalMap", () => { + it("maps the value", () => { + assertEquals(gYearLexicalMap("0001Z"), { + year: 1, + month: undefined, + day: undefined, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: 0, + }); + assertEquals(gYearLexicalMap("-0001Z"), { + year: -1, + month: undefined, + day: undefined, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: 0, + }); + assertEquals(gYearLexicalMap("-0000-00:00"), { + year: 0, + month: undefined, + day: undefined, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: 0, + }); + assertEquals(gYearLexicalMap("0001"), { + year: 1, + month: undefined, + day: undefined, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: undefined, + }); + assertEquals(gYearLexicalMap("99999+14:00"), { + year: 99999, + month: undefined, + day: undefined, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: 840, + }); + assertEquals(gYearLexicalMap("1972"), { + year: 1972, + month: undefined, + day: undefined, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: undefined, + }); + }); + + it("throws an error if the value is not a string", () => { + assertThrows(() => { + gYearLexicalMap(0); + }); + }); + + it("throws an error if the value is not a valid gYear", () => { + assertThrows(() => { + gYearLexicalMap(""); + }); + assertThrows(() => { + gYearLexicalMap("1"); + }); + assertThrows(() => { + gYearLexicalMap("10"); + }); + assertThrows(() => { + gYearLexicalMap("01000"); + }); + assertThrows(() => { + gYearLexicalMap("0001+0000"); + }); + assertThrows(() => { + gYearLexicalMap("0001+14:01"); + }); + assertThrows(() => { + gYearLexicalMap("1970-01"); + }); + assertThrows(() => { + gYearLexicalMap("1972T00:00:00"); + }); + }); +}); + +describe("gMonthDayLexicalMap", () => { + it("maps the value", () => { + assertEquals(gMonthDayLexicalMap("--01-01Z"), { + year: undefined, + month: 1, + day: 1, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: 0, + }); + assertEquals(gMonthDayLexicalMap("--12-31Z"), { + year: undefined, + month: 12, + day: 31, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: 0, + }); + assertEquals(gMonthDayLexicalMap("--01-01-00:00"), { + year: undefined, + month: 1, + day: 1, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: 0, + }); + assertEquals(gMonthDayLexicalMap("--01-01"), { + year: undefined, + month: 1, + day: 1, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: undefined, + }); + assertEquals(gMonthDayLexicalMap("--12-31+14:00"), { + year: undefined, + month: 12, + day: 31, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: 840, + }); + assertEquals(gMonthDayLexicalMap("--02-29"), { + year: undefined, + month: 2, + day: 29, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: undefined, + }); + }); + + it("throws an error if the value is not a string", () => { + assertThrows(() => { + gMonthDayLexicalMap(0); + }); + }); + + it("throws an error if the value is not a valid gMonthDay", () => { + assertThrows(() => { + gMonthDayLexicalMap(""); + }); + assertThrows(() => { + gMonthDayLexicalMap("1"); + }); + assertThrows(() => { + gMonthDayLexicalMap("--67-89"); + }); + assertThrows(() => { + gMonthDayLexicalMap("---10-10"); + }); + assertThrows(() => { + gMonthDayLexicalMap("--01-01+0000"); + }); + assertThrows(() => { + gMonthDayLexicalMap("--01-01+14:01"); + }); + assertThrows(() => { + gMonthDayLexicalMap("--02-30"); + }); + assertThrows(() => { + gMonthDayLexicalMap("1970-01-01"); + }); + assertThrows(() => { + gMonthDayLexicalMap("--02-29T00:00:00"); + }); + }); +}); + +describe("gDayLexicalMap", () => { + it("maps the value", () => { + assertEquals(gDayLexicalMap("---01Z"), { + year: undefined, + month: undefined, + day: 1, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: 0, + }); + assertEquals(gDayLexicalMap("---31Z"), { + year: undefined, + month: undefined, + day: 31, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: 0, + }); + assertEquals(gDayLexicalMap("---01-00:00"), { + year: undefined, + month: undefined, + day: 1, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: 0, + }); + assertEquals(gDayLexicalMap("---01"), { + year: undefined, + month: undefined, + day: 1, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: undefined, + }); + assertEquals(gDayLexicalMap("---31+14:00"), { + year: undefined, + month: undefined, + day: 31, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: 840, + }); + }); + + it("throws an error if the value is not a string", () => { + assertThrows(() => { + gDayLexicalMap(0); + }); + }); + + it("throws an error if the value is not a valid gDay", () => { + assertThrows(() => { + gDayLexicalMap(""); + }); + assertThrows(() => { + gDayLexicalMap("1"); + }); + assertThrows(() => { + gDayLexicalMap("10"); + }); + assertThrows(() => { + gDayLexicalMap("---89"); + }); + assertThrows(() => { + gDayLexicalMap("----10"); + }); + assertThrows(() => { + gDayLexicalMap("---01+0000"); + }); + assertThrows(() => { + gDayLexicalMap("---01+14:01"); + }); + assertThrows(() => { + gDayLexicalMap("--01-01"); + }); + assertThrows(() => { + gDayLexicalMap("1970-01-01"); + }); + assertThrows(() => { + gDayLexicalMap("---29T00:00:00"); + }); + }); +}); + +describe("gMonthLexicalMap", () => { + it("maps the value", () => { + assertEquals(gMonthLexicalMap("--01Z"), { + year: undefined, + month: 1, + day: undefined, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: 0, + }); + assertEquals(gMonthLexicalMap("--12Z"), { + year: undefined, + month: 12, + day: undefined, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: 0, + }); + assertEquals(gMonthLexicalMap("--01-00:00"), { + year: undefined, + month: 1, + day: undefined, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: 0, + }); + assertEquals(gMonthLexicalMap("--01"), { + year: undefined, + month: 1, + day: undefined, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: undefined, + }); + assertEquals(gMonthLexicalMap("--12+14:00"), { + year: undefined, + month: 12, + day: undefined, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: 840, + }); + }); + + it("throws an error if the value is not a string", () => { + assertThrows(() => { + gMonthLexicalMap(0); + }); + }); + + it("throws an error if the value is not a valid gMonth", () => { + assertThrows(() => { + gMonthLexicalMap(""); + }); + assertThrows(() => { + gMonthLexicalMap("1"); + }); + assertThrows(() => { + gMonthLexicalMap("01"); + }); + assertThrows(() => { + gMonthLexicalMap("--67"); + }); + assertThrows(() => { + gMonthLexicalMap("---10"); + }); + assertThrows(() => { + gMonthLexicalMap("--01+0000"); + }); + assertThrows(() => { + gMonthLexicalMap("--01+14:01"); + }); + assertThrows(() => { + gMonthLexicalMap("--13"); + }); + assertThrows(() => { + gMonthLexicalMap("1970-01-01"); + }); + assertThrows(() => { + gMonthLexicalMap("--02T00:00:00"); + }); + }); +}); + +describe("yearCanonicalFragmentMap", () => { + it("maps the value", () => { + assertStrictEquals(yearCanonicalFragmentMap(1), "0001"); + assertStrictEquals(yearCanonicalFragmentMap(0), "0000"); + assertStrictEquals(yearCanonicalFragmentMap(-0), "0000"); + assertStrictEquals(yearCanonicalFragmentMap(-1), "-0001"); + assertStrictEquals(yearCanonicalFragmentMap(10000), "10000"); + assertStrictEquals(yearCanonicalFragmentMap(-10000), "-10000"); + }); + + it("throws an error if the value is not an integer", () => { + assertThrows(() => { + yearCanonicalFragmentMap("0001"); + }); + assertThrows(() => { + yearCanonicalFragmentMap(1.2); + }); + }); +}); + +describe("monthCanonicalFragmentMap", () => { + it("maps the value", () => { + assertStrictEquals(monthCanonicalFragmentMap(1), "01"); + assertStrictEquals(monthCanonicalFragmentMap(12), "12"); + }); + + it("throws an error if the value is not a positive integer less than 13", () => { + assertThrows(() => { + monthCanonicalFragmentMap("01"); + }); + assertThrows(() => { + monthCanonicalFragmentMap(0); + }); + assertThrows(() => { + monthCanonicalFragmentMap(-1); + }); + assertThrows(() => { + monthCanonicalFragmentMap(1.2); + }); + assertThrows(() => { + monthCanonicalFragmentMap(13); + }); + }); +}); + +describe("dayCanonicalFragmentMap", () => { + it("maps the value", () => { + assertStrictEquals(dayCanonicalFragmentMap(1), "01"); + assertStrictEquals(dayCanonicalFragmentMap(12), "12"); + assertStrictEquals(dayCanonicalFragmentMap(21), "21"); + assertStrictEquals(dayCanonicalFragmentMap(30), "30"); + assertStrictEquals(dayCanonicalFragmentMap(31), "31"); + }); + + it("throws an error if the value is not a positive integer less than 32", () => { + assertThrows(() => { + dayCanonicalFragmentMap("01"); + }); + assertThrows(() => { + dayCanonicalFragmentMap(0); + }); + assertThrows(() => { + dayCanonicalFragmentMap(-1); + }); + assertThrows(() => { + dayCanonicalFragmentMap(1.2); + }); + assertThrows(() => { + dayCanonicalFragmentMap(32); + }); + }); +}); + +describe("hourCanonicalFragmentMap", () => { + it("maps the value", () => { + assertStrictEquals(hourCanonicalFragmentMap(0), "00"); + assertStrictEquals(hourCanonicalFragmentMap(-0), "00"); + assertStrictEquals(hourCanonicalFragmentMap(1), "01"); + assertStrictEquals(hourCanonicalFragmentMap(12), "12"); + assertStrictEquals(hourCanonicalFragmentMap(21), "21"); + assertStrictEquals(hourCanonicalFragmentMap(23), "23"); + }); + + it("throws an error if the value is not a nonnegative integer less than 24", () => { + assertThrows(() => { + hourCanonicalFragmentMap("00"); + }); + assertThrows(() => { + hourCanonicalFragmentMap(-1); + }); + assertThrows(() => { + hourCanonicalFragmentMap(1.2); + }); + assertThrows(() => { + hourCanonicalFragmentMap(24); + }); + }); +}); + +describe("minuteCanonicalFragmentMap", () => { + it("maps the value", () => { + assertStrictEquals(minuteCanonicalFragmentMap(0), "00"); + assertStrictEquals(minuteCanonicalFragmentMap(-0), "00"); + assertStrictEquals(minuteCanonicalFragmentMap(1), "01"); + assertStrictEquals(minuteCanonicalFragmentMap(12), "12"); + assertStrictEquals(minuteCanonicalFragmentMap(21), "21"); + assertStrictEquals(minuteCanonicalFragmentMap(32), "32"); + assertStrictEquals(minuteCanonicalFragmentMap(45), "45"); + assertStrictEquals(minuteCanonicalFragmentMap(59), "59"); + }); + + it("throws an error if the value is not a nonnegative integer less than 60", () => { + assertThrows(() => { + minuteCanonicalFragmentMap("00"); + }); + assertThrows(() => { + minuteCanonicalFragmentMap(-1); + }); + assertThrows(() => { + minuteCanonicalFragmentMap(1.2); + }); + assertThrows(() => { + minuteCanonicalFragmentMap(60); + }); + }); +}); + +describe("secondCanonicalFragmentMap", () => { + it("maps the value", () => { + assertStrictEquals(secondCanonicalFragmentMap(0), "00"); + assertStrictEquals(secondCanonicalFragmentMap(-0), "00"); + assertStrictEquals(secondCanonicalFragmentMap(1), "01"); + assertStrictEquals(secondCanonicalFragmentMap(1.2), "01.2"); + assertStrictEquals(secondCanonicalFragmentMap(12), "12"); + assertStrictEquals(secondCanonicalFragmentMap(21), "21"); + assertStrictEquals(secondCanonicalFragmentMap(23.1), "23.1"); + assertStrictEquals(secondCanonicalFragmentMap(32), "32"); + assertStrictEquals(secondCanonicalFragmentMap(45), "45"); + assertStrictEquals(secondCanonicalFragmentMap(59), "59"); + }); + + it("throws an error if the value is not a nonnegative decimal number less than 60", () => { + assertThrows(() => { + secondCanonicalFragmentMap("00"); + }); + assertThrows(() => { + secondCanonicalFragmentMap(-1); + }); + assertThrows(() => { + secondCanonicalFragmentMap(60); + }); + }); +}); + +describe("timezoneCanonicalFragmentMap", () => { + it("maps the value", () => { + assertStrictEquals(timezoneCanonicalFragmentMap(0), "Z"); + assertStrictEquals(timezoneCanonicalFragmentMap(-0), "Z"); + assertStrictEquals(timezoneCanonicalFragmentMap(1), "+00:01"); + assertStrictEquals(timezoneCanonicalFragmentMap(-1), "-00:01"); + assertStrictEquals(timezoneCanonicalFragmentMap(839), "+13:59"); + assertStrictEquals(timezoneCanonicalFragmentMap(-839), "-13:59"); + assertStrictEquals(timezoneCanonicalFragmentMap(840), "+14:00"); + assertStrictEquals(timezoneCanonicalFragmentMap(-840), "-14:00"); + }); + + it("throws an error if the value is not an integer between -840 and 840 inclusive", () => { + assertThrows(() => { + timezoneCanonicalFragmentMap("00"); + }); + assertThrows(() => { + timezoneCanonicalFragmentMap(-841); + }); + assertThrows(() => { + timezoneCanonicalFragmentMap(841); + }); + assertThrows(() => { + timezoneCanonicalFragmentMap(1.2); + }); + }); +}); + +describe("dateTimeCanonicalMap", () => { + it("maps the value", () => { + assertEquals( + dateTimeCanonicalMap({ + year: 1, + month: 1, + day: 1, + hour: 0, + minute: 0, + second: 0, + timezoneOffset: 0, + }), + "0001-01-01T00:00:00Z", + ); + assertEquals( + dateTimeCanonicalMap({ + year: 0, + month: 1, + day: 1, + hour: 0, + minute: 0, + second: 0, + timezoneOffset: 0, + }), + "0000-01-01T00:00:00Z", + ); + assertEquals( + dateTimeCanonicalMap({ + year: -0, + month: 1, + day: 1, + hour: -0, + minute: -0, + second: -0, + timezoneOffset: -0, + }), + "0000-01-01T00:00:00Z", + ); + assertEquals( + dateTimeCanonicalMap({ + year: 1, + month: 1, + day: 1, + hour: 0, + minute: 0, + second: 0, + timezoneOffset: undefined, + }), + "0001-01-01T00:00:00", + ); + assertEquals( + dateTimeCanonicalMap({ + year: 99999, + month: 12, + day: 31, + hour: 23, + minute: 59, + second: 59.99, + timezoneOffset: 840, + }), + "99999-12-31T23:59:59.99+14:00", + ); + assertEquals( + dateTimeCanonicalMap({ + year: 1972, + month: 2, + day: 29, + hour: 0, + minute: 0, + second: 0, + timezoneOffset: undefined, + }), + "1972-02-29T00:00:00", + ); + }); + + it("throws an error if the value is not a date/timeSevenPropertyModel value", () => { + assertThrows(() => { + dateTimeCanonicalMap(0); + }); + assertThrows(() => { + dateTimeCanonicalMap("0001-01-01T00:00:00Z"); + }); + assertThrows(() => { + dateTimeCanonicalMap({ + year: null, + month: null, + day: null, + hour: null, + minute: null, + second: null, + }); + }); + }); + + it("throws an error if the value is not a complete dateTime value", () => { + assertThrows(() => { + dateTimeCanonicalMap({}); + }); + assertThrows(() => { + dateTimeCanonicalMap({ + year: 1972, + month: 12, + day: 31, + timezoneOffset: 0, + }); + }); + }); +}); + +describe("timeCanonicalMap", () => { + it("maps the value", () => { + assertEquals( + timeCanonicalMap({ + year: undefined, + month: undefined, + day: undefined, + hour: 0, + minute: 0, + second: 0, + timezoneOffset: 0, + }), + "00:00:00Z", + ); + assertEquals( + timeCanonicalMap({ + year: undefined, + month: undefined, + day: undefined, + hour: -0, + minute: -0, + second: -0, + timezoneOffset: -0, + }), + "00:00:00Z", + ); + assertEquals( + timeCanonicalMap({ + year: undefined, + month: undefined, + day: undefined, + hour: 23, + minute: 59, + second: 59.99, + timezoneOffset: 840, + }), + "23:59:59.99+14:00", + ); + }); + + it("throws an error if the value is not a date/timeSevenPropertyModel value", () => { + assertThrows(() => { + timeCanonicalMap(0); + }); + assertThrows(() => { + timeCanonicalMap("00:00:00Z"); + }); + assertThrows(() => { + timeCanonicalMap({ + year: undefined, + month: undefined, + day: undefined, + hour: null, + minute: null, + second: null, + }); + }); + }); + + it("throws an error if the value is not a complete time value", () => { + assertThrows(() => { + timeCanonicalMap({}); + }); + assertThrows(() => { + timeCanonicalMap({ + year: 1972, + month: 12, + day: 31, + hour: 0, + minute: 0, + second: 0, + timezoneOffset: 0, + }); + }); + assertThrows(() => { + timeCanonicalMap({ + year: undefined, + month: undefined, + day: undefined, + hour: 0, + minute: 0, + second: undefined, + timezoneOffset: 0, + }); + }); + }); +}); + +describe("dateCanonicalMap", () => { + it("maps the value", () => { + assertEquals( + dateCanonicalMap({ + year: 1, + month: 1, + day: 1, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: 0, + }), + "0001-01-01Z", + ); + assertEquals( + dateCanonicalMap({ + year: 0, + month: 1, + day: 1, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: 0, + }), + "0000-01-01Z", + ); + assertEquals( + dateCanonicalMap({ + year: -0, + month: 1, + day: 1, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: -0, + }), + "0000-01-01Z", + ); + assertEquals( + dateCanonicalMap({ + year: 1, + month: 1, + day: 1, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: undefined, + }), + "0001-01-01", + ); + assertEquals( + dateCanonicalMap({ + year: 99999, + month: 12, + day: 31, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: 840, + }), + "99999-12-31+14:00", + ); + assertEquals( + dateCanonicalMap({ + year: 1972, + month: 2, + day: 29, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: undefined, + }), + "1972-02-29", + ); + }); + + it("throws an error if the value is not a date/timeSevenPropertyModel value", () => { + assertThrows(() => { + dateCanonicalMap(0); + }); + assertThrows(() => { + dateCanonicalMap("0001-01-01Z"); + }); + assertThrows(() => { + dateCanonicalMap({ + year: null, + month: null, + day: null, + hour: undefined, + minute: undefined, + second: undefined, + }); + }); + }); + + it("throws an error if the value is not a complete date value", () => { + assertThrows(() => { + dateCanonicalMap({}); + }); + assertThrows(() => { + dateCanonicalMap({ + year: 1972, + month: 12, + day: 31, + hour: 0, + minute: 0, + second: 0, + timezoneOffset: 0, + }); + }); + assertThrows(() => { + dateCanonicalMap({ year: 1972 }); + }); + }); +}); + +describe("gYearMonthCanonicalMap", () => { + it("maps the value", () => { + assertEquals( + gYearMonthCanonicalMap({ + year: 1, + month: 1, + day: undefined, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: 0, + }), + "0001-01Z", + ); + assertEquals( + gYearMonthCanonicalMap({ + year: 0, + month: 1, + day: undefined, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: 0, + }), + "0000-01Z", + ); + assertEquals( + gYearMonthCanonicalMap({ + year: -0, + month: 1, + day: undefined, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: -0, + }), + "0000-01Z", + ); + assertEquals( + gYearMonthCanonicalMap({ + year: 1, + month: 1, + day: undefined, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: undefined, + }), + "0001-01", + ); + assertEquals( + gYearMonthCanonicalMap({ + year: 99999, + month: 12, + day: undefined, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: 840, + }), + "99999-12+14:00", + ); + assertEquals( + gYearMonthCanonicalMap({ + year: 1972, + month: 2, + day: undefined, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: undefined, + }), + "1972-02", + ); + }); + + it("throws an error if the value is not a date/timeSevenPropertyModel value", () => { + assertThrows(() => { + gYearMonthCanonicalMap(0); + }); + assertThrows(() => { + gYearMonthCanonicalMap("0001-01Z"); + }); + assertThrows(() => { + gYearMonthCanonicalMap({ + year: null, + month: null, + day: undefined, + hour: undefined, + minute: undefined, + second: undefined, + }); + }); + }); + + it("throws an error if the value is not a complete yearMonth value", () => { + assertThrows(() => { + gYearMonthCanonicalMap({}); + }); + assertThrows(() => { + gYearMonthCanonicalMap({ + year: 1972, + month: 12, + day: 31, + hour: 0, + minute: 0, + second: 0, + timezoneOffset: 0, + }); + }); + assertThrows(() => { + gYearMonthCanonicalMap({ year: 1972, month: 12, day: 31 }); + }); + assertThrows(() => { + gYearMonthCanonicalMap({ year: 1972 }); + }); + }); +}); + +describe("gYearCanonicalMap", () => { + it("maps the value", () => { + assertEquals( + gYearCanonicalMap({ + year: 1, + month: undefined, + day: undefined, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: 0, + }), + "0001Z", + ); + assertEquals( + gYearCanonicalMap({ + year: 0, + month: undefined, + day: undefined, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: 0, + }), + "0000Z", + ); + assertEquals( + gYearCanonicalMap({ + year: -0, + month: undefined, + day: undefined, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: -0, + }), + "0000Z", + ); + assertEquals( + gYearCanonicalMap({ + year: 1, + month: undefined, + day: undefined, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: undefined, + }), + "0001", + ); + assertEquals( + gYearCanonicalMap({ + year: 99999, + month: undefined, + day: undefined, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: 840, + }), + "99999+14:00", + ); + assertEquals( + gYearCanonicalMap({ + year: 1972, + month: undefined, + day: undefined, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: undefined, + }), + "1972", + ); + }); + + it("throws an error if the value is not a date/timeSevenPropertyModel value", () => { + assertThrows(() => { + gYearCanonicalMap(0); + }); + assertThrows(() => { + gYearCanonicalMap("0001Z"); + }); + assertThrows(() => { + gYearCanonicalMap({ + year: null, + month: undefined, + day: undefined, + hour: undefined, + minute: undefined, + second: undefined, + }); + }); + }); + + it("throws an error if the value is not a complete gYear value", () => { + assertThrows(() => { + gYearCanonicalMap({}); + }); + assertThrows(() => { + gYearCanonicalMap({ + year: 1972, + month: 12, + day: 31, + hour: 0, + minute: 0, + second: 0, + timezoneOffset: 0, + }); + }); + assertThrows(() => { + gYearCanonicalMap({ year: 1972, month: 12, day: 31 }); + }); + }); +}); + +describe("gMonthDayCanonicalMap", () => { + it("maps the value", () => { + assertEquals( + gMonthDayCanonicalMap({ + year: undefined, + month: 1, + day: 1, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: 0, + }), + "--01-01Z", + ); + assertEquals( + gMonthDayCanonicalMap({ + year: undefined, + month: 1, + day: 1, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: undefined, + }), + "--01-01", + ); + assertEquals( + gMonthDayCanonicalMap({ + year: undefined, + month: 12, + day: 31, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: 840, + }), + "--12-31+14:00", + ); + assertEquals( + gMonthDayCanonicalMap({ + year: undefined, + month: 2, + day: 29, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: undefined, + }), + "--02-29", + ); + }); + + it("throws an error if the value is not a date/timeSevenPropertyModel value", () => { + assertThrows(() => { + gMonthDayCanonicalMap(0); + }); + assertThrows(() => { + gMonthDayCanonicalMap("--01-01Z"); + }); + assertThrows(() => { + gMonthDayCanonicalMap({ + year: undefined, + month: null, + day: null, + hour: undefined, + minute: undefined, + second: undefined, + }); + }); + }); + + it("throws an error if the value is not a complete gMonthDay value", () => { + assertThrows(() => { + gMonthDayCanonicalMap({}); + }); + assertThrows(() => { + gMonthDayCanonicalMap({ + year: 1972, + month: 12, + day: 31, + hour: 0, + minute: 0, + second: 0, + timezoneOffset: 0, + }); + }); + assertThrows(() => { + gMonthDayCanonicalMap({ year: 1972, month: 12, day: 31 }); + }); + assertThrows(() => { + gMonthDayCanonicalMap({ day: 31 }); + }); + }); +}); + +describe("gDayCanonicalMap", () => { + it("maps the value", () => { + assertEquals( + gDayCanonicalMap({ + year: undefined, + month: undefined, + day: 1, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: 0, + }), + "---01Z", + ); + assertEquals( + gDayCanonicalMap({ + year: undefined, + month: undefined, + day: 1, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: undefined, + }), + "---01", + ); + assertEquals( + gDayCanonicalMap({ + year: undefined, + month: undefined, + day: 31, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: 840, + }), + "---31+14:00", + ); + assertEquals( + gDayCanonicalMap({ + year: undefined, + month: undefined, + day: 29, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: undefined, + }), + "---29", + ); + }); + + it("throws an error if the value is not a date/timeSevenPropertyModel value", () => { + assertThrows(() => { + gDayCanonicalMap(0); + }); + assertThrows(() => { + gDayCanonicalMap("---01Z"); + }); + assertThrows(() => { + gDayCanonicalMap({ + year: undefined, + month: undefined, + day: null, + hour: undefined, + minute: undefined, + second: undefined, + }); + }); + }); + + it("throws an error if the value is not a complete gDay value", () => { + assertThrows(() => { + gDayCanonicalMap({}); + }); + assertThrows(() => { + gDayCanonicalMap({ + year: 1972, + month: 12, + day: 31, + hour: 0, + minute: 0, + second: 0, + timezoneOffset: 0, + }); + }); + assertThrows(() => { + gDayCanonicalMap({ year: 1972, month: 12, day: 31 }); + }); + }); +}); + +describe("gMonthCanonicalMap", () => { + it("maps the value", () => { + assertEquals( + gMonthCanonicalMap({ + year: undefined, + month: 1, + day: undefined, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: 0, + }), + "--01Z", + ); + assertEquals( + gMonthCanonicalMap({ + year: undefined, + month: 1, + day: undefined, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: undefined, + }), + "--01", + ); + assertEquals( + gMonthCanonicalMap({ + year: undefined, + month: 12, + day: undefined, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: 840, + }), + "--12+14:00", + ); + assertEquals( + gMonthCanonicalMap({ + year: undefined, + month: 2, + day: undefined, + hour: undefined, + minute: undefined, + second: undefined, + timezoneOffset: undefined, + }), + "--02", + ); + }); + + it("throws an error if the value is not a date/timeSevenPropertyModel value", () => { + assertThrows(() => { + gMonthCanonicalMap(0); + }); + assertThrows(() => { + gMonthCanonicalMap("--01Z"); + }); + assertThrows(() => { + gMonthCanonicalMap({ + year: undefined, + month: null, + day: undefined, + hour: undefined, + minute: undefined, + second: undefined, + }); + }); + }); + + it("throws an error if the value is not a complete gMonth value", () => { + assertThrows(() => { + gMonthCanonicalMap({}); + }); + assertThrows(() => { + gMonthCanonicalMap({ + year: 1972, + month: 12, + day: 31, + hour: 0, + minute: 0, + second: 0, + timezoneOffset: 0, + }); + }); + assertThrows(() => { + gMonthCanonicalMap({ year: 1972, month: 12, day: 31 }); + }); + }); +}); + +describe("stringLexicalMap", () => { + it("maps the value", () => { + assertStrictEquals(stringLexicalMap(""), ""); + assertStrictEquals(stringLexicalMap("etaoin"), "etaoin"); + }); + + it("throws an error if the value is not a string", () => { + assertThrows(() => { + stringLexicalMap({}); + }); + assertThrows(() => { + stringLexicalMap(0); + }); + assertThrows(() => { + stringLexicalMap(new String()); + }); + }); +}); + +describe("booleanLexicalMap", () => { + it("maps the value", () => { + assertStrictEquals(booleanLexicalMap("0"), false); + assertStrictEquals(booleanLexicalMap("false"), false); + assertStrictEquals(booleanLexicalMap("1"), true); + assertStrictEquals(booleanLexicalMap("true"), true); + }); + + it("throws an error if the value is not a string", () => { + assertThrows(() => { + booleanLexicalMap({}); + }); + assertThrows(() => { + booleanLexicalMap(0); + }); + assertThrows(() => { + booleanLexicalMap(false); + }); + }); +}); + +describe("stringCanonicalMap", () => { + it("maps the value", () => { + assertStrictEquals(stringCanonicalMap(""), ""); + assertStrictEquals(stringCanonicalMap("etaoin"), "etaoin"); + }); + + it("throws an error if the value is not a string", () => { + assertThrows(() => { + stringCanonicalMap({}); + }); + assertThrows(() => { + stringCanonicalMap(0); + }); + assertThrows(() => { + stringCanonicalMap(new String()); + }); + }); +}); + +describe("booleanCanonicalMap", () => { + it("maps the value", () => { + assertStrictEquals(booleanCanonicalMap(false), "false"); + assertStrictEquals(booleanCanonicalMap(true), "true"); + }); + + it("throws an error if the value is not a boolean", () => { + assertThrows(() => { + booleanCanonicalMap({}); + }); + assertThrows(() => { + booleanCanonicalMap(0); + }); + assertThrows(() => { + booleanCanonicalMap("false"); + }); + assertThrows(() => { + booleanCanonicalMap(new Boolean()); + }); + }); +}); + +describe("hexBinaryMap", () => { + it("maps the value", () => { + assertEquals( + new Uint8Array(hexBinaryMap("")), + new Uint8Array([]), + ); + assertEquals( + new Uint8Array(hexBinaryMap("4b494249")), + new Uint8Array([75, 73, 66, 73]), + ); + assertEquals( + new Uint8Array(hexBinaryMap("626173653634")), + new Uint8Array([98, 97, 115, 101, 54, 52]), + ); + assertEquals( + new Uint8Array(hexBinaryMap("14FB9C03D97E")), + new Uint8Array([0x14, 0xFB, 0x9C, 0x03, 0xD9, 0x7E]), + ); + }); + + it("throws an error if the value is not a string", () => { + assertThrows(() => { + hexBinaryMap({}); + }); + assertThrows(() => { + hexBinaryMap(0); + }); + assertThrows(() => { + hexBinaryMap(new ArrayBuffer()); + }); + }); + + it("throws an error if the value is not a valid hexBinary", () => { + assertThrows(() => { + hexBinaryMap("A"); + }); + assertThrows(() => { + hexBinaryMap("EG"); + }); + }); +}); + +describe("hexBinaryCanonical", () => { + it("maps the value", () => { + assertStrictEquals( + hexBinaryCanonical(new ArrayBuffer()), + "", + ); + assertEquals( + hexBinaryCanonical(new Uint8Array([75, 73, 66, 73]).buffer), + "4B494249", + ); + assertEquals( + hexBinaryCanonical( + new Uint8Array([98, 97, 115, 101, 54, 52]).buffer, + ), + "626173653634", + ); + assertEquals( + hexBinaryCanonical( + new Uint8Array([0x14, 0xFB, 0x9C, 0x03, 0xD9, 0x7E]).buffer, + ), + "14FB9C03D97E", + ); + }); + + it("throws an error if the value is not an array buffer", () => { + assertThrows(() => { + hexBinaryCanonical({}); + }); + assertThrows(() => { + hexBinaryCanonical(0); + }); + assertThrows(() => { + hexBinaryCanonical(""); + }); + assertThrows(() => { + hexBinaryCanonical(new Uint8Array([])); + }); + }); +});