Collections validation written, refactoring done, existing tests pass.
New tests have yet to be written for collections functionality.
This commit is contained in:
parent
4b04bf020f
commit
25c86b80fa
|
@ -1,18 +1,55 @@
|
|||
{"coverage":
|
||||
{"dog_and_duck/quack/quack.clj":
|
||||
{"dog_and_duck/quack/picky/constants.clj":
|
||||
[null, 1, null, null, null, null, null, null, null, null, null, null,
|
||||
null, null, null, null, null, null, null, null, 1, null, null, null,
|
||||
null, 1, null, null, null, null, 1, null, null, null, null, null, 1,
|
||||
null, null, null, 1, null, 1, null, null, null, null, null, null,
|
||||
null, null, null, null, null, 1, null, 1, null, 1, 1, 1, 1, 1, 1,
|
||||
null, 1, null, null, null, null, 1, null, null, null, null, 1, null,
|
||||
null, null, null],
|
||||
"dog_and_duck/quack/picky/utils.clj":
|
||||
[null, 1, null, null, null, null, null, null, null, null, null, null,
|
||||
null, null, null, null, null, null, null, null, null, null, null,
|
||||
null, null, null, null, null, null, null, null, null, null, null, 1,
|
||||
null, null, 7, null, 1, null, null, null, 0, null, 1, null, null,
|
||||
null, null, null, 0, 0, 0, 0, 0, null, 1, null, null, 0, 0, 0, null,
|
||||
null, null, null, true, null, null, 0, null, null, 1, null, null,
|
||||
null, 4, null, 1, null, null, null, 0, 0, 0, 0, null, 1, null, null,
|
||||
null, 3, 3, true, 3, null, 1, null, null, null, true, true, 45, 45,
|
||||
45, 70, 45, null, 0, 0, null, 0, 0, null, 1, null, null, null, null,
|
||||
null, null, true, 162, 66, true, 6, null, null, null, 53, null,
|
||||
null, 3, null, 1, null, null, null, null, null, null, null, null,
|
||||
220, 220, 220, 220, null, 220, null, 220, null, 220, 220, true,
|
||||
null, 0, 0, null, 53, null, null, 2, 2, null, 1, null, null, null,
|
||||
true, null, 1, null, null, null, null, null, null, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, null, 0, 0, 0, 0, 0, 0, null, 1, null, null, null, null,
|
||||
null, null, null, null, null, 0, 0, null, 0, null, 3, null, null,
|
||||
null, 3, null, 1, null, null, null, null, null, 0, null, 0, 0, null,
|
||||
null, 1, null, null, null, null, null, null, true, 53, 53, 53, 3,
|
||||
53, 53, 41, 53, 9, 53, 16, null, 0, 0, 0, 0, 0, null, null, 1, null,
|
||||
null, null, null, null, null, null, null, null, null, null, null,
|
||||
null, null, null, null, null, 0, 0, 0, 0, 0, 0, null, 0, 0, 0, null,
|
||||
null, 0, 0, 0, null, 0, 0, 0, 0, 0, null, 0, 0, 0, 0, 0, null, 1,
|
||||
null, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, null, 0, 0, 0, 0],
|
||||
"dog_and_duck/quack/quack.clj":
|
||||
[null, 1, null, null, null, null, null, null, null, null, null, null,
|
||||
null, null, null, null, null, null, null, null, null, null, null,
|
||||
null, null, null, null, null, null, null, null, null, null, null,
|
||||
null, null, null, null, 1, null, null, null, null, null, null, null,
|
||||
null, null, null, null, null, null, 1, null, null, null, null, null,
|
||||
null, null, null, null, null, null, null, null, null, null, null,
|
||||
null, null, null, 34, null, 34, null, 1, null, null, null, null,
|
||||
null, 4, null, 4, null, 1, null, 3, null, 3, null, 1, null, null,
|
||||
null, null, null, null, null, 0, 0, 0, 0, null, null, null, null, 1,
|
||||
null, 0, null, 0, null, 1, null, 0, null, 0, null, 1, null, null,
|
||||
null, null, null, 0, 0, 0, null, null, 1, null, null, null, null,
|
||||
null, true, true, true, true, 2, 1, null, 1, 1, true, true, 1, null,
|
||||
null, null, null, null, null, null, null, 0, 0, 0, 0, null, null, 1,
|
||||
null, null, 0, null, 1, null, null, 0, null, 1, null, null, 0, null,
|
||||
1, null, null, 2, null, null],
|
||||
"dog_and_duck/quack/picky/fault_messages.clj":
|
||||
[null, 1, null, null, null, null, null, null, null, null, null, null,
|
||||
null, null, null, null, null, null, null, null, null, 1, null, 1,
|
||||
null, null, null, null, null, null, null, null, null, null, null,
|
||||
null, 35, null, 35, null, 1, null, null, null, null, null, 4, null,
|
||||
4, null, 1, null, 3, null, 3, null, 1, null, null, null, null, null,
|
||||
null, null, 0, 0, 0, 0, null, null, null, null, 1, null, 0, null, 0,
|
||||
null, 1, null, 0, null, 0, null, 1, null, null, null, null, null, 0,
|
||||
0, 0, null, null, 1, null, null, null, null, null, true, true, true,
|
||||
true, 2, 1, null, 1, 1, true, true, 1, null, null, null, null, null,
|
||||
null, null, null, 0, 0, 0, 0, null, null, 1, null, null, 0, null, 1,
|
||||
null, null, 0, null, 1, null, null, 0, null, 1, null, null, 2, null,
|
||||
null],
|
||||
"dog_and_duck/utils/process.clj":
|
||||
[null, 1, null, null, null, null, null, null, null, null, null, null,
|
||||
|
@ -30,8 +67,15 @@
|
|||
"dog_and_duck/scratch/parser.clj":
|
||||
[null, 1, null, null, null, null, null, null, null, null, null, null,
|
||||
null, null, null, null, null, null, null, null, null, null, null,
|
||||
null, 1, null, null, null, 11, 11, 11, 11, 11, true, 0, null, 1,
|
||||
null, 1, 0, 0, 0, 0, 0, 0, 1, null, 1],
|
||||
null, 1, null, null, null, 9, 9, 9, 9, 9, true, 0, null, null, null,
|
||||
null, null, null, null, null, null, null, null, null, null],
|
||||
"dog_and_duck/quack/picky/required_properties.clj":[null, 1],
|
||||
"dog_and_duck/quack/picky/control_variables.clj":
|
||||
[null, 1, null, null, null, null, null, null, null, null, null, null,
|
||||
null, null, null, null, null, null, null, null, 1, null, null, null,
|
||||
null, null, null, null, null, null, null, null, null, null, null,
|
||||
null, null, null, null, null, null, 1, null, null, null, null, null,
|
||||
null, null, null],
|
||||
"clj_activitypub/core.clj":
|
||||
[null, 1, null, null, null, null, null, null, null, null, null, 1,
|
||||
null, null, null, null, null, 0, 0, 0, 0, 0, 0, 0, 0, null, 1, null,
|
||||
|
@ -53,44 +97,19 @@
|
|||
null, null, null, null, null, null, null, null, null, null, null,
|
||||
null, null, null, null, null, null, null, null, null, null, null,
|
||||
null, null, null, null, null, null, null, null, null, null, null,
|
||||
null, 1, null, null, null, null, null, null, null, null, null, null,
|
||||
null, null, null, null, null, null, null, null, null, null, 1, null,
|
||||
null, null, null, null, null, null, null, null, 1, null, null, null,
|
||||
1, null, 1, null, null, null, null, null, null, null, null, null,
|
||||
null, null, 1, null, 1, null, 1, 1, 1, 1, 1, 1, null, 1, null, null,
|
||||
0, null, 1, null, null, null, null, null, 0, 0, 0, 0, 0, null, 1,
|
||||
null, null, null, true, true, 46, 46, 46, 72, 46, null, 0, 0, null,
|
||||
0, 0, null, 1, null, null, null, null, 1, null, null, null, null, 1,
|
||||
null, null, null, null, null, null, true, 261, 123, true, 6, null,
|
||||
null, null, 89, null, null, 3, null, 1, null, null, null, null,
|
||||
null, null, null, null, 372, 372, 372, 372, null, 372, null, 372,
|
||||
null, 372, 372, true, null, 0, 0, null, true, null, null, 6, 6,
|
||||
null, 1, null, null, null, null, null, null, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, null, 0, 0, 0, 0, 0, 0, null, 1, null, null, null, null, null,
|
||||
true, 89, 89, 89, 5, 89, 89, 66, 89, 13, 89, 23, null, 0, 0, 0, 0,
|
||||
0, null, null, 0, null, 1, null, null, null, null, 0, null, 16, 16,
|
||||
null, 0, null, 0, null, 12, null, 1, null, null, true, 17, 17, 17,
|
||||
17, 17, 14, 13, 8, null, 1, null, 0, 3, null, 1, null, null, null,
|
||||
null, 1, null, null, null, null, null, 1, null, null, 12, null, 1,
|
||||
null, null, null, 8, 8, true, 8, null, 1, null, null, true, 3, 3, 3,
|
||||
3, 1, 3, 3, 3, 3, null, 1, null, null, null, null, 1, null, null,
|
||||
null, null, 1, null, null, null, 4, null, 1, null, null, null, 0, 0,
|
||||
0, 0, null, 1, null, null, null, null, null, 0, null, 0, 0, null, 1,
|
||||
null, null, null, null, 0, 0, 0, 0, null, null, null, 1, null, null,
|
||||
null, null, null, null, null, null, null, null, null, null, null,
|
||||
null, null, null, 0, 0, 0, 0, 0, 0, null, 0, 0, 0, null, null, 0, 0,
|
||||
null, 0, 0, 0, 0, 0, null, 0, 0, 0, 0, 0, null, 1, null, null, 0,
|
||||
null, 1, null, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, null, 0,
|
||||
0, 0, 0, null, 1, null, null, null, true, 0, true, true, null, 1,
|
||||
null, null, null, 1, null, 1, null, null, 1, null, 1, 0, null, null,
|
||||
null, 1, null, null, 1, 1, 1, 1, null, 1, 1, 1, 1, 1, 1, null, 1, 1,
|
||||
1, 0, null, null, null, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, null, 1, null, null, null, null, null, null, null, 0, 0, 0, null,
|
||||
0, 0, 0, 0, null, 1, null, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
"dog_and_duck/quack/fault_messages.clj":
|
||||
[null, 1, null, null, null, null, null, null, null, null, null, null,
|
||||
null, null, null, null, null, null, null, 1, null, 1, null, null,
|
||||
null, null, null, null, null, null, null, null],
|
||||
null, null, null, null, null, null, 1, null, null, null, null, 0,
|
||||
null, 6, 6, null, 0, null, 0, null, 4, null, 1, null, null, 12, 12,
|
||||
12, 12, 9, 8, 4, null, 1, null, 0, 3, null, 0, 0, 0, 0, null, 1,
|
||||
null, null, 3, 3, 3, 3, 1, 3, 3, 3, 3, null, 1, null, null, null,
|
||||
null, 0, 0, 0, 0, 0, 0, null, null, null, 1, null, null, null, true,
|
||||
0, true, true, null, 1, null, null, null, 1, null, 1, null, null, 1,
|
||||
null, 1, 0, null, null, null, 1, null, null, 1, 1, 1, 1, null, 1, 1,
|
||||
1, 1, 1, 1, null, 1, 1, 1, 0, null, null, null, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, null, 1, null, null, null, null, null,
|
||||
null, null, 0, 0, 0, null, 0, 0, 0, 0, null, 1, null, 0, 0, 0, 0, 0,
|
||||
0, 0, null, 1, null, null, null, null, null, null, null, null, null,
|
||||
null, null, null, null, null, null, 0, 0, 0, 0, 0, 0, null, null,
|
||||
null, null, null, 0, 0, 0, 0, null, null, 0, 0],
|
||||
"dog_and_duck/scratch/core.clj":
|
||||
[null, 1, null, null, null, null, null, null, null, null, null, null,
|
||||
null, null, null, null, null, null, null, 1, null, null, 0],
|
||||
|
@ -103,4 +122,10 @@
|
|||
null, null, null, null, null, null, null, null, null, null, null,
|
||||
null, null, 1, null, 1, 1, 1, null, null, null, null, 1, null, 1, 1,
|
||||
1, 1, null, null, 1, null, null, null, null, null, null, null, 1, 1,
|
||||
1, 1, 1, 1, null, null]}}
|
||||
1, 1, 1, 1, null, null],
|
||||
"dog_and_duck/quack/picky/collections.clj":
|
||||
[null, 1, null, null, null, null, null, null, null, null, null, null,
|
||||
null, null, null, null, null, null, null, null, null, null, null,
|
||||
null, 1, null, null, null, 0, 0, 0, 0, 0, 0, null, 1, null, null,
|
||||
null, 0, 0, 0, 0, 0, 0, 0, null, 1, null, 0, 0, 0, 0, 0, null, null,
|
||||
0, 0]}}
|
||||
|
|
|
@ -1 +1 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?><report><stats><packages value="12"/><methods value="2644"/><srcfiles value="12"/><srclines value="530"/></stats><data><all name="total"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="54% (1438/2644)"/><coverage type="line, %" value="55% (294/530)"/><package name="dog-and-duck.scratch.scratch"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="100% (66/66)"/><coverage type="line, %" value="100% (17/17)"/></package><package name="clj-activitypub.internal.thread-cache"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="83% (105/126)"/><coverage type="line, %" value="88% (30/34)"/></package><package name="dog-and-duck.quack.fault-messages"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="100% (25/25)"/><coverage type="line, %" value="100% (3/3)"/></package><package name="clj-activitypub.internal.crypto"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="19% (9/48)"/><coverage type="line, %" value="39% (9/23)"/></package><package name="dog-and-duck.quack.quack"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="47% (122/262)"/><coverage type="line, %" value="51% (25/49)"/></package><package name="clj-activitypub.webfinger"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="96% (107/112)"/><coverage type="line, %" value="89% (16/18)"/></package><package name="dog-and-duck.quack.picky"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="53% (825/1544)"/><coverage type="line, %" value="54% (135/252)"/></package><package name="clj-activitypub.internal.http-util"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="74% (29/39)"/><coverage type="line, %" value="80% (12/15)"/></package><package name="dog-and-duck.scratch.core"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="33% (2/6)"/><coverage type="line, %" value="67% (2/3)"/></package><package name="dog-and-duck.utils.process"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="89% (34/38)"/><coverage type="line, %" value="91% (10/11)"/></package><package name="dog-and-duck.scratch.parser"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="56% (43/77)"/><coverage type="line, %" value="58% (11/19)"/></package><package name="clj-activitypub.core"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="24% (71/301)"/><coverage type="line, %" value="28% (24/86)"/></package></all></data></report>
|
||||
<?xml version="1.0" encoding="UTF-8"?><report><stats><packages value="17"/><methods value="2634"/><srcfiles value="17"/><srclines value="572"/></stats><data><all name="total"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="50% (1326/2634)"/><coverage type="line, %" value="53% (303/572)"/><package name="dog-and-duck.scratch.scratch"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="100% (66/66)"/><coverage type="line, %" value="100% (17/17)"/></package><package name="clj-activitypub.internal.thread-cache"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="83% (105/126)"/><coverage type="line, %" value="88% (30/34)"/></package><package name="clj-activitypub.internal.crypto"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="19% (9/48)"/><coverage type="line, %" value="39% (9/23)"/></package><package name="dog-and-duck.quack.quack"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="47% (122/262)"/><coverage type="line, %" value="51% (25/49)"/></package><package name="clj-activitypub.webfinger"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="96% (107/112)"/><coverage type="line, %" value="89% (16/18)"/></package><package name="dog-and-duck.quack.picky"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="42% (169/406)"/><coverage type="line, %" value="59% (65/111)"/></package><package name="clj-activitypub.internal.http-util"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="74% (29/39)"/><coverage type="line, %" value="80% (12/15)"/></package><package name="dog-and-duck.quack.picky.collections"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="3% (4/133)"/><coverage type="line, %" value="17% (4/24)"/></package><package name="dog-and-duck.quack.picky.constants"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="100% (73/73)"/><coverage type="line, %" value="100% (18/18)"/></package><package name="dog-and-duck.quack.picky.required-properties"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="100% (1/1)"/><coverage type="line, %" value="100% (1/1)"/></package><package name="dog-and-duck.scratch.core"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="33% (2/6)"/><coverage type="line, %" value="67% (2/3)"/></package><package name="dog-and-duck.quack.picky.control-variables"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="100% (5/5)"/><coverage type="line, %" value="100% (3/3)"/></package><package name="dog-and-duck.utils.process"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="89% (34/38)"/><coverage type="line, %" value="91% (10/11)"/></package><package name="dog-and-duck.quack.picky.utils"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="50% (479/959)"/><coverage type="line, %" value="39% (57/147)"/></package><package name="dog-and-duck.quack.picky.fault-messages"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="100% (29/29)"/><coverage type="line, %" value="100% (3/3)"/></package><package name="dog-and-duck.scratch.parser"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="70% (21/30)"/><coverage type="line, %" value="78% (7/9)"/></package><package name="clj-activitypub.core"><coverage type="class, %" value="0% (0/1)"/><coverage type="method, %" value="0% (0/1)"/><coverage type="block, %" value="24% (71/301)"/><coverage type="line, %" value="28% (24/86)"/></package></all></data></report>
|
File diff suppressed because it is too large
Load diff
179
docs/cloverage/dog_and_duck/quack/picky/collections.clj.html
Normal file
179
docs/cloverage/dog_and_duck/quack/picky/collections.clj.html
Normal file
|
@ -0,0 +1,179 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" href="../../../coverage.css"/> <title> dog_and_duck/quack/picky/collections.clj </title>
|
||||
</head>
|
||||
<body>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
001 (ns dog-and-duck.quack.picky.collections
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
002 (:require [dog-and-duck.quack.picky.utils :refer [concat-non-empty
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
003 cond-make-fault-object
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
004 object-faults
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
005 object-reference-or-faults]]))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
006
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
007
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
008 ;;; Copyright (C) Simon Brooke, 2022
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
009
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
010 ;;; This program is free software; you can redistribute it and/or
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
011 ;;; modify it under the terms of the GNU General Public License
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
012 ;;; as published by the Free Software Foundation; either version 2
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
013 ;;; of the License, or (at your option) any later version.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
014
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
015 ;;; This program is distributed in the hope that it will be useful,
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
016 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
017 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
018 ;;; GNU General Public License for more details.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
019
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
020 ;;; You should have received a copy of the GNU General Public License
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
021 ;;; along with this program; if not, write to the Free Software
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
022 ;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
023
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
024 (defn paged-collection-faults
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
025 "Return a list of faults found in `x` considered as a paged collection
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
026 object of this sub-`type`, or `nil` if none are found."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
027 [x type]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
028 (concat-non-empty
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
029 (object-faults x type)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 8 forms covered">
|
||||
030 (list (object-reference-or-faults x type :critical :expected-collection)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 11 forms covered">
|
||||
031 (cond-make-fault-object (integer? (:totalItems x)) :should :no-total-items)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 8 forms covered">
|
||||
032 (object-reference-or-faults (:first x) nil :must :no-first-page)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 8 forms covered">
|
||||
033 (object-reference-or-faults (:last x) nil :should :no-last-page))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
034
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
035 (defn simple-collection-faults
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
036 "Return a list of faults found in `x` considered as a non-paged collection
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
037 object of this sub-`type`, or `nil` if none are found."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
038 [x type]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
039 (concat-non-empty
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
040 (object-faults x type)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
041 (cons
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 8 forms covered">
|
||||
042 (list (object-reference-or-faults x type :critical :expected-collection)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 11 forms covered">
|
||||
043 (cond-make-fault-object (integer? (:totalItems x)) :should :no-total-items)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 11 forms covered">
|
||||
044 (cond-make-fault-object (coll? (:items x)) :must :no-items-collection))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 12 forms covered">
|
||||
045 (map #(object-reference-or-faults % nil :must :not-object-reference) (:items x)))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
046
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
047 (defn collection-page-faults
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
048 [x type]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
049 (concat-non-empty
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
050 (simple-collection-faults x type)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
051 (list
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 7 forms covered">
|
||||
052 (object-reference-or-faults (:partOf x)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 7 forms covered">
|
||||
053 (apply str (drop-last 4 type))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
054 :should
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
055 :n-part-of)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 8 forms covered">
|
||||
056 (object-reference-or-faults (:next x) type :minor :no-next-page)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 8 forms covered">
|
||||
057 (object-reference-or-faults (:prev x) type :minor :no-prev-page))))
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
245
docs/cloverage/dog_and_duck/quack/picky/constants.clj.html
Normal file
245
docs/cloverage/dog_and_duck/quack/picky/constants.clj.html
Normal file
|
@ -0,0 +1,245 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" href="../../../coverage.css"/> <title> dog_and_duck/quack/picky/constants.clj </title>
|
||||
</head>
|
||||
<body>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
001 (ns dog-and-duck.quack.picky.constants
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
002 "Constants supporting the picky validator.")
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
003
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
004 ;;; Copyright (C) Simon Brooke, 2022
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
005
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
006 ;;; This program is free software; you can redistribute it and/or
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
007 ;;; modify it under the terms of the GNU General Public License
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
008 ;;; as published by the Free Software Foundation; either version 2
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
009 ;;; of the License, or (at your option) any later version.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
010
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
011 ;;; This program is distributed in the hope that it will be useful,
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
012 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
013 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
014 ;;; GNU General Public License for more details.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
015
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
016 ;;; You should have received a copy of the GNU General Public License
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
017 ;;; along with this program; if not, write to the Free Software
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
018 ;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
019
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
020 (def ^:const activitystreams-context-uri
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
021 "The URI of the context of an ActivityStreams object is expected to be this
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
022 literal string."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
023 "https://www.w3.org/ns/activitystreams")
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
024
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
025 (def ^:const actor-types
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
026 "The set of types we will accept as actors.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
027
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
028 There's an [explicit set of allowed actor types]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
029 (https://www.w3.org/TR/activitystreams-vocabulary/#actor-types)."
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
030 #{"Application"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
031 "Group"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
032 "Organization"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
033 "Person"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
034 "Service"})
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
035
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
036 (def ^:const context-key
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
037 "The Clojure reader barfs on `:@context`, although it is in principle a valid
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
038 keyword. So we'll make it once, here, to make the code more performant and
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
039 easier to read."
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
040 (keyword "@context"))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
041
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
042 (def ^:const severity
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
043 "Severity of faults found, as follows:
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
044
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
045 0. `:info` not actually a fault, but an issue noted during validation;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
046 1. `:minor` things which I consider to be faults, but which
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
047 don't actually breach the spec;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
048 2. `:should` instances where the spec says something SHOULD
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
049 be done, which isn't;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
050 3. `:must` instances where the spec says something MUST
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
051 be done, which isn't;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
052 4. `:critical` instances where I believe the fault means that
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
053 the object cannot be meaningfully processed."
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
054 #{:info :minor :should :must :critical})
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
055
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
056 (def ^:const severity-filters
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
057 "Hack for implementing a severity hierarchy"
|
||||
</span><br/>
|
||||
<span class="covered" title="8 out of 8 forms covered">
|
||||
058 {:all #{}
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
059 :info #{}
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
060 :minor #{:info}
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
061 :should #{:info :minor}
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
062 :must #{:info :minor :should}
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
063 :critical severity})
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
064
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
065 (def ^:const validation-fault-context-uri
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
066 "The URI of the context of a validation fault report object shall be this
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
067 literal string."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
068 "https://simon-brooke.github.io/dog-and-duck/codox/Validation_Faults.html")
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
069
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
070 (def ^:const verb-types
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
071 "The set of types we will accept as verbs.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
072
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
073 There's an [explicit set of allowed verb types]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
074 (https://www.w3.org/TR/activitystreams-vocabulary/#activity-types)."
|
||||
</span><br/>
|
||||
<span class="covered" title="29 out of 29 forms covered">
|
||||
075 #{"Accept" "Add" "Announce" "Arrive" "Block" "Create" "Delete" "Dislike"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
076 "Flag" "Follow" "Ignore" "Invite" "Join" "Leave" "Like" "Listen" "Move"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
077 "Offer" "Question" "Reject" "Read" "Remove" "TentativeAccept"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
078 "TentativeReject" "Travel" "Undo" "Update" "View"})
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
079
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,155 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" href="../../../coverage.css"/> <title> dog_and_duck/quack/picky/control_variables.clj </title>
|
||||
</head>
|
||||
<body>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
001 (ns dog-and-duck.quack.picky.control-variables
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
002 "Control variables for the picky validator.")
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
003
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
004 ;;; Copyright (C) Simon Brooke, 2022
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
005
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
006 ;;; This program is free software; you can redistribute it and/or
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
007 ;;; modify it under the terms of the GNU General Public License
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
008 ;;; as published by the Free Software Foundation; either version 2
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
009 ;;; of the License, or (at your option) any later version.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
010
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
011 ;;; This program is distributed in the hope that it will be useful,
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
012 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
013 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
014 ;;; GNU General Public License for more details.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
015
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
016 ;;; You should have received a copy of the GNU General Public License
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
017 ;;; along with this program; if not, write to the Free Software
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
018 ;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
019
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
020 (def ^:dynamic *reify-refs*
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
021 "If `true`, references to objects in fields will be reified and validated.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
022 If `false`, they won't, but an `:info` level fault report will be generated.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
023
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
024 There are several things in the spec which, in a document, may correctly be
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
025 either
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
026
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
027 1. a fully fleshed out object, or
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
028 2. a URI pointing to such an object.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
029
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
030 Obviously to fully validate a document we ought to reify all the refs and
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
031 check that they are themselves valid, but
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
032
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
033 a. in some of the published test documents the URIs do not reference a
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
034 valid document;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
035 b. there will be performance costs to reifying all the refs;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
036 c. in perverse cases, reifying refs might result in runaway recursion.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
037
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
038 TODO: I think that in production this should default to `true`."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
039 false)
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
040
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
041 (def ^:dynamic *reject-severity*
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
042 "The severity at which the binary validator will return `false`.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
043
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
044 In practice documents seen in the wild do not typically appear to be
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
045 fully valid, and this does not matter. This allows the sensitivity of
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
046 the binary validator (`dog-and-duck.quack.quack`) to be tuned. It's in
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
047 this (`dog-and-duck.quack.picky`) namespace, not that one, because this
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
048 namespace is where concerns about severity are handled."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
049 :must)
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
113
docs/cloverage/dog_and_duck/quack/picky/fault_messages.clj.html
Normal file
113
docs/cloverage/dog_and_duck/quack/picky/fault_messages.clj.html
Normal file
|
@ -0,0 +1,113 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" href="../../../coverage.css"/> <title> dog_and_duck/quack/picky/fault_messages.clj </title>
|
||||
</head>
|
||||
<body>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
001 (ns dog-and-duck.quack.picky.fault-messages
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
002 "Narrative values for fault reports of specific types, used by the picky
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
003 validator.")
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
004
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
005 ;;; Copyright (C) Simon Brooke, 2022
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
006
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
007 ;;; This program is free software; you can redistribute it and/or
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
008 ;;; modify it under the terms of the GNU General Public License
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
009 ;;; as published by the Free Software Foundation; either version 2
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
010 ;;; of the License, or (at your option) any later version.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
011
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
012 ;;; This program is distributed in the hope that it will be useful,
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
013 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
014 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
015 ;;; GNU General Public License for more details.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
016
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
017 ;;; You should have received a copy of the GNU General Public License
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
018 ;;; along with this program; if not, write to the Free Software
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
019 ;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
020
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
021 (def messages
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
022 "Actual fault messages to which fault codes resolve."
|
||||
</span><br/>
|
||||
<span class="covered" title="27 out of 27 forms covered">
|
||||
023 {:expected-collection "A collection was expected, but was not found."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
024 :id-not-https "Publicly facing content SHOULD use HTTPS URIs"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
025 :id-not-uri "identifiers must be publicly dereferencable URIs"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
026 :no-context "Section 3 of the ActivityPub specification states Implementers SHOULD include the ActivityPub context in their object definitions`."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
027 :no-id-persistent "Persistent objects MUST have unique global identifiers."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
028 :no-id-transient "The ActivityPub specification allows objects without `id` fields only if they are intentionally transient; even so it is preferred that the object should have an explicit null id."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
029 :no-inbox "Actor objects MUST have an `inbox` property, whose value MUST be a reference to an ordered collection."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
030 :no-items-collection "A collection expected to be simple had no items."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
031 :no-outbox "Actor objects MUST have an `outbox` property, whose value MUST be a reference to an ordered collection."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
032 :no-type "The ActivityPub specification states that the `type` field is optional, but it is hard to process objects with no known type."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
033 :not-actor-type "The `type` value of the object was not a recognised actor type."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
034 :null-id-persistent "Persistent objects MUST have non-null identifiers."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
035 :not-an-object "ActivityStreams object must be JSON objects."})
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,11 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" href="../../../coverage.css"/> <title> dog_and_duck/quack/picky/required_properties.clj </title>
|
||||
</head>
|
||||
<body>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
001 (ns dog-and-duck.quack.picky.required-properties)
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
965
docs/cloverage/dog_and_duck/quack/picky/utils.clj.html
Normal file
965
docs/cloverage/dog_and_duck/quack/picky/utils.clj.html
Normal file
|
@ -0,0 +1,965 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" href="../../../coverage.css"/> <title> dog_and_duck/quack/picky/utils.clj </title>
|
||||
</head>
|
||||
<body>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
001 (ns dog-and-duck.quack.picky.utils
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
002 "Utility functions supporting the picky validator"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
003 (:require [clojure.data.json :as json]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
004 [clojure.set :refer [intersection]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
005 [dog-and-duck.quack.picky.constants :refer [activitystreams-context-uri
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
006 actor-types
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
007 context-key severity-filters
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
008 validation-fault-context-uri
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
009 verb-types]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
010 [dog-and-duck.quack.picky.control-variables :refer [*reify-refs*]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
011 [dog-and-duck.quack.picky.fault-messages :refer [messages]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
012 [dog-and-duck.utils.process :refer [get-hostname get-pid]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
013 [taoensso.timbre :as log :refer [warn]])
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
014
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
015 (:import [java.net URI URISyntaxException]))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
016
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
017 ;;; Copyright (C) Simon Brooke, 2022
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
018
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
019 ;;; This program is free software; you can redistribute it and/or
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
020 ;;; modify it under the terms of the GNU General Public License
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
021 ;;; as published by the Free Software Foundation; either version 2
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
022 ;;; of the License, or (at your option) any later version.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
023
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
024 ;;; This program is distributed in the hope that it will be useful,
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
025 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
026 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
027 ;;; GNU General Public License for more details.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
028
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
029 ;;; You should have received a copy of the GNU General Public License
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
030 ;;; along with this program; if not, write to the Free Software
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
031 ;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
032
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
033
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
034 (defn actor-type?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
035 "Return `true` if the `x` is a recognised actor type, else `false`."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
036 [^String x]
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
037 (if (actor-types x) true false))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
038
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
039 (defn truthy?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
040 "Return `true` if `x` is truthy, else `false`. There must be some more
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
041 idiomatic way to do this?"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
042 [x]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
043 (if x true false))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
044
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
045 (defn has-type?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
046 "Return `true` if object `x` has type `type`, else `false`.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
047
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
048 The values of `type` fields of ActivityStreams objects may be lists; they
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
049 are considered to have a type if the type token is a member of the list."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
050 [x type]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 18 forms covered">
|
||||
051 (assert (map? x) (string? type))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
052 (let [tv (:type x)]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
053 (cond
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 14 forms covered">
|
||||
054 (coll? tv) (truthy? (not-empty (filter #(= % type) tv)))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
055 :else (= tv type))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
056
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
057 (defn object-or-uri?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
058 "Very basic check that `x` is either an object or a URI."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
059 [x]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
060 (try
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 11 forms covered">
|
||||
061 (cond (string? x) (uri? (URI. x))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 16 forms covered">
|
||||
062 (map? x) (if (and (:type x) (:id x)) true false)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
063 :else false)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
064 (catch URISyntaxException _ false)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
065 (catch NullPointerException _ false)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
066
|
||||
</span><br/>
|
||||
<span class="partial" title="5 out of 46 forms covered">
|
||||
067 (defmacro link-or-uri?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
068 "Very basic check that `x` is either a link object or a URI."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
069 [x]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
070 `(if (object-or-uri? ~x) (has-type? ~x "Link") false))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
071
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
072
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
073 (defn verb-type?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
074 "`true` if `x`, a string, represents a recognised ActivityStreams activity
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
075 type."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
076 [^String x]
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
077 (if (verb-types x) true false))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
078
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
079 (defn has-activity-type?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
080 "Return `true` if the object `x` has a type which is an activity type, else
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
081 `false`."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
082 [x]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
083 (let [tv (:type x)]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
084 (cond
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 11 forms covered">
|
||||
085 (coll? tv) (truthy? (not-empty (filter verb-type? tv)))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
086 :else (verb-type? tv))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
087
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
088 (defn has-actor-type?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
089 "Return `true` if the object `x` has a type which is an actor type, else
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
090 `false`."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
091 [x]
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
092 (let [tv (:type x)]
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
093 (cond
|
||||
</span><br/>
|
||||
<span class="partial" title="3 out of 11 forms covered">
|
||||
094 (coll? tv) (truthy? (not-empty (filter actor-type? tv)))
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
095 :else (actor-type? tv))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
096
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
097 (defn filter-severity
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
098 "Return a list of reports taken from these `reports` where the severity
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
099 of the report is greater than this or equal to this `severity`."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
100 [reports severity]
|
||||
</span><br/>
|
||||
<span class="partial" title="6 out of 7 forms covered">
|
||||
101 (cond (nil? reports) nil
|
||||
</span><br/>
|
||||
<span class="partial" title="8 out of 10 forms covered">
|
||||
102 (and
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
103 (coll? reports)
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
104 (every? map? reports)
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
105 (every? :severity reports)) (remove
|
||||
</span><br/>
|
||||
<span class="covered" title="7 out of 7 forms covered">
|
||||
106 #((severity-filters severity) (:severity %))
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
107 reports)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
108 :else
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
109 (throw
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
110 (ex-info
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
111 "Argument `reports` was not a collection of fault reports"
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
112 {:arguments {:reports reports
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
113 :severity severity}}))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
114
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
115 (defn context?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
116 "Returns `true` iff `x` quacks like an ActivityStreams context, else false.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
117
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
118 A context is either
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
119 1. the URI (actually an IRI) `activitystreams-context-uri`, or
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
120 2. a collection comprising that URI and a map."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
121 [x]
|
||||
</span><br/>
|
||||
<span class="partial" title="4 out of 6 forms covered">
|
||||
122 (cond
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
123 (nil? x) false
|
||||
</span><br/>
|
||||
<span class="covered" title="11 out of 11 forms covered">
|
||||
124 (string? x) (and (= x activitystreams-context-uri) true)
|
||||
</span><br/>
|
||||
<span class="partial" title="19 out of 20 forms covered">
|
||||
125 (coll? x) (and (context? (first (remove map? x)))
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
126 (= (count x) 2)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
127 true)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
128 :else false))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
129
|
||||
</span><br/>
|
||||
<span class="covered" title="33 out of 33 forms covered">
|
||||
130 (defmacro has-context?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
131 "True if `x` is an ActivityStreams object with a valid context, else `false`."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
132 [x]
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
133 `(context? (context-key ~x)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
134
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
135 (defn make-fault-object
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
136 "Return a fault object with these `severity`, `fault` and `narrative` values.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
137
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
138 An ActivityPub object MUST have a globally unique ID. Whether this is
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
139 meaningful depends on whether we persist fault report objects and serve
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
140 them, which at present I have no plans to do."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
141 ;; TODO: should not pass in the narrative; instead should use the :fault value
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
142 ;; to look up the narrative in a resource file.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
143 [severity fault]
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
144 (assoc {}
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
145 context-key validation-fault-context-uri
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
146 :id (str "https://"
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
147 (get-hostname)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
148 "/fault/"
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
149 (get-pid)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
150 ":"
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
151 (inst-ms (java.util.Date.)))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
152 :type "Fault"
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
153 :severity severity
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
154 :fault fault
|
||||
</span><br/>
|
||||
<span class="partial" title="7 out of 8 forms covered">
|
||||
155 :narrative (or (messages fault)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
156 (do
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 17 forms covered">
|
||||
157 (warn "No narrative provided for fault token " fault)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
158 (str fault)))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
159
|
||||
</span><br/>
|
||||
<span class="covered" title="60 out of 60 forms covered">
|
||||
160 (defmacro nil-if-empty
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
161 "if `x` is an empty collection, return `nil`; else return `x`."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
162 [x]
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
163 `(if (and (coll? ~x) (empty? ~x)) nil
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
164 ~x))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
165
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
166 (defn concat-non-empty
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
167 "Quick function to replace the pattern (nil-if-empty (remove nil? (concat ...)))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
168 which I'm using a lot!"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
169 [& lists]
|
||||
</span><br/>
|
||||
<span class="partial" title="28 out of 29 forms covered">
|
||||
170 (nil-if-empty (remove nil? (apply concat lists))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
171
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
172 (defn has-type-or-fault
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
173 "If object `x` has a `:type` value which is `acceptable`, return `nil`;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
174 else return a fault object with this `severity` and `token`.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
175
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
176 `acceptable` may be passed as either nil, a string, or a set of strings.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
177 If `acceptable` is `nil`, no type specific tests will be performed."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
178 [x acceptable severity token]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
179 (when acceptable
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
180 (let [tv (:type x)]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
181 (when-not
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
182 (cond
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 13 forms covered">
|
||||
183 (and (string? tv) (string? acceptable)) (= tv acceptable)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 13 forms covered">
|
||||
184 (and (string? tv) (set? acceptable)) (acceptable tv)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 15 forms covered">
|
||||
185 (and (coll? tv) (string? acceptable)) ((set tv) acceptable)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 12 forms covered">
|
||||
186 (and (coll? tv) (set? acceptable)) (not-empty
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
187 (intersection (set tv) acceptable))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
188 :else
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
189 (throw (ex-info "Type value or `acceptable` argument not as expected."
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 8 forms covered">
|
||||
190 {:arguments {:x x
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
191 :acceptable acceptable
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
192 :severity severity
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
193 :token token}})))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
194 (make-fault-object severity token)))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
195
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
196 (defn any-or-faults
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
197 "Return `nil` if validating one of these options returns `nil`; otherwise
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
198 return a list comprising a fault report object with this `severity-if-none`
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
199 and this token followed by all the fault reports from validating each
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
200 option.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
201
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
202 There are several places - but especially in validating collections - where
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
203 there are several different valid configurations, but few or no properties
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
204 are always required."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
205 [options severity-if-none token]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
206 (let [faults (filter empty? options)]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
207 (when (empty? faults)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
208 ;; i.e. there was at least one option that returned no faults...
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 7 forms covered">
|
||||
209 (cons (make-fault-object severity-if-none token) faults))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
210
|
||||
</span><br/>
|
||||
<span class="covered" title="31 out of 31 forms covered">
|
||||
211 (defmacro cond-make-fault-object
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
212 "If `v` is `false` or `nil`, return a fault object with this `severity` and `token`,
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
213 else return nil."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
214 [v severity token]
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
215 `(when-not ~v (make-fault-object ~severity ~token)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
216
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
217 (defn string-or-fault
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
218 "If this `value` is not a string, return a fault object with this `severity`
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
219 and `token`, else `nil`. If `pattern` is also passed, it is expected to be
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
220 a Regex, and the fault object will be returned unless `value` matches the
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
221 `pattern`."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
222 ([value severity token]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 10 forms covered">
|
||||
223 (when-not (string? value) (make-fault-object severity token)))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
224 ([value severity token pattern]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 14 forms covered">
|
||||
225 (when not (and (string? value) (re-matches pattern value))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
226 (make-fault-object severity token))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
227
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
228
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
229 (defn object-faults
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
230 "Return a list of faults found in object `x`, or `nil` if none are.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
231
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
232 If `expected-type` is also passed, verify that `x` has `expected-type`.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
233 `expected-type` may be passed as a string or as a set of strings. Detailed
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
234 verification of the particular features of types is not done here."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
235 ([x]
|
||||
</span><br/>
|
||||
<span class="partial" title="7 out of 8 forms covered">
|
||||
236 (nil-if-empty
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
237 (remove empty?
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
238 (list
|
||||
</span><br/>
|
||||
<span class="covered" title="18 out of 18 forms covered">
|
||||
239 (when-not (map? x)
|
||||
</span><br/>
|
||||
<span class="covered" title="12 out of 12 forms covered">
|
||||
240 (make-fault-object :critical :not-an-object))
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
241 (when-not
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
242 (has-context? x)
|
||||
</span><br/>
|
||||
<span class="covered" title="12 out of 12 forms covered">
|
||||
243 (make-fault-object :should :no-context))
|
||||
</span><br/>
|
||||
<span class="covered" title="18 out of 18 forms covered">
|
||||
244 (when-not (:type x)
|
||||
</span><br/>
|
||||
<span class="covered" title="12 out of 12 forms covered">
|
||||
245 (make-fault-object :minor :no-type))
|
||||
</span><br/>
|
||||
<span class="covered" title="42 out of 42 forms covered">
|
||||
246 (when-not (and (map? x) (contains? x :id))
|
||||
</span><br/>
|
||||
<span class="covered" title="12 out of 12 forms covered">
|
||||
247 (make-fault-object :minor :no-id-transient))))))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
248 ([x expected-type]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
249 (concat-non-empty
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
250 (object-faults x)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
251 (when expected-type
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
252 (list
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
253 (has-type-or-fault x expected-type :critical :unexpected-type))))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
254
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
255
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
256 (defn object-reference-or-faults
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
257 "If this `value` is either
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
258
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
259 1. an object of `expected-type`;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
260 2. a URI referencing an object of `expected-type`; or
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
261 3. a link object referencing an object of `expected-type`
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
262
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
263 and no faults are returned from validating the linked object, then return
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
264 `nil`; else return a sequence comprising a fault object with this `severity`
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
265 and `token`, prepended to the faults returned.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
266
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
267 As with `has-type-or-fault` (q.v.), `expected-type` may be passed as a
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
268 string, as a set of strings, or `nil` (indicating the type of the
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
269 referenced object should not be checked).
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
270
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
271 **NOTE THAT** if `*reify-refs*` is `false`, referenced objects will not
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
272 actually be checked."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
273 [value expected-type severity token]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
274 (let [faults (cond
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 7 forms covered">
|
||||
275 (string? value) (try (let [uri (URI. value)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
276 object (when *reify-refs*
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
277 (json/read-str (slurp uri)))]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
278 (when object
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
279 (object-faults object expected-type)))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
280 (catch URISyntaxException _
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
281 (make-fault-object severity token)))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 8 forms covered">
|
||||
282 (map? value) (if (has-type? value "Link")
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 7 forms covered">
|
||||
283 (cond
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
284 ;; if we were looking for a link and we've
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
285 ;; found a link, that's OK.
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
286 (= expected-type "Link") nil
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 10 forms covered">
|
||||
287 (and (set? expected-type) (expected-type "Link")) nil
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
288 (nil? expected-type) nil
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
289 :else
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
290 (object-reference-or-faults
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
291 (:href value) expected-type severity token))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
292 (object-faults value expected-type))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
293 :else (throw
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
294 (ex-info
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
295 "Argument `value` was not an object or a link to an object"
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 8 forms covered">
|
||||
296 {:arguments {:value value}
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
297 :expected-type expected-type
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
298 :severity severity
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
299 :token token})))]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 10 forms covered">
|
||||
300 (when faults (cons (make-fault-object severity token) faults))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
301
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
302 (defn coll-object-reference-or-fault
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
303 "As object-reference-or-fault, except `value` argument may also be a list of
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
304 objects and/or object references."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
305 [value expected-type severity token]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
306 (cond
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 9 forms covered">
|
||||
307 (map? value) (object-reference-or-faults value expected-type severity token)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
308 (coll? value) (concat-non-empty
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
309 (map
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
310 #(object-reference-or-faults
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
311 % expected-type severity token)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
312 value))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
313 :else (throw
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
314 (ex-info
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
315 "Argument `value` was not an object, a link to an object, nor a list of these."
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 8 forms covered">
|
||||
316 {:arguments {:value value}
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
317 :expected-type expected-type
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
318 :severity severity
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
319 :token token}))))
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
|
@ -50,466 +50,472 @@
|
|||
015
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
016 (:require [dog-and-duck.quack.picky :refer [*reject-severity* activity-faults
|
||||
016 (:require [dog-and-duck.quack.picky :refer [activity-faults actor-faults
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
017 actor-faults filter-severity link-faults
|
||||
017 link-faults
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
018 object-faults persistent-object-faults]])
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
019
|
||||
018 persistent-object-faults]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
020 (:import [java.net URI URISyntaxException]))
|
||||
019 [dog-and-duck.quack.picky.control-variables :refer [*reject-severity*]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
020 [dog-and-duck.quack.picky.utils :refer [filter-severity object-faults]])
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
021
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
022 ;;; Copyright (C) Simon Brooke, 2022
|
||||
022 (:import [java.net URI URISyntaxException]))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
023
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
024 ;;; This program is free software; you can redistribute it and/or
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
025 ;;; modify it under the terms of the GNU General Public License
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
026 ;;; as published by the Free Software Foundation; either version 2
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
027 ;;; of the License, or (at your option) any later version.
|
||||
024 ;;; Copyright (C) Simon Brooke, 2022
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
028
|
||||
025
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
029 ;;; This program is distributed in the hope that it will be useful,
|
||||
026 ;;; This program is free software; you can redistribute it and/or
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
030 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
027 ;;; modify it under the terms of the GNU General Public License
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
031 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
028 ;;; as published by the Free Software Foundation; either version 2
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
032 ;;; GNU General Public License for more details.
|
||||
029 ;;; of the License, or (at your option) any later version.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
033
|
||||
030
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
034 ;;; You should have received a copy of the GNU General Public License
|
||||
031 ;;; This program is distributed in the hope that it will be useful,
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
035 ;;; along with this program; if not, write to the Free Software
|
||||
032 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
036 ;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
033 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
034 ;;; GNU General Public License for more details.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
037
|
||||
035
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
036 ;;; You should have received a copy of the GNU General Public License
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
037 ;;; along with this program; if not, write to the Free Software
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
038 ;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
039
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
038 (defn object?
|
||||
040 (defn object?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
039 "Returns `true` iff `x` is recognisably an ActivityStreams object.
|
||||
041 "Returns `true` iff `x` is recognisably an ActivityStreams object.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
040
|
||||
042
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
041 **NOTE THAT** The ActivityStreams spec
|
||||
043 **NOTE THAT** The ActivityStreams spec
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
042 [says](https://www.w3.org/TR/activitystreams-core/#object):
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
043
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
044 > All properties are optional (including the id and type)
|
||||
044 [says](https://www.w3.org/TR/activitystreams-core/#object):
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
045
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
046 But we are *just not having that*, because otherwise we're flying blind.
|
||||
046 > All properties are optional (including the id and type)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
047 We *shall* reject objects lacking at least `:type`. Missing `:id` keys are
|
||||
047
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
048 tolerable because they represent transient objects, which we expect to
|
||||
048 But we are *just not having that*, because otherwise we're flying blind.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
049 handle.
|
||||
049 We *shall* reject objects lacking at least `:type`. Missing `:id` keys are
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
050
|
||||
050 tolerable because they represent transient objects, which we expect to
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
051 **NOTE THAT** The ActivityPub spec [says](https://www.w3.org/TR/activitypub/#obj)
|
||||
051 handle.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
052
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
053 > Implementers SHOULD include the ActivityPub context in their object
|
||||
053 **NOTE THAT** The ActivityPub spec [says](https://www.w3.org/TR/activitypub/#obj)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
054 > definitions
|
||||
054
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
055
|
||||
055 > Implementers SHOULD include the ActivityPub context in their object
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
056 but in samples found in the wild they typically don't."
|
||||
056 > definitions
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
057 ([x]
|
||||
057
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
058 but in samples found in the wild they typically don't."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
059 ([x]
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
058 (object? x *reject-severity*))
|
||||
060 (object? x *reject-severity*))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
059 ([x severity]
|
||||
061 ([x severity]
|
||||
</span><br/>
|
||||
<span class="covered" title="8 out of 8 forms covered">
|
||||
060 (empty? (filter-severity (object-faults x) severity))))
|
||||
062 (empty? (filter-severity (object-faults x) severity))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
061
|
||||
063
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
062 (defn persistent-object?
|
||||
064 (defn persistent-object?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
063 "`true` iff `x` is a persistent object.
|
||||
065 "`true` iff `x` is a persistent object.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
064
|
||||
066
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
065 Transient objects in ActivityPub are not required to have an `id` key, but persistent
|
||||
067 Transient objects in ActivityPub are not required to have an `id` key, but persistent
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
066 ones must have a key, and it must be an IRI (but normally a URI)."
|
||||
068 ones must have a key, and it must be an IRI (but normally a URI)."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
067 ([x]
|
||||
069 ([x]
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
068 (persistent-object? x *reject-severity*))
|
||||
070 (persistent-object? x *reject-severity*))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
069 ([x severity]
|
||||
071 ([x severity]
|
||||
</span><br/>
|
||||
<span class="covered" title="8 out of 8 forms covered">
|
||||
070 (empty? (filter-severity (persistent-object-faults x) severity))))
|
||||
072 (empty? (filter-severity (persistent-object-faults x) severity))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
071
|
||||
073
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
072 (defn actor?
|
||||
074 (defn actor?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
073 "Returns `true` if `x` quacks like an actor, else false."
|
||||
075 "Returns `true` if `x` quacks like an actor, else false."
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
074 ([x] (actor? x *reject-severity*))
|
||||
076 ([x] (actor? x *reject-severity*))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
075 ([x severity]
|
||||
077 ([x severity]
|
||||
</span><br/>
|
||||
<span class="covered" title="8 out of 8 forms covered">
|
||||
076 (empty? (filter-severity (actor-faults x) severity))))
|
||||
078 (empty? (filter-severity (actor-faults x) severity))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
077
|
||||
079
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
078 (defn actor-or-uri?
|
||||
080 (defn actor-or-uri?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
079 "`true` if `x` is either a URI or an actor.
|
||||
081 "`true` if `x` is either a URI or an actor.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
080
|
||||
082
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
081 **TODO**: I need to decide about whether to reify referenced objects
|
||||
083 **TODO**: I need to decide about whether to reify referenced objects
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
082 before validation or after. After reification, every reference to an actor
|
||||
084 before validation or after. After reification, every reference to an actor
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
083 *must be* to an actor object, but before, may only be to a URI pointing to
|
||||
085 *must be* to an actor object, but before, may only be to a URI pointing to
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
084 one."
|
||||
086 one."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
085 [x]
|
||||
087 [x]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
086 (try
|
||||
088 (try
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
087 (and
|
||||
089 (and
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 9 forms covered">
|
||||
088 (cond (string? x) (uri? (URI. x))
|
||||
090 (cond (string? x) (uri? (URI. x))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
089 :else (actor? x))
|
||||
091 :else (actor? x))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
090 true)
|
||||
092 true)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
091 (catch URISyntaxException _ false)
|
||||
093 (catch URISyntaxException _ false)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
092 (catch NullPointerException _ false)))
|
||||
094 (catch NullPointerException _ false)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
093
|
||||
095
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
094 (defn activity?
|
||||
096 (defn activity?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
095 "`true` iff `x` quacks like an activity, else false."
|
||||
097 "`true` iff `x` quacks like an activity, else false."
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
096 ([x] (activity? x *reject-severity*))
|
||||
098 ([x] (activity? x *reject-severity*))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
097 ([x severity]
|
||||
099 ([x severity]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 8 forms covered">
|
||||
098 (empty? (filter-severity (activity-faults x) severity))))
|
||||
100 (empty? (filter-severity (activity-faults x) severity))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
099
|
||||
101
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
100 (defn link?
|
||||
102 (defn link?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
101 "`true` iff `x` quacks like a link, else false."
|
||||
103 "`true` iff `x` quacks like a link, else false."
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
102 ([x] (link? x *reject-severity*))
|
||||
104 ([x] (link? x *reject-severity*))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
103 ([x severity]
|
||||
105 ([x severity]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 8 forms covered">
|
||||
104 (empty? (filter-severity (link-faults x) severity))))
|
||||
106 (empty? (filter-severity (link-faults x) severity))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
105
|
||||
107
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
106 (defn link-or-uri?
|
||||
108 (defn link-or-uri?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
107 "`true` iff `x` is either a URI or a link, else false.
|
||||
109 "`true` iff `x` is either a URI or a link, else false.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
108
|
||||
110
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
109 There are several points in the specification where e.g. the `:image`
|
||||
111 There are several points in the specification where e.g. the `:image`
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
110 property (if present) may be either a link or a URI."
|
||||
112 property (if present) may be either a link or a URI."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
111 [x]
|
||||
113 [x]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
112 (and
|
||||
114 (and
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 9 forms covered">
|
||||
113 (cond (string? x) (uri? (URI. x))
|
||||
115 (cond (string? x) (uri? (URI. x))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
114 :else (link? x))
|
||||
116 :else (link? x))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
115 true))
|
||||
117 true))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
116
|
||||
118
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
117 (defn collection?
|
||||
119 (defn collection?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
118 "`true` iff `x` quacks like a collection of type `object-type`, else `false`.
|
||||
120 "`true` iff `x` quacks like a collection of type `object-type`, else `false`.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
119
|
||||
121
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
120 With one argument, will recognise plain collections and ordered collections,
|
||||
122 With one argument, will recognise plain collections and ordered collections,
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
121 but (currently) not collection pages."
|
||||
123 but (currently) not collection pages."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
122 ([x ^String object-type]
|
||||
124 ([x ^String object-type]
|
||||
</span><br/>
|
||||
<span class="partial" title="10 out of 11 forms covered">
|
||||
123 (let [items (or (:items x) (:orderedItems x))]
|
||||
125 (let [items (or (:items x) (:orderedItems x))]
|
||||
</span><br/>
|
||||
<span class="partial" title="14 out of 17 forms covered">
|
||||
124 (and
|
||||
126 (and
|
||||
</span><br/>
|
||||
<span class="partial" title="5 out of 6 forms covered">
|
||||
125 (cond
|
||||
127 (cond
|
||||
</span><br/>
|
||||
<span class="partial" title="3 out of 8 forms covered">
|
||||
126 (:items x) (nil? (:orderedItems x))
|
||||
128 (:items x) (nil? (:orderedItems x))
|
||||
</span><br/>
|
||||
<span class="covered" title="8 out of 8 forms covered">
|
||||
127 (:orderedItems x) (nil? (:items x)) ;; can't have both properties
|
||||
129 (:orderedItems x) (nil? (:items x)) ;; can't have both properties
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
128 (integer? (:totalItems x)) true ;; can have neither, provided it has totalItems.
|
||||
130 (integer? (:totalItems x)) true ;; can have neither, provided it has totalItems.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
129 :else false)
|
||||
131 :else false)
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
130 (object? x)
|
||||
132 (object? x)
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
131 (= (:type x) object-type)
|
||||
133 (= (:type x) object-type)
|
||||
</span><br/>
|
||||
<span class="partial" title="2 out of 3 forms covered">
|
||||
132 (if items
|
||||
134 (if items
|
||||
</span><br/>
|
||||
<span class="partial" title="10 out of 12 forms covered">
|
||||
133 (and (coll? items)
|
||||
135 (and (coll? items)
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
134 (every? object? items) ;; if there are items, they must form a
|
||||
136 (every? object? items) ;; if there are items, they must form a
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
135 ;; collection of objects.
|
||||
137 ;; collection of objects.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
136 true)
|
||||
138 true)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
137 true) ;; but it's OK if there aren't.
|
||||
139 true) ;; but it's OK if there aren't.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
138 true)
|
||||
140 true)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
139 ;; test for totalItems not done here, because collection pages don't
|
||||
141 ;; test for totalItems not done here, because collection pages don't
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
140 ;; have it.
|
||||
142 ;; have it.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
141 ))
|
||||
143 ))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
142 ([x]
|
||||
144 ([x]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 9 forms covered">
|
||||
143 (and
|
||||
145 (and
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 10 forms covered">
|
||||
144 (or (collection? x "Collection")
|
||||
146 (or (collection? x "Collection")
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
145 (collection? x "OrderedCollection"))
|
||||
147 (collection? x "OrderedCollection"))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
146 (integer? (:totalItems x))
|
||||
148 (integer? (:totalItems x))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
147 true)))
|
||||
149 true)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
148
|
||||
150
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
149 (defn unordered-collection?
|
||||
151 (defn unordered-collection?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
150 "`true` iff `x` quacks like an unordered collection, else `false`."
|
||||
152 "`true` iff `x` quacks like an unordered collection, else `false`."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
151 [x]
|
||||
153 [x]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 18 forms covered">
|
||||
152 (and (collection? x "Collection") (integer? (:totalItems x)) true))
|
||||
154 (and (collection? x "Collection") (integer? (:totalItems x)) true))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
153
|
||||
155
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
154 (defn ordered-collection?
|
||||
156 (defn ordered-collection?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
155 "`true` iff `x` quacks like an ordered collection, else `false`."
|
||||
157 "`true` iff `x` quacks like an ordered collection, else `false`."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
156 [x]
|
||||
158 [x]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 18 forms covered">
|
||||
157 (and (collection? x "OrderedCollection") (integer? (:totalItems x)) true))
|
||||
159 (and (collection? x "OrderedCollection") (integer? (:totalItems x)) true))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
158
|
||||
160
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
159 (defn collection-page?
|
||||
161 (defn collection-page?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
160 "`true` iff `x` quacks like a page in a paged collection, else `false`."
|
||||
162 "`true` iff `x` quacks like a page in a paged collection, else `false`."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
161 [x]
|
||||
163 [x]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
162 (collection? x "CollectionPage"))
|
||||
164 (collection? x "CollectionPage"))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
163
|
||||
165
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
164 (defn ordered-collection-page?
|
||||
166 (defn ordered-collection-page?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
165 "`true` iff `x` quacks like a page in an ordered paged collection, else `false`."
|
||||
167 "`true` iff `x` quacks like a page in an ordered paged collection, else `false`."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
166 [x]
|
||||
168 [x]
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
167 (collection? x "OrderedCollectionPage"))
|
||||
169 (collection? x "OrderedCollectionPage"))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
168
|
||||
170
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
169
|
||||
171
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -8,10 +8,10 @@
|
|||
001 (ns dog-and-duck.scratch.parser
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
002 (:require [clojure.java.io :refer [file]]
|
||||
002 (:require ;; [clojure.java.io :refer [file]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
003 [clojure.string :refer [ends-with?]]
|
||||
003 ;; [clojure.string :refer [ends-with?]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
004 [clojure.walk :refer [keywordize-keys]]
|
||||
|
@ -109,41 +109,41 @@
|
|||
<span class="blank" title="0 out of 0 forms covered">
|
||||
035
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
036 (clean (slurp "resources/activitystreams-test-documents/core-ex1-jsonld.json"))
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
036 ;; (clean (slurp "resources/activitystreams-test-documents/core-ex1-jsonld.json"))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
037
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
038 (map
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
038 ;; (map
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
039 #(when
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
039 ;; #(when
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
040 (ends-with? (str %) ".json")
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
040 ;; (ends-with? (str %) ".json")
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
041 (let [objects (clean (slurp %))]
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
041 ;; (let [objects (clean (slurp %))]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
042 (list (str %)
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
042 ;; (list (str %)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
043 (count objects)
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
043 ;; (count objects)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
044 (map :type objects))))
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
044 ;; (map :type objects))))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
045 (file-seq (file "resources/activitystreams-test-documents")))
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
045 ;; (file-seq (file "resources/activitystreams-test-documents")))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
046
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
047 (-> "resources/activitystreams-test-documents/simple0020.json" slurp clean first :actor)
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
047 ;; (-> "resources/activitystreams-test-documents/simple0020.json" slurp clean first :actor)
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -94,32 +94,97 @@
|
|||
<td class="with-number">35</td><td class="with-number">5</td><td class="with-number">18</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="dog_and_duck/quack/fault_messages.clj.html">dog-and-duck.quack.fault-messages</a></td><td class="with-bar"><div class="covered"
|
||||
<td><a href="dog_and_duck/quack/picky.clj.html">dog-and-duck.quack.picky</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:41.6256157635468%;
|
||||
float:left;"> 169 </div><div class="not-covered"
|
||||
style="width:58.3743842364532%;
|
||||
float:left;"> 237 </div></td>
|
||||
<td class="with-number">41.63 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:58.55855855855856%;
|
||||
float:left;"> 65 </div><div class="partial"
|
||||
style="width:2.7027027027027026%;
|
||||
float:left;"> 3 </div><div class="not-covered"
|
||||
style="width:38.73873873873874%;
|
||||
float:left;"> 43 </div></td>
|
||||
<td class="with-number">61.26 %</td>
|
||||
<td class="with-number">251</td><td class="with-number">15</td><td class="with-number">111</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="dog_and_duck/quack/picky/collections.clj.html">dog-and-duck.quack.picky.collections</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:3.007518796992481%;
|
||||
float:left;"> 4 </div><div class="not-covered"
|
||||
style="width:96.99248120300751%;
|
||||
float:left;"> 129 </div></td>
|
||||
<td class="with-number">3.01 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:16.666666666666668%;
|
||||
float:left;"> 4 </div><div class="not-covered"
|
||||
style="width:83.33333333333333%;
|
||||
float:left;"> 20 </div></td>
|
||||
<td class="with-number">16.67 %</td>
|
||||
<td class="with-number">57</td><td class="with-number">8</td><td class="with-number">24</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="dog_and_duck/quack/picky/constants.clj.html">dog-and-duck.quack.picky.constants</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:100.0%;
|
||||
float:left;"> 25 </div></td>
|
||||
float:left;"> 73 </div></td>
|
||||
<td class="with-number">100.00 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:100.0%;
|
||||
float:left;"> 18 </div></td>
|
||||
<td class="with-number">100.00 %</td>
|
||||
<td class="with-number">79</td><td class="with-number">12</td><td class="with-number">18</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="dog_and_duck/quack/picky/control_variables.clj.html">dog-and-duck.quack.picky.control-variables</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:100.0%;
|
||||
float:left;"> 5 </div></td>
|
||||
<td class="with-number">100.00 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:100.0%;
|
||||
float:left;"> 3 </div></td>
|
||||
<td class="with-number">100.00 %</td>
|
||||
<td class="with-number">31</td><td class="with-number">5</td><td class="with-number">3</td>
|
||||
<td class="with-number">49</td><td class="with-number">6</td><td class="with-number">3</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="dog_and_duck/quack/picky.clj.html">dog-and-duck.quack.picky</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:53.432642487046635%;
|
||||
float:left;"> 825 </div><div class="not-covered"
|
||||
style="width:46.567357512953365%;
|
||||
float:left;"> 719 </div></td>
|
||||
<td class="with-number">53.43 %</td>
|
||||
<td><a href="dog_and_duck/quack/picky/fault_messages.clj.html">dog-and-duck.quack.picky.fault-messages</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:100.0%;
|
||||
float:left;"> 29 </div></td>
|
||||
<td class="with-number">100.00 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:53.57142857142857%;
|
||||
float:left;"> 135 </div><div class="partial"
|
||||
style="width:5.158730158730159%;
|
||||
float:left;"> 13 </div><div class="not-covered"
|
||||
style="width:41.26984126984127%;
|
||||
float:left;"> 104 </div></td>
|
||||
<td class="with-number">58.73 %</td>
|
||||
<td class="with-number">547</td><td class="with-number">41</td><td class="with-number">252</td>
|
||||
style="width:100.0%;
|
||||
float:left;"> 3 </div></td>
|
||||
<td class="with-number">100.00 %</td>
|
||||
<td class="with-number">35</td><td class="with-number">5</td><td class="with-number">3</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="dog_and_duck/quack/picky/required_properties.clj.html">dog-and-duck.quack.picky.required-properties</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:100.0%;
|
||||
float:left;"> 1 </div></td>
|
||||
<td class="with-number">100.00 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:100.0%;
|
||||
float:left;"> 1 </div></td>
|
||||
<td class="with-number">100.00 %</td>
|
||||
<td class="with-number">1</td><td class="with-number">0</td><td class="with-number">1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="dog_and_duck/quack/picky/utils.clj.html">dog-and-duck.quack.picky.utils</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:49.94786235662148%;
|
||||
float:left;"> 479 </div><div class="not-covered"
|
||||
style="width:50.05213764337852%;
|
||||
float:left;"> 480 </div></td>
|
||||
<td class="with-number">49.95 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:38.775510204081634%;
|
||||
float:left;"> 57 </div><div class="partial"
|
||||
style="width:6.122448979591836%;
|
||||
float:left;"> 9 </div><div class="not-covered"
|
||||
style="width:55.10204081632653%;
|
||||
float:left;"> 81 </div></td>
|
||||
<td class="with-number">44.90 %</td>
|
||||
<td class="with-number">319</td><td class="with-number">30</td><td class="with-number">147</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="dog_and_duck/quack/quack.clj.html">dog-and-duck.quack.quack</a></td><td class="with-bar"><div class="covered"
|
||||
|
@ -136,7 +201,7 @@
|
|||
style="width:36.734693877551024%;
|
||||
float:left;"> 18 </div></td>
|
||||
<td class="with-number">63.27 %</td>
|
||||
<td class="with-number">169</td><td class="with-number">21</td><td class="with-number">49</td>
|
||||
<td class="with-number">171</td><td class="with-number">21</td><td class="with-number">49</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="dog_and_duck/scratch/core.clj.html">dog-and-duck.scratch.core</a></td><td class="with-bar"><div class="covered"
|
||||
|
@ -155,20 +220,20 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td><a href="dog_and_duck/scratch/parser.clj.html">dog-and-duck.scratch.parser</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:55.84415584415584%;
|
||||
float:left;"> 43 </div><div class="not-covered"
|
||||
style="width:44.15584415584416%;
|
||||
float:left;"> 34 </div></td>
|
||||
<td class="with-number">55.84 %</td>
|
||||
style="width:70.0%;
|
||||
float:left;"> 21 </div><div class="not-covered"
|
||||
style="width:30.0%;
|
||||
float:left;"> 9 </div></td>
|
||||
<td class="with-number">70.00 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:57.89473684210526%;
|
||||
float:left;"> 11 </div><div class="partial"
|
||||
style="width:5.2631578947368425%;
|
||||
style="width:77.77777777777777%;
|
||||
float:left;"> 7 </div><div class="partial"
|
||||
style="width:11.11111111111111%;
|
||||
float:left;"> 1 </div><div class="not-covered"
|
||||
style="width:36.8421052631579%;
|
||||
float:left;"> 7 </div></td>
|
||||
<td class="with-number">63.16 %</td>
|
||||
<td class="with-number">47</td><td class="with-number">8</td><td class="with-number">19</td>
|
||||
style="width:11.11111111111111%;
|
||||
float:left;"> 1 </div></td>
|
||||
<td class="with-number">88.89 %</td>
|
||||
<td class="with-number">47</td><td class="with-number">8</td><td class="with-number">9</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="dog_and_duck/scratch/scratch.clj.html">dog-and-duck.scratch.scratch</a></td><td class="with-bar"><div class="covered"
|
||||
|
@ -198,9 +263,9 @@
|
|||
</tr>
|
||||
<tr><td>Totals:</td>
|
||||
<td class="with-bar"></td>
|
||||
<td class="with-number">54.39 %</td>
|
||||
<td class="with-number">50.34 %</td>
|
||||
<td class="with-bar"></td>
|
||||
<td class="with-number">60.38 %</td>
|
||||
<td class="with-number">57.34 %</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
3
docs/codox/dog-and-duck.quack.picky.collections.html
Normal file
3
docs/codox/dog-and-duck.quack.picky.collections.html
Normal file
File diff suppressed because one or more lines are too long
12
docs/codox/dog-and-duck.quack.picky.constants.html
Normal file
12
docs/codox/dog-and-duck.quack.picky.constants.html
Normal file
File diff suppressed because one or more lines are too long
12
docs/codox/dog-and-duck.quack.picky.control-variables.html
Normal file
12
docs/codox/dog-and-duck.quack.picky.control-variables.html
Normal file
File diff suppressed because one or more lines are too long
3
docs/codox/dog-and-duck.quack.picky.fault-messages.html
Normal file
3
docs/codox/dog-and-duck.quack.picky.fault-messages.html
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
17
docs/codox/dog-and-duck.quack.picky.utils.html
Normal file
17
docs/codox/dog-and-duck.quack.picky.utils.html
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -27,18 +27,20 @@
|
|||
possible to serialise a fault report as a
|
||||
document which in its own right conforms to the
|
||||
ActivityStreams spec."
|
||||
(:require [dog-and-duck.quack.picky.constants :refer [actor-types]]
|
||||
[dog-and-duck.quack.picky.control-variables :refer [*reify-refs*]]
|
||||
(:require [dog-and-duck.quack.picky.collections :refer [collection-page-faults
|
||||
paged-collection-faults
|
||||
simple-collection-faults]]
|
||||
[dog-and-duck.quack.picky.constants :refer [actor-types]]
|
||||
[dog-and-duck.quack.picky.utils :refer [any-or-faults
|
||||
coll-object-reference-or-fault
|
||||
concat-non-empty
|
||||
cond-make-fault-object
|
||||
has-context?
|
||||
has-activity-type?
|
||||
has-actor-type? has-type?
|
||||
has-type-or-fault
|
||||
make-fault-object
|
||||
nil-if-empty]]
|
||||
[clojure.data.json :as json])
|
||||
object-faults
|
||||
object-reference-or-faults
|
||||
string-or-fault]])
|
||||
(:import [java.net URI URISyntaxException]))
|
||||
|
||||
;;; Copyright (C) Simon Brooke, 2022
|
||||
|
@ -57,31 +59,6 @@
|
|||
;;; along with this program; if not, write to the Free Software
|
||||
;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
(defn object-faults
|
||||
"Return a list of faults found in object `x`, or `nil` if none are.
|
||||
|
||||
If `expected-type` is also passed, verify that `x` has `expected-type`.
|
||||
`expected-type` may be passed as a string or as a set of strings."
|
||||
([x]
|
||||
(nil-if-empty
|
||||
(remove empty?
|
||||
(list
|
||||
(when-not (map? x)
|
||||
(make-fault-object :critical :not-an-object))
|
||||
(when-not
|
||||
(has-context? x)
|
||||
(make-fault-object :should :no-context))
|
||||
(when-not (:type x)
|
||||
(make-fault-object :minor :no-type))
|
||||
(when-not (and (map? x) (contains? x :id))
|
||||
(make-fault-object :minor :no-id-transient))))))
|
||||
([x expected-type]
|
||||
(concat-non-empty
|
||||
(object-faults x)
|
||||
(when expected-type
|
||||
(list
|
||||
(has-type-or-fault x expected-type :critical :unexpected-type))))))
|
||||
|
||||
(defn uri-or-fault
|
||||
"If `u` is not a valid URI, return a fault object with this `severity` and
|
||||
`if-invalid-token`. If it's `nil`, return a fault object with this `severity`
|
||||
|
@ -132,82 +109,6 @@
|
|||
(uri-or-fault
|
||||
(:outbox x) :must :no-outbox :invalid-outbox-uri))))
|
||||
|
||||
(defn string-or-fault
|
||||
"If this `value` is not a string, return a fault object with this `severity`
|
||||
and `token`, else `nil`. If `pattern` is also passed, it is expected to be
|
||||
a Regex, and the fault object will be returned unless `value` matches the
|
||||
`pattern`."
|
||||
([value severity token]
|
||||
(when-not (string? value) (make-fault-object severity token)))
|
||||
([value severity token pattern]
|
||||
(when not (and (string? value) (re-matches pattern value))
|
||||
(make-fault-object severity token))))
|
||||
|
||||
(defn object-reference-or-faults
|
||||
"If this `value` is either
|
||||
|
||||
1. an object of `expected-type`;
|
||||
2. a URI referencing an object of `expected-type`; or
|
||||
3. a link object referencing an object of `expected-type`
|
||||
|
||||
and no faults are returned from validating the linked object, then return
|
||||
`nil`; else return a sequence comprising a fault object with this `severity`
|
||||
and `token`, prepended to the faults returned.
|
||||
|
||||
As with `has-type-or-fault` (q.v.), `expected-type` may be passed as a
|
||||
string, as a set of strings, or `nil` (indicating the type of the
|
||||
referenced object should not be checked).
|
||||
|
||||
**NOTE THAT** if `*reify-refs*` is `false`, referenced objects will not
|
||||
actually be checked."
|
||||
[value expected-type severity token]
|
||||
(let [faults (cond
|
||||
(string? value) (try (let [uri (URI. value)
|
||||
object (when *reify-refs*
|
||||
(json/read-str (slurp uri)))]
|
||||
(when object
|
||||
(object-faults object expected-type)))
|
||||
(catch URISyntaxException _
|
||||
(make-fault-object severity token)))
|
||||
(map? value) (if (has-type? value "Link")
|
||||
(cond
|
||||
;; if we were looking for a link and we've
|
||||
;; found a link, that's OK.
|
||||
(= expected-type "Link") nil
|
||||
(and (set? expected-type) (expected-type "Link")) nil
|
||||
(nil? expected-type) nil
|
||||
:else
|
||||
(object-reference-or-faults
|
||||
(:href value) expected-type severity token))
|
||||
(object-faults value expected-type))
|
||||
:else (throw
|
||||
(ex-info
|
||||
"Argument `value` was not an object or a link to an object"
|
||||
{:arguments {:value value}
|
||||
:expected-type expected-type
|
||||
:severity severity
|
||||
:token token})))]
|
||||
(when faults (cons (make-fault-object severity token) faults))))
|
||||
|
||||
(defn coll-object-reference-or-fault
|
||||
"As object-reference-or-fault, except `value` argument may also be a list of
|
||||
objects and/or object references."
|
||||
[value expected-type severity token]
|
||||
(cond
|
||||
(map? value) (object-reference-or-faults value expected-type severity token)
|
||||
(coll? value) (concat-non-empty
|
||||
(map
|
||||
#(object-reference-or-faults
|
||||
% expected-type severity token)
|
||||
value))
|
||||
:else (throw
|
||||
(ex-info
|
||||
"Argument `value` was not an object, a link to an object, nor a list of these."
|
||||
{:arguments {:value value}
|
||||
:expected-type expected-type
|
||||
:severity severity
|
||||
:token token}))))
|
||||
|
||||
(defn link-faults
|
||||
"A link object is required to have an `href` property. It may have all of
|
||||
`rel` | `mediaType` | `name` | `hreflang` | `height` | `width` | `preview`
|
||||
|
@ -313,41 +214,6 @@
|
|||
(make-fault-object :must :not-activity-type))
|
||||
(when-not (string? (:summary x)) (make-fault-object :should :no-summary)))))
|
||||
|
||||
(defn- paged-collection-faults
|
||||
"Return a list of faults found in `x` considered as a paged collection
|
||||
object of this sub-`type`, or `nil` if none are found."
|
||||
[x type]
|
||||
(concat-non-empty
|
||||
(object-faults x type)
|
||||
(list (object-reference-or-faults x type :critical :expected-collection)
|
||||
(cond-make-fault-object (integer? (:totalItems x)) :should :no-total-items)
|
||||
(object-reference-or-faults (:first x) nil :must :no-first-page)
|
||||
(object-reference-or-faults (:last x) nil :should :no-last-page))))
|
||||
|
||||
(defn- simple-collection-faults
|
||||
"Return a list of faults found in `x` considered as a non-paged collection
|
||||
object of this sub-`type`, or `nil` if none are found."
|
||||
[x type]
|
||||
(concat-non-empty
|
||||
(object-faults x type)
|
||||
(cons
|
||||
(list (object-reference-or-faults x type :critical :expected-collection)
|
||||
(cond-make-fault-object (integer? (:totalItems x)) :should :no-total-items)
|
||||
(cond-make-fault-object (coll? (:items x)) :must :no-items-collection))
|
||||
(map #(object-reference-or-faults % nil :must :not-object-reference) (:items x)))))
|
||||
|
||||
(defn- collection-page-faults
|
||||
[x type]
|
||||
(concat-non-empty
|
||||
(simple-collection-faults x type)
|
||||
(list
|
||||
(object-reference-or-faults (:partOf x)
|
||||
(apply str (drop-last 4 type))
|
||||
:should
|
||||
:n-part-of)
|
||||
(object-reference-or-faults (:next x) type :minor :no-next-page)
|
||||
(object-reference-or-faults (:prev x) type :minor :no-prev-page))))
|
||||
|
||||
(defn collection-faults
|
||||
"Return a list of faults found in the collection `x`; if `type` is also
|
||||
specified, it should be a string naming a specific collection type for
|
||||
|
@ -374,11 +240,12 @@
|
|||
"CollectionPage"
|
||||
"OrderedCollectionPage"])))))
|
||||
([x type]
|
||||
;; (log/info "collection-faults called with argumens " x ", " type)
|
||||
(case type
|
||||
["Collection" "OrderedCollection"] (any-or-faults
|
||||
("Collection" "OrderedCollection") (any-or-faults
|
||||
(list (simple-collection-faults x type)
|
||||
(paged-collection-faults x type))
|
||||
:must
|
||||
:no-items)
|
||||
["CollectionPage" "OrderedCollectionPage"] (collection-page-faults x type)
|
||||
("CollectionPage" "OrderedCollectionPage") (collection-page-faults x type)
|
||||
(list (make-fault-object :critical :expected-collection)))))
|
||||
|
|
57
src/dog_and_duck/quack/picky/collections.clj
Normal file
57
src/dog_and_duck/quack/picky/collections.clj
Normal file
|
@ -0,0 +1,57 @@
|
|||
(ns dog-and-duck.quack.picky.collections
|
||||
(:require [dog-and-duck.quack.picky.utils :refer [concat-non-empty
|
||||
cond-make-fault-object
|
||||
object-faults
|
||||
object-reference-or-faults]]))
|
||||
|
||||
|
||||
;;; Copyright (C) Simon Brooke, 2022
|
||||
|
||||
;;; This program is free software; you can redistribute it and/or
|
||||
;;; modify it under the terms of the GNU General Public License
|
||||
;;; as published by the Free Software Foundation; either version 2
|
||||
;;; of the License, or (at your option) any later version.
|
||||
|
||||
;;; This program is distributed in the hope that it will be useful,
|
||||
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;;; GNU General Public License for more details.
|
||||
|
||||
;;; You should have received a copy of the GNU General Public License
|
||||
;;; along with this program; if not, write to the Free Software
|
||||
;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
(defn paged-collection-faults
|
||||
"Return a list of faults found in `x` considered as a paged collection
|
||||
object of this sub-`type`, or `nil` if none are found."
|
||||
[x type]
|
||||
(concat-non-empty
|
||||
(object-faults x type)
|
||||
(list (object-reference-or-faults x type :critical :expected-collection)
|
||||
(cond-make-fault-object (integer? (:totalItems x)) :should :no-total-items)
|
||||
(object-reference-or-faults (:first x) nil :must :no-first-page)
|
||||
(object-reference-or-faults (:last x) nil :should :no-last-page))))
|
||||
|
||||
(defn simple-collection-faults
|
||||
"Return a list of faults found in `x` considered as a non-paged collection
|
||||
object of this sub-`type`, or `nil` if none are found."
|
||||
[x type]
|
||||
(concat-non-empty
|
||||
(object-faults x type)
|
||||
(cons
|
||||
(list (object-reference-or-faults x type :critical :expected-collection)
|
||||
(cond-make-fault-object (integer? (:totalItems x)) :should :no-total-items)
|
||||
(cond-make-fault-object (coll? (:items x)) :must :no-items-collection))
|
||||
(map #(object-reference-or-faults % nil :must :not-object-reference) (:items x)))))
|
||||
|
||||
(defn collection-page-faults
|
||||
[x type]
|
||||
(concat-non-empty
|
||||
(simple-collection-faults x type)
|
||||
(list
|
||||
(object-reference-or-faults (:partOf x)
|
||||
(apply str (drop-last 4 type))
|
||||
:should
|
||||
:n-part-of)
|
||||
(object-reference-or-faults (:next x) type :minor :no-next-page)
|
||||
(object-reference-or-faults (:prev x) type :minor :no-prev-page))))
|
|
@ -27,6 +27,7 @@
|
|||
:no-id-persistent "Persistent objects MUST have unique global identifiers."
|
||||
:no-id-transient "The ActivityPub specification allows objects without `id` fields only if they are intentionally transient; even so it is preferred that the object should have an explicit null id."
|
||||
:no-inbox "Actor objects MUST have an `inbox` property, whose value MUST be a reference to an ordered collection."
|
||||
:no-items-collection "A collection expected to be simple had no items."
|
||||
:no-outbox "Actor objects MUST have an `outbox` property, whose value MUST be a reference to an ordered collection."
|
||||
:no-type "The ActivityPub specification states that the `type` field is optional, but it is hard to process objects with no known type."
|
||||
:not-actor-type "The `type` value of the object was not a recognised actor type."
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
(ns dog-and-duck.quack.picky.required-properties)
|
|
@ -1,16 +1,16 @@
|
|||
(ns dog-and-duck.quack.picky.utils
|
||||
"Utility functions supporting the picky validator"
|
||||
(:require [clojure.set :refer [intersection]]
|
||||
(:require [clojure.data.json :as json]
|
||||
[clojure.set :refer [intersection]]
|
||||
[dog-and-duck.quack.picky.constants :refer [activitystreams-context-uri
|
||||
actor-types
|
||||
context-key severity-filters
|
||||
validation-fault-context-uri
|
||||
verb-types]]
|
||||
[dog-and-duck.quack.picky.control-variables :refer [*reify-refs*]]
|
||||
[dog-and-duck.quack.picky.fault-messages :refer [messages]]
|
||||
[dog-and-duck.utils.process :refer [get-hostname get-pid]]
|
||||
[taoensso.timbre :as timbre
|
||||
;; Optional, just refer what you like:
|
||||
:refer [warn]])
|
||||
[taoensso.timbre :as log :refer [warn]])
|
||||
|
||||
(:import [java.net URI URISyntaxException]))
|
||||
|
||||
|
@ -203,11 +203,117 @@
|
|||
there are several different valid configurations, but few or no properties
|
||||
are always required."
|
||||
[options severity-if-none token]
|
||||
(let [faults (remove empty? (reduce concat options))]
|
||||
(when-not (empty? faults) (cons (make-fault-object severity-if-none token) faults))))
|
||||
(let [faults (filter empty? options)]
|
||||
(when (empty? faults)
|
||||
;; i.e. there was at least one option that returned no faults...
|
||||
(cons (make-fault-object severity-if-none token) faults))))
|
||||
|
||||
(defmacro cond-make-fault-object
|
||||
"If `v` is `false` or `nil`, return a fault object with this `severity` and `token`,
|
||||
else return nil."
|
||||
[v severity token]
|
||||
`(when-not ~v (make-fault-object ~severity ~token)))
|
||||
|
||||
(defn string-or-fault
|
||||
"If this `value` is not a string, return a fault object with this `severity`
|
||||
and `token`, else `nil`. If `pattern` is also passed, it is expected to be
|
||||
a Regex, and the fault object will be returned unless `value` matches the
|
||||
`pattern`."
|
||||
([value severity token]
|
||||
(when-not (string? value) (make-fault-object severity token)))
|
||||
([value severity token pattern]
|
||||
(when not (and (string? value) (re-matches pattern value))
|
||||
(make-fault-object severity token))))
|
||||
|
||||
|
||||
(defn object-faults
|
||||
"Return a list of faults found in object `x`, or `nil` if none are.
|
||||
|
||||
If `expected-type` is also passed, verify that `x` has `expected-type`.
|
||||
`expected-type` may be passed as a string or as a set of strings. Detailed
|
||||
verification of the particular features of types is not done here."
|
||||
([x]
|
||||
(nil-if-empty
|
||||
(remove empty?
|
||||
(list
|
||||
(when-not (map? x)
|
||||
(make-fault-object :critical :not-an-object))
|
||||
(when-not
|
||||
(has-context? x)
|
||||
(make-fault-object :should :no-context))
|
||||
(when-not (:type x)
|
||||
(make-fault-object :minor :no-type))
|
||||
(when-not (and (map? x) (contains? x :id))
|
||||
(make-fault-object :minor :no-id-transient))))))
|
||||
([x expected-type]
|
||||
(concat-non-empty
|
||||
(object-faults x)
|
||||
(when expected-type
|
||||
(list
|
||||
(has-type-or-fault x expected-type :critical :unexpected-type))))))
|
||||
|
||||
|
||||
(defn object-reference-or-faults
|
||||
"If this `value` is either
|
||||
|
||||
1. an object of `expected-type`;
|
||||
2. a URI referencing an object of `expected-type`; or
|
||||
3. a link object referencing an object of `expected-type`
|
||||
|
||||
and no faults are returned from validating the linked object, then return
|
||||
`nil`; else return a sequence comprising a fault object with this `severity`
|
||||
and `token`, prepended to the faults returned.
|
||||
|
||||
As with `has-type-or-fault` (q.v.), `expected-type` may be passed as a
|
||||
string, as a set of strings, or `nil` (indicating the type of the
|
||||
referenced object should not be checked).
|
||||
|
||||
**NOTE THAT** if `*reify-refs*` is `false`, referenced objects will not
|
||||
actually be checked."
|
||||
[value expected-type severity token]
|
||||
(let [faults (cond
|
||||
(string? value) (try (let [uri (URI. value)
|
||||
object (when *reify-refs*
|
||||
(json/read-str (slurp uri)))]
|
||||
(when object
|
||||
(object-faults object expected-type)))
|
||||
(catch URISyntaxException _
|
||||
(make-fault-object severity token)))
|
||||
(map? value) (if (has-type? value "Link")
|
||||
(cond
|
||||
;; if we were looking for a link and we've
|
||||
;; found a link, that's OK.
|
||||
(= expected-type "Link") nil
|
||||
(and (set? expected-type) (expected-type "Link")) nil
|
||||
(nil? expected-type) nil
|
||||
:else
|
||||
(object-reference-or-faults
|
||||
(:href value) expected-type severity token))
|
||||
(object-faults value expected-type))
|
||||
:else (throw
|
||||
(ex-info
|
||||
"Argument `value` was not an object or a link to an object"
|
||||
{:arguments {:value value}
|
||||
:expected-type expected-type
|
||||
:severity severity
|
||||
:token token})))]
|
||||
(when faults (cons (make-fault-object severity token) faults))))
|
||||
|
||||
(defn coll-object-reference-or-fault
|
||||
"As object-reference-or-fault, except `value` argument may also be a list of
|
||||
objects and/or object references."
|
||||
[value expected-type severity token]
|
||||
(cond
|
||||
(map? value) (object-reference-or-faults value expected-type severity token)
|
||||
(coll? value) (concat-non-empty
|
||||
(map
|
||||
#(object-reference-or-faults
|
||||
% expected-type severity token)
|
||||
value))
|
||||
:else (throw
|
||||
(ex-info
|
||||
"Argument `value` was not an object, a link to an object, nor a list of these."
|
||||
{:arguments {:value value}
|
||||
:expected-type expected-type
|
||||
:severity severity
|
||||
:token token}))))
|
||||
|
|
|
@ -14,10 +14,10 @@
|
|||
toggle some checks off."
|
||||
|
||||
(:require [dog-and-duck.quack.picky :refer [activity-faults actor-faults
|
||||
link-faults object-faults
|
||||
link-faults
|
||||
persistent-object-faults]]
|
||||
[dog-and-duck.quack.picky.control-variables :refer [*reject-severity*]]
|
||||
[dog-and-duck.quack.picky.utils :refer [filter-severity]])
|
||||
[dog-and-duck.quack.picky.utils :refer [filter-severity object-faults]])
|
||||
|
||||
(:import [java.net URI URISyntaxException]))
|
||||
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
(ns dog-and-duck.quack.picky-test
|
||||
(:require [clojure.test :refer [deftest is testing]]
|
||||
[dog-and-duck.quack.picky.constants :refer [activitystreams-context-uri]]
|
||||
[dog-and-duck.quack.picky.utils :refer [filter-severity]]
|
||||
[dog-and-duck.quack.picky :refer [object-faults
|
||||
persistent-object-faults]]))
|
||||
[dog-and-duck.quack.picky.constants :refer
|
||||
[activitystreams-context-uri]]
|
||||
[dog-and-duck.quack.picky.utils :refer
|
||||
[filter-severity object-faults]]
|
||||
[dog-and-duck.quack.picky :refer
|
||||
[persistent-object-faults]]))
|
||||
|
||||
;;; Copyright (C) Simon Brooke, 2022
|
||||
|
||||
|
|
Loading…
Reference in a new issue