130 lines
5.2 KiB
Python
130 lines
5.2 KiB
Python
|
import os
|
||
|
import unittest
|
||
|
from unittest import mock
|
||
|
|
||
|
import jinja2
|
||
|
|
||
|
from pythonforandroid.build import (
|
||
|
Context, RECOMMENDED_TARGET_API, run_pymodules_install,
|
||
|
)
|
||
|
from pythonforandroid.archs import ArchARMv7_a, ArchAarch_64
|
||
|
|
||
|
|
||
|
class TestBuildBasic(unittest.TestCase):
|
||
|
|
||
|
def test_run_pymodules_install_optional_project_dir(self):
|
||
|
"""
|
||
|
Makes sure the `run_pymodules_install()` doesn't crash when the
|
||
|
`project_dir` optional parameter is None, refs #1898
|
||
|
"""
|
||
|
ctx = mock.Mock()
|
||
|
ctx.archs = [ArchARMv7_a(ctx), ArchAarch_64(ctx)]
|
||
|
modules = []
|
||
|
project_dir = None
|
||
|
with mock.patch('pythonforandroid.build.info') as m_info:
|
||
|
assert run_pymodules_install(ctx, ctx.archs[0], modules, project_dir) is None
|
||
|
assert m_info.call_args_list[-1] == mock.call(
|
||
|
'No Python modules and no setup.py to process, skipping')
|
||
|
|
||
|
def test_strip_if_with_debug_symbols(self):
|
||
|
ctx = mock.Mock()
|
||
|
ctx.python_recipe.major_minor_version_string = "python3.6"
|
||
|
ctx.get_site_packages_dir.return_value = "test-doesntexist"
|
||
|
ctx.build_dir = "nonexistant_directory"
|
||
|
ctx.archs = ["arm64"]
|
||
|
|
||
|
modules = ["mymodule"]
|
||
|
project_dir = None
|
||
|
with mock.patch('pythonforandroid.build.info'), \
|
||
|
mock.patch('sh.Command'),\
|
||
|
mock.patch('pythonforandroid.build.open'),\
|
||
|
mock.patch('pythonforandroid.build.shprint'),\
|
||
|
mock.patch('pythonforandroid.build.current_directory'),\
|
||
|
mock.patch('pythonforandroid.build.CythonRecipe') as m_CythonRecipe, \
|
||
|
mock.patch('pythonforandroid.build.project_has_setup_py') as m_project_has_setup_py, \
|
||
|
mock.patch('pythonforandroid.build.run_setuppy_install'):
|
||
|
m_project_has_setup_py.return_value = False
|
||
|
|
||
|
# Make sure it is NOT called when `with_debug_symbols` is true:
|
||
|
ctx.with_debug_symbols = True
|
||
|
assert run_pymodules_install(ctx, ctx.archs[0], modules, project_dir) is None
|
||
|
assert m_CythonRecipe().strip_object_files.called is False
|
||
|
|
||
|
# Make sure strip object files IS called when
|
||
|
# `with_debug_symbols` is fasle:
|
||
|
ctx.with_debug_symbols = False
|
||
|
assert run_pymodules_install(ctx, ctx.archs[0], modules, project_dir) is None
|
||
|
assert m_CythonRecipe().strip_object_files.called is True
|
||
|
|
||
|
|
||
|
class TestTemplates(unittest.TestCase):
|
||
|
|
||
|
def test_android_manifest_xml(self):
|
||
|
args = mock.Mock()
|
||
|
args.min_sdk_version = 12
|
||
|
args.build_mode = 'debug'
|
||
|
args.native_services = ['abcd', ]
|
||
|
args.permissions = []
|
||
|
args.add_activity = []
|
||
|
args.android_used_libs = []
|
||
|
args.meta_data = []
|
||
|
args.extra_manifest_xml = '<tag-a><tag-b></tag-b></tag-a>'
|
||
|
args.extra_manifest_application_arguments = 'android:someParameter="true" android:anotherParameter="false"'
|
||
|
render_args = {
|
||
|
"args": args,
|
||
|
"service": False,
|
||
|
"service_names": [],
|
||
|
"android_api": 1234,
|
||
|
"debug": "debug" in args.build_mode,
|
||
|
"native_services": args.native_services
|
||
|
}
|
||
|
environment = jinja2.Environment(
|
||
|
loader=jinja2.FileSystemLoader('pythonforandroid/bootstraps/sdl2/build/templates/')
|
||
|
)
|
||
|
template = environment.get_template('AndroidManifest.tmpl.xml')
|
||
|
xml = template.render(**render_args)
|
||
|
assert xml.count('android:minSdkVersion="12"') == 1
|
||
|
assert xml.count('android:anotherParameter="false"') == 1
|
||
|
assert xml.count('android:someParameter="true"') == 1
|
||
|
assert xml.count('<tag-a><tag-b></tag-b></tag-a>') == 1
|
||
|
assert xml.count('android:process=":service_') == 0
|
||
|
assert xml.count('targetSdkVersion="1234"') == 1
|
||
|
assert xml.count('android:debuggable="true"') == 1
|
||
|
assert xml.count('<service android:name="abcd" />') == 1
|
||
|
# TODO: potentially some other checks to be added here to cover other "logic" (flags and loops) in the template
|
||
|
|
||
|
|
||
|
class TestContext(unittest.TestCase):
|
||
|
|
||
|
@mock.patch.dict('pythonforandroid.build.Context.env')
|
||
|
@mock.patch('pythonforandroid.build.get_available_apis')
|
||
|
@mock.patch('pythonforandroid.build.ensure_dir')
|
||
|
def test_sdk_ndk_paths(
|
||
|
self,
|
||
|
mock_ensure_dir,
|
||
|
mock_get_available_apis,
|
||
|
):
|
||
|
mock_get_available_apis.return_value = [RECOMMENDED_TARGET_API]
|
||
|
context = Context()
|
||
|
context.setup_dirs(os.getcwd())
|
||
|
context.prepare_build_environment(
|
||
|
user_sdk_dir='sdk',
|
||
|
user_ndk_dir='ndk',
|
||
|
user_android_api=None,
|
||
|
user_ndk_api=None,
|
||
|
)
|
||
|
|
||
|
# The context was supplied with relative SDK and NDK dirs. Check
|
||
|
# that it resolved them to absolute paths.
|
||
|
real_sdk_dir = os.path.join(os.getcwd(), 'sdk')
|
||
|
real_ndk_dir = os.path.join(os.getcwd(), 'ndk')
|
||
|
assert context.sdk_dir == real_sdk_dir
|
||
|
assert context.ndk_dir == real_ndk_dir
|
||
|
|
||
|
context_paths = context.env['PATH'].split(':')
|
||
|
assert context_paths[0:3] == [
|
||
|
f'{real_ndk_dir}/toolchains/llvm/prebuilt/{context.ndk.host_tag}/bin',
|
||
|
real_ndk_dir,
|
||
|
f'{real_sdk_dir}/tools'
|
||
|
]
|