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