« 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/data
diff options
context:
space:
mode:
Diffstat (limited to 'test/unit/data')
-rw-r--r--test/unit/data/composite/control-flow/withResultOfAvailabilityCheck.js18
-rw-r--r--test/unit/data/composite/data/withPropertiesFromObject.js59
-rw-r--r--test/unit/data/composite/data/withPropertyFromObject.js107
-rw-r--r--test/unit/data/composite/data/withUniqueItemsOnly.js23
-rw-r--r--test/unit/data/things/album.js40
-rw-r--r--test/unit/data/things/art-tag.js3
-rw-r--r--test/unit/data/things/track.js34
7 files changed, 178 insertions, 106 deletions
diff --git a/test/unit/data/composite/control-flow/withResultOfAvailabilityCheck.js b/test/unit/data/composite/control-flow/withResultOfAvailabilityCheck.js
index 2bcabb4f..9d588e4c 100644
--- a/test/unit/data/composite/control-flow/withResultOfAvailabilityCheck.js
+++ b/test/unit/data/composite/control-flow/withResultOfAvailabilityCheck.js
@@ -177,10 +177,11 @@ t.test(`withResultOfAvailabilityCheck: validate dynamic inputs`, t => {
       mode: 'banana',
     }),
     {message: `Error computing composition`, cause:
-      {message: `Error computing composition withResultOfAvailabilityCheck`, cause:
-        {message: `Errors in input values provided to withResultOfAvailabilityCheck`, errors: [
-          {message: `mode: Expected one of null empty falsy index, got banana`},
-        ]}}});
+      {message: `Error in step 1 of 2, withResultOfAvailabilityCheck`, cause:
+        {message: `Error computing composition withResultOfAvailabilityCheck`, cause:
+          {message: `Errors in input values provided to withResultOfAvailabilityCheck`, errors: [
+            {message: `mode: Expected one of null empty falsy index, got banana`},
+          ]}}}});
 
   t.throws(
     () => composite.expose.compute({
@@ -188,8 +189,9 @@ t.test(`withResultOfAvailabilityCheck: validate dynamic inputs`, t => {
       mode: null,
     }),
     {message: `Error computing composition`, cause:
-      {message: `Error computing composition withResultOfAvailabilityCheck`, cause:
-        {message: `Errors in input values provided to withResultOfAvailabilityCheck`, errors: [
-          {message: `mode: Expected a value, got null`},
-        ]}}});
+      {message: `Error in step 1 of 2, withResultOfAvailabilityCheck`, cause:
+        {message: `Error computing composition withResultOfAvailabilityCheck`, cause:
+          {message: `Errors in input values provided to withResultOfAvailabilityCheck`, errors: [
+            {message: `mode: Expected a value, got null`},
+          ]}}}});
 });
diff --git a/test/unit/data/composite/data/withPropertiesFromObject.js b/test/unit/data/composite/data/withPropertiesFromObject.js
index 750dc8c4..b81d51a5 100644
--- a/test/unit/data/composite/data/withPropertiesFromObject.js
+++ b/test/unit/data/composite/data/withPropertiesFromObject.js
@@ -1,4 +1,5 @@
 import t from 'tap';
+import {quickCheckCompositeOutputs} from '#test-lib';
 
 import {compositeFrom, input} from '#composite';
 import {exposeDependency} from '#composite/control-flow';
