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