Dans la réécriture en Java de Lilies, un clic droit avec une tulipe dans le vide était censé la mettre en banque. Il ne se passait rien. Le module avait cinq tests unitaires et tous passaient.
À quoi ressemblait le gestionnaire
@EventHandler(ignoreCancelled = true)
public void onUse(PlayerInteractEvent e) {
if (e.getAction() != Action.RIGHT_CLICK_AIR) return;
// bank the tulip ...
}
ignoreCancelled = true est une habitude dans les plugins Bukkit : si un autre plugin a annulé
l'événement, on l'ignore. Ça semble inoffensif. Ici, ça a rendu tout le gestionnaire inactif.
Pourquoi il ne s'exécutait jamais
Pour PlayerInteractEvent, isCancelled() n'est pas un drapeau séparé. Il renvoie
vrai quand useInteractedBlock() vaut DENY. Quand on clique dans le vide, il n'y a
pas de bloc, et Paper construit l'événement avec DENY déjà défini. Donc chaque clic dans le vide
arrive déjà annulé, et un gestionnaire qui ignore les événements annulés n'en voit jamais un.
Les tests unitaires ne pouvaient pas l'attraper. Ils construisaient l'événement à la main et appelaient la
méthode du gestionnaire directement, donc l'événement n'était jamais annulé et la vérification
ignoreCancelled ne s'exécutait jamais du tout.
Comment ça a été trouvé
Un test de démarrage. Il lance un vrai serveur avec tous les jars de plugins chargés et déclenche de vrais événements via le gestionnaire de plugins, le même chemin que le clic d'un joueur. Il a échoué dès la première exécution. Chercher dans le reste de la suite a trouvé le même drapeau sur sept gestionnaires, y compris celui qui ramasse les gains d'argent.
La correction
@EventHandler
public void onUse(PlayerInteractEvent e) {
if (e.getAction() == Action.RIGHT_CLICK_BLOCK && e.isCancelled()) return;
// ...
}
Retirer le drapeau et dire ce que l'on veut vraiment. Un clic sur bloc refusé ne fait toujours rien, et les clics dans le vide passent.
La leçon
Un test qui appelle un gestionnaire directement saute tout ce que le framework fait avant que le gestionnaire ne s'exécute. Gardez au moins un test qui passe par la vraie porte d'entrée.