1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
import plistlib
import subprocess
from unittest import mock
import pytest
from briefcase.console import Console, LogLevel
from briefcase.exceptions import BriefcaseCommandError
from briefcase.integrations.subprocess import Subprocess
from briefcase.platforms.iOS.xcode import iOSXcodeBuildCommand
@pytest.fixture
def build_command(tmp_path):
return iOSXcodeBuildCommand(
console=Console(),
base_path=tmp_path / "base_path",
data_path=tmp_path / "briefcase",
)
@pytest.mark.parametrize("tool_debug_mode", (True, False))
def test_build_app(build_command, first_app_generated, tool_debug_mode, tmp_path):
"""An iOS App can be built."""
build_command.tools.subprocess = mock.MagicMock(spec_set=Subprocess)
# Mock the host's CPU architecture to ensure it's reflected in the Xcode call
build_command.tools.host_arch = "weird"
# Enable verbose tool logging
if tool_debug_mode:
build_command.tools.console.verbosity = LogLevel.DEEP_DEBUG
build_command.build_app(first_app_generated)
build_command.tools.subprocess.run.assert_called_with(
[
"xcodebuild",
"build",
"-project",
tmp_path
/ "base_path"
/ "build"
/ "first-app"
/ "ios"
/ "xcode"
/ "First App.xcodeproj",
"-configuration",
"Debug",
"-arch",
"weird",
"-sdk",
"iphonesimulator",
"-verbose" if tool_debug_mode else "-quiet",
],
check=True,
filter_func=None if tool_debug_mode else mock.ANY,
)
# The app metadata references the app module
with (tmp_path / "base_path/build/first-app/ios/xcode/Info.plist").open("rb") as f:
plist = plistlib.load(f)
assert plist["MainModule"] == "first_app"
def test_build_app_test_mode(build_command, first_app_generated, tmp_path):
"""An iOS App can be built in test mode."""
build_command.tools.subprocess = mock.MagicMock(spec_set=Subprocess)
# Mock the host's CPU architecture to ensure it's reflected in the Xcode call
build_command.tools.host_arch = "weird"
build_command.build_app(first_app_generated, test_mode=True)
build_command.tools.subprocess.run.assert_called_with(
[
"xcodebuild",
"build",
"-project",
tmp_path
/ "base_path"
/ "build"
/ "first-app"
/ "ios"
/ "xcode"
/ "First App.xcodeproj",
"-configuration",
"Debug",
"-arch",
"weird",
"-sdk",
"iphonesimulator",
"-quiet",
],
check=True,
filter_func=mock.ANY,
)
# The app metadata has been rewritten to reference the test module
with (tmp_path / "base_path/build/first-app/ios/xcode/Info.plist").open("rb") as f:
plist = plistlib.load(f)
assert plist["MainModule"] == "tests.first_app"
def test_build_app_failed(build_command, first_app_generated, tmp_path):
"""If xcodebuild fails, an error is raised."""
# The subprocess.run() call will raise an error
build_command.tools.subprocess = mock.MagicMock(spec_set=Subprocess)
build_command.tools.subprocess.run.side_effect = subprocess.CalledProcessError(
cmd=["xcodebuild", "..."], returncode=1
)
# Mock the host's CPU architecture to ensure it's reflected in the Xcode call
build_command.tools.host_arch = "weird"
with pytest.raises(BriefcaseCommandError):
build_command.build_app(first_app_generated)
build_command.tools.subprocess.run.assert_called_with(
[
"xcodebuild",
"build",
"-project",
tmp_path
/ "base_path"
/ "build"
/ "first-app"
/ "ios"
/ "xcode"
/ "First App.xcodeproj",
"-configuration",
"Debug",
"-arch",
"weird",
"-sdk",
"iphonesimulator",
"-quiet",
],
check=True,
filter_func=mock.ANY,
)
|