At least one numerical check still breaking.
The command line: java -jar target/uberjar/quack-0.1.0-SNAPSHOT-standalone.jar -i ../dog-and-duck/resources/activitystreams-test-documents//vocabulary-ex190-jsonld.json -o docs/samples/vocabulary-ex190-jsonld.html -f html triggers the error.
This commit is contained in:
parent
440ea003e2
commit
4c4b517212
|
@ -12,7 +12,7 @@ Download from http://example.com/FIXME.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
```
|
```bash
|
||||||
java -jar target/dog-and-duck-0.1.0-standalone.jar -i resources/activitystreams-test-documents/vocabulary-ex10-jsonld.json -f html -o report.html -s info
|
java -jar target/dog-and-duck-0.1.0-standalone.jar -i resources/activitystreams-test-documents/vocabulary-ex10-jsonld.json -f html -o report.html -s info
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -27,14 +27,14 @@
|
||||||
:cli-help-reify "If set, reify objects referenced by URIs and check them."
|
:cli-help-reify "If set, reify objects referenced by URIs and check them."
|
||||||
:cli-help-severity "The minimum severity of faults to report."
|
:cli-help-severity "The minimum severity of faults to report."
|
||||||
:expected-collection "A collection was expected, but was not found."
|
:expected-collection "A collection was expected, but was not found."
|
||||||
:faults-found "The following faults were found"
|
:faults-found "faults were found"
|
||||||
:generated-on "Generated on"
|
:generated-on "Generated on"
|
||||||
:id-not-https "Publicly facing content SHOULD use HTTPS URIs"
|
:id-not-https "Publicly facing content SHOULD use HTTPS URIs"
|
||||||
:id-not-uri "identifiers must be publicly dereferencable URIs"
|
:id-not-uri "identifiers must be publicly dereferencable URIs"
|
||||||
:invalid-actor "The value of the `actor` property of an activity MUST be an instance of an Actor type"
|
:invalid-actor "The value of the `actor` property of an activity MUST be an instance of an Actor type"
|
||||||
:invalid-attachment "The value of the `attachment` property MUST be an instance of Object or of Link."
|
:invalid-attachment "The value of the `attachment` property MUST be an instance of Object or of Link."
|
||||||
:invalid-attribution "The value of the `attributedTo` property MUST be an instance of Object or of Link, or a sequence or collection of such."
|
:invalid-attribution "The value of the `attributedTo` property MUST be an instance of Object or of Link, or a sequence or collection of such."
|
||||||
:invalid-audience "The value of the `audience` property MUST be an instance of Object or of Link, or a sequence or collection of such."
|
:invalid-audience "The value of the `audience`, `cc` and `bcc` properties MUST be instances of Object or of Link, or sequences or collections of such."
|
||||||
:invalid-closed "The value of the `closed` property MUST be one of: 1. an Object; 2. an xsd:dateTime; 3. a boolean."
|
:invalid-closed "The value of the `closed` property MUST be one of: 1. an Object; 2. an xsd:dateTime; 3. a boolean."
|
||||||
:invalid-content "The value of the `content` property MUST be a string, optionally with embedded markup."
|
:invalid-content "The value of the `content` property MUST be a string, optionally with embedded markup."
|
||||||
:invalid-context "The value of the `context` property (NOTE: different from `@context` MUST be an instance of Object or of Link, or a sequence or collection of such.)"
|
:invalid-context "The value of the `context` property (NOTE: different from `@context` MUST be an instance of Object or of Link, or a sequence or collection of such.)"
|
||||||
|
@ -50,6 +50,7 @@
|
||||||
:invalid-origin "The value of the `origin` property MUST be an Object."
|
:invalid-origin "The value of the `origin` property MUST be an Object."
|
||||||
:invalid-part-of "The value of the `partOf` property of a CollectionPage MUST be an instance of a Collection or an OrderedCollection."
|
:invalid-part-of "The value of the `partOf` property of a CollectionPage MUST be an instance of a Collection or an OrderedCollection."
|
||||||
:invalid-prior-page "The value of the `prev` property of a CollectionPage MUST be an instance of a Collection or an OrderedCollection."
|
:invalid-prior-page "The value of the `prev` property of a CollectionPage MUST be an instance of a Collection or an OrderedCollection."
|
||||||
|
:missing-part-of "The `partOf` field of a CollectionPage was missing. It identifies the Collection to which a CollectionPage object's items belong."
|
||||||
:no-context "Section 3 of the ActivityPub specification states Implementers SHOULD include the ActivityPub context in their object definitions`."
|
:no-context "Section 3 of the ActivityPub specification states Implementers SHOULD include the ActivityPub context in their object definitions`."
|
||||||
:no-faults-found "No faults were found."
|
:no-faults-found "No faults were found."
|
||||||
:no-id-persistent "Persistent objects MUST have unique global identifiers."
|
:no-id-persistent "Persistent objects MUST have unique global identifiers."
|
||||||
|
@ -63,4 +64,5 @@
|
||||||
:null-id-persistent "Persistent objects MUST have non-null identifiers."
|
:null-id-persistent "Persistent objects MUST have non-null identifiers."
|
||||||
:not-an-object "ActivityStreams object must be JSON objects."
|
:not-an-object "ActivityStreams object must be JSON objects."
|
||||||
:text-analysed "Text analysed"
|
:text-analysed "Text analysed"
|
||||||
|
:the-following "The following"
|
||||||
:validation-report-for "Validation report for"}
|
:validation-report-for "Validation report for"}
|
|
@ -149,7 +149,9 @@
|
||||||
(java.time.LocalDateTime/now)
|
(java.time.LocalDateTime/now)
|
||||||
(get-message :by)
|
(get-message :by)
|
||||||
version]))]
|
version]))]
|
||||||
[:h2 (get-message :faults-found)]
|
[:h2 (join " " (list (get-message :the-following)
|
||||||
|
(count faults)
|
||||||
|
(get-message :faults-found)))]
|
||||||
(if-not
|
(if-not
|
||||||
(empty? faults)
|
(empty? faults)
|
||||||
(apply
|
(apply
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
(ns dog-and-duck.quack.objects
|
(ns dog-and-duck.quack.objects
|
||||||
(:require [clojure.data.json :as json]
|
(:require [clojure.data.json :as json]
|
||||||
[clojure.set :refer [union]]
|
[clojure.set :refer [union]]
|
||||||
|
[clojure.walk :refer [keywordize-keys]]
|
||||||
[dog-and-duck.quack.constants :refer [actor-types
|
[dog-and-duck.quack.constants :refer [actor-types
|
||||||
noun-types
|
noun-types
|
||||||
re-rfc5646]]
|
re-rfc5646]]
|
||||||
|
@ -59,7 +60,7 @@
|
||||||
(fn [target]
|
(fn [target]
|
||||||
(try (let [uri (URI. target)]
|
(try (let [uri (URI. target)]
|
||||||
(when *reify-refs*
|
(when *reify-refs*
|
||||||
(json/read-str (slurp uri))))
|
(keywordize-keys (json/read-str (slurp uri)))))
|
||||||
(catch URISyntaxException _
|
(catch URISyntaxException _
|
||||||
(warn "Reification target" target "was not a valid URI.")
|
(warn "Reification target" target "was not a valid URI.")
|
||||||
nil)
|
nil)
|
||||||
|
@ -94,28 +95,48 @@
|
||||||
|
|
||||||
**NOTE THAT** if `*reify-refs*` is `false`, referenced objects will not
|
**NOTE THAT** if `*reify-refs*` is `false`, referenced objects will not
|
||||||
actually be checked."
|
actually be checked."
|
||||||
[value expected-type severity token]
|
([value expected-type severity token]
|
||||||
(let [faults (cond
|
(let [faults (cond
|
||||||
(string? value) (maybe-reify-or-faults value severity token expected-type)
|
(string? value) (maybe-reify-or-faults value severity token expected-type)
|
||||||
(map? value) (if (has-type? value "Link")
|
(map? value) (if (has-type? value "Link")
|
||||||
(cond
|
(cond
|
||||||
;; if we were looking for a link and we've
|
;; if we were looking for a link and we've
|
||||||
;; found a link, that's OK.
|
;; found a link, that's OK.
|
||||||
(= expected-type "Link") nil
|
(= expected-type "Link") nil
|
||||||
(and (set? expected-type) (expected-type "Link")) nil
|
(and (set? expected-type) (expected-type "Link")) nil
|
||||||
(nil? expected-type) nil
|
(nil? expected-type) nil
|
||||||
:else
|
:else
|
||||||
(object-reference-or-faults
|
(object-reference-or-faults
|
||||||
(:href value) expected-type severity token))
|
(:href value) expected-type severity token))
|
||||||
(object-faults value expected-type))
|
(object-faults value expected-type))
|
||||||
:else (throw
|
:else (throw
|
||||||
(ex-info
|
(ex-info
|
||||||
"Argument `value` was not an object or a link to an object"
|
"Argument `value` was not an object or a link to an object"
|
||||||
{:arguments {:value value}
|
{:arguments {:value value}
|
||||||
:expected-type expected-type
|
:expected-type expected-type
|
||||||
:severity severity
|
:severity severity
|
||||||
:token token})))]
|
:token token})))]
|
||||||
(when faults (cons (make-fault-object severity token) faults))))
|
(when faults (cons (make-fault-object severity token) faults)))))
|
||||||
|
|
||||||
|
(defn coll-object-reference-or-faults
|
||||||
|
"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
|
||||||
|
(string? value) (maybe-reify-or-faults value expected-type severity token)
|
||||||
|
(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}))))
|
||||||
|
|
||||||
|
|
||||||
(def object-expected-properties
|
(def object-expected-properties
|
||||||
|
@ -148,7 +169,10 @@
|
||||||
:if-invalid [:must :invalid-actor]
|
:if-invalid [:must :invalid-actor]
|
||||||
:if-missing [:must :no-actor]
|
:if-missing [:must :no-actor]
|
||||||
:required has-activity-type?
|
:required has-activity-type?
|
||||||
:validator object-or-uri?}
|
:validator (fn [pv] (coll-object-reference-or-faults pv
|
||||||
|
actor-types
|
||||||
|
:must
|
||||||
|
:invalid-actor))}
|
||||||
:altitude {:functional false
|
:altitude {:functional false
|
||||||
:if-invalid [:must :invalid-number]
|
:if-invalid [:must :invalid-number]
|
||||||
:validator xsd-float?}
|
:validator xsd-float?}
|
||||||
|
@ -157,22 +181,30 @@
|
||||||
;; a Question should have a `:oneOf` or `:anyOf`, but at this layer
|
;; a Question should have a `:oneOf` or `:anyOf`, but at this layer
|
||||||
;; that's hard to check.
|
;; that's hard to check.
|
||||||
:if-invalid [:must :invalid-option]
|
:if-invalid [:must :invalid-option]
|
||||||
:validator object-or-uri?}
|
:validator (fn [pv] (coll-object-reference-or-faults pv nil
|
||||||
|
:must
|
||||||
|
:invalid-actor))}
|
||||||
:attachment {:functional false
|
:attachment {:functional false
|
||||||
:if-invalid [:must :invalid-attachment]
|
:if-invalid [:must :invalid-attachment]
|
||||||
:validator object-or-uri?}
|
:validator (fn [pv] (coll-object-reference-or-faults pv nil
|
||||||
|
:must
|
||||||
|
:invalid-attachment))}
|
||||||
:attributedTo {:functional false
|
:attributedTo {:functional false
|
||||||
:if-invalid [:must :invalid-attribution]
|
:if-invalid [:must :invalid-attribution]
|
||||||
:validator object-or-uri?}
|
:validator (fn [pv] (coll-object-reference-or-faults pv nil
|
||||||
|
:must
|
||||||
|
:invalid-attribution))}
|
||||||
:audience {:functional false
|
:audience {:functional false
|
||||||
:if-invalid [:must :invalid-audience]
|
:if-invalid [:must :invalid-audience]
|
||||||
:validator object-or-uri?}
|
:validator (fn [pv] (coll-object-reference-or-faults pv nil
|
||||||
|
:must
|
||||||
|
:invalid-audience))}
|
||||||
:bcc {:functional false
|
:bcc {:functional false
|
||||||
:if-invalid [:must :invalid-audience] ;; do we need a separate message for bcc, cc, etc?
|
:if-invalid [:must :invalid-audience] ;; do we need a separate message for bcc, cc, etc?
|
||||||
:validator object-or-uri?}
|
:validator (fn [pv] (coll-object-reference-or-faults pv nil :must :invalid-audience))}
|
||||||
:cc {:functional false
|
:cc {:functional false
|
||||||
:if-invalid [:must :invalid-audience] ;; do we need a separate message for bcc, cc, etc?
|
:if-invalid [:must :invalid-audience] ;; do we need a separate message for bcc, cc, etc?
|
||||||
:validator object-or-uri?}
|
:validator (fn [pv] (coll-object-reference-or-faults pv nil :must :invalid-audience))}
|
||||||
:closed {:functional false
|
:closed {:functional false
|
||||||
:if-invalid [:must :invalid-closed]
|
:if-invalid [:must :invalid-closed]
|
||||||
:validator (fn [pv] (truthy? (or (object-or-uri? pv)
|
:validator (fn [pv] (truthy? (or (object-or-uri? pv)
|
||||||
|
@ -183,7 +215,7 @@
|
||||||
:validator string?}
|
:validator string?}
|
||||||
:context {:functional false
|
:context {:functional false
|
||||||
:if-invalid [:must :invalid-context]
|
:if-invalid [:must :invalid-context]
|
||||||
:validator object-or-uri?}
|
:validator (fn [pv] (coll-object-reference-or-faults pv nil :must :invalid-context))}
|
||||||
:current {:functional true
|
:current {:functional true
|
||||||
:if-missing [:minor :paged-collection-no-current]
|
:if-missing [:minor :paged-collection-no-current]
|
||||||
:if-invalid [:must :paged-collection-invalid-current]
|
:if-invalid [:must :paged-collection-invalid-current]
|
||||||
|
@ -197,8 +229,11 @@
|
||||||
(or (has-type? x "Collection")
|
(or (has-type? x "Collection")
|
||||||
(has-type? x "OrderedCollection"))
|
(has-type? x "OrderedCollection"))
|
||||||
(:first x)))
|
(:first x)))
|
||||||
:validator (fn [pv] (object-or-uri? pv #{"CollectionPage"
|
:validator (fn [pv] (object-reference-or-faults pv
|
||||||
"OrderedCollectionPage"}))}
|
#{"CollectionPage"
|
||||||
|
"OrderedCollectionPage"}
|
||||||
|
:must
|
||||||
|
:paged-collection-invalid-current))}
|
||||||
:deleted {:functional true
|
:deleted {:functional true
|
||||||
:if-missing [:minor :tombstone-missing-deleted]
|
:if-missing [:minor :tombstone-missing-deleted]
|
||||||
:if-invalid [:must :invalid-deleted]
|
:if-invalid [:must :invalid-deleted]
|
||||||
|
@ -207,7 +242,9 @@
|
||||||
:describes {:functional true
|
:describes {:functional true
|
||||||
:required (fn [x] (has-type? x "Profile"))
|
:required (fn [x] (has-type? x "Profile"))
|
||||||
:if-invalid [:must :invalid-describes]
|
:if-invalid [:must :invalid-describes]
|
||||||
:validator object-or-uri?}
|
:validator (fn [pv] (object-reference-or-faults pv nil
|
||||||
|
:must
|
||||||
|
:invalid-describes))}
|
||||||
:duration {:functional false
|
:duration {:functional false
|
||||||
:if-invalid [:must :invalid-duration]
|
:if-invalid [:must :invalid-duration]
|
||||||
:validator xsd-duration?}
|
:validator xsd-duration?}
|
||||||
|
@ -227,8 +264,10 @@
|
||||||
(or (has-type? x "Collection")
|
(or (has-type? x "Collection")
|
||||||
(has-type? x "OrderedCollection"))
|
(has-type? x "OrderedCollection"))
|
||||||
(:last x)))
|
(:last x)))
|
||||||
:validator (fn [pv] (object-or-uri? pv #{"CollectionPage"
|
:validator (fn [pv] (object-reference-or-faults pv #{"CollectionPage"
|
||||||
"OrderedCollectionPage"}))}
|
"OrderedCollectionPage"}
|
||||||
|
:must
|
||||||
|
:paged-collection-invalid-first))}
|
||||||
:formerType {:functional false
|
:formerType {:functional false
|
||||||
:if-missing [:minor :tombstone-missing-former-type]
|
:if-missing [:minor :tombstone-missing-former-type]
|
||||||
:if-invalid [:must :invalid-former-type]
|
:if-invalid [:must :invalid-former-type]
|
||||||
|
@ -236,6 +275,7 @@
|
||||||
;; The narrative of the spec says this should be an `Object`,
|
;; The narrative of the spec says this should be an `Object`,
|
||||||
;; but in all the provided examples it's a string. Furthermore,
|
;; but in all the provided examples it's a string. Furthermore,
|
||||||
;; it seems it must name a known object type within the context.
|
;; it seems it must name a known object type within the context.
|
||||||
|
;; So TODO I'm assuming an error in the spec here.
|
||||||
:validator string?}
|
:validator string?}
|
||||||
:generator {:functional false
|
:generator {:functional false
|
||||||
:if-invalid [:must :invalid-generator]
|
:if-invalid [:must :invalid-generator]
|
||||||
|
@ -253,7 +293,9 @@
|
||||||
:if-invalid [:must :invalid-icon]
|
:if-invalid [:must :invalid-icon]
|
||||||
;; an icon is also expected to have a 1:1 aspect ratio, but that's
|
;; an icon is also expected to have a 1:1 aspect ratio, but that's
|
||||||
;; too much detail at this level of verification
|
;; too much detail at this level of verification
|
||||||
:validator (fn [pv] (object-or-uri? pv "Image"))}
|
:validator (fn [pv] (coll-object-reference-or-faults pv "Image"
|
||||||
|
:must
|
||||||
|
:invalid-icon))}
|
||||||
:id {:functional true
|
:id {:functional true
|
||||||
:if-missing [:minor :no-id-transient]
|
:if-missing [:minor :no-id-transient]
|
||||||
:if-invalid [:must :invalid-id]
|
:if-invalid [:must :invalid-id]
|
||||||
|
@ -261,13 +303,19 @@
|
||||||
(catch URISyntaxException _ false)))}
|
(catch URISyntaxException _ false)))}
|
||||||
:image {:functional false
|
:image {:functional false
|
||||||
:if-invalid [:must :invalid-image]
|
:if-invalid [:must :invalid-image]
|
||||||
:validator (fn [pv] (object-or-uri? pv "Image"))}
|
:validator (fn [pv] (coll-object-reference-or-faults pv "Image"
|
||||||
|
:must
|
||||||
|
:invalid-image))}
|
||||||
:inReplyTo {:functional false
|
:inReplyTo {:functional false
|
||||||
:if-invalid [:must :invalid-in-reply-to]
|
:if-invalid [:must :invalid-in-reply-to]
|
||||||
:validator (fn [pv] (object-or-uri? pv noun-types))}
|
:validator (fn [pv] (coll-object-reference-or-faults pv noun-types
|
||||||
|
:must
|
||||||
|
:invalid-in-reply-to))}
|
||||||
:instrument {:functional false
|
:instrument {:functional false
|
||||||
:if-invalid [:must :invalid-instrument]
|
:if-invalid [:must :invalid-instrument]
|
||||||
:validator object-or-uri?}
|
:validator (fn [pv] (coll-object-reference-or-faults pv nil
|
||||||
|
:must
|
||||||
|
:invalid-instrument))}
|
||||||
:items {:collection true
|
:items {:collection true
|
||||||
:functional false
|
:functional false
|
||||||
:if-invalid [:must :invalid-items]
|
:if-invalid [:must :invalid-items]
|
||||||
|
@ -298,8 +346,10 @@
|
||||||
(has-type? x #{"Collection"
|
(has-type? x #{"Collection"
|
||||||
"OrderedCollection"})
|
"OrderedCollection"})
|
||||||
(:first x))))
|
(:first x))))
|
||||||
:validator (fn [pv] (object-or-uri? pv #{"CollectionPage"
|
:validator (fn [pv] (object-reference-or-faults pv #{"CollectionPage"
|
||||||
"OrderedCollectionPage"}))}
|
"OrderedCollectionPage"}
|
||||||
|
:must
|
||||||
|
:paged-collection-invalid-last))}
|
||||||
:latitude {:functional true
|
:latitude {:functional true
|
||||||
:if-invalid [:must :invalid-latitude]
|
:if-invalid [:must :invalid-latitude]
|
||||||
;; The XSD spec says this is an IEEE 754-2008, and the IEEE
|
;; The XSD spec says this is an IEEE 754-2008, and the IEEE
|
||||||
|
@ -308,7 +358,9 @@
|
||||||
:validator xsd-float?}
|
:validator xsd-float?}
|
||||||
:location {:functional false
|
:location {:functional false
|
||||||
:if-invalid [:must :invalid-location]
|
:if-invalid [:must :invalid-location]
|
||||||
:validator (fn [pv] (object-or-uri? pv #{"Place"}))}
|
:validator (fn [pv] (coll-object-reference-or-faults pv #{"Place"}
|
||||||
|
:must
|
||||||
|
:invalid-location))}
|
||||||
:longitude {:functional true
|
:longitude {:functional true
|
||||||
:if-invalid [:must :invalid-longitude]
|
:if-invalid [:must :invalid-longitude]
|
||||||
:validator xsd-float?}
|
:validator xsd-float?}
|
||||||
|
@ -320,18 +372,25 @@
|
||||||
:validator string?}
|
:validator string?}
|
||||||
:next {:functional true
|
:next {:functional true
|
||||||
:if-invalid [:must :invalid-next-page]
|
:if-invalid [:must :invalid-next-page]
|
||||||
:validator (fn [pv] (object-or-uri? pv #{"CollectionPage"
|
:validator (fn [pv] (object-reference-or-faults pv #{"CollectionPage"
|
||||||
"OrderedCollectionPage"}))}
|
"OrderedCollectionPage"}
|
||||||
|
:must
|
||||||
|
:invalid-next-page))}
|
||||||
:object {:functional false
|
:object {:functional false
|
||||||
:if-invalid [:must :invalid-direct-object]
|
:if-invalid [:must :invalid-direct-object]
|
||||||
:validator object-or-uri?}
|
:validator (fn [pv]
|
||||||
|
(coll-object-reference-or-faults pv nil
|
||||||
|
:must
|
||||||
|
:invalid-direct-object))}
|
||||||
:oneOf {:collection true
|
:oneOf {:collection true
|
||||||
:functional false
|
:functional false
|
||||||
;; a Question should have a `:oneOf` ot `:anyOf`, but at this layer
|
;; a Question should have a `:oneOf` ot `:anyOf`, but at this layer
|
||||||
;; that's hard to check.
|
;; that's hard to check.
|
||||||
:if-invalid [:must :invalid-option]
|
:if-invalid [:must :invalid-option]
|
||||||
:validator object-or-uri?}
|
:validator (fn [pv]
|
||||||
|
(coll-object-reference-or-faults pv nil
|
||||||
|
:must
|
||||||
|
:invalid-option))}
|
||||||
:orderedItems {:collection true
|
:orderedItems {:collection true
|
||||||
:functional false
|
:functional false
|
||||||
:if-invalid [:must :invalid-items]
|
:if-invalid [:must :invalid-items]
|
||||||
|
@ -346,29 +405,34 @@
|
||||||
:validator (fn [pv] (and (coll? pv) (every? object-or-uri? pv)))}
|
:validator (fn [pv] (and (coll? pv) (every? object-or-uri? pv)))}
|
||||||
:origin {:functional false
|
:origin {:functional false
|
||||||
:if-invalid [:must :invalid-origin]
|
:if-invalid [:must :invalid-origin]
|
||||||
:validator object-or-uri?}
|
:validator (fn [pv] (coll-object-reference-or-faults pv nil :must :invalid-origin))}
|
||||||
:partOf {:functional true
|
:partOf {:functional true
|
||||||
:if-missing [:must :missing-part-of]
|
:if-missing [:must :missing-part-of]
|
||||||
:if-invalid [:must :invalid-part-of]
|
:if-invalid [:must :invalid-part-of]
|
||||||
:required (fn [x] (object-or-uri? x #{"CollectionPage"
|
:required object-or-uri?
|
||||||
"OrderedCollectionPage"}))
|
:validator (fn [pv] (object-reference-or-faults pv #{"Collection"
|
||||||
:validator (fn [pv] (object-or-uri? pv #{"Collection"
|
"OrderedCollection"}
|
||||||
"OrderedCollection"}))}
|
:must
|
||||||
|
:invalid-part-of))}
|
||||||
:prev {:functional true
|
:prev {:functional true
|
||||||
:if-invalid [:must :invalid-prior-page]
|
:if-invalid [:must :invalid-prior-page]
|
||||||
:validator (fn [pv] (object-or-uri? pv #{"CollectionPage"
|
:validator (fn [pv] (object-reference-or-faults pv #{"CollectionPage"
|
||||||
"OrderedCollectionPage"}))}
|
"OrderedCollectionPage"}
|
||||||
|
:must
|
||||||
|
:invalid-prior-page))}
|
||||||
:preview {:functional false
|
:preview {:functional false
|
||||||
:if-invalid [:must :invalid-preview]
|
:if-invalid [:must :invalid-preview]
|
||||||
;; probably likely to be an Image or Video, but that isn't stated.
|
;; probably likely to be an Image or Video, but that isn't stated.
|
||||||
:validator object-or-uri?}
|
:validator (fn [pv] (coll-object-reference-or-faults pv nil :must :invalid-preview))}
|
||||||
:published {:functional true
|
:published {:functional true
|
||||||
:if-invalid [:must :invalid-date-time]
|
:if-invalid [:must :invalid-date-time]
|
||||||
:validator xsd-date-time?}
|
:validator xsd-date-time?}
|
||||||
:replies {:functional true
|
:replies {:functional true
|
||||||
:if-invalid [:must :invalid-replies]
|
:if-invalid [:must :invalid-replies]
|
||||||
:validator (fn [pv] (object-or-uri? pv #{"Collection"
|
:validator (fn [pv] (object-reference-or-faults pv #{"Collection"
|
||||||
"OrderedCollection"}))}
|
"OrderedCollection"}
|
||||||
|
:must
|
||||||
|
:invalid-replies))}
|
||||||
:radius {:functional true
|
:radius {:functional true
|
||||||
:if-invalid [:must :invalid-positive-number]
|
:if-invalid [:must :invalid-positive-number]
|
||||||
:validator (fn [pv] (and (xsd-float? pv) (> pv 0)))}
|
:validator (fn [pv] (and (xsd-float? pv) (> pv 0)))}
|
||||||
|
@ -381,7 +445,10 @@
|
||||||
}
|
}
|
||||||
:result {:functional false
|
:result {:functional false
|
||||||
:if-invalid [:must :invalid-result]
|
:if-invalid [:must :invalid-result]
|
||||||
:validator object-or-uri?}
|
:validator (fn [pv]
|
||||||
|
(coll-object-reference-or-faults pv nil
|
||||||
|
:must
|
||||||
|
:invalid-result))}
|
||||||
:startIndex {:functional true
|
:startIndex {:functional true
|
||||||
:if-invalid [:must :invalid-start-index]
|
:if-invalid [:must :invalid-start-index]
|
||||||
:validator xsd-non-negative-integer?}
|
:validator xsd-non-negative-integer?}
|
||||||
|
@ -392,7 +459,9 @@
|
||||||
:if-invalid [:must :invalid-subject]
|
:if-invalid [:must :invalid-subject]
|
||||||
:if-missing [:minor :no-relationship-subject]
|
:if-missing [:minor :no-relationship-subject]
|
||||||
:required (fn [x] (has-type? x "Relationship"))
|
:required (fn [x] (has-type? x "Relationship"))
|
||||||
:validator object-or-uri?}
|
:validator (fn [pv] (object-reference-or-faults pv nil
|
||||||
|
:must
|
||||||
|
:invalid-subject))}
|
||||||
:summary {:functional false
|
:summary {:functional false
|
||||||
:if-invalid [:must :invalid-summary]
|
:if-invalid [:must :invalid-summary]
|
||||||
;; TODO: HTML formatting is allowed, but other forms of formatting
|
;; TODO: HTML formatting is allowed, but other forms of formatting
|
||||||
|
@ -400,13 +469,22 @@
|
||||||
:validator string?}
|
:validator string?}
|
||||||
:tag {:functional false
|
:tag {:functional false
|
||||||
:if-invalid [:must :invalid-tag]
|
:if-invalid [:must :invalid-tag]
|
||||||
:validator object-or-uri?}
|
:validator (fn [pv]
|
||||||
|
(coll-object-reference-or-faults pv nil
|
||||||
|
:must
|
||||||
|
:invalid-tag))}
|
||||||
:target {:functional false
|
:target {:functional false
|
||||||
:if-invalid [:must :invalid-target]
|
:if-invalid [:must :invalid-target]
|
||||||
:validator object-or-uri?}
|
:validator (fn [pv]
|
||||||
|
(coll-object-reference-or-faults pv nil
|
||||||
|
:must
|
||||||
|
:invalid-target))}
|
||||||
:to {:functional false
|
:to {:functional false
|
||||||
:if-invalid [:must :invalid-to]
|
:if-invalid [:must :invalid-to]
|
||||||
:validator (fn [pv] (object-or-uri? pv actor-types))}
|
:validator (fn [pv]
|
||||||
|
(coll-object-reference-or-faults pv actor-types
|
||||||
|
:must
|
||||||
|
:invalid-to))}
|
||||||
:totalItems {:functional true
|
:totalItems {:functional true
|
||||||
:if-invalid [:must :invalid-total-items]
|
:if-invalid [:must :invalid-total-items]
|
||||||
:validator xsd-non-negative-integer?}
|
:validator xsd-non-negative-integer?}
|
||||||
|
@ -434,7 +512,7 @@
|
||||||
"Check whether this `prop` of this `obj` is required with respect to
|
"Check whether this `prop` of this `obj` is required with respect to
|
||||||
this `clause`; if it is both required and missing, return a list of
|
this `clause`; if it is both required and missing, return a list of
|
||||||
one fault; else return `nil`."
|
one fault; else return `nil`."
|
||||||
[obj prop clause]
|
[obj prop clause]
|
||||||
(let [required (:required clause)
|
(let [required (:required clause)
|
||||||
[severity token] (:if-missing clause)]
|
[severity token] (:if-missing clause)]
|
||||||
(when required
|
(when required
|
||||||
|
@ -524,21 +602,3 @@
|
||||||
(list
|
(list
|
||||||
(has-type-or-fault x expected-type :critical :unexpected-type))))))
|
(has-type-or-fault x expected-type :critical :unexpected-type))))))
|
||||||
|
|
||||||
;; (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}))))
|
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
"Return `true` if `value` matches the pattern for an
|
"Return `true` if `value` matches the pattern for an
|
||||||
[xsd:nonNegativeInteger](https://www.w3.org/TR/xmlschema11-2/#nonNegativeInteger), else `false`"
|
[xsd:nonNegativeInteger](https://www.w3.org/TR/xmlschema11-2/#nonNegativeInteger), else `false`"
|
||||||
[x]
|
[x]
|
||||||
(and (integer? x)(>= x 0)))
|
(if (integer? x) (>= x 0) false))
|
||||||
|
|
||||||
(defn has-type?
|
(defn has-type?
|
||||||
"Return `true` if object `x` has a type in `acceptable`, else `false`.
|
"Return `true` if object `x` has a type in `acceptable`, else `false`.
|
||||||
|
@ -224,7 +224,7 @@
|
||||||
(coll? x)
|
(coll? x)
|
||||||
(seq x)
|
(seq x)
|
||||||
(every?
|
(every?
|
||||||
#(has-type? % "Fault") x)))
|
#(when (map? x)(has-type? % "Fault")) x)))
|
||||||
|
|
||||||
|
|
||||||
(defmacro nil-if-empty
|
(defmacro nil-if-empty
|
||||||
|
|
Loading…
Reference in a new issue