field_ios

In-the-field app for Radroots on iOS
git clone https://radroots.dev/git/field_ios.git
Log | Files | Refs | README | LICENSE

test_xcode_selection.py (4745B)


      1 from __future__ import annotations
      2 
      3 import json
      4 import os
      5 import shutil
      6 import subprocess
      7 import sys
      8 import tempfile
      9 import unittest
     10 from pathlib import Path
     11 
     12 ROOT = Path(__file__).resolve().parent.parent
     13 
     14 
     15 class XcodeSelectionTests(unittest.TestCase):
     16     def setUp(self) -> None:
     17         self.directory = tempfile.TemporaryDirectory()
     18         self.addCleanup(self.directory.cleanup)
     19         self.root = Path(self.directory.name)
     20         (self.root / "scripts").mkdir()
     21         shutil.copyfile(ROOT / "scripts/xcode.sh", self.root / "scripts/xcode.sh")
     22         (self.root / "TeraUITests").mkdir()
     23         shutil.copyfile(
     24             ROOT / "TeraUITests/TeraAccessibilityUITests.swift",
     25             self.root / "TeraUITests/TeraAccessibilityUITests.swift",
     26         )
     27         self.arguments = self.root / "arguments.json"
     28         executable = self.root / "xcodebuild"
     29         executable.write_text(
     30             f"#!{sys.executable}\n"
     31             "import json, os, sys\n"
     32             "from pathlib import Path\n"
     33             "Path(os.environ['TEST_XCODE_ARGUMENTS']).write_text(json.dumps(sys.argv[1:]))\n"
     34         )
     35         executable.chmod(0o700)
     36         self.environment = {
     37             **os.environ,
     38             "PATH": f"{self.root}:{os.environ['PATH']}",
     39             "TEST_XCODE_ARGUMENTS": str(self.arguments),
     40             "XCODE_DERIVED_DATA": str(self.root / "derived"),
     41             "XCODE_SOURCE_PACKAGES": str(self.root / "sources"),
     42             "XCODE_PACKAGE_CACHE": str(self.root / "cache"),
     43         }
     44 
     45     def run_selector(self, target: str, *selector: str) -> subprocess.CompletedProcess:
     46         return subprocess.run(
     47             [
     48                 "/bin/bash",
     49                 str(self.root / "scripts/xcode.sh"),
     50                 "project-test",
     51                 "platform=iOS Simulator,id=078A0172-207D-4EA6-8767-74DF7C42A73A",
     52                 target,
     53                 *selector,
     54             ],
     55             env=self.environment,
     56             capture_output=True,
     57             text=True,
     58             check=False,
     59         )
     60 
     61     def assert_selection(self, target: str, *selector: str) -> None:
     62         result = self.run_selector(target, *selector)
     63         self.assertEqual(result.returncode, 0, result.stderr)
     64         arguments = json.loads(self.arguments.read_text())
     65         expected = target + (f"/{selector[0]}" if selector and selector[0] else "")
     66         self.assertIn(f"-only-testing:{expected}", arguments)
     67         self.assertEqual(arguments[-1], "test")
     68         self.assertIn("-disableAutomaticPackageResolution", arguments)
     69         self.assertIn("-onlyUsePackageVersionsFromResolvedFile", arguments)
     70         for flag, variable in [
     71             ("-derivedDataPath", "XCODE_DERIVED_DATA"),
     72             ("-clonedSourcePackagesDirPath", "XCODE_SOURCE_PACKAGES"),
     73             ("-packageCachePath", "XCODE_PACKAGE_CACHE"),
     74         ]:
     75             self.assertEqual(
     76                 arguments[arguments.index(flag) + 1], self.environment[variable]
     77             )
     78 
     79     def test_default_full_targets_and_empty_make_argument_are_preserved(self) -> None:
     80         self.assert_selection("TeraTests")
     81         self.assert_selection("TeraUITests")
     82         self.assert_selection("TeraUITests", "")
     83 
     84     def test_owned_class_and_method_select_exact_native_case(self) -> None:
     85         self.assert_selection("TeraUITests", "TeraAccessibilityUITests")
     86         self.assert_selection(
     87             "TeraUITests",
     88             "TeraAccessibilityUITests/testActualPhotoDescriptionRemainsEditableAcrossSaveFailureAndRecovery",
     89         )
     90 
     91     def test_unknown_or_injected_selector_never_launches_xcode(self) -> None:
     92         for target, selector in [
     93             ("TeraTests", "TeraAccessibilityUITests"),
     94             ("Unknown", "TeraAccessibilityUITests"),
     95             ("TeraUITests", "MissingUITests"),
     96             ("TeraUITests", "TeraAccessibilityUITests/testMissing"),
     97             ("TeraUITests", "../TeraAccessibilityUITests"),
     98             ("TeraUITests", "TeraAccessibilityUITests/"),
     99             (
    100                 "TeraUITests",
    101                 "TeraAccessibilityUITests/testMissing/-skip-testing:TeraUITests",
    102             ),
    103             ("TeraUITests", "TeraAccessibilityUITests;touch marker"),
    104         ]:
    105             with self.subTest(target=target, selector=selector):
    106                 result = self.run_selector(target, selector)
    107                 self.assertNotEqual(result.returncode, 0)
    108                 self.assertFalse(self.arguments.exists())
    109 
    110     def test_extra_arguments_never_launch_xcode(self) -> None:
    111         result = self.run_selector("TeraUITests", "", "-skip-testing:TeraUITests")
    112         self.assertNotEqual(result.returncode, 0)
    113         self.assertFalse(self.arguments.exists())
    114 
    115 
    116 if __name__ == "__main__":
    117     unittest.main()