;;; ruby-mode-tests.el --- Test suite for ruby-mode
;; Copyright (C) 2012 Free Software Foundation, Inc.
;; This file is part of GNU Emacs.
;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs. If not, see .
;;; Commentary:
;;; Code:
(require 'ruby-mode)
(defun ruby-should-indent (content column)
"Assert indentation COLUMN on the last line of CONTENT."
(with-temp-buffer
(insert content)
(ruby-mode)
(ruby-indent-line)
(should (= (current-indentation) column))))
(defun ruby-should-indent-buffer (expected content)
"Assert that CONTENT turns into EXPECTED after the buffer is re-indented.
The whitespace before and including \"|\" on each line is removed."
(with-temp-buffer
(insert (ruby-test-string content))
(ruby-mode)
(indent-region (point-min) (point-max))
(should (string= (ruby-test-string expected) (buffer-string)))))
(defun ruby-test-string (s &rest args)
(apply 'format (replace-regexp-in-string "^[ \t]*|" "" s) args))
(defun ruby-assert-state (content &rest values-plist)
"Assert syntax state values at the end of CONTENT.
VALUES-PLIST is a list with alternating index and value elements."
(with-temp-buffer
(insert content)
(ruby-mode)
(syntax-propertize (point))
(while values-plist
(should (eq (nth (car values-plist)
(parse-partial-sexp (point-min) (point)))
(cadr values-plist)))
(setq values-plist (cddr values-plist)))))
(defun ruby-assert-face (content pos face)
(with-temp-buffer
(insert content)
(ruby-mode)
(font-lock-fontify-buffer)
(should (eq face (get-text-property pos 'face)))))
(ert-deftest ruby-indent-after-symbol-made-from-string-interpolation ()
"It can indent the line after symbol made using string interpolation."
(ruby-should-indent "def foo(suffix)\n :\"bar#{suffix}\"\n"
ruby-indent-level))
(ert-deftest ruby-indent-after-js-style-symbol-with-block-beg-name ()
"JS-style hash symbol can have keyword name."
(ruby-should-indent "link_to \"home\", home_path, class: \"foo\"\n" 0))
(ert-deftest ruby-discern-singleton-class-from-heredoc ()
(ruby-assert-state "foo <#{@files.join(\"\")}\""))
(ruby-assert-state s 8 nil)
(ruby-assert-face s 9 font-lock-string-face)
(ruby-assert-face s 10 font-lock-variable-name-face)
(ruby-assert-face s 41 font-lock-string-face)))
(ert-deftest ruby-interpolation-inside-percent-literal-with-paren ()
:expected-result :failed
(let ((s "%(^#{\")\"}^)"))
(ruby-assert-face s 3 font-lock-string-face)
(ruby-assert-face s 4 font-lock-variable-name-face)
(ruby-assert-face s 10 font-lock-string-face)
;; It's confused by the closing paren in the middle.
(ruby-assert-state s 8 nil)))
(ert-deftest ruby-add-log-current-method-examples ()
(let ((pairs '(("foo" . "#foo")
("C.foo" . ".foo")
("self.foo" . ".foo"))))
(loop for (name . value) in pairs
do (with-temp-buffer
(insert (ruby-test-string
"module M
| class C
| def %s
| end
| end
|end"
name))
(ruby-mode)
(search-backward "def")
(forward-line)
(should (string= (ruby-add-log-current-method)
(format "M::C%s" value)))))))
(defvar ruby-block-test-example
(ruby-test-string
"class C
| def foo
| 1
| end
|
| def bar
| 2
| end
|
| def baz
| some do
| end
| end
|end"))
(defmacro ruby-deftest-move-to-block (name &rest body)
`(ert-deftest ,(intern (format "ruby-move-to-block-%s" name)) ()
(with-temp-buffer
(insert ruby-block-test-example)
(ruby-mode)
,@body)))
(put 'ruby-deftest-move-to-block 'lisp-indent-function 'defun)
(ruby-deftest-move-to-block works-on-do
(goto-line 11)
(ruby-end-of-block)
(should (= 12 (line-number-at-pos)))
(ruby-beginning-of-block)
(should (= 11 (line-number-at-pos))))
(ruby-deftest-move-to-block zero-is-noop
(goto-line 5)
(ruby-move-to-block 0)
(should (= 5 (line-number-at-pos))))
(ruby-deftest-move-to-block ok-with-three
(goto-line 2)
(ruby-move-to-block 3)
(should (= 13 (line-number-at-pos))))
(ruby-deftest-move-to-block ok-with-minus-two
(goto-line 10)
(ruby-move-to-block -2)
(should (= 2 (line-number-at-pos))))
(provide 'ruby-mode-tests)
;;; ruby-mode-tests.el ends here