Add create-element

This commit is contained in:
paku 2024-05-25 12:00:39 +09:00
parent f086e13e04
commit f8171dd47f
4 changed files with 87 additions and 1 deletions

View file

@ -1,5 +1,6 @@
(defsystem "piccolo-test"
:class :package-inferred-system
:pathname "tests"
:depends-on ("fiveam")
:depends-on ("fiveam"
"piccolo-test/element")
:perform (test-op (op c) (symbol-call :fiveam :run-all-tests)))

38
src/element.lisp Normal file
View file

@ -0,0 +1,38 @@
(defpackage #:piccolo/element
(:use #:cl)
(:export #:element-kind
#:element-props
#:create-element
#:expand))
(in-package #:piccolo/element)
(defclass element ()
((kind
:reader element-kind
:initarg :kind)
(props
:reader element-props
:initarg :props)))
(defun create-element (kind props &rest children)
(make-instance 'element
:kind kind
:props (append props
(and children
(list :children (flatten children))))))
(defun flatten (x)
(labels ((rec (x acc)
(cond ((null x) acc)
((atom x) (cons x acc))
(t (rec
(car x)
(rec (cdr x) acc))))))
(rec x nil)))
(defmethod expand ((elm element))
(with-accessors ((kind element-kind)
(props element-props)) elm
(if (functionp kind)
(apply kind props)
(error "element-kind is not a function."))))

View file

47
tests/element.lisp Normal file
View file

@ -0,0 +1,47 @@
(defpackage :piccolo-test/element
(:use :cl
:fiveam
:piccolo/element))
(in-package :piccolo-test/element)
(def-suite create-element)
(in-suite create-element)
(test create-html-element
(let* ((inner (create-element "span"
'(:class "red")
"World!"))
(outer (create-element "p"
nil
"Hello,"
inner)))
(with-accessors ((kind element-kind)
(props element-props)) inner
(is (string= kind "span"))
(is (equal props `(:class "red" :children ("World!")))))
(with-accessors ((kind element-kind)
(props element-props)) outer
(is (string= kind "p"))
(is (equal props `(:children ("Hello," ,inner)))))))
(test create-component-element
(labels ((comp (&key variant children)
(create-element "p"
`(:class ,variant)
"Hello,"
children)))
(let* ((inner (create-element "span"
nil
"World!"))
(outer (create-element #'comp
'(:variant "red")
inner)))
(with-accessors ((kind element-kind)
(props element-props)) outer
(is (eql kind #'comp))
(is (equal props `(:variant "red" :children (,inner)))))
(with-accessors ((kind element-kind)
(props element-props)) (expand outer)
(is (string= kind "p"))
(is (equal props `(:class "red" :children ("Hello," ,inner))))))))