A better fix for bug#21303
[emacs.git] / test / automated / python-tests.el
blobd490f7f9df5eaa4ab86f8b09f1187bbbcab57496
1 ;;; python-tests.el --- Test suite for python.el
3 ;; Copyright (C) 2013-2015 Free Software Foundation, Inc.
5 ;; This file is part of GNU Emacs.
7 ;; GNU Emacs is free software: you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation, either version 3 of the License, or
10 ;; (at your option) any later version.
12 ;; GNU Emacs is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ;; GNU General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
20 ;;; Commentary:
22 ;;; Code:
24 (require 'ert)
25 (require 'python)
27 ;; 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 (python-mode)
40 (insert ,contents)
41 (goto-char (point-min))
42 ,@body))
44 (defmacro python-tests-with-temp-file (contents &rest body)
45 "Create a `python-mode' enabled file with CONTENTS.
46 BODY is code to be executed within the temp buffer. Point is
47 always located at the beginning of buffer."
48 (declare (indent 1) (debug t))
49 ;; temp-file never actually used for anything?
50 `(let* ((temp-file (make-temp-file "python-tests" nil ".py"))
51 (buffer (find-file-noselect temp-file)))
52 (unwind-protect
53 (with-current-buffer buffer
54 (python-mode)
55 (insert ,contents)
56 (goto-char (point-min))
57 ,@body)
58 (and buffer (kill-buffer buffer))
59 (delete-file temp-file))))
61 (defun python-tests-look-at (string &optional num restore-point)
62 "Move point at beginning of STRING in the current buffer.
63 Optional argument NUM defaults to 1 and is an integer indicating
64 how many occurrences must be found, when positive the search is
65 done forwards, otherwise backwards. When RESTORE-POINT is
66 non-nil the point is not moved but the position found is still
67 returned. When searching forward and point is already looking at
68 STRING, it is skipped so the next STRING occurrence is selected."
69 (let* ((num (or num 1))
70 (starting-point (point))
71 (string (regexp-quote string))
72 (search-fn (if (> num 0) #'re-search-forward #'re-search-backward))
73 (deinc-fn (if (> num 0) #'1- #'1+))
74 (found-point))
75 (prog2
76 (catch 'exit
77 (while (not (= num 0))
78 (when (and (> num 0)
79 (looking-at string))
80 ;; Moving forward and already looking at STRING, skip it.
81 (forward-char (length (match-string-no-properties 0))))
82 (and (not (funcall search-fn string nil t))
83 (throw 'exit t))
84 (when (> num 0)
85 ;; `re-search-forward' leaves point at the end of the
86 ;; occurrence, move back so point is at the beginning
87 ;; instead.
88 (forward-char (- (length (match-string-no-properties 0)))))
89 (setq
90 num (funcall deinc-fn num)
91 found-point (point))))
92 found-point
93 (and restore-point (goto-char starting-point)))))
95 (defun python-tests-self-insert (char-or-str)
96 "Call `self-insert-command' for chars in CHAR-OR-STR."
97 (let ((chars
98 (cond
99 ((characterp char-or-str)
100 (list char-or-str))
101 ((stringp char-or-str)
102 (string-to-list char-or-str))
103 ((not
104 (cl-remove-if #'characterp char-or-str))
105 char-or-str)
106 (t (error "CHAR-OR-STR must be a char, string, or list of char")))))
107 (mapc
108 (lambda (char)
109 (let ((last-command-event char))
110 (call-interactively 'self-insert-command)))
111 chars)))
113 (defun python-tests-visible-string (&optional min max)
114 "Return the buffer string excluding invisible overlays.
115 Argument MIN and MAX delimit the region to be returned and
116 default to `point-min' and `point-max' respectively."
117 (let* ((min (or min (point-min)))
118 (max (or max (point-max)))
119 (buffer (current-buffer))
120 (buffer-contents (buffer-substring-no-properties min max))
121 (overlays
122 (sort (overlays-in min max)
123 (lambda (a b)
124 (let ((overlay-end-a (overlay-end a))
125 (overlay-end-b (overlay-end b)))
126 (> overlay-end-a overlay-end-b))))))
127 (with-temp-buffer
128 (insert buffer-contents)
129 (dolist (overlay overlays)
130 (if (overlay-get overlay 'invisible)
131 (delete-region (overlay-start overlay)
132 (overlay-end overlay))))
133 (buffer-substring-no-properties (point-min) (point-max)))))
136 ;;; Tests for your tests, so you can test while you test.
138 (ert-deftest python-tests-look-at-1 ()
139 "Test forward movement."
140 (python-tests-with-temp-buffer
141 "Lorem ipsum dolor sit amet, consectetur adipisicing elit,
142 sed do eiusmod tempor incididunt ut labore et dolore magna
143 aliqua."
144 (let ((expected (save-excursion
145 (dotimes (i 3)
146 (re-search-forward "et" nil t))
147 (forward-char -2)
148 (point))))
149 (should (= (python-tests-look-at "et" 3 t) expected))
150 ;; Even if NUM is bigger than found occurrences the point of last
151 ;; one should be returned.
152 (should (= (python-tests-look-at "et" 6 t) expected))
153 ;; If already looking at STRING, it should skip it.
154 (dotimes (i 2) (re-search-forward "et"))
155 (forward-char -2)
156 (should (= (python-tests-look-at "et") expected)))))
158 (ert-deftest python-tests-look-at-2 ()
159 "Test backward movement."
160 (python-tests-with-temp-buffer
161 "Lorem ipsum dolor sit amet, consectetur adipisicing elit,
162 sed do eiusmod tempor incididunt ut labore et dolore magna
163 aliqua."
164 (let ((expected
165 (save-excursion
166 (re-search-forward "et" nil t)
167 (forward-char -2)
168 (point))))
169 (dotimes (i 3)
170 (re-search-forward "et" nil t))
171 (should (= (python-tests-look-at "et" -3 t) expected))
172 (should (= (python-tests-look-at "et" -6 t) expected)))))
175 ;;; Bindings
178 ;;; Python specialized rx
181 ;;; Font-lock and syntax
183 (ert-deftest python-syntax-after-python-backspace ()
184 ;; `python-indent-dedent-line-backspace' garbles syntax
185 :expected-result :failed
186 (python-tests-with-temp-buffer
187 "\"\"\""
188 (goto-char (point-max))
189 (python-indent-dedent-line-backspace 1)
190 (should (string= (buffer-string) "\"\""))
191 (should (null (nth 3 (syntax-ppss))))))
194 ;;; Indentation
196 ;; See: http://www.python.org/dev/peps/pep-0008/#indentation
198 (ert-deftest python-indent-pep8-1 ()
199 "First pep8 case."
200 (python-tests-with-temp-buffer
201 "# Aligned with opening delimiter
202 foo = long_function_name(var_one, var_two,
203 var_three, var_four)
205 (should (eq (car (python-indent-context)) :no-indent))
206 (should (= (python-indent-calculate-indentation) 0))
207 (python-tests-look-at "foo = long_function_name(var_one, var_two,")
208 (should (eq (car (python-indent-context)) :after-comment))
209 (should (= (python-indent-calculate-indentation) 0))
210 (python-tests-look-at "var_three, var_four)")
211 (should (eq (car (python-indent-context)) :inside-paren))
212 (should (= (python-indent-calculate-indentation) 25))))
214 (ert-deftest python-indent-pep8-2 ()
215 "Second pep8 case."
216 (python-tests-with-temp-buffer
217 "# More indentation included to distinguish this from the rest.
218 def long_function_name(
219 var_one, var_two, var_three,
220 var_four):
221 print (var_one)
223 (should (eq (car (python-indent-context)) :no-indent))
224 (should (= (python-indent-calculate-indentation) 0))
225 (python-tests-look-at "def long_function_name(")
226 (should (eq (car (python-indent-context)) :after-comment))
227 (should (= (python-indent-calculate-indentation) 0))
228 (python-tests-look-at "var_one, var_two, var_three,")
229 (should (eq (car (python-indent-context))
230 :inside-paren-newline-start-from-block))
231 (should (= (python-indent-calculate-indentation) 8))
232 (python-tests-look-at "var_four):")
233 (should (eq (car (python-indent-context))
234 :inside-paren-newline-start-from-block))
235 (should (= (python-indent-calculate-indentation) 8))
236 (python-tests-look-at "print (var_one)")
237 (should (eq (car (python-indent-context))
238 :after-block-start))
239 (should (= (python-indent-calculate-indentation) 4))))
241 (ert-deftest python-indent-pep8-3 ()
242 "Third pep8 case."
243 (python-tests-with-temp-buffer
244 "# Extra indentation is not necessary.
245 foo = long_function_name(
246 var_one, var_two,
247 var_three, var_four)
249 (should (eq (car (python-indent-context)) :no-indent))
250 (should (= (python-indent-calculate-indentation) 0))
251 (python-tests-look-at "foo = long_function_name(")
252 (should (eq (car (python-indent-context)) :after-comment))
253 (should (= (python-indent-calculate-indentation) 0))
254 (python-tests-look-at "var_one, var_two,")
255 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
256 (should (= (python-indent-calculate-indentation) 4))
257 (python-tests-look-at "var_three, var_four)")
258 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
259 (should (= (python-indent-calculate-indentation) 4))))
261 (ert-deftest python-indent-base-case ()
262 "Check base case does not trigger errors."
263 (python-tests-with-temp-buffer
267 (goto-char (point-min))
268 (should (eq (car (python-indent-context)) :no-indent))
269 (should (= (python-indent-calculate-indentation) 0))
270 (forward-line 1)
271 (should (eq (car (python-indent-context)) :no-indent))
272 (should (= (python-indent-calculate-indentation) 0))
273 (forward-line 1)
274 (should (eq (car (python-indent-context)) :no-indent))
275 (should (= (python-indent-calculate-indentation) 0))))
277 (ert-deftest python-indent-after-comment-1 ()
278 "The most simple after-comment case that shouldn't fail."
279 (python-tests-with-temp-buffer
280 "# Contents will be modified to correct indentation
281 class Blag(object):
282 def _on_child_complete(self, child_future):
283 if self.in_terminal_state():
284 pass
285 # We only complete when all our async children have entered a
286 # terminal state. At that point, if any child failed, we fail
287 # with the exception with which the first child failed.
289 (python-tests-look-at "# We only complete")
290 (should (eq (car (python-indent-context)) :after-block-end))
291 (should (= (python-indent-calculate-indentation) 8))
292 (python-tests-look-at "# terminal state")
293 (should (eq (car (python-indent-context)) :after-comment))
294 (should (= (python-indent-calculate-indentation) 8))
295 (python-tests-look-at "# with the exception")
296 (should (eq (car (python-indent-context)) :after-comment))
297 ;; This one indents relative to previous block, even given the fact
298 ;; that it was under-indented.
299 (should (= (python-indent-calculate-indentation) 4))
300 (python-tests-look-at "# terminal state" -1)
301 ;; It doesn't hurt to check again.
302 (should (eq (car (python-indent-context)) :after-comment))
303 (python-indent-line)
304 (should (= (current-indentation) 8))
305 (python-tests-look-at "# with the exception")
306 (should (eq (car (python-indent-context)) :after-comment))
307 ;; Now everything should be lined up.
308 (should (= (python-indent-calculate-indentation) 8))))
310 (ert-deftest python-indent-after-comment-2 ()
311 "Test after-comment in weird cases."
312 (python-tests-with-temp-buffer
313 "# Contents will be modified to correct indentation
314 def func(arg):
315 # I don't do much
316 return arg
317 # This comment is badly indented because the user forced so.
318 # At this line python.el wont dedent, user is always right.
320 comment_wins_over_ender = True
322 # yeah, that.
324 (python-tests-look-at "# I don't do much")
325 (should (eq (car (python-indent-context)) :after-block-start))
326 (should (= (python-indent-calculate-indentation) 4))
327 (python-tests-look-at "return arg")
328 ;; Comment here just gets ignored, this line is not a comment so
329 ;; the rules won't apply here.
330 (should (eq (car (python-indent-context)) :after-block-start))
331 (should (= (python-indent-calculate-indentation) 4))
332 (python-tests-look-at "# This comment is badly indented")
333 (should (eq (car (python-indent-context)) :after-block-end))
334 ;; The return keyword do make indentation lose a level...
335 (should (= (python-indent-calculate-indentation) 0))
336 ;; ...but the current indentation was forced by the user.
337 (python-tests-look-at "# At this line python.el wont dedent")
338 (should (eq (car (python-indent-context)) :after-comment))
339 (should (= (python-indent-calculate-indentation) 4))
340 ;; Should behave the same for blank lines: potentially a comment.
341 (forward-line 1)
342 (should (eq (car (python-indent-context)) :after-comment))
343 (should (= (python-indent-calculate-indentation) 4))
344 (python-tests-look-at "comment_wins_over_ender")
345 ;; The comment won over the ender because the user said so.
346 (should (eq (car (python-indent-context)) :after-comment))
347 (should (= (python-indent-calculate-indentation) 4))
348 ;; The indentation calculated fine for the assignment, but the user
349 ;; choose to force it back to the first column. Next line should
350 ;; be aware of that.
351 (python-tests-look-at "# yeah, that.")
352 (should (eq (car (python-indent-context)) :after-line))
353 (should (= (python-indent-calculate-indentation) 0))))
355 (ert-deftest python-indent-after-comment-3 ()
356 "Test after-comment in buggy case."
357 (python-tests-with-temp-buffer
359 class A(object):
361 def something(self, arg):
362 if True:
363 return arg
365 # A comment
367 @adecorator
368 def method(self, a, b):
369 pass
371 (python-tests-look-at "@adecorator")
372 (should (eq (car (python-indent-context)) :after-comment))
373 (should (= (python-indent-calculate-indentation) 4))))
375 (ert-deftest python-indent-inside-paren-1 ()
376 "The most simple inside-paren case that shouldn't fail."
377 (python-tests-with-temp-buffer
379 data = {
380 'key':
382 'objlist': [
384 'pk': 1,
385 'name': 'first',
388 'pk': 2,
389 'name': 'second',
395 (python-tests-look-at "data = {")
396 (should (eq (car (python-indent-context)) :no-indent))
397 (should (= (python-indent-calculate-indentation) 0))
398 (python-tests-look-at "'key':")
399 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
400 (should (= (python-indent-calculate-indentation) 4))
401 (python-tests-look-at "{")
402 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
403 (should (= (python-indent-calculate-indentation) 4))
404 (python-tests-look-at "'objlist': [")
405 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
406 (should (= (python-indent-calculate-indentation) 8))
407 (python-tests-look-at "{")
408 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
409 (should (= (python-indent-calculate-indentation) 12))
410 (python-tests-look-at "'pk': 1,")
411 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
412 (should (= (python-indent-calculate-indentation) 16))
413 (python-tests-look-at "'name': 'first',")
414 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
415 (should (= (python-indent-calculate-indentation) 16))
416 (python-tests-look-at "},")
417 (should (eq (car (python-indent-context))
418 :inside-paren-at-closing-nested-paren))
419 (should (= (python-indent-calculate-indentation) 12))
420 (python-tests-look-at "{")
421 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
422 (should (= (python-indent-calculate-indentation) 12))
423 (python-tests-look-at "'pk': 2,")
424 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
425 (should (= (python-indent-calculate-indentation) 16))
426 (python-tests-look-at "'name': 'second',")
427 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
428 (should (= (python-indent-calculate-indentation) 16))
429 (python-tests-look-at "}")
430 (should (eq (car (python-indent-context))
431 :inside-paren-at-closing-nested-paren))
432 (should (= (python-indent-calculate-indentation) 12))
433 (python-tests-look-at "]")
434 (should (eq (car (python-indent-context))
435 :inside-paren-at-closing-nested-paren))
436 (should (= (python-indent-calculate-indentation) 8))
437 (python-tests-look-at "}")
438 (should (eq (car (python-indent-context))
439 :inside-paren-at-closing-nested-paren))
440 (should (= (python-indent-calculate-indentation) 4))
441 (python-tests-look-at "}")
442 (should (eq (car (python-indent-context)) :inside-paren-at-closing-paren))
443 (should (= (python-indent-calculate-indentation) 0))))
445 (ert-deftest python-indent-inside-paren-2 ()
446 "Another more compact paren group style."
447 (python-tests-with-temp-buffer
449 data = {'key': {
450 'objlist': [
451 {'pk': 1,
452 'name': 'first'},
453 {'pk': 2,
454 'name': 'second'}
458 (python-tests-look-at "data = {")
459 (should (eq (car (python-indent-context)) :no-indent))
460 (should (= (python-indent-calculate-indentation) 0))
461 (python-tests-look-at "'objlist': [")
462 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
463 (should (= (python-indent-calculate-indentation) 4))
464 (python-tests-look-at "{'pk': 1,")
465 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
466 (should (= (python-indent-calculate-indentation) 8))
467 (python-tests-look-at "'name': 'first'},")
468 (should (eq (car (python-indent-context)) :inside-paren))
469 (should (= (python-indent-calculate-indentation) 9))
470 (python-tests-look-at "{'pk': 2,")
471 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
472 (should (= (python-indent-calculate-indentation) 8))
473 (python-tests-look-at "'name': 'second'}")
474 (should (eq (car (python-indent-context)) :inside-paren))
475 (should (= (python-indent-calculate-indentation) 9))
476 (python-tests-look-at "]")
477 (should (eq (car (python-indent-context))
478 :inside-paren-at-closing-nested-paren))
479 (should (= (python-indent-calculate-indentation) 4))
480 (python-tests-look-at "}}")
481 (should (eq (car (python-indent-context))
482 :inside-paren-at-closing-nested-paren))
483 (should (= (python-indent-calculate-indentation) 0))
484 (python-tests-look-at "}")
485 (should (eq (car (python-indent-context)) :inside-paren-at-closing-paren))
486 (should (= (python-indent-calculate-indentation) 0))))
488 (ert-deftest python-indent-inside-paren-3 ()
489 "The simplest case possible."
490 (python-tests-with-temp-buffer
492 data = ('these',
493 'are',
494 'the',
495 'tokens')
497 (python-tests-look-at "data = ('these',")
498 (should (eq (car (python-indent-context)) :no-indent))
499 (should (= (python-indent-calculate-indentation) 0))
500 (forward-line 1)
501 (should (eq (car (python-indent-context)) :inside-paren))
502 (should (= (python-indent-calculate-indentation) 8))
503 (forward-line 1)
504 (should (eq (car (python-indent-context)) :inside-paren))
505 (should (= (python-indent-calculate-indentation) 8))
506 (forward-line 1)
507 (should (eq (car (python-indent-context)) :inside-paren))
508 (should (= (python-indent-calculate-indentation) 8))))
510 (ert-deftest python-indent-inside-paren-4 ()
511 "Respect indentation of first column."
512 (python-tests-with-temp-buffer
514 data = [ [ 'these', 'are'],
515 ['the', 'tokens' ] ]
517 (python-tests-look-at "data = [ [ 'these', 'are'],")
518 (should (eq (car (python-indent-context)) :no-indent))
519 (should (= (python-indent-calculate-indentation) 0))
520 (forward-line 1)
521 (should (eq (car (python-indent-context)) :inside-paren))
522 (should (= (python-indent-calculate-indentation) 9))))
524 (ert-deftest python-indent-inside-paren-5 ()
525 "Test when :inside-paren initial parens are skipped in context start."
526 (python-tests-with-temp-buffer
528 while ((not some_condition) and
529 another_condition):
530 do_something_interesting(
531 with_some_arg)
533 (python-tests-look-at "while ((not some_condition) and")
534 (should (eq (car (python-indent-context)) :no-indent))
535 (should (= (python-indent-calculate-indentation) 0))
536 (forward-line 1)
537 (should (eq (car (python-indent-context)) :inside-paren))
538 (should (= (python-indent-calculate-indentation) 7))
539 (forward-line 1)
540 (should (eq (car (python-indent-context)) :after-block-start))
541 (should (= (python-indent-calculate-indentation) 4))
542 (forward-line 1)
543 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
544 (should (= (python-indent-calculate-indentation) 8))))
546 (ert-deftest python-indent-inside-paren-6 ()
547 "This should be aligned.."
548 (python-tests-with-temp-buffer
550 CHOICES = (('some', 'choice'),
551 ('another', 'choice'),
552 ('more', 'choices'))
554 (python-tests-look-at "CHOICES = (('some', 'choice'),")
555 (should (eq (car (python-indent-context)) :no-indent))
556 (should (= (python-indent-calculate-indentation) 0))
557 (forward-line 1)
558 (should (eq (car (python-indent-context)) :inside-paren))
559 (should (= (python-indent-calculate-indentation) 11))
560 (forward-line 1)
561 (should (eq (car (python-indent-context)) :inside-paren))
562 (should (= (python-indent-calculate-indentation) 11))))
564 (ert-deftest python-indent-after-block-1 ()
565 "The most simple after-block case that shouldn't fail."
566 (python-tests-with-temp-buffer
568 def foo(a, b, c=True):
570 (should (eq (car (python-indent-context)) :no-indent))
571 (should (= (python-indent-calculate-indentation) 0))
572 (goto-char (point-max))
573 (should (eq (car (python-indent-context)) :after-block-start))
574 (should (= (python-indent-calculate-indentation) 4))))
576 (ert-deftest python-indent-after-block-2 ()
577 "A weird (malformed) multiline block statement."
578 (python-tests-with-temp-buffer
580 def foo(a, b, c={
581 'a':
584 (goto-char (point-max))
585 (should (eq (car (python-indent-context)) :after-block-start))
586 (should (= (python-indent-calculate-indentation) 4))))
588 (ert-deftest python-indent-after-block-3 ()
589 "A weird (malformed) sample, usually found in python shells."
590 (python-tests-with-temp-buffer
592 In [1]:
593 def func():
594 pass
596 In [2]:
597 something
599 (python-tests-look-at "pass")
600 (should (eq (car (python-indent-context)) :after-block-start))
601 (should (= (python-indent-calculate-indentation) 4))
602 (python-tests-look-at "something")
603 (end-of-line)
604 (should (eq (car (python-indent-context)) :after-line))
605 (should (= (python-indent-calculate-indentation) 0))))
607 (ert-deftest python-indent-after-backslash-1 ()
608 "The most common case."
609 (python-tests-with-temp-buffer
611 from foo.bar.baz import something, something_1 \\\\
612 something_2 something_3, \\\\
613 something_4, something_5
615 (python-tests-look-at "from foo.bar.baz import something, something_1")
616 (should (eq (car (python-indent-context)) :no-indent))
617 (should (= (python-indent-calculate-indentation) 0))
618 (python-tests-look-at "something_2 something_3,")
619 (should (eq (car (python-indent-context)) :after-backslash-first-line))
620 (should (= (python-indent-calculate-indentation) 4))
621 (python-tests-look-at "something_4, something_5")
622 (should (eq (car (python-indent-context)) :after-backslash))
623 (should (= (python-indent-calculate-indentation) 4))
624 (goto-char (point-max))
625 (should (eq (car (python-indent-context)) :after-line))
626 (should (= (python-indent-calculate-indentation) 0))))
628 (ert-deftest python-indent-after-backslash-2 ()
629 "A pretty extreme complicated case."
630 (python-tests-with-temp-buffer
632 objects = Thing.objects.all() \\\\
633 .filter(
634 type='toy',
635 status='bought'
636 ) \\\\
637 .aggregate(
638 Sum('amount')
639 ) \\\\
640 .values_list()
642 (python-tests-look-at "objects = Thing.objects.all()")
643 (should (eq (car (python-indent-context)) :no-indent))
644 (should (= (python-indent-calculate-indentation) 0))
645 (python-tests-look-at ".filter(")
646 (should (eq (car (python-indent-context))
647 :after-backslash-dotted-continuation))
648 (should (= (python-indent-calculate-indentation) 23))
649 (python-tests-look-at "type='toy',")
650 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
651 (should (= (python-indent-calculate-indentation) 27))
652 (python-tests-look-at "status='bought'")
653 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
654 (should (= (python-indent-calculate-indentation) 27))
655 (python-tests-look-at ") \\\\")
656 (should (eq (car (python-indent-context)) :inside-paren-at-closing-paren))
657 (should (= (python-indent-calculate-indentation) 23))
658 (python-tests-look-at ".aggregate(")
659 (should (eq (car (python-indent-context))
660 :after-backslash-dotted-continuation))
661 (should (= (python-indent-calculate-indentation) 23))
662 (python-tests-look-at "Sum('amount')")
663 (should (eq (car (python-indent-context)) :inside-paren-newline-start))
664 (should (= (python-indent-calculate-indentation) 27))
665 (python-tests-look-at ") \\\\")
666 (should (eq (car (python-indent-context)) :inside-paren-at-closing-paren))
667 (should (= (python-indent-calculate-indentation) 23))
668 (python-tests-look-at ".values_list()")
669 (should (eq (car (python-indent-context))
670 :after-backslash-dotted-continuation))
671 (should (= (python-indent-calculate-indentation) 23))
672 (forward-line 1)
673 (should (eq (car (python-indent-context)) :after-line))
674 (should (= (python-indent-calculate-indentation) 0))))
676 (ert-deftest python-indent-after-backslash-3 ()
677 "Backslash continuation from block start."
678 (python-tests-with-temp-buffer
680 with open('/path/to/some/file/you/want/to/read') as file_1, \\\\
681 open('/path/to/some/file/being/written', 'w') as file_2:
682 file_2.write(file_1.read())
684 (python-tests-look-at
685 "with open('/path/to/some/file/you/want/to/read') as file_1, \\\\")
686 (should (eq (car (python-indent-context)) :no-indent))
687 (should (= (python-indent-calculate-indentation) 0))
688 (python-tests-look-at
689 "open('/path/to/some/file/being/written', 'w') as file_2")
690 (should (eq (car (python-indent-context))
691 :after-backslash-block-continuation))
692 (should (= (python-indent-calculate-indentation) 5))
693 (python-tests-look-at "file_2.write(file_1.read())")
694 (should (eq (car (python-indent-context)) :after-block-start))
695 (should (= (python-indent-calculate-indentation) 4))))
697 (ert-deftest python-indent-after-backslash-4 ()
698 "Backslash continuation from assignment."
699 (python-tests-with-temp-buffer
701 super_awful_assignment = some_calculation() and \\\\
702 another_calculation() and \\\\
703 some_final_calculation()
705 (python-tests-look-at
706 "super_awful_assignment = some_calculation() and \\\\")
707 (should (eq (car (python-indent-context)) :no-indent))
708 (should (= (python-indent-calculate-indentation) 0))
709 (python-tests-look-at "another_calculation() and \\\\")
710 (should (eq (car (python-indent-context))
711 :after-backslash-assignment-continuation))
712 (should (= (python-indent-calculate-indentation) 25))
713 (python-tests-look-at "some_final_calculation()")
714 (should (eq (car (python-indent-context)) :after-backslash))
715 (should (= (python-indent-calculate-indentation) 25))))
717 (ert-deftest python-indent-after-backslash-5 ()
718 "Dotted continuation bizarre example."
719 (python-tests-with-temp-buffer
721 def delete_all_things():
722 Thing \\\\
723 .objects.all() \\\\
724 .delete()
726 (python-tests-look-at "Thing \\\\")
727 (should (eq (car (python-indent-context)) :after-block-start))
728 (should (= (python-indent-calculate-indentation) 4))
729 (python-tests-look-at ".objects.all() \\\\")
730 (should (eq (car (python-indent-context)) :after-backslash-first-line))
731 (should (= (python-indent-calculate-indentation) 8))
732 (python-tests-look-at ".delete()")
733 (should (eq (car (python-indent-context))
734 :after-backslash-dotted-continuation))
735 (should (= (python-indent-calculate-indentation) 16))))
737 (ert-deftest python-indent-block-enders-1 ()
738 "Test de-indentation for pass keyword."
739 (python-tests-with-temp-buffer
741 Class foo(object):
743 def bar(self):
744 if self.baz:
745 return (1,
749 else:
750 pass
752 (python-tests-look-at "3)")
753 (forward-line 1)
754 (should (= (python-indent-calculate-indentation) 8))
755 (python-tests-look-at "pass")
756 (forward-line 1)
757 (should (eq (car (python-indent-context)) :after-block-end))
758 (should (= (python-indent-calculate-indentation) 8))))
760 (ert-deftest python-indent-block-enders-2 ()
761 "Test de-indentation for return keyword."
762 (python-tests-with-temp-buffer
764 Class foo(object):
765 '''raise lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
767 eiusmod tempor incididunt ut labore et dolore magna aliqua.
769 def bar(self):
770 \"return (1, 2, 3).\"
771 if self.baz:
772 return (1,
776 (python-tests-look-at "def")
777 (should (= (python-indent-calculate-indentation) 4))
778 (python-tests-look-at "if")
779 (should (= (python-indent-calculate-indentation) 8))
780 (python-tests-look-at "return")
781 (should (= (python-indent-calculate-indentation) 12))
782 (goto-char (point-max))
783 (should (eq (car (python-indent-context)) :after-block-end))
784 (should (= (python-indent-calculate-indentation) 8))))
786 (ert-deftest python-indent-block-enders-3 ()
787 "Test de-indentation for continue keyword."
788 (python-tests-with-temp-buffer
790 for element in lst:
791 if element is None:
792 continue
794 (python-tests-look-at "if")
795 (should (= (python-indent-calculate-indentation) 4))
796 (python-tests-look-at "continue")
797 (should (= (python-indent-calculate-indentation) 8))
798 (forward-line 1)
799 (should (eq (car (python-indent-context)) :after-block-end))
800 (should (= (python-indent-calculate-indentation) 4))))
802 (ert-deftest python-indent-block-enders-4 ()
803 "Test de-indentation for break keyword."
804 (python-tests-with-temp-buffer
806 for element in lst:
807 if element is None:
808 break
810 (python-tests-look-at "if")
811 (should (= (python-indent-calculate-indentation) 4))
812 (python-tests-look-at "break")
813 (should (= (python-indent-calculate-indentation) 8))
814 (forward-line 1)
815 (should (eq (car (python-indent-context)) :after-block-end))
816 (should (= (python-indent-calculate-indentation) 4))))
818 (ert-deftest python-indent-block-enders-5 ()
819 "Test de-indentation for raise keyword."
820 (python-tests-with-temp-buffer
822 for element in lst:
823 if element is None:
824 raise ValueError('Element cannot be None')
826 (python-tests-look-at "if")
827 (should (= (python-indent-calculate-indentation) 4))
828 (python-tests-look-at "raise")
829 (should (= (python-indent-calculate-indentation) 8))
830 (forward-line 1)
831 (should (eq (car (python-indent-context)) :after-block-end))
832 (should (= (python-indent-calculate-indentation) 4))))
834 (ert-deftest python-indent-dedenters-1 ()
835 "Test de-indentation for the elif keyword."
836 (python-tests-with-temp-buffer
838 if save:
839 try:
840 write_to_disk(data)
841 finally:
842 cleanup()
843 elif
845 (python-tests-look-at "elif\n")
846 (should (eq (car (python-indent-context)) :at-dedenter-block-start))
847 (should (= (python-indent-calculate-indentation) 0))
848 (should (= (python-indent-calculate-indentation t) 0))))
850 (ert-deftest python-indent-dedenters-2 ()
851 "Test de-indentation for the else keyword."
852 (python-tests-with-temp-buffer
854 if save:
855 try:
856 write_to_disk(data)
857 except IOError:
858 msg = 'Error saving to disk'
859 message(msg)
860 logger.exception(msg)
861 except Exception:
862 if hide_details:
863 logger.exception('Unhandled exception')
864 else
865 finally:
866 data.free()
868 (python-tests-look-at "else\n")
869 (should (eq (car (python-indent-context)) :at-dedenter-block-start))
870 (should (= (python-indent-calculate-indentation) 8))
871 (python-indent-line t)
872 (should (= (python-indent-calculate-indentation t) 4))
873 (python-indent-line t)
874 (should (= (python-indent-calculate-indentation t) 0))
875 (python-indent-line t)
876 (should (= (python-indent-calculate-indentation t) 8))))
878 (ert-deftest python-indent-dedenters-3 ()
879 "Test de-indentation for the except keyword."
880 (python-tests-with-temp-buffer
882 if save:
883 try:
884 write_to_disk(data)
885 except
887 (python-tests-look-at "except\n")
888 (should (eq (car (python-indent-context)) :at-dedenter-block-start))
889 (should (= (python-indent-calculate-indentation) 4))
890 (python-indent-line t)
891 (should (= (python-indent-calculate-indentation t) 4))))
893 (ert-deftest python-indent-dedenters-4 ()
894 "Test de-indentation for the finally keyword."
895 (python-tests-with-temp-buffer
897 if save:
898 try:
899 write_to_disk(data)
900 finally
902 (python-tests-look-at "finally\n")
903 (should (eq (car (python-indent-context)) :at-dedenter-block-start))
904 (should (= (python-indent-calculate-indentation) 4))
905 (python-indent-line t)
906 (should (= (python-indent-calculate-indentation) 4))))
908 (ert-deftest python-indent-dedenters-5 ()
909 "Test invalid levels are skipped in a complex example."
910 (python-tests-with-temp-buffer
912 if save:
913 try:
914 write_to_disk(data)
915 except IOError:
916 msg = 'Error saving to disk'
917 message(msg)
918 logger.exception(msg)
919 finally:
920 if cleanup:
921 do_cleanup()
922 else
924 (python-tests-look-at "else\n")
925 (should (eq (car (python-indent-context)) :at-dedenter-block-start))
926 (should (= (python-indent-calculate-indentation) 8))
927 (should (= (python-indent-calculate-indentation t) 0))
928 (python-indent-line t)
929 (should (= (python-indent-calculate-indentation t) 8))))
931 (ert-deftest python-indent-dedenters-6 ()
932 "Test indentation is zero when no opening block for dedenter."
933 (python-tests-with-temp-buffer
935 try:
936 # if save:
937 write_to_disk(data)
938 else
940 (python-tests-look-at "else\n")
941 (should (eq (car (python-indent-context)) :at-dedenter-block-start))
942 (should (= (python-indent-calculate-indentation) 0))
943 (should (= (python-indent-calculate-indentation t) 0))))
945 (ert-deftest python-indent-dedenters-7 ()
946 "Test indentation case from Bug#15163."
947 (python-tests-with-temp-buffer
949 if a:
950 if b:
951 pass
952 else:
953 pass
954 else:
956 (python-tests-look-at "else:" 2)
957 (should (eq (car (python-indent-context)) :at-dedenter-block-start))
958 (should (= (python-indent-calculate-indentation) 0))
959 (should (= (python-indent-calculate-indentation t) 0))))
961 (ert-deftest python-indent-dedenters-8 ()
962 "Test indentation for Bug#18432."
963 (python-tests-with-temp-buffer
965 if (a == 1 or
966 a == 2):
967 pass
968 elif (a == 3 or
969 a == 4):
971 (python-tests-look-at "elif (a == 3 or")
972 (should (eq (car (python-indent-context)) :at-dedenter-block-start))
973 (should (= (python-indent-calculate-indentation) 0))
974 (should (= (python-indent-calculate-indentation t) 0))
975 (python-tests-look-at "a == 4):\n")
976 (should (eq (car (python-indent-context)) :inside-paren))
977 (should (= (python-indent-calculate-indentation) 6))
978 (python-indent-line)
979 (should (= (python-indent-calculate-indentation t) 4))
980 (python-indent-line t)
981 (should (= (python-indent-calculate-indentation t) 0))
982 (python-indent-line t)
983 (should (= (python-indent-calculate-indentation t) 6))))
985 (ert-deftest python-indent-inside-string-1 ()
986 "Test indentation for strings."
987 (python-tests-with-temp-buffer
989 multiline = '''
990 bunch
992 lines
995 (python-tests-look-at "multiline = '''")
996 (should (eq (car (python-indent-context)) :no-indent))
997 (should (= (python-indent-calculate-indentation) 0))
998 (python-tests-look-at "bunch")
999 (should (eq (car (python-indent-context)) :inside-string))
1000 (should (= (python-indent-calculate-indentation) 0))
1001 (python-tests-look-at "of")
1002 (should (eq (car (python-indent-context)) :inside-string))
1003 (should (= (python-indent-calculate-indentation) 0))
1004 (python-tests-look-at "lines")
1005 (should (eq (car (python-indent-context)) :inside-string))
1006 (should (= (python-indent-calculate-indentation) 0))
1007 (python-tests-look-at "'''")
1008 (should (eq (car (python-indent-context)) :inside-string))
1009 (should (= (python-indent-calculate-indentation) 0))))
1011 (ert-deftest python-indent-inside-string-2 ()
1012 "Test indentation for docstrings."
1013 (python-tests-with-temp-buffer
1015 def fn(a, b, c=True):
1016 '''docstring
1017 bunch
1019 lines
1022 (python-tests-look-at "'''docstring")
1023 (should (eq (car (python-indent-context)) :after-block-start))
1024 (should (= (python-indent-calculate-indentation) 4))
1025 (python-tests-look-at "bunch")
1026 (should (eq (car (python-indent-context)) :inside-docstring))
1027 (should (= (python-indent-calculate-indentation) 4))
1028 (python-tests-look-at "of")
1029 (should (eq (car (python-indent-context)) :inside-docstring))
1030 ;; Any indentation deeper than the base-indent must remain unmodified.
1031 (should (= (python-indent-calculate-indentation) 8))
1032 (python-tests-look-at "lines")
1033 (should (eq (car (python-indent-context)) :inside-docstring))
1034 (should (= (python-indent-calculate-indentation) 4))
1035 (python-tests-look-at "'''")
1036 (should (eq (car (python-indent-context)) :inside-docstring))
1037 (should (= (python-indent-calculate-indentation) 4))))
1039 (ert-deftest python-indent-inside-string-3 ()
1040 "Test indentation for nested strings."
1041 (python-tests-with-temp-buffer
1043 def fn(a, b, c=True):
1044 some_var = '''
1045 bunch
1047 lines
1050 (python-tests-look-at "some_var = '''")
1051 (should (eq (car (python-indent-context)) :after-block-start))
1052 (should (= (python-indent-calculate-indentation) 4))
1053 (python-tests-look-at "bunch")
1054 (should (eq (car (python-indent-context)) :inside-string))
1055 (should (= (python-indent-calculate-indentation) 4))
1056 (python-tests-look-at "of")
1057 (should (eq (car (python-indent-context)) :inside-string))
1058 (should (= (python-indent-calculate-indentation) 4))
1059 (python-tests-look-at "lines")
1060 (should (eq (car (python-indent-context)) :inside-string))
1061 (should (= (python-indent-calculate-indentation) 4))
1062 (python-tests-look-at "'''")
1063 (should (eq (car (python-indent-context)) :inside-string))
1064 (should (= (python-indent-calculate-indentation) 4))))
1066 (ert-deftest python-indent-electric-colon-1 ()
1067 "Test indentation case from Bug#18228."
1068 (python-tests-with-temp-buffer
1070 def a():
1071 pass
1073 def b()
1075 (python-tests-look-at "def b()")
1076 (goto-char (line-end-position))
1077 (python-tests-self-insert ":")
1078 (should (= (current-indentation) 0))))
1080 (ert-deftest python-indent-electric-colon-2 ()
1081 "Test indentation case for dedenter."
1082 (python-tests-with-temp-buffer
1084 if do:
1085 something()
1086 else
1088 (python-tests-look-at "else")
1089 (goto-char (line-end-position))
1090 (python-tests-self-insert ":")
1091 (should (= (current-indentation) 0))))
1093 (ert-deftest python-indent-electric-colon-3 ()
1094 "Test indentation case for multi-line dedenter."
1095 (python-tests-with-temp-buffer
1097 if do:
1098 something()
1099 elif (this
1101 that)
1103 (python-tests-look-at "that)")
1104 (goto-char (line-end-position))
1105 (python-tests-self-insert ":")
1106 (python-tests-look-at "elif" -1)
1107 (should (= (current-indentation) 0))
1108 (python-tests-look-at "and")
1109 (should (= (current-indentation) 6))
1110 (python-tests-look-at "that)")
1111 (should (= (current-indentation) 6))))
1113 (ert-deftest python-indent-region-1 ()
1114 "Test indentation case from Bug#18843."
1115 (let ((contents "
1116 def foo ():
1117 try:
1118 pass
1119 except:
1120 pass
1122 (python-tests-with-temp-buffer
1123 contents
1124 (python-indent-region (point-min) (point-max))
1125 (should (string= (buffer-substring-no-properties (point-min) (point-max))
1126 contents)))))
1128 (ert-deftest python-indent-region-2 ()
1129 "Test region indentation on comments."
1130 (let ((contents "
1131 def f():
1132 if True:
1133 pass
1135 # This is
1136 # some multiline
1137 # comment
1139 (python-tests-with-temp-buffer
1140 contents
1141 (python-indent-region (point-min) (point-max))
1142 (should (string= (buffer-substring-no-properties (point-min) (point-max))
1143 contents)))))
1145 (ert-deftest python-indent-region-3 ()
1146 "Test region indentation on comments."
1147 (let ((contents "
1148 def f():
1149 if True:
1150 pass
1151 # This is
1152 # some multiline
1153 # comment
1155 (expected "
1156 def f():
1157 if True:
1158 pass
1159 # This is
1160 # some multiline
1161 # comment
1163 (python-tests-with-temp-buffer
1164 contents
1165 (python-indent-region (point-min) (point-max))
1166 (should (string= (buffer-substring-no-properties (point-min) (point-max))
1167 expected)))))
1169 (ert-deftest python-indent-region-4 ()
1170 "Test region indentation block starts, dedenters and enders."
1171 (let ((contents "
1172 def f():
1173 if True:
1174 a = 5
1175 else:
1176 a = 10
1177 return a
1179 (expected "
1180 def f():
1181 if True:
1182 a = 5
1183 else:
1184 a = 10
1185 return a
1187 (python-tests-with-temp-buffer
1188 contents
1189 (python-indent-region (point-min) (point-max))
1190 (should (string= (buffer-substring-no-properties (point-min) (point-max))
1191 expected)))))
1193 (ert-deftest python-indent-region-5 ()
1194 "Test region indentation for docstrings."
1195 (let ((contents "
1196 def f():
1198 this is
1199 a multiline
1200 string
1202 x = \\
1204 this is an arbitrarily
1205 indented multiline
1206 string
1209 (expected "
1210 def f():
1212 this is
1213 a multiline
1214 string
1216 x = \\
1218 this is an arbitrarily
1219 indented multiline
1220 string
1223 (python-tests-with-temp-buffer
1224 contents
1225 (python-indent-region (point-min) (point-max))
1226 (should (string= (buffer-substring-no-properties (point-min) (point-max))
1227 expected)))))
1230 ;;; Mark
1232 (ert-deftest python-mark-defun-1 ()
1233 """Test `python-mark-defun' with point at defun symbol start."""
1234 (python-tests-with-temp-buffer
1236 def foo(x):
1237 return x
1239 class A:
1240 pass
1242 class B:
1244 def __init__(self):
1245 self.b = 'b'
1247 def fun(self):
1248 return self.b
1250 class C:
1251 '''docstring'''
1253 (let ((expected-mark-beginning-position
1254 (progn
1255 (python-tests-look-at "class A:")
1256 (1- (point))))
1257 (expected-mark-end-position-1
1258 (save-excursion
1259 (python-tests-look-at "pass")
1260 (forward-line)
1261 (point)))
1262 (expected-mark-end-position-2
1263 (save-excursion
1264 (python-tests-look-at "return self.b")
1265 (forward-line)
1266 (point)))
1267 (expected-mark-end-position-3
1268 (save-excursion
1269 (python-tests-look-at "'''docstring'''")
1270 (forward-line)
1271 (point))))
1272 ;; Select class A only, with point at bol.
1273 (python-mark-defun 1)
1274 (should (= (point) expected-mark-beginning-position))
1275 (should (= (marker-position (mark-marker))
1276 expected-mark-end-position-1))
1277 ;; expand to class B, start position should remain the same.
1278 (python-mark-defun 1)
1279 (should (= (point) expected-mark-beginning-position))
1280 (should (= (marker-position (mark-marker))
1281 expected-mark-end-position-2))
1282 ;; expand to class C, start position should remain the same.
1283 (python-mark-defun 1)
1284 (should (= (point) expected-mark-beginning-position))
1285 (should (= (marker-position (mark-marker))
1286 expected-mark-end-position-3)))))
1288 (ert-deftest python-mark-defun-2 ()
1289 """Test `python-mark-defun' with point at nested defun symbol start."""
1290 (python-tests-with-temp-buffer
1292 def foo(x):
1293 return x
1295 class A:
1296 pass
1298 class B:
1300 def __init__(self):
1301 self.b = 'b'
1303 def fun(self):
1304 return self.b
1306 class C:
1307 '''docstring'''
1309 (let ((expected-mark-beginning-position
1310 (progn
1311 (python-tests-look-at "def __init__(self):")
1312 (1- (line-beginning-position))))
1313 (expected-mark-end-position-1
1314 (save-excursion
1315 (python-tests-look-at "self.b = 'b'")
1316 (forward-line)
1317 (point)))
1318 (expected-mark-end-position-2
1319 (save-excursion
1320 (python-tests-look-at "return self.b")
1321 (forward-line)
1322 (point)))
1323 (expected-mark-end-position-3
1324 (save-excursion
1325 (python-tests-look-at "'''docstring'''")
1326 (forward-line)
1327 (point))))
1328 ;; Select B.__init only, with point at its start.
1329 (python-mark-defun 1)
1330 (should (= (point) expected-mark-beginning-position))
1331 (should (= (marker-position (mark-marker))
1332 expected-mark-end-position-1))
1333 ;; expand to B.fun, start position should remain the same.
1334 (python-mark-defun 1)
1335 (should (= (point) expected-mark-beginning-position))
1336 (should (= (marker-position (mark-marker))
1337 expected-mark-end-position-2))
1338 ;; expand to class C, start position should remain the same.
1339 (python-mark-defun 1)
1340 (should (= (point) expected-mark-beginning-position))
1341 (should (= (marker-position (mark-marker))
1342 expected-mark-end-position-3)))))
1344 (ert-deftest python-mark-defun-3 ()
1345 """Test `python-mark-defun' with point inside defun symbol."""
1346 (python-tests-with-temp-buffer
1348 def foo(x):
1349 return x
1351 class A:
1352 pass
1354 class B:
1356 def __init__(self):
1357 self.b = 'b'
1359 def fun(self):
1360 return self.b
1362 class C:
1363 '''docstring'''
1365 (let ((expected-mark-beginning-position
1366 (progn
1367 (python-tests-look-at "def fun(self):")
1368 (python-tests-look-at "(self):")
1369 (1- (line-beginning-position))))
1370 (expected-mark-end-position
1371 (save-excursion
1372 (python-tests-look-at "return self.b")
1373 (forward-line)
1374 (point))))
1375 ;; Should select B.fun, despite point is inside the defun symbol.
1376 (python-mark-defun 1)
1377 (should (= (point) expected-mark-beginning-position))
1378 (should (= (marker-position (mark-marker))
1379 expected-mark-end-position)))))
1382 ;;; Navigation
1384 (ert-deftest python-nav-beginning-of-defun-1 ()
1385 (python-tests-with-temp-buffer
1387 def decoratorFunctionWithArguments(arg1, arg2, arg3):
1388 '''print decorated function call data to stdout.
1390 Usage:
1392 @decoratorFunctionWithArguments('arg1', 'arg2')
1393 def func(a, b, c=True):
1394 pass
1397 def wwrap(f):
1398 print 'Inside wwrap()'
1399 def wrapped_f(*args):
1400 print 'Inside wrapped_f()'
1401 print 'Decorator arguments:', arg1, arg2, arg3
1402 f(*args)
1403 print 'After f(*args)'
1404 return wrapped_f
1405 return wwrap
1407 (python-tests-look-at "return wrap")
1408 (should (= (save-excursion
1409 (python-nav-beginning-of-defun)
1410 (point))
1411 (save-excursion
1412 (python-tests-look-at "def wrapped_f(*args):" -1)
1413 (beginning-of-line)
1414 (point))))
1415 (python-tests-look-at "def wrapped_f(*args):" -1)
1416 (should (= (save-excursion
1417 (python-nav-beginning-of-defun)
1418 (point))
1419 (save-excursion
1420 (python-tests-look-at "def wwrap(f):" -1)
1421 (beginning-of-line)
1422 (point))))
1423 (python-tests-look-at "def wwrap(f):" -1)
1424 (should (= (save-excursion
1425 (python-nav-beginning-of-defun)
1426 (point))
1427 (save-excursion
1428 (python-tests-look-at "def decoratorFunctionWithArguments" -1)
1429 (beginning-of-line)
1430 (point))))))
1432 (ert-deftest python-nav-beginning-of-defun-2 ()
1433 (python-tests-with-temp-buffer
1435 class C(object):
1437 def m(self):
1438 self.c()
1440 def b():
1441 pass
1443 def a():
1444 pass
1446 def c(self):
1447 pass
1449 ;; Nested defuns, are handled with care.
1450 (python-tests-look-at "def c(self):")
1451 (should (= (save-excursion
1452 (python-nav-beginning-of-defun)
1453 (point))
1454 (save-excursion
1455 (python-tests-look-at "def m(self):" -1)
1456 (beginning-of-line)
1457 (point))))
1458 ;; Defuns on same levels should be respected.
1459 (python-tests-look-at "def a():" -1)
1460 (should (= (save-excursion
1461 (python-nav-beginning-of-defun)
1462 (point))
1463 (save-excursion
1464 (python-tests-look-at "def b():" -1)
1465 (beginning-of-line)
1466 (point))))
1467 ;; Jump to a top level defun.
1468 (python-tests-look-at "def b():" -1)
1469 (should (= (save-excursion
1470 (python-nav-beginning-of-defun)
1471 (point))
1472 (save-excursion
1473 (python-tests-look-at "def m(self):" -1)
1474 (beginning-of-line)
1475 (point))))
1476 ;; Jump to a top level defun again.
1477 (python-tests-look-at "def m(self):" -1)
1478 (should (= (save-excursion
1479 (python-nav-beginning-of-defun)
1480 (point))
1481 (save-excursion
1482 (python-tests-look-at "class C(object):" -1)
1483 (beginning-of-line)
1484 (point))))))
1486 (ert-deftest python-nav-end-of-defun-1 ()
1487 (python-tests-with-temp-buffer
1489 class C(object):
1491 def m(self):
1492 self.c()
1494 def b():
1495 pass
1497 def a():
1498 pass
1500 def c(self):
1501 pass
1503 (should (= (save-excursion
1504 (python-tests-look-at "class C(object):")
1505 (python-nav-end-of-defun)
1506 (point))
1507 (save-excursion
1508 (point-max))))
1509 (should (= (save-excursion
1510 (python-tests-look-at "def m(self):")
1511 (python-nav-end-of-defun)
1512 (point))
1513 (save-excursion
1514 (python-tests-look-at "def c(self):")
1515 (forward-line -1)
1516 (point))))
1517 (should (= (save-excursion
1518 (python-tests-look-at "def b():")
1519 (python-nav-end-of-defun)
1520 (point))
1521 (save-excursion
1522 (python-tests-look-at "def b():")
1523 (forward-line 2)
1524 (point))))
1525 (should (= (save-excursion
1526 (python-tests-look-at "def c(self):")
1527 (python-nav-end-of-defun)
1528 (point))
1529 (save-excursion
1530 (point-max))))))
1532 (ert-deftest python-nav-end-of-defun-2 ()
1533 (python-tests-with-temp-buffer
1535 def decoratorFunctionWithArguments(arg1, arg2, arg3):
1536 '''print decorated function call data to stdout.
1538 Usage:
1540 @decoratorFunctionWithArguments('arg1', 'arg2')
1541 def func(a, b, c=True):
1542 pass
1545 def wwrap(f):
1546 print 'Inside wwrap()'
1547 def wrapped_f(*args):
1548 print 'Inside wrapped_f()'
1549 print 'Decorator arguments:', arg1, arg2, arg3
1550 f(*args)
1551 print 'After f(*args)'
1552 return wrapped_f
1553 return wwrap
1555 (should (= (save-excursion
1556 (python-tests-look-at "def decoratorFunctionWithArguments")
1557 (python-nav-end-of-defun)
1558 (point))
1559 (save-excursion
1560 (point-max))))
1561 (should (= (save-excursion
1562 (python-tests-look-at "@decoratorFunctionWithArguments")
1563 (python-nav-end-of-defun)
1564 (point))
1565 (save-excursion
1566 (point-max))))
1567 (should (= (save-excursion
1568 (python-tests-look-at "def wwrap(f):")
1569 (python-nav-end-of-defun)
1570 (point))
1571 (save-excursion
1572 (python-tests-look-at "return wwrap")
1573 (line-beginning-position))))
1574 (should (= (save-excursion
1575 (python-tests-look-at "def wrapped_f(*args):")
1576 (python-nav-end-of-defun)
1577 (point))
1578 (save-excursion
1579 (python-tests-look-at "return wrapped_f")
1580 (line-beginning-position))))
1581 (should (= (save-excursion
1582 (python-tests-look-at "f(*args)")
1583 (python-nav-end-of-defun)
1584 (point))
1585 (save-excursion
1586 (python-tests-look-at "return wrapped_f")
1587 (line-beginning-position))))))
1589 (ert-deftest python-nav-backward-defun-1 ()
1590 (python-tests-with-temp-buffer
1592 class A(object): # A
1594 def a(self): # a
1595 pass
1597 def b(self): # b
1598 pass
1600 class B(object): # B
1602 class C(object): # C
1604 def d(self): # d
1605 pass
1607 # def e(self): # e
1608 # pass
1610 def c(self): # c
1611 pass
1613 # def d(self): # d
1614 # pass
1616 (goto-char (point-max))
1617 (should (= (save-excursion (python-nav-backward-defun))
1618 (python-tests-look-at " def c(self): # c" -1)))
1619 (should (= (save-excursion (python-nav-backward-defun))
1620 (python-tests-look-at " def d(self): # d" -1)))
1621 (should (= (save-excursion (python-nav-backward-defun))
1622 (python-tests-look-at " class C(object): # C" -1)))
1623 (should (= (save-excursion (python-nav-backward-defun))
1624 (python-tests-look-at " class B(object): # B" -1)))
1625 (should (= (save-excursion (python-nav-backward-defun))
1626 (python-tests-look-at " def b(self): # b" -1)))
1627 (should (= (save-excursion (python-nav-backward-defun))
1628 (python-tests-look-at " def a(self): # a" -1)))
1629 (should (= (save-excursion (python-nav-backward-defun))
1630 (python-tests-look-at "class A(object): # A" -1)))
1631 (should (not (python-nav-backward-defun)))))
1633 (ert-deftest python-nav-backward-defun-2 ()
1634 (python-tests-with-temp-buffer
1636 def decoratorFunctionWithArguments(arg1, arg2, arg3):
1637 '''print decorated function call data to stdout.
1639 Usage:
1641 @decoratorFunctionWithArguments('arg1', 'arg2')
1642 def func(a, b, c=True):
1643 pass
1646 def wwrap(f):
1647 print 'Inside wwrap()'
1648 def wrapped_f(*args):
1649 print 'Inside wrapped_f()'
1650 print 'Decorator arguments:', arg1, arg2, arg3
1651 f(*args)
1652 print 'After f(*args)'
1653 return wrapped_f
1654 return wwrap
1656 (goto-char (point-max))
1657 (should (= (save-excursion (python-nav-backward-defun))
1658 (python-tests-look-at " def wrapped_f(*args):" -1)))
1659 (should (= (save-excursion (python-nav-backward-defun))
1660 (python-tests-look-at " def wwrap(f):" -1)))
1661 (should (= (save-excursion (python-nav-backward-defun))
1662 (python-tests-look-at "def decoratorFunctionWithArguments(arg1, arg2, arg3):" -1)))
1663 (should (not (python-nav-backward-defun)))))
1665 (ert-deftest python-nav-backward-defun-3 ()
1666 (python-tests-with-temp-buffer
1669 def u(self):
1670 pass
1672 def v(self):
1673 pass
1675 def w(self):
1676 pass
1679 class A(object):
1680 pass
1682 (goto-char (point-min))
1683 (let ((point (python-tests-look-at "class A(object):")))
1684 (should (not (python-nav-backward-defun)))
1685 (should (= point (point))))))
1687 (ert-deftest python-nav-forward-defun-1 ()
1688 (python-tests-with-temp-buffer
1690 class A(object): # A
1692 def a(self): # a
1693 pass
1695 def b(self): # b
1696 pass
1698 class B(object): # B
1700 class C(object): # C
1702 def d(self): # d
1703 pass
1705 # def e(self): # e
1706 # pass
1708 def c(self): # c
1709 pass
1711 # def d(self): # d
1712 # pass
1714 (goto-char (point-min))
1715 (should (= (save-excursion (python-nav-forward-defun))
1716 (python-tests-look-at "(object): # A")))
1717 (should (= (save-excursion (python-nav-forward-defun))
1718 (python-tests-look-at "(self): # a")))
1719 (should (= (save-excursion (python-nav-forward-defun))
1720 (python-tests-look-at "(self): # b")))
1721 (should (= (save-excursion (python-nav-forward-defun))
1722 (python-tests-look-at "(object): # B")))
1723 (should (= (save-excursion (python-nav-forward-defun))
1724 (python-tests-look-at "(object): # C")))
1725 (should (= (save-excursion (python-nav-forward-defun))
1726 (python-tests-look-at "(self): # d")))
1727 (should (= (save-excursion (python-nav-forward-defun))
1728 (python-tests-look-at "(self): # c")))
1729 (should (not (python-nav-forward-defun)))))
1731 (ert-deftest python-nav-forward-defun-2 ()
1732 (python-tests-with-temp-buffer
1734 def decoratorFunctionWithArguments(arg1, arg2, arg3):
1735 '''print decorated function call data to stdout.
1737 Usage:
1739 @decoratorFunctionWithArguments('arg1', 'arg2')
1740 def func(a, b, c=True):
1741 pass
1744 def wwrap(f):
1745 print 'Inside wwrap()'
1746 def wrapped_f(*args):
1747 print 'Inside wrapped_f()'
1748 print 'Decorator arguments:', arg1, arg2, arg3
1749 f(*args)
1750 print 'After f(*args)'
1751 return wrapped_f
1752 return wwrap
1754 (goto-char (point-min))
1755 (should (= (save-excursion (python-nav-forward-defun))
1756 (python-tests-look-at "(arg1, arg2, arg3):")))
1757 (should (= (save-excursion (python-nav-forward-defun))
1758 (python-tests-look-at "(f):")))
1759 (should (= (save-excursion (python-nav-forward-defun))
1760 (python-tests-look-at "(*args):")))
1761 (should (not (python-nav-forward-defun)))))
1763 (ert-deftest python-nav-forward-defun-3 ()
1764 (python-tests-with-temp-buffer
1766 class A(object):
1767 pass
1770 def u(self):
1771 pass
1773 def v(self):
1774 pass
1776 def w(self):
1777 pass
1780 (goto-char (point-min))
1781 (let ((point (python-tests-look-at "(object):")))
1782 (should (not (python-nav-forward-defun)))
1783 (should (= point (point))))))
1785 (ert-deftest python-nav-beginning-of-statement-1 ()
1786 (python-tests-with-temp-buffer
1788 v1 = 123 + \
1789 456 + \
1791 v2 = (value1,
1792 value2,
1794 value3,
1795 value4)
1796 v3 = ('this is a string'
1798 'that is continued'
1799 'between lines'
1800 'within a paren',
1801 # this is a comment, yo
1802 'continue previous line')
1803 v4 = '''
1804 a very long
1805 string
1808 (python-tests-look-at "v2 =")
1809 (python-util-forward-comment -1)
1810 (should (= (save-excursion
1811 (python-nav-beginning-of-statement)
1812 (point))
1813 (python-tests-look-at "v1 =" -1 t)))
1814 (python-tests-look-at "v3 =")
1815 (python-util-forward-comment -1)
1816 (should (= (save-excursion
1817 (python-nav-beginning-of-statement)
1818 (point))
1819 (python-tests-look-at "v2 =" -1 t)))
1820 (python-tests-look-at "v4 =")
1821 (python-util-forward-comment -1)
1822 (should (= (save-excursion
1823 (python-nav-beginning-of-statement)
1824 (point))
1825 (python-tests-look-at "v3 =" -1 t)))
1826 (goto-char (point-max))
1827 (python-util-forward-comment -1)
1828 (should (= (save-excursion
1829 (python-nav-beginning-of-statement)
1830 (point))
1831 (python-tests-look-at "v4 =" -1 t)))))
1833 (ert-deftest python-nav-end-of-statement-1 ()
1834 (python-tests-with-temp-buffer
1836 v1 = 123 + \
1837 456 + \
1839 v2 = (value1,
1840 value2,
1842 value3,
1843 value4)
1844 v3 = ('this is a string'
1846 'that is continued'
1847 'between lines'
1848 'within a paren',
1849 # this is a comment, yo
1850 'continue previous line')
1851 v4 = '''
1852 a very long
1853 string
1856 (python-tests-look-at "v1 =")
1857 (should (= (save-excursion
1858 (python-nav-end-of-statement)
1859 (point))
1860 (save-excursion
1861 (python-tests-look-at "789")
1862 (line-end-position))))
1863 (python-tests-look-at "v2 =")
1864 (should (= (save-excursion
1865 (python-nav-end-of-statement)
1866 (point))
1867 (save-excursion
1868 (python-tests-look-at "value4)")
1869 (line-end-position))))
1870 (python-tests-look-at "v3 =")
1871 (should (= (save-excursion
1872 (python-nav-end-of-statement)
1873 (point))
1874 (save-excursion
1875 (python-tests-look-at
1876 "'continue previous line')")
1877 (line-end-position))))
1878 (python-tests-look-at "v4 =")
1879 (should (= (save-excursion
1880 (python-nav-end-of-statement)
1881 (point))
1882 (save-excursion
1883 (goto-char (point-max))
1884 (python-util-forward-comment -1)
1885 (point))))))
1887 (ert-deftest python-nav-forward-statement-1 ()
1888 (python-tests-with-temp-buffer
1890 v1 = 123 + \
1891 456 + \
1893 v2 = (value1,
1894 value2,
1896 value3,
1897 value4)
1898 v3 = ('this is a string'
1900 'that is continued'
1901 'between lines'
1902 'within a paren',
1903 # this is a comment, yo
1904 'continue previous line')
1905 v4 = '''
1906 a very long
1907 string
1910 (python-tests-look-at "v1 =")
1911 (should (= (save-excursion
1912 (python-nav-forward-statement)
1913 (point))
1914 (python-tests-look-at "v2 =")))
1915 (should (= (save-excursion
1916 (python-nav-forward-statement)
1917 (point))
1918 (python-tests-look-at "v3 =")))
1919 (should (= (save-excursion
1920 (python-nav-forward-statement)
1921 (point))
1922 (python-tests-look-at "v4 =")))
1923 (should (= (save-excursion
1924 (python-nav-forward-statement)
1925 (point))
1926 (point-max)))))
1928 (ert-deftest python-nav-backward-statement-1 ()
1929 (python-tests-with-temp-buffer
1931 v1 = 123 + \
1932 456 + \
1934 v2 = (value1,
1935 value2,
1937 value3,
1938 value4)
1939 v3 = ('this is a string'
1941 'that is continued'
1942 'between lines'
1943 'within a paren',
1944 # this is a comment, yo
1945 'continue previous line')
1946 v4 = '''
1947 a very long
1948 string
1951 (goto-char (point-max))
1952 (should (= (save-excursion
1953 (python-nav-backward-statement)
1954 (point))
1955 (python-tests-look-at "v4 =" -1)))
1956 (should (= (save-excursion
1957 (python-nav-backward-statement)
1958 (point))
1959 (python-tests-look-at "v3 =" -1)))
1960 (should (= (save-excursion
1961 (python-nav-backward-statement)
1962 (point))
1963 (python-tests-look-at "v2 =" -1)))
1964 (should (= (save-excursion
1965 (python-nav-backward-statement)
1966 (point))
1967 (python-tests-look-at "v1 =" -1)))))
1969 (ert-deftest python-nav-backward-statement-2 ()
1970 :expected-result :failed
1971 (python-tests-with-temp-buffer
1973 v1 = 123 + \
1974 456 + \
1976 v2 = (value1,
1977 value2,
1979 value3,
1980 value4)
1982 ;; FIXME: For some reason `python-nav-backward-statement' is moving
1983 ;; back two sentences when starting from 'value4)'.
1984 (goto-char (point-max))
1985 (python-util-forward-comment -1)
1986 (should (= (save-excursion
1987 (python-nav-backward-statement)
1988 (point))
1989 (python-tests-look-at "v2 =" -1 t)))))
1991 (ert-deftest python-nav-beginning-of-block-1 ()
1992 (python-tests-with-temp-buffer
1994 def decoratorFunctionWithArguments(arg1, arg2, arg3):
1995 '''print decorated function call data to stdout.
1997 Usage:
1999 @decoratorFunctionWithArguments('arg1', 'arg2')
2000 def func(a, b, c=True):
2001 pass
2004 def wwrap(f):
2005 print 'Inside wwrap()'
2006 def wrapped_f(*args):
2007 print 'Inside wrapped_f()'
2008 print 'Decorator arguments:', arg1, arg2, arg3
2009 f(*args)
2010 print 'After f(*args)'
2011 return wrapped_f
2012 return wwrap
2014 (python-tests-look-at "return wwrap")
2015 (should (= (save-excursion
2016 (python-nav-beginning-of-block)
2017 (point))
2018 (python-tests-look-at "def decoratorFunctionWithArguments" -1)))
2019 (python-tests-look-at "print 'Inside wwrap()'")
2020 (should (= (save-excursion
2021 (python-nav-beginning-of-block)
2022 (point))
2023 (python-tests-look-at "def wwrap(f):" -1)))
2024 (python-tests-look-at "print 'After f(*args)'")
2025 (end-of-line)
2026 (should (= (save-excursion
2027 (python-nav-beginning-of-block)
2028 (point))
2029 (python-tests-look-at "def wrapped_f(*args):" -1)))
2030 (python-tests-look-at "return wrapped_f")
2031 (should (= (save-excursion
2032 (python-nav-beginning-of-block)
2033 (point))
2034 (python-tests-look-at "def wwrap(f):" -1)))))
2036 (ert-deftest python-nav-end-of-block-1 ()
2037 (python-tests-with-temp-buffer
2039 def decoratorFunctionWithArguments(arg1, arg2, arg3):
2040 '''print decorated function call data to stdout.
2042 Usage:
2044 @decoratorFunctionWithArguments('arg1', 'arg2')
2045 def func(a, b, c=True):
2046 pass
2049 def wwrap(f):
2050 print 'Inside wwrap()'
2051 def wrapped_f(*args):
2052 print 'Inside wrapped_f()'
2053 print 'Decorator arguments:', arg1, arg2, arg3
2054 f(*args)
2055 print 'After f(*args)'
2056 return wrapped_f
2057 return wwrap
2059 (python-tests-look-at "def decoratorFunctionWithArguments")
2060 (should (= (save-excursion
2061 (python-nav-end-of-block)
2062 (point))
2063 (save-excursion
2064 (goto-char (point-max))
2065 (python-util-forward-comment -1)
2066 (point))))
2067 (python-tests-look-at "def wwrap(f):")
2068 (should (= (save-excursion
2069 (python-nav-end-of-block)
2070 (point))
2071 (save-excursion
2072 (python-tests-look-at "return wrapped_f")
2073 (line-end-position))))
2074 (end-of-line)
2075 (should (= (save-excursion
2076 (python-nav-end-of-block)
2077 (point))
2078 (save-excursion
2079 (python-tests-look-at "return wrapped_f")
2080 (line-end-position))))
2081 (python-tests-look-at "f(*args)")
2082 (should (= (save-excursion
2083 (python-nav-end-of-block)
2084 (point))
2085 (save-excursion
2086 (python-tests-look-at "print 'After f(*args)'")
2087 (line-end-position))))))
2089 (ert-deftest python-nav-forward-block-1 ()
2090 "This also accounts as a test for `python-nav-backward-block'."
2091 (python-tests-with-temp-buffer
2093 if request.user.is_authenticated():
2094 # def block():
2095 # pass
2096 try:
2097 profile = request.user.get_profile()
2098 except Profile.DoesNotExist:
2099 profile = Profile.objects.create(user=request.user)
2100 else:
2101 if profile.stats:
2102 profile.recalculate_stats()
2103 else:
2104 profile.clear_stats()
2105 finally:
2106 profile.views += 1
2107 profile.save()
2109 (should (= (save-excursion (python-nav-forward-block))
2110 (python-tests-look-at "if request.user.is_authenticated():")))
2111 (should (= (save-excursion (python-nav-forward-block))
2112 (python-tests-look-at "try:")))
2113 (should (= (save-excursion (python-nav-forward-block))
2114 (python-tests-look-at "except Profile.DoesNotExist:")))
2115 (should (= (save-excursion (python-nav-forward-block))
2116 (python-tests-look-at "else:")))
2117 (should (= (save-excursion (python-nav-forward-block))
2118 (python-tests-look-at "if profile.stats:")))
2119 (should (= (save-excursion (python-nav-forward-block))
2120 (python-tests-look-at "else:")))
2121 (should (= (save-excursion (python-nav-forward-block))
2122 (python-tests-look-at "finally:")))
2123 ;; When point is at the last block, leave it there and return nil
2124 (should (not (save-excursion (python-nav-forward-block))))
2125 ;; Move backwards, and even if the number of moves is less than the
2126 ;; provided argument return the point.
2127 (should (= (save-excursion (python-nav-forward-block -10))
2128 (python-tests-look-at
2129 "if request.user.is_authenticated():" -1)))))
2131 (ert-deftest python-nav-forward-sexp-1 ()
2132 (python-tests-with-temp-buffer
2138 (python-tests-look-at "a()")
2139 (python-nav-forward-sexp)
2140 (should (looking-at "$"))
2141 (should (save-excursion
2142 (beginning-of-line)
2143 (looking-at "a()")))
2144 (python-nav-forward-sexp)
2145 (should (looking-at "$"))
2146 (should (save-excursion
2147 (beginning-of-line)
2148 (looking-at "b()")))
2149 (python-nav-forward-sexp)
2150 (should (looking-at "$"))
2151 (should (save-excursion
2152 (beginning-of-line)
2153 (looking-at "c()")))
2154 ;; The default behavior when next to a paren should do what lisp
2155 ;; does and, otherwise `blink-matching-open' breaks.
2156 (python-nav-forward-sexp -1)
2157 (should (looking-at "()"))
2158 (should (save-excursion
2159 (beginning-of-line)
2160 (looking-at "c()")))
2161 (end-of-line)
2162 ;; Skipping parens should jump to `bolp'
2163 (python-nav-forward-sexp -1 nil t)
2164 (should (looking-at "c()"))
2165 (forward-line -1)
2166 (end-of-line)
2167 ;; b()
2168 (python-nav-forward-sexp -1)
2169 (should (looking-at "()"))
2170 (python-nav-forward-sexp -1)
2171 (should (looking-at "b()"))
2172 (end-of-line)
2173 (python-nav-forward-sexp -1 nil t)
2174 (should (looking-at "b()"))
2175 (forward-line -1)
2176 (end-of-line)
2177 ;; a()
2178 (python-nav-forward-sexp -1)
2179 (should (looking-at "()"))
2180 (python-nav-forward-sexp -1)
2181 (should (looking-at "a()"))
2182 (end-of-line)
2183 (python-nav-forward-sexp -1 nil t)
2184 (should (looking-at "a()"))))
2186 (ert-deftest python-nav-forward-sexp-2 ()
2187 (python-tests-with-temp-buffer
2189 def func():
2190 if True:
2191 aaa = bbb
2192 ccc = ddd
2193 eee = fff
2194 return ggg
2196 (python-tests-look-at "aa =")
2197 (python-nav-forward-sexp)
2198 (should (looking-at " = bbb"))
2199 (python-nav-forward-sexp)
2200 (should (looking-at "$"))
2201 (should (save-excursion
2202 (back-to-indentation)
2203 (looking-at "aaa = bbb")))
2204 (python-nav-forward-sexp)
2205 (should (looking-at "$"))
2206 (should (save-excursion
2207 (back-to-indentation)
2208 (looking-at "ccc = ddd")))
2209 (python-nav-forward-sexp)
2210 (should (looking-at "$"))
2211 (should (save-excursion
2212 (back-to-indentation)
2213 (looking-at "eee = fff")))
2214 (python-nav-forward-sexp)
2215 (should (looking-at "$"))
2216 (should (save-excursion
2217 (back-to-indentation)
2218 (looking-at "return ggg")))
2219 (python-nav-forward-sexp -1)
2220 (should (looking-at "def func():"))))
2222 (ert-deftest python-nav-forward-sexp-3 ()
2223 (python-tests-with-temp-buffer
2225 from some_module import some_sub_module
2226 from another_module import another_sub_module
2228 def another_statement():
2229 pass
2231 (python-tests-look-at "some_module")
2232 (python-nav-forward-sexp)
2233 (should (looking-at " import"))
2234 (python-nav-forward-sexp)
2235 (should (looking-at " some_sub_module"))
2236 (python-nav-forward-sexp)
2237 (should (looking-at "$"))
2238 (should
2239 (save-excursion
2240 (back-to-indentation)
2241 (looking-at
2242 "from some_module import some_sub_module")))
2243 (python-nav-forward-sexp)
2244 (should (looking-at "$"))
2245 (should
2246 (save-excursion
2247 (back-to-indentation)
2248 (looking-at
2249 "from another_module import another_sub_module")))
2250 (python-nav-forward-sexp)
2251 (should (looking-at "$"))
2252 (should
2253 (save-excursion
2254 (back-to-indentation)
2255 (looking-at
2256 "pass")))
2257 (python-nav-forward-sexp -1)
2258 (should (looking-at "def another_statement():"))
2259 (python-nav-forward-sexp -1)
2260 (should (looking-at "from another_module import another_sub_module"))
2261 (python-nav-forward-sexp -1)
2262 (should (looking-at "from some_module import some_sub_module"))))
2264 (ert-deftest python-nav-forward-sexp-safe-1 ()
2265 (python-tests-with-temp-buffer
2267 profile = Profile.objects.create(user=request.user)
2268 profile.notify()
2270 (python-tests-look-at "profile =")
2271 (python-nav-forward-sexp-safe 1)
2272 (should (looking-at "$"))
2273 (beginning-of-line 1)
2274 (python-tests-look-at "user=request.user")
2275 (python-nav-forward-sexp-safe -1)
2276 (should (looking-at "(user=request.user)"))
2277 (python-nav-forward-sexp-safe -4)
2278 (should (looking-at "profile ="))
2279 (python-tests-look-at "user=request.user")
2280 (python-nav-forward-sexp-safe 3)
2281 (should (looking-at ")"))
2282 (python-nav-forward-sexp-safe 1)
2283 (should (looking-at "$"))
2284 (python-nav-forward-sexp-safe 1)
2285 (should (looking-at "$"))))
2287 (ert-deftest python-nav-up-list-1 ()
2288 (python-tests-with-temp-buffer
2290 def f():
2291 if True:
2292 return [i for i in range(3)]
2294 (python-tests-look-at "3)]")
2295 (python-nav-up-list)
2296 (should (looking-at "]"))
2297 (python-nav-up-list)
2298 (should (looking-at "$"))))
2300 (ert-deftest python-nav-backward-up-list-1 ()
2301 :expected-result :failed
2302 (python-tests-with-temp-buffer
2304 def f():
2305 if True:
2306 return [i for i in range(3)]
2308 (python-tests-look-at "3)]")
2309 (python-nav-backward-up-list)
2310 (should (looking-at "(3)\\]"))
2311 (python-nav-backward-up-list)
2312 (should (looking-at
2313 "\\[i for i in range(3)\\]"))
2314 ;; FIXME: Need to move to beginning-of-statement.
2315 (python-nav-backward-up-list)
2316 (should (looking-at
2317 "return \\[i for i in range(3)\\]"))
2318 (python-nav-backward-up-list)
2319 (should (looking-at "if True:"))
2320 (python-nav-backward-up-list)
2321 (should (looking-at "def f():"))))
2323 (ert-deftest python-indent-dedent-line-backspace-1 ()
2324 "Check de-indentation on first call. Bug#18319."
2325 (python-tests-with-temp-buffer
2327 if True:
2328 x ()
2329 if False:
2331 (python-tests-look-at "if False:")
2332 (call-interactively #'python-indent-dedent-line-backspace)
2333 (should (zerop (current-indentation)))
2334 ;; XXX: This should be a call to `undo' but it's triggering errors.
2335 (insert " ")
2336 (should (= (current-indentation) 4))
2337 (call-interactively #'python-indent-dedent-line-backspace)
2338 (should (zerop (current-indentation)))))
2340 (ert-deftest python-indent-dedent-line-backspace-2 ()
2341 "Check de-indentation with tabs. Bug#19730."
2342 (let ((tab-width 8))
2343 (python-tests-with-temp-buffer
2345 if x:
2346 \tabcdefg
2348 (python-tests-look-at "abcdefg")
2349 (goto-char (line-end-position))
2350 (call-interactively #'python-indent-dedent-line-backspace)
2351 (should
2352 (string= (buffer-substring-no-properties
2353 (line-beginning-position) (line-end-position))
2354 "\tabcdef")))))
2356 (ert-deftest python-indent-dedent-line-backspace-3 ()
2357 "Paranoid check of de-indentation with tabs. Bug#19730."
2358 (let ((tab-width 8))
2359 (python-tests-with-temp-buffer
2361 if x:
2362 \tif y:
2363 \t abcdefg
2365 (python-tests-look-at "abcdefg")
2366 (goto-char (line-end-position))
2367 (call-interactively #'python-indent-dedent-line-backspace)
2368 (should
2369 (string= (buffer-substring-no-properties
2370 (line-beginning-position) (line-end-position))
2371 "\t abcdef"))
2372 (back-to-indentation)
2373 (call-interactively #'python-indent-dedent-line-backspace)
2374 (should
2375 (string= (buffer-substring-no-properties
2376 (line-beginning-position) (line-end-position))
2377 "\tabcdef"))
2378 (call-interactively #'python-indent-dedent-line-backspace)
2379 (should
2380 (string= (buffer-substring-no-properties
2381 (line-beginning-position) (line-end-position))
2382 " abcdef"))
2383 (call-interactively #'python-indent-dedent-line-backspace)
2384 (should
2385 (string= (buffer-substring-no-properties
2386 (line-beginning-position) (line-end-position))
2387 "abcdef")))))
2390 ;;; Shell integration
2392 (defvar python-tests-shell-interpreter "python")
2394 (ert-deftest python-shell-get-process-name-1 ()
2395 "Check process name calculation sans `buffer-file-name'."
2396 (python-tests-with-temp-buffer
2398 (should (string= (python-shell-get-process-name nil)
2399 python-shell-buffer-name))
2400 (should (string= (python-shell-get-process-name t)
2401 (format "%s[%s]" python-shell-buffer-name (buffer-name))))))
2403 (ert-deftest python-shell-get-process-name-2 ()
2404 "Check process name calculation with `buffer-file-name'."
2405 (python-tests-with-temp-file
2407 ;; `buffer-file-name' is non-nil but the dedicated flag is nil and
2408 ;; should be respected.
2409 (should (string= (python-shell-get-process-name nil)
2410 python-shell-buffer-name))
2411 (should (string=
2412 (python-shell-get-process-name t)
2413 (format "%s[%s]" python-shell-buffer-name (buffer-name))))))
2415 (ert-deftest python-shell-internal-get-process-name-1 ()
2416 "Check the internal process name is buffer-unique sans `buffer-file-name'."
2417 (python-tests-with-temp-buffer
2419 (should (string= (python-shell-internal-get-process-name)
2420 (format "%s[%s]" python-shell-internal-buffer-name (buffer-name))))))
2422 (ert-deftest python-shell-internal-get-process-name-2 ()
2423 "Check the internal process name is buffer-unique with `buffer-file-name'."
2424 (python-tests-with-temp-file
2426 (should (string= (python-shell-internal-get-process-name)
2427 (format "%s[%s]" python-shell-internal-buffer-name (buffer-name))))))
2429 (ert-deftest python-shell-calculate-command-1 ()
2430 "Check the command to execute is calculated correctly.
2431 Using `python-shell-interpreter' and
2432 `python-shell-interpreter-args'."
2433 (skip-unless (executable-find python-tests-shell-interpreter))
2434 (let ((python-shell-interpreter (executable-find
2435 python-tests-shell-interpreter))
2436 (python-shell-interpreter-args "-B"))
2437 (should (string=
2438 (format "%s %s"
2439 python-shell-interpreter
2440 python-shell-interpreter-args)
2441 (python-shell-calculate-command)))))
2443 (ert-deftest python-shell-calculate-process-environment-1 ()
2444 "Test `python-shell-process-environment' modification."
2445 (let* ((python-shell-process-environment
2446 '("TESTVAR1=value1" "TESTVAR2=value2"))
2447 (process-environment
2448 (python-shell-calculate-process-environment)))
2449 (should (equal (getenv "TESTVAR1") "value1"))
2450 (should (equal (getenv "TESTVAR2") "value2"))))
2452 (ert-deftest python-shell-calculate-process-environment-2 ()
2453 "Test `python-shell-extra-pythonpaths' modification."
2454 (let* ((process-environment process-environment)
2455 (original-pythonpath (setenv "PYTHONPATH" "path3"))
2456 (paths '("path1" "path2"))
2457 (python-shell-extra-pythonpaths paths)
2458 (process-environment
2459 (python-shell-calculate-process-environment)))
2460 (should (equal (getenv "PYTHONPATH")
2461 (concat
2462 (mapconcat 'identity paths path-separator)
2463 path-separator original-pythonpath)))))
2465 (ert-deftest python-shell-calculate-process-environment-3 ()
2466 "Test `python-shell-virtualenv-root' modification."
2467 (let* ((python-shell-virtualenv-root
2468 (directory-file-name user-emacs-directory))
2469 (process-environment
2470 (python-shell-calculate-process-environment)))
2471 (should (not (getenv "PYTHONHOME")))
2472 (should (string= (getenv "VIRTUAL_ENV") python-shell-virtualenv-root))))
2474 (ert-deftest python-shell-calculate-process-environment-4 ()
2475 "Test `python-shell-unbuffered' modification."
2476 (setenv "PYTHONUNBUFFERED")
2477 (let* ((process-environment
2478 (python-shell-calculate-process-environment)))
2479 ;; Defaults to t
2480 (should python-shell-unbuffered)
2481 (should (string= (getenv "PYTHONUNBUFFERED") "1"))))
2483 (ert-deftest python-shell-calculate-process-environment-5 ()
2484 (setenv "PYTHONUNBUFFERED")
2485 "Test `python-shell-unbuffered' modification."
2486 (let* ((python-shell-unbuffered nil)
2487 (process-environment
2488 (python-shell-calculate-process-environment)))
2489 (should (not (getenv "PYTHONUNBUFFERED")))))
2491 (ert-deftest python-shell-calculate-exec-path-1 ()
2492 "Test `python-shell-exec-path' modification."
2493 (let* ((original-exec-path exec-path)
2494 (python-shell-exec-path '("path1" "path2"))
2495 (exec-path (python-shell-calculate-exec-path)))
2496 (should (equal
2497 exec-path
2498 (append python-shell-exec-path
2499 original-exec-path)))))
2501 (ert-deftest python-shell-calculate-exec-path-2 ()
2502 "Test `python-shell-virtualenv-root' modification."
2503 (let* ((original-exec-path exec-path)
2504 (python-shell-virtualenv-root
2505 (directory-file-name (expand-file-name user-emacs-directory)))
2506 (exec-path (python-shell-calculate-exec-path)))
2507 (should (equal
2508 exec-path
2509 (append (cons
2510 (format "%s/bin" python-shell-virtualenv-root)
2511 original-exec-path))))))
2513 (ert-deftest python-shell-with-environment-1 ()
2514 "Test with local `default-directory'."
2515 (let* ((original-exec-path exec-path)
2516 (python-shell-virtualenv-root
2517 (directory-file-name (expand-file-name user-emacs-directory))))
2518 (python-shell-with-environment
2519 (should (equal
2520 exec-path
2521 (append (cons
2522 (format "%s/bin" python-shell-virtualenv-root)
2523 original-exec-path))))
2524 (should (not (getenv "PYTHONHOME")))
2525 (should (string= (getenv "VIRTUAL_ENV") python-shell-virtualenv-root)))))
2527 (ert-deftest python-shell-with-environment-2 ()
2528 "Test with remote `default-directory'."
2529 (let* ((default-directory "/ssh::/example/dir/")
2530 (original-exec-path tramp-remote-path)
2531 (original-process-environment tramp-remote-process-environment)
2532 (python-shell-virtualenv-root
2533 (directory-file-name (expand-file-name user-emacs-directory))))
2534 (python-shell-with-environment
2535 (should (equal
2536 tramp-remote-path
2537 (append (cons
2538 (format "%s/bin" python-shell-virtualenv-root)
2539 original-exec-path))))
2540 (let ((process-environment tramp-remote-process-environment))
2541 (should (not (getenv "PYTHONHOME")))
2542 (should (string= (getenv "VIRTUAL_ENV")
2543 python-shell-virtualenv-root))))))
2545 (ert-deftest python-shell-make-comint-1 ()
2546 "Check comint creation for global shell buffer."
2547 (skip-unless (executable-find python-tests-shell-interpreter))
2548 ;; The interpreter can get killed too quickly to allow it to clean
2549 ;; up the tempfiles that the default python-shell-setup-codes create,
2550 ;; so it leaves tempfiles behind, which is a minor irritation.
2551 (let* ((python-shell-setup-codes nil)
2552 (python-shell-interpreter
2553 (executable-find python-tests-shell-interpreter))
2554 (proc-name (python-shell-get-process-name nil))
2555 (shell-buffer
2556 (python-tests-with-temp-buffer
2557 "" (python-shell-make-comint
2558 (python-shell-calculate-command) proc-name)))
2559 (process (get-buffer-process shell-buffer)))
2560 (unwind-protect
2561 (progn
2562 (set-process-query-on-exit-flag process nil)
2563 (should (process-live-p process))
2564 (with-current-buffer shell-buffer
2565 (should (eq major-mode 'inferior-python-mode))
2566 (should (string= (buffer-name) (format "*%s*" proc-name)))))
2567 (kill-buffer shell-buffer))))
2569 (ert-deftest python-shell-make-comint-2 ()
2570 "Check comint creation for internal shell buffer."
2571 (skip-unless (executable-find python-tests-shell-interpreter))
2572 (let* ((python-shell-setup-codes nil)
2573 (python-shell-interpreter
2574 (executable-find python-tests-shell-interpreter))
2575 (proc-name (python-shell-internal-get-process-name))
2576 (shell-buffer
2577 (python-tests-with-temp-buffer
2578 "" (python-shell-make-comint
2579 (python-shell-calculate-command) proc-name nil t)))
2580 (process (get-buffer-process shell-buffer)))
2581 (unwind-protect
2582 (progn
2583 (set-process-query-on-exit-flag process nil)
2584 (should (process-live-p process))
2585 (with-current-buffer shell-buffer
2586 (should (eq major-mode 'inferior-python-mode))
2587 (should (string= (buffer-name) (format " *%s*" proc-name)))))
2588 (kill-buffer shell-buffer))))
2590 (ert-deftest python-shell-make-comint-3 ()
2591 "Check comint creation with overridden python interpreter and args.
2592 The command passed to `python-shell-make-comint' as argument must
2593 locally override global values set in `python-shell-interpreter'
2594 and `python-shell-interpreter-args' in the new shell buffer."
2595 (skip-unless (executable-find python-tests-shell-interpreter))
2596 (let* ((python-shell-setup-codes nil)
2597 (python-shell-interpreter "interpreter")
2598 (python-shell-interpreter-args "--some-args")
2599 (proc-name (python-shell-get-process-name nil))
2600 (interpreter-override
2601 (concat (executable-find python-tests-shell-interpreter) " " "-i"))
2602 (shell-buffer
2603 (python-tests-with-temp-buffer
2604 "" (python-shell-make-comint interpreter-override proc-name nil)))
2605 (process (get-buffer-process shell-buffer)))
2606 (unwind-protect
2607 (progn
2608 (set-process-query-on-exit-flag process nil)
2609 (should (process-live-p process))
2610 (with-current-buffer shell-buffer
2611 (should (eq major-mode 'inferior-python-mode))
2612 (should (file-equal-p
2613 python-shell-interpreter
2614 (executable-find python-tests-shell-interpreter)))
2615 (should (string= python-shell-interpreter-args "-i"))))
2616 (kill-buffer shell-buffer))))
2618 (ert-deftest python-shell-make-comint-4 ()
2619 "Check shell calculated prompts regexps are set."
2620 (skip-unless (executable-find python-tests-shell-interpreter))
2621 (let* ((process-environment process-environment)
2622 (python-shell-setup-codes nil)
2623 (python-shell-interpreter
2624 (executable-find python-tests-shell-interpreter))
2625 (python-shell-interpreter-args "-i")
2626 (python-shell--prompt-calculated-input-regexp nil)
2627 (python-shell--prompt-calculated-output-regexp nil)
2628 (python-shell-prompt-detect-enabled t)
2629 (python-shell-prompt-input-regexps '("extralargeinputprompt" "sml"))
2630 (python-shell-prompt-output-regexps '("extralargeoutputprompt" "sml"))
2631 (python-shell-prompt-regexp "in")
2632 (python-shell-prompt-block-regexp "block")
2633 (python-shell-prompt-pdb-regexp "pdf")
2634 (python-shell-prompt-output-regexp "output")
2635 (startup-code (concat "import sys\n"
2636 "sys.ps1 = 'py> '\n"
2637 "sys.ps2 = '..> '\n"
2638 "sys.ps3 = 'out '\n"))
2639 (startup-file (python-shell--save-temp-file startup-code))
2640 (proc-name (python-shell-get-process-name nil))
2641 (shell-buffer
2642 (progn
2643 (setenv "PYTHONSTARTUP" startup-file)
2644 (python-tests-with-temp-buffer
2645 "" (python-shell-make-comint
2646 (python-shell-calculate-command) proc-name nil))))
2647 (process (get-buffer-process shell-buffer)))
2648 (unwind-protect
2649 (progn
2650 (set-process-query-on-exit-flag process nil)
2651 (should (process-live-p process))
2652 (with-current-buffer shell-buffer
2653 (should (eq major-mode 'inferior-python-mode))
2654 (should (string=
2655 python-shell--prompt-calculated-input-regexp
2656 (concat "^\\(extralargeinputprompt\\|\\.\\.> \\|"
2657 "block\\|py> \\|pdf\\|sml\\|in\\)")))
2658 (should (string=
2659 python-shell--prompt-calculated-output-regexp
2660 "^\\(extralargeoutputprompt\\|output\\|out \\|sml\\)"))))
2661 (delete-file startup-file)
2662 (kill-buffer shell-buffer))))
2664 (ert-deftest python-shell-get-process-1 ()
2665 "Check dedicated shell process preference over global."
2666 (skip-unless (executable-find python-tests-shell-interpreter))
2667 (python-tests-with-temp-file
2669 (let* ((python-shell-setup-codes nil)
2670 (python-shell-interpreter
2671 (executable-find python-tests-shell-interpreter))
2672 (global-proc-name (python-shell-get-process-name nil))
2673 (dedicated-proc-name (python-shell-get-process-name t))
2674 (global-shell-buffer
2675 (python-shell-make-comint
2676 (python-shell-calculate-command) global-proc-name))
2677 (dedicated-shell-buffer
2678 (python-shell-make-comint
2679 (python-shell-calculate-command) dedicated-proc-name))
2680 (global-process (get-buffer-process global-shell-buffer))
2681 (dedicated-process (get-buffer-process dedicated-shell-buffer)))
2682 (unwind-protect
2683 (progn
2684 (set-process-query-on-exit-flag global-process nil)
2685 (set-process-query-on-exit-flag dedicated-process nil)
2686 ;; Prefer dedicated if global also exists.
2687 (should (equal (python-shell-get-process) dedicated-process))
2688 (kill-buffer dedicated-shell-buffer)
2689 ;; If there's only global, use it.
2690 (should (equal (python-shell-get-process) global-process))
2691 (kill-buffer global-shell-buffer)
2692 ;; No buffer available.
2693 (should (not (python-shell-get-process))))
2694 (ignore-errors (kill-buffer global-shell-buffer))
2695 (ignore-errors (kill-buffer dedicated-shell-buffer))))))
2697 (ert-deftest python-shell-internal-get-or-create-process-1 ()
2698 "Check internal shell process creation fallback."
2699 (skip-unless (executable-find python-tests-shell-interpreter))
2700 (python-tests-with-temp-file
2702 (should (not (process-live-p (python-shell-internal-get-process-name))))
2703 (let* ((python-shell-interpreter
2704 (executable-find python-tests-shell-interpreter))
2705 (internal-process-name (python-shell-internal-get-process-name))
2706 (internal-process (python-shell-internal-get-or-create-process))
2707 (internal-shell-buffer (process-buffer internal-process)))
2708 (unwind-protect
2709 (progn
2710 (set-process-query-on-exit-flag internal-process nil)
2711 (should (equal (process-name internal-process)
2712 internal-process-name))
2713 (should (equal internal-process
2714 (python-shell-internal-get-or-create-process)))
2715 ;; Assert the internal process is not a user process
2716 (should (not (python-shell-get-process)))
2717 (kill-buffer internal-shell-buffer))
2718 (ignore-errors (kill-buffer internal-shell-buffer))))))
2720 (ert-deftest python-shell-prompt-detect-1 ()
2721 "Check prompt autodetection."
2722 (skip-unless (executable-find python-tests-shell-interpreter))
2723 (let ((process-environment process-environment))
2724 ;; Ensure no startup file is enabled
2725 (setenv "PYTHONSTARTUP" "")
2726 (should python-shell-prompt-detect-enabled)
2727 (should (equal (python-shell-prompt-detect) '(">>> " "... " "")))))
2729 (ert-deftest python-shell-prompt-detect-2 ()
2730 "Check prompt autodetection with startup file. Bug#17370."
2731 (skip-unless (executable-find python-tests-shell-interpreter))
2732 (let* ((process-environment process-environment)
2733 (startup-code (concat "import sys\n"
2734 "sys.ps1 = 'py> '\n"
2735 "sys.ps2 = '..> '\n"
2736 "sys.ps3 = 'out '\n"))
2737 (startup-file (python-shell--save-temp-file startup-code)))
2738 (unwind-protect
2739 (progn
2740 ;; Ensure startup file is enabled
2741 (setenv "PYTHONSTARTUP" startup-file)
2742 (should python-shell-prompt-detect-enabled)
2743 (should (equal (python-shell-prompt-detect) '("py> " "..> " "out "))))
2744 (ignore-errors (delete-file startup-file)))))
2746 (ert-deftest python-shell-prompt-detect-3 ()
2747 "Check prompts are not autodetected when feature is disabled."
2748 (skip-unless (executable-find python-tests-shell-interpreter))
2749 (let ((process-environment process-environment)
2750 (python-shell-prompt-detect-enabled nil))
2751 ;; Ensure no startup file is enabled
2752 (should (not python-shell-prompt-detect-enabled))
2753 (should (not (python-shell-prompt-detect)))))
2755 (ert-deftest python-shell-prompt-detect-4 ()
2756 "Check warning is shown when detection fails."
2757 (skip-unless (executable-find python-tests-shell-interpreter))
2758 (let* ((process-environment process-environment)
2759 ;; Trigger failure by removing prompts in the startup file
2760 (startup-code (concat "import sys\n"
2761 "sys.ps1 = ''\n"
2762 "sys.ps2 = ''\n"
2763 "sys.ps3 = ''\n"))
2764 (startup-file (python-shell--save-temp-file startup-code)))
2765 (unwind-protect
2766 (progn
2767 (kill-buffer (get-buffer-create "*Warnings*"))
2768 (should (not (get-buffer "*Warnings*")))
2769 (setenv "PYTHONSTARTUP" startup-file)
2770 (should python-shell-prompt-detect-failure-warning)
2771 (should python-shell-prompt-detect-enabled)
2772 (should (not (python-shell-prompt-detect)))
2773 (should (get-buffer "*Warnings*")))
2774 (ignore-errors (delete-file startup-file)))))
2776 (ert-deftest python-shell-prompt-detect-5 ()
2777 "Check disabled warnings are not shown when detection fails."
2778 (skip-unless (executable-find python-tests-shell-interpreter))
2779 (let* ((process-environment process-environment)
2780 (startup-code (concat "import sys\n"
2781 "sys.ps1 = ''\n"
2782 "sys.ps2 = ''\n"
2783 "sys.ps3 = ''\n"))
2784 (startup-file (python-shell--save-temp-file startup-code))
2785 (python-shell-prompt-detect-failure-warning nil))
2786 (unwind-protect
2787 (progn
2788 (kill-buffer (get-buffer-create "*Warnings*"))
2789 (should (not (get-buffer "*Warnings*")))
2790 (setenv "PYTHONSTARTUP" startup-file)
2791 (should (not python-shell-prompt-detect-failure-warning))
2792 (should python-shell-prompt-detect-enabled)
2793 (should (not (python-shell-prompt-detect)))
2794 (should (not (get-buffer "*Warnings*"))))
2795 (ignore-errors (delete-file startup-file)))))
2797 (ert-deftest python-shell-prompt-detect-6 ()
2798 "Warnings are not shown when detection is disabled."
2799 (skip-unless (executable-find python-tests-shell-interpreter))
2800 (let* ((process-environment process-environment)
2801 (startup-code (concat "import sys\n"
2802 "sys.ps1 = ''\n"
2803 "sys.ps2 = ''\n"
2804 "sys.ps3 = ''\n"))
2805 (startup-file (python-shell--save-temp-file startup-code))
2806 (python-shell-prompt-detect-failure-warning t)
2807 (python-shell-prompt-detect-enabled nil))
2808 (unwind-protect
2809 (progn
2810 (kill-buffer (get-buffer-create "*Warnings*"))
2811 (should (not (get-buffer "*Warnings*")))
2812 (setenv "PYTHONSTARTUP" startup-file)
2813 (should python-shell-prompt-detect-failure-warning)
2814 (should (not python-shell-prompt-detect-enabled))
2815 (should (not (python-shell-prompt-detect)))
2816 (should (not (get-buffer "*Warnings*"))))
2817 (ignore-errors (delete-file startup-file)))))
2819 (ert-deftest python-shell-prompt-validate-regexps-1 ()
2820 "Check `python-shell-prompt-input-regexps' are validated."
2821 (let* ((python-shell-prompt-input-regexps '("\\("))
2822 (error-data (should-error (python-shell-prompt-validate-regexps)
2823 :type 'user-error)))
2824 (should
2825 (string= (cadr error-data)
2826 "Invalid regexp \\( in `python-shell-prompt-input-regexps'"))))
2828 (ert-deftest python-shell-prompt-validate-regexps-2 ()
2829 "Check `python-shell-prompt-output-regexps' are validated."
2830 (let* ((python-shell-prompt-output-regexps '("\\("))
2831 (error-data (should-error (python-shell-prompt-validate-regexps)
2832 :type 'user-error)))
2833 (should
2834 (string= (cadr error-data)
2835 "Invalid regexp \\( in `python-shell-prompt-output-regexps'"))))
2837 (ert-deftest python-shell-prompt-validate-regexps-3 ()
2838 "Check `python-shell-prompt-regexp' is validated."
2839 (let* ((python-shell-prompt-regexp "\\(")
2840 (error-data (should-error (python-shell-prompt-validate-regexps)
2841 :type 'user-error)))
2842 (should
2843 (string= (cadr error-data)
2844 "Invalid regexp \\( in `python-shell-prompt-regexp'"))))
2846 (ert-deftest python-shell-prompt-validate-regexps-4 ()
2847 "Check `python-shell-prompt-block-regexp' is validated."
2848 (let* ((python-shell-prompt-block-regexp "\\(")
2849 (error-data (should-error (python-shell-prompt-validate-regexps)
2850 :type 'user-error)))
2851 (should
2852 (string= (cadr error-data)
2853 "Invalid regexp \\( in `python-shell-prompt-block-regexp'"))))
2855 (ert-deftest python-shell-prompt-validate-regexps-5 ()
2856 "Check `python-shell-prompt-pdb-regexp' is validated."
2857 (let* ((python-shell-prompt-pdb-regexp "\\(")
2858 (error-data (should-error (python-shell-prompt-validate-regexps)
2859 :type 'user-error)))
2860 (should
2861 (string= (cadr error-data)
2862 "Invalid regexp \\( in `python-shell-prompt-pdb-regexp'"))))
2864 (ert-deftest python-shell-prompt-validate-regexps-6 ()
2865 "Check `python-shell-prompt-output-regexp' is validated."
2866 (let* ((python-shell-prompt-output-regexp "\\(")
2867 (error-data (should-error (python-shell-prompt-validate-regexps)
2868 :type 'user-error)))
2869 (should
2870 (string= (cadr error-data)
2871 "Invalid regexp \\( in `python-shell-prompt-output-regexp'"))))
2873 (ert-deftest python-shell-prompt-validate-regexps-7 ()
2874 "Check default regexps are valid."
2875 ;; should not signal error
2876 (python-shell-prompt-validate-regexps))
2878 (ert-deftest python-shell-prompt-set-calculated-regexps-1 ()
2879 "Check regexps are validated."
2880 (let* ((python-shell-prompt-output-regexp '("\\("))
2881 (python-shell--prompt-calculated-input-regexp nil)
2882 (python-shell--prompt-calculated-output-regexp nil)
2883 (python-shell-prompt-detect-enabled nil)
2884 (error-data (should-error (python-shell-prompt-set-calculated-regexps)
2885 :type 'user-error)))
2886 (should
2887 (string= (cadr error-data)
2888 "Invalid regexp \\( in `python-shell-prompt-output-regexp'"))))
2890 (ert-deftest python-shell-prompt-set-calculated-regexps-2 ()
2891 "Check `python-shell-prompt-input-regexps' are set."
2892 (let* ((python-shell-prompt-input-regexps '("my" "prompt"))
2893 (python-shell-prompt-output-regexps '(""))
2894 (python-shell-prompt-regexp "")
2895 (python-shell-prompt-block-regexp "")
2896 (python-shell-prompt-pdb-regexp "")
2897 (python-shell-prompt-output-regexp "")
2898 (python-shell--prompt-calculated-input-regexp nil)
2899 (python-shell--prompt-calculated-output-regexp nil)
2900 (python-shell-prompt-detect-enabled nil))
2901 (python-shell-prompt-set-calculated-regexps)
2902 (should (string= python-shell--prompt-calculated-input-regexp
2903 "^\\(prompt\\|my\\|\\)"))))
2905 (ert-deftest python-shell-prompt-set-calculated-regexps-3 ()
2906 "Check `python-shell-prompt-output-regexps' are set."
2907 (let* ((python-shell-prompt-input-regexps '(""))
2908 (python-shell-prompt-output-regexps '("my" "prompt"))
2909 (python-shell-prompt-regexp "")
2910 (python-shell-prompt-block-regexp "")
2911 (python-shell-prompt-pdb-regexp "")
2912 (python-shell-prompt-output-regexp "")
2913 (python-shell--prompt-calculated-input-regexp nil)
2914 (python-shell--prompt-calculated-output-regexp nil)
2915 (python-shell-prompt-detect-enabled nil))
2916 (python-shell-prompt-set-calculated-regexps)
2917 (should (string= python-shell--prompt-calculated-output-regexp
2918 "^\\(prompt\\|my\\|\\)"))))
2920 (ert-deftest python-shell-prompt-set-calculated-regexps-4 ()
2921 "Check user defined prompts are set."
2922 (let* ((python-shell-prompt-input-regexps '(""))
2923 (python-shell-prompt-output-regexps '(""))
2924 (python-shell-prompt-regexp "prompt")
2925 (python-shell-prompt-block-regexp "block")
2926 (python-shell-prompt-pdb-regexp "pdb")
2927 (python-shell-prompt-output-regexp "output")
2928 (python-shell--prompt-calculated-input-regexp nil)
2929 (python-shell--prompt-calculated-output-regexp nil)
2930 (python-shell-prompt-detect-enabled nil))
2931 (python-shell-prompt-set-calculated-regexps)
2932 (should (string= python-shell--prompt-calculated-input-regexp
2933 "^\\(prompt\\|block\\|pdb\\|\\)"))
2934 (should (string= python-shell--prompt-calculated-output-regexp
2935 "^\\(output\\|\\)"))))
2937 (ert-deftest python-shell-prompt-set-calculated-regexps-5 ()
2938 "Check order of regexps (larger first)."
2939 (let* ((python-shell-prompt-input-regexps '("extralargeinputprompt" "sml"))
2940 (python-shell-prompt-output-regexps '("extralargeoutputprompt" "sml"))
2941 (python-shell-prompt-regexp "in")
2942 (python-shell-prompt-block-regexp "block")
2943 (python-shell-prompt-pdb-regexp "pdf")
2944 (python-shell-prompt-output-regexp "output")
2945 (python-shell--prompt-calculated-input-regexp nil)
2946 (python-shell--prompt-calculated-output-regexp nil)
2947 (python-shell-prompt-detect-enabled nil))
2948 (python-shell-prompt-set-calculated-regexps)
2949 (should (string= python-shell--prompt-calculated-input-regexp
2950 "^\\(extralargeinputprompt\\|block\\|pdf\\|sml\\|in\\)"))
2951 (should (string= python-shell--prompt-calculated-output-regexp
2952 "^\\(extralargeoutputprompt\\|output\\|sml\\)"))))
2954 (ert-deftest python-shell-prompt-set-calculated-regexps-6 ()
2955 "Check detected prompts are included `regexp-quote'd."
2956 (skip-unless (executable-find python-tests-shell-interpreter))
2957 (let* ((python-shell-prompt-input-regexps '(""))
2958 (python-shell-prompt-output-regexps '(""))
2959 (python-shell-prompt-regexp "")
2960 (python-shell-prompt-block-regexp "")
2961 (python-shell-prompt-pdb-regexp "")
2962 (python-shell-prompt-output-regexp "")
2963 (python-shell--prompt-calculated-input-regexp nil)
2964 (python-shell--prompt-calculated-output-regexp nil)
2965 (python-shell-prompt-detect-enabled t)
2966 (process-environment process-environment)
2967 (startup-code (concat "import sys\n"
2968 "sys.ps1 = 'p.> '\n"
2969 "sys.ps2 = '..> '\n"
2970 "sys.ps3 = 'o.t '\n"))
2971 (startup-file (python-shell--save-temp-file startup-code)))
2972 (unwind-protect
2973 (progn
2974 (setenv "PYTHONSTARTUP" startup-file)
2975 (python-shell-prompt-set-calculated-regexps)
2976 (should (string= python-shell--prompt-calculated-input-regexp
2977 "^\\(\\.\\.> \\|p\\.> \\|\\)"))
2978 (should (string= python-shell--prompt-calculated-output-regexp
2979 "^\\(o\\.t \\|\\)")))
2980 (ignore-errors (delete-file startup-file)))))
2982 (ert-deftest python-shell-buffer-substring-1 ()
2983 "Selecting a substring of the whole buffer must match its contents."
2984 (python-tests-with-temp-buffer
2986 class Foo(models.Model):
2987 pass
2990 class Bar(models.Model):
2991 pass
2993 (should (string= (buffer-string)
2994 (python-shell-buffer-substring (point-min) (point-max))))))
2996 (ert-deftest python-shell-buffer-substring-2 ()
2997 "Main block should be removed if NOMAIN is non-nil."
2998 (python-tests-with-temp-buffer
3000 class Foo(models.Model):
3001 pass
3003 class Bar(models.Model):
3004 pass
3006 if __name__ == \"__main__\":
3007 foo = Foo()
3008 print (foo)
3010 (should (string= (python-shell-buffer-substring (point-min) (point-max) t)
3012 class Foo(models.Model):
3013 pass
3015 class Bar(models.Model):
3016 pass
3021 "))))
3023 (ert-deftest python-shell-buffer-substring-3 ()
3024 "Main block should be removed if NOMAIN is non-nil."
3025 (python-tests-with-temp-buffer
3027 class Foo(models.Model):
3028 pass
3030 if __name__ == \"__main__\":
3031 foo = Foo()
3032 print (foo)
3034 class Bar(models.Model):
3035 pass
3037 (should (string= (python-shell-buffer-substring (point-min) (point-max) t)
3039 class Foo(models.Model):
3040 pass
3046 class Bar(models.Model):
3047 pass
3048 "))))
3050 (ert-deftest python-shell-buffer-substring-4 ()
3051 "Coding cookie should be added for substrings."
3052 (python-tests-with-temp-buffer
3053 "# coding: latin-1
3055 class Foo(models.Model):
3056 pass
3058 if __name__ == \"__main__\":
3059 foo = Foo()
3060 print (foo)
3062 class Bar(models.Model):
3063 pass
3065 (should (string= (python-shell-buffer-substring
3066 (python-tests-look-at "class Foo(models.Model):")
3067 (progn (python-nav-forward-sexp) (point)))
3068 "# -*- coding: latin-1 -*-
3070 class Foo(models.Model):
3071 pass"))))
3073 (ert-deftest python-shell-buffer-substring-5 ()
3074 "The proper amount of blank lines is added for a substring."
3075 (python-tests-with-temp-buffer
3076 "# coding: latin-1
3078 class Foo(models.Model):
3079 pass
3081 if __name__ == \"__main__\":
3082 foo = Foo()
3083 print (foo)
3085 class Bar(models.Model):
3086 pass
3088 (should (string= (python-shell-buffer-substring
3089 (python-tests-look-at "class Bar(models.Model):")
3090 (progn (python-nav-forward-sexp) (point)))
3091 "# -*- coding: latin-1 -*-
3100 class Bar(models.Model):
3101 pass"))))
3103 (ert-deftest python-shell-buffer-substring-6 ()
3104 "Handle substring with coding cookie in the second line."
3105 (python-tests-with-temp-buffer
3107 # coding: latin-1
3109 class Foo(models.Model):
3110 pass
3112 if __name__ == \"__main__\":
3113 foo = Foo()
3114 print (foo)
3116 class Bar(models.Model):
3117 pass
3119 (should (string= (python-shell-buffer-substring
3120 (python-tests-look-at "# coding: latin-1")
3121 (python-tests-look-at "if __name__ == \"__main__\":"))
3122 "# -*- coding: latin-1 -*-
3125 class Foo(models.Model):
3126 pass
3128 "))))
3130 (ert-deftest python-shell-buffer-substring-7 ()
3131 "Ensure first coding cookie gets precedence."
3132 (python-tests-with-temp-buffer
3133 "# coding: utf-8
3134 # coding: latin-1
3136 class Foo(models.Model):
3137 pass
3139 if __name__ == \"__main__\":
3140 foo = Foo()
3141 print (foo)
3143 class Bar(models.Model):
3144 pass
3146 (should (string= (python-shell-buffer-substring
3147 (python-tests-look-at "# coding: latin-1")
3148 (python-tests-look-at "if __name__ == \"__main__\":"))
3149 "# -*- coding: utf-8 -*-
3152 class Foo(models.Model):
3153 pass
3155 "))))
3157 (ert-deftest python-shell-buffer-substring-8 ()
3158 "Ensure first coding cookie gets precedence when sending whole buffer."
3159 (python-tests-with-temp-buffer
3160 "# coding: utf-8
3161 # coding: latin-1
3163 class Foo(models.Model):
3164 pass
3166 (should (string= (python-shell-buffer-substring (point-min) (point-max))
3167 "# coding: utf-8
3170 class Foo(models.Model):
3171 pass
3172 "))))
3174 (ert-deftest python-shell-buffer-substring-9 ()
3175 "Check substring starting from `point-min'."
3176 (python-tests-with-temp-buffer
3177 "# coding: utf-8
3179 class Foo(models.Model):
3180 pass
3182 class Bar(models.Model):
3183 pass
3185 (should (string= (python-shell-buffer-substring
3186 (point-min)
3187 (python-tests-look-at "class Bar(models.Model):"))
3188 "# coding: utf-8
3190 class Foo(models.Model):
3191 pass
3193 "))))
3196 ;;; Shell completion
3198 (ert-deftest python-shell-completion-native-interpreter-disabled-p-1 ()
3199 (let* ((python-shell-completion-native-disabled-interpreters (list "pypy"))
3200 (python-shell-interpreter "/some/path/to/bin/pypy"))
3201 (should (python-shell-completion-native-interpreter-disabled-p))))
3206 ;;; PDB Track integration
3209 ;;; Symbol completion
3212 ;;; Fill paragraph
3215 ;;; Skeletons
3218 ;;; FFAP
3221 ;;; Code check
3224 ;;; Eldoc
3226 (ert-deftest python-eldoc--get-symbol-at-point-1 ()
3227 "Test paren handling."
3228 (python-tests-with-temp-buffer
3230 map(xx
3231 map(codecs.open('somefile'
3233 (python-tests-look-at "ap(xx")
3234 (should (string= (python-eldoc--get-symbol-at-point) "map"))
3235 (goto-char (line-end-position))
3236 (should (string= (python-eldoc--get-symbol-at-point) "map"))
3237 (python-tests-look-at "('somefile'")
3238 (should (string= (python-eldoc--get-symbol-at-point) "map"))
3239 (goto-char (line-end-position))
3240 (should (string= (python-eldoc--get-symbol-at-point) "codecs.open"))))
3242 (ert-deftest python-eldoc--get-symbol-at-point-2 ()
3243 "Ensure self is replaced with the class name."
3244 (python-tests-with-temp-buffer
3246 class TheClass:
3248 def some_method(self, n):
3249 return n
3251 def other(self):
3252 return self.some_method(1234)
3255 (python-tests-look-at "self.some_method")
3256 (should (string= (python-eldoc--get-symbol-at-point)
3257 "TheClass.some_method"))
3258 (python-tests-look-at "1234)")
3259 (should (string= (python-eldoc--get-symbol-at-point)
3260 "TheClass.some_method"))))
3262 (ert-deftest python-eldoc--get-symbol-at-point-3 ()
3263 "Ensure symbol is found when point is at end of buffer."
3264 (python-tests-with-temp-buffer
3266 some_symbol
3269 (goto-char (point-max))
3270 (should (string= (python-eldoc--get-symbol-at-point)
3271 "some_symbol"))))
3273 (ert-deftest python-eldoc--get-symbol-at-point-4 ()
3274 "Ensure symbol is found when point is at whitespace."
3275 (python-tests-with-temp-buffer
3277 some_symbol some_other_symbol
3279 (python-tests-look-at " some_other_symbol")
3280 (should (string= (python-eldoc--get-symbol-at-point)
3281 "some_symbol"))))
3284 ;;; Imenu
3286 (ert-deftest python-imenu-create-index-1 ()
3287 (python-tests-with-temp-buffer
3289 class Foo(models.Model):
3290 pass
3293 class Bar(models.Model):
3294 pass
3297 def decorator(arg1, arg2, arg3):
3298 '''print decorated function call data to stdout.
3300 Usage:
3302 @decorator('arg1', 'arg2')
3303 def func(a, b, c=True):
3304 pass
3307 def wrap(f):
3308 print ('wrap')
3309 def wrapped_f(*args):
3310 print ('wrapped_f')
3311 print ('Decorator arguments:', arg1, arg2, arg3)
3312 f(*args)
3313 print ('called f(*args)')
3314 return wrapped_f
3315 return wrap
3318 class Baz(object):
3320 def a(self):
3321 pass
3323 def b(self):
3324 pass
3326 class Frob(object):
3328 def c(self):
3329 pass
3331 (goto-char (point-max))
3332 (should (equal
3333 (list
3334 (cons "Foo (class)" (copy-marker 2))
3335 (cons "Bar (class)" (copy-marker 38))
3336 (list
3337 "decorator (def)"
3338 (cons "*function definition*" (copy-marker 74))
3339 (list
3340 "wrap (def)"
3341 (cons "*function definition*" (copy-marker 254))
3342 (cons "wrapped_f (def)" (copy-marker 294))))
3343 (list
3344 "Baz (class)"
3345 (cons "*class definition*" (copy-marker 519))
3346 (cons "a (def)" (copy-marker 539))
3347 (cons "b (def)" (copy-marker 570))
3348 (list
3349 "Frob (class)"
3350 (cons "*class definition*" (copy-marker 601))
3351 (cons "c (def)" (copy-marker 626)))))
3352 (python-imenu-create-index)))))
3354 (ert-deftest python-imenu-create-index-2 ()
3355 (python-tests-with-temp-buffer
3357 class Foo(object):
3358 def foo(self):
3359 def foo1():
3360 pass
3362 def foobar(self):
3363 pass
3365 (goto-char (point-max))
3366 (should (equal
3367 (list
3368 (list
3369 "Foo (class)"
3370 (cons "*class definition*" (copy-marker 2))
3371 (list
3372 "foo (def)"
3373 (cons "*function definition*" (copy-marker 21))
3374 (cons "foo1 (def)" (copy-marker 40)))
3375 (cons "foobar (def)" (copy-marker 78))))
3376 (python-imenu-create-index)))))
3378 (ert-deftest python-imenu-create-index-3 ()
3379 (python-tests-with-temp-buffer
3381 class Foo(object):
3382 def foo(self):
3383 def foo1():
3384 pass
3385 def foo2():
3386 pass
3388 (goto-char (point-max))
3389 (should (equal
3390 (list
3391 (list
3392 "Foo (class)"
3393 (cons "*class definition*" (copy-marker 2))
3394 (list
3395 "foo (def)"
3396 (cons "*function definition*" (copy-marker 21))
3397 (cons "foo1 (def)" (copy-marker 40))
3398 (cons "foo2 (def)" (copy-marker 77)))))
3399 (python-imenu-create-index)))))
3401 (ert-deftest python-imenu-create-index-4 ()
3402 (python-tests-with-temp-buffer
3404 class Foo(object):
3405 class Bar(object):
3406 def __init__(self):
3407 pass
3409 def __str__(self):
3410 pass
3412 def __init__(self):
3413 pass
3415 (goto-char (point-max))
3416 (should (equal
3417 (list
3418 (list
3419 "Foo (class)"
3420 (cons "*class definition*" (copy-marker 2))
3421 (list
3422 "Bar (class)"
3423 (cons "*class definition*" (copy-marker 21))
3424 (cons "__init__ (def)" (copy-marker 44))
3425 (cons "__str__ (def)" (copy-marker 90)))
3426 (cons "__init__ (def)" (copy-marker 135))))
3427 (python-imenu-create-index)))))
3429 (ert-deftest python-imenu-create-flat-index-1 ()
3430 (python-tests-with-temp-buffer
3432 class Foo(models.Model):
3433 pass
3436 class Bar(models.Model):
3437 pass
3440 def decorator(arg1, arg2, arg3):
3441 '''print decorated function call data to stdout.
3443 Usage:
3445 @decorator('arg1', 'arg2')
3446 def func(a, b, c=True):
3447 pass
3450 def wrap(f):
3451 print ('wrap')
3452 def wrapped_f(*args):
3453 print ('wrapped_f')
3454 print ('Decorator arguments:', arg1, arg2, arg3)
3455 f(*args)
3456 print ('called f(*args)')
3457 return wrapped_f
3458 return wrap
3461 class Baz(object):
3463 def a(self):
3464 pass
3466 def b(self):
3467 pass
3469 class Frob(object):
3471 def c(self):
3472 pass
3474 (goto-char (point-max))
3475 (should (equal
3476 (list (cons "Foo" (copy-marker 2))
3477 (cons "Bar" (copy-marker 38))
3478 (cons "decorator" (copy-marker 74))
3479 (cons "decorator.wrap" (copy-marker 254))
3480 (cons "decorator.wrap.wrapped_f" (copy-marker 294))
3481 (cons "Baz" (copy-marker 519))
3482 (cons "Baz.a" (copy-marker 539))
3483 (cons "Baz.b" (copy-marker 570))
3484 (cons "Baz.Frob" (copy-marker 601))
3485 (cons "Baz.Frob.c" (copy-marker 626)))
3486 (python-imenu-create-flat-index)))))
3488 (ert-deftest python-imenu-create-flat-index-2 ()
3489 (python-tests-with-temp-buffer
3491 class Foo(object):
3492 class Bar(object):
3493 def __init__(self):
3494 pass
3496 def __str__(self):
3497 pass
3499 def __init__(self):
3500 pass
3502 (goto-char (point-max))
3503 (should (equal
3504 (list
3505 (cons "Foo" (copy-marker 2))
3506 (cons "Foo.Bar" (copy-marker 21))
3507 (cons "Foo.Bar.__init__" (copy-marker 44))
3508 (cons "Foo.Bar.__str__" (copy-marker 90))
3509 (cons "Foo.__init__" (copy-marker 135)))
3510 (python-imenu-create-flat-index)))))
3513 ;;; Misc helpers
3515 (ert-deftest python-info-current-defun-1 ()
3516 (python-tests-with-temp-buffer
3518 def foo(a, b):
3520 (forward-line 1)
3521 (should (string= "foo" (python-info-current-defun)))
3522 (should (string= "def foo" (python-info-current-defun t)))
3523 (forward-line 1)
3524 (should (not (python-info-current-defun)))
3525 (indent-for-tab-command)
3526 (should (string= "foo" (python-info-current-defun)))
3527 (should (string= "def foo" (python-info-current-defun t)))))
3529 (ert-deftest python-info-current-defun-2 ()
3530 (python-tests-with-temp-buffer
3532 class C(object):
3534 def m(self):
3535 if True:
3536 return [i for i in range(3)]
3537 else:
3538 return []
3540 def b():
3541 do_b()
3543 def a():
3544 do_a()
3546 def c(self):
3547 do_c()
3549 (forward-line 1)
3550 (should (string= "C" (python-info-current-defun)))
3551 (should (string= "class C" (python-info-current-defun t)))
3552 (python-tests-look-at "return [i for ")
3553 (should (string= "C.m" (python-info-current-defun)))
3554 (should (string= "def C.m" (python-info-current-defun t)))
3555 (python-tests-look-at "def b():")
3556 (should (string= "C.m.b" (python-info-current-defun)))
3557 (should (string= "def C.m.b" (python-info-current-defun t)))
3558 (forward-line 2)
3559 (indent-for-tab-command)
3560 (python-indent-dedent-line-backspace 1)
3561 (should (string= "C.m" (python-info-current-defun)))
3562 (should (string= "def C.m" (python-info-current-defun t)))
3563 (python-tests-look-at "def c(self):")
3564 (forward-line -1)
3565 (indent-for-tab-command)
3566 (should (string= "C.m.a" (python-info-current-defun)))
3567 (should (string= "def C.m.a" (python-info-current-defun t)))
3568 (python-indent-dedent-line-backspace 1)
3569 (should (string= "C.m" (python-info-current-defun)))
3570 (should (string= "def C.m" (python-info-current-defun t)))
3571 (python-indent-dedent-line-backspace 1)
3572 (should (string= "C" (python-info-current-defun)))
3573 (should (string= "class C" (python-info-current-defun t)))
3574 (python-tests-look-at "def c(self):")
3575 (should (string= "C.c" (python-info-current-defun)))
3576 (should (string= "def C.c" (python-info-current-defun t)))
3577 (python-tests-look-at "do_c()")
3578 (should (string= "C.c" (python-info-current-defun)))
3579 (should (string= "def C.c" (python-info-current-defun t)))))
3581 (ert-deftest python-info-current-defun-3 ()
3582 (python-tests-with-temp-buffer
3584 def decoratorFunctionWithArguments(arg1, arg2, arg3):
3585 '''print decorated function call data to stdout.
3587 Usage:
3589 @decoratorFunctionWithArguments('arg1', 'arg2')
3590 def func(a, b, c=True):
3591 pass
3594 def wwrap(f):
3595 print 'Inside wwrap()'
3596 def wrapped_f(*args):
3597 print 'Inside wrapped_f()'
3598 print 'Decorator arguments:', arg1, arg2, arg3
3599 f(*args)
3600 print 'After f(*args)'
3601 return wrapped_f
3602 return wwrap
3604 (python-tests-look-at "def wwrap(f):")
3605 (forward-line -1)
3606 (should (not (python-info-current-defun)))
3607 (indent-for-tab-command 1)
3608 (should (string= (python-info-current-defun)
3609 "decoratorFunctionWithArguments"))
3610 (should (string= (python-info-current-defun t)
3611 "def decoratorFunctionWithArguments"))
3612 (python-tests-look-at "def wrapped_f(*args):")
3613 (should (string= (python-info-current-defun)
3614 "decoratorFunctionWithArguments.wwrap.wrapped_f"))
3615 (should (string= (python-info-current-defun t)
3616 "def decoratorFunctionWithArguments.wwrap.wrapped_f"))
3617 (python-tests-look-at "return wrapped_f")
3618 (should (string= (python-info-current-defun)
3619 "decoratorFunctionWithArguments.wwrap"))
3620 (should (string= (python-info-current-defun t)
3621 "def decoratorFunctionWithArguments.wwrap"))
3622 (end-of-line 1)
3623 (python-tests-look-at "return wwrap")
3624 (should (string= (python-info-current-defun)
3625 "decoratorFunctionWithArguments"))
3626 (should (string= (python-info-current-defun t)
3627 "def decoratorFunctionWithArguments"))))
3629 (ert-deftest python-info-current-symbol-1 ()
3630 (python-tests-with-temp-buffer
3632 class C(object):
3634 def m(self):
3635 self.c()
3637 def c(self):
3638 print ('a')
3640 (python-tests-look-at "self.c()")
3641 (should (string= "self.c" (python-info-current-symbol)))
3642 (should (string= "C.c" (python-info-current-symbol t)))))
3644 (ert-deftest python-info-current-symbol-2 ()
3645 (python-tests-with-temp-buffer
3647 class C(object):
3649 class M(object):
3651 def a(self):
3652 self.c()
3654 def c(self):
3655 pass
3657 (python-tests-look-at "self.c()")
3658 (should (string= "self.c" (python-info-current-symbol)))
3659 (should (string= "C.M.c" (python-info-current-symbol t)))))
3661 (ert-deftest python-info-current-symbol-3 ()
3662 "Keywords should not be considered symbols."
3663 :expected-result :failed
3664 (python-tests-with-temp-buffer
3666 class C(object):
3667 pass
3669 ;; FIXME: keywords are not symbols.
3670 (python-tests-look-at "class C")
3671 (should (not (python-info-current-symbol)))
3672 (should (not (python-info-current-symbol t)))
3673 (python-tests-look-at "C(object)")
3674 (should (string= "C" (python-info-current-symbol)))
3675 (should (string= "class C" (python-info-current-symbol t)))))
3677 (ert-deftest python-info-statement-starts-block-p-1 ()
3678 (python-tests-with-temp-buffer
3680 def long_function_name(
3681 var_one, var_two, var_three,
3682 var_four):
3683 print (var_one)
3685 (python-tests-look-at "def long_function_name")
3686 (should (python-info-statement-starts-block-p))
3687 (python-tests-look-at "print (var_one)")
3688 (python-util-forward-comment -1)
3689 (should (python-info-statement-starts-block-p))))
3691 (ert-deftest python-info-statement-starts-block-p-2 ()
3692 (python-tests-with-temp-buffer
3694 if width == 0 and height == 0 and \\\\
3695 color == 'red' and emphasis == 'strong' or \\\\
3696 highlight > 100:
3697 raise ValueError('sorry, you lose')
3699 (python-tests-look-at "if width == 0 and")
3700 (should (python-info-statement-starts-block-p))
3701 (python-tests-look-at "raise ValueError(")
3702 (python-util-forward-comment -1)
3703 (should (python-info-statement-starts-block-p))))
3705 (ert-deftest python-info-statement-ends-block-p-1 ()
3706 (python-tests-with-temp-buffer
3708 def long_function_name(
3709 var_one, var_two, var_three,
3710 var_four):
3711 print (var_one)
3713 (python-tests-look-at "print (var_one)")
3714 (should (python-info-statement-ends-block-p))))
3716 (ert-deftest python-info-statement-ends-block-p-2 ()
3717 (python-tests-with-temp-buffer
3719 if width == 0 and height == 0 and \\\\
3720 color == 'red' and emphasis == 'strong' or \\\\
3721 highlight > 100:
3722 raise ValueError(
3723 'sorry, you lose'
3727 (python-tests-look-at "raise ValueError(")
3728 (should (python-info-statement-ends-block-p))))
3730 (ert-deftest python-info-beginning-of-statement-p-1 ()
3731 (python-tests-with-temp-buffer
3733 def long_function_name(
3734 var_one, var_two, var_three,
3735 var_four):
3736 print (var_one)
3738 (python-tests-look-at "def long_function_name")
3739 (should (python-info-beginning-of-statement-p))
3740 (forward-char 10)
3741 (should (not (python-info-beginning-of-statement-p)))
3742 (python-tests-look-at "print (var_one)")
3743 (should (python-info-beginning-of-statement-p))
3744 (goto-char (line-beginning-position))
3745 (should (not (python-info-beginning-of-statement-p)))))
3747 (ert-deftest python-info-beginning-of-statement-p-2 ()
3748 (python-tests-with-temp-buffer
3750 if width == 0 and height == 0 and \\\\
3751 color == 'red' and emphasis == 'strong' or \\\\
3752 highlight > 100:
3753 raise ValueError(
3754 'sorry, you lose'
3758 (python-tests-look-at "if width == 0 and")
3759 (should (python-info-beginning-of-statement-p))
3760 (forward-char 10)
3761 (should (not (python-info-beginning-of-statement-p)))
3762 (python-tests-look-at "raise ValueError(")
3763 (should (python-info-beginning-of-statement-p))
3764 (goto-char (line-beginning-position))
3765 (should (not (python-info-beginning-of-statement-p)))))
3767 (ert-deftest python-info-end-of-statement-p-1 ()
3768 (python-tests-with-temp-buffer
3770 def long_function_name(
3771 var_one, var_two, var_three,
3772 var_four):
3773 print (var_one)
3775 (python-tests-look-at "def long_function_name")
3776 (should (not (python-info-end-of-statement-p)))
3777 (end-of-line)
3778 (should (not (python-info-end-of-statement-p)))
3779 (python-tests-look-at "print (var_one)")
3780 (python-util-forward-comment -1)
3781 (should (python-info-end-of-statement-p))
3782 (python-tests-look-at "print (var_one)")
3783 (should (not (python-info-end-of-statement-p)))
3784 (end-of-line)
3785 (should (python-info-end-of-statement-p))))
3787 (ert-deftest python-info-end-of-statement-p-2 ()
3788 (python-tests-with-temp-buffer
3790 if width == 0 and height == 0 and \\\\
3791 color == 'red' and emphasis == 'strong' or \\\\
3792 highlight > 100:
3793 raise ValueError(
3794 'sorry, you lose'
3798 (python-tests-look-at "if width == 0 and")
3799 (should (not (python-info-end-of-statement-p)))
3800 (end-of-line)
3801 (should (not (python-info-end-of-statement-p)))
3802 (python-tests-look-at "raise ValueError(")
3803 (python-util-forward-comment -1)
3804 (should (python-info-end-of-statement-p))
3805 (python-tests-look-at "raise ValueError(")
3806 (should (not (python-info-end-of-statement-p)))
3807 (end-of-line)
3808 (should (not (python-info-end-of-statement-p)))
3809 (goto-char (point-max))
3810 (python-util-forward-comment -1)
3811 (should (python-info-end-of-statement-p))))
3813 (ert-deftest python-info-beginning-of-block-p-1 ()
3814 (python-tests-with-temp-buffer
3816 def long_function_name(
3817 var_one, var_two, var_three,
3818 var_four):
3819 print (var_one)
3821 (python-tests-look-at "def long_function_name")
3822 (should (python-info-beginning-of-block-p))
3823 (python-tests-look-at "var_one, var_two, var_three,")
3824 (should (not (python-info-beginning-of-block-p)))
3825 (python-tests-look-at "print (var_one)")
3826 (should (not (python-info-beginning-of-block-p)))))
3828 (ert-deftest python-info-beginning-of-block-p-2 ()
3829 (python-tests-with-temp-buffer
3831 if width == 0 and height == 0 and \\\\
3832 color == 'red' and emphasis == 'strong' or \\\\
3833 highlight > 100:
3834 raise ValueError(
3835 'sorry, you lose'
3839 (python-tests-look-at "if width == 0 and")
3840 (should (python-info-beginning-of-block-p))
3841 (python-tests-look-at "color == 'red' and emphasis")
3842 (should (not (python-info-beginning-of-block-p)))
3843 (python-tests-look-at "raise ValueError(")
3844 (should (not (python-info-beginning-of-block-p)))))
3846 (ert-deftest python-info-end-of-block-p-1 ()
3847 (python-tests-with-temp-buffer
3849 def long_function_name(
3850 var_one, var_two, var_three,
3851 var_four):
3852 print (var_one)
3854 (python-tests-look-at "def long_function_name")
3855 (should (not (python-info-end-of-block-p)))
3856 (python-tests-look-at "var_one, var_two, var_three,")
3857 (should (not (python-info-end-of-block-p)))
3858 (python-tests-look-at "var_four):")
3859 (end-of-line)
3860 (should (not (python-info-end-of-block-p)))
3861 (python-tests-look-at "print (var_one)")
3862 (should (not (python-info-end-of-block-p)))
3863 (end-of-line 1)
3864 (should (python-info-end-of-block-p))))
3866 (ert-deftest python-info-end-of-block-p-2 ()
3867 (python-tests-with-temp-buffer
3869 if width == 0 and height == 0 and \\\\
3870 color == 'red' and emphasis == 'strong' or \\\\
3871 highlight > 100:
3872 raise ValueError(
3873 'sorry, you lose'
3877 (python-tests-look-at "if width == 0 and")
3878 (should (not (python-info-end-of-block-p)))
3879 (python-tests-look-at "color == 'red' and emphasis == 'strong' or")
3880 (should (not (python-info-end-of-block-p)))
3881 (python-tests-look-at "highlight > 100:")
3882 (end-of-line)
3883 (should (not (python-info-end-of-block-p)))
3884 (python-tests-look-at "raise ValueError(")
3885 (should (not (python-info-end-of-block-p)))
3886 (end-of-line 1)
3887 (should (not (python-info-end-of-block-p)))
3888 (goto-char (point-max))
3889 (python-util-forward-comment -1)
3890 (should (python-info-end-of-block-p))))
3892 (ert-deftest python-info-dedenter-opening-block-position-1 ()
3893 (python-tests-with-temp-buffer
3895 if request.user.is_authenticated():
3896 try:
3897 profile = request.user.get_profile()
3898 except Profile.DoesNotExist:
3899 profile = Profile.objects.create(user=request.user)
3900 else:
3901 if profile.stats:
3902 profile.recalculate_stats()
3903 else:
3904 profile.clear_stats()
3905 finally:
3906 profile.views += 1
3907 profile.save()
3909 (python-tests-look-at "try:")
3910 (should (not (python-info-dedenter-opening-block-position)))
3911 (python-tests-look-at "except Profile.DoesNotExist:")
3912 (should (= (python-tests-look-at "try:" -1 t)
3913 (python-info-dedenter-opening-block-position)))
3914 (python-tests-look-at "else:")
3915 (should (= (python-tests-look-at "except Profile.DoesNotExist:" -1 t)
3916 (python-info-dedenter-opening-block-position)))
3917 (python-tests-look-at "if profile.stats:")
3918 (should (not (python-info-dedenter-opening-block-position)))
3919 (python-tests-look-at "else:")
3920 (should (= (python-tests-look-at "if profile.stats:" -1 t)
3921 (python-info-dedenter-opening-block-position)))
3922 (python-tests-look-at "finally:")
3923 (should (= (python-tests-look-at "else:" -2 t)
3924 (python-info-dedenter-opening-block-position)))))
3926 (ert-deftest python-info-dedenter-opening-block-position-2 ()
3927 (python-tests-with-temp-buffer
3929 if request.user.is_authenticated():
3930 profile = Profile.objects.get_or_create(user=request.user)
3931 if profile.stats:
3932 profile.recalculate_stats()
3934 data = {
3935 'else': 'do it'
3937 'else'
3939 (python-tests-look-at "'else': 'do it'")
3940 (should (not (python-info-dedenter-opening-block-position)))
3941 (python-tests-look-at "'else'")
3942 (should (not (python-info-dedenter-opening-block-position)))))
3944 (ert-deftest python-info-dedenter-opening-block-position-3 ()
3945 (python-tests-with-temp-buffer
3947 if save:
3948 try:
3949 write_to_disk(data)
3950 except IOError:
3951 msg = 'Error saving to disk'
3952 message(msg)
3953 logger.exception(msg)
3954 except Exception:
3955 if hide_details:
3956 logger.exception('Unhandled exception')
3957 else
3958 finally:
3959 data.free()
3961 (python-tests-look-at "try:")
3962 (should (not (python-info-dedenter-opening-block-position)))
3964 (python-tests-look-at "except IOError:")
3965 (should (= (python-tests-look-at "try:" -1 t)
3966 (python-info-dedenter-opening-block-position)))
3968 (python-tests-look-at "except Exception:")
3969 (should (= (python-tests-look-at "except IOError:" -1 t)
3970 (python-info-dedenter-opening-block-position)))
3972 (python-tests-look-at "if hide_details:")
3973 (should (not (python-info-dedenter-opening-block-position)))
3975 ;; check indentation modifies the detected opening block
3976 (python-tests-look-at "else")
3977 (should (= (python-tests-look-at "if hide_details:" -1 t)
3978 (python-info-dedenter-opening-block-position)))
3980 (indent-line-to 8)
3981 (should (= (python-tests-look-at "if hide_details:" -1 t)
3982 (python-info-dedenter-opening-block-position)))
3984 (indent-line-to 4)
3985 (should (= (python-tests-look-at "except Exception:" -1 t)
3986 (python-info-dedenter-opening-block-position)))
3988 (indent-line-to 0)
3989 (should (= (python-tests-look-at "if save:" -1 t)
3990 (python-info-dedenter-opening-block-position)))))
3992 (ert-deftest python-info-dedenter-opening-block-positions-1 ()
3993 (python-tests-with-temp-buffer
3995 if save:
3996 try:
3997 write_to_disk(data)
3998 except IOError:
3999 msg = 'Error saving to disk'
4000 message(msg)
4001 logger.exception(msg)
4002 except Exception:
4003 if hide_details:
4004 logger.exception('Unhandled exception')
4005 else
4006 finally:
4007 data.free()
4009 (python-tests-look-at "try:")
4010 (should (not (python-info-dedenter-opening-block-positions)))
4012 (python-tests-look-at "except IOError:")
4013 (should
4014 (equal (list
4015 (python-tests-look-at "try:" -1 t))
4016 (python-info-dedenter-opening-block-positions)))
4018 (python-tests-look-at "except Exception:")
4019 (should
4020 (equal (list
4021 (python-tests-look-at "except IOError:" -1 t))
4022 (python-info-dedenter-opening-block-positions)))
4024 (python-tests-look-at "if hide_details:")
4025 (should (not (python-info-dedenter-opening-block-positions)))
4027 ;; check indentation does not modify the detected opening blocks
4028 (python-tests-look-at "else")
4029 (should
4030 (equal (list
4031 (python-tests-look-at "if hide_details:" -1 t)
4032 (python-tests-look-at "except Exception:" -1 t)
4033 (python-tests-look-at "if save:" -1 t))
4034 (python-info-dedenter-opening-block-positions)))
4036 (indent-line-to 8)
4037 (should
4038 (equal (list
4039 (python-tests-look-at "if hide_details:" -1 t)
4040 (python-tests-look-at "except Exception:" -1 t)
4041 (python-tests-look-at "if save:" -1 t))
4042 (python-info-dedenter-opening-block-positions)))
4044 (indent-line-to 4)
4045 (should
4046 (equal (list
4047 (python-tests-look-at "if hide_details:" -1 t)
4048 (python-tests-look-at "except Exception:" -1 t)
4049 (python-tests-look-at "if save:" -1 t))
4050 (python-info-dedenter-opening-block-positions)))
4052 (indent-line-to 0)
4053 (should
4054 (equal (list
4055 (python-tests-look-at "if hide_details:" -1 t)
4056 (python-tests-look-at "except Exception:" -1 t)
4057 (python-tests-look-at "if save:" -1 t))
4058 (python-info-dedenter-opening-block-positions)))))
4060 (ert-deftest python-info-dedenter-opening-block-positions-2 ()
4061 "Test detection of opening blocks for elif."
4062 (python-tests-with-temp-buffer
4064 if var:
4065 if var2:
4066 something()
4067 elif var3:
4068 something_else()
4069 elif
4071 (python-tests-look-at "elif var3:")
4072 (should
4073 (equal (list
4074 (python-tests-look-at "if var2:" -1 t)
4075 (python-tests-look-at "if var:" -1 t))
4076 (python-info-dedenter-opening-block-positions)))
4078 (python-tests-look-at "elif\n")
4079 (should
4080 (equal (list
4081 (python-tests-look-at "elif var3:" -1 t)
4082 (python-tests-look-at "if var:" -1 t))
4083 (python-info-dedenter-opening-block-positions)))))
4085 (ert-deftest python-info-dedenter-opening-block-positions-3 ()
4086 "Test detection of opening blocks for else."
4087 (python-tests-with-temp-buffer
4089 try:
4090 something()
4091 except:
4092 if var:
4093 if var2:
4094 something()
4095 elif var3:
4096 something_else()
4097 else
4099 if var4:
4100 while var5:
4101 var4.pop()
4102 else
4104 for value in var6:
4105 if value > 0:
4106 print value
4107 else
4109 (python-tests-look-at "else\n")
4110 (should
4111 (equal (list
4112 (python-tests-look-at "elif var3:" -1 t)
4113 (python-tests-look-at "if var:" -1 t)
4114 (python-tests-look-at "except:" -1 t))
4115 (python-info-dedenter-opening-block-positions)))
4117 (python-tests-look-at "else\n")
4118 (should
4119 (equal (list
4120 (python-tests-look-at "while var5:" -1 t)
4121 (python-tests-look-at "if var4:" -1 t))
4122 (python-info-dedenter-opening-block-positions)))
4124 (python-tests-look-at "else\n")
4125 (should
4126 (equal (list
4127 (python-tests-look-at "if value > 0:" -1 t)
4128 (python-tests-look-at "for value in var6:" -1 t)
4129 (python-tests-look-at "if var4:" -1 t))
4130 (python-info-dedenter-opening-block-positions)))))
4132 (ert-deftest python-info-dedenter-opening-block-positions-4 ()
4133 "Test detection of opening blocks for except."
4134 (python-tests-with-temp-buffer
4136 try:
4137 something()
4138 except ValueError:
4139 something_else()
4140 except
4142 (python-tests-look-at "except ValueError:")
4143 (should
4144 (equal (list (python-tests-look-at "try:" -1 t))
4145 (python-info-dedenter-opening-block-positions)))
4147 (python-tests-look-at "except\n")
4148 (should
4149 (equal (list (python-tests-look-at "except ValueError:" -1 t))
4150 (python-info-dedenter-opening-block-positions)))))
4152 (ert-deftest python-info-dedenter-opening-block-positions-5 ()
4153 "Test detection of opening blocks for finally."
4154 (python-tests-with-temp-buffer
4156 try:
4157 something()
4158 finally
4160 try:
4161 something_else()
4162 except:
4163 logger.exception('something went wrong')
4164 finally
4166 try:
4167 something_else_else()
4168 except Exception:
4169 logger.exception('something else went wrong')
4170 else:
4171 print ('all good')
4172 finally
4174 (python-tests-look-at "finally\n")
4175 (should
4176 (equal (list (python-tests-look-at "try:" -1 t))
4177 (python-info-dedenter-opening-block-positions)))
4179 (python-tests-look-at "finally\n")
4180 (should
4181 (equal (list (python-tests-look-at "except:" -1 t))
4182 (python-info-dedenter-opening-block-positions)))
4184 (python-tests-look-at "finally\n")
4185 (should
4186 (equal (list (python-tests-look-at "else:" -1 t))
4187 (python-info-dedenter-opening-block-positions)))))
4189 (ert-deftest python-info-dedenter-opening-block-message-1 ()
4190 "Test dedenters inside strings are ignored."
4191 (python-tests-with-temp-buffer
4192 "'''
4193 try:
4194 something()
4195 except:
4196 logger.exception('something went wrong')
4199 (python-tests-look-at "except\n")
4200 (should (not (python-info-dedenter-opening-block-message)))))
4202 (ert-deftest python-info-dedenter-opening-block-message-2 ()
4203 "Test except keyword."
4204 (python-tests-with-temp-buffer
4206 try:
4207 something()
4208 except:
4209 logger.exception('something went wrong')
4211 (python-tests-look-at "except:")
4212 (should (string=
4213 "Closes try:"
4214 (substring-no-properties
4215 (python-info-dedenter-opening-block-message))))
4216 (end-of-line)
4217 (should (string=
4218 "Closes try:"
4219 (substring-no-properties
4220 (python-info-dedenter-opening-block-message))))))
4222 (ert-deftest python-info-dedenter-opening-block-message-3 ()
4223 "Test else keyword."
4224 (python-tests-with-temp-buffer
4226 try:
4227 something()
4228 except:
4229 logger.exception('something went wrong')
4230 else:
4231 logger.debug('all good')
4233 (python-tests-look-at "else:")
4234 (should (string=
4235 "Closes except:"
4236 (substring-no-properties
4237 (python-info-dedenter-opening-block-message))))
4238 (end-of-line)
4239 (should (string=
4240 "Closes except:"
4241 (substring-no-properties
4242 (python-info-dedenter-opening-block-message))))))
4244 (ert-deftest python-info-dedenter-opening-block-message-4 ()
4245 "Test finally keyword."
4246 (python-tests-with-temp-buffer
4248 try:
4249 something()
4250 except:
4251 logger.exception('something went wrong')
4252 else:
4253 logger.debug('all good')
4254 finally:
4255 clean()
4257 (python-tests-look-at "finally:")
4258 (should (string=
4259 "Closes else:"
4260 (substring-no-properties
4261 (python-info-dedenter-opening-block-message))))
4262 (end-of-line)
4263 (should (string=
4264 "Closes else:"
4265 (substring-no-properties
4266 (python-info-dedenter-opening-block-message))))))
4268 (ert-deftest python-info-dedenter-opening-block-message-5 ()
4269 "Test elif keyword."
4270 (python-tests-with-temp-buffer
4272 if a:
4273 something()
4274 elif b:
4276 (python-tests-look-at "elif b:")
4277 (should (string=
4278 "Closes if a:"
4279 (substring-no-properties
4280 (python-info-dedenter-opening-block-message))))
4281 (end-of-line)
4282 (should (string=
4283 "Closes if a:"
4284 (substring-no-properties
4285 (python-info-dedenter-opening-block-message))))))
4288 (ert-deftest python-info-dedenter-statement-p-1 ()
4289 "Test dedenters inside strings are ignored."
4290 (python-tests-with-temp-buffer
4291 "'''
4292 try:
4293 something()
4294 except:
4295 logger.exception('something went wrong')
4298 (python-tests-look-at "except\n")
4299 (should (not (python-info-dedenter-statement-p)))))
4301 (ert-deftest python-info-dedenter-statement-p-2 ()
4302 "Test except keyword."
4303 (python-tests-with-temp-buffer
4305 try:
4306 something()
4307 except:
4308 logger.exception('something went wrong')
4310 (python-tests-look-at "except:")
4311 (should (= (point) (python-info-dedenter-statement-p)))
4312 (end-of-line)
4313 (should (= (save-excursion
4314 (back-to-indentation)
4315 (point))
4316 (python-info-dedenter-statement-p)))))
4318 (ert-deftest python-info-dedenter-statement-p-3 ()
4319 "Test else keyword."
4320 (python-tests-with-temp-buffer
4322 try:
4323 something()
4324 except:
4325 logger.exception('something went wrong')
4326 else:
4327 logger.debug('all good')
4329 (python-tests-look-at "else:")
4330 (should (= (point) (python-info-dedenter-statement-p)))
4331 (end-of-line)
4332 (should (= (save-excursion
4333 (back-to-indentation)
4334 (point))
4335 (python-info-dedenter-statement-p)))))
4337 (ert-deftest python-info-dedenter-statement-p-4 ()
4338 "Test finally keyword."
4339 (python-tests-with-temp-buffer
4341 try:
4342 something()
4343 except:
4344 logger.exception('something went wrong')
4345 else:
4346 logger.debug('all good')
4347 finally:
4348 clean()
4350 (python-tests-look-at "finally:")
4351 (should (= (point) (python-info-dedenter-statement-p)))
4352 (end-of-line)
4353 (should (= (save-excursion
4354 (back-to-indentation)
4355 (point))
4356 (python-info-dedenter-statement-p)))))
4358 (ert-deftest python-info-dedenter-statement-p-5 ()
4359 "Test elif keyword."
4360 (python-tests-with-temp-buffer
4362 if a:
4363 something()
4364 elif b:
4366 (python-tests-look-at "elif b:")
4367 (should (= (point) (python-info-dedenter-statement-p)))
4368 (end-of-line)
4369 (should (= (save-excursion
4370 (back-to-indentation)
4371 (point))
4372 (python-info-dedenter-statement-p)))))
4374 (ert-deftest python-info-line-ends-backslash-p-1 ()
4375 (python-tests-with-temp-buffer
4377 objects = Thing.objects.all() \\\\
4378 .filter(
4379 type='toy',
4380 status='bought'
4381 ) \\\\
4382 .aggregate(
4383 Sum('amount')
4384 ) \\\\
4385 .values_list()
4387 (should (python-info-line-ends-backslash-p 2)) ; .filter(...
4388 (should (python-info-line-ends-backslash-p 3))
4389 (should (python-info-line-ends-backslash-p 4))
4390 (should (python-info-line-ends-backslash-p 5))
4391 (should (python-info-line-ends-backslash-p 6)) ; ) \...
4392 (should (python-info-line-ends-backslash-p 7))
4393 (should (python-info-line-ends-backslash-p 8))
4394 (should (python-info-line-ends-backslash-p 9))
4395 (should (not (python-info-line-ends-backslash-p 10))))) ; .values_list()...
4397 (ert-deftest python-info-beginning-of-backslash-1 ()
4398 (python-tests-with-temp-buffer
4400 objects = Thing.objects.all() \\\\
4401 .filter(
4402 type='toy',
4403 status='bought'
4404 ) \\\\
4405 .aggregate(
4406 Sum('amount')
4407 ) \\\\
4408 .values_list()
4410 (let ((first 2)
4411 (second (python-tests-look-at ".filter("))
4412 (third (python-tests-look-at ".aggregate(")))
4413 (should (= first (python-info-beginning-of-backslash 2)))
4414 (should (= second (python-info-beginning-of-backslash 3)))
4415 (should (= second (python-info-beginning-of-backslash 4)))
4416 (should (= second (python-info-beginning-of-backslash 5)))
4417 (should (= second (python-info-beginning-of-backslash 6)))
4418 (should (= third (python-info-beginning-of-backslash 7)))
4419 (should (= third (python-info-beginning-of-backslash 8)))
4420 (should (= third (python-info-beginning-of-backslash 9)))
4421 (should (not (python-info-beginning-of-backslash 10))))))
4423 (ert-deftest python-info-continuation-line-p-1 ()
4424 (python-tests-with-temp-buffer
4426 if width == 0 and height == 0 and \\\\
4427 color == 'red' and emphasis == 'strong' or \\\\
4428 highlight > 100:
4429 raise ValueError(
4430 'sorry, you lose'
4434 (python-tests-look-at "if width == 0 and height == 0 and")
4435 (should (not (python-info-continuation-line-p)))
4436 (python-tests-look-at "color == 'red' and emphasis == 'strong' or")
4437 (should (python-info-continuation-line-p))
4438 (python-tests-look-at "highlight > 100:")
4439 (should (python-info-continuation-line-p))
4440 (python-tests-look-at "raise ValueError(")
4441 (should (not (python-info-continuation-line-p)))
4442 (python-tests-look-at "'sorry, you lose'")
4443 (should (python-info-continuation-line-p))
4444 (forward-line 1)
4445 (should (python-info-continuation-line-p))
4446 (python-tests-look-at ")")
4447 (should (python-info-continuation-line-p))
4448 (forward-line 1)
4449 (should (not (python-info-continuation-line-p)))))
4451 (ert-deftest python-info-block-continuation-line-p-1 ()
4452 (python-tests-with-temp-buffer
4454 if width == 0 and height == 0 and \\\\
4455 color == 'red' and emphasis == 'strong' or \\\\
4456 highlight > 100:
4457 raise ValueError(
4458 'sorry, you lose'
4462 (python-tests-look-at "if width == 0 and")
4463 (should (not (python-info-block-continuation-line-p)))
4464 (python-tests-look-at "color == 'red' and emphasis == 'strong' or")
4465 (should (= (python-info-block-continuation-line-p)
4466 (python-tests-look-at "if width == 0 and" -1 t)))
4467 (python-tests-look-at "highlight > 100:")
4468 (should (not (python-info-block-continuation-line-p)))))
4470 (ert-deftest python-info-block-continuation-line-p-2 ()
4471 (python-tests-with-temp-buffer
4473 def foo(a,
4476 pass
4478 (python-tests-look-at "def foo(a,")
4479 (should (not (python-info-block-continuation-line-p)))
4480 (python-tests-look-at "b,")
4481 (should (= (python-info-block-continuation-line-p)
4482 (python-tests-look-at "def foo(a," -1 t)))
4483 (python-tests-look-at "c):")
4484 (should (not (python-info-block-continuation-line-p)))))
4486 (ert-deftest python-info-assignment-statement-p-1 ()
4487 (python-tests-with-temp-buffer
4489 data = foo(), bar() \\\\
4490 baz(), 4 \\\\
4491 5, 6
4493 (python-tests-look-at "data = foo(), bar()")
4494 (should (python-info-assignment-statement-p))
4495 (should (python-info-assignment-statement-p t))
4496 (python-tests-look-at "baz(), 4")
4497 (should (python-info-assignment-statement-p))
4498 (should (not (python-info-assignment-statement-p t)))
4499 (python-tests-look-at "5, 6")
4500 (should (python-info-assignment-statement-p))
4501 (should (not (python-info-assignment-statement-p t)))))
4503 (ert-deftest python-info-assignment-statement-p-2 ()
4504 (python-tests-with-temp-buffer
4506 data = (foo(), bar()
4507 baz(), 4
4508 5, 6)
4510 (python-tests-look-at "data = (foo(), bar()")
4511 (should (python-info-assignment-statement-p))
4512 (should (python-info-assignment-statement-p t))
4513 (python-tests-look-at "baz(), 4")
4514 (should (python-info-assignment-statement-p))
4515 (should (not (python-info-assignment-statement-p t)))
4516 (python-tests-look-at "5, 6)")
4517 (should (python-info-assignment-statement-p))
4518 (should (not (python-info-assignment-statement-p t)))))
4520 (ert-deftest python-info-assignment-statement-p-3 ()
4521 (python-tests-with-temp-buffer
4523 data '=' 42
4525 (python-tests-look-at "data '=' 42")
4526 (should (not (python-info-assignment-statement-p)))
4527 (should (not (python-info-assignment-statement-p t)))))
4529 (ert-deftest python-info-assignment-continuation-line-p-1 ()
4530 (python-tests-with-temp-buffer
4532 data = foo(), bar() \\\\
4533 baz(), 4 \\\\
4534 5, 6
4536 (python-tests-look-at "data = foo(), bar()")
4537 (should (not (python-info-assignment-continuation-line-p)))
4538 (python-tests-look-at "baz(), 4")
4539 (should (= (python-info-assignment-continuation-line-p)
4540 (python-tests-look-at "foo()," -1 t)))
4541 (python-tests-look-at "5, 6")
4542 (should (not (python-info-assignment-continuation-line-p)))))
4544 (ert-deftest python-info-assignment-continuation-line-p-2 ()
4545 (python-tests-with-temp-buffer
4547 data = (foo(), bar()
4548 baz(), 4
4549 5, 6)
4551 (python-tests-look-at "data = (foo(), bar()")
4552 (should (not (python-info-assignment-continuation-line-p)))
4553 (python-tests-look-at "baz(), 4")
4554 (should (= (python-info-assignment-continuation-line-p)
4555 (python-tests-look-at "(foo()," -1 t)))
4556 (python-tests-look-at "5, 6)")
4557 (should (not (python-info-assignment-continuation-line-p)))))
4559 (ert-deftest python-info-looking-at-beginning-of-defun-1 ()
4560 (python-tests-with-temp-buffer
4562 def decorat0r(deff):
4563 '''decorates stuff.
4565 @decorat0r
4566 def foo(arg):
4569 def wrap():
4570 deff()
4571 return wwrap
4573 (python-tests-look-at "def decorat0r(deff):")
4574 (should (python-info-looking-at-beginning-of-defun))
4575 (python-tests-look-at "def foo(arg):")
4576 (should (not (python-info-looking-at-beginning-of-defun)))
4577 (python-tests-look-at "def wrap():")
4578 (should (python-info-looking-at-beginning-of-defun))
4579 (python-tests-look-at "deff()")
4580 (should (not (python-info-looking-at-beginning-of-defun)))))
4582 (ert-deftest python-info-current-line-comment-p-1 ()
4583 (python-tests-with-temp-buffer
4585 # this is a comment
4586 foo = True # another comment
4587 '#this is a string'
4588 if foo:
4589 # more comments
4590 print ('bar') # print bar
4592 (python-tests-look-at "# this is a comment")
4593 (should (python-info-current-line-comment-p))
4594 (python-tests-look-at "foo = True # another comment")
4595 (should (not (python-info-current-line-comment-p)))
4596 (python-tests-look-at "'#this is a string'")
4597 (should (not (python-info-current-line-comment-p)))
4598 (python-tests-look-at "# more comments")
4599 (should (python-info-current-line-comment-p))
4600 (python-tests-look-at "print ('bar') # print bar")
4601 (should (not (python-info-current-line-comment-p)))))
4603 (ert-deftest python-info-current-line-empty-p ()
4604 (python-tests-with-temp-buffer
4606 # this is a comment
4608 foo = True # another comment
4610 (should (python-info-current-line-empty-p))
4611 (python-tests-look-at "# this is a comment")
4612 (should (not (python-info-current-line-empty-p)))
4613 (forward-line 1)
4614 (should (python-info-current-line-empty-p))))
4616 (ert-deftest python-info-docstring-p-1 ()
4617 "Test module docstring detection."
4618 (python-tests-with-temp-buffer
4619 "# -*- coding: utf-8 -*-
4620 #!/usr/bin/python
4623 Module Docstring Django style.
4625 u'''Additional module docstring.'''
4626 '''Not a module docstring.'''
4628 (python-tests-look-at "Module Docstring Django style.")
4629 (should (python-info-docstring-p))
4630 (python-tests-look-at "u'''Additional module docstring.'''")
4631 (should (python-info-docstring-p))
4632 (python-tests-look-at "'''Not a module docstring.'''")
4633 (should (not (python-info-docstring-p)))))
4635 (ert-deftest python-info-docstring-p-2 ()
4636 "Test variable docstring detection."
4637 (python-tests-with-temp-buffer
4639 variable = 42
4640 U'''Variable docstring.'''
4641 '''Additional variable docstring.'''
4642 '''Not a variable docstring.'''
4644 (python-tests-look-at "Variable docstring.")
4645 (should (python-info-docstring-p))
4646 (python-tests-look-at "u'''Additional variable docstring.'''")
4647 (should (python-info-docstring-p))
4648 (python-tests-look-at "'''Not a variable docstring.'''")
4649 (should (not (python-info-docstring-p)))))
4651 (ert-deftest python-info-docstring-p-3 ()
4652 "Test function docstring detection."
4653 (python-tests-with-temp-buffer
4655 def func(a, b):
4656 r'''
4657 Function docstring.
4659 onetwo style.
4661 R'''Additional function docstring.'''
4662 '''Not a function docstring.'''
4663 return a + b
4665 (python-tests-look-at "Function docstring.")
4666 (should (python-info-docstring-p))
4667 (python-tests-look-at "R'''Additional function docstring.'''")
4668 (should (python-info-docstring-p))
4669 (python-tests-look-at "'''Not a function docstring.'''")
4670 (should (not (python-info-docstring-p)))))
4672 (ert-deftest python-info-docstring-p-4 ()
4673 "Test class docstring detection."
4674 (python-tests-with-temp-buffer
4676 class Class:
4677 ur'''
4678 Class docstring.
4680 symmetric style.
4682 uR'''
4683 Additional class docstring.
4685 '''Not a class docstring.'''
4686 pass
4688 (python-tests-look-at "Class docstring.")
4689 (should (python-info-docstring-p))
4690 (python-tests-look-at "uR'''") ;; Additional class docstring
4691 (should (python-info-docstring-p))
4692 (python-tests-look-at "'''Not a class docstring.'''")
4693 (should (not (python-info-docstring-p)))))
4695 (ert-deftest python-info-docstring-p-5 ()
4696 "Test class attribute docstring detection."
4697 (python-tests-with-temp-buffer
4699 class Class:
4700 attribute = 42
4701 Ur'''
4702 Class attribute docstring.
4704 pep-257 style.
4707 UR'''
4708 Additional class attribute docstring.
4710 '''Not a class attribute docstring.'''
4711 pass
4713 (python-tests-look-at "Class attribute docstring.")
4714 (should (python-info-docstring-p))
4715 (python-tests-look-at "UR'''") ;; Additional class attr docstring
4716 (should (python-info-docstring-p))
4717 (python-tests-look-at "'''Not a class attribute docstring.'''")
4718 (should (not (python-info-docstring-p)))))
4720 (ert-deftest python-info-docstring-p-6 ()
4721 "Test class method docstring detection."
4722 (python-tests-with-temp-buffer
4724 class Class:
4726 def __init__(self, a, b):
4727 self.a = a
4728 self.b = b
4730 def __call__(self):
4731 '''Method docstring.
4733 pep-257-nn style.
4735 '''Additional method docstring.'''
4736 '''Not a method docstring.'''
4737 return self.a + self.b
4739 (python-tests-look-at "Method docstring.")
4740 (should (python-info-docstring-p))
4741 (python-tests-look-at "'''Additional method docstring.'''")
4742 (should (python-info-docstring-p))
4743 (python-tests-look-at "'''Not a method docstring.'''")
4744 (should (not (python-info-docstring-p)))))
4746 (ert-deftest python-info-encoding-from-cookie-1 ()
4747 "Should detect it on first line."
4748 (python-tests-with-temp-buffer
4749 "# coding=latin-1
4751 foo = True # another comment
4753 (should (eq (python-info-encoding-from-cookie) 'latin-1))))
4755 (ert-deftest python-info-encoding-from-cookie-2 ()
4756 "Should detect it on second line."
4757 (python-tests-with-temp-buffer
4759 # coding=latin-1
4761 foo = True # another comment
4763 (should (eq (python-info-encoding-from-cookie) 'latin-1))))
4765 (ert-deftest python-info-encoding-from-cookie-3 ()
4766 "Should not be detected on third line (and following ones)."
4767 (python-tests-with-temp-buffer
4770 # coding=latin-1
4771 foo = True # another comment
4773 (should (not (python-info-encoding-from-cookie)))))
4775 (ert-deftest python-info-encoding-from-cookie-4 ()
4776 "Should detect Emacs style."
4777 (python-tests-with-temp-buffer
4778 "# -*- coding: latin-1 -*-
4780 foo = True # another comment"
4781 (should (eq (python-info-encoding-from-cookie) 'latin-1))))
4783 (ert-deftest python-info-encoding-from-cookie-5 ()
4784 "Should detect Vim style."
4785 (python-tests-with-temp-buffer
4786 "# vim: set fileencoding=latin-1 :
4788 foo = True # another comment"
4789 (should (eq (python-info-encoding-from-cookie) 'latin-1))))
4791 (ert-deftest python-info-encoding-from-cookie-6 ()
4792 "First cookie wins."
4793 (python-tests-with-temp-buffer
4794 "# -*- coding: iso-8859-1 -*-
4795 # vim: set fileencoding=latin-1 :
4797 foo = True # another comment"
4798 (should (eq (python-info-encoding-from-cookie) 'iso-8859-1))))
4800 (ert-deftest python-info-encoding-from-cookie-7 ()
4801 "First cookie wins."
4802 (python-tests-with-temp-buffer
4803 "# vim: set fileencoding=latin-1 :
4804 # -*- coding: iso-8859-1 -*-
4806 foo = True # another comment"
4807 (should (eq (python-info-encoding-from-cookie) 'latin-1))))
4809 (ert-deftest python-info-encoding-1 ()
4810 "Should return the detected encoding from cookie."
4811 (python-tests-with-temp-buffer
4812 "# vim: set fileencoding=latin-1 :
4814 foo = True # another comment"
4815 (should (eq (python-info-encoding) 'latin-1))))
4817 (ert-deftest python-info-encoding-2 ()
4818 "Should default to utf-8."
4819 (python-tests-with-temp-buffer
4820 "# No encoding for you
4822 foo = True # another comment"
4823 (should (eq (python-info-encoding) 'utf-8))))
4826 ;;; Utility functions
4828 (ert-deftest python-util-goto-line-1 ()
4829 (python-tests-with-temp-buffer
4830 (concat
4831 "# a comment
4832 # another comment
4833 def foo(a, b, c):
4834 pass" (make-string 20 ?\n))
4835 (python-util-goto-line 10)
4836 (should (= (line-number-at-pos) 10))
4837 (python-util-goto-line 20)
4838 (should (= (line-number-at-pos) 20))))
4840 (ert-deftest python-util-clone-local-variables-1 ()
4841 (let ((buffer (generate-new-buffer
4842 "python-util-clone-local-variables-1"))
4843 (varcons
4844 '((python-fill-docstring-style . django)
4845 (python-shell-interpreter . "python")
4846 (python-shell-interpreter-args . "manage.py shell")
4847 (python-shell-prompt-regexp . "In \\[[0-9]+\\]: ")
4848 (python-shell-prompt-output-regexp . "Out\\[[0-9]+\\]: ")
4849 (python-shell-extra-pythonpaths "/home/user/pylib/")
4850 (python-shell-completion-setup-code
4851 . "from IPython.core.completerlib import module_completion")
4852 (python-shell-completion-string-code
4853 . "';'.join(get_ipython().Completer.all_completions('''%s'''))\n")
4854 (python-shell-virtualenv-root
4855 . "/home/user/.virtualenvs/project"))))
4856 (with-current-buffer buffer
4857 (kill-all-local-variables)
4858 (dolist (ccons varcons)
4859 (set (make-local-variable (car ccons)) (cdr ccons))))
4860 (python-tests-with-temp-buffer
4862 (python-util-clone-local-variables buffer)
4863 (dolist (ccons varcons)
4864 (should
4865 (equal (symbol-value (car ccons)) (cdr ccons)))))
4866 (kill-buffer buffer)))
4868 (ert-deftest python-util-strip-string-1 ()
4869 (should (string= (python-util-strip-string "\t\r\n str") "str"))
4870 (should (string= (python-util-strip-string "str \n\r") "str"))
4871 (should (string= (python-util-strip-string "\t\r\n str \n\r ") "str"))
4872 (should
4873 (string= (python-util-strip-string "\n str \nin \tg \n\r") "str \nin \tg"))
4874 (should (string= (python-util-strip-string "\n \t \n\r ") ""))
4875 (should (string= (python-util-strip-string "") "")))
4877 (ert-deftest python-util-forward-comment-1 ()
4878 (python-tests-with-temp-buffer
4879 (concat
4880 "# a comment
4881 # another comment
4882 # bad indented comment
4883 # more comments" (make-string 9999 ?\n))
4884 (python-util-forward-comment 1)
4885 (should (= (point) (point-max)))
4886 (python-util-forward-comment -1)
4887 (should (= (point) (point-min)))))
4889 (ert-deftest python-util-valid-regexp-p-1 ()
4890 (should (python-util-valid-regexp-p ""))
4891 (should (python-util-valid-regexp-p python-shell-prompt-regexp))
4892 (should (not (python-util-valid-regexp-p "\\("))))
4895 ;;; Electricity
4897 (ert-deftest python-parens-electric-indent-1 ()
4898 (let ((eim electric-indent-mode))
4899 (unwind-protect
4900 (progn
4901 (python-tests-with-temp-buffer
4903 from django.conf.urls import patterns, include, url
4905 from django.contrib import admin
4907 from myapp import views
4910 urlpatterns = patterns('',
4911 url(r'^$', views.index
4914 (electric-indent-mode 1)
4915 (python-tests-look-at "views.index")
4916 (end-of-line)
4918 ;; Inserting commas within the same line should leave
4919 ;; indentation unchanged.
4920 (python-tests-self-insert ",")
4921 (should (= (current-indentation) 4))
4923 ;; As well as any other input happening within the same
4924 ;; set of parens.
4925 (python-tests-self-insert " name='index')")
4926 (should (= (current-indentation) 4))
4928 ;; But a comma outside it, should trigger indentation.
4929 (python-tests-self-insert ",")
4930 (should (= (current-indentation) 23))
4932 ;; Newline indents to the first argument column
4933 (python-tests-self-insert "\n")
4934 (should (= (current-indentation) 23))
4936 ;; All this input must not change indentation
4937 (indent-line-to 4)
4938 (python-tests-self-insert "url(r'^/login$', views.login)")
4939 (should (= (current-indentation) 4))
4941 ;; But this comma does
4942 (python-tests-self-insert ",")
4943 (should (= (current-indentation) 23))))
4944 (or eim (electric-indent-mode -1)))))
4946 (ert-deftest python-triple-quote-pairing ()
4947 (let ((epm electric-pair-mode))
4948 (unwind-protect
4949 (progn
4950 (python-tests-with-temp-buffer
4951 "\"\"\n"
4952 (or epm (electric-pair-mode 1))
4953 (goto-char (1- (point-max)))
4954 (python-tests-self-insert ?\")
4955 (should (string= (buffer-string)
4956 "\"\"\"\"\"\"\n"))
4957 (should (= (point) 4)))
4958 (python-tests-with-temp-buffer
4959 "\n"
4960 (python-tests-self-insert (list ?\" ?\" ?\"))
4961 (should (string= (buffer-string)
4962 "\"\"\"\"\"\"\n"))
4963 (should (= (point) 4)))
4964 (python-tests-with-temp-buffer
4965 "\"\n\"\"\n"
4966 (goto-char (1- (point-max)))
4967 (python-tests-self-insert ?\")
4968 (should (= (point) (1- (point-max))))
4969 (should (string= (buffer-string)
4970 "\"\n\"\"\"\n"))))
4971 (or epm (electric-pair-mode -1)))))
4974 ;;; Hideshow support
4976 (ert-deftest python-hideshow-hide-levels-1 ()
4977 "Should hide all methods when called after class start."
4978 (let ((enabled hs-minor-mode))
4979 (unwind-protect
4980 (progn
4981 (python-tests-with-temp-buffer
4983 class SomeClass:
4985 def __init__(self, arg, kwarg=1):
4986 self.arg = arg
4987 self.kwarg = kwarg
4989 def filter(self, nums):
4990 def fn(item):
4991 return item in [self.arg, self.kwarg]
4992 return filter(fn, nums)
4994 def __str__(self):
4995 return '%s-%s' % (self.arg, self.kwarg)
4997 (hs-minor-mode 1)
4998 (python-tests-look-at "class SomeClass:")
4999 (forward-line)
5000 (hs-hide-level 1)
5001 (should
5002 (string=
5003 (python-tests-visible-string)
5005 class SomeClass:
5007 def __init__(self, arg, kwarg=1):
5008 def filter(self, nums):
5009 def __str__(self):"))))
5010 (or enabled (hs-minor-mode -1)))))
5012 (ert-deftest python-hideshow-hide-levels-2 ()
5013 "Should hide nested methods and parens at end of defun."
5014 (let ((enabled hs-minor-mode))
5015 (unwind-protect
5016 (progn
5017 (python-tests-with-temp-buffer
5019 class SomeClass:
5021 def __init__(self, arg, kwarg=1):
5022 self.arg = arg
5023 self.kwarg = kwarg
5025 def filter(self, nums):
5026 def fn(item):
5027 return item in [self.arg, self.kwarg]
5028 return filter(fn, nums)
5030 def __str__(self):
5031 return '%s-%s' % (self.arg, self.kwarg)
5033 (hs-minor-mode 1)
5034 (python-tests-look-at "def fn(item):")
5035 (hs-hide-block)
5036 (should
5037 (string=
5038 (python-tests-visible-string)
5040 class SomeClass:
5042 def __init__(self, arg, kwarg=1):
5043 self.arg = arg
5044 self.kwarg = kwarg
5046 def filter(self, nums):
5047 def fn(item):
5048 return filter(fn, nums)
5050 def __str__(self):
5051 return '%s-%s' % (self.arg, self.kwarg)
5052 "))))
5053 (or enabled (hs-minor-mode -1)))))
5057 (provide 'python-tests)
5059 ;; Local Variables:
5060 ;; coding: utf-8
5061 ;; indent-tabs-mode: nil
5062 ;; End:
5064 ;;; python-tests.el ends here