]> code.delx.au - gnu-emacs/blob - test/automated/python-tests.el
Stop some python tests leaving temp-files behind
[gnu-emacs] / test / automated / python-tests.el
1 ;;; python-tests.el --- Test suite for python.el
2
3 ;; Copyright (C) 2013 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 (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))
37
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))))
54
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)))))
88
89 \f
90 ;;; Tests for your tests, so you can test while you test.
91
92 (ert-deftest python-tests-look-at-1 ()
93 "Test forward movement."
94 (python-tests-with-temp-buffer
95 "Lorem ipsum dolor sit amet, consectetur adipisicing elit,
96 sed do eiusmod tempor incididunt ut labore et dolore magna
97 aliqua."
98 (let ((expected (save-excursion
99 (dotimes (i 3)
100 (re-search-forward "et" nil t))
101 (forward-char -2)
102 (point))))
103 (should (= (python-tests-look-at "et" 3 t) expected))
104 ;; Even if NUM is bigger than found occurrences the point of last
105 ;; one should be returned.
106 (should (= (python-tests-look-at "et" 6 t) expected))
107 ;; If already looking at STRING, it should skip it.
108 (dotimes (i 2) (re-search-forward "et"))
109 (forward-char -2)
110 (should (= (python-tests-look-at "et") expected)))))
111
112 (ert-deftest python-tests-look-at-2 ()
113 "Test backward movement."
114 (python-tests-with-temp-buffer
115 "Lorem ipsum dolor sit amet, consectetur adipisicing elit,
116 sed do eiusmod tempor incididunt ut labore et dolore magna
117 aliqua."
118 (let ((expected
119 (save-excursion
120 (re-search-forward "et" nil t)
121 (forward-char -2)
122 (point))))
123 (dotimes (i 3)
124 (re-search-forward "et" nil t))
125 (should (= (python-tests-look-at "et" -3 t) expected))
126 (should (= (python-tests-look-at "et" -6 t) expected)))))
127
128 \f
129 ;;; Bindings
130
131 \f
132 ;;; Python specialized rx
133
134 \f
135 ;;; Font-lock and syntax
136
137 \f
138 ;;; Indentation
139
140 ;; See: http://www.python.org/dev/peps/pep-0008/#indentation
141
142 (ert-deftest python-indent-pep8-1 ()
143 "First pep8 case."
144 (python-tests-with-temp-buffer
145 "# Aligned with opening delimiter
146 foo = long_function_name(var_one, var_two,
147 var_three, var_four)
148 "
149 (should (eq (car (python-indent-context)) 'no-indent))
150 (should (= (python-indent-calculate-indentation) 0))
151 (python-tests-look-at "foo = long_function_name(var_one, var_two,")
152 (should (eq (car (python-indent-context)) 'after-line))
153 (should (= (python-indent-calculate-indentation) 0))
154 (python-tests-look-at "var_three, var_four)")
155 (should (eq (car (python-indent-context)) 'inside-paren))
156 (should (= (python-indent-calculate-indentation) 25))))
157
158 (ert-deftest python-indent-pep8-2 ()
159 "Second pep8 case."
160 (python-tests-with-temp-buffer
161 "# More indentation included to distinguish this from the rest.
162 def long_function_name(
163 var_one, var_two, var_three,
164 var_four):
165 print (var_one)
166 "
167 (should (eq (car (python-indent-context)) 'no-indent))
168 (should (= (python-indent-calculate-indentation) 0))
169 (python-tests-look-at "def long_function_name(")
170 (should (eq (car (python-indent-context)) 'after-line))
171 (should (= (python-indent-calculate-indentation) 0))
172 (python-tests-look-at "var_one, var_two, var_three,")
173 (should (eq (car (python-indent-context)) 'inside-paren))
174 (should (= (python-indent-calculate-indentation) 8))
175 (python-tests-look-at "var_four):")
176 (should (eq (car (python-indent-context)) 'inside-paren))
177 (should (= (python-indent-calculate-indentation) 8))
178 (python-tests-look-at "print (var_one)")
179 (should (eq (car (python-indent-context)) 'after-beginning-of-block))
180 (should (= (python-indent-calculate-indentation) 4))))
181
182 (ert-deftest python-indent-pep8-3 ()
183 "Third pep8 case."
184 (python-tests-with-temp-buffer
185 "# Extra indentation is not necessary.
186 foo = long_function_name(
187 var_one, var_two,
188 var_three, var_four)
189 "
190 (should (eq (car (python-indent-context)) 'no-indent))
191 (should (= (python-indent-calculate-indentation) 0))
192 (python-tests-look-at "foo = long_function_name(")
193 (should (eq (car (python-indent-context)) 'after-line))
194 (should (= (python-indent-calculate-indentation) 0))
195 (python-tests-look-at "var_one, var_two,")
196 (should (eq (car (python-indent-context)) 'inside-paren))
197 (should (= (python-indent-calculate-indentation) 4))
198 (python-tests-look-at "var_three, var_four)")
199 (should (eq (car (python-indent-context)) 'inside-paren))
200 (should (= (python-indent-calculate-indentation) 4))))
201
202 (ert-deftest python-indent-inside-paren-1 ()
203 "The most simple inside-paren case that shouldn't fail."
204 (python-tests-with-temp-buffer
205 "
206 data = {
207 'key':
208 {
209 'objlist': [
210 {
211 'pk': 1,
212 'name': 'first',
213 },
214 {
215 'pk': 2,
216 'name': 'second',
217 }
218 ]
219 }
220 }
221 "
222 (python-tests-look-at "data = {")
223 (should (eq (car (python-indent-context)) 'after-line))
224 (should (= (python-indent-calculate-indentation) 0))
225 (python-tests-look-at "'key':")
226 (should (eq (car (python-indent-context)) 'inside-paren))
227 (should (= (python-indent-calculate-indentation) 4))
228 (python-tests-look-at "{")
229 (should (eq (car (python-indent-context)) 'inside-paren))
230 (should (= (python-indent-calculate-indentation) 4))
231 (python-tests-look-at "'objlist': [")
232 (should (eq (car (python-indent-context)) 'inside-paren))
233 (should (= (python-indent-calculate-indentation) 8))
234 (python-tests-look-at "{")
235 (should (eq (car (python-indent-context)) 'inside-paren))
236 (should (= (python-indent-calculate-indentation) 12))
237 (python-tests-look-at "'pk': 1,")
238 (should (eq (car (python-indent-context)) 'inside-paren))
239 (should (= (python-indent-calculate-indentation) 16))
240 (python-tests-look-at "'name': 'first',")
241 (should (eq (car (python-indent-context)) 'inside-paren))
242 (should (= (python-indent-calculate-indentation) 16))
243 (python-tests-look-at "},")
244 (should (eq (car (python-indent-context)) 'inside-paren))
245 (should (= (python-indent-calculate-indentation) 12))
246 (python-tests-look-at "{")
247 (should (eq (car (python-indent-context)) 'inside-paren))
248 (should (= (python-indent-calculate-indentation) 12))
249 (python-tests-look-at "'pk': 2,")
250 (should (eq (car (python-indent-context)) 'inside-paren))
251 (should (= (python-indent-calculate-indentation) 16))
252 (python-tests-look-at "'name': 'second',")
253 (should (eq (car (python-indent-context)) 'inside-paren))
254 (should (= (python-indent-calculate-indentation) 16))
255 (python-tests-look-at "}")
256 (should (eq (car (python-indent-context)) 'inside-paren))
257 (should (= (python-indent-calculate-indentation) 12))
258 (python-tests-look-at "]")
259 (should (eq (car (python-indent-context)) 'inside-paren))
260 (should (= (python-indent-calculate-indentation) 8))
261 (python-tests-look-at "}")
262 (should (eq (car (python-indent-context)) 'inside-paren))
263 (should (= (python-indent-calculate-indentation) 4))
264 (python-tests-look-at "}")
265 (should (eq (car (python-indent-context)) 'inside-paren))
266 (should (= (python-indent-calculate-indentation) 0))))
267
268 (ert-deftest python-indent-inside-paren-2 ()
269 "Another more compact paren group style."
270 (python-tests-with-temp-buffer
271 "
272 data = {'key': {
273 'objlist': [
274 {'pk': 1,
275 'name': 'first'},
276 {'pk': 2,
277 'name': 'second'}
278 ]
279 }}
280 "
281 (python-tests-look-at "data = {")
282 (should (eq (car (python-indent-context)) 'after-line))
283 (should (= (python-indent-calculate-indentation) 0))
284 (python-tests-look-at "'objlist': [")
285 (should (eq (car (python-indent-context)) 'inside-paren))
286 (should (= (python-indent-calculate-indentation) 4))
287 (python-tests-look-at "{'pk': 1,")
288 (should (eq (car (python-indent-context)) 'inside-paren))
289 (should (= (python-indent-calculate-indentation) 8))
290 (python-tests-look-at "'name': 'first'},")
291 (should (eq (car (python-indent-context)) 'inside-paren))
292 (should (= (python-indent-calculate-indentation) 9))
293 (python-tests-look-at "{'pk': 2,")
294 (should (eq (car (python-indent-context)) 'inside-paren))
295 (should (= (python-indent-calculate-indentation) 8))
296 (python-tests-look-at "'name': 'second'}")
297 (should (eq (car (python-indent-context)) 'inside-paren))
298 (should (= (python-indent-calculate-indentation) 9))
299 (python-tests-look-at "]")
300 (should (eq (car (python-indent-context)) 'inside-paren))
301 (should (= (python-indent-calculate-indentation) 4))
302 (python-tests-look-at "}}")
303 (should (eq (car (python-indent-context)) 'inside-paren))
304 (should (= (python-indent-calculate-indentation) 0))
305 (python-tests-look-at "}")
306 (should (eq (car (python-indent-context)) 'inside-paren))
307 (should (= (python-indent-calculate-indentation) 0))))
308
309 (ert-deftest python-indent-after-block-1 ()
310 "The most simple after-block case that shouldn't fail."
311 (python-tests-with-temp-buffer
312 "
313 def foo(a, b, c=True):
314 "
315 (should (eq (car (python-indent-context)) 'no-indent))
316 (should (= (python-indent-calculate-indentation) 0))
317 (goto-char (point-max))
318 (should (eq (car (python-indent-context)) 'after-beginning-of-block))
319 (should (= (python-indent-calculate-indentation) 4))))
320
321 (ert-deftest python-indent-after-block-2 ()
322 "A weird (malformed) multiline block statement."
323 (python-tests-with-temp-buffer
324 "
325 def foo(a, b, c={
326 'a':
327 }):
328 "
329 (goto-char (point-max))
330 (should (eq (car (python-indent-context)) 'after-beginning-of-block))
331 (should (= (python-indent-calculate-indentation) 4))))
332
333 (ert-deftest python-indent-dedenters-1 ()
334 "Check all dedenters."
335 (python-tests-with-temp-buffer
336 "
337 def foo(a, b, c):
338 if a:
339 print (a)
340 elif b:
341 print (b)
342 else:
343 try:
344 print (c.pop())
345 except (IndexError, AttributeError):
346 print (c)
347 finally:
348 print ('nor a, nor b are true')
349 "
350 (python-tests-look-at "if a:")
351 (should (eq (car (python-indent-context)) 'after-beginning-of-block))
352 (should (= (python-indent-calculate-indentation) 4))
353 (python-tests-look-at "print (a)")
354 (should (eq (car (python-indent-context)) 'after-beginning-of-block))
355 (should (= (python-indent-calculate-indentation) 8))
356 (python-tests-look-at "elif b:")
357 (should (eq (car (python-indent-context)) 'after-line))
358 (should (= (python-indent-calculate-indentation) 4))
359 (python-tests-look-at "print (b)")
360 (should (eq (car (python-indent-context)) 'after-beginning-of-block))
361 (should (= (python-indent-calculate-indentation) 8))
362 (python-tests-look-at "else:")
363 (should (eq (car (python-indent-context)) 'after-line))
364 (should (= (python-indent-calculate-indentation) 4))
365 (python-tests-look-at "try:")
366 (should (eq (car (python-indent-context)) 'after-beginning-of-block))
367 (should (= (python-indent-calculate-indentation) 8))
368 (python-tests-look-at "print (c.pop())")
369 (should (eq (car (python-indent-context)) 'after-beginning-of-block))
370 (should (= (python-indent-calculate-indentation) 12))
371 (python-tests-look-at "except (IndexError, AttributeError):")
372 (should (eq (car (python-indent-context)) 'after-line))
373 (should (= (python-indent-calculate-indentation) 8))
374 (python-tests-look-at "print (c)")
375 (should (eq (car (python-indent-context)) 'after-beginning-of-block))
376 (should (= (python-indent-calculate-indentation) 12))
377 (python-tests-look-at "finally:")
378 (should (eq (car (python-indent-context)) 'after-line))
379 (should (= (python-indent-calculate-indentation) 8))
380 (python-tests-look-at "print ('nor a, nor b are true')")
381 (should (eq (car (python-indent-context)) 'after-beginning-of-block))
382 (should (= (python-indent-calculate-indentation) 12))))
383
384 (ert-deftest python-indent-after-backslash-1 ()
385 "The most common case."
386 (python-tests-with-temp-buffer
387 "
388 from foo.bar.baz import something, something_1 \\\\
389 something_2 something_3, \\\\
390 something_4, something_5
391 "
392 (python-tests-look-at "from foo.bar.baz import something, something_1")
393 (should (eq (car (python-indent-context)) 'after-line))
394 (should (= (python-indent-calculate-indentation) 0))
395 (python-tests-look-at "something_2 something_3,")
396 (should (eq (car (python-indent-context)) 'after-backslash))
397 (should (= (python-indent-calculate-indentation) 4))
398 (python-tests-look-at "something_4, something_5")
399 (should (eq (car (python-indent-context)) 'after-backslash))
400 (should (= (python-indent-calculate-indentation) 4))
401 (goto-char (point-max))
402 (should (eq (car (python-indent-context)) 'after-line))
403 (should (= (python-indent-calculate-indentation) 0))))
404
405 (ert-deftest python-indent-after-backslash-2 ()
406 "A pretty extreme complicated case."
407 (python-tests-with-temp-buffer
408 "
409 objects = Thing.objects.all() \\\\
410 .filter(
411 type='toy',
412 status='bought'
413 ) \\\\
414 .aggregate(
415 Sum('amount')
416 ) \\\\
417 .values_list()
418 "
419 (python-tests-look-at "objects = Thing.objects.all()")
420 (should (eq (car (python-indent-context)) 'after-line))
421 (should (= (python-indent-calculate-indentation) 0))
422 (python-tests-look-at ".filter(")
423 (should (eq (car (python-indent-context)) 'after-backslash))
424 (should (= (python-indent-calculate-indentation) 23))
425 (python-tests-look-at "type='toy',")
426 (should (eq (car (python-indent-context)) 'inside-paren))
427 (should (= (python-indent-calculate-indentation) 27))
428 (python-tests-look-at "status='bought'")
429 (should (eq (car (python-indent-context)) 'inside-paren))
430 (should (= (python-indent-calculate-indentation) 27))
431 (python-tests-look-at ") \\\\")
432 (should (eq (car (python-indent-context)) 'inside-paren))
433 (should (= (python-indent-calculate-indentation) 23))
434 (python-tests-look-at ".aggregate(")
435 (should (eq (car (python-indent-context)) 'after-backslash))
436 (should (= (python-indent-calculate-indentation) 23))
437 (python-tests-look-at "Sum('amount')")
438 (should (eq (car (python-indent-context)) 'inside-paren))
439 (should (= (python-indent-calculate-indentation) 27))
440 (python-tests-look-at ") \\\\")
441 (should (eq (car (python-indent-context)) 'inside-paren))
442 (should (= (python-indent-calculate-indentation) 23))
443 (python-tests-look-at ".values_list()")
444 (should (eq (car (python-indent-context)) 'after-backslash))
445 (should (= (python-indent-calculate-indentation) 23))
446 (forward-line 1)
447 (should (eq (car (python-indent-context)) 'after-line))
448 (should (= (python-indent-calculate-indentation) 0))))
449
450 (ert-deftest python-indent-block-enders ()
451 "Test `python-indent-block-enders' value honoring."
452 (python-tests-with-temp-buffer
453 "
454 Class foo(object):
455
456 def bar(self):
457 if self.baz:
458 return (1,
459 2,
460 3)
461
462 else:
463 pass
464 "
465 (python-tests-look-at "3)")
466 (forward-line 1)
467 (should (= (python-indent-calculate-indentation) 8))
468 (python-tests-look-at "pass")
469 (forward-line 1)
470 (should (= (python-indent-calculate-indentation) 8))))
471
472 \f
473 ;;; Navigation
474
475 (ert-deftest python-nav-beginning-of-defun-1 ()
476 (python-tests-with-temp-buffer
477 "
478 def decoratorFunctionWithArguments(arg1, arg2, arg3):
479 '''print decorated function call data to stdout.
480
481 Usage:
482
483 @decoratorFunctionWithArguments('arg1', 'arg2')
484 def func(a, b, c=True):
485 pass
486 '''
487
488 def wwrap(f):
489 print 'Inside wwrap()'
490 def wrapped_f(*args):
491 print 'Inside wrapped_f()'
492 print 'Decorator arguments:', arg1, arg2, arg3
493 f(*args)
494 print 'After f(*args)'
495 return wrapped_f
496 return wwrap
497 "
498 (python-tests-look-at "return wrap")
499 (should (= (save-excursion
500 (python-nav-beginning-of-defun)
501 (point))
502 (save-excursion
503 (python-tests-look-at "def wrapped_f(*args):" -1)
504 (beginning-of-line)
505 (point))))
506 (python-tests-look-at "def wrapped_f(*args):" -1)
507 (should (= (save-excursion
508 (python-nav-beginning-of-defun)
509 (point))
510 (save-excursion
511 (python-tests-look-at "def wwrap(f):" -1)
512 (beginning-of-line)
513 (point))))
514 (python-tests-look-at "def wwrap(f):" -1)
515 (should (= (save-excursion
516 (python-nav-beginning-of-defun)
517 (point))
518 (save-excursion
519 (python-tests-look-at "def decoratorFunctionWithArguments" -1)
520 (beginning-of-line)
521 (point))))))
522
523 (ert-deftest python-nav-beginning-of-defun-2 ()
524 (python-tests-with-temp-buffer
525 "
526 class C(object):
527
528 def m(self):
529 self.c()
530
531 def b():
532 pass
533
534 def a():
535 pass
536
537 def c(self):
538 pass
539 "
540 ;; Nested defuns, are handled with care.
541 (python-tests-look-at "def c(self):")
542 (should (= (save-excursion
543 (python-nav-beginning-of-defun)
544 (point))
545 (save-excursion
546 (python-tests-look-at "def m(self):" -1)
547 (beginning-of-line)
548 (point))))
549 ;; Defuns on same levels should be respected.
550 (python-tests-look-at "def a():" -1)
551 (should (= (save-excursion
552 (python-nav-beginning-of-defun)
553 (point))
554 (save-excursion
555 (python-tests-look-at "def b():" -1)
556 (beginning-of-line)
557 (point))))
558 ;; Jump to a top level defun.
559 (python-tests-look-at "def b():" -1)
560 (should (= (save-excursion
561 (python-nav-beginning-of-defun)
562 (point))
563 (save-excursion
564 (python-tests-look-at "def m(self):" -1)
565 (beginning-of-line)
566 (point))))
567 ;; Jump to a top level defun again.
568 (python-tests-look-at "def m(self):" -1)
569 (should (= (save-excursion
570 (python-nav-beginning-of-defun)
571 (point))
572 (save-excursion
573 (python-tests-look-at "class C(object):" -1)
574 (beginning-of-line)
575 (point))))))
576
577 (ert-deftest python-nav-end-of-defun-1 ()
578 (python-tests-with-temp-buffer
579 "
580 class C(object):
581
582 def m(self):
583 self.c()
584
585 def b():
586 pass
587
588 def a():
589 pass
590
591 def c(self):
592 pass
593 "
594 (should (= (save-excursion
595 (python-tests-look-at "class C(object):")
596 (python-nav-end-of-defun)
597 (point))
598 (save-excursion
599 (point-max))))
600 (should (= (save-excursion
601 (python-tests-look-at "def m(self):")
602 (python-nav-end-of-defun)
603 (point))
604 (save-excursion
605 (python-tests-look-at "def c(self):")
606 (forward-line -1)
607 (point))))
608 (should (= (save-excursion
609 (python-tests-look-at "def b():")
610 (python-nav-end-of-defun)
611 (point))
612 (save-excursion
613 (python-tests-look-at "def b():")
614 (forward-line 2)
615 (point))))
616 (should (= (save-excursion
617 (python-tests-look-at "def c(self):")
618 (python-nav-end-of-defun)
619 (point))
620 (save-excursion
621 (point-max))))))
622
623 (ert-deftest python-nav-end-of-defun-2 ()
624 (python-tests-with-temp-buffer
625 "
626 def decoratorFunctionWithArguments(arg1, arg2, arg3):
627 '''print decorated function call data to stdout.
628
629 Usage:
630
631 @decoratorFunctionWithArguments('arg1', 'arg2')
632 def func(a, b, c=True):
633 pass
634 '''
635
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
645 "
646 (should (= (save-excursion
647 (python-tests-look-at "def decoratorFunctionWithArguments")
648 (python-nav-end-of-defun)
649 (point))
650 (save-excursion
651 (point-max))))
652 (should (= (save-excursion
653 (python-tests-look-at "@decoratorFunctionWithArguments")
654 (python-nav-end-of-defun)
655 (point))
656 (save-excursion
657 (point-max))))
658 (should (= (save-excursion
659 (python-tests-look-at "def wwrap(f):")
660 (python-nav-end-of-defun)
661 (point))
662 (save-excursion
663 (python-tests-look-at "return wwrap")
664 (line-beginning-position))))
665 (should (= (save-excursion
666 (python-tests-look-at "def wrapped_f(*args):")
667 (python-nav-end-of-defun)
668 (point))
669 (save-excursion
670 (python-tests-look-at "return wrapped_f")
671 (line-beginning-position))))
672 (should (= (save-excursion
673 (python-tests-look-at "f(*args)")
674 (python-nav-end-of-defun)
675 (point))
676 (save-excursion
677 (python-tests-look-at "return wrapped_f")
678 (line-beginning-position))))))
679
680 (ert-deftest python-nav-backward-defun-1 ()
681 (python-tests-with-temp-buffer
682 "
683 class A(object): # A
684
685 def a(self): # a
686 pass
687
688 def b(self): # b
689 pass
690
691 class B(object): # B
692
693 class C(object): # C
694
695 def d(self): # d
696 pass
697
698 # def e(self): # e
699 # pass
700
701 def c(self): # c
702 pass
703
704 # def d(self): # d
705 # pass
706 "
707 (goto-char (point-max))
708 (should (= (save-excursion (python-nav-backward-defun))
709 (python-tests-look-at " def c(self): # c" -1)))
710 (should (= (save-excursion (python-nav-backward-defun))
711 (python-tests-look-at " def d(self): # d" -1)))
712 (should (= (save-excursion (python-nav-backward-defun))
713 (python-tests-look-at " class C(object): # C" -1)))
714 (should (= (save-excursion (python-nav-backward-defun))
715 (python-tests-look-at " class B(object): # B" -1)))
716 (should (= (save-excursion (python-nav-backward-defun))
717 (python-tests-look-at " def b(self): # b" -1)))
718 (should (= (save-excursion (python-nav-backward-defun))
719 (python-tests-look-at " def a(self): # a" -1)))
720 (should (= (save-excursion (python-nav-backward-defun))
721 (python-tests-look-at "class A(object): # A" -1)))
722 (should (not (python-nav-backward-defun)))))
723
724 (ert-deftest python-nav-backward-defun-2 ()
725 (python-tests-with-temp-buffer
726 "
727 def decoratorFunctionWithArguments(arg1, arg2, arg3):
728 '''print decorated function call data to stdout.
729
730 Usage:
731
732 @decoratorFunctionWithArguments('arg1', 'arg2')
733 def func(a, b, c=True):
734 pass
735 '''
736
737 def wwrap(f):
738 print 'Inside wwrap()'
739 def wrapped_f(*args):
740 print 'Inside wrapped_f()'
741 print 'Decorator arguments:', arg1, arg2, arg3
742 f(*args)
743 print 'After f(*args)'
744 return wrapped_f
745 return wwrap
746 "
747 (goto-char (point-max))
748 (should (= (save-excursion (python-nav-backward-defun))
749 (python-tests-look-at " def wrapped_f(*args):" -1)))
750 (should (= (save-excursion (python-nav-backward-defun))
751 (python-tests-look-at " def wwrap(f):" -1)))
752 (should (= (save-excursion (python-nav-backward-defun))
753 (python-tests-look-at "def decoratorFunctionWithArguments(arg1, arg2, arg3):" -1)))
754 (should (not (python-nav-backward-defun)))))
755
756 (ert-deftest python-nav-backward-defun-3 ()
757 (python-tests-with-temp-buffer
758 "
759 '''
760 def u(self):
761 pass
762
763 def v(self):
764 pass
765
766 def w(self):
767 pass
768 '''
769
770 class A(object):
771 pass
772 "
773 (goto-char (point-min))
774 (let ((point (python-tests-look-at "class A(object):")))
775 (should (not (python-nav-backward-defun)))
776 (should (= point (point))))))
777
778 (ert-deftest python-nav-forward-defun-1 ()
779 (python-tests-with-temp-buffer
780 "
781 class A(object): # A
782
783 def a(self): # a
784 pass
785
786 def b(self): # b
787 pass
788
789 class B(object): # B
790
791 class C(object): # C
792
793 def d(self): # d
794 pass
795
796 # def e(self): # e
797 # pass
798
799 def c(self): # c
800 pass
801
802 # def d(self): # d
803 # pass
804 "
805 (goto-char (point-min))
806 (should (= (save-excursion (python-nav-forward-defun))
807 (python-tests-look-at "(object): # A")))
808 (should (= (save-excursion (python-nav-forward-defun))
809 (python-tests-look-at "(self): # a")))
810 (should (= (save-excursion (python-nav-forward-defun))
811 (python-tests-look-at "(self): # b")))
812 (should (= (save-excursion (python-nav-forward-defun))
813 (python-tests-look-at "(object): # B")))
814 (should (= (save-excursion (python-nav-forward-defun))
815 (python-tests-look-at "(object): # C")))
816 (should (= (save-excursion (python-nav-forward-defun))
817 (python-tests-look-at "(self): # d")))
818 (should (= (save-excursion (python-nav-forward-defun))
819 (python-tests-look-at "(self): # c")))
820 (should (not (python-nav-forward-defun)))))
821
822 (ert-deftest python-nav-forward-defun-2 ()
823 (python-tests-with-temp-buffer
824 "
825 def decoratorFunctionWithArguments(arg1, arg2, arg3):
826 '''print decorated function call data to stdout.
827
828 Usage:
829
830 @decoratorFunctionWithArguments('arg1', 'arg2')
831 def func(a, b, c=True):
832 pass
833 '''
834
835 def wwrap(f):
836 print 'Inside wwrap()'
837 def wrapped_f(*args):
838 print 'Inside wrapped_f()'
839 print 'Decorator arguments:', arg1, arg2, arg3
840 f(*args)
841 print 'After f(*args)'
842 return wrapped_f
843 return wwrap
844 "
845 (goto-char (point-min))
846 (should (= (save-excursion (python-nav-forward-defun))
847 (python-tests-look-at "(arg1, arg2, arg3):")))
848 (should (= (save-excursion (python-nav-forward-defun))
849 (python-tests-look-at "(f):")))
850 (should (= (save-excursion (python-nav-forward-defun))
851 (python-tests-look-at "(*args):")))
852 (should (not (python-nav-forward-defun)))))
853
854 (ert-deftest python-nav-forward-defun-3 ()
855 (python-tests-with-temp-buffer
856 "
857 class A(object):
858 pass
859
860 '''
861 def u(self):
862 pass
863
864 def v(self):
865 pass
866
867 def w(self):
868 pass
869 '''
870 "
871 (goto-char (point-min))
872 (let ((point (python-tests-look-at "(object):")))
873 (should (not (python-nav-forward-defun)))
874 (should (= point (point))))))
875
876 (ert-deftest python-nav-beginning-of-statement-1 ()
877 (python-tests-with-temp-buffer
878 "
879 v1 = 123 + \
880 456 + \
881 789
882 v2 = (value1,
883 value2,
884
885 value3,
886 value4)
887 v3 = ('this is a string'
888
889 'that is continued'
890 'between lines'
891 'within a paren',
892 # this is a comment, yo
893 'continue previous line')
894 v4 = '''
895 a very long
896 string
897 '''
898 "
899 (python-tests-look-at "v2 =")
900 (python-util-forward-comment -1)
901 (should (= (save-excursion
902 (python-nav-beginning-of-statement)
903 (point))
904 (python-tests-look-at "v1 =" -1 t)))
905 (python-tests-look-at "v3 =")
906 (python-util-forward-comment -1)
907 (should (= (save-excursion
908 (python-nav-beginning-of-statement)
909 (point))
910 (python-tests-look-at "v2 =" -1 t)))
911 (python-tests-look-at "v4 =")
912 (python-util-forward-comment -1)
913 (should (= (save-excursion
914 (python-nav-beginning-of-statement)
915 (point))
916 (python-tests-look-at "v3 =" -1 t)))
917 (goto-char (point-max))
918 (python-util-forward-comment -1)
919 (should (= (save-excursion
920 (python-nav-beginning-of-statement)
921 (point))
922 (python-tests-look-at "v4 =" -1 t)))))
923
924 (ert-deftest python-nav-end-of-statement-1 ()
925 (python-tests-with-temp-buffer
926 "
927 v1 = 123 + \
928 456 + \
929 789
930 v2 = (value1,
931 value2,
932
933 value3,
934 value4)
935 v3 = ('this is a string'
936
937 'that is continued'
938 'between lines'
939 'within a paren',
940 # this is a comment, yo
941 'continue previous line')
942 v4 = '''
943 a very long
944 string
945 '''
946 "
947 (python-tests-look-at "v1 =")
948 (should (= (save-excursion
949 (python-nav-end-of-statement)
950 (point))
951 (save-excursion
952 (python-tests-look-at "789")
953 (line-end-position))))
954 (python-tests-look-at "v2 =")
955 (should (= (save-excursion
956 (python-nav-end-of-statement)
957 (point))
958 (save-excursion
959 (python-tests-look-at "value4)")
960 (line-end-position))))
961 (python-tests-look-at "v3 =")
962 (should (= (save-excursion
963 (python-nav-end-of-statement)
964 (point))
965 (save-excursion
966 (python-tests-look-at
967 "'continue previous line')")
968 (line-end-position))))
969 (python-tests-look-at "v4 =")
970 (should (= (save-excursion
971 (python-nav-end-of-statement)
972 (point))
973 (save-excursion
974 (goto-char (point-max))
975 (python-util-forward-comment -1)
976 (point))))))
977
978 (ert-deftest python-nav-forward-statement-1 ()
979 (python-tests-with-temp-buffer
980 "
981 v1 = 123 + \
982 456 + \
983 789
984 v2 = (value1,
985 value2,
986
987 value3,
988 value4)
989 v3 = ('this is a string'
990
991 'that is continued'
992 'between lines'
993 'within a paren',
994 # this is a comment, yo
995 'continue previous line')
996 v4 = '''
997 a very long
998 string
999 '''
1000 "
1001 (python-tests-look-at "v1 =")
1002 (should (= (save-excursion
1003 (python-nav-forward-statement)
1004 (point))
1005 (python-tests-look-at "v2 =")))
1006 (should (= (save-excursion
1007 (python-nav-forward-statement)
1008 (point))
1009 (python-tests-look-at "v3 =")))
1010 (should (= (save-excursion
1011 (python-nav-forward-statement)
1012 (point))
1013 (python-tests-look-at "v4 =")))
1014 (should (= (save-excursion
1015 (python-nav-forward-statement)
1016 (point))
1017 (point-max)))))
1018
1019 (ert-deftest python-nav-backward-statement-1 ()
1020 (python-tests-with-temp-buffer
1021 "
1022 v1 = 123 + \
1023 456 + \
1024 789
1025 v2 = (value1,
1026 value2,
1027
1028 value3,
1029 value4)
1030 v3 = ('this is a string'
1031
1032 'that is continued'
1033 'between lines'
1034 'within a paren',
1035 # this is a comment, yo
1036 'continue previous line')
1037 v4 = '''
1038 a very long
1039 string
1040 '''
1041 "
1042 (goto-char (point-max))
1043 (should (= (save-excursion
1044 (python-nav-backward-statement)
1045 (point))
1046 (python-tests-look-at "v4 =" -1)))
1047 (should (= (save-excursion
1048 (python-nav-backward-statement)
1049 (point))
1050 (python-tests-look-at "v3 =" -1)))
1051 (should (= (save-excursion
1052 (python-nav-backward-statement)
1053 (point))
1054 (python-tests-look-at "v2 =" -1)))
1055 (should (= (save-excursion
1056 (python-nav-backward-statement)
1057 (point))
1058 (python-tests-look-at "v1 =" -1)))))
1059
1060 (ert-deftest python-nav-backward-statement-2 ()
1061 :expected-result :failed
1062 (python-tests-with-temp-buffer
1063 "
1064 v1 = 123 + \
1065 456 + \
1066 789
1067 v2 = (value1,
1068 value2,
1069
1070 value3,
1071 value4)
1072 "
1073 ;; FIXME: For some reason `python-nav-backward-statement' is moving
1074 ;; back two sentences when starting from 'value4)'.
1075 (goto-char (point-max))
1076 (python-util-forward-comment -1)
1077 (should (= (save-excursion
1078 (python-nav-backward-statement)
1079 (point))
1080 (python-tests-look-at "v2 =" -1 t)))))
1081
1082 (ert-deftest python-nav-beginning-of-block-1 ()
1083 (python-tests-with-temp-buffer
1084 "
1085 def decoratorFunctionWithArguments(arg1, arg2, arg3):
1086 '''print decorated function call data to stdout.
1087
1088 Usage:
1089
1090 @decoratorFunctionWithArguments('arg1', 'arg2')
1091 def func(a, b, c=True):
1092 pass
1093 '''
1094
1095 def wwrap(f):
1096 print 'Inside wwrap()'
1097 def wrapped_f(*args):
1098 print 'Inside wrapped_f()'
1099 print 'Decorator arguments:', arg1, arg2, arg3
1100 f(*args)
1101 print 'After f(*args)'
1102 return wrapped_f
1103 return wwrap
1104 "
1105 (python-tests-look-at "return wwrap")
1106 (should (= (save-excursion
1107 (python-nav-beginning-of-block)
1108 (point))
1109 (python-tests-look-at "def decoratorFunctionWithArguments" -1)))
1110 (python-tests-look-at "print 'Inside wwrap()'")
1111 (should (= (save-excursion
1112 (python-nav-beginning-of-block)
1113 (point))
1114 (python-tests-look-at "def wwrap(f):" -1)))
1115 (python-tests-look-at "print 'After f(*args)'")
1116 (end-of-line)
1117 (should (= (save-excursion
1118 (python-nav-beginning-of-block)
1119 (point))
1120 (python-tests-look-at "def wrapped_f(*args):" -1)))
1121 (python-tests-look-at "return wrapped_f")
1122 (should (= (save-excursion
1123 (python-nav-beginning-of-block)
1124 (point))
1125 (python-tests-look-at "def wwrap(f):" -1)))))
1126
1127 (ert-deftest python-nav-end-of-block-1 ()
1128 (python-tests-with-temp-buffer
1129 "
1130 def decoratorFunctionWithArguments(arg1, arg2, arg3):
1131 '''print decorated function call data to stdout.
1132
1133 Usage:
1134
1135 @decoratorFunctionWithArguments('arg1', 'arg2')
1136 def func(a, b, c=True):
1137 pass
1138 '''
1139
1140 def wwrap(f):
1141 print 'Inside wwrap()'
1142 def wrapped_f(*args):
1143 print 'Inside wrapped_f()'
1144 print 'Decorator arguments:', arg1, arg2, arg3
1145 f(*args)
1146 print 'After f(*args)'
1147 return wrapped_f
1148 return wwrap
1149 "
1150 (python-tests-look-at "def decoratorFunctionWithArguments")
1151 (should (= (save-excursion
1152 (python-nav-end-of-block)
1153 (point))
1154 (save-excursion
1155 (goto-char (point-max))
1156 (python-util-forward-comment -1)
1157 (point))))
1158 (python-tests-look-at "def wwrap(f):")
1159 (should (= (save-excursion
1160 (python-nav-end-of-block)
1161 (point))
1162 (save-excursion
1163 (python-tests-look-at "return wrapped_f")
1164 (line-end-position))))
1165 (end-of-line)
1166 (should (= (save-excursion
1167 (python-nav-end-of-block)
1168 (point))
1169 (save-excursion
1170 (python-tests-look-at "return wrapped_f")
1171 (line-end-position))))
1172 (python-tests-look-at "f(*args)")
1173 (should (= (save-excursion
1174 (python-nav-end-of-block)
1175 (point))
1176 (save-excursion
1177 (python-tests-look-at "print 'After f(*args)'")
1178 (line-end-position))))))
1179
1180 (ert-deftest python-nav-forward-block-1 ()
1181 "This also accounts as a test for `python-nav-backward-block'."
1182 (python-tests-with-temp-buffer
1183 "
1184 if request.user.is_authenticated():
1185 # def block():
1186 # pass
1187 try:
1188 profile = request.user.get_profile()
1189 except Profile.DoesNotExist:
1190 profile = Profile.objects.create(user=request.user)
1191 else:
1192 if profile.stats:
1193 profile.recalculate_stats()
1194 else:
1195 profile.clear_stats()
1196 finally:
1197 profile.views += 1
1198 profile.save()
1199 "
1200 (should (= (save-excursion (python-nav-forward-block))
1201 (python-tests-look-at "if request.user.is_authenticated():")))
1202 (should (= (save-excursion (python-nav-forward-block))
1203 (python-tests-look-at "try:")))
1204 (should (= (save-excursion (python-nav-forward-block))
1205 (python-tests-look-at "except Profile.DoesNotExist:")))
1206 (should (= (save-excursion (python-nav-forward-block))
1207 (python-tests-look-at "else:")))
1208 (should (= (save-excursion (python-nav-forward-block))
1209 (python-tests-look-at "if profile.stats:")))
1210 (should (= (save-excursion (python-nav-forward-block))
1211 (python-tests-look-at "else:")))
1212 (should (= (save-excursion (python-nav-forward-block))
1213 (python-tests-look-at "finally:")))
1214 ;; When point is at the last block, leave it there and return nil
1215 (should (not (save-excursion (python-nav-forward-block))))
1216 ;; Move backwards, and even if the number of moves is less than the
1217 ;; provided argument return the point.
1218 (should (= (save-excursion (python-nav-forward-block -10))
1219 (python-tests-look-at
1220 "if request.user.is_authenticated():" -1)))))
1221
1222 (ert-deftest python-nav-lisp-forward-sexp-safe-1 ()
1223 (python-tests-with-temp-buffer
1224 "
1225 profile = Profile.objects.create(user=request.user)
1226 profile.notify()
1227 "
1228 (python-tests-look-at "profile =")
1229 (python-nav-lisp-forward-sexp-safe 4)
1230 (should (looking-at "(user=request.user)"))
1231 (python-tests-look-at "user=request.user")
1232 (python-nav-lisp-forward-sexp-safe -1)
1233 (should (looking-at "(user=request.user)"))
1234 (python-nav-lisp-forward-sexp-safe -4)
1235 (should (looking-at "profile ="))
1236 (python-tests-look-at "user=request.user")
1237 (python-nav-lisp-forward-sexp-safe 3)
1238 (should (looking-at ")"))
1239 (python-nav-lisp-forward-sexp-safe 1)
1240 (should (looking-at "$"))
1241 (python-nav-lisp-forward-sexp-safe 1)
1242 (should (looking-at ".notify()"))))
1243
1244 (ert-deftest python-nav-forward-sexp-1 ()
1245 (python-tests-with-temp-buffer
1246 "
1247 a()
1248 b()
1249 c()
1250 "
1251 (python-tests-look-at "a()")
1252 (python-nav-forward-sexp)
1253 (should (looking-at "$"))
1254 (should (save-excursion
1255 (beginning-of-line)
1256 (looking-at "a()")))
1257 (python-nav-forward-sexp)
1258 (should (looking-at "$"))
1259 (should (save-excursion
1260 (beginning-of-line)
1261 (looking-at "b()")))
1262 (python-nav-forward-sexp)
1263 (should (looking-at "$"))
1264 (should (save-excursion
1265 (beginning-of-line)
1266 (looking-at "c()")))
1267 ;; Movement next to a paren should do what lisp does and
1268 ;; unfortunately It can't change, because otherwise
1269 ;; `blink-matching-open' breaks.
1270 (python-nav-forward-sexp -1)
1271 (should (looking-at "()"))
1272 (should (save-excursion
1273 (beginning-of-line)
1274 (looking-at "c()")))
1275 (python-nav-forward-sexp -1)
1276 (should (looking-at "c()"))
1277 (python-nav-forward-sexp -1)
1278 (should (looking-at "b()"))
1279 (python-nav-forward-sexp -1)
1280 (should (looking-at "a()"))))
1281
1282 (ert-deftest python-nav-forward-sexp-2 ()
1283 (python-tests-with-temp-buffer
1284 "
1285 def func():
1286 if True:
1287 aaa = bbb
1288 ccc = ddd
1289 eee = fff
1290 return ggg
1291 "
1292 (python-tests-look-at "aa =")
1293 (python-nav-forward-sexp)
1294 (should (looking-at " = bbb"))
1295 (python-nav-forward-sexp)
1296 (should (looking-at "$"))
1297 (should (save-excursion
1298 (back-to-indentation)
1299 (looking-at "aaa = bbb")))
1300 (python-nav-forward-sexp)
1301 (should (looking-at "$"))
1302 (should (save-excursion
1303 (back-to-indentation)
1304 (looking-at "ccc = ddd")))
1305 (python-nav-forward-sexp)
1306 (should (looking-at "$"))
1307 (should (save-excursion
1308 (back-to-indentation)
1309 (looking-at "eee = fff")))
1310 (python-nav-forward-sexp)
1311 (should (looking-at "$"))
1312 (should (save-excursion
1313 (back-to-indentation)
1314 (looking-at "return ggg")))
1315 (python-nav-forward-sexp -1)
1316 (should (looking-at "def func():"))))
1317
1318 (ert-deftest python-nav-forward-sexp-3 ()
1319 (python-tests-with-temp-buffer
1320 "
1321 from some_module import some_sub_module
1322 from another_module import another_sub_module
1323
1324 def another_statement():
1325 pass
1326 "
1327 (python-tests-look-at "some_module")
1328 (python-nav-forward-sexp)
1329 (should (looking-at " import"))
1330 (python-nav-forward-sexp)
1331 (should (looking-at " some_sub_module"))
1332 (python-nav-forward-sexp)
1333 (should (looking-at "$"))
1334 (should
1335 (save-excursion
1336 (back-to-indentation)
1337 (looking-at
1338 "from some_module import some_sub_module")))
1339 (python-nav-forward-sexp)
1340 (should (looking-at "$"))
1341 (should
1342 (save-excursion
1343 (back-to-indentation)
1344 (looking-at
1345 "from another_module import another_sub_module")))
1346 (python-nav-forward-sexp)
1347 (should (looking-at "$"))
1348 (should
1349 (save-excursion
1350 (back-to-indentation)
1351 (looking-at
1352 "pass")))
1353 (python-nav-forward-sexp -1)
1354 (should (looking-at "def another_statement():"))
1355 (python-nav-forward-sexp -1)
1356 (should (looking-at "from another_module import another_sub_module"))
1357 (python-nav-forward-sexp -1)
1358 (should (looking-at "from some_module import some_sub_module"))))
1359
1360 (ert-deftest python-nav-up-list-1 ()
1361 (python-tests-with-temp-buffer
1362 "
1363 def f():
1364 if True:
1365 return [i for i in range(3)]
1366 "
1367 (python-tests-look-at "3)]")
1368 (python-nav-up-list)
1369 (should (looking-at "]"))
1370 (python-nav-up-list)
1371 (should (looking-at "$"))))
1372
1373 (ert-deftest python-nav-backward-up-list-1 ()
1374 :expected-result :failed
1375 (python-tests-with-temp-buffer
1376 "
1377 def f():
1378 if True:
1379 return [i for i in range(3)]
1380 "
1381 (python-tests-look-at "3)]")
1382 (python-nav-backward-up-list)
1383 (should (looking-at "(3)\\]"))
1384 (python-nav-backward-up-list)
1385 (should (looking-at
1386 "\\[i for i in range(3)\\]"))
1387 ;; FIXME: Need to move to beginning-of-statement.
1388 (python-nav-backward-up-list)
1389 (should (looking-at
1390 "return \\[i for i in range(3)\\]"))
1391 (python-nav-backward-up-list)
1392 (should (looking-at "if True:"))
1393 (python-nav-backward-up-list)
1394 (should (looking-at "def f():"))))
1395
1396 \f
1397 ;;; Shell integration
1398
1399 (defvar python-tests-shell-interpreter "python")
1400
1401 (ert-deftest python-shell-get-process-name-1 ()
1402 "Check process name calculation on different scenarios."
1403 (python-tests-with-temp-buffer
1404 ""
1405 (should (string= (python-shell-get-process-name nil)
1406 python-shell-buffer-name))
1407 ;; When the `current-buffer' doesn't have `buffer-file-name', even
1408 ;; if dedicated flag is non-nil should not include its name.
1409 (should (string= (python-shell-get-process-name t)
1410 python-shell-buffer-name)))
1411 (python-tests-with-temp-file
1412 ""
1413 ;; `buffer-file-name' is non-nil but the dedicated flag is nil and
1414 ;; should be respected.
1415 (should (string= (python-shell-get-process-name nil)
1416 python-shell-buffer-name))
1417 (should (string=
1418 (python-shell-get-process-name t)
1419 (format "%s[%s]" python-shell-buffer-name buffer-file-name)))))
1420
1421 (ert-deftest python-shell-internal-get-process-name-1 ()
1422 "Check the internal process name is config-unique."
1423 (let* ((python-shell-interpreter python-tests-shell-interpreter)
1424 (python-shell-interpreter-args "")
1425 (python-shell-prompt-regexp ">>> ")
1426 (python-shell-prompt-block-regexp "[.][.][.] ")
1427 (python-shell-setup-codes "")
1428 (python-shell-process-environment "")
1429 (python-shell-extra-pythonpaths "")
1430 (python-shell-exec-path "")
1431 (python-shell-virtualenv-path "")
1432 (expected (python-tests-with-temp-buffer
1433 "" (python-shell-internal-get-process-name))))
1434 ;; Same configurations should match.
1435 (should
1436 (string= expected
1437 (python-tests-with-temp-buffer
1438 "" (python-shell-internal-get-process-name))))
1439 (let ((python-shell-interpreter-args "-B"))
1440 ;; A minimal change should generate different names.
1441 (should
1442 (not (string=
1443 expected
1444 (python-tests-with-temp-buffer
1445 "" (python-shell-internal-get-process-name))))))))
1446
1447 (ert-deftest python-shell-parse-command-1 ()
1448 "Check the command to execute is calculated correctly.
1449 Using `python-shell-interpreter' and
1450 `python-shell-interpreter-args'."
1451 (skip-unless (executable-find python-tests-shell-interpreter))
1452 (let ((python-shell-interpreter (executable-find
1453 python-tests-shell-interpreter))
1454 (python-shell-interpreter-args "-B"))
1455 (should (string=
1456 (format "%s %s"
1457 python-shell-interpreter
1458 python-shell-interpreter-args)
1459 (python-shell-parse-command)))))
1460
1461 (ert-deftest python-shell-calculate-process-environment-1 ()
1462 "Test `python-shell-process-environment' modification."
1463 (let* ((original-process-environment process-environment)
1464 (python-shell-process-environment
1465 '("TESTVAR1=value1" "TESTVAR2=value2"))
1466 (process-environment
1467 (python-shell-calculate-process-environment)))
1468 (should (equal (getenv "TESTVAR1") "value1"))
1469 (should (equal (getenv "TESTVAR2") "value2"))))
1470
1471 (ert-deftest python-shell-calculate-process-environment-2 ()
1472 "Test `python-shell-extra-pythonpaths' modification."
1473 (let* ((original-process-environment process-environment)
1474 (original-pythonpath (getenv "PYTHONPATH"))
1475 (paths '("path1" "path2"))
1476 (python-shell-extra-pythonpaths paths)
1477 (process-environment
1478 (python-shell-calculate-process-environment)))
1479 (should (equal (getenv "PYTHONPATH")
1480 (concat
1481 (mapconcat 'identity paths path-separator)
1482 path-separator original-pythonpath)))))
1483
1484 (ert-deftest python-shell-calculate-process-environment-3 ()
1485 "Test `python-shell-virtualenv-path' modification."
1486 (let* ((original-process-environment process-environment)
1487 (original-path (or (getenv "PATH") ""))
1488 (python-shell-virtualenv-path
1489 (directory-file-name user-emacs-directory))
1490 (process-environment
1491 (python-shell-calculate-process-environment)))
1492 (should (not (getenv "PYTHONHOME")))
1493 (should (string= (getenv "VIRTUAL_ENV") python-shell-virtualenv-path))
1494 (should (equal (getenv "PATH")
1495 (format "%s/bin%s%s"
1496 python-shell-virtualenv-path
1497 path-separator original-path)))))
1498
1499 (ert-deftest python-shell-calculate-exec-path-1 ()
1500 "Test `python-shell-exec-path' modification."
1501 (let* ((original-exec-path exec-path)
1502 (python-shell-exec-path '("path1" "path2"))
1503 (exec-path (python-shell-calculate-exec-path)))
1504 (should (equal
1505 exec-path
1506 (append python-shell-exec-path
1507 original-exec-path)))))
1508
1509 (ert-deftest python-shell-calculate-exec-path-2 ()
1510 "Test `python-shell-exec-path' modification."
1511 (let* ((original-exec-path exec-path)
1512 (python-shell-virtualenv-path
1513 (directory-file-name user-emacs-directory))
1514 (exec-path (python-shell-calculate-exec-path)))
1515 (should (equal
1516 exec-path
1517 (append (cons
1518 (format "%s/bin" python-shell-virtualenv-path)
1519 original-exec-path))))))
1520
1521 (ert-deftest python-shell-make-comint-1 ()
1522 "Check comint creation for global shell buffer."
1523 (skip-unless (executable-find python-tests-shell-interpreter))
1524 ;; The interpreter can get killed too quickly to allow it to clean
1525 ;; up the tempfiles that the default python-shell-setup-codes create,
1526 ;; so it leaves tempfiles behind, which is a minor irritation.
1527 (let* ((python-shell-setup-codes nil)
1528 (python-shell-interpreter
1529 (executable-find python-tests-shell-interpreter))
1530 (proc-name (python-shell-get-process-name nil))
1531 (shell-buffer
1532 (python-tests-with-temp-buffer
1533 "" (python-shell-make-comint
1534 (python-shell-parse-command) proc-name)))
1535 (process (get-buffer-process shell-buffer)))
1536 (unwind-protect
1537 (progn
1538 (set-process-query-on-exit-flag process nil)
1539 (should (process-live-p process))
1540 (with-current-buffer shell-buffer
1541 (should (eq major-mode 'inferior-python-mode))
1542 (should (string= (buffer-name) (format "*%s*" proc-name)))))
1543 (kill-buffer shell-buffer))))
1544
1545 (ert-deftest python-shell-make-comint-2 ()
1546 "Check comint creation for internal shell buffer."
1547 (skip-unless (executable-find python-tests-shell-interpreter))
1548 (let* ((python-shell-setup-codes nil)
1549 (python-shell-interpreter
1550 (executable-find python-tests-shell-interpreter))
1551 (proc-name (python-shell-internal-get-process-name))
1552 (shell-buffer
1553 (python-tests-with-temp-buffer
1554 "" (python-shell-make-comint
1555 (python-shell-parse-command) proc-name nil t)))
1556 (process (get-buffer-process shell-buffer)))
1557 (unwind-protect
1558 (progn
1559 (set-process-query-on-exit-flag process nil)
1560 (should (process-live-p process))
1561 (with-current-buffer shell-buffer
1562 (should (eq major-mode 'inferior-python-mode))
1563 (should (string= (buffer-name) (format " *%s*" proc-name)))))
1564 (kill-buffer shell-buffer))))
1565
1566 (ert-deftest python-shell-get-process-1 ()
1567 "Check dedicated shell process preference over global."
1568 (skip-unless (executable-find python-tests-shell-interpreter))
1569 (python-tests-with-temp-file
1570 ""
1571 (let* ((python-shell-setup-codes nil)
1572 (python-shell-interpreter
1573 (executable-find python-tests-shell-interpreter))
1574 (global-proc-name (python-shell-get-process-name nil))
1575 (dedicated-proc-name (python-shell-get-process-name t))
1576 (global-shell-buffer
1577 (python-shell-make-comint
1578 (python-shell-parse-command) global-proc-name))
1579 (dedicated-shell-buffer
1580 (python-shell-make-comint
1581 (python-shell-parse-command) dedicated-proc-name))
1582 (global-process (get-buffer-process global-shell-buffer))
1583 (dedicated-process (get-buffer-process dedicated-shell-buffer)))
1584 (unwind-protect
1585 (progn
1586 (set-process-query-on-exit-flag global-process nil)
1587 (set-process-query-on-exit-flag dedicated-process nil)
1588 ;; Prefer dedicated if global also exists.
1589 (should (equal (python-shell-get-process) dedicated-process))
1590 (kill-buffer dedicated-shell-buffer)
1591 ;; If there's only global, use it.
1592 (should (equal (python-shell-get-process) global-process))
1593 (kill-buffer global-shell-buffer)
1594 ;; No buffer available.
1595 (should (not (python-shell-get-process))))
1596 (ignore-errors (kill-buffer global-shell-buffer))
1597 (ignore-errors (kill-buffer dedicated-shell-buffer))))))
1598
1599 (ert-deftest python-shell-get-or-create-process-1 ()
1600 "Check shell process creation fallback."
1601 :expected-result :failed
1602 (python-tests-with-temp-file
1603 ""
1604 ;; XXX: Break early until we can skip stuff. We need to mimic
1605 ;; user interaction because `python-shell-get-or-create-process'
1606 ;; asks for all arguments interactively when a shell process
1607 ;; doesn't exist.
1608 (should nil)
1609 (let* ((python-shell-interpreter
1610 (executable-find python-tests-shell-interpreter))
1611 (use-dialog-box)
1612 (dedicated-process-name (python-shell-get-process-name t))
1613 (dedicated-process (python-shell-get-or-create-process))
1614 (dedicated-shell-buffer (process-buffer dedicated-process)))
1615 (unwind-protect
1616 (progn
1617 (set-process-query-on-exit-flag dedicated-process nil)
1618 ;; Prefer dedicated if not buffer exist.
1619 (should (equal (process-name dedicated-process)
1620 dedicated-process-name))
1621 (kill-buffer dedicated-shell-buffer)
1622 ;; No buffer available.
1623 (should (not (python-shell-get-process))))
1624 (ignore-errors (kill-buffer dedicated-shell-buffer))))))
1625
1626 (ert-deftest python-shell-internal-get-or-create-process-1 ()
1627 "Check internal shell process creation fallback."
1628 (skip-unless (executable-find python-tests-shell-interpreter))
1629 (python-tests-with-temp-file
1630 ""
1631 (should (not (process-live-p (python-shell-internal-get-process-name))))
1632 (let* ((python-shell-interpreter
1633 (executable-find python-tests-shell-interpreter))
1634 (internal-process-name (python-shell-internal-get-process-name))
1635 (internal-process (python-shell-internal-get-or-create-process))
1636 (internal-shell-buffer (process-buffer internal-process)))
1637 (unwind-protect
1638 (progn
1639 (set-process-query-on-exit-flag internal-process nil)
1640 (should (equal (process-name internal-process)
1641 internal-process-name))
1642 (should (equal internal-process
1643 (python-shell-internal-get-or-create-process)))
1644 ;; No user buffer available.
1645 (should (not (python-shell-get-process)))
1646 (kill-buffer internal-shell-buffer))
1647 (ignore-errors (kill-buffer internal-shell-buffer))))))
1648
1649 \f
1650 ;;; Shell completion
1651
1652 \f
1653 ;;; PDB Track integration
1654
1655 \f
1656 ;;; Symbol completion
1657
1658 \f
1659 ;;; Fill paragraph
1660
1661 \f
1662 ;;; Skeletons
1663
1664 \f
1665 ;;; FFAP
1666
1667 \f
1668 ;;; Code check
1669
1670 \f
1671 ;;; Eldoc
1672
1673 \f
1674 ;;; Imenu
1675
1676 (ert-deftest python-imenu-create-index-1 ()
1677 (python-tests-with-temp-buffer
1678 "
1679 class Foo(models.Model):
1680 pass
1681
1682
1683 class Bar(models.Model):
1684 pass
1685
1686
1687 def decorator(arg1, arg2, arg3):
1688 '''print decorated function call data to stdout.
1689
1690 Usage:
1691
1692 @decorator('arg1', 'arg2')
1693 def func(a, b, c=True):
1694 pass
1695 '''
1696
1697 def wrap(f):
1698 print ('wrap')
1699 def wrapped_f(*args):
1700 print ('wrapped_f')
1701 print ('Decorator arguments:', arg1, arg2, arg3)
1702 f(*args)
1703 print ('called f(*args)')
1704 return wrapped_f
1705 return wrap
1706
1707
1708 class Baz(object):
1709
1710 def a(self):
1711 pass
1712
1713 def b(self):
1714 pass
1715
1716 class Frob(object):
1717
1718 def c(self):
1719 pass
1720 "
1721 (goto-char (point-max))
1722 (should (equal
1723 (list
1724 (cons "Foo (class)" (copy-marker 2))
1725 (cons "Bar (class)" (copy-marker 38))
1726 (list
1727 "decorator (def)"
1728 (cons "*function definition*" (copy-marker 74))
1729 (list
1730 "wrap (def)"
1731 (cons "*function definition*" (copy-marker 254))
1732 (cons "wrapped_f (def)" (copy-marker 294))))
1733 (list
1734 "Baz (class)"
1735 (cons "*class definition*" (copy-marker 519))
1736 (cons "a (def)" (copy-marker 539))
1737 (cons "b (def)" (copy-marker 570))
1738 (list
1739 "Frob (class)"
1740 (cons "*class definition*" (copy-marker 601))
1741 (cons "c (def)" (copy-marker 626)))))
1742 (python-imenu-create-index)))))
1743
1744 (ert-deftest python-imenu-create-index-2 ()
1745 (python-tests-with-temp-buffer
1746 "
1747 class Foo(object):
1748 def foo(self):
1749 def foo1():
1750 pass
1751
1752 def foobar(self):
1753 pass
1754 "
1755 (goto-char (point-max))
1756 (should (equal
1757 (list
1758 (list
1759 "Foo (class)"
1760 (cons "*class definition*" (copy-marker 2))
1761 (list
1762 "foo (def)"
1763 (cons "*function definition*" (copy-marker 21))
1764 (cons "foo1 (def)" (copy-marker 40)))
1765 (cons "foobar (def)" (copy-marker 78))))
1766 (python-imenu-create-index)))))
1767
1768 (ert-deftest python-imenu-create-index-3 ()
1769 (python-tests-with-temp-buffer
1770 "
1771 class Foo(object):
1772 def foo(self):
1773 def foo1():
1774 pass
1775 def foo2():
1776 pass
1777 "
1778 (goto-char (point-max))
1779 (should (equal
1780 (list
1781 (list
1782 "Foo (class)"
1783 (cons "*class definition*" (copy-marker 2))
1784 (list
1785 "foo (def)"
1786 (cons "*function definition*" (copy-marker 21))
1787 (cons "foo1 (def)" (copy-marker 40))
1788 (cons "foo2 (def)" (copy-marker 77)))))
1789 (python-imenu-create-index)))))
1790
1791 (ert-deftest python-imenu-create-index-4 ()
1792 (python-tests-with-temp-buffer
1793 "
1794 class Foo(object):
1795 class Bar(object):
1796 def __init__(self):
1797 pass
1798
1799 def __str__(self):
1800 pass
1801
1802 def __init__(self):
1803 pass
1804 "
1805 (goto-char (point-max))
1806 (should (equal
1807 (list
1808 (list
1809 "Foo (class)"
1810 (cons "*class definition*" (copy-marker 2))
1811 (list
1812 "Bar (class)"
1813 (cons "*class definition*" (copy-marker 21))
1814 (cons "__init__ (def)" (copy-marker 44))
1815 (cons "__str__ (def)" (copy-marker 90)))
1816 (cons "__init__ (def)" (copy-marker 135))))
1817 (python-imenu-create-index)))))
1818
1819 (ert-deftest python-imenu-create-flat-index-1 ()
1820 (python-tests-with-temp-buffer
1821 "
1822 class Foo(models.Model):
1823 pass
1824
1825
1826 class Bar(models.Model):
1827 pass
1828
1829
1830 def decorator(arg1, arg2, arg3):
1831 '''print decorated function call data to stdout.
1832
1833 Usage:
1834
1835 @decorator('arg1', 'arg2')
1836 def func(a, b, c=True):
1837 pass
1838 '''
1839
1840 def wrap(f):
1841 print ('wrap')
1842 def wrapped_f(*args):
1843 print ('wrapped_f')
1844 print ('Decorator arguments:', arg1, arg2, arg3)
1845 f(*args)
1846 print ('called f(*args)')
1847 return wrapped_f
1848 return wrap
1849
1850
1851 class Baz(object):
1852
1853 def a(self):
1854 pass
1855
1856 def b(self):
1857 pass
1858
1859 class Frob(object):
1860
1861 def c(self):
1862 pass
1863 "
1864 (goto-char (point-max))
1865 (should (equal
1866 (list (cons "Foo" (copy-marker 2))
1867 (cons "Bar" (copy-marker 38))
1868 (cons "decorator" (copy-marker 74))
1869 (cons "decorator.wrap" (copy-marker 254))
1870 (cons "decorator.wrap.wrapped_f" (copy-marker 294))
1871 (cons "Baz" (copy-marker 519))
1872 (cons "Baz.a" (copy-marker 539))
1873 (cons "Baz.b" (copy-marker 570))
1874 (cons "Baz.Frob" (copy-marker 601))
1875 (cons "Baz.Frob.c" (copy-marker 626)))
1876 (python-imenu-create-flat-index)))))
1877
1878 (ert-deftest python-imenu-create-flat-index-2 ()
1879 (python-tests-with-temp-buffer
1880 "
1881 class Foo(object):
1882 class Bar(object):
1883 def __init__(self):
1884 pass
1885
1886 def __str__(self):
1887 pass
1888
1889 def __init__(self):
1890 pass
1891 "
1892 (goto-char (point-max))
1893 (should (equal
1894 (list
1895 (cons "Foo" (copy-marker 2))
1896 (cons "Foo.Bar" (copy-marker 21))
1897 (cons "Foo.Bar.__init__" (copy-marker 44))
1898 (cons "Foo.Bar.__str__" (copy-marker 90))
1899 (cons "Foo.__init__" (copy-marker 135)))
1900 (python-imenu-create-flat-index)))))
1901
1902 \f
1903 ;;; Misc helpers
1904
1905 (ert-deftest python-info-current-defun-1 ()
1906 (python-tests-with-temp-buffer
1907 "
1908 def foo(a, b):
1909 "
1910 (forward-line 1)
1911 (should (string= "foo" (python-info-current-defun)))
1912 (should (string= "def foo" (python-info-current-defun t)))
1913 (forward-line 1)
1914 (should (not (python-info-current-defun)))
1915 (indent-for-tab-command)
1916 (should (string= "foo" (python-info-current-defun)))
1917 (should (string= "def foo" (python-info-current-defun t)))))
1918
1919 (ert-deftest python-info-current-defun-2 ()
1920 (python-tests-with-temp-buffer
1921 "
1922 class C(object):
1923
1924 def m(self):
1925 if True:
1926 return [i for i in range(3)]
1927 else:
1928 return []
1929
1930 def b():
1931 do_b()
1932
1933 def a():
1934 do_a()
1935
1936 def c(self):
1937 do_c()
1938 "
1939 (forward-line 1)
1940 (should (string= "C" (python-info-current-defun)))
1941 (should (string= "class C" (python-info-current-defun t)))
1942 (python-tests-look-at "return [i for ")
1943 (should (string= "C.m" (python-info-current-defun)))
1944 (should (string= "def C.m" (python-info-current-defun t)))
1945 (python-tests-look-at "def b():")
1946 (should (string= "C.m.b" (python-info-current-defun)))
1947 (should (string= "def C.m.b" (python-info-current-defun t)))
1948 (forward-line 2)
1949 (indent-for-tab-command)
1950 (python-indent-dedent-line-backspace 1)
1951 (should (string= "C.m" (python-info-current-defun)))
1952 (should (string= "def C.m" (python-info-current-defun t)))
1953 (python-tests-look-at "def c(self):")
1954 (forward-line -1)
1955 (indent-for-tab-command)
1956 (should (string= "C.m.a" (python-info-current-defun)))
1957 (should (string= "def C.m.a" (python-info-current-defun t)))
1958 (python-indent-dedent-line-backspace 1)
1959 (should (string= "C.m" (python-info-current-defun)))
1960 (should (string= "def C.m" (python-info-current-defun t)))
1961 (python-indent-dedent-line-backspace 1)
1962 (should (string= "C" (python-info-current-defun)))
1963 (should (string= "class C" (python-info-current-defun t)))
1964 (python-tests-look-at "def c(self):")
1965 (should (string= "C.c" (python-info-current-defun)))
1966 (should (string= "def C.c" (python-info-current-defun t)))
1967 (python-tests-look-at "do_c()")
1968 (should (string= "C.c" (python-info-current-defun)))
1969 (should (string= "def C.c" (python-info-current-defun t)))))
1970
1971 (ert-deftest python-info-current-defun-3 ()
1972 (python-tests-with-temp-buffer
1973 "
1974 def decoratorFunctionWithArguments(arg1, arg2, arg3):
1975 '''print decorated function call data to stdout.
1976
1977 Usage:
1978
1979 @decoratorFunctionWithArguments('arg1', 'arg2')
1980 def func(a, b, c=True):
1981 pass
1982 '''
1983
1984 def wwrap(f):
1985 print 'Inside wwrap()'
1986 def wrapped_f(*args):
1987 print 'Inside wrapped_f()'
1988 print 'Decorator arguments:', arg1, arg2, arg3
1989 f(*args)
1990 print 'After f(*args)'
1991 return wrapped_f
1992 return wwrap
1993 "
1994 (python-tests-look-at "def wwrap(f):")
1995 (forward-line -1)
1996 (should (not (python-info-current-defun)))
1997 (indent-for-tab-command 1)
1998 (should (string= (python-info-current-defun)
1999 "decoratorFunctionWithArguments"))
2000 (should (string= (python-info-current-defun t)
2001 "def decoratorFunctionWithArguments"))
2002 (python-tests-look-at "def wrapped_f(*args):")
2003 (should (string= (python-info-current-defun)
2004 "decoratorFunctionWithArguments.wwrap.wrapped_f"))
2005 (should (string= (python-info-current-defun t)
2006 "def decoratorFunctionWithArguments.wwrap.wrapped_f"))
2007 (python-tests-look-at "return wrapped_f")
2008 (should (string= (python-info-current-defun)
2009 "decoratorFunctionWithArguments.wwrap"))
2010 (should (string= (python-info-current-defun t)
2011 "def decoratorFunctionWithArguments.wwrap"))
2012 (end-of-line 1)
2013 (python-tests-look-at "return wwrap")
2014 (should (string= (python-info-current-defun)
2015 "decoratorFunctionWithArguments"))
2016 (should (string= (python-info-current-defun t)
2017 "def decoratorFunctionWithArguments"))))
2018
2019 (ert-deftest python-info-current-symbol-1 ()
2020 (python-tests-with-temp-buffer
2021 "
2022 class C(object):
2023
2024 def m(self):
2025 self.c()
2026
2027 def c(self):
2028 print ('a')
2029 "
2030 (python-tests-look-at "self.c()")
2031 (should (string= "self.c" (python-info-current-symbol)))
2032 (should (string= "C.c" (python-info-current-symbol t)))))
2033
2034 (ert-deftest python-info-current-symbol-2 ()
2035 (python-tests-with-temp-buffer
2036 "
2037 class C(object):
2038
2039 class M(object):
2040
2041 def a(self):
2042 self.c()
2043
2044 def c(self):
2045 pass
2046 "
2047 (python-tests-look-at "self.c()")
2048 (should (string= "self.c" (python-info-current-symbol)))
2049 (should (string= "C.M.c" (python-info-current-symbol t)))))
2050
2051 (ert-deftest python-info-current-symbol-3 ()
2052 "Keywords should not be considered symbols."
2053 :expected-result :failed
2054 (python-tests-with-temp-buffer
2055 "
2056 class C(object):
2057 pass
2058 "
2059 ;; FIXME: keywords are not symbols.
2060 (python-tests-look-at "class C")
2061 (should (not (python-info-current-symbol)))
2062 (should (not (python-info-current-symbol t)))
2063 (python-tests-look-at "C(object)")
2064 (should (string= "C" (python-info-current-symbol)))
2065 (should (string= "class C" (python-info-current-symbol t)))))
2066
2067 (ert-deftest python-info-statement-starts-block-p-1 ()
2068 (python-tests-with-temp-buffer
2069 "
2070 def long_function_name(
2071 var_one, var_two, var_three,
2072 var_four):
2073 print (var_one)
2074 "
2075 (python-tests-look-at "def long_function_name")
2076 (should (python-info-statement-starts-block-p))
2077 (python-tests-look-at "print (var_one)")
2078 (python-util-forward-comment -1)
2079 (should (python-info-statement-starts-block-p))))
2080
2081 (ert-deftest python-info-statement-starts-block-p-2 ()
2082 (python-tests-with-temp-buffer
2083 "
2084 if width == 0 and height == 0 and \\\\
2085 color == 'red' and emphasis == 'strong' or \\\\
2086 highlight > 100:
2087 raise ValueError('sorry, you lose')
2088 "
2089 (python-tests-look-at "if width == 0 and")
2090 (should (python-info-statement-starts-block-p))
2091 (python-tests-look-at "raise ValueError(")
2092 (python-util-forward-comment -1)
2093 (should (python-info-statement-starts-block-p))))
2094
2095 (ert-deftest python-info-statement-ends-block-p-1 ()
2096 (python-tests-with-temp-buffer
2097 "
2098 def long_function_name(
2099 var_one, var_two, var_three,
2100 var_four):
2101 print (var_one)
2102 "
2103 (python-tests-look-at "print (var_one)")
2104 (should (python-info-statement-ends-block-p))))
2105
2106 (ert-deftest python-info-statement-ends-block-p-2 ()
2107 (python-tests-with-temp-buffer
2108 "
2109 if width == 0 and height == 0 and \\\\
2110 color == 'red' and emphasis == 'strong' or \\\\
2111 highlight > 100:
2112 raise ValueError(
2113 'sorry, you lose'
2114
2115 )
2116 "
2117 (python-tests-look-at "raise ValueError(")
2118 (should (python-info-statement-ends-block-p))))
2119
2120 (ert-deftest python-info-beginning-of-statement-p-1 ()
2121 (python-tests-with-temp-buffer
2122 "
2123 def long_function_name(
2124 var_one, var_two, var_three,
2125 var_four):
2126 print (var_one)
2127 "
2128 (python-tests-look-at "def long_function_name")
2129 (should (python-info-beginning-of-statement-p))
2130 (forward-char 10)
2131 (should (not (python-info-beginning-of-statement-p)))
2132 (python-tests-look-at "print (var_one)")
2133 (should (python-info-beginning-of-statement-p))
2134 (goto-char (line-beginning-position))
2135 (should (not (python-info-beginning-of-statement-p)))))
2136
2137 (ert-deftest python-info-beginning-of-statement-p-2 ()
2138 (python-tests-with-temp-buffer
2139 "
2140 if width == 0 and height == 0 and \\\\
2141 color == 'red' and emphasis == 'strong' or \\\\
2142 highlight > 100:
2143 raise ValueError(
2144 'sorry, you lose'
2145
2146 )
2147 "
2148 (python-tests-look-at "if width == 0 and")
2149 (should (python-info-beginning-of-statement-p))
2150 (forward-char 10)
2151 (should (not (python-info-beginning-of-statement-p)))
2152 (python-tests-look-at "raise ValueError(")
2153 (should (python-info-beginning-of-statement-p))
2154 (goto-char (line-beginning-position))
2155 (should (not (python-info-beginning-of-statement-p)))))
2156
2157 (ert-deftest python-info-end-of-statement-p-1 ()
2158 (python-tests-with-temp-buffer
2159 "
2160 def long_function_name(
2161 var_one, var_two, var_three,
2162 var_four):
2163 print (var_one)
2164 "
2165 (python-tests-look-at "def long_function_name")
2166 (should (not (python-info-end-of-statement-p)))
2167 (end-of-line)
2168 (should (not (python-info-end-of-statement-p)))
2169 (python-tests-look-at "print (var_one)")
2170 (python-util-forward-comment -1)
2171 (should (python-info-end-of-statement-p))
2172 (python-tests-look-at "print (var_one)")
2173 (should (not (python-info-end-of-statement-p)))
2174 (end-of-line)
2175 (should (python-info-end-of-statement-p))))
2176
2177 (ert-deftest python-info-end-of-statement-p-2 ()
2178 (python-tests-with-temp-buffer
2179 "
2180 if width == 0 and height == 0 and \\\\
2181 color == 'red' and emphasis == 'strong' or \\\\
2182 highlight > 100:
2183 raise ValueError(
2184 'sorry, you lose'
2185
2186 )
2187 "
2188 (python-tests-look-at "if width == 0 and")
2189 (should (not (python-info-end-of-statement-p)))
2190 (end-of-line)
2191 (should (not (python-info-end-of-statement-p)))
2192 (python-tests-look-at "raise ValueError(")
2193 (python-util-forward-comment -1)
2194 (should (python-info-end-of-statement-p))
2195 (python-tests-look-at "raise ValueError(")
2196 (should (not (python-info-end-of-statement-p)))
2197 (end-of-line)
2198 (should (not (python-info-end-of-statement-p)))
2199 (goto-char (point-max))
2200 (python-util-forward-comment -1)
2201 (should (python-info-end-of-statement-p))))
2202
2203 (ert-deftest python-info-beginning-of-block-p-1 ()
2204 (python-tests-with-temp-buffer
2205 "
2206 def long_function_name(
2207 var_one, var_two, var_three,
2208 var_four):
2209 print (var_one)
2210 "
2211 (python-tests-look-at "def long_function_name")
2212 (should (python-info-beginning-of-block-p))
2213 (python-tests-look-at "var_one, var_two, var_three,")
2214 (should (not (python-info-beginning-of-block-p)))
2215 (python-tests-look-at "print (var_one)")
2216 (should (not (python-info-beginning-of-block-p)))))
2217
2218 (ert-deftest python-info-beginning-of-block-p-2 ()
2219 (python-tests-with-temp-buffer
2220 "
2221 if width == 0 and height == 0 and \\\\
2222 color == 'red' and emphasis == 'strong' or \\\\
2223 highlight > 100:
2224 raise ValueError(
2225 'sorry, you lose'
2226
2227 )
2228 "
2229 (python-tests-look-at "if width == 0 and")
2230 (should (python-info-beginning-of-block-p))
2231 (python-tests-look-at "color == 'red' and emphasis")
2232 (should (not (python-info-beginning-of-block-p)))
2233 (python-tests-look-at "raise ValueError(")
2234 (should (not (python-info-beginning-of-block-p)))))
2235
2236 (ert-deftest python-info-end-of-block-p-1 ()
2237 (python-tests-with-temp-buffer
2238 "
2239 def long_function_name(
2240 var_one, var_two, var_three,
2241 var_four):
2242 print (var_one)
2243 "
2244 (python-tests-look-at "def long_function_name")
2245 (should (not (python-info-end-of-block-p)))
2246 (python-tests-look-at "var_one, var_two, var_three,")
2247 (should (not (python-info-end-of-block-p)))
2248 (python-tests-look-at "var_four):")
2249 (end-of-line)
2250 (should (not (python-info-end-of-block-p)))
2251 (python-tests-look-at "print (var_one)")
2252 (should (not (python-info-end-of-block-p)))
2253 (end-of-line 1)
2254 (should (python-info-end-of-block-p))))
2255
2256 (ert-deftest python-info-end-of-block-p-2 ()
2257 (python-tests-with-temp-buffer
2258 "
2259 if width == 0 and height == 0 and \\\\
2260 color == 'red' and emphasis == 'strong' or \\\\
2261 highlight > 100:
2262 raise ValueError(
2263 'sorry, you lose'
2264
2265 )
2266 "
2267 (python-tests-look-at "if width == 0 and")
2268 (should (not (python-info-end-of-block-p)))
2269 (python-tests-look-at "color == 'red' and emphasis == 'strong' or")
2270 (should (not (python-info-end-of-block-p)))
2271 (python-tests-look-at "highlight > 100:")
2272 (end-of-line)
2273 (should (not (python-info-end-of-block-p)))
2274 (python-tests-look-at "raise ValueError(")
2275 (should (not (python-info-end-of-block-p)))
2276 (end-of-line 1)
2277 (should (not (python-info-end-of-block-p)))
2278 (goto-char (point-max))
2279 (python-util-forward-comment -1)
2280 (should (python-info-end-of-block-p))))
2281
2282 (ert-deftest python-info-closing-block-1 ()
2283 (python-tests-with-temp-buffer
2284 "
2285 if request.user.is_authenticated():
2286 try:
2287 profile = request.user.get_profile()
2288 except Profile.DoesNotExist:
2289 profile = Profile.objects.create(user=request.user)
2290 else:
2291 if profile.stats:
2292 profile.recalculate_stats()
2293 else:
2294 profile.clear_stats()
2295 finally:
2296 profile.views += 1
2297 profile.save()
2298 "
2299 (python-tests-look-at "try:")
2300 (should (not (python-info-closing-block)))
2301 (python-tests-look-at "except Profile.DoesNotExist:")
2302 (should (= (python-tests-look-at "try:" -1 t)
2303 (python-info-closing-block)))
2304 (python-tests-look-at "else:")
2305 (should (= (python-tests-look-at "except Profile.DoesNotExist:" -1 t)
2306 (python-info-closing-block)))
2307 (python-tests-look-at "if profile.stats:")
2308 (should (not (python-info-closing-block)))
2309 (python-tests-look-at "else:")
2310 (should (= (python-tests-look-at "if profile.stats:" -1 t)
2311 (python-info-closing-block)))
2312 (python-tests-look-at "finally:")
2313 (should (= (python-tests-look-at "else:" -2 t)
2314 (python-info-closing-block)))))
2315
2316 (ert-deftest python-info-closing-block-2 ()
2317 (python-tests-with-temp-buffer
2318 "
2319 if request.user.is_authenticated():
2320 profile = Profile.objects.get_or_create(user=request.user)
2321 if profile.stats:
2322 profile.recalculate_stats()
2323
2324 data = {
2325 'else': 'do it'
2326 }
2327 'else'
2328 "
2329 (python-tests-look-at "'else': 'do it'")
2330 (should (not (python-info-closing-block)))
2331 (python-tests-look-at "'else'")
2332 (should (not (python-info-closing-block)))))
2333
2334 (ert-deftest python-info-line-ends-backslash-p-1 ()
2335 (python-tests-with-temp-buffer
2336 "
2337 objects = Thing.objects.all() \\\\
2338 .filter(
2339 type='toy',
2340 status='bought'
2341 ) \\\\
2342 .aggregate(
2343 Sum('amount')
2344 ) \\\\
2345 .values_list()
2346 "
2347 (should (python-info-line-ends-backslash-p 2)) ; .filter(...
2348 (should (python-info-line-ends-backslash-p 3))
2349 (should (python-info-line-ends-backslash-p 4))
2350 (should (python-info-line-ends-backslash-p 5))
2351 (should (python-info-line-ends-backslash-p 6)) ; ) \...
2352 (should (python-info-line-ends-backslash-p 7))
2353 (should (python-info-line-ends-backslash-p 8))
2354 (should (python-info-line-ends-backslash-p 9))
2355 (should (not (python-info-line-ends-backslash-p 10))))) ; .values_list()...
2356
2357 (ert-deftest python-info-beginning-of-backslash-1 ()
2358 (python-tests-with-temp-buffer
2359 "
2360 objects = Thing.objects.all() \\\\
2361 .filter(
2362 type='toy',
2363 status='bought'
2364 ) \\\\
2365 .aggregate(
2366 Sum('amount')
2367 ) \\\\
2368 .values_list()
2369 "
2370 (let ((first 2)
2371 (second (python-tests-look-at ".filter("))
2372 (third (python-tests-look-at ".aggregate(")))
2373 (should (= first (python-info-beginning-of-backslash 2)))
2374 (should (= second (python-info-beginning-of-backslash 3)))
2375 (should (= second (python-info-beginning-of-backslash 4)))
2376 (should (= second (python-info-beginning-of-backslash 5)))
2377 (should (= second (python-info-beginning-of-backslash 6)))
2378 (should (= third (python-info-beginning-of-backslash 7)))
2379 (should (= third (python-info-beginning-of-backslash 8)))
2380 (should (= third (python-info-beginning-of-backslash 9)))
2381 (should (not (python-info-beginning-of-backslash 10))))))
2382
2383 (ert-deftest python-info-continuation-line-p-1 ()
2384 (python-tests-with-temp-buffer
2385 "
2386 if width == 0 and height == 0 and \\\\
2387 color == 'red' and emphasis == 'strong' or \\\\
2388 highlight > 100:
2389 raise ValueError(
2390 'sorry, you lose'
2391
2392 )
2393 "
2394 (python-tests-look-at "if width == 0 and height == 0 and")
2395 (should (not (python-info-continuation-line-p)))
2396 (python-tests-look-at "color == 'red' and emphasis == 'strong' or")
2397 (should (python-info-continuation-line-p))
2398 (python-tests-look-at "highlight > 100:")
2399 (should (python-info-continuation-line-p))
2400 (python-tests-look-at "raise ValueError(")
2401 (should (not (python-info-continuation-line-p)))
2402 (python-tests-look-at "'sorry, you lose'")
2403 (should (python-info-continuation-line-p))
2404 (forward-line 1)
2405 (should (python-info-continuation-line-p))
2406 (python-tests-look-at ")")
2407 (should (python-info-continuation-line-p))
2408 (forward-line 1)
2409 (should (not (python-info-continuation-line-p)))))
2410
2411 (ert-deftest python-info-block-continuation-line-p-1 ()
2412 (python-tests-with-temp-buffer
2413 "
2414 if width == 0 and height == 0 and \\\\
2415 color == 'red' and emphasis == 'strong' or \\\\
2416 highlight > 100:
2417 raise ValueError(
2418 'sorry, you lose'
2419
2420 )
2421 "
2422 (python-tests-look-at "if width == 0 and")
2423 (should (not (python-info-block-continuation-line-p)))
2424 (python-tests-look-at "color == 'red' and emphasis == 'strong' or")
2425 (should (= (python-info-block-continuation-line-p)
2426 (python-tests-look-at "if width == 0 and" -1 t)))
2427 (python-tests-look-at "highlight > 100:")
2428 (should (not (python-info-block-continuation-line-p)))))
2429
2430 (ert-deftest python-info-block-continuation-line-p-2 ()
2431 (python-tests-with-temp-buffer
2432 "
2433 def foo(a,
2434 b,
2435 c):
2436 pass
2437 "
2438 (python-tests-look-at "def foo(a,")
2439 (should (not (python-info-block-continuation-line-p)))
2440 (python-tests-look-at "b,")
2441 (should (= (python-info-block-continuation-line-p)
2442 (python-tests-look-at "def foo(a," -1 t)))
2443 (python-tests-look-at "c):")
2444 (should (not (python-info-block-continuation-line-p)))))
2445
2446 (ert-deftest python-info-assignment-continuation-line-p-1 ()
2447 (python-tests-with-temp-buffer
2448 "
2449 data = foo(), bar() \\\\
2450 baz(), 4 \\\\
2451 5, 6
2452 "
2453 (python-tests-look-at "data = foo(), bar()")
2454 (should (not (python-info-assignment-continuation-line-p)))
2455 (python-tests-look-at "baz(), 4")
2456 (should (= (python-info-assignment-continuation-line-p)
2457 (python-tests-look-at "foo()," -1 t)))
2458 (python-tests-look-at "5, 6")
2459 (should (not (python-info-assignment-continuation-line-p)))))
2460
2461 (ert-deftest python-info-assignment-continuation-line-p-2 ()
2462 (python-tests-with-temp-buffer
2463 "
2464 data = (foo(), bar()
2465 baz(), 4
2466 5, 6)
2467 "
2468 (python-tests-look-at "data = (foo(), bar()")
2469 (should (not (python-info-assignment-continuation-line-p)))
2470 (python-tests-look-at "baz(), 4")
2471 (should (= (python-info-assignment-continuation-line-p)
2472 (python-tests-look-at "(foo()," -1 t)))
2473 (python-tests-look-at "5, 6)")
2474 (should (not (python-info-assignment-continuation-line-p)))))
2475
2476 (ert-deftest python-info-looking-at-beginning-of-defun-1 ()
2477 (python-tests-with-temp-buffer
2478 "
2479 def decorat0r(deff):
2480 '''decorates stuff.
2481
2482 @decorat0r
2483 def foo(arg):
2484 ...
2485 '''
2486 def wrap():
2487 deff()
2488 return wwrap
2489 "
2490 (python-tests-look-at "def decorat0r(deff):")
2491 (should (python-info-looking-at-beginning-of-defun))
2492 (python-tests-look-at "def foo(arg):")
2493 (should (not (python-info-looking-at-beginning-of-defun)))
2494 (python-tests-look-at "def wrap():")
2495 (should (python-info-looking-at-beginning-of-defun))
2496 (python-tests-look-at "deff()")
2497 (should (not (python-info-looking-at-beginning-of-defun)))))
2498
2499 (ert-deftest python-info-current-line-comment-p-1 ()
2500 (python-tests-with-temp-buffer
2501 "
2502 # this is a comment
2503 foo = True # another comment
2504 '#this is a string'
2505 if foo:
2506 # more comments
2507 print ('bar') # print bar
2508 "
2509 (python-tests-look-at "# this is a comment")
2510 (should (python-info-current-line-comment-p))
2511 (python-tests-look-at "foo = True # another comment")
2512 (should (not (python-info-current-line-comment-p)))
2513 (python-tests-look-at "'#this is a string'")
2514 (should (not (python-info-current-line-comment-p)))
2515 (python-tests-look-at "# more comments")
2516 (should (python-info-current-line-comment-p))
2517 (python-tests-look-at "print ('bar') # print bar")
2518 (should (not (python-info-current-line-comment-p)))))
2519
2520 (ert-deftest python-info-current-line-empty-p ()
2521 (python-tests-with-temp-buffer
2522 "
2523 # this is a comment
2524
2525 foo = True # another comment
2526 "
2527 (should (python-info-current-line-empty-p))
2528 (python-tests-look-at "# this is a comment")
2529 (should (not (python-info-current-line-empty-p)))
2530 (forward-line 1)
2531 (should (python-info-current-line-empty-p))))
2532
2533 \f
2534 ;;; Utility functions
2535
2536 (ert-deftest python-util-goto-line-1 ()
2537 (python-tests-with-temp-buffer
2538 (concat
2539 "# a comment
2540 # another comment
2541 def foo(a, b, c):
2542 pass" (make-string 20 ?\n))
2543 (python-util-goto-line 10)
2544 (should (= (line-number-at-pos) 10))
2545 (python-util-goto-line 20)
2546 (should (= (line-number-at-pos) 20))))
2547
2548 (ert-deftest python-util-clone-local-variables-1 ()
2549 (let ((buffer (generate-new-buffer
2550 "python-util-clone-local-variables-1"))
2551 (varcons
2552 '((python-fill-docstring-style . django)
2553 (python-shell-interpreter . "python")
2554 (python-shell-interpreter-args . "manage.py shell")
2555 (python-shell-prompt-regexp . "In \\[[0-9]+\\]: ")
2556 (python-shell-prompt-output-regexp . "Out\\[[0-9]+\\]: ")
2557 (python-shell-extra-pythonpaths "/home/user/pylib/")
2558 (python-shell-completion-setup-code
2559 . "from IPython.core.completerlib import module_completion")
2560 (python-shell-completion-module-string-code
2561 . "';'.join(module_completion('''%s'''))\n")
2562 (python-shell-completion-string-code
2563 . "';'.join(get_ipython().Completer.all_completions('''%s'''))\n")
2564 (python-shell-virtualenv-path
2565 . "/home/user/.virtualenvs/project"))))
2566 (with-current-buffer buffer
2567 (kill-all-local-variables)
2568 (dolist (ccons varcons)
2569 (set (make-local-variable (car ccons)) (cdr ccons))))
2570 (python-tests-with-temp-buffer
2571 ""
2572 (python-util-clone-local-variables buffer)
2573 (dolist (ccons varcons)
2574 (should
2575 (equal (symbol-value (car ccons)) (cdr ccons)))))
2576 (kill-buffer buffer)))
2577
2578 (ert-deftest python-util-forward-comment-1 ()
2579 (python-tests-with-temp-buffer
2580 (concat
2581 "# a comment
2582 # another comment
2583 # bad indented comment
2584 # more comments" (make-string 9999 ?\n))
2585 (python-util-forward-comment 1)
2586 (should (= (point) (point-max)))
2587 (python-util-forward-comment -1)
2588 (should (= (point) (point-min)))))
2589
2590
2591 (provide 'python-tests)
2592
2593 ;; Local Variables:
2594 ;; coding: utf-8
2595 ;; indent-tabs-mode: nil
2596 ;; End:
2597
2598 ;;; python-tests.el ends here