]> Lady’s Gitweb - Pisces/blobdiff - iri.test.js
Make base32 handling less forgiving
[Pisces] / iri.test.js
index 51749cdbd840d2791d775b70938065d439ff80b7..f92957d42be98bec950c09174b3c515655bb0d94 100644 (file)
@@ -1,32 +1,44 @@
 // ♓🌟 Piscēs ∷ iri.test.js
 // ====================================================================
 //
 // ♓🌟 Piscēs ∷ iri.test.js
 // ====================================================================
 //
-// Copyright © 2020–2022 Lady [@ Lady’s Computer].
+// Copyright © 2022 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/>.
 
 //
 // 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 {
+  assertEquals,
+  assertStrictEquals,
+  describe,
+  it,
+} from "./dev-deps.js";
 import {
   composeReference,
 import {
   composeReference,
-  iri2uri,
+  escapeForIRI,
+  escapeForURI,
   isAbsoluteIRI,
   isAbsoluteIRI,
+  isAbsoluteLEIRI,
   isAbsoluteURI,
   isIRI,
   isAbsoluteURI,
   isIRI,
+  isIRIPath,
   isIRIReference,
   isIRIReference,
+  isIRISuffix,
+  isLEIRI,
+  isLEIRIPath,
+  isLEIRIReference,
+  isLEIRISuffix,
   isURI,
   isURI,
+  isURIPath,
   isURIReference,
   isURIReference,
+  isURISuffix,
+  mergePaths,
   parseReference,
   removeDotSegments,
   resolveReference,
 } from "./iri.js";
   parseReference,
   removeDotSegments,
   resolveReference,
 } from "./iri.js";
