« get me outta code hell

Merge branch 'preview' into track-data-cleanup - hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/test/lib
diff options
context:
space:
mode:
author(quasar) nebula <qznebula@protonmail.com>2023-09-05 21:03:16 -0300
committer(quasar) nebula <qznebula@protonmail.com>2023-09-05 21:03:16 -0300
commit044ac1a804e0f42aaa13a9280ba68effc7a65606 (patch)
treecd6df28a76822c46cac9976781014edc98c8d41a /test/lib
parenta3b80f08fc54cda6a6787bcd078059823026add6 (diff)
parent0ff743b1350b1d42ba23d9701a0b7acfb7501254 (diff)
Merge branch 'preview' into track-data-cleanup
Diffstat (limited to 'test/lib')
-rw-r--r--test/lib/content-function.js96
1 files changed, 81 insertions, 15 deletions
diff --git a/test/lib/content-function.js b/test/lib/content-function.js
index bb12be8..5cb499b 100644
--- a/test/lib/content-function.js
+++ b/test/lib/content-function.js
@@ -1,5 +1,6 @@
 import * as path from 'node:path';
 import {fileURLToPath} from 'node:url';
+import {inspect} from 'node:util';
 
 import chroma from 'chroma-js';
 
@@ -90,27 +91,92 @@ export function testContentFunctions(t, message, fn) {
       t.matchSnapshot(result, description);
     };
 
-    evaluate.stubTemplate = name => {
+    evaluate.stubTemplate = name =>
       // Creates a particularly permissable template, allowing any slot values
       // to be stored and just outputting the contents of those slots as-are.
+      _stubTemplate(name, false);
 
-      return new (class extends html.Template {
-        #slotValues = {};
+    evaluate.stubContentFunction = name =>
+      // Like stubTemplate, but instead of a template directly, returns
+      // an object describing a content function - suitable for passing
+      // into evaluate.mock.
+      _stubTemplate(name, true);
 
-        constructor() {
-          super({
-            content: () => `${name}: ${JSON.stringify(this.#slotValues)}`,
-          });
-        }
+    const _stubTemplate = (name, mockContentFunction) => {
+      const inspectNicely = (value, opts = {}) =>
+        inspect(value, {
+          ...opts,
+          colors: false,
+          sort: true,
+        });
 
-        setSlots(slotNamesToValues) {
-          Object.assign(this.#slotValues, slotNamesToValues);
-        }
+      const makeTemplate = formatContentFn =>
+        new (class extends html.Template {
+          #slotValues = {};
 
-        setSlot(slotName, slotValue) {
-          this.#slotValues[slotName] = slotValue;
-        }
-      });
+          constructor() {
+            super({
+              content: () => this.#getContent(formatContentFn),
+            });
+          }
+
+          setSlots(slotNamesToValues) {
+            Object.assign(this.#slotValues, slotNamesToValues);
+          }
+
+          setSlot(slotName, slotValue) {
+            this.#slotValues[slotName] = slotValue;
+          }
+
+          #getContent(formatContentFn) {
+            const toInspect =
+              Object.fromEntries(
+                Object.entries(this.#slotValues)
+                  .filter(([key, value]) => value !== null));
+
+            const inspected =
+              inspectNicely(toInspect, {
+                breakLength: Infinity,
+                compact: true,
+                depth: Infinity,
+              });
+
+            return formatContentFn(inspected); `${name}: ${inspected}`;
+          }
+        });
+
+      if (mockContentFunction) {
+        return {
+          data: (...args) => ({args}),
+          generate: (data) =>
+            makeTemplate(slots => {
+              const argsLines =
+                (empty(data.args)
+                  ? []
+                  : inspectNicely(data.args, {depth: Infinity})
+                      .split('\n'));
+
+              return (`[mocked: ${name}` +
+
+                (empty(data.args)
+                  ? ``
+               : argsLines.length === 1
+                  ? `\n args: ${argsLines[0]}`
+                  : `\n args: ${argsLines[0]}\n` +
+                    argsLines.slice(1).join('\n').replace(/^/gm, ' ')) +
+
+                (!empty(data.args)
+                  ? `\n `
+                  : ` - `) +
+
+                (slots
+                  ? `slots: ${slots}]`
+                  : `slots: none]`));
+            }),
+        };
+      } else {
+        return makeTemplate(slots => `${name}: ${slots}`);
+      }
     };
 
     evaluate.mock = (...opts) => {