content: tree-aware validation (descends into sections) + 6 tests (416/416)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 30s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 30s
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
;; content-on-sx — document integrity validation.
|
||||
;;
|
||||
;; Guards imports, edits and federated input: checks each block's id and the
|
||||
;; required fields/types for its kind, plus document-level duplicate ids. Returns
|
||||
;; a list of issue dicts {:id :kind :detail}; an empty list means valid. Dispatch
|
||||
;; on block type is a validation-boundary concern, not core behaviour.
|
||||
;; Guards imports, edits and federated input: walks the whole block TREE (into
|
||||
;; nested sections) checking each block's id and required fields/types, plus
|
||||
;; tree-wide duplicate ids. Returns issue dicts {:id :kind :detail}; empty = ok.
|
||||
;; Tree detection is inline (class + st-iv-get) so this file needs no section.sx.
|
||||
;; Dispatch on block type is a validation-boundary concern, not core behaviour.
|
||||
;;
|
||||
;; Requires (loaded by harness): block.sx, doc.sx.
|
||||
|
||||
@@ -35,6 +36,30 @@
|
||||
|
||||
(define ct-uniq (fn (xs) (ct-uniq-loop xs (list))))
|
||||
|
||||
;; ── tree flatten (descends into CtSection children; guards malformed children) ──
|
||||
(define
|
||||
ct-section-block?
|
||||
(fn (b) (and (st-instance? b) (= (get b :class) "CtSection"))))
|
||||
(define
|
||||
ct-tree-blocks
|
||||
(fn
|
||||
(blocks)
|
||||
(if
|
||||
(= (len blocks) 0)
|
||||
(list)
|
||||
(let
|
||||
((b (first blocks)))
|
||||
(append
|
||||
(cons
|
||||
b
|
||||
(if
|
||||
(ct-section-block? b)
|
||||
(let
|
||||
((ch (st-iv-get b "children")))
|
||||
(if (list? ch) (ct-tree-blocks ch) (list)))
|
||||
(list)))
|
||||
(ct-tree-blocks (rest blocks)))))))
|
||||
|
||||
;; ── id checks ──
|
||||
(define
|
||||
content/-id-issues
|
||||
@@ -120,32 +145,36 @@
|
||||
id
|
||||
(list? (blk-get b "items"))
|
||||
"list items must be a list")))
|
||||
((= t "section")
|
||||
(ct-field-issue
|
||||
id
|
||||
(list? (blk-get b "children"))
|
||||
"section children must be a list"))
|
||||
(else (list (ct-issue id "type" (str "unknown block type: " t))))))))
|
||||
|
||||
(define
|
||||
content/-block-issues
|
||||
(fn (b) (append (content/-id-issues b) (content/-field-issues b))))
|
||||
|
||||
;; ── document-level: duplicate ids ──
|
||||
;; ── duplicate ids across the whole tree ──
|
||||
(define
|
||||
content/-dup-issues
|
||||
(fn
|
||||
(doc)
|
||||
(let
|
||||
((ids (doc-ids doc)))
|
||||
(map
|
||||
(fn (id) (ct-issue id "duplicate" (str "duplicate block id: " id)))
|
||||
(ct-uniq
|
||||
(filter (fn (id) (> (ct-count-in id ids) 1)) ids))))))
|
||||
(ids)
|
||||
(map
|
||||
(fn (id) (ct-issue id "duplicate" (str "duplicate block id: " id)))
|
||||
(ct-uniq (filter (fn (id) (> (ct-count-in id ids) 1)) ids)))))
|
||||
|
||||
;; ── public ──
|
||||
(define
|
||||
content/validate
|
||||
(fn
|
||||
(doc)
|
||||
(append
|
||||
(content/-dup-issues doc)
|
||||
(ct-flatmap content/-block-issues (doc-blocks doc)))))
|
||||
(let
|
||||
((all (ct-tree-blocks (doc-blocks doc))))
|
||||
(append
|
||||
(content/-dup-issues (map (fn (b) (blk-id b)) all))
|
||||
(ct-flatmap content/-block-issues all)))))
|
||||
|
||||
(define
|
||||
content/valid?
|
||||
|
||||
Reference in New Issue
Block a user