Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/navigation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: Research navigation and public source checks
'on':
push:
branches: [main]
paths: ['README.md', 'docs/**', 'tools/navigation_check.py', 'tests/test_navigation.py', '.github/workflows/navigation.yml']
paths: ['README.md', 'docs/**', 'tools/navigation_check.py', 'tests/test_navigation*.py', '.github/workflows/navigation.yml']
pull_request:
paths: ['README.md', 'docs/**', 'tools/navigation_check.py', 'tests/test_navigation.py', '.github/workflows/navigation.yml']
paths: ['README.md', 'docs/**', 'tools/navigation_check.py', 'tests/test_navigation*.py', '.github/workflows/navigation.yml']
workflow_dispatch:
permissions:
contents: read
Expand Down
105 changes: 105 additions & 0 deletions tests/test_navigation_workflow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
"""Static contract for the navigation workflow's top-level test path filter.

This reads the workflow's existing single-line, quoted flow-list syntax. It
is not a general YAML parser, a GitHub event replay, or a whole-workflow audit.
The basename matcher is limited to direct children of tests/: unlike a raw
fnmatch over the whole path, its '*' cannot consume a directory separator.
"""
from __future__ import annotations

import ast
import fnmatch
from pathlib import Path
import re
import unittest


ROOT = Path(__file__).resolve().parents[1]
WORKFLOW = ROOT / '.github' / 'workflows' / 'navigation.yml'


def selected_test_path(path: str, patterns: list[str]) -> bool:
"""Evaluate only the workflow's single-directory tests/ filter subset."""
directory, separator, name = path.partition('/')
if directory != 'tests' or not separator or not name or '/' in name:
return False
return any(
pattern.startswith('tests/')
and '/' not in pattern[len('tests/'):]
and fnmatch.fnmatchcase(name, pattern[len('tests/'):])
for pattern in patterns
)


class NavigationWorkflowTests(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.workflow = WORKFLOW.read_text(encoding='utf-8')
matches = re.findall(
r'^ pull_request:\n paths: (\[[^\n]*\])$',
cls.workflow,
re.MULTILINE,
)
if len(matches) != 1:
raise AssertionError('expected one pull_request paths flow list')
cls.paths = ast.literal_eval(matches[0])
if not isinstance(cls.paths, list) or not all(
isinstance(path, str) for path in cls.paths
):
raise AssertionError('expected a list of quoted path strings')

def test_filter_is_narrow_and_retains_existing_triggers(self):
self.assertEqual(self.paths, [
'README.md',
'docs/**',
'tools/navigation_check.py',
'tests/test_navigation*.py',
'.github/workflows/navigation.yml',
])

def test_original_navigation_test_is_selected(self):
self.assertTrue(selected_test_path('tests/test_navigation.py', self.paths))

def test_manifest_regression_file_is_selected(self):
self.assertTrue(selected_test_path(
'tests/test_navigation_manifest.py', self.paths))

def test_this_trigger_regression_file_is_selected(self):
self.assertTrue(selected_test_path(
'tests/test_navigation_workflow.py', self.paths))

def test_other_top_level_navigation_tests_are_selected(self):
self.assertTrue(selected_test_path(
'tests/test_navigation_links.py', self.paths))

def test_nearby_unrelated_and_nested_paths_are_not_selected(self):
for path in (
'tests/test_unrelated.py',
'tests/navigation.py',
'tests/test_navigation.py.txt',
'tests/nested/test_navigation_manifest.py',
'other/tests/test_navigation_manifest.py',
'tests/test_Navigation_manifest.py',
):
with self.subTest(path=path):
self.assertFalse(selected_test_path(path, self.paths))

def test_existing_discovery_command_remains(self):
command = (
"python -B -S -m unittest discover -s tests -p 'test_*.py' -v "
"> navigation-evidence/tests-normal.log 2>&1"
)
self.assertEqual(self.workflow.count(command), 1)

def test_push_filter_matches_pull_request_filter(self):
matches = re.findall(
r'^ push:\n branches: \[main\]\n paths: (\[[^\n]*\])$',
self.workflow,
re.MULTILINE,
)
self.assertEqual(len(matches), 1)
self.assertEqual(ast.literal_eval(matches[0]), self.paths)


if __name__ == '__main__':
unittest.main()
Loading