• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2019 The Pigweed Authors
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may not
4# use this file except in compliance with the License. You may obtain a copy of
5# the License at
6#
7#     https://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations under
13# the License.
14"""Tests for pw_module.check."""
15
16import logging
17import pathlib
18import shutil
19import tempfile
20import unittest
21
22import pw_module.check
23
24_LOG = logging.getLogger(__name__)
25
26
27class TestWithTempDirectory(unittest.TestCase):
28    """Tests for pw_module.check."""
29    def setUp(self):
30        # Create a temporary directory for the test.
31        self.test_dir = tempfile.mkdtemp()
32
33    def tearDown(self):
34        # Remove it after the test.
35        shutil.rmtree(self.test_dir)
36
37    def create_file(self, path, contents=''):
38        """Create a file and any directories assuming '/' path separator"""
39        full_file_path = pathlib.Path(self.test_dir, path)
40        if full_file_path.exists():
41            raise Exception(f'File exists already: {path}')
42
43        # Make parent directories if they don't exsit.
44        full_file_path.parent.mkdir(parents=True, exist_ok=True)
45
46        with open(full_file_path, 'w') as fd:
47            fd.write(contents)
48
49        return full_file_path
50
51    def assert_no_issues(self, checker, directory=None):
52        if directory is not None:
53            directory = str(pathlib.Path(self.test_dir, directory))
54        else:
55            directory = self.test_dir
56        return self.assertFalse(list(checker(directory)))
57
58    def assert_issue(self, checker, match, directory=None):
59        if directory is not None:
60            directory = str(pathlib.Path(self.test_dir, directory))
61        else:
62            directory = self.test_dir
63        issues = list(checker(directory))
64        self.assertTrue(any((match in issue.message) for issue in issues))
65
66    # Have Python code --> have setup.py.
67    def test_pwck001_have_setup_py(self):
68        # Python files; no setup --> error.
69        self.create_file('pw_foo/py/pw_foo/__init__.py')
70        self.create_file('pw_foo/py/pw_foo/bar.py')
71        self.assert_issue(pw_module.check.check_python_proper_module,
72                          'setup.py')
73
74        # Python files; have setup.py --> ok.
75        self.create_file('pw_foo/py/setup.py')
76        self.assert_no_issues(pw_module.check.check_python_proper_module)
77
78    # Have C++ code --> have C++ tests.
79    def test_pwck002_have_python_tests(self):
80        self.create_file('pw_foo/public/foo.h')
81        self.create_file('pw_foo/foo.cc')
82        self.assert_issue(pw_module.check.check_have_cc_tests, 'tests')
83
84        self.create_file('pw_foo/foo_test.cc')
85        self.assert_no_issues(pw_module.check.check_have_cc_tests)
86
87    # Have Python code --> have Python tests.
88    def test_pwck003_have_python_tests(self):
89        self.create_file('pw_foo/py/pw_foo/__init__.py')
90        self.create_file('pw_foo/py/setup.py')
91        self.assert_issue(pw_module.check.check_have_python_tests, 'tests')
92
93        self.create_file('pw_foo/py/foo_test.py')
94        self.assert_no_issues(pw_module.check.check_have_python_tests)
95
96    # Have README.md
97    def test_pwck004_have_readme(self):
98        self.assert_issue(pw_module.check.check_has_readme, 'README')
99        self.create_file('README.md')
100        self.assert_no_issues(pw_module.check.check_has_readme)
101
102    # Have ReST docs of some kind
103    def test_pwck005_have_rst_docs(self):
104        checker = pw_module.check.check_has_rst_docs
105        self.assert_issue(checker, 'ReST')
106        self.create_file('pw_foo/docs.rst')
107        self.assert_no_issues(checker)
108
109    # Have ReST docs of some kind
110    def test_pwck006_have_public_or_override_headers(self):
111        checker = pw_module.check.check_has_public_or_override_headers
112        module_name = 'pw_foo'
113
114        # Only have a doc? Great.
115        self.create_file('pw_foo/docs.rst')
116        self.assert_no_issues(checker, directory=module_name)
117
118        # CC files with no public header --> error.
119        self.create_file('pw_foo/implementation.cc')
120        self.create_file('pw_foo/implementation_test.cc')
121        self.assert_issue(checker, 'public/pw_foo', directory=module_name)
122
123        # CC files with public header in unmatched module folder --> error.
124        bad_header = self.create_file('pw_foo/public/wrong/foo.h')
125        self.assert_issue(checker, 'public/pw_foo', directory=module_name)
126
127        # Remove the "bad" header.
128        bad_header_parent = bad_header.parent
129        bad_header.unlink()
130        bad_header_parent.rmdir()
131
132        # Finally create the correct header.
133        self.create_file('pw_foo/public/pw_foo/baz.h')
134        self.assert_no_issues(checker, directory=module_name)
135
136        # Reject if there are multiple directories in public/...
137        self.create_file('pw_foo/public/fake/fake.h')
138        self.assert_issue(checker, 'multiple', directory=module_name)
139
140
141if __name__ == '__main__':
142    import sys
143    logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
144    unittest.main()
145