]> Lady’s Gitweb - Sutra/blobdiff - xsd/functions.test.js
Add all X·S·D non‐auxillary functions
[Sutra] / xsd / functions.test.js
diff --git a/xsd/functions.test.js b/xsd/functions.test.js
new file mode 100644 (file)
index 0000000..8692c33
--- /dev/null
@@ -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 <https://mozilla.org/MPL/2.0/>.
+
+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([]));
+    });
+  });
+});
This page took 0.701073 seconds and 4 git commands to generate.