-import {
-  assert,
-  assertEquals,
-  assertStrictEquals,
-} from "./dev-deps.js";
 
 
-const exampleURIs = {
+const exampleURIReferences = {
   "ftp://ftp.is.co.za/rfc/rfc1808.txt": {
     scheme: "ftp",
     authority: "ftp.is.co.za",
   "ftp://ftp.is.co.za/rfc/rfc1808.txt": {
     scheme: "ftp",
     authority: "ftp.is.co.za",
@@ -71,17 +83,15 @@ const exampleURIs = {
     query: "name=ferret",
     fragment: "nose",
   },
     query: "name=ferret",
     fragment: "nose",
   },
-};
-
-const exampleURIReferences = {
-  ...exampleURIs,
   "./this:that": {
     path: "./this:that",
   },
 };
 
   "./this:that": {
     path: "./this:that",
   },
 };
 
-const exampleIRIs = {
-  ...exampleURIs,
+// If `path` is non·empty, it must contain an IRI character for tests
+// to pass.
+const exampleIRIReferences = {
+  ...exampleURIReferences,
   "http://ヒキワリ.ナットウ.ニホン": {
     scheme: "http",
     authority: "ヒキワリ.ナットウ.ニホン",
   "http://ヒキワリ.ナットウ.ニホン": {
     scheme: "http",
     authority: "ヒキワリ.ナットウ.ニホン",
@@ -92,71 +102,331 @@ const exampleIRIs = {
     authority: "JP納豆.例.jp",
     path: "/dir1/引き割り.html",
   },
     authority: "JP納豆.例.jp",
     path: "/dir1/引き割り.html",
   },
+  "/dir1/引き割り.html": {
+    path: "/dir1/引き割り.html",
+  },
 };
 
 };
 
-const exampleIRIReferences = {
-  ...exampleURIReferences,
-  ...exampleIRIs,
+// If `path` is non·empty, it must contain an LEIRI character for tests
+// to pass.
+const exampleLEIRIReferences = {
+  ...exampleIRIReferences,
+  "http://example.com/ foo /": {
+    scheme: "http",
+    authority: "example.com",
+    path: "/ foo /",
+  },
+  "\0": {
+    path: "\0",
+  },
 };
 
 };
 
-Deno.test({
-  name: "Identifies U·R·Is.",
-  fn: () => {
-    for (const uri of Object.keys(exampleURIs)) {
-      assert(isURI(uri));
+// These will not parse, so the parse result must be empty.
+const exampleReferences = {
+  ...exampleLEIRIReferences,
+  "\uD800": {},
+  "\uFFFE": {},
+  "\uFFFF": {},
+};
+
+describe("composeReference", () => {
+  it("[[Call]] correctly composes references", () => {
+    for (
+      const [iri, value] of Object.entries(exampleLEIRIReferences)
+    ) {
+      assertStrictEquals(composeReference(value), iri);
+    }
+  });
+});
+
+describe("escapeForIRI", () => {
+  it("[[Call]] converts L·E·I·R·Is to I·R·Is", () => {
+    assertStrictEquals(
+      escapeForIRI(" æ\0"),
+      "%20æ%00",
+    );
+    assertStrictEquals(
+      escapeForIRI("\u{F0000}?\u{F0000}#\u{F0000}"),
+      "%F3%B0%80%80?\u{F0000}#%F3%B0%80%80",
+    );
+  });
+});
+
+describe("escapeForURI", () => {
+  it("[[Call]] converts L·E·I·R·Is to U·R·Is", () => {
+    assertStrictEquals(
+      escapeForURI("/dir1/引き割り.html"),
+      "/dir1/%E5%BC%95%E3%81%8D%E5%89%B2%E3%82%8A.html",
+    );
+    assertStrictEquals(
+      escapeForURI(" æ\0"),
+      "%20%C3%A6%00",
+    );
+    assertStrictEquals(
+      escapeForURI("\u{F0000}?\u{F0000}#\u{F0000}"),
+      "%F3%B0%80%80?%F3%B0%80%80#%F3%B0%80%80",
+    );
+  });
+});
+
+describe("isAbsoluteIRI", () => {
+  it("[[Call]] identifies absolute I·R·Is", () => {
+    for (
+      const [iri, { scheme, fragment }] of Object.entries(
+        exampleReferences,
+      )
+    ) {
+      assertStrictEquals(
+        isAbsoluteIRI(iri),
+        iri in exampleIRIReferences && scheme != null &&
+          fragment == null,
+        iri,
+      );
     }
     }
-  },
+  });
 });
 
 });
 
-Deno.test({
-  name: "Identifies absolute U·R·Is.",
-  fn: () => {
-    for (const [uri, { fragment }] of Object.entries(exampleURIs)) {
-      assertStrictEquals(isAbsoluteURI(uri), fragment == null);
+describe("isAbsoluteLEIRI", () => {
+  it("[[Call]] identifies absolute L·E·I·R·Is", () => {
+    for (
+      const [leiri, { scheme, fragment }] of Object.entries(
+        exampleReferences,
+      )
+    ) {
+      assertStrictEquals(
+        isAbsoluteLEIRI(leiri),
+        leiri in exampleLEIRIReferences && scheme != null &&
+          fragment == null,
+        leiri,
+      );
     }
     }
-  },
+  });
 });
 
 });
 
-Deno.test({
-  name: "Identifies U·R·I references.",
-  fn: () => {
-    for (const uri of Object.keys(exampleURIReferences)) {
-      assert(isURIReference(uri));
+describe("isAbsoluteURI", () => {
+  it("[[Call]] identifies absolute U·R·Is", () => {
+    for (
+      const [uri, { scheme, fragment }] of Object.entries(
+        exampleReferences,
+      )
+    ) {
+      assertStrictEquals(
+        isAbsoluteURI(uri),
+        uri in exampleURIReferences && scheme != null &&
+          fragment == null,
+        uri,
+      );
     }
     }
-  },
+  });
 });
 
 });
 
-Deno.test({
-  name: "Identifies I·R·Is.",
-  fn: () => {
-    for (const iri of Object.keys(exampleIRIs)) {
-      assert(isIRI(iri));
+describe("isIRI", () => {
+  it("[[Call]] identifies I·R·Is", () => {
+    for (
+      const [iri, { scheme }] of Object.entries(exampleReferences)
+    ) {
+      assertStrictEquals(
+        isIRI(iri),
+        iri in exampleIRIReferences && scheme != null,
+        iri,
+      );
     }
     }
-  },
+  });
 });
 
 });
 
-Deno.test({
-  name: "Identifies absolute I·R·Is.",
-  fn: () => {
-    for (const [iri, { fragment }] of Object.entries(exampleIRIs)) {
-      assertStrictEquals(isAbsoluteIRI(iri), fragment == null);
+describe("isIRIPath", () => {
+  it("[[Call]] identifies I·R·I paths", () => {
+    for (const [iri, { path }] of Object.entries(exampleReferences)) {
+      if (path === "") {
+        continue;
+      } else {
+        assertStrictEquals(
+          isIRIPath(path ?? iri),
+          iri in exampleIRIReferences,
+          path,
+        );
+      }
     }
     }
-  },
+  });
 });
 
 });
 
-Deno.test({
-  name: "Identifies I·R·I references.",
-  fn: () => {
-    for (const iri of Object.keys(exampleIRIReferences)) {
-      assert(isIRIReference(iri));
+describe("isIRIReference", () => {
+  it("[[Call]] identifies I·R·I references", () => {
+    for (const iri of Object.keys(exampleReferences)) {
+      assertStrictEquals(
+        isIRIReference(iri),
+        iri in exampleIRIReferences,
+        iri,
+      );
     }
     }
-  },
+  });
 });
 
 });
 
-Deno.test({
-  name: "Correctly parses references.",
-  fn: () => {
-    for (const [iri, value] of Object.entries(exampleIRIReferences)) {
+describe("isIRISuffix", () => {
+  it("[[Call]] identifies I·R·I suffixes", () => {
+    for (
+      const [iri, { authority, path }] of Object.entries(
+        exampleReferences,
+      )
+    ) {
+      if (!authority) {
+        continue;
+      } else {
+        assertStrictEquals(
+          isIRISuffix(authority + path),
+          iri in exampleIRIReferences,
+          path,
+        );
+      }
+    }
+  });
+});
+
+describe("isLEIRI", () => {
+  it("[[Call]] identifies L·E·I·R·Is", () => {
+    for (
+      const [leiri, { scheme }] of Object.entries(exampleReferences)
+    ) {
+      assertStrictEquals(
+        isLEIRI(leiri),
+        leiri in exampleLEIRIReferences && scheme != null,
+        leiri,
+      );
+    }
+  });
+});
+
+describe("isLEIRIPath", () => {
+  it("[[Call]] identifies L·E·I·R·I paths", () => {
+    for (
+      const [leiri, { path }] of Object.entries(exampleReferences)
+    ) {
+      if (path === "") {
+        continue;
+      } else {
+        assertStrictEquals(
+          isLEIRIPath(path ?? leiri),
+          leiri in exampleLEIRIReferences,
+          path,
+        );
+      }
+    }
+  });
+});
+
+describe("isLEIRIReference", () => {
+  it("[[Call]] identifies L·E·I·R·I references", () => {
+    for (const leiri of Object.keys(exampleReferences)) {
+      assertStrictEquals(
+        isLEIRIReference(leiri),
+        leiri in exampleLEIRIReferences,
+        leiri,
+      );
+    }
+  });
+});
+
+describe("isLEIRISuffix", () => {
+  it("[[Call]] identifies L·E·I·R·I suffixes", () => {
+    for (
+      const [leiri, { authority, path }] of Object.entries(
+        exampleReferences,
+      )
+    ) {
+      if (!authority) {
+        continue;
+      } else {
+        assertStrictEquals(
+          isLEIRISuffix(authority + path),
+          leiri in exampleLEIRIReferences,
+          path,
+        );
+      }
+    }
+  });
+});
+
+describe("isURI", () => {
+  it("[[Call]] identifies U·R·Is", () => {
+    for (
+      const [uri, { scheme }] of Object.entries(exampleReferences)
+    ) {
+      assertStrictEquals(
+        isURI(uri),
+        uri in exampleURIReferences && scheme != null,
+        uri,
+      );
+    }
+  });
+});
+
+describe("isURIPath", () => {
+  it("[[Call]] identifies U·R·I paths", () => {
+    for (const [uri, { path }] of Object.entries(exampleReferences)) {
+      if (path === "") {
+        continue;
+      } else {
+        assertStrictEquals(
+          isURIPath(path ?? uri),
+          uri in exampleURIReferences,
+          path,
+        );
+      }
+    }
+  });
+});
+
+describe("isURIReference", () => {
+  it("[[Call]] identifies U·R·I references", () => {
+    for (const uri of Object.keys(exampleReferences)) {
+      assertStrictEquals(
+        isURIReference(uri),
+        uri in exampleURIReferences,
+        uri,
+      );
+    }
+  });
+});
+
+describe("isURISuffix", () => {
+  it("[[Call]] identifies U·R·I suffixes", () => {
+    for (
+      const [uri, { authority, path }] of Object.entries(
+        exampleReferences,
+      )
+    ) {
+      if (!authority) {
+        continue;
+      } else {
+        assertStrictEquals(
+          isURISuffix(authority + path),
+          uri in exampleURIReferences,
+          path,
+        );
+      }
+    }
+  });
+});
+
+describe("mergePaths", () => {
+  it("[[Call]] handles the case of an empty base path", () => {
+    assertStrictEquals(
+      mergePaths("", "etaoin"),
+      "/etaoin",
+    );
+  });
+
+  it("[[Call]] handles the case of a non·empty base path", () => {
+    assertStrictEquals(
+      mergePaths("/etaoin/cmfwyp", "shrdlu"),
+      "/etaoin/shrdlu",
+    );
+  });
+});
+
+describe("parseReference", () => {
+  it("[[Call]] correctly parses references", () => {
+    for (const [iri, value] of Object.entries(exampleReferences)) {
       assertEquals(parseReference(iri), {
         scheme: undefined,
         authority: undefined,
       assertEquals(parseReference(iri), {
         scheme: undefined,
         authority: undefined,
@@ -166,42 +436,21 @@ Deno.test({
         ...value,
       });
     }
         ...value,
       });
     }
-  },
-});
-
-Deno.test({
-  name: "Correctly composes references.",
-  fn: () => {
-    for (const [iri, value] of Object.entries(exampleIRIReferences)) {
-      assertStrictEquals(composeReference(value), iri);
-    }
-  },
-});
-
-Deno.test({
-  name: "Converts IRIs to URIs.",
-  fn: () => {
-    assertStrictEquals(
-      iri2uri("/dir1/引き割り.html"),
-      "/dir1/%E5%BC%95%E3%81%8D%E5%89%B2%E3%82%8A.html",
-    );
-  },
+  });
 });
 
 });
 
-Deno.test({
-  name: "Correctly removes dot segments.",
-  fn: () => {
+describe("removeDotSegments", () => {
+  it("[[Call]] correctly removes dot segments", () => {
     assertStrictEquals(removeDotSegments("/a/b/c/./../../g"), "/a/g");
     assertStrictEquals(
       removeDotSegments("mid/content=5/../6"),
       "mid/6",
     );
     assertStrictEquals(removeDotSegments("/a/b/c/./../../g"), "/a/g");
     assertStrictEquals(
       removeDotSegments("mid/content=5/../6"),
       "mid/6",
     );
-  },
+  });
 });
 
 });
 
-Deno.test({
-  name: "Correctly resolves references.",
-  fn: () => {
+describe("resolveReference", () => {
+  it("[[Call]] correctly resolves references", () => {
     const base = "http://a/b/c/d;p?q";
     assertStrictEquals(resolveReference("g:h", base), "g:h");
     assertStrictEquals(resolveReference("g", base), "http://a/b/c/g");
     const base = "http://a/b/c/d;p?q";
     assertStrictEquals(resolveReference("g:h", base), "g:h");
     assertStrictEquals(resolveReference("g", base), "http://a/b/c/g");
@@ -329,5 +578,5 @@ Deno.test({
       "http://a/b/c/g#s/../x",
     );
     assertStrictEquals(resolveReference("http:g", base), "http:g");
       "http://a/b/c/g#s/../x",
     );
     assertStrictEquals(resolveReference("http:g", base), "http:g");
-  },
+  });
 });
 });
This page took 0.033568 seconds and 4 git commands to generate.