Cannabis Freedom Index

Changelog 1ce6d97tree

Fix Guyana history citations and validate profile/history source lists

1 history entry edited1 file of code, design or docs +39 −2 lines

History changes.yaml

Edited 1

British Guiana regulates the sale of bhang

description

Ordinance No. 22 licensed the sale of ganja and bhang.[@1] The chapter describes the measure as anticipatory: officials introduced it before cannabis … labourers from India, though by the early twentieth century it had fallen from fashion.[@12]

Code, design and documents 1 file

scripts/history-scope.test.cjs +37 −0
@@ -967,4 +967,41 @@ test("no history entry is dated in the future: history is what has happened", ()
 });
 
+test("country sections and history entries have complete, valid inline citation lists", async () => {
+  const { citeParts, references } = await import("../src/lib/cite.js");
+  const bad = [];
+  const check = (text, keys, resolve, where) => {
+    try {
+      citeParts(text, references(), resolve, keys, where);
+    } catch (error) {
+      bad.push(error.message);
+    }
+  };
+  for (const entry of changes) {
+    check(entry.description, entry.sources.map((_, i) => String(i + 1)), (key) => {
+      const source = entry.sources[Number(key) - 1];
+      return source && [source.title, source.url];
+    }, `changes.yaml: ${entry.id}`);
+  }
+  for (const file of fs.readdirSync("countries", { recursive: true }).filter(f => f.endsWith(".yaml"))) {
+    const profile = y.load(fs.readFileSync(`countries/${file}`, "utf8"));
+    // State files number their shared references across several segments;
+    // national profiles give each cited section its own list of source keys.
+    if (Array.isArray(profile.sources)) continue;
+    const visit = (value, where) => {
+      if (!value || typeof value !== "object") return;
+      if (typeof value.text === "string" && Array.isArray(value.sources)) {
+        check(value.text, value.sources, (key) => {
+          const source = value.sources.includes(key) && profile.sources[key];
+          return source && [source.title, source.url];
+        }, where);
+      }
+      for (const [key, child] of Object.entries(value)) visit(child, `${where}.${key}`);
+    };
+    visit(profile.segments, `countries/${file}: segments`);
+    visit(profile.context, `countries/${file}: context`);
+  }
+  assert.deepEqual(bad, []);
+});
+
 test("every article's inline citations resolve to its own front-matter sources", () => {
   // Article [@n] marks index the article's front-matter `sources`, not the

    ↑↓ to move, ↵ to open.