@@ -62,6 +63,8 @@ t.test(`withPropertiesFromObject: output shapes & values`, t => {
       ['foo', 'baz', 'missing3'],
   };
 
+  const qcco = quickCheckCompositeOutputs(t, dependencies);
+
   const mapLevel1 = [
     [input.value('prefix_value'), [
       ['object_dependency', [
@@ -153,28 +156,10 @@ t.test(`withPropertiesFromObject: output shapes & values`, t => {
           properties: propertiesInput,
         });
 
-        quickCheckOutputs(step, outputDict);
+        qcco(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);
-  }
 });
 
 t.test(`withPropertiesFromObject: validate static inputs`, t => {
@@ -226,11 +211,12 @@ t.test(`withPropertiesFromObject: validate dynamic inputs`, t => {
       properties: 'onceMore',
     }),
     {message: `Error computing composition`, cause:
-      {message: `Error computing composition withPropertiesFromObject`, cause:
-        {message: `Errors in input values provided to withPropertiesFromObject`, errors: [
-          {message: `object: Expected an object, got string`},
-          {message: `properties: Expected an array, got string`},
-        ]}}});
+      {message: `Error in step 1 of 2, withPropertiesFromObject`, cause:
+        {message: `Error computing composition withPropertiesFromObject`, cause:
+          {message: `Errors in input values provided to withPropertiesFromObject`, errors: [
+            {message: `object: Expected an object, got string`},
+            {message: `properties: Expected an array, got string`},
+          ]}}}});
 
   t.throws(
     () => composite.expose.compute({
@@ -238,17 +224,18 @@ t.test(`withPropertiesFromObject: validate dynamic inputs`, t => {
       properties: ['abc', 'def', 123],
     }),
     {message: `Error computing composition`, cause:
-      {message: `Error computing composition withPropertiesFromObject`, cause:
-        {message: `Errors in input values provided to withPropertiesFromObject`, errors: [
-          {message: `object: Expected an object, got array`},
-          {message: `properties: Errors validating array items`, errors: [
-            {
-              [Symbol.for('hsmusic.annotateError.indexInSourceArray')]: 2,
-              message: `Error at zero-index 2: 123`,
-              cause: {
-                message: `Expected a string, got number`,
+      {message: `Error in step 1 of 2, withPropertiesFromObject`, cause:
+        {message: `Error computing composition withPropertiesFromObject`, cause:
+          {message: `Errors in input values provided to withPropertiesFromObject`, errors: [
+            {message: `object: Expected an object, got array`},
+            {message: `properties: Errors validating array items`, errors: [
+              {
+                [Symbol.for('hsmusic.annotateError.indexInSourceArray')]: 2,
+                message: `Error at zero-index 2: 123`,
+                cause: {
+                  message: `Expected a string, got number`,
+                },
               },
-            },
-          ]},
-        ]}}});
+            ]},
+          ]}}}});
 });
diff --git a/test/unit/data/composite/data/withPropertyFromObject.js b/test/unit/data/composite/data/withPropertyFromObject.js
index 6a772c36..912c924c 100644
--- a/test/unit/data/composite/data/withPropertyFromObject.js
+++ b/test/unit/data/composite/data/withPropertyFromObject.js
@@ -1,5 +1,7 @@
 import t from 'tap';
+import {quickCheckCompositeOutputs} from '#test-lib';
 
+import CacheableObject from '#cacheable-object';
 import {compositeFrom, input} from '#composite';
 import {exposeDependency} from '#composite/control-flow';
 import {withPropertyFromObject} from '#composite/data';
@@ -42,6 +44,89 @@ t.test(`withPropertyFromObject: basic behavior`, t => {
   }), null);
 });
 
