-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_metadata.py
More file actions
168 lines (126 loc) · 7.33 KB
/
Copy pathtest_metadata.py
File metadata and controls
168 lines (126 loc) · 7.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
"""Automatisierte Metadaten-, Sicherheits-, Ökosystem- und Dokumentationsparitätstests für DevCenter."""
from pathlib import Path
REPO_ROOT = Path(__file__).resolve().parent.parent
def test_readme_and_readme_de_existence_and_language_links():
"""Prüft, dass README.md und README_de.md existieren und wechselseitig verlinkt sind."""
readme_en = REPO_ROOT / "README.md"
readme_de = REPO_ROOT / "README_de.md"
assert readme_en.is_file(), "README.md fehlt im Repo-Root"
assert readme_de.is_file(), "README_de.md fehlt im Repo-Root"
content_en = readme_en.read_text(encoding="utf-8")
content_de = readme_de.read_text(encoding="utf-8")
assert "README_de.md" in content_en, "README.md muss auf README_de.md verlinken"
assert "README.md" in content_de, "README_de.md muss auf README.md verlinken"
assert "DevCenter" in content_en
assert "DevCenter" in content_de
def test_badges_parity():
"""Prüft, dass beide README-Dateien synchronisierte Badges enthalten."""
content_en = (REPO_ROOT / "README.md").read_text(encoding="utf-8")
content_de = (REPO_ROOT / "README_de.md").read_text(encoding="utf-8")
required_badges = [
"badge/version-1.0.0-blue",
"badge/python-3.11",
"badge/license-GPL",
"badge/ecosystem-dev--bricks",
"badge/umbrella-open--bricks",
"badge/LLM--Context-llms.txt",
]
for badge in required_badges:
assert badge in content_en, f"Badge {badge} fehlt in README.md"
assert badge in content_de, f"Badge {badge} fehlt in README_de.md"
def test_mermaid_diagrams_present():
"""Prüft, dass beide READMEs interaktive Mermaid-Diagramme für Architektur und Datenschutz enthalten."""
content_en = (REPO_ROOT / "README.md").read_text(encoding="utf-8")
content_de = (REPO_ROOT / "README_de.md").read_text(encoding="utf-8")
assert "```mermaid" in content_en, "README.md muss mindestens ein Mermaid-Diagramm enthalten"
assert "```mermaid" in content_de, "README_de.md muss mindestens ein Mermaid-Diagramm enthalten"
assert "Editor" in content_en
assert "PyInstaller" in content_en or "Builder" in content_en
assert "SQLite" in content_en or "FileManager" in content_en
def test_security_policy_bilingual_and_contacts():
"""Prüft, dass SECURITY.md zweisprachig ist, Zero-Egress, 48h SLA und die Sicherheitskontakte enthält."""
sec_file = REPO_ROOT / "SECURITY.md"
assert sec_file.is_file(), "SECURITY.md fehlt im Repo-Root"
content = sec_file.read_text(encoding="utf-8")
assert "security@open-bricks.org" in content, "SECURITY.md muss security@open-bricks.org als Kontakt enthalten"
assert "security@ellmos.ai" in content, "SECURITY.md muss security@ellmos.ai als Kontakt enthalten"
assert "48" in content, "SECURITY.md muss 48h Reaktions-SLA erwähnen"
assert "local-first" in content.lower(), "SECURITY.md muss local-first erwähnen"
assert "zero-egress" in content.lower() or "offline" in content.lower()
assert "keyring" in content.lower()
assert "advisories" in content.lower()
assert "Sicherheitsrichtlinie" in content, "SECURITY.md muss einen deutschen Abschnitt enthalten"
def test_llms_txt_currency_and_structure():
"""Prüft, dass llms.txt aktuell ist, Suchphrasen und wichtige Dateireferenzen enthält."""
llms_file = REPO_ROOT / "llms.txt"
assert llms_file.is_file(), "llms.txt fehlt im Repo-Root"
content = llms_file.read_text(encoding="utf-8")
assert "https://github.com/dev-bricks/DevCenter" in content
assert "2026-08-24" in content, "llms.txt Last-checked Timestamp muss auf 2026-08-24 stehen"
assert "local-first Python IDE" in content
assert "dev-bricks" in content
assert "open-bricks" in content.lower() or "umbrella" in content.lower()
def test_pyproject_version_and_pep621_metadata():
"""Prüft die Gültigkeit von pyproject.toml, PEP 621 Classifiers, URLs und Linter-Konfiguration."""
pyproject_file = REPO_ROOT / "pyproject.toml"
assert pyproject_file.is_file(), "pyproject.toml fehlt im Repo-Root"
content = pyproject_file.read_text(encoding="utf-8")
assert 'name = "devcenter-suite"' in content
assert 'version = "1.0.0"' in content
assert "classifiers = [" in content
assert "keywords = [" in content
assert "[project.urls]" in content
assert "Homepage =" in content
assert "Repository =" in content
assert "Security =" in content
assert "Parent Organization" in content
assert "Umbrella Ecosystem" in content
assert "[tool.ruff]" in content
assert "[tool.ruff.lint]" in content
def test_sibling_ecosystem_matrix_presence():
"""Prüft, dass beide Dokumentationen eine Ökosystem-Matrix mit dev-bricks & open-bricks enthalten."""
content_en = (REPO_ROOT / "README.md").read_text(encoding="utf-8")
content_de = (REPO_ROOT / "README_de.md").read_text(encoding="utf-8")
assert "dev-bricks" in content_en
assert "open-bricks" in content_en
assert "MethodenAnalyser" in content_en or "CodeBox" in content_en
assert "dev-bricks" in content_de
assert "open-bricks" in content_de
def test_changelog_currency():
"""Prüft, dass CHANGELOG.md einen aktuellen Eintrag für 2026-08-24 enthält."""
changelog_file = REPO_ROOT / "CHANGELOG.md"
assert changelog_file.is_file(), "CHANGELOG.md fehlt im Repo-Root"
content = changelog_file.read_text(encoding="utf-8")
assert "2026-08-24" in content, "CHANGELOG.md muss einen Eintrag für 2026-08-24 enthalten"
def test_cross_platform_smoke_scripts_and_ci():
"""Prüft, dass Linux- und macOS-Plattform-Smokes existieren und im CI-Workflow mit Concurrency verdrahtet sind."""
linux_smoke = REPO_ROOT / "tests" / "linux_platform_smoke.py"
macos_smoke = REPO_ROOT / "tests" / "macos_platform_smoke.py"
workflow = REPO_ROOT / ".github" / "workflows" / "tests.yml"
assert linux_smoke.is_file(), "linux_platform_smoke.py fehlt in tests/"
assert macos_smoke.is_file(), "macos_platform_smoke.py fehlt in tests/"
assert workflow.is_file(), "tests.yml fehlt in .github/workflows/"
workflow_content = workflow.read_text(encoding="utf-8")
assert "actions/checkout@v4" in workflow_content
assert "actions/setup-python@v5" in workflow_content
assert "concurrency:" in workflow_content
assert "cancel-in-progress: true" in workflow_content
assert "linux-platform-smoke:" in workflow_content
assert "macos-platform-smoke:" in workflow_content
assert "tests/linux_platform_smoke.py" in workflow_content
assert "tests/macos_platform_smoke.py" in workflow_content
def test_offline_and_zero_egress_invariants():
"""Prüft, dass Core-Module keine ungeprüften externen Netzwerk-Libraries importieren."""
import core.app_paths
import core.settings_manager
assert hasattr(core.app_paths, "get_app_data_dir")
assert hasattr(core.app_paths, "get_settings_path")
assert hasattr(core.app_paths, "get_app_icon_path")
assert hasattr(core.settings_manager, "SettingsManager")
def test_gitignore_hygiene_and_lock_exclusion():
"""Prüft, dass .gitignore Schutz vor Lock-Dateien und Sync-Konflikten bietet."""
gitignore_file = REPO_ROOT / ".gitignore"
assert gitignore_file.is_file(), ".gitignore fehlt im Repo-Root"
content = gitignore_file.read_text(encoding="utf-8")
assert "LOCK*.txt" in content
assert "*.sync-conflict-*" in content or "*.conflict" in content