]> code.delx.au - gnu-emacs/blob - test/automated/python-tests.el
Merge from origin/emacs-24
[gnu-emacs] / test / automated / python-tests.el
1 ;;; python-tests.el --- Test suite for python.el
2
3 ;; Copyright (C) 2013-2015 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 'ert)
25 (require 'python)
26
27 (defmacro python-tests-with-temp-buffer (contents &rest body)
28 "Create a `python-mode' enabled temp buffer with CONTENTS.
29 BODY is code to be executed within the temp buffer. Point is
30 always located at the beginning of buffer."
31 (declare (indent 1) (debug t))
32 `(with-temp-buffer
33 (python-mode)
34 (insert ,contents)
35 (goto-char (point-min))
36 ,@body))
37
38 (defmacro python-tests-with-temp-file (contents &rest body)
39 "Create a `python-mode' enabled file with CONTENTS.
40 BODY is code to be executed within the temp buffer. Point is
41 always located at the beginning of buffer."
42 (declare (indent 1) (debug t))
43 ;; temp-file never actually used for anything?
44 `(let* ((temp-file (make-temp-file "python-tests" nil ".py"))
45 (buffer (find-file-noselect temp-file)))
46 (unwind-protect
47 (with-current-buffer buffer
48 (python-mode)
49 (insert ,contents)
50 (goto-char (point-min))
51 ,@body)
52 (and buffer (kill-buffer buffer))
53 (delete-file temp-file))))
54
55 (defun python-tests-look-at (string &optional num restore-point)
56 "Move point at beginning of STRING in the current buffer.
57 Optional argument NUM defaults to 1 and is an integer indicating
58 how many occurrences must be found, when positive the search is
59 done forwards, otherwise backwards. When RESTORE-POINT is
60 non-nil the point is not moved but the position found is still
61 returned. When searching forward and point is already looking at
62 STRING, it is skipped so the next STRING occurrence is selected."
63 (let* ((num (or num 1))
64 (starting-point (point))
65 (string (regexp-quote string))
66 (search-fn (if (> num 0) #'re-search-forward #'re-search-backward))
67 (deinc-fn (if (> num 0) #'1- #'1+))
68 (found-point))
69 (prog2
70 (catch 'exit
71 (while (not (= num 0))
72 (when (and (> num 0)
73 (looking-at string))
74 ;; Moving forward and already looking at STRING, skip it.
75 (forward-char (length (match-string-no-properties 0))))
76 (and (not (funcall search-fn string nil t))
77 (throw 'exit t))
78 (when (> num 0)
79 ;; `re-search-forward' leaves point at the end of the
80 ;; occurrence, move back so point is at the beginning
81 ;; instead.
82 (forward-char (- (length (match-string-no-properties 0)))))
83 (setq
84 num (funcall deinc-fn num)
85 found-point (point))))
86 found-point
87 (and restore-point (goto-char starting-point)))))
88
89 (defun python-tests-self-insert (char-or-str)
90 "Call `self-insert-command' for chars in CHAR-OR-STR."
91 (let ((chars
92 (cond
93 ((characterp char-or-str)
94 (list char-or-str))
95 ((stringp char-or-str)
96 (string-to-list char-or-str))
97 ((not
98 (cl-remove-if #'characterp char-or-str))
99 char-or-str)
100 (t (error "CHAR-OR-STR must be a char, string, or list of char")))))
101 (mapc
102 (lambda (char)
103 (let ((last-command-event char))
104 (call-interactively 'self-insert-command)))
105 chars)))
106
107 \f
108 ;;; Tests for your tests, so you can test while you test.
109
110 (ert-deftest python-tests-look-at-1 ()
111 "Test forward movement."
112 (python-tests-with-temp-buffer
113 "Lorem ipsum dolor sit amet, consectetur adipisicing elit,
114 sed do eiusmod tempor incididunt ut labore et dolore magna
115 aliqua."
116 (let ((expected (save-excursion
117 (dotimes (i 3)
118 (re-search-forward "et" nil t))
119 (forward-char -2)
120 (point))))
121 (should (= (python-tests-look-at "et" 3 t) expected))
122 ;; Even if NUM is bigger than found occurrences the point of last
123 ;; one should be returned.
124 (should (= (python-tests-look-at "et" 6 t) expected))
125 ;; If already looking at STRING, it should skip it.
126 (dotimes (i 2) (re-search-forward "et"))
127 (forward-char -2)
128 (should (= (python-tests-look-at "et") expected)))))
129
130 (ert-deftest python-tests-look-at-2 ()
131 "Test backward movement."
132 (python-tests-with-temp-buffer
133 "Lorem ipsum dolor sit amet, consectetur adipisicing elit,
134 sed do eiusmod tempor incididunt ut labore et dolore magna
135 aliqua."
136 (let ((expected
137 (save-excursion
138 (re-search-forward "et" nil t)
139 (forward-char -2)
140 (point))))
141 (dotimes (i 3)
142 (re-search-forward "et" nil t))
143 (should (= (python-tests-look-at "et" -3 t) expected))
144 (should (= (python-tests-look-at "et" -6 t) expected)))))
145
146 \f
147 ;;; Bindings
148
149 \f
150 ;;; Python specialized rx
151
152 \f
153 ;;; Font-lock and syntax
154
155 (ert-deftest python-syntax-after-python-backspace ()
156 ;; `python-indent-dedent-line-backspace' garbles syntax
157 :expected-result :failed
158 (python-tests-with-temp-buffer
159 "\"\"\""
160 (goto-char (point-max))
161 (python-indent-dedent-line-backspace 1)
162 (should (string= (buffer-string) "\"\""))
163 (should (null (nth 3 (syntax-ppss))))))
164
165 \f
166 ;;; Indentation
167
168 ;; See: http://www.python.org/dev/peps/pep-0008/#indentation
169
170 (ert-deftest python-indent-pep8-1 ()
171 "First pep8 case."
172 (python-tests-with-temp-buffer
173 "# Aligned with opening delimiter
174 foo = long_function_name(var_one, var_two,
175 var_three, var_four)
176 "
177 (should (eq (car (python-indent-context)) :no-indent))
178 (should (= (python-indent-calculate-indentation) 0))
179 (python-tests-look-at "foo = long_function_name(var_one, var_two,")
180 (should (eq (car (python-indent-context)) :after-line))
181 (should (= (python-indent-calculate-indentation) 0))
182 (python-tests-look-at "var_three, var_four)")
183 (should (eq (car (python-indent-context)) :inside-paren))
184 (should (= (python-indent-calculate-indentation) 25))))
185
186 (ert-deftest python-indent-pep8-2 ()
187 "Second pep8 case."
188 (python-tests-with-temp-buffer
189 "# More indentation included to distinguish this from the rest.
190 def long_function_name(
191 var_one, var_two, var_three,
192 var_four):
193 print (var_one)
194 "
195 (should (eq (car (python-indent-context)) :no-indent))
196 (should (= (python-indent-calculate-indentation) 0))
197 (python-tests-look-at "def long_function_name(")
198 (should (eq (car (python-indent-context)) :after-line))
199 (should (= (python-indent-calculate-indentation) 0))
200 (python-tests-look-at "var_one, var_two, var_three,")
201 (should (eq (car (python-indent-context))
202 :inside-paren-newline-start-from-block))
203 (should (= (python-indent-calculate-indentation) 8))
204 (python-tests-look-at "var_four):")
205 (should (eq (car (python-indent-context))
206 :inside-paren-newline-start-from-block))
207 (should (= (python-indent-calculate-indentation) 8))
208 (python-tests-look-at "print (var_one)")
209 (should (eq (car (python-indent-context))
210 :after-block-start))
211 (should (= (python-indent-calculate-indentation) 4))))
212
213 (ert-deftest python-indent-pep8-3 ()
214 "Third pep8 case."
215 (python-tests-with-temp-buffer
216 "# Extra indentation is not necessary.
217 foo = long_function_name(
218 var_one, var_two,
219 var_three, var_four)
220 "
221 (should (eq (car (python-indent-context)) :no-indent))
222 (should (= (python-indent-calculate-indentation) 0))
223 (python-tests-look-at "foo = long_function_name(")
224 (should (eq (car (python-indent-context)) :after-line))
225 (should (= (python-indent-calculate-indentation) 0))
226 (python-tests-look-at "var_one, var_two,")
227 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
228 (should (= (python-indent-calculate-indentation) 4))
229 (python-tests-look-at "var_three, var_four)")
230 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
231 (should (= (python-indent-calculate-indentation) 4))))
232
233 (ert-deftest python-indent-base-case ()
234 "Check base case does not trigger errors."
235 (python-tests-with-temp-buffer
236 "
237
238 "
239 (goto-char (point-min))
240 (should (eq (car (python-indent-context)) :no-indent))
241 (should (= (python-indent-calculate-indentation) 0))
242 (forward-line 1)
243 (should (eq (car (python-indent-context)) :after-line))
244 (should (= (python-indent-calculate-indentation) 0))
245 (forward-line 1)
246 (should (eq (car (python-indent-context)) :after-line))
247 (should (= (python-indent-calculate-indentation) 0))))
248
249 (ert-deftest python-indent-after-comment-1 ()
250 "The most simple after-comment case that shouldn't fail."
251 (python-tests-with-temp-buffer
252 "# Contents will be modified to correct indentation
253 class Blag(object):
254 def _on_child_complete(self, child_future):
255 if self.in_terminal_state():
256 pass
257 # We only complete when all our async children have entered a
258 # terminal state. At that point, if any child failed, we fail
259 # with the exception with which the first child failed.
260 "
261 (python-tests-look-at "# We only complete")
262 (should (eq (car (python-indent-context)) :after-block-end))
263 (should (= (python-indent-calculate-indentation) 8))
264 (python-tests-look-at "# terminal state")
265 (should (eq (car (python-indent-context)) :after-comment))
266 (should (= (python-indent-calculate-indentation) 8))
267 (python-tests-look-at "# with the exception")
268 (should (eq (car (python-indent-context)) :after-comment))
269 ;; This one indents relative to previous block, even given the fact
270 ;; that it was under-indented.
271 (should (= (python-indent-calculate-indentation) 4))
272 (python-tests-look-at "# terminal state" -1)
273 ;; It doesn't hurt to check again.
274 (should (eq (car (python-indent-context)) :after-comment))
275 (python-indent-line)
276 (should (= (current-indentation) 8))
277 (python-tests-look-at "# with the exception")
278 (should (eq (car (python-indent-context)) :after-comment))
279 ;; Now everything should be lined up.
280 (should (= (python-indent-calculate-indentation) 8))))
281
282 (ert-deftest python-indent-after-comment-2 ()
283 "Test after-comment in weird cases."
284 (python-tests-with-temp-buffer
285 "# Contents will be modified to correct indentation
286 def func(arg):
287 # I don't do much
288 return arg
289 # This comment is badly indented just because.
290 # But we won't mess with the user in this line.
291
292 now_we_do_mess_cause_this_is_not_a_comment = 1
293
294 # yeah, that.
295 "
296 (python-tests-look-at "# I don't do much")
297 (should (eq (car (python-indent-context)) :after-block-start))
298 (should (= (python-indent-calculate-indentation) 4))
299 (python-tests-look-at "return arg")
300 ;; Comment here just gets ignored, this line is not a comment so
301 ;; the rules won't apply here.
302 (should (eq (car (python-indent-context)) :after-block-start))
303 (should (= (python-indent-calculate-indentation) 4))
304 (python-tests-look-at "# This comment is badly")
305 (should (eq (car (python-indent-context)) :after-block-end))
306 ;; The return keyword moves indentation backwards 4 spaces, but
307 ;; let's assume this comment was placed there because the user
308 ;; wanted to (manually adding spaces or whatever).
309 (should (= (python-indent-calculate-indentation) 0))
310 (python-tests-look-at "# but we won't mess")
311 (should (eq (car (python-indent-context)) :after-comment))
312 (should (= (python-indent-calculate-indentation) 4))
313 ;; Behave the same for blank lines: potentially a comment.
314 (forward-line 1)
315 (should (eq (car (python-indent-context)) :after-comment))
316 (should (= (python-indent-calculate-indentation) 4))
317 (python-tests-look-at "now_we_do_mess")
318 ;; Here is where comment indentation starts to get ignored and
319 ;; where the user can't freely indent anymore.
320 (should (eq (car (python-indent-context)) :after-block-end))
321 (should (= (python-indent-calculate-indentation) 0))
322 (python-tests-look-at "# yeah, that.")
323 (should (eq (car (python-indent-context)) :after-line))
324 (should (= (python-indent-calculate-indentation) 0))))
325
326 (ert-deftest python-indent-inside-paren-1 ()
327 "The most simple inside-paren case that shouldn't fail."
328 (python-tests-with-temp-buffer
329 "
330 data = {
331 'key':
332 {
333 'objlist': [
334 {
335 'pk': 1,
336 'name': 'first',
337 },
338 {
339 'pk': 2,
340 'name': 'second',
341 }
342 ]
343 }
344 }
345 "
346 (python-tests-look-at "data = {")
347 (should (eq (car (python-indent-context)) :after-line))
348 (should (= (python-indent-calculate-indentation) 0))
349 (python-tests-look-at "'key':")
350 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
351 (should (= (python-indent-calculate-indentation) 4))
352 (python-tests-look-at "{")
353 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
354 (should (= (python-indent-calculate-indentation) 4))
355 (python-tests-look-at "'objlist': [")
356 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
357 (should (= (python-indent-calculate-indentation) 8))
358 (python-tests-look-at "{")
359 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
360 (should (= (python-indent-calculate-indentation) 12))
361 (python-tests-look-at "'pk': 1,")
362 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
363 (should (= (python-indent-calculate-indentation) 16))
364 (python-tests-look-at "'name': 'first',")
365 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
366 (should (= (python-indent-calculate-indentation) 16))
367 (python-tests-look-at "},")
368 (should (eq (car (python-indent-context))
369 :inside-paren-at-closing-nested-paren))
370 (should (= (python-indent-calculate-indentation) 12))
371 (python-tests-look-at "{")
372 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
373 (should (= (python-indent-calculate-indentation) 12))
374 (python-tests-look-at "'pk': 2,")
375 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
376 (should (= (python-indent-calculate-indentation) 16))
377 (python-tests-look-at "'name': 'second',")
378 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
379 (should (= (python-indent-calculate-indentation) 16))
380 (python-tests-look-at "}")
381 (should (eq (car (python-indent-context))
382 :inside-paren-at-closing-nested-paren))
383 (should (= (python-indent-calculate-indentation) 12))
384 (python-tests-look-at "]")
385 (should (eq (car (python-indent-context))
386 :inside-paren-at-closing-nested-paren))
387 (should (= (python-indent-calculate-indentation) 8))
388 (python-tests-look-at "}")
389 (should (eq (car (python-indent-context))
390 :inside-paren-at-closing-nested-paren))
391 (should (= (python-indent-calculate-indentation) 4))
392 (python-tests-look-at "}")
393 (should (eq (car (python-indent-context)) :inside-paren-at-closing-paren))
394 (should (= (python-indent-calculate-indentation) 0))))
395
396 (ert-deftest python-indent-inside-paren-2 ()
397 "Another more compact paren group style."
398 (python-tests-with-temp-buffer
399 "
400 data = {'key': {
401 'objlist': [
402 {'pk': 1,
403 'name': 'first'},
404 {'pk': 2,
405 'name': 'second'}
406 ]
407 }}
408 "
409 (python-tests-look-at "data = {")
410 (should (eq (car (python-indent-context)) :after-line))
411 (should (= (python-indent-calculate-indentation) 0))
412 (python-tests-look-at "'objlist': [")
413 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
414 (should (= (python-indent-calculate-indentation) 4))
415 (python-tests-look-at "{'pk': 1,")
416 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
417 (should (= (python-indent-calculate-indentation) 8))
418 (python-tests-look-at "'name': 'first'},")
419 (should (eq (car (python-indent-context)) :inside-paren))
420 (should (= (python-indent-calculate-indentation) 9))
421 (python-tests-look-at "{'pk': 2,")
422 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
423 (should (= (python-indent-calculate-indentation) 8))
424 (python-tests-look-at "'name': 'second'}")
425 (should (eq (car (python-indent-context)) :inside-paren))
426 (should (= (python-indent-calculate-indentation) 9))
427 (python-tests-look-at "]")
428 (should (eq (car (python-indent-context))
429 :inside-paren-at-closing-nested-paren))
430 (should (= (python-indent-calculate-indentation) 4))
431 (python-tests-look-at "}}")
432 (should (eq (car (python-indent-context))
433 :inside-paren-at-closing-nested-paren))
434 (should (= (python-indent-calculate-indentation) 0))
435 (python-tests-look-at "}")
436 (should (eq (car (python-indent-context)) :inside-paren-at-closing-paren))
437 (should (= (python-indent-calculate-indentation) 0))))
438
439 (ert-deftest python-indent-inside-paren-3 ()
440 "The simplest case possible."
441 (python-tests-with-temp-buffer
442 "
443 data = ('these',
444 'are',
445 'the',
446 'tokens')
447 "
448 (python-tests-look-at "data = ('these',")
449 (should (eq (car (python-indent-context)) :after-line))
450 (should (= (python-indent-calculate-indentation) 0))
451 (forward-line 1)
452 (should (eq (car (python-indent-context)) :inside-paren))
453 (should (= (python-indent-calculate-indentation) 8))
454 (forward-line 1)
455 (should (eq (car (python-indent-context)) :inside-paren))
456 (should (= (python-indent-calculate-indentation) 8))
457 (forward-line 1)
458 (should (eq (car (python-indent-context)) :inside-paren))
459 (should (= (python-indent-calculate-indentation) 8))))
460
461 (ert-deftest python-indent-inside-paren-4 ()
462 "Respect indentation of first column."
463 (python-tests-with-temp-buffer
464 "
465 data = [ [ 'these', 'are'],
466 ['the', 'tokens' ] ]
467 "
468 (python-tests-look-at "data = [ [ 'these', 'are'],")
469 (should (eq (car (python-indent-context)) :after-line))
470 (should (= (python-indent-calculate-indentation) 0))
471 (forward-line 1)
472 (should (eq (car (python-indent-context)) :inside-paren))
473 (should (= (python-indent-calculate-indentation) 9))))
474
475 (ert-deftest python-indent-inside-paren-5 ()
476 "Test when :inside-paren initial parens are skipped in context start."
477 (python-tests-with-temp-buffer
478 "
479 while ((not some_condition) and
480 another_condition):
481 do_something_interesting(
482 with_some_arg)
483 "
484 (python-tests-look-at "while ((not some_condition) and")
485 (should (eq (car (python-indent-context)) :after-line))
486 (should (= (python-indent-calculate-indentation) 0))
487 (forward-line 1)
488 (should (eq (car (python-indent-context)) :inside-paren))
489 (should (= (python-indent-calculate-indentation) 7))
490 (forward-line 1)
491 (should (eq (car (python-indent-context)) :after-block-start))
492 (should (= (python-indent-calculate-indentation) 4))
493 (forward-line 1)
494 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
495 (should (= (python-indent-calculate-indentation) 8))))
496
497 (ert-deftest python-indent-inside-paren-6 ()
498 "This should be aligned.."
499 (python-tests-with-temp-buffer
500 "
501 CHOICES = (('some', 'choice'),
502 ('another', 'choice'),
503 ('more', 'choices'))
504 "
505 (python-tests-look-at "CHOICES = (('some', 'choice'),")
506 (should (eq (car (python-indent-context)) :after-line))
507 (should (= (python-indent-calculate-indentation) 0))
508 (forward-line 1)
509 (should (eq (car (python-indent-context)) :inside-paren))
510 (should (= (python-indent-calculate-indentation) 11))
511 (forward-line 1)
512 (should (eq (car (python-indent-context)) :inside-paren))
513 (should (= (python-indent-calculate-indentation) 11))))
514
515 (ert-deftest python-indent-after-block-1 ()
516 "The most simple after-block case that shouldn't fail."
517 (python-tests-with-temp-buffer
518 "
519 def foo(a, b, c=True):
520 "
521 (should (eq (car (python-indent-context)) :no-indent))
522 (should (= (python-indent-calculate-indentation) 0))
523 (goto-char (point-max))
524 (should (eq (car (python-indent-context)) :after-block-start))
525 (should (= (python-indent-calculate-indentation) 4))))
526
527 (ert-deftest python-indent-after-block-2 ()
528 "A weird (malformed) multiline block statement."
529 (python-tests-with-temp-buffer
530 "
531 def foo(a, b, c={
532 'a':
533 }):
534 "
535 (goto-char (point-max))
536 (should (eq (car (python-indent-context)) :after-block-start))
537 (should (= (python-indent-calculate-indentation) 4))))
538
539 (ert-deftest python-indent-after-block-3 ()
540 "A weird (malformed) sample, usually found in python shells."
541 (python-tests-with-temp-buffer
542 "
543 In [1]:
544 def func():
545 pass
546
547 In [2]:
548 something
549 "
550 (python-tests-look-at "pass")
551 (should (eq (car (python-indent-context)) :after-block-start))
552 (should (= (python-indent-calculate-indentation) 4))
553 (python-tests-look-at "something")
554 (end-of-line)
555 (should (eq (car (python-indent-context)) :after-line))
556 (should (= (python-indent-calculate-indentation) 0))))
557
558 (ert-deftest python-indent-after-backslash-1 ()
559 "The most common case."
560 (python-tests-with-temp-buffer
561 "
562 from foo.bar.baz import something, something_1 \\\\
563 something_2 something_3, \\\\
564 something_4, something_5
565 "
566 (python-tests-look-at "from foo.bar.baz import something, something_1")
567 (should (eq (car (python-indent-context)) :after-line))
568 (should (= (python-indent-calculate-indentation) 0))
569 (python-tests-look-at "something_2 something_3,")
570 (should (eq (car (python-indent-context)) :after-backslash-first-line))
571 (should (= (python-indent-calculate-indentation) 4))
572 (python-tests-look-at "something_4, something_5")
573 (should (eq (car (python-indent-context)) :after-backslash))
574 (should (= (python-indent-calculate-indentation) 4))
575 (goto-char (point-max))
576 (should (eq (car (python-indent-context)) :after-line))
577 (should (= (python-indent-calculate-indentation) 0))))
578
579 (ert-deftest python-indent-after-backslash-2 ()
580 "A pretty extreme complicated case."
581 (python-tests-with-temp-buffer
582 "
583 objects = Thing.objects.all() \\\\
584 .filter(
585 type='toy',
586 status='bought'
587 ) \\\\
588 .aggregate(
589 Sum('amount')
590 ) \\\\
591 .values_list()
592 "
593 (python-tests-look-at "objects = Thing.objects.all()")
594 (should (eq (car (python-indent-context)) :after-line))
595 (should (= (python-indent-calculate-indentation) 0))
596 (python-tests-look-at ".filter(")
597 (should (eq (car (python-indent-context))
598 :after-backslash-dotted-continuation))
599 (should (= (python-indent-calculate-indentation) 23))
600 (python-tests-look-at "type='toy',")
601 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
602 (should (= (python-indent-calculate-indentation) 27))
603 (python-tests-look-at "status='bought'")
604 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
605 (should (= (python-indent-calculate-indentation) 27))
606 (python-tests-look-at ") \\\\")
607 (should (eq (car (python-indent-context)) :inside-paren-at-closing-paren))
608 (should (= (python-indent-calculate-indentation) 23))
609 (python-tests-look-at ".aggregate(")
610 (should (eq (car (python-indent-context))
611 :after-backslash-dotted-continuation))
612 (should (= (python-indent-calculate-indentation) 23))
613 (python-tests-look-at "Sum('amount')")
614 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
615 (should (= (python-indent-calculate-indentation) 27))
616 (python-tests-look-at ") \\\\")
617 (should (eq (car (python-indent-context)) :inside-paren-at-closing-paren))
618 (should (= (python-indent-calculate-indentation) 23))
619 (python-tests-look-at ".values_list()")
620 (should (eq (car (python-indent-context))
621 :after-backslash-dotted-continuation))
622 (should (= (python-indent-calculate-indentation) 23))
623 (forward-line 1)
624 (should (eq (car (python-indent-context)) :after-line))
625 (should (= (python-indent-calculate-indentation) 0))))
626
627 (ert-deftest python-indent-after-backslash-3 ()
628 "Backslash continuation from block start."
629 (python-tests-with-temp-buffer
630 "
631 with open('/path/to/some/file/you/want/to/read') as file_1, \\\\
632 open('/path/to/some/file/being/written', 'w') as file_2:
633 file_2.write(file_1.read())
634 "
635 (python-tests-look-at
636 "with open('/path/to/some/file/you/want/to/read') as file_1, \\\\")
637 (should (eq (car (python-indent-context)) :after-line))
638 (should (= (python-indent-calculate-indentation) 0))
639 (python-tests-look-at
640 "open('/path/to/some/file/being/written', 'w') as file_2")
641 (should (eq (car (python-indent-context))
642 :after-backslash-block-continuation))
643 (should (= (python-indent-calculate-indentation) 5))
644 (python-tests-look-at "file_2.write(file_1.read())")
645 (should (eq (car (python-indent-context)) :after-block-start))
646 (should (= (python-indent-calculate-indentation) 4))))
647
648 (ert-deftest python-indent-after-backslash-4 ()
649 "Backslash continuation from assignment."
650 (python-tests-with-temp-buffer
651 "
652 super_awful_assignment = some_calculation() and \\\\
653 another_calculation() and \\\\
654 some_final_calculation()
655 "
656 (python-tests-look-at
657 "super_awful_assignment = some_calculation() and \\\\")
658 (should (eq (car (python-indent-context)) :after-line))
659 (should (= (python-indent-calculate-indentation) 0))
660 (python-tests-look-at "another_calculation() and \\\\")
661 (should (eq (car (python-indent-context))
662 :after-backslash-assignment-continuation))
663 (should (= (python-indent-calculate-indentation) 25))
664 (python-tests-look-at "some_final_calculation()")
665 (should (eq (car (python-indent-context)) :after-backslash))
666 (should (= (python-indent-calculate-indentation) 25))))
667
668 (ert-deftest python-indent-after-backslash-5 ()
669 "Dotted continuation bizarre example."
670 (python-tests-with-temp-buffer
671 "
672 def delete_all_things():
673 Thing \\\\
674 .objects.all() \\\\
675 .delete()
676 "
677 (python-tests-look-at "Thing \\\\")
678 (should (eq (car (python-indent-context)) :after-block-start))
679 (should (= (python-indent-calculate-indentation) 4))
680 (python-tests-look-at ".objects.all() \\\\")
681 (should (eq (car (python-indent-context)) :after-backslash-first-line))
682 (should (= (python-indent-calculate-indentation) 8))
683 (python-tests-look-at ".delete()")
684 (should (eq (car (python-indent-context))
685 :after-backslash-dotted-continuation))
686 (should (= (python-indent-calculate-indentation) 16))))
687
688 (ert-deftest python-indent-block-enders-1 ()
689 "Test de-indentation for pass keyword."
690 (python-tests-with-temp-buffer
691 "
692 Class foo(object):
693
694 def bar(self):
695 if self.baz:
696 return (1,
697 2,
698 3)
699
700 else:
701 pass
702 "
703 (python-tests-look-at "3)")
704 (forward-line 1)
705 (should (= (python-indent-calculate-indentation) 8))
706 (python-tests-look-at "pass")
707 (forward-line 1)
708 (should (eq (car (python-indent-context)) :after-block-end))
709 (should (= (python-indent-calculate-indentation) 8))))
710
711 (ert-deftest python-indent-block-enders-2 ()
712 "Test de-indentation for return keyword."
713 (python-tests-with-temp-buffer
714 "
715 Class foo(object):
716 '''raise lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
717
718 eiusmod tempor incididunt ut labore et dolore magna aliqua.
719 '''
720 def bar(self):
721 \"return (1, 2, 3).\"
722 if self.baz:
723 return (1,
724 2,
725 3)
726 "
727 (python-tests-look-at "def")
728 (should (= (python-indent-calculate-indentation) 4))
729 (python-tests-look-at "if")
730 (should (= (python-indent-calculate-indentation) 8))
731 (python-tests-look-at "return")
732 (should (= (python-indent-calculate-indentation) 12))
733 (goto-char (point-max))
734 (should (eq (car (python-indent-context)) :after-block-end))
735 (should (= (python-indent-calculate-indentation) 8))))
736
737 (ert-deftest python-indent-block-enders-3 ()
738 "Test de-indentation for continue keyword."
739 (python-tests-with-temp-buffer
740 "
741 for element in lst:
742 if element is None:
743 continue
744 "
745 (python-tests-look-at "if")
746 (should (= (python-indent-calculate-indentation) 4))
747 (python-tests-look-at "continue")
748 (should (= (python-indent-calculate-indentation) 8))
749 (forward-line 1)
750 (should (eq (car (python-indent-context)) :after-block-end))
751 (should (= (python-indent-calculate-indentation) 4))))
752
753 (ert-deftest python-indent-block-enders-4 ()
754 "Test de-indentation for break keyword."
755 (python-tests-with-temp-buffer
756 "
757 for element in lst:
758 if element is None:
759 break
760 "
761 (python-tests-look-at "if")
762 (should (= (python-indent-calculate-indentation) 4))
763 (python-tests-look-at "break")
764 (should (= (python-indent-calculate-indentation) 8))
765 (forward-line 1)
766 (should (eq (car (python-indent-context)) :after-block-end))
767 (should (= (python-indent-calculate-indentation) 4))))
768
769 (ert-deftest python-indent-block-enders-5 ()
770 "Test de-indentation for raise keyword."
771 (python-tests-with-temp-buffer
772 "
773 for element in lst:
774 if element is None:
775 raise ValueError('Element cannot be None')
776 "
777 (python-tests-look-at "if")
778 (should (= (python-indent-calculate-indentation) 4))
779 (python-tests-look-at "raise")
780 (should (= (python-indent-calculate-indentation) 8))
781 (forward-line 1)
782 (should (eq (car (python-indent-context)) :after-block-end))
783 (should (= (python-indent-calculate-indentation) 4))))
784
785 (ert-deftest python-indent-dedenters-1 ()
786 "Test de-indentation for the elif keyword."
787 (python-tests-with-temp-buffer
788 "
789 if save:
790 try:
791 write_to_disk(data)
792 finally:
793 cleanup()
794 elif
795 "
796 (python-tests-look-at "elif\n")
797 (should (eq (car (python-indent-context)) :at-dedenter-block-start))
798 (should (= (python-indent-calculate-indentation) 0))
799 (should (= (python-indent-calculate-indentation t) 0))))
800
801 (ert-deftest python-indent-dedenters-2 ()
802 "Test de-indentation for the else keyword."
803 (python-tests-with-temp-buffer
804 "
805 if save:
806 try:
807 write_to_disk(data)
808 except IOError:
809 msg = 'Error saving to disk'
810 message(msg)
811 logger.exception(msg)
812 except Exception:
813 if hide_details:
814 logger.exception('Unhandled exception')
815 else
816 finally:
817 data.free()
818 "
819 (python-tests-look-at "else\n")
820 (should (eq (car (python-indent-context)) :at-dedenter-block-start))
821 (should (= (python-indent-calculate-indentation) 8))
822 (python-indent-line t)
823 (should (= (python-indent-calculate-indentation t) 4))
824 (python-indent-line t)
825 (should (= (python-indent-calculate-indentation t) 0))
826 (python-indent-line t)
827 (should (= (python-indent-calculate-indentation t) 8))))
828
829 (ert-deftest python-indent-dedenters-3 ()
830 "Test de-indentation for the except keyword."
831 (python-tests-with-temp-buffer
832 "
833 if save:
834 try:
835 write_to_disk(data)
836 except
837 "
838 (python-tests-look-at "except\n")
839 (should (eq (car (python-indent-context)) :at-dedenter-block-start))
840 (should (= (python-indent-calculate-indentation) 4))
841 (python-indent-line t)
842 (should (= (python-indent-calculate-indentation t) 4))))
843
844 (ert-deftest python-indent-dedenters-4 ()
845 "Test de-indentation for the finally keyword."
846 (python-tests-with-temp-buffer
847 "
848 if save:
849 try:
850 write_to_disk(data)
851 finally
852 "
853 (python-tests-look-at "finally\n")
854 (should (eq (car (python-indent-context)) :at-dedenter-block-start))
855 (should (= (python-indent-calculate-indentation) 4))
856 (python-indent-line t)
857 (should (= (python-indent-calculate-indentation) 4))))
858
859 (ert-deftest python-indent-dedenters-5 ()
860 "Test invalid levels are skipped in a complex example."
861 (python-tests-with-temp-buffer
862 "
863 if save:
864 try:
865 write_to_disk(data)
866 except IOError:
867 msg = 'Error saving to disk'
868 message(msg)
869 logger.exception(msg)
870 finally:
871 if cleanup:
872 do_cleanup()
873 else
874 "
875 (python-tests-look-at "else\n")
876 (should (eq (car (python-indent-context)) :at-dedenter-block-start))
877 (should (= (python-indent-calculate-indentation) 8))
878 (should (= (python-indent-calculate-indentation t) 0))
879 (python-indent-line t)
880 (should (= (python-indent-calculate-indentation t) 8))))
881
882 (ert-deftest python-indent-dedenters-6 ()
883 "Test indentation is zero when no opening block for dedenter."
884 (python-tests-with-temp-buffer
885 "
886 try:
887 # if save:
888 write_to_disk(data)
889 else
890 "
891 (python-tests-look-at "else\n")
892 (should (eq (car (python-indent-context)) :at-dedenter-block-start))
893 (should (= (python-indent-calculate-indentation) 0))
894 (should (= (python-indent-calculate-indentation t) 0))))
895
896 (ert-deftest python-indent-dedenters-7 ()
897 "Test indentation case from Bug#15163."
898 (python-tests-with-temp-buffer
899 "
900 if a:
901 if b:
902 pass
903 else:
904 pass
905 else:
906 "
907 (python-tests-look-at "else:" 2)
908 (should (eq (car (python-indent-context)) :at-dedenter-block-start))
909 (should (= (python-indent-calculate-indentation) 0))
910 (should (= (python-indent-calculate-indentation t) 0))))
911
912 (ert-deftest python-indent-dedenters-8 ()
913 "Test indentation for Bug#18432."
914 (python-tests-with-temp-buffer
915 "
916 if (a == 1 or
917 a == 2):
918 pass
919 elif (a == 3 or
920 a == 4):
921 "
922 (python-tests-look-at "elif (a == 3 or")
923 (should (eq (car (python-indent-context)) :at-dedenter-block-start))
924 (should (= (python-indent-calculate-indentation) 0))
925 (should (= (python-indent-calculate-indentation t) 0))
926 (python-tests-look-at "a == 4):\n")
927 (should (eq (car (python-indent-context)) :inside-paren))
928 (should (= (python-indent-calculate-indentation) 6))
929 (python-indent-line)
930 (should (= (python-indent-calculate-indentation t) 4))
931 (python-indent-line t)
932 (should (= (python-indent-calculate-indentation t) 0))
933 (python-indent-line t)
934 (should (= (python-indent-calculate-indentation t) 6))))
935
936 (ert-deftest python-indent-inside-string-1 ()
937 "Test indentation for strings."
938 (python-tests-with-temp-buffer
939 "
940 multiline = '''
941 bunch
942 of
943 lines
944 '''
945 "
946 (python-tests-look-at "multiline = '''")
947 (should (eq (car (python-indent-context)) :after-line))
948 (should (= (python-indent-calculate-indentation) 0))
949 (python-tests-look-at "bunch")
950 (should (eq (car (python-indent-context)) :inside-string))
951 (should (= (python-indent-calculate-indentation) 0))
952 (python-tests-look-at "of")
953 (should (eq (car (python-indent-context)) :inside-string))
954 (should (= (python-indent-calculate-indentation) 0))
955 (python-tests-look-at "lines")
956 (should (eq (car (python-indent-context)) :inside-string))
957 (should (= (python-indent-calculate-indentation) 0))
958 (python-tests-look-at "'''")
959 (should (eq (car (python-indent-context)) :inside-string))
960 (should (= (python-indent-calculate-indentation) 0))))
961
962 (ert-deftest python-indent-inside-string-2 ()
963 "Test indentation for docstrings."
964 (python-tests-with-temp-buffer
965 "
966 def fn(a, b, c=True):
967 '''docstring
968 bunch
969 of
970 lines
971 '''
972 "
973 (python-tests-look-at "'''docstring")
974 (should (eq (car (python-indent-context)) :after-block-start))
975 (should (= (python-indent-calculate-indentation) 4))
976 (python-tests-look-at "bunch")
977 (should (eq (car (python-indent-context)) :inside-string))
978 (should (= (python-indent-calculate-indentation) 4))
979 (python-tests-look-at "of")
980 (should (eq (car (python-indent-context)) :inside-string))
981 (should (= (python-indent-calculate-indentation) 4))
982 (python-tests-look-at "lines")
983 (should (eq (car (python-indent-context)) :inside-string))
984 (should (= (python-indent-calculate-indentation) 4))
985 (python-tests-look-at "'''")
986 (should (eq (car (python-indent-context)) :inside-string))
987 (should (= (python-indent-calculate-indentation) 4))))
988
989 (ert-deftest python-indent-inside-string-3 ()
990 "Test indentation for nested strings."
991 (python-tests-with-temp-buffer
992 "
993 def fn(a, b, c=True):
994 some_var = '''
995 bunch
996 of
997 lines
998 '''
999 "
1000 (python-tests-look-at "some_var = '''")
1001 (should (eq (car (python-indent-context)) :after-block-start))
1002 (should (= (python-indent-calculate-indentation) 4))
1003 (python-tests-look-at "bunch")
1004 (should (eq (car (python-indent-context)) :inside-string))
1005 (should (= (python-indent-calculate-indentation) 4))
1006 (python-tests-look-at "of")
1007 (should (eq (car (python-indent-context)) :inside-string))
1008 (should (= (python-indent-calculate-indentation) 4))
1009 (python-tests-look-at "lines")
1010 (should (eq (car (python-indent-context)) :inside-string))
1011 (should (= (python-indent-calculate-indentation) 4))
1012 (python-tests-look-at "'''")
1013 (should (eq (car (python-indent-context)) :inside-string))
1014 (should (= (python-indent-calculate-indentation) 4))))
1015
1016 (ert-deftest python-indent-electric-colon-1 ()
1017 "Test indentation case from Bug#18228."
1018 (python-tests-with-temp-buffer
1019 "
1020 def a():
1021 pass
1022
1023 def b()
1024 "
1025 (python-tests-look-at "def b()")
1026 (goto-char (line-end-position))
1027 (python-tests-self-insert ":")
1028 (should (= (current-indentation) 0))))
1029
1030 (ert-deftest python-indent-electric-colon-2 ()
1031 "Test indentation case for dedenter."
1032 (python-tests-with-temp-buffer
1033 "
1034 if do:
1035 something()
1036 else
1037 "
1038 (python-tests-look-at "else")
1039 (goto-char (line-end-position))
1040 (python-tests-self-insert ":")
1041 (should (= (current-indentation) 0))))
1042
1043 (ert-deftest python-indent-electric-colon-3 ()
1044 "Test indentation case for multi-line dedenter."
1045 (python-tests-with-temp-buffer
1046 "
1047 if do:
1048 something()
1049 elif (this
1050 and
1051 that)
1052 "
1053 (python-tests-look-at "that)")
1054 (goto-char (line-end-position))
1055 (python-tests-self-insert ":")
1056 (python-tests-look-at "elif" -1)
1057 (should (= (current-indentation) 0))
1058 (python-tests-look-at "and")
1059 (should (= (current-indentation) 6))
1060 (python-tests-look-at "that)")
1061 (should (= (current-indentation) 6))))
1062
1063 (ert-deftest python-indent-region-1 ()
1064 "Test indentation case from Bug#18843."
1065 (let ((contents "
1066 def foo ():
1067 try:
1068 pass
1069 except:
1070 pass
1071 "))
1072 (python-tests-with-temp-buffer
1073 contents
1074 (python-indent-region (point-min) (point-max))
1075 (should (string= (buffer-substring-no-properties (point-min) (point-max))
1076 contents)))))
1077
1078 (ert-deftest python-indent-region-2 ()
1079 "Test region indentation on comments."
1080 (let ((contents "
1081 def f():
1082 if True:
1083 pass
1084
1085 # This is
1086 # some multiline
1087 # comment
1088 "))
1089 (python-tests-with-temp-buffer
1090 contents
1091 (python-indent-region (point-min) (point-max))
1092 (should (string= (buffer-substring-no-properties (point-min) (point-max))
1093 contents)))))
1094
1095 (ert-deftest python-indent-region-3 ()
1096 "Test region indentation on comments."
1097 (let ((contents "
1098 def f():
1099 if True:
1100 pass
1101 # This is
1102 # some multiline
1103 # comment
1104 ")
1105 (expected "
1106 def f():
1107 if True:
1108 pass
1109 # This is
1110 # some multiline
1111 # comment
1112 "))
1113 (python-tests-with-temp-buffer
1114 contents
1115 (python-indent-region (point-min) (point-max))
1116 (should (string= (buffer-substring-no-properties (point-min) (point-max))
1117 expected)))))
1118
1119 (ert-deftest python-indent-region-4 ()
1120 "Test region indentation block starts, dedenters and enders."
1121 (let ((contents "
1122 def f():
1123 if True:
1124 a = 5
1125 else:
1126 a = 10
1127 return a
1128 ")
1129 (expected "
1130 def f():
1131 if True:
1132 a = 5
1133 else:
1134 a = 10
1135 return a
1136 "))
1137 (python-tests-with-temp-buffer
1138 contents
1139 (python-indent-region (point-min) (point-max))
1140 (should (string= (buffer-substring-no-properties (point-min) (point-max))
1141 expected)))))
1142
1143 (ert-deftest python-indent-region-5 ()
1144 "Test region indentation leaves strings untouched (start delimiter)."
1145 (let ((contents "
1146 def f():
1147 '''
1148 this is
1149 a multiline
1150 string
1151 '''
1152 ")
1153 (expected "
1154 def f():
1155 '''
1156 this is
1157 a multiline
1158 string
1159 '''
1160 "))
1161 (python-tests-with-temp-buffer
1162 contents
1163 (python-indent-region (point-min) (point-max))
1164 (should (string= (buffer-substring-no-properties (point-min) (point-max))
1165 expected)))))
1166
1167 \f
1168 ;;; Navigation
1169
1170 (ert-deftest python-nav-beginning-of-defun-1 ()
1171 (python-tests-with-temp-buffer
1172 "
1173 def decoratorFunctionWithArguments(arg1, arg2, arg3):
1174 '''print decorated function call data to stdout.
1175
1176 Usage:
1177
1178 @decoratorFunctionWithArguments('arg1', 'arg2')
1179 def func(a, b, c=True):
1180 pass
1181 '''
1182
1183 def wwrap(f):
1184 print 'Inside wwrap()'
1185 def wrapped_f(*args):
1186 print 'Inside wrapped_f()'
1187 print 'Decorator arguments:', arg1, arg2, arg3
1188 f(*args)
1189 print 'After f(*args)'
1190 return wrapped_f
1191 return wwrap
1192 "
1193 (python-tests-look-at "return wrap")
1194 (should (= (save-excursion
1195 (python-nav-beginning-of-defun)
1196 (point))
1197 (save-excursion
1198 (python-tests-look-at "def wrapped_f(*args):" -1)
1199 (beginning-of-line)
1200 (point))))
1201 (python-tests-look-at "def wrapped_f(*args):" -1)
1202 (should (= (save-excursion
1203 (python-nav-beginning-of-defun)
1204 (point))
1205 (save-excursion
1206 (python-tests-look-at "def wwrap(f):" -1)
1207 (beginning-of-line)
1208 (point))))
1209 (python-tests-look-at "def wwrap(f):" -1)
1210 (should (= (save-excursion
1211 (python-nav-beginning-of-defun)
1212 (point))
1213 (save-excursion
1214 (python-tests-look-at "def decoratorFunctionWithArguments" -1)
1215 (beginning-of-line)
1216 (point))))))
1217
1218 (ert-deftest python-nav-beginning-of-defun-2 ()
1219 (python-tests-with-temp-buffer
1220 "
1221 class C(object):
1222
1223 def m(self):
1224 self.c()
1225
1226 def b():
1227 pass
1228
1229 def a():
1230 pass
1231
1232 def c(self):
1233 pass
1234 "
1235 ;; Nested defuns, are handled with care.
1236 (python-tests-look-at "def c(self):")
1237 (should (= (save-excursion
1238 (python-nav-beginning-of-defun)
1239 (point))
1240 (save-excursion
1241 (python-tests-look-at "def m(self):" -1)
1242 (beginning-of-line)
1243 (point))))
1244 ;; Defuns on same levels should be respected.
1245 (python-tests-look-at "def a():" -1)
1246 (should (= (save-excursion
1247 (python-nav-beginning-of-defun)
1248 (point))
1249 (save-excursion
1250 (python-tests-look-at "def b():" -1)
1251 (beginning-of-line)
1252 (point))))
1253 ;; Jump to a top level defun.
1254 (python-tests-look-at "def b():" -1)
1255 (should (= (save-excursion
1256 (python-nav-beginning-of-defun)
1257 (point))
1258 (save-excursion
1259 (python-tests-look-at "def m(self):" -1)
1260 (beginning-of-line)
1261 (point))))
1262 ;; Jump to a top level defun again.
1263 (python-tests-look-at "def m(self):" -1)
1264 (should (= (save-excursion
1265 (python-nav-beginning-of-defun)
1266 (point))
1267 (save-excursion
1268 (python-tests-look-at "class C(object):" -1)
1269 (beginning-of-line)
1270 (point))))))
1271
1272 (ert-deftest python-nav-end-of-defun-1 ()
1273 (python-tests-with-temp-buffer
1274 "
1275 class C(object):
1276
1277 def m(self):
1278 self.c()
1279
1280 def b():
1281 pass
1282
1283 def a():
1284 pass
1285
1286 def c(self):
1287 pass
1288 "
1289 (should (= (save-excursion
1290 (python-tests-look-at "class C(object):")
1291 (python-nav-end-of-defun)
1292 (point))
1293 (save-excursion
1294 (point-max))))
1295 (should (= (save-excursion
1296 (python-tests-look-at "def m(self):")
1297 (python-nav-end-of-defun)
1298 (point))
1299 (save-excursion
1300 (python-tests-look-at "def c(self):")
1301 (forward-line -1)
1302 (point))))
1303 (should (= (save-excursion
1304 (python-tests-look-at "def b():")
1305 (python-nav-end-of-defun)
1306 (point))
1307 (save-excursion
1308 (python-tests-look-at "def b():")
1309 (forward-line 2)
1310 (point))))
1311 (should (= (save-excursion
1312 (python-tests-look-at "def c(self):")
1313 (python-nav-end-of-defun)
1314 (point))
1315 (save-excursion
1316 (point-max))))))
1317
1318 (ert-deftest python-nav-end-of-defun-2 ()
1319 (python-tests-with-temp-buffer
1320 "
1321 def decoratorFunctionWithArguments(arg1, arg2, arg3):
1322 '''print decorated function call data to stdout.
1323
1324 Usage:
1325
1326 @decoratorFunctionWithArguments('arg1', 'arg2')
1327 def func(a, b, c=True):
1328 pass
1329 '''
1330
1331 def wwrap(f):
1332 print 'Inside wwrap()'
1333 def wrapped_f(*args):
1334 print 'Inside wrapped_f()'
1335 print 'Decorator arguments:', arg1, arg2, arg3
1336 f(*args)
1337 print 'After f(*args)'
1338 return wrapped_f
1339 return wwrap
1340 "
1341 (should (= (save-excursion
1342 (python-tests-look-at "def decoratorFunctionWithArguments")
1343 (python-nav-end-of-defun)
1344 (point))
1345 (save-excursion
1346 (point-max))))
1347 (should (= (save-excursion
1348 (python-tests-look-at "@decoratorFunctionWithArguments")
1349 (python-nav-end-of-defun)
1350 (point))
1351 (save-excursion
1352 (point-max))))
1353 (should (= (save-excursion
1354 (python-tests-look-at "def wwrap(f):")
1355 (python-nav-end-of-defun)
1356 (point))
1357 (save-excursion
1358 (python-tests-look-at "return wwrap")
1359 (line-beginning-position))))
1360 (should (= (save-excursion
1361 (python-tests-look-at "def wrapped_f(*args):")
1362 (python-nav-end-of-defun)
1363 (point))
1364 (save-excursion
1365 (python-tests-look-at "return wrapped_f")
1366 (line-beginning-position))))
1367 (should (= (save-excursion
1368 (python-tests-look-at "f(*args)")
1369 (python-nav-end-of-defun)
1370 (point))
1371 (save-excursion
1372 (python-tests-look-at "return wrapped_f")
1373 (line-beginning-position))))))
1374
1375 (ert-deftest python-nav-backward-defun-1 ()
1376 (python-tests-with-temp-buffer
1377 "
1378 class A(object): # A
1379
1380 def a(self): # a
1381 pass
1382
1383 def b(self): # b
1384 pass
1385
1386 class B(object): # B
1387
1388 class C(object): # C
1389
1390 def d(self): # d
1391 pass
1392
1393 # def e(self): # e
1394 # pass
1395
1396 def c(self): # c
1397 pass
1398
1399 # def d(self): # d
1400 # pass
1401 "
1402 (goto-char (point-max))
1403 (should (= (save-excursion (python-nav-backward-defun))
1404 (python-tests-look-at " def c(self): # c" -1)))
1405 (should (= (save-excursion (python-nav-backward-defun))
1406 (python-tests-look-at " def d(self): # d" -1)))
1407 (should (= (save-excursion (python-nav-backward-defun))
1408 (python-tests-look-at " class C(object): # C" -1)))
1409 (should (= (save-excursion (python-nav-backward-defun))
1410 (python-tests-look-at " class B(object): # B" -1)))
1411 (should (= (save-excursion (python-nav-backward-defun))
1412 (python-tests-look-at " def b(self): # b" -1)))
1413 (should (= (save-excursion (python-nav-backward-defun))
1414 (python-tests-look-at " def a(self): # a" -1)))
1415 (should (= (save-excursion (python-nav-backward-defun))
1416 (python-tests-look-at "class A(object): # A" -1)))
1417 (should (not (python-nav-backward-defun)))))
1418
1419 (ert-deftest python-nav-backward-defun-2 ()
1420 (python-tests-with-temp-buffer
1421 "
1422 def decoratorFunctionWithArguments(arg1, arg2, arg3):
1423 '''print decorated function call data to stdout.
1424
1425 Usage:
1426
1427 @decoratorFunctionWithArguments('arg1', 'arg2')
1428 def func(a, b, c=True):
1429 pass
1430 '''
1431
1432 def wwrap(f):
1433 print 'Inside wwrap()'
1434 def wrapped_f(*args):
1435 print 'Inside wrapped_f()'
1436 print 'Decorator arguments:', arg1, arg2, arg3
1437 f(*args)
1438 print 'After f(*args)'
1439 return wrapped_f
1440 return wwrap
1441 "
1442 (goto-char (point-max))
1443 (should (= (save-excursion (python-nav-backward-defun))
1444 (python-tests-look-at " def wrapped_f(*args):" -1)))
1445 (should (= (save-excursion (python-nav-backward-defun))
1446 (python-tests-look-at " def wwrap(f):" -1)))
1447 (should (= (save-excursion (python-nav-backward-defun))
1448 (python-tests-look-at "def decoratorFunctionWithArguments(arg1, arg2, arg3):" -1)))
1449 (should (not (python-nav-backward-defun)))))
1450
1451 (ert-deftest python-nav-backward-defun-3 ()
1452 (python-tests-with-temp-buffer
1453 "
1454 '''
1455 def u(self):
1456 pass
1457
1458 def v(self):
1459 pass
1460
1461 def w(self):
1462 pass
1463 '''
1464
1465 class A(object):
1466 pass
1467 "
1468 (goto-char (point-min))
1469 (let ((point (python-tests-look-at "class A(object):")))
1470 (should (not (python-nav-backward-defun)))
1471 (should (= point (point))))))
1472
1473 (ert-deftest python-nav-forward-defun-1 ()
1474 (python-tests-with-temp-buffer
1475 "
1476 class A(object): # A
1477
1478 def a(self): # a
1479 pass
1480
1481 def b(self): # b
1482 pass
1483
1484 class B(object): # B
1485
1486 class C(object): # C
1487
1488 def d(self): # d
1489 pass
1490
1491 # def e(self): # e
1492 # pass
1493
1494 def c(self): # c
1495 pass
1496
1497 # def d(self): # d
1498 # pass
1499 "
1500 (goto-char (point-min))
1501 (should (= (save-excursion (python-nav-forward-defun))
1502 (python-tests-look-at "(object): # A")))
1503 (should (= (save-excursion (python-nav-forward-defun))
1504 (python-tests-look-at "(self): # a")))
1505 (should (= (save-excursion (python-nav-forward-defun))
1506 (python-tests-look-at "(self): # b")))
1507 (should (= (save-excursion (python-nav-forward-defun))
1508 (python-tests-look-at "(object): # B")))
1509 (should (= (save-excursion (python-nav-forward-defun))
1510 (python-tests-look-at "(object): # C")))
1511 (should (= (save-excursion (python-nav-forward-defun))
1512 (python-tests-look-at "(self): # d")))
1513 (should (= (save-excursion (python-nav-forward-defun))
1514 (python-tests-look-at "(self): # c")))
1515 (should (not (python-nav-forward-defun)))))
1516
1517 (ert-deftest python-nav-forward-defun-2 ()
1518 (python-tests-with-temp-buffer
1519 "
1520 def decoratorFunctionWithArguments(arg1, arg2, arg3):
1521 '''print decorated function call data to stdout.
1522
1523 Usage:
1524
1525 @decoratorFunctionWithArguments('arg1', 'arg2')
1526 def func(a, b, c=True):
1527 pass
1528 '''
1529
1530 def wwrap(f):
1531 print 'Inside wwrap()'
1532 def wrapped_f(*args):
1533 print 'Inside wrapped_f()'
1534 print 'Decorator arguments:', arg1, arg2, arg3
1535 f(*args)
1536 print 'After f(*args)'
1537 return wrapped_f
1538 return wwrap
1539 "
1540 (goto-char (point-min))
1541 (should (= (save-excursion (python-nav-forward-defun))
1542 (python-tests-look-at "(arg1, arg2, arg3):")))
1543 (should (= (save-excursion (python-nav-forward-defun))
1544 (python-tests-look-at "(f):")))
1545 (should (= (save-excursion (python-nav-forward-defun))
1546 (python-tests-look-at "(*args):")))
1547 (should (not (python-nav-forward-defun)))))
1548
1549 (ert-deftest python-nav-forward-defun-3 ()
1550 (python-tests-with-temp-buffer
1551 "
1552 class A(object):
1553 pass
1554
1555 '''
1556 def u(self):
1557 pass
1558
1559 def v(self):
1560 pass
1561
1562 def w(self):
1563 pass
1564 '''
1565 "
1566 (goto-char (point-min))
1567 (let ((point (python-tests-look-at "(object):")))
1568 (should (not (python-nav-forward-defun)))
1569 (should (= point (point))))))
1570
1571 (ert-deftest python-nav-beginning-of-statement-1 ()
1572 (python-tests-with-temp-buffer
1573 "
1574 v1 = 123 + \
1575 456 + \
1576 789
1577 v2 = (value1,
1578 value2,
1579
1580 value3,
1581 value4)
1582 v3 = ('this is a string'
1583
1584 'that is continued'
1585 'between lines'
1586 'within a paren',
1587 # this is a comment, yo
1588 'continue previous line')
1589 v4 = '''
1590 a very long
1591 string
1592 '''
1593 "
1594 (python-tests-look-at "v2 =")
1595 (python-util-forward-comment -1)
1596 (should (= (save-excursion
1597 (python-nav-beginning-of-statement)
1598 (point))
1599 (python-tests-look-at "v1 =" -1 t)))
1600 (python-tests-look-at "v3 =")
1601 (python-util-forward-comment -1)
1602 (should (= (save-excursion
1603 (python-nav-beginning-of-statement)
1604 (point))
1605 (python-tests-look-at "v2 =" -1 t)))
1606 (python-tests-look-at "v4 =")
1607 (python-util-forward-comment -1)
1608 (should (= (save-excursion
1609 (python-nav-beginning-of-statement)
1610 (point))
1611 (python-tests-look-at "v3 =" -1 t)))
1612 (goto-char (point-max))
1613 (python-util-forward-comment -1)
1614 (should (= (save-excursion
1615 (python-nav-beginning-of-statement)
1616 (point))
1617 (python-tests-look-at "v4 =" -1 t)))))
1618
1619 (ert-deftest python-nav-end-of-statement-1 ()
1620 (python-tests-with-temp-buffer
1621 "
1622 v1 = 123 + \
1623 456 + \
1624 789
1625 v2 = (value1,
1626 value2,
1627
1628 value3,
1629 value4)
1630 v3 = ('this is a string'
1631
1632 'that is continued'
1633 'between lines'
1634 'within a paren',
1635 # this is a comment, yo
1636 'continue previous line')
1637 v4 = '''
1638 a very long
1639 string
1640 '''
1641 "
1642 (python-tests-look-at "v1 =")
1643 (should (= (save-excursion
1644 (python-nav-end-of-statement)
1645 (point))
1646 (save-excursion
1647 (python-tests-look-at "789")
1648 (line-end-position))))
1649 (python-tests-look-at "v2 =")
1650 (should (= (save-excursion
1651 (python-nav-end-of-statement)
1652 (point))
1653 (save-excursion
1654 (python-tests-look-at "value4)")
1655 (line-end-position))))
1656 (python-tests-look-at "v3 =")
1657 (should (= (save-excursion
1658 (python-nav-end-of-statement)
1659 (point))
1660 (save-excursion
1661 (python-tests-look-at
1662 "'continue previous line')")
1663 (line-end-position))))
1664 (python-tests-look-at "v4 =")
1665 (should (= (save-excursion
1666 (python-nav-end-of-statement)
1667 (point))
1668 (save-excursion
1669 (goto-char (point-max))
1670 (python-util-forward-comment -1)
1671 (point))))))
1672
1673 (ert-deftest python-nav-forward-statement-1 ()
1674 (python-tests-with-temp-buffer
1675 "
1676 v1 = 123 + \
1677 456 + \
1678 789
1679 v2 = (value1,
1680 value2,
1681
1682 value3,
1683 value4)
1684 v3 = ('this is a string'
1685
1686 'that is continued'
1687 'between lines'
1688 'within a paren',
1689 # this is a comment, yo
1690 'continue previous line')
1691 v4 = '''
1692 a very long
1693 string
1694 '''
1695 "
1696 (python-tests-look-at "v1 =")
1697 (should (= (save-excursion
1698 (python-nav-forward-statement)
1699 (point))
1700 (python-tests-look-at "v2 =")))
1701 (should (= (save-excursion
1702 (python-nav-forward-statement)
1703 (point))
1704 (python-tests-look-at "v3 =")))
1705 (should (= (save-excursion
1706 (python-nav-forward-statement)
1707 (point))
1708 (python-tests-look-at "v4 =")))
1709 (should (= (save-excursion
1710 (python-nav-forward-statement)
1711 (point))
1712 (point-max)))))
1713
1714 (ert-deftest python-nav-backward-statement-1 ()
1715 (python-tests-with-temp-buffer
1716 "
1717 v1 = 123 + \
1718 456 + \
1719 789
1720 v2 = (value1,
1721 value2,
1722
1723 value3,
1724 value4)
1725 v3 = ('this is a string'
1726
1727 'that is continued'
1728 'between lines'
1729 'within a paren',
1730 # this is a comment, yo
1731 'continue previous line')
1732 v4 = '''
1733 a very long
1734 string
1735 '''
1736 "
1737 (goto-char (point-max))
1738 (should (= (save-excursion
1739 (python-nav-backward-statement)
1740 (point))
1741 (python-tests-look-at "v4 =" -1)))
1742 (should (= (save-excursion
1743 (python-nav-backward-statement)
1744 (point))
1745 (python-tests-look-at "v3 =" -1)))
1746 (should (= (save-excursion
1747 (python-nav-backward-statement)
1748 (point))
1749 (python-tests-look-at "v2 =" -1)))
1750 (should (= (save-excursion
1751 (python-nav-backward-statement)
1752 (point))
1753 (python-tests-look-at "v1 =" -1)))))
1754
1755 (ert-deftest python-nav-backward-statement-2 ()
1756 :expected-result :failed
1757 (python-tests-with-temp-buffer
1758 "
1759 v1 = 123 + \
1760 456 + \
1761 789
1762 v2 = (value1,
1763 value2,
1764
1765 value3,
1766 value4)
1767 "
1768 ;; FIXME: For some reason `python-nav-backward-statement' is moving
1769 ;; back two sentences when starting from 'value4)'.
1770 (goto-char (point-max))
1771 (python-util-forward-comment -1)
1772 (should (= (save-excursion
1773 (python-nav-backward-statement)
1774 (point))
1775 (python-tests-look-at "v2 =" -1 t)))))
1776
1777 (ert-deftest python-nav-beginning-of-block-1 ()
1778 (python-tests-with-temp-buffer
1779 "
1780 def decoratorFunctionWithArguments(arg1, arg2, arg3):
1781 '''print decorated function call data to stdout.
1782
1783 Usage:
1784
1785 @decoratorFunctionWithArguments('arg1', 'arg2')
1786 def func(a, b, c=True):
1787 pass
1788 '''
1789
1790 def wwrap(f):
1791 print 'Inside wwrap()'
1792 def wrapped_f(*args):
1793 print 'Inside wrapped_f()'
1794 print 'Decorator arguments:', arg1, arg2, arg3
1795 f(*args)
1796 print 'After f(*args)'
1797 return wrapped_f
1798 return wwrap
1799 "
1800 (python-tests-look-at "return wwrap")
1801 (should (= (save-excursion
1802 (python-nav-beginning-of-block)
1803 (point))
1804 (python-tests-look-at "def decoratorFunctionWithArguments" -1)))
1805 (python-tests-look-at "print 'Inside wwrap()'")
1806 (should (= (save-excursion
1807 (python-nav-beginning-of-block)
1808 (point))
1809 (python-tests-look-at "def wwrap(f):" -1)))
1810 (python-tests-look-at "print 'After f(*args)'")
1811 (end-of-line)
1812 (should (= (save-excursion
1813 (python-nav-beginning-of-block)
1814 (point))
1815 (python-tests-look-at "def wrapped_f(*args):" -1)))
1816 (python-tests-look-at "return wrapped_f")
1817 (should (= (save-excursion
1818 (python-nav-beginning-of-block)
1819 (point))
1820 (python-tests-look-at "def wwrap(f):" -1)))))
1821
1822 (ert-deftest python-nav-end-of-block-1 ()
1823 (python-tests-with-temp-buffer
1824 "
1825 def decoratorFunctionWithArguments(arg1, arg2, arg3):
1826 '''print decorated function call data to stdout.
1827
1828 Usage:
1829
1830 @decoratorFunctionWithArguments('arg1', 'arg2')
1831 def func(a, b, c=True):
1832 pass
1833 '''
1834
1835 def wwrap(f):
1836 print 'Inside wwrap()'
1837 def wrapped_f(*args):
1838 print 'Inside wrapped_f()'
1839 print 'Decorator arguments:', arg1, arg2, arg3
1840 f(*args)
1841 print 'After f(*args)'
1842 return wrapped_f
1843 return wwrap
1844 "
1845 (python-tests-look-at "def decoratorFunctionWithArguments")
1846 (should (= (save-excursion
1847 (python-nav-end-of-block)
1848 (point))
1849 (save-excursion
1850 (goto-char (point-max))
1851 (python-util-forward-comment -1)
1852 (point))))
1853 (python-tests-look-at "def wwrap(f):")
1854 (should (= (save-excursion
1855 (python-nav-end-of-block)
1856 (point))
1857 (save-excursion
1858 (python-tests-look-at "return wrapped_f")
1859 (line-end-position))))
1860 (end-of-line)
1861 (should (= (save-excursion
1862 (python-nav-end-of-block)
1863 (point))
1864 (save-excursion
1865 (python-tests-look-at "return wrapped_f")
1866 (line-end-position))))
1867 (python-tests-look-at "f(*args)")
1868 (should (= (save-excursion
1869 (python-nav-end-of-block)
1870 (point))
1871 (save-excursion
1872 (python-tests-look-at "print 'After f(*args)'")
1873 (line-end-position))))))
1874
1875 (ert-deftest python-nav-forward-block-1 ()
1876 "This also accounts as a test for `python-nav-backward-block'."
1877 (python-tests-with-temp-buffer
1878 "
1879 if request.user.is_authenticated():
1880 # def block():
1881 # pass
1882 try:
1883 profile = request.user.get_profile()
1884 except Profile.DoesNotExist:
1885 profile = Profile.objects.create(user=request.user)
1886 else:
1887 if profile.stats:
1888 profile.recalculate_stats()
1889 else:
1890 profile.clear_stats()
1891 finally:
1892 profile.views += 1
1893 profile.save()
1894 "
1895 (should (= (save-excursion (python-nav-forward-block))
1896 (python-tests-look-at "if request.user.is_authenticated():")))
1897 (should (= (save-excursion (python-nav-forward-block))
1898 (python-tests-look-at "try:")))
1899 (should (= (save-excursion (python-nav-forward-block))
1900 (python-tests-look-at "except Profile.DoesNotExist:")))
1901 (should (= (save-excursion (python-nav-forward-block))
1902 (python-tests-look-at "else:")))
1903 (should (= (save-excursion (python-nav-forward-block))
1904 (python-tests-look-at "if profile.stats:")))
1905 (should (= (save-excursion (python-nav-forward-block))
1906 (python-tests-look-at "else:")))
1907 (should (= (save-excursion (python-nav-forward-block))
1908 (python-tests-look-at "finally:")))
1909 ;; When point is at the last block, leave it there and return nil
1910 (should (not (save-excursion (python-nav-forward-block))))
1911 ;; Move backwards, and even if the number of moves is less than the
1912 ;; provided argument return the point.
1913 (should (= (save-excursion (python-nav-forward-block -10))
1914 (python-tests-look-at
1915 "if request.user.is_authenticated():" -1)))))
1916
1917 (ert-deftest python-nav-forward-sexp-1 ()
1918 (python-tests-with-temp-buffer
1919 "
1920 a()
1921 b()
1922 c()
1923 "
1924 (python-tests-look-at "a()")
1925 (python-nav-forward-sexp)
1926 (should (looking-at "$"))
1927 (should (save-excursion
1928 (beginning-of-line)
1929 (looking-at "a()")))
1930 (python-nav-forward-sexp)
1931 (should (looking-at "$"))
1932 (should (save-excursion
1933 (beginning-of-line)
1934 (looking-at "b()")))
1935 (python-nav-forward-sexp)
1936 (should (looking-at "$"))
1937 (should (save-excursion
1938 (beginning-of-line)
1939 (looking-at "c()")))
1940 ;; Movement next to a paren should do what lisp does and
1941 ;; unfortunately It can't change, because otherwise
1942 ;; `blink-matching-open' breaks.
1943 (python-nav-forward-sexp -1)
1944 (should (looking-at "()"))
1945 (should (save-excursion
1946 (beginning-of-line)
1947 (looking-at "c()")))
1948 (python-nav-forward-sexp -1)
1949 (should (looking-at "c()"))
1950 (python-nav-forward-sexp -1)
1951 (should (looking-at "b()"))
1952 (python-nav-forward-sexp -1)
1953 (should (looking-at "a()"))))
1954
1955 (ert-deftest python-nav-forward-sexp-2 ()
1956 (python-tests-with-temp-buffer
1957 "
1958 def func():
1959 if True:
1960 aaa = bbb
1961 ccc = ddd
1962 eee = fff
1963 return ggg
1964 "
1965 (python-tests-look-at "aa =")
1966 (python-nav-forward-sexp)
1967 (should (looking-at " = bbb"))
1968 (python-nav-forward-sexp)
1969 (should (looking-at "$"))
1970 (should (save-excursion
1971 (back-to-indentation)
1972 (looking-at "aaa = bbb")))
1973 (python-nav-forward-sexp)
1974 (should (looking-at "$"))
1975 (should (save-excursion
1976 (back-to-indentation)
1977 (looking-at "ccc = ddd")))
1978 (python-nav-forward-sexp)
1979 (should (looking-at "$"))
1980 (should (save-excursion
1981 (back-to-indentation)
1982 (looking-at "eee = fff")))
1983 (python-nav-forward-sexp)
1984 (should (looking-at "$"))
1985 (should (save-excursion
1986 (back-to-indentation)
1987 (looking-at "return ggg")))
1988 (python-nav-forward-sexp -1)
1989 (should (looking-at "def func():"))))
1990
1991 (ert-deftest python-nav-forward-sexp-3 ()
1992 (python-tests-with-temp-buffer
1993 "
1994 from some_module import some_sub_module
1995 from another_module import another_sub_module
1996
1997 def another_statement():
1998 pass
1999 "
2000 (python-tests-look-at "some_module")
2001 (python-nav-forward-sexp)
2002 (should (looking-at " import"))
2003 (python-nav-forward-sexp)
2004 (should (looking-at " some_sub_module"))
2005 (python-nav-forward-sexp)
2006 (should (looking-at "$"))
2007 (should
2008 (save-excursion
2009 (back-to-indentation)
2010 (looking-at
2011 "from some_module import some_sub_module")))
2012 (python-nav-forward-sexp)
2013 (should (looking-at "$"))
2014 (should
2015 (save-excursion
2016 (back-to-indentation)
2017 (looking-at
2018 "from another_module import another_sub_module")))
2019 (python-nav-forward-sexp)
2020 (should (looking-at "$"))
2021 (should
2022 (save-excursion
2023 (back-to-indentation)
2024 (looking-at
2025 "pass")))
2026 (python-nav-forward-sexp -1)
2027 (should (looking-at "def another_statement():"))
2028 (python-nav-forward-sexp -1)
2029 (should (looking-at "from another_module import another_sub_module"))
2030 (python-nav-forward-sexp -1)
2031 (should (looking-at "from some_module import some_sub_module"))))
2032
2033 (ert-deftest python-nav-forward-sexp-safe-1 ()
2034 (python-tests-with-temp-buffer
2035 "
2036 profile = Profile.objects.create(user=request.user)
2037 profile.notify()
2038 "
2039 (python-tests-look-at "profile =")
2040 (python-nav-forward-sexp-safe 1)
2041 (should (looking-at "$"))
2042 (beginning-of-line 1)
2043 (python-tests-look-at "user=request.user")
2044 (python-nav-forward-sexp-safe -1)
2045 (should (looking-at "(user=request.user)"))
2046 (python-nav-forward-sexp-safe -4)
2047 (should (looking-at "profile ="))
2048 (python-tests-look-at "user=request.user")
2049 (python-nav-forward-sexp-safe 3)
2050 (should (looking-at ")"))
2051 (python-nav-forward-sexp-safe 1)
2052 (should (looking-at "$"))
2053 (python-nav-forward-sexp-safe 1)
2054 (should (looking-at "$"))))
2055
2056 (ert-deftest python-nav-up-list-1 ()
2057 (python-tests-with-temp-buffer
2058 "
2059 def f():
2060 if True:
2061 return [i for i in range(3)]
2062 "
2063 (python-tests-look-at "3)]")
2064 (python-nav-up-list)
2065 (should (looking-at "]"))
2066 (python-nav-up-list)
2067 (should (looking-at "$"))))
2068
2069 (ert-deftest python-nav-backward-up-list-1 ()
2070 :expected-result :failed
2071 (python-tests-with-temp-buffer
2072 "
2073 def f():
2074 if True:
2075 return [i for i in range(3)]
2076 "
2077 (python-tests-look-at "3)]")
2078 (python-nav-backward-up-list)
2079 (should (looking-at "(3)\\]"))
2080 (python-nav-backward-up-list)
2081 (should (looking-at
2082 "\\[i for i in range(3)\\]"))
2083 ;; FIXME: Need to move to beginning-of-statement.
2084 (python-nav-backward-up-list)
2085 (should (looking-at
2086 "return \\[i for i in range(3)\\]"))
2087 (python-nav-backward-up-list)
2088 (should (looking-at "if True:"))
2089 (python-nav-backward-up-list)
2090 (should (looking-at "def f():"))))
2091
2092 (ert-deftest python-indent-dedent-line-backspace-1 ()
2093 "Check de-indentation on first call. Bug#18319."
2094 (python-tests-with-temp-buffer
2095 "
2096 if True:
2097 x ()
2098 if False:
2099 "
2100 (python-tests-look-at "if False:")
2101 (call-interactively #'python-indent-dedent-line-backspace)
2102 (should (zerop (current-indentation)))
2103 ;; XXX: This should be a call to `undo' but it's triggering errors.
2104 (insert " ")
2105 (should (= (current-indentation) 4))
2106 (call-interactively #'python-indent-dedent-line-backspace)
2107 (should (zerop (current-indentation)))))
2108
2109 \f
2110 ;;; Shell integration
2111
2112 (defvar python-tests-shell-interpreter "python")
2113
2114 (ert-deftest python-shell-get-process-name-1 ()
2115 "Check process name calculation sans `buffer-file-name'."
2116 (python-tests-with-temp-buffer
2117 ""
2118 (should (string= (python-shell-get-process-name nil)
2119 python-shell-buffer-name))
2120 (should (string= (python-shell-get-process-name t)
2121 (format "%s[%s]" python-shell-buffer-name (buffer-name))))))
2122
2123 (ert-deftest python-shell-get-process-name-2 ()
2124 "Check process name calculation with `buffer-file-name'."
2125 (python-tests-with-temp-file
2126 ""
2127 ;; `buffer-file-name' is non-nil but the dedicated flag is nil and
2128 ;; should be respected.
2129 (should (string= (python-shell-get-process-name nil)
2130 python-shell-buffer-name))
2131 (should (string=
2132 (python-shell-get-process-name t)
2133 (format "%s[%s]" python-shell-buffer-name (buffer-name))))))
2134
2135 (ert-deftest python-shell-internal-get-process-name-1 ()
2136 "Check the internal process name is buffer-unique sans `buffer-file-name'."
2137 (python-tests-with-temp-buffer
2138 ""
2139 (should (string= (python-shell-internal-get-process-name)
2140 (format "%s[%s]" python-shell-internal-buffer-name (buffer-name))))))
2141
2142 (ert-deftest python-shell-internal-get-process-name-2 ()
2143 "Check the internal process name is buffer-unique with `buffer-file-name'."
2144 (python-tests-with-temp-file
2145 ""
2146 (should (string= (python-shell-internal-get-process-name)
2147 (format "%s[%s]" python-shell-internal-buffer-name (buffer-name))))))
2148
2149 (ert-deftest python-shell-calculate-command-1 ()
2150 "Check the command to execute is calculated correctly.
2151 Using `python-shell-interpreter' and
2152 `python-shell-interpreter-args'."
2153 (skip-unless (executable-find python-tests-shell-interpreter))
2154 (let ((python-shell-interpreter (executable-find
2155 python-tests-shell-interpreter))
2156 (python-shell-interpreter-args "-B"))
2157 (should (string=
2158 (format "%s %s"
2159 python-shell-interpreter
2160 python-shell-interpreter-args)
2161 (python-shell-calculate-command)))))
2162
2163 (ert-deftest python-shell-calculate-process-environment-1 ()
2164 "Test `python-shell-process-environment' modification."
2165 (let* ((python-shell-process-environment
2166 '("TESTVAR1=value1" "TESTVAR2=value2"))
2167 (process-environment
2168 (python-shell-calculate-process-environment)))
2169 (should (equal (getenv "TESTVAR1") "value1"))
2170 (should (equal (getenv "TESTVAR2") "value2"))))
2171
2172 (ert-deftest python-shell-calculate-process-environment-2 ()
2173 "Test `python-shell-extra-pythonpaths' modification."
2174 (let* ((process-environment process-environment)
2175 (original-pythonpath (setenv "PYTHONPATH" "path3"))
2176 (paths '("path1" "path2"))
2177 (python-shell-extra-pythonpaths paths)
2178 (process-environment
2179 (python-shell-calculate-process-environment)))
2180 (should (equal (getenv "PYTHONPATH")
2181 (concat
2182 (mapconcat 'identity paths path-separator)
2183 path-separator original-pythonpath)))))
2184
2185 (ert-deftest python-shell-calculate-process-environment-3 ()
2186 "Test `python-shell-virtualenv-root' modification."
2187 (let* ((original-path (or (getenv "PATH") ""))
2188 (python-shell-virtualenv-root
2189 (directory-file-name user-emacs-directory))
2190 (process-environment
2191 (python-shell-calculate-process-environment)))
2192 (should (not (getenv "PYTHONHOME")))
2193 (should (string= (getenv "VIRTUAL_ENV") python-shell-virtualenv-root))
2194 (should (equal (getenv "PATH")
2195 (format "%s/bin%s%s"
2196 python-shell-virtualenv-root
2197 path-separator original-path)))))
2198
2199 (ert-deftest python-shell-calculate-process-environment-4 ()
2200 "Test `python-shell-unbuffered' modification."
2201 (setenv "PYTHONUNBUFFERED")
2202 (let* ((process-environment
2203 (python-shell-calculate-process-environment)))
2204 ;; Defaults to t
2205 (should python-shell-unbuffered)
2206 (should (string= (getenv "PYTHONUNBUFFERED") "1"))))
2207
2208 (ert-deftest python-shell-calculate-process-environment-5 ()
2209 (setenv "PYTHONUNBUFFERED")
2210 "Test `python-shell-unbuffered' modification."
2211 (let* ((python-shell-unbuffered nil)
2212 (process-environment
2213 (python-shell-calculate-process-environment)))
2214 (should (not (getenv "PYTHONUNBUFFERED")))))
2215
2216 (ert-deftest python-shell-calculate-exec-path-1 ()
2217 "Test `python-shell-exec-path' modification."
2218 (let* ((original-exec-path exec-path)
2219 (python-shell-exec-path '("path1" "path2"))
2220 (exec-path (python-shell-calculate-exec-path)))
2221 (should (equal
2222 exec-path
2223 (append python-shell-exec-path
2224 original-exec-path)))))
2225
2226 (ert-deftest python-shell-calculate-exec-path-2 ()
2227 "Test `python-shell-exec-path' modification."
2228 (let* ((original-exec-path exec-path)
2229 (python-shell-virtualenv-root
2230 (directory-file-name (expand-file-name user-emacs-directory)))
2231 (exec-path (python-shell-calculate-exec-path)))
2232 (should (equal
2233 exec-path
2234 (append (cons
2235 (format "%s/bin" python-shell-virtualenv-root)
2236 original-exec-path))))))
2237
2238 (ert-deftest python-shell-make-comint-1 ()
2239 "Check comint creation for global shell buffer."
2240 (skip-unless (executable-find python-tests-shell-interpreter))
2241 ;; The interpreter can get killed too quickly to allow it to clean
2242 ;; up the tempfiles that the default python-shell-setup-codes create,
2243 ;; so it leaves tempfiles behind, which is a minor irritation.
2244 (let* ((python-shell-setup-codes nil)
2245 (python-shell-interpreter
2246 (executable-find python-tests-shell-interpreter))
2247 (proc-name (python-shell-get-process-name nil))
2248 (shell-buffer
2249 (python-tests-with-temp-buffer
2250 "" (python-shell-make-comint
2251 (python-shell-calculate-command) proc-name)))
2252 (process (get-buffer-process shell-buffer)))
2253 (unwind-protect
2254 (progn
2255 (set-process-query-on-exit-flag process nil)
2256 (should (process-live-p process))
2257 (with-current-buffer shell-buffer
2258 (should (eq major-mode 'inferior-python-mode))
2259 (should (string= (buffer-name) (format "*%s*" proc-name)))))
2260 (kill-buffer shell-buffer))))
2261
2262 (ert-deftest python-shell-make-comint-2 ()
2263 "Check comint creation for internal shell buffer."
2264 (skip-unless (executable-find python-tests-shell-interpreter))
2265 (let* ((python-shell-setup-codes nil)
2266 (python-shell-interpreter
2267 (executable-find python-tests-shell-interpreter))
2268 (proc-name (python-shell-internal-get-process-name))
2269 (shell-buffer
2270 (python-tests-with-temp-buffer
2271 "" (python-shell-make-comint
2272 (python-shell-calculate-command) proc-name nil t)))
2273 (process (get-buffer-process shell-buffer)))
2274 (unwind-protect
2275 (progn
2276 (set-process-query-on-exit-flag process nil)
2277 (should (process-live-p process))
2278 (with-current-buffer shell-buffer
2279 (should (eq major-mode 'inferior-python-mode))
2280 (should (string= (buffer-name) (format " *%s*" proc-name)))))
2281 (kill-buffer shell-buffer))))
2282
2283 (ert-deftest python-shell-make-comint-3 ()
2284 "Check comint creation with overridden python interpreter and args.
2285 The command passed to `python-shell-make-comint' as argument must
2286 locally override global values set in `python-shell-interpreter'
2287 and `python-shell-interpreter-args' in the new shell buffer."
2288 (skip-unless (executable-find python-tests-shell-interpreter))
2289 (let* ((python-shell-setup-codes nil)
2290 (python-shell-interpreter "interpreter")
2291 (python-shell-interpreter-args "--some-args")
2292 (proc-name (python-shell-get-process-name nil))
2293 (interpreter-override
2294 (concat (executable-find python-tests-shell-interpreter) " " "-i"))
2295 (shell-buffer
2296 (python-tests-with-temp-buffer
2297 "" (python-shell-make-comint interpreter-override proc-name nil)))
2298 (process (get-buffer-process shell-buffer)))
2299 (unwind-protect
2300 (progn
2301 (set-process-query-on-exit-flag process nil)
2302 (should (process-live-p process))
2303 (with-current-buffer shell-buffer
2304 (should (eq major-mode 'inferior-python-mode))
2305 (should (file-equal-p
2306 python-shell-interpreter
2307 (executable-find python-tests-shell-interpreter)))
2308 (should (string= python-shell-interpreter-args "-i"))))
2309 (kill-buffer shell-buffer))))
2310
2311 (ert-deftest python-shell-make-comint-4 ()
2312 "Check shell calculated prompts regexps are set."
2313 (skip-unless (executable-find python-tests-shell-interpreter))
2314 (let* ((process-environment process-environment)
2315 (python-shell-setup-codes nil)
2316 (python-shell-interpreter
2317 (executable-find python-tests-shell-interpreter))
2318 (python-shell-interpreter-args "-i")
2319 (python-shell--prompt-calculated-input-regexp nil)
2320 (python-shell--prompt-calculated-output-regexp nil)
2321 (python-shell-prompt-detect-enabled t)
2322 (python-shell-prompt-input-regexps '("extralargeinputprompt" "sml"))
2323 (python-shell-prompt-output-regexps '("extralargeoutputprompt" "sml"))
2324 (python-shell-prompt-regexp "in")
2325 (python-shell-prompt-block-regexp "block")
2326 (python-shell-prompt-pdb-regexp "pdf")
2327 (python-shell-prompt-output-regexp "output")
2328 (startup-code (concat "import sys\n"
2329 "sys.ps1 = 'py> '\n"
2330 "sys.ps2 = '..> '\n"
2331 "sys.ps3 = 'out '\n"))
2332 (startup-file (python-shell--save-temp-file startup-code))
2333 (proc-name (python-shell-get-process-name nil))
2334 (shell-buffer
2335 (progn
2336 (setenv "PYTHONSTARTUP" startup-file)
2337 (python-tests-with-temp-buffer
2338 "" (python-shell-make-comint
2339 (python-shell-calculate-command) proc-name nil))))
2340 (process (get-buffer-process shell-buffer)))
2341 (unwind-protect
2342 (progn
2343 (set-process-query-on-exit-flag process nil)
2344 (should (process-live-p process))
2345 (with-current-buffer shell-buffer
2346 (should (eq major-mode 'inferior-python-mode))
2347 (should (string=
2348 python-shell--prompt-calculated-input-regexp
2349 (concat "^\\(extralargeinputprompt\\|\\.\\.> \\|"
2350 "block\\|py> \\|pdf\\|sml\\|in\\)")))
2351 (should (string=
2352 python-shell--prompt-calculated-output-regexp
2353 "^\\(extralargeoutputprompt\\|output\\|out \\|sml\\)"))))
2354 (delete-file startup-file)
2355 (kill-buffer shell-buffer))))
2356
2357 (ert-deftest python-shell-get-process-1 ()
2358 "Check dedicated shell process preference over global."
2359 (skip-unless (executable-find python-tests-shell-interpreter))
2360 (python-tests-with-temp-file
2361 ""
2362 (let* ((python-shell-setup-codes nil)
2363 (python-shell-interpreter
2364 (executable-find python-tests-shell-interpreter))
2365 (global-proc-name (python-shell-get-process-name nil))
2366 (dedicated-proc-name (python-shell-get-process-name t))
2367 (global-shell-buffer
2368 (python-shell-make-comint
2369 (python-shell-calculate-command) global-proc-name))
2370 (dedicated-shell-buffer
2371 (python-shell-make-comint
2372 (python-shell-calculate-command) dedicated-proc-name))
2373 (global-process (get-buffer-process global-shell-buffer))
2374 (dedicated-process (get-buffer-process dedicated-shell-buffer)))
2375 (unwind-protect
2376 (progn
2377 (set-process-query-on-exit-flag global-process nil)
2378 (set-process-query-on-exit-flag dedicated-process nil)
2379 ;; Prefer dedicated if global also exists.
2380 (should (equal (python-shell-get-process) dedicated-process))
2381 (kill-buffer dedicated-shell-buffer)
2382 ;; If there's only global, use it.
2383 (should (equal (python-shell-get-process) global-process))
2384 (kill-buffer global-shell-buffer)
2385 ;; No buffer available.
2386 (should (not (python-shell-get-process))))
2387 (ignore-errors (kill-buffer global-shell-buffer))
2388 (ignore-errors (kill-buffer dedicated-shell-buffer))))))
2389
2390 (ert-deftest python-shell-internal-get-or-create-process-1 ()
2391 "Check internal shell process creation fallback."
2392 (skip-unless (executable-find python-tests-shell-interpreter))
2393 (python-tests-with-temp-file
2394 ""
2395 (should (not (process-live-p (python-shell-internal-get-process-name))))
2396 (let* ((python-shell-interpreter
2397 (executable-find python-tests-shell-interpreter))
2398 (internal-process-name (python-shell-internal-get-process-name))
2399 (internal-process (python-shell-internal-get-or-create-process))
2400 (internal-shell-buffer (process-buffer internal-process)))
2401 (unwind-protect
2402 (progn
2403 (set-process-query-on-exit-flag internal-process nil)
2404 (should (equal (process-name internal-process)
2405 internal-process-name))
2406 (should (equal internal-process
2407 (python-shell-internal-get-or-create-process)))
2408 ;; Assert the internal process is not a user process
2409 (should (not (python-shell-get-process)))
2410 (kill-buffer internal-shell-buffer))
2411 (ignore-errors (kill-buffer internal-shell-buffer))))))
2412
2413 (ert-deftest python-shell-prompt-detect-1 ()
2414 "Check prompt autodetection."
2415 (skip-unless (executable-find python-tests-shell-interpreter))
2416 (let ((process-environment process-environment))
2417 ;; Ensure no startup file is enabled
2418 (setenv "PYTHONSTARTUP" "")
2419 (should python-shell-prompt-detect-enabled)
2420 (should (equal (python-shell-prompt-detect) '(">>> " "... " "")))))
2421
2422 (ert-deftest python-shell-prompt-detect-2 ()
2423 "Check prompt autodetection with startup file. Bug#17370."
2424 (skip-unless (executable-find python-tests-shell-interpreter))
2425 (let* ((process-environment process-environment)
2426 (startup-code (concat "import sys\n"
2427 "sys.ps1 = 'py> '\n"
2428 "sys.ps2 = '..> '\n"
2429 "sys.ps3 = 'out '\n"))
2430 (startup-file (python-shell--save-temp-file startup-code)))
2431 (unwind-protect
2432 (progn
2433 ;; Ensure startup file is enabled
2434 (setenv "PYTHONSTARTUP" startup-file)
2435 (should python-shell-prompt-detect-enabled)
2436 (should (equal (python-shell-prompt-detect) '("py> " "..> " "out "))))
2437 (ignore-errors (delete-file startup-file)))))
2438
2439 (ert-deftest python-shell-prompt-detect-3 ()
2440 "Check prompts are not autodetected when feature is disabled."
2441 (skip-unless (executable-find python-tests-shell-interpreter))
2442 (let ((process-environment process-environment)
2443 (python-shell-prompt-detect-enabled nil))
2444 ;; Ensure no startup file is enabled
2445 (should (not python-shell-prompt-detect-enabled))
2446 (should (not (python-shell-prompt-detect)))))
2447
2448 (ert-deftest python-shell-prompt-detect-4 ()
2449 "Check warning is shown when detection fails."
2450 (skip-unless (executable-find python-tests-shell-interpreter))
2451 (let* ((process-environment process-environment)
2452 ;; Trigger failure by removing prompts in the startup file
2453 (startup-code (concat "import sys\n"
2454 "sys.ps1 = ''\n"
2455 "sys.ps2 = ''\n"
2456 "sys.ps3 = ''\n"))
2457 (startup-file (python-shell--save-temp-file startup-code)))
2458 (unwind-protect
2459 (progn
2460 (kill-buffer (get-buffer-create "*Warnings*"))
2461 (should (not (get-buffer "*Warnings*")))
2462 (setenv "PYTHONSTARTUP" startup-file)
2463 (should python-shell-prompt-detect-failure-warning)
2464 (should python-shell-prompt-detect-enabled)
2465 (should (not (python-shell-prompt-detect)))
2466 (should (get-buffer "*Warnings*")))
2467 (ignore-errors (delete-file startup-file)))))
2468
2469 (ert-deftest python-shell-prompt-detect-5 ()
2470 "Check disabled warnings are not shown when detection fails."
2471 (skip-unless (executable-find python-tests-shell-interpreter))
2472 (let* ((process-environment process-environment)
2473 (startup-code (concat "import sys\n"
2474 "sys.ps1 = ''\n"
2475 "sys.ps2 = ''\n"
2476 "sys.ps3 = ''\n"))
2477 (startup-file (python-shell--save-temp-file startup-code))
2478 (python-shell-prompt-detect-failure-warning nil))
2479 (unwind-protect
2480 (progn
2481 (kill-buffer (get-buffer-create "*Warnings*"))
2482 (should (not (get-buffer "*Warnings*")))
2483 (setenv "PYTHONSTARTUP" startup-file)
2484 (should (not python-shell-prompt-detect-failure-warning))
2485 (should python-shell-prompt-detect-enabled)
2486 (should (not (python-shell-prompt-detect)))
2487 (should (not (get-buffer "*Warnings*"))))
2488 (ignore-errors (delete-file startup-file)))))
2489
2490 (ert-deftest python-shell-prompt-detect-6 ()
2491 "Warnings are not shown when detection is disabled."
2492 (skip-unless (executable-find python-tests-shell-interpreter))
2493 (let* ((process-environment process-environment)
2494 (startup-code (concat "import sys\n"
2495 "sys.ps1 = ''\n"
2496 "sys.ps2 = ''\n"
2497 "sys.ps3 = ''\n"))
2498 (startup-file (python-shell--save-temp-file startup-code))
2499 (python-shell-prompt-detect-failure-warning t)
2500 (python-shell-prompt-detect-enabled nil))
2501 (unwind-protect
2502 (progn
2503 (kill-buffer (get-buffer-create "*Warnings*"))
2504 (should (not (get-buffer "*Warnings*")))
2505 (setenv "PYTHONSTARTUP" startup-file)
2506 (should python-shell-prompt-detect-failure-warning)
2507 (should (not python-shell-prompt-detect-enabled))
2508 (should (not (python-shell-prompt-detect)))
2509 (should (not (get-buffer "*Warnings*"))))
2510 (ignore-errors (delete-file startup-file)))))
2511
2512 (ert-deftest python-shell-prompt-validate-regexps-1 ()
2513 "Check `python-shell-prompt-input-regexps' are validated."
2514 (let* ((python-shell-prompt-input-regexps '("\\("))
2515 (error-data (should-error (python-shell-prompt-validate-regexps)
2516 :type 'user-error)))
2517 (should
2518 (string= (cadr error-data)
2519 "Invalid regexp \\( in `python-shell-prompt-input-regexps'"))))
2520
2521 (ert-deftest python-shell-prompt-validate-regexps-2 ()
2522 "Check `python-shell-prompt-output-regexps' are validated."
2523 (let* ((python-shell-prompt-output-regexps '("\\("))
2524 (error-data (should-error (python-shell-prompt-validate-regexps)
2525 :type 'user-error)))
2526 (should
2527 (string= (cadr error-data)
2528 "Invalid regexp \\( in `python-shell-prompt-output-regexps'"))))
2529
2530 (ert-deftest python-shell-prompt-validate-regexps-3 ()
2531 "Check `python-shell-prompt-regexp' is validated."
2532 (let* ((python-shell-prompt-regexp "\\(")
2533 (error-data (should-error (python-shell-prompt-validate-regexps)
2534 :type 'user-error)))
2535 (should
2536 (string= (cadr error-data)
2537 "Invalid regexp \\( in `python-shell-prompt-regexp'"))))
2538
2539 (ert-deftest python-shell-prompt-validate-regexps-4 ()
2540 "Check `python-shell-prompt-block-regexp' is validated."
2541 (let* ((python-shell-prompt-block-regexp "\\(")
2542 (error-data (should-error (python-shell-prompt-validate-regexps)
2543 :type 'user-error)))
2544 (should
2545 (string= (cadr error-data)
2546 "Invalid regexp \\( in `python-shell-prompt-block-regexp'"))))
2547
2548 (ert-deftest python-shell-prompt-validate-regexps-5 ()
2549 "Check `python-shell-prompt-pdb-regexp' is validated."
2550 (let* ((python-shell-prompt-pdb-regexp "\\(")
2551 (error-data (should-error (python-shell-prompt-validate-regexps)
2552 :type 'user-error)))
2553 (should
2554 (string= (cadr error-data)
2555 "Invalid regexp \\( in `python-shell-prompt-pdb-regexp'"))))
2556
2557 (ert-deftest python-shell-prompt-validate-regexps-6 ()
2558 "Check `python-shell-prompt-output-regexp' is validated."
2559 (let* ((python-shell-prompt-output-regexp "\\(")
2560 (error-data (should-error (python-shell-prompt-validate-regexps)
2561 :type 'user-error)))
2562 (should
2563 (string= (cadr error-data)
2564 "Invalid regexp \\( in `python-shell-prompt-output-regexp'"))))
2565
2566 (ert-deftest python-shell-prompt-validate-regexps-7 ()
2567 "Check default regexps are valid."
2568 ;; should not signal error
2569 (python-shell-prompt-validate-regexps))
2570
2571 (ert-deftest python-shell-prompt-set-calculated-regexps-1 ()
2572 "Check regexps are validated."
2573 (let* ((python-shell-prompt-output-regexp '("\\("))
2574 (python-shell--prompt-calculated-input-regexp nil)
2575 (python-shell--prompt-calculated-output-regexp nil)
2576 (python-shell-prompt-detect-enabled nil)
2577 (error-data (should-error (python-shell-prompt-set-calculated-regexps)
2578 :type 'user-error)))
2579 (should
2580 (string= (cadr error-data)
2581 "Invalid regexp \\( in `python-shell-prompt-output-regexp'"))))
2582
2583 (ert-deftest python-shell-prompt-set-calculated-regexps-2 ()
2584 "Check `python-shell-prompt-input-regexps' are set."
2585 (let* ((python-shell-prompt-input-regexps '("my" "prompt"))
2586 (python-shell-prompt-output-regexps '(""))
2587 (python-shell-prompt-regexp "")
2588 (python-shell-prompt-block-regexp "")
2589 (python-shell-prompt-pdb-regexp "")
2590 (python-shell-prompt-output-regexp "")
2591 (python-shell--prompt-calculated-input-regexp nil)
2592 (python-shell--prompt-calculated-output-regexp nil)
2593 (python-shell-prompt-detect-enabled nil))
2594 (python-shell-prompt-set-calculated-regexps)
2595 (should (string= python-shell--prompt-calculated-input-regexp
2596 "^\\(prompt\\|my\\|\\)"))))
2597
2598 (ert-deftest python-shell-prompt-set-calculated-regexps-3 ()
2599 "Check `python-shell-prompt-output-regexps' are set."
2600 (let* ((python-shell-prompt-input-regexps '(""))
2601 (python-shell-prompt-output-regexps '("my" "prompt"))
2602 (python-shell-prompt-regexp "")
2603 (python-shell-prompt-block-regexp "")
2604 (python-shell-prompt-pdb-regexp "")
2605 (python-shell-prompt-output-regexp "")
2606 (python-shell--prompt-calculated-input-regexp nil)
2607 (python-shell--prompt-calculated-output-regexp nil)
2608 (python-shell-prompt-detect-enabled nil))
2609 (python-shell-prompt-set-calculated-regexps)
2610 (should (string= python-shell--prompt-calculated-output-regexp
2611 "^\\(prompt\\|my\\|\\)"))))
2612
2613 (ert-deftest python-shell-prompt-set-calculated-regexps-4 ()
2614 "Check user defined prompts are set."
2615 (let* ((python-shell-prompt-input-regexps '(""))
2616 (python-shell-prompt-output-regexps '(""))
2617 (python-shell-prompt-regexp "prompt")
2618 (python-shell-prompt-block-regexp "block")
2619 (python-shell-prompt-pdb-regexp "pdb")
2620 (python-shell-prompt-output-regexp "output")
2621 (python-shell--prompt-calculated-input-regexp nil)
2622 (python-shell--prompt-calculated-output-regexp nil)
2623 (python-shell-prompt-detect-enabled nil))
2624 (python-shell-prompt-set-calculated-regexps)
2625 (should (string= python-shell--prompt-calculated-input-regexp
2626 "^\\(prompt\\|block\\|pdb\\|\\)"))
2627 (should (string= python-shell--prompt-calculated-output-regexp
2628 "^\\(output\\|\\)"))))
2629
2630 (ert-deftest python-shell-prompt-set-calculated-regexps-5 ()
2631 "Check order of regexps (larger first)."
2632 (let* ((python-shell-prompt-input-regexps '("extralargeinputprompt" "sml"))
2633 (python-shell-prompt-output-regexps '("extralargeoutputprompt" "sml"))
2634 (python-shell-prompt-regexp "in")
2635 (python-shell-prompt-block-regexp "block")
2636 (python-shell-prompt-pdb-regexp "pdf")
2637 (python-shell-prompt-output-regexp "output")
2638 (python-shell--prompt-calculated-input-regexp nil)
2639 (python-shell--prompt-calculated-output-regexp nil)
2640 (python-shell-prompt-detect-enabled nil))
2641 (python-shell-prompt-set-calculated-regexps)
2642 (should (string= python-shell--prompt-calculated-input-regexp
2643 "^\\(extralargeinputprompt\\|block\\|pdf\\|sml\\|in\\)"))
2644 (should (string= python-shell--prompt-calculated-output-regexp
2645 "^\\(extralargeoutputprompt\\|output\\|sml\\)"))))
2646
2647 (ert-deftest python-shell-prompt-set-calculated-regexps-6 ()
2648 "Check detected prompts are included `regexp-quote'd."
2649 (skip-unless (executable-find python-tests-shell-interpreter))
2650 (let* ((python-shell-prompt-input-regexps '(""))
2651 (python-shell-prompt-output-regexps '(""))
2652 (python-shell-prompt-regexp "")
2653 (python-shell-prompt-block-regexp "")
2654 (python-shell-prompt-pdb-regexp "")
2655 (python-shell-prompt-output-regexp "")
2656 (python-shell--prompt-calculated-input-regexp nil)
2657 (python-shell--prompt-calculated-output-regexp nil)
2658 (python-shell-prompt-detect-enabled t)
2659 (process-environment process-environment)
2660 (startup-code (concat "import sys\n"
2661 "sys.ps1 = 'p.> '\n"
2662 "sys.ps2 = '..> '\n"
2663 "sys.ps3 = 'o.t '\n"))
2664 (startup-file (python-shell--save-temp-file startup-code)))
2665 (unwind-protect
2666 (progn
2667 (setenv "PYTHONSTARTUP" startup-file)
2668 (python-shell-prompt-set-calculated-regexps)
2669 (should (string= python-shell--prompt-calculated-input-regexp
2670 "^\\(\\.\\.> \\|p\\.> \\|\\)"))
2671 (should (string= python-shell--prompt-calculated-output-regexp
2672 "^\\(o\\.t \\|\\)")))
2673 (ignore-errors (delete-file startup-file)))))
2674
2675 (ert-deftest python-shell-buffer-substring-1 ()
2676 "Selecting a substring of the whole buffer must match its contents."
2677 (python-tests-with-temp-buffer
2678 "
2679 class Foo(models.Model):
2680 pass
2681
2682
2683 class Bar(models.Model):
2684 pass
2685 "
2686 (should (string= (buffer-string)
2687 (python-shell-buffer-substring (point-min) (point-max))))))
2688
2689 (ert-deftest python-shell-buffer-substring-2 ()
2690 "Main block should be removed if NOMAIN is non-nil."
2691 (python-tests-with-temp-buffer
2692 "
2693 class Foo(models.Model):
2694 pass
2695
2696 class Bar(models.Model):
2697 pass
2698
2699 if __name__ == \"__main__\":
2700 foo = Foo()
2701 print (foo)
2702 "
2703 (should (string= (python-shell-buffer-substring (point-min) (point-max) t)
2704 "
2705 class Foo(models.Model):
2706 pass
2707
2708 class Bar(models.Model):
2709 pass
2710
2711
2712
2713
2714 "))))
2715
2716 (ert-deftest python-shell-buffer-substring-3 ()
2717 "Main block should be removed if NOMAIN is non-nil."
2718 (python-tests-with-temp-buffer
2719 "
2720 class Foo(models.Model):
2721 pass
2722
2723 if __name__ == \"__main__\":
2724 foo = Foo()
2725 print (foo)
2726
2727 class Bar(models.Model):
2728 pass
2729 "
2730 (should (string= (python-shell-buffer-substring (point-min) (point-max) t)
2731 "
2732 class Foo(models.Model):
2733 pass
2734
2735
2736
2737
2738
2739 class Bar(models.Model):
2740 pass
2741 "))))
2742
2743 (ert-deftest python-shell-buffer-substring-4 ()
2744 "Coding cookie should be added for substrings."
2745 (python-tests-with-temp-buffer
2746 "# coding: latin-1
2747
2748 class Foo(models.Model):
2749 pass
2750
2751 if __name__ == \"__main__\":
2752 foo = Foo()
2753 print (foo)
2754
2755 class Bar(models.Model):
2756 pass
2757 "
2758 (should (string= (python-shell-buffer-substring
2759 (python-tests-look-at "class Foo(models.Model):")
2760 (progn (python-nav-forward-sexp) (point)))
2761 "# -*- coding: latin-1 -*-
2762
2763 class Foo(models.Model):
2764 pass"))))
2765
2766 (ert-deftest python-shell-buffer-substring-5 ()
2767 "The proper amount of blank lines is added for a substring."
2768 (python-tests-with-temp-buffer
2769 "# coding: latin-1
2770
2771 class Foo(models.Model):
2772 pass
2773
2774 if __name__ == \"__main__\":
2775 foo = Foo()
2776 print (foo)
2777
2778 class Bar(models.Model):
2779 pass
2780 "
2781 (should (string= (python-shell-buffer-substring
2782 (python-tests-look-at "class Bar(models.Model):")
2783 (progn (python-nav-forward-sexp) (point)))
2784 "# -*- coding: latin-1 -*-
2785
2786
2787
2788
2789
2790
2791
2792
2793 class Bar(models.Model):
2794 pass"))))
2795
2796 (ert-deftest python-shell-buffer-substring-6 ()
2797 "Handle substring with coding cookie in the second line."
2798 (python-tests-with-temp-buffer
2799 "
2800 # coding: latin-1
2801
2802 class Foo(models.Model):
2803 pass
2804
2805 if __name__ == \"__main__\":
2806 foo = Foo()
2807 print (foo)
2808
2809 class Bar(models.Model):
2810 pass
2811 "
2812 (should (string= (python-shell-buffer-substring
2813 (python-tests-look-at "# coding: latin-1")
2814 (python-tests-look-at "if __name__ == \"__main__\":"))
2815 "# -*- coding: latin-1 -*-
2816
2817
2818 class Foo(models.Model):
2819 pass
2820
2821 "))))
2822
2823 (ert-deftest python-shell-buffer-substring-7 ()
2824 "Ensure first coding cookie gets precedence."
2825 (python-tests-with-temp-buffer
2826 "# coding: utf-8
2827 # coding: latin-1
2828
2829 class Foo(models.Model):
2830 pass
2831
2832 if __name__ == \"__main__\":
2833 foo = Foo()
2834 print (foo)
2835
2836 class Bar(models.Model):
2837 pass
2838 "
2839 (should (string= (python-shell-buffer-substring
2840 (python-tests-look-at "# coding: latin-1")
2841 (python-tests-look-at "if __name__ == \"__main__\":"))
2842 "# -*- coding: utf-8 -*-
2843
2844
2845 class Foo(models.Model):
2846 pass
2847
2848 "))))
2849
2850 (ert-deftest python-shell-buffer-substring-8 ()
2851 "Ensure first coding cookie gets precedence when sending whole buffer."
2852 (python-tests-with-temp-buffer
2853 "# coding: utf-8
2854 # coding: latin-1
2855
2856 class Foo(models.Model):
2857 pass
2858 "
2859 (should (string= (python-shell-buffer-substring (point-min) (point-max))
2860 "# coding: utf-8
2861
2862
2863 class Foo(models.Model):
2864 pass
2865 "))))
2866
2867 (ert-deftest python-shell-buffer-substring-9 ()
2868 "Check substring starting from `point-min'."
2869 (python-tests-with-temp-buffer
2870 "# coding: utf-8
2871
2872 class Foo(models.Model):
2873 pass
2874
2875 class Bar(models.Model):
2876 pass
2877 "
2878 (should (string= (python-shell-buffer-substring
2879 (point-min)
2880 (python-tests-look-at "class Bar(models.Model):"))
2881 "# coding: utf-8
2882
2883 class Foo(models.Model):
2884 pass
2885
2886 "))))
2887
2888 \f
2889 ;;; Shell completion
2890
2891 (ert-deftest python-shell-completion-native-interpreter-disabled-p-1 ()
2892 (let* ((python-shell-completion-native-disabled-interpreters (list "pypy"))
2893 (python-shell-interpreter "/some/path/to/bin/pypy"))
2894 (should (python-shell-completion-native-interpreter-disabled-p))))
2895
2896
2897
2898 \f
2899 ;;; PDB Track integration
2900
2901 \f
2902 ;;; Symbol completion
2903
2904 \f
2905 ;;; Fill paragraph
2906
2907 \f
2908 ;;; Skeletons
2909
2910 \f
2911 ;;; FFAP
2912
2913 \f
2914 ;;; Code check
2915
2916 \f
2917 ;;; Eldoc
2918
2919 \f
2920 ;;; Imenu
2921
2922 (ert-deftest python-imenu-create-index-1 ()
2923 (python-tests-with-temp-buffer
2924 "
2925 class Foo(models.Model):
2926 pass
2927
2928
2929 class Bar(models.Model):
2930 pass
2931
2932
2933 def decorator(arg1, arg2, arg3):
2934 '''print decorated function call data to stdout.
2935
2936 Usage:
2937
2938 @decorator('arg1', 'arg2')
2939 def func(a, b, c=True):
2940 pass
2941 '''
2942
2943 def wrap(f):
2944 print ('wrap')
2945 def wrapped_f(*args):
2946 print ('wrapped_f')
2947 print ('Decorator arguments:', arg1, arg2, arg3)
2948 f(*args)
2949 print ('called f(*args)')
2950 return wrapped_f
2951 return wrap
2952
2953
2954 class Baz(object):
2955
2956 def a(self):
2957 pass
2958
2959 def b(self):
2960 pass
2961
2962 class Frob(object):
2963
2964 def c(self):
2965 pass
2966 "
2967 (goto-char (point-max))
2968 (should (equal
2969 (list
2970 (cons "Foo (class)" (copy-marker 2))
2971 (cons "Bar (class)" (copy-marker 38))
2972 (list
2973 "decorator (def)"
2974 (cons "*function definition*" (copy-marker 74))
2975 (list
2976 "wrap (def)"
2977 (cons "*function definition*" (copy-marker 254))
2978 (cons "wrapped_f (def)" (copy-marker 294))))
2979 (list
2980 "Baz (class)"
2981 (cons "*class definition*" (copy-marker 519))
2982 (cons "a (def)" (copy-marker 539))
2983 (cons "b (def)" (copy-marker 570))
2984 (list
2985 "Frob (class)"
2986 (cons "*class definition*" (copy-marker 601))
2987 (cons "c (def)" (copy-marker 626)))))
2988 (python-imenu-create-index)))))
2989
2990 (ert-deftest python-imenu-create-index-2 ()
2991 (python-tests-with-temp-buffer
2992 "
2993 class Foo(object):
2994 def foo(self):
2995 def foo1():
2996 pass
2997
2998 def foobar(self):
2999 pass
3000 "
3001 (goto-char (point-max))
3002 (should (equal
3003 (list
3004 (list
3005 "Foo (class)"
3006 (cons "*class definition*" (copy-marker 2))
3007 (list
3008 "foo (def)"
3009 (cons "*function definition*" (copy-marker 21))
3010 (cons "foo1 (def)" (copy-marker 40)))
3011 (cons "foobar (def)" (copy-marker 78))))
3012 (python-imenu-create-index)))))
3013
3014 (ert-deftest python-imenu-create-index-3 ()
3015 (python-tests-with-temp-buffer
3016 "
3017 class Foo(object):
3018 def foo(self):
3019 def foo1():
3020 pass
3021 def foo2():
3022 pass
3023 "
3024 (goto-char (point-max))
3025 (should (equal
3026 (list
3027 (list
3028 "Foo (class)"
3029 (cons "*class definition*" (copy-marker 2))
3030 (list
3031 "foo (def)"
3032 (cons "*function definition*" (copy-marker 21))
3033 (cons "foo1 (def)" (copy-marker 40))
3034 (cons "foo2 (def)" (copy-marker 77)))))
3035 (python-imenu-create-index)))))
3036
3037 (ert-deftest python-imenu-create-index-4 ()
3038 (python-tests-with-temp-buffer
3039 "
3040 class Foo(object):
3041 class Bar(object):
3042 def __init__(self):
3043 pass
3044
3045 def __str__(self):
3046 pass
3047
3048 def __init__(self):
3049 pass
3050 "
3051 (goto-char (point-max))
3052 (should (equal
3053 (list
3054 (list
3055 "Foo (class)"
3056 (cons "*class definition*" (copy-marker 2))
3057 (list
3058 "Bar (class)"
3059 (cons "*class definition*" (copy-marker 21))
3060 (cons "__init__ (def)" (copy-marker 44))
3061 (cons "__str__ (def)" (copy-marker 90)))
3062 (cons "__init__ (def)" (copy-marker 135))))
3063 (python-imenu-create-index)))))
3064
3065 (ert-deftest python-imenu-create-flat-index-1 ()
3066 (python-tests-with-temp-buffer
3067 "
3068 class Foo(models.Model):
3069 pass
3070
3071
3072 class Bar(models.Model):
3073 pass
3074
3075
3076 def decorator(arg1, arg2, arg3):
3077 '''print decorated function call data to stdout.
3078
3079 Usage:
3080
3081 @decorator('arg1', 'arg2')
3082 def func(a, b, c=True):
3083 pass
3084 '''
3085
3086 def wrap(f):
3087 print ('wrap')
3088 def wrapped_f(*args):
3089 print ('wrapped_f')
3090 print ('Decorator arguments:', arg1, arg2, arg3)
3091 f(*args)
3092 print ('called f(*args)')
3093 return wrapped_f
3094 return wrap
3095
3096
3097 class Baz(object):
3098
3099 def a(self):
3100 pass
3101
3102 def b(self):
3103 pass
3104
3105 class Frob(object):
3106
3107 def c(self):
3108 pass
3109 "
3110 (goto-char (point-max))
3111 (should (equal
3112 (list (cons "Foo" (copy-marker 2))
3113 (cons "Bar" (copy-marker 38))
3114 (cons "decorator" (copy-marker 74))
3115 (cons "decorator.wrap" (copy-marker 254))
3116 (cons "decorator.wrap.wrapped_f" (copy-marker 294))
3117 (cons "Baz" (copy-marker 519))
3118 (cons "Baz.a" (copy-marker 539))
3119 (cons "Baz.b" (copy-marker 570))
3120 (cons "Baz.Frob" (copy-marker 601))
3121 (cons "Baz.Frob.c" (copy-marker 626)))
3122 (python-imenu-create-flat-index)))))
3123
3124 (ert-deftest python-imenu-create-flat-index-2 ()
3125 (python-tests-with-temp-buffer
3126 "
3127 class Foo(object):
3128 class Bar(object):
3129 def __init__(self):
3130 pass
3131
3132 def __str__(self):
3133 pass
3134
3135 def __init__(self):
3136 pass
3137 "
3138 (goto-char (point-max))
3139 (should (equal
3140 (list
3141 (cons "Foo" (copy-marker 2))
3142 (cons "Foo.Bar" (copy-marker 21))
3143 (cons "Foo.Bar.__init__" (copy-marker 44))
3144 (cons "Foo.Bar.__str__" (copy-marker 90))
3145 (cons "Foo.__init__" (copy-marker 135)))
3146 (python-imenu-create-flat-index)))))
3147
3148 \f
3149 ;;; Misc helpers
3150
3151 (ert-deftest python-info-current-defun-1 ()
3152 (python-tests-with-temp-buffer
3153 "
3154 def foo(a, b):
3155 "
3156 (forward-line 1)
3157 (should (string= "foo" (python-info-current-defun)))
3158 (should (string= "def foo" (python-info-current-defun t)))
3159 (forward-line 1)
3160 (should (not (python-info-current-defun)))
3161 (indent-for-tab-command)
3162 (should (string= "foo" (python-info-current-defun)))
3163 (should (string= "def foo" (python-info-current-defun t)))))
3164
3165 (ert-deftest python-info-current-defun-2 ()
3166 (python-tests-with-temp-buffer
3167 "
3168 class C(object):
3169
3170 def m(self):
3171 if True:
3172 return [i for i in range(3)]
3173 else:
3174 return []
3175
3176 def b():
3177 do_b()
3178
3179 def a():
3180 do_a()
3181
3182 def c(self):
3183 do_c()
3184 "
3185 (forward-line 1)
3186 (should (string= "C" (python-info-current-defun)))
3187 (should (string= "class C" (python-info-current-defun t)))
3188 (python-tests-look-at "return [i for ")
3189 (should (string= "C.m" (python-info-current-defun)))
3190 (should (string= "def C.m" (python-info-current-defun t)))
3191 (python-tests-look-at "def b():")
3192 (should (string= "C.m.b" (python-info-current-defun)))
3193 (should (string= "def C.m.b" (python-info-current-defun t)))
3194 (forward-line 2)
3195 (indent-for-tab-command)
3196 (python-indent-dedent-line-backspace 1)
3197 (should (string= "C.m" (python-info-current-defun)))
3198 (should (string= "def C.m" (python-info-current-defun t)))
3199 (python-tests-look-at "def c(self):")
3200 (forward-line -1)
3201 (indent-for-tab-command)
3202 (should (string= "C.m.a" (python-info-current-defun)))
3203 (should (string= "def C.m.a" (python-info-current-defun t)))
3204 (python-indent-dedent-line-backspace 1)
3205 (should (string= "C.m" (python-info-current-defun)))
3206 (should (string= "def C.m" (python-info-current-defun t)))
3207 (python-indent-dedent-line-backspace 1)
3208 (should (string= "C" (python-info-current-defun)))
3209 (should (string= "class C" (python-info-current-defun t)))
3210 (python-tests-look-at "def c(self):")
3211 (should (string= "C.c" (python-info-current-defun)))
3212 (should (string= "def C.c" (python-info-current-defun t)))
3213 (python-tests-look-at "do_c()")
3214 (should (string= "C.c" (python-info-current-defun)))
3215 (should (string= "def C.c" (python-info-current-defun t)))))
3216
3217 (ert-deftest python-info-current-defun-3 ()
3218 (python-tests-with-temp-buffer
3219 "
3220 def decoratorFunctionWithArguments(arg1, arg2, arg3):
3221 '''print decorated function call data to stdout.
3222
3223 Usage:
3224
3225 @decoratorFunctionWithArguments('arg1', 'arg2')
3226 def func(a, b, c=True):
3227 pass
3228 '''
3229
3230 def wwrap(f):
3231 print 'Inside wwrap()'
3232 def wrapped_f(*args):
3233 print 'Inside wrapped_f()'
3234 print 'Decorator arguments:', arg1, arg2, arg3
3235 f(*args)
3236 print 'After f(*args)'
3237 return wrapped_f
3238 return wwrap
3239 "
3240 (python-tests-look-at "def wwrap(f):")
3241 (forward-line -1)
3242 (should (not (python-info-current-defun)))
3243 (indent-for-tab-command 1)
3244 (should (string= (python-info-current-defun)
3245 "decoratorFunctionWithArguments"))
3246 (should (string= (python-info-current-defun t)
3247 "def decoratorFunctionWithArguments"))
3248 (python-tests-look-at "def wrapped_f(*args):")
3249 (should (string= (python-info-current-defun)
3250 "decoratorFunctionWithArguments.wwrap.wrapped_f"))
3251 (should (string= (python-info-current-defun t)
3252 "def decoratorFunctionWithArguments.wwrap.wrapped_f"))
3253 (python-tests-look-at "return wrapped_f")
3254 (should (string= (python-info-current-defun)
3255 "decoratorFunctionWithArguments.wwrap"))
3256 (should (string= (python-info-current-defun t)
3257 "def decoratorFunctionWithArguments.wwrap"))
3258 (end-of-line 1)
3259 (python-tests-look-at "return wwrap")
3260 (should (string= (python-info-current-defun)
3261 "decoratorFunctionWithArguments"))
3262 (should (string= (python-info-current-defun t)
3263 "def decoratorFunctionWithArguments"))))
3264
3265 (ert-deftest python-info-current-symbol-1 ()
3266 (python-tests-with-temp-buffer
3267 "
3268 class C(object):
3269
3270 def m(self):
3271 self.c()
3272
3273 def c(self):
3274 print ('a')
3275 "
3276 (python-tests-look-at "self.c()")
3277 (should (string= "self.c" (python-info-current-symbol)))
3278 (should (string= "C.c" (python-info-current-symbol t)))))
3279
3280 (ert-deftest python-info-current-symbol-2 ()
3281 (python-tests-with-temp-buffer
3282 "
3283 class C(object):
3284
3285 class M(object):
3286
3287 def a(self):
3288 self.c()
3289
3290 def c(self):
3291 pass
3292 "
3293 (python-tests-look-at "self.c()")
3294 (should (string= "self.c" (python-info-current-symbol)))
3295 (should (string= "C.M.c" (python-info-current-symbol t)))))
3296
3297 (ert-deftest python-info-current-symbol-3 ()
3298 "Keywords should not be considered symbols."
3299 :expected-result :failed
3300 (python-tests-with-temp-buffer
3301 "
3302 class C(object):
3303 pass
3304 "
3305 ;; FIXME: keywords are not symbols.
3306 (python-tests-look-at "class C")
3307 (should (not (python-info-current-symbol)))
3308 (should (not (python-info-current-symbol t)))
3309 (python-tests-look-at "C(object)")
3310 (should (string= "C" (python-info-current-symbol)))
3311 (should (string= "class C" (python-info-current-symbol t)))))
3312
3313 (ert-deftest python-info-statement-starts-block-p-1 ()
3314 (python-tests-with-temp-buffer
3315 "
3316 def long_function_name(
3317 var_one, var_two, var_three,
3318 var_four):
3319 print (var_one)
3320 "
3321 (python-tests-look-at "def long_function_name")
3322 (should (python-info-statement-starts-block-p))
3323 (python-tests-look-at "print (var_one)")
3324 (python-util-forward-comment -1)
3325 (should (python-info-statement-starts-block-p))))
3326
3327 (ert-deftest python-info-statement-starts-block-p-2 ()
3328 (python-tests-with-temp-buffer
3329 "
3330 if width == 0 and height == 0 and \\\\
3331 color == 'red' and emphasis == 'strong' or \\\\
3332 highlight > 100:
3333 raise ValueError('sorry, you lose')
3334 "
3335 (python-tests-look-at "if width == 0 and")
3336 (should (python-info-statement-starts-block-p))
3337 (python-tests-look-at "raise ValueError(")
3338 (python-util-forward-comment -1)
3339 (should (python-info-statement-starts-block-p))))
3340
3341 (ert-deftest python-info-statement-ends-block-p-1 ()
3342 (python-tests-with-temp-buffer
3343 "
3344 def long_function_name(
3345 var_one, var_two, var_three,
3346 var_four):
3347 print (var_one)
3348 "
3349 (python-tests-look-at "print (var_one)")
3350 (should (python-info-statement-ends-block-p))))
3351
3352 (ert-deftest python-info-statement-ends-block-p-2 ()
3353 (python-tests-with-temp-buffer
3354 "
3355 if width == 0 and height == 0 and \\\\
3356 color == 'red' and emphasis == 'strong' or \\\\
3357 highlight > 100:
3358 raise ValueError(
3359 'sorry, you lose'
3360
3361 )
3362 "
3363 (python-tests-look-at "raise ValueError(")
3364 (should (python-info-statement-ends-block-p))))
3365
3366 (ert-deftest python-info-beginning-of-statement-p-1 ()
3367 (python-tests-with-temp-buffer
3368 "
3369 def long_function_name(
3370 var_one, var_two, var_three,
3371 var_four):
3372 print (var_one)
3373 "
3374 (python-tests-look-at "def long_function_name")
3375 (should (python-info-beginning-of-statement-p))
3376 (forward-char 10)
3377 (should (not (python-info-beginning-of-statement-p)))
3378 (python-tests-look-at "print (var_one)")
3379 (should (python-info-beginning-of-statement-p))
3380 (goto-char (line-beginning-position))
3381 (should (not (python-info-beginning-of-statement-p)))))
3382
3383 (ert-deftest python-info-beginning-of-statement-p-2 ()
3384 (python-tests-with-temp-buffer
3385 "
3386 if width == 0 and height == 0 and \\\\
3387 color == 'red' and emphasis == 'strong' or \\\\
3388 highlight > 100:
3389 raise ValueError(
3390 'sorry, you lose'
3391
3392 )
3393 "
3394 (python-tests-look-at "if width == 0 and")
3395 (should (python-info-beginning-of-statement-p))
3396 (forward-char 10)
3397 (should (not (python-info-beginning-of-statement-p)))
3398 (python-tests-look-at "raise ValueError(")
3399 (should (python-info-beginning-of-statement-p))
3400 (goto-char (line-beginning-position))
3401 (should (not (python-info-beginning-of-statement-p)))))
3402
3403 (ert-deftest python-info-end-of-statement-p-1 ()
3404 (python-tests-with-temp-buffer
3405 "
3406 def long_function_name(
3407 var_one, var_two, var_three,
3408 var_four):
3409 print (var_one)
3410 "
3411 (python-tests-look-at "def long_function_name")
3412 (should (not (python-info-end-of-statement-p)))
3413 (end-of-line)
3414 (should (not (python-info-end-of-statement-p)))
3415 (python-tests-look-at "print (var_one)")
3416 (python-util-forward-comment -1)
3417 (should (python-info-end-of-statement-p))
3418 (python-tests-look-at "print (var_one)")
3419 (should (not (python-info-end-of-statement-p)))
3420 (end-of-line)
3421 (should (python-info-end-of-statement-p))))
3422
3423 (ert-deftest python-info-end-of-statement-p-2 ()
3424 (python-tests-with-temp-buffer
3425 "
3426 if width == 0 and height == 0 and \\\\
3427 color == 'red' and emphasis == 'strong' or \\\\
3428 highlight > 100:
3429 raise ValueError(
3430 'sorry, you lose'
3431
3432 )
3433 "
3434 (python-tests-look-at "if width == 0 and")
3435 (should (not (python-info-end-of-statement-p)))
3436 (end-of-line)
3437 (should (not (python-info-end-of-statement-p)))
3438 (python-tests-look-at "raise ValueError(")
3439 (python-util-forward-comment -1)
3440 (should (python-info-end-of-statement-p))
3441 (python-tests-look-at "raise ValueError(")
3442 (should (not (python-info-end-of-statement-p)))
3443 (end-of-line)
3444 (should (not (python-info-end-of-statement-p)))
3445 (goto-char (point-max))
3446 (python-util-forward-comment -1)
3447 (should (python-info-end-of-statement-p))))
3448
3449 (ert-deftest python-info-beginning-of-block-p-1 ()
3450 (python-tests-with-temp-buffer
3451 "
3452 def long_function_name(
3453 var_one, var_two, var_three,
3454 var_four):
3455 print (var_one)
3456 "
3457 (python-tests-look-at "def long_function_name")
3458 (should (python-info-beginning-of-block-p))
3459 (python-tests-look-at "var_one, var_two, var_three,")
3460 (should (not (python-info-beginning-of-block-p)))
3461 (python-tests-look-at "print (var_one)")
3462 (should (not (python-info-beginning-of-block-p)))))
3463
3464 (ert-deftest python-info-beginning-of-block-p-2 ()
3465 (python-tests-with-temp-buffer
3466 "
3467 if width == 0 and height == 0 and \\\\
3468 color == 'red' and emphasis == 'strong' or \\\\
3469 highlight > 100:
3470 raise ValueError(
3471 'sorry, you lose'
3472
3473 )
3474 "
3475 (python-tests-look-at "if width == 0 and")
3476 (should (python-info-beginning-of-block-p))
3477 (python-tests-look-at "color == 'red' and emphasis")
3478 (should (not (python-info-beginning-of-block-p)))
3479 (python-tests-look-at "raise ValueError(")
3480 (should (not (python-info-beginning-of-block-p)))))
3481
3482 (ert-deftest python-info-end-of-block-p-1 ()
3483 (python-tests-with-temp-buffer
3484 "
3485 def long_function_name(
3486 var_one, var_two, var_three,
3487 var_four):
3488 print (var_one)
3489 "
3490 (python-tests-look-at "def long_function_name")
3491 (should (not (python-info-end-of-block-p)))
3492 (python-tests-look-at "var_one, var_two, var_three,")
3493 (should (not (python-info-end-of-block-p)))
3494 (python-tests-look-at "var_four):")
3495 (end-of-line)
3496 (should (not (python-info-end-of-block-p)))
3497 (python-tests-look-at "print (var_one)")
3498 (should (not (python-info-end-of-block-p)))
3499 (end-of-line 1)
3500 (should (python-info-end-of-block-p))))
3501
3502 (ert-deftest python-info-end-of-block-p-2 ()
3503 (python-tests-with-temp-buffer
3504 "
3505 if width == 0 and height == 0 and \\\\
3506 color == 'red' and emphasis == 'strong' or \\\\
3507 highlight > 100:
3508 raise ValueError(
3509 'sorry, you lose'
3510
3511 )
3512 "
3513 (python-tests-look-at "if width == 0 and")
3514 (should (not (python-info-end-of-block-p)))
3515 (python-tests-look-at "color == 'red' and emphasis == 'strong' or")
3516 (should (not (python-info-end-of-block-p)))
3517 (python-tests-look-at "highlight > 100:")
3518 (end-of-line)
3519 (should (not (python-info-end-of-block-p)))
3520 (python-tests-look-at "raise ValueError(")
3521 (should (not (python-info-end-of-block-p)))
3522 (end-of-line 1)
3523 (should (not (python-info-end-of-block-p)))
3524 (goto-char (point-max))
3525 (python-util-forward-comment -1)
3526 (should (python-info-end-of-block-p))))
3527
3528 (ert-deftest python-info-dedenter-opening-block-position-1 ()
3529 (python-tests-with-temp-buffer
3530 "
3531 if request.user.is_authenticated():
3532 try:
3533 profile = request.user.get_profile()
3534 except Profile.DoesNotExist:
3535 profile = Profile.objects.create(user=request.user)
3536 else:
3537 if profile.stats:
3538 profile.recalculate_stats()
3539 else:
3540 profile.clear_stats()
3541 finally:
3542 profile.views += 1
3543 profile.save()
3544 "
3545 (python-tests-look-at "try:")
3546 (should (not (python-info-dedenter-opening-block-position)))
3547 (python-tests-look-at "except Profile.DoesNotExist:")
3548 (should (= (python-tests-look-at "try:" -1 t)
3549 (python-info-dedenter-opening-block-position)))
3550 (python-tests-look-at "else:")
3551 (should (= (python-tests-look-at "except Profile.DoesNotExist:" -1 t)
3552 (python-info-dedenter-opening-block-position)))
3553 (python-tests-look-at "if profile.stats:")
3554 (should (not (python-info-dedenter-opening-block-position)))
3555 (python-tests-look-at "else:")
3556 (should (= (python-tests-look-at "if profile.stats:" -1 t)
3557 (python-info-dedenter-opening-block-position)))
3558 (python-tests-look-at "finally:")
3559 (should (= (python-tests-look-at "else:" -2 t)
3560 (python-info-dedenter-opening-block-position)))))
3561
3562 (ert-deftest python-info-dedenter-opening-block-position-2 ()
3563 (python-tests-with-temp-buffer
3564 "
3565 if request.user.is_authenticated():
3566 profile = Profile.objects.get_or_create(user=request.user)
3567 if profile.stats:
3568 profile.recalculate_stats()
3569
3570 data = {
3571 'else': 'do it'
3572 }
3573 'else'
3574 "
3575 (python-tests-look-at "'else': 'do it'")
3576 (should (not (python-info-dedenter-opening-block-position)))
3577 (python-tests-look-at "'else'")
3578 (should (not (python-info-dedenter-opening-block-position)))))
3579
3580 (ert-deftest python-info-dedenter-opening-block-position-3 ()
3581 (python-tests-with-temp-buffer
3582 "
3583 if save:
3584 try:
3585 write_to_disk(data)
3586 except IOError:
3587 msg = 'Error saving to disk'
3588 message(msg)
3589 logger.exception(msg)
3590 except Exception:
3591 if hide_details:
3592 logger.exception('Unhandled exception')
3593 else
3594 finally:
3595 data.free()
3596 "
3597 (python-tests-look-at "try:")
3598 (should (not (python-info-dedenter-opening-block-position)))
3599
3600 (python-tests-look-at "except IOError:")
3601 (should (= (python-tests-look-at "try:" -1 t)
3602 (python-info-dedenter-opening-block-position)))
3603
3604 (python-tests-look-at "except Exception:")
3605 (should (= (python-tests-look-at "except IOError:" -1 t)
3606 (python-info-dedenter-opening-block-position)))
3607
3608 (python-tests-look-at "if hide_details:")
3609 (should (not (python-info-dedenter-opening-block-position)))
3610
3611 ;; check indentation modifies the detected opening block
3612 (python-tests-look-at "else")
3613 (should (= (python-tests-look-at "if hide_details:" -1 t)
3614 (python-info-dedenter-opening-block-position)))
3615
3616 (indent-line-to 8)
3617 (should (= (python-tests-look-at "if hide_details:" -1 t)
3618 (python-info-dedenter-opening-block-position)))
3619
3620 (indent-line-to 4)
3621 (should (= (python-tests-look-at "except Exception:" -1 t)
3622 (python-info-dedenter-opening-block-position)))
3623
3624 (indent-line-to 0)
3625 (should (= (python-tests-look-at "if save:" -1 t)
3626 (python-info-dedenter-opening-block-position)))))
3627
3628 (ert-deftest python-info-dedenter-opening-block-positions-1 ()
3629 (python-tests-with-temp-buffer
3630 "
3631 if save:
3632 try:
3633 write_to_disk(data)
3634 except IOError:
3635 msg = 'Error saving to disk'
3636 message(msg)
3637 logger.exception(msg)
3638 except Exception:
3639 if hide_details:
3640 logger.exception('Unhandled exception')
3641 else
3642 finally:
3643 data.free()
3644 "
3645 (python-tests-look-at "try:")
3646 (should (not (python-info-dedenter-opening-block-positions)))
3647
3648 (python-tests-look-at "except IOError:")
3649 (should
3650 (equal (list
3651 (python-tests-look-at "try:" -1 t))
3652 (python-info-dedenter-opening-block-positions)))
3653
3654 (python-tests-look-at "except Exception:")
3655 (should
3656 (equal (list
3657 (python-tests-look-at "except IOError:" -1 t))
3658 (python-info-dedenter-opening-block-positions)))
3659
3660 (python-tests-look-at "if hide_details:")
3661 (should (not (python-info-dedenter-opening-block-positions)))
3662
3663 ;; check indentation does not modify the detected opening blocks
3664 (python-tests-look-at "else")
3665 (should
3666 (equal (list
3667 (python-tests-look-at "if hide_details:" -1 t)
3668 (python-tests-look-at "except Exception:" -1 t)
3669 (python-tests-look-at "if save:" -1 t))
3670 (python-info-dedenter-opening-block-positions)))
3671
3672 (indent-line-to 8)
3673 (should
3674 (equal (list
3675 (python-tests-look-at "if hide_details:" -1 t)
3676 (python-tests-look-at "except Exception:" -1 t)
3677 (python-tests-look-at "if save:" -1 t))
3678 (python-info-dedenter-opening-block-positions)))
3679
3680 (indent-line-to 4)
3681 (should
3682 (equal (list
3683 (python-tests-look-at "if hide_details:" -1 t)
3684 (python-tests-look-at "except Exception:" -1 t)
3685 (python-tests-look-at "if save:" -1 t))
3686 (python-info-dedenter-opening-block-positions)))
3687
3688 (indent-line-to 0)
3689 (should
3690 (equal (list
3691 (python-tests-look-at "if hide_details:" -1 t)
3692 (python-tests-look-at "except Exception:" -1 t)
3693 (python-tests-look-at "if save:" -1 t))
3694 (python-info-dedenter-opening-block-positions)))))
3695
3696 (ert-deftest python-info-dedenter-opening-block-positions-2 ()
3697 "Test detection of opening blocks for elif."
3698 (python-tests-with-temp-buffer
3699 "
3700 if var:
3701 if var2:
3702 something()
3703 elif var3:
3704 something_else()
3705 elif
3706 "
3707 (python-tests-look-at "elif var3:")
3708 (should
3709 (equal (list
3710 (python-tests-look-at "if var2:" -1 t)
3711 (python-tests-look-at "if var:" -1 t))
3712 (python-info-dedenter-opening-block-positions)))
3713
3714 (python-tests-look-at "elif\n")
3715 (should
3716 (equal (list
3717 (python-tests-look-at "elif var3:" -1 t)
3718 (python-tests-look-at "if var:" -1 t))
3719 (python-info-dedenter-opening-block-positions)))))
3720
3721 (ert-deftest python-info-dedenter-opening-block-positions-3 ()
3722 "Test detection of opening blocks for else."
3723 (python-tests-with-temp-buffer
3724 "
3725 try:
3726 something()
3727 except:
3728 if var:
3729 if var2:
3730 something()
3731 elif var3:
3732 something_else()
3733 else
3734
3735 if var4:
3736 while var5:
3737 var4.pop()
3738 else
3739
3740 for value in var6:
3741 if value > 0:
3742 print value
3743 else
3744 "
3745 (python-tests-look-at "else\n")
3746 (should
3747 (equal (list
3748 (python-tests-look-at "elif var3:" -1 t)
3749 (python-tests-look-at "if var:" -1 t)
3750 (python-tests-look-at "except:" -1 t))
3751 (python-info-dedenter-opening-block-positions)))
3752
3753 (python-tests-look-at "else\n")
3754 (should
3755 (equal (list
3756 (python-tests-look-at "while var5:" -1 t)
3757 (python-tests-look-at "if var4:" -1 t))
3758 (python-info-dedenter-opening-block-positions)))
3759
3760 (python-tests-look-at "else\n")
3761 (should
3762 (equal (list
3763 (python-tests-look-at "if value > 0:" -1 t)
3764 (python-tests-look-at "for value in var6:" -1 t)
3765 (python-tests-look-at "if var4:" -1 t))
3766 (python-info-dedenter-opening-block-positions)))))
3767
3768 (ert-deftest python-info-dedenter-opening-block-positions-4 ()
3769 "Test detection of opening blocks for except."
3770 (python-tests-with-temp-buffer
3771 "
3772 try:
3773 something()
3774 except ValueError:
3775 something_else()
3776 except
3777 "
3778 (python-tests-look-at "except ValueError:")
3779 (should
3780 (equal (list (python-tests-look-at "try:" -1 t))
3781 (python-info-dedenter-opening-block-positions)))
3782
3783 (python-tests-look-at "except\n")
3784 (should
3785 (equal (list (python-tests-look-at "except ValueError:" -1 t))
3786 (python-info-dedenter-opening-block-positions)))))
3787
3788 (ert-deftest python-info-dedenter-opening-block-positions-5 ()
3789 "Test detection of opening blocks for finally."
3790 (python-tests-with-temp-buffer
3791 "
3792 try:
3793 something()
3794 finally
3795
3796 try:
3797 something_else()
3798 except:
3799 logger.exception('something went wrong')
3800 finally
3801
3802 try:
3803 something_else_else()
3804 except Exception:
3805 logger.exception('something else went wrong')
3806 else:
3807 print ('all good')
3808 finally
3809 "
3810 (python-tests-look-at "finally\n")
3811 (should
3812 (equal (list (python-tests-look-at "try:" -1 t))
3813 (python-info-dedenter-opening-block-positions)))
3814
3815 (python-tests-look-at "finally\n")
3816 (should
3817 (equal (list (python-tests-look-at "except:" -1 t))
3818 (python-info-dedenter-opening-block-positions)))
3819
3820 (python-tests-look-at "finally\n")
3821 (should
3822 (equal (list (python-tests-look-at "else:" -1 t))
3823 (python-info-dedenter-opening-block-positions)))))
3824
3825 (ert-deftest python-info-dedenter-opening-block-message-1 ()
3826 "Test dedenters inside strings are ignored."
3827 (python-tests-with-temp-buffer
3828 "'''
3829 try:
3830 something()
3831 except:
3832 logger.exception('something went wrong')
3833 '''
3834 "
3835 (python-tests-look-at "except\n")
3836 (should (not (python-info-dedenter-opening-block-message)))))
3837
3838 (ert-deftest python-info-dedenter-opening-block-message-2 ()
3839 "Test except keyword."
3840 (python-tests-with-temp-buffer
3841 "
3842 try:
3843 something()
3844 except:
3845 logger.exception('something went wrong')
3846 "
3847 (python-tests-look-at "except:")
3848 (should (string=
3849 "Closes try:"
3850 (substring-no-properties
3851 (python-info-dedenter-opening-block-message))))
3852 (end-of-line)
3853 (should (string=
3854 "Closes try:"
3855 (substring-no-properties
3856 (python-info-dedenter-opening-block-message))))))
3857
3858 (ert-deftest python-info-dedenter-opening-block-message-3 ()
3859 "Test else keyword."
3860 (python-tests-with-temp-buffer
3861 "
3862 try:
3863 something()
3864 except:
3865 logger.exception('something went wrong')
3866 else:
3867 logger.debug('all good')
3868 "
3869 (python-tests-look-at "else:")
3870 (should (string=
3871 "Closes except:"
3872 (substring-no-properties
3873 (python-info-dedenter-opening-block-message))))
3874 (end-of-line)
3875 (should (string=
3876 "Closes except:"
3877 (substring-no-properties
3878 (python-info-dedenter-opening-block-message))))))
3879
3880 (ert-deftest python-info-dedenter-opening-block-message-4 ()
3881 "Test finally keyword."
3882 (python-tests-with-temp-buffer
3883 "
3884 try:
3885 something()
3886 except:
3887 logger.exception('something went wrong')
3888 else:
3889 logger.debug('all good')
3890 finally:
3891 clean()
3892 "
3893 (python-tests-look-at "finally:")
3894 (should (string=
3895 "Closes else:"
3896 (substring-no-properties
3897 (python-info-dedenter-opening-block-message))))
3898 (end-of-line)
3899 (should (string=
3900 "Closes else:"
3901 (substring-no-properties
3902 (python-info-dedenter-opening-block-message))))))
3903
3904 (ert-deftest python-info-dedenter-opening-block-message-5 ()
3905 "Test elif keyword."
3906 (python-tests-with-temp-buffer
3907 "
3908 if a:
3909 something()
3910 elif b:
3911 "
3912 (python-tests-look-at "elif b:")
3913 (should (string=
3914 "Closes if a:"
3915 (substring-no-properties
3916 (python-info-dedenter-opening-block-message))))
3917 (end-of-line)
3918 (should (string=
3919 "Closes if a:"
3920 (substring-no-properties
3921 (python-info-dedenter-opening-block-message))))))
3922
3923
3924 (ert-deftest python-info-dedenter-statement-p-1 ()
3925 "Test dedenters inside strings are ignored."
3926 (python-tests-with-temp-buffer
3927 "'''
3928 try:
3929 something()
3930 except:
3931 logger.exception('something went wrong')
3932 '''
3933 "
3934 (python-tests-look-at "except\n")
3935 (should (not (python-info-dedenter-statement-p)))))
3936
3937 (ert-deftest python-info-dedenter-statement-p-2 ()
3938 "Test except keyword."
3939 (python-tests-with-temp-buffer
3940 "
3941 try:
3942 something()
3943 except:
3944 logger.exception('something went wrong')
3945 "
3946 (python-tests-look-at "except:")
3947 (should (= (point) (python-info-dedenter-statement-p)))
3948 (end-of-line)
3949 (should (= (save-excursion
3950 (back-to-indentation)
3951 (point))
3952 (python-info-dedenter-statement-p)))))
3953
3954 (ert-deftest python-info-dedenter-statement-p-3 ()
3955 "Test else keyword."
3956 (python-tests-with-temp-buffer
3957 "
3958 try:
3959 something()
3960 except:
3961 logger.exception('something went wrong')
3962 else:
3963 logger.debug('all good')
3964 "
3965 (python-tests-look-at "else:")
3966 (should (= (point) (python-info-dedenter-statement-p)))
3967 (end-of-line)
3968 (should (= (save-excursion
3969 (back-to-indentation)
3970 (point))
3971 (python-info-dedenter-statement-p)))))
3972
3973 (ert-deftest python-info-dedenter-statement-p-4 ()
3974 "Test finally keyword."
3975 (python-tests-with-temp-buffer
3976 "
3977 try:
3978 something()
3979 except:
3980 logger.exception('something went wrong')
3981 else:
3982 logger.debug('all good')
3983 finally:
3984 clean()
3985 "
3986 (python-tests-look-at "finally:")
3987 (should (= (point) (python-info-dedenter-statement-p)))
3988 (end-of-line)
3989 (should (= (save-excursion
3990 (back-to-indentation)
3991 (point))
3992 (python-info-dedenter-statement-p)))))
3993
3994 (ert-deftest python-info-dedenter-statement-p-5 ()
3995 "Test elif keyword."
3996 (python-tests-with-temp-buffer
3997 "
3998 if a:
3999 something()
4000 elif b:
4001 "
4002 (python-tests-look-at "elif b:")
4003 (should (= (point) (python-info-dedenter-statement-p)))
4004 (end-of-line)
4005 (should (= (save-excursion
4006 (back-to-indentation)
4007 (point))
4008 (python-info-dedenter-statement-p)))))
4009
4010 (ert-deftest python-info-line-ends-backslash-p-1 ()
4011 (python-tests-with-temp-buffer
4012 "
4013 objects = Thing.objects.all() \\\\
4014 .filter(
4015 type='toy',
4016 status='bought'
4017 ) \\\\
4018 .aggregate(
4019 Sum('amount')
4020 ) \\\\
4021 .values_list()
4022 "
4023 (should (python-info-line-ends-backslash-p 2)) ; .filter(...
4024 (should (python-info-line-ends-backslash-p 3))
4025 (should (python-info-line-ends-backslash-p 4))
4026 (should (python-info-line-ends-backslash-p 5))
4027 (should (python-info-line-ends-backslash-p 6)) ; ) \...
4028 (should (python-info-line-ends-backslash-p 7))
4029 (should (python-info-line-ends-backslash-p 8))
4030 (should (python-info-line-ends-backslash-p 9))
4031 (should (not (python-info-line-ends-backslash-p 10))))) ; .values_list()...
4032
4033 (ert-deftest python-info-beginning-of-backslash-1 ()
4034 (python-tests-with-temp-buffer
4035 "
4036 objects = Thing.objects.all() \\\\
4037 .filter(
4038 type='toy',
4039 status='bought'
4040 ) \\\\
4041 .aggregate(
4042 Sum('amount')
4043 ) \\\\
4044 .values_list()
4045 "
4046 (let ((first 2)
4047 (second (python-tests-look-at ".filter("))
4048 (third (python-tests-look-at ".aggregate(")))
4049 (should (= first (python-info-beginning-of-backslash 2)))
4050 (should (= second (python-info-beginning-of-backslash 3)))
4051 (should (= second (python-info-beginning-of-backslash 4)))
4052 (should (= second (python-info-beginning-of-backslash 5)))
4053 (should (= second (python-info-beginning-of-backslash 6)))
4054 (should (= third (python-info-beginning-of-backslash 7)))
4055 (should (= third (python-info-beginning-of-backslash 8)))
4056 (should (= third (python-info-beginning-of-backslash 9)))
4057 (should (not (python-info-beginning-of-backslash 10))))))
4058
4059 (ert-deftest python-info-continuation-line-p-1 ()
4060 (python-tests-with-temp-buffer
4061 "
4062 if width == 0 and height == 0 and \\\\
4063 color == 'red' and emphasis == 'strong' or \\\\
4064 highlight > 100:
4065 raise ValueError(
4066 'sorry, you lose'
4067
4068 )
4069 "
4070 (python-tests-look-at "if width == 0 and height == 0 and")
4071 (should (not (python-info-continuation-line-p)))
4072 (python-tests-look-at "color == 'red' and emphasis == 'strong' or")
4073 (should (python-info-continuation-line-p))
4074 (python-tests-look-at "highlight > 100:")
4075 (should (python-info-continuation-line-p))
4076 (python-tests-look-at "raise ValueError(")
4077 (should (not (python-info-continuation-line-p)))
4078 (python-tests-look-at "'sorry, you lose'")
4079 (should (python-info-continuation-line-p))
4080 (forward-line 1)
4081 (should (python-info-continuation-line-p))
4082 (python-tests-look-at ")")
4083 (should (python-info-continuation-line-p))
4084 (forward-line 1)
4085 (should (not (python-info-continuation-line-p)))))
4086
4087 (ert-deftest python-info-block-continuation-line-p-1 ()
4088 (python-tests-with-temp-buffer
4089 "
4090 if width == 0 and height == 0 and \\\\
4091 color == 'red' and emphasis == 'strong' or \\\\
4092 highlight > 100:
4093 raise ValueError(
4094 'sorry, you lose'
4095
4096 )
4097 "
4098 (python-tests-look-at "if width == 0 and")
4099 (should (not (python-info-block-continuation-line-p)))
4100 (python-tests-look-at "color == 'red' and emphasis == 'strong' or")
4101 (should (= (python-info-block-continuation-line-p)
4102 (python-tests-look-at "if width == 0 and" -1 t)))
4103 (python-tests-look-at "highlight > 100:")
4104 (should (not (python-info-block-continuation-line-p)))))
4105
4106 (ert-deftest python-info-block-continuation-line-p-2 ()
4107 (python-tests-with-temp-buffer
4108 "
4109 def foo(a,
4110 b,
4111 c):
4112 pass
4113 "
4114 (python-tests-look-at "def foo(a,")
4115 (should (not (python-info-block-continuation-line-p)))
4116 (python-tests-look-at "b,")
4117 (should (= (python-info-block-continuation-line-p)
4118 (python-tests-look-at "def foo(a," -1 t)))
4119 (python-tests-look-at "c):")
4120 (should (not (python-info-block-continuation-line-p)))))
4121
4122 (ert-deftest python-info-assignment-continuation-line-p-1 ()
4123 (python-tests-with-temp-buffer
4124 "
4125 data = foo(), bar() \\\\
4126 baz(), 4 \\\\
4127 5, 6
4128 "
4129 (python-tests-look-at "data = foo(), bar()")
4130 (should (not (python-info-assignment-continuation-line-p)))
4131 (python-tests-look-at "baz(), 4")
4132 (should (= (python-info-assignment-continuation-line-p)
4133 (python-tests-look-at "foo()," -1 t)))
4134 (python-tests-look-at "5, 6")
4135 (should (not (python-info-assignment-continuation-line-p)))))
4136
4137 (ert-deftest python-info-assignment-continuation-line-p-2 ()
4138 (python-tests-with-temp-buffer
4139 "
4140 data = (foo(), bar()
4141 baz(), 4
4142 5, 6)
4143 "
4144 (python-tests-look-at "data = (foo(), bar()")
4145 (should (not (python-info-assignment-continuation-line-p)))
4146 (python-tests-look-at "baz(), 4")
4147 (should (= (python-info-assignment-continuation-line-p)
4148 (python-tests-look-at "(foo()," -1 t)))
4149 (python-tests-look-at "5, 6)")
4150 (should (not (python-info-assignment-continuation-line-p)))))
4151
4152 (ert-deftest python-info-looking-at-beginning-of-defun-1 ()
4153 (python-tests-with-temp-buffer
4154 "
4155 def decorat0r(deff):
4156 '''decorates stuff.
4157
4158 @decorat0r
4159 def foo(arg):
4160 ...
4161 '''
4162 def wrap():
4163 deff()
4164 return wwrap
4165 "
4166 (python-tests-look-at "def decorat0r(deff):")
4167 (should (python-info-looking-at-beginning-of-defun))
4168 (python-tests-look-at "def foo(arg):")
4169 (should (not (python-info-looking-at-beginning-of-defun)))
4170 (python-tests-look-at "def wrap():")
4171 (should (python-info-looking-at-beginning-of-defun))
4172 (python-tests-look-at "deff()")
4173 (should (not (python-info-looking-at-beginning-of-defun)))))
4174
4175 (ert-deftest python-info-current-line-comment-p-1 ()
4176 (python-tests-with-temp-buffer
4177 "
4178 # this is a comment
4179 foo = True # another comment
4180 '#this is a string'
4181 if foo:
4182 # more comments
4183 print ('bar') # print bar
4184 "
4185 (python-tests-look-at "# this is a comment")
4186 (should (python-info-current-line-comment-p))
4187 (python-tests-look-at "foo = True # another comment")
4188 (should (not (python-info-current-line-comment-p)))
4189 (python-tests-look-at "'#this is a string'")
4190 (should (not (python-info-current-line-comment-p)))
4191 (python-tests-look-at "# more comments")
4192 (should (python-info-current-line-comment-p))
4193 (python-tests-look-at "print ('bar') # print bar")
4194 (should (not (python-info-current-line-comment-p)))))
4195
4196 (ert-deftest python-info-current-line-empty-p ()
4197 (python-tests-with-temp-buffer
4198 "
4199 # this is a comment
4200
4201 foo = True # another comment
4202 "
4203 (should (python-info-current-line-empty-p))
4204 (python-tests-look-at "# this is a comment")
4205 (should (not (python-info-current-line-empty-p)))
4206 (forward-line 1)
4207 (should (python-info-current-line-empty-p))))
4208
4209 (ert-deftest python-info-encoding-from-cookie-1 ()
4210 "Should detect it on first line."
4211 (python-tests-with-temp-buffer
4212 "# coding=latin-1
4213
4214 foo = True # another comment
4215 "
4216 (should (eq (python-info-encoding-from-cookie) 'latin-1))))
4217
4218 (ert-deftest python-info-encoding-from-cookie-2 ()
4219 "Should detect it on second line."
4220 (python-tests-with-temp-buffer
4221 "
4222 # coding=latin-1
4223
4224 foo = True # another comment
4225 "
4226 (should (eq (python-info-encoding-from-cookie) 'latin-1))))
4227
4228 (ert-deftest python-info-encoding-from-cookie-3 ()
4229 "Should not be detected on third line (and following ones)."
4230 (python-tests-with-temp-buffer
4231 "
4232
4233 # coding=latin-1
4234 foo = True # another comment
4235 "
4236 (should (not (python-info-encoding-from-cookie)))))
4237
4238 (ert-deftest python-info-encoding-from-cookie-4 ()
4239 "Should detect Emacs style."
4240 (python-tests-with-temp-buffer
4241 "# -*- coding: latin-1 -*-
4242
4243 foo = True # another comment"
4244 (should (eq (python-info-encoding-from-cookie) 'latin-1))))
4245
4246 (ert-deftest python-info-encoding-from-cookie-5 ()
4247 "Should detect Vim style."
4248 (python-tests-with-temp-buffer
4249 "# vim: set fileencoding=latin-1 :
4250
4251 foo = True # another comment"
4252 (should (eq (python-info-encoding-from-cookie) 'latin-1))))
4253
4254 (ert-deftest python-info-encoding-from-cookie-6 ()
4255 "First cookie wins."
4256 (python-tests-with-temp-buffer
4257 "# -*- coding: iso-8859-1 -*-
4258 # vim: set fileencoding=latin-1 :
4259
4260 foo = True # another comment"
4261 (should (eq (python-info-encoding-from-cookie) 'iso-8859-1))))
4262
4263 (ert-deftest python-info-encoding-from-cookie-7 ()
4264 "First cookie wins."
4265 (python-tests-with-temp-buffer
4266 "# vim: set fileencoding=latin-1 :
4267 # -*- coding: iso-8859-1 -*-
4268
4269 foo = True # another comment"
4270 (should (eq (python-info-encoding-from-cookie) 'latin-1))))
4271
4272 (ert-deftest python-info-encoding-1 ()
4273 "Should return the detected encoding from cookie."
4274 (python-tests-with-temp-buffer
4275 "# vim: set fileencoding=latin-1 :
4276
4277 foo = True # another comment"
4278 (should (eq (python-info-encoding) 'latin-1))))
4279
4280 (ert-deftest python-info-encoding-2 ()
4281 "Should default to utf-8."
4282 (python-tests-with-temp-buffer
4283 "# No encoding for you
4284
4285 foo = True # another comment"
4286 (should (eq (python-info-encoding) 'utf-8))))
4287
4288 \f
4289 ;;; Utility functions
4290
4291 (ert-deftest python-util-goto-line-1 ()
4292 (python-tests-with-temp-buffer
4293 (concat
4294 "# a comment
4295 # another comment
4296 def foo(a, b, c):
4297 pass" (make-string 20 ?\n))
4298 (python-util-goto-line 10)
4299 (should (= (line-number-at-pos) 10))
4300 (python-util-goto-line 20)
4301 (should (= (line-number-at-pos) 20))))
4302
4303 (ert-deftest python-util-clone-local-variables-1 ()
4304 (let ((buffer (generate-new-buffer
4305 "python-util-clone-local-variables-1"))
4306 (varcons
4307 '((python-fill-docstring-style . django)
4308 (python-shell-interpreter . "python")
4309 (python-shell-interpreter-args . "manage.py shell")
4310 (python-shell-prompt-regexp . "In \\[[0-9]+\\]: ")
4311 (python-shell-prompt-output-regexp . "Out\\[[0-9]+\\]: ")
4312 (python-shell-extra-pythonpaths "/home/user/pylib/")
4313 (python-shell-completion-setup-code
4314 . "from IPython.core.completerlib import module_completion")
4315 (python-shell-completion-string-code
4316 . "';'.join(get_ipython().Completer.all_completions('''%s'''))\n")
4317 (python-shell-virtualenv-root
4318 . "/home/user/.virtualenvs/project"))))
4319 (with-current-buffer buffer
4320 (kill-all-local-variables)
4321 (dolist (ccons varcons)
4322 (set (make-local-variable (car ccons)) (cdr ccons))))
4323 (python-tests-with-temp-buffer
4324 ""
4325 (python-util-clone-local-variables buffer)
4326 (dolist (ccons varcons)
4327 (should
4328 (equal (symbol-value (car ccons)) (cdr ccons)))))
4329 (kill-buffer buffer)))
4330
4331 (ert-deftest python-util-strip-string-1 ()
4332 (should (string= (python-util-strip-string "\t\r\n str") "str"))
4333 (should (string= (python-util-strip-string "str \n\r") "str"))
4334 (should (string= (python-util-strip-string "\t\r\n str \n\r ") "str"))
4335 (should
4336 (string= (python-util-strip-string "\n str \nin \tg \n\r") "str \nin \tg"))
4337 (should (string= (python-util-strip-string "\n \t \n\r ") ""))
4338 (should (string= (python-util-strip-string "") "")))
4339
4340 (ert-deftest python-util-forward-comment-1 ()
4341 (python-tests-with-temp-buffer
4342 (concat
4343 "# a comment
4344 # another comment
4345 # bad indented comment
4346 # more comments" (make-string 9999 ?\n))
4347 (python-util-forward-comment 1)
4348 (should (= (point) (point-max)))
4349 (python-util-forward-comment -1)
4350 (should (= (point) (point-min)))))
4351
4352 (ert-deftest python-util-valid-regexp-p-1 ()
4353 (should (python-util-valid-regexp-p ""))
4354 (should (python-util-valid-regexp-p python-shell-prompt-regexp))
4355 (should (not (python-util-valid-regexp-p "\\("))))
4356
4357 \f
4358 ;;; Electricity
4359
4360 (ert-deftest python-parens-electric-indent-1 ()
4361 (require 'electric)
4362 (let ((eim electric-indent-mode))
4363 (unwind-protect
4364 (progn
4365 (python-tests-with-temp-buffer
4366 "
4367 from django.conf.urls import patterns, include, url
4368
4369 from django.contrib import admin
4370
4371 from myapp import views
4372
4373
4374 urlpatterns = patterns('',
4375 url(r'^$', views.index
4376 )
4377 "
4378 (electric-indent-mode 1)
4379 (python-tests-look-at "views.index")
4380 (end-of-line)
4381
4382 ;; Inserting commas within the same line should leave
4383 ;; indentation unchanged.
4384 (python-tests-self-insert ",")
4385 (should (= (current-indentation) 4))
4386
4387 ;; As well as any other input happening within the same
4388 ;; set of parens.
4389 (python-tests-self-insert " name='index')")
4390 (should (= (current-indentation) 4))
4391
4392 ;; But a comma outside it, should trigger indentation.
4393 (python-tests-self-insert ",")
4394 (should (= (current-indentation) 23))
4395
4396 ;; Newline indents to the first argument column
4397 (python-tests-self-insert "\n")
4398 (should (= (current-indentation) 23))
4399
4400 ;; All this input must not change indentation
4401 (indent-line-to 4)
4402 (python-tests-self-insert "url(r'^/login$', views.login)")
4403 (should (= (current-indentation) 4))
4404
4405 ;; But this comma does
4406 (python-tests-self-insert ",")
4407 (should (= (current-indentation) 23))))
4408 (or eim (electric-indent-mode -1)))))
4409
4410 (ert-deftest python-triple-quote-pairing ()
4411 (require 'electric)
4412 (let ((epm electric-pair-mode))
4413 (unwind-protect
4414 (progn
4415 (python-tests-with-temp-buffer
4416 "\"\"\n"
4417 (or epm (electric-pair-mode 1))
4418 (goto-char (1- (point-max)))
4419 (python-tests-self-insert ?\")
4420 (should (string= (buffer-string)
4421 "\"\"\"\"\"\"\n"))
4422 (should (= (point) 4)))
4423 (python-tests-with-temp-buffer
4424 "\n"
4425 (python-tests-self-insert (list ?\" ?\" ?\"))
4426 (should (string= (buffer-string)
4427 "\"\"\"\"\"\"\n"))
4428 (should (= (point) 4)))
4429 (python-tests-with-temp-buffer
4430 "\"\n\"\"\n"
4431 (goto-char (1- (point-max)))
4432 (python-tests-self-insert ?\")
4433 (should (= (point) (1- (point-max))))
4434 (should (string= (buffer-string)
4435 "\"\n\"\"\"\n"))))
4436 (or epm (electric-pair-mode -1)))))
4437
4438
4439 (provide 'python-tests)
4440
4441 ;; Local Variables:
4442 ;; coding: utf-8
4443 ;; indent-tabs-mode: nil
4444 ;; End:
4445
4446 ;;; python-tests.el ends here