|
1 | 1 | """ |
2 | 2 | Documentation testing |
3 | 3 |
|
4 | | -Based on: |
| 4 | +Inspired by: |
5 | 5 | https://github.com/cprogrammer1994/ModernGL/blob/master/tests/test_documentation.py |
6 | 6 | by Szabolcs Dombi |
| 7 | +
|
| 8 | +This version is simplified: |
| 9 | +* Only test if the attribute or method is present in the class. Function parameters are not inspected. |
| 10 | +* Include ignore pattern in the implemented set |
7 | 11 | """ |
8 | | -import inspect |
9 | 12 | import os |
10 | 13 | import re |
11 | | -import unittest |
12 | | - |
13 | | -os.environ['DEMOSYS_SETTINGS_MODULE'] = 'tests.settings' # noqa |
14 | 14 |
|
15 | | -import demosys |
16 | | -from demosys import effects, opengl |
| 15 | +from demosys.test import DemosysTestCase |
| 16 | +from demosys.utils import module_loading |
17 | 17 |
|
18 | | -# Modules we want to remove from types |
19 | | -MODULES = [ |
20 | | - 'demosys.', |
21 | | - 'opengl.', |
22 | | - 'texture.', |
23 | | - 'shader.', |
24 | | - 'resources.', |
25 | | - 'data.', |
26 | | - 'moderngl.', |
27 | | - 'buffer.', |
28 | | - 'rocket.', |
29 | | - 'tracks.', |
30 | | - 'scene.', |
31 | | - 'buffer.', |
32 | | - 'depth.', |
33 | | - 'texture_array.', |
34 | | - 'program.', |
35 | | - 'vertex_array.', |
36 | | - 'array.', |
37 | | -] |
| 18 | +os.environ['DEMOSYS_SETTINGS_MODULE'] = 'tests.settings' # noqa |
38 | 19 |
|
39 | | -class TestCase(unittest.TestCase): |
40 | 20 |
|
| 21 | +class TestCase(DemosysTestCase): |
| 22 | + """ |
| 23 | + Test reference docs |
| 24 | + """ |
41 | 25 | def validate(self, filename, module, classname, ignore): |
42 | | - root = os.path.dirname(os.path.dirname(__file__)) |
43 | | - with open(os.path.normpath(os.path.join(root, 'docs', 'source', filename))) as f: |
| 26 | + """ |
| 27 | + Finds all automethod and autoattribute statements in an rst file |
| 28 | + comparing them to the attributes found in the actual class |
| 29 | + """ |
| 30 | + with open(os.path.normpath(os.path.join('docs', 'reference', filename))) as f: |
44 | 31 | docs = f.read() |
45 | | - methods = re.findall(r'^\.\. automethod:: ([^\(\n]+)([^\n]+)', docs, flags=re.M) |
46 | | - attributes = re.findall(r'^\.\. autoattribute:: ([^\n]+)', docs, flags=re.M) |
47 | | - documented = set(filter(lambda x: x.startswith(classname), [a for a, b in methods] + attributes)) |
48 | | - implemented = set(classname + '.' + x for x in dir(getattr(module, classname)) if not x.startswith('_')) |
49 | | - ignored = set(classname + '.' + x for x in ignore) |
50 | | - self.assertSetEqual(implemented - documented - ignored, set(), msg='Implemented but not Documented') |
51 | | - self.assertSetEqual(documented - implemented, set(), msg='Documented but not Implemented') |
52 | | - |
53 | | - for method, docsig in methods: |
54 | | - classname, methodname = method.split('.') |
55 | | - sig = str(inspect.signature(getattr(getattr(module, classname), methodname))) |
56 | | - print(sig) |
57 | | - sig = sig.replace('self, ', '').replace('typing.', '').replace(' -> None', '') |
58 | 32 |
|
59 | | - for m in MODULES: |
60 | | - sig = sig.replace(m, '') |
| 33 | + module = module_loading.import_module(module) |
61 | 34 |
|
62 | | - sig = sig.replace('(self)', '()').replace(', *,', ',').replace('(*, ', '(') |
63 | | - sig = re.sub(r'-> \'(\w+)\'', r'-> \1', sig) |
| 35 | + methods = re.findall(r'^\.\. automethod:: ([^\(\n]+)', docs, flags=re.M) |
| 36 | + attributes = re.findall(r'^\.\. autoattribute:: ([^\n]+)', docs, flags=re.M) |
64 | 37 |
|
65 | | - self.assertEqual(docsig, sig, msg=filename + '::' + method) |
| 38 | + documented = set(filter(lambda x: x.startswith(classname), [a for a in methods] + attributes)) |
| 39 | + implemented = set(classname + '.' + x for x in dir(getattr(module, classname)) |
| 40 | + if not x.startswith('_') or x == '__init__') |
| 41 | + print(implemented) |
| 42 | + ignored = set(classname + '.' + x for x in ignore) |
66 | 43 |
|
67 | | - # def test_effect_docs(self): |
68 | | - # self.validate( |
69 | | - # os.path.join('reference', 'effect.rst'), |
70 | | - # effects, 'Effect', []) |
| 44 | + self.assertSetEqual(implemented - documented - ignored, set(), msg='Implemented but not Documented') |
| 45 | + self.assertSetEqual(documented - implemented - ignored, set(), msg='Documented but not Implemented') |
71 | 46 |
|
72 | | - # def test_vao_docs(self): |
73 | | - # self.validate( |
74 | | - # os.path.join('reference', 'vao.rst'), |
75 | | - # opengl, 'VAO', [] |
76 | | - # ) |
| 47 | + def test_demosys_contex_base(self): |
| 48 | + self.validate('demosys.context.base.rst', 'demosys.context.base', 'BaseWindow', []) |
77 | 49 |
|
78 | | -if __name__ == '__main__': |
79 | | - unittest.main() |
| 50 | + def test_demosys_context_glfw(self): |
| 51 | + self.validate('demosys.context.glfw.rst', 'demosys.context.glfw', 'Window', []) |
0 commit comments