1
0

test_emojis_models.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. """Tests des emojis du serveur et des noms de modèles. Lancer depuis la racine du projet : python -m unittest"""
  2. import unittest
  3. from types import SimpleNamespace
  4. from bot.emojis import discord_emojis, emoji_names, short_emojis, usable_emojis
  5. from bot.models import display_name, is_known, thinking_off
  6. class FakeEmoji:
  7. """Emoji personnalisé, écrit comme discord.Emoji (<:nom:id>, <a:nom:id> s'il est animé)."""
  8. def __init__(self, name: str, id: int, animated: bool = False, available: bool = True, roles=()):
  9. self.name, self.id, self.animated, self.available, self.roles = name, id, animated, available, list(roles)
  10. def __str__(self) -> str:
  11. return f"<{'a' if self.animated else ''}:{self.name}:{self.id}>"
  12. def guild(*emojis: FakeEmoji, roles=()) -> SimpleNamespace:
  13. return SimpleNamespace(emojis=list(emojis), me=SimpleNamespace(roles=list(roles)))
  14. HAP = FakeEmoji("hap", 111)
  15. DANCE = FakeEmoji("dance", 222, animated=True)
  16. GUILD = guild(HAP, DANCE)
  17. class DiscordEmojisTest(unittest.TestCase):
  18. def test_name_replaced(self):
  19. self.assertEqual(discord_emojis("Coucou :hap: !", GUILD), "Coucou <:hap:111> !")
  20. def test_animated(self):
  21. self.assertEqual(discord_emojis(":dance:", GUILD), "<a:dance:222>")
  22. def test_several_in_a_row(self):
  23. self.assertEqual(discord_emojis(":hap::dance: :hap:", GUILD), "<:hap:111><a:dance:222> <:hap:111>")
  24. def test_case_tolerated(self):
  25. self.assertEqual(discord_emojis(":Hap: :DANCE:", GUILD), "<:hap:111> <a:dance:222>")
  26. def test_unknown_name_kept(self):
  27. self.assertEqual(discord_emojis(":inconnu: à 12:30:45", GUILD), ":inconnu: à 12:30:45")
  28. def test_code_kept(self):
  29. for text in ("```\n:hap:\n```", "```py\nprint(':hap:')\n```", "`:hap:`"):
  30. with self.subTest(text):
  31. self.assertEqual(discord_emojis(text, GUILD), text)
  32. self.assertEqual(discord_emojis("`:hap:` donne :hap:", GUILD), "`:hap:` donne <:hap:111>")
  33. def test_already_a_code(self):
  34. self.assertEqual(discord_emojis("<:hap:111> <a:dance:222>", GUILD), "<:hap:111> <a:dance:222>")
  35. def test_no_guild(self):
  36. self.assertEqual(discord_emojis("Coucou :hap: !", None), "Coucou :hap: !")
  37. self.assertEqual(discord_emojis("Coucou :hap: !", guild()), "Coucou :hap: !")
  38. def test_unusable_emoji_not_replaced(self):
  39. hidden = guild(FakeEmoji("hap", 111, available=False), FakeEmoji("vip", 333, roles=["role_vip"]))
  40. self.assertEqual(discord_emojis(":hap: :vip:", hidden), ":hap: :vip:")
  41. class ShortEmojisTest(unittest.TestCase):
  42. def test_codes_replaced_by_names(self):
  43. self.assertEqual(short_emojis("Coucou <:hap:111> <a:dance:222> !"), "Coucou :hap: :dance: !")
  44. def test_text_without_emoji_kept(self):
  45. self.assertEqual(short_emojis("Coucou :hap: <@123> <#456>"), "Coucou :hap: <@123> <#456>")
  46. def test_round_trip(self):
  47. text = "Coucou :hap: et :dance: !"
  48. self.assertEqual(short_emojis(discord_emojis(text, GUILD)), text)
  49. class UsableEmojisTest(unittest.TestCase):
  50. def test_sorted_by_name(self):
  51. zebra, apple, upper = FakeEmoji("zebre", 1), FakeEmoji("abricot", 2), FakeEmoji("Banane", 3)
  52. self.assertEqual(usable_emojis(guild(zebra, apple, upper)), [apple, upper, zebra])
  53. self.assertEqual(emoji_names(guild(zebra, apple, upper)), ["abricot", "Banane", "zebre"])
  54. def test_unavailable_excluded(self):
  55. self.assertEqual(emoji_names(guild(HAP, FakeEmoji("parti", 4, available=False))), ["hap"])
  56. def test_roles(self):
  57. vip = FakeEmoji("vip", 5, roles=["role_vip"])
  58. self.assertEqual(emoji_names(guild(HAP, vip)), ["hap"])
  59. self.assertEqual(emoji_names(guild(HAP, vip, roles=["role_autre"])), ["hap"])
  60. self.assertEqual(emoji_names(guild(HAP, vip, roles=["role_autre", "role_vip"])), ["hap", "vip"])
  61. def test_bot_not_a_member(self):
  62. vip = FakeEmoji("vip", 5, roles=["role_vip"])
  63. self.assertEqual(emoji_names(SimpleNamespace(emojis=[HAP, vip], me=None)), ["hap"])
  64. def test_no_guild(self):
  65. self.assertEqual(usable_emojis(None), [])
  66. self.assertEqual(emoji_names(None), [])
  67. class ModelsTest(unittest.TestCase):
  68. def test_is_known(self):
  69. for model in ("claude-sonnet-5-5", "claude-haiku-5-5", "claude-opus-5-5"):
  70. with self.subTest(model):
  71. self.assertTrue(is_known(model))
  72. for model in ("claude-sonnet-5-6", "claude-sonet-5-5", "gpt-4", ""):
  73. with self.subTest(model):
  74. self.assertFalse(is_known(model))
  75. def test_display_name(self):
  76. names = {
  77. "claude-sonnet-5-5": "Sonnet 5.5",
  78. "claude-opus-5-5": "Opus 5.5",
  79. "claude-sonnet-4-5-20250929": "Sonnet 4.5",
  80. "claude-opus-5": "Opus 5",
  81. "claude-opus-4-20250514": "Opus 4",
  82. "claude-haiku-4-10": "Haiku 4.10",
  83. }
  84. for model, name in names.items():
  85. with self.subTest(model):
  86. self.assertEqual(display_name(model), name)
  87. def test_display_name_unusual_id_kept(self):
  88. for model in ("claude-3-5-sonnet-20241022", "claude-sonnet-5-5-latest", "Claude-Sonnet-5-5",
  89. "claude-sonnet", "gpt-4", ""):
  90. with self.subTest(model):
  91. self.assertEqual(display_name(model), model)
  92. def test_thinking_off(self):
  93. self.assertEqual(thinking_off("claude-sonnet-5-5"), {"type": "between_tools"})
  94. self.assertIsNone(thinking_off("claude-opus-5-5"))
  95. self.assertEqual(thinking_off("claude-haiku-5-5"), {"type": "disabled"})
  96. self.assertEqual(thinking_off("claude-opus-4-8"), {"type": "disabled"}) # modèle plus ancien
  97. self.assertEqual(thinking_off("modele-inconnu"), {"type": "disabled"})
  98. if __name__ == "__main__":
  99. unittest.main()