Files
gh-atournayre-claude-market…/skills/git-pr/tests/test_milestone_cache.py
2025-11-29 17:58:54 +08:00

211 lines
6.8 KiB
Python

#!/usr/bin/env python3
"""Tests unitaires pour milestone_cache"""
import json
import os
import sys
import tempfile
import unittest
from pathlib import Path
from unittest.mock import patch, MagicMock
sys.path.insert(0, str(Path(__file__).parent.parent / "scripts"))
from milestone_cache import MilestoneCache, CACHE_DIR, CACHE_FILE
class TestNormalizeSemver(unittest.TestCase):
"""Test normalisation semver"""
def test_normalise_un_chiffre_ajoute_zero_zero(self):
cache = MilestoneCache()
self.assertEqual(cache.normalize_semver("26"), "26.0.0")
def test_normalise_deux_chiffres_ajoute_zero(self):
cache = MilestoneCache()
self.assertEqual(cache.normalize_semver("26.1"), "26.1.0")
def test_normalise_trois_chiffres_reste_identique(self):
cache = MilestoneCache()
self.assertEqual(cache.normalize_semver("26.1.1"), "26.1.1")
def test_normalise_conserve_suffixe(self):
cache = MilestoneCache()
self.assertEqual(cache.normalize_semver("26.0.0 (Avenant)"), "26.0.0 (Avenant)")
class TestGenerateAliases(unittest.TestCase):
"""Test génération aliases stricte"""
def test_genere_alias_pour_titre_avec_parentheses(self):
cache = MilestoneCache()
self.assertEqual(cache.generate_aliases("26.1.1 (Hotfix)"), ["26.1.1"])
def test_genere_alias_pour_titre_avec_avenant(self):
cache = MilestoneCache()
self.assertEqual(cache.generate_aliases("26.0.0 (Avenant)"), ["26.0.0"])
def test_genere_pas_alias_pour_titre_sans_parentheses(self):
cache = MilestoneCache()
self.assertEqual(cache.generate_aliases("26.1.0"), [])
def test_genere_pas_alias_pour_titre_non_semver(self):
cache = MilestoneCache()
self.assertEqual(cache.generate_aliases("Release Candidate"), [])
class TestFindExactMatch(unittest.TestCase):
"""Test recherche exacte"""
def test_trouve_par_titre_exact(self):
cache = MilestoneCache()
cache.cache = {
"milestones": [
{"number": 42, "title": "26.0.0 (Avenant)", "aliases": ["26.0.0"]}
]
}
result = cache.find("26.0.0 (Avenant)")
self.assertIsNotNone(result)
self.assertEqual(result["number"], 42)
def test_ne_trouve_pas_si_titre_different(self):
cache = MilestoneCache()
cache.cache = {
"milestones": [
{"number": 42, "title": "26.0.0 (Avenant)", "aliases": ["26.0.0"]}
]
}
result = cache.find("27.0.0")
self.assertIsNone(result)
class TestFindByAlias(unittest.TestCase):
"""Test recherche par alias"""
def test_query_trouve_via_alias(self):
cache = MilestoneCache()
cache.cache = {
"milestones": [
{"number": 43, "title": "26.1.1 (Hotfix)", "aliases": ["26.1.1"]}
]
}
result = cache.find("26.1.1")
self.assertIsNotNone(result)
self.assertEqual(result["title"], "26.1.1 (Hotfix)")
def test_query_trouve_milestone_sans_parentheses(self):
cache = MilestoneCache()
cache.cache = {
"milestones": [
{"number": 44, "title": "26.1.0", "aliases": []}
]
}
result = cache.find("26.1.0")
self.assertIsNotNone(result)
self.assertEqual(result["number"], 44)
class TestNoCollisionMatch(unittest.TestCase):
"""Test pas de collision entre versions"""
def test_query_partielle_ne_trouve_pas_version_complete(self):
cache = MilestoneCache()
cache.cache = {
"milestones": [
{"number": 43, "title": "26.1.1 (Hotfix)", "aliases": ["26.1.1"]}
]
}
result = cache.find("26.1")
self.assertIsNone(result)
def test_query_majeure_ne_trouve_pas_version_mineure(self):
cache = MilestoneCache()
cache.cache = {
"milestones": [
{"number": 42, "title": "26.0.0 (Avenant)", "aliases": ["26.0.0"]}
]
}
result = cache.find("26")
self.assertIsNone(result)
class TestFindWithNormalization(unittest.TestCase):
"""Test recherche avec normalisation"""
def test_query_normalisee_trouve_milestone(self):
cache = MilestoneCache()
cache.cache = {
"milestones": [
{"number": 44, "title": "26.1.0", "aliases": []}
]
}
normalized = cache.normalize_semver("26.1")
result = cache.find(normalized)
self.assertIsNotNone(result)
self.assertEqual(result["title"], "26.1.0")
def test_query_majeure_normalisee_trouve_avenant(self):
cache = MilestoneCache()
cache.cache = {
"milestones": [
{"number": 42, "title": "26.0.0 (Avenant)", "aliases": ["26.0.0"]}
]
}
normalized = cache.normalize_semver("26")
result = cache.find(normalized)
self.assertIsNotNone(result)
self.assertEqual(result["title"], "26.0.0 (Avenant)")
class TestCachePersistence(unittest.TestCase):
"""Test sauvegarde/chargement"""
def test_charge_cache_vide_si_fichier_inexistant(self):
cache = MilestoneCache()
cache.cache = {"milestones": []}
self.assertEqual(cache.cache["milestones"], [])
class TestCreateMilestone(unittest.TestCase):
"""Test création milestone inexistant"""
@patch('milestone_cache.subprocess.run')
def test_cree_milestone_via_api(self, mock_run):
mock_run.side_effect = [
MagicMock(stdout="git@github.com:owner/repo.git\n"),
MagicMock(stdout='{"number": 50, "title": "99.0.0"}')
]
cache = MilestoneCache()
result = cache.create("99.0.0")
self.assertEqual(result["number"], 50)
self.assertEqual(result["title"], "99.0.0")
class TestCreateWithNormalization(unittest.TestCase):
"""Test création avec normalisation semver"""
@patch('milestone_cache.subprocess.run')
def test_cree_milestone_normalise_depuis_majeure(self, mock_run):
mock_run.side_effect = [
MagicMock(stdout="git@github.com:owner/repo.git\n"),
MagicMock(stdout='{"number": 51, "title": "26.0.0"}')
]
cache = MilestoneCache()
normalized = cache.normalize_semver("26")
result = cache.create(normalized)
self.assertEqual(result["title"], "26.0.0")
@patch('milestone_cache.subprocess.run')
def test_cree_milestone_normalise_depuis_mineure(self, mock_run):
mock_run.side_effect = [
MagicMock(stdout="git@github.com:owner/repo.git\n"),
MagicMock(stdout='{"number": 52, "title": "26.1.0"}')
]
cache = MilestoneCache()
normalized = cache.normalize_semver("26.1")
result = cache.create(normalized)
self.assertEqual(result["title"], "26.1.0")
if __name__ == "__main__":
unittest.main()