Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Delta Between Two Patch Sets: tests/test_packagerWebExt.py

Issue 29501558: Issue 5383 - Add tests for the Chrome and Firefox packagers (Closed)
Left Patch Set: Rebase against master, renaming gecko-webext to gecko Created Oct. 11, 2017, 3:59 p.m.
Right Patch Set: Addressing Vasily's comments Created Oct. 22, 2017, 11:11 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « tests/test_packagerEdge.py ('k') | tox.ini » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 # This Source Code Form is subject to the terms of the Mozilla Public 1 # This Source Code Form is subject to the terms of the Mozilla Public
2 # License, v. 2.0. If a copy of the MPL was not distributed with this 2 # License, v. 2.0. If a copy of the MPL was not distributed with this
3 # file, You can obtain one at http://mozilla.org/MPL/2.0/. 3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
4 4
5 import difflib
6 import json
5 import os 7 import os
8 import re
6 import shutil 9 import shutil
7 import zipfile 10 import zipfile
8 import json 11 from xml.etree import ElementTree
9 import re
10 from struct import unpack 12 from struct import unpack
11 import difflib
12 13
13 import pytest 14 import pytest
15 from Crypto.Signature import PKCS1_v1_5
16 from Crypto.PublicKey import RSA
14 from Crypto.Hash import SHA 17 from Crypto.Hash import SHA
15 from Crypto.PublicKey import RSA
16 from Crypto.Signature import PKCS1_v1_5
17 from xml.etree import ElementTree
18
19 18
20 from buildtools import packager 19 from buildtools import packager
21 from buildtools.packagerChrome import defaultLocale 20 from buildtools.packagerChrome import defaultLocale
22 from buildtools.build import processArgs 21 from buildtools.build import processArgs
23 22
24 LOCALES_MODULE = { 23 LOCALES_MODULE = {
25 'test.Foobar': { 24 'test.Foobar': {
26 'message': 'Ensuring dict-copy from modules for $domain$', 25 'message': 'Ensuring dict-copy from modules for $domain$',
27 'description': 'test description', 26 'description': 'test description',
28 'placeholders': {'content': '$1', 'example': 'www.adblockplus.org'} 27 'placeholders': {'content': '$1', 'example': 'www.adblockplus.org'}
29 } 28 }
30 } 29 }
31 30
32 DTD_TEST = ('<!ENTITY access.key "access key(&amp;a)">'
33 '<!ENTITY ampersand "foo &amp;-bar">')
34
35 PROPERTIES_TEST = 'description=very descriptive!'
36
37 ALL_LANGUAGES = ['en_US', 'de', 'it'] 31 ALL_LANGUAGES = ['en_US', 'de', 'it']
38
39 32
40 MESSAGES_EN_US = json.dumps({ 33 MESSAGES_EN_US = json.dumps({
41 'name': {'message': 'Adblock Plus'}, 34 'name': {'message': 'Adblock Plus'},
42 'name_devbuild': {'message': 'devbuild-marker'}, 35 'name_devbuild': {'message': 'devbuild-marker'},
43 'description': { 36 'description': {
44 'message': 'Adblock Plus is the most popular ad blocker ever, ' 37 'message': 'Adblock Plus is the most popular ad blocker ever, '
45 'and also supports websites by not blocking ' 38 'and also supports websites by not blocking '
46 'unobstrusive ads by default (configurable).' 39 'unobstrusive ads by default (configurable).'
47 }, 40 },
48 }) 41 })
49 42
50 43
51 class Content(object): 44 class Content(object):
52 """Base class for a unified ZipFile / Directory interface. 45 """Base class for a unified ZipFile / Directory interface.
53 46
54 Base class for providing a unified context manager interface for 47 Base class for providing a unified context manager interface for
55 accessing files. This class is subclassed by ZipContent and DirContent, 48 accessing files. This class is subclassed by ZipContent and DirContent,
56 which provide the additional methods "namelist()" and "read(path)". 49 which provide the additional methods "namelist()" and "read(path)".
57 """ 50 """
58 51
59 def __enter__(self): 52 def __enter__(self):
60 return self 53 return self
61 54
62 def __exit__(self, exc_type, exc_value, exc_tb): 55 def __exit__(self, exc_type, exc_value, exc_tb):
63 self._close() 56 self._close()
64 57
65 58
66 class ZipContent(Content): 59 class ZipContent(Content):
67 """Provides a unified context manager for ZipFile access. 60 """Provide a unified context manager for ZipFile access.
68 61
69 Inherits the context manager API from Content. 62 Inherits the context manager API from Content.
70 If desired, the specified ZipFile is deleted on exiting the manager. 63 If desired, the specified ZipFile is deleted on exiting the manager.
71 """ 64 """
72 65
73 def __init__(self, zip_path, delete_on_close=True): 66 def __init__(self, zip_path, delete_on_close=True):
74 """Constructor of ZipContent handling the file <zip_path>. 67 """Construct ZipContent object handling the file <zip_path>.
75 68
76 The parameter 'delete_on_close' causes the context manager to 69 The parameter 'delete_on_close' causes the context manager to
77 delete the handled ZipFile (specified by zip_path) if set to 70 delete the handled ZipFile (specified by zip_path) if set to
78 True (default). 71 True (default).
79 """ 72 """
80
81 self._zip_path = zip_path 73 self._zip_path = zip_path
82 self._zip_file = zipfile.ZipFile(zip_path) 74 self._zip_file = zipfile.ZipFile(zip_path)
83 self._delete_on_close = delete_on_close 75 self._delete_on_close = delete_on_close
84 super(ZipContent, self).__init__() 76 super(ZipContent, self).__init__()
85 77
86 def _close(self): 78 def _close(self):
87 self._zip_file.close() 79 self._zip_file.close()
88 if self._delete_on_close: 80 if self._delete_on_close:
89 # if specified, delete the handled file 81 # if specified, delete the handled file
90 os.remove(self._zip_path) 82 os.remove(self._zip_path)
91 83
92 def namelist(self): 84 def namelist(self):
93 return self._zip_file.namelist() 85 return self._zip_file.namelist()
94 86
95 def read(self, path): 87 def read(self, path):
96 return self._zip_file.read(path) 88 return self._zip_file.read(path)
97 89
98 90
99 class DirContent(Content): 91 class DirContent(Content):
100 """Provides a unified context manager for directory access. 92 """Provides a unified context manager for directory access.
101 93
102 Inherits the context managet API from Content. 94 Inherits the context managet API from Content.
103 """ 95 """
104 96
105 def __init__(self, path): 97 def __init__(self, path):
106 """Constructor of DirContent handling <path>. 98 """Construct a DirContent object handling <path>."""
107 """
108
109 self._path = path 99 self._path = path
110 super(DirContent, self).__init__() 100 super(DirContent, self).__init__()
111 101
112 def _close(self): 102 def _close(self):
113 pass 103 pass
114 104
115 def namelist(self): 105 def namelist(self):
116 """Generate a list of filenames, as expected from ZipFile.nameslist(). 106 """Generate a list of filenames."""
117 """
118
119 result = [] 107 result = []
120 for parent, directories, files in os.walk(self._path): 108 for parent, directories, files in os.walk(self._path):
121 for filename in files: 109 for filename in files:
122 file_path = os.path.join(parent, filename) 110 file_path = os.path.join(parent, filename)
123 rel_path = os.path.relpath(file_path, self._path) 111 rel_path = os.path.relpath(file_path, self._path)
124 result.append(rel_path) 112 result.append(rel_path)
125 return result 113 return result
126 114
127 def read(self, path): 115 def read(self, path):
128 content = None 116 content = None
129 with open(os.path.join(self._path, path)) as fp: 117 with open(os.path.join(self._path, path)) as fp:
130 content = fp.read() 118 content = fp.read()
131 return content 119 return content
132 120
133 121
134 def copy_metadata(filename, tmpdir): 122 def copy_metadata(filename, tmpdir):
135 """Copy the used metadata to the used temporary directory.""" 123 """Copy the used metadata to the used temporary directory."""
136 path = os.path.join(os.path.dirname(__file__), filename) 124 path = os.path.join(os.path.dirname(__file__), filename)
137 destination = str(tmpdir.join(filename)) 125 destination = str(tmpdir.join(filename))
138 shutil.copy(path, destination) 126 shutil.copy(path, destination)
139 127
140 128
141 def run_webext_build(ext_type, build_opt, srcdir, buildnum=None, keyfile=None): 129 def run_webext_build(ext_type, build_opt, srcdir, keyfile=None):
142 """Run a build process.""" 130 """Run a build process."""
143 if build_opt == 'build': 131 cmd_mapping = {
144 build_args = ['build'] 132 'devenv': ['devenv'],
145 elif build_opt == 'release': 133 'development_build': ['build', '-b', '1337'],
146 build_args = ['build', '-r'] 134 'release_build': ['build', '-r'],
147 else: 135 }
148 build_args = ['devenv'] 136
149 137 args = ['build.py', '-t', ext_type] + cmd_mapping[build_opt]
150 args = ['build.py', '-t', ext_type] + build_args
151 138
152 if keyfile: 139 if keyfile:
153 args += ['-k', keyfile] 140 args += ['-k', keyfile]
154 if buildnum:
155 args += ['-b', buildnum]
156 141
157 processArgs(str(srcdir), args) 142 processArgs(str(srcdir), args)
158 143
159 144
160 def locale_files(languages, rootfolder, srcdir): 145 def locale_files(languages, rootfolder, srcdir):
161 """Generate example locales. 146 """Generate example locales.
162 147
163 languages: tuple, list or set of languages to include 148 languages: tuple, list or set of languages to include
164 rootdir: folder-name to create the locale-folders in 149 rootdir: folder-name to create the locale-folders in
165 """ 150 """
(...skipping 20 matching lines...) Expand all
186 """Source directory for building the package.""" 171 """Source directory for building the package."""
187 for size in ['44', '50', '150']: 172 for size in ['44', '50', '150']:
188 path = tmpdir.join('chrome', 'icons', 'abp-{}.png'.format(size)) 173 path = tmpdir.join('chrome', 'icons', 'abp-{}.png'.format(size))
189 path.write(size, ensure=True) 174 path.write(size, ensure=True)
190 175
191 tmpdir.join('bar.json').write(json.dumps({})) 176 tmpdir.join('bar.json').write(json.dumps({}))
192 return tmpdir 177 return tmpdir
193 178
194 179
195 @pytest.fixture 180 @pytest.fixture
196 def gecko_import(tmpdir):
197 tmpdir.mkdir('_imp').mkdir('en-US').join('gecko.dtd').write(DTD_TEST)
198
199
200 @pytest.fixture
201 def locale_modules(tmpdir): 181 def locale_modules(tmpdir):
202 mod_dir = tmpdir.mkdir('_modules') 182 mod_dir = tmpdir.mkdir('_modules')
203 lang_dir = mod_dir.mkdir('en-US') 183 lang_dir = mod_dir.mkdir('en_US')
204 lang_dir.join('module.json').write(json.dumps(LOCALES_MODULE)) 184 lang_dir.join('module.json').write(json.dumps(LOCALES_MODULE))
205 lang_dir.join('unit.properties').write(json.dumps(PROPERTIES_TEST))
206 185
207 186
208 @pytest.fixture 187 @pytest.fixture
209 def icons(srcdir): 188 def icons(srcdir):
210 icons_dir = srcdir.mkdir('icons') 189 icons_dir = srcdir.mkdir('icons')
211 for filename in ['abp-16.png', 'abp-19.png', 'abp-53.png']: 190 for filename in ['abp-16.png', 'abp-19.png', 'abp-53.png']:
212 shutil.copy( 191 shutil.copy(
213 os.path.join(os.path.dirname(__file__), filename), 192 os.path.join(os.path.dirname(__file__), filename),
214 os.path.join(str(icons_dir), filename), 193 os.path.join(str(icons_dir), filename),
215 ) 194 )
(...skipping 19 matching lines...) Expand all
235 @pytest.fixture 214 @pytest.fixture
236 def edge_metadata(tmpdir): 215 def edge_metadata(tmpdir):
237 filename = 'metadata.edge' 216 filename = 'metadata.edge'
238 copy_metadata(filename, tmpdir) 217 copy_metadata(filename, tmpdir)
239 218
240 return packager.readMetadata(str(tmpdir), 'edge') 219 return packager.readMetadata(str(tmpdir), 'edge')
241 220
242 221
243 @pytest.fixture 222 @pytest.fixture
244 def keyfile(tmpdir): 223 def keyfile(tmpdir):
245 """Test-privatekey for signing chrome release-package""" 224 """Test-privatekey for signing chrome release-package."""
246 return os.path.join(os.path.dirname(__file__), 'chrome_rsa.pem') 225 return os.path.join(os.path.dirname(__file__), 'chrome_rsa.pem')
247 226
248 227
249 @pytest.fixture 228 @pytest.fixture
250 def lib_files(tmpdir): 229 def lib_files(tmpdir):
251 files = packager.Files(['lib'], set()) 230 files = packager.Files(['lib'], set())
252 files['ext/a.js'] = 'var bar;' 231 files['ext/a.js'] = 'require("./c.js");\nvar bar;'
253 files['lib/b.js'] = 'var foo;' 232 files['lib/b.js'] = 'var foo;'
233 files['ext/c.js'] = 'var this_is_c;'
254 234
255 tmpdir.mkdir('lib').join('b.js').write(files['lib/b.js']) 235 tmpdir.mkdir('lib').join('b.js').write(files['lib/b.js'])
256 tmpdir.mkdir('ext').join('a.js').write(files['ext/a.js']) 236 ext_dir = tmpdir.mkdir('ext')
237 ext_dir.join('a.js').write(files['ext/a.js'])
238 ext_dir.join('c.js').write(files['ext/c.js'])
257 239
258 return files 240 return files
259 241
260 242
261 def comparable_xml(xml): 243 def comparable_xml(xml):
262 """Create a nonambiguous representation of a given XML tree.""" 244 """Create a nonambiguous representation of a given XML tree.
245
246 Note that this function is not safe against ambiguous tags
247 containing differently distributed children, e.g.:
248
249 '<a><b><c/></b><b><d/></b></a>'
250 vs.
251 '<a><b/><b><c/><d/></b></a>'
252
253 This is irrelevant for comparing the XML used by the tests of this
254 module.
255 """
263 def get_leafs_string(tree): 256 def get_leafs_string(tree):
264 """Recursively build a string representing all xml leaf-nodes.""" 257 """Recursively build a string representing all xml leaf-nodes."""
265 root_str = '{}|{}|{}'.format(tree.tag, tree.tail, tree.text).strip() 258 root_str = '{}|{}|{}'.format(tree.tag, tree.tail, tree.text).strip()
266 result = [] 259 result = []
267 260
268 if len(tree) > 0: 261 if len(tree) > 0:
269 for subtree in tree: 262 for subtree in tree:
270 for leaf in get_leafs_string(subtree): 263 for leaf in get_leafs_string(subtree):
271 result.append('{}__{}'.format(root_str, leaf)) 264 result.append('{}__{}'.format(root_str, leaf))
272 for k, v in tree.attrib.items(): 265 for k, v in tree.attrib.items():
(...skipping 22 matching lines...) Expand all
295 generated = comparable_xml(manifest) 288 generated = comparable_xml(manifest)
296 expected = comparable_xml(fp.read()) 289 expected = comparable_xml(fp.read())
297 else: 290 else:
298 generated = comparable_json(manifest) 291 generated = comparable_json(manifest)
299 expected = comparable_json(fp.read()) 292 expected = comparable_json(fp.read())
300 293
301 diff = list(difflib.unified_diff(generated, expected, n=0)) 294 diff = list(difflib.unified_diff(generated, expected, n=0))
302 assert len(diff) == 0, '\n'.join(diff) 295 assert len(diff) == 0, '\n'.join(diff)
303 296
304 297
305 def assert_gecko_locale_conversion(package, prefix): 298 def assert_webpack_bundle(package, prefix, excluded=False):
306 locale = json.loads(package.read(os.path.join(
307 prefix, '_locales/en_US/messages.json')))
308
309 assert locale.get('test_Foobar', {}) == LOCALES_MODULE['test.Foobar']
310 assert locale.get('access_key', {}) == {'message': 'access key'}
311 assert locale.get('ampersand', {}) == {'message': 'foo -bar'}
312 assert locale.get('_description', {}) == {'message': 'very descriptive!"'}
313
314
315 def assert_convert_js(package, prefix, excluded=False):
316 libfoo = package.read(os.path.join(prefix, 'lib/foo.js')) 299 libfoo = package.read(os.path.join(prefix, 'lib/foo.js'))
300 libfoomap = package.read(os.path.join(prefix, 'lib/foo.js.map'))
317 301
318 assert 'var bar;' in libfoo 302 assert 'var bar;' in libfoo
319 assert 'require.modules["ext_a"]' in libfoo 303 assert 'webpack:///./ext/a.js' in libfoomap
304
305 assert 'var this_is_c;' in libfoo
306 assert 'webpack:///./ext/c.js' in libfoomap
320 307
321 assert ('var foo;' in libfoo) != excluded 308 assert ('var foo;' in libfoo) != excluded
322 assert ('require.modules["b"]' in libfoo) != excluded 309 assert ('webpack:///./lib/b.js' in libfoomap) != excluded
323 310
324 311
325 def assert_devenv_scripts(package, devenv): 312 def assert_devenv_scripts(package, prefix, devenv):
326 manifest = json.loads(package.read('manifest.json')) 313 manifest = json.loads(package.read(os.path.join(prefix, 'manifest.json')))
327 filenames = package.namelist() 314 filenames = package.namelist()
328 scripts = [ 315 scripts = [
329 'ext/common.js', 316 'ext/common.js',
330 'ext/background.js', 317 'ext/background.js',
331 ] 318 ]
332 319
333 assert ('qunit/index.html' in filenames) == devenv 320 assert (os.path.join(prefix, 'qunit/index.html') in filenames) == devenv
334 assert ('devenvPoller__.js' in filenames) == devenv 321 assert (os.path.join(prefix, 'devenvPoller__.js') in filenames) == devenv
335 assert ('devenvVersion__' in filenames) == devenv 322 assert (os.path.join(prefix, 'devenvVersion__') in filenames) == devenv
336 323
337 if devenv: 324 if devenv:
338 assert '../ext/common.js' in package.read('qunit/index.html') 325 quint_index = package.read(os.path.join(prefix, 'qunit/index.html'))
339 assert '../ext/background.js' in package.read('qunit/index.html') 326 assert '../ext/common.js' in quint_index
327 assert '../ext/background.js' in quint_index
340 328
341 assert set(manifest['background']['scripts']) == set( 329 assert set(manifest['background']['scripts']) == set(
342 scripts + ['devenvPoller__.js'] 330 scripts + ['devenvPoller__.js']
343 ) 331 )
344 else: 332 else:
345 assert set(manifest['background']['scripts']) == set(scripts) 333 assert set(manifest['background']['scripts']) == set(scripts)
346 334
347 335
348 def assert_base_files(package, platform): 336 def assert_base_files(package, platform, prefix):
349 filenames = set(package.namelist()) 337 filenames = set(package.namelist())
350 338
351 if platform in {'chrome', 'gecko'}: 339 if platform == 'edge':
352 assert 'bar.json' in filenames
353 assert 'manifest.json' in filenames
354 assert 'lib/foo.js' in filenames
355 assert 'foo/logo_50.png' in filenames
356 assert 'icons/logo_150.png' in filenames
357 else:
358 assert 'AppxManifest.xml' in filenames 340 assert 'AppxManifest.xml' in filenames
359 assert 'AppxBlockMap.xml' in filenames 341 assert 'AppxBlockMap.xml' in filenames
360 assert '[Content_Types].xml' in filenames 342 assert '[Content_Types].xml' in filenames
361 343
362 assert 'Extension/bar.json' in filenames
363 assert 'Extension/lib/foo.js' in filenames
364
365 assert package.read('Assets/logo_44.png') == '44' 344 assert package.read('Assets/logo_44.png') == '44'
366 assert package.read('Extension/icons/abp-44.png') == '44' 345 assert package.read('Extension/icons/abp-44.png') == '44'
346
347 assert os.path.join(prefix, 'bar.json') in filenames
348 assert os.path.join(prefix, 'manifest.json') in filenames
349 assert os.path.join(prefix, 'lib/foo.js') in filenames
350 assert os.path.join(prefix, 'foo/logo_50.png') in filenames
351 assert os.path.join(prefix, 'icons/logo_150.png') in filenames
367 352
368 353
369 def assert_chrome_signature(filename, keyfile): 354 def assert_chrome_signature(filename, keyfile):
370 with open(filename, 'r') as fp: 355 with open(filename, 'r') as fp:
371 content = fp.read() 356 content = fp.read()
372 357
373 _, _, l_pubkey, l_signature = unpack('<4sIII', content[:16]) 358 _, _, l_pubkey, l_signature = unpack('<4sIII', content[:16])
374 signature = content[16 + l_pubkey: 16 + l_pubkey + l_signature] 359 signature = content[16 + l_pubkey: 16 + l_pubkey + l_signature]
375 360
376 digest = SHA.new() 361 digest = SHA.new()
(...skipping 19 matching lines...) Expand all
396 for match in re.finditer(r'__MSG_(\S+)__', manifest): 381 for match in re.finditer(r'__MSG_(\S+)__', manifest):
397 name = match.group(1) 382 name = match.group(1)
398 383
399 for other in translations[1:]: 384 for other in translations[1:]:
400 assert translations[0][name]['message'] == other[name]['message'] 385 assert translations[0][name]['message'] == other[name]['message']
401 386
402 387
403 @pytest.mark.usefixtures( 388 @pytest.mark.usefixtures(
404 'all_lang_locales', 389 'all_lang_locales',
405 'locale_modules', 390 'locale_modules',
406 'gecko_import',
407 'icons', 391 'icons',
408 'lib_files', 392 'lib_files',
409 'chrome_metadata', 393 'chrome_metadata',
410 'gecko_webext_metadata', 394 'gecko_webext_metadata',
411 'edge_metadata', 395 'edge_metadata',
412 ) 396 )
413 @pytest.mark.parametrize('platform,dev_build_release,buildnum', [ 397 @pytest.mark.parametrize('platform,command', [
414 ('chrome', 'build', '1337'), 398 ('chrome', 'development_build'),
415 ('chrome', 'devenv', None), 399 ('chrome', 'devenv'),
416 ('chrome', 'release', None), 400 ('chrome', 'release_build'),
417 ('gecko', 'build', '1337'), 401 ('gecko', 'development_build'),
418 ('gecko', 'devenv', None), 402 ('gecko', 'devenv'),
419 ('gecko', 'release', None), 403 ('gecko', 'release_build'),
420 ('edge', 'build', '1337'), 404 ('edge', 'development_build'),
421 pytest.param('edge', 'devenv', None, marks=pytest.mark.xfail), 405 ('edge', 'devenv'),
422 ('edge', 'release', None), 406 ('edge', 'release_build'),
423 ]) 407 ])
424 def test_build_webext(platform, dev_build_release, keyfile, tmpdir, srcdir, 408 def test_build_webext(platform, command, keyfile, tmpdir, srcdir, capsys):
425 buildnum, capsys): 409 release = command == 'release_build'
426 release = dev_build_release == 'release' 410 devenv = command == 'devenv'
427 devenv = dev_build_release == 'devenv'
428 411
429 if platform == 'chrome' and release: 412 if platform == 'chrome' and release:
430 key = keyfile 413 key = keyfile
431 else: 414 else:
432 key = None 415 key = None
433 416
434 manifests = { 417 manifests = {
435 'gecko': [('', 'manifest', 'json')], 418 'gecko': [('', 'manifest', 'json')],
436 'chrome': [('', 'manifest', 'json')], 419 'chrome': [('', 'manifest', 'json')],
437 'edge': [('', 'AppxManifest', 'xml'), 420 'edge': [('', 'AppxManifest', 'xml'),
438 ('Extension', 'manifest', 'json')], 421 ('Extension', 'manifest', 'json')],
439 } 422 }
440 423
441 filenames = { 424 filenames = {
442 'gecko': 'adblockplusfirefox-1.2.3{}.xpi', 425 'gecko': 'adblockplusfirefox-1.2.3{}.xpi',
443 'chrome': 'adblockpluschrome-1.2.3{{}}.{}'.format( 426 'chrome': 'adblockpluschrome-1.2.3{{}}.{}'.format(
444 {True: 'crx', False: 'zip'}[release] 427 {True: 'crx', False: 'zip'}[release]
445 ), 428 ),
446 'edge': 'adblockplusedge-1.2.3{}.appx', 429 'edge': 'adblockplusedge-1.2.3{}.appx',
447 } 430 }
448 431
449 if platform == 'edge': 432 if platform == 'edge':
450 prefix = 'Extension' 433 prefix = 'Extension'
451 else: 434 else:
452 prefix = '' 435 prefix = ''
453 436
454 run_webext_build(platform, dev_build_release, srcdir, buildnum=buildnum, 437 run_webext_build(platform, command, srcdir, keyfile=key)
455 keyfile=key)
456 438
457 # The makeIcons() in packagerChrome.py should warn about non-square 439 # The makeIcons() in packagerChrome.py should warn about non-square
458 # icons via stderr. 440 # icons via stderr.
459 if platform in {'chrome', 'gecko'}: 441 out, err = capsys.readouterr()
460 out, err = capsys.readouterr() 442 assert 'icon should be square' in err
461 assert 'icon should be square' in err
462 443
463 if devenv: 444 if devenv:
464 content_class = DirContent 445 content_class = DirContent
465 out_file_path = os.path.join(str(srcdir), 'devenv.' + platform) 446 out_file_path = os.path.join(str(srcdir), 'devenv.' + platform)
466 else: 447 else:
467 content_class = ZipContent 448 content_class = ZipContent
468 449
469 if release: 450 if release:
470 add_version = '' 451 add_version = ''
471 else: 452 else:
472 add_version = '.' + buildnum 453 add_version = '.1337'
473 454
474 out_file = filenames[platform].format(add_version) 455 out_file = filenames[platform].format(add_version)
475 456
476 out_file_path = os.path.abspath(os.path.join( 457 out_file_path = os.path.abspath(os.path.join(
477 os.path.dirname(__file__), os.pardir, out_file)) 458 os.path.dirname(__file__), os.pardir, out_file))
478 assert os.path.exists(out_file_path) 459 assert os.path.exists(out_file_path)
479 460
480 if release and platform == 'chrome': 461 if release and platform == 'chrome':
481 assert_chrome_signature(out_file_path, keyfile) 462 assert_chrome_signature(out_file_path, keyfile)
482 463
483 with content_class(out_file_path) as package: 464 with content_class(out_file_path) as package:
484 assert_base_files(package, platform) 465 assert_base_files(package, platform, prefix)
485 assert_all_locales_present(package, prefix) 466 assert_all_locales_present(package, prefix)
486 assert_gecko_locale_conversion(package, prefix) 467 assert_webpack_bundle(package, prefix, platform == 'gecko')
487 assert_convert_js(package, prefix, platform == 'gecko')
488 468
489 if platform == 'chrome': 469 if platform == 'chrome':
490 assert_locale_upfix(package) 470 assert_locale_upfix(package)
491 if platform in {'chrome', 'gecko'}: 471
492 assert_devenv_scripts(package, devenv) 472 assert_devenv_scripts(package, prefix, devenv)
493 473
494 for folder, name, ext in manifests[platform]: 474 for folder, name, ext in manifests[platform]:
495 filename = '{{}}_{}_{}.{{}}'.format(platform, dev_build_release) 475 filename = '{{}}_{}_{}.{{}}'.format(platform, command)
496 expected = os.path.join( 476 expected = os.path.join(
497 os.path.dirname(__file__), 477 os.path.dirname(__file__),
498 'expecteddata', 478 'expecteddata',
499 filename.format(name, ext), 479 filename.format(name, ext),
500 ) 480 )
501 481
502 assert_manifest_content( 482 assert_manifest_content(
503 package.read(os.path.join(folder, '{}.{}'.format(name, ext))), 483 package.read(os.path.join(folder, '{}.{}'.format(name, ext))),
504 expected, 484 expected,
505 ) 485 )
LEFTRIGHT

Powered by Google App Engine
This is Rietveld