Commit | Line | Data |
---|---|---|
c28662a8 DG |
1 | ;;; ruby-mode-tests.el --- Test suite for ruby-mode |
2 | ||
3 | ;; Copyright (C) 2012 Free Software Foundation, Inc. | |
4 | ||
5 | ;; This file is part of GNU Emacs. | |
6 | ||
7 | ;; GNU Emacs is free software: you can redistribute it and/or modify | |
8 | ;; it under the terms of the GNU General Public License as published by | |
9 | ;; the Free Software Foundation, either version 3 of the License, or | |
10 | ;; (at your option) any later version. | |
11 | ||
12 | ;; GNU Emacs is distributed in the hope that it will be useful, | |
13 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | ;; GNU General Public License for more details. | |
16 | ||
17 | ;; You should have received a copy of the GNU General Public License | |
18 | ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | |
19 | ||
20 | ;;; Commentary: | |
21 | ||
22 | ;;; Code: | |
23 | ||
24 | (require 'ruby-mode) | |
25 | ||
9cd80478 | 26 | (defun ruby-should-indent (content column) |
9d2ed8a2 | 27 | "Assert indentation COLUMN on the last line of CONTENT." |
9cd80478 DG |
28 | (with-temp-buffer |
29 | (insert content) | |
30 | (ruby-mode) | |
31 | (ruby-indent-line) | |
9d2ed8a2 DG |
32 | (should (= (current-indentation) column)))) |
33 | ||
34 | (defun ruby-should-indent-buffer (expected content) | |
35 | "Assert that CONTENT turns into EXPECTED after the buffer is re-indented. | |
36 | ||
37 | The whitespace before and including \"|\" on each line is removed." | |
38 | (with-temp-buffer | |
5745cae6 DG |
39 | (insert (ruby-test-string content)) |
40 | (ruby-mode) | |
41 | (indent-region (point-min) (point-max)) | |
42 | (should (string= (ruby-test-string expected) (buffer-string))))) | |
43 | ||
44 | (defun ruby-test-string (s &rest args) | |
45 | (apply 'format (replace-regexp-in-string "^[ \t]*|" "" s) args)) | |
9cd80478 DG |
46 | |
47 | (defun ruby-assert-state (content &rest values-plist) | |
48 | "Assert syntax state values at the end of CONTENT. | |
49 | ||
50 | VALUES-PLIST is a list with alternating index and value elements." | |
51 | (with-temp-buffer | |
52 | (insert content) | |
53 | (ruby-mode) | |
54 | (syntax-propertize (point)) | |
55 | (while values-plist | |
56 | (should (eq (nth (car values-plist) | |
57 | (parse-partial-sexp (point-min) (point))) | |
58 | (cadr values-plist))) | |
59 | (setq values-plist (cddr values-plist))))) | |
60 | ||
0ba2d4b6 DG |
61 | (defun ruby-assert-face (content pos face) |
62 | (with-temp-buffer | |
63 | (insert content) | |
64 | (ruby-mode) | |
65 | (font-lock-fontify-buffer) | |
66 | (should (eq face (get-text-property pos 'face))))) | |
67 | ||
9cd80478 | 68 | (ert-deftest ruby-indent-after-symbol-made-from-string-interpolation () |
c28662a8 | 69 | "It can indent the line after symbol made using string interpolation." |
9cd80478 DG |
70 | (ruby-should-indent "def foo(suffix)\n :\"bar#{suffix}\"\n" |
71 | ruby-indent-level)) | |
72 | ||
73 | (ert-deftest ruby-indent-after-js-style-symbol-with-block-beg-name () | |
74 | "JS-style hash symbol can have keyword name." | |
75 | (ruby-should-indent "link_to \"home\", home_path, class: \"foo\"\n" 0)) | |
76 | ||
77 | (ert-deftest ruby-discern-singleton-class-from-heredoc () | |
78 | (ruby-assert-state "foo <<asd\n" 3 ?\n) | |
79 | (ruby-assert-state "class <<asd\n" 3 nil)) | |
c28662a8 | 80 | |
f178c32d DG |
81 | (ert-deftest ruby-heredoc-font-lock () |
82 | (let ((s "foo <<eos.gsub('^ *', '')")) | |
83 | (ruby-assert-face s 9 'font-lock-string-face) | |
84 | (ruby-assert-face s 10 nil))) | |
85 | ||
86 | (ert-deftest ruby-singleton-class-no-heredoc-font-lock () | |
87 | (ruby-assert-face "class<<a" 8 nil)) | |
88 | ||
9d2ed8a2 DG |
89 | (ert-deftest ruby-deep-indent () |
90 | (let ((ruby-deep-arglist nil) | |
91 | (ruby-deep-indent-paren '(?\( ?\{ ?\[ ?\] t))) | |
92 | (ruby-should-indent "foo = [1,\n2" 7) | |
93 | (ruby-should-indent "foo = {a: b,\nc: d" 7) | |
94 | (ruby-should-indent "foo(a,\nb" 4))) | |
95 | ||
96 | (ert-deftest ruby-deep-indent-disabled () | |
97 | (let ((ruby-deep-arglist nil) | |
98 | (ruby-deep-indent-paren nil)) | |
99 | (ruby-should-indent "foo = [\n1" ruby-indent-level) | |
100 | (ruby-should-indent "foo = {\na: b" ruby-indent-level) | |
101 | (ruby-should-indent "foo(\na" ruby-indent-level))) | |
102 | ||
0ba2d4b6 DG |
103 | (ert-deftest ruby-indent-after-keyword-in-a-string () |
104 | (ruby-should-indent "a = \"abc\nif\"\n " 0) | |
105 | (ruby-should-indent "a = %w[abc\n def]\n " 0) | |
106 | (ruby-should-indent "a = \"abc\n def\"\n " 0)) | |
107 | ||
9d2ed8a2 DG |
108 | (ert-deftest ruby-indent-simple () |
109 | (ruby-should-indent-buffer | |
110 | "if foo | |
111 | | bar | |
112 | |end | |
113 | |zot | |
114 | |" | |
115 | "if foo | |
116 | |bar | |
117 | | end | |
118 | | zot | |
119 | |")) | |
120 | ||
121 | (ert-deftest ruby-indent-keyword-label () | |
122 | (ruby-should-indent-buffer | |
123 | "bar(class: XXX) do | |
124 | | foo | |
125 | |end | |
126 | |bar | |
127 | |" | |
128 | "bar(class: XXX) do | |
129 | | foo | |
130 | | end | |
131 | | bar | |
132 | |")) | |
133 | ||
134 | (ert-deftest ruby-indent-method-with-question-mark () | |
135 | (ruby-should-indent-buffer | |
136 | "if x.is_a?(XXX) | |
137 | | foo | |
138 | |end | |
139 | |" | |
140 | "if x.is_a?(XXX) | |
141 | | foo | |
142 | | end | |
143 | |")) | |
144 | ||
145 | (ert-deftest ruby-indent-expr-in-regexp () | |
146 | (ruby-should-indent-buffer | |
147 | "if /#{foo}/ =~ s | |
148 | | x = 1 | |
149 | |end | |
150 | |" | |
151 | "if /#{foo}/ =~ s | |
152 | | x = 1 | |
153 | | end | |
154 | |")) | |
155 | ||
156 | (ert-deftest ruby-indent-singleton-class () | |
157 | :expected-result :failed ; Doesn't work yet, when no space before "<<". | |
158 | (ruby-should-indent-buffer | |
159 | "class<<bar | |
160 | | foo | |
161 | |end | |
162 | |" | |
163 | "class<<bar | |
164 | |foo | |
165 | | end | |
166 | |")) | |
167 | ||
168 | (ert-deftest ruby-indent-array-literal () | |
169 | (let ((ruby-deep-indent-paren nil)) | |
170 | (ruby-should-indent-buffer | |
171 | "foo = [ | |
172 | | bar | |
173 | |] | |
174 | |" | |
175 | "foo = [ | |
176 | | bar | |
177 | | ] | |
178 | |")) | |
179 | (ruby-should-indent-buffer | |
180 | "foo do | |
181 | | [bar] | |
182 | |end | |
183 | |" | |
184 | "foo do | |
185 | |[bar] | |
186 | | end | |
187 | |")) | |
188 | ||
189 | (ert-deftest ruby-indent-begin-end () | |
190 | (ruby-should-indent-buffer | |
191 | "begin | |
192 | | a[b] | |
193 | |end | |
194 | |" | |
195 | "begin | |
196 | | a[b] | |
197 | | end | |
198 | |")) | |
199 | ||
200 | (ert-deftest ruby-indent-array-after-paren-and-space () | |
201 | (ruby-should-indent-buffer | |
202 | "class A | |
203 | | def foo | |
204 | | foo( []) | |
205 | | end | |
206 | |end | |
207 | |" | |
208 | "class A | |
209 | | def foo | |
210 | |foo( []) | |
211 | |end | |
212 | | end | |
213 | |")) | |
214 | ||
d1e1e53d | 215 | (ert-deftest ruby-move-to-block-stops-at-indentation () |
0d9e2599 NN |
216 | (with-temp-buffer |
217 | (insert "def f\nend") | |
218 | (beginning-of-line) | |
219 | (ruby-mode) | |
220 | (ruby-move-to-block -1) | |
d1e1e53d | 221 | (should (looking-at "^def")))) |
0d9e2599 NN |
222 | |
223 | (ert-deftest ruby-toggle-block-to-do-end () | |
224 | (with-temp-buffer | |
c3268831 | 225 | (insert "foo {|b|\n}") |
0d9e2599 | 226 | (ruby-mode) |
c3268831 | 227 | (beginning-of-line) |
0d9e2599 | 228 | (ruby-toggle-block) |
c3268831 | 229 | (should (string= "foo do |b|\nend" (buffer-string))))) |
0d9e2599 NN |
230 | |
231 | (ert-deftest ruby-toggle-block-to-brace () | |
32fb8162 DG |
232 | (let ((pairs '((16 . "foo {|b| b + 2 }") |
233 | (15 . "foo {|b|\n b + 2\n}")))) | |
234 | (dolist (pair pairs) | |
235 | (with-temp-buffer | |
236 | (let ((fill-column (car pair))) | |
237 | (insert "foo do |b|\n b + 2\nend") | |
238 | (ruby-mode) | |
239 | (beginning-of-line) | |
240 | (ruby-toggle-block) | |
241 | (should (string= (cdr pair) (buffer-string)))))))) | |
c3268831 DG |
242 | |
243 | (ert-deftest ruby-toggle-block-to-multiline () | |
244 | (with-temp-buffer | |
245 | (insert "foo {|b| b + 1}") | |
246 | (ruby-mode) | |
247 | (beginning-of-line) | |
0d9e2599 | 248 | (ruby-toggle-block) |
c3268831 | 249 | (should (string= "foo do |b|\n b + 1\nend" (buffer-string))))) |
0d9e2599 | 250 | |
0ba2d4b6 DG |
251 | (ert-deftest ruby-recognize-symbols-starting-with-at-character () |
252 | (ruby-assert-face ":@abc" 3 'font-lock-constant-face)) | |
253 | ||
254 | (ert-deftest ruby-hash-character-not-interpolation () | |
255 | (ruby-assert-face "\"This is #{interpolation}\"" 15 | |
256 | 'font-lock-variable-name-face) | |
257 | (ruby-assert-face "\"This is \\#{no interpolation} despite the #\"" | |
258 | 15 'font-lock-string-face) | |
616c6c36 DG |
259 | (ruby-assert-face "\n#@comment, not ruby code" 5 'font-lock-comment-face) |
260 | (ruby-assert-state "\n#@comment, not ruby code" 4 t) | |
0ba2d4b6 | 261 | (ruby-assert-face "# A comment cannot have #{an interpolation} in it" |
616c6c36 DG |
262 | 30 'font-lock-comment-face) |
263 | (ruby-assert-face "# #{comment}\n \"#{interpolation}\"" 16 | |
264 | 'font-lock-variable-name-face)) | |
0ba2d4b6 | 265 | |
5745cae6 DG |
266 | (ert-deftest ruby-add-log-current-method-examples () |
267 | (let ((pairs '(("foo" . "#foo") | |
268 | ("C.foo" . ".foo") | |
269 | ("self.foo" . ".foo")))) | |
270 | (loop for (name . value) in pairs | |
271 | do (with-temp-buffer | |
272 | (insert (ruby-test-string | |
273 | "module M | |
274 | | class C | |
275 | | def %s | |
276 | | end | |
277 | | end | |
278 | |end" | |
279 | name)) | |
280 | (ruby-mode) | |
281 | (search-backward "def") | |
282 | (forward-line) | |
283 | (should (string= (ruby-add-log-current-method) | |
284 | (format "M::C%s" value))))))) | |
285 | ||
c28662a8 DG |
286 | (provide 'ruby-mode-tests) |
287 | ||
288 | ;;; ruby-mode-tests.el ends here |