* lisp/progmodes/python.el (python-nav--syntactically): Fix cornercases
[bpt/emacs.git] / test / automated / python-tests.el
CommitLineData
4dddd5dc
FEG
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)
52b823c8 27 "Create a `python-mode' enabled temp buffer with CONTENTS.
4dddd5dc
FEG
28BODY is code to be executed within the temp buffer. Point is
29always 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
b85f3423
FEG
37(defmacro python-tests-with-temp-file (contents &rest body)
38 "Create a `python-mode' enabled file with CONTENTS.
39BODY is code to be executed within the temp buffer. Point is
40always 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
4dddd5dc
FEG
52(defun python-tests-look-at (string &optional num restore-point)
53 "Move point at beginning of STRING in the current buffer.
54Optional argument NUM defaults to 1 and is an integer indicating
52b823c8 55how many occurrences must be found, when positive the search is
4dddd5dc
FEG
56done forwards, otherwise backwards. When RESTORE-POINT is
57non-nil the point is not moved but the position found is still
58returned. When searching forward and point is already looking at
59STRING, 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,
93sed do eiusmod tempor incididunt ut labore et dolore magna
94aliqua."
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,
113sed do eiusmod tempor incididunt ut labore et dolore magna
114aliqua."
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
143foo = 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.
159def 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.
183foo = 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 "
203data = {
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 "
269data = {'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 "
310def 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 "
322def 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 "
334def 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 "
385from 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 "
406objects = 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
c9886b39 447(ert-deftest python-indent-block-enders ()
b9edfa5c 448 "Test `python-indent-block-enders' value honoring."
c9886b39
FEG
449 (python-tests-with-temp-buffer
450 "
451Class 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
4dddd5dc
FEG
469\f
470;;; Navigation
471
472(ert-deftest python-nav-beginning-of-defun-1 ()
473 (python-tests-with-temp-buffer
474 "
475def 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 "
523class 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 "
577class 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 "
623def 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
083850a6
FEG
677(ert-deftest python-nav-backward-defun-1 ()
678 (python-tests-with-temp-buffer
679 "
680class 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
04754d36
FEG
721(ert-deftest python-nav-backward-defun-2 ()
722 (python-tests-with-temp-buffer
723 "
724def 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
767class 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
083850a6
FEG
775(ert-deftest python-nav-forward-defun-1 ()
776 (python-tests-with-temp-buffer
777 "
778class 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)))))
4dddd5dc 818
04754d36
FEG
819(ert-deftest python-nav-forward-defun-2 ()
820 (python-tests-with-temp-buffer
821 "
822def 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 "
854class 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
4dddd5dc
FEG
873(ert-deftest python-nav-beginning-of-statement-1 ()
874 (python-tests-with-temp-buffer
875 "
876v1 = 123 + \
877 456 + \
878 789
879v2 = (value1,
880 value2,
881
882 value3,
883 value4)
884v3 = ('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')
891v4 = '''
892a very long
893string
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 "
924v1 = 123 + \
925 456 + \
926 789
927v2 = (value1,
928 value2,
929
930 value3,
931 value4)
932v3 = ('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')
939v4 = '''
940a very long
941string
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 "
978v1 = 123 + \
979 456 + \
980 789
981v2 = (value1,
982 value2,
983
984 value3,
985 value4)
986v3 = ('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')
993v4 = '''
994a very long
995string
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 "
1019v1 = 123 + \
1020 456 + \
1021 789
1022v2 = (value1,
1023 value2,
1024
1025 value3,
1026 value4)
1027v3 = ('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')
1034v4 = '''
1035a very long
1036string
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 "
1061v1 = 123 + \
1062 456 + \
1063 789
1064v2 = (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 "
1082def 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 "
1127def 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 "
1181if 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 "
1222profile = Profile.objects.create(user=request.user)
1223profile.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 "
1244a()
1245b()
1246c()
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 "
1282def 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 "
1318from some_module import some_sub_module
1319from another_module import another_sub_module
1320
1321def 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 "
1360def 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 "
1374def 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
b85f3423
FEG
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.
1446Using `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
4dddd5dc
FEG
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(ert-deftest python-imenu-prev-index-position-1 ()
1677 (require 'imenu)
1678 (python-tests-with-temp-buffer
1679 "
1680def decoratorFunctionWithArguments(arg1, arg2, arg3):
1681 '''print decorated function call data to stdout.
1682
1683 Usage:
1684
1685 @decoratorFunctionWithArguments('arg1', 'arg2')
1686 def func(a, b, c=True):
1687 pass
1688 '''
1689
1690 def wwrap(f):
1691 print 'Inside wwrap()'
1692 def wrapped_f(*args):
1693 print 'Inside wrapped_f()'
1694 print 'Decorator arguments:', arg1, arg2, arg3
1695 f(*args)
1696 print 'After f(*args)'
1697 return wrapped_f
1698 return wwrap
1699
1700def test(): # Some comment
1701 'This is a test function'
1702 print 'test'
1703
1704class C(object):
1705
1706 def m(self):
1707 self.c()
1708
1709 def b():
1710 pass
1711
1712 def a():
1713 pass
1714
1715 def c(self):
1716 pass
1717"
1718 (let ((expected
1719 '(("*Rescan*" . -99)
1720 ("decoratorFunctionWithArguments" . 2)
1721 ("decoratorFunctionWithArguments.wwrap" . 224)
1722 ("decoratorFunctionWithArguments.wwrap.wrapped_f" . 273)
1723 ("test" . 500)
1724 ("C" . 575)
1725 ("C.m" . 593)
1726 ("C.m.b" . 628)
1727 ("C.m.a" . 663)
1728 ("C.c" . 698))))
1729 (mapc
1730 (lambda (elt)
1731 (should (= (cdr (assoc-string (car elt) expected))
1732 (if (markerp (cdr elt))
1733 (marker-position (cdr elt))
1734 (cdr elt)))))
1735 (imenu--make-index-alist)))))
1736
1737\f
1738;;; Misc helpers
1739
1740(ert-deftest python-info-current-defun-1 ()
1741 (python-tests-with-temp-buffer
1742 "
1743def foo(a, b):
1744"
1745 (forward-line 1)
1746 (should (string= "foo" (python-info-current-defun)))
1747 (should (string= "def foo" (python-info-current-defun t)))
1748 (forward-line 1)
1749 (should (not (python-info-current-defun)))
1750 (indent-for-tab-command)
1751 (should (string= "foo" (python-info-current-defun)))
1752 (should (string= "def foo" (python-info-current-defun t)))))
1753
1754(ert-deftest python-info-current-defun-2 ()
1755 (python-tests-with-temp-buffer
1756 "
1757class C(object):
1758
1759 def m(self):
1760 if True:
1761 return [i for i in range(3)]
1762 else:
1763 return []
1764
1765 def b():
c9886b39 1766 do_b()
4dddd5dc
FEG
1767
1768 def a():
c9886b39 1769 do_a()
4dddd5dc
FEG
1770
1771 def c(self):
c9886b39 1772 do_c()
4dddd5dc
FEG
1773"
1774 (forward-line 1)
1775 (should (string= "C" (python-info-current-defun)))
1776 (should (string= "class C" (python-info-current-defun t)))
1777 (python-tests-look-at "return [i for ")
1778 (should (string= "C.m" (python-info-current-defun)))
1779 (should (string= "def C.m" (python-info-current-defun t)))
1780 (python-tests-look-at "def b():")
1781 (should (string= "C.m.b" (python-info-current-defun)))
1782 (should (string= "def C.m.b" (python-info-current-defun t)))
1783 (forward-line 2)
1784 (indent-for-tab-command)
1785 (python-indent-dedent-line-backspace 1)
1786 (should (string= "C.m" (python-info-current-defun)))
1787 (should (string= "def C.m" (python-info-current-defun t)))
1788 (python-tests-look-at "def c(self):")
1789 (forward-line -1)
1790 (indent-for-tab-command)
1791 (should (string= "C.m.a" (python-info-current-defun)))
1792 (should (string= "def C.m.a" (python-info-current-defun t)))
1793 (python-indent-dedent-line-backspace 1)
1794 (should (string= "C.m" (python-info-current-defun)))
1795 (should (string= "def C.m" (python-info-current-defun t)))
1796 (python-indent-dedent-line-backspace 1)
1797 (should (string= "C" (python-info-current-defun)))
1798 (should (string= "class C" (python-info-current-defun t)))
1799 (python-tests-look-at "def c(self):")
1800 (should (string= "C.c" (python-info-current-defun)))
1801 (should (string= "def C.c" (python-info-current-defun t)))
c9886b39 1802 (python-tests-look-at "do_c()")
4dddd5dc
FEG
1803 (should (string= "C.c" (python-info-current-defun)))
1804 (should (string= "def C.c" (python-info-current-defun t)))))
1805
1806(ert-deftest python-info-current-defun-3 ()
1807 (python-tests-with-temp-buffer
1808 "
1809def decoratorFunctionWithArguments(arg1, arg2, arg3):
1810 '''print decorated function call data to stdout.
1811
1812 Usage:
1813
1814 @decoratorFunctionWithArguments('arg1', 'arg2')
1815 def func(a, b, c=True):
1816 pass
1817 '''
1818
1819 def wwrap(f):
1820 print 'Inside wwrap()'
1821 def wrapped_f(*args):
1822 print 'Inside wrapped_f()'
1823 print 'Decorator arguments:', arg1, arg2, arg3
1824 f(*args)
1825 print 'After f(*args)'
1826 return wrapped_f
1827 return wwrap
1828"
1829 (python-tests-look-at "def wwrap(f):")
1830 (forward-line -1)
1831 (should (not (python-info-current-defun)))
1832 (indent-for-tab-command 1)
1833 (should (string= (python-info-current-defun)
1834 "decoratorFunctionWithArguments"))
1835 (should (string= (python-info-current-defun t)
1836 "def decoratorFunctionWithArguments"))
1837 (python-tests-look-at "def wrapped_f(*args):")
1838 (should (string= (python-info-current-defun)
1839 "decoratorFunctionWithArguments.wwrap.wrapped_f"))
1840 (should (string= (python-info-current-defun t)
1841 "def decoratorFunctionWithArguments.wwrap.wrapped_f"))
1842 (python-tests-look-at "return wrapped_f")
1843 (should (string= (python-info-current-defun)
1844 "decoratorFunctionWithArguments.wwrap"))
1845 (should (string= (python-info-current-defun t)
1846 "def decoratorFunctionWithArguments.wwrap"))
1847 (end-of-line 1)
1848 (python-tests-look-at "return wwrap")
1849 (should (string= (python-info-current-defun)
1850 "decoratorFunctionWithArguments"))
1851 (should (string= (python-info-current-defun t)
1852 "def decoratorFunctionWithArguments"))))
1853
1854(ert-deftest python-info-current-symbol-1 ()
1855 (python-tests-with-temp-buffer
1856 "
1857class C(object):
1858
1859 def m(self):
1860 self.c()
1861
1862 def c(self):
1863 print ('a')
1864"
1865 (python-tests-look-at "self.c()")
1866 (should (string= "self.c" (python-info-current-symbol)))
1867 (should (string= "C.c" (python-info-current-symbol t)))))
1868
1869(ert-deftest python-info-current-symbol-2 ()
1870 (python-tests-with-temp-buffer
1871 "
1872class C(object):
1873
1874 class M(object):
1875
1876 def a(self):
1877 self.c()
1878
1879 def c(self):
1880 pass
1881"
1882 (python-tests-look-at "self.c()")
1883 (should (string= "self.c" (python-info-current-symbol)))
1884 (should (string= "C.M.c" (python-info-current-symbol t)))))
1885
1886(ert-deftest python-info-current-symbol-3 ()
1887 "Keywords should not be considered symbols."
1888 :expected-result :failed
1889 (python-tests-with-temp-buffer
1890 "
1891class C(object):
1892 pass
1893"
1894 ;; FIXME: keywords are not symbols.
1895 (python-tests-look-at "class C")
1896 (should (not (python-info-current-symbol)))
1897 (should (not (python-info-current-symbol t)))
1898 (python-tests-look-at "C(object)")
1899 (should (string= "C" (python-info-current-symbol)))
1900 (should (string= "class C" (python-info-current-symbol t)))))
1901
1902(ert-deftest python-info-statement-starts-block-p-1 ()
1903 (python-tests-with-temp-buffer
1904 "
1905def long_function_name(
1906 var_one, var_two, var_three,
1907 var_four):
1908 print (var_one)
1909"
1910 (python-tests-look-at "def long_function_name")
1911 (should (python-info-statement-starts-block-p))
1912 (python-tests-look-at "print (var_one)")
1913 (python-util-forward-comment -1)
1914 (should (python-info-statement-starts-block-p))))
1915
1916(ert-deftest python-info-statement-starts-block-p-2 ()
1917 (python-tests-with-temp-buffer
1918 "
1919if width == 0 and height == 0 and \\\\
1920 color == 'red' and emphasis == 'strong' or \\\\
1921 highlight > 100:
1922 raise ValueError('sorry, you lose')
1923"
1924 (python-tests-look-at "if width == 0 and")
1925 (should (python-info-statement-starts-block-p))
1926 (python-tests-look-at "raise ValueError(")
1927 (python-util-forward-comment -1)
1928 (should (python-info-statement-starts-block-p))))
1929
1930(ert-deftest python-info-statement-ends-block-p-1 ()
1931 (python-tests-with-temp-buffer
1932 "
1933def long_function_name(
1934 var_one, var_two, var_three,
1935 var_four):
1936 print (var_one)
1937"
1938 (python-tests-look-at "print (var_one)")
1939 (should (python-info-statement-ends-block-p))))
1940
1941(ert-deftest python-info-statement-ends-block-p-2 ()
1942 (python-tests-with-temp-buffer
1943 "
1944if width == 0 and height == 0 and \\\\
1945 color == 'red' and emphasis == 'strong' or \\\\
1946 highlight > 100:
1947 raise ValueError(
1948'sorry, you lose'
1949
1950)
1951"
1952 (python-tests-look-at "raise ValueError(")
1953 (should (python-info-statement-ends-block-p))))
1954
1955(ert-deftest python-info-beginning-of-statement-p-1 ()
1956 (python-tests-with-temp-buffer
1957 "
1958def long_function_name(
1959 var_one, var_two, var_three,
1960 var_four):
1961 print (var_one)
1962"
1963 (python-tests-look-at "def long_function_name")
1964 (should (python-info-beginning-of-statement-p))
1965 (forward-char 10)
1966 (should (not (python-info-beginning-of-statement-p)))
1967 (python-tests-look-at "print (var_one)")
1968 (should (python-info-beginning-of-statement-p))
1969 (goto-char (line-beginning-position))
1970 (should (not (python-info-beginning-of-statement-p)))))
1971
1972(ert-deftest python-info-beginning-of-statement-p-2 ()
1973 (python-tests-with-temp-buffer
1974 "
1975if width == 0 and height == 0 and \\\\
1976 color == 'red' and emphasis == 'strong' or \\\\
1977 highlight > 100:
1978 raise ValueError(
1979'sorry, you lose'
1980
1981)
1982"
1983 (python-tests-look-at "if width == 0 and")
1984 (should (python-info-beginning-of-statement-p))
1985 (forward-char 10)
1986 (should (not (python-info-beginning-of-statement-p)))
1987 (python-tests-look-at "raise ValueError(")
1988 (should (python-info-beginning-of-statement-p))
1989 (goto-char (line-beginning-position))
1990 (should (not (python-info-beginning-of-statement-p)))))
1991
1992(ert-deftest python-info-end-of-statement-p-1 ()
1993 (python-tests-with-temp-buffer
1994 "
1995def long_function_name(
1996 var_one, var_two, var_three,
1997 var_four):
1998 print (var_one)
1999"
2000 (python-tests-look-at "def long_function_name")
2001 (should (not (python-info-end-of-statement-p)))
2002 (end-of-line)
2003 (should (not (python-info-end-of-statement-p)))
2004 (python-tests-look-at "print (var_one)")
2005 (python-util-forward-comment -1)
2006 (should (python-info-end-of-statement-p))
2007 (python-tests-look-at "print (var_one)")
2008 (should (not (python-info-end-of-statement-p)))
2009 (end-of-line)
2010 (should (python-info-end-of-statement-p))))
2011
2012(ert-deftest python-info-end-of-statement-p-2 ()
2013 (python-tests-with-temp-buffer
2014 "
2015if width == 0 and height == 0 and \\\\
2016 color == 'red' and emphasis == 'strong' or \\\\
2017 highlight > 100:
2018 raise ValueError(
2019'sorry, you lose'
2020
2021)
2022"
2023 (python-tests-look-at "if width == 0 and")
2024 (should (not (python-info-end-of-statement-p)))
2025 (end-of-line)
2026 (should (not (python-info-end-of-statement-p)))
2027 (python-tests-look-at "raise ValueError(")
2028 (python-util-forward-comment -1)
2029 (should (python-info-end-of-statement-p))
2030 (python-tests-look-at "raise ValueError(")
2031 (should (not (python-info-end-of-statement-p)))
2032 (end-of-line)
2033 (should (not (python-info-end-of-statement-p)))
2034 (goto-char (point-max))
2035 (python-util-forward-comment -1)
2036 (should (python-info-end-of-statement-p))))
2037
2038(ert-deftest python-info-beginning-of-block-p-1 ()
2039 (python-tests-with-temp-buffer
2040 "
2041def long_function_name(
2042 var_one, var_two, var_three,
2043 var_four):
2044 print (var_one)
2045"
2046 (python-tests-look-at "def long_function_name")
2047 (should (python-info-beginning-of-block-p))
2048 (python-tests-look-at "var_one, var_two, var_three,")
2049 (should (not (python-info-beginning-of-block-p)))
2050 (python-tests-look-at "print (var_one)")
2051 (should (not (python-info-beginning-of-block-p)))))
2052
2053(ert-deftest python-info-beginning-of-block-p-2 ()
2054 (python-tests-with-temp-buffer
2055 "
2056if width == 0 and height == 0 and \\\\
2057 color == 'red' and emphasis == 'strong' or \\\\
2058 highlight > 100:
2059 raise ValueError(
2060'sorry, you lose'
2061
2062)
2063"
2064 (python-tests-look-at "if width == 0 and")
2065 (should (python-info-beginning-of-block-p))
2066 (python-tests-look-at "color == 'red' and emphasis")
2067 (should (not (python-info-beginning-of-block-p)))
2068 (python-tests-look-at "raise ValueError(")
2069 (should (not (python-info-beginning-of-block-p)))))
2070
2071(ert-deftest python-info-end-of-block-p-1 ()
2072 (python-tests-with-temp-buffer
2073 "
2074def long_function_name(
2075 var_one, var_two, var_three,
2076 var_four):
2077 print (var_one)
2078"
2079 (python-tests-look-at "def long_function_name")
2080 (should (not (python-info-end-of-block-p)))
2081 (python-tests-look-at "var_one, var_two, var_three,")
2082 (should (not (python-info-end-of-block-p)))
2083 (python-tests-look-at "var_four):")
2084 (end-of-line)
2085 (should (not (python-info-end-of-block-p)))
2086 (python-tests-look-at "print (var_one)")
2087 (should (not (python-info-end-of-block-p)))
2088 (end-of-line 1)
2089 (should (python-info-end-of-block-p))))
2090
2091(ert-deftest python-info-end-of-block-p-2 ()
2092 (python-tests-with-temp-buffer
2093 "
2094if width == 0 and height == 0 and \\\\
2095 color == 'red' and emphasis == 'strong' or \\\\
2096 highlight > 100:
2097 raise ValueError(
2098'sorry, you lose'
2099
2100)
2101"
2102 (python-tests-look-at "if width == 0 and")
2103 (should (not (python-info-end-of-block-p)))
2104 (python-tests-look-at "color == 'red' and emphasis == 'strong' or")
2105 (should (not (python-info-end-of-block-p)))
2106 (python-tests-look-at "highlight > 100:")
2107 (end-of-line)
2108 (should (not (python-info-end-of-block-p)))
2109 (python-tests-look-at "raise ValueError(")
2110 (should (not (python-info-end-of-block-p)))
2111 (end-of-line 1)
2112 (should (not (python-info-end-of-block-p)))
2113 (goto-char (point-max))
2114 (python-util-forward-comment -1)
2115 (should (python-info-end-of-block-p))))
2116
2117(ert-deftest python-info-closing-block-1 ()
2118 (python-tests-with-temp-buffer
2119 "
2120if request.user.is_authenticated():
2121 try:
2122 profile = request.user.get_profile()
2123 except Profile.DoesNotExist:
2124 profile = Profile.objects.create(user=request.user)
2125 else:
2126 if profile.stats:
2127 profile.recalculate_stats()
2128 else:
2129 profile.clear_stats()
2130 finally:
2131 profile.views += 1
2132 profile.save()
2133"
2134 (python-tests-look-at "try:")
2135 (should (not (python-info-closing-block)))
2136 (python-tests-look-at "except Profile.DoesNotExist:")
2137 (should (= (python-tests-look-at "try:" -1 t)
2138 (python-info-closing-block)))
2139 (python-tests-look-at "else:")
2140 (should (= (python-tests-look-at "except Profile.DoesNotExist:" -1 t)
2141 (python-info-closing-block)))
2142 (python-tests-look-at "if profile.stats:")
2143 (should (not (python-info-closing-block)))
2144 (python-tests-look-at "else:")
2145 (should (= (python-tests-look-at "if profile.stats:" -1 t)
2146 (python-info-closing-block)))
2147 (python-tests-look-at "finally:")
2148 (should (= (python-tests-look-at "else:" -2 t)
2149 (python-info-closing-block)))))
2150
2151(ert-deftest python-info-closing-block-2 ()
2152 (python-tests-with-temp-buffer
2153 "
2154if request.user.is_authenticated():
2155 profile = Profile.objects.get_or_create(user=request.user)
2156 if profile.stats:
2157 profile.recalculate_stats()
2158
2159data = {
2160 'else': 'do it'
2161}
2162 'else'
2163"
2164 (python-tests-look-at "'else': 'do it'")
2165 (should (not (python-info-closing-block)))
2166 (python-tests-look-at "'else'")
2167 (should (not (python-info-closing-block)))))
2168
2169(ert-deftest python-info-line-ends-backslash-p-1 ()
2170 (python-tests-with-temp-buffer
2171 "
2172objects = Thing.objects.all() \\\\
2173 .filter(
2174 type='toy',
2175 status='bought'
2176 ) \\\\
2177 .aggregate(
2178 Sum('amount')
2179 ) \\\\
2180 .values_list()
2181"
2182 (should (python-info-line-ends-backslash-p 2)) ; .filter(...
2183 (should (python-info-line-ends-backslash-p 3))
2184 (should (python-info-line-ends-backslash-p 4))
2185 (should (python-info-line-ends-backslash-p 5))
2186 (should (python-info-line-ends-backslash-p 6)) ; ) \...
2187 (should (python-info-line-ends-backslash-p 7))
2188 (should (python-info-line-ends-backslash-p 8))
2189 (should (python-info-line-ends-backslash-p 9))
2190 (should (not (python-info-line-ends-backslash-p 10))))) ; .values_list()...
2191
2192(ert-deftest python-info-beginning-of-backslash-1 ()
2193 (python-tests-with-temp-buffer
2194 "
2195objects = Thing.objects.all() \\\\
2196 .filter(
2197 type='toy',
2198 status='bought'
2199 ) \\\\
2200 .aggregate(
2201 Sum('amount')
2202 ) \\\\
2203 .values_list()
2204"
2205 (let ((first 2)
2206 (second (python-tests-look-at ".filter("))
2207 (third (python-tests-look-at ".aggregate(")))
2208 (should (= first (python-info-beginning-of-backslash 2)))
2209 (should (= second (python-info-beginning-of-backslash 3)))
2210 (should (= second (python-info-beginning-of-backslash 4)))
2211 (should (= second (python-info-beginning-of-backslash 5)))
2212 (should (= second (python-info-beginning-of-backslash 6)))
2213 (should (= third (python-info-beginning-of-backslash 7)))
2214 (should (= third (python-info-beginning-of-backslash 8)))
2215 (should (= third (python-info-beginning-of-backslash 9)))
2216 (should (not (python-info-beginning-of-backslash 10))))))
2217
2218(ert-deftest python-info-continuation-line-p-1 ()
2219 (python-tests-with-temp-buffer
2220 "
2221if 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 height == 0 and")
2230 (should (not (python-info-continuation-line-p)))
2231 (python-tests-look-at "color == 'red' and emphasis == 'strong' or")
2232 (should (python-info-continuation-line-p))
2233 (python-tests-look-at "highlight > 100:")
2234 (should (python-info-continuation-line-p))
2235 (python-tests-look-at "raise ValueError(")
2236 (should (not (python-info-continuation-line-p)))
2237 (python-tests-look-at "'sorry, you lose'")
2238 (should (python-info-continuation-line-p))
2239 (forward-line 1)
2240 (should (python-info-continuation-line-p))
2241 (python-tests-look-at ")")
2242 (should (python-info-continuation-line-p))
2243 (forward-line 1)
2244 (should (not (python-info-continuation-line-p)))))
2245
2246(ert-deftest python-info-block-continuation-line-p-1 ()
2247 (python-tests-with-temp-buffer
2248 "
2249if width == 0 and height == 0 and \\\\
2250 color == 'red' and emphasis == 'strong' or \\\\
2251 highlight > 100:
2252 raise ValueError(
2253'sorry, you lose'
2254
2255)
2256"
2257 (python-tests-look-at "if width == 0 and")
2258 (should (not (python-info-block-continuation-line-p)))
2259 (python-tests-look-at "color == 'red' and emphasis == 'strong' or")
2260 (should (= (python-info-block-continuation-line-p)
2261 (python-tests-look-at "if width == 0 and" -1 t)))
2262 (python-tests-look-at "highlight > 100:")
2263 (should (not (python-info-block-continuation-line-p)))))
2264
2265(ert-deftest python-info-block-continuation-line-p-2 ()
2266 (python-tests-with-temp-buffer
2267 "
2268def foo(a,
2269 b,
2270 c):
2271 pass
2272"
2273 (python-tests-look-at "def foo(a,")
2274 (should (not (python-info-block-continuation-line-p)))
2275 (python-tests-look-at "b,")
2276 (should (= (python-info-block-continuation-line-p)
2277 (python-tests-look-at "def foo(a," -1 t)))
2278 (python-tests-look-at "c):")
2279 (should (not (python-info-block-continuation-line-p)))))
2280
2281(ert-deftest python-info-assignment-continuation-line-p-1 ()
2282 (python-tests-with-temp-buffer
2283 "
2284data = foo(), bar() \\\\
2285 baz(), 4 \\\\
2286 5, 6
2287"
2288 (python-tests-look-at "data = foo(), bar()")
2289 (should (not (python-info-assignment-continuation-line-p)))
2290 (python-tests-look-at "baz(), 4")
2291 (should (= (python-info-assignment-continuation-line-p)
2292 (python-tests-look-at "foo()," -1 t)))
2293 (python-tests-look-at "5, 6")
2294 (should (not (python-info-assignment-continuation-line-p)))))
2295
2296(ert-deftest python-info-assignment-continuation-line-p-2 ()
2297 (python-tests-with-temp-buffer
2298 "
2299data = (foo(), bar()
2300 baz(), 4
2301 5, 6)
2302"
2303 (python-tests-look-at "data = (foo(), bar()")
2304 (should (not (python-info-assignment-continuation-line-p)))
2305 (python-tests-look-at "baz(), 4")
2306 (should (= (python-info-assignment-continuation-line-p)
2307 (python-tests-look-at "(foo()," -1 t)))
2308 (python-tests-look-at "5, 6)")
2309 (should (not (python-info-assignment-continuation-line-p)))))
2310
2311(ert-deftest python-info-looking-at-beginning-of-defun-1 ()
2312 (python-tests-with-temp-buffer
2313 "
2314def decorat0r(deff):
2315 '''decorates stuff.
2316
2317 @decorat0r
2318 def foo(arg):
2319 ...
2320 '''
2321 def wrap():
2322 deff()
2323 return wwrap
2324"
2325 (python-tests-look-at "def decorat0r(deff):")
2326 (should (python-info-looking-at-beginning-of-defun))
2327 (python-tests-look-at "def foo(arg):")
2328 (should (not (python-info-looking-at-beginning-of-defun)))
2329 (python-tests-look-at "def wrap():")
2330 (should (python-info-looking-at-beginning-of-defun))
2331 (python-tests-look-at "deff()")
2332 (should (not (python-info-looking-at-beginning-of-defun)))))
2333
2334(ert-deftest python-info-current-line-comment-p-1 ()
2335 (python-tests-with-temp-buffer
2336 "
2337# this is a comment
2338foo = True # another comment
2339'#this is a string'
2340if foo:
2341 # more comments
2342 print ('bar') # print bar
2343"
2344 (python-tests-look-at "# this is a comment")
2345 (should (python-info-current-line-comment-p))
2346 (python-tests-look-at "foo = True # another comment")
2347 (should (not (python-info-current-line-comment-p)))
2348 (python-tests-look-at "'#this is a string'")
2349 (should (not (python-info-current-line-comment-p)))
2350 (python-tests-look-at "# more comments")
2351 (should (python-info-current-line-comment-p))
2352 (python-tests-look-at "print ('bar') # print bar")
2353 (should (not (python-info-current-line-comment-p)))))
2354
2355(ert-deftest python-info-current-line-empty-p ()
2356 (python-tests-with-temp-buffer
2357 "
2358# this is a comment
2359
2360foo = True # another comment
2361"
2362 (should (python-info-current-line-empty-p))
2363 (python-tests-look-at "# this is a comment")
2364 (should (not (python-info-current-line-empty-p)))
2365 (forward-line 1)
2366 (should (python-info-current-line-empty-p))))
2367
2368\f
2369;;; Utility functions
2370
2371(ert-deftest python-util-goto-line-1 ()
2372 (python-tests-with-temp-buffer
2373 (concat
2374 "# a comment
2375# another comment
2376def foo(a, b, c):
2377 pass" (make-string 20 ?\n))
2378 (python-util-goto-line 10)
2379 (should (= (line-number-at-pos) 10))
2380 (python-util-goto-line 20)
2381 (should (= (line-number-at-pos) 20))))
2382
2383(ert-deftest python-util-clone-local-variables-1 ()
2384 (let ((buffer (generate-new-buffer
2385 "python-util-clone-local-variables-1"))
2386 (varcons
2387 '((python-fill-docstring-style . django)
2388 (python-shell-interpreter . "python")
2389 (python-shell-interpreter-args . "manage.py shell")
2390 (python-shell-prompt-regexp . "In \\[[0-9]+\\]: ")
2391 (python-shell-prompt-output-regexp . "Out\\[[0-9]+\\]: ")
2392 (python-shell-extra-pythonpaths "/home/user/pylib/")
2393 (python-shell-completion-setup-code
2394 . "from IPython.core.completerlib import module_completion")
2395 (python-shell-completion-module-string-code
2396 . "';'.join(module_completion('''%s'''))\n")
2397 (python-shell-completion-string-code
2398 . "';'.join(get_ipython().Completer.all_completions('''%s'''))\n")
2399 (python-shell-virtualenv-path
2400 . "/home/user/.virtualenvs/project"))))
2401 (with-current-buffer buffer
2402 (kill-all-local-variables)
2403 (dolist (ccons varcons)
2404 (set (make-local-variable (car ccons)) (cdr ccons))))
2405 (python-tests-with-temp-buffer
2406 ""
2407 (python-util-clone-local-variables buffer)
2408 (dolist (ccons varcons)
2409 (should
2410 (equal (symbol-value (car ccons)) (cdr ccons)))))
2411 (kill-buffer buffer)))
2412
2413(ert-deftest python-util-forward-comment-1 ()
2414 (python-tests-with-temp-buffer
2415 (concat
2416 "# a comment
2417# another comment
2418 # bad indented comment
2419# more comments" (make-string 9999 ?\n))
2420 (python-util-forward-comment 1)
2421 (should (= (point) (point-max)))
2422 (python-util-forward-comment -1)
2423 (should (= (point) (point-min)))))
2424
2425
2426(provide 'python-tests)
2427
2428;; Local Variables:
2429;; coding: utf-8
2430;; indent-tabs-mode: nil
2431;; End:
2432
2433;;; python-tests.el ends here