1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/addon-sdk/source/python-lib/cuddlefish/tests/test_xpi.py Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,516 @@ 1.4 +# This Source Code Form is subject to the terms of the Mozilla Public 1.5 +# License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 +# file, You can obtain one at http://mozilla.org/MPL/2.0/. 1.7 + 1.8 +import os 1.9 +import unittest 1.10 +import zipfile 1.11 +import pprint 1.12 +import shutil 1.13 + 1.14 +import simplejson as json 1.15 +from cuddlefish import xpi, packaging, manifest, buildJID 1.16 +from cuddlefish.tests import test_packaging 1.17 +from test_linker import up 1.18 + 1.19 +import xml.etree.ElementTree as ElementTree 1.20 + 1.21 +xpi_template_path = os.path.join(test_packaging.static_files_path, 1.22 + 'xpi-template') 1.23 + 1.24 +fake_manifest = '<RDF><!-- Extension metadata is here. --></RDF>' 1.25 + 1.26 +class PrefsTests(unittest.TestCase): 1.27 + def makexpi(self, pkg_name): 1.28 + self.xpiname = "%s.xpi" % pkg_name 1.29 + create_xpi(self.xpiname, pkg_name, 'preferences-files') 1.30 + self.xpi = zipfile.ZipFile(self.xpiname, 'r') 1.31 + options = self.xpi.read('harness-options.json') 1.32 + self.xpi_harness_options = json.loads(options) 1.33 + 1.34 + def setUp(self): 1.35 + self.xpiname = None 1.36 + self.xpi = None 1.37 + 1.38 + def tearDown(self): 1.39 + if self.xpi: 1.40 + self.xpi.close() 1.41 + if self.xpiname and os.path.exists(self.xpiname): 1.42 + os.remove(self.xpiname) 1.43 + 1.44 + def testPackageWithSimplePrefs(self): 1.45 + self.makexpi('simple-prefs') 1.46 + packageName = 'jid1-fZHqN9JfrDBa8A@jetpack' 1.47 + self.failUnless('options.xul' in self.xpi.namelist()) 1.48 + optsxul = self.xpi.read('options.xul').decode("utf-8") 1.49 + self.failUnlessEqual(self.xpi_harness_options["jetpackID"], packageName) 1.50 + self.failUnlessEqual(self.xpi_harness_options["preferencesBranch"], packageName) 1.51 + 1.52 + root = ElementTree.XML(optsxul.encode('utf-8')) 1.53 + 1.54 + xulNamespacePrefix = \ 1.55 + "{http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul}" 1.56 + 1.57 + settings = root.findall(xulNamespacePrefix + 'setting') 1.58 + 1.59 + def assertPref(setting, name, prefType, title): 1.60 + self.failUnlessEqual(setting.get('data-jetpack-id'), packageName) 1.61 + self.failUnlessEqual(setting.get('pref'), 1.62 + 'extensions.' + packageName + '.' + name) 1.63 + self.failUnlessEqual(setting.get('pref-name'), name) 1.64 + self.failUnlessEqual(setting.get('type'), prefType) 1.65 + self.failUnlessEqual(setting.get('title'), title) 1.66 + 1.67 + assertPref(settings[0], 'test', 'bool', u't\u00EBst') 1.68 + assertPref(settings[1], 'test2', 'string', u't\u00EBst') 1.69 + assertPref(settings[2], 'test3', 'menulist', '"><test') 1.70 + assertPref(settings[3], 'test4', 'radio', u't\u00EBst') 1.71 + 1.72 + menuItems = settings[2].findall( 1.73 + '%(0)smenulist/%(0)smenupopup/%(0)smenuitem' % { "0": xulNamespacePrefix }) 1.74 + radios = settings[3].findall( 1.75 + '%(0)sradiogroup/%(0)sradio' % { "0": xulNamespacePrefix }) 1.76 + 1.77 + def assertOption(option, value, label): 1.78 + self.failUnlessEqual(option.get('value'), value) 1.79 + self.failUnlessEqual(option.get('label'), label) 1.80 + 1.81 + assertOption(menuItems[0], "0", "label1") 1.82 + assertOption(menuItems[1], "1", "label2") 1.83 + assertOption(radios[0], "red", "rouge") 1.84 + assertOption(radios[1], "blue", "bleu") 1.85 + 1.86 + prefsjs = self.xpi.read('defaults/preferences/prefs.js').decode("utf-8") 1.87 + exp = [u'pref("extensions.jid1-fZHqN9JfrDBa8A@jetpack.test", false);', 1.88 + u'pref("extensions.jid1-fZHqN9JfrDBa8A@jetpack.test2", "\u00FCnic\u00F8d\u00E9");', 1.89 + u'pref("extensions.jid1-fZHqN9JfrDBa8A@jetpack.test3", "1");', 1.90 + u'pref("extensions.jid1-fZHqN9JfrDBa8A@jetpack.test4", "red");', 1.91 + ] 1.92 + self.failUnlessEqual(prefsjs, "\n".join(exp)+"\n") 1.93 + 1.94 + def testPackageWithPreferencesBranch(self): 1.95 + self.makexpi('preferences-branch') 1.96 + self.failUnless('options.xul' in self.xpi.namelist()) 1.97 + optsxul = self.xpi.read('options.xul').decode("utf-8") 1.98 + self.failUnlessEqual(self.xpi_harness_options["preferencesBranch"], 1.99 + "human-readable") 1.100 + 1.101 + root = ElementTree.XML(optsxul.encode('utf-8')) 1.102 + xulNamespacePrefix = \ 1.103 + "{http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul}" 1.104 + 1.105 + setting = root.find(xulNamespacePrefix + 'setting') 1.106 + self.failUnlessEqual(setting.get('pref'), 1.107 + 'extensions.human-readable.test42') 1.108 + 1.109 + prefsjs = self.xpi.read('defaults/preferences/prefs.js').decode("utf-8") 1.110 + self.failUnlessEqual(prefsjs, 1.111 + 'pref("extensions.human-readable.test42", true);\n') 1.112 + 1.113 + def testPackageWithNoPrefs(self): 1.114 + self.makexpi('no-prefs') 1.115 + self.failIf('options.xul' in self.xpi.namelist()) 1.116 + self.failUnlessEqual(self.xpi_harness_options["jetpackID"], 1.117 + "jid1-fZHqN9JfrDBa8A@jetpack") 1.118 + prefsjs = self.xpi.read('defaults/preferences/prefs.js').decode("utf-8") 1.119 + self.failUnlessEqual(prefsjs, "") 1.120 + 1.121 + def testPackageWithInvalidPreferencesBranch(self): 1.122 + self.makexpi('curly-id') 1.123 + self.failIfEqual(self.xpi_harness_options["preferencesBranch"], 1.124 + "invalid^branch*name") 1.125 + self.failUnlessEqual(self.xpi_harness_options["preferencesBranch"], 1.126 + "{34a1eae1-c20a-464f-9b0e-000000000000}") 1.127 + 1.128 + def testPackageWithCurlyID(self): 1.129 + self.makexpi('curly-id') 1.130 + self.failUnlessEqual(self.xpi_harness_options["jetpackID"], 1.131 + "{34a1eae1-c20a-464f-9b0e-000000000000}") 1.132 + 1.133 + self.failUnless('options.xul' in self.xpi.namelist()) 1.134 + optsxul = self.xpi.read('options.xul').decode("utf-8") 1.135 + 1.136 + root = ElementTree.XML(optsxul.encode('utf-8')) 1.137 + xulNamespacePrefix = \ 1.138 + "{http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul}" 1.139 + 1.140 + setting = root.find(xulNamespacePrefix + 'setting') 1.141 + self.failUnlessEqual(setting.get('pref'), 1.142 + 'extensions.{34a1eae1-c20a-464f-9b0e-000000000000}.test13') 1.143 + 1.144 + prefsjs = self.xpi.read('defaults/preferences/prefs.js').decode("utf-8") 1.145 + self.failUnlessEqual(prefsjs, 1.146 + 'pref("extensions.{34a1eae1-c20a-464f-9b0e-000000000000}.test13", 26);\n') 1.147 + 1.148 + 1.149 +class Bug588119Tests(unittest.TestCase): 1.150 + def makexpi(self, pkg_name): 1.151 + self.xpiname = "%s.xpi" % pkg_name 1.152 + create_xpi(self.xpiname, pkg_name, 'bug-588119-files') 1.153 + self.xpi = zipfile.ZipFile(self.xpiname, 'r') 1.154 + options = self.xpi.read('harness-options.json') 1.155 + self.xpi_harness_options = json.loads(options) 1.156 + 1.157 + def setUp(self): 1.158 + self.xpiname = None 1.159 + self.xpi = None 1.160 + 1.161 + def tearDown(self): 1.162 + if self.xpi: 1.163 + self.xpi.close() 1.164 + if self.xpiname and os.path.exists(self.xpiname): 1.165 + os.remove(self.xpiname) 1.166 + 1.167 + def testPackageWithImplicitIcon(self): 1.168 + self.makexpi('implicit-icon') 1.169 + assert 'icon.png' in self.xpi.namelist() 1.170 + 1.171 + def testPackageWithImplicitIcon64(self): 1.172 + self.makexpi('implicit-icon') 1.173 + assert 'icon64.png' in self.xpi.namelist() 1.174 + 1.175 + def testPackageWithExplicitIcon(self): 1.176 + self.makexpi('explicit-icon') 1.177 + assert 'icon.png' in self.xpi.namelist() 1.178 + 1.179 + def testPackageWithExplicitIcon64(self): 1.180 + self.makexpi('explicit-icon') 1.181 + assert 'icon64.png' in self.xpi.namelist() 1.182 + 1.183 + def testPackageWithNoIcon(self): 1.184 + self.makexpi('no-icon') 1.185 + assert 'icon.png' not in self.xpi.namelist() 1.186 + 1.187 + def testIconPathNotInHarnessOptions(self): 1.188 + self.makexpi('implicit-icon') 1.189 + assert 'icon' not in self.xpi_harness_options 1.190 + 1.191 + def testIcon64PathNotInHarnessOptions(self): 1.192 + self.makexpi('implicit-icon') 1.193 + assert 'icon64' not in self.xpi_harness_options 1.194 + 1.195 +class ExtraHarnessOptions(unittest.TestCase): 1.196 + def setUp(self): 1.197 + self.xpiname = None 1.198 + self.xpi = None 1.199 + 1.200 + def tearDown(self): 1.201 + if self.xpi: 1.202 + self.xpi.close() 1.203 + if self.xpiname and os.path.exists(self.xpiname): 1.204 + os.remove(self.xpiname) 1.205 + 1.206 + def testOptions(self): 1.207 + pkg_name = "extra-options" 1.208 + self.xpiname = "%s.xpi" % pkg_name 1.209 + create_xpi(self.xpiname, pkg_name, "bug-669274-files", 1.210 + extra_harness_options={"builderVersion": "futuristic"}) 1.211 + self.xpi = zipfile.ZipFile(self.xpiname, 'r') 1.212 + options = self.xpi.read('harness-options.json') 1.213 + hopts = json.loads(options) 1.214 + self.failUnless("builderVersion" in hopts) 1.215 + self.failUnlessEqual(hopts["builderVersion"], "futuristic") 1.216 + 1.217 + def testBadOptionName(self): 1.218 + pkg_name = "extra-options" 1.219 + self.xpiname = "%s.xpi" % pkg_name 1.220 + self.failUnlessRaises(xpi.HarnessOptionAlreadyDefinedError, 1.221 + create_xpi, 1.222 + self.xpiname, pkg_name, "bug-669274-files", 1.223 + extra_harness_options={"main": "already in use"}) 1.224 + 1.225 +class SmallXPI(unittest.TestCase): 1.226 + def setUp(self): 1.227 + self.root = up(os.path.abspath(__file__), 4) 1.228 + def get_linker_files_dir(self, name): 1.229 + return os.path.join(up(os.path.abspath(__file__)), "linker-files", name) 1.230 + def get_pkg(self, name): 1.231 + d = self.get_linker_files_dir(name) 1.232 + return packaging.get_config_in_dir(d) 1.233 + 1.234 + def get_basedir(self): 1.235 + return os.path.join(".test_tmp", self.id()) 1.236 + def make_basedir(self): 1.237 + basedir = self.get_basedir() 1.238 + if os.path.isdir(basedir): 1.239 + here = os.path.abspath(os.getcwd()) 1.240 + assert os.path.abspath(basedir).startswith(here) # safety 1.241 + shutil.rmtree(basedir) 1.242 + os.makedirs(basedir) 1.243 + return basedir 1.244 + 1.245 + def test_contents(self): 1.246 + target_cfg = self.get_pkg("three") 1.247 + package_path = [self.get_linker_files_dir("three-deps")] 1.248 + pkg_cfg = packaging.build_config(self.root, target_cfg, 1.249 + packagepath=package_path) 1.250 + deps = packaging.get_deps_for_targets(pkg_cfg, 1.251 + [target_cfg.name, "addon-sdk"]) 1.252 + addon_sdk_dir = pkg_cfg.packages["addon-sdk"].lib[0] 1.253 + m = manifest.build_manifest(target_cfg, pkg_cfg, deps, scan_tests=False) 1.254 + used_files = list(m.get_used_files(True)) 1.255 + here = up(os.path.abspath(__file__)) 1.256 + def absify(*parts): 1.257 + fn = os.path.join(here, "linker-files", *parts) 1.258 + return os.path.abspath(fn) 1.259 + expected = [absify(*parts) for parts in 1.260 + [("three", "lib", "main.js"), 1.261 + ("three-deps", "three-a", "lib", "main.js"), 1.262 + ("three-deps", "three-a", "lib", "subdir", "subfile.js"), 1.263 + ("three", "data", "msg.txt"), 1.264 + ("three", "data", "subdir", "submsg.txt"), 1.265 + ("three-deps", "three-b", "lib", "main.js"), 1.266 + ("three-deps", "three-c", "lib", "main.js"), 1.267 + ("three-deps", "three-c", "lib", "sub", "foo.js") 1.268 + ]] 1.269 + 1.270 + add_addon_sdk= lambda path: os.path.join(addon_sdk_dir, path) 1.271 + expected.extend([add_addon_sdk(module) for module in [ 1.272 + os.path.join("sdk", "self.js"), 1.273 + os.path.join("sdk", "core", "promise.js"), 1.274 + os.path.join("sdk", "net", "url.js"), 1.275 + os.path.join("sdk", "util", "object.js"), 1.276 + os.path.join("sdk", "util", "array.js") 1.277 + ]]) 1.278 + 1.279 + missing = set(expected) - set(used_files) 1.280 + extra = set(used_files) - set(expected) 1.281 + 1.282 + self.failUnlessEqual(list(missing), []) 1.283 + self.failUnlessEqual(list(extra), []) 1.284 + used_deps = m.get_used_packages() 1.285 + 1.286 + build = packaging.generate_build_for_target(pkg_cfg, target_cfg.name, 1.287 + used_deps, 1.288 + include_tests=False) 1.289 + options = {'main': target_cfg.main} 1.290 + options.update(build) 1.291 + basedir = self.make_basedir() 1.292 + xpi_name = os.path.join(basedir, "contents.xpi") 1.293 + xpi.build_xpi(template_root_dir=xpi_template_path, 1.294 + manifest=fake_manifest, 1.295 + xpi_path=xpi_name, 1.296 + harness_options=options, 1.297 + limit_to=used_files) 1.298 + x = zipfile.ZipFile(xpi_name, "r") 1.299 + names = x.namelist() 1.300 + expected = ["components/", 1.301 + "components/harness.js", 1.302 + # the real template also has 'bootstrap.js', but the fake 1.303 + # one in tests/static-files/xpi-template doesn't 1.304 + "harness-options.json", 1.305 + "install.rdf", 1.306 + "defaults/preferences/prefs.js", 1.307 + "resources/", 1.308 + "resources/addon-sdk/", 1.309 + "resources/addon-sdk/lib/", 1.310 + "resources/addon-sdk/lib/sdk/", 1.311 + "resources/addon-sdk/lib/sdk/self.js", 1.312 + "resources/addon-sdk/lib/sdk/core/", 1.313 + "resources/addon-sdk/lib/sdk/util/", 1.314 + "resources/addon-sdk/lib/sdk/net/", 1.315 + "resources/addon-sdk/lib/sdk/core/promise.js", 1.316 + "resources/addon-sdk/lib/sdk/util/object.js", 1.317 + "resources/addon-sdk/lib/sdk/util/array.js", 1.318 + "resources/addon-sdk/lib/sdk/net/url.js", 1.319 + "resources/three/", 1.320 + "resources/three/lib/", 1.321 + "resources/three/lib/main.js", 1.322 + "resources/three/data/", 1.323 + "resources/three/data/msg.txt", 1.324 + "resources/three/data/subdir/", 1.325 + "resources/three/data/subdir/submsg.txt", 1.326 + "resources/three-a/", 1.327 + "resources/three-a/lib/", 1.328 + "resources/three-a/lib/main.js", 1.329 + "resources/three-a/lib/subdir/", 1.330 + "resources/three-a/lib/subdir/subfile.js", 1.331 + "resources/three-b/", 1.332 + "resources/three-b/lib/", 1.333 + "resources/three-b/lib/main.js", 1.334 + "resources/three-c/", 1.335 + "resources/three-c/lib/", 1.336 + "resources/three-c/lib/main.js", 1.337 + "resources/three-c/lib/sub/", 1.338 + "resources/three-c/lib/sub/foo.js", 1.339 + # notably absent: three-a/lib/unused.js 1.340 + "locale/", 1.341 + "locale/fr-FR.json", 1.342 + "locales.json", 1.343 + ] 1.344 + # showing deltas makes failures easier to investigate 1.345 + missing = set(expected) - set(names) 1.346 + extra = set(names) - set(expected) 1.347 + self.failUnlessEqual((list(missing), list(extra)), ([], [])) 1.348 + self.failUnlessEqual(sorted(names), sorted(expected)) 1.349 + 1.350 + # check locale files 1.351 + localedata = json.loads(x.read("locales.json")) 1.352 + self.failUnlessEqual(sorted(localedata["locales"]), sorted(["fr-FR"])) 1.353 + content = x.read("locale/fr-FR.json") 1.354 + locales = json.loads(content) 1.355 + # Locale files are merged into one. 1.356 + # Conflicts are silently resolved by taking last package translation, 1.357 + # so that we get "No" translation from three-c instead of three-b one. 1.358 + self.failUnlessEqual(locales, json.loads(u''' 1.359 + { 1.360 + "No": "Nein", 1.361 + "one": "un", 1.362 + "What?": "Quoi?", 1.363 + "Yes": "Oui", 1.364 + "plural": { 1.365 + "other": "other", 1.366 + "one": "one" 1.367 + }, 1.368 + "uft8_value": "\u00e9" 1.369 + }''')) 1.370 + 1.371 + def test_scantests(self): 1.372 + target_cfg = self.get_pkg("three") 1.373 + package_path = [self.get_linker_files_dir("three-deps")] 1.374 + pkg_cfg = packaging.build_config(self.root, target_cfg, 1.375 + packagepath=package_path) 1.376 + 1.377 + deps = packaging.get_deps_for_targets(pkg_cfg, 1.378 + [target_cfg.name, "addon-sdk"]) 1.379 + m = manifest.build_manifest(target_cfg, pkg_cfg, deps, scan_tests=True) 1.380 + self.failUnlessEqual(sorted(m.get_all_test_modules()), 1.381 + sorted(["three/tests/test-one", "three/tests/test-two"])) 1.382 + # the current __init__.py code omits limit_to=used_files for 'cfx 1.383 + # test', so all test files are included in the XPI. But the test 1.384 + # runner will only execute the tests that m.get_all_test_modules() 1.385 + # tells us about (which are put into the .allTestModules property of 1.386 + # harness-options.json). 1.387 + used_deps = m.get_used_packages() 1.388 + 1.389 + build = packaging.generate_build_for_target(pkg_cfg, target_cfg.name, 1.390 + used_deps, 1.391 + include_tests=True) 1.392 + options = {'main': target_cfg.main} 1.393 + options.update(build) 1.394 + basedir = self.make_basedir() 1.395 + xpi_name = os.path.join(basedir, "contents.xpi") 1.396 + xpi.build_xpi(template_root_dir=xpi_template_path, 1.397 + manifest=fake_manifest, 1.398 + xpi_path=xpi_name, 1.399 + harness_options=options, 1.400 + limit_to=None) 1.401 + x = zipfile.ZipFile(xpi_name, "r") 1.402 + names = x.namelist() 1.403 + self.failUnless("resources/addon-sdk/lib/sdk/deprecated/unit-test.js" in names, names) 1.404 + self.failUnless("resources/addon-sdk/lib/sdk/deprecated/unit-test-finder.js" in names, names) 1.405 + self.failUnless("resources/addon-sdk/lib/sdk/test/harness.js" in names, names) 1.406 + self.failUnless("resources/addon-sdk/lib/sdk/test/runner.js" in names, names) 1.407 + # all files are copied into the XPI, even the things that don't look 1.408 + # like tests. 1.409 + self.failUnless("resources/three/tests/test-one.js" in names, names) 1.410 + self.failUnless("resources/three/tests/test-two.js" in names, names) 1.411 + self.failUnless("resources/three/tests/nontest.js" in names, names) 1.412 + 1.413 + def test_scantests_filter(self): 1.414 + target_cfg = self.get_pkg("three") 1.415 + package_path = [self.get_linker_files_dir("three-deps")] 1.416 + pkg_cfg = packaging.build_config(self.root, target_cfg, 1.417 + packagepath=package_path) 1.418 + deps = packaging.get_deps_for_targets(pkg_cfg, 1.419 + [target_cfg.name, "addon-sdk"]) 1.420 + FILTER = ".*one.*" 1.421 + m = manifest.build_manifest(target_cfg, pkg_cfg, deps, scan_tests=True, 1.422 + test_filter_re=FILTER) 1.423 + self.failUnlessEqual(sorted(m.get_all_test_modules()), 1.424 + sorted(["three/tests/test-one"])) 1.425 + # the current __init__.py code omits limit_to=used_files for 'cfx 1.426 + # test', so all test files are included in the XPI. But the test 1.427 + # runner will only execute the tests that m.get_all_test_modules() 1.428 + # tells us about (which are put into the .allTestModules property of 1.429 + # harness-options.json). 1.430 + used_deps = m.get_used_packages() 1.431 + 1.432 + build = packaging.generate_build_for_target(pkg_cfg, target_cfg.name, 1.433 + used_deps, 1.434 + include_tests=True) 1.435 + options = {'main': target_cfg.main} 1.436 + options.update(build) 1.437 + basedir = self.make_basedir() 1.438 + xpi_name = os.path.join(basedir, "contents.xpi") 1.439 + xpi.build_xpi(template_root_dir=xpi_template_path, 1.440 + manifest=fake_manifest, 1.441 + xpi_path=xpi_name, 1.442 + harness_options=options, 1.443 + limit_to=None) 1.444 + x = zipfile.ZipFile(xpi_name, "r") 1.445 + names = x.namelist() 1.446 + self.failUnless("resources/addon-sdk/lib/sdk/deprecated/unit-test.js" in names, names) 1.447 + self.failUnless("resources/addon-sdk/lib/sdk/deprecated/unit-test-finder.js" in names, names) 1.448 + self.failUnless("resources/addon-sdk/lib/sdk/test/harness.js" in names, names) 1.449 + self.failUnless("resources/addon-sdk/lib/sdk/test/runner.js" in names, names) 1.450 + # get_all_test_modules() respects the filter. But all files are still 1.451 + # copied into the XPI. 1.452 + self.failUnless("resources/three/tests/test-one.js" in names, names) 1.453 + self.failUnless("resources/three/tests/test-two.js" in names, names) 1.454 + self.failUnless("resources/three/tests/nontest.js" in names, names) 1.455 + 1.456 + 1.457 +def document_dir(name): 1.458 + if name in ['packages', 'xpi-template']: 1.459 + dirname = os.path.join(test_packaging.static_files_path, name) 1.460 + document_dir_files(dirname) 1.461 + elif name == 'xpi-output': 1.462 + create_xpi('test-xpi.xpi') 1.463 + document_zip_file('test-xpi.xpi') 1.464 + os.remove('test-xpi.xpi') 1.465 + else: 1.466 + raise Exception('unknown dir: %s' % name) 1.467 + 1.468 +def normpath(path): 1.469 + """ 1.470 + Make a platform-specific relative path use '/' as a separator. 1.471 + """ 1.472 + 1.473 + return path.replace(os.path.sep, '/') 1.474 + 1.475 +def document_zip_file(path): 1.476 + zip = zipfile.ZipFile(path, 'r') 1.477 + for name in sorted(zip.namelist()): 1.478 + contents = zip.read(name) 1.479 + lines = contents.splitlines() 1.480 + if len(lines) == 1 and name.endswith('.json') and len(lines[0]) > 75: 1.481 + # Ideally we would json-decode this, but it results 1.482 + # in an annoying 'u' before every string literal, 1.483 + # since json decoding makes all strings unicode. 1.484 + contents = eval(contents) 1.485 + contents = pprint.pformat(contents) 1.486 + lines = contents.splitlines() 1.487 + contents = "\n ".join(lines) 1.488 + print "%s:\n %s" % (normpath(name), contents) 1.489 + zip.close() 1.490 + 1.491 +def document_dir_files(path): 1.492 + filename_contents_tuples = [] 1.493 + for dirpath, dirnames, filenames in os.walk(path): 1.494 + relpath = dirpath[len(path)+1:] 1.495 + for filename in filenames: 1.496 + abspath = os.path.join(dirpath, filename) 1.497 + contents = open(abspath, 'r').read() 1.498 + contents = "\n ".join(contents.splitlines()) 1.499 + relfilename = os.path.join(relpath, filename) 1.500 + filename_contents_tuples.append((normpath(relfilename), contents)) 1.501 + filename_contents_tuples.sort() 1.502 + for filename, contents in filename_contents_tuples: 1.503 + print "%s:" % filename 1.504 + print " %s" % contents 1.505 + 1.506 +def create_xpi(xpiname, pkg_name='aardvark', dirname='static-files', 1.507 + extra_harness_options={}): 1.508 + configs = test_packaging.get_configs(pkg_name, dirname) 1.509 + options = {'main': configs.target_cfg.main, 1.510 + 'jetpackID': buildJID(configs.target_cfg), } 1.511 + options.update(configs.build) 1.512 + xpi.build_xpi(template_root_dir=xpi_template_path, 1.513 + manifest=fake_manifest, 1.514 + xpi_path=xpiname, 1.515 + harness_options=options, 1.516 + extra_harness_options=extra_harness_options) 1.517 + 1.518 +if __name__ == '__main__': 1.519 + unittest.main()