blob: 99e8b037968fb5f0fec4de31bb1a99e6e3cc2ff9 [file] [log] [blame]
Colin Cross8bb10e82018-06-07 16:46:02 -07001#!/usr/bin/env python
2#
3# Copyright (C) 2018 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17"""Unit tests for manifest_fixer_test.py."""
18
19import StringIO
20import sys
21import unittest
22from xml.dom import minidom
23
24import manifest_fixer
25
26sys.dont_write_bytecode = True
27
28
29class CompareVersionGtTest(unittest.TestCase):
30 """Unit tests for compare_version_gt function."""
31
32 def test_sdk(self):
33 """Test comparing sdk versions."""
34 self.assertTrue(manifest_fixer.compare_version_gt('28', '27'))
35 self.assertFalse(manifest_fixer.compare_version_gt('27', '28'))
36 self.assertFalse(manifest_fixer.compare_version_gt('28', '28'))
37
38 def test_codename(self):
39 """Test comparing codenames."""
40 self.assertTrue(manifest_fixer.compare_version_gt('Q', 'P'))
41 self.assertFalse(manifest_fixer.compare_version_gt('P', 'Q'))
42 self.assertFalse(manifest_fixer.compare_version_gt('Q', 'Q'))
43
44 def test_sdk_codename(self):
45 """Test comparing sdk versions with codenames."""
46 self.assertTrue(manifest_fixer.compare_version_gt('Q', '28'))
47 self.assertFalse(manifest_fixer.compare_version_gt('28', 'Q'))
48
49 def test_compare_numeric(self):
50 """Test that numbers are compared in numeric and not lexicographic order."""
51 self.assertTrue(manifest_fixer.compare_version_gt('18', '8'))
52
53
54class RaiseMinSdkVersionTest(unittest.TestCase):
55 """Unit tests for raise_min_sdk_version function."""
56
Colin Cross496d66d2018-09-10 14:02:18 -070057 def raise_min_sdk_version_test(self, input_manifest, min_sdk_version,
58 library):
Colin Cross8bb10e82018-06-07 16:46:02 -070059 doc = minidom.parseString(input_manifest)
Colin Cross1b6a3cf2018-07-24 14:51:30 -070060 manifest_fixer.raise_min_sdk_version(doc, min_sdk_version, library)
Colin Cross8bb10e82018-06-07 16:46:02 -070061 output = StringIO.StringIO()
62 manifest_fixer.write_xml(output, doc)
63 return output.getvalue()
64
65 manifest_tmpl = (
66 '<?xml version="1.0" encoding="utf-8"?>\n'
67 '<manifest xmlns:android="http://schemas.android.com/apk/res/android">\n'
68 '%s'
69 '</manifest>\n')
70
Colin Cross1b6a3cf2018-07-24 14:51:30 -070071 # pylint: disable=redefined-builtin
72 def uses_sdk(self, min=None, target=None, extra=''):
Colin Cross496d66d2018-09-10 14:02:18 -070073 attrs = ''
Colin Cross1b6a3cf2018-07-24 14:51:30 -070074 if min:
75 attrs += ' android:minSdkVersion="%s"' % (min)
76 if target:
77 attrs += ' android:targetSdkVersion="%s"' % (target)
Colin Cross8bb10e82018-06-07 16:46:02 -070078 if extra:
Colin Cross496d66d2018-09-10 14:02:18 -070079 attrs += ' ' + extra
Colin Cross1b6a3cf2018-07-24 14:51:30 -070080 return ' <uses-sdk%s/>\n' % (attrs)
Colin Cross8bb10e82018-06-07 16:46:02 -070081
82 def test_no_uses_sdk(self):
83 """Tests inserting a uses-sdk element into a manifest."""
84
85 manifest_input = self.manifest_tmpl % ''
Colin Cross1b6a3cf2018-07-24 14:51:30 -070086 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='28')
87 output = self.raise_min_sdk_version_test(manifest_input, '28', False)
Colin Cross8bb10e82018-06-07 16:46:02 -070088 self.assertEqual(output, expected)
89
90 def test_no_min(self):
91 """Tests inserting a minSdkVersion attribute into a uses-sdk element."""
92
93 manifest_input = self.manifest_tmpl % ' <uses-sdk extra="foo"/>\n'
Colin Cross1b6a3cf2018-07-24 14:51:30 -070094 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='28',
95 extra='extra="foo"')
96 output = self.raise_min_sdk_version_test(manifest_input, '28', False)
Colin Cross8bb10e82018-06-07 16:46:02 -070097 self.assertEqual(output, expected)
98
99 def test_raise_min(self):
100 """Tests inserting a minSdkVersion attribute into a uses-sdk element."""
101
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700102 manifest_input = self.manifest_tmpl % self.uses_sdk(min='27')
Colin Cross496d66d2018-09-10 14:02:18 -0700103 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='28')
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700104 output = self.raise_min_sdk_version_test(manifest_input, '28', False)
Colin Cross8bb10e82018-06-07 16:46:02 -0700105 self.assertEqual(output, expected)
106
107 def test_raise(self):
108 """Tests raising a minSdkVersion attribute."""
109
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700110 manifest_input = self.manifest_tmpl % self.uses_sdk(min='27')
Colin Cross496d66d2018-09-10 14:02:18 -0700111 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='28')
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700112 output = self.raise_min_sdk_version_test(manifest_input, '28', False)
Colin Cross8bb10e82018-06-07 16:46:02 -0700113 self.assertEqual(output, expected)
114
115 def test_no_raise_min(self):
116 """Tests a minSdkVersion that doesn't need raising."""
117
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700118 manifest_input = self.manifest_tmpl % self.uses_sdk(min='28')
Colin Cross496d66d2018-09-10 14:02:18 -0700119 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='27')
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700120 output = self.raise_min_sdk_version_test(manifest_input, '27', False)
Colin Cross8bb10e82018-06-07 16:46:02 -0700121 self.assertEqual(output, expected)
122
123 def test_raise_codename(self):
124 """Tests raising a minSdkVersion attribute to a codename."""
125
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700126 manifest_input = self.manifest_tmpl % self.uses_sdk(min='28')
Colin Cross496d66d2018-09-10 14:02:18 -0700127 expected = self.manifest_tmpl % self.uses_sdk(min='P', target='P')
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700128 output = self.raise_min_sdk_version_test(manifest_input, 'P', False)
Colin Cross8bb10e82018-06-07 16:46:02 -0700129 self.assertEqual(output, expected)
130
131 def test_no_raise_codename(self):
132 """Tests a minSdkVersion codename that doesn't need raising."""
133
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700134 manifest_input = self.manifest_tmpl % self.uses_sdk(min='P')
Colin Cross496d66d2018-09-10 14:02:18 -0700135 expected = self.manifest_tmpl % self.uses_sdk(min='P', target='28')
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700136 output = self.raise_min_sdk_version_test(manifest_input, '28', False)
Colin Cross8bb10e82018-06-07 16:46:02 -0700137 self.assertEqual(output, expected)
138
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700139 def test_target(self):
140 """Tests an existing targetSdkVersion is preserved."""
141
142 manifest_input = self.manifest_tmpl % self.uses_sdk(min='26', target='27')
143 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='27')
144 output = self.raise_min_sdk_version_test(manifest_input, '28', False)
145 self.assertEqual(output, expected)
146
147 def test_no_target(self):
148 """Tests inserting targetSdkVersion when minSdkVersion exists."""
149
150 manifest_input = self.manifest_tmpl % self.uses_sdk(min='27')
Colin Cross496d66d2018-09-10 14:02:18 -0700151 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='28')
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700152 output = self.raise_min_sdk_version_test(manifest_input, '28', False)
153 self.assertEqual(output, expected)
154
155 def test_target_no_min(self):
Colin Cross496d66d2018-09-10 14:02:18 -0700156 """Tests inserting targetSdkVersion when minSdkVersion exists."""
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700157
Colin Cross496d66d2018-09-10 14:02:18 -0700158 manifest_input = self.manifest_tmpl % self.uses_sdk(target='27')
159 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='27')
160 output = self.raise_min_sdk_version_test(manifest_input, '28', False)
161 self.assertEqual(output, expected)
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700162
163 def test_no_target_no_min(self):
164 """Tests inserting targetSdkVersion when minSdkVersion does not exist."""
165
166 manifest_input = self.manifest_tmpl % ''
167 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='28')
168 output = self.raise_min_sdk_version_test(manifest_input, '28', False)
169 self.assertEqual(output, expected)
170
171 def test_library_no_target(self):
Colin Cross496d66d2018-09-10 14:02:18 -0700172 """Tests inserting targetSdkVersion when minSdkVersion exists."""
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700173
Colin Cross496d66d2018-09-10 14:02:18 -0700174 manifest_input = self.manifest_tmpl % self.uses_sdk(min='27')
175 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='1')
176 output = self.raise_min_sdk_version_test(manifest_input, '28', True)
177 self.assertEqual(output, expected)
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700178
179 def test_library_target_no_min(self):
Colin Cross496d66d2018-09-10 14:02:18 -0700180 """Tests inserting targetSdkVersion when minSdkVersion exists."""
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700181
Colin Cross496d66d2018-09-10 14:02:18 -0700182 manifest_input = self.manifest_tmpl % self.uses_sdk(target='27')
183 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='27')
184 output = self.raise_min_sdk_version_test(manifest_input, '28', True)
185 self.assertEqual(output, expected)
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700186
187 def test_library_no_target_no_min(self):
Colin Cross496d66d2018-09-10 14:02:18 -0700188 """Tests inserting targetSdkVersion when minSdkVersion does not exist."""
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700189
Colin Cross496d66d2018-09-10 14:02:18 -0700190 manifest_input = self.manifest_tmpl % ''
191 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='1')
192 output = self.raise_min_sdk_version_test(manifest_input, '28', True)
193 self.assertEqual(output, expected)
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700194
Colin Cross8bb10e82018-06-07 16:46:02 -0700195 def test_extra(self):
196 """Tests that extra attributes and elements are maintained."""
197
198 manifest_input = self.manifest_tmpl % (
199 ' <!-- comment -->\n'
200 ' <uses-sdk android:minSdkVersion="27" extra="foo"/>\n'
201 ' <application/>\n')
202
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700203 # pylint: disable=line-too-long
Colin Cross8bb10e82018-06-07 16:46:02 -0700204 expected = self.manifest_tmpl % (
205 ' <!-- comment -->\n'
Colin Cross496d66d2018-09-10 14:02:18 -0700206 ' <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="28" extra="foo"/>\n'
Colin Cross8bb10e82018-06-07 16:46:02 -0700207 ' <application/>\n')
208
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700209 output = self.raise_min_sdk_version_test(manifest_input, '28', False)
Colin Cross8bb10e82018-06-07 16:46:02 -0700210
211 self.assertEqual(output, expected)
212
213 def test_indent(self):
214 """Tests that an inserted element copies the existing indentation."""
215
216 manifest_input = self.manifest_tmpl % ' <!-- comment -->\n'
217
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700218 # pylint: disable=line-too-long
Colin Cross8bb10e82018-06-07 16:46:02 -0700219 expected = self.manifest_tmpl % (
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700220 ' <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="28"/>\n'
Colin Cross8bb10e82018-06-07 16:46:02 -0700221 ' <!-- comment -->\n')
222
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700223 output = self.raise_min_sdk_version_test(manifest_input, '28', False)
Colin Cross8bb10e82018-06-07 16:46:02 -0700224
225 self.assertEqual(output, expected)
226
Jiyong Parkc08f46f2018-06-18 11:01:00 +0900227
228class AddUsesLibrariesTest(unittest.TestCase):
229 """Unit tests for add_uses_libraries function."""
230
231 def run_test(self, input_manifest, new_uses_libraries):
232 doc = minidom.parseString(input_manifest)
233 manifest_fixer.add_uses_libraries(doc, new_uses_libraries)
234 output = StringIO.StringIO()
235 manifest_fixer.write_xml(output, doc)
236 return output.getvalue()
237
238 manifest_tmpl = (
239 '<?xml version="1.0" encoding="utf-8"?>\n'
240 '<manifest xmlns:android="http://schemas.android.com/apk/res/android">\n'
241 ' <application>\n'
242 '%s'
243 ' </application>\n'
244 '</manifest>\n')
245
246 def uses_libraries(self, name_required_pairs):
247 ret = ''
248 for name, required in name_required_pairs:
249 ret += (
250 ' <uses-library android:name="%s" android:required="%s"/>\n'
251 ) % (name, required)
252
253 return ret
254
255 def test_empty(self):
256 """Empty new_uses_libraries must not touch the manifest."""
257 manifest_input = self.manifest_tmpl % self.uses_libraries([
258 ('foo', 'true'),
259 ('bar', 'false')])
260 expected = manifest_input
261 output = self.run_test(manifest_input, [])
262 self.assertEqual(output, expected)
263
264 def test_not_overwrite(self):
265 """new_uses_libraries must not overwrite existing tags."""
266 manifest_input = self.manifest_tmpl % self.uses_libraries([
267 ('foo', 'true'),
268 ('bar', 'false')])
269 expected = manifest_input
270 output = self.run_test(manifest_input, ['foo', 'bar'])
271 self.assertEqual(output, expected)
272
273 def test_add(self):
274 """New names are added with 'required:true'."""
275 manifest_input = self.manifest_tmpl % self.uses_libraries([
276 ('foo', 'true'),
277 ('bar', 'false')])
278 expected = self.manifest_tmpl % self.uses_libraries([
279 ('foo', 'true'),
280 ('bar', 'false'),
281 ('baz', 'true'),
282 ('qux', 'true')])
283 output = self.run_test(manifest_input, ['bar', 'baz', 'qux'])
284 self.assertEqual(output, expected)
285
286 def test_no_application(self):
287 """When there is no <application> tag, the tag is added."""
288 manifest_input = (
289 '<?xml version="1.0" encoding="utf-8"?>\n'
290 '<manifest xmlns:android='
291 '"http://schemas.android.com/apk/res/android">\n'
292 '</manifest>\n')
293 expected = self.manifest_tmpl % self.uses_libraries([
294 ('foo', 'true'),
295 ('bar', 'true')])
296 output = self.run_test(manifest_input, ['foo', 'bar'])
297 self.assertEqual(output, expected)
298
299 def test_empty_application(self):
300 """Even when here is an empty <application/> tag, the libs are added."""
301 manifest_input = (
302 '<?xml version="1.0" encoding="utf-8"?>\n'
303 '<manifest xmlns:android='
304 '"http://schemas.android.com/apk/res/android">\n'
305 ' <application/>\n'
306 '</manifest>\n')
307 expected = self.manifest_tmpl % self.uses_libraries([
308 ('foo', 'true'),
309 ('bar', 'true')])
310 output = self.run_test(manifest_input, ['foo', 'bar'])
311 self.assertEqual(output, expected)
312
313
David Brazdild5b74992018-08-28 12:41:01 +0100314class AddUsesNonSdkApiTest(unittest.TestCase):
315 """Unit tests for add_uses_libraries function."""
316
317 def run_test(self, input_manifest):
318 doc = minidom.parseString(input_manifest)
319 manifest_fixer.add_uses_non_sdk_api(doc)
320 output = StringIO.StringIO()
321 manifest_fixer.write_xml(output, doc)
322 return output.getvalue()
323
324 manifest_tmpl = (
325 '<?xml version="1.0" encoding="utf-8"?>\n'
326 '<manifest xmlns:android="http://schemas.android.com/apk/res/android">\n'
327 ' <application%s/>\n'
328 '</manifest>\n')
329
330 def uses_non_sdk_api(self, value):
331 return ' android:usesNonSdkApi="true"' if value else ''
332
333 def test_set_true(self):
334 """Empty new_uses_libraries must not touch the manifest."""
335 manifest_input = self.manifest_tmpl % self.uses_non_sdk_api(False)
336 expected = self.manifest_tmpl % self.uses_non_sdk_api(True)
337 output = self.run_test(manifest_input)
338 self.assertEqual(output, expected)
339
340 def test_already_set(self):
341 """new_uses_libraries must not overwrite existing tags."""
342 manifest_input = self.manifest_tmpl % self.uses_non_sdk_api(True)
343 expected = manifest_input
344 output = self.run_test(manifest_input)
345 self.assertEqual(output, expected)
346
347
Colin Cross8bb10e82018-06-07 16:46:02 -0700348if __name__ == '__main__':
349 unittest.main()