Files
Forge-Engine/screens/data_actions/compute_operation.py
T
williamandClaude Sonnet 5 bb84b7b377
Build and deploy / test (push) Failing after 13s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
Phase 0 : factorise compute_new_value + ajoute pytest/node test à la CI
1. Duplication éliminée avant que la Phase 2 (hasard/opérations
   mathématiques) n'en ajoute 6 de plus aux DEUX fichiers : la chaîne
   d'opérations quasi identique entre screens/data_actions/
   apply_data_action.py (champ d'objet) et apply_variable_action.py
   (variable globale) est factorisée dans un nouveau
   compute_operation.py::compute_new_value(operation, current, raw_value,
   is_decimal), réutilisé par les deux. Nouveau tests/test_compute_operation.py
   verrouille le comportement des 7 opérations existantes (dont les cas
   limites : valeur invalide, type décimal vs entier, opération inconnue)
   avant d'en ajouter d'autres.

2. .gitea/workflows/deploy.yml déployait en prod à chaque push sur main
   sans jamais exécuter la suite de tests — rien ne bloquait
   techniquement un commit cassé. Nouveau job "test" (pytest + node:test
   sur la logique pure de static/js/play/, via des conteneurs officiels
   plutôt que des actions du marketplace, cohérent avec le choix déjà
   fait dans ce fichier) tourne sur CHAQUE push (main ET dev, utile pour
   ce dépôt qui travaille sur dev) ; "build-and-push"/"deploy" gagnent un
   "needs: test" et restent réservés à main (filtre sur gitea.ref) — un
   push sur dev ne redéploie jamais la prod, seulement les tests.

Vérifié : 223 tests passent (8 nouveaux), YAML validé.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 15:00:23 +02:00

36 lines
1.6 KiB
Python

def compute_new_value(operation, current, raw_value, is_decimal):
"""Calcule la nouvelle valeur d'un champ d'objet ou d'une variable
globale pour une opération de DATA_OPERATIONS (voir
screens/labels/data_operations.py) — logique partagée par
apply_data_action.py (champ d'objet) et apply_variable_action.py
(variable globale), qui ne diffèrent que par l'origine de `current`
et la façon dont le résultat est persisté. `is_decimal` : True pour
un champ/une variable de type "nombre_decimal" (résultat numérique
gardé en flottant), False sinon (résultat toujours entier).
Lève ValueError si `operation` n'est pas reconnue — à l'appelant de
la traduire en son propre échec (ex. `return False`)."""
if operation == "definir_texte":
return raw_value or ""
if operation == "definir_nombre":
try:
return float(raw_value) if is_decimal else int(float(raw_value))
except (TypeError, ValueError):
return 0
if operation == "definir_bool_vrai":
return 1
if operation == "definir_bool_faux":
return 0
if operation == "basculer_bool":
return 0 if current else 1
if operation in ("incrementer", "decrementer"):
try:
amount = float(raw_value) if raw_value not in (None, "") else 0
except (TypeError, ValueError):
amount = 0
if operation == "decrementer":
amount = -amount
result = (current or 0) + amount
return result if is_decimal else int(result)
raise ValueError(f"opération inconnue : {operation!r}")