+(ert-deftest escape-dollar ()
+ (with-temp-buffer
+ (yas-minor-mode 1)
+ (yas-expand-snippet "bla\\${1:bla}ble")
+ (should (string= (yas--buffer-contents) "bla${1:bla}ble"))))
+
+(ert-deftest escape-closing-brace ()
+ (with-temp-buffer
+ (yas-minor-mode 1)
+ (yas-expand-snippet "bla${1:bla\\}}ble")
+ (should (string= (yas--buffer-contents) "blabla}ble"))
+ (should (string= (yas-field-value 1) "bla}"))))
+
+(ert-deftest escape-backslashes ()
+ (with-temp-buffer
+ (yas-minor-mode 1)
+ (yas-expand-snippet "bla\\ble")
+ (should (string= (yas--buffer-contents) "bla\\ble"))))
+
+(ert-deftest escape-backquotes ()
+ (with-temp-buffer
+ (yas-minor-mode 1)
+ (yas-expand-snippet "bla`(upcase \"foo\\`bar\")`ble")
+ (should (string= (yas--buffer-contents) "blaFOO`BARble"))))
+
+(ert-deftest escape-some-elisp-with-strings ()
+ "elisp with strings and unbalance parens inside it"
+ (with-temp-buffer
+ (yas-minor-mode 1)
+ ;; The rules here is: to output a literal `"' you need to escape
+ ;; it with one backslash. You don't need to escape them in
+ ;; embedded elisp.
+ (yas-expand-snippet "soon \\\"`(concat (upcase \"(my arms\")\"\\\" were all around her\")`")
+ (should (string= (yas--buffer-contents) "soon \"(MY ARMS\" were all around her"))))
+
+(ert-deftest escape-some-elisp-with-backslashes ()
+ (with-temp-buffer
+ (yas-minor-mode 1)
+ ;; And the rule here is: to output a literal `\' inside a string
+ ;; inside embedded elisp you need a total of six `\'
+ (yas-expand-snippet "bla`(upcase \"hey\\\\\\yo\")`ble")
+ (should (string= (yas--buffer-contents) "blaHEY\\YOble"))))
+
+(ert-deftest be-careful-when-escaping-in-yas-selected-text ()
+ (with-temp-buffer
+ (yas-minor-mode 1)
+ (let ((yas-selected-text "He\\\\o world!"))
+ (yas-expand-snippet "Look ma! `(yas-selected-text)`")
+ (should (string= (yas--buffer-contents) "Look ma! He\\\\o world!")))
+ (yas-exit-all-snippets)
+ (erase-buffer)
+ (let ((yas-selected-text "He\"o world!"))
+ (yas-expand-snippet "Look ma! `(yas-selected-text)`")
+ (should (string= (yas--buffer-contents) "Look ma! He\"o world!")))
+ (yas-exit-all-snippets)
+ (erase-buffer)
+ (let ((yas-selected-text "He\"\)\\o world!"))
+ (yas-expand-snippet "Look ma! `(yas-selected-text)`")
+ (should (string= (yas--buffer-contents) "Look ma! He\"\)\\o world!")))
+ (yas-exit-all-snippets)
+ (erase-buffer)))
+
+(ert-deftest be-careful-when-escaping-in-yas-selected-text-2 ()
+ (with-temp-buffer
+ (yas-minor-mode 1)
+ (let ((yas-selected-text "He)}o world!"))
+ (yas-expand-snippet "Look ma! ${1:`(yas-selected-text)`} OK?")
+ (should (string= (yas--buffer-contents) "Look ma! He)}o world! OK?")))))
+
+(ert-deftest example-for-issue-271 ()
+ (with-temp-buffer
+ (yas-minor-mode 1)
+ (let ((yas-selected-text "aaa")
+ (snippet "if ${1:condition}\n`yas-selected-text`\nelse\n$3\nend"))
+ (yas-expand-snippet snippet)
+ (yas-next-field)
+ (yas-mock-insert "bbb")
+ (should (string= (yas--buffer-contents) "if condition\naaa\nelse\nbbb\nend")))))
+
+(defmacro yas--with-font-locked-temp-buffer (&rest body)
+ "Like `with-temp-buffer', but ensure `font-lock-mode'."
+ (declare (indent 0) (debug t))
+ (let ((temp-buffer (make-symbol "temp-buffer")))
+ ;; NOTE: buffer name must not start with a space, otherwise
+ ;; `font-lock-mode' doesn't turn on.
+ `(let ((,temp-buffer (generate-new-buffer "*yas-temp*")))
+ (with-current-buffer ,temp-buffer
+ ;; pretend we're interactive so `font-lock-mode' turns on
+ (let ((noninteractive nil)
+ ;; turn on font locking after major mode change
+ (change-major-mode-after-body-hook #'font-lock-mode))
+ (unwind-protect
+ (progn (require 'font-lock)
+ ;; turn on font locking before major mode change
+ (font-lock-mode +1)
+ ,@body)
+ (and (buffer-name ,temp-buffer)
+ (kill-buffer ,temp-buffer))))))))
+
+(defmacro yas-saving-variables (&rest body)
+ `(yas-call-with-saving-variables #'(lambda () ,@body)))
+
+(defmacro yas-with-snippet-dirs (dirs &rest body)
+ (declare (indent defun))
+ `(yas-call-with-snippet-dirs ,dirs
+ #'(lambda ()
+ ,@body)))
+
+(ert-deftest example-for-issue-474 ()
+ (yas--with-font-locked-temp-buffer
+ (c-mode)
+ (yas-minor-mode 1)
+ (insert "#include <foo>\n")
+ (let ((yas-good-grace nil)) (yas-expand-snippet "`\"TODO: \"`"))
+ (should (string= (yas--buffer-contents) "#include <foo>\nTODO: "))))
+
+(ert-deftest example-for-issue-404 ()
+ (yas--with-font-locked-temp-buffer
+ (c++-mode)
+ (yas-minor-mode 1)
+ (insert "#include <foo>\n")
+ (let ((yas-good-grace nil)) (yas-expand-snippet "main"))
+ (should (string= (yas--buffer-contents) "#include <foo>\nmain"))))
+
+(ert-deftest example-for-issue-404-c-mode ()
+ (yas--with-font-locked-temp-buffer
+ (c-mode)
+ (yas-minor-mode 1)
+ (insert "#include <foo>\n")
+ (let ((yas-good-grace nil)) (yas-expand-snippet "main"))
+ (should (string= (yas--buffer-contents) "#include <foo>\nmain"))))