erplibre/test/test_install_sh_confirm.py

84 lines
2.5 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
# © 2026 TechnoLibre (http://www.technolibre.ca)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
"""La question qu'install.sh pose avant l'installation du venv d'outillage.
L'installation peut SUPPRIMER un .venv.erplibre existant : elle ne part que
sur un oui explicite. La réponse se donne en français ou en anglais (o, oui,
y, yes, toute casse) ; Entrée seule vaut non. Sans terminal sur l'entrée,
personne ne peut consentir, et la réponse est non sans question posée.
"""
import os
import select
import subprocess
import unittest
from pathlib import Path
RACINE = Path(__file__).resolve().parent.parent
SCRIPT = (
"source <(sed -n '/^el_confirmer()/,/^}/p' install.sh); "
'el_confirmer "Lancer ?"'
)
def repondre_au_terminal(reponse):
"""Lance el_confirmer sur un pseudo-terminal, y tape la réponse.
Rend le code de sortie et ce que le terminal a affiché.
"""
maitre, esclave = os.openpty()
proc = subprocess.Popen(
["bash", "-c", SCRIPT],
cwd=RACINE,
stdin=esclave,
stdout=esclave,
stderr=esclave,
)
os.close(esclave)
os.write(maitre, (reponse + "\n").encode())
code = proc.wait(timeout=10)
lu = b""
while select.select([maitre], [], [], 0.2)[0]:
try:
morceau = os.read(maitre, 4096)
except OSError:
break
if not morceau:
break
lu += morceau
os.close(maitre)
return code, lu.decode(errors="replace")
class TestConfirmer(unittest.TestCase):
def test_oui_en_francais_et_en_anglais(self):
for reponse in ("o", "O", "oui", "Oui", "y", "Y", "yes", "YES"):
with self.subTest(reponse=reponse):
self.assertEqual(repondre_au_terminal(reponse)[0], 0)
def test_entree_seule_et_non_refusent(self):
for reponse in ("", "n", "non", "no", "ouais", "x"):
with self.subTest(reponse=reponse):
self.assertEqual(repondre_au_terminal(reponse)[0], 1)
def test_la_question_annonce_le_defaut(self):
self.assertIn("Lancer ? [o/N]", repondre_au_terminal("n")[1])
def test_sans_terminal_la_reponse_est_non(self):
proc = subprocess.run(
["bash", "-c", SCRIPT],
cwd=RACINE,
input="o\n",
capture_output=True,
text=True,
check=False,
)
self.assertEqual(proc.returncode, 1)
self.assertNotIn("[o/N]", proc.stdout)
if __name__ == "__main__":
unittest.main()