зеркало из https://github.com/mozilla/gecko-dev.git
Bug 780561 - Unit tests for the new packager code. r=ted,r=gps
This commit is contained in:
Родитель
0151c8b56a
Коммит
30605cdec8
|
@ -13,6 +13,7 @@ test_dirs := \
|
|||
mozbuild/mozbuild/test \
|
||||
mozbuild/mozbuild/test/compilation \
|
||||
mozbuild/mozbuild/test/frontend \
|
||||
mozbuild/mozpack/test \
|
||||
$(NULL)
|
||||
|
||||
PYTHON_UNIT_TESTS := $(foreach dir,$(test_dirs),$(wildcard $(srcdir)/$(dir)/*.py))
|
||||
|
|
|
@ -0,0 +1,148 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
import unittest
|
||||
import mozunit
|
||||
from mozpack.chrome.flags import (
|
||||
Flag,
|
||||
StringFlag,
|
||||
VersionFlag,
|
||||
Flags,
|
||||
)
|
||||
from mozpack.errors import ErrorMessage
|
||||
|
||||
|
||||
class TestFlag(unittest.TestCase):
|
||||
def test_flag(self):
|
||||
flag = Flag('flag')
|
||||
self.assertEqual(str(flag), '')
|
||||
self.assertTrue(flag.matches(False))
|
||||
self.assertTrue(flag.matches('false'))
|
||||
self.assertFalse(flag.matches('true'))
|
||||
self.assertRaises(ErrorMessage, flag.add_definition, 'flag=')
|
||||
self.assertRaises(ErrorMessage, flag.add_definition, 'flag=42')
|
||||
self.assertRaises(ErrorMessage, flag.add_definition, 'flag!=false')
|
||||
|
||||
flag.add_definition('flag=1')
|
||||
self.assertEqual(str(flag), 'flag=1')
|
||||
self.assertTrue(flag.matches(True))
|
||||
self.assertTrue(flag.matches('1'))
|
||||
self.assertFalse(flag.matches('no'))
|
||||
|
||||
flag.add_definition('flag=true')
|
||||
self.assertEqual(str(flag), 'flag=true')
|
||||
self.assertTrue(flag.matches(True))
|
||||
self.assertTrue(flag.matches('true'))
|
||||
self.assertFalse(flag.matches('0'))
|
||||
|
||||
flag.add_definition('flag=no')
|
||||
self.assertEqual(str(flag), 'flag=no')
|
||||
self.assertTrue(flag.matches('false'))
|
||||
self.assertFalse(flag.matches('1'))
|
||||
|
||||
flag.add_definition('flag')
|
||||
self.assertEqual(str(flag), 'flag')
|
||||
self.assertFalse(flag.matches('false'))
|
||||
self.assertTrue(flag.matches('true'))
|
||||
self.assertFalse(flag.matches(False))
|
||||
|
||||
def test_string_flag(self):
|
||||
flag = StringFlag('flag')
|
||||
self.assertEqual(str(flag), '')
|
||||
self.assertTrue(flag.matches('foo'))
|
||||
self.assertRaises(ErrorMessage, flag.add_definition, 'flag>=2')
|
||||
|
||||
flag.add_definition('flag=foo')
|
||||
self.assertEqual(str(flag), 'flag=foo')
|
||||
self.assertTrue(flag.matches('foo'))
|
||||
self.assertFalse(flag.matches('bar'))
|
||||
|
||||
flag.add_definition('flag=bar')
|
||||
self.assertEqual(str(flag), 'flag=foo flag=bar')
|
||||
self.assertTrue(flag.matches('foo'))
|
||||
self.assertTrue(flag.matches('bar'))
|
||||
self.assertFalse(flag.matches('baz'))
|
||||
|
||||
flag = StringFlag('flag')
|
||||
flag.add_definition('flag!=bar')
|
||||
self.assertEqual(str(flag), 'flag!=bar')
|
||||
self.assertTrue(flag.matches('foo'))
|
||||
self.assertFalse(flag.matches('bar'))
|
||||
|
||||
def test_version_flag(self):
|
||||
flag = VersionFlag('flag')
|
||||
self.assertEqual(str(flag), '')
|
||||
self.assertTrue(flag.matches('1.0'))
|
||||
self.assertRaises(ErrorMessage, flag.add_definition, 'flag!=2')
|
||||
|
||||
flag.add_definition('flag=1.0')
|
||||
self.assertEqual(str(flag), 'flag=1.0')
|
||||
self.assertTrue(flag.matches('1.0'))
|
||||
self.assertFalse(flag.matches('2.0'))
|
||||
|
||||
flag.add_definition('flag=2.0')
|
||||
self.assertEqual(str(flag), 'flag=1.0 flag=2.0')
|
||||
self.assertTrue(flag.matches('1.0'))
|
||||
self.assertTrue(flag.matches('2.0'))
|
||||
self.assertFalse(flag.matches('3.0'))
|
||||
|
||||
flag = VersionFlag('flag')
|
||||
flag.add_definition('flag>=2.0')
|
||||
self.assertEqual(str(flag), 'flag>=2.0')
|
||||
self.assertFalse(flag.matches('1.0'))
|
||||
self.assertTrue(flag.matches('2.0'))
|
||||
self.assertTrue(flag.matches('3.0'))
|
||||
|
||||
flag.add_definition('flag<1.10')
|
||||
self.assertEqual(str(flag), 'flag>=2.0 flag<1.10')
|
||||
self.assertTrue(flag.matches('1.0'))
|
||||
self.assertTrue(flag.matches('1.9'))
|
||||
self.assertFalse(flag.matches('1.10'))
|
||||
self.assertFalse(flag.matches('1.20'))
|
||||
self.assertTrue(flag.matches('2.0'))
|
||||
self.assertTrue(flag.matches('3.0'))
|
||||
self.assertRaises(Exception, flag.add_definition, 'flag<')
|
||||
self.assertRaises(Exception, flag.add_definition, 'flag>')
|
||||
self.assertRaises(Exception, flag.add_definition, 'flag>=')
|
||||
self.assertRaises(Exception, flag.add_definition, 'flag<=')
|
||||
self.assertRaises(Exception, flag.add_definition, 'flag!=1.0')
|
||||
|
||||
|
||||
class TestFlags(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.flags = Flags('contentaccessible=yes',
|
||||
'appversion>=3.5',
|
||||
'application=foo',
|
||||
'application=bar',
|
||||
'appversion<2.0',
|
||||
'platform',
|
||||
'abi!=Linux_x86-gcc3')
|
||||
|
||||
def test_flags_str(self):
|
||||
self.assertEqual(str(self.flags), 'contentaccessible=yes ' +
|
||||
'appversion>=3.5 appversion<2.0 application=foo ' +
|
||||
'application=bar platform abi!=Linux_x86-gcc3')
|
||||
|
||||
def test_flags_match_unset(self):
|
||||
self.assertTrue(self.flags.match(os='WINNT'))
|
||||
|
||||
def test_flags_match(self):
|
||||
self.assertTrue(self.flags.match(application='foo'))
|
||||
self.assertFalse(self.flags.match(application='qux'))
|
||||
|
||||
def test_flags_match_different(self):
|
||||
self.assertTrue(self.flags.match(abi='WINNT_x86-MSVC'))
|
||||
self.assertFalse(self.flags.match(abi='Linux_x86-gcc3'))
|
||||
|
||||
def test_flags_match_version(self):
|
||||
self.assertTrue(self.flags.match(appversion='1.0'))
|
||||
self.assertTrue(self.flags.match(appversion='1.5'))
|
||||
self.assertFalse(self.flags.match(appversion='2.0'))
|
||||
self.assertFalse(self.flags.match(appversion='3.0'))
|
||||
self.assertTrue(self.flags.match(appversion='3.5'))
|
||||
self.assertTrue(self.flags.match(appversion='3.10'))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
mozunit.main()
|
|
@ -0,0 +1,149 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
import unittest
|
||||
import mozunit
|
||||
import os
|
||||
from mozpack.chrome.manifest import (
|
||||
ManifestContent,
|
||||
ManifestLocale,
|
||||
ManifestSkin,
|
||||
Manifest,
|
||||
ManifestResource,
|
||||
ManifestOverride,
|
||||
ManifestComponent,
|
||||
ManifestContract,
|
||||
ManifestInterfaces,
|
||||
ManifestBinaryComponent,
|
||||
ManifestCategory,
|
||||
ManifestStyle,
|
||||
ManifestOverlay,
|
||||
MANIFESTS_TYPES,
|
||||
parse_manifest,
|
||||
parse_manifest_line,
|
||||
)
|
||||
from mozpack.errors import errors, AccumulatedErrors
|
||||
from test_errors import TestErrors
|
||||
|
||||
|
||||
class TestManifest(unittest.TestCase):
|
||||
def test_parse_manifest(self):
|
||||
manifest = [
|
||||
'content global content/global/',
|
||||
'content global content/global/ application=foo application=bar' +
|
||||
' platform',
|
||||
'locale global en-US content/en-US/',
|
||||
'locale global en-US content/en-US/ application=foo',
|
||||
'skin global classic/1.0 content/skin/classic/',
|
||||
'skin global classic/1.0 content/skin/classic/ application=foo' +
|
||||
' os=WINNT',
|
||||
'',
|
||||
'manifest pdfjs/chrome.manifest',
|
||||
'resource gre-resources toolkit/res/',
|
||||
'override chrome://global/locale/netError.dtd' +
|
||||
' chrome://browser/locale/netError.dtd',
|
||||
'# Comment',
|
||||
'component {b2bba4df-057d-41ea-b6b1-94a10a8ede68} foo.js',
|
||||
'contract @mozilla.org/foo;1' +
|
||||
' {b2bba4df-057d-41ea-b6b1-94a10a8ede68}',
|
||||
'interfaces foo.xpt # Inline comment',
|
||||
'binary-component bar.so',
|
||||
'category command-line-handler m-browser' +
|
||||
' @mozilla.org/browser/clh;1' +
|
||||
' application={ec8030f7-c20a-464f-9b0e-13a3a9e97384}',
|
||||
'style chrome://global/content/customizeToolbar.xul' +
|
||||
' chrome://browser/skin/',
|
||||
'overlay chrome://global/content/viewSource.xul' +
|
||||
' chrome://browser/content/viewSourceOverlay.xul',
|
||||
]
|
||||
other_manifest = [
|
||||
'content global content/global/'
|
||||
]
|
||||
expected_result = [
|
||||
ManifestContent('', 'global', 'content/global/'),
|
||||
ManifestContent('', 'global', 'content/global/', 'application=foo',
|
||||
'application=bar', 'platform'),
|
||||
ManifestLocale('', 'global', 'en-US', 'content/en-US/'),
|
||||
ManifestLocale('', 'global', 'en-US', 'content/en-US/',
|
||||
'application=foo'),
|
||||
ManifestSkin('', 'global', 'classic/1.0', 'content/skin/classic/'),
|
||||
ManifestSkin('', 'global', 'classic/1.0', 'content/skin/classic/',
|
||||
'application=foo', 'os=WINNT'),
|
||||
Manifest('', 'pdfjs/chrome.manifest'),
|
||||
ManifestResource('', 'gre-resources', 'toolkit/res/'),
|
||||
ManifestOverride('', 'chrome://global/locale/netError.dtd',
|
||||
'chrome://browser/locale/netError.dtd'),
|
||||
ManifestComponent('', '{b2bba4df-057d-41ea-b6b1-94a10a8ede68}',
|
||||
'foo.js'),
|
||||
ManifestContract('', '@mozilla.org/foo;1',
|
||||
'{b2bba4df-057d-41ea-b6b1-94a10a8ede68}'),
|
||||
ManifestInterfaces('', 'foo.xpt'),
|
||||
ManifestBinaryComponent('', 'bar.so'),
|
||||
ManifestCategory('', 'command-line-handler', 'm-browser',
|
||||
'@mozilla.org/browser/clh;1', 'application=' +
|
||||
'{ec8030f7-c20a-464f-9b0e-13a3a9e97384}'),
|
||||
ManifestStyle('', 'chrome://global/content/customizeToolbar.xul',
|
||||
'chrome://browser/skin/'),
|
||||
ManifestOverlay('', 'chrome://global/content/viewSource.xul',
|
||||
'chrome://browser/content/viewSourceOverlay.xul'),
|
||||
]
|
||||
with mozunit.MockedOpen({'manifest': '\n'.join(manifest),
|
||||
'other/manifest': '\n'.join(other_manifest)}):
|
||||
# Ensure we have tests for all types of manifests.
|
||||
self.assertEqual(set(type(e) for e in expected_result),
|
||||
set(MANIFESTS_TYPES.values()))
|
||||
self.assertEqual(list(parse_manifest(os.curdir, 'manifest')),
|
||||
expected_result)
|
||||
self.assertEqual(list(parse_manifest(os.curdir, 'other/manifest')),
|
||||
[ManifestContent('other', 'global',
|
||||
'content/global/')])
|
||||
|
||||
def test_manifest_rebase(self):
|
||||
m = parse_manifest_line('chrome', 'content global content/global/')
|
||||
m = m.rebase('')
|
||||
self.assertEqual(str(m), 'content global chrome/content/global/')
|
||||
m = m.rebase('chrome')
|
||||
self.assertEqual(str(m), 'content global content/global/')
|
||||
|
||||
m = parse_manifest_line('chrome/foo', 'content global content/global/')
|
||||
m = m.rebase('chrome')
|
||||
self.assertEqual(str(m), 'content global foo/content/global/')
|
||||
m = m.rebase('chrome/foo')
|
||||
self.assertEqual(str(m), 'content global content/global/')
|
||||
|
||||
m = parse_manifest_line('modules/foo', 'resource foo ./')
|
||||
m = m.rebase('modules')
|
||||
self.assertEqual(str(m), 'resource foo foo/')
|
||||
m = m.rebase('modules/foo')
|
||||
self.assertEqual(str(m), 'resource foo ./')
|
||||
|
||||
m = parse_manifest_line('chrome', 'content browser browser/content/')
|
||||
m = m.rebase('chrome/browser').move('jar:browser.jar!').rebase('')
|
||||
self.assertEqual(str(m), 'content browser jar:browser.jar!/content/')
|
||||
|
||||
|
||||
class TestManifestErrors(TestErrors, unittest.TestCase):
|
||||
def test_parse_manifest_errors(self):
|
||||
manifest = [
|
||||
'skin global classic/1.0 content/skin/classic/ platform',
|
||||
'',
|
||||
'binary-component bar.so',
|
||||
'unsupported foo',
|
||||
]
|
||||
with mozunit.MockedOpen({'manifest': '\n'.join(manifest)}):
|
||||
with self.assertRaises(AccumulatedErrors):
|
||||
with errors.accumulate():
|
||||
list(parse_manifest(os.curdir, 'manifest'))
|
||||
out = self.get_output()
|
||||
# Expecting 2 errors
|
||||
self.assertEqual(len(out), 2)
|
||||
path = os.path.abspath('manifest')
|
||||
# First on line 1
|
||||
self.assertTrue(out[0].startswith('Error: %s:1: ' % path))
|
||||
# Second on line 4
|
||||
self.assertTrue(out[1].startswith('Error: %s:4: ' % path))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
mozunit.main()
|
|
@ -0,0 +1,178 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
from mozpack.copier import (
|
||||
FileCopier,
|
||||
FileRegistry,
|
||||
Jarrer,
|
||||
)
|
||||
from mozpack.files import GeneratedFile
|
||||
from mozpack.mozjar import JarReader
|
||||
import mozpack.path
|
||||
import unittest
|
||||
import mozunit
|
||||
import os
|
||||
import shutil
|
||||
from mozpack.errors import ErrorMessage
|
||||
from tempfile import mkdtemp
|
||||
from mozpack.test.test_files import (
|
||||
MockDest,
|
||||
MatchTestTemplate,
|
||||
)
|
||||
|
||||
|
||||
class TestFileRegistry(MatchTestTemplate, unittest.TestCase):
|
||||
def add(self, path):
|
||||
self.registry.add(path, GeneratedFile(path))
|
||||
|
||||
def do_check(self, pattern, result):
|
||||
self.checked = True
|
||||
if result:
|
||||
self.assertTrue(self.registry.contains(pattern))
|
||||
else:
|
||||
self.assertFalse(self.registry.contains(pattern))
|
||||
self.assertEqual(self.registry.match(pattern), result)
|
||||
|
||||
def test_file_registry(self):
|
||||
self.registry = FileRegistry()
|
||||
self.registry.add('foo', GeneratedFile('foo'))
|
||||
bar = GeneratedFile('bar')
|
||||
self.registry.add('bar', bar)
|
||||
self.assertEqual(self.registry.paths(), ['foo', 'bar'])
|
||||
self.assertEqual(self.registry['bar'], bar)
|
||||
|
||||
self.assertRaises(ErrorMessage, self.registry.add, 'foo',
|
||||
GeneratedFile('foo2'))
|
||||
|
||||
self.assertRaises(ErrorMessage, self.registry.remove, 'qux')
|
||||
|
||||
self.assertRaises(ErrorMessage, self.registry.add, 'foo/bar',
|
||||
GeneratedFile('foobar'))
|
||||
self.assertRaises(ErrorMessage, self.registry.add, 'foo/bar/baz',
|
||||
GeneratedFile('foobar'))
|
||||
|
||||
self.assertEqual(self.registry.paths(), ['foo', 'bar'])
|
||||
|
||||
self.registry.remove('foo')
|
||||
self.assertEqual(self.registry.paths(), ['bar'])
|
||||
self.registry.remove('bar')
|
||||
self.assertEqual(self.registry.paths(), [])
|
||||
|
||||
self.do_match_test()
|
||||
self.assertTrue(self.checked)
|
||||
self.assertEqual(self.registry.paths(), [
|
||||
'bar',
|
||||
'foo/bar',
|
||||
'foo/baz',
|
||||
'foo/qux/1',
|
||||
'foo/qux/bar',
|
||||
'foo/qux/2/test',
|
||||
'foo/qux/2/test2',
|
||||
])
|
||||
|
||||
self.registry.remove('foo/qux')
|
||||
self.assertEqual(self.registry.paths(), ['bar', 'foo/bar', 'foo/baz'])
|
||||
|
||||
self.registry.add('foo/qux', GeneratedFile('fooqux'))
|
||||
self.assertEqual(self.registry.paths(), ['bar', 'foo/bar', 'foo/baz',
|
||||
'foo/qux'])
|
||||
self.registry.remove('foo/b*')
|
||||
self.assertEqual(self.registry.paths(), ['bar', 'foo/qux'])
|
||||
|
||||
self.assertEqual([f for f, c in self.registry], ['bar', 'foo/qux'])
|
||||
self.assertEqual(len(self.registry), 2)
|
||||
|
||||
self.add('foo/.foo')
|
||||
self.assertTrue(self.registry.contains('foo/.foo'))
|
||||
|
||||
|
||||
class TestFileCopier(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.tmpdir = mkdtemp()
|
||||
|
||||
def tearDown(self):
|
||||
shutil.rmtree(self.tmpdir)
|
||||
|
||||
def all_dirs(self, base):
|
||||
all_dirs = set()
|
||||
for root, dirs, files in os.walk(base):
|
||||
if not dirs:
|
||||
all_dirs.add(mozpack.path.relpath(root, base))
|
||||
return all_dirs
|
||||
|
||||
def all_files(self, base):
|
||||
all_files = set()
|
||||
for root, dirs, files in os.walk(base):
|
||||
for f in files:
|
||||
all_files.add(
|
||||
mozpack.path.join(mozpack.path.relpath(root, base), f))
|
||||
return all_files
|
||||
|
||||
def test_file_copier(self):
|
||||
copier = FileCopier()
|
||||
copier.add('foo/bar', GeneratedFile('foobar'))
|
||||
copier.add('foo/qux', GeneratedFile('fooqux'))
|
||||
copier.add('foo/deep/nested/directory/file', GeneratedFile('fooz'))
|
||||
copier.add('bar', GeneratedFile('bar'))
|
||||
copier.add('qux/foo', GeneratedFile('quxfoo'))
|
||||
copier.add('qux/bar', GeneratedFile(''))
|
||||
|
||||
copier.copy(self.tmpdir)
|
||||
self.assertEqual(self.all_files(self.tmpdir), set(copier.paths()))
|
||||
self.assertEqual(self.all_dirs(self.tmpdir),
|
||||
set(['foo/deep/nested/directory', 'qux']))
|
||||
|
||||
copier.remove('foo')
|
||||
copier.add('test', GeneratedFile('test'))
|
||||
copier.copy(self.tmpdir)
|
||||
self.assertEqual(self.all_files(self.tmpdir), set(copier.paths()))
|
||||
self.assertEqual(self.all_dirs(self.tmpdir), set(['qux']))
|
||||
|
||||
|
||||
class TestJarrer(unittest.TestCase):
|
||||
def check_jar(self, dest, copier):
|
||||
jar = JarReader(fileobj=dest)
|
||||
self.assertEqual([f.filename for f in jar], copier.paths())
|
||||
for f in jar:
|
||||
self.assertEqual(f.uncompressed_data.read(),
|
||||
copier[f.filename].content)
|
||||
|
||||
def test_jarrer(self):
|
||||
copier = Jarrer()
|
||||
copier.add('foo/bar', GeneratedFile('foobar'))
|
||||
copier.add('foo/qux', GeneratedFile('fooqux'))
|
||||
copier.add('foo/deep/nested/directory/file', GeneratedFile('fooz'))
|
||||
copier.add('bar', GeneratedFile('bar'))
|
||||
copier.add('qux/foo', GeneratedFile('quxfoo'))
|
||||
copier.add('qux/bar', GeneratedFile(''))
|
||||
|
||||
dest = MockDest()
|
||||
copier.copy(dest)
|
||||
self.check_jar(dest, copier)
|
||||
|
||||
copier.remove('foo')
|
||||
copier.add('test', GeneratedFile('test'))
|
||||
copier.copy(dest)
|
||||
self.check_jar(dest, copier)
|
||||
|
||||
copier.remove('test')
|
||||
copier.add('test', GeneratedFile('replaced-content'))
|
||||
copier.copy(dest)
|
||||
self.check_jar(dest, copier)
|
||||
|
||||
copier.copy(dest)
|
||||
self.check_jar(dest, copier)
|
||||
|
||||
preloaded = ['qux/bar', 'bar']
|
||||
copier.preload(preloaded)
|
||||
copier.copy(dest)
|
||||
|
||||
dest.seek(0)
|
||||
jar = JarReader(fileobj=dest)
|
||||
self.assertEqual([f.filename for f in jar], preloaded +
|
||||
[p for p in copier.paths() if not p in preloaded])
|
||||
self.assertEqual(jar.last_preloaded, preloaded[-1])
|
||||
|
||||
if __name__ == '__main__':
|
||||
mozunit.main()
|
|
@ -0,0 +1,93 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
from mozpack.errors import (
|
||||
errors,
|
||||
ErrorMessage,
|
||||
AccumulatedErrors,
|
||||
)
|
||||
import unittest
|
||||
import mozunit
|
||||
import sys
|
||||
from cStringIO import StringIO
|
||||
|
||||
|
||||
class TestErrors(object):
|
||||
def setUp(self):
|
||||
errors.out = StringIO()
|
||||
errors.ignore_errors(False)
|
||||
|
||||
def tearDown(self):
|
||||
errors.out = sys.stderr
|
||||
|
||||
def get_output(self):
|
||||
return [l.strip() for l in errors.out.getvalue().splitlines()]
|
||||
|
||||
|
||||
class TestErrorsImpl(TestErrors, unittest.TestCase):
|
||||
def test_plain_error(self):
|
||||
errors.warn('foo')
|
||||
self.assertRaises(ErrorMessage, errors.error, 'foo')
|
||||
self.assertRaises(ErrorMessage, errors.fatal, 'foo')
|
||||
self.assertEquals(self.get_output(), ['Warning: foo'])
|
||||
|
||||
def test_ignore_errors(self):
|
||||
errors.ignore_errors()
|
||||
errors.warn('foo')
|
||||
errors.error('bar')
|
||||
self.assertRaises(ErrorMessage, errors.fatal, 'foo')
|
||||
self.assertEquals(self.get_output(), ['Warning: foo', 'Warning: bar'])
|
||||
|
||||
def test_no_error(self):
|
||||
with errors.accumulate():
|
||||
errors.warn('1')
|
||||
|
||||
def test_simple_error(self):
|
||||
with self.assertRaises(AccumulatedErrors):
|
||||
with errors.accumulate():
|
||||
errors.error('1')
|
||||
self.assertEquals(self.get_output(), ['Error: 1'])
|
||||
|
||||
def test_error_loop(self):
|
||||
with self.assertRaises(AccumulatedErrors):
|
||||
with errors.accumulate():
|
||||
for i in range(3):
|
||||
errors.error('%d' % i)
|
||||
self.assertEquals(self.get_output(),
|
||||
['Error: 0', 'Error: 1', 'Error: 2'])
|
||||
|
||||
def test_multiple_errors(self):
|
||||
with self.assertRaises(AccumulatedErrors):
|
||||
with errors.accumulate():
|
||||
errors.error('foo')
|
||||
for i in range(3):
|
||||
if i == 2:
|
||||
errors.warn('%d' % i)
|
||||
else:
|
||||
errors.error('%d' % i)
|
||||
errors.error('bar')
|
||||
self.assertEquals(self.get_output(),
|
||||
['Error: foo', 'Error: 0', 'Error: 1',
|
||||
'Warning: 2', 'Error: bar'])
|
||||
|
||||
def test_errors_context(self):
|
||||
with self.assertRaises(AccumulatedErrors):
|
||||
with errors.accumulate():
|
||||
self.assertEqual(errors.get_context(), None)
|
||||
with errors.context('foo', 1):
|
||||
self.assertEqual(errors.get_context(), ('foo', 1))
|
||||
errors.error('a')
|
||||
with errors.context('bar', 2):
|
||||
self.assertEqual(errors.get_context(), ('bar', 2))
|
||||
errors.error('b')
|
||||
self.assertEqual(errors.get_context(), ('foo', 1))
|
||||
errors.error('c')
|
||||
self.assertEqual(self.get_output(), [
|
||||
'Error: foo:1: a',
|
||||
'Error: bar:2: b',
|
||||
'Error: foo:1: c',
|
||||
])
|
||||
|
||||
if __name__ == '__main__':
|
||||
mozunit.main()
|
|
@ -0,0 +1,573 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
from mozpack.files import (
|
||||
Dest,
|
||||
File,
|
||||
GeneratedFile,
|
||||
DeflatedFile,
|
||||
ManifestFile,
|
||||
XPTFile,
|
||||
MinifiedProperties,
|
||||
FileFinder,
|
||||
)
|
||||
from mozpack.mozjar import (
|
||||
JarReader,
|
||||
JarWriter,
|
||||
)
|
||||
from mozpack.chrome.manifest import (
|
||||
ManifestContent,
|
||||
ManifestResource,
|
||||
ManifestLocale,
|
||||
ManifestOverride,
|
||||
)
|
||||
import unittest
|
||||
import mozunit
|
||||
import os
|
||||
import shutil
|
||||
import random
|
||||
import string
|
||||
import mozpack.path
|
||||
from mozpack.copier import ensure_parent_dir
|
||||
from tempfile import mkdtemp
|
||||
from io import BytesIO
|
||||
from xpt import Typelib
|
||||
|
||||
|
||||
class TestWithTmpDir(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.tmpdir = mkdtemp()
|
||||
|
||||
def tearDown(self):
|
||||
shutil.rmtree(self.tmpdir)
|
||||
|
||||
def tmppath(self, relpath):
|
||||
return os.path.normpath(os.path.join(self.tmpdir, relpath))
|
||||
|
||||
|
||||
class MockDest(BytesIO, Dest):
|
||||
def __init__(self):
|
||||
BytesIO.__init__(self)
|
||||
self.mode = None
|
||||
|
||||
def read(self, length=-1):
|
||||
if self.mode != 'r':
|
||||
self.seek(0)
|
||||
self.mode = 'r'
|
||||
return BytesIO.read(self, length)
|
||||
|
||||
def write(self, data):
|
||||
if self.mode != 'w':
|
||||
self.seek(0)
|
||||
self.truncate(0)
|
||||
self.mode = 'w'
|
||||
return BytesIO.write(self, data)
|
||||
|
||||
def exists(self):
|
||||
return True
|
||||
|
||||
def close(self):
|
||||
if self.mode:
|
||||
self.mode = None
|
||||
|
||||
|
||||
class DestNoWrite(Dest):
|
||||
def write(self, data):
|
||||
raise RuntimeError
|
||||
|
||||
|
||||
class TestDest(TestWithTmpDir):
|
||||
def test_dest(self):
|
||||
dest = Dest(self.tmppath('dest'))
|
||||
self.assertFalse(dest.exists())
|
||||
dest.write('foo')
|
||||
self.assertTrue(dest.exists())
|
||||
dest.write('foo')
|
||||
self.assertEqual(dest.read(4), 'foof')
|
||||
self.assertEqual(dest.read(), 'oo')
|
||||
self.assertEqual(dest.read(), '')
|
||||
dest.write('bar')
|
||||
self.assertEqual(dest.read(4), 'bar')
|
||||
dest.close()
|
||||
self.assertEqual(dest.read(), 'bar')
|
||||
dest.write('foo')
|
||||
dest.close()
|
||||
dest.write('qux')
|
||||
self.assertEqual(dest.read(), 'qux')
|
||||
|
||||
rand = ''.join(random.choice(string.letters) for i in xrange(131597))
|
||||
samples = [
|
||||
'',
|
||||
'test',
|
||||
'fooo',
|
||||
'same',
|
||||
'same',
|
||||
'Different and longer',
|
||||
rand,
|
||||
rand,
|
||||
rand[:-1] + '_',
|
||||
'test'
|
||||
]
|
||||
|
||||
|
||||
class TestFile(TestWithTmpDir):
|
||||
def test_file(self):
|
||||
'''
|
||||
Check that File.copy yields the proper content in the destination file
|
||||
in all situations that trigger different code paths:
|
||||
- different content
|
||||
- different content of the same size
|
||||
- same content
|
||||
- long content
|
||||
'''
|
||||
src = self.tmppath('src')
|
||||
dest = self.tmppath('dest')
|
||||
|
||||
for content in samples:
|
||||
with open(src, 'wb') as tmp:
|
||||
tmp.write(content)
|
||||
# Ensure the destination file, when it exists, is older than the
|
||||
# source
|
||||
if os.path.exists(dest):
|
||||
time = os.path.getmtime(src) - 1
|
||||
os.utime(dest, (time, time))
|
||||
f = File(src)
|
||||
f.copy(dest)
|
||||
self.assertEqual(content, open(dest, 'rb').read())
|
||||
self.assertEqual(content, f.open().read())
|
||||
self.assertEqual(content, f.open().read())
|
||||
|
||||
def test_file_dest(self):
|
||||
'''
|
||||
Similar to test_file, but for a destination object instead of
|
||||
a destination file. This ensures the destination object is being
|
||||
used properly by File.copy, ensuring that other subclasses of Dest
|
||||
will work.
|
||||
'''
|
||||
src = self.tmppath('src')
|
||||
dest = MockDest()
|
||||
|
||||
for content in samples:
|
||||
with open(src, 'wb') as tmp:
|
||||
tmp.write(content)
|
||||
f = File(src)
|
||||
f.copy(dest)
|
||||
self.assertEqual(content, dest.getvalue())
|
||||
|
||||
def test_file_open(self):
|
||||
'''
|
||||
Test whether File.open returns an appropriately reset file object.
|
||||
'''
|
||||
src = self.tmppath('src')
|
||||
content = ''.join(samples)
|
||||
with open(src, 'wb') as tmp:
|
||||
tmp.write(content)
|
||||
|
||||
f = File(src)
|
||||
self.assertEqual(content[:42], f.open().read(42))
|
||||
self.assertEqual(content, f.open().read())
|
||||
|
||||
def test_file_no_write(self):
|
||||
'''
|
||||
Test various conditions where File.copy is expected not to write
|
||||
in the destination file.
|
||||
'''
|
||||
src = self.tmppath('src')
|
||||
dest = self.tmppath('dest')
|
||||
|
||||
with open(src, 'wb') as tmp:
|
||||
tmp.write('test')
|
||||
|
||||
# Initial copy
|
||||
f = File(src)
|
||||
f.copy(dest)
|
||||
|
||||
# Ensure subsequent copies won't trigger writes
|
||||
f.copy(DestNoWrite(dest))
|
||||
self.assertEqual('test', open(dest, 'rb').read())
|
||||
|
||||
# When the source file is newer, but with the same content, no copy
|
||||
# should occur
|
||||
time = os.path.getmtime(src) - 1
|
||||
os.utime(dest, (time, time))
|
||||
f.copy(DestNoWrite(dest))
|
||||
self.assertEqual('test', open(dest, 'rb').read())
|
||||
|
||||
# When the source file is older than the destination file, even with
|
||||
# different content, no copy should occur.
|
||||
with open(src, 'wb') as tmp:
|
||||
tmp.write('fooo')
|
||||
time = os.path.getmtime(dest) - 1
|
||||
os.utime(src, (time, time))
|
||||
f.copy(DestNoWrite(dest))
|
||||
self.assertEqual('test', open(dest, 'rb').read())
|
||||
|
||||
# Double check that under conditions where a copy occurs, we would get
|
||||
# an exception.
|
||||
time = os.path.getmtime(src) - 1
|
||||
os.utime(dest, (time, time))
|
||||
self.assertRaises(RuntimeError, f.copy, DestNoWrite(dest))
|
||||
|
||||
|
||||
class TestGeneratedFile(TestWithTmpDir):
|
||||
def test_generated_file(self):
|
||||
'''
|
||||
Check that GeneratedFile.copy yields the proper content in the
|
||||
destination file in all situations that trigger different code paths
|
||||
(see TestFile.test_file)
|
||||
'''
|
||||
dest = self.tmppath('dest')
|
||||
|
||||
for content in samples:
|
||||
f = GeneratedFile(content)
|
||||
f.copy(dest)
|
||||
self.assertEqual(content, open(dest, 'rb').read())
|
||||
|
||||
def test_generated_file_open(self):
|
||||
'''
|
||||
Test whether GeneratedFile.open returns an appropriately reset file
|
||||
object.
|
||||
'''
|
||||
content = ''.join(samples)
|
||||
f = GeneratedFile(content)
|
||||
self.assertEqual(content[:42], f.open().read(42))
|
||||
self.assertEqual(content, f.open().read())
|
||||
|
||||
def test_generated_file_no_write(self):
|
||||
'''
|
||||
Test various conditions where GeneratedFile.copy is expected not to
|
||||
write in the destination file.
|
||||
'''
|
||||
dest = self.tmppath('dest')
|
||||
|
||||
# Initial copy
|
||||
f = GeneratedFile('test')
|
||||
f.copy(dest)
|
||||
|
||||
# Ensure subsequent copies won't trigger writes
|
||||
f.copy(DestNoWrite(dest))
|
||||
self.assertEqual('test', open(dest, 'rb').read())
|
||||
|
||||
# When using a new instance with the same content, no copy should occur
|
||||
f = GeneratedFile('test')
|
||||
f.copy(DestNoWrite(dest))
|
||||
self.assertEqual('test', open(dest, 'rb').read())
|
||||
|
||||
# Double check that under conditions where a copy occurs, we would get
|
||||
# an exception.
|
||||
f = GeneratedFile('fooo')
|
||||
self.assertRaises(RuntimeError, f.copy, DestNoWrite(dest))
|
||||
|
||||
|
||||
class TestDeflatedFile(TestWithTmpDir):
|
||||
def test_deflated_file(self):
|
||||
'''
|
||||
Check that DeflatedFile.copy yields the proper content in the
|
||||
destination file in all situations that trigger different code paths
|
||||
(see TestFile.test_file)
|
||||
'''
|
||||
src = self.tmppath('src.jar')
|
||||
dest = self.tmppath('dest')
|
||||
|
||||
contents = {}
|
||||
with JarWriter(src) as jar:
|
||||
for content in samples:
|
||||
name = ''.join(random.choice(string.letters)
|
||||
for i in xrange(8))
|
||||
jar.add(name, content, compress=True)
|
||||
contents[name] = content
|
||||
|
||||
for j in JarReader(src):
|
||||
f = DeflatedFile(j)
|
||||
f.copy(dest)
|
||||
self.assertEqual(contents[j.filename], open(dest, 'rb').read())
|
||||
|
||||
def test_deflated_file_open(self):
|
||||
'''
|
||||
Test whether DeflatedFile.open returns an appropriately reset file
|
||||
object.
|
||||
'''
|
||||
src = self.tmppath('src.jar')
|
||||
content = ''.join(samples)
|
||||
with JarWriter(src) as jar:
|
||||
jar.add('content', content)
|
||||
|
||||
f = DeflatedFile(JarReader(src)['content'])
|
||||
self.assertEqual(content[:42], f.open().read(42))
|
||||
self.assertEqual(content, f.open().read())
|
||||
|
||||
def test_deflated_file_no_write(self):
|
||||
'''
|
||||
Test various conditions where DeflatedFile.copy is expected not to
|
||||
write in the destination file.
|
||||
'''
|
||||
src = self.tmppath('src.jar')
|
||||
dest = self.tmppath('dest')
|
||||
|
||||
with JarWriter(src) as jar:
|
||||
jar.add('test', 'test')
|
||||
jar.add('test2', 'test')
|
||||
jar.add('fooo', 'fooo')
|
||||
|
||||
jar = JarReader(src)
|
||||
# Initial copy
|
||||
f = DeflatedFile(jar['test'])
|
||||
f.copy(dest)
|
||||
|
||||
# Ensure subsequent copies won't trigger writes
|
||||
f.copy(DestNoWrite(dest))
|
||||
self.assertEqual('test', open(dest, 'rb').read())
|
||||
|
||||
# When using a different file with the same content, no copy should
|
||||
# occur
|
||||
f = DeflatedFile(jar['test2'])
|
||||
f.copy(DestNoWrite(dest))
|
||||
self.assertEqual('test', open(dest, 'rb').read())
|
||||
|
||||
# Double check that under conditions where a copy occurs, we would get
|
||||
# an exception.
|
||||
f = DeflatedFile(jar['fooo'])
|
||||
self.assertRaises(RuntimeError, f.copy, DestNoWrite(dest))
|
||||
|
||||
|
||||
class TestManifestFile(TestWithTmpDir):
|
||||
def test_manifest_file(self):
|
||||
f = ManifestFile('chrome')
|
||||
f.add(ManifestContent('chrome', 'global', 'toolkit/content/global/'))
|
||||
f.add(ManifestResource('chrome', 'gre-resources', 'toolkit/res/'))
|
||||
f.add(ManifestResource('chrome/pdfjs', 'pdfjs', './'))
|
||||
f.add(ManifestContent('chrome/pdfjs', 'pdfjs', 'pdfjs'))
|
||||
f.add(ManifestLocale('chrome', 'browser', 'en-US',
|
||||
'en-US/locale/browser/'))
|
||||
|
||||
f.copy(self.tmppath('chrome.manifest'))
|
||||
self.assertEqual(open(self.tmppath('chrome.manifest')).readlines(), [
|
||||
'content global toolkit/content/global/\n',
|
||||
'resource gre-resources toolkit/res/\n',
|
||||
'resource pdfjs pdfjs/\n',
|
||||
'content pdfjs pdfjs/pdfjs\n',
|
||||
'locale browser en-US en-US/locale/browser/\n',
|
||||
])
|
||||
|
||||
self.assertRaises(
|
||||
ValueError,
|
||||
f.remove,
|
||||
ManifestContent('', 'global', 'toolkit/content/global/')
|
||||
)
|
||||
self.assertRaises(
|
||||
ValueError,
|
||||
f.remove,
|
||||
ManifestOverride('chrome', 'chrome://global/locale/netError.dtd',
|
||||
'chrome://browser/locale/netError.dtd')
|
||||
)
|
||||
|
||||
f.remove(ManifestContent('chrome', 'global',
|
||||
'toolkit/content/global/'))
|
||||
self.assertRaises(
|
||||
ValueError,
|
||||
f.remove,
|
||||
ManifestContent('chrome', 'global', 'toolkit/content/global/')
|
||||
)
|
||||
|
||||
f.copy(self.tmppath('chrome.manifest'))
|
||||
content = open(self.tmppath('chrome.manifest')).read()
|
||||
self.assertEqual(content[:42], f.open().read(42))
|
||||
self.assertEqual(content, f.open().read())
|
||||
|
||||
# Compiled typelib for the following IDL:
|
||||
# interface foo;
|
||||
# [uuid(5f70da76-519c-4858-b71e-e3c92333e2d6)]
|
||||
# interface bar {
|
||||
# void bar(in foo f);
|
||||
# };
|
||||
bar_xpt = GeneratedFile(
|
||||
b'\x58\x50\x43\x4F\x4D\x0A\x54\x79\x70\x65\x4C\x69\x62\x0D\x0A\x1A' +
|
||||
b'\x01\x02\x00\x02\x00\x00\x00\x7B\x00\x00\x00\x24\x00\x00\x00\x5C' +
|
||||
b'\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' +
|
||||
b'\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x5F' +
|
||||
b'\x70\xDA\x76\x51\x9C\x48\x58\xB7\x1E\xE3\xC9\x23\x33\xE2\xD6\x00' +
|
||||
b'\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x0D\x00\x66\x6F\x6F\x00' +
|
||||
b'\x62\x61\x72\x00\x62\x61\x72\x00\x00\x00\x00\x01\x00\x00\x00\x00' +
|
||||
b'\x09\x01\x80\x92\x00\x01\x80\x06\x00\x00\x00'
|
||||
)
|
||||
|
||||
# Compiled typelib for the following IDL:
|
||||
# [uuid(3271bebc-927e-4bef-935e-44e0aaf3c1e5)]
|
||||
# interface foo {
|
||||
# void foo();
|
||||
# };
|
||||
foo_xpt = GeneratedFile(
|
||||
b'\x58\x50\x43\x4F\x4D\x0A\x54\x79\x70\x65\x4C\x69\x62\x0D\x0A\x1A' +
|
||||
b'\x01\x02\x00\x01\x00\x00\x00\x57\x00\x00\x00\x24\x00\x00\x00\x40' +
|
||||
b'\x80\x00\x00\x32\x71\xBE\xBC\x92\x7E\x4B\xEF\x93\x5E\x44\xE0\xAA' +
|
||||
b'\xF3\xC1\xE5\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x09\x00' +
|
||||
b'\x66\x6F\x6F\x00\x66\x6F\x6F\x00\x00\x00\x00\x01\x00\x00\x00\x00' +
|
||||
b'\x05\x00\x80\x06\x00\x00\x00'
|
||||
)
|
||||
|
||||
# Compiled typelib for the following IDL:
|
||||
# [uuid(7057f2aa-fdc2-4559-abde-08d939f7e80d)]
|
||||
# interface foo {
|
||||
# void foo();
|
||||
# };
|
||||
foo2_xpt = GeneratedFile(
|
||||
b'\x58\x50\x43\x4F\x4D\x0A\x54\x79\x70\x65\x4C\x69\x62\x0D\x0A\x1A' +
|
||||
b'\x01\x02\x00\x01\x00\x00\x00\x57\x00\x00\x00\x24\x00\x00\x00\x40' +
|
||||
b'\x80\x00\x00\x70\x57\xF2\xAA\xFD\xC2\x45\x59\xAB\xDE\x08\xD9\x39' +
|
||||
b'\xF7\xE8\x0D\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x09\x00' +
|
||||
b'\x66\x6F\x6F\x00\x66\x6F\x6F\x00\x00\x00\x00\x01\x00\x00\x00\x00' +
|
||||
b'\x05\x00\x80\x06\x00\x00\x00'
|
||||
)
|
||||
|
||||
|
||||
def read_interfaces(file):
|
||||
return dict((i.name, i) for i in Typelib.read(file).interfaces)
|
||||
|
||||
|
||||
class TestXPTFile(TestWithTmpDir):
|
||||
def test_xpt_file(self):
|
||||
x = XPTFile()
|
||||
x.add(foo_xpt)
|
||||
x.add(bar_xpt)
|
||||
x.copy(self.tmppath('interfaces.xpt'))
|
||||
|
||||
foo = read_interfaces(foo_xpt.open())
|
||||
foo2 = read_interfaces(foo2_xpt.open())
|
||||
bar = read_interfaces(bar_xpt.open())
|
||||
linked = read_interfaces(self.tmppath('interfaces.xpt'))
|
||||
self.assertEqual(foo['foo'], linked['foo'])
|
||||
self.assertEqual(bar['bar'], linked['bar'])
|
||||
|
||||
x.remove(foo_xpt)
|
||||
x.copy(self.tmppath('interfaces2.xpt'))
|
||||
linked = read_interfaces(self.tmppath('interfaces2.xpt'))
|
||||
self.assertEqual(bar['foo'], linked['foo'])
|
||||
self.assertEqual(bar['bar'], linked['bar'])
|
||||
|
||||
x.add(foo_xpt)
|
||||
x.copy(DestNoWrite(self.tmppath('interfaces.xpt')))
|
||||
linked = read_interfaces(self.tmppath('interfaces.xpt'))
|
||||
self.assertEqual(foo['foo'], linked['foo'])
|
||||
self.assertEqual(bar['bar'], linked['bar'])
|
||||
|
||||
x = XPTFile()
|
||||
x.add(foo2_xpt)
|
||||
x.add(bar_xpt)
|
||||
x.copy(self.tmppath('interfaces.xpt'))
|
||||
linked = read_interfaces(self.tmppath('interfaces.xpt'))
|
||||
self.assertEqual(foo2['foo'], linked['foo'])
|
||||
self.assertEqual(bar['bar'], linked['bar'])
|
||||
|
||||
x = XPTFile()
|
||||
x.add(foo_xpt)
|
||||
x.add(foo2_xpt)
|
||||
x.add(bar_xpt)
|
||||
from xpt import DataError
|
||||
self.assertRaises(DataError, x.copy, self.tmppath('interfaces.xpt'))
|
||||
|
||||
|
||||
class TestMinifiedProperties(TestWithTmpDir):
|
||||
def test_minified_properties(self):
|
||||
propLines = [
|
||||
'# Comments are removed',
|
||||
'foo = bar',
|
||||
'',
|
||||
'# Another comment',
|
||||
]
|
||||
prop = GeneratedFile('\n'.join(propLines))
|
||||
self.assertEqual(MinifiedProperties(prop).open().readlines(),
|
||||
['foo = bar\n', '\n'])
|
||||
open(self.tmppath('prop'), 'wb').write('\n'.join(propLines))
|
||||
MinifiedProperties(File(self.tmppath('prop'))) \
|
||||
.copy(self.tmppath('prop2'))
|
||||
self.assertEqual(open(self.tmppath('prop2')).readlines(),
|
||||
['foo = bar\n', '\n'])
|
||||
|
||||
|
||||
class MatchTestTemplate(object):
|
||||
def do_match_test(self):
|
||||
self.add('bar')
|
||||
self.add('foo/bar')
|
||||
self.add('foo/baz')
|
||||
self.add('foo/qux/1')
|
||||
self.add('foo/qux/bar')
|
||||
self.add('foo/qux/2/test')
|
||||
self.add('foo/qux/2/test2')
|
||||
|
||||
self.do_check('', [
|
||||
'bar', 'foo/bar', 'foo/baz', 'foo/qux/1', 'foo/qux/bar',
|
||||
'foo/qux/2/test', 'foo/qux/2/test2'
|
||||
])
|
||||
self.do_check('*', [
|
||||
'bar', 'foo/bar', 'foo/baz', 'foo/qux/1', 'foo/qux/bar',
|
||||
'foo/qux/2/test', 'foo/qux/2/test2'
|
||||
])
|
||||
self.do_check('foo/qux', [
|
||||
'foo/qux/1', 'foo/qux/bar', 'foo/qux/2/test', 'foo/qux/2/test2'
|
||||
])
|
||||
self.do_check('foo/b*', ['foo/bar', 'foo/baz'])
|
||||
self.do_check('baz', [])
|
||||
self.do_check('foo/foo', [])
|
||||
self.do_check('foo/*ar', ['foo/bar'])
|
||||
self.do_check('*ar', ['bar'])
|
||||
self.do_check('*/bar', ['foo/bar'])
|
||||
self.do_check('foo/*ux', [
|
||||
'foo/qux/1', 'foo/qux/bar', 'foo/qux/2/test', 'foo/qux/2/test2'
|
||||
])
|
||||
self.do_check('foo/q*ux', [
|
||||
'foo/qux/1', 'foo/qux/bar', 'foo/qux/2/test', 'foo/qux/2/test2'
|
||||
])
|
||||
self.do_check('foo/*/2/test*', ['foo/qux/2/test', 'foo/qux/2/test2'])
|
||||
self.do_check('**/bar', ['bar', 'foo/bar', 'foo/qux/bar'])
|
||||
self.do_check('foo/**/test', ['foo/qux/2/test'])
|
||||
self.do_check('foo/**', [
|
||||
'foo/bar', 'foo/baz', 'foo/qux/1', 'foo/qux/bar',
|
||||
'foo/qux/2/test', 'foo/qux/2/test2'
|
||||
])
|
||||
self.do_check('**/2/test*', ['foo/qux/2/test', 'foo/qux/2/test2'])
|
||||
self.do_check('**/foo', [
|
||||
'foo/bar', 'foo/baz', 'foo/qux/1', 'foo/qux/bar',
|
||||
'foo/qux/2/test', 'foo/qux/2/test2'
|
||||
])
|
||||
self.do_check('**/barbaz', [])
|
||||
self.do_check('f**/bar', ['foo/bar'])
|
||||
|
||||
|
||||
class TestFileFinder(MatchTestTemplate, TestWithTmpDir):
|
||||
def add(self, path):
|
||||
ensure_parent_dir(self.tmppath(path))
|
||||
open(self.tmppath(path), 'wb').write(path)
|
||||
|
||||
def do_check(self, pattern, result):
|
||||
if result:
|
||||
self.assertTrue(self.finder.contains(pattern))
|
||||
else:
|
||||
self.assertFalse(self.finder.contains(pattern))
|
||||
self.assertEqual(sorted(list(f for f, c in self.finder.find(pattern))),
|
||||
sorted(result))
|
||||
|
||||
def test_file_finder(self):
|
||||
self.finder = FileFinder(self.tmpdir)
|
||||
self.do_match_test()
|
||||
self.add('foo/.foo')
|
||||
self.add('foo/.bar/foo')
|
||||
self.assertTrue(self.finder.contains('foo/.foo'))
|
||||
self.assertTrue(self.finder.contains('foo/.bar'))
|
||||
self.assertTrue('foo/.foo' in [f for f, c in
|
||||
self.finder.find('foo/.foo')])
|
||||
self.assertTrue('foo/.bar/foo' in [f for f, c in
|
||||
self.finder.find('foo/.bar')])
|
||||
self.assertEqual(sorted([f for f, c in self.finder.find('foo/.*')]),
|
||||
['foo/.bar/foo', 'foo/.foo'])
|
||||
for pattern in ['foo', '**', '**/*', '**/foo', 'foo/*']:
|
||||
self.assertFalse('foo/.foo' in [f for f, c in
|
||||
self.finder.find(pattern)])
|
||||
self.assertFalse('foo/.bar/foo' in [f for f, c in
|
||||
self.finder.find(pattern)])
|
||||
self.assertEqual(sorted([f for f, c in self.finder.find(pattern)]),
|
||||
sorted([f for f, c in self.finder
|
||||
if mozpack.path.match(f, pattern)]))
|
||||
|
||||
if __name__ == '__main__':
|
||||
mozunit.main()
|
|
@ -0,0 +1,259 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
from mozpack.mozjar import (
|
||||
JarReaderError,
|
||||
JarWriterError,
|
||||
JarStruct,
|
||||
JarReader,
|
||||
JarWriter,
|
||||
Deflater,
|
||||
OrderedDict,
|
||||
)
|
||||
from mozpack.test.test_files import MockDest
|
||||
import unittest
|
||||
import mozunit
|
||||
|
||||
|
||||
class TestJarStruct(unittest.TestCase):
|
||||
class Foo(JarStruct):
|
||||
MAGIC = 0x01020304
|
||||
STRUCT = OrderedDict([
|
||||
('foo', 'uint32'),
|
||||
('bar', 'uint16'),
|
||||
('qux', 'uint16'),
|
||||
('length', 'uint16'),
|
||||
('length2', 'uint16'),
|
||||
('string', 'length'),
|
||||
('string2', 'length2'),
|
||||
])
|
||||
|
||||
def test_jar_struct(self):
|
||||
foo = TestJarStruct.Foo()
|
||||
self.assertEqual(foo.signature, TestJarStruct.Foo.MAGIC)
|
||||
self.assertEqual(foo['foo'], 0)
|
||||
self.assertEqual(foo['bar'], 0)
|
||||
self.assertEqual(foo['qux'], 0)
|
||||
self.assertFalse('length' in foo)
|
||||
self.assertFalse('length2' in foo)
|
||||
self.assertEqual(foo['string'], '')
|
||||
self.assertEqual(foo['string2'], '')
|
||||
|
||||
self.assertEqual(foo.size, 16)
|
||||
|
||||
foo['foo'] = 0x42434445
|
||||
foo['bar'] = 0xabcd
|
||||
foo['qux'] = 0xef01
|
||||
foo['string'] = 'abcde'
|
||||
foo['string2'] = 'Arbitrarily long string'
|
||||
|
||||
serialized = b'\x04\x03\x02\x01\x45\x44\x43\x42\xcd\xab\x01\xef' + \
|
||||
b'\x05\x00\x17\x00abcdeArbitrarily long string'
|
||||
self.assertEqual(foo.size, len(serialized))
|
||||
foo_serialized = foo.serialize()
|
||||
self.assertEqual(foo_serialized, serialized)
|
||||
|
||||
def do_test_read_jar_struct(self, data):
|
||||
self.assertRaises(JarReaderError, TestJarStruct.Foo, data)
|
||||
self.assertRaises(JarReaderError, TestJarStruct.Foo, data[2:])
|
||||
|
||||
foo = TestJarStruct.Foo(data[1:])
|
||||
self.assertEqual(foo['foo'], 0x45444342)
|
||||
self.assertEqual(foo['bar'], 0xcdab)
|
||||
self.assertEqual(foo['qux'], 0x01ef)
|
||||
self.assertFalse('length' in foo)
|
||||
self.assertFalse('length2' in foo)
|
||||
self.assertEqual(foo['string'], '012345')
|
||||
self.assertEqual(foo['string2'], '67')
|
||||
|
||||
def test_read_jar_struct(self):
|
||||
data = b'\x00\x04\x03\x02\x01\x42\x43\x44\x45\xab\xcd\xef' + \
|
||||
b'\x01\x06\x00\x02\x0001234567890'
|
||||
self.do_test_read_jar_struct(data)
|
||||
|
||||
def test_read_jar_struct_memoryview(self):
|
||||
data = b'\x00\x04\x03\x02\x01\x42\x43\x44\x45\xab\xcd\xef' + \
|
||||
b'\x01\x06\x00\x02\x0001234567890'
|
||||
self.do_test_read_jar_struct(memoryview(data))
|
||||
|
||||
|
||||
class TestDeflater(unittest.TestCase):
|
||||
def wrap(self, data):
|
||||
return data
|
||||
|
||||
def test_deflater_no_compress(self):
|
||||
deflater = Deflater(False)
|
||||
deflater.write(self.wrap('abc'))
|
||||
self.assertFalse(deflater.compressed)
|
||||
self.assertEqual(deflater.uncompressed_size, 3)
|
||||
self.assertEqual(deflater.compressed_size, deflater.uncompressed_size)
|
||||
self.assertEqual(deflater.compressed_data, 'abc')
|
||||
self.assertEqual(deflater.crc32, 0x352441c2)
|
||||
|
||||
def test_deflater_compress_no_gain(self):
|
||||
deflater = Deflater(True)
|
||||
deflater.write(self.wrap('abc'))
|
||||
self.assertFalse(deflater.compressed)
|
||||
self.assertEqual(deflater.uncompressed_size, 3)
|
||||
self.assertEqual(deflater.compressed_size, deflater.uncompressed_size)
|
||||
self.assertEqual(deflater.compressed_data, 'abc')
|
||||
self.assertEqual(deflater.crc32, 0x352441c2)
|
||||
|
||||
def test_deflater_compress(self):
|
||||
deflater = Deflater(True)
|
||||
deflater.write(self.wrap('aaaaaaaaaaaaanopqrstuvwxyz'))
|
||||
self.assertTrue(deflater.compressed)
|
||||
self.assertEqual(deflater.uncompressed_size, 26)
|
||||
self.assertNotEqual(deflater.compressed_size,
|
||||
deflater.uncompressed_size)
|
||||
self.assertEqual(deflater.crc32, 0xd46b97ed)
|
||||
# The CRC is the same as when not compressed
|
||||
deflater = Deflater(False)
|
||||
self.assertFalse(deflater.compressed)
|
||||
deflater.write(self.wrap('aaaaaaaaaaaaanopqrstuvwxyz'))
|
||||
self.assertEqual(deflater.crc32, 0xd46b97ed)
|
||||
|
||||
|
||||
class TestDeflaterMemoryView(TestDeflater):
|
||||
def wrap(self, data):
|
||||
return memoryview(data)
|
||||
|
||||
|
||||
class TestJar(unittest.TestCase):
|
||||
optimize = False
|
||||
|
||||
def test_jar(self):
|
||||
s = MockDest()
|
||||
with JarWriter(fileobj=s, optimize=self.optimize) as jar:
|
||||
jar.add('foo', 'foo')
|
||||
self.assertRaises(JarWriterError, jar.add, 'foo', 'bar')
|
||||
jar.add('bar', 'aaaaaaaaaaaaanopqrstuvwxyz')
|
||||
jar.add('baz/qux', 'aaaaaaaaaaaaanopqrstuvwxyz', False)
|
||||
|
||||
files = [j for j in JarReader(fileobj=s)]
|
||||
|
||||
self.assertEqual(files[0].filename, 'foo')
|
||||
self.assertFalse(files[0].compressed)
|
||||
self.assertEqual(files[0].read(), 'foo')
|
||||
|
||||
self.assertEqual(files[1].filename, 'bar')
|
||||
self.assertTrue(files[1].compressed)
|
||||
self.assertEqual(files[1].read(), 'aaaaaaaaaaaaanopqrstuvwxyz')
|
||||
|
||||
self.assertEqual(files[2].filename, 'baz/qux')
|
||||
self.assertFalse(files[2].compressed)
|
||||
self.assertEqual(files[2].read(), 'aaaaaaaaaaaaanopqrstuvwxyz')
|
||||
|
||||
s = MockDest()
|
||||
with JarWriter(fileobj=s, compress=False,
|
||||
optimize=self.optimize) as jar:
|
||||
jar.add('bar', 'aaaaaaaaaaaaanopqrstuvwxyz')
|
||||
jar.add('foo', 'foo')
|
||||
jar.add('baz/qux', 'aaaaaaaaaaaaanopqrstuvwxyz', True)
|
||||
|
||||
jar = JarReader(fileobj=s)
|
||||
files = [j for j in jar]
|
||||
|
||||
self.assertEqual(files[0].filename, 'bar')
|
||||
self.assertFalse(files[0].compressed)
|
||||
self.assertEqual(files[0].read(), 'aaaaaaaaaaaaanopqrstuvwxyz')
|
||||
|
||||
self.assertEqual(files[1].filename, 'foo')
|
||||
self.assertFalse(files[1].compressed)
|
||||
self.assertEqual(files[1].read(), 'foo')
|
||||
|
||||
self.assertEqual(files[2].filename, 'baz/qux')
|
||||
self.assertTrue(files[2].compressed)
|
||||
self.assertEqual(files[2].read(), 'aaaaaaaaaaaaanopqrstuvwxyz')
|
||||
|
||||
self.assertTrue('bar' in jar)
|
||||
self.assertTrue('foo' in jar)
|
||||
self.assertFalse('baz' in jar)
|
||||
self.assertTrue('baz/qux' in jar)
|
||||
self.assertTrue(jar['bar'], files[1])
|
||||
self.assertTrue(jar['foo'], files[0])
|
||||
self.assertTrue(jar['baz/qux'], files[2])
|
||||
|
||||
s.seek(0)
|
||||
jar = JarReader(fileobj=s)
|
||||
self.assertTrue('bar' in jar)
|
||||
self.assertTrue('foo' in jar)
|
||||
self.assertFalse('baz' in jar)
|
||||
self.assertTrue('baz/qux' in jar)
|
||||
|
||||
files[0].seek(0)
|
||||
self.assertEqual(jar['bar'].filename, files[0].filename)
|
||||
self.assertEqual(jar['bar'].compressed, files[0].compressed)
|
||||
self.assertEqual(jar['bar'].read(), files[0].read())
|
||||
|
||||
files[1].seek(0)
|
||||
self.assertEqual(jar['foo'].filename, files[1].filename)
|
||||
self.assertEqual(jar['foo'].compressed, files[1].compressed)
|
||||
self.assertEqual(jar['foo'].read(), files[1].read())
|
||||
|
||||
files[2].seek(0)
|
||||
self.assertEqual(jar['baz/qux'].filename, files[2].filename)
|
||||
self.assertEqual(jar['baz/qux'].compressed, files[2].compressed)
|
||||
self.assertEqual(jar['baz/qux'].read(), files[2].read())
|
||||
|
||||
def test_rejar(self):
|
||||
s = MockDest()
|
||||
with JarWriter(fileobj=s, optimize=self.optimize) as jar:
|
||||
jar.add('foo', 'foo')
|
||||
jar.add('bar', 'aaaaaaaaaaaaanopqrstuvwxyz')
|
||||
jar.add('baz/qux', 'aaaaaaaaaaaaanopqrstuvwxyz', False)
|
||||
|
||||
new = MockDest()
|
||||
with JarWriter(fileobj=new, optimize=self.optimize) as jar:
|
||||
for j in JarReader(fileobj=s):
|
||||
jar.add(j.filename, j)
|
||||
|
||||
jar = JarReader(fileobj=new)
|
||||
files = [j for j in jar]
|
||||
|
||||
self.assertEqual(files[0].filename, 'foo')
|
||||
self.assertFalse(files[0].compressed)
|
||||
self.assertEqual(files[0].read(), 'foo')
|
||||
|
||||
self.assertEqual(files[1].filename, 'bar')
|
||||
self.assertTrue(files[1].compressed)
|
||||
self.assertEqual(files[1].read(), 'aaaaaaaaaaaaanopqrstuvwxyz')
|
||||
|
||||
self.assertEqual(files[2].filename, 'baz/qux')
|
||||
self.assertTrue(files[2].compressed)
|
||||
self.assertEqual(files[2].read(), 'aaaaaaaaaaaaanopqrstuvwxyz')
|
||||
|
||||
|
||||
class TestOptimizeJar(TestJar):
|
||||
optimize = True
|
||||
|
||||
|
||||
class TestPreload(unittest.TestCase):
|
||||
def test_preload(self):
|
||||
s = MockDest()
|
||||
with JarWriter(fileobj=s) as jar:
|
||||
jar.add('foo', 'foo')
|
||||
jar.add('bar', 'abcdefghijklmnopqrstuvwxyz')
|
||||
jar.add('baz/qux', 'aaaaaaaaaaaaanopqrstuvwxyz')
|
||||
|
||||
jar = JarReader(fileobj=s)
|
||||
self.assertEqual(jar.last_preloaded, None)
|
||||
|
||||
with JarWriter(fileobj=s) as jar:
|
||||
jar.add('foo', 'foo')
|
||||
jar.add('bar', 'abcdefghijklmnopqrstuvwxyz')
|
||||
jar.add('baz/qux', 'aaaaaaaaaaaaanopqrstuvwxyz')
|
||||
jar.preload(['baz/qux', 'bar'])
|
||||
|
||||
jar = JarReader(fileobj=s)
|
||||
self.assertEqual(jar.last_preloaded, 'bar')
|
||||
files = [j for j in jar]
|
||||
|
||||
self.assertEqual(files[0].filename, 'baz/qux')
|
||||
self.assertEqual(files[1].filename, 'bar')
|
||||
self.assertEqual(files[2].filename, 'foo')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
mozunit.main()
|
|
@ -0,0 +1,256 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
import unittest
|
||||
import mozunit
|
||||
import os
|
||||
from mozpack.packager import (
|
||||
preprocess_manifest,
|
||||
SimplePackager,
|
||||
SimpleManifestSink,
|
||||
CallDeque,
|
||||
)
|
||||
from mozpack.files import GeneratedFile
|
||||
from mozpack.chrome.manifest import (
|
||||
ManifestResource,
|
||||
ManifestContent,
|
||||
)
|
||||
from mozunit import MockedOpen
|
||||
from Preprocessor import Preprocessor
|
||||
from mozpack.errors import (
|
||||
errors,
|
||||
ErrorMessage,
|
||||
)
|
||||
import mozpack.path
|
||||
|
||||
MANIFEST = '''
|
||||
bar/*
|
||||
[foo]
|
||||
foo/*
|
||||
-foo/bar
|
||||
chrome.manifest
|
||||
; comment
|
||||
#ifdef baz
|
||||
[baz]
|
||||
baz@SUFFIX@
|
||||
#endif
|
||||
'''
|
||||
|
||||
|
||||
class TestPreprocessManifest(unittest.TestCase):
|
||||
MANIFEST_PATH = os.path.join(os.path.abspath(os.curdir), 'manifest')
|
||||
|
||||
EXPECTED_LOG = [
|
||||
((MANIFEST_PATH, 2), 'add', '', 'bar/*'),
|
||||
((MANIFEST_PATH, 4), 'add', 'foo', 'foo/*'),
|
||||
((MANIFEST_PATH, 5), 'remove', 'foo', 'foo/bar'),
|
||||
((MANIFEST_PATH, 6), 'add', 'foo', 'chrome.manifest')
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
class MockSink(object):
|
||||
def __init__(self):
|
||||
self.log = []
|
||||
|
||||
def add(self, section, path):
|
||||
self._log(errors.get_context(), 'add', section, path)
|
||||
|
||||
def remove(self, section, path):
|
||||
self._log(errors.get_context(), 'remove', section, path)
|
||||
|
||||
def _log(self, *args):
|
||||
self.log.append(args)
|
||||
|
||||
self.sink = MockSink()
|
||||
|
||||
def test_preprocess_manifest(self):
|
||||
with MockedOpen({'manifest': MANIFEST}):
|
||||
preprocess_manifest(self.sink, 'manifest')
|
||||
self.assertEqual(self.sink.log, self.EXPECTED_LOG)
|
||||
|
||||
def test_preprocess_manifest_missing_define(self):
|
||||
with MockedOpen({'manifest': MANIFEST}):
|
||||
self.assertRaises(
|
||||
Preprocessor.Error,
|
||||
preprocess_manifest,
|
||||
self.sink,
|
||||
'manifest',
|
||||
{'baz': 1}
|
||||
)
|
||||
|
||||
def test_preprocess_manifest_defines(self):
|
||||
with MockedOpen({'manifest': MANIFEST}):
|
||||
preprocess_manifest(self.sink, 'manifest',
|
||||
{'baz': 1, 'SUFFIX': '.exe'})
|
||||
self.assertEqual(self.sink.log, self.EXPECTED_LOG +
|
||||
[((self.MANIFEST_PATH, 10), 'add', 'baz', 'baz.exe')])
|
||||
|
||||
|
||||
class MockFormatter(object):
|
||||
def __init__(self):
|
||||
self.log = []
|
||||
|
||||
def add_base(self, *args):
|
||||
self._log(errors.get_context(), 'add_base', *args)
|
||||
|
||||
def add_manifest(self, *args):
|
||||
self._log(errors.get_context(), 'add_manifest', *args)
|
||||
|
||||
def add_interfaces(self, *args):
|
||||
self._log(errors.get_context(), 'add_interfaces', *args)
|
||||
|
||||
def add(self, *args):
|
||||
self._log(errors.get_context(), 'add', *args)
|
||||
|
||||
def _log(self, *args):
|
||||
self.log.append(args)
|
||||
|
||||
|
||||
class TestSimplePackager(unittest.TestCase):
|
||||
def test_simple_packager(self):
|
||||
class GeneratedFileWithPath(GeneratedFile):
|
||||
def __init__(self, path, content):
|
||||
GeneratedFile.__init__(self, content)
|
||||
self.path = path
|
||||
|
||||
formatter = MockFormatter()
|
||||
packager = SimplePackager(formatter)
|
||||
curdir = os.path.abspath(os.curdir)
|
||||
file = GeneratedFileWithPath(os.path.join(curdir, 'foo',
|
||||
'bar.manifest'),
|
||||
'resource bar bar/\ncontent bar bar/')
|
||||
with errors.context('manifest', 1):
|
||||
packager.add('foo/bar.manifest', file)
|
||||
|
||||
file = GeneratedFileWithPath(os.path.join(curdir, 'foo',
|
||||
'baz.manifest'),
|
||||
'resource baz baz/')
|
||||
with errors.context('manifest', 2):
|
||||
packager.add('bar/baz.manifest', file)
|
||||
|
||||
with errors.context('manifest', 3):
|
||||
packager.add('qux/qux.manifest',
|
||||
GeneratedFile('resource qux qux/'))
|
||||
bar_xpt = GeneratedFile('bar.xpt')
|
||||
qux_xpt = GeneratedFile('qux.xpt')
|
||||
foo_html = GeneratedFile('foo_html')
|
||||
bar_html = GeneratedFile('bar_html')
|
||||
with errors.context('manifest', 4):
|
||||
packager.add('foo/bar.xpt', bar_xpt)
|
||||
with errors.context('manifest', 5):
|
||||
packager.add('foo/bar/foo.html', foo_html)
|
||||
packager.add('foo/bar/bar.html', bar_html)
|
||||
|
||||
file = GeneratedFileWithPath(os.path.join(curdir, 'foo.manifest'),
|
||||
''.join([
|
||||
'manifest foo/bar.manifest\n',
|
||||
'manifest bar/baz.manifest\n',
|
||||
]))
|
||||
with errors.context('manifest', 6):
|
||||
packager.add('foo.manifest', file)
|
||||
with errors.context('manifest', 7):
|
||||
packager.add('foo/qux.xpt', qux_xpt)
|
||||
|
||||
self.assertEqual(formatter.log, [])
|
||||
|
||||
with errors.context('dummy', 1):
|
||||
packager.close()
|
||||
self.maxDiff = None
|
||||
self.assertEqual(formatter.log, [
|
||||
(('dummy', 1), 'add_base', 'qux'),
|
||||
((os.path.join(curdir, 'foo', 'bar.manifest'), 1),
|
||||
'add_manifest', ManifestResource('foo', 'bar', 'bar/')),
|
||||
((os.path.join(curdir, 'foo', 'bar.manifest'), 2),
|
||||
'add_manifest', ManifestContent('foo', 'bar', 'bar/')),
|
||||
(('bar/baz.manifest', 1),
|
||||
'add_manifest', ManifestResource('bar', 'baz', 'baz/')),
|
||||
(('qux/qux.manifest', 1),
|
||||
'add_manifest', ManifestResource('qux', 'qux', 'qux/')),
|
||||
(('manifest', 4), 'add_interfaces', 'foo/bar.xpt', bar_xpt),
|
||||
(('manifest', 7), 'add_interfaces', 'foo/qux.xpt', qux_xpt),
|
||||
(('manifest', 5), 'add', 'foo/bar/foo.html', foo_html),
|
||||
(('manifest', 5), 'add', 'foo/bar/bar.html', bar_html),
|
||||
])
|
||||
|
||||
self.assertEqual(packager.get_bases(), set(['', 'qux']))
|
||||
|
||||
|
||||
class TestSimpleManifestSink(unittest.TestCase):
|
||||
def test_simple_manifest_parser(self):
|
||||
class MockFinder(object):
|
||||
def __init__(self, files):
|
||||
self.files = files
|
||||
self.log = []
|
||||
|
||||
def find(self, path):
|
||||
self.log.append(path)
|
||||
for f in sorted(self.files):
|
||||
if mozpack.path.match(f, path):
|
||||
yield f, self.files[f]
|
||||
|
||||
formatter = MockFormatter()
|
||||
foobar = GeneratedFile('foobar')
|
||||
foobaz = GeneratedFile('foobaz')
|
||||
fooqux = GeneratedFile('fooqux')
|
||||
finder = MockFinder({
|
||||
'bin/foo/bar': foobar,
|
||||
'bin/foo/baz': foobaz,
|
||||
'bin/foo/qux': fooqux,
|
||||
'bin/foo/chrome.manifest': GeneratedFile('resource foo foo/'),
|
||||
'bin/chrome.manifest':
|
||||
GeneratedFile('manifest foo/chrome.manifest'),
|
||||
})
|
||||
parser = SimpleManifestSink(finder, formatter)
|
||||
parser.add('section0', 'bin/foo/b*')
|
||||
parser.add('section1', 'bin/foo/qux')
|
||||
parser.add('section1', 'bin/foo/chrome.manifest')
|
||||
self.assertRaises(ErrorMessage, parser.add, 'section1', 'bin/bar')
|
||||
|
||||
self.assertEqual(formatter.log, [])
|
||||
parser.close()
|
||||
self.assertEqual(formatter.log, [
|
||||
(('foo/chrome.manifest', 1),
|
||||
'add_manifest', ManifestResource('foo', 'foo', 'foo/')),
|
||||
(None, 'add', 'foo/bar', foobar),
|
||||
(None, 'add', 'foo/baz', foobaz),
|
||||
(None, 'add', 'foo/qux', fooqux),
|
||||
])
|
||||
|
||||
self.assertEqual(finder.log, [
|
||||
'bin/foo/b*',
|
||||
'bin/foo/qux',
|
||||
'bin/foo/chrome.manifest',
|
||||
'bin/bar',
|
||||
'bin/**/chrome.manifest'
|
||||
])
|
||||
|
||||
|
||||
class TestCallDeque(unittest.TestCase):
|
||||
def test_call_deque(self):
|
||||
class Logger(object):
|
||||
def __init__(self):
|
||||
self._log = []
|
||||
|
||||
def log(self, str):
|
||||
self._log.append(str)
|
||||
|
||||
@staticmethod
|
||||
def staticlog(logger, str):
|
||||
logger.log(str)
|
||||
|
||||
def do_log(logger, str):
|
||||
logger.log(str)
|
||||
|
||||
logger = Logger()
|
||||
d = CallDeque()
|
||||
d.append(logger.log, 'foo')
|
||||
d.append(logger.log, 'bar')
|
||||
d.append(logger.staticlog, logger, 'baz')
|
||||
d.append(do_log, logger, 'qux')
|
||||
self.assertEqual(logger._log, [])
|
||||
d.execute()
|
||||
self.assertEqual(logger._log, ['foo', 'bar', 'baz', 'qux'])
|
||||
|
||||
if __name__ == '__main__':
|
||||
mozunit.main()
|
|
@ -0,0 +1,238 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
import mozunit
|
||||
from mozpack.packager.formats import (
|
||||
FlatFormatter,
|
||||
JarFormatter,
|
||||
OmniJarFormatter,
|
||||
)
|
||||
from mozpack.copier import FileRegistry
|
||||
from mozpack.files import GeneratedFile
|
||||
from mozpack.chrome.manifest import (
|
||||
ManifestContent,
|
||||
ManifestResource,
|
||||
ManifestBinaryComponent,
|
||||
)
|
||||
from mozpack.test.test_files import (
|
||||
TestWithTmpDir,
|
||||
foo_xpt,
|
||||
bar_xpt,
|
||||
read_interfaces,
|
||||
)
|
||||
|
||||
|
||||
class TestFlatFormatter(TestWithTmpDir):
|
||||
def test_flat_formatter(self):
|
||||
registry = FileRegistry()
|
||||
formatter = FlatFormatter(registry)
|
||||
formatter.add_base('app')
|
||||
formatter.add('f/oo/bar', GeneratedFile('foobar'))
|
||||
formatter.add('f/oo/baz', GeneratedFile('foobaz'))
|
||||
formatter.add('f/oo/qux', GeneratedFile('fooqux'))
|
||||
formatter.add_manifest(ManifestContent('f/oo', 'bar', 'bar'))
|
||||
formatter.add_manifest(ManifestContent('f/oo', 'qux', 'qux'))
|
||||
self.assertEqual(registry.paths(),
|
||||
['f/oo/bar', 'f/oo/baz', 'f/oo/qux',
|
||||
'chrome.manifest', 'f/f.manifest',
|
||||
'f/oo/oo.manifest'])
|
||||
self.assertEqual(registry['chrome.manifest'].open().read(),
|
||||
'manifest f/f.manifest\n')
|
||||
self.assertEqual(registry['f/f.manifest'].open().read(),
|
||||
'manifest oo/oo.manifest\n')
|
||||
self.assertEqual(registry['f/oo/oo.manifest'].open().read(), ''.join([
|
||||
'content bar bar\n',
|
||||
'content qux qux\n',
|
||||
]))
|
||||
|
||||
formatter.add_interfaces('components/foo.xpt', foo_xpt)
|
||||
formatter.add_interfaces('components/bar.xpt', bar_xpt)
|
||||
self.assertEqual(registry.paths(),
|
||||
['f/oo/bar', 'f/oo/baz', 'f/oo/qux',
|
||||
'chrome.manifest', 'f/f.manifest',
|
||||
'f/oo/oo.manifest', 'components/components.manifest',
|
||||
'components/interfaces.xpt'])
|
||||
self.assertEqual(registry['chrome.manifest'].open().read(), ''.join([
|
||||
'manifest f/f.manifest\n',
|
||||
'manifest components/components.manifest\n',
|
||||
]))
|
||||
self.assertEqual(
|
||||
registry['components/components.manifest'].open().read(),
|
||||
'interfaces interfaces.xpt\n'
|
||||
)
|
||||
|
||||
registry['components/interfaces.xpt'] \
|
||||
.copy(self.tmppath('interfaces.xpt'))
|
||||
linked = read_interfaces(self.tmppath('interfaces.xpt'))
|
||||
foo = read_interfaces(foo_xpt.open())
|
||||
bar = read_interfaces(bar_xpt.open())
|
||||
self.assertEqual(foo['foo'], linked['foo'])
|
||||
self.assertEqual(bar['bar'], linked['bar'])
|
||||
|
||||
formatter.add_manifest(ManifestContent('app/chrome', 'content',
|
||||
'foo/'))
|
||||
self.assertEqual(registry['chrome.manifest'].open().read(), ''.join([
|
||||
'manifest f/f.manifest\n',
|
||||
'manifest components/components.manifest\n',
|
||||
]))
|
||||
self.assertEqual(registry['app/chrome.manifest'].open().read(),
|
||||
'manifest chrome/chrome.manifest\n')
|
||||
self.assertEqual(registry['app/chrome/chrome.manifest'].open().read(),
|
||||
'content content foo/\n')
|
||||
|
||||
def test_bases(self):
|
||||
formatter = FlatFormatter(FileRegistry())
|
||||
formatter.add_base('')
|
||||
formatter.add_base('browser')
|
||||
formatter.add_base('webapprt')
|
||||
self.assertEqual(formatter._get_base('platform.ini'), '')
|
||||
self.assertEqual(formatter._get_base('browser/application.ini'),
|
||||
'browser')
|
||||
self.assertEqual(formatter._get_base('webapprt/webapprt.ini'),
|
||||
'webapprt')
|
||||
|
||||
|
||||
class TestJarFormatter(TestWithTmpDir):
|
||||
def test_jar_formatter(self):
|
||||
registry = FileRegistry()
|
||||
formatter = JarFormatter(registry)
|
||||
formatter.add_manifest(ManifestContent('f', 'oo', 'oo/'))
|
||||
formatter.add_manifest(ManifestContent('f', 'bar', 'oo/bar/'))
|
||||
formatter.add('f/oo/bar/baz', GeneratedFile('foobarbaz'))
|
||||
formatter.add('f/oo/qux', GeneratedFile('fooqux'))
|
||||
|
||||
self.assertEqual(registry.paths(),
|
||||
['chrome.manifest', 'f/f.manifest', 'f/oo.jar'])
|
||||
self.assertEqual(registry['chrome.manifest'].open().read(),
|
||||
'manifest f/f.manifest\n')
|
||||
self.assertEqual(registry['f/f.manifest'].open().read(), ''.join([
|
||||
'content oo jar:oo.jar!/\n',
|
||||
'content bar jar:oo.jar!/bar/\n',
|
||||
]))
|
||||
self.assertTrue(formatter.contains('f/oo/bar/baz'))
|
||||
self.assertFalse(formatter.contains('foo/bar/baz'))
|
||||
self.assertEqual(registry['f/oo.jar'].paths(), ['bar/baz', 'qux'])
|
||||
|
||||
formatter.add_manifest(ManifestResource('f', 'foo', 'resource://bar/'))
|
||||
self.assertEqual(registry['f/f.manifest'].open().read(), ''.join([
|
||||
'content oo jar:oo.jar!/\n',
|
||||
'content bar jar:oo.jar!/bar/\n',
|
||||
'resource foo resource://bar/\n',
|
||||
]))
|
||||
|
||||
|
||||
class TestOmniJarFormatter(TestWithTmpDir):
|
||||
def test_omnijar_formatter(self):
|
||||
registry = FileRegistry()
|
||||
formatter = OmniJarFormatter(registry, 'omni.foo')
|
||||
formatter.add_base('app')
|
||||
formatter.add('chrome/f/oo/bar', GeneratedFile('foobar'))
|
||||
formatter.add('chrome/f/oo/baz', GeneratedFile('foobaz'))
|
||||
formatter.add('chrome/f/oo/qux', GeneratedFile('fooqux'))
|
||||
formatter.add_manifest(ManifestContent('chrome/f/oo', 'bar', 'bar'))
|
||||
formatter.add_manifest(ManifestContent('chrome/f/oo', 'qux', 'qux'))
|
||||
self.assertEqual(registry.paths(), ['omni.foo'])
|
||||
self.assertEqual(registry['omni.foo'].paths(), [
|
||||
'chrome/f/oo/bar',
|
||||
'chrome/f/oo/baz',
|
||||
'chrome/f/oo/qux',
|
||||
'chrome.manifest',
|
||||
'chrome/chrome.manifest',
|
||||
'chrome/f/f.manifest',
|
||||
'chrome/f/oo/oo.manifest',
|
||||
])
|
||||
self.assertEqual(registry['omni.foo']['chrome.manifest']
|
||||
.open().read(), 'manifest chrome/chrome.manifest\n')
|
||||
self.assertEqual(registry['omni.foo']['chrome/chrome.manifest']
|
||||
.open().read(), 'manifest f/f.manifest\n')
|
||||
self.assertEqual(registry['omni.foo']['chrome/f/f.manifest']
|
||||
.open().read(), 'manifest oo/oo.manifest\n')
|
||||
self.assertEqual(registry['omni.foo']['chrome/f/oo/oo.manifest']
|
||||
.open().read(), ''.join([
|
||||
'content bar bar\n',
|
||||
'content qux qux\n',
|
||||
]))
|
||||
self.assertTrue(formatter.contains('chrome/f/oo/bar'))
|
||||
self.assertFalse(formatter.contains('chrome/foo/bar'))
|
||||
|
||||
formatter.add_interfaces('components/foo.xpt', foo_xpt)
|
||||
formatter.add_interfaces('components/bar.xpt', bar_xpt)
|
||||
self.assertEqual(registry['omni.foo'].paths(), [
|
||||
'chrome/f/oo/bar',
|
||||
'chrome/f/oo/baz',
|
||||
'chrome/f/oo/qux',
|
||||
'chrome.manifest',
|
||||
'chrome/chrome.manifest',
|
||||
'chrome/f/f.manifest',
|
||||
'chrome/f/oo/oo.manifest',
|
||||
'components/components.manifest',
|
||||
'components/interfaces.xpt',
|
||||
])
|
||||
self.assertEqual(registry['omni.foo']['chrome.manifest']
|
||||
.open().read(), ''.join([
|
||||
'manifest chrome/chrome.manifest\n',
|
||||
'manifest components/components.manifest\n'
|
||||
]))
|
||||
self.assertEqual(registry['omni.foo']
|
||||
['components/components.manifest'].open().read(),
|
||||
'interfaces interfaces.xpt\n')
|
||||
|
||||
registry['omni.foo'][
|
||||
'components/interfaces.xpt'].copy(self.tmppath('interfaces.xpt'))
|
||||
linked = read_interfaces(self.tmppath('interfaces.xpt'))
|
||||
foo = read_interfaces(foo_xpt.open())
|
||||
bar = read_interfaces(bar_xpt.open())
|
||||
self.assertEqual(foo['foo'], linked['foo'])
|
||||
self.assertEqual(bar['bar'], linked['bar'])
|
||||
|
||||
formatter.add('app/chrome/foo/baz', GeneratedFile('foobaz'))
|
||||
formatter.add_manifest(ManifestContent('app/chrome', 'content',
|
||||
'foo/'))
|
||||
self.assertEqual(registry.paths(), ['omni.foo', 'app/omni.foo'])
|
||||
self.assertEqual(registry['app/omni.foo'].paths(), [
|
||||
'chrome/foo/baz',
|
||||
'chrome.manifest',
|
||||
'chrome/chrome.manifest',
|
||||
])
|
||||
self.assertEqual(registry['app/omni.foo']['chrome.manifest']
|
||||
.open().read(), 'manifest chrome/chrome.manifest\n')
|
||||
self.assertEqual(registry['app/omni.foo']['chrome/chrome.manifest']
|
||||
.open().read(), 'content content foo/\n')
|
||||
|
||||
formatter.add_manifest(ManifestBinaryComponent('components', 'foo.so'))
|
||||
formatter.add('components/foo.so', GeneratedFile('foo'))
|
||||
self.assertEqual(registry.paths(), [
|
||||
'omni.foo', 'app/omni.foo', 'chrome.manifest',
|
||||
'components/components.manifest', 'components/foo.so',
|
||||
])
|
||||
self.assertEqual(registry['chrome.manifest'].open().read(),
|
||||
'manifest components/components.manifest\n')
|
||||
self.assertEqual(registry['components/components.manifest']
|
||||
.open().read(), 'binary-component foo.so\n')
|
||||
|
||||
formatter.add_manifest(ManifestBinaryComponent('app/components',
|
||||
'foo.so'))
|
||||
formatter.add('app/components/foo.so', GeneratedFile('foo'))
|
||||
self.assertEqual(registry.paths(), [
|
||||
'omni.foo', 'app/omni.foo', 'chrome.manifest',
|
||||
'components/components.manifest', 'components/foo.so',
|
||||
'app/chrome.manifest', 'app/components/components.manifest',
|
||||
'app/components/foo.so',
|
||||
])
|
||||
self.assertEqual(registry['app/chrome.manifest'].open().read(),
|
||||
'manifest components/components.manifest\n')
|
||||
self.assertEqual(registry['app/components/components.manifest']
|
||||
.open().read(), 'binary-component foo.so\n')
|
||||
|
||||
formatter.add('app/foo', GeneratedFile('foo'))
|
||||
self.assertEqual(registry.paths(), [
|
||||
'omni.foo', 'app/omni.foo', 'chrome.manifest',
|
||||
'components/components.manifest', 'components/foo.so',
|
||||
'app/chrome.manifest', 'app/components/components.manifest',
|
||||
'app/components/foo.so', 'app/foo'
|
||||
])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
mozunit.main()
|
|
@ -0,0 +1,120 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
from mozpack.path import (
|
||||
relpath,
|
||||
join,
|
||||
normpath,
|
||||
dirname,
|
||||
commonprefix,
|
||||
basename,
|
||||
split,
|
||||
splitext,
|
||||
basedir,
|
||||
match,
|
||||
rebase,
|
||||
)
|
||||
import unittest
|
||||
import mozunit
|
||||
import os
|
||||
|
||||
|
||||
class TestPath(unittest.TestCase):
|
||||
def test_relpath(self):
|
||||
self.assertEqual(relpath('foo', 'foo'), '')
|
||||
self.assertEqual(relpath(os.path.join('foo', 'bar'), 'foo/bar'), '')
|
||||
self.assertEqual(relpath(os.path.join('foo', 'bar'), 'foo'), 'bar')
|
||||
self.assertEqual(relpath(os.path.join('foo', 'bar', 'baz'), 'foo'),
|
||||
'bar/baz')
|
||||
self.assertEqual(relpath(os.path.join('foo', 'bar'), 'foo/bar/baz'),
|
||||
'..')
|
||||
self.assertEqual(relpath(os.path.join('foo', 'bar'), 'foo/baz'),
|
||||
'../bar')
|
||||
self.assertEqual(relpath('foo/', 'foo'), '')
|
||||
self.assertEqual(relpath('foo/bar/', 'foo'), 'bar')
|
||||
|
||||
def test_join(self):
|
||||
self.assertEqual(join('foo', 'bar', 'baz'), 'foo/bar/baz')
|
||||
self.assertEqual(join('foo', '', 'bar'), 'foo/bar')
|
||||
self.assertEqual(join('', 'foo', 'bar'), 'foo/bar')
|
||||
self.assertEqual(join('', 'foo', '/bar'), '/bar')
|
||||
|
||||
def test_normpath(self):
|
||||
self.assertEqual(normpath(os.path.join('foo', 'bar', 'baz',
|
||||
'..', 'qux')), 'foo/bar/qux')
|
||||
|
||||
def test_dirname(self):
|
||||
self.assertEqual(dirname('foo/bar/baz'), 'foo/bar')
|
||||
self.assertEqual(dirname('foo/bar'), 'foo')
|
||||
self.assertEqual(dirname('foo'), '')
|
||||
self.assertEqual(dirname('foo/bar/'), 'foo/bar')
|
||||
|
||||
def test_commonprefix(self):
|
||||
self.assertEqual(commonprefix([os.path.join('foo', 'bar', 'baz'),
|
||||
'foo/qux', 'foo/baz/qux']), 'foo/')
|
||||
self.assertEqual(commonprefix([os.path.join('foo', 'bar', 'baz'),
|
||||
'foo/qux', 'baz/qux']), '')
|
||||
|
||||
def test_basename(self):
|
||||
self.assertEqual(basename('foo/bar/baz'), 'baz')
|
||||
self.assertEqual(basename('foo/bar'), 'bar')
|
||||
self.assertEqual(basename('foo'), 'foo')
|
||||
self.assertEqual(basename('foo/bar/'), '')
|
||||
|
||||
def test_split(self):
|
||||
self.assertEqual(split(os.path.join('foo', 'bar', 'baz')),
|
||||
['foo', 'bar', 'baz'])
|
||||
|
||||
def test_splitext(self):
|
||||
self.assertEqual(splitext(os.path.join('foo', 'bar', 'baz.qux')),
|
||||
('foo/bar/baz', '.qux'))
|
||||
|
||||
def test_basedir(self):
|
||||
foobarbaz = os.path.join('foo', 'bar', 'baz')
|
||||
self.assertEqual(basedir(foobarbaz, ['foo', 'bar', 'baz']), 'foo')
|
||||
self.assertEqual(basedir(foobarbaz, ['foo', 'foo/bar', 'baz']),
|
||||
'foo/bar')
|
||||
self.assertEqual(basedir(foobarbaz, ['foo/bar', 'foo', 'baz']),
|
||||
'foo/bar')
|
||||
self.assertEqual(basedir(foobarbaz, ['foo', 'bar', '']), 'foo')
|
||||
self.assertEqual(basedir(foobarbaz, ['bar', 'baz', '']), '')
|
||||
|
||||
def test_match(self):
|
||||
self.assertTrue(match('foo', ''))
|
||||
self.assertTrue(match('foo/bar/baz.qux', 'foo/bar'))
|
||||
self.assertTrue(match('foo/bar/baz.qux', 'foo'))
|
||||
self.assertTrue(match('foo', '*'))
|
||||
self.assertTrue(match('foo/bar/baz.qux', 'foo/bar/*'))
|
||||
self.assertTrue(match('foo/bar/baz.qux', 'foo/bar/*'))
|
||||
self.assertTrue(match('foo/bar/baz.qux', 'foo/bar/*'))
|
||||
self.assertTrue(match('foo/bar/baz.qux', 'foo/bar/*'))
|
||||
self.assertTrue(match('foo/bar/baz.qux', 'foo/*/baz.qux'))
|
||||
self.assertTrue(match('foo/bar/baz.qux', '*/bar/baz.qux'))
|
||||
self.assertTrue(match('foo/bar/baz.qux', '*/*/baz.qux'))
|
||||
self.assertTrue(match('foo/bar/baz.qux', '*/*/*'))
|
||||
self.assertTrue(match('foo/bar/baz.qux', 'foo/*/*'))
|
||||
self.assertTrue(match('foo/bar/baz.qux', 'foo/*/*.qux'))
|
||||
self.assertTrue(match('foo/bar/baz.qux', 'foo/b*/*z.qux'))
|
||||
self.assertTrue(match('foo/bar/baz.qux', 'foo/b*r/ba*z.qux'))
|
||||
self.assertFalse(match('foo/bar/baz.qux', 'foo/b*z/ba*r.qux'))
|
||||
self.assertTrue(match('foo/bar/baz.qux', '**'))
|
||||
self.assertTrue(match('foo/bar/baz.qux', '**/baz.qux'))
|
||||
self.assertTrue(match('foo/bar/baz.qux', '**/bar/baz.qux'))
|
||||
self.assertTrue(match('foo/bar/baz.qux', 'foo/**/baz.qux'))
|
||||
self.assertTrue(match('foo/bar/baz.qux', 'foo/**/*.qux'))
|
||||
self.assertTrue(match('foo/bar/baz.qux', '**/foo/bar/baz.qux'))
|
||||
self.assertTrue(match('foo/bar/baz.qux', 'foo/**/bar/baz.qux'))
|
||||
self.assertTrue(match('foo/bar/baz.qux', 'foo/**/bar/*.qux'))
|
||||
self.assertTrue(match('foo/bar/baz.qux', 'foo/**/*.qux'))
|
||||
self.assertTrue(match('foo/bar/baz.qux', '**/*.qux'))
|
||||
self.assertFalse(match('foo/bar/baz.qux', '**.qux'))
|
||||
self.assertFalse(match('foo/bar', 'foo/*/bar'))
|
||||
|
||||
def test_rebase(self):
|
||||
self.assertEqual(rebase('foo', 'foo/bar', 'bar/baz'), 'baz')
|
||||
self.assertEqual(rebase('foo', 'foo', 'bar/baz'), 'bar/baz')
|
||||
self.assertEqual(rebase('foo/bar', 'foo', 'baz'), 'bar/baz')
|
||||
|
||||
if __name__ == '__main__':
|
||||
mozunit.main()
|
|
@ -0,0 +1,97 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
from mozpack.unify import (
|
||||
UnifiedFinder,
|
||||
UnifiedBuildFinder,
|
||||
)
|
||||
import mozunit
|
||||
from mozpack.test.test_files import TestWithTmpDir
|
||||
from mozpack.copier import ensure_parent_dir
|
||||
import os
|
||||
from mozpack.errors import ErrorMessage
|
||||
|
||||
|
||||
class TestUnified(TestWithTmpDir):
|
||||
def create_one(self, which, path, content):
|
||||
file = self.tmppath(os.path.join(which, path))
|
||||
ensure_parent_dir(file)
|
||||
open(file, 'wb').write(content)
|
||||
|
||||
def create_both(self, path, content):
|
||||
for p in ['a', 'b']:
|
||||
self.create_one(p, path, content)
|
||||
|
||||
|
||||
class TestUnifiedFinder(TestUnified):
|
||||
def test_unified_finder(self):
|
||||
self.create_both('foo/bar', 'foobar')
|
||||
self.create_both('foo/baz', 'foobaz')
|
||||
self.create_one('a', 'bar', 'bar')
|
||||
self.create_one('b', 'baz', 'baz')
|
||||
self.create_one('a', 'qux', 'foobar')
|
||||
self.create_one('b', 'qux', 'baz')
|
||||
self.create_one('a', 'test/foo', 'a\nb\nc\n')
|
||||
self.create_one('b', 'test/foo', 'b\nc\na\n')
|
||||
self.create_both('test/bar', 'a\nb\nc\n')
|
||||
|
||||
finder = UnifiedFinder(self.tmppath('a'), self.tmppath('b'),
|
||||
sorted=['test'])
|
||||
self.assertEqual(sorted([(f, c.open().read())
|
||||
for f, c in finder.find('foo')]),
|
||||
[('foo/bar', 'foobar'), ('foo/baz', 'foobaz')])
|
||||
self.assertRaises(ErrorMessage, any, finder.find('bar'))
|
||||
self.assertRaises(ErrorMessage, any, finder.find('baz'))
|
||||
self.assertRaises(ErrorMessage, any, finder.find('qux'))
|
||||
self.assertEqual(sorted([(f, c.open().read())
|
||||
for f, c in finder.find('test')]),
|
||||
[('test/bar', 'a\nb\nc\n'),
|
||||
('test/foo', 'a\nb\nc\n')])
|
||||
|
||||
|
||||
class TestUnifiedBuildFinder(TestUnified):
|
||||
def test_unified_build_finder(self):
|
||||
self.create_both('chrome.manifest', 'a\nb\nc\n')
|
||||
self.create_one('a', 'chrome/chrome.manifest', 'a\nb\nc\n')
|
||||
self.create_one('b', 'chrome/chrome.manifest', 'b\nc\na\n')
|
||||
self.create_one('a', 'chrome/browser/foo/buildconfig.html',
|
||||
'\n'.join([
|
||||
'<html>',
|
||||
'<body>',
|
||||
'<h1>about:buildconfig</h1>',
|
||||
'<div>foo</div>',
|
||||
'</body>',
|
||||
'</html>',
|
||||
]))
|
||||
self.create_one('b', 'chrome/browser/foo/buildconfig.html',
|
||||
'\n'.join([
|
||||
'<html>',
|
||||
'<body>',
|
||||
'<h1>about:buildconfig</h1>',
|
||||
'<div>bar</div>',
|
||||
'</body>',
|
||||
'</html>',
|
||||
]))
|
||||
finder = UnifiedBuildFinder(self.tmppath('a'), self.tmppath('b'))
|
||||
self.assertEqual(sorted([(f, c.open().read()) for f, c in
|
||||
finder.find('**/chrome.manifest')]),
|
||||
[('chrome.manifest', 'a\nb\nc\n'),
|
||||
('chrome/chrome.manifest', 'a\nb\nc\n')])
|
||||
|
||||
self.assertEqual(sorted([(f, c.open().read()) for f, c in
|
||||
finder.find('**/buildconfig.html')]),
|
||||
[('chrome/browser/foo/buildconfig.html', '\n'.join([
|
||||
'<html>',
|
||||
'<body>',
|
||||
'<h1>about:buildconfig</h1>',
|
||||
'<div>foo</div>',
|
||||
'<hr> </hr>',
|
||||
'<div>bar</div>',
|
||||
'</body>',
|
||||
'</html>',
|
||||
]))])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
mozunit.main()
|
Загрузка…
Ссылка в новой задаче