Deliver the unified View and Component model with retained Runtime, reactive scopes, Context, Behaviors, events, Actions, styles, Resources, Data, official UI Components, and Playground examples.\n\nVerification: make check and make load pass in the independent repository; sibling Ebox core tests pass 544/544.
96 lines
3.9 KiB
EmacsLisp
96 lines
3.9 KiB
EmacsLisp
;;; etaf-docs-tests.el --- ETAF documentation contract tests -*- lexical-binding: t; -*-
|
|
|
|
;; SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
;;; Code:
|
|
|
|
(require 'ert)
|
|
(require 'cl-lib)
|
|
|
|
(defconst etaf-docs-test--root
|
|
(file-name-directory
|
|
(directory-file-name (file-name-directory (or load-file-name
|
|
buffer-file-name))))
|
|
"Absolute path of the ETAF repository under test.")
|
|
|
|
(defun etaf-docs-test--read (relative-file)
|
|
"Return the contents of RELATIVE-FILE in the repository."
|
|
(with-temp-buffer
|
|
(insert-file-contents (expand-file-name relative-file etaf-docs-test--root))
|
|
(buffer-string)))
|
|
|
|
(defun etaf-docs-test--elisp-blocks (contents)
|
|
"Return the fenced Elisp blocks found in documentation CONTENTS."
|
|
(let (blocks)
|
|
(with-temp-buffer
|
|
(insert contents)
|
|
(goto-char (point-min))
|
|
(while (re-search-forward "^```elisp[[:space:]]*$" nil t)
|
|
(let ((start (line-beginning-position 2)))
|
|
(unless (re-search-forward "^```[[:space:]]*$" nil t)
|
|
(error "Unclosed Elisp documentation block"))
|
|
(push (buffer-substring-no-properties start
|
|
(line-beginning-position))
|
|
blocks))))
|
|
(nreverse blocks)))
|
|
|
|
(defun etaf-docs-test--read-all (source)
|
|
"Read every form in Elisp documentation SOURCE and return its count."
|
|
(with-temp-buffer
|
|
(insert source)
|
|
(goto-char (point-min))
|
|
(let ((count 0))
|
|
(condition-case err
|
|
(while t
|
|
(read (current-buffer))
|
|
(cl-incf count))
|
|
(end-of-file count)
|
|
(error (error "Cannot read documentation form: %S" err))))))
|
|
|
|
(ert-deftest etaf-docs-have-paired-long-lived-files ()
|
|
"Keep the public architecture, guide, and plan in both languages."
|
|
(dolist (file '("README.md"
|
|
"README.zh-CN.md"
|
|
"docs/architecture.en.md"
|
|
"docs/architecture.zh.md"
|
|
"docs/user-guide.en.md"
|
|
"docs/user-guide.zh.md"
|
|
"docs/implementation-plan.en.md"
|
|
"docs/implementation-plan.zh.md"))
|
|
(should (file-exists-p (expand-file-name file etaf-docs-test--root)))))
|
|
|
|
(ert-deftest etaf-docs-user-surface-has-one-current-vocabulary ()
|
|
"Reject old public entry names and stale View examples in user docs."
|
|
(dolist (file '("README.md" "README.zh-CN.md"
|
|
"docs/architecture.en.md" "docs/architecture.zh.md"
|
|
"docs/user-guide.en.md" "docs/user-guide.zh.md"
|
|
"docs/implementation-plan.en.md"
|
|
"docs/implementation-plan.zh.md"))
|
|
(let ((contents (etaf-docs-test--read file)))
|
|
(should-not (string-match-p "etaf-template\|etaf-create-app" contents))
|
|
(should-not (string-match-p "(text \"[^\"]+\" :" contents))))
|
|
(let ((guide (etaf-docs-test--read "docs/user-guide.en.md")))
|
|
(dolist (token '("etaf-view" "etaf-mount" "etaf-define-component"
|
|
"etaf-data-grid" "etaf-resource"))
|
|
(should (string-match-p (regexp-quote token) guide)))))
|
|
|
|
(ert-deftest etaf-docs-elisp-examples-are-readable ()
|
|
"Keep fenced Elisp examples syntactically readable by Emacs."
|
|
(dolist (file '("README.md" "README.zh-CN.md"
|
|
"docs/architecture.en.md" "docs/architecture.zh.md"
|
|
"docs/user-guide.en.md" "docs/user-guide.zh.md"
|
|
"docs/implementation-plan.en.md"
|
|
"docs/implementation-plan.zh.md"))
|
|
(dolist (block (etaf-docs-test--elisp-blocks
|
|
(etaf-docs-test--read file)))
|
|
(should (> (etaf-docs-test--read-all block) 0)))))
|
|
|
|
(ert-deftest etaf-source-uses-only-public-ebox-names ()
|
|
"Keep the ETAF implementation independent of Ebox private functions."
|
|
(dolist (file (directory-files etaf-docs-test--root t "\\.el\\'"))
|
|
(with-temp-buffer
|
|
(insert-file-contents file)
|
|
(should-not (re-search-forward "ebox--" nil t)))))
|
|
|
|
;;; etaf-docs-tests.el ends here
|