blob: 590899719a9738b170d90e82a86577027efa0214 [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 Cross1b6a3cf2018-07-24 14:51:30 -070057 def raise_min_sdk_version_test(self, input_manifest, min_sdk_version, library):
Colin Cross8bb10e82018-06-07 16:46:02 -070058 doc = minidom.parseString(input_manifest)
Colin Cross1b6a3cf2018-07-24 14:51:30 -070059 manifest_fixer.raise_min_sdk_version(doc, min_sdk_version, library)
Colin Cross8bb10e82018-06-07 16:46:02 -070060 output = StringIO.StringIO()
61 manifest_fixer.write_xml(output, doc)
62 return output.getvalue()
63
64 manifest_tmpl = (
65 '<?xml version="1.0" encoding="utf-8"?>\n'
66 '<manifest xmlns:android="http://schemas.android.com/apk/res/android">\n'
67 '%s'
68 '</manifest>\n')
69
Colin Cross1b6a3cf2018-07-24 14:51:30 -070070 # pylint: disable=redefined-builtin
71 def uses_sdk(self, min=None, target=None, extra=''):
72 attrs = ""
73 if min:
74 attrs += ' android:minSdkVersion="%s"' % (min)
75 if target:
76 attrs += ' android:targetSdkVersion="%s"' % (target)
Colin Cross8bb10e82018-06-07 16:46:02 -070077 if extra:
Colin Cross1b6a3cf2018-07-24 14:51:30 -070078 attrs += ' ' + extra
79 return ' <uses-sdk%s/>\n' % (attrs)
Colin Cross8bb10e82018-06-07 16:46:02 -070080
81 def test_no_uses_sdk(self):
82 """Tests inserting a uses-sdk element into a manifest."""
83
84 manifest_input = self.manifest_tmpl % ''
Colin Cross1b6a3cf2018-07-24 14:51:30 -070085 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='28')
86 output = self.raise_min_sdk_version_test(manifest_input, '28', False)
Colin Cross8bb10e82018-06-07 16:46:02 -070087 self.assertEqual(output, expected)
88
89 def test_no_min(self):
90 """Tests inserting a minSdkVersion attribute into a uses-sdk element."""
91
92 manifest_input = self.manifest_tmpl % ' <uses-sdk extra="foo"/>\n'
Colin Cross1b6a3cf2018-07-24 14:51:30 -070093 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='28',
94 extra='extra="foo"')
95 output = self.raise_min_sdk_version_test(manifest_input, '28', False)
Colin Cross8bb10e82018-06-07 16:46:02 -070096 self.assertEqual(output, expected)
97
98 def test_raise_min(self):
99 """Tests inserting a minSdkVersion attribute into a uses-sdk element."""
100
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700101 manifest_input = self.manifest_tmpl % self.uses_sdk(min='27')
102 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='27')
103 output = self.raise_min_sdk_version_test(manifest_input, '28', False)
Colin Cross8bb10e82018-06-07 16:46:02 -0700104 self.assertEqual(output, expected)
105
106 def test_raise(self):
107 """Tests raising a minSdkVersion attribute."""
108
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700109 manifest_input = self.manifest_tmpl % self.uses_sdk(min='27')
110 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='27')
111 output = self.raise_min_sdk_version_test(manifest_input, '28', False)
Colin Cross8bb10e82018-06-07 16:46:02 -0700112 self.assertEqual(output, expected)
113
114 def test_no_raise_min(self):
115 """Tests a minSdkVersion that doesn't need raising."""
116
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700117 manifest_input = self.manifest_tmpl % self.uses_sdk(min='28')
118 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='28')
119 output = self.raise_min_sdk_version_test(manifest_input, '27', False)
Colin Cross8bb10e82018-06-07 16:46:02 -0700120 self.assertEqual(output, expected)
121
122 def test_raise_codename(self):
123 """Tests raising a minSdkVersion attribute to a codename."""
124
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700125 manifest_input = self.manifest_tmpl % self.uses_sdk(min='28')
126 expected = self.manifest_tmpl % self.uses_sdk(min='P', target='28')
127 output = self.raise_min_sdk_version_test(manifest_input, 'P', False)
Colin Cross8bb10e82018-06-07 16:46:02 -0700128 self.assertEqual(output, expected)
129
130 def test_no_raise_codename(self):
131 """Tests a minSdkVersion codename that doesn't need raising."""
132
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700133 manifest_input = self.manifest_tmpl % self.uses_sdk(min='P')
134 expected = self.manifest_tmpl % self.uses_sdk(min='P', target='P')
135 output = self.raise_min_sdk_version_test(manifest_input, '28', False)
Colin Cross8bb10e82018-06-07 16:46:02 -0700136 self.assertEqual(output, expected)
137
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700138 def test_target(self):
139 """Tests an existing targetSdkVersion is preserved."""
140
141 manifest_input = self.manifest_tmpl % self.uses_sdk(min='26', target='27')
142 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='27')
143 output = self.raise_min_sdk_version_test(manifest_input, '28', False)
144 self.assertEqual(output, expected)
145
146 def test_no_target(self):
147 """Tests inserting targetSdkVersion when minSdkVersion exists."""
148
149 manifest_input = self.manifest_tmpl % self.uses_sdk(min='27')
150 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='27')
151 output = self.raise_min_sdk_version_test(manifest_input, '28', False)
152 self.assertEqual(output, expected)
153
154 def test_target_no_min(self):
155 """Tests inserting targetSdkVersion when minSdkVersion exists."""
156
157 manifest_input = self.manifest_tmpl % self.uses_sdk(target='27')
158 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='27')
159 output = self.raise_min_sdk_version_test(manifest_input, '28', False)
160 self.assertEqual(output, expected)
161
162 def test_no_target_no_min(self):
163 """Tests inserting targetSdkVersion when minSdkVersion does not exist."""
164
165 manifest_input = self.manifest_tmpl % ''
166 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='28')
167 output = self.raise_min_sdk_version_test(manifest_input, '28', False)
168 self.assertEqual(output, expected)
169
170 def test_library_no_target(self):
171 """Tests inserting targetSdkVersion when minSdkVersion exists."""
172
173 manifest_input = self.manifest_tmpl % self.uses_sdk(min='27')
174 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='27')
175 output = self.raise_min_sdk_version_test(manifest_input, '28', True)
176 self.assertEqual(output, expected)
177
178 def test_library_target_no_min(self):
179 """Tests inserting targetSdkVersion when minSdkVersion exists."""
180
181 manifest_input = self.manifest_tmpl % self.uses_sdk(target='27')
182 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='27')
183 output = self.raise_min_sdk_version_test(manifest_input, '28', True)
184 self.assertEqual(output, expected)
185
186 def test_library_no_target_no_min(self):
187 """Tests inserting targetSdkVersion when minSdkVersion does not exist."""
188
189 manifest_input = self.manifest_tmpl % ''
190 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='1')
191 output = self.raise_min_sdk_version_test(manifest_input, '28', True)
192 self.assertEqual(output, expected)
193
Colin Cross8bb10e82018-06-07 16:46:02 -0700194 def test_extra(self):
195 """Tests that extra attributes and elements are maintained."""
196
197 manifest_input = self.manifest_tmpl % (
198 ' <!-- comment -->\n'
199 ' <uses-sdk android:minSdkVersion="27" extra="foo"/>\n'
200 ' <application/>\n')
201
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700202 # pylint: disable=line-too-long
Colin Cross8bb10e82018-06-07 16:46:02 -0700203 expected = self.manifest_tmpl % (
204 ' <!-- comment -->\n'
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700205 ' <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="27" extra="foo"/>\n'
Colin Cross8bb10e82018-06-07 16:46:02 -0700206 ' <application/>\n')
207
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700208 output = self.raise_min_sdk_version_test(manifest_input, '28', False)
Colin Cross8bb10e82018-06-07 16:46:02 -0700209
210 self.assertEqual(output, expected)
211
212 def test_indent(self):
213 """Tests that an inserted element copies the existing indentation."""
214
215 manifest_input = self.manifest_tmpl % ' <!-- comment -->\n'
216
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700217 # pylint: disable=line-too-long
Colin Cross8bb10e82018-06-07 16:46:02 -0700218 expected = self.manifest_tmpl % (
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700219 ' <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="28"/>\n'
Colin Cross8bb10e82018-06-07 16:46:02 -0700220 ' <!-- comment -->\n')
221
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700222 output = self.raise_min_sdk_version_test(manifest_input, '28', False)
Colin Cross8bb10e82018-06-07 16:46:02 -0700223
224 self.assertEqual(output, expected)
225
Jiyong Parkc08f46f2018-06-18 11:01:00 +0900226
227class AddUsesLibrariesTest(unittest.TestCase):
228 """Unit tests for add_uses_libraries function."""
229
230 def run_test(self, input_manifest, new_uses_libraries):
231 doc = minidom.parseString(input_manifest)
232 manifest_fixer.add_uses_libraries(doc, new_uses_libraries)
233 output = StringIO.StringIO()
234 manifest_fixer.write_xml(output, doc)
235 return output.getvalue()
236
237 manifest_tmpl = (
238 '<?xml version="1.0" encoding="utf-8"?>\n'
239 '<manifest xmlns:android="http://schemas.android.com/apk/res/android">\n'
240 ' <application>\n'
241 '%s'
242 ' </application>\n'
243 '</manifest>\n')
244
245 def uses_libraries(self, name_required_pairs):
246 ret = ''
247 for name, required in name_required_pairs:
248 ret += (
249 ' <uses-library android:name="%s" android:required="%s"/>\n'
250 ) % (name, required)
251
252 return ret
253
254 def test_empty(self):
255 """Empty new_uses_libraries must not touch the manifest."""
256 manifest_input = self.manifest_tmpl % self.uses_libraries([
257 ('foo', 'true'),
258 ('bar', 'false')])
259 expected = manifest_input
260 output = self.run_test(manifest_input, [])
261 self.assertEqual(output, expected)
262
263 def test_not_overwrite(self):
264 """new_uses_libraries must not overwrite existing tags."""
265 manifest_input = self.manifest_tmpl % self.uses_libraries([
266 ('foo', 'true'),
267 ('bar', 'false')])
268 expected = manifest_input
269 output = self.run_test(manifest_input, ['foo', 'bar'])
270 self.assertEqual(output, expected)
271
272 def test_add(self):
273 """New names are added with 'required:true'."""
274 manifest_input = self.manifest_tmpl % self.uses_libraries([
275 ('foo', 'true'),
276 ('bar', 'false')])
277 expected = self.manifest_tmpl % self.uses_libraries([
278 ('foo', 'true'),
279 ('bar', 'false'),
280 ('baz', 'true'),
281 ('qux', 'true')])
282 output = self.run_test(manifest_input, ['bar', 'baz', 'qux'])
283 self.assertEqual(output, expected)
284
285 def test_no_application(self):
286 """When there is no <application> tag, the tag is added."""
287 manifest_input = (
288 '<?xml version="1.0" encoding="utf-8"?>\n'
289 '<manifest xmlns:android='
290 '"http://schemas.android.com/apk/res/android">\n'
291 '</manifest>\n')
292 expected = self.manifest_tmpl % self.uses_libraries([
293 ('foo', 'true'),
294 ('bar', 'true')])
295 output = self.run_test(manifest_input, ['foo', 'bar'])
296 self.assertEqual(output, expected)
297
298 def test_empty_application(self):
299 """Even when here is an empty <application/> tag, the libs are added."""
300 manifest_input = (
301 '<?xml version="1.0" encoding="utf-8"?>\n'
302 '<manifest xmlns:android='
303 '"http://schemas.android.com/apk/res/android">\n'
304 ' <application/>\n'
305 '</manifest>\n')
306 expected = self.manifest_tmpl % self.uses_libraries([
307 ('foo', 'true'),
308 ('bar', 'true')])
309 output = self.run_test(manifest_input, ['foo', 'bar'])
310 self.assertEqual(output, expected)
311
312
Colin Cross8bb10e82018-06-07 16:46:02 -0700313if __name__ == '__main__':
314 unittest.main()