Fix a test in python-test.el
[emacs.git] / test / lisp / progmodes / python-tests.el
blob3b75e81afeeea2275956c63c9bbdb7cac4d81d81
1 ;;; python-tests.el --- Test suite for python.el
3 ;; Copyright (C) 2013-2017 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 ;; Dependencies for testing:
28 (require 'electric)
29 (require 'hideshow)
30 (require 'tramp-sh)
33 (defmacro python-tests-with-temp-buffer (contents &rest body)
34 "Create a `python-mode' enabled temp buffer with CONTENTS.
35 BODY is code to be executed within the temp buffer. Point is
36 always located at the beginning of buffer."
37 (declare (indent 1) (debug t))
38 `(with-temp-buffer
39 (let ((python-indent-guess-indent-offset nil))
40 (python-mode)
41 (insert ,contents)
42 (goto-char (point-min))
43 ,@body)))
45 (defmacro python-tests-with-temp-file (contents &rest body)
46 "Create a `python-mode' enabled file with CONTENTS.
47 BODY is code to be executed within the temp buffer. Point is
48 always located at the beginning of buffer."
49 (declare (indent 1) (debug t))
50 ;; temp-file never actually used for anything?
51 `(let* ((temp-file (make-temp-file "python-tests" nil ".py"))
52 (buffer (find-file-noselect temp-file))
53 (python-indent-guess-indent-offset nil))
54 (unwind-protect
55 (with-current-buffer buffer
56 (python-mode)
57 (insert ,contents)
58 (goto-char (point-min))
59 ,@body)
60 (and buffer (kill-buffer buffer))
61 (delete-file temp-file))))
63 (defun python-tests-look-at (string &optional num restore-point)
64 "Move point at beginning of STRING in the current buffer.
65 Optional argument NUM defaults to 1 and is an integer indicating
66 how many occurrences must be found, when positive the search is
67 done forwards, otherwise backwards. When RESTORE-POINT is
68 non-nil the point is not moved but the position found is still
69 returned. When searching forward and point is already looking at
70 STRING, it is skipped so the next STRING occurrence is selected."
71 (let* ((num (or num 1))
72 (starting-point (point))
73 (string (regexp-quote string))
74 (search-fn (if (> num 0) #'re-search-forward #'re-search-backward))
75 (deinc-fn (if (> num 0) #'1- #'1+))
76 (found-point))
77 (prog2
78 (catch 'exit
79 (while (not (= num 0))
80 (when (and (> num 0)
81 (looking-at string))
82 ;; Moving forward and already looking at STRING, skip it.
83 (forward-char (length (match-string-no-properties 0))))
84 (and (not (funcall search-fn string nil t))
85 (throw 'exit t))
86 (when (> num 0)
87 ;; `re-search-forward' leaves point at the end of the
88 ;; occurrence, move back so point is at the beginning
89 ;; instead.
90 (forward-char (- (length (match-string-no-properties 0)))))
91 (setq
92 num (funcall deinc-fn num)
93 found-point (point))))
94 found-point
95 (and restore-point (goto-char starting-point)))))
97 (defun python-tests-self-insert (char-or-str)
98 "Call `self-insert-command' for chars in CHAR-OR-STR."
99 (let ((chars
100 (cond
101 ((characterp char-or-str)
102 (list char-or-str))
103 ((stringp char-or-str)
104 (string-to-list char-or-str))
105 ((not
106 (cl-remove-if #'characterp char-or-str))
107 char-or-str)
108 (t (error "CHAR-OR-STR must be a char, string, or list of char")))))
109 (mapc
110 (lambda (char)
111 (let ((last-command-event char))
112 (call-interactively 'self-insert-command)))
113 chars)))
115 (defun python-tests-visible-string (&optional min max)
116 "Return the buffer string excluding invisible overlays.
117 Argument MIN and MAX delimit the region to be returned and
118 default to `point-min' and `point-max' respectively."
119 (let* ((min (or min (point-min)))
120 (max (or max (point-max)))
121 (buffer (current-buffer))
122 (buffer-contents (buffer-substring-no-properties min max))
123 (overlays
124 (sort (overlays-in min max)
125 (lambda (a b)
126 (let ((overlay-end-a (overlay-end a))
127 (overlay-end-b (overlay-end b)))
128 (> overlay-end-a overlay-end-b))))))
129 (with-temp-buffer
130 (insert buffer-contents)
131 (dolist (overlay overlays)
132 (if (overlay-get overlay 'invisible)
133 (delete-region (overlay-start overlay)
134 (overlay-end overlay))))
135 (buffer-substring-no-properties (point-min) (point-max)))))
138 ;;; Tests for your tests, so you can test while you test.
140 (ert-deftest python-tests-look-at-1 ()
141 "Test forward movement."
142 (python-tests-with-temp-buffer
143 "Lorem ipsum dolor sit amet, consectetur adipisicing elit,
144 sed do eiusmod tempor incididunt ut labore et dolore magna
145 aliqua."
146 (let ((expected (save-excursion
147 (dotimes (i 3)
148 (re-search-forward "et" nil t))
149 (forward-char -2)
150 (point))))
151 (should (= (python-tests-look-at "et" 3 t) expected))
152 ;; Even if NUM is bigger than found occurrences the point of last
153 ;; one should be returned.
154 (should (= (python-tests-look-at "et" 6 t) expected))
155 ;; If already looking at STRING, it should skip it.
156 (dotimes (i 2) (re-search-forward "et"))
157 (forward-char -2)
158 (should (= (python-tests-look-at "et") expected)))))
160 (ert-deftest python-tests-look-at-2 ()
161 "Test backward movement."
162 (python-tests-with-temp-buffer
163 "Lorem ipsum dolor sit amet, consectetur adipisicing elit,
164 sed do eiusmod tempor incididunt ut labore et dolore magna
165 aliqua."
166 (let ((expected
167 (save-excursion
168 (re-search-forward "et" nil t)
169 (forward-char -2)
170 (point))))
171 (dotimes (i 3)
172 (re-search-forward "et" nil t))
173 (should (= (python-tests-look-at "et" -3 t) expected))
174 (should (= (python-tests-look-at "et" -6 t) expected)))))
177 ;;; Bindings
180 ;;; Python specialized rx
183 ;;; Font-lock and syntax
185 (ert-deftest python-syntax-after-python-backspace ()
186 ;; `python-indent-dedent-line-backspace' garbles syntax
187 :expected-result :failed
188 (python-tests-with-temp-buffer
189 "\"\"\""
190 (goto-char (point-max))
191 (python-indent-dedent-line-backspace 1)
192 (should (string= (buffer-string) "\"\""))
193 (should (null (nth 3 (syntax-ppss))))))
196 ;;; Indentation
198 ;; See: http://www.python.org/dev/peps/pep-0008/#indentation
200 (ert-deftest python-indent-pep8-1 ()
201 "First pep8 case."
202 (python-tests-with-temp-buffer
203 "# Aligned with opening delimiter
204 foo = long_function_name(var_one, var_two,
205 var_three, var_four)
207 (should (eq (car (python-indent-context)) :no-indent))
208 (should (= (python-indent-calculate-indentation) 0))
209 (python-tests-look-at "foo = long_function_name(var_one, var_two,")
210 (should (eq (car (python-indent-context)) :after-comment))
211 (should (= (python-indent-calculate-indentation) 0))
212 (python-tests-look-at "var_three, var_four)")
213 (should (eq (car (python-indent-context)) :inside-paren))
214 (should (= (python-indent-calculate-indentation) 25))))
216 (ert-deftest python-indent-pep8-2 ()
217 "Second pep8 case."
218 (python-tests-with-temp-buffer
219 "# More indentation included to distinguish this from the rest.
220 def long_function_name(
221 var_one, var_two, var_three,
222 var_four):
223 print (var_one)
225 (should (eq (car (python-indent-context)) :no-indent))
226 (should (= (python-indent-calculate-indentation) 0))
227 (python-tests-look-at "def long_function_name(")
228 (should (eq (car (python-indent-context)) :after-comment))
229 (should (= (python-indent-calculate-indentation) 0))
230 (python-tests-look-at "var_one, var_two, var_three,")
231 (should (eq (car (python-indent-context))
232 :inside-paren-newline-start-from-block))
233 (should (= (python-indent-calculate-indentation) 8))
234 (python-tests-look-at "var_four):")
235 (should (eq (car (python-indent-context))
236 :inside-paren-newline-start-from-block))
237 (should (= (python-indent-calculate-indentation) 8))
238 (python-tests-look-at "print (var_one)")
239 (should (eq (car (python-indent-context))
240 :after-block-start))
241 (should (= (python-indent-calculate-indentation) 4))))
243 (ert-deftest python-indent-pep8-3 ()
244 "Third pep8 case."
245 (python-tests-with-temp-buffer
246 "# Extra indentation is not necessary.
247 foo = long_function_name(
248 var_one, var_two,
249 var_three, var_four)
251 (should (eq (car (python-indent-context)) :no-indent))
252 (should (= (python-indent-calculate-indentation) 0))
253 (python-tests-look-at "foo = long_function_name(")
254 (should (eq (car (python-indent-context)) :after-comment))
255 (should (= (python-indent-calculate-indentation) 0))
256 (python-tests-look-at "var_one, var_two,")
257 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
258 (should (= (python-indent-calculate-indentation) 4))
259 (python-tests-look-at "var_three, var_four)")
260 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
261 (should (= (python-indent-calculate-indentation) 4))))
263 (ert-deftest python-indent-base-case ()
264 "Check base case does not trigger errors."
265 (python-tests-with-temp-buffer
269 (goto-char (point-min))
270 (should (eq (car (python-indent-context)) :no-indent))
271 (should (= (python-indent-calculate-indentation) 0))
272 (forward-line 1)
273 (should (eq (car (python-indent-context)) :no-indent))
274 (should (= (python-indent-calculate-indentation) 0))
275 (forward-line 1)
276 (should (eq (car (python-indent-context)) :no-indent))
277 (should (= (python-indent-calculate-indentation) 0))))
279 (ert-deftest python-indent-after-comment-1 ()
280 "The most simple after-comment case that shouldn't fail."
281 (python-tests-with-temp-buffer
282 "# Contents will be modified to correct indentation
283 class Blag(object):
284 def _on_child_complete(self, child_future):
285 if self.in_terminal_state():
286 pass
287 # We only complete when all our async children have entered a
288 # terminal state. At that point, if any child failed, we fail
289 # with the exception with which the first child failed.
291 (python-tests-look-at "# We only complete")
292 (should (eq (car (python-indent-context)) :after-block-end))
293 (should (= (python-indent-calculate-indentation) 8))
294 (python-tests-look-at "# terminal state")
295 (should (eq (car (python-indent-context)) :after-comment))
296 (should (= (python-indent-calculate-indentation) 8))
297 (python-tests-look-at "# with the exception")
298 (should (eq (car (python-indent-context)) :after-comment))
299 ;; This one indents relative to previous block, even given the fact
300 ;; that it was under-indented.
301 (should (= (python-indent-calculate-indentation) 4))
302 (python-tests-look-at "# terminal state" -1)
303 ;; It doesn't hurt to check again.
304 (should (eq (car (python-indent-context)) :after-comment))
305 (python-indent-line)
306 (should (= (current-indentation) 8))
307 (python-tests-look-at "# with the exception")
308 (should (eq (car (python-indent-context)) :after-comment))
309 ;; Now everything should be lined up.
310 (should (= (python-indent-calculate-indentation) 8))))
312 (ert-deftest python-indent-after-comment-2 ()
313 "Test after-comment in weird cases."
314 (python-tests-with-temp-buffer
315 "# Contents will be modified to correct indentation
316 def func(arg):
317 # I don't do much
318 return arg
319 # This comment is badly indented because the user forced so.
320 # At this line python.el wont dedent, user is always right.
322 comment_wins_over_ender = True
324 # yeah, that.
326 (python-tests-look-at "# I don't do much")
327 (should (eq (car (python-indent-context)) :after-block-start))
328 (should (= (python-indent-calculate-indentation) 4))
329 (python-tests-look-at "return arg")
330 ;; Comment here just gets ignored, this line is not a comment so
331 ;; the rules won't apply here.
332 (should (eq (car (python-indent-context)) :after-block-start))
333 (should (= (python-indent-calculate-indentation) 4))
334 (python-tests-look-at "# This comment is badly indented")
335 (should (eq (car (python-indent-context)) :after-block-end))
336 ;; The return keyword do make indentation lose a level...
337 (should (= (python-indent-calculate-indentation) 0))
338 ;; ...but the current indentation was forced by the user.
339 (python-tests-look-at "# At this line python.el wont dedent")
340 (should (eq (car (python-indent-context)) :after-comment))
341 (should (= (python-indent-calculate-indentation) 4))
342 ;; Should behave the same for blank lines: potentially a comment.
343 (forward-line 1)
344 (should (eq (car (python-indent-context)) :after-comment))
345 (should (= (python-indent-calculate-indentation) 4))
346 (python-tests-look-at "comment_wins_over_ender")
347 ;; The comment won over the ender because the user said so.
348 (should (eq (car (python-indent-context)) :after-comment))
349 (should (= (python-indent-calculate-indentation) 4))
350 ;; The indentation calculated fine for the assignment, but the user
351 ;; choose to force it back to the first column. Next line should
352 ;; be aware of that.
353 (python-tests-look-at "# yeah, that.")
354 (should (eq (car (python-indent-context)) :after-line))
355 (should (= (python-indent-calculate-indentation) 0))))
357 (ert-deftest python-indent-after-comment-3 ()
358 "Test after-comment in buggy case."
359 (python-tests-with-temp-buffer
361 class A(object):
363 def something(self, arg):
364 if True:
365 return arg
367 # A comment
369 @adecorator
370 def method(self, a, b):
371 pass
373 (python-tests-look-at "@adecorator")
374 (should (eq (car (python-indent-context)) :after-comment))
375 (should (= (python-indent-calculate-indentation) 4))))
377 (ert-deftest python-indent-inside-paren-1 ()
378 "The most simple inside-paren case that shouldn't fail."
379 (python-tests-with-temp-buffer
381 data = {
382 'key':
384 'objlist': [
386 'pk': 1,
387 'name': 'first',
390 'pk': 2,
391 'name': 'second',
397 (python-tests-look-at "data = {")
398 (should (eq (car (python-indent-context)) :no-indent))
399 (should (= (python-indent-calculate-indentation) 0))
400 (python-tests-look-at "'key':")
401 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
402 (should (= (python-indent-calculate-indentation) 4))
403 (python-tests-look-at "{")
404 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
405 (should (= (python-indent-calculate-indentation) 4))
406 (python-tests-look-at "'objlist': [")
407 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
408 (should (= (python-indent-calculate-indentation) 8))
409 (python-tests-look-at "{")
410 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
411 (should (= (python-indent-calculate-indentation) 12))
412 (python-tests-look-at "'pk': 1,")
413 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
414 (should (= (python-indent-calculate-indentation) 16))
415 (python-tests-look-at "'name': 'first',")
416 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
417 (should (= (python-indent-calculate-indentation) 16))
418 (python-tests-look-at "},")
419 (should (eq (car (python-indent-context))
420 :inside-paren-at-closing-nested-paren))
421 (should (= (python-indent-calculate-indentation) 12))
422 (python-tests-look-at "{")
423 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
424 (should (= (python-indent-calculate-indentation) 12))
425 (python-tests-look-at "'pk': 2,")
426 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
427 (should (= (python-indent-calculate-indentation) 16))
428 (python-tests-look-at "'name': 'second',")
429 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
430 (should (= (python-indent-calculate-indentation) 16))
431 (python-tests-look-at "}")
432 (should (eq (car (python-indent-context))
433 :inside-paren-at-closing-nested-paren))
434 (should (= (python-indent-calculate-indentation) 12))
435 (python-tests-look-at "]")
436 (should (eq (car (python-indent-context))
437 :inside-paren-at-closing-nested-paren))
438 (should (= (python-indent-calculate-indentation) 8))
439 (python-tests-look-at "}")
440 (should (eq (car (python-indent-context))
441 :inside-paren-at-closing-nested-paren))
442 (should (= (python-indent-calculate-indentation) 4))
443 (python-tests-look-at "}")
444 (should (eq (car (python-indent-context)) :inside-paren-at-closing-paren))
445 (should (= (python-indent-calculate-indentation) 0))))
447 (ert-deftest python-indent-inside-paren-2 ()
448 "Another more compact paren group style."
449 (python-tests-with-temp-buffer
451 data = {'key': {
452 'objlist': [
453 {'pk': 1,
454 'name': 'first'},
455 {'pk': 2,
456 'name': 'second'}
460 (python-tests-look-at "data = {")
461 (should (eq (car (python-indent-context)) :no-indent))
462 (should (= (python-indent-calculate-indentation) 0))
463 (python-tests-look-at "'objlist': [")
464 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
465 (should (= (python-indent-calculate-indentation) 4))
466 (python-tests-look-at "{'pk': 1,")
467 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
468 (should (= (python-indent-calculate-indentation) 8))
469 (python-tests-look-at "'name': 'first'},")
470 (should (eq (car (python-indent-context)) :inside-paren))
471 (should (= (python-indent-calculate-indentation) 9))
472 (python-tests-look-at "{'pk': 2,")
473 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
474 (should (= (python-indent-calculate-indentation) 8))
475 (python-tests-look-at "'name': 'second'}")
476 (should (eq (car (python-indent-context)) :inside-paren))
477 (should (= (python-indent-calculate-indentation) 9))
478 (python-tests-look-at "]")
479 (should (eq (car (python-indent-context))
480 :inside-paren-at-closing-nested-paren))
481 (should (= (python-indent-calculate-indentation) 4))
482 (python-tests-look-at "}}")
483 (should (eq (car (python-indent-context))
484 :inside-paren-at-closing-nested-paren))
485 (should (= (python-indent-calculate-indentation) 0))
486 (python-tests-look-at "}")
487 (should (eq (car (python-indent-context)) :inside-paren-at-closing-paren))
488 (should (= (python-indent-calculate-indentation) 0))))
490 (ert-deftest python-indent-inside-paren-3 ()
491 "The simplest case possible."
492 (python-tests-with-temp-buffer
494 data = ('these',
495 'are',
496 'the',
497 'tokens')
499 (python-tests-look-at "data = ('these',")
500 (should (eq (car (python-indent-context)) :no-indent))
501 (should (= (python-indent-calculate-indentation) 0))
502 (forward-line 1)
503 (should (eq (car (python-indent-context)) :inside-paren))
504 (should (= (python-indent-calculate-indentation) 8))
505 (forward-line 1)
506 (should (eq (car (python-indent-context)) :inside-paren))
507 (should (= (python-indent-calculate-indentation) 8))
508 (forward-line 1)
509 (should (eq (car (python-indent-context)) :inside-paren))
510 (should (= (python-indent-calculate-indentation) 8))))
512 (ert-deftest python-indent-inside-paren-4 ()
513 "Respect indentation of first column."
514 (python-tests-with-temp-buffer
516 data = [ [ 'these', 'are'],
517 ['the', 'tokens' ] ]
519 (python-tests-look-at "data = [ [ 'these', 'are'],")
520 (should (eq (car (python-indent-context)) :no-indent))
521 (should (= (python-indent-calculate-indentation) 0))
522 (forward-line 1)
523 (should (eq (car (python-indent-context)) :inside-paren))
524 (should (= (python-indent-calculate-indentation) 9))))
526 (ert-deftest python-indent-inside-paren-5 ()
527 "Test when :inside-paren initial parens are skipped in context start."
528 (python-tests-with-temp-buffer
530 while ((not some_condition) and
531 another_condition):
532 do_something_interesting(
533 with_some_arg)
535 (python-tests-look-at "while ((not some_condition) and")
536 (should (eq (car (python-indent-context)) :no-indent))
537 (should (= (python-indent-calculate-indentation) 0))
538 (forward-line 1)
539 (should (eq (car (python-indent-context)) :inside-paren))
540 (should (= (python-indent-calculate-indentation) 7))
541 (forward-line 1)
542 (should (eq (car (python-indent-context)) :after-block-start))
543 (should (= (python-indent-calculate-indentation) 4))
544 (forward-line 1)
545 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
546 (should (= (python-indent-calculate-indentation) 8))))
548 (ert-deftest python-indent-inside-paren-6 ()
549 "This should be aligned.."
550 (python-tests-with-temp-buffer
552 CHOICES = (('some', 'choice'),
553 ('another', 'choice'),
554 ('more', 'choices'))
556 (python-tests-look-at "CHOICES = (('some', 'choice'),")
557 (should (eq (car (python-indent-context)) :no-indent))
558 (should (= (python-indent-calculate-indentation) 0))
559 (forward-line 1)
560 (should (eq (car (python-indent-context)) :inside-paren))
561 (should (= (python-indent-calculate-indentation) 11))
562 (forward-line 1)
563 (should (eq (car (python-indent-context)) :inside-paren))
564 (should (= (python-indent-calculate-indentation) 11))))
566 (ert-deftest python-indent-inside-paren-7 ()
567 "Test for Bug#21762."
568 (python-tests-with-temp-buffer
569 "import re as myre\nvar = [\n"
570 (goto-char (point-max))
571 ;; This signals an error if the test fails
572 (should (eq (car (python-indent-context)) :inside-paren-newline-start))))
574 (ert-deftest python-indent-after-block-1 ()
575 "The most simple after-block case that shouldn't fail."
576 (python-tests-with-temp-buffer
578 def foo(a, b, c=True):
580 (should (eq (car (python-indent-context)) :no-indent))
581 (should (= (python-indent-calculate-indentation) 0))
582 (goto-char (point-max))
583 (should (eq (car (python-indent-context)) :after-block-start))
584 (should (= (python-indent-calculate-indentation) 4))))
586 (ert-deftest python-indent-after-block-2 ()
587 "A weird (malformed) multiline block statement."
588 (python-tests-with-temp-buffer
590 def foo(a, b, c={
591 'a':
594 (goto-char (point-max))
595 (should (eq (car (python-indent-context)) :after-block-start))
596 (should (= (python-indent-calculate-indentation) 4))))
598 (ert-deftest python-indent-after-block-3 ()
599 "A weird (malformed) sample, usually found in python shells."
600 (python-tests-with-temp-buffer
602 In [1]:
603 def func():
604 pass
606 In [2]:
607 something
609 (python-tests-look-at "pass")
610 (should (eq (car (python-indent-context)) :after-block-start))
611 (should (= (python-indent-calculate-indentation) 4))
612 (python-tests-look-at "something")
613 (end-of-line)
614 (should (eq (car (python-indent-context)) :after-line))
615 (should (= (python-indent-calculate-indentation) 0))))
617 (ert-deftest python-indent-after-async-block-1 ()
618 "Test PEP492 async def."
619 (python-tests-with-temp-buffer
621 async def foo(a, b, c=True):
623 (should (eq (car (python-indent-context)) :no-indent))
624 (should (= (python-indent-calculate-indentation) 0))
625 (goto-char (point-max))
626 (should (eq (car (python-indent-context)) :after-block-start))
627 (should (= (python-indent-calculate-indentation) 4))))
629 (ert-deftest python-indent-after-async-block-2 ()
630 "Test PEP492 async with."
631 (python-tests-with-temp-buffer
633 async with foo(a) as mgr:
635 (should (eq (car (python-indent-context)) :no-indent))
636 (should (= (python-indent-calculate-indentation) 0))
637 (goto-char (point-max))
638 (should (eq (car (python-indent-context)) :after-block-start))
639 (should (= (python-indent-calculate-indentation) 4))))
641 (ert-deftest python-indent-after-async-block-3 ()
642 "Test PEP492 async for."
643 (python-tests-with-temp-buffer
645 async for a in sequencer():
647 (should (eq (car (python-indent-context)) :no-indent))
648 (should (= (python-indent-calculate-indentation) 0))
649 (goto-char (point-max))
650 (should (eq (car (python-indent-context)) :after-block-start))
651 (should (= (python-indent-calculate-indentation) 4))))
653 (ert-deftest python-indent-after-backslash-1 ()
654 "The most common case."
655 (python-tests-with-temp-buffer
657 from foo.bar.baz import something, something_1 \\\\
658 something_2 something_3, \\\\
659 something_4, something_5
661 (python-tests-look-at "from foo.bar.baz import something, something_1")
662 (should (eq (car (python-indent-context)) :no-indent))
663 (should (= (python-indent-calculate-indentation) 0))
664 (python-tests-look-at "something_2 something_3,")
665 (should (eq (car (python-indent-context)) :after-backslash-first-line))
666 (should (= (python-indent-calculate-indentation) 4))
667 (python-tests-look-at "something_4, something_5")
668 (should (eq (car (python-indent-context)) :after-backslash))
669 (should (= (python-indent-calculate-indentation) 4))
670 (goto-char (point-max))
671 (should (eq (car (python-indent-context)) :after-line))
672 (should (= (python-indent-calculate-indentation) 0))))
674 (ert-deftest python-indent-after-backslash-2 ()
675 "A pretty extreme complicated case."
676 (python-tests-with-temp-buffer
678 objects = Thing.objects.all() \\\\
679 .filter(
680 type='toy',
681 status='bought'
682 ) \\\\
683 .aggregate(
684 Sum('amount')
685 ) \\\\
686 .values_list()
688 (python-tests-look-at "objects = Thing.objects.all()")
689 (should (eq (car (python-indent-context)) :no-indent))
690 (should (= (python-indent-calculate-indentation) 0))
691 (python-tests-look-at ".filter(")
692 (should (eq (car (python-indent-context))
693 :after-backslash-dotted-continuation))
694 (should (= (python-indent-calculate-indentation) 23))
695 (python-tests-look-at "type='toy',")
696 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
697 (should (= (python-indent-calculate-indentation) 27))
698 (python-tests-look-at "status='bought'")
699 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
700 (should (= (python-indent-calculate-indentation) 27))
701 (python-tests-look-at ") \\\\")
702 (should (eq (car (python-indent-context)) :inside-paren-at-closing-paren))
703 (should (= (python-indent-calculate-indentation) 23))
704 (python-tests-look-at ".aggregate(")
705 (should (eq (car (python-indent-context))
706 :after-backslash-dotted-continuation))
707 (should (= (python-indent-calculate-indentation) 23))
708 (python-tests-look-at "Sum('amount')")
709 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
710 (should (= (python-indent-calculate-indentation) 27))
711 (python-tests-look-at ") \\\\")
712 (should (eq (car (python-indent-context)) :inside-paren-at-closing-paren))
713 (should (= (python-indent-calculate-indentation) 23))
714 (python-tests-look-at ".values_list()")
715 (should (eq (car (python-indent-context))
716 :after-backslash-dotted-continuation))
717 (should (= (python-indent-calculate-indentation) 23))
718 (forward-line 1)
719 (should (eq (car (python-indent-context)) :after-line))
720 (should (= (python-indent-calculate-indentation) 0))))
722 (ert-deftest python-indent-after-backslash-3 ()
723 "Backslash continuation from block start."
724 (python-tests-with-temp-buffer
726 with open('/path/to/some/file/you/want/to/read') as file_1, \\\\
727 open('/path/to/some/file/being/written', 'w') as file_2:
728 file_2.write(file_1.read())
730 (python-tests-look-at
731 "with open('/path/to/some/file/you/want/to/read') as file_1, \\\\")
732 (should (eq (car (python-indent-context)) :no-indent))
733 (should (= (python-indent-calculate-indentation) 0))
734 (python-tests-look-at
735 "open('/path/to/some/file/being/written', 'w') as file_2")
736 (should (eq (car (python-indent-context))
737 :after-backslash-block-continuation))
738 (should (= (python-indent-calculate-indentation) 5))
739 (python-tests-look-at "file_2.write(file_1.read())")
740 (should (eq (car (python-indent-context)) :after-block-start))
741 (should (= (python-indent-calculate-indentation) 4))))
743 (ert-deftest python-indent-after-backslash-4 ()
744 "Backslash continuation from assignment."
745 (python-tests-with-temp-buffer
747 super_awful_assignment = some_calculation() and \\\\
748 another_calculation() and \\\\
749 some_final_calculation()
751 (python-tests-look-at
752 "super_awful_assignment = some_calculation() and \\\\")
753 (should (eq (car (python-indent-context)) :no-indent))
754 (should (= (python-indent-calculate-indentation) 0))
755 (python-tests-look-at "another_calculation() and \\\\")
756 (should (eq (car (python-indent-context))
757 :after-backslash-assignment-continuation))
758 (should (= (python-indent-calculate-indentation) 25))
759 (python-tests-look-at "some_final_calculation()")
760 (should (eq (car (python-indent-context)) :after-backslash))
761 (should (= (python-indent-calculate-indentation) 25))))
763 (ert-deftest python-indent-after-backslash-5 ()
764 "Dotted continuation bizarre example."
765 (python-tests-with-temp-buffer
767 def delete_all_things():
768 Thing \\\\
769 .objects.all() \\\\
770 .delete()
772 (python-tests-look-at "Thing \\\\")
773 (should (eq (car (python-indent-context)) :after-block-start))
774 (should (= (python-indent-calculate-indentation) 4))
775 (python-tests-look-at ".objects.all() \\\\")
776 (should (eq (car (python-indent-context)) :after-backslash-first-line))
777 (should (= (python-indent-calculate-indentation) 8))
778 (python-tests-look-at ".delete()")
779 (should (eq (car (python-indent-context))
780 :after-backslash-dotted-continuation))
781 (should (= (python-indent-calculate-indentation) 16))))
783 (ert-deftest python-indent-block-enders-1 ()
784 "Test de-indentation for pass keyword."
785 (python-tests-with-temp-buffer
787 Class foo(object):
789 def bar(self):
790 if self.baz:
791 return (1,
795 else:
796 pass
798 (python-tests-look-at "3)")
799 (forward-line 1)
800 (should (= (python-indent-calculate-indentation) 8))
801 (python-tests-look-at "pass")
802 (forward-line 1)
803 (should (eq (car (python-indent-context)) :after-block-end))
804 (should (= (python-indent-calculate-indentation) 8))))
806 (ert-deftest python-indent-block-enders-2 ()
807 "Test de-indentation for return keyword."
808 (python-tests-with-temp-buffer
810 Class foo(object):
811 '''raise lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
813 eiusmod tempor incididunt ut labore et dolore magna aliqua.
815 def bar(self):
816 \"return (1, 2, 3).\"
817 if self.baz:
818 return (1,
822 (python-tests-look-at "def")
823 (should (= (python-indent-calculate-indentation) 4))
824 (python-tests-look-at "if")
825 (should (= (python-indent-calculate-indentation) 8))
826 (python-tests-look-at "return")
827 (should (= (python-indent-calculate-indentation) 12))
828 (goto-char (point-max))
829 (should (eq (car (python-indent-context)) :after-block-end))
830 (should (= (python-indent-calculate-indentation) 8))))
832 (ert-deftest python-indent-block-enders-3 ()
833 "Test de-indentation for continue keyword."
834 (python-tests-with-temp-buffer
836 for element in lst:
837 if element is None:
838 continue
840 (python-tests-look-at "if")
841 (should (= (python-indent-calculate-indentation) 4))
842 (python-tests-look-at "continue")
843 (should (= (python-indent-calculate-indentation) 8))
844 (forward-line 1)
845 (should (eq (car (python-indent-context)) :after-block-end))
846 (should (= (python-indent-calculate-indentation) 4))))
848 (ert-deftest python-indent-block-enders-4 ()
849 "Test de-indentation for break keyword."
850 (python-tests-with-temp-buffer
852 for element in lst:
853 if element is None:
854 break
856 (python-tests-look-at "if")
857 (should (= (python-indent-calculate-indentation) 4))
858 (python-tests-look-at "break")
859 (should (= (python-indent-calculate-indentation) 8))
860 (forward-line 1)
861 (should (eq (car (python-indent-context)) :after-block-end))
862 (should (= (python-indent-calculate-indentation) 4))))
864 (ert-deftest python-indent-block-enders-5 ()
865 "Test de-indentation for raise keyword."
866 (python-tests-with-temp-buffer
868 for element in lst:
869 if element is None:
870 raise ValueError('Element cannot be None')
872 (python-tests-look-at "if")
873 (should (= (python-indent-calculate-indentation) 4))
874 (python-tests-look-at "raise")
875 (should (= (python-indent-calculate-indentation) 8))
876 (forward-line 1)
877 (should (eq (car (python-indent-context)) :after-block-end))
878 (should (= (python-indent-calculate-indentation) 4))))
880 (ert-deftest python-indent-dedenters-1 ()
881 "Test de-indentation for the elif keyword."
882 (python-tests-with-temp-buffer
884 if save:
885 try:
886 write_to_disk(data)
887 finally:
888 cleanup()
889 elif
891 (python-tests-look-at "elif\n")
892 (should (eq (car (python-indent-context)) :at-dedenter-block-start))
893 (should (= (python-indent-calculate-indentation) 0))
894 (should (= (python-indent-calculate-indentation t) 0))))
896 (ert-deftest python-indent-dedenters-2 ()
897 "Test de-indentation for the else keyword."
898 (python-tests-with-temp-buffer
900 if save:
901 try:
902 write_to_disk(data)
903 except IOError:
904 msg = 'Error saving to disk'
905 message(msg)
906 logger.exception(msg)
907 except Exception:
908 if hide_details:
909 logger.exception('Unhandled exception')
910 else
911 finally:
912 data.free()
914 (python-tests-look-at "else\n")
915 (should (eq (car (python-indent-context)) :at-dedenter-block-start))
916 (should (= (python-indent-calculate-indentation) 8))
917 (python-indent-line t)
918 (should (= (python-indent-calculate-indentation t) 4))
919 (python-indent-line t)
920 (should (= (python-indent-calculate-indentation t) 0))
921 (python-indent-line t)
922 (should (= (python-indent-calculate-indentation t) 8))))
924 (ert-deftest python-indent-dedenters-3 ()
925 "Test de-indentation for the except keyword."
926 (python-tests-with-temp-buffer
928 if save:
929 try:
930 write_to_disk(data)
931 except
933 (python-tests-look-at "except\n")
934 (should (eq (car (python-indent-context)) :at-dedenter-block-start))
935 (should (= (python-indent-calculate-indentation) 4))
936 (python-indent-line t)
937 (should (= (python-indent-calculate-indentation t) 4))))
939 (ert-deftest python-indent-dedenters-4 ()
940 "Test de-indentation for the finally keyword."
941 (python-tests-with-temp-buffer
943 if save:
944 try:
945 write_to_disk(data)
946 finally
948 (python-tests-look-at "finally\n")
949 (should (eq (car (python-indent-context)) :at-dedenter-block-start))
950 (should (= (python-indent-calculate-indentation) 4))
951 (python-indent-line t)
952 (should (= (python-indent-calculate-indentation) 4))))
954 (ert-deftest python-indent-dedenters-5 ()
955 "Test invalid levels are skipped in a complex example."
956 (python-tests-with-temp-buffer
958 if save:
959 try:
960 write_to_disk(data)
961 except IOError:
962 msg = 'Error saving to disk'
963 message(msg)
964 logger.exception(msg)
965 finally:
966 if cleanup:
967 do_cleanup()
968 else
970 (python-tests-look-at "else\n")
971 (should (eq (car (python-indent-context)) :at-dedenter-block-start))
972 (should (= (python-indent-calculate-indentation) 8))
973 (should (= (python-indent-calculate-indentation t) 0))
974 (python-indent-line t)
975 (should (= (python-indent-calculate-indentation t) 8))))
977 (ert-deftest python-indent-dedenters-6 ()
978 "Test indentation is zero when no opening block for dedenter."
979 (python-tests-with-temp-buffer
981 try:
982 # if save:
983 write_to_disk(data)
984 else
986 (python-tests-look-at "else\n")
987 (should (eq (car (python-indent-context)) :at-dedenter-block-start))
988 (should (= (python-indent-calculate-indentation) 0))
989 (should (= (python-indent-calculate-indentation t) 0))))
991 (ert-deftest python-indent-dedenters-7 ()
992 "Test indentation case from Bug#15163."
993 (python-tests-with-temp-buffer
995 if a:
996 if b:
997 pass
998 else:
999 pass
1000 else:
1002 (python-tests-look-at "else:" 2)
1003 (should (eq (car (python-indent-context)) :at-dedenter-block-start))
1004 (should (= (python-indent-calculate-indentation) 0))
1005 (should (= (python-indent-calculate-indentation t) 0))))
1007 (ert-deftest python-indent-dedenters-8 ()
1008 "Test indentation for Bug#18432."
1009 (python-tests-with-temp-buffer
1011 if (a == 1 or
1012 a == 2):
1013 pass
1014 elif (a == 3 or
1015 a == 4):
1017 (python-tests-look-at "elif (a == 3 or")
1018 (should (eq (car (python-indent-context)) :at-dedenter-block-start))
1019 (should (= (python-indent-calculate-indentation) 0))
1020 (should (= (python-indent-calculate-indentation t) 0))
1021 (python-tests-look-at "a == 4):\n")
1022 (should (eq (car (python-indent-context)) :inside-paren))
1023 (should (= (python-indent-calculate-indentation) 6))
1024 (python-indent-line)
1025 (should (= (python-indent-calculate-indentation t) 4))
1026 (python-indent-line t)
1027 (should (= (python-indent-calculate-indentation t) 0))
1028 (python-indent-line t)
1029 (should (= (python-indent-calculate-indentation t) 6))))
1031 (ert-deftest python-indent-inside-string-1 ()
1032 "Test indentation for strings."
1033 (python-tests-with-temp-buffer
1035 multiline = '''
1036 bunch
1038 lines
1041 (python-tests-look-at "multiline = '''")
1042 (should (eq (car (python-indent-context)) :no-indent))
1043 (should (= (python-indent-calculate-indentation) 0))
1044 (python-tests-look-at "bunch")
1045 (should (eq (car (python-indent-context)) :inside-string))
1046 (should (= (python-indent-calculate-indentation) 0))
1047 (python-tests-look-at "of")
1048 (should (eq (car (python-indent-context)) :inside-string))
1049 (should (= (python-indent-calculate-indentation) 0))
1050 (python-tests-look-at "lines")
1051 (should (eq (car (python-indent-context)) :inside-string))
1052 (should (= (python-indent-calculate-indentation) 0))
1053 (python-tests-look-at "'''")
1054 (should (eq (car (python-indent-context)) :inside-string))
1055 (should (= (python-indent-calculate-indentation) 0))))
1057 (ert-deftest python-indent-inside-string-2 ()
1058 "Test indentation for docstrings."
1059 (python-tests-with-temp-buffer
1061 def fn(a, b, c=True):
1062 '''docstring
1063 bunch
1065 lines
1068 (python-tests-look-at "'''docstring")
1069 (should (eq (car (python-indent-context)) :after-block-start))
1070 (should (= (python-indent-calculate-indentation) 4))
1071 (python-tests-look-at "bunch")
1072 (should (eq (car (python-indent-context)) :inside-docstring))
1073 (should (= (python-indent-calculate-indentation) 4))
1074 (python-tests-look-at "of")
1075 (should (eq (car (python-indent-context)) :inside-docstring))
1076 ;; Any indentation deeper than the base-indent must remain unmodified.
1077 (should (= (python-indent-calculate-indentation) 8))
1078 (python-tests-look-at "lines")
1079 (should (eq (car (python-indent-context)) :inside-docstring))
1080 (should (= (python-indent-calculate-indentation) 4))
1081 (python-tests-look-at "'''")
1082 (should (eq (car (python-indent-context)) :inside-docstring))
1083 (should (= (python-indent-calculate-indentation) 4))))
1085 (ert-deftest python-indent-inside-string-3 ()
1086 "Test indentation for nested strings."
1087 (python-tests-with-temp-buffer
1089 def fn(a, b, c=True):
1090 some_var = '''
1091 bunch
1093 lines
1096 (python-tests-look-at "some_var = '''")
1097 (should (eq (car (python-indent-context)) :after-block-start))
1098 (should (= (python-indent-calculate-indentation) 4))
1099 (python-tests-look-at "bunch")
1100 (should (eq (car (python-indent-context)) :inside-string))
1101 (should (= (python-indent-calculate-indentation) 4))
1102 (python-tests-look-at "of")
1103 (should (eq (car (python-indent-context)) :inside-string))
1104 (should (= (python-indent-calculate-indentation) 4))
1105 (python-tests-look-at "lines")
1106 (should (eq (car (python-indent-context)) :inside-string))
1107 (should (= (python-indent-calculate-indentation) 4))
1108 (python-tests-look-at "'''")
1109 (should (eq (car (python-indent-context)) :inside-string))
1110 (should (= (python-indent-calculate-indentation) 4))))
1112 (ert-deftest python-indent-electric-colon-1 ()
1113 "Test indentation case from Bug#18228."
1114 (python-tests-with-temp-buffer
1116 def a():
1117 pass
1119 def b()
1121 (python-tests-look-at "def b()")
1122 (goto-char (line-end-position))
1123 (python-tests-self-insert ":")
1124 (should (= (current-indentation) 0))))
1126 (ert-deftest python-indent-electric-colon-2 ()
1127 "Test indentation case for dedenter."
1128 (python-tests-with-temp-buffer
1130 if do:
1131 something()
1132 else
1134 (python-tests-look-at "else")
1135 (goto-char (line-end-position))
1136 (python-tests-self-insert ":")
1137 (should (= (current-indentation) 0))))
1139 (ert-deftest python-indent-electric-colon-3 ()
1140 "Test indentation case for multi-line dedenter."
1141 (python-tests-with-temp-buffer
1143 if do:
1144 something()
1145 elif (this
1147 that)
1149 (python-tests-look-at "that)")
1150 (goto-char (line-end-position))
1151 (python-tests-self-insert ":")
1152 (python-tests-look-at "elif" -1)
1153 (should (= (current-indentation) 0))
1154 (python-tests-look-at "and")
1155 (should (= (current-indentation) 6))
1156 (python-tests-look-at "that)")
1157 (should (= (current-indentation) 6))))
1159 (ert-deftest python-indent-electric-colon-4 ()
1160 "Test indentation case where there is one more-indented previous open block."
1161 (python-tests-with-temp-buffer
1163 def f():
1164 if True:
1165 a = 5
1167 if True:
1168 a = 10
1170 b = 3
1172 else
1174 (python-tests-look-at "else")
1175 (goto-char (line-end-position))
1176 (python-tests-self-insert ":")
1177 (python-tests-look-at "else" -1)
1178 (should (= (current-indentation) 4))))
1180 (ert-deftest python-indent-region-1 ()
1181 "Test indentation case from Bug#18843."
1182 (let ((contents "
1183 def foo ():
1184 try:
1185 pass
1186 except:
1187 pass
1189 (python-tests-with-temp-buffer
1190 contents
1191 (python-indent-region (point-min) (point-max))
1192 (should (string= (buffer-substring-no-properties (point-min) (point-max))
1193 contents)))))
1195 (ert-deftest python-indent-region-2 ()
1196 "Test region indentation on comments."
1197 (let ((contents "
1198 def f():
1199 if True:
1200 pass
1202 # This is
1203 # some multiline
1204 # comment
1206 (python-tests-with-temp-buffer
1207 contents
1208 (python-indent-region (point-min) (point-max))
1209 (should (string= (buffer-substring-no-properties (point-min) (point-max))
1210 contents)))))
1212 (ert-deftest python-indent-region-3 ()
1213 "Test region indentation on comments."
1214 (let ((contents "
1215 def f():
1216 if True:
1217 pass
1218 # This is
1219 # some multiline
1220 # comment
1222 (expected "
1223 def f():
1224 if True:
1225 pass
1226 # This is
1227 # some multiline
1228 # comment
1230 (python-tests-with-temp-buffer
1231 contents
1232 (python-indent-region (point-min) (point-max))
1233 (should (string= (buffer-substring-no-properties (point-min) (point-max))
1234 expected)))))
1236 (ert-deftest python-indent-region-4 ()
1237 "Test region indentation block starts, dedenters and enders."
1238 (let ((contents "
1239 def f():
1240 if True:
1241 a = 5
1242 else:
1243 a = 10
1244 return a
1246 (expected "
1247 def f():
1248 if True:
1249 a = 5
1250 else:
1251 a = 10
1252 return a
1254 (python-tests-with-temp-buffer
1255 contents
1256 (python-indent-region (point-min) (point-max))
1257 (should (string= (buffer-substring-no-properties (point-min) (point-max))
1258 expected)))))
1260 (ert-deftest python-indent-region-5 ()
1261 "Test region indentation for docstrings."
1262 (let ((contents "
1263 def f():
1265 this is
1266 a multiline
1267 string
1269 x = \\
1271 this is an arbitrarily
1272 indented multiline
1273 string
1276 (expected "
1277 def f():
1279 this is
1280 a multiline
1281 string
1283 x = \\
1285 this is an arbitrarily
1286 indented multiline
1287 string
1290 (python-tests-with-temp-buffer
1291 contents
1292 (python-indent-region (point-min) (point-max))
1293 (should (string= (buffer-substring-no-properties (point-min) (point-max))
1294 expected)))))
1297 ;;; Mark
1299 (ert-deftest python-mark-defun-1 ()
1300 """Test `python-mark-defun' with point at defun symbol start."""
1301 (python-tests-with-temp-buffer
1303 def foo(x):
1304 return x
1306 class A:
1307 pass
1309 class B:
1311 def __init__(self):
1312 self.b = 'b'
1314 def fun(self):
1315 return self.b
1317 class C:
1318 '''docstring'''
1320 (let ((expected-mark-beginning-position
1321 (progn
1322 (python-tests-look-at "class A:")
1323 (1- (point))))
1324 (expected-mark-end-position-1
1325 (save-excursion
1326 (python-tests-look-at "pass")
1327 (forward-line)
1328 (point)))
1329 (expected-mark-end-position-2
1330 (save-excursion
1331 (python-tests-look-at "return self.b")
1332 (forward-line)
1333 (point)))
1334 (expected-mark-end-position-3
1335 (save-excursion
1336 (python-tests-look-at "'''docstring'''")
1337 (forward-line)
1338 (point))))
1339 ;; Select class A only, with point at bol.
1340 (python-mark-defun 1)
1341 (should (= (point) expected-mark-beginning-position))
1342 (should (= (marker-position (mark-marker))
1343 expected-mark-end-position-1))
1344 ;; expand to class B, start position should remain the same.
1345 (python-mark-defun 1)
1346 (should (= (point) expected-mark-beginning-position))
1347 (should (= (marker-position (mark-marker))
1348 expected-mark-end-position-2))
1349 ;; expand to class C, start position should remain the same.
1350 (python-mark-defun 1)
1351 (should (= (point) expected-mark-beginning-position))
1352 (should (= (marker-position (mark-marker))
1353 expected-mark-end-position-3)))))
1355 (ert-deftest python-mark-defun-2 ()
1356 """Test `python-mark-defun' with point at nested defun symbol start."""
1357 (python-tests-with-temp-buffer
1359 def foo(x):
1360 return x
1362 class A:
1363 pass
1365 class B:
1367 def __init__(self):
1368 self.b = 'b'
1370 def fun(self):
1371 return self.b
1373 class C:
1374 '''docstring'''
1376 (let ((expected-mark-beginning-position
1377 (progn
1378 (python-tests-look-at "def __init__(self):")
1379 (1- (line-beginning-position))))
1380 (expected-mark-end-position-1
1381 (save-excursion
1382 (python-tests-look-at "self.b = 'b'")
1383 (forward-line)
1384 (point)))
1385 (expected-mark-end-position-2
1386 (save-excursion
1387 (python-tests-look-at "return self.b")
1388 (forward-line)
1389 (point)))
1390 (expected-mark-end-position-3
1391 (save-excursion
1392 (python-tests-look-at "'''docstring'''")
1393 (forward-line)
1394 (point))))
1395 ;; Select B.__init only, with point at its start.
1396 (python-mark-defun 1)
1397 (should (= (point) expected-mark-beginning-position))
1398 (should (= (marker-position (mark-marker))
1399 expected-mark-end-position-1))
1400 ;; expand to B.fun, start position should remain the same.
1401 (python-mark-defun 1)
1402 (should (= (point) expected-mark-beginning-position))
1403 (should (= (marker-position (mark-marker))
1404 expected-mark-end-position-2))
1405 ;; expand to class C, start position should remain the same.
1406 (python-mark-defun 1)
1407 (should (= (point) expected-mark-beginning-position))
1408 (should (= (marker-position (mark-marker))
1409 expected-mark-end-position-3)))))
1411 (ert-deftest python-mark-defun-3 ()
1412 """Test `python-mark-defun' with point inside defun symbol."""
1413 (python-tests-with-temp-buffer
1415 def foo(x):
1416 return x
1418 class A:
1419 pass
1421 class B:
1423 def __init__(self):
1424 self.b = 'b'
1426 def fun(self):
1427 return self.b
1429 class C:
1430 '''docstring'''
1432 (let ((expected-mark-beginning-position
1433 (progn
1434 (python-tests-look-at "def fun(self):")
1435 (python-tests-look-at "(self):")
1436 (1- (line-beginning-position))))
1437 (expected-mark-end-position
1438 (save-excursion
1439 (python-tests-look-at "return self.b")
1440 (forward-line)
1441 (point))))
1442 ;; Should select B.fun, despite point is inside the defun symbol.
1443 (python-mark-defun 1)
1444 (should (= (point) expected-mark-beginning-position))
1445 (should (= (marker-position (mark-marker))
1446 expected-mark-end-position)))))
1449 ;;; Navigation
1451 (ert-deftest python-nav-beginning-of-defun-1 ()
1452 (python-tests-with-temp-buffer
1454 def decoratorFunctionWithArguments(arg1, arg2, arg3):
1455 '''print decorated function call data to stdout.
1457 Usage:
1459 @decoratorFunctionWithArguments('arg1', 'arg2')
1460 def func(a, b, c=True):
1461 pass
1464 def wwrap(f):
1465 print 'Inside wwrap()'
1466 def wrapped_f(*args):
1467 print 'Inside wrapped_f()'
1468 print 'Decorator arguments:', arg1, arg2, arg3
1469 f(*args)
1470 print 'After f(*args)'
1471 return wrapped_f
1472 return wwrap
1474 (python-tests-look-at "return wrap")
1475 (should (= (save-excursion
1476 (python-nav-beginning-of-defun)
1477 (point))
1478 (save-excursion
1479 (python-tests-look-at "def wrapped_f(*args):" -1)
1480 (beginning-of-line)
1481 (point))))
1482 (python-tests-look-at "def wrapped_f(*args):" -1)
1483 (should (= (save-excursion
1484 (python-nav-beginning-of-defun)
1485 (point))
1486 (save-excursion
1487 (python-tests-look-at "def wwrap(f):" -1)
1488 (beginning-of-line)
1489 (point))))
1490 (python-tests-look-at "def wwrap(f):" -1)
1491 (should (= (save-excursion
1492 (python-nav-beginning-of-defun)
1493 (point))
1494 (save-excursion
1495 (python-tests-look-at "def decoratorFunctionWithArguments" -1)
1496 (beginning-of-line)
1497 (point))))))
1499 (ert-deftest python-nav-beginning-of-defun-2 ()
1500 (python-tests-with-temp-buffer
1502 class C(object):
1504 def m(self):
1505 self.c()
1507 def b():
1508 pass
1510 def a():
1511 pass
1513 def c(self):
1514 pass
1516 ;; Nested defuns, are handled with care.
1517 (python-tests-look-at "def c(self):")
1518 (should (= (save-excursion
1519 (python-nav-beginning-of-defun)
1520 (point))
1521 (save-excursion
1522 (python-tests-look-at "def m(self):" -1)
1523 (beginning-of-line)
1524 (point))))
1525 ;; Defuns on same levels should be respected.
1526 (python-tests-look-at "def a():" -1)
1527 (should (= (save-excursion
1528 (python-nav-beginning-of-defun)
1529 (point))
1530 (save-excursion
1531 (python-tests-look-at "def b():" -1)
1532 (beginning-of-line)
1533 (point))))
1534 ;; Jump to a top level defun.
1535 (python-tests-look-at "def b():" -1)
1536 (should (= (save-excursion
1537 (python-nav-beginning-of-defun)
1538 (point))
1539 (save-excursion
1540 (python-tests-look-at "def m(self):" -1)
1541 (beginning-of-line)
1542 (point))))
1543 ;; Jump to a top level defun again.
1544 (python-tests-look-at "def m(self):" -1)
1545 (should (= (save-excursion
1546 (python-nav-beginning-of-defun)
1547 (point))
1548 (save-excursion
1549 (python-tests-look-at "class C(object):" -1)
1550 (beginning-of-line)
1551 (point))))))
1553 (ert-deftest python-nav-beginning-of-defun-3 ()
1554 (python-tests-with-temp-buffer
1556 class C(object):
1558 async def m(self):
1559 return await self.c()
1561 async def c(self):
1562 pass
1564 (python-tests-look-at "self.c()")
1565 (should (= (save-excursion
1566 (python-nav-beginning-of-defun)
1567 (point))
1568 (save-excursion
1569 (python-tests-look-at "async def m" -1)
1570 (beginning-of-line)
1571 (point))))))
1573 (ert-deftest python-nav-end-of-defun-1 ()
1574 (python-tests-with-temp-buffer
1576 class C(object):
1578 def m(self):
1579 self.c()
1581 def b():
1582 pass
1584 def a():
1585 pass
1587 def c(self):
1588 pass
1590 (should (= (save-excursion
1591 (python-tests-look-at "class C(object):")
1592 (python-nav-end-of-defun)
1593 (point))
1594 (save-excursion
1595 (point-max))))
1596 (should (= (save-excursion
1597 (python-tests-look-at "def m(self):")
1598 (python-nav-end-of-defun)
1599 (point))
1600 (save-excursion
1601 (python-tests-look-at "def c(self):")
1602 (forward-line -1)
1603 (point))))
1604 (should (= (save-excursion
1605 (python-tests-look-at "def b():")
1606 (python-nav-end-of-defun)
1607 (point))
1608 (save-excursion
1609 (python-tests-look-at "def b():")
1610 (forward-line 2)
1611 (point))))
1612 (should (= (save-excursion
1613 (python-tests-look-at "def c(self):")
1614 (python-nav-end-of-defun)
1615 (point))
1616 (save-excursion
1617 (point-max))))))
1619 (ert-deftest python-nav-end-of-defun-2 ()
1620 (python-tests-with-temp-buffer
1622 def decoratorFunctionWithArguments(arg1, arg2, arg3):
1623 '''print decorated function call data to stdout.
1625 Usage:
1627 @decoratorFunctionWithArguments('arg1', 'arg2')
1628 def func(a, b, c=True):
1629 pass
1632 def wwrap(f):
1633 print 'Inside wwrap()'
1634 def wrapped_f(*args):
1635 print 'Inside wrapped_f()'
1636 print 'Decorator arguments:', arg1, arg2, arg3
1637 f(*args)
1638 print 'After f(*args)'
1639 return wrapped_f
1640 return wwrap
1642 (should (= (save-excursion
1643 (python-tests-look-at "def decoratorFunctionWithArguments")
1644 (python-nav-end-of-defun)
1645 (point))
1646 (save-excursion
1647 (point-max))))
1648 (should (= (save-excursion
1649 (python-tests-look-at "@decoratorFunctionWithArguments")
1650 (python-nav-end-of-defun)
1651 (point))
1652 (save-excursion
1653 (point-max))))
1654 (should (= (save-excursion
1655 (python-tests-look-at "def wwrap(f):")
1656 (python-nav-end-of-defun)
1657 (point))
1658 (save-excursion
1659 (python-tests-look-at "return wwrap")
1660 (line-beginning-position))))
1661 (should (= (save-excursion
1662 (python-tests-look-at "def wrapped_f(*args):")
1663 (python-nav-end-of-defun)
1664 (point))
1665 (save-excursion
1666 (python-tests-look-at "return wrapped_f")
1667 (line-beginning-position))))
1668 (should (= (save-excursion
1669 (python-tests-look-at "f(*args)")
1670 (python-nav-end-of-defun)
1671 (point))
1672 (save-excursion
1673 (python-tests-look-at "return wrapped_f")
1674 (line-beginning-position))))))
1676 (ert-deftest python-nav-backward-defun-1 ()
1677 (python-tests-with-temp-buffer
1679 class A(object): # A
1681 def a(self): # a
1682 pass
1684 def b(self): # b
1685 pass
1687 class B(object): # B
1689 class C(object): # C
1691 def d(self): # d
1692 pass
1694 # def e(self): # e
1695 # pass
1697 def c(self): # c
1698 pass
1700 # def d(self): # d
1701 # pass
1703 (goto-char (point-max))
1704 (should (= (save-excursion (python-nav-backward-defun))
1705 (python-tests-look-at " def c(self): # c" -1)))
1706 (should (= (save-excursion (python-nav-backward-defun))
1707 (python-tests-look-at " def d(self): # d" -1)))
1708 (should (= (save-excursion (python-nav-backward-defun))
1709 (python-tests-look-at " class C(object): # C" -1)))
1710 (should (= (save-excursion (python-nav-backward-defun))
1711 (python-tests-look-at " class B(object): # B" -1)))
1712 (should (= (save-excursion (python-nav-backward-defun))
1713 (python-tests-look-at " def b(self): # b" -1)))
1714 (should (= (save-excursion (python-nav-backward-defun))
1715 (python-tests-look-at " def a(self): # a" -1)))
1716 (should (= (save-excursion (python-nav-backward-defun))
1717 (python-tests-look-at "class A(object): # A" -1)))
1718 (should (not (python-nav-backward-defun)))))
1720 (ert-deftest python-nav-backward-defun-2 ()
1721 (python-tests-with-temp-buffer
1723 def decoratorFunctionWithArguments(arg1, arg2, arg3):
1724 '''print decorated function call data to stdout.
1726 Usage:
1728 @decoratorFunctionWithArguments('arg1', 'arg2')
1729 def func(a, b, c=True):
1730 pass
1733 def wwrap(f):
1734 print 'Inside wwrap()'
1735 def wrapped_f(*args):
1736 print 'Inside wrapped_f()'
1737 print 'Decorator arguments:', arg1, arg2, arg3
1738 f(*args)
1739 print 'After f(*args)'
1740 return wrapped_f
1741 return wwrap
1743 (goto-char (point-max))
1744 (should (= (save-excursion (python-nav-backward-defun))
1745 (python-tests-look-at " def wrapped_f(*args):" -1)))
1746 (should (= (save-excursion (python-nav-backward-defun))
1747 (python-tests-look-at " def wwrap(f):" -1)))
1748 (should (= (save-excursion (python-nav-backward-defun))
1749 (python-tests-look-at "def decoratorFunctionWithArguments(arg1, arg2, arg3):" -1)))
1750 (should (not (python-nav-backward-defun)))))
1752 (ert-deftest python-nav-backward-defun-3 ()
1753 (python-tests-with-temp-buffer
1756 def u(self):
1757 pass
1759 def v(self):
1760 pass
1762 def w(self):
1763 pass
1766 class A(object):
1767 pass
1769 (goto-char (point-min))
1770 (let ((point (python-tests-look-at "class A(object):")))
1771 (should (not (python-nav-backward-defun)))
1772 (should (= point (point))))))
1774 (ert-deftest python-nav-forward-defun-1 ()
1775 (python-tests-with-temp-buffer
1777 class A(object): # A
1779 def a(self): # a
1780 pass
1782 def b(self): # b
1783 pass
1785 class B(object): # B
1787 class C(object): # C
1789 def d(self): # d
1790 pass
1792 # def e(self): # e
1793 # pass
1795 def c(self): # c
1796 pass
1798 # def d(self): # d
1799 # pass
1801 (goto-char (point-min))
1802 (should (= (save-excursion (python-nav-forward-defun))
1803 (python-tests-look-at "(object): # A")))
1804 (should (= (save-excursion (python-nav-forward-defun))
1805 (python-tests-look-at "(self): # a")))
1806 (should (= (save-excursion (python-nav-forward-defun))
1807 (python-tests-look-at "(self): # b")))
1808 (should (= (save-excursion (python-nav-forward-defun))
1809 (python-tests-look-at "(object): # B")))
1810 (should (= (save-excursion (python-nav-forward-defun))
1811 (python-tests-look-at "(object): # C")))
1812 (should (= (save-excursion (python-nav-forward-defun))
1813 (python-tests-look-at "(self): # d")))
1814 (should (= (save-excursion (python-nav-forward-defun))
1815 (python-tests-look-at "(self): # c")))
1816 (should (not (python-nav-forward-defun)))))
1818 (ert-deftest python-nav-forward-defun-2 ()
1819 (python-tests-with-temp-buffer
1821 def decoratorFunctionWithArguments(arg1, arg2, arg3):
1822 '''print decorated function call data to stdout.
1824 Usage:
1826 @decoratorFunctionWithArguments('arg1', 'arg2')
1827 def func(a, b, c=True):
1828 pass
1831 def wwrap(f):
1832 print 'Inside wwrap()'
1833 def wrapped_f(*args):
1834 print 'Inside wrapped_f()'
1835 print 'Decorator arguments:', arg1, arg2, arg3
1836 f(*args)
1837 print 'After f(*args)'
1838 return wrapped_f
1839 return wwrap
1841 (goto-char (point-min))
1842 (should (= (save-excursion (python-nav-forward-defun))
1843 (python-tests-look-at "(arg1, arg2, arg3):")))
1844 (should (= (save-excursion (python-nav-forward-defun))
1845 (python-tests-look-at "(f):")))
1846 (should (= (save-excursion (python-nav-forward-defun))
1847 (python-tests-look-at "(*args):")))
1848 (should (not (python-nav-forward-defun)))))
1850 (ert-deftest python-nav-forward-defun-3 ()
1851 (python-tests-with-temp-buffer
1853 class A(object):
1854 pass
1857 def u(self):
1858 pass
1860 def v(self):
1861 pass
1863 def w(self):
1864 pass
1867 (goto-char (point-min))
1868 (let ((point (python-tests-look-at "(object):")))
1869 (should (not (python-nav-forward-defun)))
1870 (should (= point (point))))))
1872 (ert-deftest python-nav-beginning-of-statement-1 ()
1873 (python-tests-with-temp-buffer
1875 v1 = 123 + \
1876 456 + \
1878 v2 = (value1,
1879 value2,
1881 value3,
1882 value4)
1883 v3 = ('this is a string'
1885 'that is continued'
1886 'between lines'
1887 'within a paren',
1888 # this is a comment, yo
1889 'continue previous line')
1890 v4 = '''
1891 a very long
1892 string
1895 (python-tests-look-at "v2 =")
1896 (python-util-forward-comment -1)
1897 (should (= (save-excursion
1898 (python-nav-beginning-of-statement)
1899 (point))
1900 (python-tests-look-at "v1 =" -1 t)))
1901 (python-tests-look-at "v3 =")
1902 (python-util-forward-comment -1)
1903 (should (= (save-excursion
1904 (python-nav-beginning-of-statement)
1905 (point))
1906 (python-tests-look-at "v2 =" -1 t)))
1907 (python-tests-look-at "v4 =")
1908 (python-util-forward-comment -1)
1909 (should (= (save-excursion
1910 (python-nav-beginning-of-statement)
1911 (point))
1912 (python-tests-look-at "v3 =" -1 t)))
1913 (goto-char (point-max))
1914 (python-util-forward-comment -1)
1915 (should (= (save-excursion
1916 (python-nav-beginning-of-statement)
1917 (point))
1918 (python-tests-look-at "v4 =" -1 t)))))
1920 (ert-deftest python-nav-end-of-statement-1 ()
1921 (python-tests-with-temp-buffer
1923 v1 = 123 + \
1924 456 + \
1926 v2 = (value1,
1927 value2,
1929 value3,
1930 value4)
1931 v3 = ('this is a string'
1933 'that is continued'
1934 'between lines'
1935 'within a paren',
1936 # this is a comment, yo
1937 'continue previous line')
1938 v4 = '''
1939 a very long
1940 string
1943 (python-tests-look-at "v1 =")
1944 (should (= (save-excursion
1945 (python-nav-end-of-statement)
1946 (point))
1947 (save-excursion
1948 (python-tests-look-at "789")
1949 (line-end-position))))
1950 (python-tests-look-at "v2 =")
1951 (should (= (save-excursion
1952 (python-nav-end-of-statement)
1953 (point))
1954 (save-excursion
1955 (python-tests-look-at "value4)")
1956 (line-end-position))))
1957 (python-tests-look-at "v3 =")
1958 (should (= (save-excursion
1959 (python-nav-end-of-statement)
1960 (point))
1961 (save-excursion
1962 (python-tests-look-at
1963 "'continue previous line')")
1964 (line-end-position))))
1965 (python-tests-look-at "v4 =")
1966 (should (= (save-excursion
1967 (python-nav-end-of-statement)
1968 (point))
1969 (save-excursion
1970 (goto-char (point-max))
1971 (python-util-forward-comment -1)
1972 (point))))))
1974 (ert-deftest python-nav-forward-statement-1 ()
1975 (python-tests-with-temp-buffer
1977 v1 = 123 + \
1978 456 + \
1980 v2 = (value1,
1981 value2,
1983 value3,
1984 value4)
1985 v3 = ('this is a string'
1987 'that is continued'
1988 'between lines'
1989 'within a paren',
1990 # this is a comment, yo
1991 'continue previous line')
1992 v4 = '''
1993 a very long
1994 string
1997 (python-tests-look-at "v1 =")
1998 (should (= (save-excursion
1999 (python-nav-forward-statement)
2000 (point))
2001 (python-tests-look-at "v2 =")))
2002 (should (= (save-excursion
2003 (python-nav-forward-statement)
2004 (point))
2005 (python-tests-look-at "v3 =")))
2006 (should (= (save-excursion
2007 (python-nav-forward-statement)
2008 (point))
2009 (python-tests-look-at "v4 =")))
2010 (should (= (save-excursion
2011 (python-nav-forward-statement)
2012 (point))
2013 (point-max)))))
2015 (ert-deftest python-nav-backward-statement-1 ()
2016 (python-tests-with-temp-buffer
2018 v1 = 123 + \
2019 456 + \
2021 v2 = (value1,
2022 value2,
2024 value3,
2025 value4)
2026 v3 = ('this is a string'
2028 'that is continued'
2029 'between lines'
2030 'within a paren',
2031 # this is a comment, yo
2032 'continue previous line')
2033 v4 = '''
2034 a very long
2035 string
2038 (goto-char (point-max))
2039 (should (= (save-excursion
2040 (python-nav-backward-statement)
2041 (point))
2042 (python-tests-look-at "v4 =" -1)))
2043 (should (= (save-excursion
2044 (python-nav-backward-statement)
2045 (point))
2046 (python-tests-look-at "v3 =" -1)))
2047 (should (= (save-excursion
2048 (python-nav-backward-statement)
2049 (point))
2050 (python-tests-look-at "v2 =" -1)))
2051 (should (= (save-excursion
2052 (python-nav-backward-statement)
2053 (point))
2054 (python-tests-look-at "v1 =" -1)))))
2056 (ert-deftest python-nav-backward-statement-2 ()
2057 :expected-result :failed
2058 (python-tests-with-temp-buffer
2060 v1 = 123 + \
2061 456 + \
2063 v2 = (value1,
2064 value2,
2066 value3,
2067 value4)
2069 ;; FIXME: For some reason `python-nav-backward-statement' is moving
2070 ;; back two sentences when starting from 'value4)'.
2071 (goto-char (point-max))
2072 (python-util-forward-comment -1)
2073 (should (= (save-excursion
2074 (python-nav-backward-statement)
2075 (point))
2076 (python-tests-look-at "v2 =" -1 t)))))
2078 (ert-deftest python-nav-beginning-of-block-1 ()
2079 (python-tests-with-temp-buffer
2081 def decoratorFunctionWithArguments(arg1, arg2, arg3):
2082 '''print decorated function call data to stdout.
2084 Usage:
2086 @decoratorFunctionWithArguments('arg1', 'arg2')
2087 def func(a, b, c=True):
2088 pass
2091 def wwrap(f):
2092 print 'Inside wwrap()'
2093 def wrapped_f(*args):
2094 print 'Inside wrapped_f()'
2095 print 'Decorator arguments:', arg1, arg2, arg3
2096 f(*args)
2097 print 'After f(*args)'
2098 return wrapped_f
2099 return wwrap
2101 (python-tests-look-at "return wwrap")
2102 (should (= (save-excursion
2103 (python-nav-beginning-of-block)
2104 (point))
2105 (python-tests-look-at "def decoratorFunctionWithArguments" -1)))
2106 (python-tests-look-at "print 'Inside wwrap()'")
2107 (should (= (save-excursion
2108 (python-nav-beginning-of-block)
2109 (point))
2110 (python-tests-look-at "def wwrap(f):" -1)))
2111 (python-tests-look-at "print 'After f(*args)'")
2112 (end-of-line)
2113 (should (= (save-excursion
2114 (python-nav-beginning-of-block)
2115 (point))
2116 (python-tests-look-at "def wrapped_f(*args):" -1)))
2117 (python-tests-look-at "return wrapped_f")
2118 (should (= (save-excursion
2119 (python-nav-beginning-of-block)
2120 (point))
2121 (python-tests-look-at "def wwrap(f):" -1)))))
2123 (ert-deftest python-nav-end-of-block-1 ()
2124 (python-tests-with-temp-buffer
2126 def decoratorFunctionWithArguments(arg1, arg2, arg3):
2127 '''print decorated function call data to stdout.
2129 Usage:
2131 @decoratorFunctionWithArguments('arg1', 'arg2')
2132 def func(a, b, c=True):
2133 pass
2136 def wwrap(f):
2137 print 'Inside wwrap()'
2138 def wrapped_f(*args):
2139 print 'Inside wrapped_f()'
2140 print 'Decorator arguments:', arg1, arg2, arg3
2141 f(*args)
2142 print 'After f(*args)'
2143 return wrapped_f
2144 return wwrap
2146 (python-tests-look-at "def decoratorFunctionWithArguments")
2147 (should (= (save-excursion
2148 (python-nav-end-of-block)
2149 (point))
2150 (save-excursion
2151 (goto-char (point-max))
2152 (python-util-forward-comment -1)
2153 (point))))
2154 (python-tests-look-at "def wwrap(f):")
2155 (should (= (save-excursion
2156 (python-nav-end-of-block)
2157 (point))
2158 (save-excursion
2159 (python-tests-look-at "return wrapped_f")
2160 (line-end-position))))
2161 (end-of-line)
2162 (should (= (save-excursion
2163 (python-nav-end-of-block)
2164 (point))
2165 (save-excursion
2166 (python-tests-look-at "return wrapped_f")
2167 (line-end-position))))
2168 (python-tests-look-at "f(*args)")
2169 (should (= (save-excursion
2170 (python-nav-end-of-block)
2171 (point))
2172 (save-excursion
2173 (python-tests-look-at "print 'After f(*args)'")
2174 (line-end-position))))))
2176 (ert-deftest python-nav-forward-block-1 ()
2177 "This also accounts as a test for `python-nav-backward-block'."
2178 (python-tests-with-temp-buffer
2180 if request.user.is_authenticated():
2181 # def block():
2182 # pass
2183 try:
2184 profile = request.user.get_profile()
2185 except Profile.DoesNotExist:
2186 profile = Profile.objects.create(user=request.user)
2187 else:
2188 if profile.stats:
2189 profile.recalculate_stats()
2190 else:
2191 profile.clear_stats()
2192 finally:
2193 profile.views += 1
2194 profile.save()
2196 (should (= (save-excursion (python-nav-forward-block))
2197 (python-tests-look-at "if request.user.is_authenticated():")))
2198 (should (= (save-excursion (python-nav-forward-block))
2199 (python-tests-look-at "try:")))
2200 (should (= (save-excursion (python-nav-forward-block))
2201 (python-tests-look-at "except Profile.DoesNotExist:")))
2202 (should (= (save-excursion (python-nav-forward-block))
2203 (python-tests-look-at "else:")))
2204 (should (= (save-excursion (python-nav-forward-block))
2205 (python-tests-look-at "if profile.stats:")))
2206 (should (= (save-excursion (python-nav-forward-block))
2207 (python-tests-look-at "else:")))
2208 (should (= (save-excursion (python-nav-forward-block))
2209 (python-tests-look-at "finally:")))
2210 ;; When point is at the last block, leave it there and return nil
2211 (should (not (save-excursion (python-nav-forward-block))))
2212 ;; Move backwards, and even if the number of moves is less than the
2213 ;; provided argument return the point.
2214 (should (= (save-excursion (python-nav-forward-block -10))
2215 (python-tests-look-at
2216 "if request.user.is_authenticated():" -1)))))
2218 (ert-deftest python-nav-forward-sexp-1 ()
2219 (python-tests-with-temp-buffer
2225 (python-tests-look-at "a()")
2226 (python-nav-forward-sexp)
2227 (should (looking-at "$"))
2228 (should (save-excursion
2229 (beginning-of-line)
2230 (looking-at "a()")))
2231 (python-nav-forward-sexp)
2232 (should (looking-at "$"))
2233 (should (save-excursion
2234 (beginning-of-line)
2235 (looking-at "b()")))
2236 (python-nav-forward-sexp)
2237 (should (looking-at "$"))
2238 (should (save-excursion
2239 (beginning-of-line)
2240 (looking-at "c()")))
2241 ;; The default behavior when next to a paren should do what lisp
2242 ;; does and, otherwise `blink-matching-open' breaks.
2243 (python-nav-forward-sexp -1)
2244 (should (looking-at "()"))
2245 (should (save-excursion
2246 (beginning-of-line)
2247 (looking-at "c()")))
2248 (end-of-line)
2249 ;; Skipping parens should jump to `bolp'
2250 (python-nav-forward-sexp -1 nil t)
2251 (should (looking-at "c()"))
2252 (forward-line -1)
2253 (end-of-line)
2254 ;; b()
2255 (python-nav-forward-sexp -1)
2256 (should (looking-at "()"))
2257 (python-nav-forward-sexp -1)
2258 (should (looking-at "b()"))
2259 (end-of-line)
2260 (python-nav-forward-sexp -1 nil t)
2261 (should (looking-at "b()"))
2262 (forward-line -1)
2263 (end-of-line)
2264 ;; a()
2265 (python-nav-forward-sexp -1)
2266 (should (looking-at "()"))
2267 (python-nav-forward-sexp -1)
2268 (should (looking-at "a()"))
2269 (end-of-line)
2270 (python-nav-forward-sexp -1 nil t)
2271 (should (looking-at "a()"))))
2273 (ert-deftest python-nav-forward-sexp-2 ()
2274 (python-tests-with-temp-buffer
2276 def func():
2277 if True:
2278 aaa = bbb
2279 ccc = ddd
2280 eee = fff
2281 return ggg
2283 (python-tests-look-at "aa =")
2284 (python-nav-forward-sexp)
2285 (should (looking-at " = bbb"))
2286 (python-nav-forward-sexp)
2287 (should (looking-at "$"))
2288 (should (save-excursion
2289 (back-to-indentation)
2290 (looking-at "aaa = bbb")))
2291 (python-nav-forward-sexp)
2292 (should (looking-at "$"))
2293 (should (save-excursion
2294 (back-to-indentation)
2295 (looking-at "ccc = ddd")))
2296 (python-nav-forward-sexp)
2297 (should (looking-at "$"))
2298 (should (save-excursion
2299 (back-to-indentation)
2300 (looking-at "eee = fff")))
2301 (python-nav-forward-sexp)
2302 (should (looking-at "$"))
2303 (should (save-excursion
2304 (back-to-indentation)
2305 (looking-at "return ggg")))
2306 (python-nav-forward-sexp -1)
2307 (should (looking-at "def func():"))))
2309 (ert-deftest python-nav-forward-sexp-3 ()
2310 (python-tests-with-temp-buffer
2312 from some_module import some_sub_module
2313 from another_module import another_sub_module
2315 def another_statement():
2316 pass
2318 (python-tests-look-at "some_module")
2319 (python-nav-forward-sexp)
2320 (should (looking-at " import"))
2321 (python-nav-forward-sexp)
2322 (should (looking-at " some_sub_module"))
2323 (python-nav-forward-sexp)
2324 (should (looking-at "$"))
2325 (should
2326 (save-excursion
2327 (back-to-indentation)
2328 (looking-at
2329 "from some_module import some_sub_module")))
2330 (python-nav-forward-sexp)
2331 (should (looking-at "$"))
2332 (should
2333 (save-excursion
2334 (back-to-indentation)
2335 (looking-at
2336 "from another_module import another_sub_module")))
2337 (python-nav-forward-sexp)
2338 (should (looking-at "$"))
2339 (should
2340 (save-excursion
2341 (back-to-indentation)
2342 (looking-at
2343 "pass")))
2344 (python-nav-forward-sexp -1)
2345 (should (looking-at "def another_statement():"))
2346 (python-nav-forward-sexp -1)
2347 (should (looking-at "from another_module import another_sub_module"))
2348 (python-nav-forward-sexp -1)
2349 (should (looking-at "from some_module import some_sub_module"))))
2351 (ert-deftest python-nav-forward-sexp-safe-1 ()
2352 (python-tests-with-temp-buffer
2354 profile = Profile.objects.create(user=request.user)
2355 profile.notify()
2357 (python-tests-look-at "profile =")
2358 (python-nav-forward-sexp-safe 1)
2359 (should (looking-at "$"))
2360 (beginning-of-line 1)
2361 (python-tests-look-at "user=request.user")
2362 (python-nav-forward-sexp-safe -1)
2363 (should (looking-at "(user=request.user)"))
2364 (python-nav-forward-sexp-safe -4)
2365 (should (looking-at "profile ="))
2366 (python-tests-look-at "user=request.user")
2367 (python-nav-forward-sexp-safe 3)
2368 (should (looking-at ")"))
2369 (python-nav-forward-sexp-safe 1)
2370 (should (looking-at "$"))
2371 (python-nav-forward-sexp-safe 1)
2372 (should (looking-at "$"))))
2374 (ert-deftest python-nav-up-list-1 ()
2375 (python-tests-with-temp-buffer
2377 def f():
2378 if True:
2379 return [i for i in range(3)]
2381 (python-tests-look-at "3)]")
2382 (python-nav-up-list)
2383 (should (looking-at "]"))
2384 (python-nav-up-list)
2385 (should (looking-at "$"))))
2387 (ert-deftest python-nav-backward-up-list-1 ()
2388 :expected-result :failed
2389 (python-tests-with-temp-buffer
2391 def f():
2392 if True:
2393 return [i for i in range(3)]
2395 (python-tests-look-at "3)]")
2396 (python-nav-backward-up-list)
2397 (should (looking-at "(3)\\]"))
2398 (python-nav-backward-up-list)
2399 (should (looking-at
2400 "\\[i for i in range(3)\\]"))
2401 ;; FIXME: Need to move to beginning-of-statement.
2402 (python-nav-backward-up-list)
2403 (should (looking-at
2404 "return \\[i for i in range(3)\\]"))
2405 (python-nav-backward-up-list)
2406 (should (looking-at "if True:"))
2407 (python-nav-backward-up-list)
2408 (should (looking-at "def f():"))))
2410 (ert-deftest python-indent-dedent-line-backspace-1 ()
2411 "Check de-indentation on first call. Bug#18319."
2412 (python-tests-with-temp-buffer
2414 if True:
2415 x ()
2416 if False:
2418 (python-tests-look-at "if False:")
2419 (call-interactively #'python-indent-dedent-line-backspace)
2420 (should (zerop (current-indentation)))
2421 ;; XXX: This should be a call to `undo' but it's triggering errors.
2422 (insert " ")
2423 (should (= (current-indentation) 4))
2424 (call-interactively #'python-indent-dedent-line-backspace)
2425 (should (zerop (current-indentation)))))
2427 (ert-deftest python-indent-dedent-line-backspace-2 ()
2428 "Check de-indentation with tabs. Bug#19730."
2429 (let ((tab-width 8))
2430 (python-tests-with-temp-buffer
2432 if x:
2433 \tabcdefg
2435 (python-tests-look-at "abcdefg")
2436 (goto-char (line-end-position))
2437 (call-interactively #'python-indent-dedent-line-backspace)
2438 (should
2439 (string= (buffer-substring-no-properties
2440 (line-beginning-position) (line-end-position))
2441 "\tabcdef")))))
2443 (ert-deftest python-indent-dedent-line-backspace-3 ()
2444 "Paranoid check of de-indentation with tabs. Bug#19730."
2445 (let ((tab-width 8))
2446 (python-tests-with-temp-buffer
2448 if x:
2449 \tif y:
2450 \t abcdefg
2452 (python-tests-look-at "abcdefg")
2453 (goto-char (line-end-position))
2454 (call-interactively #'python-indent-dedent-line-backspace)
2455 (should
2456 (string= (buffer-substring-no-properties
2457 (line-beginning-position) (line-end-position))
2458 "\t abcdef"))
2459 (back-to-indentation)
2460 (call-interactively #'python-indent-dedent-line-backspace)
2461 (should
2462 (string= (buffer-substring-no-properties
2463 (line-beginning-position) (line-end-position))
2464 "\tabcdef"))
2465 (call-interactively #'python-indent-dedent-line-backspace)
2466 (should
2467 (string= (buffer-substring-no-properties
2468 (line-beginning-position) (line-end-position))
2469 " abcdef"))
2470 (call-interactively #'python-indent-dedent-line-backspace)
2471 (should
2472 (string= (buffer-substring-no-properties
2473 (line-beginning-position) (line-end-position))
2474 "abcdef")))))
2476 (ert-deftest python-bob-infloop-avoid ()
2477 "Test that strings at BOB don't confuse syntax analysis. Bug#24905"
2478 (python-tests-with-temp-buffer
2479 " \"\n"
2480 (goto-char (point-min))
2481 (call-interactively 'font-lock-fontify-buffer)))
2484 ;;; Shell integration
2486 (defvar python-tests-shell-interpreter "python")
2488 (ert-deftest python-shell-get-process-name-1 ()
2489 "Check process name calculation sans `buffer-file-name'."
2490 (python-tests-with-temp-buffer
2492 (should (string= (python-shell-get-process-name nil)
2493 python-shell-buffer-name))
2494 (should (string= (python-shell-get-process-name t)
2495 (format "%s[%s]" python-shell-buffer-name (buffer-name))))))
2497 (ert-deftest python-shell-get-process-name-2 ()
2498 "Check process name calculation with `buffer-file-name'."
2499 (python-tests-with-temp-file
2501 ;; `buffer-file-name' is non-nil but the dedicated flag is nil and
2502 ;; should be respected.
2503 (should (string= (python-shell-get-process-name nil)
2504 python-shell-buffer-name))
2505 (should (string=
2506 (python-shell-get-process-name t)
2507 (format "%s[%s]" python-shell-buffer-name (buffer-name))))))
2509 (ert-deftest python-shell-internal-get-process-name-1 ()
2510 "Check the internal process name is buffer-unique sans `buffer-file-name'."
2511 (python-tests-with-temp-buffer
2513 (should (string= (python-shell-internal-get-process-name)
2514 (format "%s[%s]" python-shell-internal-buffer-name (buffer-name))))))
2516 (ert-deftest python-shell-internal-get-process-name-2 ()
2517 "Check the internal process name is buffer-unique with `buffer-file-name'."
2518 (python-tests-with-temp-file
2520 (should (string= (python-shell-internal-get-process-name)
2521 (format "%s[%s]" python-shell-internal-buffer-name (buffer-name))))))
2523 (ert-deftest python-shell-calculate-command-1 ()
2524 "Check the command to execute is calculated correctly.
2525 Using `python-shell-interpreter' and
2526 `python-shell-interpreter-args'."
2527 (skip-unless (executable-find python-tests-shell-interpreter))
2528 (let ((python-shell-interpreter (executable-find
2529 python-tests-shell-interpreter))
2530 (python-shell-interpreter-args "-B"))
2531 (should (string=
2532 (format "%s %s"
2533 (shell-quote-argument python-shell-interpreter)
2534 python-shell-interpreter-args)
2535 (python-shell-calculate-command)))))
2537 (ert-deftest python-shell-calculate-pythonpath-1 ()
2538 "Test PYTHONPATH calculation."
2539 (let ((process-environment '("PYTHONPATH=/path0"))
2540 (python-shell-extra-pythonpaths '("/path1" "/path2")))
2541 (should (string= (python-shell-calculate-pythonpath)
2542 (concat "/path1" path-separator
2543 "/path2" path-separator "/path0")))))
2545 (ert-deftest python-shell-calculate-pythonpath-2 ()
2546 "Test existing paths are moved to front."
2547 (let ((process-environment
2548 (list (concat "PYTHONPATH=/path0" path-separator "/path1")))
2549 (python-shell-extra-pythonpaths '("/path1" "/path2")))
2550 (should (string= (python-shell-calculate-pythonpath)
2551 (concat "/path1" path-separator
2552 "/path2" path-separator "/path0")))))
2554 (ert-deftest python-shell-calculate-process-environment-1 ()
2555 "Test `python-shell-process-environment' modification."
2556 (let* ((python-shell-process-environment
2557 '("TESTVAR1=value1" "TESTVAR2=value2"))
2558 (process-environment (python-shell-calculate-process-environment)))
2559 (should (equal (getenv "TESTVAR1") "value1"))
2560 (should (equal (getenv "TESTVAR2") "value2"))))
2562 (ert-deftest python-shell-calculate-process-environment-2 ()
2563 "Test `python-shell-extra-pythonpaths' modification."
2564 (let* ((process-environment process-environment)
2565 (original-pythonpath (setenv "PYTHONPATH" "/path0"))
2566 (python-shell-extra-pythonpaths '("/path1" "/path2"))
2567 (process-environment (python-shell-calculate-process-environment)))
2568 (should (equal (getenv "PYTHONPATH")
2569 (concat "/path1" path-separator
2570 "/path2" path-separator "/path0")))))
2572 (ert-deftest python-shell-calculate-process-environment-3 ()
2573 "Test `python-shell-virtualenv-root' modification."
2574 (let* ((python-shell-virtualenv-root "/env")
2575 (process-environment
2576 (let (process-environment process-environment)
2577 (setenv "PYTHONHOME" "/home")
2578 (setenv "VIRTUAL_ENV")
2579 (python-shell-calculate-process-environment))))
2580 (should (not (getenv "PYTHONHOME")))
2581 (should (string= (getenv "VIRTUAL_ENV") "/env"))))
2583 (ert-deftest python-shell-calculate-process-environment-4 ()
2584 "Test PYTHONUNBUFFERED when `python-shell-unbuffered' is non-nil."
2585 (let* ((python-shell-unbuffered t)
2586 (process-environment
2587 (let ((process-environment process-environment))
2588 (setenv "PYTHONUNBUFFERED")
2589 (python-shell-calculate-process-environment))))
2590 (should (string= (getenv "PYTHONUNBUFFERED") "1"))))
2592 (ert-deftest python-shell-calculate-process-environment-5 ()
2593 "Test PYTHONUNBUFFERED when `python-shell-unbuffered' is nil."
2594 (let* ((python-shell-unbuffered nil)
2595 (process-environment
2596 (let ((process-environment process-environment))
2597 (setenv "PYTHONUNBUFFERED")
2598 (python-shell-calculate-process-environment))))
2599 (should (not (getenv "PYTHONUNBUFFERED")))))
2601 (ert-deftest python-shell-calculate-process-environment-6 ()
2602 "Test PYTHONUNBUFFERED=1 when `python-shell-unbuffered' is nil."
2603 (let* ((python-shell-unbuffered nil)
2604 (process-environment
2605 (let ((process-environment process-environment))
2606 (setenv "PYTHONUNBUFFERED" "1")
2607 (python-shell-calculate-process-environment))))
2608 ;; User default settings must remain untouched:
2609 (should (string= (getenv "PYTHONUNBUFFERED") "1"))))
2611 (ert-deftest python-shell-calculate-process-environment-7 ()
2612 "Test no side-effects on `process-environment'."
2613 (let* ((python-shell-process-environment
2614 '("TESTVAR1=value1" "TESTVAR2=value2"))
2615 (python-shell-virtualenv-root (or (getenv "VIRTUAL_ENV") "/env"))
2616 (python-shell-unbuffered t)
2617 (python-shell-extra-pythonpaths'("/path1" "/path2"))
2618 (original-process-environment (copy-sequence process-environment)))
2619 (python-shell-calculate-process-environment)
2620 (should (equal process-environment original-process-environment))))
2622 (ert-deftest python-shell-calculate-process-environment-8 ()
2623 "Test no side-effects on `tramp-remote-process-environment'."
2624 (let* ((default-directory "/ssh::/example/dir/")
2625 (python-shell-process-environment
2626 '("TESTVAR1=value1" "TESTVAR2=value2"))
2627 (python-shell-virtualenv-root "/env")
2628 (python-shell-unbuffered t)
2629 (python-shell-extra-pythonpaths'("/path1" "/path2"))
2630 (original-process-environment
2631 (copy-sequence tramp-remote-process-environment)))
2632 (python-shell-calculate-process-environment)
2633 (should (equal tramp-remote-process-environment original-process-environment))))
2635 (ert-deftest python-shell-calculate-exec-path-1 ()
2636 "Test `python-shell-exec-path' modification."
2637 (let* ((exec-path '("/path0"))
2638 (python-shell-exec-path '("/path1" "/path2"))
2639 (new-exec-path (python-shell-calculate-exec-path)))
2640 (should (equal new-exec-path '("/path1" "/path2" "/path0")))))
2642 (ert-deftest python-shell-calculate-exec-path-2 ()
2643 "Test `python-shell-virtualenv-root' modification."
2644 (let* ((exec-path '("/path0"))
2645 (python-shell-virtualenv-root "/env")
2646 (new-exec-path (python-shell-calculate-exec-path)))
2647 (should (equal new-exec-path
2648 (list (expand-file-name "/env/bin") "/path0")))))
2650 (ert-deftest python-shell-calculate-exec-path-3 ()
2651 "Test complete `python-shell-virtualenv-root' modification."
2652 (let* ((exec-path '("/path0"))
2653 (python-shell-exec-path '("/path1" "/path2"))
2654 (python-shell-virtualenv-root "/env")
2655 (new-exec-path (python-shell-calculate-exec-path)))
2656 (should (equal new-exec-path
2657 (list (expand-file-name "/env/bin")
2658 "/path1" "/path2" "/path0")))))
2660 (ert-deftest python-shell-calculate-exec-path-4 ()
2661 "Test complete `python-shell-virtualenv-root' with remote."
2662 (let* ((default-directory "/ssh::/example/dir/")
2663 (python-shell-remote-exec-path '("/path0"))
2664 (python-shell-exec-path '("/path1" "/path2"))
2665 (python-shell-virtualenv-root "/env")
2666 (new-exec-path (python-shell-calculate-exec-path)))
2667 (should (equal new-exec-path
2668 (list (expand-file-name "/env/bin")
2669 "/path1" "/path2" "/path0")))))
2671 (ert-deftest python-shell-calculate-exec-path-5 ()
2672 "Test no side-effects on `exec-path'."
2673 (let* ((exec-path '("/path0"))
2674 (python-shell-exec-path '("/path1" "/path2"))
2675 (python-shell-virtualenv-root "/env")
2676 (original-exec-path (copy-sequence exec-path)))
2677 (python-shell-calculate-exec-path)
2678 (should (equal exec-path original-exec-path))))
2680 (ert-deftest python-shell-calculate-exec-path-6 ()
2681 "Test no side-effects on `python-shell-remote-exec-path'."
2682 (let* ((default-directory "/ssh::/example/dir/")
2683 (python-shell-remote-exec-path '("/path0"))
2684 (python-shell-exec-path '("/path1" "/path2"))
2685 (python-shell-virtualenv-root "/env")
2686 (original-exec-path (copy-sequence python-shell-remote-exec-path)))
2687 (python-shell-calculate-exec-path)
2688 (should (equal python-shell-remote-exec-path original-exec-path))))
2690 (ert-deftest python-shell-with-environment-1 ()
2691 "Test environment with local `default-directory'."
2692 (let* ((exec-path '("/path0"))
2693 (python-shell-exec-path '("/path1" "/path2"))
2694 (original-exec-path exec-path)
2695 (python-shell-virtualenv-root "/env"))
2696 (python-shell-with-environment
2697 (should (equal exec-path
2698 (list (expand-file-name "/env/bin")
2699 "/path1" "/path2" "/path0")))
2700 (should (not (getenv "PYTHONHOME")))
2701 (should (string= (getenv "VIRTUAL_ENV") "/env")))
2702 (should (equal exec-path original-exec-path))))
2704 (ert-deftest python-shell-with-environment-2 ()
2705 "Test environment with remote `default-directory'."
2706 (let* ((default-directory "/ssh::/example/dir/")
2707 (python-shell-remote-exec-path '("/remote1" "/remote2"))
2708 (python-shell-exec-path '("/path1" "/path2"))
2709 (tramp-remote-process-environment '("EMACS=t"))
2710 (original-process-environment (copy-sequence tramp-remote-process-environment))
2711 (python-shell-virtualenv-root "/env"))
2712 (python-shell-with-environment
2713 (should (equal (python-shell-calculate-exec-path)
2714 (list (expand-file-name "/env/bin")
2715 "/path1" "/path2" "/remote1" "/remote2")))
2716 (let ((process-environment (python-shell-calculate-process-environment)))
2717 (should (not (getenv "PYTHONHOME")))
2718 (should (string= (getenv "VIRTUAL_ENV") "/env"))
2719 (should (equal tramp-remote-process-environment process-environment))))
2720 (should (equal tramp-remote-process-environment original-process-environment))))
2722 (ert-deftest python-shell-with-environment-3 ()
2723 "Test `python-shell-with-environment' is idempotent."
2724 (let* ((python-shell-extra-pythonpaths '("/example/dir/"))
2725 (python-shell-exec-path '("path1" "path2"))
2726 (python-shell-virtualenv-root "/home/user/env")
2727 (single-call
2728 (python-shell-with-environment
2729 (list exec-path process-environment)))
2730 (nested-call
2731 (python-shell-with-environment
2732 (python-shell-with-environment
2733 (list exec-path process-environment)))))
2734 (should (equal single-call nested-call))))
2736 (ert-deftest python-shell-make-comint-1 ()
2737 "Check comint creation for global shell buffer."
2738 (skip-unless (executable-find python-tests-shell-interpreter))
2739 ;; The interpreter can get killed too quickly to allow it to clean
2740 ;; up the tempfiles that the default python-shell-setup-codes create,
2741 ;; so it leaves tempfiles behind, which is a minor irritation.
2742 (let* ((python-shell-setup-codes nil)
2743 (python-shell-interpreter
2744 (executable-find python-tests-shell-interpreter))
2745 (proc-name (python-shell-get-process-name nil))
2746 (shell-buffer
2747 (python-tests-with-temp-buffer
2748 "" (python-shell-make-comint
2749 (python-shell-calculate-command) proc-name)))
2750 (process (get-buffer-process shell-buffer)))
2751 (unwind-protect
2752 (progn
2753 (set-process-query-on-exit-flag process nil)
2754 (should (process-live-p process))
2755 (with-current-buffer shell-buffer
2756 (should (eq major-mode 'inferior-python-mode))
2757 (should (string= (buffer-name) (format "*%s*" proc-name)))))
2758 (kill-buffer shell-buffer))))
2760 (ert-deftest python-shell-make-comint-2 ()
2761 "Check comint creation for internal shell buffer."
2762 (skip-unless (executable-find python-tests-shell-interpreter))
2763 (let* ((python-shell-setup-codes nil)
2764 (python-shell-interpreter
2765 (executable-find python-tests-shell-interpreter))
2766 (proc-name (python-shell-internal-get-process-name))
2767 (shell-buffer
2768 (python-tests-with-temp-buffer
2769 "" (python-shell-make-comint
2770 (python-shell-calculate-command) proc-name nil t)))
2771 (process (get-buffer-process shell-buffer)))
2772 (unwind-protect
2773 (progn
2774 (set-process-query-on-exit-flag process nil)
2775 (should (process-live-p process))
2776 (with-current-buffer shell-buffer
2777 (should (eq major-mode 'inferior-python-mode))
2778 (should (string= (buffer-name) (format " *%s*" proc-name)))))
2779 (kill-buffer shell-buffer))))
2781 (ert-deftest python-shell-make-comint-3 ()
2782 "Check comint creation with overridden python interpreter and args.
2783 The command passed to `python-shell-make-comint' as argument must
2784 locally override global values set in `python-shell-interpreter'
2785 and `python-shell-interpreter-args' in the new shell buffer."
2786 (skip-unless (executable-find python-tests-shell-interpreter))
2787 (let* ((python-shell-setup-codes nil)
2788 (python-shell-interpreter "interpreter")
2789 (python-shell-interpreter-args "--some-args")
2790 (proc-name (python-shell-get-process-name nil))
2791 (interpreter-override
2792 (concat (executable-find python-tests-shell-interpreter) " " "-i"))
2793 (shell-buffer
2794 (python-tests-with-temp-buffer
2795 "" (python-shell-make-comint interpreter-override proc-name nil)))
2796 (process (get-buffer-process shell-buffer)))
2797 (unwind-protect
2798 (progn
2799 (set-process-query-on-exit-flag process nil)
2800 (should (process-live-p process))
2801 (with-current-buffer shell-buffer
2802 (should (eq major-mode 'inferior-python-mode))
2803 (should (file-equal-p
2804 python-shell-interpreter
2805 (executable-find python-tests-shell-interpreter)))
2806 (should (string= python-shell-interpreter-args "-i"))))
2807 (kill-buffer shell-buffer))))
2809 (ert-deftest python-shell-make-comint-4 ()
2810 "Check shell calculated prompts regexps are set."
2811 (skip-unless (executable-find python-tests-shell-interpreter))
2812 (let* ((process-environment process-environment)
2813 (python-shell-setup-codes nil)
2814 (python-shell-interpreter
2815 (executable-find python-tests-shell-interpreter))
2816 (python-shell-interpreter-args "-i")
2817 (python-shell--prompt-calculated-input-regexp nil)
2818 (python-shell--prompt-calculated-output-regexp nil)
2819 (python-shell-prompt-detect-enabled t)
2820 (python-shell-prompt-input-regexps '("extralargeinputprompt" "sml"))
2821 (python-shell-prompt-output-regexps '("extralargeoutputprompt" "sml"))
2822 (python-shell-prompt-regexp "in")
2823 (python-shell-prompt-block-regexp "block")
2824 (python-shell-prompt-pdb-regexp "pdf")
2825 (python-shell-prompt-output-regexp "output")
2826 (startup-code (concat "import sys\n"
2827 "sys.ps1 = 'py> '\n"
2828 "sys.ps2 = '..> '\n"
2829 "sys.ps3 = 'out '\n"))
2830 (startup-file (python-shell--save-temp-file startup-code))
2831 (proc-name (python-shell-get-process-name nil))
2832 (shell-buffer
2833 (progn
2834 (setenv "PYTHONSTARTUP" startup-file)
2835 (python-tests-with-temp-buffer
2836 "" (python-shell-make-comint
2837 (python-shell-calculate-command) proc-name nil))))
2838 (process (get-buffer-process shell-buffer)))
2839 (unwind-protect
2840 (progn
2841 (set-process-query-on-exit-flag process nil)
2842 (should (process-live-p process))
2843 (with-current-buffer shell-buffer
2844 (should (eq major-mode 'inferior-python-mode))
2845 (should (string=
2846 python-shell--prompt-calculated-input-regexp
2847 (concat "^\\(extralargeinputprompt\\|\\.\\.> \\|"
2848 "block\\|py> \\|pdf\\|sml\\|in\\)")))
2849 (should (string=
2850 python-shell--prompt-calculated-output-regexp
2851 "^\\(extralargeoutputprompt\\|output\\|out \\|sml\\)"))))
2852 (delete-file startup-file)
2853 (kill-buffer shell-buffer))))
2855 (ert-deftest python-shell-get-process-1 ()
2856 "Check dedicated shell process preference over global."
2857 (skip-unless (executable-find python-tests-shell-interpreter))
2858 (python-tests-with-temp-file
2860 (let* ((python-shell-setup-codes nil)
2861 (python-shell-interpreter
2862 (executable-find python-tests-shell-interpreter))
2863 (global-proc-name (python-shell-get-process-name nil))
2864 (dedicated-proc-name (python-shell-get-process-name t))
2865 (global-shell-buffer
2866 (python-shell-make-comint
2867 (python-shell-calculate-command) global-proc-name))
2868 (dedicated-shell-buffer
2869 (python-shell-make-comint
2870 (python-shell-calculate-command) dedicated-proc-name))
2871 (global-process (get-buffer-process global-shell-buffer))
2872 (dedicated-process (get-buffer-process dedicated-shell-buffer)))
2873 (unwind-protect
2874 (progn
2875 (set-process-query-on-exit-flag global-process nil)
2876 (set-process-query-on-exit-flag dedicated-process nil)
2877 ;; Prefer dedicated if global also exists.
2878 (should (equal (python-shell-get-process) dedicated-process))
2879 (kill-buffer dedicated-shell-buffer)
2880 ;; If there's only global, use it.
2881 (should (equal (python-shell-get-process) global-process))
2882 (kill-buffer global-shell-buffer)
2883 ;; No buffer available.
2884 (should (not (python-shell-get-process))))
2885 (ignore-errors (kill-buffer global-shell-buffer))
2886 (ignore-errors (kill-buffer dedicated-shell-buffer))))))
2888 (ert-deftest python-shell-internal-get-or-create-process-1 ()
2889 "Check internal shell process creation fallback."
2890 (skip-unless (executable-find python-tests-shell-interpreter))
2891 (python-tests-with-temp-file
2893 (should (not (process-live-p (python-shell-internal-get-process-name))))
2894 (let* ((python-shell-interpreter
2895 (executable-find python-tests-shell-interpreter))
2896 (internal-process-name (python-shell-internal-get-process-name))
2897 (internal-process (python-shell-internal-get-or-create-process))
2898 (internal-shell-buffer (process-buffer internal-process)))
2899 (unwind-protect
2900 (progn
2901 (set-process-query-on-exit-flag internal-process nil)
2902 (should (equal (process-name internal-process)
2903 internal-process-name))
2904 (should (equal internal-process
2905 (python-shell-internal-get-or-create-process)))
2906 ;; Assert the internal process is not a user process
2907 (should (not (python-shell-get-process)))
2908 (kill-buffer internal-shell-buffer))
2909 (ignore-errors (kill-buffer internal-shell-buffer))))))
2911 (ert-deftest python-shell-prompt-detect-1 ()
2912 "Check prompt autodetection."
2913 (skip-unless (executable-find python-tests-shell-interpreter))
2914 (let ((process-environment process-environment))
2915 ;; Ensure no startup file is enabled
2916 (setenv "PYTHONSTARTUP" "")
2917 (should python-shell-prompt-detect-enabled)
2918 (should (equal (python-shell-prompt-detect) '(">>> " "... " "")))))
2920 (ert-deftest python-shell-prompt-detect-2 ()
2921 "Check prompt autodetection with startup file. Bug#17370."
2922 (skip-unless (executable-find python-tests-shell-interpreter))
2923 (let* ((process-environment process-environment)
2924 (startup-code (concat "import sys\n"
2925 "sys.ps1 = 'py> '\n"
2926 "sys.ps2 = '..> '\n"
2927 "sys.ps3 = 'out '\n"))
2928 (startup-file (python-shell--save-temp-file startup-code)))
2929 (unwind-protect
2930 (progn
2931 ;; Ensure startup file is enabled
2932 (setenv "PYTHONSTARTUP" startup-file)
2933 (should python-shell-prompt-detect-enabled)
2934 (should (equal (python-shell-prompt-detect) '("py> " "..> " "out "))))
2935 (ignore-errors (delete-file startup-file)))))
2937 (ert-deftest python-shell-prompt-detect-3 ()
2938 "Check prompts are not autodetected when feature is disabled."
2939 (skip-unless (executable-find python-tests-shell-interpreter))
2940 (let ((process-environment process-environment)
2941 (python-shell-prompt-detect-enabled nil))
2942 ;; Ensure no startup file is enabled
2943 (should (not python-shell-prompt-detect-enabled))
2944 (should (not (python-shell-prompt-detect)))))
2946 (ert-deftest python-shell-prompt-detect-4 ()
2947 "Check warning is shown when detection fails."
2948 (skip-unless (executable-find python-tests-shell-interpreter))
2949 (let* ((process-environment process-environment)
2950 ;; Trigger failure by removing prompts in the startup file
2951 (startup-code (concat "import sys\n"
2952 "sys.ps1 = ''\n"
2953 "sys.ps2 = ''\n"
2954 "sys.ps3 = ''\n"))
2955 (startup-file (python-shell--save-temp-file startup-code)))
2956 (unwind-protect
2957 (progn
2958 (kill-buffer (get-buffer-create "*Warnings*"))
2959 (should (not (get-buffer "*Warnings*")))
2960 (setenv "PYTHONSTARTUP" startup-file)
2961 (should python-shell-prompt-detect-failure-warning)
2962 (should python-shell-prompt-detect-enabled)
2963 (should (not (python-shell-prompt-detect)))
2964 (should (get-buffer "*Warnings*")))
2965 (ignore-errors (delete-file startup-file)))))
2967 (ert-deftest python-shell-prompt-detect-5 ()
2968 "Check disabled warnings are not shown when detection fails."
2969 (skip-unless (executable-find python-tests-shell-interpreter))
2970 (let* ((process-environment process-environment)
2971 (startup-code (concat "import sys\n"
2972 "sys.ps1 = ''\n"
2973 "sys.ps2 = ''\n"
2974 "sys.ps3 = ''\n"))
2975 (startup-file (python-shell--save-temp-file startup-code))
2976 (python-shell-prompt-detect-failure-warning nil))
2977 (unwind-protect
2978 (progn
2979 (kill-buffer (get-buffer-create "*Warnings*"))
2980 (should (not (get-buffer "*Warnings*")))
2981 (setenv "PYTHONSTARTUP" startup-file)
2982 (should (not python-shell-prompt-detect-failure-warning))
2983 (should python-shell-prompt-detect-enabled)
2984 (should (not (python-shell-prompt-detect)))
2985 (should (not (get-buffer "*Warnings*"))))
2986 (ignore-errors (delete-file startup-file)))))
2988 (ert-deftest python-shell-prompt-detect-6 ()
2989 "Warnings are not shown when detection is disabled."
2990 (skip-unless (executable-find python-tests-shell-interpreter))
2991 (let* ((process-environment process-environment)
2992 (startup-code (concat "import sys\n"
2993 "sys.ps1 = ''\n"
2994 "sys.ps2 = ''\n"
2995 "sys.ps3 = ''\n"))
2996 (startup-file (python-shell--save-temp-file startup-code))
2997 (python-shell-prompt-detect-failure-warning t)
2998 (python-shell-prompt-detect-enabled nil))
2999 (unwind-protect
3000 (progn
3001 (kill-buffer (get-buffer-create "*Warnings*"))
3002 (should (not (get-buffer "*Warnings*")))
3003 (setenv "PYTHONSTARTUP" startup-file)
3004 (should python-shell-prompt-detect-failure-warning)
3005 (should (not python-shell-prompt-detect-enabled))
3006 (should (not (python-shell-prompt-detect)))
3007 (should (not (get-buffer "*Warnings*"))))
3008 (ignore-errors (delete-file startup-file)))))
3010 (ert-deftest python-shell-prompt-validate-regexps-1 ()
3011 "Check `python-shell-prompt-input-regexps' are validated."
3012 (let* ((python-shell-prompt-input-regexps '("\\("))
3013 (error-data (should-error (python-shell-prompt-validate-regexps)
3014 :type 'user-error)))
3015 (should
3016 (string= (cadr error-data)
3017 (format-message
3018 "Invalid regexp \\( in `python-shell-prompt-input-regexps'")))))
3020 (ert-deftest python-shell-prompt-validate-regexps-2 ()
3021 "Check `python-shell-prompt-output-regexps' are validated."
3022 (let* ((python-shell-prompt-output-regexps '("\\("))
3023 (error-data (should-error (python-shell-prompt-validate-regexps)
3024 :type 'user-error)))
3025 (should
3026 (string= (cadr error-data)
3027 (format-message
3028 "Invalid regexp \\( in `python-shell-prompt-output-regexps'")))))
3030 (ert-deftest python-shell-prompt-validate-regexps-3 ()
3031 "Check `python-shell-prompt-regexp' is validated."
3032 (let* ((python-shell-prompt-regexp "\\(")
3033 (error-data (should-error (python-shell-prompt-validate-regexps)
3034 :type 'user-error)))
3035 (should
3036 (string= (cadr error-data)
3037 (format-message
3038 "Invalid regexp \\( in `python-shell-prompt-regexp'")))))
3040 (ert-deftest python-shell-prompt-validate-regexps-4 ()
3041 "Check `python-shell-prompt-block-regexp' is validated."
3042 (let* ((python-shell-prompt-block-regexp "\\(")
3043 (error-data (should-error (python-shell-prompt-validate-regexps)
3044 :type 'user-error)))
3045 (should
3046 (string= (cadr error-data)
3047 (format-message
3048 "Invalid regexp \\( in `python-shell-prompt-block-regexp'")))))
3050 (ert-deftest python-shell-prompt-validate-regexps-5 ()
3051 "Check `python-shell-prompt-pdb-regexp' is validated."
3052 (let* ((python-shell-prompt-pdb-regexp "\\(")
3053 (error-data (should-error (python-shell-prompt-validate-regexps)
3054 :type 'user-error)))
3055 (should
3056 (string= (cadr error-data)
3057 (format-message
3058 "Invalid regexp \\( in `python-shell-prompt-pdb-regexp'")))))
3060 (ert-deftest python-shell-prompt-validate-regexps-6 ()
3061 "Check `python-shell-prompt-output-regexp' is validated."
3062 (let* ((python-shell-prompt-output-regexp "\\(")
3063 (error-data (should-error (python-shell-prompt-validate-regexps)
3064 :type 'user-error)))
3065 (should
3066 (string= (cadr error-data)
3067 (format-message
3068 "Invalid regexp \\( in `python-shell-prompt-output-regexp'")))))
3070 (ert-deftest python-shell-prompt-validate-regexps-7 ()
3071 "Check default regexps are valid."
3072 ;; should not signal error
3073 (python-shell-prompt-validate-regexps))
3075 (ert-deftest python-shell-prompt-set-calculated-regexps-1 ()
3076 "Check regexps are validated."
3077 (let* ((python-shell-prompt-output-regexp '("\\("))
3078 (python-shell--prompt-calculated-input-regexp nil)
3079 (python-shell--prompt-calculated-output-regexp nil)
3080 (python-shell-prompt-detect-enabled nil)
3081 (error-data (should-error (python-shell-prompt-set-calculated-regexps)
3082 :type 'user-error)))
3083 (should
3084 (string= (cadr error-data)
3085 (format-message
3086 "Invalid regexp \\( in `python-shell-prompt-output-regexp'")))))
3088 (ert-deftest python-shell-prompt-set-calculated-regexps-2 ()
3089 "Check `python-shell-prompt-input-regexps' are set."
3090 (let* ((python-shell-prompt-input-regexps '("my" "prompt"))
3091 (python-shell-prompt-output-regexps '(""))
3092 (python-shell-prompt-regexp "")
3093 (python-shell-prompt-block-regexp "")
3094 (python-shell-prompt-pdb-regexp "")
3095 (python-shell-prompt-output-regexp "")
3096 (python-shell--prompt-calculated-input-regexp nil)
3097 (python-shell--prompt-calculated-output-regexp nil)
3098 (python-shell-prompt-detect-enabled nil))
3099 (python-shell-prompt-set-calculated-regexps)
3100 (should (string= python-shell--prompt-calculated-input-regexp
3101 "^\\(prompt\\|my\\|\\)"))))
3103 (ert-deftest python-shell-prompt-set-calculated-regexps-3 ()
3104 "Check `python-shell-prompt-output-regexps' are set."
3105 (let* ((python-shell-prompt-input-regexps '(""))
3106 (python-shell-prompt-output-regexps '("my" "prompt"))
3107 (python-shell-prompt-regexp "")
3108 (python-shell-prompt-block-regexp "")
3109 (python-shell-prompt-pdb-regexp "")
3110 (python-shell-prompt-output-regexp "")
3111 (python-shell--prompt-calculated-input-regexp nil)
3112 (python-shell--prompt-calculated-output-regexp nil)
3113 (python-shell-prompt-detect-enabled nil))
3114 (python-shell-prompt-set-calculated-regexps)
3115 (should (string= python-shell--prompt-calculated-output-regexp
3116 "^\\(prompt\\|my\\|\\)"))))
3118 (ert-deftest python-shell-prompt-set-calculated-regexps-4 ()
3119 "Check user defined prompts are set."
3120 (let* ((python-shell-prompt-input-regexps '(""))
3121 (python-shell-prompt-output-regexps '(""))
3122 (python-shell-prompt-regexp "prompt")
3123 (python-shell-prompt-block-regexp "block")
3124 (python-shell-prompt-pdb-regexp "pdb")
3125 (python-shell-prompt-output-regexp "output")
3126 (python-shell--prompt-calculated-input-regexp nil)
3127 (python-shell--prompt-calculated-output-regexp nil)
3128 (python-shell-prompt-detect-enabled nil))
3129 (python-shell-prompt-set-calculated-regexps)
3130 (should (string= python-shell--prompt-calculated-input-regexp
3131 "^\\(prompt\\|block\\|pdb\\|\\)"))
3132 (should (string= python-shell--prompt-calculated-output-regexp
3133 "^\\(output\\|\\)"))))
3135 (ert-deftest python-shell-prompt-set-calculated-regexps-5 ()
3136 "Check order of regexps (larger first)."
3137 (let* ((python-shell-prompt-input-regexps '("extralargeinputprompt" "sml"))
3138 (python-shell-prompt-output-regexps '("extralargeoutputprompt" "sml"))
3139 (python-shell-prompt-regexp "in")
3140 (python-shell-prompt-block-regexp "block")
3141 (python-shell-prompt-pdb-regexp "pdf")
3142 (python-shell-prompt-output-regexp "output")
3143 (python-shell--prompt-calculated-input-regexp nil)
3144 (python-shell--prompt-calculated-output-regexp nil)
3145 (python-shell-prompt-detect-enabled nil))
3146 (python-shell-prompt-set-calculated-regexps)
3147 (should (string= python-shell--prompt-calculated-input-regexp
3148 "^\\(extralargeinputprompt\\|block\\|pdf\\|sml\\|in\\)"))
3149 (should (string= python-shell--prompt-calculated-output-regexp
3150 "^\\(extralargeoutputprompt\\|output\\|sml\\)"))))
3152 (ert-deftest python-shell-prompt-set-calculated-regexps-6 ()
3153 "Check detected prompts are included `regexp-quote'd."
3154 (skip-unless (executable-find python-tests-shell-interpreter))
3155 (let* ((python-shell-prompt-input-regexps '(""))
3156 (python-shell-prompt-output-regexps '(""))
3157 (python-shell-prompt-regexp "")
3158 (python-shell-prompt-block-regexp "")
3159 (python-shell-prompt-pdb-regexp "")
3160 (python-shell-prompt-output-regexp "")
3161 (python-shell--prompt-calculated-input-regexp nil)
3162 (python-shell--prompt-calculated-output-regexp nil)
3163 (python-shell-prompt-detect-enabled t)
3164 (process-environment process-environment)
3165 (startup-code (concat "import sys\n"
3166 "sys.ps1 = 'p.> '\n"
3167 "sys.ps2 = '..> '\n"
3168 "sys.ps3 = 'o.t '\n"))
3169 (startup-file (python-shell--save-temp-file startup-code)))
3170 (unwind-protect
3171 (progn
3172 (setenv "PYTHONSTARTUP" startup-file)
3173 (python-shell-prompt-set-calculated-regexps)
3174 (should (string= python-shell--prompt-calculated-input-regexp
3175 "^\\(\\.\\.> \\|p\\.> \\|\\)"))
3176 (should (string= python-shell--prompt-calculated-output-regexp
3177 "^\\(o\\.t \\|\\)")))
3178 (ignore-errors (delete-file startup-file)))))
3180 (ert-deftest python-shell-buffer-substring-1 ()
3181 "Selecting a substring of the whole buffer must match its contents."
3182 (python-tests-with-temp-buffer
3184 class Foo(models.Model):
3185 pass
3188 class Bar(models.Model):
3189 pass
3191 (should (string= (buffer-string)
3192 (python-shell-buffer-substring (point-min) (point-max))))))
3194 (ert-deftest python-shell-buffer-substring-2 ()
3195 "Main block should be removed if NOMAIN is non-nil."
3196 (python-tests-with-temp-buffer
3198 class Foo(models.Model):
3199 pass
3201 class Bar(models.Model):
3202 pass
3204 if __name__ == \"__main__\":
3205 foo = Foo()
3206 print (foo)
3208 (should (string= (python-shell-buffer-substring (point-min) (point-max) t)
3210 class Foo(models.Model):
3211 pass
3213 class Bar(models.Model):
3214 pass
3219 "))))
3221 (ert-deftest python-shell-buffer-substring-3 ()
3222 "Main block should be removed if NOMAIN is non-nil."
3223 (python-tests-with-temp-buffer
3225 class Foo(models.Model):
3226 pass
3228 if __name__ == \"__main__\":
3229 foo = Foo()
3230 print (foo)
3232 class Bar(models.Model):
3233 pass
3235 (should (string= (python-shell-buffer-substring (point-min) (point-max) t)
3237 class Foo(models.Model):
3238 pass
3244 class Bar(models.Model):
3245 pass
3246 "))))
3248 (ert-deftest python-shell-buffer-substring-4 ()
3249 "Coding cookie should be added for substrings."
3250 (python-tests-with-temp-buffer
3251 "# coding: latin-1
3253 class Foo(models.Model):
3254 pass
3256 if __name__ == \"__main__\":
3257 foo = Foo()
3258 print (foo)
3260 class Bar(models.Model):
3261 pass
3263 (should (string= (python-shell-buffer-substring
3264 (python-tests-look-at "class Foo(models.Model):")
3265 (progn (python-nav-forward-sexp) (point)))
3266 "# -*- coding: latin-1 -*-
3268 class Foo(models.Model):
3269 pass"))))
3271 (ert-deftest python-shell-buffer-substring-5 ()
3272 "The proper amount of blank lines is added for a substring."
3273 (python-tests-with-temp-buffer
3274 "# coding: latin-1
3276 class Foo(models.Model):
3277 pass
3279 if __name__ == \"__main__\":
3280 foo = Foo()
3281 print (foo)
3283 class Bar(models.Model):
3284 pass
3286 (should (string= (python-shell-buffer-substring
3287 (python-tests-look-at "class Bar(models.Model):")
3288 (progn (python-nav-forward-sexp) (point)))
3289 "# -*- coding: latin-1 -*-
3298 class Bar(models.Model):
3299 pass"))))
3301 (ert-deftest python-shell-buffer-substring-6 ()
3302 "Handle substring with coding cookie in the second line."
3303 (python-tests-with-temp-buffer
3305 # coding: latin-1
3307 class Foo(models.Model):
3308 pass
3310 if __name__ == \"__main__\":
3311 foo = Foo()
3312 print (foo)
3314 class Bar(models.Model):
3315 pass
3317 (should (string= (python-shell-buffer-substring
3318 (python-tests-look-at "# coding: latin-1")
3319 (python-tests-look-at "if __name__ == \"__main__\":"))
3320 "# -*- coding: latin-1 -*-
3323 class Foo(models.Model):
3324 pass
3326 "))))
3328 (ert-deftest python-shell-buffer-substring-7 ()
3329 "Ensure first coding cookie gets precedence."
3330 (python-tests-with-temp-buffer
3331 "# coding: utf-8
3332 # coding: latin-1
3334 class Foo(models.Model):
3335 pass
3337 if __name__ == \"__main__\":
3338 foo = Foo()
3339 print (foo)
3341 class Bar(models.Model):
3342 pass
3344 (should (string= (python-shell-buffer-substring
3345 (python-tests-look-at "# coding: latin-1")
3346 (python-tests-look-at "if __name__ == \"__main__\":"))
3347 "# -*- coding: utf-8 -*-
3350 class Foo(models.Model):
3351 pass
3353 "))))
3355 (ert-deftest python-shell-buffer-substring-8 ()
3356 "Ensure first coding cookie gets precedence when sending whole buffer."
3357 (python-tests-with-temp-buffer
3358 "# coding: utf-8
3359 # coding: latin-1
3361 class Foo(models.Model):
3362 pass
3364 (should (string= (python-shell-buffer-substring (point-min) (point-max))
3365 "# coding: utf-8
3368 class Foo(models.Model):
3369 pass
3370 "))))
3372 (ert-deftest python-shell-buffer-substring-9 ()
3373 "Check substring starting from `point-min'."
3374 (python-tests-with-temp-buffer
3375 "# coding: utf-8
3377 class Foo(models.Model):
3378 pass
3380 class Bar(models.Model):
3381 pass
3383 (should (string= (python-shell-buffer-substring
3384 (point-min)
3385 (python-tests-look-at "class Bar(models.Model):"))
3386 "# coding: utf-8
3388 class Foo(models.Model):
3389 pass
3391 "))))
3393 (ert-deftest python-shell-buffer-substring-10 ()
3394 "Check substring from partial block."
3395 (python-tests-with-temp-buffer
3397 def foo():
3398 print ('a')
3400 (should (string= (python-shell-buffer-substring
3401 (python-tests-look-at "print ('a')")
3402 (point-max))
3403 "if True:
3405 print ('a')
3406 "))))
3408 (ert-deftest python-shell-buffer-substring-11 ()
3409 "Check substring from partial block and point within indentation."
3410 (python-tests-with-temp-buffer
3412 def foo():
3413 print ('a')
3415 (should (string= (python-shell-buffer-substring
3416 (progn
3417 (python-tests-look-at "print ('a')")
3418 (backward-char 1)
3419 (point))
3420 (point-max))
3421 "if True:
3423 print ('a')
3424 "))))
3426 (ert-deftest python-shell-buffer-substring-12 ()
3427 "Check substring from partial block and point in whitespace."
3428 (python-tests-with-temp-buffer
3430 def foo():
3432 # Whitespace
3434 print ('a')
3436 (should (string= (python-shell-buffer-substring
3437 (python-tests-look-at "# Whitespace")
3438 (point-max))
3439 "if True:
3442 # Whitespace
3444 print ('a')
3445 "))))
3449 ;;; Shell completion
3451 (ert-deftest python-shell-completion-native-interpreter-disabled-p-1 ()
3452 (let* ((python-shell-completion-native-disabled-interpreters (list "pypy"))
3453 (python-shell-interpreter "/some/path/to/bin/pypy"))
3454 (should (python-shell-completion-native-interpreter-disabled-p))))
3459 ;;; PDB Track integration
3462 ;;; Symbol completion
3465 ;;; Fill paragraph
3468 ;;; Skeletons
3471 ;;; FFAP
3474 ;;; Code check
3477 ;;; Eldoc
3479 (ert-deftest python-eldoc--get-symbol-at-point-1 ()
3480 "Test paren handling."
3481 (python-tests-with-temp-buffer
3483 map(xx
3484 map(codecs.open('somefile'
3486 (python-tests-look-at "ap(xx")
3487 (should (string= (python-eldoc--get-symbol-at-point) "map"))
3488 (goto-char (line-end-position))
3489 (should (string= (python-eldoc--get-symbol-at-point) "map"))
3490 (python-tests-look-at "('somefile'")
3491 (should (string= (python-eldoc--get-symbol-at-point) "map"))
3492 (goto-char (line-end-position))
3493 (should (string= (python-eldoc--get-symbol-at-point) "codecs.open"))))
3495 (ert-deftest python-eldoc--get-symbol-at-point-2 ()
3496 "Ensure self is replaced with the class name."
3497 (python-tests-with-temp-buffer
3499 class TheClass:
3501 def some_method(self, n):
3502 return n
3504 def other(self):
3505 return self.some_method(1234)
3508 (python-tests-look-at "self.some_method")
3509 (should (string= (python-eldoc--get-symbol-at-point)
3510 "TheClass.some_method"))
3511 (python-tests-look-at "1234)")
3512 (should (string= (python-eldoc--get-symbol-at-point)
3513 "TheClass.some_method"))))
3515 (ert-deftest python-eldoc--get-symbol-at-point-3 ()
3516 "Ensure symbol is found when point is at end of buffer."
3517 (python-tests-with-temp-buffer
3519 some_symbol
3522 (goto-char (point-max))
3523 (should (string= (python-eldoc--get-symbol-at-point)
3524 "some_symbol"))))
3526 (ert-deftest python-eldoc--get-symbol-at-point-4 ()
3527 "Ensure symbol is found when point is at whitespace."
3528 (python-tests-with-temp-buffer
3530 some_symbol some_other_symbol
3532 (python-tests-look-at " some_other_symbol")
3533 (should (string= (python-eldoc--get-symbol-at-point)
3534 "some_symbol"))))
3537 ;;; Imenu
3539 (ert-deftest python-imenu-create-index-1 ()
3540 (python-tests-with-temp-buffer
3542 class Foo(models.Model):
3543 pass
3546 class Bar(models.Model):
3547 pass
3550 def decorator(arg1, arg2, arg3):
3551 '''print decorated function call data to stdout.
3553 Usage:
3555 @decorator('arg1', 'arg2')
3556 def func(a, b, c=True):
3557 pass
3560 def wrap(f):
3561 print ('wrap')
3562 def wrapped_f(*args):
3563 print ('wrapped_f')
3564 print ('Decorator arguments:', arg1, arg2, arg3)
3565 f(*args)
3566 print ('called f(*args)')
3567 return wrapped_f
3568 return wrap
3571 class Baz(object):
3573 def a(self):
3574 pass
3576 def b(self):
3577 pass
3579 class Frob(object):
3581 def c(self):
3582 pass
3584 async def d(self):
3585 pass
3587 (goto-char (point-max))
3588 (should (equal
3589 (list
3590 (cons "Foo (class)" (copy-marker 2))
3591 (cons "Bar (class)" (copy-marker 38))
3592 (list
3593 "decorator (def)"
3594 (cons "*function definition*" (copy-marker 74))
3595 (list
3596 "wrap (def)"
3597 (cons "*function definition*" (copy-marker 254))
3598 (cons "wrapped_f (def)" (copy-marker 294))))
3599 (list
3600 "Baz (class)"
3601 (cons "*class definition*" (copy-marker 519))
3602 (cons "a (def)" (copy-marker 539))
3603 (cons "b (def)" (copy-marker 570))
3604 (list
3605 "Frob (class)"
3606 (cons "*class definition*" (copy-marker 601))
3607 (cons "c (def)" (copy-marker 626))
3608 (cons "d (async def)" (copy-marker 665)))))
3609 (python-imenu-create-index)))))
3611 (ert-deftest python-imenu-create-index-2 ()
3612 (python-tests-with-temp-buffer
3614 class Foo(object):
3615 def foo(self):
3616 def foo1():
3617 pass
3619 def foobar(self):
3620 pass
3622 (goto-char (point-max))
3623 (should (equal
3624 (list
3625 (list
3626 "Foo (class)"
3627 (cons "*class definition*" (copy-marker 2))
3628 (list
3629 "foo (def)"
3630 (cons "*function definition*" (copy-marker 21))
3631 (cons "foo1 (def)" (copy-marker 40)))
3632 (cons "foobar (def)" (copy-marker 78))))
3633 (python-imenu-create-index)))))
3635 (ert-deftest python-imenu-create-index-3 ()
3636 (python-tests-with-temp-buffer
3638 class Foo(object):
3639 def foo(self):
3640 def foo1():
3641 pass
3642 def foo2():
3643 pass
3645 (goto-char (point-max))
3646 (should (equal
3647 (list
3648 (list
3649 "Foo (class)"
3650 (cons "*class definition*" (copy-marker 2))
3651 (list
3652 "foo (def)"
3653 (cons "*function definition*" (copy-marker 21))
3654 (cons "foo1 (def)" (copy-marker 40))
3655 (cons "foo2 (def)" (copy-marker 77)))))
3656 (python-imenu-create-index)))))
3658 (ert-deftest python-imenu-create-index-4 ()
3659 (python-tests-with-temp-buffer
3661 class Foo(object):
3662 class Bar(object):
3663 def __init__(self):
3664 pass
3666 def __str__(self):
3667 pass
3669 def __init__(self):
3670 pass
3672 (goto-char (point-max))
3673 (should (equal
3674 (list
3675 (list
3676 "Foo (class)"
3677 (cons "*class definition*" (copy-marker 2))
3678 (list
3679 "Bar (class)"
3680 (cons "*class definition*" (copy-marker 21))
3681 (cons "__init__ (def)" (copy-marker 44))
3682 (cons "__str__ (def)" (copy-marker 90)))
3683 (cons "__init__ (def)" (copy-marker 135))))
3684 (python-imenu-create-index)))))
3686 (ert-deftest python-imenu-create-flat-index-1 ()
3687 (python-tests-with-temp-buffer
3689 class Foo(models.Model):
3690 pass
3693 class Bar(models.Model):
3694 pass
3697 def decorator(arg1, arg2, arg3):
3698 '''print decorated function call data to stdout.
3700 Usage:
3702 @decorator('arg1', 'arg2')
3703 def func(a, b, c=True):
3704 pass
3707 def wrap(f):
3708 print ('wrap')
3709 def wrapped_f(*args):
3710 print ('wrapped_f')
3711 print ('Decorator arguments:', arg1, arg2, arg3)
3712 f(*args)
3713 print ('called f(*args)')
3714 return wrapped_f
3715 return wrap
3718 class Baz(object):
3720 def a(self):
3721 pass
3723 def b(self):
3724 pass
3726 class Frob(object):
3728 def c(self):
3729 pass
3731 async def d(self):
3732 pass
3734 (goto-char (point-max))
3735 (should (equal
3736 (list (cons "Foo" (copy-marker 2))
3737 (cons "Bar" (copy-marker 38))
3738 (cons "decorator" (copy-marker 74))
3739 (cons "decorator.wrap" (copy-marker 254))
3740 (cons "decorator.wrap.wrapped_f" (copy-marker 294))
3741 (cons "Baz" (copy-marker 519))
3742 (cons "Baz.a" (copy-marker 539))
3743 (cons "Baz.b" (copy-marker 570))
3744 (cons "Baz.Frob" (copy-marker 601))
3745 (cons "Baz.Frob.c" (copy-marker 626))
3746 (cons "Baz.Frob.d" (copy-marker 665)))
3747 (python-imenu-create-flat-index)))))
3749 (ert-deftest python-imenu-create-flat-index-2 ()
3750 (python-tests-with-temp-buffer
3752 class Foo(object):
3753 class Bar(object):
3754 def __init__(self):
3755 pass
3757 def __str__(self):
3758 pass
3760 def __init__(self):
3761 pass
3763 (goto-char (point-max))
3764 (should (equal
3765 (list
3766 (cons "Foo" (copy-marker 2))
3767 (cons "Foo.Bar" (copy-marker 21))
3768 (cons "Foo.Bar.__init__" (copy-marker 44))
3769 (cons "Foo.Bar.__str__" (copy-marker 90))
3770 (cons "Foo.__init__" (copy-marker 135)))
3771 (python-imenu-create-flat-index)))))
3774 ;;; Misc helpers
3776 (ert-deftest python-info-current-defun-1 ()
3777 (python-tests-with-temp-buffer
3779 def foo(a, b):
3781 (forward-line 1)
3782 (should (string= "foo" (python-info-current-defun)))
3783 (should (string= "def foo" (python-info-current-defun t)))
3784 (forward-line 1)
3785 (should (not (python-info-current-defun)))
3786 (indent-for-tab-command)
3787 (should (string= "foo" (python-info-current-defun)))
3788 (should (string= "def foo" (python-info-current-defun t)))))
3790 (ert-deftest python-info-current-defun-2 ()
3791 (python-tests-with-temp-buffer
3793 class C(object):
3795 def m(self):
3796 if True:
3797 return [i for i in range(3)]
3798 else:
3799 return []
3801 def b():
3802 do_b()
3804 def a():
3805 do_a()
3807 def c(self):
3808 do_c()
3810 (forward-line 1)
3811 (should (string= "C" (python-info-current-defun)))
3812 (should (string= "class C" (python-info-current-defun t)))
3813 (python-tests-look-at "return [i for ")
3814 (should (string= "C.m" (python-info-current-defun)))
3815 (should (string= "def C.m" (python-info-current-defun t)))
3816 (python-tests-look-at "def b():")
3817 (should (string= "C.m.b" (python-info-current-defun)))
3818 (should (string= "def C.m.b" (python-info-current-defun t)))
3819 (forward-line 2)
3820 (indent-for-tab-command)
3821 (python-indent-dedent-line-backspace 1)
3822 (should (string= "C.m" (python-info-current-defun)))
3823 (should (string= "def C.m" (python-info-current-defun t)))
3824 (python-tests-look-at "def c(self):")
3825 (forward-line -1)
3826 (indent-for-tab-command)
3827 (should (string= "C.m.a" (python-info-current-defun)))
3828 (should (string= "def C.m.a" (python-info-current-defun t)))
3829 (python-indent-dedent-line-backspace 1)
3830 (should (string= "C.m" (python-info-current-defun)))
3831 (should (string= "def C.m" (python-info-current-defun t)))
3832 (python-indent-dedent-line-backspace 1)
3833 (should (string= "C" (python-info-current-defun)))
3834 (should (string= "class C" (python-info-current-defun t)))
3835 (python-tests-look-at "def c(self):")
3836 (should (string= "C.c" (python-info-current-defun)))
3837 (should (string= "def C.c" (python-info-current-defun t)))
3838 (python-tests-look-at "do_c()")
3839 (should (string= "C.c" (python-info-current-defun)))
3840 (should (string= "def C.c" (python-info-current-defun t)))))
3842 (ert-deftest python-info-current-defun-3 ()
3843 (python-tests-with-temp-buffer
3845 def decoratorFunctionWithArguments(arg1, arg2, arg3):
3846 '''print decorated function call data to stdout.
3848 Usage:
3850 @decoratorFunctionWithArguments('arg1', 'arg2')
3851 def func(a, b, c=True):
3852 pass
3855 def wwrap(f):
3856 print 'Inside wwrap()'
3857 def wrapped_f(*args):
3858 print 'Inside wrapped_f()'
3859 print 'Decorator arguments:', arg1, arg2, arg3
3860 f(*args)
3861 print 'After f(*args)'
3862 return wrapped_f
3863 return wwrap
3865 (python-tests-look-at "def wwrap(f):")
3866 (forward-line -1)
3867 (should (not (python-info-current-defun)))
3868 (indent-for-tab-command 1)
3869 (should (string= (python-info-current-defun)
3870 "decoratorFunctionWithArguments"))
3871 (should (string= (python-info-current-defun t)
3872 "def decoratorFunctionWithArguments"))
3873 (python-tests-look-at "def wrapped_f(*args):")
3874 (should (string= (python-info-current-defun)
3875 "decoratorFunctionWithArguments.wwrap.wrapped_f"))
3876 (should (string= (python-info-current-defun t)
3877 "def decoratorFunctionWithArguments.wwrap.wrapped_f"))
3878 (python-tests-look-at "return wrapped_f")
3879 (should (string= (python-info-current-defun)
3880 "decoratorFunctionWithArguments.wwrap"))
3881 (should (string= (python-info-current-defun t)
3882 "def decoratorFunctionWithArguments.wwrap"))
3883 (end-of-line 1)
3884 (python-tests-look-at "return wwrap")
3885 (should (string= (python-info-current-defun)
3886 "decoratorFunctionWithArguments"))
3887 (should (string= (python-info-current-defun t)
3888 "def decoratorFunctionWithArguments"))))
3890 (ert-deftest python-info-current-symbol-1 ()
3891 (python-tests-with-temp-buffer
3893 class C(object):
3895 def m(self):
3896 self.c()
3898 def c(self):
3899 print ('a')
3901 (python-tests-look-at "self.c()")
3902 (should (string= "self.c" (python-info-current-symbol)))
3903 (should (string= "C.c" (python-info-current-symbol t)))))
3905 (ert-deftest python-info-current-symbol-2 ()
3906 (python-tests-with-temp-buffer
3908 class C(object):
3910 class M(object):
3912 def a(self):
3913 self.c()
3915 def c(self):
3916 pass
3918 (python-tests-look-at "self.c()")
3919 (should (string= "self.c" (python-info-current-symbol)))
3920 (should (string= "C.M.c" (python-info-current-symbol t)))))
3922 (ert-deftest python-info-current-symbol-3 ()
3923 "Keywords should not be considered symbols."
3924 :expected-result :failed
3925 (python-tests-with-temp-buffer
3927 class C(object):
3928 pass
3930 ;; FIXME: keywords are not symbols.
3931 (python-tests-look-at "class C")
3932 (should (not (python-info-current-symbol)))
3933 (should (not (python-info-current-symbol t)))
3934 (python-tests-look-at "C(object)")
3935 (should (string= "C" (python-info-current-symbol)))
3936 (should (string= "class C" (python-info-current-symbol t)))))
3938 (ert-deftest python-info-statement-starts-block-p-1 ()
3939 (python-tests-with-temp-buffer
3941 def long_function_name(
3942 var_one, var_two, var_three,
3943 var_four):
3944 print (var_one)
3946 (python-tests-look-at "def long_function_name")
3947 (should (python-info-statement-starts-block-p))
3948 (python-tests-look-at "print (var_one)")
3949 (python-util-forward-comment -1)
3950 (should (python-info-statement-starts-block-p))))
3952 (ert-deftest python-info-statement-starts-block-p-2 ()
3953 (python-tests-with-temp-buffer
3955 if width == 0 and height == 0 and \\\\
3956 color == 'red' and emphasis == 'strong' or \\\\
3957 highlight > 100:
3958 raise ValueError('sorry, you lose')
3960 (python-tests-look-at "if width == 0 and")
3961 (should (python-info-statement-starts-block-p))
3962 (python-tests-look-at "raise ValueError(")
3963 (python-util-forward-comment -1)
3964 (should (python-info-statement-starts-block-p))))
3966 (ert-deftest python-info-statement-ends-block-p-1 ()
3967 (python-tests-with-temp-buffer
3969 def long_function_name(
3970 var_one, var_two, var_three,
3971 var_four):
3972 print (var_one)
3974 (python-tests-look-at "print (var_one)")
3975 (should (python-info-statement-ends-block-p))))
3977 (ert-deftest python-info-statement-ends-block-p-2 ()
3978 (python-tests-with-temp-buffer
3980 if width == 0 and height == 0 and \\\\
3981 color == 'red' and emphasis == 'strong' or \\\\
3982 highlight > 100:
3983 raise ValueError(
3984 'sorry, you lose'
3988 (python-tests-look-at "raise ValueError(")
3989 (should (python-info-statement-ends-block-p))))
3991 (ert-deftest python-info-beginning-of-statement-p-1 ()
3992 (python-tests-with-temp-buffer
3994 def long_function_name(
3995 var_one, var_two, var_three,
3996 var_four):
3997 print (var_one)
3999 (python-tests-look-at "def long_function_name")
4000 (should (python-info-beginning-of-statement-p))
4001 (forward-char 10)
4002 (should (not (python-info-beginning-of-statement-p)))
4003 (python-tests-look-at "print (var_one)")
4004 (should (python-info-beginning-of-statement-p))
4005 (goto-char (line-beginning-position))
4006 (should (not (python-info-beginning-of-statement-p)))))
4008 (ert-deftest python-info-beginning-of-statement-p-2 ()
4009 (python-tests-with-temp-buffer
4011 if width == 0 and height == 0 and \\\\
4012 color == 'red' and emphasis == 'strong' or \\\\
4013 highlight > 100:
4014 raise ValueError(
4015 'sorry, you lose'
4019 (python-tests-look-at "if width == 0 and")
4020 (should (python-info-beginning-of-statement-p))
4021 (forward-char 10)
4022 (should (not (python-info-beginning-of-statement-p)))
4023 (python-tests-look-at "raise ValueError(")
4024 (should (python-info-beginning-of-statement-p))
4025 (goto-char (line-beginning-position))
4026 (should (not (python-info-beginning-of-statement-p)))))
4028 (ert-deftest python-info-end-of-statement-p-1 ()
4029 (python-tests-with-temp-buffer
4031 def long_function_name(
4032 var_one, var_two, var_three,
4033 var_four):
4034 print (var_one)
4036 (python-tests-look-at "def long_function_name")
4037 (should (not (python-info-end-of-statement-p)))
4038 (end-of-line)
4039 (should (not (python-info-end-of-statement-p)))
4040 (python-tests-look-at "print (var_one)")
4041 (python-util-forward-comment -1)
4042 (should (python-info-end-of-statement-p))
4043 (python-tests-look-at "print (var_one)")
4044 (should (not (python-info-end-of-statement-p)))
4045 (end-of-line)
4046 (should (python-info-end-of-statement-p))))
4048 (ert-deftest python-info-end-of-statement-p-2 ()
4049 (python-tests-with-temp-buffer
4051 if width == 0 and height == 0 and \\\\
4052 color == 'red' and emphasis == 'strong' or \\\\
4053 highlight > 100:
4054 raise ValueError(
4055 'sorry, you lose'
4059 (python-tests-look-at "if width == 0 and")
4060 (should (not (python-info-end-of-statement-p)))
4061 (end-of-line)
4062 (should (not (python-info-end-of-statement-p)))
4063 (python-tests-look-at "raise ValueError(")
4064 (python-util-forward-comment -1)
4065 (should (python-info-end-of-statement-p))
4066 (python-tests-look-at "raise ValueError(")
4067 (should (not (python-info-end-of-statement-p)))
4068 (end-of-line)
4069 (should (not (python-info-end-of-statement-p)))
4070 (goto-char (point-max))
4071 (python-util-forward-comment -1)
4072 (should (python-info-end-of-statement-p))))
4074 (ert-deftest python-info-beginning-of-block-p-1 ()
4075 (python-tests-with-temp-buffer
4077 def long_function_name(
4078 var_one, var_two, var_three,
4079 var_four):
4080 print (var_one)
4082 (python-tests-look-at "def long_function_name")
4083 (should (python-info-beginning-of-block-p))
4084 (python-tests-look-at "var_one, var_two, var_three,")
4085 (should (not (python-info-beginning-of-block-p)))
4086 (python-tests-look-at "print (var_one)")
4087 (should (not (python-info-beginning-of-block-p)))))
4089 (ert-deftest python-info-beginning-of-block-p-2 ()
4090 (python-tests-with-temp-buffer
4092 if width == 0 and height == 0 and \\\\
4093 color == 'red' and emphasis == 'strong' or \\\\
4094 highlight > 100:
4095 raise ValueError(
4096 'sorry, you lose'
4100 (python-tests-look-at "if width == 0 and")
4101 (should (python-info-beginning-of-block-p))
4102 (python-tests-look-at "color == 'red' and emphasis")
4103 (should (not (python-info-beginning-of-block-p)))
4104 (python-tests-look-at "raise ValueError(")
4105 (should (not (python-info-beginning-of-block-p)))))
4107 (ert-deftest python-info-end-of-block-p-1 ()
4108 (python-tests-with-temp-buffer
4110 def long_function_name(
4111 var_one, var_two, var_three,
4112 var_four):
4113 print (var_one)
4115 (python-tests-look-at "def long_function_name")
4116 (should (not (python-info-end-of-block-p)))
4117 (python-tests-look-at "var_one, var_two, var_three,")
4118 (should (not (python-info-end-of-block-p)))
4119 (python-tests-look-at "var_four):")
4120 (end-of-line)
4121 (should (not (python-info-end-of-block-p)))
4122 (python-tests-look-at "print (var_one)")
4123 (should (not (python-info-end-of-block-p)))
4124 (end-of-line 1)
4125 (should (python-info-end-of-block-p))))
4127 (ert-deftest python-info-end-of-block-p-2 ()
4128 (python-tests-with-temp-buffer
4130 if width == 0 and height == 0 and \\\\
4131 color == 'red' and emphasis == 'strong' or \\\\
4132 highlight > 100:
4133 raise ValueError(
4134 'sorry, you lose'
4138 (python-tests-look-at "if width == 0 and")
4139 (should (not (python-info-end-of-block-p)))
4140 (python-tests-look-at "color == 'red' and emphasis == 'strong' or")
4141 (should (not (python-info-end-of-block-p)))
4142 (python-tests-look-at "highlight > 100:")
4143 (end-of-line)
4144 (should (not (python-info-end-of-block-p)))
4145 (python-tests-look-at "raise ValueError(")
4146 (should (not (python-info-end-of-block-p)))
4147 (end-of-line 1)
4148 (should (not (python-info-end-of-block-p)))
4149 (goto-char (point-max))
4150 (python-util-forward-comment -1)
4151 (should (python-info-end-of-block-p))))
4153 (ert-deftest python-info-dedenter-opening-block-position-1 ()
4154 (python-tests-with-temp-buffer
4156 if request.user.is_authenticated():
4157 try:
4158 profile = request.user.get_profile()
4159 except Profile.DoesNotExist:
4160 profile = Profile.objects.create(user=request.user)
4161 else:
4162 if profile.stats:
4163 profile.recalculate_stats()
4164 else:
4165 profile.clear_stats()
4166 finally:
4167 profile.views += 1
4168 profile.save()
4170 (python-tests-look-at "try:")
4171 (should (not (python-info-dedenter-opening-block-position)))
4172 (python-tests-look-at "except Profile.DoesNotExist:")
4173 (should (= (python-tests-look-at "try:" -1 t)
4174 (python-info-dedenter-opening-block-position)))
4175 (python-tests-look-at "else:")
4176 (should (= (python-tests-look-at "except Profile.DoesNotExist:" -1 t)
4177 (python-info-dedenter-opening-block-position)))
4178 (python-tests-look-at "if profile.stats:")
4179 (should (not (python-info-dedenter-opening-block-position)))
4180 (python-tests-look-at "else:")
4181 (should (= (python-tests-look-at "if profile.stats:" -1 t)
4182 (python-info-dedenter-opening-block-position)))
4183 (python-tests-look-at "finally:")
4184 (should (= (python-tests-look-at "else:" -2 t)
4185 (python-info-dedenter-opening-block-position)))))
4187 (ert-deftest python-info-dedenter-opening-block-position-2 ()
4188 (python-tests-with-temp-buffer
4190 if request.user.is_authenticated():
4191 profile = Profile.objects.get_or_create(user=request.user)
4192 if profile.stats:
4193 profile.recalculate_stats()
4195 data = {
4196 'else': 'do it'
4198 'else'
4200 (python-tests-look-at "'else': 'do it'")
4201 (should (not (python-info-dedenter-opening-block-position)))
4202 (python-tests-look-at "'else'")
4203 (should (not (python-info-dedenter-opening-block-position)))))
4205 (ert-deftest python-info-dedenter-opening-block-position-3 ()
4206 (python-tests-with-temp-buffer
4208 if save:
4209 try:
4210 write_to_disk(data)
4211 except IOError:
4212 msg = 'Error saving to disk'
4213 message(msg)
4214 logger.exception(msg)
4215 except Exception:
4216 if hide_details:
4217 logger.exception('Unhandled exception')
4218 else
4219 finally:
4220 data.free()
4222 (python-tests-look-at "try:")
4223 (should (not (python-info-dedenter-opening-block-position)))
4225 (python-tests-look-at "except IOError:")
4226 (should (= (python-tests-look-at "try:" -1 t)
4227 (python-info-dedenter-opening-block-position)))
4229 (python-tests-look-at "except Exception:")
4230 (should (= (python-tests-look-at "except IOError:" -1 t)
4231 (python-info-dedenter-opening-block-position)))
4233 (python-tests-look-at "if hide_details:")
4234 (should (not (python-info-dedenter-opening-block-position)))
4236 ;; check indentation modifies the detected opening block
4237 (python-tests-look-at "else")
4238 (should (= (python-tests-look-at "if hide_details:" -1 t)
4239 (python-info-dedenter-opening-block-position)))
4241 (indent-line-to 8)
4242 (should (= (python-tests-look-at "if hide_details:" -1 t)
4243 (python-info-dedenter-opening-block-position)))
4245 (indent-line-to 4)
4246 (should (= (python-tests-look-at "except Exception:" -1 t)
4247 (python-info-dedenter-opening-block-position)))
4249 (indent-line-to 0)
4250 (should (= (python-tests-look-at "if save:" -1 t)
4251 (python-info-dedenter-opening-block-position)))))
4253 (ert-deftest python-info-dedenter-opening-block-positions-1 ()
4254 (python-tests-with-temp-buffer
4256 if save:
4257 try:
4258 write_to_disk(data)
4259 except IOError:
4260 msg = 'Error saving to disk'
4261 message(msg)
4262 logger.exception(msg)
4263 except Exception:
4264 if hide_details:
4265 logger.exception('Unhandled exception')
4266 else
4267 finally:
4268 data.free()
4270 (python-tests-look-at "try:")
4271 (should (not (python-info-dedenter-opening-block-positions)))
4273 (python-tests-look-at "except IOError:")
4274 (should
4275 (equal (list
4276 (python-tests-look-at "try:" -1 t))
4277 (python-info-dedenter-opening-block-positions)))
4279 (python-tests-look-at "except Exception:")
4280 (should
4281 (equal (list
4282 (python-tests-look-at "except IOError:" -1 t))
4283 (python-info-dedenter-opening-block-positions)))
4285 (python-tests-look-at "if hide_details:")
4286 (should (not (python-info-dedenter-opening-block-positions)))
4288 ;; check indentation does not modify the detected opening blocks
4289 (python-tests-look-at "else")
4290 (should
4291 (equal (list
4292 (python-tests-look-at "if hide_details:" -1 t)
4293 (python-tests-look-at "except Exception:" -1 t)
4294 (python-tests-look-at "if save:" -1 t))
4295 (python-info-dedenter-opening-block-positions)))
4297 (indent-line-to 8)
4298 (should
4299 (equal (list
4300 (python-tests-look-at "if hide_details:" -1 t)
4301 (python-tests-look-at "except Exception:" -1 t)
4302 (python-tests-look-at "if save:" -1 t))
4303 (python-info-dedenter-opening-block-positions)))
4305 (indent-line-to 4)
4306 (should
4307 (equal (list
4308 (python-tests-look-at "if hide_details:" -1 t)
4309 (python-tests-look-at "except Exception:" -1 t)
4310 (python-tests-look-at "if save:" -1 t))
4311 (python-info-dedenter-opening-block-positions)))
4313 (indent-line-to 0)
4314 (should
4315 (equal (list
4316 (python-tests-look-at "if hide_details:" -1 t)
4317 (python-tests-look-at "except Exception:" -1 t)
4318 (python-tests-look-at "if save:" -1 t))
4319 (python-info-dedenter-opening-block-positions)))))
4321 (ert-deftest python-info-dedenter-opening-block-positions-2 ()
4322 "Test detection of opening blocks for elif."
4323 (python-tests-with-temp-buffer
4325 if var:
4326 if var2:
4327 something()
4328 elif var3:
4329 something_else()
4330 elif
4332 (python-tests-look-at "elif var3:")
4333 (should
4334 (equal (list
4335 (python-tests-look-at "if var2:" -1 t)
4336 (python-tests-look-at "if var:" -1 t))
4337 (python-info-dedenter-opening-block-positions)))
4339 (python-tests-look-at "elif\n")
4340 (should
4341 (equal (list
4342 (python-tests-look-at "elif var3:" -1 t)
4343 (python-tests-look-at "if var:" -1 t))
4344 (python-info-dedenter-opening-block-positions)))))
4346 (ert-deftest python-info-dedenter-opening-block-positions-3 ()
4347 "Test detection of opening blocks for else."
4348 (python-tests-with-temp-buffer
4350 try:
4351 something()
4352 except:
4353 if var:
4354 if var2:
4355 something()
4356 elif var3:
4357 something_else()
4358 else
4360 if var4:
4361 while var5:
4362 var4.pop()
4363 else
4365 for value in var6:
4366 if value > 0:
4367 print value
4368 else
4370 (python-tests-look-at "else\n")
4371 (should
4372 (equal (list
4373 (python-tests-look-at "elif var3:" -1 t)
4374 (python-tests-look-at "if var:" -1 t)
4375 (python-tests-look-at "except:" -1 t))
4376 (python-info-dedenter-opening-block-positions)))
4378 (python-tests-look-at "else\n")
4379 (should
4380 (equal (list
4381 (python-tests-look-at "while var5:" -1 t)
4382 (python-tests-look-at "if var4:" -1 t))
4383 (python-info-dedenter-opening-block-positions)))
4385 (python-tests-look-at "else\n")
4386 (should
4387 (equal (list
4388 (python-tests-look-at "if value > 0:" -1 t)
4389 (python-tests-look-at "for value in var6:" -1 t)
4390 (python-tests-look-at "if var4:" -1 t))
4391 (python-info-dedenter-opening-block-positions)))))
4393 (ert-deftest python-info-dedenter-opening-block-positions-4 ()
4394 "Test detection of opening blocks for except."
4395 (python-tests-with-temp-buffer
4397 try:
4398 something()
4399 except ValueError:
4400 something_else()
4401 except
4403 (python-tests-look-at "except ValueError:")
4404 (should
4405 (equal (list (python-tests-look-at "try:" -1 t))
4406 (python-info-dedenter-opening-block-positions)))
4408 (python-tests-look-at "except\n")
4409 (should
4410 (equal (list (python-tests-look-at "except ValueError:" -1 t))
4411 (python-info-dedenter-opening-block-positions)))))
4413 (ert-deftest python-info-dedenter-opening-block-positions-5 ()
4414 "Test detection of opening blocks for finally."
4415 (python-tests-with-temp-buffer
4417 try:
4418 something()
4419 finally
4421 try:
4422 something_else()
4423 except:
4424 logger.exception('something went wrong')
4425 finally
4427 try:
4428 something_else_else()
4429 except Exception:
4430 logger.exception('something else went wrong')
4431 else:
4432 print ('all good')
4433 finally
4435 (python-tests-look-at "finally\n")
4436 (should
4437 (equal (list (python-tests-look-at "try:" -1 t))
4438 (python-info-dedenter-opening-block-positions)))
4440 (python-tests-look-at "finally\n")
4441 (should
4442 (equal (list (python-tests-look-at "except:" -1 t))
4443 (python-info-dedenter-opening-block-positions)))
4445 (python-tests-look-at "finally\n")
4446 (should
4447 (equal (list (python-tests-look-at "else:" -1 t))
4448 (python-info-dedenter-opening-block-positions)))))
4450 (ert-deftest python-info-dedenter-opening-block-message-1 ()
4451 "Test dedenters inside strings are ignored."
4452 (python-tests-with-temp-buffer
4453 "'''
4454 try:
4455 something()
4456 except:
4457 logger.exception('something went wrong')
4460 (python-tests-look-at "except\n")
4461 (should (not (python-info-dedenter-opening-block-message)))))
4463 (ert-deftest python-info-dedenter-opening-block-message-2 ()
4464 "Test except keyword."
4465 (python-tests-with-temp-buffer
4467 try:
4468 something()
4469 except:
4470 logger.exception('something went wrong')
4472 (python-tests-look-at "except:")
4473 (should (string=
4474 "Closes try:"
4475 (substring-no-properties
4476 (python-info-dedenter-opening-block-message))))
4477 (end-of-line)
4478 (should (string=
4479 "Closes try:"
4480 (substring-no-properties
4481 (python-info-dedenter-opening-block-message))))))
4483 (ert-deftest python-info-dedenter-opening-block-message-3 ()
4484 "Test else keyword."
4485 (python-tests-with-temp-buffer
4487 try:
4488 something()
4489 except:
4490 logger.exception('something went wrong')
4491 else:
4492 logger.debug('all good')
4494 (python-tests-look-at "else:")
4495 (should (string=
4496 "Closes except:"
4497 (substring-no-properties
4498 (python-info-dedenter-opening-block-message))))
4499 (end-of-line)
4500 (should (string=
4501 "Closes except:"
4502 (substring-no-properties
4503 (python-info-dedenter-opening-block-message))))))
4505 (ert-deftest python-info-dedenter-opening-block-message-4 ()
4506 "Test finally keyword."
4507 (python-tests-with-temp-buffer
4509 try:
4510 something()
4511 except:
4512 logger.exception('something went wrong')
4513 else:
4514 logger.debug('all good')
4515 finally:
4516 clean()
4518 (python-tests-look-at "finally:")
4519 (should (string=
4520 "Closes else:"
4521 (substring-no-properties
4522 (python-info-dedenter-opening-block-message))))
4523 (end-of-line)
4524 (should (string=
4525 "Closes else:"
4526 (substring-no-properties
4527 (python-info-dedenter-opening-block-message))))))
4529 (ert-deftest python-info-dedenter-opening-block-message-5 ()
4530 "Test elif keyword."
4531 (python-tests-with-temp-buffer
4533 if a:
4534 something()
4535 elif b:
4537 (python-tests-look-at "elif b:")
4538 (should (string=
4539 "Closes if a:"
4540 (substring-no-properties
4541 (python-info-dedenter-opening-block-message))))
4542 (end-of-line)
4543 (should (string=
4544 "Closes if a:"
4545 (substring-no-properties
4546 (python-info-dedenter-opening-block-message))))))
4549 (ert-deftest python-info-dedenter-statement-p-1 ()
4550 "Test dedenters inside strings are ignored."
4551 (python-tests-with-temp-buffer
4552 "'''
4553 try:
4554 something()
4555 except:
4556 logger.exception('something went wrong')
4559 (python-tests-look-at "except\n")
4560 (should (not (python-info-dedenter-statement-p)))))
4562 (ert-deftest python-info-dedenter-statement-p-2 ()
4563 "Test except keyword."
4564 (python-tests-with-temp-buffer
4566 try:
4567 something()
4568 except:
4569 logger.exception('something went wrong')
4571 (python-tests-look-at "except:")
4572 (should (= (point) (python-info-dedenter-statement-p)))
4573 (end-of-line)
4574 (should (= (save-excursion
4575 (back-to-indentation)
4576 (point))
4577 (python-info-dedenter-statement-p)))))
4579 (ert-deftest python-info-dedenter-statement-p-3 ()
4580 "Test else keyword."
4581 (python-tests-with-temp-buffer
4583 try:
4584 something()
4585 except:
4586 logger.exception('something went wrong')
4587 else:
4588 logger.debug('all good')
4590 (python-tests-look-at "else:")
4591 (should (= (point) (python-info-dedenter-statement-p)))
4592 (end-of-line)
4593 (should (= (save-excursion
4594 (back-to-indentation)
4595 (point))
4596 (python-info-dedenter-statement-p)))))
4598 (ert-deftest python-info-dedenter-statement-p-4 ()
4599 "Test finally keyword."
4600 (python-tests-with-temp-buffer
4602 try:
4603 something()
4604 except:
4605 logger.exception('something went wrong')
4606 else:
4607 logger.debug('all good')
4608 finally:
4609 clean()
4611 (python-tests-look-at "finally:")
4612 (should (= (point) (python-info-dedenter-statement-p)))
4613 (end-of-line)
4614 (should (= (save-excursion
4615 (back-to-indentation)
4616 (point))
4617 (python-info-dedenter-statement-p)))))
4619 (ert-deftest python-info-dedenter-statement-p-5 ()
4620 "Test elif keyword."
4621 (python-tests-with-temp-buffer
4623 if a:
4624 something()
4625 elif b:
4627 (python-tests-look-at "elif b:")
4628 (should (= (point) (python-info-dedenter-statement-p)))
4629 (end-of-line)
4630 (should (= (save-excursion
4631 (back-to-indentation)
4632 (point))
4633 (python-info-dedenter-statement-p)))))
4635 (ert-deftest python-info-line-ends-backslash-p-1 ()
4636 (python-tests-with-temp-buffer
4638 objects = Thing.objects.all() \\\\
4639 .filter(
4640 type='toy',
4641 status='bought'
4642 ) \\\\
4643 .aggregate(
4644 Sum('amount')
4645 ) \\\\
4646 .values_list()
4648 (should (python-info-line-ends-backslash-p 2)) ; .filter(...
4649 (should (python-info-line-ends-backslash-p 3))
4650 (should (python-info-line-ends-backslash-p 4))
4651 (should (python-info-line-ends-backslash-p 5))
4652 (should (python-info-line-ends-backslash-p 6)) ; ) \...
4653 (should (python-info-line-ends-backslash-p 7))
4654 (should (python-info-line-ends-backslash-p 8))
4655 (should (python-info-line-ends-backslash-p 9))
4656 (should (not (python-info-line-ends-backslash-p 10))))) ; .values_list()...
4658 (ert-deftest python-info-beginning-of-backslash-1 ()
4659 (python-tests-with-temp-buffer
4661 objects = Thing.objects.all() \\\\
4662 .filter(
4663 type='toy',
4664 status='bought'
4665 ) \\\\
4666 .aggregate(
4667 Sum('amount')
4668 ) \\\\
4669 .values_list()
4671 (let ((first 2)
4672 (second (python-tests-look-at ".filter("))
4673 (third (python-tests-look-at ".aggregate(")))
4674 (should (= first (python-info-beginning-of-backslash 2)))
4675 (should (= second (python-info-beginning-of-backslash 3)))
4676 (should (= second (python-info-beginning-of-backslash 4)))
4677 (should (= second (python-info-beginning-of-backslash 5)))
4678 (should (= second (python-info-beginning-of-backslash 6)))
4679 (should (= third (python-info-beginning-of-backslash 7)))
4680 (should (= third (python-info-beginning-of-backslash 8)))
4681 (should (= third (python-info-beginning-of-backslash 9)))
4682 (should (not (python-info-beginning-of-backslash 10))))))
4684 (ert-deftest python-info-continuation-line-p-1 ()
4685 (python-tests-with-temp-buffer
4687 if width == 0 and height == 0 and \\\\
4688 color == 'red' and emphasis == 'strong' or \\\\
4689 highlight > 100:
4690 raise ValueError(
4691 'sorry, you lose'
4695 (python-tests-look-at "if width == 0 and height == 0 and")
4696 (should (not (python-info-continuation-line-p)))
4697 (python-tests-look-at "color == 'red' and emphasis == 'strong' or")
4698 (should (python-info-continuation-line-p))
4699 (python-tests-look-at "highlight > 100:")
4700 (should (python-info-continuation-line-p))
4701 (python-tests-look-at "raise ValueError(")
4702 (should (not (python-info-continuation-line-p)))
4703 (python-tests-look-at "'sorry, you lose'")
4704 (should (python-info-continuation-line-p))
4705 (forward-line 1)
4706 (should (python-info-continuation-line-p))
4707 (python-tests-look-at ")")
4708 (should (python-info-continuation-line-p))
4709 (forward-line 1)
4710 (should (not (python-info-continuation-line-p)))))
4712 (ert-deftest python-info-block-continuation-line-p-1 ()
4713 (python-tests-with-temp-buffer
4715 if width == 0 and height == 0 and \\\\
4716 color == 'red' and emphasis == 'strong' or \\\\
4717 highlight > 100:
4718 raise ValueError(
4719 'sorry, you lose'
4723 (python-tests-look-at "if width == 0 and")
4724 (should (not (python-info-block-continuation-line-p)))
4725 (python-tests-look-at "color == 'red' and emphasis == 'strong' or")
4726 (should (= (python-info-block-continuation-line-p)
4727 (python-tests-look-at "if width == 0 and" -1 t)))
4728 (python-tests-look-at "highlight > 100:")
4729 (should (not (python-info-block-continuation-line-p)))))
4731 (ert-deftest python-info-block-continuation-line-p-2 ()
4732 (python-tests-with-temp-buffer
4734 def foo(a,
4737 pass
4739 (python-tests-look-at "def foo(a,")
4740 (should (not (python-info-block-continuation-line-p)))
4741 (python-tests-look-at "b,")
4742 (should (= (python-info-block-continuation-line-p)
4743 (python-tests-look-at "def foo(a," -1 t)))
4744 (python-tests-look-at "c):")
4745 (should (not (python-info-block-continuation-line-p)))))
4747 (ert-deftest python-info-assignment-statement-p-1 ()
4748 (python-tests-with-temp-buffer
4750 data = foo(), bar() \\\\
4751 baz(), 4 \\\\
4752 5, 6
4754 (python-tests-look-at "data = foo(), bar()")
4755 (should (python-info-assignment-statement-p))
4756 (should (python-info-assignment-statement-p t))
4757 (python-tests-look-at "baz(), 4")
4758 (should (python-info-assignment-statement-p))
4759 (should (not (python-info-assignment-statement-p t)))
4760 (python-tests-look-at "5, 6")
4761 (should (python-info-assignment-statement-p))
4762 (should (not (python-info-assignment-statement-p t)))))
4764 (ert-deftest python-info-assignment-statement-p-2 ()
4765 (python-tests-with-temp-buffer
4767 data = (foo(), bar()
4768 baz(), 4
4769 5, 6)
4771 (python-tests-look-at "data = (foo(), bar()")
4772 (should (python-info-assignment-statement-p))
4773 (should (python-info-assignment-statement-p t))
4774 (python-tests-look-at "baz(), 4")
4775 (should (python-info-assignment-statement-p))
4776 (should (not (python-info-assignment-statement-p t)))
4777 (python-tests-look-at "5, 6)")
4778 (should (python-info-assignment-statement-p))
4779 (should (not (python-info-assignment-statement-p t)))))
4781 (ert-deftest python-info-assignment-statement-p-3 ()
4782 (python-tests-with-temp-buffer
4784 data '=' 42
4786 (python-tests-look-at "data '=' 42")
4787 (should (not (python-info-assignment-statement-p)))
4788 (should (not (python-info-assignment-statement-p t)))))
4790 (ert-deftest python-info-assignment-continuation-line-p-1 ()
4791 (python-tests-with-temp-buffer
4793 data = foo(), bar() \\\\
4794 baz(), 4 \\\\
4795 5, 6
4797 (python-tests-look-at "data = foo(), bar()")
4798 (should (not (python-info-assignment-continuation-line-p)))
4799 (python-tests-look-at "baz(), 4")
4800 (should (= (python-info-assignment-continuation-line-p)
4801 (python-tests-look-at "foo()," -1 t)))
4802 (python-tests-look-at "5, 6")
4803 (should (not (python-info-assignment-continuation-line-p)))))
4805 (ert-deftest python-info-assignment-continuation-line-p-2 ()
4806 (python-tests-with-temp-buffer
4808 data = (foo(), bar()
4809 baz(), 4
4810 5, 6)
4812 (python-tests-look-at "data = (foo(), bar()")
4813 (should (not (python-info-assignment-continuation-line-p)))
4814 (python-tests-look-at "baz(), 4")
4815 (should (= (python-info-assignment-continuation-line-p)
4816 (python-tests-look-at "(foo()," -1 t)))
4817 (python-tests-look-at "5, 6)")
4818 (should (not (python-info-assignment-continuation-line-p)))))
4820 (ert-deftest python-info-looking-at-beginning-of-defun-1 ()
4821 (python-tests-with-temp-buffer
4823 def decorat0r(deff):
4824 '''decorates stuff.
4826 @decorat0r
4827 def foo(arg):
4830 def wrap():
4831 deff()
4832 return wwrap
4834 (python-tests-look-at "def decorat0r(deff):")
4835 (should (python-info-looking-at-beginning-of-defun))
4836 (python-tests-look-at "def foo(arg):")
4837 (should (not (python-info-looking-at-beginning-of-defun)))
4838 (python-tests-look-at "def wrap():")
4839 (should (python-info-looking-at-beginning-of-defun))
4840 (python-tests-look-at "deff()")
4841 (should (not (python-info-looking-at-beginning-of-defun)))))
4843 (ert-deftest python-info-current-line-comment-p-1 ()
4844 (python-tests-with-temp-buffer
4846 # this is a comment
4847 foo = True # another comment
4848 '#this is a string'
4849 if foo:
4850 # more comments
4851 print ('bar') # print bar
4853 (python-tests-look-at "# this is a comment")
4854 (should (python-info-current-line-comment-p))
4855 (python-tests-look-at "foo = True # another comment")
4856 (should (not (python-info-current-line-comment-p)))
4857 (python-tests-look-at "'#this is a string'")
4858 (should (not (python-info-current-line-comment-p)))
4859 (python-tests-look-at "# more comments")
4860 (should (python-info-current-line-comment-p))
4861 (python-tests-look-at "print ('bar') # print bar")
4862 (should (not (python-info-current-line-comment-p)))))
4864 (ert-deftest python-info-current-line-empty-p ()
4865 (python-tests-with-temp-buffer
4867 # this is a comment
4869 foo = True # another comment
4871 (should (python-info-current-line-empty-p))
4872 (python-tests-look-at "# this is a comment")
4873 (should (not (python-info-current-line-empty-p)))
4874 (forward-line 1)
4875 (should (python-info-current-line-empty-p))))
4877 (ert-deftest python-info-docstring-p-1 ()
4878 "Test module docstring detection."
4879 (python-tests-with-temp-buffer
4880 "# -*- coding: utf-8 -*-
4881 #!/usr/bin/python
4884 Module Docstring Django style.
4886 u'''Additional module docstring.'''
4887 '''Not a module docstring.'''
4889 (python-tests-look-at "Module Docstring Django style.")
4890 (should (python-info-docstring-p))
4891 (python-tests-look-at "u'''Additional module docstring.'''")
4892 (should (python-info-docstring-p))
4893 (python-tests-look-at "'''Not a module docstring.'''")
4894 (should (not (python-info-docstring-p)))))
4896 (ert-deftest python-info-docstring-p-2 ()
4897 "Test variable docstring detection."
4898 (python-tests-with-temp-buffer
4900 variable = 42
4901 U'''Variable docstring.'''
4902 '''Additional variable docstring.'''
4903 '''Not a variable docstring.'''
4905 (python-tests-look-at "Variable docstring.")
4906 (should (python-info-docstring-p))
4907 (python-tests-look-at "u'''Additional variable docstring.'''")
4908 (should (python-info-docstring-p))
4909 (python-tests-look-at "'''Not a variable docstring.'''")
4910 (should (not (python-info-docstring-p)))))
4912 (ert-deftest python-info-docstring-p-3 ()
4913 "Test function docstring detection."
4914 (python-tests-with-temp-buffer
4916 def func(a, b):
4917 r'''
4918 Function docstring.
4920 onetwo style.
4922 R'''Additional function docstring.'''
4923 '''Not a function docstring.'''
4924 return a + b
4926 (python-tests-look-at "Function docstring.")
4927 (should (python-info-docstring-p))
4928 (python-tests-look-at "R'''Additional function docstring.'''")
4929 (should (python-info-docstring-p))
4930 (python-tests-look-at "'''Not a function docstring.'''")
4931 (should (not (python-info-docstring-p)))))
4933 (ert-deftest python-info-docstring-p-4 ()
4934 "Test class docstring detection."
4935 (python-tests-with-temp-buffer
4937 class Class:
4938 ur'''
4939 Class docstring.
4941 symmetric style.
4943 uR'''
4944 Additional class docstring.
4946 '''Not a class docstring.'''
4947 pass
4949 (python-tests-look-at "Class docstring.")
4950 (should (python-info-docstring-p))
4951 (python-tests-look-at "uR'''") ;; Additional class docstring
4952 (should (python-info-docstring-p))
4953 (python-tests-look-at "'''Not a class docstring.'''")
4954 (should (not (python-info-docstring-p)))))
4956 (ert-deftest python-info-docstring-p-5 ()
4957 "Test class attribute docstring detection."
4958 (python-tests-with-temp-buffer
4960 class Class:
4961 attribute = 42
4962 Ur'''
4963 Class attribute docstring.
4965 pep-257 style.
4968 UR'''
4969 Additional class attribute docstring.
4971 '''Not a class attribute docstring.'''
4972 pass
4974 (python-tests-look-at "Class attribute docstring.")
4975 (should (python-info-docstring-p))
4976 (python-tests-look-at "UR'''") ;; Additional class attr docstring
4977 (should (python-info-docstring-p))
4978 (python-tests-look-at "'''Not a class attribute docstring.'''")
4979 (should (not (python-info-docstring-p)))))
4981 (ert-deftest python-info-docstring-p-6 ()
4982 "Test class method docstring detection."
4983 (python-tests-with-temp-buffer
4985 class Class:
4987 def __init__(self, a, b):
4988 self.a = a
4989 self.b = b
4991 def __call__(self):
4992 '''Method docstring.
4994 pep-257-nn style.
4996 '''Additional method docstring.'''
4997 '''Not a method docstring.'''
4998 return self.a + self.b
5000 (python-tests-look-at "Method docstring.")
5001 (should (python-info-docstring-p))
5002 (python-tests-look-at "'''Additional method docstring.'''")
5003 (should (python-info-docstring-p))
5004 (python-tests-look-at "'''Not a method docstring.'''")
5005 (should (not (python-info-docstring-p)))))
5007 (ert-deftest python-info-encoding-from-cookie-1 ()
5008 "Should detect it on first line."
5009 (python-tests-with-temp-buffer
5010 "# coding=latin-1
5012 foo = True # another comment
5014 (should (eq (python-info-encoding-from-cookie) 'latin-1))))
5016 (ert-deftest python-info-encoding-from-cookie-2 ()
5017 "Should detect it on second line."
5018 (python-tests-with-temp-buffer
5020 # coding=latin-1
5022 foo = True # another comment
5024 (should (eq (python-info-encoding-from-cookie) 'latin-1))))
5026 (ert-deftest python-info-encoding-from-cookie-3 ()
5027 "Should not be detected on third line (and following ones)."
5028 (python-tests-with-temp-buffer
5031 # coding=latin-1
5032 foo = True # another comment
5034 (should (not (python-info-encoding-from-cookie)))))
5036 (ert-deftest python-info-encoding-from-cookie-4 ()
5037 "Should detect Emacs style."
5038 (python-tests-with-temp-buffer
5039 "# -*- coding: latin-1 -*-
5041 foo = True # another comment"
5042 (should (eq (python-info-encoding-from-cookie) 'latin-1))))
5044 (ert-deftest python-info-encoding-from-cookie-5 ()
5045 "Should detect Vim style."
5046 (python-tests-with-temp-buffer
5047 "# vim: set fileencoding=latin-1 :
5049 foo = True # another comment"
5050 (should (eq (python-info-encoding-from-cookie) 'latin-1))))
5052 (ert-deftest python-info-encoding-from-cookie-6 ()
5053 "First cookie wins."
5054 (python-tests-with-temp-buffer
5055 "# -*- coding: iso-8859-1 -*-
5056 # vim: set fileencoding=latin-1 :
5058 foo = True # another comment"
5059 (should (eq (python-info-encoding-from-cookie) 'iso-8859-1))))
5061 (ert-deftest python-info-encoding-from-cookie-7 ()
5062 "First cookie wins."
5063 (python-tests-with-temp-buffer
5064 "# vim: set fileencoding=latin-1 :
5065 # -*- coding: iso-8859-1 -*-
5067 foo = True # another comment"
5068 (should (eq (python-info-encoding-from-cookie) 'latin-1))))
5070 (ert-deftest python-info-encoding-1 ()
5071 "Should return the detected encoding from cookie."
5072 (python-tests-with-temp-buffer
5073 "# vim: set fileencoding=latin-1 :
5075 foo = True # another comment"
5076 (should (eq (python-info-encoding) 'latin-1))))
5078 (ert-deftest python-info-encoding-2 ()
5079 "Should default to utf-8."
5080 (python-tests-with-temp-buffer
5081 "# No encoding for you
5083 foo = True # another comment"
5084 (should (eq (python-info-encoding) 'utf-8))))
5087 ;;; Utility functions
5089 (ert-deftest python-util-goto-line-1 ()
5090 (python-tests-with-temp-buffer
5091 (concat
5092 "# a comment
5093 # another comment
5094 def foo(a, b, c):
5095 pass" (make-string 20 ?\n))
5096 (python-util-goto-line 10)
5097 (should (= (line-number-at-pos) 10))
5098 (python-util-goto-line 20)
5099 (should (= (line-number-at-pos) 20))))
5101 (ert-deftest python-util-clone-local-variables-1 ()
5102 (let ((buffer (generate-new-buffer
5103 "python-util-clone-local-variables-1"))
5104 (varcons
5105 '((python-fill-docstring-style . django)
5106 (python-shell-interpreter . "python")
5107 (python-shell-interpreter-args . "manage.py shell")
5108 (python-shell-prompt-regexp . "In \\[[0-9]+\\]: ")
5109 (python-shell-prompt-output-regexp . "Out\\[[0-9]+\\]: ")
5110 (python-shell-extra-pythonpaths "/home/user/pylib/")
5111 (python-shell-completion-setup-code
5112 . "from IPython.core.completerlib import module_completion")
5113 (python-shell-completion-string-code
5114 . "';'.join(get_ipython().Completer.all_completions('''%s'''))\n")
5115 (python-shell-virtualenv-root
5116 . "/home/user/.virtualenvs/project"))))
5117 (with-current-buffer buffer
5118 (kill-all-local-variables)
5119 (dolist (ccons varcons)
5120 (set (make-local-variable (car ccons)) (cdr ccons))))
5121 (python-tests-with-temp-buffer
5123 (python-util-clone-local-variables buffer)
5124 (dolist (ccons varcons)
5125 (should
5126 (equal (symbol-value (car ccons)) (cdr ccons)))))
5127 (kill-buffer buffer)))
5129 (ert-deftest python-util-strip-string-1 ()
5130 (should (string= (python-util-strip-string "\t\r\n str") "str"))
5131 (should (string= (python-util-strip-string "str \n\r") "str"))
5132 (should (string= (python-util-strip-string "\t\r\n str \n\r ") "str"))
5133 (should
5134 (string= (python-util-strip-string "\n str \nin \tg \n\r") "str \nin \tg"))
5135 (should (string= (python-util-strip-string "\n \t \n\r ") ""))
5136 (should (string= (python-util-strip-string "") "")))
5138 (ert-deftest python-util-forward-comment-1 ()
5139 (python-tests-with-temp-buffer
5140 (concat
5141 "# a comment
5142 # another comment
5143 # bad indented comment
5144 # more comments" (make-string 9999 ?\n))
5145 (python-util-forward-comment 1)
5146 (should (= (point) (point-max)))
5147 (python-util-forward-comment -1)
5148 (should (= (point) (point-min)))))
5150 (ert-deftest python-util-valid-regexp-p-1 ()
5151 (should (python-util-valid-regexp-p ""))
5152 (should (python-util-valid-regexp-p python-shell-prompt-regexp))
5153 (should (not (python-util-valid-regexp-p "\\("))))
5156 ;;; Electricity
5158 (ert-deftest python-parens-electric-indent-1 ()
5159 (let ((eim electric-indent-mode))
5160 (unwind-protect
5161 (progn
5162 (python-tests-with-temp-buffer
5164 from django.conf.urls import patterns, include, url
5166 from django.contrib import admin
5168 from myapp import views
5171 urlpatterns = patterns('',
5172 url(r'^$', views.index
5175 (electric-indent-mode 1)
5176 (python-tests-look-at "views.index")
5177 (end-of-line)
5179 ;; Inserting commas within the same line should leave
5180 ;; indentation unchanged.
5181 (python-tests-self-insert ",")
5182 (should (= (current-indentation) 4))
5184 ;; As well as any other input happening within the same
5185 ;; set of parens.
5186 (python-tests-self-insert " name='index')")
5187 (should (= (current-indentation) 4))
5189 ;; But a comma outside it, should trigger indentation.
5190 (python-tests-self-insert ",")
5191 (should (= (current-indentation) 23))
5193 ;; Newline indents to the first argument column
5194 (python-tests-self-insert "\n")
5195 (should (= (current-indentation) 23))
5197 ;; All this input must not change indentation
5198 (indent-line-to 4)
5199 (python-tests-self-insert "url(r'^/login$', views.login)")
5200 (should (= (current-indentation) 4))
5202 ;; But this comma does
5203 (python-tests-self-insert ",")
5204 (should (= (current-indentation) 23))))
5205 (or eim (electric-indent-mode -1)))))
5207 (ert-deftest python-triple-quote-pairing ()
5208 (let ((epm electric-pair-mode))
5209 (unwind-protect
5210 (progn
5211 (python-tests-with-temp-buffer
5212 "\"\"\n"
5213 (or epm (electric-pair-mode 1))
5214 (goto-char (1- (point-max)))
5215 (python-tests-self-insert ?\")
5216 (should (string= (buffer-string)
5217 "\"\"\"\"\"\"\n"))
5218 (should (= (point) 4)))
5219 (python-tests-with-temp-buffer
5220 "\n"
5221 (python-tests-self-insert (list ?\" ?\" ?\"))
5222 (should (string= (buffer-string)
5223 "\"\"\"\"\"\"\n"))
5224 (should (= (point) 4)))
5225 (python-tests-with-temp-buffer
5226 "\"\n\"\"\n"
5227 (goto-char (1- (point-max)))
5228 (python-tests-self-insert ?\")
5229 (should (= (point) (1- (point-max))))
5230 (should (string= (buffer-string)
5231 "\"\n\"\"\"\n"))))
5232 (or epm (electric-pair-mode -1)))))
5235 ;;; Hideshow support
5237 (ert-deftest python-hideshow-hide-levels-1 ()
5238 "Should hide all methods when called after class start."
5239 (let ((enabled hs-minor-mode))
5240 (unwind-protect
5241 (progn
5242 (python-tests-with-temp-buffer
5244 class SomeClass:
5246 def __init__(self, arg, kwarg=1):
5247 self.arg = arg
5248 self.kwarg = kwarg
5250 def filter(self, nums):
5251 def fn(item):
5252 return item in [self.arg, self.kwarg]
5253 return filter(fn, nums)
5255 def __str__(self):
5256 return '%s-%s' % (self.arg, self.kwarg)
5258 (hs-minor-mode 1)
5259 (python-tests-look-at "class SomeClass:")
5260 (forward-line)
5261 (hs-hide-level 1)
5262 (should
5263 (string=
5264 (python-tests-visible-string)
5266 class SomeClass:
5268 def __init__(self, arg, kwarg=1):
5269 def filter(self, nums):
5270 def __str__(self):"))))
5271 (or enabled (hs-minor-mode -1)))))
5273 (ert-deftest python-hideshow-hide-levels-2 ()
5274 "Should hide nested methods and parens at end of defun."
5275 (let ((enabled hs-minor-mode))
5276 (unwind-protect
5277 (progn
5278 (python-tests-with-temp-buffer
5280 class SomeClass:
5282 def __init__(self, arg, kwarg=1):
5283 self.arg = arg
5284 self.kwarg = kwarg
5286 def filter(self, nums):
5287 def fn(item):
5288 return item in [self.arg, self.kwarg]
5289 return filter(fn, nums)
5291 def __str__(self):
5292 return '%s-%s' % (self.arg, self.kwarg)
5294 (hs-minor-mode 1)
5295 (python-tests-look-at "def fn(item):")
5296 (hs-hide-block)
5297 (should
5298 (string=
5299 (python-tests-visible-string)
5301 class SomeClass:
5303 def __init__(self, arg, kwarg=1):
5304 self.arg = arg
5305 self.kwarg = kwarg
5307 def filter(self, nums):
5308 def fn(item):
5309 return filter(fn, nums)
5311 def __str__(self):
5312 return '%s-%s' % (self.arg, self.kwarg)
5313 "))))
5314 (or enabled (hs-minor-mode -1)))))
5317 (ert-deftest python-tests--python-nav-end-of-statement--infloop ()
5318 "Checks that `python-nav-end-of-statement' doesn't infloop in a
5319 buffer with overlapping strings."
5320 (python-tests-with-temp-buffer "''' '\n''' ' '\n"
5321 (syntax-propertize (point-max))
5322 ;; Create a situation where strings nominally overlap. This
5323 ;; shouldn't happen in practice, but apparently it can happen when
5324 ;; a package calls `syntax-ppss' in a narrowed buffer during JIT
5325 ;; lock.
5326 (put-text-property 4 5 'syntax-table (string-to-syntax "|"))
5327 (remove-text-properties 8 9 '(syntax-table nil))
5328 (goto-char 4)
5329 (setq-local syntax-propertize-function nil)
5330 ;; The next form should not infloop. We have to disable
5331 ;; ‘debug-on-error’ so that ‘cl-assert’ doesn’t call the debugger.
5332 (should-error (let ((debug-on-error nil))
5333 (python-nav-end-of-statement)))
5334 (should (eolp))))
5337 (provide 'python-tests)
5339 ;; Local Variables:
5340 ;; indent-tabs-mode: nil
5341 ;; End:
5343 ;;; python-tests.el ends here