etaf/tests/etaf-resource-tests.el
Kinneyzhang 43b17192d9 feat: implement unified etaf architecture
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.
2026-08-05 02:56:13 +08:00

112 lines
3.9 KiB
EmacsLisp

;;; etaf-resource-tests.el --- ETAF Resource tests -*- lexical-binding: t; -*-
;; SPDX-License-Identifier: GPL-3.0-or-later
;;; Code:
(require 'ert)
(require 'etaf-resource)
(ert-deftest etaf-resource-loads-synchronous-value ()
"Expose successful loader output through the public Resource readers."
(let ((resource (etaf-resource (lambda () "ready") :name 'success-test)))
(unwind-protect
(progn
(should (eq 'success (etaf-resource-status resource)))
(should (equal "ready" (etaf-resource-value resource)))
(should-not (etaf-resource-error resource)))
(etaf-resource-dispose resource))))
(ert-deftest etaf-resource-captures-loader-error-state ()
"Capture synchronous loader failures without signaling them."
(let ((resource (etaf-resource (lambda () (error "boom"))
:name 'error-test)))
(unwind-protect
(progn
(should (eq 'error (etaf-resource-status resource)))
(should-not (etaf-resource-value resource))
(should (eq 'error (car (etaf-resource-error resource))))
(should (string-match-p "boom"
(cadr (etaf-resource-error resource)))))
(etaf-resource-dispose resource))))
(ert-deftest etaf-resource-reload-runs-cleanup-and-replaces-value ()
"Run loader cleanup on reload and disposal."
(let ((load-count 0)
(cleanup-count 0)
resource)
(setq resource
(etaf-resource
(lambda ()
(cl-incf load-count)
(etaf-resource-result
load-count
:cleanup (lambda () (cl-incf cleanup-count))))
:name 'reload-test))
(unwind-protect
(progn
(should (= 1 (etaf-resource-value resource)))
(should (= 0 cleanup-count))
(etaf-resource-load resource)
(should (= 2 (etaf-resource-value resource)))
(should (= 1 cleanup-count))
(should-not (etaf-resource-dispose resource))
(should (= 2 cleanup-count))
(should-error (etaf-resource-load resource)
:type 'etaf-resource-error))
(when resource
(etaf-resource-dispose resource)))))
(ert-deftest etaf-resource-parent-scope-disposes-resource-cleanup ()
"Attach Resource cleanup to the active parent Scope."
(let ((scope (etaf-effect-scope :detached t :name 'parent-test))
resource
cleanup-count)
(setq cleanup-count 0)
(setq resource
(etaf-scope-run
scope
(lambda ()
(etaf-resource
(lambda ()
(etaf-resource-result
"scoped"
:cleanup (lambda () (cl-incf cleanup-count))))
:name 'scoped-test))))
(should (equal "scoped" (etaf-resource-value resource)))
(should-not (etaf-scope-stop scope))
(should (= 1 cleanup-count))
(should-error (etaf-resource-load resource)
:type 'etaf-resource-error)))
(ert-deftest etaf-error-boundary-run-handles-body-error ()
"Convert an explicitly wrapped body error into a handler result."
(let ((seen nil))
(should
(equal "handled"
(etaf-error-boundary-run
(lambda () (error "render failed"))
(lambda (condition)
(setq seen condition)
"handled")
:name 'boundary-test)))
(should (eq 'error (car seen)))
(should (string-match-p "render failed" (cadr seen)))))
(ert-deftest etaf-error-boundary-run-preserves-unhandled-errors ()
"Do not swallow errors outside the wrapped body or inside the handler."
(should-error
(progn
(etaf-error-boundary-run
(lambda () "ok")
(lambda (_condition) "unused"))
(error "outside"))
:type 'error)
(should-error
(etaf-error-boundary-run
(lambda () (error "body"))
(lambda (_condition) (error "handler")))
:type 'error))
;;; etaf-resource-tests.el ends here