+t.test(`withPropertyFromObject: "internal" input`, t => {
+  t.plan(7);
+
+  const composite = compositeFrom({
+    compose: false,
+
+    steps: [
+      withPropertyFromObject({
+        object: 'object',
+        property: 'property',
+        internal: 'internal',
+      }),
+
+      exposeDependency({dependency: '#value'}),
+    ],
+  });
+
+  const thing = new (class extends CacheableObject {
+    static [CacheableObject.propertyDescriptors] = {
+      foo: {
+        flags: {update: true, expose: false},
+      },
+
+      bar: {
+        flags: {update: true, expose: true},
+      },
+
+      baz: {
+        flags: {update: true, expose: true},
+        expose: {
+          transform: baz => baz * 2,
+        },
+      },
+    };
+  });
+
+  thing.foo = 100;
+  thing.bar = 200;
+  thing.baz = 300;
+
+  t.match(composite, {
+    expose: {
+      dependencies: ['object', 'property', 'internal'],
+    },
+  });
+
+  t.equal(composite.expose.compute({
+    object: thing,
+    property: 'foo',
+    internal: true,
+  }), 100);
+
+  t.equal(composite.expose.compute({
+    object: thing,
+    property: 'bar',
+    internal: true,
+  }), 200);
+
+  t.equal(composite.expose.compute({
+    object: thing,
+    property: 'baz',
+    internal: true,
+  }), 300);
+
+  t.equal(composite.expose.compute({
+    object: thing,
+    property: 'baz',
+    internal: false,
+  }), 600);
+
+  t.equal(composite.expose.compute({
+    object: thing,
+    property: 'bimbam',
+    internal: false,
+  }), null);
+
+  t.equal(composite.expose.compute({
+    object: null,
+    property: 'bambim',
+    internal: false,
+  }), null);
+});
+
 t.test(`withPropertyFromObject: output shapes & values`, t => {
   t.plan(2 * 3 ** 2);
 
@@ -56,6 +141,8 @@ t.test(`withPropertyFromObject: output shapes & values`, t => {
       'baz',
   };
 
+  const qcco = quickCheckCompositeOutputs(t, dependencies);
+
   const mapLevel1 = [
     ['object_dependency', [
       ['property_dependency', {
@@ -98,25 +185,7 @@ t.test(`withPropertyFromObject: output shapes & values`, t => {
         property: propertyInput,
       });
 
-      quickCheckOutputs(step, outputDict);
+      qcco(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/data/withUniqueItemsOnly.js b/test/unit/data/composite/data/withUniqueItemsOnly.js
index 965b14b5..50b16f43 100644
--- a/test/unit/data/composite/data/withUniqueItemsOnly.js
+++ b/test/unit/data/composite/data/withUniqueItemsOnly.js
@@ -1,4 +1,5 @@
 import t from 'tap';
+import {quickCheckCompositeOutputs} from '#test-lib';
 
 import {compositeFrom, input} from '#composite';
 import {exposeDependency} from '#composite/control-flow';
@@ -44,6 +45,8 @@ t.test(`withUniqueItemsOnly: output shapes & values`, t => {
       [8, 8, 7, 6, 6, 5, 'bar', true, true, 5],
   };
 
+  const qcco = quickCheckCompositeOutputs(t, dependencies);
+
   const mapLevel1 = [
     ['list_dependency', {
       '#list_dependency': [1, 2, 3, 4, 'foo', false],
@@ -61,24 +64,6 @@ t.test(`withUniqueItemsOnly: output shapes & values`, t => {
       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);
+    qcco(step, outputDict);
   }
 });
diff --git a/test/unit/data/things/album.js b/test/unit/data/things/album.js
index d28ab709..06265b09 100644
--- a/test/unit/data/things/album.js
+++ b/test/unit/data/things/album.js
@@ -262,6 +262,13 @@ t.test(`Album.tracks`, t => {
   const section6 = stubTrackSection(album, [], 'section6');
   const sections = [section1, section2, section3, section4, section5, section6];
 
+  const section1_ref = `unqualified-track-section:section1`;
+  const section2_ref = `unqualified-track-section:section2`;
+  const section3_ref = `unqualified-track-section:section3`;
+  const section4_ref = `unqualified-track-section:section4`;
+  const section5_ref = `unqualified-track-section:section5`;
+  const section6_ref = `unqualified-track-section:section6`;
+
   for (const track of tracks) {
     track.albumData = [album];
   }
@@ -276,7 +283,8 @@ t.test(`Album.tracks`, t => {
   section1.tracks = ['track:track1', 'track:track2', 'track:track3'];
   section1.ownTrackData = [track1, track2, track3];
 
-  album.trackSections = [section1];
+  album.trackSections = [section1_ref];
+  album.ownTrackSectionData = [section1];
 
   t.same(album.tracks, [track1, track2, track3],
     `Album.tracks #2: pulls tracks from one track section`);
@@ -287,7 +295,8 @@ t.test(`Album.tracks`, t => {
   section1.ownTrackData = [track1];
   section2.ownTrackData = [track2, track3];
 
-  album.trackSections = [section1, section2];
+  album.trackSections = [section1_ref, section2_ref];
+  album.ownTrackSectionData = [section1, section2];
 
   t.same(album.tracks, [track1, track2, track3],
     `Album.tracks #3: pulls tracks from multiple track sections`);
@@ -302,7 +311,8 @@ t.test(`Album.tracks`, t => {
   section3.ownTrackData = [];
   section4.ownTrackData = [track3];
 
-  album.trackSections = [section1, section2, section3, section4];
+  album.trackSections = [section1_ref, section2_ref, section3_ref, section4_ref];
+  album.ownTrackSectionData = [section1, section2, section3, section4];
 
   t.same(album.tracks, [track1, track2, track3],
     `Album.tracks #4: filters out references without matches`);
@@ -321,7 +331,8 @@ t.test(`Album.tracks`, t => {
   section5.ownTrackData = [];
   section6.ownTrackData = [track3];
 
-  album.trackSections = [section1, section2, section3, section4, section5, section6];
+  album.trackSections = [section1_ref, section2_ref, section3_ref, section4_ref, section5_ref, section6_ref];
+  album.ownTrackSectionData = [section1, section2, section3, section4, section5, section6];
 
   t.same(album.tracks, [track1, track2, track3],
     `Album.tracks #5: skips empty track sections`);
@@ -345,6 +356,12 @@ t.test(`Album.trackSections`, t => {
   const section5 = stubTrackSection(album, [], 'section5');
   const sections = [section1, section2, section3, section4, section5];
 
+  const section1_ref = `unqualified-track-section:section1`;
+  const section2_ref = `unqualified-track-section:section2`;
+  const section3_ref = `unqualified-track-section:section3`;
+  const section4_ref = `unqualified-track-section:section4`;
+  const section5_ref = `unqualified-track-section:section5`;
+
   for (const track of tracks) {
     track.albumData = [album];
   }
@@ -355,7 +372,8 @@ t.test(`Album.trackSections`, t => {
   section1.ownTrackData = [track1, track2];
   section2.ownTrackData = [track3, track4];
 
-  album.trackSections = [section1, section2];
+  album.trackSections = [section1_ref, section2_ref];
+  album.ownTrackSectionData = [section1, section2];
 
   t.match(album.trackSections, [
     {tracks: [track1, track2]},
@@ -378,7 +396,8 @@ t.test(`Album.trackSections`, t => {
   section1.name = 'First section';
   section2.name = 'Second section';
 
-  album.trackSections = [section1, section2, section3];
+  album.trackSections = [section1_ref, section2_ref, section3_ref];
+  album.ownTrackSectionData = [section1, section2, section3];
 
   t.match(album.trackSections, [
     {name: 'First section', tracks: [track1]},
@@ -392,7 +411,7 @@ t.test(`Album.trackSections`, t => {
 
   // XXX_decacheWikiData
   album.trackSections = [];
-  album.trackSections = [section1, section2, section3];
+  album.trackSections = [section1_ref, section2_ref, section3_ref];
 
   t.match(album.trackSections, [
     {tracks: [track1], color: '#123456'},
@@ -404,7 +423,7 @@ t.test(`Album.trackSections`, t => {
 
   // XXX_decacheWikiData
   album.trackSections = [];
-  album.trackSections = [section1, section2, section3];
+  album.trackSections = [section1_ref, section2_ref, section3_ref];
 
   t.match(album.trackSections, [
     {tracks: [track1], dateOriginallyReleased: null},
@@ -417,7 +436,7 @@ t.test(`Album.trackSections`, t => {
 
   // XXX_decacheWikiData
   album.trackSections = [];
-  album.trackSections = [section1, section2, section3];
+  album.trackSections = [section1_ref, section2_ref, section3_ref];
 
   t.match(album.trackSections, [
     {tracks: [track1], isDefaultTrackSection: true},
@@ -443,7 +462,8 @@ t.test(`Album.trackSections`, t => {
   section4.color = '#556677';
   section5.color = '#778899';
 
-  album.trackSections = [section1, section2, section3, section4, section5];
+  album.trackSections = [section1_ref, section2_ref, section3_ref, section4_ref, section5_ref];
+  album.ownTrackSectionData = [section1, section2, section3, section4, section5];
 
   t.match(album.trackSections, [
     {tracks: [track1, track2], color: '#112233'},
diff --git a/test/unit/data/things/art-tag.js b/test/unit/data/things/art-tag.js
index 427b357b..cf2135c6 100644
--- a/test/unit/data/things/art-tag.js
+++ b/test/unit/data/things/art-tag.js
@@ -16,7 +16,8 @@ function stubAlbum(tracks, directory = 'bar') {
   album.directory = directory;
 
   const trackSection = stubTrackSection(album, tracks);
-  album.trackSections = [trackSection];
+  album.trackSections = [`unqualified-track-section:${trackSection.unqualifiedDirectory}`];
+  album.ownTrackSectionData = [trackSection];
 
   return album;
 }
diff --git a/test/unit/data/things/track.js b/test/unit/data/things/track.js
index 644d21ce..74231e20 100644
--- a/test/unit/data/things/track.js
+++ b/test/unit/data/things/track.js
@@ -19,7 +19,8 @@ function stubAlbum(tracks, directory = 'bar') {
   album.directory = directory;
 
   const trackSection = stubTrackSection(album, tracks);
-  album.trackSections = [trackSection];
+  album.trackSections = [`unqualified-track-section:${trackSection.unqualifiedDirectory}`];
+  album.ownTrackSectionData = [trackSection];
 
   return album;
 }
@@ -93,6 +94,10 @@ t.test(`Track.album`, t => {
   const album2 = new Album();
   const section1 = new TrackSection();
   const section2 = new TrackSection();
+  section1.unqualifiedDirectory = 'section1';
+  section2.unqualifiedDirectory = 'section2';
+  const section1_ref = `unqualified-track-section:section1`;
+  const section2_ref = `unqualified-track-section:section2`;
 
   t.equal(track1.album, null,
     `album #1: defaults to null`);
@@ -105,8 +110,10 @@ t.test(`Track.album`, t => {
   section2.ownAlbumData = [album2];
   section1.tracks = ['track:track1'];
   section2.tracks = ['track:track2'];
-  album1.trackSections = [section1];
-  album2.trackSections = [section2];
+  album1.trackSections = [section1_ref];
+  album2.trackSections = [section2_ref];
+  album1.ownTrackSectionData = [section1];
+  album2.ownTrackSectionData = [section2];
 
   t.equal(track1.album, album1,
     `album #2: is album when album's trackSections matches track`);
@@ -125,7 +132,7 @@ t.test(`Track.album`, t => {
 
   // XXX_decacheWikiData
   album1.trackSections = [];
-  album1.trackSections = [section1];
+  album1.trackSections = [section1_ref];
   track1.albumData = [];
   track1.albumData = [album2, album1];
 
@@ -137,7 +144,7 @@ t.test(`Track.album`, t => {
 
   // XXX_decacheWikiData
   album1.trackSections = [];
-  album1.trackSections = [section1];
+  album1.trackSections = [section1_ref];
   track1.albumData = [];
   track1.albumData = [album2, album1];
 
@@ -273,7 +280,7 @@ t.test(`Track.artistContribs`, t => {
 
   XXX_decacheWikiData();
 
-  t.same(track.artistContribs,
+  t.match(track.artistContribs,
     [{artist: artist1, annotation: `composition`}, {artist: artist2, annotation: null}],
     `artistContribs #2: inherits album artistContribs`);
 
@@ -281,7 +288,7 @@ t.test(`Track.artistContribs`, t => {
     {artist: `Artist 1`, annotation: `arrangement`},
   ];
 
-  t.same(track.artistContribs, [{artist: artist1, annotation: `arrangement`}],
+  t.match(track.artistContribs, [{artist: artist1, annotation: `arrangement`}],
     `artistContribs #3: resolves from own value`);
 
   track.artistContribs = [
@@ -290,7 +297,7 @@ t.test(`Track.artistContribs`, t => {
     {artist: `Artist 2`, annotation: `usual`},
   ];
 
-  t.same(track.artistContribs,
+  t.match(track.artistContribs,
     [{artist: artist1, annotation: `snooping`}, {artist: artist2, annotation: `usual`}],
     `artistContribs #4: filters out names without matches`);
 });
@@ -308,12 +315,13 @@ t.test(`Track.color`, t => {
   t.equal(track.color, null,
     `color #1: defaults to null`);
 
-  const section = stubTrackSection(album, [track]);
+  const section = stubTrackSection(album, [track], 'section');
 
   album.color = '#abcdef';
   section.color = '#beeeef';
 
-  album.trackSections = [section];
+  album.trackSections = [`unqualified-track-section:section`];
+  album.ownTrackSectionData = [section];
 
   XXX_decacheWikiData();
 
@@ -449,7 +457,7 @@ t.test(`Track.coverArtistContribs`, t => {
 
   XXX_decacheWikiData();
 
-  t.same(track.coverArtistContribs,
+  t.match(track.coverArtistContribs,
     [{artist: artist1, annotation: `lines`}, {artist: artist2, annotation: null}],
     `coverArtistContribs #2: inherits album trackCoverArtistContribs`);
 
@@ -457,7 +465,7 @@ t.test(`Track.coverArtistContribs`, t => {
     {artist: `Artist 1`, annotation: `collage`},
   ];
 
-  t.same(track.coverArtistContribs, [{artist: artist1, annotation: `collage`}],
+  t.match(track.coverArtistContribs, [{artist: artist1, annotation: `collage`}],
     `coverArtistContribs #3: resolves from own value`);
 
   track.coverArtistContribs = [
@@ -466,7 +474,7 @@ t.test(`Track.coverArtistContribs`, t => {
     {artist: `Artist 2`, annotation: `usual`},
   ];
 
-  t.same(track.coverArtistContribs,
+  t.match(track.coverArtistContribs,
     [{artist: artist1, annotation: `snooping`}, {artist: artist2, annotation: `usual`}],
     `coverArtistContribs #4: filters out names without matches`);