* lisp/progmodes/python.el (python-indent-post-self-insert-function):
[emacs.git] / test / automated / python-tests.el
bloba35242fe88228a5cb9a9fdf8368500092c72e9d8
1 ;;; python-tests.el --- Test suite for python.el
3 ;; Copyright (C) 2013-2014 Free Software Foundation, Inc.
5 ;; This file is part of GNU Emacs.
7 ;; GNU Emacs is free software: you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation, either version 3 of the License, or
10 ;; (at your option) any later version.
12 ;; GNU Emacs is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ;; GNU General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
20 ;;; Commentary:
22 ;;; Code:
24 (require 'ert)
25 (require 'python)
27 (defmacro python-tests-with-temp-buffer (contents &rest body)
28 "Create a `python-mode' enabled temp buffer with CONTENTS.
29 BODY is code to be executed within the temp buffer. Point is
30 always located at the beginning of buffer."
31 (declare (indent 1) (debug t))
32 `(with-temp-buffer
33 (python-mode)
34 (insert ,contents)
35 (goto-char (point-min))
36 ,@body))
38 (defmacro python-tests-with-temp-file (contents &rest body)
39 "Create a `python-mode' enabled file with CONTENTS.
40 BODY is code to be executed within the temp buffer. Point is
41 always located at the beginning of buffer."
42 (declare (indent 1) (debug t))
43 ;; temp-file never actually used for anything?
44 `(let* ((temp-file (make-temp-file "python-tests" nil ".py"))
45 (buffer (find-file-noselect temp-file)))
46 (unwind-protect
47 (with-current-buffer buffer
48 (python-mode)
49 (insert ,contents)
50 (goto-char (point-min))
51 ,@body)
52 (and buffer (kill-buffer buffer))
53 (delete-file temp-file))))
55 (defun python-tests-look-at (string &optional num restore-point)
56 "Move point at beginning of STRING in the current buffer.
57 Optional argument NUM defaults to 1 and is an integer indicating
58 how many occurrences must be found, when positive the search is
59 done forwards, otherwise backwards. When RESTORE-POINT is
60 non-nil the point is not moved but the position found is still
61 returned. When searching forward and point is already looking at
62 STRING, it is skipped so the next STRING occurrence is selected."
63 (let* ((num (or num 1))
64 (starting-point (point))
65 (string (regexp-quote string))
66 (search-fn (if (> num 0) #'re-search-forward #'re-search-backward))
67 (deinc-fn (if (> num 0) #'1- #'1+))
68 (found-point))
69 (prog2
70 (catch 'exit
71 (while (not (= num 0))
72 (when (and (> num 0)
73 (looking-at string))
74 ;; Moving forward and already looking at STRING, skip it.
75 (forward-char (length (match-string-no-properties 0))))
76 (and (not (funcall search-fn string nil t))
77 (throw 'exit t))
78 (when (> num 0)
79 ;; `re-search-forward' leaves point at the end of the
80 ;; occurrence, move back so point is at the beginning
81 ;; instead.
82 (forward-char (- (length (match-string-no-properties 0)))))
83 (setq
84 num (funcall deinc-fn num)
85 found-point (point))))
86 found-point
87 (and restore-point (goto-char starting-point)))))
89 (defun python-tests-self-insert (char-or-str)
90 "Call `self-insert-command' for chars in CHAR-OR-STR."
91 (let ((chars
92 (cond
93 ((characterp char-or-str)
94 (list char-or-str))
95 ((stringp char-or-str)
96 (string-to-list char-or-str))
97 ((not
98 (cl-remove-if #'characterp char-or-str))
99 char-or-str)
100 (t (error "CHAR-OR-STR must be a char, string, or list of char")))))
101 (mapc
102 (lambda (char)
103 (let ((last-command-event char))
104 (call-interactively 'self-insert-command)))
105 chars)))
108 ;;; Tests for your tests, so you can test while you test.
110 (ert-deftest python-tests-look-at-1 ()
111 "Test forward movement."
112 (python-tests-with-temp-buffer
113 "Lorem ipsum dolor sit amet, consectetur adipisicing elit,
114 sed do eiusmod tempor incididunt ut labore et dolore magna
115 aliqua."
116 (let ((expected (save-excursion
117 (dotimes (i 3)
118 (re-search-forward "et" nil t))
119 (forward-char -2)
120 (point))))
121 (should (= (python-tests-look-at "et" 3 t) expected))
122 ;; Even if NUM is bigger than found occurrences the point of last
123 ;; one should be returned.
124 (should (= (python-tests-look-at "et" 6 t) expected))
125 ;; If already looking at STRING, it should skip it.
126 (dotimes (i 2) (re-search-forward "et"))
127 (forward-char -2)
128 (should (= (python-tests-look-at "et") expected)))))
130 (ert-deftest python-tests-look-at-2 ()
131 "Test backward movement."
132 (python-tests-with-temp-buffer
133 "Lorem ipsum dolor sit amet, consectetur adipisicing elit,
134 sed do eiusmod tempor incididunt ut labore et dolore magna
135 aliqua."
136 (let ((expected
137 (save-excursion
138 (re-search-forward "et" nil t)
139 (forward-char -2)
140 (point))))
141 (dotimes (i 3)
142 (re-search-forward "et" nil t))
143 (should (= (python-tests-look-at "et" -3 t) expected))
144 (should (= (python-tests-look-at "et" -6 t) expected)))))
147 ;;; Bindings
150 ;;; Python specialized rx
153 ;;; Font-lock and syntax
155 (ert-deftest python-syntax-after-python-backspace ()
156 ;; `python-indent-dedent-line-backspace' garbles syntax
157 :expected-result :failed
158 (python-tests-with-temp-buffer
159 "\"\"\""
160 (goto-char (point-max))
161 (python-indent-dedent-line-backspace 1)
162 (should (string= (buffer-string) "\"\""))
163 (should (null (nth 3 (syntax-ppss))))))
166 ;;; Indentation
168 ;; See: http://www.python.org/dev/peps/pep-0008/#indentation
170 (ert-deftest python-indent-pep8-1 ()
171 "First pep8 case."
172 (python-tests-with-temp-buffer
173 "# Aligned with opening delimiter
174 foo = long_function_name(var_one, var_two,
175 var_three, var_four)
177 (should (eq (car (python-indent-context)) 'no-indent))
178 (should (= (python-indent-calculate-indentation) 0))
179 (python-tests-look-at "foo = long_function_name(var_one, var_two,")
180 (should (eq (car (python-indent-context)) 'after-line))
181 (should (= (python-indent-calculate-indentation) 0))
182 (python-tests-look-at "var_three, var_four)")
183 (should (eq (car (python-indent-context)) 'inside-paren))
184 (should (= (python-indent-calculate-indentation) 25))))
186 (ert-deftest python-indent-pep8-2 ()
187 "Second pep8 case."
188 (python-tests-with-temp-buffer
189 "# More indentation included to distinguish this from the rest.
190 def long_function_name(
191 var_one, var_two, var_three,
192 var_four):
193 print (var_one)
195 (should (eq (car (python-indent-context)) 'no-indent))
196 (should (= (python-indent-calculate-indentation) 0))
197 (python-tests-look-at "def long_function_name(")
198 (should (eq (car (python-indent-context)) 'after-line))
199 (should (= (python-indent-calculate-indentation) 0))
200 (python-tests-look-at "var_one, var_two, var_three,")
201 (should (eq (car (python-indent-context)) 'inside-paren))
202 (should (= (python-indent-calculate-indentation) 8))
203 (python-tests-look-at "var_four):")
204 (should (eq (car (python-indent-context)) 'inside-paren))
205 (should (= (python-indent-calculate-indentation) 8))
206 (python-tests-look-at "print (var_one)")
207 (should (eq (car (python-indent-context)) 'after-beginning-of-block))
208 (should (= (python-indent-calculate-indentation) 4))))
210 (ert-deftest python-indent-pep8-3 ()
211 "Third pep8 case."
212 (python-tests-with-temp-buffer
213 "# Extra indentation is not necessary.
214 foo = long_function_name(
215 var_one, var_two,
216 var_three, var_four)
218 (should (eq (car (python-indent-context)) 'no-indent))
219 (should (= (python-indent-calculate-indentation) 0))
220 (python-tests-look-at "foo = long_function_name(")
221 (should (eq (car (python-indent-context)) 'after-line))
222 (should (= (python-indent-calculate-indentation) 0))
223 (python-tests-look-at "var_one, var_two,")
224 (should (eq (car (python-indent-context)) 'inside-paren))
225 (should (= (python-indent-calculate-indentation) 4))
226 (python-tests-look-at "var_three, var_four)")
227 (should (eq (car (python-indent-context)) 'inside-paren))
228 (should (= (python-indent-calculate-indentation) 4))))
230 (ert-deftest python-indent-after-comment-1 ()
231 "The most simple after-comment case that shouldn't fail."
232 (python-tests-with-temp-buffer
233 "# Contents will be modified to correct indentation
234 class Blag(object):
235 def _on_child_complete(self, child_future):
236 if self.in_terminal_state():
237 pass
238 # We only complete when all our async children have entered a
239 # terminal state. At that point, if any child failed, we fail
240 # with the exception with which the first child failed.
242 (python-tests-look-at "# We only complete")
243 (should (eq (car (python-indent-context)) 'after-line))
244 (should (= (python-indent-calculate-indentation) 8))
245 (python-tests-look-at "# terminal state")
246 (should (eq (car (python-indent-context)) 'after-comment))
247 (should (= (python-indent-calculate-indentation) 8))
248 (python-tests-look-at "# with the exception")
249 (should (eq (car (python-indent-context)) 'after-comment))
250 ;; This one indents relative to previous block, even given the fact
251 ;; that it was under-indented.
252 (should (= (python-indent-calculate-indentation) 4))
253 (python-tests-look-at "# terminal state" -1)
254 ;; It doesn't hurt to check again.
255 (should (eq (car (python-indent-context)) 'after-comment))
256 (python-indent-line)
257 (should (= (current-indentation) 8))
258 (python-tests-look-at "# with the exception")
259 (should (eq (car (python-indent-context)) 'after-comment))
260 ;; Now everything should be lined up.
261 (should (= (python-indent-calculate-indentation) 8))))
263 (ert-deftest python-indent-after-comment-2 ()
264 "Test after-comment in weird cases."
265 (python-tests-with-temp-buffer
266 "# Contents will be modified to correct indentation
267 def func(arg):
268 # I don't do much
269 return arg
270 # This comment is badly indented just because.
271 # But we won't mess with the user in this line.
273 now_we_do_mess_cause_this_is_not_a_comment = 1
275 # yeah, that.
277 (python-tests-look-at "# I don't do much")
278 (should (eq (car (python-indent-context)) 'after-beginning-of-block))
279 (should (= (python-indent-calculate-indentation) 4))
280 (python-tests-look-at "return arg")
281 ;; Comment here just gets ignored, this line is not a comment so
282 ;; the rules won't apply here.
283 (should (eq (car (python-indent-context)) 'after-beginning-of-block))
284 (should (= (python-indent-calculate-indentation) 4))
285 (python-tests-look-at "# This comment is badly")
286 (should (eq (car (python-indent-context)) 'after-line))
287 ;; The return keyword moves indentation backwards 4 spaces, but
288 ;; let's assume this comment was placed there because the user
289 ;; wanted to (manually adding spaces or whatever).
290 (should (= (python-indent-calculate-indentation) 0))
291 (python-tests-look-at "# but we won't mess")
292 (should (eq (car (python-indent-context)) 'after-comment))
293 (should (= (python-indent-calculate-indentation) 4))
294 ;; Behave the same for blank lines: potentially a comment.
295 (forward-line 1)
296 (should (eq (car (python-indent-context)) 'after-comment))
297 (should (= (python-indent-calculate-indentation) 4))
298 (python-tests-look-at "now_we_do_mess")
299 ;; Here is where comment indentation starts to get ignored and
300 ;; where the user can't freely indent anymore.
301 (should (eq (car (python-indent-context)) 'after-line))
302 (should (= (python-indent-calculate-indentation) 0))
303 (python-tests-look-at "# yeah, that.")
304 (should (eq (car (python-indent-context)) 'after-line))
305 (should (= (python-indent-calculate-indentation) 0))))
307 (ert-deftest python-indent-inside-paren-1 ()
308 "The most simple inside-paren case that shouldn't fail."
309 (python-tests-with-temp-buffer
311 data = {
312 'key':
314 'objlist': [
316 'pk': 1,
317 'name': 'first',
320 'pk': 2,
321 'name': 'second',
327 (python-tests-look-at "data = {")
328 (should (eq (car (python-indent-context)) 'after-line))
329 (should (= (python-indent-calculate-indentation) 0))
330 (python-tests-look-at "'key':")
331 (should (eq (car (python-indent-context)) 'inside-paren))
332 (should (= (python-indent-calculate-indentation) 4))
333 (python-tests-look-at "{")
334 (should (eq (car (python-indent-context)) 'inside-paren))
335 (should (= (python-indent-calculate-indentation) 4))
336 (python-tests-look-at "'objlist': [")
337 (should (eq (car (python-indent-context)) 'inside-paren))
338 (should (= (python-indent-calculate-indentation) 8))
339 (python-tests-look-at "{")
340 (should (eq (car (python-indent-context)) 'inside-paren))
341 (should (= (python-indent-calculate-indentation) 12))
342 (python-tests-look-at "'pk': 1,")
343 (should (eq (car (python-indent-context)) 'inside-paren))
344 (should (= (python-indent-calculate-indentation) 16))
345 (python-tests-look-at "'name': 'first',")
346 (should (eq (car (python-indent-context)) 'inside-paren))
347 (should (= (python-indent-calculate-indentation) 16))
348 (python-tests-look-at "},")
349 (should (eq (car (python-indent-context)) 'inside-paren))
350 (should (= (python-indent-calculate-indentation) 12))
351 (python-tests-look-at "{")
352 (should (eq (car (python-indent-context)) 'inside-paren))
353 (should (= (python-indent-calculate-indentation) 12))
354 (python-tests-look-at "'pk': 2,")
355 (should (eq (car (python-indent-context)) 'inside-paren))
356 (should (= (python-indent-calculate-indentation) 16))
357 (python-tests-look-at "'name': 'second',")
358 (should (eq (car (python-indent-context)) 'inside-paren))
359 (should (= (python-indent-calculate-indentation) 16))
360 (python-tests-look-at "}")
361 (should (eq (car (python-indent-context)) 'inside-paren))
362 (should (= (python-indent-calculate-indentation) 12))
363 (python-tests-look-at "]")
364 (should (eq (car (python-indent-context)) 'inside-paren))
365 (should (= (python-indent-calculate-indentation) 8))
366 (python-tests-look-at "}")
367 (should (eq (car (python-indent-context)) 'inside-paren))
368 (should (= (python-indent-calculate-indentation) 4))
369 (python-tests-look-at "}")
370 (should (eq (car (python-indent-context)) 'inside-paren))
371 (should (= (python-indent-calculate-indentation) 0))))
373 (ert-deftest python-indent-inside-paren-2 ()
374 "Another more compact paren group style."
375 (python-tests-with-temp-buffer
377 data = {'key': {
378 'objlist': [
379 {'pk': 1,
380 'name': 'first'},
381 {'pk': 2,
382 'name': 'second'}
386 (python-tests-look-at "data = {")
387 (should (eq (car (python-indent-context)) 'after-line))
388 (should (= (python-indent-calculate-indentation) 0))
389 (python-tests-look-at "'objlist': [")
390 (should (eq (car (python-indent-context)) 'inside-paren))
391 (should (= (python-indent-calculate-indentation) 4))
392 (python-tests-look-at "{'pk': 1,")
393 (should (eq (car (python-indent-context)) 'inside-paren))
394 (should (= (python-indent-calculate-indentation) 8))
395 (python-tests-look-at "'name': 'first'},")
396 (should (eq (car (python-indent-context)) 'inside-paren))
397 (should (= (python-indent-calculate-indentation) 9))
398 (python-tests-look-at "{'pk': 2,")
399 (should (eq (car (python-indent-context)) 'inside-paren))
400 (should (= (python-indent-calculate-indentation) 8))
401 (python-tests-look-at "'name': 'second'}")
402 (should (eq (car (python-indent-context)) 'inside-paren))
403 (should (= (python-indent-calculate-indentation) 9))
404 (python-tests-look-at "]")
405 (should (eq (car (python-indent-context)) 'inside-paren))
406 (should (= (python-indent-calculate-indentation) 4))
407 (python-tests-look-at "}}")
408 (should (eq (car (python-indent-context)) 'inside-paren))
409 (should (= (python-indent-calculate-indentation) 0))
410 (python-tests-look-at "}")
411 (should (eq (car (python-indent-context)) 'inside-paren))
412 (should (= (python-indent-calculate-indentation) 0))))
414 (ert-deftest python-indent-after-block-1 ()
415 "The most simple after-block case that shouldn't fail."
416 (python-tests-with-temp-buffer
418 def foo(a, b, c=True):
420 (should (eq (car (python-indent-context)) 'no-indent))
421 (should (= (python-indent-calculate-indentation) 0))
422 (goto-char (point-max))
423 (should (eq (car (python-indent-context)) 'after-beginning-of-block))
424 (should (= (python-indent-calculate-indentation) 4))))
426 (ert-deftest python-indent-after-block-2 ()
427 "A weird (malformed) multiline block statement."
428 (python-tests-with-temp-buffer
430 def foo(a, b, c={
431 'a':
434 (goto-char (point-max))
435 (should (eq (car (python-indent-context)) 'after-beginning-of-block))
436 (should (= (python-indent-calculate-indentation) 4))))
438 (ert-deftest python-indent-dedenters-1 ()
439 "Check all dedenters."
440 (python-tests-with-temp-buffer
442 def foo(a, b, c):
443 if a:
444 print (a)
445 elif b:
446 print (b)
447 else:
448 try:
449 print (c.pop())
450 except (IndexError, AttributeError):
451 print (c)
452 finally:
453 print ('nor a, nor b are true')
455 (python-tests-look-at "if a:")
456 (should (eq (car (python-indent-context)) 'after-beginning-of-block))
457 (should (= (python-indent-calculate-indentation) 4))
458 (python-tests-look-at "print (a)")
459 (should (eq (car (python-indent-context)) 'after-beginning-of-block))
460 (should (= (python-indent-calculate-indentation) 8))
461 (python-tests-look-at "elif b:")
462 (should (eq (car (python-indent-context)) 'after-line))
463 (should (= (python-indent-calculate-indentation) 4))
464 (python-tests-look-at "print (b)")
465 (should (eq (car (python-indent-context)) 'after-beginning-of-block))
466 (should (= (python-indent-calculate-indentation) 8))
467 (python-tests-look-at "else:")
468 (should (eq (car (python-indent-context)) 'after-line))
469 (should (= (python-indent-calculate-indentation) 4))
470 (python-tests-look-at "try:")
471 (should (eq (car (python-indent-context)) 'after-beginning-of-block))
472 (should (= (python-indent-calculate-indentation) 8))
473 (python-tests-look-at "print (c.pop())")
474 (should (eq (car (python-indent-context)) 'after-beginning-of-block))
475 (should (= (python-indent-calculate-indentation) 12))
476 (python-tests-look-at "except (IndexError, AttributeError):")
477 (should (eq (car (python-indent-context)) 'after-line))
478 (should (= (python-indent-calculate-indentation) 8))
479 (python-tests-look-at "print (c)")
480 (should (eq (car (python-indent-context)) 'after-beginning-of-block))
481 (should (= (python-indent-calculate-indentation) 12))
482 (python-tests-look-at "finally:")
483 (should (eq (car (python-indent-context)) 'after-line))
484 (should (= (python-indent-calculate-indentation) 8))
485 (python-tests-look-at "print ('nor a, nor b are true')")
486 (should (eq (car (python-indent-context)) 'after-beginning-of-block))
487 (should (= (python-indent-calculate-indentation) 12))))
489 (ert-deftest python-indent-dedenters-2 ()
490 "Check one-liner block special case.."
491 (python-tests-with-temp-buffer
493 cond = True
494 if cond:
496 if cond: print 'True'
497 else: print 'False'
499 else:
500 return
502 (python-tests-look-at "else: print 'False'")
503 ;; When a block has code after ":" it's just considered a simple
504 ;; line as that's a common thing to happen in one-liners.
505 (should (eq (car (python-indent-context)) 'after-line))
506 (should (= (python-indent-calculate-indentation) 4))
507 (python-tests-look-at "else:")
508 (should (eq (car (python-indent-context)) 'after-line))
509 (should (= (python-indent-calculate-indentation) 0))))
511 (ert-deftest python-indent-after-backslash-1 ()
512 "The most common case."
513 (python-tests-with-temp-buffer
515 from foo.bar.baz import something, something_1 \\\\
516 something_2 something_3, \\\\
517 something_4, something_5
519 (python-tests-look-at "from foo.bar.baz import something, something_1")
520 (should (eq (car (python-indent-context)) 'after-line))
521 (should (= (python-indent-calculate-indentation) 0))
522 (python-tests-look-at "something_2 something_3,")
523 (should (eq (car (python-indent-context)) 'after-backslash))
524 (should (= (python-indent-calculate-indentation) 4))
525 (python-tests-look-at "something_4, something_5")
526 (should (eq (car (python-indent-context)) 'after-backslash))
527 (should (= (python-indent-calculate-indentation) 4))
528 (goto-char (point-max))
529 (should (eq (car (python-indent-context)) 'after-line))
530 (should (= (python-indent-calculate-indentation) 0))))
532 (ert-deftest python-indent-after-backslash-2 ()
533 "A pretty extreme complicated case."
534 (python-tests-with-temp-buffer
536 objects = Thing.objects.all() \\\\
537 .filter(
538 type='toy',
539 status='bought'
540 ) \\\\
541 .aggregate(
542 Sum('amount')
543 ) \\\\
544 .values_list()
546 (python-tests-look-at "objects = Thing.objects.all()")
547 (should (eq (car (python-indent-context)) 'after-line))
548 (should (= (python-indent-calculate-indentation) 0))
549 (python-tests-look-at ".filter(")
550 (should (eq (car (python-indent-context)) 'after-backslash))
551 (should (= (python-indent-calculate-indentation) 23))
552 (python-tests-look-at "type='toy',")
553 (should (eq (car (python-indent-context)) 'inside-paren))
554 (should (= (python-indent-calculate-indentation) 27))
555 (python-tests-look-at "status='bought'")
556 (should (eq (car (python-indent-context)) 'inside-paren))
557 (should (= (python-indent-calculate-indentation) 27))
558 (python-tests-look-at ") \\\\")
559 (should (eq (car (python-indent-context)) 'inside-paren))
560 (should (= (python-indent-calculate-indentation) 23))
561 (python-tests-look-at ".aggregate(")
562 (should (eq (car (python-indent-context)) 'after-backslash))
563 (should (= (python-indent-calculate-indentation) 23))
564 (python-tests-look-at "Sum('amount')")
565 (should (eq (car (python-indent-context)) 'inside-paren))
566 (should (= (python-indent-calculate-indentation) 27))
567 (python-tests-look-at ") \\\\")
568 (should (eq (car (python-indent-context)) 'inside-paren))
569 (should (= (python-indent-calculate-indentation) 23))
570 (python-tests-look-at ".values_list()")
571 (should (eq (car (python-indent-context)) 'after-backslash))
572 (should (= (python-indent-calculate-indentation) 23))
573 (forward-line 1)
574 (should (eq (car (python-indent-context)) 'after-line))
575 (should (= (python-indent-calculate-indentation) 0))))
577 (ert-deftest python-indent-block-enders-1 ()
578 "Test `python-indent-block-enders' value honoring."
579 (python-tests-with-temp-buffer
581 Class foo(object):
583 def bar(self):
584 if self.baz:
585 return (1,
589 else:
590 pass
592 (python-tests-look-at "3)")
593 (forward-line 1)
594 (should (= (python-indent-calculate-indentation) 8))
595 (python-tests-look-at "pass")
596 (forward-line 1)
597 (should (= (python-indent-calculate-indentation) 8))))
599 (ert-deftest python-indent-block-enders-2 ()
600 "Test `python-indent-block-enders' value honoring."
601 (python-tests-with-temp-buffer
603 Class foo(object):
604 '''raise lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
606 eiusmod tempor incididunt ut labore et dolore magna aliqua.
608 def bar(self):
609 \"return (1, 2, 3).\"
610 if self.baz:
611 return (1,
615 (python-tests-look-at "def")
616 (should (= (python-indent-calculate-indentation) 4))
617 (python-tests-look-at "if")
618 (should (= (python-indent-calculate-indentation) 8))))
621 ;;; Navigation
623 (ert-deftest python-nav-beginning-of-defun-1 ()
624 (python-tests-with-temp-buffer
626 def decoratorFunctionWithArguments(arg1, arg2, arg3):
627 '''print decorated function call data to stdout.
629 Usage:
631 @decoratorFunctionWithArguments('arg1', 'arg2')
632 def func(a, b, c=True):
633 pass
636 def wwrap(f):
637 print 'Inside wwrap()'
638 def wrapped_f(*args):
639 print 'Inside wrapped_f()'
640 print 'Decorator arguments:', arg1, arg2, arg3
641 f(*args)
642 print 'After f(*args)'
643 return wrapped_f
644 return wwrap
646 (python-tests-look-at "return wrap")
647 (should (= (save-excursion
648 (python-nav-beginning-of-defun)
649 (point))
650 (save-excursion
651 (python-tests-look-at "def wrapped_f(*args):" -1)
652 (beginning-of-line)
653 (point))))
654 (python-tests-look-at "def wrapped_f(*args):" -1)
655 (should (= (save-excursion
656 (python-nav-beginning-of-defun)
657 (point))
658 (save-excursion
659 (python-tests-look-at "def wwrap(f):" -1)
660 (beginning-of-line)
661 (point))))
662 (python-tests-look-at "def wwrap(f):" -1)
663 (should (= (save-excursion
664 (python-nav-beginning-of-defun)
665 (point))
666 (save-excursion
667 (python-tests-look-at "def decoratorFunctionWithArguments" -1)
668 (beginning-of-line)
669 (point))))))
671 (ert-deftest python-nav-beginning-of-defun-2 ()
672 (python-tests-with-temp-buffer
674 class C(object):
676 def m(self):
677 self.c()
679 def b():
680 pass
682 def a():
683 pass
685 def c(self):
686 pass
688 ;; Nested defuns, are handled with care.
689 (python-tests-look-at "def c(self):")
690 (should (= (save-excursion
691 (python-nav-beginning-of-defun)
692 (point))
693 (save-excursion
694 (python-tests-look-at "def m(self):" -1)
695 (beginning-of-line)
696 (point))))
697 ;; Defuns on same levels should be respected.
698 (python-tests-look-at "def a():" -1)
699 (should (= (save-excursion
700 (python-nav-beginning-of-defun)
701 (point))
702 (save-excursion
703 (python-tests-look-at "def b():" -1)
704 (beginning-of-line)
705 (point))))
706 ;; Jump to a top level defun.
707 (python-tests-look-at "def b():" -1)
708 (should (= (save-excursion
709 (python-nav-beginning-of-defun)
710 (point))
711 (save-excursion
712 (python-tests-look-at "def m(self):" -1)
713 (beginning-of-line)
714 (point))))
715 ;; Jump to a top level defun again.
716 (python-tests-look-at "def m(self):" -1)
717 (should (= (save-excursion
718 (python-nav-beginning-of-defun)
719 (point))
720 (save-excursion
721 (python-tests-look-at "class C(object):" -1)
722 (beginning-of-line)
723 (point))))))
725 (ert-deftest python-nav-end-of-defun-1 ()
726 (python-tests-with-temp-buffer
728 class C(object):
730 def m(self):
731 self.c()
733 def b():
734 pass
736 def a():
737 pass
739 def c(self):
740 pass
742 (should (= (save-excursion
743 (python-tests-look-at "class C(object):")
744 (python-nav-end-of-defun)
745 (point))
746 (save-excursion
747 (point-max))))
748 (should (= (save-excursion
749 (python-tests-look-at "def m(self):")
750 (python-nav-end-of-defun)
751 (point))
752 (save-excursion
753 (python-tests-look-at "def c(self):")
754 (forward-line -1)
755 (point))))
756 (should (= (save-excursion
757 (python-tests-look-at "def b():")
758 (python-nav-end-of-defun)
759 (point))
760 (save-excursion
761 (python-tests-look-at "def b():")
762 (forward-line 2)
763 (point))))
764 (should (= (save-excursion
765 (python-tests-look-at "def c(self):")
766 (python-nav-end-of-defun)
767 (point))
768 (save-excursion
769 (point-max))))))
771 (ert-deftest python-nav-end-of-defun-2 ()
772 (python-tests-with-temp-buffer
774 def decoratorFunctionWithArguments(arg1, arg2, arg3):
775 '''print decorated function call data to stdout.
777 Usage:
779 @decoratorFunctionWithArguments('arg1', 'arg2')
780 def func(a, b, c=True):
781 pass
784 def wwrap(f):
785 print 'Inside wwrap()'
786 def wrapped_f(*args):
787 print 'Inside wrapped_f()'
788 print 'Decorator arguments:', arg1, arg2, arg3
789 f(*args)
790 print 'After f(*args)'
791 return wrapped_f
792 return wwrap
794 (should (= (save-excursion
795 (python-tests-look-at "def decoratorFunctionWithArguments")
796 (python-nav-end-of-defun)
797 (point))
798 (save-excursion
799 (point-max))))
800 (should (= (save-excursion
801 (python-tests-look-at "@decoratorFunctionWithArguments")
802 (python-nav-end-of-defun)
803 (point))
804 (save-excursion
805 (point-max))))
806 (should (= (save-excursion
807 (python-tests-look-at "def wwrap(f):")
808 (python-nav-end-of-defun)
809 (point))
810 (save-excursion
811 (python-tests-look-at "return wwrap")
812 (line-beginning-position))))
813 (should (= (save-excursion
814 (python-tests-look-at "def wrapped_f(*args):")
815 (python-nav-end-of-defun)
816 (point))
817 (save-excursion
818 (python-tests-look-at "return wrapped_f")
819 (line-beginning-position))))
820 (should (= (save-excursion
821 (python-tests-look-at "f(*args)")
822 (python-nav-end-of-defun)
823 (point))
824 (save-excursion
825 (python-tests-look-at "return wrapped_f")
826 (line-beginning-position))))))
828 (ert-deftest python-nav-backward-defun-1 ()
829 (python-tests-with-temp-buffer
831 class A(object): # A
833 def a(self): # a
834 pass
836 def b(self): # b
837 pass
839 class B(object): # B
841 class C(object): # C
843 def d(self): # d
844 pass
846 # def e(self): # e
847 # pass
849 def c(self): # c
850 pass
852 # def d(self): # d
853 # pass
855 (goto-char (point-max))
856 (should (= (save-excursion (python-nav-backward-defun))
857 (python-tests-look-at " def c(self): # c" -1)))
858 (should (= (save-excursion (python-nav-backward-defun))
859 (python-tests-look-at " def d(self): # d" -1)))
860 (should (= (save-excursion (python-nav-backward-defun))
861 (python-tests-look-at " class C(object): # C" -1)))
862 (should (= (save-excursion (python-nav-backward-defun))
863 (python-tests-look-at " class B(object): # B" -1)))
864 (should (= (save-excursion (python-nav-backward-defun))
865 (python-tests-look-at " def b(self): # b" -1)))
866 (should (= (save-excursion (python-nav-backward-defun))
867 (python-tests-look-at " def a(self): # a" -1)))
868 (should (= (save-excursion (python-nav-backward-defun))
869 (python-tests-look-at "class A(object): # A" -1)))
870 (should (not (python-nav-backward-defun)))))
872 (ert-deftest python-nav-backward-defun-2 ()
873 (python-tests-with-temp-buffer
875 def decoratorFunctionWithArguments(arg1, arg2, arg3):
876 '''print decorated function call data to stdout.
878 Usage:
880 @decoratorFunctionWithArguments('arg1', 'arg2')
881 def func(a, b, c=True):
882 pass
885 def wwrap(f):
886 print 'Inside wwrap()'
887 def wrapped_f(*args):
888 print 'Inside wrapped_f()'
889 print 'Decorator arguments:', arg1, arg2, arg3
890 f(*args)
891 print 'After f(*args)'
892 return wrapped_f
893 return wwrap
895 (goto-char (point-max))
896 (should (= (save-excursion (python-nav-backward-defun))
897 (python-tests-look-at " def wrapped_f(*args):" -1)))
898 (should (= (save-excursion (python-nav-backward-defun))
899 (python-tests-look-at " def wwrap(f):" -1)))
900 (should (= (save-excursion (python-nav-backward-defun))
901 (python-tests-look-at "def decoratorFunctionWithArguments(arg1, arg2, arg3):" -1)))
902 (should (not (python-nav-backward-defun)))))
904 (ert-deftest python-nav-backward-defun-3 ()
905 (python-tests-with-temp-buffer
908 def u(self):
909 pass
911 def v(self):
912 pass
914 def w(self):
915 pass
918 class A(object):
919 pass
921 (goto-char (point-min))
922 (let ((point (python-tests-look-at "class A(object):")))
923 (should (not (python-nav-backward-defun)))
924 (should (= point (point))))))
926 (ert-deftest python-nav-forward-defun-1 ()
927 (python-tests-with-temp-buffer
929 class A(object): # A
931 def a(self): # a
932 pass
934 def b(self): # b
935 pass
937 class B(object): # B
939 class C(object): # C
941 def d(self): # d
942 pass
944 # def e(self): # e
945 # pass
947 def c(self): # c
948 pass
950 # def d(self): # d
951 # pass
953 (goto-char (point-min))
954 (should (= (save-excursion (python-nav-forward-defun))
955 (python-tests-look-at "(object): # A")))
956 (should (= (save-excursion (python-nav-forward-defun))
957 (python-tests-look-at "(self): # a")))
958 (should (= (save-excursion (python-nav-forward-defun))
959 (python-tests-look-at "(self): # b")))
960 (should (= (save-excursion (python-nav-forward-defun))
961 (python-tests-look-at "(object): # B")))
962 (should (= (save-excursion (python-nav-forward-defun))
963 (python-tests-look-at "(object): # C")))
964 (should (= (save-excursion (python-nav-forward-defun))
965 (python-tests-look-at "(self): # d")))
966 (should (= (save-excursion (python-nav-forward-defun))
967 (python-tests-look-at "(self): # c")))
968 (should (not (python-nav-forward-defun)))))
970 (ert-deftest python-nav-forward-defun-2 ()
971 (python-tests-with-temp-buffer
973 def decoratorFunctionWithArguments(arg1, arg2, arg3):
974 '''print decorated function call data to stdout.
976 Usage:
978 @decoratorFunctionWithArguments('arg1', 'arg2')
979 def func(a, b, c=True):
980 pass
983 def wwrap(f):
984 print 'Inside wwrap()'
985 def wrapped_f(*args):
986 print 'Inside wrapped_f()'
987 print 'Decorator arguments:', arg1, arg2, arg3
988 f(*args)
989 print 'After f(*args)'
990 return wrapped_f
991 return wwrap
993 (goto-char (point-min))
994 (should (= (save-excursion (python-nav-forward-defun))
995 (python-tests-look-at "(arg1, arg2, arg3):")))
996 (should (= (save-excursion (python-nav-forward-defun))
997 (python-tests-look-at "(f):")))
998 (should (= (save-excursion (python-nav-forward-defun))
999 (python-tests-look-at "(*args):")))
1000 (should (not (python-nav-forward-defun)))))
1002 (ert-deftest python-nav-forward-defun-3 ()
1003 (python-tests-with-temp-buffer
1005 class A(object):
1006 pass
1009 def u(self):
1010 pass
1012 def v(self):
1013 pass
1015 def w(self):
1016 pass
1019 (goto-char (point-min))
1020 (let ((point (python-tests-look-at "(object):")))
1021 (should (not (python-nav-forward-defun)))
1022 (should (= point (point))))))
1024 (ert-deftest python-nav-beginning-of-statement-1 ()
1025 (python-tests-with-temp-buffer
1027 v1 = 123 + \
1028 456 + \
1030 v2 = (value1,
1031 value2,
1033 value3,
1034 value4)
1035 v3 = ('this is a string'
1037 'that is continued'
1038 'between lines'
1039 'within a paren',
1040 # this is a comment, yo
1041 'continue previous line')
1042 v4 = '''
1043 a very long
1044 string
1047 (python-tests-look-at "v2 =")
1048 (python-util-forward-comment -1)
1049 (should (= (save-excursion
1050 (python-nav-beginning-of-statement)
1051 (point))
1052 (python-tests-look-at "v1 =" -1 t)))
1053 (python-tests-look-at "v3 =")
1054 (python-util-forward-comment -1)
1055 (should (= (save-excursion
1056 (python-nav-beginning-of-statement)
1057 (point))
1058 (python-tests-look-at "v2 =" -1 t)))
1059 (python-tests-look-at "v4 =")
1060 (python-util-forward-comment -1)
1061 (should (= (save-excursion
1062 (python-nav-beginning-of-statement)
1063 (point))
1064 (python-tests-look-at "v3 =" -1 t)))
1065 (goto-char (point-max))
1066 (python-util-forward-comment -1)
1067 (should (= (save-excursion
1068 (python-nav-beginning-of-statement)
1069 (point))
1070 (python-tests-look-at "v4 =" -1 t)))))
1072 (ert-deftest python-nav-end-of-statement-1 ()
1073 (python-tests-with-temp-buffer
1075 v1 = 123 + \
1076 456 + \
1078 v2 = (value1,
1079 value2,
1081 value3,
1082 value4)
1083 v3 = ('this is a string'
1085 'that is continued'
1086 'between lines'
1087 'within a paren',
1088 # this is a comment, yo
1089 'continue previous line')
1090 v4 = '''
1091 a very long
1092 string
1095 (python-tests-look-at "v1 =")
1096 (should (= (save-excursion
1097 (python-nav-end-of-statement)
1098 (point))
1099 (save-excursion
1100 (python-tests-look-at "789")
1101 (line-end-position))))
1102 (python-tests-look-at "v2 =")
1103 (should (= (save-excursion
1104 (python-nav-end-of-statement)
1105 (point))
1106 (save-excursion
1107 (python-tests-look-at "value4)")
1108 (line-end-position))))
1109 (python-tests-look-at "v3 =")
1110 (should (= (save-excursion
1111 (python-nav-end-of-statement)
1112 (point))
1113 (save-excursion
1114 (python-tests-look-at
1115 "'continue previous line')")
1116 (line-end-position))))
1117 (python-tests-look-at "v4 =")
1118 (should (= (save-excursion
1119 (python-nav-end-of-statement)
1120 (point))
1121 (save-excursion
1122 (goto-char (point-max))
1123 (python-util-forward-comment -1)
1124 (point))))))
1126 (ert-deftest python-nav-forward-statement-1 ()
1127 (python-tests-with-temp-buffer
1129 v1 = 123 + \
1130 456 + \
1132 v2 = (value1,
1133 value2,
1135 value3,
1136 value4)
1137 v3 = ('this is a string'
1139 'that is continued'
1140 'between lines'
1141 'within a paren',
1142 # this is a comment, yo
1143 'continue previous line')
1144 v4 = '''
1145 a very long
1146 string
1149 (python-tests-look-at "v1 =")
1150 (should (= (save-excursion
1151 (python-nav-forward-statement)
1152 (point))
1153 (python-tests-look-at "v2 =")))
1154 (should (= (save-excursion
1155 (python-nav-forward-statement)
1156 (point))
1157 (python-tests-look-at "v3 =")))
1158 (should (= (save-excursion
1159 (python-nav-forward-statement)
1160 (point))
1161 (python-tests-look-at "v4 =")))
1162 (should (= (save-excursion
1163 (python-nav-forward-statement)
1164 (point))
1165 (point-max)))))
1167 (ert-deftest python-nav-backward-statement-1 ()
1168 (python-tests-with-temp-buffer
1170 v1 = 123 + \
1171 456 + \
1173 v2 = (value1,
1174 value2,
1176 value3,
1177 value4)
1178 v3 = ('this is a string'
1180 'that is continued'
1181 'between lines'
1182 'within a paren',
1183 # this is a comment, yo
1184 'continue previous line')
1185 v4 = '''
1186 a very long
1187 string
1190 (goto-char (point-max))
1191 (should (= (save-excursion
1192 (python-nav-backward-statement)
1193 (point))
1194 (python-tests-look-at "v4 =" -1)))
1195 (should (= (save-excursion
1196 (python-nav-backward-statement)
1197 (point))
1198 (python-tests-look-at "v3 =" -1)))
1199 (should (= (save-excursion
1200 (python-nav-backward-statement)
1201 (point))
1202 (python-tests-look-at "v2 =" -1)))
1203 (should (= (save-excursion
1204 (python-nav-backward-statement)
1205 (point))
1206 (python-tests-look-at "v1 =" -1)))))
1208 (ert-deftest python-nav-backward-statement-2 ()
1209 :expected-result :failed
1210 (python-tests-with-temp-buffer
1212 v1 = 123 + \
1213 456 + \
1215 v2 = (value1,
1216 value2,
1218 value3,
1219 value4)
1221 ;; FIXME: For some reason `python-nav-backward-statement' is moving
1222 ;; back two sentences when starting from 'value4)'.
1223 (goto-char (point-max))
1224 (python-util-forward-comment -1)
1225 (should (= (save-excursion
1226 (python-nav-backward-statement)
1227 (point))
1228 (python-tests-look-at "v2 =" -1 t)))))
1230 (ert-deftest python-nav-beginning-of-block-1 ()
1231 (python-tests-with-temp-buffer
1233 def decoratorFunctionWithArguments(arg1, arg2, arg3):
1234 '''print decorated function call data to stdout.
1236 Usage:
1238 @decoratorFunctionWithArguments('arg1', 'arg2')
1239 def func(a, b, c=True):
1240 pass
1243 def wwrap(f):
1244 print 'Inside wwrap()'
1245 def wrapped_f(*args):
1246 print 'Inside wrapped_f()'
1247 print 'Decorator arguments:', arg1, arg2, arg3
1248 f(*args)
1249 print 'After f(*args)'
1250 return wrapped_f
1251 return wwrap
1253 (python-tests-look-at "return wwrap")
1254 (should (= (save-excursion
1255 (python-nav-beginning-of-block)
1256 (point))
1257 (python-tests-look-at "def decoratorFunctionWithArguments" -1)))
1258 (python-tests-look-at "print 'Inside wwrap()'")
1259 (should (= (save-excursion
1260 (python-nav-beginning-of-block)
1261 (point))
1262 (python-tests-look-at "def wwrap(f):" -1)))
1263 (python-tests-look-at "print 'After f(*args)'")
1264 (end-of-line)
1265 (should (= (save-excursion
1266 (python-nav-beginning-of-block)
1267 (point))
1268 (python-tests-look-at "def wrapped_f(*args):" -1)))
1269 (python-tests-look-at "return wrapped_f")
1270 (should (= (save-excursion
1271 (python-nav-beginning-of-block)
1272 (point))
1273 (python-tests-look-at "def wwrap(f):" -1)))))
1275 (ert-deftest python-nav-end-of-block-1 ()
1276 (python-tests-with-temp-buffer
1278 def decoratorFunctionWithArguments(arg1, arg2, arg3):
1279 '''print decorated function call data to stdout.
1281 Usage:
1283 @decoratorFunctionWithArguments('arg1', 'arg2')
1284 def func(a, b, c=True):
1285 pass
1288 def wwrap(f):
1289 print 'Inside wwrap()'
1290 def wrapped_f(*args):
1291 print 'Inside wrapped_f()'
1292 print 'Decorator arguments:', arg1, arg2, arg3
1293 f(*args)
1294 print 'After f(*args)'
1295 return wrapped_f
1296 return wwrap
1298 (python-tests-look-at "def decoratorFunctionWithArguments")
1299 (should (= (save-excursion
1300 (python-nav-end-of-block)
1301 (point))
1302 (save-excursion
1303 (goto-char (point-max))
1304 (python-util-forward-comment -1)
1305 (point))))
1306 (python-tests-look-at "def wwrap(f):")
1307 (should (= (save-excursion
1308 (python-nav-end-of-block)
1309 (point))
1310 (save-excursion
1311 (python-tests-look-at "return wrapped_f")
1312 (line-end-position))))
1313 (end-of-line)
1314 (should (= (save-excursion
1315 (python-nav-end-of-block)
1316 (point))
1317 (save-excursion
1318 (python-tests-look-at "return wrapped_f")
1319 (line-end-position))))
1320 (python-tests-look-at "f(*args)")
1321 (should (= (save-excursion
1322 (python-nav-end-of-block)
1323 (point))
1324 (save-excursion
1325 (python-tests-look-at "print 'After f(*args)'")
1326 (line-end-position))))))
1328 (ert-deftest python-nav-forward-block-1 ()
1329 "This also accounts as a test for `python-nav-backward-block'."
1330 (python-tests-with-temp-buffer
1332 if request.user.is_authenticated():
1333 # def block():
1334 # pass
1335 try:
1336 profile = request.user.get_profile()
1337 except Profile.DoesNotExist:
1338 profile = Profile.objects.create(user=request.user)
1339 else:
1340 if profile.stats:
1341 profile.recalculate_stats()
1342 else:
1343 profile.clear_stats()
1344 finally:
1345 profile.views += 1
1346 profile.save()
1348 (should (= (save-excursion (python-nav-forward-block))
1349 (python-tests-look-at "if request.user.is_authenticated():")))
1350 (should (= (save-excursion (python-nav-forward-block))
1351 (python-tests-look-at "try:")))
1352 (should (= (save-excursion (python-nav-forward-block))
1353 (python-tests-look-at "except Profile.DoesNotExist:")))
1354 (should (= (save-excursion (python-nav-forward-block))
1355 (python-tests-look-at "else:")))
1356 (should (= (save-excursion (python-nav-forward-block))
1357 (python-tests-look-at "if profile.stats:")))
1358 (should (= (save-excursion (python-nav-forward-block))
1359 (python-tests-look-at "else:")))
1360 (should (= (save-excursion (python-nav-forward-block))
1361 (python-tests-look-at "finally:")))
1362 ;; When point is at the last block, leave it there and return nil
1363 (should (not (save-excursion (python-nav-forward-block))))
1364 ;; Move backwards, and even if the number of moves is less than the
1365 ;; provided argument return the point.
1366 (should (= (save-excursion (python-nav-forward-block -10))
1367 (python-tests-look-at
1368 "if request.user.is_authenticated():" -1)))))
1370 (ert-deftest python-nav-forward-sexp-1 ()
1371 (python-tests-with-temp-buffer
1377 (python-tests-look-at "a()")
1378 (python-nav-forward-sexp)
1379 (should (looking-at "$"))
1380 (should (save-excursion
1381 (beginning-of-line)
1382 (looking-at "a()")))
1383 (python-nav-forward-sexp)
1384 (should (looking-at "$"))
1385 (should (save-excursion
1386 (beginning-of-line)
1387 (looking-at "b()")))
1388 (python-nav-forward-sexp)
1389 (should (looking-at "$"))
1390 (should (save-excursion
1391 (beginning-of-line)
1392 (looking-at "c()")))
1393 ;; Movement next to a paren should do what lisp does and
1394 ;; unfortunately It can't change, because otherwise
1395 ;; `blink-matching-open' breaks.
1396 (python-nav-forward-sexp -1)
1397 (should (looking-at "()"))
1398 (should (save-excursion
1399 (beginning-of-line)
1400 (looking-at "c()")))
1401 (python-nav-forward-sexp -1)
1402 (should (looking-at "c()"))
1403 (python-nav-forward-sexp -1)
1404 (should (looking-at "b()"))
1405 (python-nav-forward-sexp -1)
1406 (should (looking-at "a()"))))
1408 (ert-deftest python-nav-forward-sexp-2 ()
1409 (python-tests-with-temp-buffer
1411 def func():
1412 if True:
1413 aaa = bbb
1414 ccc = ddd
1415 eee = fff
1416 return ggg
1418 (python-tests-look-at "aa =")
1419 (python-nav-forward-sexp)
1420 (should (looking-at " = bbb"))
1421 (python-nav-forward-sexp)
1422 (should (looking-at "$"))
1423 (should (save-excursion
1424 (back-to-indentation)
1425 (looking-at "aaa = bbb")))
1426 (python-nav-forward-sexp)
1427 (should (looking-at "$"))
1428 (should (save-excursion
1429 (back-to-indentation)
1430 (looking-at "ccc = ddd")))
1431 (python-nav-forward-sexp)
1432 (should (looking-at "$"))
1433 (should (save-excursion
1434 (back-to-indentation)
1435 (looking-at "eee = fff")))
1436 (python-nav-forward-sexp)
1437 (should (looking-at "$"))
1438 (should (save-excursion
1439 (back-to-indentation)
1440 (looking-at "return ggg")))
1441 (python-nav-forward-sexp -1)
1442 (should (looking-at "def func():"))))
1444 (ert-deftest python-nav-forward-sexp-3 ()
1445 (python-tests-with-temp-buffer
1447 from some_module import some_sub_module
1448 from another_module import another_sub_module
1450 def another_statement():
1451 pass
1453 (python-tests-look-at "some_module")
1454 (python-nav-forward-sexp)
1455 (should (looking-at " import"))
1456 (python-nav-forward-sexp)
1457 (should (looking-at " some_sub_module"))
1458 (python-nav-forward-sexp)
1459 (should (looking-at "$"))
1460 (should
1461 (save-excursion
1462 (back-to-indentation)
1463 (looking-at
1464 "from some_module import some_sub_module")))
1465 (python-nav-forward-sexp)
1466 (should (looking-at "$"))
1467 (should
1468 (save-excursion
1469 (back-to-indentation)
1470 (looking-at
1471 "from another_module import another_sub_module")))
1472 (python-nav-forward-sexp)
1473 (should (looking-at "$"))
1474 (should
1475 (save-excursion
1476 (back-to-indentation)
1477 (looking-at
1478 "pass")))
1479 (python-nav-forward-sexp -1)
1480 (should (looking-at "def another_statement():"))
1481 (python-nav-forward-sexp -1)
1482 (should (looking-at "from another_module import another_sub_module"))
1483 (python-nav-forward-sexp -1)
1484 (should (looking-at "from some_module import some_sub_module"))))
1486 (ert-deftest python-nav-forward-sexp-safe-1 ()
1487 (python-tests-with-temp-buffer
1489 profile = Profile.objects.create(user=request.user)
1490 profile.notify()
1492 (python-tests-look-at "profile =")
1493 (python-nav-forward-sexp-safe 1)
1494 (should (looking-at "$"))
1495 (beginning-of-line 1)
1496 (python-tests-look-at "user=request.user")
1497 (python-nav-forward-sexp-safe -1)
1498 (should (looking-at "(user=request.user)"))
1499 (python-nav-forward-sexp-safe -4)
1500 (should (looking-at "profile ="))
1501 (python-tests-look-at "user=request.user")
1502 (python-nav-forward-sexp-safe 3)
1503 (should (looking-at ")"))
1504 (python-nav-forward-sexp-safe 1)
1505 (should (looking-at "$"))
1506 (python-nav-forward-sexp-safe 1)
1507 (should (looking-at "$"))))
1509 (ert-deftest python-nav-up-list-1 ()
1510 (python-tests-with-temp-buffer
1512 def f():
1513 if True:
1514 return [i for i in range(3)]
1516 (python-tests-look-at "3)]")
1517 (python-nav-up-list)
1518 (should (looking-at "]"))
1519 (python-nav-up-list)
1520 (should (looking-at "$"))))
1522 (ert-deftest python-nav-backward-up-list-1 ()
1523 :expected-result :failed
1524 (python-tests-with-temp-buffer
1526 def f():
1527 if True:
1528 return [i for i in range(3)]
1530 (python-tests-look-at "3)]")
1531 (python-nav-backward-up-list)
1532 (should (looking-at "(3)\\]"))
1533 (python-nav-backward-up-list)
1534 (should (looking-at
1535 "\\[i for i in range(3)\\]"))
1536 ;; FIXME: Need to move to beginning-of-statement.
1537 (python-nav-backward-up-list)
1538 (should (looking-at
1539 "return \\[i for i in range(3)\\]"))
1540 (python-nav-backward-up-list)
1541 (should (looking-at "if True:"))
1542 (python-nav-backward-up-list)
1543 (should (looking-at "def f():"))))
1546 ;;; Shell integration
1548 (defvar python-tests-shell-interpreter "python")
1550 (ert-deftest python-shell-get-process-name-1 ()
1551 "Check process name calculation on different scenarios."
1552 (python-tests-with-temp-buffer
1554 (should (string= (python-shell-get-process-name nil)
1555 python-shell-buffer-name))
1556 ;; When the `current-buffer' doesn't have `buffer-file-name', even
1557 ;; if dedicated flag is non-nil should not include its name.
1558 (should (string= (python-shell-get-process-name t)
1559 python-shell-buffer-name)))
1560 (python-tests-with-temp-file
1562 ;; `buffer-file-name' is non-nil but the dedicated flag is nil and
1563 ;; should be respected.
1564 (should (string= (python-shell-get-process-name nil)
1565 python-shell-buffer-name))
1566 (should (string=
1567 (python-shell-get-process-name t)
1568 (format "%s[%s]" python-shell-buffer-name buffer-file-name)))))
1570 (ert-deftest python-shell-internal-get-process-name-1 ()
1571 "Check the internal process name is config-unique."
1572 (let* ((python-shell-interpreter python-tests-shell-interpreter)
1573 (python-shell-interpreter-args "")
1574 (python-shell-prompt-regexp ">>> ")
1575 (python-shell-prompt-block-regexp "[.][.][.] ")
1576 (python-shell-setup-codes "")
1577 (python-shell-process-environment "")
1578 (python-shell-extra-pythonpaths "")
1579 (python-shell-exec-path "")
1580 (python-shell-virtualenv-path "")
1581 (expected (python-tests-with-temp-buffer
1582 "" (python-shell-internal-get-process-name))))
1583 ;; Same configurations should match.
1584 (should
1585 (string= expected
1586 (python-tests-with-temp-buffer
1587 "" (python-shell-internal-get-process-name))))
1588 (let ((python-shell-interpreter-args "-B"))
1589 ;; A minimal change should generate different names.
1590 (should
1591 (not (string=
1592 expected
1593 (python-tests-with-temp-buffer
1594 "" (python-shell-internal-get-process-name))))))))
1596 (ert-deftest python-shell-parse-command-1 ()
1597 "Check the command to execute is calculated correctly.
1598 Using `python-shell-interpreter' and
1599 `python-shell-interpreter-args'."
1600 (skip-unless (executable-find python-tests-shell-interpreter))
1601 (let ((python-shell-interpreter (executable-find
1602 python-tests-shell-interpreter))
1603 (python-shell-interpreter-args "-B"))
1604 (should (string=
1605 (format "%s %s"
1606 python-shell-interpreter
1607 python-shell-interpreter-args)
1608 (python-shell-parse-command)))))
1610 (ert-deftest python-shell-calculate-process-environment-1 ()
1611 "Test `python-shell-process-environment' modification."
1612 (let* ((original-process-environment process-environment)
1613 (python-shell-process-environment
1614 '("TESTVAR1=value1" "TESTVAR2=value2"))
1615 (process-environment
1616 (python-shell-calculate-process-environment)))
1617 (should (equal (getenv "TESTVAR1") "value1"))
1618 (should (equal (getenv "TESTVAR2") "value2"))))
1620 (ert-deftest python-shell-calculate-process-environment-2 ()
1621 "Test `python-shell-extra-pythonpaths' modification."
1622 (let* ((original-process-environment process-environment)
1623 (original-pythonpath (getenv "PYTHONPATH"))
1624 (paths '("path1" "path2"))
1625 (python-shell-extra-pythonpaths paths)
1626 (process-environment
1627 (python-shell-calculate-process-environment)))
1628 (should (equal (getenv "PYTHONPATH")
1629 (concat
1630 (mapconcat 'identity paths path-separator)
1631 path-separator original-pythonpath)))))
1633 (ert-deftest python-shell-calculate-process-environment-3 ()
1634 "Test `python-shell-virtualenv-path' modification."
1635 (let* ((original-process-environment process-environment)
1636 (original-path (or (getenv "PATH") ""))
1637 (python-shell-virtualenv-path
1638 (directory-file-name user-emacs-directory))
1639 (process-environment
1640 (python-shell-calculate-process-environment)))
1641 (should (not (getenv "PYTHONHOME")))
1642 (should (string= (getenv "VIRTUAL_ENV") python-shell-virtualenv-path))
1643 (should (equal (getenv "PATH")
1644 (format "%s/bin%s%s"
1645 python-shell-virtualenv-path
1646 path-separator original-path)))))
1648 (ert-deftest python-shell-calculate-exec-path-1 ()
1649 "Test `python-shell-exec-path' modification."
1650 (let* ((original-exec-path exec-path)
1651 (python-shell-exec-path '("path1" "path2"))
1652 (exec-path (python-shell-calculate-exec-path)))
1653 (should (equal
1654 exec-path
1655 (append python-shell-exec-path
1656 original-exec-path)))))
1658 (ert-deftest python-shell-calculate-exec-path-2 ()
1659 "Test `python-shell-exec-path' modification."
1660 (let* ((original-exec-path exec-path)
1661 (python-shell-virtualenv-path
1662 (directory-file-name user-emacs-directory))
1663 (exec-path (python-shell-calculate-exec-path)))
1664 (should (equal
1665 exec-path
1666 (append (cons
1667 (format "%s/bin" python-shell-virtualenv-path)
1668 original-exec-path))))))
1670 (ert-deftest python-shell-make-comint-1 ()
1671 "Check comint creation for global shell buffer."
1672 (skip-unless (executable-find python-tests-shell-interpreter))
1673 ;; The interpreter can get killed too quickly to allow it to clean
1674 ;; up the tempfiles that the default python-shell-setup-codes create,
1675 ;; so it leaves tempfiles behind, which is a minor irritation.
1676 (let* ((python-shell-setup-codes nil)
1677 (python-shell-interpreter
1678 (executable-find python-tests-shell-interpreter))
1679 (proc-name (python-shell-get-process-name nil))
1680 (shell-buffer
1681 (python-tests-with-temp-buffer
1682 "" (python-shell-make-comint
1683 (python-shell-parse-command) proc-name)))
1684 (process (get-buffer-process shell-buffer)))
1685 (unwind-protect
1686 (progn
1687 (set-process-query-on-exit-flag process nil)
1688 (should (process-live-p process))
1689 (with-current-buffer shell-buffer
1690 (should (eq major-mode 'inferior-python-mode))
1691 (should (string= (buffer-name) (format "*%s*" proc-name)))))
1692 (kill-buffer shell-buffer))))
1694 (ert-deftest python-shell-make-comint-2 ()
1695 "Check comint creation for internal shell buffer."
1696 (skip-unless (executable-find python-tests-shell-interpreter))
1697 (let* ((python-shell-setup-codes nil)
1698 (python-shell-interpreter
1699 (executable-find python-tests-shell-interpreter))
1700 (proc-name (python-shell-internal-get-process-name))
1701 (shell-buffer
1702 (python-tests-with-temp-buffer
1703 "" (python-shell-make-comint
1704 (python-shell-parse-command) proc-name nil t)))
1705 (process (get-buffer-process shell-buffer)))
1706 (unwind-protect
1707 (progn
1708 (set-process-query-on-exit-flag process nil)
1709 (should (process-live-p process))
1710 (with-current-buffer shell-buffer
1711 (should (eq major-mode 'inferior-python-mode))
1712 (should (string= (buffer-name) (format " *%s*" proc-name)))))
1713 (kill-buffer shell-buffer))))
1715 (ert-deftest python-shell-get-process-1 ()
1716 "Check dedicated shell process preference over global."
1717 (skip-unless (executable-find python-tests-shell-interpreter))
1718 (python-tests-with-temp-file
1720 (let* ((python-shell-setup-codes nil)
1721 (python-shell-interpreter
1722 (executable-find python-tests-shell-interpreter))
1723 (global-proc-name (python-shell-get-process-name nil))
1724 (dedicated-proc-name (python-shell-get-process-name t))
1725 (global-shell-buffer
1726 (python-shell-make-comint
1727 (python-shell-parse-command) global-proc-name))
1728 (dedicated-shell-buffer
1729 (python-shell-make-comint
1730 (python-shell-parse-command) dedicated-proc-name))
1731 (global-process (get-buffer-process global-shell-buffer))
1732 (dedicated-process (get-buffer-process dedicated-shell-buffer)))
1733 (unwind-protect
1734 (progn
1735 (set-process-query-on-exit-flag global-process nil)
1736 (set-process-query-on-exit-flag dedicated-process nil)
1737 ;; Prefer dedicated if global also exists.
1738 (should (equal (python-shell-get-process) dedicated-process))
1739 (kill-buffer dedicated-shell-buffer)
1740 ;; If there's only global, use it.
1741 (should (equal (python-shell-get-process) global-process))
1742 (kill-buffer global-shell-buffer)
1743 ;; No buffer available.
1744 (should (not (python-shell-get-process))))
1745 (ignore-errors (kill-buffer global-shell-buffer))
1746 (ignore-errors (kill-buffer dedicated-shell-buffer))))))
1748 (ert-deftest python-shell-get-or-create-process-1 ()
1749 "Check shell process creation fallback."
1750 :expected-result :failed
1751 (python-tests-with-temp-file
1753 ;; XXX: Break early until we can skip stuff. We need to mimic
1754 ;; user interaction because `python-shell-get-or-create-process'
1755 ;; asks for all arguments interactively when a shell process
1756 ;; doesn't exist.
1757 (should nil)
1758 (let* ((python-shell-interpreter
1759 (executable-find python-tests-shell-interpreter))
1760 (use-dialog-box)
1761 (dedicated-process-name (python-shell-get-process-name t))
1762 (dedicated-process (python-shell-get-or-create-process))
1763 (dedicated-shell-buffer (process-buffer dedicated-process)))
1764 (unwind-protect
1765 (progn
1766 (set-process-query-on-exit-flag dedicated-process nil)
1767 ;; Prefer dedicated if not buffer exist.
1768 (should (equal (process-name dedicated-process)
1769 dedicated-process-name))
1770 (kill-buffer dedicated-shell-buffer)
1771 ;; No buffer available.
1772 (should (not (python-shell-get-process))))
1773 (ignore-errors (kill-buffer dedicated-shell-buffer))))))
1775 (ert-deftest python-shell-internal-get-or-create-process-1 ()
1776 "Check internal shell process creation fallback."
1777 (skip-unless (executable-find python-tests-shell-interpreter))
1778 (python-tests-with-temp-file
1780 (should (not (process-live-p (python-shell-internal-get-process-name))))
1781 (let* ((python-shell-interpreter
1782 (executable-find python-tests-shell-interpreter))
1783 (internal-process-name (python-shell-internal-get-process-name))
1784 (internal-process (python-shell-internal-get-or-create-process))
1785 (internal-shell-buffer (process-buffer internal-process)))
1786 (unwind-protect
1787 (progn
1788 (set-process-query-on-exit-flag internal-process nil)
1789 (should (equal (process-name internal-process)
1790 internal-process-name))
1791 (should (equal internal-process
1792 (python-shell-internal-get-or-create-process)))
1793 ;; No user buffer available.
1794 (should (not (python-shell-get-process)))
1795 (kill-buffer internal-shell-buffer))
1796 (ignore-errors (kill-buffer internal-shell-buffer))))))
1799 ;;; Shell completion
1802 ;;; PDB Track integration
1805 ;;; Symbol completion
1808 ;;; Fill paragraph
1811 ;;; Skeletons
1814 ;;; FFAP
1817 ;;; Code check
1820 ;;; Eldoc
1823 ;;; Imenu
1825 (ert-deftest python-imenu-create-index-1 ()
1826 (python-tests-with-temp-buffer
1828 class Foo(models.Model):
1829 pass
1832 class Bar(models.Model):
1833 pass
1836 def decorator(arg1, arg2, arg3):
1837 '''print decorated function call data to stdout.
1839 Usage:
1841 @decorator('arg1', 'arg2')
1842 def func(a, b, c=True):
1843 pass
1846 def wrap(f):
1847 print ('wrap')
1848 def wrapped_f(*args):
1849 print ('wrapped_f')
1850 print ('Decorator arguments:', arg1, arg2, arg3)
1851 f(*args)
1852 print ('called f(*args)')
1853 return wrapped_f
1854 return wrap
1857 class Baz(object):
1859 def a(self):
1860 pass
1862 def b(self):
1863 pass
1865 class Frob(object):
1867 def c(self):
1868 pass
1870 (goto-char (point-max))
1871 (should (equal
1872 (list
1873 (cons "Foo (class)" (copy-marker 2))
1874 (cons "Bar (class)" (copy-marker 38))
1875 (list
1876 "decorator (def)"
1877 (cons "*function definition*" (copy-marker 74))
1878 (list
1879 "wrap (def)"
1880 (cons "*function definition*" (copy-marker 254))
1881 (cons "wrapped_f (def)" (copy-marker 294))))
1882 (list
1883 "Baz (class)"
1884 (cons "*class definition*" (copy-marker 519))
1885 (cons "a (def)" (copy-marker 539))
1886 (cons "b (def)" (copy-marker 570))
1887 (list
1888 "Frob (class)"
1889 (cons "*class definition*" (copy-marker 601))
1890 (cons "c (def)" (copy-marker 626)))))
1891 (python-imenu-create-index)))))
1893 (ert-deftest python-imenu-create-index-2 ()
1894 (python-tests-with-temp-buffer
1896 class Foo(object):
1897 def foo(self):
1898 def foo1():
1899 pass
1901 def foobar(self):
1902 pass
1904 (goto-char (point-max))
1905 (should (equal
1906 (list
1907 (list
1908 "Foo (class)"
1909 (cons "*class definition*" (copy-marker 2))
1910 (list
1911 "foo (def)"
1912 (cons "*function definition*" (copy-marker 21))
1913 (cons "foo1 (def)" (copy-marker 40)))
1914 (cons "foobar (def)" (copy-marker 78))))
1915 (python-imenu-create-index)))))
1917 (ert-deftest python-imenu-create-index-3 ()
1918 (python-tests-with-temp-buffer
1920 class Foo(object):
1921 def foo(self):
1922 def foo1():
1923 pass
1924 def foo2():
1925 pass
1927 (goto-char (point-max))
1928 (should (equal
1929 (list
1930 (list
1931 "Foo (class)"
1932 (cons "*class definition*" (copy-marker 2))
1933 (list
1934 "foo (def)"
1935 (cons "*function definition*" (copy-marker 21))
1936 (cons "foo1 (def)" (copy-marker 40))
1937 (cons "foo2 (def)" (copy-marker 77)))))
1938 (python-imenu-create-index)))))
1940 (ert-deftest python-imenu-create-index-4 ()
1941 (python-tests-with-temp-buffer
1943 class Foo(object):
1944 class Bar(object):
1945 def __init__(self):
1946 pass
1948 def __str__(self):
1949 pass
1951 def __init__(self):
1952 pass
1954 (goto-char (point-max))
1955 (should (equal
1956 (list
1957 (list
1958 "Foo (class)"
1959 (cons "*class definition*" (copy-marker 2))
1960 (list
1961 "Bar (class)"
1962 (cons "*class definition*" (copy-marker 21))
1963 (cons "__init__ (def)" (copy-marker 44))
1964 (cons "__str__ (def)" (copy-marker 90)))
1965 (cons "__init__ (def)" (copy-marker 135))))
1966 (python-imenu-create-index)))))
1968 (ert-deftest python-imenu-create-flat-index-1 ()
1969 (python-tests-with-temp-buffer
1971 class Foo(models.Model):
1972 pass
1975 class Bar(models.Model):
1976 pass
1979 def decorator(arg1, arg2, arg3):
1980 '''print decorated function call data to stdout.
1982 Usage:
1984 @decorator('arg1', 'arg2')
1985 def func(a, b, c=True):
1986 pass
1989 def wrap(f):
1990 print ('wrap')
1991 def wrapped_f(*args):
1992 print ('wrapped_f')
1993 print ('Decorator arguments:', arg1, arg2, arg3)
1994 f(*args)
1995 print ('called f(*args)')
1996 return wrapped_f
1997 return wrap
2000 class Baz(object):
2002 def a(self):
2003 pass
2005 def b(self):
2006 pass
2008 class Frob(object):
2010 def c(self):
2011 pass
2013 (goto-char (point-max))
2014 (should (equal
2015 (list (cons "Foo" (copy-marker 2))
2016 (cons "Bar" (copy-marker 38))
2017 (cons "decorator" (copy-marker 74))
2018 (cons "decorator.wrap" (copy-marker 254))
2019 (cons "decorator.wrap.wrapped_f" (copy-marker 294))
2020 (cons "Baz" (copy-marker 519))
2021 (cons "Baz.a" (copy-marker 539))
2022 (cons "Baz.b" (copy-marker 570))
2023 (cons "Baz.Frob" (copy-marker 601))
2024 (cons "Baz.Frob.c" (copy-marker 626)))
2025 (python-imenu-create-flat-index)))))
2027 (ert-deftest python-imenu-create-flat-index-2 ()
2028 (python-tests-with-temp-buffer
2030 class Foo(object):
2031 class Bar(object):
2032 def __init__(self):
2033 pass
2035 def __str__(self):
2036 pass
2038 def __init__(self):
2039 pass
2041 (goto-char (point-max))
2042 (should (equal
2043 (list
2044 (cons "Foo" (copy-marker 2))
2045 (cons "Foo.Bar" (copy-marker 21))
2046 (cons "Foo.Bar.__init__" (copy-marker 44))
2047 (cons "Foo.Bar.__str__" (copy-marker 90))
2048 (cons "Foo.__init__" (copy-marker 135)))
2049 (python-imenu-create-flat-index)))))
2052 ;;; Misc helpers
2054 (ert-deftest python-info-current-defun-1 ()
2055 (python-tests-with-temp-buffer
2057 def foo(a, b):
2059 (forward-line 1)
2060 (should (string= "foo" (python-info-current-defun)))
2061 (should (string= "def foo" (python-info-current-defun t)))
2062 (forward-line 1)
2063 (should (not (python-info-current-defun)))
2064 (indent-for-tab-command)
2065 (should (string= "foo" (python-info-current-defun)))
2066 (should (string= "def foo" (python-info-current-defun t)))))
2068 (ert-deftest python-info-current-defun-2 ()
2069 (python-tests-with-temp-buffer
2071 class C(object):
2073 def m(self):
2074 if True:
2075 return [i for i in range(3)]
2076 else:
2077 return []
2079 def b():
2080 do_b()
2082 def a():
2083 do_a()
2085 def c(self):
2086 do_c()
2088 (forward-line 1)
2089 (should (string= "C" (python-info-current-defun)))
2090 (should (string= "class C" (python-info-current-defun t)))
2091 (python-tests-look-at "return [i for ")
2092 (should (string= "C.m" (python-info-current-defun)))
2093 (should (string= "def C.m" (python-info-current-defun t)))
2094 (python-tests-look-at "def b():")
2095 (should (string= "C.m.b" (python-info-current-defun)))
2096 (should (string= "def C.m.b" (python-info-current-defun t)))
2097 (forward-line 2)
2098 (indent-for-tab-command)
2099 (python-indent-dedent-line-backspace 1)
2100 (should (string= "C.m" (python-info-current-defun)))
2101 (should (string= "def C.m" (python-info-current-defun t)))
2102 (python-tests-look-at "def c(self):")
2103 (forward-line -1)
2104 (indent-for-tab-command)
2105 (should (string= "C.m.a" (python-info-current-defun)))
2106 (should (string= "def C.m.a" (python-info-current-defun t)))
2107 (python-indent-dedent-line-backspace 1)
2108 (should (string= "C.m" (python-info-current-defun)))
2109 (should (string= "def C.m" (python-info-current-defun t)))
2110 (python-indent-dedent-line-backspace 1)
2111 (should (string= "C" (python-info-current-defun)))
2112 (should (string= "class C" (python-info-current-defun t)))
2113 (python-tests-look-at "def c(self):")
2114 (should (string= "C.c" (python-info-current-defun)))
2115 (should (string= "def C.c" (python-info-current-defun t)))
2116 (python-tests-look-at "do_c()")
2117 (should (string= "C.c" (python-info-current-defun)))
2118 (should (string= "def C.c" (python-info-current-defun t)))))
2120 (ert-deftest python-info-current-defun-3 ()
2121 (python-tests-with-temp-buffer
2123 def decoratorFunctionWithArguments(arg1, arg2, arg3):
2124 '''print decorated function call data to stdout.
2126 Usage:
2128 @decoratorFunctionWithArguments('arg1', 'arg2')
2129 def func(a, b, c=True):
2130 pass
2133 def wwrap(f):
2134 print 'Inside wwrap()'
2135 def wrapped_f(*args):
2136 print 'Inside wrapped_f()'
2137 print 'Decorator arguments:', arg1, arg2, arg3
2138 f(*args)
2139 print 'After f(*args)'
2140 return wrapped_f
2141 return wwrap
2143 (python-tests-look-at "def wwrap(f):")
2144 (forward-line -1)
2145 (should (not (python-info-current-defun)))
2146 (indent-for-tab-command 1)
2147 (should (string= (python-info-current-defun)
2148 "decoratorFunctionWithArguments"))
2149 (should (string= (python-info-current-defun t)
2150 "def decoratorFunctionWithArguments"))
2151 (python-tests-look-at "def wrapped_f(*args):")
2152 (should (string= (python-info-current-defun)
2153 "decoratorFunctionWithArguments.wwrap.wrapped_f"))
2154 (should (string= (python-info-current-defun t)
2155 "def decoratorFunctionWithArguments.wwrap.wrapped_f"))
2156 (python-tests-look-at "return wrapped_f")
2157 (should (string= (python-info-current-defun)
2158 "decoratorFunctionWithArguments.wwrap"))
2159 (should (string= (python-info-current-defun t)
2160 "def decoratorFunctionWithArguments.wwrap"))
2161 (end-of-line 1)
2162 (python-tests-look-at "return wwrap")
2163 (should (string= (python-info-current-defun)
2164 "decoratorFunctionWithArguments"))
2165 (should (string= (python-info-current-defun t)
2166 "def decoratorFunctionWithArguments"))))
2168 (ert-deftest python-info-current-symbol-1 ()
2169 (python-tests-with-temp-buffer
2171 class C(object):
2173 def m(self):
2174 self.c()
2176 def c(self):
2177 print ('a')
2179 (python-tests-look-at "self.c()")
2180 (should (string= "self.c" (python-info-current-symbol)))
2181 (should (string= "C.c" (python-info-current-symbol t)))))
2183 (ert-deftest python-info-current-symbol-2 ()
2184 (python-tests-with-temp-buffer
2186 class C(object):
2188 class M(object):
2190 def a(self):
2191 self.c()
2193 def c(self):
2194 pass
2196 (python-tests-look-at "self.c()")
2197 (should (string= "self.c" (python-info-current-symbol)))
2198 (should (string= "C.M.c" (python-info-current-symbol t)))))
2200 (ert-deftest python-info-current-symbol-3 ()
2201 "Keywords should not be considered symbols."
2202 :expected-result :failed
2203 (python-tests-with-temp-buffer
2205 class C(object):
2206 pass
2208 ;; FIXME: keywords are not symbols.
2209 (python-tests-look-at "class C")
2210 (should (not (python-info-current-symbol)))
2211 (should (not (python-info-current-symbol t)))
2212 (python-tests-look-at "C(object)")
2213 (should (string= "C" (python-info-current-symbol)))
2214 (should (string= "class C" (python-info-current-symbol t)))))
2216 (ert-deftest python-info-statement-starts-block-p-1 ()
2217 (python-tests-with-temp-buffer
2219 def long_function_name(
2220 var_one, var_two, var_three,
2221 var_four):
2222 print (var_one)
2224 (python-tests-look-at "def long_function_name")
2225 (should (python-info-statement-starts-block-p))
2226 (python-tests-look-at "print (var_one)")
2227 (python-util-forward-comment -1)
2228 (should (python-info-statement-starts-block-p))))
2230 (ert-deftest python-info-statement-starts-block-p-2 ()
2231 (python-tests-with-temp-buffer
2233 if width == 0 and height == 0 and \\\\
2234 color == 'red' and emphasis == 'strong' or \\\\
2235 highlight > 100:
2236 raise ValueError('sorry, you lose')
2238 (python-tests-look-at "if width == 0 and")
2239 (should (python-info-statement-starts-block-p))
2240 (python-tests-look-at "raise ValueError(")
2241 (python-util-forward-comment -1)
2242 (should (python-info-statement-starts-block-p))))
2244 (ert-deftest python-info-statement-ends-block-p-1 ()
2245 (python-tests-with-temp-buffer
2247 def long_function_name(
2248 var_one, var_two, var_three,
2249 var_four):
2250 print (var_one)
2252 (python-tests-look-at "print (var_one)")
2253 (should (python-info-statement-ends-block-p))))
2255 (ert-deftest python-info-statement-ends-block-p-2 ()
2256 (python-tests-with-temp-buffer
2258 if width == 0 and height == 0 and \\\\
2259 color == 'red' and emphasis == 'strong' or \\\\
2260 highlight > 100:
2261 raise ValueError(
2262 'sorry, you lose'
2266 (python-tests-look-at "raise ValueError(")
2267 (should (python-info-statement-ends-block-p))))
2269 (ert-deftest python-info-beginning-of-statement-p-1 ()
2270 (python-tests-with-temp-buffer
2272 def long_function_name(
2273 var_one, var_two, var_three,
2274 var_four):
2275 print (var_one)
2277 (python-tests-look-at "def long_function_name")
2278 (should (python-info-beginning-of-statement-p))
2279 (forward-char 10)
2280 (should (not (python-info-beginning-of-statement-p)))
2281 (python-tests-look-at "print (var_one)")
2282 (should (python-info-beginning-of-statement-p))
2283 (goto-char (line-beginning-position))
2284 (should (not (python-info-beginning-of-statement-p)))))
2286 (ert-deftest python-info-beginning-of-statement-p-2 ()
2287 (python-tests-with-temp-buffer
2289 if width == 0 and height == 0 and \\\\
2290 color == 'red' and emphasis == 'strong' or \\\\
2291 highlight > 100:
2292 raise ValueError(
2293 'sorry, you lose'
2297 (python-tests-look-at "if width == 0 and")
2298 (should (python-info-beginning-of-statement-p))
2299 (forward-char 10)
2300 (should (not (python-info-beginning-of-statement-p)))
2301 (python-tests-look-at "raise ValueError(")
2302 (should (python-info-beginning-of-statement-p))
2303 (goto-char (line-beginning-position))
2304 (should (not (python-info-beginning-of-statement-p)))))
2306 (ert-deftest python-info-end-of-statement-p-1 ()
2307 (python-tests-with-temp-buffer
2309 def long_function_name(
2310 var_one, var_two, var_three,
2311 var_four):
2312 print (var_one)
2314 (python-tests-look-at "def long_function_name")
2315 (should (not (python-info-end-of-statement-p)))
2316 (end-of-line)
2317 (should (not (python-info-end-of-statement-p)))
2318 (python-tests-look-at "print (var_one)")
2319 (python-util-forward-comment -1)
2320 (should (python-info-end-of-statement-p))
2321 (python-tests-look-at "print (var_one)")
2322 (should (not (python-info-end-of-statement-p)))
2323 (end-of-line)
2324 (should (python-info-end-of-statement-p))))
2326 (ert-deftest python-info-end-of-statement-p-2 ()
2327 (python-tests-with-temp-buffer
2329 if width == 0 and height == 0 and \\\\
2330 color == 'red' and emphasis == 'strong' or \\\\
2331 highlight > 100:
2332 raise ValueError(
2333 'sorry, you lose'
2337 (python-tests-look-at "if width == 0 and")
2338 (should (not (python-info-end-of-statement-p)))
2339 (end-of-line)
2340 (should (not (python-info-end-of-statement-p)))
2341 (python-tests-look-at "raise ValueError(")
2342 (python-util-forward-comment -1)
2343 (should (python-info-end-of-statement-p))
2344 (python-tests-look-at "raise ValueError(")
2345 (should (not (python-info-end-of-statement-p)))
2346 (end-of-line)
2347 (should (not (python-info-end-of-statement-p)))
2348 (goto-char (point-max))
2349 (python-util-forward-comment -1)
2350 (should (python-info-end-of-statement-p))))
2352 (ert-deftest python-info-beginning-of-block-p-1 ()
2353 (python-tests-with-temp-buffer
2355 def long_function_name(
2356 var_one, var_two, var_three,
2357 var_four):
2358 print (var_one)
2360 (python-tests-look-at "def long_function_name")
2361 (should (python-info-beginning-of-block-p))
2362 (python-tests-look-at "var_one, var_two, var_three,")
2363 (should (not (python-info-beginning-of-block-p)))
2364 (python-tests-look-at "print (var_one)")
2365 (should (not (python-info-beginning-of-block-p)))))
2367 (ert-deftest python-info-beginning-of-block-p-2 ()
2368 (python-tests-with-temp-buffer
2370 if width == 0 and height == 0 and \\\\
2371 color == 'red' and emphasis == 'strong' or \\\\
2372 highlight > 100:
2373 raise ValueError(
2374 'sorry, you lose'
2378 (python-tests-look-at "if width == 0 and")
2379 (should (python-info-beginning-of-block-p))
2380 (python-tests-look-at "color == 'red' and emphasis")
2381 (should (not (python-info-beginning-of-block-p)))
2382 (python-tests-look-at "raise ValueError(")
2383 (should (not (python-info-beginning-of-block-p)))))
2385 (ert-deftest python-info-end-of-block-p-1 ()
2386 (python-tests-with-temp-buffer
2388 def long_function_name(
2389 var_one, var_two, var_three,
2390 var_four):
2391 print (var_one)
2393 (python-tests-look-at "def long_function_name")
2394 (should (not (python-info-end-of-block-p)))
2395 (python-tests-look-at "var_one, var_two, var_three,")
2396 (should (not (python-info-end-of-block-p)))
2397 (python-tests-look-at "var_four):")
2398 (end-of-line)
2399 (should (not (python-info-end-of-block-p)))
2400 (python-tests-look-at "print (var_one)")
2401 (should (not (python-info-end-of-block-p)))
2402 (end-of-line 1)
2403 (should (python-info-end-of-block-p))))
2405 (ert-deftest python-info-end-of-block-p-2 ()
2406 (python-tests-with-temp-buffer
2408 if width == 0 and height == 0 and \\\\
2409 color == 'red' and emphasis == 'strong' or \\\\
2410 highlight > 100:
2411 raise ValueError(
2412 'sorry, you lose'
2416 (python-tests-look-at "if width == 0 and")
2417 (should (not (python-info-end-of-block-p)))
2418 (python-tests-look-at "color == 'red' and emphasis == 'strong' or")
2419 (should (not (python-info-end-of-block-p)))
2420 (python-tests-look-at "highlight > 100:")
2421 (end-of-line)
2422 (should (not (python-info-end-of-block-p)))
2423 (python-tests-look-at "raise ValueError(")
2424 (should (not (python-info-end-of-block-p)))
2425 (end-of-line 1)
2426 (should (not (python-info-end-of-block-p)))
2427 (goto-char (point-max))
2428 (python-util-forward-comment -1)
2429 (should (python-info-end-of-block-p))))
2431 (ert-deftest python-info-closing-block-1 ()
2432 (python-tests-with-temp-buffer
2434 if request.user.is_authenticated():
2435 try:
2436 profile = request.user.get_profile()
2437 except Profile.DoesNotExist:
2438 profile = Profile.objects.create(user=request.user)
2439 else:
2440 if profile.stats:
2441 profile.recalculate_stats()
2442 else:
2443 profile.clear_stats()
2444 finally:
2445 profile.views += 1
2446 profile.save()
2448 (python-tests-look-at "try:")
2449 (should (not (python-info-closing-block)))
2450 (python-tests-look-at "except Profile.DoesNotExist:")
2451 (should (= (python-tests-look-at "try:" -1 t)
2452 (python-info-closing-block)))
2453 (python-tests-look-at "else:")
2454 (should (= (python-tests-look-at "except Profile.DoesNotExist:" -1 t)
2455 (python-info-closing-block)))
2456 (python-tests-look-at "if profile.stats:")
2457 (should (not (python-info-closing-block)))
2458 (python-tests-look-at "else:")
2459 (should (= (python-tests-look-at "if profile.stats:" -1 t)
2460 (python-info-closing-block)))
2461 (python-tests-look-at "finally:")
2462 (should (= (python-tests-look-at "else:" -2 t)
2463 (python-info-closing-block)))))
2465 (ert-deftest python-info-closing-block-2 ()
2466 (python-tests-with-temp-buffer
2468 if request.user.is_authenticated():
2469 profile = Profile.objects.get_or_create(user=request.user)
2470 if profile.stats:
2471 profile.recalculate_stats()
2473 data = {
2474 'else': 'do it'
2476 'else'
2478 (python-tests-look-at "'else': 'do it'")
2479 (should (not (python-info-closing-block)))
2480 (python-tests-look-at "'else'")
2481 (should (not (python-info-closing-block)))))
2483 (ert-deftest python-info-line-ends-backslash-p-1 ()
2484 (python-tests-with-temp-buffer
2486 objects = Thing.objects.all() \\\\
2487 .filter(
2488 type='toy',
2489 status='bought'
2490 ) \\\\
2491 .aggregate(
2492 Sum('amount')
2493 ) \\\\
2494 .values_list()
2496 (should (python-info-line-ends-backslash-p 2)) ; .filter(...
2497 (should (python-info-line-ends-backslash-p 3))
2498 (should (python-info-line-ends-backslash-p 4))
2499 (should (python-info-line-ends-backslash-p 5))
2500 (should (python-info-line-ends-backslash-p 6)) ; ) \...
2501 (should (python-info-line-ends-backslash-p 7))
2502 (should (python-info-line-ends-backslash-p 8))
2503 (should (python-info-line-ends-backslash-p 9))
2504 (should (not (python-info-line-ends-backslash-p 10))))) ; .values_list()...
2506 (ert-deftest python-info-beginning-of-backslash-1 ()
2507 (python-tests-with-temp-buffer
2509 objects = Thing.objects.all() \\\\
2510 .filter(
2511 type='toy',
2512 status='bought'
2513 ) \\\\
2514 .aggregate(
2515 Sum('amount')
2516 ) \\\\
2517 .values_list()
2519 (let ((first 2)
2520 (second (python-tests-look-at ".filter("))
2521 (third (python-tests-look-at ".aggregate(")))
2522 (should (= first (python-info-beginning-of-backslash 2)))
2523 (should (= second (python-info-beginning-of-backslash 3)))
2524 (should (= second (python-info-beginning-of-backslash 4)))
2525 (should (= second (python-info-beginning-of-backslash 5)))
2526 (should (= second (python-info-beginning-of-backslash 6)))
2527 (should (= third (python-info-beginning-of-backslash 7)))
2528 (should (= third (python-info-beginning-of-backslash 8)))
2529 (should (= third (python-info-beginning-of-backslash 9)))
2530 (should (not (python-info-beginning-of-backslash 10))))))
2532 (ert-deftest python-info-continuation-line-p-1 ()
2533 (python-tests-with-temp-buffer
2535 if width == 0 and height == 0 and \\\\
2536 color == 'red' and emphasis == 'strong' or \\\\
2537 highlight > 100:
2538 raise ValueError(
2539 'sorry, you lose'
2543 (python-tests-look-at "if width == 0 and height == 0 and")
2544 (should (not (python-info-continuation-line-p)))
2545 (python-tests-look-at "color == 'red' and emphasis == 'strong' or")
2546 (should (python-info-continuation-line-p))
2547 (python-tests-look-at "highlight > 100:")
2548 (should (python-info-continuation-line-p))
2549 (python-tests-look-at "raise ValueError(")
2550 (should (not (python-info-continuation-line-p)))
2551 (python-tests-look-at "'sorry, you lose'")
2552 (should (python-info-continuation-line-p))
2553 (forward-line 1)
2554 (should (python-info-continuation-line-p))
2555 (python-tests-look-at ")")
2556 (should (python-info-continuation-line-p))
2557 (forward-line 1)
2558 (should (not (python-info-continuation-line-p)))))
2560 (ert-deftest python-info-block-continuation-line-p-1 ()
2561 (python-tests-with-temp-buffer
2563 if width == 0 and height == 0 and \\\\
2564 color == 'red' and emphasis == 'strong' or \\\\
2565 highlight > 100:
2566 raise ValueError(
2567 'sorry, you lose'
2571 (python-tests-look-at "if width == 0 and")
2572 (should (not (python-info-block-continuation-line-p)))
2573 (python-tests-look-at "color == 'red' and emphasis == 'strong' or")
2574 (should (= (python-info-block-continuation-line-p)
2575 (python-tests-look-at "if width == 0 and" -1 t)))
2576 (python-tests-look-at "highlight > 100:")
2577 (should (not (python-info-block-continuation-line-p)))))
2579 (ert-deftest python-info-block-continuation-line-p-2 ()
2580 (python-tests-with-temp-buffer
2582 def foo(a,
2585 pass
2587 (python-tests-look-at "def foo(a,")
2588 (should (not (python-info-block-continuation-line-p)))
2589 (python-tests-look-at "b,")
2590 (should (= (python-info-block-continuation-line-p)
2591 (python-tests-look-at "def foo(a," -1 t)))
2592 (python-tests-look-at "c):")
2593 (should (not (python-info-block-continuation-line-p)))))
2595 (ert-deftest python-info-assignment-continuation-line-p-1 ()
2596 (python-tests-with-temp-buffer
2598 data = foo(), bar() \\\\
2599 baz(), 4 \\\\
2600 5, 6
2602 (python-tests-look-at "data = foo(), bar()")
2603 (should (not (python-info-assignment-continuation-line-p)))
2604 (python-tests-look-at "baz(), 4")
2605 (should (= (python-info-assignment-continuation-line-p)
2606 (python-tests-look-at "foo()," -1 t)))
2607 (python-tests-look-at "5, 6")
2608 (should (not (python-info-assignment-continuation-line-p)))))
2610 (ert-deftest python-info-assignment-continuation-line-p-2 ()
2611 (python-tests-with-temp-buffer
2613 data = (foo(), bar()
2614 baz(), 4
2615 5, 6)
2617 (python-tests-look-at "data = (foo(), bar()")
2618 (should (not (python-info-assignment-continuation-line-p)))
2619 (python-tests-look-at "baz(), 4")
2620 (should (= (python-info-assignment-continuation-line-p)
2621 (python-tests-look-at "(foo()," -1 t)))
2622 (python-tests-look-at "5, 6)")
2623 (should (not (python-info-assignment-continuation-line-p)))))
2625 (ert-deftest python-info-looking-at-beginning-of-defun-1 ()
2626 (python-tests-with-temp-buffer
2628 def decorat0r(deff):
2629 '''decorates stuff.
2631 @decorat0r
2632 def foo(arg):
2635 def wrap():
2636 deff()
2637 return wwrap
2639 (python-tests-look-at "def decorat0r(deff):")
2640 (should (python-info-looking-at-beginning-of-defun))
2641 (python-tests-look-at "def foo(arg):")
2642 (should (not (python-info-looking-at-beginning-of-defun)))
2643 (python-tests-look-at "def wrap():")
2644 (should (python-info-looking-at-beginning-of-defun))
2645 (python-tests-look-at "deff()")
2646 (should (not (python-info-looking-at-beginning-of-defun)))))
2648 (ert-deftest python-info-current-line-comment-p-1 ()
2649 (python-tests-with-temp-buffer
2651 # this is a comment
2652 foo = True # another comment
2653 '#this is a string'
2654 if foo:
2655 # more comments
2656 print ('bar') # print bar
2658 (python-tests-look-at "# this is a comment")
2659 (should (python-info-current-line-comment-p))
2660 (python-tests-look-at "foo = True # another comment")
2661 (should (not (python-info-current-line-comment-p)))
2662 (python-tests-look-at "'#this is a string'")
2663 (should (not (python-info-current-line-comment-p)))
2664 (python-tests-look-at "# more comments")
2665 (should (python-info-current-line-comment-p))
2666 (python-tests-look-at "print ('bar') # print bar")
2667 (should (not (python-info-current-line-comment-p)))))
2669 (ert-deftest python-info-current-line-empty-p ()
2670 (python-tests-with-temp-buffer
2672 # this is a comment
2674 foo = True # another comment
2676 (should (python-info-current-line-empty-p))
2677 (python-tests-look-at "# this is a comment")
2678 (should (not (python-info-current-line-empty-p)))
2679 (forward-line 1)
2680 (should (python-info-current-line-empty-p))))
2683 ;;; Utility functions
2685 (ert-deftest python-util-goto-line-1 ()
2686 (python-tests-with-temp-buffer
2687 (concat
2688 "# a comment
2689 # another comment
2690 def foo(a, b, c):
2691 pass" (make-string 20 ?\n))
2692 (python-util-goto-line 10)
2693 (should (= (line-number-at-pos) 10))
2694 (python-util-goto-line 20)
2695 (should (= (line-number-at-pos) 20))))
2697 (ert-deftest python-util-clone-local-variables-1 ()
2698 (let ((buffer (generate-new-buffer
2699 "python-util-clone-local-variables-1"))
2700 (varcons
2701 '((python-fill-docstring-style . django)
2702 (python-shell-interpreter . "python")
2703 (python-shell-interpreter-args . "manage.py shell")
2704 (python-shell-prompt-regexp . "In \\[[0-9]+\\]: ")
2705 (python-shell-prompt-output-regexp . "Out\\[[0-9]+\\]: ")
2706 (python-shell-extra-pythonpaths "/home/user/pylib/")
2707 (python-shell-completion-setup-code
2708 . "from IPython.core.completerlib import module_completion")
2709 (python-shell-completion-module-string-code
2710 . "';'.join(module_completion('''%s'''))\n")
2711 (python-shell-completion-string-code
2712 . "';'.join(get_ipython().Completer.all_completions('''%s'''))\n")
2713 (python-shell-virtualenv-path
2714 . "/home/user/.virtualenvs/project"))))
2715 (with-current-buffer buffer
2716 (kill-all-local-variables)
2717 (dolist (ccons varcons)
2718 (set (make-local-variable (car ccons)) (cdr ccons))))
2719 (python-tests-with-temp-buffer
2721 (python-util-clone-local-variables buffer)
2722 (dolist (ccons varcons)
2723 (should
2724 (equal (symbol-value (car ccons)) (cdr ccons)))))
2725 (kill-buffer buffer)))
2727 (ert-deftest python-util-strip-string-1 ()
2728 (should (string= (python-util-strip-string "\t\r\n str") "str"))
2729 (should (string= (python-util-strip-string "str \n\r") "str"))
2730 (should (string= (python-util-strip-string "\t\r\n str \n\r ") "str"))
2731 (should
2732 (string= (python-util-strip-string "\n str \nin \tg \n\r") "str \nin \tg"))
2733 (should (string= (python-util-strip-string "\n \t \n\r ") ""))
2734 (should (string= (python-util-strip-string "") "")))
2736 (ert-deftest python-util-forward-comment-1 ()
2737 (python-tests-with-temp-buffer
2738 (concat
2739 "# a comment
2740 # another comment
2741 # bad indented comment
2742 # more comments" (make-string 9999 ?\n))
2743 (python-util-forward-comment 1)
2744 (should (= (point) (point-max)))
2745 (python-util-forward-comment -1)
2746 (should (= (point) (point-min)))))
2749 ;;; Electricity
2751 (ert-deftest python-parens-electric-indent-1 ()
2752 (require 'electric)
2753 (let ((eim electric-indent-mode))
2754 (unwind-protect
2755 (progn
2756 (python-tests-with-temp-buffer
2758 from django.conf.urls import patterns, include, url
2760 from django.contrib import admin
2762 from myapp import views
2765 urlpatterns = patterns('',
2766 url(r'^$', views.index
2769 (electric-indent-mode 1)
2770 (python-tests-look-at "views.index")
2771 (end-of-line)
2773 ;; Inserting commas within the same line should leave
2774 ;; indentation unchanged.
2775 (python-tests-self-insert ",")
2776 (should (= (current-indentation) 4))
2778 ;; As well as any other input happening within the same
2779 ;; set of parens.
2780 (python-tests-self-insert " name='index')")
2781 (should (= (current-indentation) 4))
2783 ;; But a comma outside it, should trigger indentation.
2784 (python-tests-self-insert ",")
2785 (should (= (current-indentation) 23))
2787 ;; Newline indents to the first argument column
2788 (python-tests-self-insert "\n")
2789 (should (= (current-indentation) 23))
2791 ;; All this input must not change indentation
2792 (indent-line-to 4)
2793 (python-tests-self-insert "url(r'^/login$', views.login)")
2794 (should (= (current-indentation) 4))
2796 ;; But this comma does
2797 (python-tests-self-insert ",")
2798 (should (= (current-indentation) 23))))
2799 (or eim (electric-indent-mode -1)))))
2801 (ert-deftest python-triple-quote-pairing ()
2802 (require 'electric)
2803 (let ((epm electric-pair-mode))
2804 (unwind-protect
2805 (progn
2806 (python-tests-with-temp-buffer
2807 "\"\"\n"
2808 (or epm (electric-pair-mode 1))
2809 (goto-char (1- (point-max)))
2810 (python-tests-self-insert ?\")
2811 (should (string= (buffer-string)
2812 "\"\"\"\"\"\"\n"))
2813 (should (= (point) 4)))
2814 (python-tests-with-temp-buffer
2815 "\n"
2816 (python-tests-self-insert (list ?\" ?\" ?\"))
2817 (should (string= (buffer-string)
2818 "\"\"\"\"\"\"\n"))
2819 (should (= (point) 4)))
2820 (python-tests-with-temp-buffer
2821 "\"\n\"\"\n"
2822 (goto-char (1- (point-max)))
2823 (python-tests-self-insert ?\")
2824 (should (= (point) (1- (point-max))))
2825 (should (string= (buffer-string)
2826 "\"\n\"\"\"\n"))))
2827 (or epm (electric-pair-mode -1)))))
2830 (provide 'python-tests)
2832 ;; Local Variables:
2833 ;; coding: utf-8
2834 ;; indent-tabs-mode: nil
2835 ;; End:
2837 ;;; python-tests.el ends here