doc/misc/erc.texi: fix typo
[emacs.git] / test / automated / python-tests.el
blob42c26fc3482f2dd59eb106ab9e917d6c7a6d9f40
1 ;;; python-tests.el --- Test suite for python.el
3 ;; Copyright (C) 2013-2015 Free Software Foundation, Inc.
5 ;; This file is part of GNU Emacs.
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.
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.
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/>.
20 ;;; Commentary:
22 ;;; Code:
24 (require 'ert)
25 (require 'python)
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))
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))))
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)))))
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)))
108 ;;; Tests for your tests, so you can test while you test.
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)))))
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)))))
147 ;;; Bindings
150 ;;; Python specialized rx
153 ;;; Font-lock and syntax
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))))))
166 ;;; Indentation
168 ;; See: http://www.python.org/dev/peps/pep-0008/#indentation
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)
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-comment))
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))))
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)
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-comment))
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))))
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)
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-comment))
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))))
233 (ert-deftest python-indent-base-case ()
234 "Check base case does not trigger errors."
235 (python-tests-with-temp-buffer
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))))
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.
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))))
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 because the user forced so.
290 # At this line python.el wont dedent, user is always right.
292 comment_wins_over_ender = True
294 # yeah, that.
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 indented")
305 (should (eq (car (python-indent-context)) :after-block-end))
306 ;; The return keyword do make indentation lose a level...
307 (should (= (python-indent-calculate-indentation) 0))
308 ;; ...but the current indentation was forced by the user.
309 (python-tests-look-at "# At this line python.el wont dedent")
310 (should (eq (car (python-indent-context)) :after-comment))
311 (should (= (python-indent-calculate-indentation) 4))
312 ;; Should behave the same for blank lines: potentially a comment.
313 (forward-line 1)
314 (should (eq (car (python-indent-context)) :after-comment))
315 (should (= (python-indent-calculate-indentation) 4))
316 (python-tests-look-at "comment_wins_over_ender")
317 ;; The comment won over the ender because the user said so.
318 (should (eq (car (python-indent-context)) :after-comment))
319 (should (= (python-indent-calculate-indentation) 4))
320 ;; The indentation calculated fine for the assignment, but the user
321 ;; choose to force it back to the first column. Next line should
322 ;; be aware of that.
323 (python-tests-look-at "# yeah, that.")
324 (should (eq (car (python-indent-context)) :after-line))
325 (should (= (python-indent-calculate-indentation) 0))))
327 (ert-deftest python-indent-after-comment-3 ()
328 "Test after-comment in buggy case."
329 (python-tests-with-temp-buffer
331 class A(object):
333 def something(self, arg):
334 if True:
335 return arg
337 # A comment
339 @adecorator
340 def method(self, a, b):
341 pass
343 (python-tests-look-at "@adecorator")
344 (should (eq (car (python-indent-context)) :after-comment))
345 (should (= (python-indent-calculate-indentation) 4))))
347 (ert-deftest python-indent-inside-paren-1 ()
348 "The most simple inside-paren case that shouldn't fail."
349 (python-tests-with-temp-buffer
351 data = {
352 'key':
354 'objlist': [
356 'pk': 1,
357 'name': 'first',
360 'pk': 2,
361 'name': 'second',
367 (python-tests-look-at "data = {")
368 (should (eq (car (python-indent-context)) :after-line))
369 (should (= (python-indent-calculate-indentation) 0))
370 (python-tests-look-at "'key':")
371 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
372 (should (= (python-indent-calculate-indentation) 4))
373 (python-tests-look-at "{")
374 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
375 (should (= (python-indent-calculate-indentation) 4))
376 (python-tests-look-at "'objlist': [")
377 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
378 (should (= (python-indent-calculate-indentation) 8))
379 (python-tests-look-at "{")
380 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
381 (should (= (python-indent-calculate-indentation) 12))
382 (python-tests-look-at "'pk': 1,")
383 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
384 (should (= (python-indent-calculate-indentation) 16))
385 (python-tests-look-at "'name': 'first',")
386 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
387 (should (= (python-indent-calculate-indentation) 16))
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) 12))
392 (python-tests-look-at "{")
393 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
394 (should (= (python-indent-calculate-indentation) 12))
395 (python-tests-look-at "'pk': 2,")
396 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
397 (should (= (python-indent-calculate-indentation) 16))
398 (python-tests-look-at "'name': 'second',")
399 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
400 (should (= (python-indent-calculate-indentation) 16))
401 (python-tests-look-at "}")
402 (should (eq (car (python-indent-context))
403 :inside-paren-at-closing-nested-paren))
404 (should (= (python-indent-calculate-indentation) 12))
405 (python-tests-look-at "]")
406 (should (eq (car (python-indent-context))
407 :inside-paren-at-closing-nested-paren))
408 (should (= (python-indent-calculate-indentation) 8))
409 (python-tests-look-at "}")
410 (should (eq (car (python-indent-context))
411 :inside-paren-at-closing-nested-paren))
412 (should (= (python-indent-calculate-indentation) 4))
413 (python-tests-look-at "}")
414 (should (eq (car (python-indent-context)) :inside-paren-at-closing-paren))
415 (should (= (python-indent-calculate-indentation) 0))))
417 (ert-deftest python-indent-inside-paren-2 ()
418 "Another more compact paren group style."
419 (python-tests-with-temp-buffer
421 data = {'key': {
422 'objlist': [
423 {'pk': 1,
424 'name': 'first'},
425 {'pk': 2,
426 'name': 'second'}
430 (python-tests-look-at "data = {")
431 (should (eq (car (python-indent-context)) :after-line))
432 (should (= (python-indent-calculate-indentation) 0))
433 (python-tests-look-at "'objlist': [")
434 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
435 (should (= (python-indent-calculate-indentation) 4))
436 (python-tests-look-at "{'pk': 1,")
437 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
438 (should (= (python-indent-calculate-indentation) 8))
439 (python-tests-look-at "'name': 'first'},")
440 (should (eq (car (python-indent-context)) :inside-paren))
441 (should (= (python-indent-calculate-indentation) 9))
442 (python-tests-look-at "{'pk': 2,")
443 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
444 (should (= (python-indent-calculate-indentation) 8))
445 (python-tests-look-at "'name': 'second'}")
446 (should (eq (car (python-indent-context)) :inside-paren))
447 (should (= (python-indent-calculate-indentation) 9))
448 (python-tests-look-at "]")
449 (should (eq (car (python-indent-context))
450 :inside-paren-at-closing-nested-paren))
451 (should (= (python-indent-calculate-indentation) 4))
452 (python-tests-look-at "}}")
453 (should (eq (car (python-indent-context))
454 :inside-paren-at-closing-nested-paren))
455 (should (= (python-indent-calculate-indentation) 0))
456 (python-tests-look-at "}")
457 (should (eq (car (python-indent-context)) :inside-paren-at-closing-paren))
458 (should (= (python-indent-calculate-indentation) 0))))
460 (ert-deftest python-indent-inside-paren-3 ()
461 "The simplest case possible."
462 (python-tests-with-temp-buffer
464 data = ('these',
465 'are',
466 'the',
467 'tokens')
469 (python-tests-look-at "data = ('these',")
470 (should (eq (car (python-indent-context)) :after-line))
471 (should (= (python-indent-calculate-indentation) 0))
472 (forward-line 1)
473 (should (eq (car (python-indent-context)) :inside-paren))
474 (should (= (python-indent-calculate-indentation) 8))
475 (forward-line 1)
476 (should (eq (car (python-indent-context)) :inside-paren))
477 (should (= (python-indent-calculate-indentation) 8))
478 (forward-line 1)
479 (should (eq (car (python-indent-context)) :inside-paren))
480 (should (= (python-indent-calculate-indentation) 8))))
482 (ert-deftest python-indent-inside-paren-4 ()
483 "Respect indentation of first column."
484 (python-tests-with-temp-buffer
486 data = [ [ 'these', 'are'],
487 ['the', 'tokens' ] ]
489 (python-tests-look-at "data = [ [ 'these', 'are'],")
490 (should (eq (car (python-indent-context)) :after-line))
491 (should (= (python-indent-calculate-indentation) 0))
492 (forward-line 1)
493 (should (eq (car (python-indent-context)) :inside-paren))
494 (should (= (python-indent-calculate-indentation) 9))))
496 (ert-deftest python-indent-inside-paren-5 ()
497 "Test when :inside-paren initial parens are skipped in context start."
498 (python-tests-with-temp-buffer
500 while ((not some_condition) and
501 another_condition):
502 do_something_interesting(
503 with_some_arg)
505 (python-tests-look-at "while ((not some_condition) and")
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) 7))
511 (forward-line 1)
512 (should (eq (car (python-indent-context)) :after-block-start))
513 (should (= (python-indent-calculate-indentation) 4))
514 (forward-line 1)
515 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
516 (should (= (python-indent-calculate-indentation) 8))))
518 (ert-deftest python-indent-inside-paren-6 ()
519 "This should be aligned.."
520 (python-tests-with-temp-buffer
522 CHOICES = (('some', 'choice'),
523 ('another', 'choice'),
524 ('more', 'choices'))
526 (python-tests-look-at "CHOICES = (('some', 'choice'),")
527 (should (eq (car (python-indent-context)) :after-line))
528 (should (= (python-indent-calculate-indentation) 0))
529 (forward-line 1)
530 (should (eq (car (python-indent-context)) :inside-paren))
531 (should (= (python-indent-calculate-indentation) 11))
532 (forward-line 1)
533 (should (eq (car (python-indent-context)) :inside-paren))
534 (should (= (python-indent-calculate-indentation) 11))))
536 (ert-deftest python-indent-after-block-1 ()
537 "The most simple after-block case that shouldn't fail."
538 (python-tests-with-temp-buffer
540 def foo(a, b, c=True):
542 (should (eq (car (python-indent-context)) :no-indent))
543 (should (= (python-indent-calculate-indentation) 0))
544 (goto-char (point-max))
545 (should (eq (car (python-indent-context)) :after-block-start))
546 (should (= (python-indent-calculate-indentation) 4))))
548 (ert-deftest python-indent-after-block-2 ()
549 "A weird (malformed) multiline block statement."
550 (python-tests-with-temp-buffer
552 def foo(a, b, c={
553 'a':
556 (goto-char (point-max))
557 (should (eq (car (python-indent-context)) :after-block-start))
558 (should (= (python-indent-calculate-indentation) 4))))
560 (ert-deftest python-indent-after-block-3 ()
561 "A weird (malformed) sample, usually found in python shells."
562 (python-tests-with-temp-buffer
564 In [1]:
565 def func():
566 pass
568 In [2]:
569 something
571 (python-tests-look-at "pass")
572 (should (eq (car (python-indent-context)) :after-block-start))
573 (should (= (python-indent-calculate-indentation) 4))
574 (python-tests-look-at "something")
575 (end-of-line)
576 (should (eq (car (python-indent-context)) :after-line))
577 (should (= (python-indent-calculate-indentation) 0))))
579 (ert-deftest python-indent-after-backslash-1 ()
580 "The most common case."
581 (python-tests-with-temp-buffer
583 from foo.bar.baz import something, something_1 \\\\
584 something_2 something_3, \\\\
585 something_4, something_5
587 (python-tests-look-at "from foo.bar.baz import something, something_1")
588 (should (eq (car (python-indent-context)) :after-line))
589 (should (= (python-indent-calculate-indentation) 0))
590 (python-tests-look-at "something_2 something_3,")
591 (should (eq (car (python-indent-context)) :after-backslash-first-line))
592 (should (= (python-indent-calculate-indentation) 4))
593 (python-tests-look-at "something_4, something_5")
594 (should (eq (car (python-indent-context)) :after-backslash))
595 (should (= (python-indent-calculate-indentation) 4))
596 (goto-char (point-max))
597 (should (eq (car (python-indent-context)) :after-line))
598 (should (= (python-indent-calculate-indentation) 0))))
600 (ert-deftest python-indent-after-backslash-2 ()
601 "A pretty extreme complicated case."
602 (python-tests-with-temp-buffer
604 objects = Thing.objects.all() \\\\
605 .filter(
606 type='toy',
607 status='bought'
608 ) \\\\
609 .aggregate(
610 Sum('amount')
611 ) \\\\
612 .values_list()
614 (python-tests-look-at "objects = Thing.objects.all()")
615 (should (eq (car (python-indent-context)) :after-line))
616 (should (= (python-indent-calculate-indentation) 0))
617 (python-tests-look-at ".filter(")
618 (should (eq (car (python-indent-context))
619 :after-backslash-dotted-continuation))
620 (should (= (python-indent-calculate-indentation) 23))
621 (python-tests-look-at "type='toy',")
622 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
623 (should (= (python-indent-calculate-indentation) 27))
624 (python-tests-look-at "status='bought'")
625 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
626 (should (= (python-indent-calculate-indentation) 27))
627 (python-tests-look-at ") \\\\")
628 (should (eq (car (python-indent-context)) :inside-paren-at-closing-paren))
629 (should (= (python-indent-calculate-indentation) 23))
630 (python-tests-look-at ".aggregate(")
631 (should (eq (car (python-indent-context))
632 :after-backslash-dotted-continuation))
633 (should (= (python-indent-calculate-indentation) 23))
634 (python-tests-look-at "Sum('amount')")
635 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
636 (should (= (python-indent-calculate-indentation) 27))
637 (python-tests-look-at ") \\\\")
638 (should (eq (car (python-indent-context)) :inside-paren-at-closing-paren))
639 (should (= (python-indent-calculate-indentation) 23))
640 (python-tests-look-at ".values_list()")
641 (should (eq (car (python-indent-context))
642 :after-backslash-dotted-continuation))
643 (should (= (python-indent-calculate-indentation) 23))
644 (forward-line 1)
645 (should (eq (car (python-indent-context)) :after-line))
646 (should (= (python-indent-calculate-indentation) 0))))
648 (ert-deftest python-indent-after-backslash-3 ()
649 "Backslash continuation from block start."
650 (python-tests-with-temp-buffer
652 with open('/path/to/some/file/you/want/to/read') as file_1, \\\\
653 open('/path/to/some/file/being/written', 'w') as file_2:
654 file_2.write(file_1.read())
656 (python-tests-look-at
657 "with open('/path/to/some/file/you/want/to/read') as file_1, \\\\")
658 (should (eq (car (python-indent-context)) :after-line))
659 (should (= (python-indent-calculate-indentation) 0))
660 (python-tests-look-at
661 "open('/path/to/some/file/being/written', 'w') as file_2")
662 (should (eq (car (python-indent-context))
663 :after-backslash-block-continuation))
664 (should (= (python-indent-calculate-indentation) 5))
665 (python-tests-look-at "file_2.write(file_1.read())")
666 (should (eq (car (python-indent-context)) :after-block-start))
667 (should (= (python-indent-calculate-indentation) 4))))
669 (ert-deftest python-indent-after-backslash-4 ()
670 "Backslash continuation from assignment."
671 (python-tests-with-temp-buffer
673 super_awful_assignment = some_calculation() and \\\\
674 another_calculation() and \\\\
675 some_final_calculation()
677 (python-tests-look-at
678 "super_awful_assignment = some_calculation() and \\\\")
679 (should (eq (car (python-indent-context)) :after-line))
680 (should (= (python-indent-calculate-indentation) 0))
681 (python-tests-look-at "another_calculation() and \\\\")
682 (should (eq (car (python-indent-context))
683 :after-backslash-assignment-continuation))
684 (should (= (python-indent-calculate-indentation) 25))
685 (python-tests-look-at "some_final_calculation()")
686 (should (eq (car (python-indent-context)) :after-backslash))
687 (should (= (python-indent-calculate-indentation) 25))))
689 (ert-deftest python-indent-after-backslash-5 ()
690 "Dotted continuation bizarre example."
691 (python-tests-with-temp-buffer
693 def delete_all_things():
694 Thing \\\\
695 .objects.all() \\\\
696 .delete()
698 (python-tests-look-at "Thing \\\\")
699 (should (eq (car (python-indent-context)) :after-block-start))
700 (should (= (python-indent-calculate-indentation) 4))
701 (python-tests-look-at ".objects.all() \\\\")
702 (should (eq (car (python-indent-context)) :after-backslash-first-line))
703 (should (= (python-indent-calculate-indentation) 8))
704 (python-tests-look-at ".delete()")
705 (should (eq (car (python-indent-context))
706 :after-backslash-dotted-continuation))
707 (should (= (python-indent-calculate-indentation) 16))))
709 (ert-deftest python-indent-block-enders-1 ()
710 "Test de-indentation for pass keyword."
711 (python-tests-with-temp-buffer
713 Class foo(object):
715 def bar(self):
716 if self.baz:
717 return (1,
721 else:
722 pass
724 (python-tests-look-at "3)")
725 (forward-line 1)
726 (should (= (python-indent-calculate-indentation) 8))
727 (python-tests-look-at "pass")
728 (forward-line 1)
729 (should (eq (car (python-indent-context)) :after-block-end))
730 (should (= (python-indent-calculate-indentation) 8))))
732 (ert-deftest python-indent-block-enders-2 ()
733 "Test de-indentation for return keyword."
734 (python-tests-with-temp-buffer
736 Class foo(object):
737 '''raise lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
739 eiusmod tempor incididunt ut labore et dolore magna aliqua.
741 def bar(self):
742 \"return (1, 2, 3).\"
743 if self.baz:
744 return (1,
748 (python-tests-look-at "def")
749 (should (= (python-indent-calculate-indentation) 4))
750 (python-tests-look-at "if")
751 (should (= (python-indent-calculate-indentation) 8))
752 (python-tests-look-at "return")
753 (should (= (python-indent-calculate-indentation) 12))
754 (goto-char (point-max))
755 (should (eq (car (python-indent-context)) :after-block-end))
756 (should (= (python-indent-calculate-indentation) 8))))
758 (ert-deftest python-indent-block-enders-3 ()
759 "Test de-indentation for continue keyword."
760 (python-tests-with-temp-buffer
762 for element in lst:
763 if element is None:
764 continue
766 (python-tests-look-at "if")
767 (should (= (python-indent-calculate-indentation) 4))
768 (python-tests-look-at "continue")
769 (should (= (python-indent-calculate-indentation) 8))
770 (forward-line 1)
771 (should (eq (car (python-indent-context)) :after-block-end))
772 (should (= (python-indent-calculate-indentation) 4))))
774 (ert-deftest python-indent-block-enders-4 ()
775 "Test de-indentation for break keyword."
776 (python-tests-with-temp-buffer
778 for element in lst:
779 if element is None:
780 break
782 (python-tests-look-at "if")
783 (should (= (python-indent-calculate-indentation) 4))
784 (python-tests-look-at "break")
785 (should (= (python-indent-calculate-indentation) 8))
786 (forward-line 1)
787 (should (eq (car (python-indent-context)) :after-block-end))
788 (should (= (python-indent-calculate-indentation) 4))))
790 (ert-deftest python-indent-block-enders-5 ()
791 "Test de-indentation for raise keyword."
792 (python-tests-with-temp-buffer
794 for element in lst:
795 if element is None:
796 raise ValueError('Element cannot be None')
798 (python-tests-look-at "if")
799 (should (= (python-indent-calculate-indentation) 4))
800 (python-tests-look-at "raise")
801 (should (= (python-indent-calculate-indentation) 8))
802 (forward-line 1)
803 (should (eq (car (python-indent-context)) :after-block-end))
804 (should (= (python-indent-calculate-indentation) 4))))
806 (ert-deftest python-indent-dedenters-1 ()
807 "Test de-indentation for the elif keyword."
808 (python-tests-with-temp-buffer
810 if save:
811 try:
812 write_to_disk(data)
813 finally:
814 cleanup()
815 elif
817 (python-tests-look-at "elif\n")
818 (should (eq (car (python-indent-context)) :at-dedenter-block-start))
819 (should (= (python-indent-calculate-indentation) 0))
820 (should (= (python-indent-calculate-indentation t) 0))))
822 (ert-deftest python-indent-dedenters-2 ()
823 "Test de-indentation for the else keyword."
824 (python-tests-with-temp-buffer
826 if save:
827 try:
828 write_to_disk(data)
829 except IOError:
830 msg = 'Error saving to disk'
831 message(msg)
832 logger.exception(msg)
833 except Exception:
834 if hide_details:
835 logger.exception('Unhandled exception')
836 else
837 finally:
838 data.free()
840 (python-tests-look-at "else\n")
841 (should (eq (car (python-indent-context)) :at-dedenter-block-start))
842 (should (= (python-indent-calculate-indentation) 8))
843 (python-indent-line t)
844 (should (= (python-indent-calculate-indentation t) 4))
845 (python-indent-line t)
846 (should (= (python-indent-calculate-indentation t) 0))
847 (python-indent-line t)
848 (should (= (python-indent-calculate-indentation t) 8))))
850 (ert-deftest python-indent-dedenters-3 ()
851 "Test de-indentation for the except keyword."
852 (python-tests-with-temp-buffer
854 if save:
855 try:
856 write_to_disk(data)
857 except
859 (python-tests-look-at "except\n")
860 (should (eq (car (python-indent-context)) :at-dedenter-block-start))
861 (should (= (python-indent-calculate-indentation) 4))
862 (python-indent-line t)
863 (should (= (python-indent-calculate-indentation t) 4))))
865 (ert-deftest python-indent-dedenters-4 ()
866 "Test de-indentation for the finally keyword."
867 (python-tests-with-temp-buffer
869 if save:
870 try:
871 write_to_disk(data)
872 finally
874 (python-tests-look-at "finally\n")
875 (should (eq (car (python-indent-context)) :at-dedenter-block-start))
876 (should (= (python-indent-calculate-indentation) 4))
877 (python-indent-line t)
878 (should (= (python-indent-calculate-indentation) 4))))
880 (ert-deftest python-indent-dedenters-5 ()
881 "Test invalid levels are skipped in a complex example."
882 (python-tests-with-temp-buffer
884 if save:
885 try:
886 write_to_disk(data)
887 except IOError:
888 msg = 'Error saving to disk'
889 message(msg)
890 logger.exception(msg)
891 finally:
892 if cleanup:
893 do_cleanup()
894 else
896 (python-tests-look-at "else\n")
897 (should (eq (car (python-indent-context)) :at-dedenter-block-start))
898 (should (= (python-indent-calculate-indentation) 8))
899 (should (= (python-indent-calculate-indentation t) 0))
900 (python-indent-line t)
901 (should (= (python-indent-calculate-indentation t) 8))))
903 (ert-deftest python-indent-dedenters-6 ()
904 "Test indentation is zero when no opening block for dedenter."
905 (python-tests-with-temp-buffer
907 try:
908 # if save:
909 write_to_disk(data)
910 else
912 (python-tests-look-at "else\n")
913 (should (eq (car (python-indent-context)) :at-dedenter-block-start))
914 (should (= (python-indent-calculate-indentation) 0))
915 (should (= (python-indent-calculate-indentation t) 0))))
917 (ert-deftest python-indent-dedenters-7 ()
918 "Test indentation case from Bug#15163."
919 (python-tests-with-temp-buffer
921 if a:
922 if b:
923 pass
924 else:
925 pass
926 else:
928 (python-tests-look-at "else:" 2)
929 (should (eq (car (python-indent-context)) :at-dedenter-block-start))
930 (should (= (python-indent-calculate-indentation) 0))
931 (should (= (python-indent-calculate-indentation t) 0))))
933 (ert-deftest python-indent-dedenters-8 ()
934 "Test indentation for Bug#18432."
935 (python-tests-with-temp-buffer
937 if (a == 1 or
938 a == 2):
939 pass
940 elif (a == 3 or
941 a == 4):
943 (python-tests-look-at "elif (a == 3 or")
944 (should (eq (car (python-indent-context)) :at-dedenter-block-start))
945 (should (= (python-indent-calculate-indentation) 0))
946 (should (= (python-indent-calculate-indentation t) 0))
947 (python-tests-look-at "a == 4):\n")
948 (should (eq (car (python-indent-context)) :inside-paren))
949 (should (= (python-indent-calculate-indentation) 6))
950 (python-indent-line)
951 (should (= (python-indent-calculate-indentation t) 4))
952 (python-indent-line t)
953 (should (= (python-indent-calculate-indentation t) 0))
954 (python-indent-line t)
955 (should (= (python-indent-calculate-indentation t) 6))))
957 (ert-deftest python-indent-inside-string-1 ()
958 "Test indentation for strings."
959 (python-tests-with-temp-buffer
961 multiline = '''
962 bunch
964 lines
967 (python-tests-look-at "multiline = '''")
968 (should (eq (car (python-indent-context)) :after-line))
969 (should (= (python-indent-calculate-indentation) 0))
970 (python-tests-look-at "bunch")
971 (should (eq (car (python-indent-context)) :inside-string))
972 (should (= (python-indent-calculate-indentation) 0))
973 (python-tests-look-at "of")
974 (should (eq (car (python-indent-context)) :inside-string))
975 (should (= (python-indent-calculate-indentation) 0))
976 (python-tests-look-at "lines")
977 (should (eq (car (python-indent-context)) :inside-string))
978 (should (= (python-indent-calculate-indentation) 0))
979 (python-tests-look-at "'''")
980 (should (eq (car (python-indent-context)) :inside-string))
981 (should (= (python-indent-calculate-indentation) 0))))
983 (ert-deftest python-indent-inside-string-2 ()
984 "Test indentation for docstrings."
985 (python-tests-with-temp-buffer
987 def fn(a, b, c=True):
988 '''docstring
989 bunch
991 lines
994 (python-tests-look-at "'''docstring")
995 (should (eq (car (python-indent-context)) :after-block-start))
996 (should (= (python-indent-calculate-indentation) 4))
997 (python-tests-look-at "bunch")
998 (should (eq (car (python-indent-context)) :inside-string))
999 (should (= (python-indent-calculate-indentation) 4))
1000 (python-tests-look-at "of")
1001 (should (eq (car (python-indent-context)) :inside-string))
1002 (should (= (python-indent-calculate-indentation) 4))
1003 (python-tests-look-at "lines")
1004 (should (eq (car (python-indent-context)) :inside-string))
1005 (should (= (python-indent-calculate-indentation) 4))
1006 (python-tests-look-at "'''")
1007 (should (eq (car (python-indent-context)) :inside-string))
1008 (should (= (python-indent-calculate-indentation) 4))))
1010 (ert-deftest python-indent-inside-string-3 ()
1011 "Test indentation for nested strings."
1012 (python-tests-with-temp-buffer
1014 def fn(a, b, c=True):
1015 some_var = '''
1016 bunch
1018 lines
1021 (python-tests-look-at "some_var = '''")
1022 (should (eq (car (python-indent-context)) :after-block-start))
1023 (should (= (python-indent-calculate-indentation) 4))
1024 (python-tests-look-at "bunch")
1025 (should (eq (car (python-indent-context)) :inside-string))
1026 (should (= (python-indent-calculate-indentation) 4))
1027 (python-tests-look-at "of")
1028 (should (eq (car (python-indent-context)) :inside-string))
1029 (should (= (python-indent-calculate-indentation) 4))
1030 (python-tests-look-at "lines")
1031 (should (eq (car (python-indent-context)) :inside-string))
1032 (should (= (python-indent-calculate-indentation) 4))
1033 (python-tests-look-at "'''")
1034 (should (eq (car (python-indent-context)) :inside-string))
1035 (should (= (python-indent-calculate-indentation) 4))))
1037 (ert-deftest python-indent-electric-colon-1 ()
1038 "Test indentation case from Bug#18228."
1039 (python-tests-with-temp-buffer
1041 def a():
1042 pass
1044 def b()
1046 (python-tests-look-at "def b()")
1047 (goto-char (line-end-position))
1048 (python-tests-self-insert ":")
1049 (should (= (current-indentation) 0))))
1051 (ert-deftest python-indent-electric-colon-2 ()
1052 "Test indentation case for dedenter."
1053 (python-tests-with-temp-buffer
1055 if do:
1056 something()
1057 else
1059 (python-tests-look-at "else")
1060 (goto-char (line-end-position))
1061 (python-tests-self-insert ":")
1062 (should (= (current-indentation) 0))))
1064 (ert-deftest python-indent-electric-colon-3 ()
1065 "Test indentation case for multi-line dedenter."
1066 (python-tests-with-temp-buffer
1068 if do:
1069 something()
1070 elif (this
1072 that)
1074 (python-tests-look-at "that)")
1075 (goto-char (line-end-position))
1076 (python-tests-self-insert ":")
1077 (python-tests-look-at "elif" -1)
1078 (should (= (current-indentation) 0))
1079 (python-tests-look-at "and")
1080 (should (= (current-indentation) 6))
1081 (python-tests-look-at "that)")
1082 (should (= (current-indentation) 6))))
1084 (ert-deftest python-indent-region-1 ()
1085 "Test indentation case from Bug#18843."
1086 (let ((contents "
1087 def foo ():
1088 try:
1089 pass
1090 except:
1091 pass
1093 (python-tests-with-temp-buffer
1094 contents
1095 (python-indent-region (point-min) (point-max))
1096 (should (string= (buffer-substring-no-properties (point-min) (point-max))
1097 contents)))))
1099 (ert-deftest python-indent-region-2 ()
1100 "Test region indentation on comments."
1101 (let ((contents "
1102 def f():
1103 if True:
1104 pass
1106 # This is
1107 # some multiline
1108 # comment
1110 (python-tests-with-temp-buffer
1111 contents
1112 (python-indent-region (point-min) (point-max))
1113 (should (string= (buffer-substring-no-properties (point-min) (point-max))
1114 contents)))))
1116 (ert-deftest python-indent-region-3 ()
1117 "Test region indentation on comments."
1118 (let ((contents "
1119 def f():
1120 if True:
1121 pass
1122 # This is
1123 # some multiline
1124 # comment
1126 (expected "
1127 def f():
1128 if True:
1129 pass
1130 # This is
1131 # some multiline
1132 # comment
1134 (python-tests-with-temp-buffer
1135 contents
1136 (python-indent-region (point-min) (point-max))
1137 (should (string= (buffer-substring-no-properties (point-min) (point-max))
1138 expected)))))
1140 (ert-deftest python-indent-region-4 ()
1141 "Test region indentation block starts, dedenders and enders."
1142 (let ((contents "
1143 def f():
1144 if True:
1145 a = 5
1146 else:
1147 a = 10
1148 return a
1150 (expected "
1151 def f():
1152 if True:
1153 a = 5
1154 else:
1155 a = 10
1156 return a
1158 (python-tests-with-temp-buffer
1159 contents
1160 (python-indent-region (point-min) (point-max))
1161 (should (string= (buffer-substring-no-properties (point-min) (point-max))
1162 expected)))))
1164 (ert-deftest python-indent-region-5 ()
1165 "Test region indentation leaves strings untouched (start delimiter)."
1166 (let ((contents "
1167 def f():
1169 this is
1170 a multiline
1171 string
1174 (expected "
1175 def f():
1177 this is
1178 a multiline
1179 string
1182 (python-tests-with-temp-buffer
1183 contents
1184 (python-indent-region (point-min) (point-max))
1185 (should (string= (buffer-substring-no-properties (point-min) (point-max))
1186 expected)))))
1189 ;;; Navigation
1191 (ert-deftest python-nav-beginning-of-defun-1 ()
1192 (python-tests-with-temp-buffer
1194 def decoratorFunctionWithArguments(arg1, arg2, arg3):
1195 '''print decorated function call data to stdout.
1197 Usage:
1199 @decoratorFunctionWithArguments('arg1', 'arg2')
1200 def func(a, b, c=True):
1201 pass
1204 def wwrap(f):
1205 print 'Inside wwrap()'
1206 def wrapped_f(*args):
1207 print 'Inside wrapped_f()'
1208 print 'Decorator arguments:', arg1, arg2, arg3
1209 f(*args)
1210 print 'After f(*args)'
1211 return wrapped_f
1212 return wwrap
1214 (python-tests-look-at "return wrap")
1215 (should (= (save-excursion
1216 (python-nav-beginning-of-defun)
1217 (point))
1218 (save-excursion
1219 (python-tests-look-at "def wrapped_f(*args):" -1)
1220 (beginning-of-line)
1221 (point))))
1222 (python-tests-look-at "def wrapped_f(*args):" -1)
1223 (should (= (save-excursion
1224 (python-nav-beginning-of-defun)
1225 (point))
1226 (save-excursion
1227 (python-tests-look-at "def wwrap(f):" -1)
1228 (beginning-of-line)
1229 (point))))
1230 (python-tests-look-at "def wwrap(f):" -1)
1231 (should (= (save-excursion
1232 (python-nav-beginning-of-defun)
1233 (point))
1234 (save-excursion
1235 (python-tests-look-at "def decoratorFunctionWithArguments" -1)
1236 (beginning-of-line)
1237 (point))))))
1239 (ert-deftest python-nav-beginning-of-defun-2 ()
1240 (python-tests-with-temp-buffer
1242 class C(object):
1244 def m(self):
1245 self.c()
1247 def b():
1248 pass
1250 def a():
1251 pass
1253 def c(self):
1254 pass
1256 ;; Nested defuns, are handled with care.
1257 (python-tests-look-at "def c(self):")
1258 (should (= (save-excursion
1259 (python-nav-beginning-of-defun)
1260 (point))
1261 (save-excursion
1262 (python-tests-look-at "def m(self):" -1)
1263 (beginning-of-line)
1264 (point))))
1265 ;; Defuns on same levels should be respected.
1266 (python-tests-look-at "def a():" -1)
1267 (should (= (save-excursion
1268 (python-nav-beginning-of-defun)
1269 (point))
1270 (save-excursion
1271 (python-tests-look-at "def b():" -1)
1272 (beginning-of-line)
1273 (point))))
1274 ;; Jump to a top level defun.
1275 (python-tests-look-at "def b():" -1)
1276 (should (= (save-excursion
1277 (python-nav-beginning-of-defun)
1278 (point))
1279 (save-excursion
1280 (python-tests-look-at "def m(self):" -1)
1281 (beginning-of-line)
1282 (point))))
1283 ;; Jump to a top level defun again.
1284 (python-tests-look-at "def m(self):" -1)
1285 (should (= (save-excursion
1286 (python-nav-beginning-of-defun)
1287 (point))
1288 (save-excursion
1289 (python-tests-look-at "class C(object):" -1)
1290 (beginning-of-line)
1291 (point))))))
1293 (ert-deftest python-nav-end-of-defun-1 ()
1294 (python-tests-with-temp-buffer
1296 class C(object):
1298 def m(self):
1299 self.c()
1301 def b():
1302 pass
1304 def a():
1305 pass
1307 def c(self):
1308 pass
1310 (should (= (save-excursion
1311 (python-tests-look-at "class C(object):")
1312 (python-nav-end-of-defun)
1313 (point))
1314 (save-excursion
1315 (point-max))))
1316 (should (= (save-excursion
1317 (python-tests-look-at "def m(self):")
1318 (python-nav-end-of-defun)
1319 (point))
1320 (save-excursion
1321 (python-tests-look-at "def c(self):")
1322 (forward-line -1)
1323 (point))))
1324 (should (= (save-excursion
1325 (python-tests-look-at "def b():")
1326 (python-nav-end-of-defun)
1327 (point))
1328 (save-excursion
1329 (python-tests-look-at "def b():")
1330 (forward-line 2)
1331 (point))))
1332 (should (= (save-excursion
1333 (python-tests-look-at "def c(self):")
1334 (python-nav-end-of-defun)
1335 (point))
1336 (save-excursion
1337 (point-max))))))
1339 (ert-deftest python-nav-end-of-defun-2 ()
1340 (python-tests-with-temp-buffer
1342 def decoratorFunctionWithArguments(arg1, arg2, arg3):
1343 '''print decorated function call data to stdout.
1345 Usage:
1347 @decoratorFunctionWithArguments('arg1', 'arg2')
1348 def func(a, b, c=True):
1349 pass
1352 def wwrap(f):
1353 print 'Inside wwrap()'
1354 def wrapped_f(*args):
1355 print 'Inside wrapped_f()'
1356 print 'Decorator arguments:', arg1, arg2, arg3
1357 f(*args)
1358 print 'After f(*args)'
1359 return wrapped_f
1360 return wwrap
1362 (should (= (save-excursion
1363 (python-tests-look-at "def decoratorFunctionWithArguments")
1364 (python-nav-end-of-defun)
1365 (point))
1366 (save-excursion
1367 (point-max))))
1368 (should (= (save-excursion
1369 (python-tests-look-at "@decoratorFunctionWithArguments")
1370 (python-nav-end-of-defun)
1371 (point))
1372 (save-excursion
1373 (point-max))))
1374 (should (= (save-excursion
1375 (python-tests-look-at "def wwrap(f):")
1376 (python-nav-end-of-defun)
1377 (point))
1378 (save-excursion
1379 (python-tests-look-at "return wwrap")
1380 (line-beginning-position))))
1381 (should (= (save-excursion
1382 (python-tests-look-at "def wrapped_f(*args):")
1383 (python-nav-end-of-defun)
1384 (point))
1385 (save-excursion
1386 (python-tests-look-at "return wrapped_f")
1387 (line-beginning-position))))
1388 (should (= (save-excursion
1389 (python-tests-look-at "f(*args)")
1390 (python-nav-end-of-defun)
1391 (point))
1392 (save-excursion
1393 (python-tests-look-at "return wrapped_f")
1394 (line-beginning-position))))))
1396 (ert-deftest python-nav-backward-defun-1 ()
1397 (python-tests-with-temp-buffer
1399 class A(object): # A
1401 def a(self): # a
1402 pass
1404 def b(self): # b
1405 pass
1407 class B(object): # B
1409 class C(object): # C
1411 def d(self): # d
1412 pass
1414 # def e(self): # e
1415 # pass
1417 def c(self): # c
1418 pass
1420 # def d(self): # d
1421 # pass
1423 (goto-char (point-max))
1424 (should (= (save-excursion (python-nav-backward-defun))
1425 (python-tests-look-at " def c(self): # c" -1)))
1426 (should (= (save-excursion (python-nav-backward-defun))
1427 (python-tests-look-at " def d(self): # d" -1)))
1428 (should (= (save-excursion (python-nav-backward-defun))
1429 (python-tests-look-at " class C(object): # C" -1)))
1430 (should (= (save-excursion (python-nav-backward-defun))
1431 (python-tests-look-at " class B(object): # B" -1)))
1432 (should (= (save-excursion (python-nav-backward-defun))
1433 (python-tests-look-at " def b(self): # b" -1)))
1434 (should (= (save-excursion (python-nav-backward-defun))
1435 (python-tests-look-at " def a(self): # a" -1)))
1436 (should (= (save-excursion (python-nav-backward-defun))
1437 (python-tests-look-at "class A(object): # A" -1)))
1438 (should (not (python-nav-backward-defun)))))
1440 (ert-deftest python-nav-backward-defun-2 ()
1441 (python-tests-with-temp-buffer
1443 def decoratorFunctionWithArguments(arg1, arg2, arg3):
1444 '''print decorated function call data to stdout.
1446 Usage:
1448 @decoratorFunctionWithArguments('arg1', 'arg2')
1449 def func(a, b, c=True):
1450 pass
1453 def wwrap(f):
1454 print 'Inside wwrap()'
1455 def wrapped_f(*args):
1456 print 'Inside wrapped_f()'
1457 print 'Decorator arguments:', arg1, arg2, arg3
1458 f(*args)
1459 print 'After f(*args)'
1460 return wrapped_f
1461 return wwrap
1463 (goto-char (point-max))
1464 (should (= (save-excursion (python-nav-backward-defun))
1465 (python-tests-look-at " def wrapped_f(*args):" -1)))
1466 (should (= (save-excursion (python-nav-backward-defun))
1467 (python-tests-look-at " def wwrap(f):" -1)))
1468 (should (= (save-excursion (python-nav-backward-defun))
1469 (python-tests-look-at "def decoratorFunctionWithArguments(arg1, arg2, arg3):" -1)))
1470 (should (not (python-nav-backward-defun)))))
1472 (ert-deftest python-nav-backward-defun-3 ()
1473 (python-tests-with-temp-buffer
1476 def u(self):
1477 pass
1479 def v(self):
1480 pass
1482 def w(self):
1483 pass
1486 class A(object):
1487 pass
1489 (goto-char (point-min))
1490 (let ((point (python-tests-look-at "class A(object):")))
1491 (should (not (python-nav-backward-defun)))
1492 (should (= point (point))))))
1494 (ert-deftest python-nav-forward-defun-1 ()
1495 (python-tests-with-temp-buffer
1497 class A(object): # A
1499 def a(self): # a
1500 pass
1502 def b(self): # b
1503 pass
1505 class B(object): # B
1507 class C(object): # C
1509 def d(self): # d
1510 pass
1512 # def e(self): # e
1513 # pass
1515 def c(self): # c
1516 pass
1518 # def d(self): # d
1519 # pass
1521 (goto-char (point-min))
1522 (should (= (save-excursion (python-nav-forward-defun))
1523 (python-tests-look-at "(object): # A")))
1524 (should (= (save-excursion (python-nav-forward-defun))
1525 (python-tests-look-at "(self): # a")))
1526 (should (= (save-excursion (python-nav-forward-defun))
1527 (python-tests-look-at "(self): # b")))
1528 (should (= (save-excursion (python-nav-forward-defun))
1529 (python-tests-look-at "(object): # B")))
1530 (should (= (save-excursion (python-nav-forward-defun))
1531 (python-tests-look-at "(object): # C")))
1532 (should (= (save-excursion (python-nav-forward-defun))
1533 (python-tests-look-at "(self): # d")))
1534 (should (= (save-excursion (python-nav-forward-defun))
1535 (python-tests-look-at "(self): # c")))
1536 (should (not (python-nav-forward-defun)))))
1538 (ert-deftest python-nav-forward-defun-2 ()
1539 (python-tests-with-temp-buffer
1541 def decoratorFunctionWithArguments(arg1, arg2, arg3):
1542 '''print decorated function call data to stdout.
1544 Usage:
1546 @decoratorFunctionWithArguments('arg1', 'arg2')
1547 def func(a, b, c=True):
1548 pass
1551 def wwrap(f):
1552 print 'Inside wwrap()'
1553 def wrapped_f(*args):
1554 print 'Inside wrapped_f()'
1555 print 'Decorator arguments:', arg1, arg2, arg3
1556 f(*args)
1557 print 'After f(*args)'
1558 return wrapped_f
1559 return wwrap
1561 (goto-char (point-min))
1562 (should (= (save-excursion (python-nav-forward-defun))
1563 (python-tests-look-at "(arg1, arg2, arg3):")))
1564 (should (= (save-excursion (python-nav-forward-defun))
1565 (python-tests-look-at "(f):")))
1566 (should (= (save-excursion (python-nav-forward-defun))
1567 (python-tests-look-at "(*args):")))
1568 (should (not (python-nav-forward-defun)))))
1570 (ert-deftest python-nav-forward-defun-3 ()
1571 (python-tests-with-temp-buffer
1573 class A(object):
1574 pass
1577 def u(self):
1578 pass
1580 def v(self):
1581 pass
1583 def w(self):
1584 pass
1587 (goto-char (point-min))
1588 (let ((point (python-tests-look-at "(object):")))
1589 (should (not (python-nav-forward-defun)))
1590 (should (= point (point))))))
1592 (ert-deftest python-nav-beginning-of-statement-1 ()
1593 (python-tests-with-temp-buffer
1595 v1 = 123 + \
1596 456 + \
1598 v2 = (value1,
1599 value2,
1601 value3,
1602 value4)
1603 v3 = ('this is a string'
1605 'that is continued'
1606 'between lines'
1607 'within a paren',
1608 # this is a comment, yo
1609 'continue previous line')
1610 v4 = '''
1611 a very long
1612 string
1615 (python-tests-look-at "v2 =")
1616 (python-util-forward-comment -1)
1617 (should (= (save-excursion
1618 (python-nav-beginning-of-statement)
1619 (point))
1620 (python-tests-look-at "v1 =" -1 t)))
1621 (python-tests-look-at "v3 =")
1622 (python-util-forward-comment -1)
1623 (should (= (save-excursion
1624 (python-nav-beginning-of-statement)
1625 (point))
1626 (python-tests-look-at "v2 =" -1 t)))
1627 (python-tests-look-at "v4 =")
1628 (python-util-forward-comment -1)
1629 (should (= (save-excursion
1630 (python-nav-beginning-of-statement)
1631 (point))
1632 (python-tests-look-at "v3 =" -1 t)))
1633 (goto-char (point-max))
1634 (python-util-forward-comment -1)
1635 (should (= (save-excursion
1636 (python-nav-beginning-of-statement)
1637 (point))
1638 (python-tests-look-at "v4 =" -1 t)))))
1640 (ert-deftest python-nav-end-of-statement-1 ()
1641 (python-tests-with-temp-buffer
1643 v1 = 123 + \
1644 456 + \
1646 v2 = (value1,
1647 value2,
1649 value3,
1650 value4)
1651 v3 = ('this is a string'
1653 'that is continued'
1654 'between lines'
1655 'within a paren',
1656 # this is a comment, yo
1657 'continue previous line')
1658 v4 = '''
1659 a very long
1660 string
1663 (python-tests-look-at "v1 =")
1664 (should (= (save-excursion
1665 (python-nav-end-of-statement)
1666 (point))
1667 (save-excursion
1668 (python-tests-look-at "789")
1669 (line-end-position))))
1670 (python-tests-look-at "v2 =")
1671 (should (= (save-excursion
1672 (python-nav-end-of-statement)
1673 (point))
1674 (save-excursion
1675 (python-tests-look-at "value4)")
1676 (line-end-position))))
1677 (python-tests-look-at "v3 =")
1678 (should (= (save-excursion
1679 (python-nav-end-of-statement)
1680 (point))
1681 (save-excursion
1682 (python-tests-look-at
1683 "'continue previous line')")
1684 (line-end-position))))
1685 (python-tests-look-at "v4 =")
1686 (should (= (save-excursion
1687 (python-nav-end-of-statement)
1688 (point))
1689 (save-excursion
1690 (goto-char (point-max))
1691 (python-util-forward-comment -1)
1692 (point))))))
1694 (ert-deftest python-nav-forward-statement-1 ()
1695 (python-tests-with-temp-buffer
1697 v1 = 123 + \
1698 456 + \
1700 v2 = (value1,
1701 value2,
1703 value3,
1704 value4)
1705 v3 = ('this is a string'
1707 'that is continued'
1708 'between lines'
1709 'within a paren',
1710 # this is a comment, yo
1711 'continue previous line')
1712 v4 = '''
1713 a very long
1714 string
1717 (python-tests-look-at "v1 =")
1718 (should (= (save-excursion
1719 (python-nav-forward-statement)
1720 (point))
1721 (python-tests-look-at "v2 =")))
1722 (should (= (save-excursion
1723 (python-nav-forward-statement)
1724 (point))
1725 (python-tests-look-at "v3 =")))
1726 (should (= (save-excursion
1727 (python-nav-forward-statement)
1728 (point))
1729 (python-tests-look-at "v4 =")))
1730 (should (= (save-excursion
1731 (python-nav-forward-statement)
1732 (point))
1733 (point-max)))))
1735 (ert-deftest python-nav-backward-statement-1 ()
1736 (python-tests-with-temp-buffer
1738 v1 = 123 + \
1739 456 + \
1741 v2 = (value1,
1742 value2,
1744 value3,
1745 value4)
1746 v3 = ('this is a string'
1748 'that is continued'
1749 'between lines'
1750 'within a paren',
1751 # this is a comment, yo
1752 'continue previous line')
1753 v4 = '''
1754 a very long
1755 string
1758 (goto-char (point-max))
1759 (should (= (save-excursion
1760 (python-nav-backward-statement)
1761 (point))
1762 (python-tests-look-at "v4 =" -1)))
1763 (should (= (save-excursion
1764 (python-nav-backward-statement)
1765 (point))
1766 (python-tests-look-at "v3 =" -1)))
1767 (should (= (save-excursion
1768 (python-nav-backward-statement)
1769 (point))
1770 (python-tests-look-at "v2 =" -1)))
1771 (should (= (save-excursion
1772 (python-nav-backward-statement)
1773 (point))
1774 (python-tests-look-at "v1 =" -1)))))
1776 (ert-deftest python-nav-backward-statement-2 ()
1777 :expected-result :failed
1778 (python-tests-with-temp-buffer
1780 v1 = 123 + \
1781 456 + \
1783 v2 = (value1,
1784 value2,
1786 value3,
1787 value4)
1789 ;; FIXME: For some reason `python-nav-backward-statement' is moving
1790 ;; back two sentences when starting from 'value4)'.
1791 (goto-char (point-max))
1792 (python-util-forward-comment -1)
1793 (should (= (save-excursion
1794 (python-nav-backward-statement)
1795 (point))
1796 (python-tests-look-at "v2 =" -1 t)))))
1798 (ert-deftest python-nav-beginning-of-block-1 ()
1799 (python-tests-with-temp-buffer
1801 def decoratorFunctionWithArguments(arg1, arg2, arg3):
1802 '''print decorated function call data to stdout.
1804 Usage:
1806 @decoratorFunctionWithArguments('arg1', 'arg2')
1807 def func(a, b, c=True):
1808 pass
1811 def wwrap(f):
1812 print 'Inside wwrap()'
1813 def wrapped_f(*args):
1814 print 'Inside wrapped_f()'
1815 print 'Decorator arguments:', arg1, arg2, arg3
1816 f(*args)
1817 print 'After f(*args)'
1818 return wrapped_f
1819 return wwrap
1821 (python-tests-look-at "return wwrap")
1822 (should (= (save-excursion
1823 (python-nav-beginning-of-block)
1824 (point))
1825 (python-tests-look-at "def decoratorFunctionWithArguments" -1)))
1826 (python-tests-look-at "print 'Inside wwrap()'")
1827 (should (= (save-excursion
1828 (python-nav-beginning-of-block)
1829 (point))
1830 (python-tests-look-at "def wwrap(f):" -1)))
1831 (python-tests-look-at "print 'After f(*args)'")
1832 (end-of-line)
1833 (should (= (save-excursion
1834 (python-nav-beginning-of-block)
1835 (point))
1836 (python-tests-look-at "def wrapped_f(*args):" -1)))
1837 (python-tests-look-at "return wrapped_f")
1838 (should (= (save-excursion
1839 (python-nav-beginning-of-block)
1840 (point))
1841 (python-tests-look-at "def wwrap(f):" -1)))))
1843 (ert-deftest python-nav-end-of-block-1 ()
1844 (python-tests-with-temp-buffer
1846 def decoratorFunctionWithArguments(arg1, arg2, arg3):
1847 '''print decorated function call data to stdout.
1849 Usage:
1851 @decoratorFunctionWithArguments('arg1', 'arg2')
1852 def func(a, b, c=True):
1853 pass
1856 def wwrap(f):
1857 print 'Inside wwrap()'
1858 def wrapped_f(*args):
1859 print 'Inside wrapped_f()'
1860 print 'Decorator arguments:', arg1, arg2, arg3
1861 f(*args)
1862 print 'After f(*args)'
1863 return wrapped_f
1864 return wwrap
1866 (python-tests-look-at "def decoratorFunctionWithArguments")
1867 (should (= (save-excursion
1868 (python-nav-end-of-block)
1869 (point))
1870 (save-excursion
1871 (goto-char (point-max))
1872 (python-util-forward-comment -1)
1873 (point))))
1874 (python-tests-look-at "def wwrap(f):")
1875 (should (= (save-excursion
1876 (python-nav-end-of-block)
1877 (point))
1878 (save-excursion
1879 (python-tests-look-at "return wrapped_f")
1880 (line-end-position))))
1881 (end-of-line)
1882 (should (= (save-excursion
1883 (python-nav-end-of-block)
1884 (point))
1885 (save-excursion
1886 (python-tests-look-at "return wrapped_f")
1887 (line-end-position))))
1888 (python-tests-look-at "f(*args)")
1889 (should (= (save-excursion
1890 (python-nav-end-of-block)
1891 (point))
1892 (save-excursion
1893 (python-tests-look-at "print 'After f(*args)'")
1894 (line-end-position))))))
1896 (ert-deftest python-nav-forward-block-1 ()
1897 "This also accounts as a test for `python-nav-backward-block'."
1898 (python-tests-with-temp-buffer
1900 if request.user.is_authenticated():
1901 # def block():
1902 # pass
1903 try:
1904 profile = request.user.get_profile()
1905 except Profile.DoesNotExist:
1906 profile = Profile.objects.create(user=request.user)
1907 else:
1908 if profile.stats:
1909 profile.recalculate_stats()
1910 else:
1911 profile.clear_stats()
1912 finally:
1913 profile.views += 1
1914 profile.save()
1916 (should (= (save-excursion (python-nav-forward-block))
1917 (python-tests-look-at "if request.user.is_authenticated():")))
1918 (should (= (save-excursion (python-nav-forward-block))
1919 (python-tests-look-at "try:")))
1920 (should (= (save-excursion (python-nav-forward-block))
1921 (python-tests-look-at "except Profile.DoesNotExist:")))
1922 (should (= (save-excursion (python-nav-forward-block))
1923 (python-tests-look-at "else:")))
1924 (should (= (save-excursion (python-nav-forward-block))
1925 (python-tests-look-at "if profile.stats:")))
1926 (should (= (save-excursion (python-nav-forward-block))
1927 (python-tests-look-at "else:")))
1928 (should (= (save-excursion (python-nav-forward-block))
1929 (python-tests-look-at "finally:")))
1930 ;; When point is at the last block, leave it there and return nil
1931 (should (not (save-excursion (python-nav-forward-block))))
1932 ;; Move backwards, and even if the number of moves is less than the
1933 ;; provided argument return the point.
1934 (should (= (save-excursion (python-nav-forward-block -10))
1935 (python-tests-look-at
1936 "if request.user.is_authenticated():" -1)))))
1938 (ert-deftest python-nav-forward-sexp-1 ()
1939 (python-tests-with-temp-buffer
1945 (python-tests-look-at "a()")
1946 (python-nav-forward-sexp)
1947 (should (looking-at "$"))
1948 (should (save-excursion
1949 (beginning-of-line)
1950 (looking-at "a()")))
1951 (python-nav-forward-sexp)
1952 (should (looking-at "$"))
1953 (should (save-excursion
1954 (beginning-of-line)
1955 (looking-at "b()")))
1956 (python-nav-forward-sexp)
1957 (should (looking-at "$"))
1958 (should (save-excursion
1959 (beginning-of-line)
1960 (looking-at "c()")))
1961 ;; Movement next to a paren should do what lisp does and
1962 ;; unfortunately It can't change, because otherwise
1963 ;; `blink-matching-open' breaks.
1964 (python-nav-forward-sexp -1)
1965 (should (looking-at "()"))
1966 (should (save-excursion
1967 (beginning-of-line)
1968 (looking-at "c()")))
1969 (python-nav-forward-sexp -1)
1970 (should (looking-at "c()"))
1971 (python-nav-forward-sexp -1)
1972 (should (looking-at "b()"))
1973 (python-nav-forward-sexp -1)
1974 (should (looking-at "a()"))))
1976 (ert-deftest python-nav-forward-sexp-2 ()
1977 (python-tests-with-temp-buffer
1979 def func():
1980 if True:
1981 aaa = bbb
1982 ccc = ddd
1983 eee = fff
1984 return ggg
1986 (python-tests-look-at "aa =")
1987 (python-nav-forward-sexp)
1988 (should (looking-at " = bbb"))
1989 (python-nav-forward-sexp)
1990 (should (looking-at "$"))
1991 (should (save-excursion
1992 (back-to-indentation)
1993 (looking-at "aaa = bbb")))
1994 (python-nav-forward-sexp)
1995 (should (looking-at "$"))
1996 (should (save-excursion
1997 (back-to-indentation)
1998 (looking-at "ccc = ddd")))
1999 (python-nav-forward-sexp)
2000 (should (looking-at "$"))
2001 (should (save-excursion
2002 (back-to-indentation)
2003 (looking-at "eee = fff")))
2004 (python-nav-forward-sexp)
2005 (should (looking-at "$"))
2006 (should (save-excursion
2007 (back-to-indentation)
2008 (looking-at "return ggg")))
2009 (python-nav-forward-sexp -1)
2010 (should (looking-at "def func():"))))
2012 (ert-deftest python-nav-forward-sexp-3 ()
2013 (python-tests-with-temp-buffer
2015 from some_module import some_sub_module
2016 from another_module import another_sub_module
2018 def another_statement():
2019 pass
2021 (python-tests-look-at "some_module")
2022 (python-nav-forward-sexp)
2023 (should (looking-at " import"))
2024 (python-nav-forward-sexp)
2025 (should (looking-at " some_sub_module"))
2026 (python-nav-forward-sexp)
2027 (should (looking-at "$"))
2028 (should
2029 (save-excursion
2030 (back-to-indentation)
2031 (looking-at
2032 "from some_module import some_sub_module")))
2033 (python-nav-forward-sexp)
2034 (should (looking-at "$"))
2035 (should
2036 (save-excursion
2037 (back-to-indentation)
2038 (looking-at
2039 "from another_module import another_sub_module")))
2040 (python-nav-forward-sexp)
2041 (should (looking-at "$"))
2042 (should
2043 (save-excursion
2044 (back-to-indentation)
2045 (looking-at
2046 "pass")))
2047 (python-nav-forward-sexp -1)
2048 (should (looking-at "def another_statement():"))
2049 (python-nav-forward-sexp -1)
2050 (should (looking-at "from another_module import another_sub_module"))
2051 (python-nav-forward-sexp -1)
2052 (should (looking-at "from some_module import some_sub_module"))))
2054 (ert-deftest python-nav-forward-sexp-safe-1 ()
2055 (python-tests-with-temp-buffer
2057 profile = Profile.objects.create(user=request.user)
2058 profile.notify()
2060 (python-tests-look-at "profile =")
2061 (python-nav-forward-sexp-safe 1)
2062 (should (looking-at "$"))
2063 (beginning-of-line 1)
2064 (python-tests-look-at "user=request.user")
2065 (python-nav-forward-sexp-safe -1)
2066 (should (looking-at "(user=request.user)"))
2067 (python-nav-forward-sexp-safe -4)
2068 (should (looking-at "profile ="))
2069 (python-tests-look-at "user=request.user")
2070 (python-nav-forward-sexp-safe 3)
2071 (should (looking-at ")"))
2072 (python-nav-forward-sexp-safe 1)
2073 (should (looking-at "$"))
2074 (python-nav-forward-sexp-safe 1)
2075 (should (looking-at "$"))))
2077 (ert-deftest python-nav-up-list-1 ()
2078 (python-tests-with-temp-buffer
2080 def f():
2081 if True:
2082 return [i for i in range(3)]
2084 (python-tests-look-at "3)]")
2085 (python-nav-up-list)
2086 (should (looking-at "]"))
2087 (python-nav-up-list)
2088 (should (looking-at "$"))))
2090 (ert-deftest python-nav-backward-up-list-1 ()
2091 :expected-result :failed
2092 (python-tests-with-temp-buffer
2094 def f():
2095 if True:
2096 return [i for i in range(3)]
2098 (python-tests-look-at "3)]")
2099 (python-nav-backward-up-list)
2100 (should (looking-at "(3)\\]"))
2101 (python-nav-backward-up-list)
2102 (should (looking-at
2103 "\\[i for i in range(3)\\]"))
2104 ;; FIXME: Need to move to beginning-of-statement.
2105 (python-nav-backward-up-list)
2106 (should (looking-at
2107 "return \\[i for i in range(3)\\]"))
2108 (python-nav-backward-up-list)
2109 (should (looking-at "if True:"))
2110 (python-nav-backward-up-list)
2111 (should (looking-at "def f():"))))
2113 (ert-deftest python-indent-dedent-line-backspace-1 ()
2114 "Check de-indentation on first call. Bug#18319."
2115 (python-tests-with-temp-buffer
2117 if True:
2118 x ()
2119 if False:
2121 (python-tests-look-at "if False:")
2122 (call-interactively #'python-indent-dedent-line-backspace)
2123 (should (zerop (current-indentation)))
2124 ;; XXX: This should be a call to `undo' but it's triggering errors.
2125 (insert " ")
2126 (should (= (current-indentation) 4))
2127 (call-interactively #'python-indent-dedent-line-backspace)
2128 (should (zerop (current-indentation)))))
2130 (ert-deftest python-indent-dedent-line-backspace-2 ()
2131 "Check de-indentation with tabs. Bug#19730."
2132 (let ((tab-width 8))
2133 (python-tests-with-temp-buffer
2135 if x:
2136 \tabcdefg
2138 (python-tests-look-at "abcdefg")
2139 (goto-char (line-end-position))
2140 (call-interactively #'python-indent-dedent-line-backspace)
2141 (should
2142 (string= (buffer-substring-no-properties
2143 (line-beginning-position) (line-end-position))
2144 "\tabcdef")))))
2146 (ert-deftest python-indent-dedent-line-backspace-3 ()
2147 "Paranoid check of de-indentation with tabs. Bug#19730."
2148 (let ((tab-width 8))
2149 (python-tests-with-temp-buffer
2151 if x:
2152 \tif y:
2153 \t abcdefg
2155 (python-tests-look-at "abcdefg")
2156 (goto-char (line-end-position))
2157 (call-interactively #'python-indent-dedent-line-backspace)
2158 (should
2159 (string= (buffer-substring-no-properties
2160 (line-beginning-position) (line-end-position))
2161 "\t abcdef"))
2162 (back-to-indentation)
2163 (call-interactively #'python-indent-dedent-line-backspace)
2164 (should
2165 (string= (buffer-substring-no-properties
2166 (line-beginning-position) (line-end-position))
2167 "\tabcdef"))
2168 (call-interactively #'python-indent-dedent-line-backspace)
2169 (should
2170 (string= (buffer-substring-no-properties
2171 (line-beginning-position) (line-end-position))
2172 " abcdef"))
2173 (call-interactively #'python-indent-dedent-line-backspace)
2174 (should
2175 (string= (buffer-substring-no-properties
2176 (line-beginning-position) (line-end-position))
2177 "abcdef")))))
2180 ;;; Shell integration
2182 (defvar python-tests-shell-interpreter "python")
2184 (ert-deftest python-shell-get-process-name-1 ()
2185 "Check process name calculation on different scenarios."
2186 (python-tests-with-temp-buffer
2188 (should (string= (python-shell-get-process-name nil)
2189 python-shell-buffer-name))
2190 ;; When the `current-buffer' doesn't have `buffer-file-name', even
2191 ;; if dedicated flag is non-nil should not include its name.
2192 (should (string= (python-shell-get-process-name t)
2193 python-shell-buffer-name)))
2194 (python-tests-with-temp-file
2196 ;; `buffer-file-name' is non-nil but the dedicated flag is nil and
2197 ;; should be respected.
2198 (should (string= (python-shell-get-process-name nil)
2199 python-shell-buffer-name))
2200 (should (string=
2201 (python-shell-get-process-name t)
2202 (format "%s[%s]" python-shell-buffer-name buffer-file-name)))))
2204 (ert-deftest python-shell-internal-get-process-name-1 ()
2205 "Check the internal process name is config-unique."
2206 (let* ((python-shell-interpreter python-tests-shell-interpreter)
2207 (python-shell-interpreter-args "")
2208 (python-shell-prompt-regexp ">>> ")
2209 (python-shell-prompt-block-regexp "[.][.][.] ")
2210 (python-shell-setup-codes "")
2211 (python-shell-process-environment "")
2212 (python-shell-extra-pythonpaths "")
2213 (python-shell-exec-path "")
2214 (python-shell-virtualenv-path "")
2215 (expected (python-tests-with-temp-buffer
2216 "" (python-shell-internal-get-process-name))))
2217 ;; Same configurations should match.
2218 (should
2219 (string= expected
2220 (python-tests-with-temp-buffer
2221 "" (python-shell-internal-get-process-name))))
2222 (let ((python-shell-interpreter-args "-B"))
2223 ;; A minimal change should generate different names.
2224 (should
2225 (not (string=
2226 expected
2227 (python-tests-with-temp-buffer
2228 "" (python-shell-internal-get-process-name))))))))
2230 (ert-deftest python-shell-parse-command-1 ()
2231 "Check the command to execute is calculated correctly.
2232 Using `python-shell-interpreter' and
2233 `python-shell-interpreter-args'."
2234 (skip-unless (executable-find python-tests-shell-interpreter))
2235 (let ((python-shell-interpreter (executable-find
2236 python-tests-shell-interpreter))
2237 (python-shell-interpreter-args "-B"))
2238 (should (string=
2239 (format "%s %s"
2240 python-shell-interpreter
2241 python-shell-interpreter-args)
2242 (python-shell-parse-command)))))
2244 (ert-deftest python-shell-calculate-process-environment-1 ()
2245 "Test `python-shell-process-environment' modification."
2246 (let* ((original-process-environment process-environment)
2247 (python-shell-process-environment
2248 '("TESTVAR1=value1" "TESTVAR2=value2"))
2249 (process-environment
2250 (python-shell-calculate-process-environment)))
2251 (should (equal (getenv "TESTVAR1") "value1"))
2252 (should (equal (getenv "TESTVAR2") "value2"))))
2254 (ert-deftest python-shell-calculate-process-environment-2 ()
2255 "Test `python-shell-extra-pythonpaths' modification."
2256 (let* ((original-process-environment process-environment)
2257 (original-pythonpath (getenv "PYTHONPATH"))
2258 (paths '("path1" "path2"))
2259 (python-shell-extra-pythonpaths paths)
2260 (process-environment
2261 (python-shell-calculate-process-environment)))
2262 (should (equal (getenv "PYTHONPATH")
2263 (concat
2264 (mapconcat 'identity paths path-separator)
2265 path-separator original-pythonpath)))))
2267 (ert-deftest python-shell-calculate-process-environment-3 ()
2268 "Test `python-shell-virtualenv-path' modification."
2269 (let* ((original-process-environment process-environment)
2270 (original-path (or (getenv "PATH") ""))
2271 (python-shell-virtualenv-path
2272 (directory-file-name user-emacs-directory))
2273 (process-environment
2274 (python-shell-calculate-process-environment)))
2275 (should (not (getenv "PYTHONHOME")))
2276 (should (string= (getenv "VIRTUAL_ENV") python-shell-virtualenv-path))
2277 (should (equal (getenv "PATH")
2278 (format "%s/bin%s%s"
2279 python-shell-virtualenv-path
2280 path-separator original-path)))))
2282 (ert-deftest python-shell-calculate-process-environment-4 ()
2283 "Test `python-shell-unbuffered' modification."
2284 (setenv "PYTHONUNBUFFERED")
2285 (let* ((process-environment
2286 (python-shell-calculate-process-environment)))
2287 ;; Defaults to t
2288 (should python-shell-unbuffered)
2289 (should (string= (getenv "PYTHONUNBUFFERED") "1"))))
2291 (ert-deftest python-shell-calculate-process-environment-5 ()
2292 (setenv "PYTHONUNBUFFERED")
2293 "Test `python-shell-unbuffered' modification."
2294 (let* ((python-shell-unbuffered nil)
2295 (process-environment
2296 (python-shell-calculate-process-environment)))
2297 (should (not (getenv "PYTHONUNBUFFERED")))))
2299 (ert-deftest python-shell-calculate-exec-path-1 ()
2300 "Test `python-shell-exec-path' modification."
2301 (let* ((original-exec-path exec-path)
2302 (python-shell-exec-path '("path1" "path2"))
2303 (exec-path (python-shell-calculate-exec-path)))
2304 (should (equal
2305 exec-path
2306 (append python-shell-exec-path
2307 original-exec-path)))))
2309 (ert-deftest python-shell-calculate-exec-path-2 ()
2310 "Test `python-shell-exec-path' modification."
2311 (let* ((original-exec-path exec-path)
2312 (python-shell-virtualenv-path
2313 (directory-file-name (expand-file-name user-emacs-directory)))
2314 (exec-path (python-shell-calculate-exec-path)))
2315 (should (equal
2316 exec-path
2317 (append (cons
2318 (format "%s/bin" python-shell-virtualenv-path)
2319 original-exec-path))))))
2321 (ert-deftest python-shell-make-comint-1 ()
2322 "Check comint creation for global shell buffer."
2323 (skip-unless (executable-find python-tests-shell-interpreter))
2324 ;; The interpreter can get killed too quickly to allow it to clean
2325 ;; up the tempfiles that the default python-shell-setup-codes create,
2326 ;; so it leaves tempfiles behind, which is a minor irritation.
2327 (let* ((python-shell-setup-codes nil)
2328 (python-shell-interpreter
2329 (executable-find python-tests-shell-interpreter))
2330 (proc-name (python-shell-get-process-name nil))
2331 (shell-buffer
2332 (python-tests-with-temp-buffer
2333 "" (python-shell-make-comint
2334 (python-shell-parse-command) proc-name)))
2335 (process (get-buffer-process shell-buffer)))
2336 (unwind-protect
2337 (progn
2338 (set-process-query-on-exit-flag process nil)
2339 (should (process-live-p process))
2340 (with-current-buffer shell-buffer
2341 (should (eq major-mode 'inferior-python-mode))
2342 (should (string= (buffer-name) (format "*%s*" proc-name)))))
2343 (kill-buffer shell-buffer))))
2345 (ert-deftest python-shell-make-comint-2 ()
2346 "Check comint creation for internal shell buffer."
2347 (skip-unless (executable-find python-tests-shell-interpreter))
2348 (let* ((python-shell-setup-codes nil)
2349 (python-shell-interpreter
2350 (executable-find python-tests-shell-interpreter))
2351 (proc-name (python-shell-internal-get-process-name))
2352 (shell-buffer
2353 (python-tests-with-temp-buffer
2354 "" (python-shell-make-comint
2355 (python-shell-parse-command) proc-name nil t)))
2356 (process (get-buffer-process shell-buffer)))
2357 (unwind-protect
2358 (progn
2359 (set-process-query-on-exit-flag process nil)
2360 (should (process-live-p process))
2361 (with-current-buffer shell-buffer
2362 (should (eq major-mode 'inferior-python-mode))
2363 (should (string= (buffer-name) (format " *%s*" proc-name)))))
2364 (kill-buffer shell-buffer))))
2366 (ert-deftest python-shell-make-comint-3 ()
2367 "Check comint creation with overridden python interpreter and args.
2368 The command passed to `python-shell-make-comint' as argument must
2369 locally override global values set in `python-shell-interpreter'
2370 and `python-shell-interpreter-args' in the new shell buffer."
2371 (skip-unless (executable-find python-tests-shell-interpreter))
2372 (let* ((python-shell-setup-codes nil)
2373 (python-shell-interpreter "interpreter")
2374 (python-shell-interpreter-args "--some-args")
2375 (proc-name (python-shell-get-process-name nil))
2376 (interpreter-override
2377 (concat (executable-find python-tests-shell-interpreter) " " "-i"))
2378 (shell-buffer
2379 (python-tests-with-temp-buffer
2380 "" (python-shell-make-comint interpreter-override proc-name nil)))
2381 (process (get-buffer-process shell-buffer)))
2382 (unwind-protect
2383 (progn
2384 (set-process-query-on-exit-flag process nil)
2385 (should (process-live-p process))
2386 (with-current-buffer shell-buffer
2387 (should (eq major-mode 'inferior-python-mode))
2388 (should (file-equal-p
2389 python-shell-interpreter
2390 (executable-find python-tests-shell-interpreter)))
2391 (should (string= python-shell-interpreter-args "-i"))))
2392 (kill-buffer shell-buffer))))
2394 (ert-deftest python-shell-make-comint-4 ()
2395 "Check shell calculated prompts regexps are set."
2396 (skip-unless (executable-find python-tests-shell-interpreter))
2397 (let* ((process-environment process-environment)
2398 (python-shell-setup-codes nil)
2399 (python-shell-interpreter
2400 (executable-find python-tests-shell-interpreter))
2401 (python-shell-interpreter-args "-i")
2402 (python-shell--prompt-calculated-input-regexp nil)
2403 (python-shell--prompt-calculated-output-regexp nil)
2404 (python-shell-prompt-detect-enabled t)
2405 (python-shell-prompt-input-regexps '("extralargeinputprompt" "sml"))
2406 (python-shell-prompt-output-regexps '("extralargeoutputprompt" "sml"))
2407 (python-shell-prompt-regexp "in")
2408 (python-shell-prompt-block-regexp "block")
2409 (python-shell-prompt-pdb-regexp "pdf")
2410 (python-shell-prompt-output-regexp "output")
2411 (startup-code (concat "import sys\n"
2412 "sys.ps1 = 'py> '\n"
2413 "sys.ps2 = '..> '\n"
2414 "sys.ps3 = 'out '\n"))
2415 (startup-file (python-shell--save-temp-file startup-code))
2416 (proc-name (python-shell-get-process-name nil))
2417 (shell-buffer
2418 (progn
2419 (setenv "PYTHONSTARTUP" startup-file)
2420 (python-tests-with-temp-buffer
2421 "" (python-shell-make-comint
2422 (python-shell-parse-command) proc-name nil))))
2423 (process (get-buffer-process shell-buffer)))
2424 (unwind-protect
2425 (progn
2426 (set-process-query-on-exit-flag process nil)
2427 (should (process-live-p process))
2428 (with-current-buffer shell-buffer
2429 (should (eq major-mode 'inferior-python-mode))
2430 (should (string=
2431 python-shell--prompt-calculated-input-regexp
2432 (concat "^\\(extralargeinputprompt\\|\\.\\.> \\|"
2433 "block\\|py> \\|pdf\\|sml\\|in\\)")))
2434 (should (string=
2435 python-shell--prompt-calculated-output-regexp
2436 "^\\(extralargeoutputprompt\\|output\\|out \\|sml\\)"))))
2437 (delete-file startup-file)
2438 (kill-buffer shell-buffer))))
2440 (ert-deftest python-shell-get-process-1 ()
2441 "Check dedicated shell process preference over global."
2442 (skip-unless (executable-find python-tests-shell-interpreter))
2443 (python-tests-with-temp-file
2445 (let* ((python-shell-setup-codes nil)
2446 (python-shell-interpreter
2447 (executable-find python-tests-shell-interpreter))
2448 (global-proc-name (python-shell-get-process-name nil))
2449 (dedicated-proc-name (python-shell-get-process-name t))
2450 (global-shell-buffer
2451 (python-shell-make-comint
2452 (python-shell-parse-command) global-proc-name))
2453 (dedicated-shell-buffer
2454 (python-shell-make-comint
2455 (python-shell-parse-command) dedicated-proc-name))
2456 (global-process (get-buffer-process global-shell-buffer))
2457 (dedicated-process (get-buffer-process dedicated-shell-buffer)))
2458 (unwind-protect
2459 (progn
2460 (set-process-query-on-exit-flag global-process nil)
2461 (set-process-query-on-exit-flag dedicated-process nil)
2462 ;; Prefer dedicated if global also exists.
2463 (should (equal (python-shell-get-process) dedicated-process))
2464 (kill-buffer dedicated-shell-buffer)
2465 ;; If there's only global, use it.
2466 (should (equal (python-shell-get-process) global-process))
2467 (kill-buffer global-shell-buffer)
2468 ;; No buffer available.
2469 (should (not (python-shell-get-process))))
2470 (ignore-errors (kill-buffer global-shell-buffer))
2471 (ignore-errors (kill-buffer dedicated-shell-buffer))))))
2473 (ert-deftest python-shell-get-or-create-process-1 ()
2474 "Check shell dedicated process creation."
2475 (skip-unless (executable-find python-tests-shell-interpreter))
2476 (python-tests-with-temp-file
2478 (let* ((cmd
2479 (concat (executable-find python-tests-shell-interpreter) " -i"))
2480 (use-dialog-box)
2481 (dedicated-process-name (python-shell-get-process-name t))
2482 (dedicated-process (python-shell-get-or-create-process cmd t))
2483 (dedicated-shell-buffer (process-buffer dedicated-process)))
2484 (unwind-protect
2485 (progn
2486 (set-process-query-on-exit-flag dedicated-process nil)
2487 ;; should be dedicated.
2488 (should (equal (process-name dedicated-process)
2489 dedicated-process-name))
2490 (kill-buffer dedicated-shell-buffer)
2491 ;; Check there are no processes for current buffer.
2492 (should (not (python-shell-get-process))))
2493 (ignore-errors (kill-buffer dedicated-shell-buffer))))))
2495 (ert-deftest python-shell-get-or-create-process-2 ()
2496 "Check shell global process creation."
2497 (skip-unless (executable-find python-tests-shell-interpreter))
2498 (python-tests-with-temp-file
2500 (let* ((cmd
2501 (concat (executable-find python-tests-shell-interpreter) " -i"))
2502 (use-dialog-box)
2503 (process-name (python-shell-get-process-name nil))
2504 (process (python-shell-get-or-create-process cmd))
2505 (shell-buffer (process-buffer process)))
2506 (unwind-protect
2507 (progn
2508 (set-process-query-on-exit-flag process nil)
2509 ;; should be global.
2510 (should (equal (process-name process) process-name))
2511 (kill-buffer shell-buffer)
2512 ;; Check there are no processes for current buffer.
2513 (should (not (python-shell-get-process))))
2514 (ignore-errors (kill-buffer shell-buffer))))))
2516 (ert-deftest python-shell-get-or-create-process-3 ()
2517 "Check shell dedicated/global process preference."
2518 (skip-unless (executable-find python-tests-shell-interpreter))
2519 (python-tests-with-temp-file
2521 (let* ((cmd
2522 (concat (executable-find python-tests-shell-interpreter) " -i"))
2523 (python-shell-interpreter python-tests-shell-interpreter)
2524 (use-dialog-box)
2525 (dedicated-process-name (python-shell-get-process-name t))
2526 (global-process)
2527 (dedicated-process))
2528 (progn
2529 ;; Create global process
2530 (run-python cmd nil)
2531 (setq global-process (get-buffer-process "*Python*"))
2532 (should global-process)
2533 (set-process-query-on-exit-flag global-process nil)
2534 ;; Create dedicated process
2535 (run-python cmd t)
2536 (setq dedicated-process (get-process dedicated-process-name))
2537 (should dedicated-process)
2538 (set-process-query-on-exit-flag dedicated-process nil)
2539 ;; Prefer dedicated.
2540 (should (equal (python-shell-get-or-create-process)
2541 dedicated-process))
2542 ;; Kill the dedicated so the global takes over.
2543 (kill-buffer (process-buffer dedicated-process))
2544 ;; Detect global.
2545 (should (equal (python-shell-get-or-create-process) global-process))
2546 ;; Kill the global.
2547 (kill-buffer (process-buffer global-process))
2548 ;; Check there are no processes for current buffer.
2549 (should (not (python-shell-get-process)))))))
2551 (ert-deftest python-shell-internal-get-or-create-process-1 ()
2552 "Check internal shell process creation fallback."
2553 (skip-unless (executable-find python-tests-shell-interpreter))
2554 (python-tests-with-temp-file
2556 (should (not (process-live-p (python-shell-internal-get-process-name))))
2557 (let* ((python-shell-interpreter
2558 (executable-find python-tests-shell-interpreter))
2559 (internal-process-name (python-shell-internal-get-process-name))
2560 (internal-process (python-shell-internal-get-or-create-process))
2561 (internal-shell-buffer (process-buffer internal-process)))
2562 (unwind-protect
2563 (progn
2564 (set-process-query-on-exit-flag internal-process nil)
2565 (should (equal (process-name internal-process)
2566 internal-process-name))
2567 (should (equal internal-process
2568 (python-shell-internal-get-or-create-process)))
2569 ;; Assert the internal process is not a user process
2570 (should (not (python-shell-get-process)))
2571 (kill-buffer internal-shell-buffer))
2572 (ignore-errors (kill-buffer internal-shell-buffer))))))
2574 (ert-deftest python-shell-prompt-detect-1 ()
2575 "Check prompt autodetection."
2576 (skip-unless (executable-find python-tests-shell-interpreter))
2577 (let ((process-environment process-environment))
2578 ;; Ensure no startup file is enabled
2579 (setenv "PYTHONSTARTUP" "")
2580 (should python-shell-prompt-detect-enabled)
2581 (should (equal (python-shell-prompt-detect) '(">>> " "... " "")))))
2583 (ert-deftest python-shell-prompt-detect-2 ()
2584 "Check prompt autodetection with startup file. Bug#17370."
2585 (skip-unless (executable-find python-tests-shell-interpreter))
2586 (let* ((process-environment process-environment)
2587 (startup-code (concat "import sys\n"
2588 "sys.ps1 = 'py> '\n"
2589 "sys.ps2 = '..> '\n"
2590 "sys.ps3 = 'out '\n"))
2591 (startup-file (python-shell--save-temp-file startup-code)))
2592 (unwind-protect
2593 (progn
2594 ;; Ensure startup file is enabled
2595 (setenv "PYTHONSTARTUP" startup-file)
2596 (should python-shell-prompt-detect-enabled)
2597 (should (equal (python-shell-prompt-detect) '("py> " "..> " "out "))))
2598 (ignore-errors (delete-file startup-file)))))
2600 (ert-deftest python-shell-prompt-detect-3 ()
2601 "Check prompts are not autodetected when feature is disabled."
2602 (skip-unless (executable-find python-tests-shell-interpreter))
2603 (let ((process-environment process-environment)
2604 (python-shell-prompt-detect-enabled nil))
2605 ;; Ensure no startup file is enabled
2606 (should (not python-shell-prompt-detect-enabled))
2607 (should (not (python-shell-prompt-detect)))))
2609 (ert-deftest python-shell-prompt-detect-4 ()
2610 "Check warning is shown when detection fails."
2611 (skip-unless (executable-find python-tests-shell-interpreter))
2612 (let* ((process-environment process-environment)
2613 ;; Trigger failure by removing prompts in the startup file
2614 (startup-code (concat "import sys\n"
2615 "sys.ps1 = ''\n"
2616 "sys.ps2 = ''\n"
2617 "sys.ps3 = ''\n"))
2618 (startup-file (python-shell--save-temp-file startup-code)))
2619 (unwind-protect
2620 (progn
2621 (kill-buffer (get-buffer-create "*Warnings*"))
2622 (should (not (get-buffer "*Warnings*")))
2623 (setenv "PYTHONSTARTUP" startup-file)
2624 (should python-shell-prompt-detect-failure-warning)
2625 (should python-shell-prompt-detect-enabled)
2626 (should (not (python-shell-prompt-detect)))
2627 (should (get-buffer "*Warnings*")))
2628 (ignore-errors (delete-file startup-file)))))
2630 (ert-deftest python-shell-prompt-detect-5 ()
2631 "Check disabled warnings are not shown when detection fails."
2632 (skip-unless (executable-find python-tests-shell-interpreter))
2633 (let* ((process-environment process-environment)
2634 (startup-code (concat "import sys\n"
2635 "sys.ps1 = ''\n"
2636 "sys.ps2 = ''\n"
2637 "sys.ps3 = ''\n"))
2638 (startup-file (python-shell--save-temp-file startup-code))
2639 (python-shell-prompt-detect-failure-warning nil))
2640 (unwind-protect
2641 (progn
2642 (kill-buffer (get-buffer-create "*Warnings*"))
2643 (should (not (get-buffer "*Warnings*")))
2644 (setenv "PYTHONSTARTUP" startup-file)
2645 (should (not python-shell-prompt-detect-failure-warning))
2646 (should python-shell-prompt-detect-enabled)
2647 (should (not (python-shell-prompt-detect)))
2648 (should (not (get-buffer "*Warnings*"))))
2649 (ignore-errors (delete-file startup-file)))))
2651 (ert-deftest python-shell-prompt-detect-6 ()
2652 "Warnings are not shown when detection is disabled."
2653 (skip-unless (executable-find python-tests-shell-interpreter))
2654 (let* ((process-environment process-environment)
2655 (startup-code (concat "import sys\n"
2656 "sys.ps1 = ''\n"
2657 "sys.ps2 = ''\n"
2658 "sys.ps3 = ''\n"))
2659 (startup-file (python-shell--save-temp-file startup-code))
2660 (python-shell-prompt-detect-failure-warning t)
2661 (python-shell-prompt-detect-enabled nil))
2662 (unwind-protect
2663 (progn
2664 (kill-buffer (get-buffer-create "*Warnings*"))
2665 (should (not (get-buffer "*Warnings*")))
2666 (setenv "PYTHONSTARTUP" startup-file)
2667 (should python-shell-prompt-detect-failure-warning)
2668 (should (not python-shell-prompt-detect-enabled))
2669 (should (not (python-shell-prompt-detect)))
2670 (should (not (get-buffer "*Warnings*"))))
2671 (ignore-errors (delete-file startup-file)))))
2673 (ert-deftest python-shell-prompt-validate-regexps-1 ()
2674 "Check `python-shell-prompt-input-regexps' are validated."
2675 (let* ((python-shell-prompt-input-regexps '("\\("))
2676 (error-data (should-error (python-shell-prompt-validate-regexps)
2677 :type 'user-error)))
2678 (should
2679 (string= (cadr error-data)
2680 "Invalid regexp \\( in `python-shell-prompt-input-regexps'"))))
2682 (ert-deftest python-shell-prompt-validate-regexps-2 ()
2683 "Check `python-shell-prompt-output-regexps' are validated."
2684 (let* ((python-shell-prompt-output-regexps '("\\("))
2685 (error-data (should-error (python-shell-prompt-validate-regexps)
2686 :type 'user-error)))
2687 (should
2688 (string= (cadr error-data)
2689 "Invalid regexp \\( in `python-shell-prompt-output-regexps'"))))
2691 (ert-deftest python-shell-prompt-validate-regexps-3 ()
2692 "Check `python-shell-prompt-regexp' is validated."
2693 (let* ((python-shell-prompt-regexp "\\(")
2694 (error-data (should-error (python-shell-prompt-validate-regexps)
2695 :type 'user-error)))
2696 (should
2697 (string= (cadr error-data)
2698 "Invalid regexp \\( in `python-shell-prompt-regexp'"))))
2700 (ert-deftest python-shell-prompt-validate-regexps-4 ()
2701 "Check `python-shell-prompt-block-regexp' is validated."
2702 (let* ((python-shell-prompt-block-regexp "\\(")
2703 (error-data (should-error (python-shell-prompt-validate-regexps)
2704 :type 'user-error)))
2705 (should
2706 (string= (cadr error-data)
2707 "Invalid regexp \\( in `python-shell-prompt-block-regexp'"))))
2709 (ert-deftest python-shell-prompt-validate-regexps-5 ()
2710 "Check `python-shell-prompt-pdb-regexp' is validated."
2711 (let* ((python-shell-prompt-pdb-regexp "\\(")
2712 (error-data (should-error (python-shell-prompt-validate-regexps)
2713 :type 'user-error)))
2714 (should
2715 (string= (cadr error-data)
2716 "Invalid regexp \\( in `python-shell-prompt-pdb-regexp'"))))
2718 (ert-deftest python-shell-prompt-validate-regexps-6 ()
2719 "Check `python-shell-prompt-output-regexp' is validated."
2720 (let* ((python-shell-prompt-output-regexp "\\(")
2721 (error-data (should-error (python-shell-prompt-validate-regexps)
2722 :type 'user-error)))
2723 (should
2724 (string= (cadr error-data)
2725 "Invalid regexp \\( in `python-shell-prompt-output-regexp'"))))
2727 (ert-deftest python-shell-prompt-validate-regexps-7 ()
2728 "Check default regexps are valid."
2729 ;; should not signal error
2730 (python-shell-prompt-validate-regexps))
2732 (ert-deftest python-shell-prompt-set-calculated-regexps-1 ()
2733 "Check regexps are validated."
2734 (let* ((python-shell-prompt-output-regexp '("\\("))
2735 (python-shell--prompt-calculated-input-regexp nil)
2736 (python-shell--prompt-calculated-output-regexp nil)
2737 (python-shell-prompt-detect-enabled nil)
2738 (error-data (should-error (python-shell-prompt-set-calculated-regexps)
2739 :type 'user-error)))
2740 (should
2741 (string= (cadr error-data)
2742 "Invalid regexp \\( in `python-shell-prompt-output-regexp'"))))
2744 (ert-deftest python-shell-prompt-set-calculated-regexps-2 ()
2745 "Check `python-shell-prompt-input-regexps' are set."
2746 (let* ((python-shell-prompt-input-regexps '("my" "prompt"))
2747 (python-shell-prompt-output-regexps '(""))
2748 (python-shell-prompt-regexp "")
2749 (python-shell-prompt-block-regexp "")
2750 (python-shell-prompt-pdb-regexp "")
2751 (python-shell-prompt-output-regexp "")
2752 (python-shell--prompt-calculated-input-regexp nil)
2753 (python-shell--prompt-calculated-output-regexp nil)
2754 (python-shell-prompt-detect-enabled nil))
2755 (python-shell-prompt-set-calculated-regexps)
2756 (should (string= python-shell--prompt-calculated-input-regexp
2757 "^\\(prompt\\|my\\|\\)"))))
2759 (ert-deftest python-shell-prompt-set-calculated-regexps-3 ()
2760 "Check `python-shell-prompt-output-regexps' are set."
2761 (let* ((python-shell-prompt-input-regexps '(""))
2762 (python-shell-prompt-output-regexps '("my" "prompt"))
2763 (python-shell-prompt-regexp "")
2764 (python-shell-prompt-block-regexp "")
2765 (python-shell-prompt-pdb-regexp "")
2766 (python-shell-prompt-output-regexp "")
2767 (python-shell--prompt-calculated-input-regexp nil)
2768 (python-shell--prompt-calculated-output-regexp nil)
2769 (python-shell-prompt-detect-enabled nil))
2770 (python-shell-prompt-set-calculated-regexps)
2771 (should (string= python-shell--prompt-calculated-output-regexp
2772 "^\\(prompt\\|my\\|\\)"))))
2774 (ert-deftest python-shell-prompt-set-calculated-regexps-4 ()
2775 "Check user defined prompts are set."
2776 (let* ((python-shell-prompt-input-regexps '(""))
2777 (python-shell-prompt-output-regexps '(""))
2778 (python-shell-prompt-regexp "prompt")
2779 (python-shell-prompt-block-regexp "block")
2780 (python-shell-prompt-pdb-regexp "pdb")
2781 (python-shell-prompt-output-regexp "output")
2782 (python-shell--prompt-calculated-input-regexp nil)
2783 (python-shell--prompt-calculated-output-regexp nil)
2784 (python-shell-prompt-detect-enabled nil))
2785 (python-shell-prompt-set-calculated-regexps)
2786 (should (string= python-shell--prompt-calculated-input-regexp
2787 "^\\(prompt\\|block\\|pdb\\|\\)"))
2788 (should (string= python-shell--prompt-calculated-output-regexp
2789 "^\\(output\\|\\)"))))
2791 (ert-deftest python-shell-prompt-set-calculated-regexps-5 ()
2792 "Check order of regexps (larger first)."
2793 (let* ((python-shell-prompt-input-regexps '("extralargeinputprompt" "sml"))
2794 (python-shell-prompt-output-regexps '("extralargeoutputprompt" "sml"))
2795 (python-shell-prompt-regexp "in")
2796 (python-shell-prompt-block-regexp "block")
2797 (python-shell-prompt-pdb-regexp "pdf")
2798 (python-shell-prompt-output-regexp "output")
2799 (python-shell--prompt-calculated-input-regexp nil)
2800 (python-shell--prompt-calculated-output-regexp nil)
2801 (python-shell-prompt-detect-enabled nil))
2802 (python-shell-prompt-set-calculated-regexps)
2803 (should (string= python-shell--prompt-calculated-input-regexp
2804 "^\\(extralargeinputprompt\\|block\\|pdf\\|sml\\|in\\)"))
2805 (should (string= python-shell--prompt-calculated-output-regexp
2806 "^\\(extralargeoutputprompt\\|output\\|sml\\)"))))
2808 (ert-deftest python-shell-prompt-set-calculated-regexps-6 ()
2809 "Check detected prompts are included `regexp-quote'd."
2810 (skip-unless (executable-find python-tests-shell-interpreter))
2811 (let* ((python-shell-prompt-input-regexps '(""))
2812 (python-shell-prompt-output-regexps '(""))
2813 (python-shell-prompt-regexp "")
2814 (python-shell-prompt-block-regexp "")
2815 (python-shell-prompt-pdb-regexp "")
2816 (python-shell-prompt-output-regexp "")
2817 (python-shell--prompt-calculated-input-regexp nil)
2818 (python-shell--prompt-calculated-output-regexp nil)
2819 (python-shell-prompt-detect-enabled t)
2820 (process-environment process-environment)
2821 (startup-code (concat "import sys\n"
2822 "sys.ps1 = 'p.> '\n"
2823 "sys.ps2 = '..> '\n"
2824 "sys.ps3 = 'o.t '\n"))
2825 (startup-file (python-shell--save-temp-file startup-code)))
2826 (unwind-protect
2827 (progn
2828 (setenv "PYTHONSTARTUP" startup-file)
2829 (python-shell-prompt-set-calculated-regexps)
2830 (should (string= python-shell--prompt-calculated-input-regexp
2831 "^\\(\\.\\.> \\|p\\.> \\|\\)"))
2832 (should (string= python-shell--prompt-calculated-output-regexp
2833 "^\\(o\\.t \\|\\)")))
2834 (ignore-errors (delete-file startup-file)))))
2836 (ert-deftest python-shell-buffer-substring-1 ()
2837 "Selecting a substring of the whole buffer must match its contents."
2838 (python-tests-with-temp-buffer
2840 class Foo(models.Model):
2841 pass
2844 class Bar(models.Model):
2845 pass
2847 (should (string= (buffer-string)
2848 (python-shell-buffer-substring (point-min) (point-max))))))
2850 (ert-deftest python-shell-buffer-substring-2 ()
2851 "Main block should be removed if NOMAIN is non-nil."
2852 (python-tests-with-temp-buffer
2854 class Foo(models.Model):
2855 pass
2857 class Bar(models.Model):
2858 pass
2860 if __name__ == \"__main__\":
2861 foo = Foo()
2862 print (foo)
2864 (should (string= (python-shell-buffer-substring (point-min) (point-max) t)
2866 class Foo(models.Model):
2867 pass
2869 class Bar(models.Model):
2870 pass
2875 "))))
2877 (ert-deftest python-shell-buffer-substring-3 ()
2878 "Main block should be removed if NOMAIN is non-nil."
2879 (python-tests-with-temp-buffer
2881 class Foo(models.Model):
2882 pass
2884 if __name__ == \"__main__\":
2885 foo = Foo()
2886 print (foo)
2888 class Bar(models.Model):
2889 pass
2891 (should (string= (python-shell-buffer-substring (point-min) (point-max) t)
2893 class Foo(models.Model):
2894 pass
2900 class Bar(models.Model):
2901 pass
2902 "))))
2904 (ert-deftest python-shell-buffer-substring-4 ()
2905 "Coding cookie should be added for substrings."
2906 (python-tests-with-temp-buffer
2907 "# coding: latin-1
2909 class Foo(models.Model):
2910 pass
2912 if __name__ == \"__main__\":
2913 foo = Foo()
2914 print (foo)
2916 class Bar(models.Model):
2917 pass
2919 (should (string= (python-shell-buffer-substring
2920 (python-tests-look-at "class Foo(models.Model):")
2921 (progn (python-nav-forward-sexp) (point)))
2922 "# -*- coding: latin-1 -*-
2924 class Foo(models.Model):
2925 pass"))))
2927 (ert-deftest python-shell-buffer-substring-5 ()
2928 "The proper amount of blank lines is added for a substring."
2929 (python-tests-with-temp-buffer
2930 "# coding: latin-1
2932 class Foo(models.Model):
2933 pass
2935 if __name__ == \"__main__\":
2936 foo = Foo()
2937 print (foo)
2939 class Bar(models.Model):
2940 pass
2942 (should (string= (python-shell-buffer-substring
2943 (python-tests-look-at "class Bar(models.Model):")
2944 (progn (python-nav-forward-sexp) (point)))
2945 "# -*- coding: latin-1 -*-
2954 class Bar(models.Model):
2955 pass"))))
2957 (ert-deftest python-shell-buffer-substring-6 ()
2958 "Handle substring with coding cookie in the second line."
2959 (python-tests-with-temp-buffer
2961 # coding: latin-1
2963 class Foo(models.Model):
2964 pass
2966 if __name__ == \"__main__\":
2967 foo = Foo()
2968 print (foo)
2970 class Bar(models.Model):
2971 pass
2973 (should (string= (python-shell-buffer-substring
2974 (python-tests-look-at "# coding: latin-1")
2975 (python-tests-look-at "if __name__ == \"__main__\":"))
2976 "# -*- coding: latin-1 -*-
2979 class Foo(models.Model):
2980 pass
2982 "))))
2984 (ert-deftest python-shell-buffer-substring-7 ()
2985 "Ensure first coding cookie gets precedence."
2986 (python-tests-with-temp-buffer
2987 "# coding: utf-8
2988 # coding: latin-1
2990 class Foo(models.Model):
2991 pass
2993 if __name__ == \"__main__\":
2994 foo = Foo()
2995 print (foo)
2997 class Bar(models.Model):
2998 pass
3000 (should (string= (python-shell-buffer-substring
3001 (python-tests-look-at "# coding: latin-1")
3002 (python-tests-look-at "if __name__ == \"__main__\":"))
3003 "# -*- coding: utf-8 -*-
3006 class Foo(models.Model):
3007 pass
3009 "))))
3011 (ert-deftest python-shell-buffer-substring-8 ()
3012 "Ensure first coding cookie gets precedence when sending whole buffer."
3013 (python-tests-with-temp-buffer
3014 "# coding: utf-8
3015 # coding: latin-1
3017 class Foo(models.Model):
3018 pass
3020 (should (string= (python-shell-buffer-substring (point-min) (point-max))
3021 "# coding: utf-8
3024 class Foo(models.Model):
3025 pass
3026 "))))
3028 (ert-deftest python-shell-buffer-substring-9 ()
3029 "Check substring starting from `point-min'."
3030 (python-tests-with-temp-buffer
3031 "# coding: utf-8
3033 class Foo(models.Model):
3034 pass
3036 class Bar(models.Model):
3037 pass
3039 (should (string= (python-shell-buffer-substring
3040 (point-min)
3041 (python-tests-look-at "class Bar(models.Model):"))
3042 "# coding: utf-8
3044 class Foo(models.Model):
3045 pass
3047 "))))
3050 ;;; Shell completion
3053 ;;; PDB Track integration
3056 ;;; Symbol completion
3059 ;;; Fill paragraph
3062 ;;; Skeletons
3065 ;;; FFAP
3068 ;;; Code check
3071 ;;; Eldoc
3074 ;;; Imenu
3076 (ert-deftest python-imenu-create-index-1 ()
3077 (python-tests-with-temp-buffer
3079 class Foo(models.Model):
3080 pass
3083 class Bar(models.Model):
3084 pass
3087 def decorator(arg1, arg2, arg3):
3088 '''print decorated function call data to stdout.
3090 Usage:
3092 @decorator('arg1', 'arg2')
3093 def func(a, b, c=True):
3094 pass
3097 def wrap(f):
3098 print ('wrap')
3099 def wrapped_f(*args):
3100 print ('wrapped_f')
3101 print ('Decorator arguments:', arg1, arg2, arg3)
3102 f(*args)
3103 print ('called f(*args)')
3104 return wrapped_f
3105 return wrap
3108 class Baz(object):
3110 def a(self):
3111 pass
3113 def b(self):
3114 pass
3116 class Frob(object):
3118 def c(self):
3119 pass
3121 (goto-char (point-max))
3122 (should (equal
3123 (list
3124 (cons "Foo (class)" (copy-marker 2))
3125 (cons "Bar (class)" (copy-marker 38))
3126 (list
3127 "decorator (def)"
3128 (cons "*function definition*" (copy-marker 74))
3129 (list
3130 "wrap (def)"
3131 (cons "*function definition*" (copy-marker 254))
3132 (cons "wrapped_f (def)" (copy-marker 294))))
3133 (list
3134 "Baz (class)"
3135 (cons "*class definition*" (copy-marker 519))
3136 (cons "a (def)" (copy-marker 539))
3137 (cons "b (def)" (copy-marker 570))
3138 (list
3139 "Frob (class)"
3140 (cons "*class definition*" (copy-marker 601))
3141 (cons "c (def)" (copy-marker 626)))))
3142 (python-imenu-create-index)))))
3144 (ert-deftest python-imenu-create-index-2 ()
3145 (python-tests-with-temp-buffer
3147 class Foo(object):
3148 def foo(self):
3149 def foo1():
3150 pass
3152 def foobar(self):
3153 pass
3155 (goto-char (point-max))
3156 (should (equal
3157 (list
3158 (list
3159 "Foo (class)"
3160 (cons "*class definition*" (copy-marker 2))
3161 (list
3162 "foo (def)"
3163 (cons "*function definition*" (copy-marker 21))
3164 (cons "foo1 (def)" (copy-marker 40)))
3165 (cons "foobar (def)" (copy-marker 78))))
3166 (python-imenu-create-index)))))
3168 (ert-deftest python-imenu-create-index-3 ()
3169 (python-tests-with-temp-buffer
3171 class Foo(object):
3172 def foo(self):
3173 def foo1():
3174 pass
3175 def foo2():
3176 pass
3178 (goto-char (point-max))
3179 (should (equal
3180 (list
3181 (list
3182 "Foo (class)"
3183 (cons "*class definition*" (copy-marker 2))
3184 (list
3185 "foo (def)"
3186 (cons "*function definition*" (copy-marker 21))
3187 (cons "foo1 (def)" (copy-marker 40))
3188 (cons "foo2 (def)" (copy-marker 77)))))
3189 (python-imenu-create-index)))))
3191 (ert-deftest python-imenu-create-index-4 ()
3192 (python-tests-with-temp-buffer
3194 class Foo(object):
3195 class Bar(object):
3196 def __init__(self):
3197 pass
3199 def __str__(self):
3200 pass
3202 def __init__(self):
3203 pass
3205 (goto-char (point-max))
3206 (should (equal
3207 (list
3208 (list
3209 "Foo (class)"
3210 (cons "*class definition*" (copy-marker 2))
3211 (list
3212 "Bar (class)"
3213 (cons "*class definition*" (copy-marker 21))
3214 (cons "__init__ (def)" (copy-marker 44))
3215 (cons "__str__ (def)" (copy-marker 90)))
3216 (cons "__init__ (def)" (copy-marker 135))))
3217 (python-imenu-create-index)))))
3219 (ert-deftest python-imenu-create-flat-index-1 ()
3220 (python-tests-with-temp-buffer
3222 class Foo(models.Model):
3223 pass
3226 class Bar(models.Model):
3227 pass
3230 def decorator(arg1, arg2, arg3):
3231 '''print decorated function call data to stdout.
3233 Usage:
3235 @decorator('arg1', 'arg2')
3236 def func(a, b, c=True):
3237 pass
3240 def wrap(f):
3241 print ('wrap')
3242 def wrapped_f(*args):
3243 print ('wrapped_f')
3244 print ('Decorator arguments:', arg1, arg2, arg3)
3245 f(*args)
3246 print ('called f(*args)')
3247 return wrapped_f
3248 return wrap
3251 class Baz(object):
3253 def a(self):
3254 pass
3256 def b(self):
3257 pass
3259 class Frob(object):
3261 def c(self):
3262 pass
3264 (goto-char (point-max))
3265 (should (equal
3266 (list (cons "Foo" (copy-marker 2))
3267 (cons "Bar" (copy-marker 38))
3268 (cons "decorator" (copy-marker 74))
3269 (cons "decorator.wrap" (copy-marker 254))
3270 (cons "decorator.wrap.wrapped_f" (copy-marker 294))
3271 (cons "Baz" (copy-marker 519))
3272 (cons "Baz.a" (copy-marker 539))
3273 (cons "Baz.b" (copy-marker 570))
3274 (cons "Baz.Frob" (copy-marker 601))
3275 (cons "Baz.Frob.c" (copy-marker 626)))
3276 (python-imenu-create-flat-index)))))
3278 (ert-deftest python-imenu-create-flat-index-2 ()
3279 (python-tests-with-temp-buffer
3281 class Foo(object):
3282 class Bar(object):
3283 def __init__(self):
3284 pass
3286 def __str__(self):
3287 pass
3289 def __init__(self):
3290 pass
3292 (goto-char (point-max))
3293 (should (equal
3294 (list
3295 (cons "Foo" (copy-marker 2))
3296 (cons "Foo.Bar" (copy-marker 21))
3297 (cons "Foo.Bar.__init__" (copy-marker 44))
3298 (cons "Foo.Bar.__str__" (copy-marker 90))
3299 (cons "Foo.__init__" (copy-marker 135)))
3300 (python-imenu-create-flat-index)))))
3303 ;;; Misc helpers
3305 (ert-deftest python-info-current-defun-1 ()
3306 (python-tests-with-temp-buffer
3308 def foo(a, b):
3310 (forward-line 1)
3311 (should (string= "foo" (python-info-current-defun)))
3312 (should (string= "def foo" (python-info-current-defun t)))
3313 (forward-line 1)
3314 (should (not (python-info-current-defun)))
3315 (indent-for-tab-command)
3316 (should (string= "foo" (python-info-current-defun)))
3317 (should (string= "def foo" (python-info-current-defun t)))))
3319 (ert-deftest python-info-current-defun-2 ()
3320 (python-tests-with-temp-buffer
3322 class C(object):
3324 def m(self):
3325 if True:
3326 return [i for i in range(3)]
3327 else:
3328 return []
3330 def b():
3331 do_b()
3333 def a():
3334 do_a()
3336 def c(self):
3337 do_c()
3339 (forward-line 1)
3340 (should (string= "C" (python-info-current-defun)))
3341 (should (string= "class C" (python-info-current-defun t)))
3342 (python-tests-look-at "return [i for ")
3343 (should (string= "C.m" (python-info-current-defun)))
3344 (should (string= "def C.m" (python-info-current-defun t)))
3345 (python-tests-look-at "def b():")
3346 (should (string= "C.m.b" (python-info-current-defun)))
3347 (should (string= "def C.m.b" (python-info-current-defun t)))
3348 (forward-line 2)
3349 (indent-for-tab-command)
3350 (python-indent-dedent-line-backspace 1)
3351 (should (string= "C.m" (python-info-current-defun)))
3352 (should (string= "def C.m" (python-info-current-defun t)))
3353 (python-tests-look-at "def c(self):")
3354 (forward-line -1)
3355 (indent-for-tab-command)
3356 (should (string= "C.m.a" (python-info-current-defun)))
3357 (should (string= "def C.m.a" (python-info-current-defun t)))
3358 (python-indent-dedent-line-backspace 1)
3359 (should (string= "C.m" (python-info-current-defun)))
3360 (should (string= "def C.m" (python-info-current-defun t)))
3361 (python-indent-dedent-line-backspace 1)
3362 (should (string= "C" (python-info-current-defun)))
3363 (should (string= "class C" (python-info-current-defun t)))
3364 (python-tests-look-at "def c(self):")
3365 (should (string= "C.c" (python-info-current-defun)))
3366 (should (string= "def C.c" (python-info-current-defun t)))
3367 (python-tests-look-at "do_c()")
3368 (should (string= "C.c" (python-info-current-defun)))
3369 (should (string= "def C.c" (python-info-current-defun t)))))
3371 (ert-deftest python-info-current-defun-3 ()
3372 (python-tests-with-temp-buffer
3374 def decoratorFunctionWithArguments(arg1, arg2, arg3):
3375 '''print decorated function call data to stdout.
3377 Usage:
3379 @decoratorFunctionWithArguments('arg1', 'arg2')
3380 def func(a, b, c=True):
3381 pass
3384 def wwrap(f):
3385 print 'Inside wwrap()'
3386 def wrapped_f(*args):
3387 print 'Inside wrapped_f()'
3388 print 'Decorator arguments:', arg1, arg2, arg3
3389 f(*args)
3390 print 'After f(*args)'
3391 return wrapped_f
3392 return wwrap
3394 (python-tests-look-at "def wwrap(f):")
3395 (forward-line -1)
3396 (should (not (python-info-current-defun)))
3397 (indent-for-tab-command 1)
3398 (should (string= (python-info-current-defun)
3399 "decoratorFunctionWithArguments"))
3400 (should (string= (python-info-current-defun t)
3401 "def decoratorFunctionWithArguments"))
3402 (python-tests-look-at "def wrapped_f(*args):")
3403 (should (string= (python-info-current-defun)
3404 "decoratorFunctionWithArguments.wwrap.wrapped_f"))
3405 (should (string= (python-info-current-defun t)
3406 "def decoratorFunctionWithArguments.wwrap.wrapped_f"))
3407 (python-tests-look-at "return wrapped_f")
3408 (should (string= (python-info-current-defun)
3409 "decoratorFunctionWithArguments.wwrap"))
3410 (should (string= (python-info-current-defun t)
3411 "def decoratorFunctionWithArguments.wwrap"))
3412 (end-of-line 1)
3413 (python-tests-look-at "return wwrap")
3414 (should (string= (python-info-current-defun)
3415 "decoratorFunctionWithArguments"))
3416 (should (string= (python-info-current-defun t)
3417 "def decoratorFunctionWithArguments"))))
3419 (ert-deftest python-info-current-symbol-1 ()
3420 (python-tests-with-temp-buffer
3422 class C(object):
3424 def m(self):
3425 self.c()
3427 def c(self):
3428 print ('a')
3430 (python-tests-look-at "self.c()")
3431 (should (string= "self.c" (python-info-current-symbol)))
3432 (should (string= "C.c" (python-info-current-symbol t)))))
3434 (ert-deftest python-info-current-symbol-2 ()
3435 (python-tests-with-temp-buffer
3437 class C(object):
3439 class M(object):
3441 def a(self):
3442 self.c()
3444 def c(self):
3445 pass
3447 (python-tests-look-at "self.c()")
3448 (should (string= "self.c" (python-info-current-symbol)))
3449 (should (string= "C.M.c" (python-info-current-symbol t)))))
3451 (ert-deftest python-info-current-symbol-3 ()
3452 "Keywords should not be considered symbols."
3453 :expected-result :failed
3454 (python-tests-with-temp-buffer
3456 class C(object):
3457 pass
3459 ;; FIXME: keywords are not symbols.
3460 (python-tests-look-at "class C")
3461 (should (not (python-info-current-symbol)))
3462 (should (not (python-info-current-symbol t)))
3463 (python-tests-look-at "C(object)")
3464 (should (string= "C" (python-info-current-symbol)))
3465 (should (string= "class C" (python-info-current-symbol t)))))
3467 (ert-deftest python-info-statement-starts-block-p-1 ()
3468 (python-tests-with-temp-buffer
3470 def long_function_name(
3471 var_one, var_two, var_three,
3472 var_four):
3473 print (var_one)
3475 (python-tests-look-at "def long_function_name")
3476 (should (python-info-statement-starts-block-p))
3477 (python-tests-look-at "print (var_one)")
3478 (python-util-forward-comment -1)
3479 (should (python-info-statement-starts-block-p))))
3481 (ert-deftest python-info-statement-starts-block-p-2 ()
3482 (python-tests-with-temp-buffer
3484 if width == 0 and height == 0 and \\\\
3485 color == 'red' and emphasis == 'strong' or \\\\
3486 highlight > 100:
3487 raise ValueError('sorry, you lose')
3489 (python-tests-look-at "if width == 0 and")
3490 (should (python-info-statement-starts-block-p))
3491 (python-tests-look-at "raise ValueError(")
3492 (python-util-forward-comment -1)
3493 (should (python-info-statement-starts-block-p))))
3495 (ert-deftest python-info-statement-ends-block-p-1 ()
3496 (python-tests-with-temp-buffer
3498 def long_function_name(
3499 var_one, var_two, var_three,
3500 var_four):
3501 print (var_one)
3503 (python-tests-look-at "print (var_one)")
3504 (should (python-info-statement-ends-block-p))))
3506 (ert-deftest python-info-statement-ends-block-p-2 ()
3507 (python-tests-with-temp-buffer
3509 if width == 0 and height == 0 and \\\\
3510 color == 'red' and emphasis == 'strong' or \\\\
3511 highlight > 100:
3512 raise ValueError(
3513 'sorry, you lose'
3517 (python-tests-look-at "raise ValueError(")
3518 (should (python-info-statement-ends-block-p))))
3520 (ert-deftest python-info-beginning-of-statement-p-1 ()
3521 (python-tests-with-temp-buffer
3523 def long_function_name(
3524 var_one, var_two, var_three,
3525 var_four):
3526 print (var_one)
3528 (python-tests-look-at "def long_function_name")
3529 (should (python-info-beginning-of-statement-p))
3530 (forward-char 10)
3531 (should (not (python-info-beginning-of-statement-p)))
3532 (python-tests-look-at "print (var_one)")
3533 (should (python-info-beginning-of-statement-p))
3534 (goto-char (line-beginning-position))
3535 (should (not (python-info-beginning-of-statement-p)))))
3537 (ert-deftest python-info-beginning-of-statement-p-2 ()
3538 (python-tests-with-temp-buffer
3540 if width == 0 and height == 0 and \\\\
3541 color == 'red' and emphasis == 'strong' or \\\\
3542 highlight > 100:
3543 raise ValueError(
3544 'sorry, you lose'
3548 (python-tests-look-at "if width == 0 and")
3549 (should (python-info-beginning-of-statement-p))
3550 (forward-char 10)
3551 (should (not (python-info-beginning-of-statement-p)))
3552 (python-tests-look-at "raise ValueError(")
3553 (should (python-info-beginning-of-statement-p))
3554 (goto-char (line-beginning-position))
3555 (should (not (python-info-beginning-of-statement-p)))))
3557 (ert-deftest python-info-end-of-statement-p-1 ()
3558 (python-tests-with-temp-buffer
3560 def long_function_name(
3561 var_one, var_two, var_three,
3562 var_four):
3563 print (var_one)
3565 (python-tests-look-at "def long_function_name")
3566 (should (not (python-info-end-of-statement-p)))
3567 (end-of-line)
3568 (should (not (python-info-end-of-statement-p)))
3569 (python-tests-look-at "print (var_one)")
3570 (python-util-forward-comment -1)
3571 (should (python-info-end-of-statement-p))
3572 (python-tests-look-at "print (var_one)")
3573 (should (not (python-info-end-of-statement-p)))
3574 (end-of-line)
3575 (should (python-info-end-of-statement-p))))
3577 (ert-deftest python-info-end-of-statement-p-2 ()
3578 (python-tests-with-temp-buffer
3580 if width == 0 and height == 0 and \\\\
3581 color == 'red' and emphasis == 'strong' or \\\\
3582 highlight > 100:
3583 raise ValueError(
3584 'sorry, you lose'
3588 (python-tests-look-at "if width == 0 and")
3589 (should (not (python-info-end-of-statement-p)))
3590 (end-of-line)
3591 (should (not (python-info-end-of-statement-p)))
3592 (python-tests-look-at "raise ValueError(")
3593 (python-util-forward-comment -1)
3594 (should (python-info-end-of-statement-p))
3595 (python-tests-look-at "raise ValueError(")
3596 (should (not (python-info-end-of-statement-p)))
3597 (end-of-line)
3598 (should (not (python-info-end-of-statement-p)))
3599 (goto-char (point-max))
3600 (python-util-forward-comment -1)
3601 (should (python-info-end-of-statement-p))))
3603 (ert-deftest python-info-beginning-of-block-p-1 ()
3604 (python-tests-with-temp-buffer
3606 def long_function_name(
3607 var_one, var_two, var_three,
3608 var_four):
3609 print (var_one)
3611 (python-tests-look-at "def long_function_name")
3612 (should (python-info-beginning-of-block-p))
3613 (python-tests-look-at "var_one, var_two, var_three,")
3614 (should (not (python-info-beginning-of-block-p)))
3615 (python-tests-look-at "print (var_one)")
3616 (should (not (python-info-beginning-of-block-p)))))
3618 (ert-deftest python-info-beginning-of-block-p-2 ()
3619 (python-tests-with-temp-buffer
3621 if width == 0 and height == 0 and \\\\
3622 color == 'red' and emphasis == 'strong' or \\\\
3623 highlight > 100:
3624 raise ValueError(
3625 'sorry, you lose'
3629 (python-tests-look-at "if width == 0 and")
3630 (should (python-info-beginning-of-block-p))
3631 (python-tests-look-at "color == 'red' and emphasis")
3632 (should (not (python-info-beginning-of-block-p)))
3633 (python-tests-look-at "raise ValueError(")
3634 (should (not (python-info-beginning-of-block-p)))))
3636 (ert-deftest python-info-end-of-block-p-1 ()
3637 (python-tests-with-temp-buffer
3639 def long_function_name(
3640 var_one, var_two, var_three,
3641 var_four):
3642 print (var_one)
3644 (python-tests-look-at "def long_function_name")
3645 (should (not (python-info-end-of-block-p)))
3646 (python-tests-look-at "var_one, var_two, var_three,")
3647 (should (not (python-info-end-of-block-p)))
3648 (python-tests-look-at "var_four):")
3649 (end-of-line)
3650 (should (not (python-info-end-of-block-p)))
3651 (python-tests-look-at "print (var_one)")
3652 (should (not (python-info-end-of-block-p)))
3653 (end-of-line 1)
3654 (should (python-info-end-of-block-p))))
3656 (ert-deftest python-info-end-of-block-p-2 ()
3657 (python-tests-with-temp-buffer
3659 if width == 0 and height == 0 and \\\\
3660 color == 'red' and emphasis == 'strong' or \\\\
3661 highlight > 100:
3662 raise ValueError(
3663 'sorry, you lose'
3667 (python-tests-look-at "if width == 0 and")
3668 (should (not (python-info-end-of-block-p)))
3669 (python-tests-look-at "color == 'red' and emphasis == 'strong' or")
3670 (should (not (python-info-end-of-block-p)))
3671 (python-tests-look-at "highlight > 100:")
3672 (end-of-line)
3673 (should (not (python-info-end-of-block-p)))
3674 (python-tests-look-at "raise ValueError(")
3675 (should (not (python-info-end-of-block-p)))
3676 (end-of-line 1)
3677 (should (not (python-info-end-of-block-p)))
3678 (goto-char (point-max))
3679 (python-util-forward-comment -1)
3680 (should (python-info-end-of-block-p))))
3682 (ert-deftest python-info-dedenter-opening-block-position-1 ()
3683 (python-tests-with-temp-buffer
3685 if request.user.is_authenticated():
3686 try:
3687 profile = request.user.get_profile()
3688 except Profile.DoesNotExist:
3689 profile = Profile.objects.create(user=request.user)
3690 else:
3691 if profile.stats:
3692 profile.recalculate_stats()
3693 else:
3694 profile.clear_stats()
3695 finally:
3696 profile.views += 1
3697 profile.save()
3699 (python-tests-look-at "try:")
3700 (should (not (python-info-dedenter-opening-block-position)))
3701 (python-tests-look-at "except Profile.DoesNotExist:")
3702 (should (= (python-tests-look-at "try:" -1 t)
3703 (python-info-dedenter-opening-block-position)))
3704 (python-tests-look-at "else:")
3705 (should (= (python-tests-look-at "except Profile.DoesNotExist:" -1 t)
3706 (python-info-dedenter-opening-block-position)))
3707 (python-tests-look-at "if profile.stats:")
3708 (should (not (python-info-dedenter-opening-block-position)))
3709 (python-tests-look-at "else:")
3710 (should (= (python-tests-look-at "if profile.stats:" -1 t)
3711 (python-info-dedenter-opening-block-position)))
3712 (python-tests-look-at "finally:")
3713 (should (= (python-tests-look-at "else:" -2 t)
3714 (python-info-dedenter-opening-block-position)))))
3716 (ert-deftest python-info-dedenter-opening-block-position-2 ()
3717 (python-tests-with-temp-buffer
3719 if request.user.is_authenticated():
3720 profile = Profile.objects.get_or_create(user=request.user)
3721 if profile.stats:
3722 profile.recalculate_stats()
3724 data = {
3725 'else': 'do it'
3727 'else'
3729 (python-tests-look-at "'else': 'do it'")
3730 (should (not (python-info-dedenter-opening-block-position)))
3731 (python-tests-look-at "'else'")
3732 (should (not (python-info-dedenter-opening-block-position)))))
3734 (ert-deftest python-info-dedenter-opening-block-position-3 ()
3735 (python-tests-with-temp-buffer
3737 if save:
3738 try:
3739 write_to_disk(data)
3740 except IOError:
3741 msg = 'Error saving to disk'
3742 message(msg)
3743 logger.exception(msg)
3744 except Exception:
3745 if hide_details:
3746 logger.exception('Unhandled exception')
3747 else
3748 finally:
3749 data.free()
3751 (python-tests-look-at "try:")
3752 (should (not (python-info-dedenter-opening-block-position)))
3754 (python-tests-look-at "except IOError:")
3755 (should (= (python-tests-look-at "try:" -1 t)
3756 (python-info-dedenter-opening-block-position)))
3758 (python-tests-look-at "except Exception:")
3759 (should (= (python-tests-look-at "except IOError:" -1 t)
3760 (python-info-dedenter-opening-block-position)))
3762 (python-tests-look-at "if hide_details:")
3763 (should (not (python-info-dedenter-opening-block-position)))
3765 ;; check indentation modifies the detected opening block
3766 (python-tests-look-at "else")
3767 (should (= (python-tests-look-at "if hide_details:" -1 t)
3768 (python-info-dedenter-opening-block-position)))
3770 (indent-line-to 8)
3771 (should (= (python-tests-look-at "if hide_details:" -1 t)
3772 (python-info-dedenter-opening-block-position)))
3774 (indent-line-to 4)
3775 (should (= (python-tests-look-at "except Exception:" -1 t)
3776 (python-info-dedenter-opening-block-position)))
3778 (indent-line-to 0)
3779 (should (= (python-tests-look-at "if save:" -1 t)
3780 (python-info-dedenter-opening-block-position)))))
3782 (ert-deftest python-info-dedenter-opening-block-positions-1 ()
3783 (python-tests-with-temp-buffer
3785 if save:
3786 try:
3787 write_to_disk(data)
3788 except IOError:
3789 msg = 'Error saving to disk'
3790 message(msg)
3791 logger.exception(msg)
3792 except Exception:
3793 if hide_details:
3794 logger.exception('Unhandled exception')
3795 else
3796 finally:
3797 data.free()
3799 (python-tests-look-at "try:")
3800 (should (not (python-info-dedenter-opening-block-positions)))
3802 (python-tests-look-at "except IOError:")
3803 (should
3804 (equal (list
3805 (python-tests-look-at "try:" -1 t))
3806 (python-info-dedenter-opening-block-positions)))
3808 (python-tests-look-at "except Exception:")
3809 (should
3810 (equal (list
3811 (python-tests-look-at "except IOError:" -1 t))
3812 (python-info-dedenter-opening-block-positions)))
3814 (python-tests-look-at "if hide_details:")
3815 (should (not (python-info-dedenter-opening-block-positions)))
3817 ;; check indentation does not modify the detected opening blocks
3818 (python-tests-look-at "else")
3819 (should
3820 (equal (list
3821 (python-tests-look-at "if hide_details:" -1 t)
3822 (python-tests-look-at "except Exception:" -1 t)
3823 (python-tests-look-at "if save:" -1 t))
3824 (python-info-dedenter-opening-block-positions)))
3826 (indent-line-to 8)
3827 (should
3828 (equal (list
3829 (python-tests-look-at "if hide_details:" -1 t)
3830 (python-tests-look-at "except Exception:" -1 t)
3831 (python-tests-look-at "if save:" -1 t))
3832 (python-info-dedenter-opening-block-positions)))
3834 (indent-line-to 4)
3835 (should
3836 (equal (list
3837 (python-tests-look-at "if hide_details:" -1 t)
3838 (python-tests-look-at "except Exception:" -1 t)
3839 (python-tests-look-at "if save:" -1 t))
3840 (python-info-dedenter-opening-block-positions)))
3842 (indent-line-to 0)
3843 (should
3844 (equal (list
3845 (python-tests-look-at "if hide_details:" -1 t)
3846 (python-tests-look-at "except Exception:" -1 t)
3847 (python-tests-look-at "if save:" -1 t))
3848 (python-info-dedenter-opening-block-positions)))))
3850 (ert-deftest python-info-dedenter-opening-block-positions-2 ()
3851 "Test detection of opening blocks for elif."
3852 (python-tests-with-temp-buffer
3854 if var:
3855 if var2:
3856 something()
3857 elif var3:
3858 something_else()
3859 elif
3861 (python-tests-look-at "elif var3:")
3862 (should
3863 (equal (list
3864 (python-tests-look-at "if var2:" -1 t)
3865 (python-tests-look-at "if var:" -1 t))
3866 (python-info-dedenter-opening-block-positions)))
3868 (python-tests-look-at "elif\n")
3869 (should
3870 (equal (list
3871 (python-tests-look-at "elif var3:" -1 t)
3872 (python-tests-look-at "if var:" -1 t))
3873 (python-info-dedenter-opening-block-positions)))))
3875 (ert-deftest python-info-dedenter-opening-block-positions-3 ()
3876 "Test detection of opening blocks for else."
3877 (python-tests-with-temp-buffer
3879 try:
3880 something()
3881 except:
3882 if var:
3883 if var2:
3884 something()
3885 elif var3:
3886 something_else()
3887 else
3889 if var4:
3890 while var5:
3891 var4.pop()
3892 else
3894 for value in var6:
3895 if value > 0:
3896 print value
3897 else
3899 (python-tests-look-at "else\n")
3900 (should
3901 (equal (list
3902 (python-tests-look-at "elif var3:" -1 t)
3903 (python-tests-look-at "if var:" -1 t)
3904 (python-tests-look-at "except:" -1 t))
3905 (python-info-dedenter-opening-block-positions)))
3907 (python-tests-look-at "else\n")
3908 (should
3909 (equal (list
3910 (python-tests-look-at "while var5:" -1 t)
3911 (python-tests-look-at "if var4:" -1 t))
3912 (python-info-dedenter-opening-block-positions)))
3914 (python-tests-look-at "else\n")
3915 (should
3916 (equal (list
3917 (python-tests-look-at "if value > 0:" -1 t)
3918 (python-tests-look-at "for value in var6:" -1 t)
3919 (python-tests-look-at "if var4:" -1 t))
3920 (python-info-dedenter-opening-block-positions)))))
3922 (ert-deftest python-info-dedenter-opening-block-positions-4 ()
3923 "Test detection of opening blocks for except."
3924 (python-tests-with-temp-buffer
3926 try:
3927 something()
3928 except ValueError:
3929 something_else()
3930 except
3932 (python-tests-look-at "except ValueError:")
3933 (should
3934 (equal (list (python-tests-look-at "try:" -1 t))
3935 (python-info-dedenter-opening-block-positions)))
3937 (python-tests-look-at "except\n")
3938 (should
3939 (equal (list (python-tests-look-at "except ValueError:" -1 t))
3940 (python-info-dedenter-opening-block-positions)))))
3942 (ert-deftest python-info-dedenter-opening-block-positions-5 ()
3943 "Test detection of opening blocks for finally."
3944 (python-tests-with-temp-buffer
3946 try:
3947 something()
3948 finally
3950 try:
3951 something_else()
3952 except:
3953 logger.exception('something went wrong')
3954 finally
3956 try:
3957 something_else_else()
3958 except Exception:
3959 logger.exception('something else went wrong')
3960 else:
3961 print ('all good')
3962 finally
3964 (python-tests-look-at "finally\n")
3965 (should
3966 (equal (list (python-tests-look-at "try:" -1 t))
3967 (python-info-dedenter-opening-block-positions)))
3969 (python-tests-look-at "finally\n")
3970 (should
3971 (equal (list (python-tests-look-at "except:" -1 t))
3972 (python-info-dedenter-opening-block-positions)))
3974 (python-tests-look-at "finally\n")
3975 (should
3976 (equal (list (python-tests-look-at "else:" -1 t))
3977 (python-info-dedenter-opening-block-positions)))))
3979 (ert-deftest python-info-dedenter-opening-block-message-1 ()
3980 "Test dedenters inside strings are ignored."
3981 (python-tests-with-temp-buffer
3982 "'''
3983 try:
3984 something()
3985 except:
3986 logger.exception('something went wrong')
3989 (python-tests-look-at "except\n")
3990 (should (not (python-info-dedenter-opening-block-message)))))
3992 (ert-deftest python-info-dedenter-opening-block-message-2 ()
3993 "Test except keyword."
3994 (python-tests-with-temp-buffer
3996 try:
3997 something()
3998 except:
3999 logger.exception('something went wrong')
4001 (python-tests-look-at "except:")
4002 (should (string=
4003 "Closes try:"
4004 (substring-no-properties
4005 (python-info-dedenter-opening-block-message))))
4006 (end-of-line)
4007 (should (string=
4008 "Closes try:"
4009 (substring-no-properties
4010 (python-info-dedenter-opening-block-message))))))
4012 (ert-deftest python-info-dedenter-opening-block-message-3 ()
4013 "Test else keyword."
4014 (python-tests-with-temp-buffer
4016 try:
4017 something()
4018 except:
4019 logger.exception('something went wrong')
4020 else:
4021 logger.debug('all good')
4023 (python-tests-look-at "else:")
4024 (should (string=
4025 "Closes except:"
4026 (substring-no-properties
4027 (python-info-dedenter-opening-block-message))))
4028 (end-of-line)
4029 (should (string=
4030 "Closes except:"
4031 (substring-no-properties
4032 (python-info-dedenter-opening-block-message))))))
4034 (ert-deftest python-info-dedenter-opening-block-message-4 ()
4035 "Test finally keyword."
4036 (python-tests-with-temp-buffer
4038 try:
4039 something()
4040 except:
4041 logger.exception('something went wrong')
4042 else:
4043 logger.debug('all good')
4044 finally:
4045 clean()
4047 (python-tests-look-at "finally:")
4048 (should (string=
4049 "Closes else:"
4050 (substring-no-properties
4051 (python-info-dedenter-opening-block-message))))
4052 (end-of-line)
4053 (should (string=
4054 "Closes else:"
4055 (substring-no-properties
4056 (python-info-dedenter-opening-block-message))))))
4058 (ert-deftest python-info-dedenter-opening-block-message-5 ()
4059 "Test elif keyword."
4060 (python-tests-with-temp-buffer
4062 if a:
4063 something()
4064 elif b:
4066 (python-tests-look-at "elif b:")
4067 (should (string=
4068 "Closes if a:"
4069 (substring-no-properties
4070 (python-info-dedenter-opening-block-message))))
4071 (end-of-line)
4072 (should (string=
4073 "Closes if a:"
4074 (substring-no-properties
4075 (python-info-dedenter-opening-block-message))))))
4078 (ert-deftest python-info-dedenter-statement-p-1 ()
4079 "Test dedenters inside strings are ignored."
4080 (python-tests-with-temp-buffer
4081 "'''
4082 try:
4083 something()
4084 except:
4085 logger.exception('something went wrong')
4088 (python-tests-look-at "except\n")
4089 (should (not (python-info-dedenter-statement-p)))))
4091 (ert-deftest python-info-dedenter-statement-p-2 ()
4092 "Test except keyword."
4093 (python-tests-with-temp-buffer
4095 try:
4096 something()
4097 except:
4098 logger.exception('something went wrong')
4100 (python-tests-look-at "except:")
4101 (should (= (point) (python-info-dedenter-statement-p)))
4102 (end-of-line)
4103 (should (= (save-excursion
4104 (back-to-indentation)
4105 (point))
4106 (python-info-dedenter-statement-p)))))
4108 (ert-deftest python-info-dedenter-statement-p-3 ()
4109 "Test else keyword."
4110 (python-tests-with-temp-buffer
4112 try:
4113 something()
4114 except:
4115 logger.exception('something went wrong')
4116 else:
4117 logger.debug('all good')
4119 (python-tests-look-at "else:")
4120 (should (= (point) (python-info-dedenter-statement-p)))
4121 (end-of-line)
4122 (should (= (save-excursion
4123 (back-to-indentation)
4124 (point))
4125 (python-info-dedenter-statement-p)))))
4127 (ert-deftest python-info-dedenter-statement-p-4 ()
4128 "Test finally keyword."
4129 (python-tests-with-temp-buffer
4131 try:
4132 something()
4133 except:
4134 logger.exception('something went wrong')
4135 else:
4136 logger.debug('all good')
4137 finally:
4138 clean()
4140 (python-tests-look-at "finally:")
4141 (should (= (point) (python-info-dedenter-statement-p)))
4142 (end-of-line)
4143 (should (= (save-excursion
4144 (back-to-indentation)
4145 (point))
4146 (python-info-dedenter-statement-p)))))
4148 (ert-deftest python-info-dedenter-statement-p-5 ()
4149 "Test elif keyword."
4150 (python-tests-with-temp-buffer
4152 if a:
4153 something()
4154 elif b:
4156 (python-tests-look-at "elif b:")
4157 (should (= (point) (python-info-dedenter-statement-p)))
4158 (end-of-line)
4159 (should (= (save-excursion
4160 (back-to-indentation)
4161 (point))
4162 (python-info-dedenter-statement-p)))))
4164 (ert-deftest python-info-line-ends-backslash-p-1 ()
4165 (python-tests-with-temp-buffer
4167 objects = Thing.objects.all() \\\\
4168 .filter(
4169 type='toy',
4170 status='bought'
4171 ) \\\\
4172 .aggregate(
4173 Sum('amount')
4174 ) \\\\
4175 .values_list()
4177 (should (python-info-line-ends-backslash-p 2)) ; .filter(...
4178 (should (python-info-line-ends-backslash-p 3))
4179 (should (python-info-line-ends-backslash-p 4))
4180 (should (python-info-line-ends-backslash-p 5))
4181 (should (python-info-line-ends-backslash-p 6)) ; ) \...
4182 (should (python-info-line-ends-backslash-p 7))
4183 (should (python-info-line-ends-backslash-p 8))
4184 (should (python-info-line-ends-backslash-p 9))
4185 (should (not (python-info-line-ends-backslash-p 10))))) ; .values_list()...
4187 (ert-deftest python-info-beginning-of-backslash-1 ()
4188 (python-tests-with-temp-buffer
4190 objects = Thing.objects.all() \\\\
4191 .filter(
4192 type='toy',
4193 status='bought'
4194 ) \\\\
4195 .aggregate(
4196 Sum('amount')
4197 ) \\\\
4198 .values_list()
4200 (let ((first 2)
4201 (second (python-tests-look-at ".filter("))
4202 (third (python-tests-look-at ".aggregate(")))
4203 (should (= first (python-info-beginning-of-backslash 2)))
4204 (should (= second (python-info-beginning-of-backslash 3)))
4205 (should (= second (python-info-beginning-of-backslash 4)))
4206 (should (= second (python-info-beginning-of-backslash 5)))
4207 (should (= second (python-info-beginning-of-backslash 6)))
4208 (should (= third (python-info-beginning-of-backslash 7)))
4209 (should (= third (python-info-beginning-of-backslash 8)))
4210 (should (= third (python-info-beginning-of-backslash 9)))
4211 (should (not (python-info-beginning-of-backslash 10))))))
4213 (ert-deftest python-info-continuation-line-p-1 ()
4214 (python-tests-with-temp-buffer
4216 if width == 0 and height == 0 and \\\\
4217 color == 'red' and emphasis == 'strong' or \\\\
4218 highlight > 100:
4219 raise ValueError(
4220 'sorry, you lose'
4224 (python-tests-look-at "if width == 0 and height == 0 and")
4225 (should (not (python-info-continuation-line-p)))
4226 (python-tests-look-at "color == 'red' and emphasis == 'strong' or")
4227 (should (python-info-continuation-line-p))
4228 (python-tests-look-at "highlight > 100:")
4229 (should (python-info-continuation-line-p))
4230 (python-tests-look-at "raise ValueError(")
4231 (should (not (python-info-continuation-line-p)))
4232 (python-tests-look-at "'sorry, you lose'")
4233 (should (python-info-continuation-line-p))
4234 (forward-line 1)
4235 (should (python-info-continuation-line-p))
4236 (python-tests-look-at ")")
4237 (should (python-info-continuation-line-p))
4238 (forward-line 1)
4239 (should (not (python-info-continuation-line-p)))))
4241 (ert-deftest python-info-block-continuation-line-p-1 ()
4242 (python-tests-with-temp-buffer
4244 if width == 0 and height == 0 and \\\\
4245 color == 'red' and emphasis == 'strong' or \\\\
4246 highlight > 100:
4247 raise ValueError(
4248 'sorry, you lose'
4252 (python-tests-look-at "if width == 0 and")
4253 (should (not (python-info-block-continuation-line-p)))
4254 (python-tests-look-at "color == 'red' and emphasis == 'strong' or")
4255 (should (= (python-info-block-continuation-line-p)
4256 (python-tests-look-at "if width == 0 and" -1 t)))
4257 (python-tests-look-at "highlight > 100:")
4258 (should (not (python-info-block-continuation-line-p)))))
4260 (ert-deftest python-info-block-continuation-line-p-2 ()
4261 (python-tests-with-temp-buffer
4263 def foo(a,
4266 pass
4268 (python-tests-look-at "def foo(a,")
4269 (should (not (python-info-block-continuation-line-p)))
4270 (python-tests-look-at "b,")
4271 (should (= (python-info-block-continuation-line-p)
4272 (python-tests-look-at "def foo(a," -1 t)))
4273 (python-tests-look-at "c):")
4274 (should (not (python-info-block-continuation-line-p)))))
4276 (ert-deftest python-info-assignment-continuation-line-p-1 ()
4277 (python-tests-with-temp-buffer
4279 data = foo(), bar() \\\\
4280 baz(), 4 \\\\
4281 5, 6
4283 (python-tests-look-at "data = foo(), bar()")
4284 (should (not (python-info-assignment-continuation-line-p)))
4285 (python-tests-look-at "baz(), 4")
4286 (should (= (python-info-assignment-continuation-line-p)
4287 (python-tests-look-at "foo()," -1 t)))
4288 (python-tests-look-at "5, 6")
4289 (should (not (python-info-assignment-continuation-line-p)))))
4291 (ert-deftest python-info-assignment-continuation-line-p-2 ()
4292 (python-tests-with-temp-buffer
4294 data = (foo(), bar()
4295 baz(), 4
4296 5, 6)
4298 (python-tests-look-at "data = (foo(), bar()")
4299 (should (not (python-info-assignment-continuation-line-p)))
4300 (python-tests-look-at "baz(), 4")
4301 (should (= (python-info-assignment-continuation-line-p)
4302 (python-tests-look-at "(foo()," -1 t)))
4303 (python-tests-look-at "5, 6)")
4304 (should (not (python-info-assignment-continuation-line-p)))))
4306 (ert-deftest python-info-looking-at-beginning-of-defun-1 ()
4307 (python-tests-with-temp-buffer
4309 def decorat0r(deff):
4310 '''decorates stuff.
4312 @decorat0r
4313 def foo(arg):
4316 def wrap():
4317 deff()
4318 return wwrap
4320 (python-tests-look-at "def decorat0r(deff):")
4321 (should (python-info-looking-at-beginning-of-defun))
4322 (python-tests-look-at "def foo(arg):")
4323 (should (not (python-info-looking-at-beginning-of-defun)))
4324 (python-tests-look-at "def wrap():")
4325 (should (python-info-looking-at-beginning-of-defun))
4326 (python-tests-look-at "deff()")
4327 (should (not (python-info-looking-at-beginning-of-defun)))))
4329 (ert-deftest python-info-current-line-comment-p-1 ()
4330 (python-tests-with-temp-buffer
4332 # this is a comment
4333 foo = True # another comment
4334 '#this is a string'
4335 if foo:
4336 # more comments
4337 print ('bar') # print bar
4339 (python-tests-look-at "# this is a comment")
4340 (should (python-info-current-line-comment-p))
4341 (python-tests-look-at "foo = True # another comment")
4342 (should (not (python-info-current-line-comment-p)))
4343 (python-tests-look-at "'#this is a string'")
4344 (should (not (python-info-current-line-comment-p)))
4345 (python-tests-look-at "# more comments")
4346 (should (python-info-current-line-comment-p))
4347 (python-tests-look-at "print ('bar') # print bar")
4348 (should (not (python-info-current-line-comment-p)))))
4350 (ert-deftest python-info-current-line-empty-p ()
4351 (python-tests-with-temp-buffer
4353 # this is a comment
4355 foo = True # another comment
4357 (should (python-info-current-line-empty-p))
4358 (python-tests-look-at "# this is a comment")
4359 (should (not (python-info-current-line-empty-p)))
4360 (forward-line 1)
4361 (should (python-info-current-line-empty-p))))
4363 (ert-deftest python-info-encoding-from-cookie-1 ()
4364 "Should detect it on first line."
4365 (python-tests-with-temp-buffer
4366 "# coding=latin-1
4368 foo = True # another comment
4370 (should (eq (python-info-encoding-from-cookie) 'latin-1))))
4372 (ert-deftest python-info-encoding-from-cookie-2 ()
4373 "Should detect it on second line."
4374 (python-tests-with-temp-buffer
4376 # coding=latin-1
4378 foo = True # another comment
4380 (should (eq (python-info-encoding-from-cookie) 'latin-1))))
4382 (ert-deftest python-info-encoding-from-cookie-3 ()
4383 "Should not be detected on third line (and following ones)."
4384 (python-tests-with-temp-buffer
4387 # coding=latin-1
4388 foo = True # another comment
4390 (should (not (python-info-encoding-from-cookie)))))
4392 (ert-deftest python-info-encoding-from-cookie-4 ()
4393 "Should detect Emacs style."
4394 (python-tests-with-temp-buffer
4395 "# -*- coding: latin-1 -*-
4397 foo = True # another comment"
4398 (should (eq (python-info-encoding-from-cookie) 'latin-1))))
4400 (ert-deftest python-info-encoding-from-cookie-5 ()
4401 "Should detect Vim style."
4402 (python-tests-with-temp-buffer
4403 "# vim: set fileencoding=latin-1 :
4405 foo = True # another comment"
4406 (should (eq (python-info-encoding-from-cookie) 'latin-1))))
4408 (ert-deftest python-info-encoding-from-cookie-6 ()
4409 "First cookie wins."
4410 (python-tests-with-temp-buffer
4411 "# -*- coding: iso-8859-1 -*-
4412 # vim: set fileencoding=latin-1 :
4414 foo = True # another comment"
4415 (should (eq (python-info-encoding-from-cookie) 'iso-8859-1))))
4417 (ert-deftest python-info-encoding-from-cookie-7 ()
4418 "First cookie wins."
4419 (python-tests-with-temp-buffer
4420 "# vim: set fileencoding=latin-1 :
4421 # -*- coding: iso-8859-1 -*-
4423 foo = True # another comment"
4424 (should (eq (python-info-encoding-from-cookie) 'latin-1))))
4426 (ert-deftest python-info-encoding-1 ()
4427 "Should return the detected encoding from cookie."
4428 (python-tests-with-temp-buffer
4429 "# vim: set fileencoding=latin-1 :
4431 foo = True # another comment"
4432 (should (eq (python-info-encoding) 'latin-1))))
4434 (ert-deftest python-info-encoding-2 ()
4435 "Should default to utf-8."
4436 (python-tests-with-temp-buffer
4437 "# No encoding for you
4439 foo = True # another comment"
4440 (should (eq (python-info-encoding) 'utf-8))))
4443 ;;; Utility functions
4445 (ert-deftest python-util-goto-line-1 ()
4446 (python-tests-with-temp-buffer
4447 (concat
4448 "# a comment
4449 # another comment
4450 def foo(a, b, c):
4451 pass" (make-string 20 ?\n))
4452 (python-util-goto-line 10)
4453 (should (= (line-number-at-pos) 10))
4454 (python-util-goto-line 20)
4455 (should (= (line-number-at-pos) 20))))
4457 (ert-deftest python-util-clone-local-variables-1 ()
4458 (let ((buffer (generate-new-buffer
4459 "python-util-clone-local-variables-1"))
4460 (varcons
4461 '((python-fill-docstring-style . django)
4462 (python-shell-interpreter . "python")
4463 (python-shell-interpreter-args . "manage.py shell")
4464 (python-shell-prompt-regexp . "In \\[[0-9]+\\]: ")
4465 (python-shell-prompt-output-regexp . "Out\\[[0-9]+\\]: ")
4466 (python-shell-extra-pythonpaths "/home/user/pylib/")
4467 (python-shell-completion-setup-code
4468 . "from IPython.core.completerlib import module_completion")
4469 (python-shell-completion-string-code
4470 . "';'.join(get_ipython().Completer.all_completions('''%s'''))\n")
4471 (python-shell-virtualenv-path
4472 . "/home/user/.virtualenvs/project"))))
4473 (with-current-buffer buffer
4474 (kill-all-local-variables)
4475 (dolist (ccons varcons)
4476 (set (make-local-variable (car ccons)) (cdr ccons))))
4477 (python-tests-with-temp-buffer
4479 (python-util-clone-local-variables buffer)
4480 (dolist (ccons varcons)
4481 (should
4482 (equal (symbol-value (car ccons)) (cdr ccons)))))
4483 (kill-buffer buffer)))
4485 (ert-deftest python-util-strip-string-1 ()
4486 (should (string= (python-util-strip-string "\t\r\n str") "str"))
4487 (should (string= (python-util-strip-string "str \n\r") "str"))
4488 (should (string= (python-util-strip-string "\t\r\n str \n\r ") "str"))
4489 (should
4490 (string= (python-util-strip-string "\n str \nin \tg \n\r") "str \nin \tg"))
4491 (should (string= (python-util-strip-string "\n \t \n\r ") ""))
4492 (should (string= (python-util-strip-string "") "")))
4494 (ert-deftest python-util-forward-comment-1 ()
4495 (python-tests-with-temp-buffer
4496 (concat
4497 "# a comment
4498 # another comment
4499 # bad indented comment
4500 # more comments" (make-string 9999 ?\n))
4501 (python-util-forward-comment 1)
4502 (should (= (point) (point-max)))
4503 (python-util-forward-comment -1)
4504 (should (= (point) (point-min)))))
4506 (ert-deftest python-util-valid-regexp-p-1 ()
4507 (should (python-util-valid-regexp-p ""))
4508 (should (python-util-valid-regexp-p python-shell-prompt-regexp))
4509 (should (not (python-util-valid-regexp-p "\\("))))
4512 ;;; Electricity
4514 (ert-deftest python-parens-electric-indent-1 ()
4515 (require 'electric)
4516 (let ((eim electric-indent-mode))
4517 (unwind-protect
4518 (progn
4519 (python-tests-with-temp-buffer
4521 from django.conf.urls import patterns, include, url
4523 from django.contrib import admin
4525 from myapp import views
4528 urlpatterns = patterns('',
4529 url(r'^$', views.index
4532 (electric-indent-mode 1)
4533 (python-tests-look-at "views.index")
4534 (end-of-line)
4536 ;; Inserting commas within the same line should leave
4537 ;; indentation unchanged.
4538 (python-tests-self-insert ",")
4539 (should (= (current-indentation) 4))
4541 ;; As well as any other input happening within the same
4542 ;; set of parens.
4543 (python-tests-self-insert " name='index')")
4544 (should (= (current-indentation) 4))
4546 ;; But a comma outside it, should trigger indentation.
4547 (python-tests-self-insert ",")
4548 (should (= (current-indentation) 23))
4550 ;; Newline indents to the first argument column
4551 (python-tests-self-insert "\n")
4552 (should (= (current-indentation) 23))
4554 ;; All this input must not change indentation
4555 (indent-line-to 4)
4556 (python-tests-self-insert "url(r'^/login$', views.login)")
4557 (should (= (current-indentation) 4))
4559 ;; But this comma does
4560 (python-tests-self-insert ",")
4561 (should (= (current-indentation) 23))))
4562 (or eim (electric-indent-mode -1)))))
4564 (ert-deftest python-triple-quote-pairing ()
4565 (require 'electric)
4566 (let ((epm electric-pair-mode))
4567 (unwind-protect
4568 (progn
4569 (python-tests-with-temp-buffer
4570 "\"\"\n"
4571 (or epm (electric-pair-mode 1))
4572 (goto-char (1- (point-max)))
4573 (python-tests-self-insert ?\")
4574 (should (string= (buffer-string)
4575 "\"\"\"\"\"\"\n"))
4576 (should (= (point) 4)))
4577 (python-tests-with-temp-buffer
4578 "\n"
4579 (python-tests-self-insert (list ?\" ?\" ?\"))
4580 (should (string= (buffer-string)
4581 "\"\"\"\"\"\"\n"))
4582 (should (= (point) 4)))
4583 (python-tests-with-temp-buffer
4584 "\"\n\"\"\n"
4585 (goto-char (1- (point-max)))
4586 (python-tests-self-insert ?\")
4587 (should (= (point) (1- (point-max))))
4588 (should (string= (buffer-string)
4589 "\"\n\"\"\"\n"))))
4590 (or epm (electric-pair-mode -1)))))
4593 (provide 'python-tests)
4595 ;; Local Variables:
4596 ;; coding: utf-8
4597 ;; indent-tabs-mode: nil
4598 ;; End:
4600 ;;; python-tests.el ends here