Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 22s
Facade read-by-id was top-level only while content/edit's update/delete are tree-wide — could not read back a nested block content/edit just modified. Added generic ct-find-id (doc.sx) + doc-find-deep/doc-has-deep?; content/find + has? now descend into sections. content/find-top/has-top? keep top-level lookup. Audit: remaining doc-find/ct-index-of callers are positional insert/move (top-level by design). +6 api tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
134 lines
4.1 KiB
Plaintext
134 lines
4.1 KiB
Plaintext
;; Phase 1 — public API facade. End-to-end through content/*.
|
|
|
|
(st-bootstrap-classes!)
|
|
(content/bootstrap!)
|
|
|
|
;; ── build a document via the facade ──
|
|
(define d0 (content/empty "post"))
|
|
(define
|
|
h
|
|
(content/block
|
|
"heading"
|
|
"h"
|
|
(list (list "level" 1) (list "text" "Hi"))))
|
|
(define p (content/block "text" "p" (list (list "text" "World"))))
|
|
(define d1 (content/append (content/append d0 h) p))
|
|
|
|
(content/op? (content/insert h nil))
|
|
(content-test "count" (content/count d1) 2)
|
|
(content-test "ids" (content/ids d1) (list "h" "p"))
|
|
(content-test "types" (content/types d1) (list "heading" "text"))
|
|
(content-test "find" (blk-id (content/find d1 "p")) "p")
|
|
(content-test "has? yes" (content/has? d1 "h") true)
|
|
(content-test "has? no" (content/has? d1 "x") false)
|
|
|
|
;; ── content/op? distinguishes a single op from a list / a block ──
|
|
(content-test "op? on insert" (content/op? (content/insert h nil)) true)
|
|
(content-test
|
|
"op? on update"
|
|
(content/op? (content/update "p" "text" "z"))
|
|
true)
|
|
(content-test "op? on list" (content/op? (list (content/delete "h"))) false)
|
|
(content-test "op? on block" (content/op? h) false)
|
|
(content-test "op? on doc" (content/op? d1) false)
|
|
|
|
;; ── edit with a single op ──
|
|
(define
|
|
img
|
|
(content/block
|
|
"image"
|
|
"img"
|
|
(list (list "src" "/c.png") (list "alt" "cat"))))
|
|
(define d2 (content/edit d1 (content/insert img "h")))
|
|
(content-test "edit single op order" (content/ids d2) (list "h" "img" "p"))
|
|
(content-test "edit single immutable" (content/ids d1) (list "h" "p"))
|
|
(content-test
|
|
"edit update"
|
|
(str
|
|
(blk-send
|
|
(content/find
|
|
(content/edit d1 (content/update "p" "text" "Edited"))
|
|
"p")
|
|
"text"))
|
|
"Edited")
|
|
(content-test
|
|
"edit delete"
|
|
(content/ids (content/edit d1 (content/delete "h")))
|
|
(list "p"))
|
|
(content-test
|
|
"edit move"
|
|
(content/ids (content/edit d1 (content/move "p" 0)))
|
|
(list "p" "h"))
|
|
|
|
;; ── edit with a stream of ops ──
|
|
(define ops (list (content/insert img "h") (content/delete "p")))
|
|
(content-test
|
|
"edit op stream"
|
|
(content/ids (content/edit d1 ops))
|
|
(list "h" "img"))
|
|
(content-test "edit op stream immutable" (content/ids d1) (list "h" "p"))
|
|
|
|
;; ── render via facade ──
|
|
(content-test
|
|
"render html"
|
|
(content/render d1 "html")
|
|
"<h1>Hi</h1><p>World</p>")
|
|
(content-test
|
|
"render sx"
|
|
(content/render d1 "sx")
|
|
"(article (h1 \"Hi\")(p \"World\"))")
|
|
(content-test
|
|
"render html keyword"
|
|
(content/render d1 :html)
|
|
"<h1>Hi</h1><p>World</p>")
|
|
(content-test
|
|
"render sx keyword"
|
|
(content/render d1 :sx)
|
|
"(article (h1 \"Hi\")(p \"World\"))")
|
|
(content-test "content/html" (content/html d1) "<h1>Hi</h1><p>World</p>")
|
|
(content-test "content/sx" (content/sx d1) "(article (h1 \"Hi\")(p \"World\"))")
|
|
|
|
;; ── render reflects each version ──
|
|
(content-test
|
|
"render edited version"
|
|
(content/render (content/edit d1 (content/update "h" "text" "Hey")) "html")
|
|
"<h1>Hey</h1><p>World</p>")
|
|
(content-test
|
|
"render original unchanged"
|
|
(content/render d1 "html")
|
|
"<h1>Hi</h1><p>World</p>")
|
|
|
|
;; ── facade find/has? are TREE-WIDE (reach into sections); find-top/has-top?
|
|
;; keep the top-level-only lookup. This makes the read-by-id surface consistent
|
|
;; with content/edit, whose update/delete are already tree-wide. ──
|
|
(content-bootstrap-section!)
|
|
(define
|
|
nd
|
|
(content/append
|
|
(content/empty "nested")
|
|
(mk-section
|
|
"sec"
|
|
(list (content/block "text" "inner" (list (list "text" "deep")))))))
|
|
(content-test
|
|
"find nested (deep)"
|
|
(blk-id (content/find nd "inner"))
|
|
"inner")
|
|
(content-test "has? nested (deep)" (content/has? nd "inner") true)
|
|
(content-test "find-top misses nested" (content/find-top nd "inner") nil)
|
|
(content-test "has-top? misses nested" (content/has-top? nd "inner") false)
|
|
(content-test
|
|
"find-top sees top-level"
|
|
(blk-id (content/find-top nd "sec"))
|
|
"sec")
|
|
;; a nested block updated by id via content/edit is now readable by id via
|
|
;; content/find (was impossible when find was top-level-only).
|
|
(content-test
|
|
"edit-then-find nested round-trip"
|
|
(str
|
|
(blk-send
|
|
(content/find
|
|
(content/edit nd (content/update "inner" "text" "edited"))
|
|
"inner")
|
|
"text"))
|
|
"edited")
|