227 lines
7.7 KiB
Python
227 lines
7.7 KiB
Python
#!/usr/bin/env python3
|
|
"""Tests for scripts/freshness.py — 8 tests."""
|
|
|
|
import json
|
|
import os
|
|
import sys
|
|
import tempfile
|
|
|
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__) or ".", ".."))
|
|
import importlib.util
|
|
spec = importlib.util.spec_from_file_location(
|
|
"freshness", os.path.join(os.path.dirname(__file__) or ".", "..", "scripts", "freshness.py"))
|
|
mod = importlib.util.module_from_spec(spec)
|
|
spec.loader.exec_module(mod)
|
|
|
|
compute_file_hash = mod.compute_file_hash
|
|
check_freshness = mod.check_freshness
|
|
load_knowledge_entries = mod.load_knowledge_entries
|
|
|
|
|
|
def test_compute_file_hash():
|
|
"""File hash should be computed correctly."""
|
|
with tempfile.NamedTemporaryFile(mode='w', delete=False) as f:
|
|
f.write("test content")
|
|
f.flush()
|
|
h = compute_file_hash(f.name)
|
|
assert h is not None
|
|
assert h.startswith("sha256:")
|
|
os.unlink(f.name)
|
|
print("PASS: test_compute_file_hash")
|
|
|
|
|
|
def test_compute_file_hash_nonexistent():
|
|
"""Nonexistent file should return None."""
|
|
h = compute_file_hash("/nonexistent/file.txt")
|
|
assert h is None
|
|
print("PASS: test_compute_file_hash_nonexistent")
|
|
|
|
|
|
def test_load_knowledge_entries_empty():
|
|
"""Empty knowledge dir should return empty list."""
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
entries = load_knowledge_entries(tmpdir)
|
|
assert entries == []
|
|
print("PASS: test_load_knowledge_entries_empty")
|
|
|
|
|
|
def test_load_knowledge_entries_from_index():
|
|
"""Should load entries from index.json."""
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
# Create index.json
|
|
index_path = os.path.join(tmpdir, "index.json")
|
|
with open(index_path, "w") as f:
|
|
json.dump({
|
|
"facts": [
|
|
{
|
|
"fact": "Test fact",
|
|
"source_file": "test.py",
|
|
"source_hash": "sha256:abc123",
|
|
"category": "fact",
|
|
"confidence": 0.9
|
|
}
|
|
]
|
|
}, f)
|
|
|
|
entries = load_knowledge_entries(tmpdir)
|
|
assert len(entries) == 1
|
|
assert entries[0]["fact"] == "Test fact"
|
|
assert entries[0]["source_file"] == "test.py"
|
|
print("PASS: test_load_knowledge_entries_from_index")
|
|
|
|
|
|
def test_load_knowledge_entries_from_yaml():
|
|
"""Should load entries from YAML files."""
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
# Create global directory
|
|
global_dir = os.path.join(tmpdir, "global")
|
|
os.makedirs(global_dir)
|
|
|
|
# Create YAML file
|
|
yaml_path = os.path.join(global_dir, "test.yaml")
|
|
with open(yaml_path, "w") as f:
|
|
f.write("""
|
|
pitfalls:
|
|
- description: "Test pitfall"
|
|
source_file: "test.py"
|
|
source_hash: "sha256:def456"
|
|
category: "pitfall"
|
|
confidence: 0.8
|
|
""")
|
|
|
|
entries = load_knowledge_entries(tmpdir)
|
|
assert len(entries) == 1
|
|
assert entries[0]["fact"] == "Test pitfall"
|
|
assert entries[0]["category"] == "pitfall"
|
|
print("PASS: test_load_knowledge_entries_from_yaml")
|
|
|
|
|
|
def test_check_freshness_no_changes():
|
|
"""With no source file reference, entries should be counted correctly."""
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
# Create knowledge dir
|
|
knowledge_dir = os.path.join(tmpdir, "knowledge")
|
|
os.makedirs(knowledge_dir)
|
|
|
|
# Create repo dir
|
|
repo_dir = os.path.join(tmpdir, "repo")
|
|
os.makedirs(repo_dir)
|
|
|
|
# Create index.json with entry that has no source_file
|
|
index_path = os.path.join(knowledge_dir, "index.json")
|
|
with open(index_path, "w") as f:
|
|
json.dump({
|
|
"facts": [
|
|
{
|
|
"fact": "General knowledge",
|
|
"category": "fact",
|
|
"confidence": 0.9
|
|
# No source_file or source_hash
|
|
}
|
|
]
|
|
}, f)
|
|
|
|
result = check_freshness(knowledge_dir, repo_dir, days=1)
|
|
|
|
# Entry without source_file should be counted as "fresh" (no_source status)
|
|
assert result["summary"]["total"] == 1
|
|
assert result["summary"]["stale"] == 0
|
|
assert result["summary"]["fresh"] == 1
|
|
assert result["fresh_entries"][0]["status"] == "no_source"
|
|
print("PASS: test_check_freshness_no_changes")
|
|
|
|
|
|
def test_check_freshness_with_hash_mismatch():
|
|
"""Hash mismatch should mark entry as stale."""
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
# Create knowledge dir
|
|
knowledge_dir = os.path.join(tmpdir, "knowledge")
|
|
os.makedirs(knowledge_dir)
|
|
|
|
# Create repo dir with a file
|
|
repo_dir = os.path.join(tmpdir, "repo")
|
|
os.makedirs(repo_dir)
|
|
|
|
test_file = os.path.join(repo_dir, "test.py")
|
|
with open(test_file, "w") as f:
|
|
f.write("print('hello')")
|
|
|
|
# Create index.json with wrong hash
|
|
index_path = os.path.join(knowledge_dir, "index.json")
|
|
with open(index_path, "w") as f:
|
|
json.dump({
|
|
"facts": [
|
|
{
|
|
"fact": "Test fact",
|
|
"source_file": "test.py",
|
|
"source_hash": "sha256:wronghash",
|
|
"category": "fact",
|
|
"confidence": 0.9
|
|
}
|
|
]
|
|
}, f)
|
|
|
|
# Initialize git repo
|
|
os.system(f"cd {repo_dir} && git init && git add . && git commit -m 'init' 2>/dev/null")
|
|
|
|
result = check_freshness(knowledge_dir, repo_dir, days=1)
|
|
|
|
assert result["summary"]["total"] == 1
|
|
assert result["summary"]["stale"] == 1
|
|
assert result["summary"]["fresh"] == 0
|
|
assert result["stale_entries"][0]["reason"] == "hash_mismatch"
|
|
print("PASS: test_check_freshness_with_hash_mismatch")
|
|
|
|
|
|
def test_check_freshness_missing_source():
|
|
"""Missing source file should mark entry as stale."""
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
# Create knowledge dir
|
|
knowledge_dir = os.path.join(tmpdir, "knowledge")
|
|
os.makedirs(knowledge_dir)
|
|
|
|
# Create repo dir (without the referenced file)
|
|
repo_dir = os.path.join(tmpdir, "repo")
|
|
os.makedirs(repo_dir)
|
|
|
|
# Create index.json referencing nonexistent file
|
|
index_path = os.path.join(knowledge_dir, "index.json")
|
|
with open(index_path, "w") as f:
|
|
json.dump({
|
|
"facts": [
|
|
{
|
|
"fact": "Test fact",
|
|
"source_file": "nonexistent.py",
|
|
"source_hash": "sha256:abc123",
|
|
"category": "fact",
|
|
"confidence": 0.9
|
|
}
|
|
]
|
|
}, f)
|
|
|
|
# Initialize git repo
|
|
os.system(f"cd {repo_dir} && git init && git add . && git commit -m 'init' 2>/dev/null")
|
|
|
|
result = check_freshness(knowledge_dir, repo_dir, days=1)
|
|
|
|
assert result["summary"]["total"] == 1
|
|
assert result["summary"]["stale"] == 1
|
|
assert result["summary"]["fresh"] == 0
|
|
assert result["stale_entries"][0]["reason"] == "source_missing"
|
|
print("PASS: test_check_freshness_missing_source")
|
|
|
|
|
|
def run_all():
|
|
test_compute_file_hash()
|
|
test_compute_file_hash_nonexistent()
|
|
test_load_knowledge_entries_empty()
|
|
test_load_knowledge_entries_from_index()
|
|
test_load_knowledge_entries_from_yaml()
|
|
test_check_freshness_no_changes()
|
|
test_check_freshness_with_hash_mismatch()
|
|
test_check_freshness_missing_source()
|
|
print("\nAll 8 tests passed!")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
run_all() |