« get me outta code hell

hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/test/unit
diff options
context:
space:
mode:
Diffstat (limited to 'test/unit')
-rw-r--r--test/unit/data/cacheable-object.js2
-rw-r--r--test/unit/data/composite/data/withUniqueItemsOnly.js84
-rw-r--r--test/unit/data/composite/wiki-data/withParsedCommentaryEntries.js102
-rw-r--r--test/unit/data/things/track.js48
-rw-r--r--test/unit/data/things/validators.js17
5 files changed, 232 insertions, 21 deletions
diff --git a/test/unit/data/cacheable-object.js b/test/unit/data/cacheable-object.js
index 57e562d8..5ed9a4a9 100644
--- a/test/unit/data/cacheable-object.js
+++ b/test/unit/data/cacheable-object.js
@@ -1,6 +1,6 @@
 import t from 'tap';
 
-import {CacheableObject} from '#things';
+import CacheableObject from '#cacheable-object';
 
 function newCacheableObject(PD) {
   return new (class extends CacheableObject {
diff --git a/test/unit/data/composite/data/withUniqueItemsOnly.js b/test/unit/data/composite/data/withUniqueItemsOnly.js
new file mode 100644
index 00000000..965b14b5
--- /dev/null
+++ b/test/unit/data/composite/data/withUniqueItemsOnly.js
@@ -0,0 +1,84 @@
+import t from 'tap';
+
+import {compositeFrom, input} from '#composite';
+import {exposeDependency} from '#composite/control-flow';
+import {withUniqueItemsOnly} from '#composite/data';
+
+t.test(`withUniqueItemsOnly: basic behavior`, t => {
+  t.plan(3);
+
+  const composite = compositeFrom({
+    compose: false,
+
+    steps: [
+      withUniqueItemsOnly({
+        list: 'list',
+      }),
+
+      exposeDependency({dependency: '#list'}),
+    ],
+  });
+
+  t.match(composite, {
+    expose: {
+      dependencies: ['list'],
+    },
+  });
+
+  t.same(composite.expose.compute({
+    list: ['apple', 'banana', 'banana', 'banana', 'apple', 'watermelon'],
+  }), ['apple', 'banana', 'watermelon']);
+
+  t.same(composite.expose.compute({
+    list: [],
+  }), []);
+});
+
+t.test(`withUniqueItemsOnly: output shapes & values`, t => {
+  t.plan(2 * 3 ** 1);
+
+  const dependencies = {
+    ['list_dependency']:
+      [1, 1, 2, 3, 3, 4, 'foo', false, false, 4],
+    [input('list_neither')]:
+      [8, 8, 7, 6, 6, 5, 'bar', true, true, 5],
+  };
+
+  const mapLevel1 = [
+    ['list_dependency', {
+      '#list_dependency': [1, 2, 3, 4, 'foo', false],
+    }],
+    [input.value([-1, -1, 'interesting', 'very', 'interesting']), {
+      '#uniqueItems': [-1, 'interesting', 'very'],
+    }],
+    [input('list_neither'), {
+      '#uniqueItems': [8, 7, 6, 5, 'bar', true],
+    }],
+  ];
+
+  for (const [listInput, outputDict] of mapLevel1) {
+    const step = withUniqueItemsOnly({
+      list: listInput,
+    });
+
+    quickCheckOutputs(step, outputDict);
+  }
+
+  function quickCheckOutputs(step, outputDict) {
+    t.same(
+      Object.keys(step.toDescription().outputs),
+      Object.keys(outputDict));
+
+    const composite = compositeFrom({
+      compose: false,
+      steps: [step, {
+        dependencies: Object.keys(outputDict),
+        compute: dependencies => dependencies,
+      }],
+    });
+
+    t.same(
+      composite.expose.compute(dependencies),
+      outputDict);
+  }
+});
diff --git a/test/unit/data/composite/wiki-data/withParsedCommentaryEntries.js b/test/unit/data/composite/wiki-data/withParsedCommentaryEntries.js
new file mode 100644
index 00000000..babe4fae
--- /dev/null
+++ b/test/unit/data/composite/wiki-data/withParsedCommentaryEntries.js
@@ -0,0 +1,102 @@
+import t from 'tap';
+
+import {compositeFrom, input} from '#composite';
+import thingConstructors from '#things';
+
+import {exposeDependency} from '#composite/control-flow';
+import {withParsedCommentaryEntries} from '#composite/wiki-data';
+
+const {Artist} = thingConstructors;
+
+const composite = compositeFrom({
+  compose: false,
+
+  steps: [
+    withParsedCommentaryEntries({
+      from: 'from',
+    }),
+
+    exposeDependency({dependency: '#parsedCommentaryEntries'}),
+  ],
+});
+
+function stubArtist(artistName = `Test Artist`) {
+  const artist = new Artist();
+  artist.name = artistName;
+
+  return artist;
+}
+
+t.test(`withParsedCommentaryEntries: basic behavior`, t => {
+  t.plan(3);
+
+  const artist1 = stubArtist(`Mobius Trip`);
+  const artist2 = stubArtist(`Hadron Kaleido`);
+
+  const artistData = [artist1, artist2];
+
+  t.match(composite, {
+    expose: {
+      dependencies: ['from', 'artistData'],
+    },
+  });
+
+  t.same(composite.expose.compute({
+    artistData,
+    from:
+      `<i>Mobius Trip:</i>\n` +
+      `Some commentary.\n` +
+      `Very cool.\n`,
+  }), [
+    {
+      artists: [artist1],
+      artistDisplayText: null,
+      annotation: null,
+      date: null,
+      body: `Some commentary.\nVery cool.`,
+    },
+  ]);
+
+  t.same(composite.expose.compute({
+    artistData,
+    from:
+      `<i>Mobius Trip|Moo-bius Trip:</i> (music, art, 12 January 2015)\n` +
+      `First commentary entry.\n` +
+      `Very cool.\n` +
+      `<i>Hadron Kaleido|<b>[[artist:hadron-kaleido|The Ol' Hadron]]</b>:</i> (moral support, 4/4/2022)\n` +
+      `Second commentary entry. Yes. So cool.\n` +
+      `<i>Mystery Artist:</i> (pingas, August 25, 2023)\n` +
+      `Oh no.. Oh dear...\n` +
+      `<i>Mobius Trip, Hadron Kaleido:</i>\n` +
+      `And back around we go.`,
+  }), [
+    {
+      artists: [artist1],
+      artistDisplayText: `Moo-bius Trip`,
+      annotation: `music, art`,
+      date: new Date('12 January 2015'),
+      body: `First commentary entry.\nVery cool.`,
+    },
+    {
+      artists: [artist2],
+      artistDisplayText: `<b>[[artist:hadron-kaleido|The Ol' Hadron]]</b>`,
+      annotation: `moral support`,
+      date: new Date('4 April 2022'),
+      body: `Second commentary entry. Yes. So cool.`,
+    },
+    {
+      artists: [],
+      artistDisplayText: null,
+      annotation: `pingas`,
+      date: new Date('25 August 2023'),
+      body: `Oh no.. Oh dear...`,
+    },
+    {
+      artists: [artist1, artist2],
+      artistDisplayText: null,
+      annotation: null,
+      date: null,
+      body: `And back around we go.`,
+    },
+  ]);
+});
diff --git a/test/unit/data/things/track.js b/test/unit/data/things/track.js
index 51f86070..f84ba1cb 100644
--- a/test/unit/data/things/track.js
+++ b/test/unit/data/things/track.js
@@ -215,7 +215,7 @@ t.test(`Track.color`, t => {
 });
 
 t.test(`Track.commentatorArtists`, t => {
-  t.plan(6);
+  t.plan(8);
 
   const track = new Track();
   const artist1 = stubArtist(`SnooPING`);
@@ -227,47 +227,67 @@ t.test(`Track.commentatorArtists`, t => {
     artistData: [artist1, artist2, artist3],
   });
 
-  track.commentary =
+  // Keep track of the last commentary string in a separate value, since
+  // the track.commentary property exposes as a completely different format
+  // (i.e. an array of objects, one for each entry), and so isn't compatible
+  // with the += operator on its own.
+  let commentary;
+
+  track.commentary = commentary =
     `<i>SnooPING:</i>\n` +
     `Wow.\n`;
 
   t.same(track.commentatorArtists, [artist1],
     `Track.commentatorArtists #1: works with one commentator`);
 
-  track.commentary +=
+  track.commentary = commentary +=
     `<i>ASUsual:</i>\n` +
     `Yes!\n`;
 
   t.same(track.commentatorArtists, [artist1, artist2],
     `Track.commentatorArtists #2: works with two commentators`);
 
-  track.commentary +=
-    `<i><b>Icy:</b></i>\n` +
+  track.commentary = commentary +=
+    `<i>Icy|<b>Icy What You Did There</b>:</i>\n` +
     `Incredible.\n`;
 
   t.same(track.commentatorArtists, [artist1, artist2, artist3],
-    `Track.commentatorArtists #3: works with boldface name`);
+    `Track.commentatorArtists #3: works with custom artist text`);
 
-  track.commentary =
+  track.commentary = commentary =
     `<i>Icy:</i> (project manager)\n` +
     `Very good track.\n`;
 
   t.same(track.commentatorArtists, [artist3],
-    `Track.commentatorArtists #4: works with parenthical accent`);
+    `Track.commentatorArtists #4: works with annotation`);
 
-  track.commentary +=
-    `<i>SNooPING ASUsual Icy:</i>\n` +
-    `WITH ALL THREE POWERS COMBINED...`;
+  track.commentary = commentary =
+    `<i>Icy:</i> (project manager, 08/15/2023)\n` +
+    `Very very good track.\n`;
+
+  t.same(track.commentatorArtists, [artist3],
+    `Track.commentatorArtists #5: works with date`);
+
+  track.commentary = commentary +=
+    `<i>Ohohohoho:</i>\n` +
+    `OHOHOHOHOHOHO...\n`;
 
   t.same(track.commentatorArtists, [artist3],
-    `Track.commentatorArtists #5: ignores artist names not found`);
+    `Track.commentatorArtists #6: ignores artist names not found`);
 
-  track.commentary +=
+  track.commentary = commentary +=
     `<i>Icy:</i>\n` +
     `I'm back!\n`;
 
   t.same(track.commentatorArtists, [artist3],
-    `Track.commentatorArtists #6: ignores duplicate artist`);
+    `Track.commentatorArtists #7: ignores duplicate artist`);
+
+  track.commentary = commentary +=
+    `<i>SNooPING, ASUsual, Icy:</i>\n` +
+    `WITH ALL THREE POWERS COMBINED...`;
+
+  t.same(track.commentatorArtists, [artist3, artist1, artist2],
+    `Track.commentatorArtists #8: works with more than one artist in one entry`);
 });
 
 t.test(`Track.coverArtistContribs`, t => {
diff --git a/test/unit/data/things/validators.js b/test/unit/data/things/validators.js
index bb33bf86..aa56a10e 100644
--- a/test/unit/data/things/validators.js
+++ b/test/unit/data/things/validators.js
@@ -149,13 +149,18 @@ t.test('isColor', t => {
 });
 
 t.test('isCommentary', t => {
-  t.plan(6);
+  t.plan(9);
+
+  // TODO: Test specific error messages.
   t.ok(isCommentary(`<i>Toby Fox:</i>\ndogsong.mp3`));
-  t.ok(isCommentary(`Technically, this works:</i>`));
-  t.ok(isCommentary(`<i><b>Whodunnit:</b></i>`));
-  t.throws(() => isCommentary(123), TypeError);
-  t.throws(() => isCommentary(``), TypeError);
-  t.throws(() => isCommentary(`<i><u>Toby Fox:</u></i>`));
+  t.ok(isCommentary(`<i>Toby Fox:</i> (music)\ndogsong.mp3`));
+  t.throws(() => isCommentary(`dogsong.mp3\n<i>Toby Fox:</i>\ndogsong.mp3`));
+  t.throws(() => isCommentary(`<i>Toby Fox:</i> dogsong.mp3`));
+  t.throws(() => isCommentary(`<i>Toby Fox:</i> (music) dogsong.mp3`));
+  t.throws(() => isCommentary(`<i>I Have Nothing To Say:</i>`));
+  t.throws(() => isCommentary(123));
+  t.throws(() => isCommentary(``));
+  t.throws(() => isCommentary(`Technically, ah, er:</i>\nCorrect`));
 });
 
 t.test('isContribution', t => {