;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Test-cases
(load-file (concat (file-name-directory load-file-name) "../emmet-mode.el"))
(emmet-defparameter *emmet-test-cases* nil)
(defun emmet-test-cases (&rest args)
(let ((cmd (car args)))
(flet
((run-cases
(fn cases)
(loop for c in cases
for i to (1- (length cases)) do
(let ((expected (cdr c))
(actual (funcall fn (car c))))
(when (not (equal expected actual))
(princ
(concat "*** [FAIL] | \"" name "\" " (number-to-string i) "\n\n"
(format "%s" (car c)) "\t=>\n\n"
"Expected\n" (format "%s" expected) "\n\nActual\n" (format "%s" actual) "\n\n"))
(return 'fail))))))
(cond ((eql cmd 'assign)
(let ((name (cadr args))
(fn (caddr args))
(defs (cadddr args)))
(let ((place (assoc name *emmet-test-cases*)))
(if place
(setf (cdr place) (cons fn defs))
(setq *emmet-test-cases*
(cons (cons name (cons fn defs)) *emmet-test-cases*))))))
(t
(loop for test in (reverse *emmet-test-cases*) do
(let ((name (symbol-name (car test)))
(fn (cadr test))
(cases (cddr test)))
(let ((res (run-cases fn cases)))
(if (not (eql res 'fail))
(princ (concat " [PASS] | \"" name "\" "
(number-to-string (length cases)) " tests.\n")))))))))))
(defmacro define-emmet-transform-test-case (name fn &rest tests)
`(emmet-test-cases 'assign ',name
,fn
',(loop for x on tests by #'cddr collect
(cons (car x)
(emmet-join-string (cadr x)
"\n")))))
(defmacro define-emmet-transform-html-test-case (name &rest tests)
`(define-emmet-transform-test-case ,name
'emmet-html-transform
,@tests))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; XML-abbrev tests
(define-emmet-transform-html-test-case Tags
"a" ("")
"a.x" ("")
"a#q.x" ("")
"a#q.x.y.z" ("")
"#q" ("
")
".x" ("")
"#q.x" ("")
"#q.x.y.z" (""))
(define-emmet-transform-html-test-case Empty-tags
"a/" ("")
"a/.x" ("")
"a/#q.x" ("")
"a/#q.x.y.z" (""))
(define-emmet-transform-html-test-case Self-closing-tags
"input type=text" ("")
"img" ("
")
"img>metadata/*2" ("
"
" "
" "
""))
(define-emmet-transform-html-test-case Siblings
"a+b" (""
"")
"a+b+c" (""
""
"")
"a.x+b" (""
"")
"a#q.x+b" (""
"")
"a#q.x.y.z+b" (""
"")
"a#q.x.y.z+b#p.l.m.n" (""
""))
(define-emmet-transform-html-test-case Tag-expansion
"table+" ("")
"dl+" (""
" "
" "
"
")
"ul+" ("")
"ul++ol+" (""
""
" "
"
")
"ul#q.x.y m=l+" (""))
(define-emmet-transform-html-test-case Parent-child
"a>b" ("")
"a>b>c" ("")
"a.x>b" ("")
"a#q.x>b" ("")
"a#q.x.y.z>b" ("")
"a#q.x.y.z>b#p.l.m.n" ("")
"#q>.x" ("")
"a>b+c" (""
" "
" "
"")
"a>b+c>d" (""
" "
" "
""))
(define-emmet-transform-html-test-case Climb-up
"a>b>c^d" (""
" "
" "
"")
"a>b>c^^d" (""
"")
"a*2>b*2>c^d" (""
" "
" "
" "
""
""
" "
" "
" "
"")
"div+a>p>span{foo}+em>b^^^p"
(""
""
" "
" foo"
" "
"
"
""
"")
"div+div>p>span+em^blockquote{foo}"
(""
""
"
"
" "
" "
"
"
"
"
" foo"
"
"
"
"))
(define-emmet-transform-html-test-case Multiplication
"a*1" ("")
"a*2" (""
"")
"a/*2" (""
"")
"a*2+b*2" (""
""
""
"")
"a*2>b*2" (""
" "
" "
""
""
" "
" "
"")
"a>b*2" (""
" "
" "
"")
"a#q.x>b#q.x*2" (""
" "
" "
"")
"a#q.x>b/#q.x*2" (""
" "
" "
""))
(define-emmet-transform-html-test-case Numbering
"a.$x*3" (""
""
"")
"ul>li.item$*3" ("")
"ul>li.item$$$*3" ("")
"ul>li.item$@-*2" ("")
"ul>li.item$@-1000*2" ("")
"a.$*2>b.$$@-*3" (""
" "
" "
" "
""
""
" "
" "
" "
"")
"(div>(a#id$$*2)+b.c$@-3+c#d$)*2"
(""
"")
"a:b$$$-c$$@-:d$@-3-e$$@100/#b.c$*3"
(""
""
"")
"ul>li.item${name: item$ price: $\\$}*3"
(""
" - name: item1 price: 1$
"
" - name: item2 price: 2$
"
" - name: item3 price: 3$
"
"
"))
(define-emmet-transform-html-test-case Properties
"a x" ("")
"a x=" ("")
"a x=\"\"" ("")
"a x=y" ("")
"a x=\"y\"" ("")
"a x=\"()\"" ("")
"a x m" ("")
"a x= m=\"\"" ("")
"a x=y m=l" ("")
"a/ x=y m=l" ("")
"a#foo x=y m=l" ("")
"a.foo x=y m=l" ("")
"a#foo.bar.mu x=y m=l" ("")
"a/#foo.bar.mu x=y m=l" ("")
"a x=y+b" (""
"")
"a x=y+b x=y" (""
"")
"a x=y>b" ("")
"a x=y>b x=y" ("")
"a x=y>b x=y+c x=y" (""
" "
" "
""))
(define-emmet-transform-html-test-case Parentheses
"(a)" ("")
"(a)+(b)" (""
"")
"a>(b)" ("")
"(a>b)>c" ("")
"(a>b)+c" (""
"")
"z+(a>b)+c+k" (""
""
""
"")
"(a)*2" (""
"")
"((a)*2)" (""
"")
"((a))*2" (""
"")
"(a>b)*2" (""
"")
"(a+b)*2" (""
""
""
""))
(define-emmet-transform-html-test-case Text
"a{Click me}" ("Click me")
"a>{Click me}*3" (""
" Click me"
" Click me"
" Click me"
"")
"a{click}+b{here}" ("click"
"here")
"a>{click}+b{here}" (""
" click"
" here"
"")
"p>{Click }+a{here}+{ to continue}"
(""
" Click "
" here"
" to continue"
"
")
"p{Click }+a{here}+{ to continue}"
("Click
"
"here"
" to continue")
"xxx#id.cls p=1{txt}"
("txt"))
(define-emmet-transform-html-test-case Filter-comment
"a.b|c" (""
""
"")
"#a>.b|c" (""
""
""))
(define-emmet-transform-html-test-case Filter-HAML
"a|haml" ("%a")
"a#q.x.y.z|haml" ("%a#q.x.y.z")
"a#q.x x=y m=l|haml" ("%a#q.x{:x => \"y\", :m => \"l\"}")
"div|haml" ("%div")
"div.footer|haml" (".footer")
".footer|haml" (".footer")
"p>{This is haml}*2+a href=#+br|haml"
("%p"
" This is haml"
" This is haml"
" %a{:href => \"#\"}"
" %br"))
(define-emmet-transform-html-test-case Filter-Hiccup
"a|hic" ("[:a]")
"a#q.x.y.z|hic" ("[:a#q.x.y.z]")
"a#q.x x=y m=l|hic" ("[:a#q.x {:x \"y\", :m \"l\"}]")
".footer|hic" ("[:div.footer]")
"p>a href=#+br|hic" ("[:p"
" [:a {:href \"#\"}]"
" [:br]]")
"#q>(a*2>b{x})+p>{m}+b|hic"
("[:div#q"
" [:a [:b \"x\"]]"
" [:a [:b \"x\"]]"
" [:p"
" \"m\""
" [:b]]]"))
(define-emmet-transform-html-test-case Filter-escape
"script src="|e" ("<script src=\""\">"
"</script>"))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; CSS-abbrev tests
(defmacro define-emmet-unit-test-case (name fn &rest tests)
`(emmet-test-cases 'assign ',name
,fn
',(loop for x on tests by #'cddr collect
(cons (car x) (cadr x)))))
(define-emmet-unit-test-case CSS-toknize
#'emmet-css-toknize
"" ("")
"abc" ("abc")
"abc+" ("abc+")
"abc+cde" ("abc" "cde")
"abc++cde" ("abc+" "cde")
"abc+cde+" ("abc" "cde+")
"abc++cde+" ("abc+" "cde+")
"ab:c+0p0x#aa+p0+cde+" ("ab:c+0p0x#aa" "p0" "cde+")
"ab+#0+p+#c+x++cde+" ("ab+#0" "p+#c" "x+" "cde+")
"abc def" ("abc def")
"-abc+-xyz" ("-abc" "-xyz")
"-abc+-10" ("-abc+-10"))
(define-emmet-unit-test-case CSS-parse-arg-number
#'emmet-css-arg-number
"" (error "expected css number arguments")
"0" (("0" "px") . "")
"0-1-2" (("0" "px") . "1-2")
"-100" (("-100" "px") . "")
"-10e-20" (("-10" "em") . "-20")
"35p#a" (("35" "%") . "#a")
" 0p" (("0" "%") . ""))
(define-emmet-unit-test-case CSS-parse-arg-color
#'emmet-css-arg-color
"" (error "expected css color argument")
"abc" (error "expected css color argument")
"#x" (error "expected css color argument")
"#a" ("#aaa" . "")
"#09" ("#090909" . "")
"#3D5-2" ("#3D5" . "-2")
"#1a2B-3" ("#1a2B1a" . "-3")
"#1A2b3x" ("#1A2b31" . "x")
"#1a2B3Cx" ("#1a2B3C" . "x")
"#1A2B3C4D-2" ("#1A2B3C" . "4D-2")
" #abc" ("#abc" . ""))
(define-emmet-unit-test-case CSS-parse-arg-something
#'emmet-css-arg-something
"" (error "expected css argument")
"abc" ("abc" . "")
"abc def" ("abc" . " def")
"url(http://abc.com) auto" ("url(http://abc.com)" . " auto"))
(define-emmet-unit-test-case CSS-parse-args
#'emmet-css-parse-args
"" nil
"1-2--3-4" (("1" "px") ("2" "px") ("-3" "px") ("4" "px"))
"-10-2p-30#abc" (("-10" "px") ("2" "%") ("-30" "px") "#abc")
"1p2x3-4e5x" (("1" "%") ("2" "ex") ("3" "px") ("4" "em") ("5" "ex"))
"#abc#de#f-3" ("#abc" "#dedede" "#fff" ("-3" "px")))
(define-emmet-unit-test-case CSS-split-vendor-prefixes
#'emmet-css-split-vendor-prefixes
"" ("" nil)
"-abc" ("abc" auto)
"-wmso-abc" ("abc" (119 109 115 111)))
(define-emmet-unit-test-case CSS-exprs
#'emmet-css-expr
"" (("" nil nil))
"cl:l+ov:h+bg+" (("cl:l" nil nil) ("ov:h" nil nil) ("bg+" nil nil))
"m10-auto!" (("m" nil t ("10" "px") "auto"))
"bg++c!" (("bg+" nil nil) ("c" nil t))
"m+0-10-10--20!+p0-0" (("m+" nil t ("0" "px") ("10" "px") ("10" "px") ("-20" "px"))
("p" nil nil ("0" "px") ("0" "px")))
"bg+#abc#bc#c-3!" (("bg+" nil t "#abc" "#bcbcbc" "#ccc" ("-3" "px"))))
(defmacro define-emmet-transform-css-test-case (name &rest tests)
`(define-emmet-transform-test-case ,name
'emmet-css-transform
,@tests))
(define-emmet-transform-css-test-case CSS-transform
;; supplying values with units
"m10" ("margin: 10px;")
"m1.5" ("margin: 1.5em;")
"m1.5ex" ("margin: 1.5ex;")
"m1.5x" ("margin: 1.5ex;")
"m10foo" ("margin: 10foo;")
"m10ex20em" ("margin: 10ex 20em;")
"m10x20e" ("margin: 10ex 20em;")
"m10x-5" ("margin: 10ex -5px;")
;; Color values
"c#3" ("color: #333;")
"bd5#0rgb" ("border: 5px rgb(0,0,0);")
"bd5#20rgb" ("border: 5px rgb(32,32,32);")
"bd5#0s" ("border: 5px #000 solid;")
"bd5#2rgbs" ("border: 5px rgb(34,34,34) solid;")
;; Unitless property
"lh2" ("line-height: 2;")
"fw400" ("font-weight: 400;")
;;
"m0+p0-1p2e3x" ("margin: 0px;"
"padding: 0px 1% 2em 3ex;")
"p!+m10e!+f" ("padding: !important;"
"margin: 10em !important;"
"font: ;")
"fs" ("font-style: italic;")
"xxxxxx 0 auto 0e auto!" ("xxxxxx: 0px auto 0em auto !important;")
"p auto+m auto+bg+#F00 x.jpg 10 10 repeat-x"
("padding: auto;"
"margin: auto;"
"background: #F00 url(x.jpg) 10px 10px repeat-x;")
"-bdrs" ("-webkit-border-radius: ;"
"-moz-border-radius: ;"
"border-radius: ;")
"-super-foo" ("-webkit-super-foo: ;"
"-moz-super-foo: ;"
"-ms-super-foo: ;"
"-o-super-foo: ;"
"super-foo: ;")
"-wm-trf" ("-webkit-transform: ;"
"-moz-transform: ;"
"transform: ;")
"@m print 1" ("@media print {"
" 1px"
"}")
"@i http://github.com/smihica/index.css"
("@import url(http://github.com/smihica/index.css);")
)
;; start
(emmet-test-cases)