diff --git a/piccolo-test.asd b/piccolo-test.asd index 4bb1d78..0f7e34b 100644 --- a/piccolo-test.asd +++ b/piccolo-test.asd @@ -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))) diff --git a/src/element.lisp b/src/element.lisp new file mode 100644 index 0000000..09c41e4 --- /dev/null +++ b/src/element.lisp @@ -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.")))) diff --git a/tests/.keep b/tests/.keep deleted file mode 100644 index e69de29..0000000 diff --git a/tests/element.lisp b/tests/element.lisp new file mode 100644 index 0000000..db2887d --- /dev/null +++ b/tests/element.lisp @@ -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))))))))