1+ import io
12import sys
23import pytest
34import mock
5+ from pythonforandroid .recipe import Recipe
46from pythonforandroid .toolchain import ToolchainCL
57from pythonforandroid .util import BuildInterruptingException
68
@@ -13,6 +15,10 @@ def patch_argparse_print_help():
1315 return mock .patch ('argparse.ArgumentParser.print_help' )
1416
1517
18+ def patch_sys_stdout ():
19+ return mock .patch ('sys.stdout' , new_callable = io .StringIO )
20+
21+
1622def raises_system_exit ():
1723 return pytest .raises (SystemExit )
1824
@@ -51,6 +57,8 @@ def test_create(self):
5157 'create' ,
5258 '--sdk-dir=/tmp/android-sdk' ,
5359 '--ndk-dir=/tmp/android-ndk' ,
60+ '--bootstrap=service_only' ,
61+ '--requirements=python3' ,
5462 '--dist-name=test_toolchain' ,
5563 ]
5664 with patch_sys_argv (argv ), mock .patch (
@@ -62,8 +70,11 @@ def test_create(self):
6270 ) as m_get_ndk_platform_dir , mock .patch (
6371 'pythonforandroid.build.get_cython_path'
6472 ) as m_get_cython_path , mock .patch (
65- 'pythonforandroid.toolchain.build_dist_from_args'
66- ) as m_build_dist_from_args :
73+ 'pythonforandroid.toolchain.build_recipes'
74+ ) as m_build_recipes , mock .patch (
75+ 'pythonforandroid.bootstraps.service_only.'
76+ 'ServiceOnlyBootstrap.run_distribute'
77+ ) as m_run_distribute :
6778 m_get_available_apis .return_value = [27 ]
6879 m_get_toolchain_versions .return_value = (['4.9' ], True )
6980 m_get_ndk_platform_dir .return_value = (
@@ -74,16 +85,54 @@ def test_create(self):
7485 assert m_get_toolchain_versions .call_args_list == [
7586 mock .call ('/tmp/android-ndk' , mock .ANY )]
7687 assert m_get_cython_path .call_args_list == [mock .call ()]
77- assert m_build_dist_from_args .call_count == 1
88+ build_order = [
89+ 'hostpython3' , 'libffi' , 'openssl' , 'sqlite3' , 'python3' ,
90+ 'genericndkbuild' , 'setuptools' , 'six' , 'pyjnius' , 'android' ,
91+ ]
92+ python_modules = []
93+ context = mock .ANY
94+ project_dir = None
95+ assert m_build_recipes .call_args_list == [
96+ mock .call (
97+ build_order ,
98+ python_modules ,
99+ context ,
100+ project_dir ,
101+ ignore_project_setup_py = False
102+ )
103+ ]
104+ assert m_run_distribute .call_args_list == [mock .call ()]
78105
79106 def test_create_no_sdk_dir (self ):
80107 """
81108 The `--sdk-dir` is mandatory to `create` a distribution.
82109 """
83110 argv = ['toolchain.py' , 'create' ]
84- with mock . patch ( 'sys.argv' , argv ), pytest .raises (
111+ with patch_sys_argv ( argv ), pytest .raises (
85112 BuildInterruptingException
86113 ) as ex_info :
87114 ToolchainCL ()
88115 assert ex_info .value .message == (
89116 'Android SDK dir was not specified, exiting.' )
117+
118+ @pytest .mark .skipif (sys .version_info < (3 , 0 ), reason = "requires python3" )
119+ def test_recipes (self ):
120+ """
121+ Checks the `recipes` command prints out recipes information without crashing.
122+ """
123+ argv = ['toolchain.py' , 'recipes' ]
124+ with patch_sys_argv (argv ), patch_sys_stdout () as m_stdout :
125+ ToolchainCL ()
126+ # check if we have common patterns in the output
127+ expected_strings = (
128+ 'conflicts:' ,
129+ 'depends:' ,
130+ 'kivy' ,
131+ 'optional depends:' ,
132+ 'python3' ,
133+ 'sdl2' ,
134+ )
135+ for expected_string in expected_strings :
136+ assert expected_string in m_stdout .getvalue ()
137+ # deletes static attribute to not mess with other tests
138+ del Recipe .recipes
0 commit comments