1
1
import os
2
- import pytest
3
- import codecs
4
2
import tempfile
3
+ from unittest import mock
4
+
5
+ import pytest
6
+
5
7
import buildozer as buildozer_module
6
8
from buildozer import Buildozer
7
9
from buildozer .targets .android import TargetAndroid
8
- from unittest import mock
9
10
10
11
11
12
def patch_buildozer (method ):
@@ -51,25 +52,110 @@ def patch_platform(platform):
51
52
52
53
53
54
class TestTargetAndroid :
55
+
54
56
@staticmethod
55
57
def default_specfile_path ():
56
58
return os .path .join (os .path .dirname (buildozer_module .__file__ ), "default.spec" )
57
59
58
60
def setup_method (self ):
59
- """Creates a temporary spec file containing the content of the default.spec."""
60
- self .specfile = tempfile .NamedTemporaryFile (suffix = ".spec" , delete = False )
61
- default_spec = codecs .open (self .default_specfile_path (), encoding = "utf-8" )
62
- self .specfile .write (default_spec .read ().encode ("utf-8" ))
63
- self .specfile .close ()
64
- self .buildozer = Buildozer (filename = self .specfile .name , target = "android" )
65
- self .target_android = TargetAndroid (self .buildozer )
61
+ """
62
+ Create a temporary directory that will contain the spec file and will
63
+ serve as the root_dir.
64
+ """
65
+ self .temp_dir = tempfile .TemporaryDirectory ()
66
66
67
67
def tear_method (self ):
68
- """Deletes the temporary spec file."""
69
- os .unlink (self .specfile .name )
68
+ """
69
+ Remove the temporary directory created in self.setup_method.
70
+ """
71
+ self .temp_dir .cleanup ()
72
+
73
+ def init_target (self , options = None ):
74
+ """
75
+ Create a buildozer.spec file in the temporary directory and init the
76
+ Buildozer and TargetAndroid instances.
77
+
78
+ The optional argument can be used to overwrite the config options in
79
+ the buildozer.spec file, e.g.:
80
+
81
+ self.init_target({'title': 'Test App'})
82
+
83
+ will replace line 4 of the default spec file.
84
+ """
85
+ if options is None :
86
+ options = {}
87
+
88
+ spec_path = os .path .join (self .temp_dir .name , 'buildozer.spec' )
89
+
90
+ with open (TestTargetAndroid .default_specfile_path ()) as f :
91
+ default_spec = f .readlines ()
92
+
93
+ spec = []
94
+ for line in default_spec :
95
+ if line .strip ():
96
+ key = line .split ()[0 ]
97
+
98
+ if key .startswith ('#' ):
99
+ key = key [1 :]
100
+
101
+ if key in options :
102
+ line = '{} = {}\n ' .format (key , options [key ])
103
+
104
+ spec .append (line )
105
+
106
+ with open (spec_path , 'w' ) as f :
107
+ f .writelines (spec )
108
+
109
+ self .buildozer = Buildozer (filename = spec_path , target = 'android' )
110
+ self .target_android = TargetAndroid (self .buildozer )
111
+
112
+ def call_build_package (self ):
113
+ """
114
+ Call the build_package() method of the tested TargetAndroid instance,
115
+ patching the functions that would otherwise produce side-effects.
116
+
117
+ Return the mocked execute_build_package() method of the TargetAndroid
118
+ instance so that tests can easily check which command-line arguments
119
+ would be passed on to python-for-android's toolchain.
120
+ """
121
+ expected_dist_dir = (
122
+ '{buildozer_dir}/android/platform/build-armeabi-v7a/dists/myapp__armeabi-v7a' .format (
123
+ buildozer_dir = self .buildozer .buildozer_dir )
124
+ )
125
+
126
+ with patch_target_android (
127
+ '_update_libraries_references'
128
+ ) as m_update_libraries_references , patch_target_android (
129
+ '_generate_whitelist'
130
+ ) as m_generate_whitelist , mock .patch (
131
+ 'buildozer.targets.android.TargetAndroid.execute_build_package'
132
+ ) as m_execute_build_package , mock .patch (
133
+ 'buildozer.targets.android.copyfile'
134
+ ) as m_copyfile , mock .patch (
135
+ 'buildozer.targets.android.os.listdir'
136
+ ) as m_listdir :
137
+ m_listdir .return_value = ['30.0.0-rc2' ]
138
+ self .target_android .build_package ()
139
+
140
+ assert m_listdir .call_count == 1
141
+ assert m_update_libraries_references .call_args_list == [
142
+ mock .call (expected_dist_dir )
143
+ ]
144
+ assert m_generate_whitelist .call_args_list == [mock .call (expected_dist_dir )]
145
+ assert m_copyfile .call_args_list == [
146
+ mock .call (
147
+ '{expected_dist_dir}/bin/MyApplication-0.1-debug.apk' .format (
148
+ expected_dist_dir = expected_dist_dir
149
+ ),
150
+ '{bin_dir}/myapp-0.1-armeabi-v7a-debug.apk' .format (bin_dir = self .buildozer .bin_dir ),
151
+ )
152
+ ]
153
+
154
+ return m_execute_build_package
70
155
71
156
def test_init (self ):
72
157
"""Tests init defaults."""
158
+ self .init_target ()
73
159
assert self .target_android ._arch == "armeabi-v7a"
74
160
assert self .target_android ._build_dir .endswith (
75
161
".buildozer/android/platform/build-armeabi-v7a"
@@ -100,6 +186,7 @@ def test_init_positional_buildozer(self):
100
186
101
187
def test_sdkmanager (self ):
102
188
"""Tests the _sdkmanager() method."""
189
+ self .init_target ()
103
190
kwargs = {}
104
191
with patch_buildozer_cmd () as m_cmd , patch_buildozer_cmd_expect () as m_cmd_expect , patch_os_isfile () as m_isfile :
105
192
m_isfile .return_value = True
@@ -119,6 +206,7 @@ def test_sdkmanager(self):
119
206
120
207
def test_check_requirements (self ):
121
208
"""Basic tests for the check_requirements() method."""
209
+ self .init_target ()
122
210
assert not hasattr (self .target_android , "adb_cmd" )
123
211
assert not hasattr (self .target_android , "javac_cmd" )
124
212
assert "PATH" not in self .buildozer .environ
@@ -139,6 +227,7 @@ def test_check_requirements(self):
139
227
140
228
def test_check_configuration_tokens (self ):
141
229
"""Basic tests for the check_configuration_tokens() method."""
230
+ self .init_target ()
142
231
with mock .patch (
143
232
"buildozer.targets.android.Target.check_configuration_tokens"
144
233
) as m_check_configuration_tokens :
@@ -148,6 +237,7 @@ def test_check_configuration_tokens(self):
148
237
@pytest .mark .parametrize ("platform" , ["linux" , "darwin" ])
149
238
def test_install_android_sdk (self , platform ):
150
239
"""Basic tests for the _install_android_sdk() method."""
240
+ self .init_target ()
151
241
with patch_buildozer_file_exists () as m_file_exists , patch_buildozer_download () as m_download :
152
242
m_file_exists .return_value = True
153
243
sdk_dir = self .target_android ._install_android_sdk ()
@@ -178,28 +268,8 @@ def test_install_android_sdk(self, platform):
178
268
179
269
def test_build_package (self ):
180
270
"""Basic tests for the build_package() method."""
181
- expected_dist_dir = (
182
- "{buildozer_dir}/android/platform/build-armeabi-v7a/dists/myapp__armeabi-v7a" .format (
183
- buildozer_dir = self .buildozer .buildozer_dir )
184
- )
185
- with patch_target_android (
186
- "_update_libraries_references"
187
- ) as m_update_libraries_references , patch_target_android (
188
- "_generate_whitelist"
189
- ) as m_generate_whitelist , mock .patch (
190
- "buildozer.targets.android.TargetAndroid.execute_build_package"
191
- ) as m_execute_build_package , mock .patch (
192
- "buildozer.targets.android.copyfile"
193
- ) as m_copyfile , mock .patch (
194
- "buildozer.targets.android.os.listdir"
195
- ) as m_listdir :
196
- m_listdir .return_value = ["30.0.0-rc2" ]
197
- self .target_android .build_package ()
198
- assert m_listdir .call_count == 1
199
- assert m_update_libraries_references .call_args_list == [
200
- mock .call (expected_dist_dir )
201
- ]
202
- assert m_generate_whitelist .call_args_list == [mock .call (expected_dist_dir )]
271
+ self .init_target ()
272
+ m_execute_build_package = self .call_build_package ()
203
273
assert m_execute_build_package .call_args_list == [
204
274
mock .call (
205
275
[
@@ -217,11 +287,38 @@ def test_build_package(self):
217
287
]
218
288
)
219
289
]
220
- assert m_copyfile .call_args_list == [
290
+
291
+ def test_build_package_intent_filters (self ):
292
+ """
293
+ The build_package() method should honour the manifest.intent_filters
294
+ config option.
295
+ """
296
+ filters_path = os .path .join (self .temp_dir .name , 'filters.xml' )
297
+
298
+ with open (filters_path , 'w' ) as f :
299
+ f .write ('<?xml version="1.0" encoding="utf-8"?>' )
300
+
301
+ self .init_target ({
302
+ 'android.manifest.intent_filters' : 'filters.xml'
303
+ })
304
+
305
+ m_execute_build_package = self .call_build_package ()
306
+
307
+ assert m_execute_build_package .call_args_list == [
221
308
mock .call (
222
- "{expected_dist_dir}/bin/MyApplication-0.1-debug.apk" .format (
223
- expected_dist_dir = expected_dist_dir
224
- ),
225
- "{bin_dir}/myapp-0.1-armeabi-v7a-debug.apk" .format (bin_dir = self .buildozer .bin_dir ),
309
+ [
310
+ ('--name' , "'My Application'" ),
311
+ ('--version' , '0.1' ),
312
+ ('--package' , 'org.test.myapp' ),
313
+ ('--minsdk' , '21' ),
314
+ ('--ndk-api' , '21' ),
315
+ ('--private' , '{buildozer_dir}/android/app' .format (buildozer_dir = self .buildozer .buildozer_dir )),
316
+ ('--android-entrypoint' , 'org.kivy.android.PythonActivity' ),
317
+ ('--android-apptheme' , '@android:style/Theme.NoTitleBar' ),
318
+ ('--orientation' , 'portrait' ),
319
+ ('--window' ,),
320
+ ('--intent-filters' , os .path .realpath (filters_path )),
321
+ ('debug' ,),
322
+ ]
226
323
)
227
324
]
0 commit comments