Coverage for test_doctests.py : 96%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# -*- coding: utf-8 -*-
2#@+leo-ver=5-thin
3#@+node:ekr.20210926044012.1: * @file ../unittests/test_doctests.py
4#@@first
5"""Run all doctests."""
6import doctest
7import glob
8import os
9import unittest
10from leo.core import leoGlobals as g
12unittest_dir = os.path.dirname(__file__)
13leo_dir = os.path.abspath(os.path.join(unittest_dir, '..'))
15#@+others # Define a function containing a doctest.
16#@+node:ekr.20210926053601.1: ** factorial (test_dectests.py)
17def factorial(n):
18 # Modified from https://docs.python.org/3/library/doctest.html
19 # Must import factorial. See: stackoverflow.com/questions/65066002
20 """Return the factorial of n, an exact integer >= 0.
22 >>> from leo.unittests.test_doctests import factorial
24 >>> [factorial(n) for n in range(6)]
25 [1, 1, 2, 6, 24, 120]
26 >>> factorial(30)
27 265252859812191058636308480000000
28 >>> factorial(-1)
29 Traceback (most recent call last):
30 ...
31 ValueError: n must be >= 0
33 Factorials of floats are OK, but the float must be an exact integer:
34 >>> factorial(30.1)
35 Traceback (most recent call last):
36 ...
37 ValueError: n must be exact integer
38 >>> factorial(30.0)
39 265252859812191058636308480000000
41 It must also not be ridiculously large:
42 >>> factorial(1e100)
43 Traceback (most recent call last):
44 ...
45 OverflowError: n too large
47 """ # Blank line above is required.
49 import math
50 if not n >= 0:
51 raise ValueError("n must be >= 0")
52 if math.floor(n) != n:
53 raise ValueError("n must be exact integer")
54 if n+1 == n: # catch a value like 1e300
55 raise OverflowError("n too large")
56 result = 1
57 factor = 2
58 while factor <= n:
59 result *= factor
60 factor += 1
61 return result
62#@-others
64class TestDocTests(unittest.TestCase): # No need to be a subclass of leoTest2.LeoUnitTest.
66 def test_all_doctests(self):
67 fails_list = [] # List of files with failing doctests.
68 files_list = [] # List of files containing a doctest.
69 n = 0 # Total doctests found
70 for module in ('core', 'plugins', 'unittests'):
71 module_path = os.path.join(leo_dir, module)
72 self.assertTrue(os.path.exists(module_path), msg=repr(module_path))
73 path = os.path.join(module_path, '**', '*.py')
74 files = glob.glob(path, recursive=True)
75 files = [z for z in files if not z.endswith('__init__.py')]
76 for f in files:
77 # Exclude two problematic files.
78 if 'dtest.py' in f or 'javascript.py' in f:
79 continue
80 fails, count = doctest.testfile(f, False)
81 n += count
82 if count:
83 files_list.append(f)
84 if fails:
85 fails_list.append(f)
86 print(f"{fails} failures in {g.shortFileName(f)}")
87 self.assertEqual(fails_list, [])
88 if 0:
89 g.trace(f"{n} doctests found in {len(files_list)} file{g.plural(len(files_list))}")
90 g.printObj(files_list, tag="files containing any doctest")
91 g.printObj(fails_list, tag="files containing a failed doctest")
92#@-leo