"""Test the validate_yesno config-validation helper. The installer had four near-identical blocks validating that AUTOLOGIN, NO_GPU_DRIVERS, INSTALL_CLAUDE_CODE, and INSTALL_DEVICE_UDEV_RULES are empty or exactly yes/no. validate_yesno collapses them into one testable helper: empty passes (the default), yes/no pass, anything else fails with a named error. Method: sed-extract validate_yesno from the real `archsetup` and drive it with plain args. Run from repo root: python3 -m unittest tests.installer-steps.test_validate_yesno """ import os import subprocess import textwrap import unittest REPO_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")) ARCHSETUP = os.path.join(REPO_ROOT, "archsetup") def run(name, value): script = textwrap.dedent(f"""\ source <(sed -n '/^validate_yesno() {{/,/^}}/p' "{ARCHSETUP}") validate_yesno {name!r} {value!r} echo "RC=$?" """) return subprocess.run( ["bash", "-c", script], capture_output=True, text=True, timeout=10, ) class ValidateYesno(unittest.TestCase): def test_yes_passes(self): self.assertIn("RC=0", run("AUTOLOGIN", "yes").stdout) def test_no_passes(self): self.assertIn("RC=0", run("AUTOLOGIN", "no").stdout) def test_empty_passes(self): self.assertIn("RC=0", run("AUTOLOGIN", "").stdout) def test_other_value_fails_with_named_error(self): r = run("NO_GPU_DRIVERS", "maybe") self.assertNotIn("RC=0", r.stdout) self.assertIn("NO_GPU_DRIVERS", r.stderr) self.assertIn("maybe", r.stderr) def test_capitalized_yes_fails(self): # The values are compared exactly; "Yes" is not accepted. self.assertNotIn("RC=0", run("AUTOLOGIN", "Yes").stdout) if __name__ == "__main__": unittest.main()