Test that public functions and classes are documented.
()
| 283 | |
| 284 | |
| 285 | def test_documented(): |
| 286 | """Test that public functions and classes are documented.""" |
| 287 | doc_dir = (Path(__file__).parents[2] / "doc" / "api").absolute() |
| 288 | doc_file = doc_dir / "python_reference.rst" |
| 289 | if not doc_file.is_file(): |
| 290 | pytest.skip(f"Documentation file not found: {doc_file}") |
| 291 | api_files = ( |
| 292 | "covariance", |
| 293 | "creating_from_arrays", |
| 294 | "datasets", |
| 295 | "decoding", |
| 296 | "events", |
| 297 | "file_io", |
| 298 | "forward", |
| 299 | "inverse", |
| 300 | "logging", |
| 301 | "most_used_classes", |
| 302 | "mri", |
| 303 | "preprocessing", |
| 304 | "reading_raw_data", |
| 305 | "realtime", |
| 306 | "report", |
| 307 | "sensor_space", |
| 308 | "simulation", |
| 309 | "source_space", |
| 310 | "statistics", |
| 311 | "time_frequency", |
| 312 | "visualization", |
| 313 | "export", |
| 314 | ) |
| 315 | known_names = list() |
| 316 | for api_file in api_files: |
| 317 | with open(doc_dir / f"{api_file}.rst", "rb") as fid: |
| 318 | for line in fid: |
| 319 | line = line.decode("utf-8") |
| 320 | if not line.startswith(" "): # at least two spaces |
| 321 | continue |
| 322 | line = line.split() |
| 323 | if len(line) == 1 and line[0] != ":": |
| 324 | known_names.append(line[0].split(".")[-1]) |
| 325 | known_names = set(known_names) |
| 326 | |
| 327 | missing = [] |
| 328 | for name in public_modules: |
| 329 | with _record_warnings(): # traits warnings |
| 330 | module = __import__(name, globals()) |
| 331 | for submod in name.split(".")[1:]: |
| 332 | module = getattr(module, submod) |
| 333 | try: |
| 334 | classes = inspect.getmembers(module, inspect.isclass) |
| 335 | except ModuleNotFoundError as exc: # e.g., mne.decoding but no sklearn |
| 336 | if "'sklearn'" in str(exc): |
| 337 | continue |
| 338 | raise |
| 339 | functions = inspect.getmembers(module, inspect.isfunction) |
| 340 | checks = list(classes) + list(functions) |
| 341 | for this_name, cf in checks: |
| 342 | if not this_name.startswith("_") and this_name not in known_names: |
nothing calls this directly
no test coverage detected