]>
Lady’s Gitweb - Etiquette/blob - model.test.js
1 // SPDX-FileCopyrightText: 2023, 2025 Lady <https://www.ladys.computer/about/#lady>
2 // SPDX-License-Identifier: MPL-2.0
4 * ⁌ 📧🏷️ Étiquette ∷ model.test.js
6 * Copyright © 2023, 2025 Lady [@ Ladys Computer].
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at <https://mozilla.org/MPL/2.0/>.
24 } from "./dev-deps.js";
25 import { TagSystem
} from "./model.js";
27 describe("TagSystem", () => {
28 it("[[Call]] throws", () => {
34 it("[[Construct]] creates a new TagSystem", () => {
36 Object
.getPrototypeOf(new TagSystem("example", "1972-12-31")),
41 it("[[Construct]] uses the identifier if provided", () => {
43 new TagSystem("example", "1972-12-31", "etaoin").identifier
,
48 it("[[Construct]] uses an empty identifier if none is provided", () => {
50 new TagSystem("example", "1972-12-31").identifier
,
55 it("[[Construct]] throws if provided an invalid domain", () => {
57 new TagSystem("example@example", "1972-12-31");
60 new TagSystem("0.0.0.0", "1972-12-31");
64 it("[[Construct]] throws if provided an invalid date", () => {
66 new TagSystem("example", "1969");
69 new TagSystem("example", "1972-12-31T00:00:00Z");
73 describe("::Tag", () => {
78 system
= new TagSystem("example", "1972-12-31");
82 it("[[Get]] returns the same value every time", () => {
83 assertStrictEquals(Tag
, system
.Tag
);
86 it("[[Call]] throws", () => {
92 it("[[Construct]] returns a new Tag", () => {
94 Object
.getPrototypeOf(new Tag()),
99 it('[[Construct]] defaults the kind to "Tag"', () => {
100 assertStrictEquals(new Tag().kind
, "Tag");
103 it("[[Construct]] correctly sets the tag kind", () => {
105 new Tag("RelationshipTag").kind
,
110 it("[[Construct]] defaults the preferred label to the empty string", () => {
111 assertEquals({ ...new Tag().prefLabel
}, { "@value": "" });
114 it("[[Construct]] correctly sets the preferred label to a simple string", () => {
116 { ...new Tag("RelationshipTag", "Shadow, Me").prefLabel
},
117 { "@value": "Shadow, Me" },
121 it("[[Construct]] initializes tag identifiers to null", () => {
123 new Tag().identifier
,
128 it("[[Construct]] correctly sets the preferred label to a language‐tagged string", () => {
131 ...new Tag("RelationshipTag", {
132 "@value": "Shadow, Me",
136 { "@value": "Shadow, Me", "@language": "en" },
140 it("[[Construct]] throws if the tag kind is not recognized", () => {
146 describe(".all", () => {
147 it("[[Call]] yields all the persisted tags", () => {
148 const tags
= new Set(function* () {
151 // Generate 5 tags and remember their identifiers.
152 const tag
= new Tag();
154 yield tag
.identifier
;
157 for (const tag
of Tag
.all()) {
159 Object
.getPrototypeOf(tag
),
164 new Set(Array
.from(Tag
.all(), (tag
) => tag
.identifier
)),
170 describe(".constructor", () => {
171 it("[[Get]] is `Function`", () => {
172 assertStrictEquals(Tag
.constructor, Function
);
176 describe(".fromIRI", () => {
177 it("[[Call]] returns the persisted tag with the given I·R·I", () => {
178 const tag
= new Tag();
180 const { identifier
, iri
} = tag
;
181 const retrieved
= Tag
.fromIRI(iri
);
183 Object
.getPrototypeOf(retrieved
),
186 assertStrictEquals(retrieved
.identifier
, identifier
);
189 it("[[Call]] returns undefined if no tag with the given I·R·I has been persisted", () => {
192 `https://${system.authorityName}/tag:${system.taggingEntity}:000-0000`,
198 it("[[Call]] throws if passed an invalid I·R·I", () => {
200 Tag
.fromIRI(`bad iri`);
205 describe(".fromIdentifier", () => {
206 it("[[Call]] returns the persisted tag with the given identifier", () => {
207 const tag
= new Tag();
209 const { identifier
} = tag
;
210 const retrieved
= Tag
.fromIdentifier(identifier
);
212 Object
.getPrototypeOf(retrieved
),
215 assertStrictEquals(retrieved
.identifier
, identifier
);
218 it("[[Call]] returns undefined if no tag with the given identifier has been persisted", () => {
219 assertStrictEquals(Tag
.fromIdentifier("000-0000"), undefined);
222 it("[[Call]] throws if passed an invalid identifier", () => {
224 Tag
.fromIdentifier(""); // wrong format
227 Tag
.fromIdentifier("100-0000"); // bad checksum
232 describe(".fromTagURI", () => {
233 it("[[Call]] returns the persisted tag with the given Tag U·R·I", () => {
234 const tag
= new Tag();
236 const { identifier
, tagURI
} = tag
;
237 const retrieved
= Tag
.fromTagURI(tagURI
);
239 Object
.getPrototypeOf(retrieved
),
242 assertStrictEquals(retrieved
.identifier
, identifier
);
245 it("[[Call]] returns undefined if no tag with the given Tag U·R·I has been persisted", () => {
247 Tag
.fromTagURI(`tag:${system.taggingEntity}:`),
251 Tag
.fromTagURI(`tag:${system.taggingEntity}:000-0000`),
256 it("[[Call]] throws if passed an invalid Tag U·R·I", () => {
258 Tag
.fromTagURI(""); // wrong format
262 "tag:unexample,1970-01-01:Z", // incorrect tagging entity
268 describe(".identifiers", () => {
269 it("[[Call]] yields all the persisted identifiers", () => {
270 const tags
= new Set(function* () {
273 // Generate 5 tags and remember their identifiers.
274 const tag
= new Tag();
276 yield tag
.identifier
;
280 new Set(Tag
.identifiers()),
286 describe(".system", () => {
287 it("[[Call]] returns the `TagSystem`", () => {
288 assertEquals(Tag
.system
, system
);
292 // `.[Storage.toInstance]` is tested by `.fromIdentifier`.
294 describe("::addAltLabel", () => {
295 it("[[Call]] does nothing if called with no arguments", () => {
296 const tag
= new Tag();
298 assertEquals([...tag
.altLabels()], []);
301 it("[[Call]] adds the provided alternative labels", () => {
302 const tag
= new Tag();
306 { "@value": "three", "@language": "en" },
309 Array
.from(tag
.altLabels(), ($) => ({ ...$ })),
313 { "@value": "three", "@language": "en" },
318 it("[[Call]] returns this", () => {
319 const tag
= new Tag();
320 assertStrictEquals(tag
.addAltLabel(), tag
);
324 describe("::addBroaderTag", () => {
325 it("[[Call]] does nothing if called with no arguments", () => {
326 const tag
= new Tag();
328 assertEquals([...tag
.broaderTags()], []);
331 it("[[Call]] adds the provided broader tags", () => {
332 const broader
= new Tag();
334 const broader2
= new Tag();
336 const tag
= new Tag();
337 tag
.addBroaderTag(broader
, broader2
);
339 Array
.from(tag
.broaderTags(), ($) => $.identifier
),
340 [broader
.identifier
, broader2
.identifier
],
344 it("[[Call]] returns this", () => {
345 const tag
= new Tag();
346 assertStrictEquals(tag
.addBroaderTag(), tag
);
349 it("[[Call]] throws when adding a non‐persisted tag", () => {
350 const tag
= new Tag();
352 tag
.addBroaderTag(new Tag());
356 it("[[Call]] throws when adding an unrecognized identifier", () => {
357 const tag
= new Tag();
359 tag
.addBroaderTag("000-0000"); // not persisted
362 tag
.addBroaderTag(""); // bad format
367 describe("::addHiddenLabel", () => {
368 it("[[Call]] does nothing if called with no arguments", () => {
369 const tag
= new Tag();
370 tag
.addHiddenLabel();
371 assertEquals([...tag
.hiddenLabels()], []);
374 it("[[Call]] adds the provided hidden labels", () => {
375 const tag
= new Tag();
379 { "@value": "three", "@language": "en" },
382 Array
.from(tag
.hiddenLabels(), ($) => ({ ...$ })),
386 { "@value": "three", "@language": "en" },
391 it("[[Call]] returns this", () => {
392 const tag
= new Tag();
393 assertStrictEquals(tag
.addHiddenLabel(), tag
);
397 describe("::addInCanonTag", () => {
398 it("[[Call]] does nothing if called with no arguments", () => {
399 const tag
= new Tag("EntityTag");
401 assertEquals([...tag
.inCanonTags()], []);
404 it("[[Call]] adds the provided canon tags", () => {
405 const canon
= new Tag("CanonTag");
407 const canon2
= new Tag("CanonTag");
409 const tag
= new Tag("EntityTag");
410 tag
.addInCanonTag(canon
, canon2
);
412 Array
.from(tag
.inCanonTags(), ($) => $.identifier
),
413 [canon
.identifier
, canon2
.identifier
],
417 it("[[Call]] returns this", () => {
418 const tag
= new Tag("EntityTag");
419 assertStrictEquals(tag
.addInCanonTag(), tag
);
422 it("[[Call]] throws when this is not a tag which can be placed in canon", () => {
423 const canon
= new Tag("CanonTag");
426 new Tag().addInCanonTag(canon
);
430 it("[[Call]] throws when provided with a non‐canon tag", () => {
431 const notCanon
= new Tag();
433 const tag
= new Tag("EntityTag");
435 tag
.addInCanonTag(notCanon
);
439 it("[[Call]] throws when adding a non‐persisted tag", () => {
440 const tag
= new Tag("EntityTag");
442 tag
.addInCanonTag(new Tag("CanonTag"));
446 it("[[Call]] throws when adding an unrecognized identifier", () => {
447 const tag
= new Tag("EntityTag");
449 tag
.addInCanonTag("000-0000"); // not persisted
452 tag
.addInCanonTag(""); // bad format
457 describe("::addInvolvesTag", () => {
458 it("[[Call]] does nothing if called with no arguments", () => {
459 const tag
= new Tag("ConceptualTag");
460 tag
.addInvolvesTag();
461 assertEquals([...tag
.involvesTags()], []);
464 it("[[Call]] adds the provided tags", () => {
465 const involved
= new Tag();
467 const involved2
= new Tag();
469 const tag
= new Tag("ConceptualTag");
470 tag
.addInvolvesTag(involved
, involved2
);
472 Array
.from(tag
.involvesTags(), ($) => $.identifier
),
473 [involved
.identifier
, involved2
.identifier
],
477 it("[[Call]] returns this", () => {
478 const tag
= new Tag("ConceptualTag");
479 assertStrictEquals(tag
.addInvolvesTag(), tag
);
482 it("[[Call]] throws when this is not a conceptual tag", () => {
483 const involved
= new Tag();
486 new Tag().addInvolvesTag(involved
);
490 it("[[Call]] throws when this is a relationship tag and provided with a non‐involvable tag", () => {
491 const notInvolved
= new Tag();
492 notInvolved
.persist();
493 const tag
= new Tag("RelationshipTag");
495 tag
.addInvolvesTag(notInvolved
);
499 it("[[Call]] throws when adding a non‐persisted tag", () => {
500 const tag
= new Tag("ConceptualTag");
502 tag
.addInvolvesTag(new Tag());
506 it("[[Call]] throws when adding an unrecognized identifier", () => {
507 const tag
= new Tag("ConceptualTag");
509 tag
.addInvolvesTag("000-0000"); // not persisted
512 tag
.addInvolvesTag(""); // bad format
517 // `::altLabels` is tested by `::addAltLabel`.
519 describe("::authorityName", () => {
520 it("[[Get]] returns the authority name of the tag system", () => {
522 new Tag().authorityName
,
523 system
.authorityName
,
528 // `::broaderTags` is tested by `::addBroaderTag`.
530 describe("::broaderTransitiveTags", () => {
531 it("[[Call]] returns broader tags transitively", () => {
532 const superBroad
= new Tag();
533 superBroad
.persist();
534 const broad
= new Tag();
535 broad
.addBroaderTag(superBroad
);
537 const tag
= new Tag();
538 tag
.addBroaderTag(broad
);
540 Array
.from(tag
.broaderTransitiveTags(), ($) => $.identifier
),
541 [broad
.identifier
, superBroad
.identifier
],
545 it("[[Call]] cannot recurse infinitely", () => {
546 const tag
= new Tag();
548 const broad
= new Tag();
549 broad
.addBroaderTag(tag
);
551 tag
.addBroaderTag(broad
);
554 Array
.from(tag
.broaderTransitiveTags(), ($) => $.identifier
),
555 [broad
.identifier
, tag
.identifier
],
560 describe("::deleteAltLabel", () => {
561 it("[[Call]] does nothing if called with no arguments", () => {
562 const tag
= new Tag();
563 tag
.addAltLabel("etaoin");
564 tag
.deleteAltLabel();
566 Array
.from(tag
.altLabels(), ($) => ({ ...$ })),
567 [{ "@value": "etaoin" }],
571 it("[[Call]] deletes only the provided hidden labels", () => {
572 const tag
= new Tag();
576 { "@value": "three", "@language": "en" },
582 { "@value": "three", "@language": "en" },
583 { "@value": "four", "@language": "en" },
586 Array
.from(tag
.altLabels(), ($) => ({ ...$ })),
587 [{ "@value": "four" }],
591 it("[[Call]] returns this", () => {
592 const tag
= new Tag();
593 assertStrictEquals(tag
.deleteAltLabel(), tag
);
597 describe("::deleteBroaderTag", () => {
598 it("[[Call]] does nothing if called with no arguments", () => {
599 const broader
= new Tag();
601 const tag
= new Tag();
602 tag
.addBroaderTag(broader
);
603 tag
.deleteBroaderTag();
605 Array
.from(tag
.broaderTags(), ($) => $.identifier
),
606 [broader
.identifier
],
610 it("[[Call]] deletes only the provided broader tags", () => {
611 const superBroader
= new Tag();
612 superBroader
.persist();
613 const broader
= new Tag();
614 broader
.addBroaderTag(superBroader
);
616 const broader2
= new Tag();
617 broader2
.addBroaderTag(superBroader
);
619 const tag
= new Tag();
620 tag
.addBroaderTag(broader
, broader2
);
621 tag
.deleteBroaderTag(broader
, superBroader
, "000-0000", "");
623 Array
.from(tag
.broaderTags(), ($) => $.identifier
),
624 [broader2
.identifier
],
628 it("[[Call]] returns this", () => {
629 const tag
= new Tag();
630 assertStrictEquals(tag
.deleteBroaderTag(), tag
);
634 describe("::deleteHiddenLabel", () => {
635 it("[[Call]] does nothing if called with no arguments", () => {
636 const tag
= new Tag();
637 tag
.addHiddenLabel("etaoin");
638 tag
.deleteHiddenLabel();
640 Array
.from(tag
.hiddenLabels(), ($) => ({ ...$ })),
641 [{ "@value": "etaoin" }],
645 it("[[Call]] deletes only the provided alternative labels", () => {
646 const tag
= new Tag();
650 { "@value": "three", "@language": "en" },
653 tag
.deleteHiddenLabel(
656 { "@value": "three", "@language": "en" },
657 { "@value": "four", "@language": "en" },
660 Array
.from(tag
.hiddenLabels(), ($) => ({ ...$ })),
661 [{ "@value": "four" }],
665 it("[[Call]] returns this", () => {
666 const tag
= new Tag();
667 assertStrictEquals(tag
.deleteHiddenLabel(), tag
);
671 describe("::deleteInCanonTag", () => {
672 it("[[Call]] does nothing if called with no arguments", () => {
673 const canon
= new Tag("CanonTag");
675 const tag
= new Tag("EntityTag");
676 tag
.addInCanonTag(canon
);
677 tag
.deleteInCanonTag();
679 Array
.from(tag
.inCanonTags(), ($) => $.identifier
),
684 it("[[Call]] deletes only the provided canon tags", () => {
685 const canon
= new Tag("CanonTag");
687 const canon2
= new Tag("CanonTag");
689 const tag
= new Tag("EntityTag");
690 tag
.addInCanonTag(canon
, canon2
);
691 tag
.deleteInCanonTag(canon
, "000-0000", "");
693 Array
.from(tag
.inCanonTags(), ($) => $.identifier
),
698 it("[[Call]] returns this", () => {
699 const tag
= new Tag("EntityTag");
700 assertStrictEquals(tag
.deleteInCanonTag(), tag
);
704 describe("::deleteInvolvesTag", () => {
705 it("[[Call]] does nothing if called with no arguments", () => {
706 const involved
= new Tag();
708 const tag
= new Tag("ConceptualTag");
709 tag
.addInvolvesTag(involved
);
710 tag
.deleteInvolvesTag();
712 Array
.from(tag
.involvesTags(), ($) => $.identifier
),
713 [involved
.identifier
],
717 it("[[Call]] deletes only the provided involved tags", () => {
718 const character
= new Tag("CharacterTag");
720 const involved
= new Tag("RelationshipTag");
721 involved
.addInvolvesTag(character
);
723 const involved2
= new Tag("RelationshipTag");
724 involved2
.addInvolvesTag(character
);
726 const tag
= new Tag("RelationshipTag");
727 tag
.addInvolvesTag(involved
, involved2
);
728 tag
.deleteInvolvesTag(involved
, character
, "000-0000", "");
730 Array
.from(tag
.involvesTags(), ($) => $.identifier
),
731 [involved2
.identifier
],
735 it("[[Call]] returns this", () => {
736 const tag
= new Tag("ConceptualTag");
737 assertStrictEquals(tag
.deleteInvolvesTag(), tag
);
741 describe("::hasInCanonTags", () => {
742 it("[[Call]] yields the persisted tags which have this tag in canon", () => {
743 const canon
= new Tag("CanonTag");
745 const entity
= new Tag("EntityTag");
746 entity
.addInCanonTag(canon
);
748 const entity2
= new Tag("EntityTag");
749 entity2
.addInCanonTag(canon
);
751 const tag
= Tag
.fromIdentifier(canon
.identifier
); // reload
753 Array
.from(tag
.hasInCanonTags(), ($) => $.identifier
),
754 [entity
.identifier
, entity2
.identifier
],
759 // `::hiddenLabels` is tested by `::addHiddenLabel`.
761 // `::identifier` is tested by a `.fromIdentifier`.
763 // `::inCanonTags` is tested by `::addInCanonTag`.
765 describe("::involvedInTags", () => {
766 it("[[Call]] yields the persisted tags which involve this tag", () => {
767 const involved
= new Tag();
769 const conceptual
= new Tag("ConceptualTag");
770 conceptual
.addInvolvesTag(involved
);
771 conceptual
.persist();
772 const conceptual2
= new Tag("ConceptualTag");
773 conceptual2
.addInvolvesTag(involved
);
774 conceptual2
.persist();
775 const tag
= Tag
.fromIdentifier(involved
.identifier
); // reload
777 Array
.from(tag
.involvedInTags(), ($) => $.identifier
),
778 [conceptual
.identifier
, conceptual2
.identifier
],
783 // `::involvesTags` is tested by `::addInvolvesTag`.
785 // `::iri` is tested by a `.fromIRI`.
787 // `::iriSpace` is tested by a `.fromIRI`.
789 // `::kind` is tested by the constructor.
791 describe("::narrowerTags", () => {
792 it("[[Call]] yields the persisted tags which are narrower than this tag", () => {
793 const broader
= new Tag();
795 const narrower
= new Tag();
796 narrower
.addBroaderTag(broader
);
798 const narrower2
= new Tag();
799 narrower2
.addBroaderTag(broader
);
801 const tag
= Tag
.fromIdentifier(broader
.identifier
); // reload
803 Array
.from(tag
.narrowerTags(), ($) => $.identifier
),
804 [narrower
.identifier
, narrower2
.identifier
],
809 describe("::narrowerTransitiveTags", () => {
810 it("[[Call]] returns narrower tags transitively", () => {
811 const broad
= new Tag();
813 const narrow
= new Tag();
814 narrow
.addBroaderTag(broad
);
816 const superNarrow
= new Tag();
817 superNarrow
.addBroaderTag(narrow
);
818 superNarrow
.persist();
819 const tag
= Tag
.fromIdentifier(broad
.identifier
); // reload
822 tag
.narrowerTransitiveTags(),
825 [narrow
.identifier
, superNarrow
.identifier
],
829 it("[[Call]] cannot recurse infinitely", () => {
830 const tag
= new Tag();
832 const broad
= new Tag();
833 broad
.addBroaderTag(tag
);
835 tag
.addBroaderTag(broad
);
838 Array
.from(tag
.broaderTransitiveTags(), ($) => $.identifier
),
839 [broad
.identifier
, tag
.identifier
],
844 describe("::persist", () => {
845 it("[[Call]] returns an object with expected properties if there were changes", () => {
846 const tag
= new Tag();
847 const activity
= tag
.persist();
852 "https://ns.1024.gdn/Tagging/discovery.context.jsonld",
857 assertArrayIncludes(activity
["@type"], ["TagActivity"]);
858 assert("endTime" in activity
);
861 it("[[Call]] returns a Create activity with a type predicate for new objects", () => {
862 const activity
= new Tag().persist();
863 assertEquals(activity
["@type"], ["TagActivity", "Create"]);
864 assertArrayIncludes(activity
.states
, [{
870 it("[[Call]] returns an Update activity for old objects", () => {
871 const tag
= new Tag();
873 tag
.prefLabel
= "etaoin";
874 const activity
= tag
.persist();
875 assertEquals(activity
["@type"], ["TagActivity", "Update"]);
878 it("[[Call]] states and unstates changes", () => {
879 const broader1
= new Tag();
881 const broader2
= new Tag();
883 const tag
= new Tag();
884 tag
.addBroaderTag(broader1
);
886 tag
.prefLabel
= "etaoin";
887 tag
.deleteBroaderTag(broader1
);
888 tag
.addBroaderTag(broader2
);
889 const activity
= tag
.persist();
890 assertObjectMatch(activity
, {
892 { predicate: "prefLabel", object: { "@value": "" } },
893 { predicate: "broader", object: broader1
.iri
},
896 { predicate: "prefLabel", object: { "@value": "etaoin" } },
897 { predicate: "broader", object: broader2
.iri
},
902 it("[[Call]] doesn’t state if there are no additions", () => {
903 const tag
= new Tag();
904 tag
.addAltLabel("etaoin");
906 tag
.deleteAltLabel("etaoin");
907 const activity
= tag
.persist();
908 assertFalse("state" in activity
);
911 it("[[Call]] doesn’t unstate if there are no removals", () => {
912 const tag
= new Tag();
914 tag
.addAltLabel("etaoin");
915 const activity
= tag
.persist();
916 assertFalse("unstate" in activity
);
919 it("[[Call]] returns null if no meaningful changes were made", () => {
920 const tag
= new Tag();
922 const activity
= tag
.persist();
923 assertStrictEquals(activity
, null);
926 it("[[Call]] returns undefined for a silent persist", () => {
927 const broader
= new Tag();
929 const tag
= new Tag();
930 tag
.prefLabel
= "etaoin";
931 tag
.addBroaderTag(broader
);
932 assertStrictEquals(tag
.persist(true), undefined);
936 describe("::prefLabel", () => {
937 it("[[Set]] sets the preferred label", () => {
938 const tag
= new Tag();
939 tag
.prefLabel
= "one";
940 assertEquals({ ...tag
.prefLabel
}, { "@value": "one" });
941 tag
.prefLabel
= { "@value": "two" };
942 assertEquals({ ...tag
.prefLabel
}, { "@value": "two" });
943 tag
.prefLabel
= { "@value": "three", "@language": "en" };
945 { ...tag
.prefLabel
},
946 { "@value": "three", "@language": "en" },
951 describe("::system", () => {
952 it("[[Get]] returns the tag system", () => {
953 assertStrictEquals(new Tag().system
, system
);
957 // `::tagURI` is tested by a `.fromTagURI`.
959 describe("::taggingEntity", () => {
960 it("[[Get]] returns the tagging entity of the tag system", () => {
962 new Tag().taggingEntity
,
963 system
.taggingEntity
,
968 describe("::toString", () => {
969 it("[[Get]] returns the string value of the preferred label", () => {
970 const tag
= new Tag();
971 tag
.prefLabel
= { "@value": "etaoin", "@language": "zxx" };
972 assertStrictEquals(tag
.toString(), "etaoin");
976 // `::[Storage.toObject]` is tested by `::persist`.
979 describe("::apply", () => {
984 system
= new TagSystem("example", "1972-12-31");
988 it("[[Call]] throws if no activity is provided", () => {
994 it("[[Call]] throws with an invalid activity", () => {
1000 it("[[Call]] throws when specifying an invalid object", () => {
1001 assertThrows(() => {
1006 assertThrows(() => {
1008 object: `${system.iriSpace}000-0000`,
1013 it("[[Call]] returns the tag being modified", () => {
1014 const tag
= new Tag();
1016 const applied
= system
.apply({ object: tag
.iri
});
1018 Object
.getPrototypeOf(applied
),
1019 system
.Tag
.prototype,
1021 assertStrictEquals(tag
.identifier
, applied
.identifier
);
1024 it("[[Call]] applies the changes", () => {
1025 const broaderTag
= new Tag();
1026 const broaderActivity
= broaderTag
.persist();
1027 const otherBroaderTag
= new Tag();
1028 const otherBroaderActivity
= otherBroaderTag
.persist();
1029 const tag
= new Tag("EntityTag", "my pref label");
1030 tag
.addHiddenLabel("label");
1031 tag
.addBroaderTag(broaderTag
);
1032 const createActivity
= tag
.persist();
1033 tag
.prefLabel
= "new pref label";
1034 tag
.addAltLabel("alternative label");
1035 tag
.deleteHiddenLabel("label");
1036 tag
.addBroaderTag(otherBroaderTag
);
1037 tag
.deleteBroaderTag(broaderTag
);
1038 const updateActivity
= tag
.persist();
1039 const otherSystem
= new TagSystem(
1040 system
.authorityName
,
1043 otherSystem
.apply(broaderActivity
);
1044 otherSystem
.apply(otherBroaderActivity
);
1045 const appliedCreate
= otherSystem
.apply(createActivity
);
1046 assertStrictEquals(appliedCreate
.kind
, "EntityTag");
1047 assertStrictEquals(appliedCreate
.identifier
, tag
.identifier
);
1049 { ...appliedCreate
.prefLabel
},
1050 { "@value": "my pref label" },
1053 [...appliedCreate
.hiddenLabels()].map(($) => ({ ...$ })),
1054 [{ "@value": "label" }],
1057 [...appliedCreate
.broaderTags()].map(($) => $.identifier
),
1058 [broaderTag
.identifier
],
1060 const appliedUpdate
= otherSystem
.apply(updateActivity
);
1062 { ...appliedUpdate
.prefLabel
},
1063 { "@value": "new pref label" },
1066 [...appliedUpdate
.altLabels()].map(($) => ({ ...$ })),
1067 [{ "@value": "alternative label" }],
1069 assertEquals([...appliedUpdate
.hiddenLabels()], []);
1071 [...appliedUpdate
.broaderTags()].map(($) => $.identifier
),
1072 [otherBroaderTag
.identifier
],
1076 it("[[Call]] silently fails deleting preflabels", () => {
1077 const tag
= new system
.Tag("Tag", "my pref label");
1079 const applied
= system
.apply({
1082 predicate: "prefLabel",
1083 object: "my pref label",
1087 { ...applied
.prefLabel
},
1088 { "@value": "my pref label" },
1092 it("[[Call]] silently fails deleting unrecognized statements", () => {
1093 const tag
= new Tag();
1095 const otherTag
= new Tag();
1096 otherTag
.persist(true);
1097 const applied
= system
.apply({
1100 predicate: "bad_statement",
1101 object: otherTag
.iri
,
1107 it("[[Call]] silently fails deleting immutable statements", () => {
1108 const tag
= new Tag();
1110 const applied
= system
.apply({
1112 unstates: [{ predicate: "a", object: "Tag" }],
1114 assertStrictEquals(applied
.kind
, "Tag");
1117 it("[[Call]] silently fails deleting inverse statements", () => {
1118 const tag
= new Tag();
1120 const otherTag
= new Tag();
1121 otherTag
.addBroaderTag(tag
);
1122 otherTag
.persist(true);
1123 const applied
= system
.apply({
1125 unstates: [{ predicate: "narrower", object: otherTag
.iri
}],
1128 [...applied
.narrowerTags()][0].identifier
,
1129 otherTag
.identifier
,
1133 it("[[Call]] sets preflabels", () => {
1134 const tag
= new Tag("Tag", "my pref label");
1136 const applied
= system
.apply({
1138 states: [{ predicate: "prefLabel", object: "new pref label" }],
1141 { ...applied
.prefLabel
},
1142 { "@value": "new pref label" },
1146 it("[[Call]] silently fails setting unrecognized statements", () => {
1147 const tag
= new Tag();
1149 const otherTag
= new Tag();
1150 otherTag
.persist(true);
1151 const applied
= system
.apply({
1153 states: [{ predicate: "bad_statement", object: otherTag
.iri
}],
1158 it("[[Call]] silently fails setting immutable statements", () => {
1159 const tag
= new Tag();
1161 const applied
= system
.apply({
1163 states: [{ predicate: "a", object: "RelationshipTag" }],
1165 assertStrictEquals(applied
.kind
, "Tag");
1168 it("[[Call]] silently fails setting inverse statements", () => {
1169 const tag
= new Tag();
1171 const otherTag
= new Tag();
1172 otherTag
.persist(true);
1173 const applied
= system
.apply({
1175 unstates: [{ predicate: "narrower", object: otherTag
.iri
}],
1177 assertEquals([...applied
.narrowerTags()], []);
1181 describe("::authorityName", () => {
1182 it("[[Get]] returns the authority name", () => {
1183 const system
= new TagSystem("etaoin.example", "1972-12-31");
1184 assertStrictEquals(system
.authorityName
, "etaoin.example");
1188 describe("::authorityName", () => {
1189 it("[[Get]] returns the date", () => {
1190 const system
= new TagSystem("etaoin.example", "1972-12-31");
1191 assertStrictEquals(system
.date
, "1972-12-31");
1195 describe("::identifiers", () => {
1196 it("[[Get]] yields the extant entities", () => {
1197 const system
= new TagSystem("etaoin.example", "1972-12-31");
1198 const tags
= new Set(function* () {
1201 // Generate 5 tags and remember their identifiers.
1202 const tag
= new system
.Tag();
1204 yield tag
.identifier
;
1208 new Set(Array
.from(system
.entities(), ($) => $.identifier
)),
1214 describe("::identifier", () => {
1215 it("[[Get]] returns the identifier", () => {
1216 const system
= new TagSystem("etaoin.example", "1972-12-31");
1217 assertStrictEquals(system
.identifier
, "");
1218 const system2
= new TagSystem(
1223 assertStrictEquals(system2
.identifier
, "etaoin");
1227 describe("::identifiers", () => {
1228 it("[[Get]] yields the identifiers in use", () => {
1229 const system
= new TagSystem("etaoin.example", "1972-12-31");
1230 const tags
= new Set(function* () {
1233 // Generate 5 tags and remember their identifiers.
1234 const tag
= new system
.Tag();
1236 yield tag
.identifier
;
1239 assertEquals(new Set(system
.identifiers()), tags
);
1243 describe("::iri", () => {
1244 it("[[Get]] returns the I·R·I", () => {
1245 const system
= new TagSystem("etaoin.example", "1972-12-31");
1248 "https://etaoin.example/tag:etaoin.example,1972-12-31:",
1250 const system2
= new TagSystem(
1257 "https://etaoin.example/tag:etaoin.example,1972-12-31:etaoin",
1262 describe("::iriSpace", () => {
1263 it("[[Get]] returns the I·R·I space", () => {
1264 const system
= new TagSystem("etaoin.example", "1972-12-31");
1267 "https://etaoin.example/tag:etaoin.example,1972-12-31:",
1269 const system2
= new TagSystem(
1276 "https://etaoin.example/tag:etaoin.example,1972-12-31:",
1281 describe("::tagURI", () => {
1282 it("[[Get]] returns the Tag U·R·I", () => {
1283 const system
= new TagSystem("etaoin.example", "1972-12-31");
1286 "tag:etaoin.example,1972-12-31:",
1288 const system2
= new TagSystem(
1295 "tag:etaoin.example,1972-12-31:etaoin",
1300 describe("::taggingEntity", () => {
1301 it("[[Get]] returns the tagging entity", () => {
1302 const system
= new TagSystem("etaoin.example", "1972-12-31");
1304 system
.taggingEntity
,
1305 "etaoin.example,1972-12-31",
This page took 0.168908 seconds and 5 git commands to generate.