1 # Copyright 2019 The Pigweed Authors
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
7 # https://www.apache.org/licenses/LICENSE-2.0
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
14 """Tests for pw_module.check."""
22 import pw_module.check
24 _LOG = logging.getLogger(__name__)
27 class TestWithTempDirectory(unittest.TestCase):
28 """Tests for pw_module.check."""
30 # Create a temporary directory for the test.
31 self.test_dir = tempfile.mkdtemp()
34 # Remove it after the test.
35 shutil.rmtree(self.test_dir)
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}')
43 # Make parent directories if they don't exsit.
44 full_file_path.parent.mkdir(parents=True, exist_ok=True)
46 with open(full_file_path, 'w') as fd:
51 def assert_no_issues(self, checker, directory=None):
52 if directory is not None:
53 directory = str(pathlib.Path(self.test_dir, directory))
55 directory = self.test_dir
56 return self.assertFalse(list(checker(directory)))
58 def assert_issue(self, checker, match, directory=None):
59 if directory is not None:
60 directory = str(pathlib.Path(self.test_dir, directory))
62 directory = self.test_dir
63 issues = list(checker(directory))
64 self.assertTrue(any((match in issue.message) for issue in issues))
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,
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)
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')
84 self.create_file('pw_foo/foo_test.cc')
85 self.assert_no_issues(pw_module.check.check_have_cc_tests)
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')
93 self.create_file('pw_foo/py/foo_test.py')
94 self.assert_no_issues(pw_module.check.check_have_python_tests)
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)
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)
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'
114 # Only have a doc? Great.
115 self.create_file('pw_foo/docs.rst')
116 self.assert_no_issues(checker, directory=module_name)
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)
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)
127 # Remove the "bad" header.
128 bad_header_parent = bad_header.parent
130 bad_header_parent.rmdir()
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)
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)
141 if __name__ == '__main__':
143 logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)