erplibre/test/test_version.py
Mathieu Benoit cfbdd9406e [REF] format : passer l'outillage et les tests sous ruff
Le formateur de ce dépôt est ruff depuis qu'il remplace black, qui ne connaît
aucune cible au-delà de py313 ; ce passage applique sa norme à l'arbre entier,
d'un coup, pour qu'aucun commit de fond n'ait à porter du style. L'écart tient
presque entièrement aux chaînes coupées à la main que ruff recolle quand elles
tiennent sur une ligne, et aux « with » multiples qu'il regroupe : aucune
valeur ne change, et les clés de traduction non plus.
Vérifié : la suite unitaire reste verte après le passage, et le contrôle de
syntaxe ne signale rien.

--- EN ---

This repository's formatter is ruff since it replaced black, which knows no
target beyond py313; this pass applies its standard to the whole tree at once,
so that no substantive commit has to carry style. The difference is almost
entirely the hand-split strings ruff joins back when they fit on one line, and
the multiple "with" it merges: no value changes, nor do the translation keys.
Checked: the unit suite stays green after the pass, and the syntax check
reports nothing.

Assisted-by: Claude Opus 5
2026-09-24 14:40:38 -04:00

246 lines
8 KiB
Python

#!/usr/bin/env python3
# © 2026 TechnoLibre (http://www.technolibre.ca)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
import json
import os
import sys
import tempfile
import unittest
from unittest.mock import MagicMock, patch
from script.version.update_env_version import (
ADDONS_TEMPLATE_FILE,
ERPLIBRE_TEMPLATE_VERSION,
MANIFEST_TEMPLATE_FILE,
ODOO_TEMPLATE_FILE,
POETRY_LOCK_TEMPLATE_FILE,
PYPROJECT_TEMPLATE_FILE,
VENV_TEMPLATE_FILE,
Update,
die,
remove_dot_path,
)
class TestRemoveDotPath(unittest.TestCase):
def test_removes_dot_slash(self):
self.assertEqual(remove_dot_path("./path/to/file"), "path/to/file")
def test_no_dot_slash(self):
self.assertEqual(remove_dot_path("path/to/file"), "path/to/file")
def test_just_dot_slash(self):
self.assertEqual(remove_dot_path("./"), "")
def test_nested_dot_slash(self):
self.assertEqual(remove_dot_path("./a/./b"), "a/./b")
def test_empty_string(self):
self.assertEqual(remove_dot_path(""), "")
def test_single_file(self):
self.assertEqual(remove_dot_path("file.txt"), "file.txt")
class TestDie(unittest.TestCase):
def test_die_true_exits(self):
with self.assertRaises(SystemExit) as cm:
die(True, "error message")
self.assertEqual(cm.exception.code, 1)
def test_die_false_no_exit(self):
die(False, "no error")
def test_die_custom_code(self):
with self.assertRaises(SystemExit) as cm:
die(True, "error", code=42)
self.assertEqual(cm.exception.code, 42)
class TestConstants(unittest.TestCase):
def test_erplibre_template_version(self):
result = ERPLIBRE_TEMPLATE_VERSION % ("18.0", "3.12.10")
self.assertEqual(result, "odoo18.0_python3.12.10")
def test_venv_template(self):
result = VENV_TEMPLATE_FILE % "odoo18.0_python3.12.10"
self.assertEqual(result, ".venv.odoo18.0_python3.12.10")
def test_manifest_template(self):
result = MANIFEST_TEMPLATE_FILE % "18.0"
self.assertEqual(result, "default.dev.odoo18.0.xml")
def test_pyproject_template(self):
result = PYPROJECT_TEMPLATE_FILE % "odoo18.0_python3.12.10"
self.assertEqual(result, "pyproject.odoo18.0_python3.12.10.toml")
def test_poetry_lock_template(self):
result = POETRY_LOCK_TEMPLATE_FILE % "odoo18.0_python3.12.10"
self.assertEqual(result, "poetry.odoo18.0_python3.12.10.lock")
def test_addons_template(self):
result = ADDONS_TEMPLATE_FILE % "18.0"
self.assertEqual(result, "odoo18.0/addons")
def test_odoo_template(self):
result = ODOO_TEMPLATE_FILE % "18.0"
self.assertEqual(result, "odoo18.0")
class TestUpdateValidateVersion(unittest.TestCase):
"""Test validate_version() sets expected paths based on version data."""
def _make_update(self, data_version, config_args=None):
with patch("sys.argv", ["prog"]):
update = Update()
update.data_version = data_version
if config_args:
for k, v in config_args.items():
setattr(update.config, k, v)
return update
def test_explicit_erplibre_version(self):
data = {
"odoo18.0_python3.12.10": {
"odoo_version": "18.0",
"python_version": "3.12.10",
"poetry_version": "2.1.3",
"default": True,
}
}
update = self._make_update(
data,
{"erplibre_version": "odoo18.0_python3.12.10"},
)
update.validate_version()
self.assertEqual(update.new_version_odoo, "18.0")
self.assertEqual(update.new_version_python, "3.12.10")
self.assertEqual(update.new_version_poetry, "2.1.3")
self.assertEqual(update.new_version_erplibre, "odoo18.0_python3.12.10")
def test_explicit_odoo_version(self):
data = {}
update = self._make_update(data, {"odoo_version": "17.0"})
update.new_version_python = "3.10.18"
update.config.python_version = "3.10.18"
update.validate_version()
self.assertEqual(update.new_version_odoo, "17.0")
def test_default_version_fallback(self):
data = {
"odoo18.0_python3.12.10": {
"odoo_version": "18.0",
"python_version": "3.12.10",
"poetry_version": "2.1.3",
"default": True,
}
}
update = self._make_update(data)
update.detected_version_erplibre = None
update.validate_version()
self.assertEqual(update.new_version_odoo, "18.0")
def test_detected_version_used(self):
data = {
"odoo17.0_python3.10.18": {
"odoo_version": "17.0",
"python_version": "3.10.18",
"poetry_version": "1.8.3",
}
}
update = self._make_update(data)
update.detected_version_erplibre = "odoo17.0_python3.10.18"
update.validate_version()
self.assertEqual(update.new_version_odoo, "17.0")
self.assertEqual(update.new_version_python, "3.10.18")
def test_expected_paths_set(self):
data = {
"odoo18.0_python3.12.10": {
"odoo_version": "18.0",
"python_version": "3.12.10",
"poetry_version": "2.1.3",
"default": True,
}
}
update = self._make_update(
data,
{"erplibre_version": "odoo18.0_python3.12.10"},
)
update.validate_version()
self.assertIn(
"default.dev.odoo18.0.xml", update.expected_manifest_name
)
self.assertIn("requirement", update.expected_pyproject_path)
self.assertIn("requirement", update.expected_poetry_lock_path)
self.assertEqual(update.expected_odoo_name, "odoo18.0")
class TestUpdateDetectVersion(unittest.TestCase):
def test_detect_version_no_files(self):
with patch("sys.argv", ["prog"]):
update = Update()
with patch("os.path.exists", return_value=False):
result = update.detect_version()
self.assertFalse(result)
def test_detect_version_matching(self):
with patch("sys.argv", ["prog"]):
update = Update()
update.data_version = {
"odoo18.0_python3.12.10": {
"odoo_version": "18.0",
"python_version": "3.12.10",
}
}
tmpdir = tempfile.mkdtemp()
py_file = os.path.join(tmpdir, "python_ver")
odoo_file = os.path.join(tmpdir, "odoo_ver")
poetry_file = os.path.join(tmpdir, "poetry_ver")
with open(py_file, "w") as f:
f.write("3.12.10")
with open(odoo_file, "w") as f:
f.write("18.0")
with open(poetry_file, "w") as f:
f.write("2.1.3")
with (
patch(
"script.version.update_env_version.VERSION_PYTHON_FILE",
py_file,
),
patch(
"script.version.update_env_version.VERSION_ODOO_FILE",
odoo_file,
),
patch(
"script.version.update_env_version.VERSION_POETRY_FILE",
poetry_file,
),
patch(
"script.version.update_env_version.INSTALLED_ODOO_VERSION_FILE",
os.path.join(tmpdir, "nonexist"),
),
):
result = update.detect_version()
self.assertTrue(result)
self.assertEqual(
update.detected_version_erplibre, "odoo18.0_python3.12.10"
)
class TestUpdatePrintLog(unittest.TestCase):
def test_empty_log(self):
with patch("sys.argv", ["prog"]):
update = Update()
update.print_log()
def test_with_entries(self):
with patch("sys.argv", ["prog"]):
update = Update()
update.execute_log = ["entry1", "entry2"]
update.print_log()
if __name__ == "__main__":
unittest.main()