|
1 # This Source Code Form is subject to the terms of the Mozilla Public |
|
2 # License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 # file, You can obtain one at http://mozilla.org/MPL/2.0/. |
|
4 |
|
5 import os |
|
6 import unittest |
|
7 import zipfile |
|
8 import pprint |
|
9 import shutil |
|
10 |
|
11 import simplejson as json |
|
12 from cuddlefish import xpi, packaging, manifest, buildJID |
|
13 from cuddlefish.tests import test_packaging |
|
14 from test_linker import up |
|
15 |
|
16 import xml.etree.ElementTree as ElementTree |
|
17 |
|
18 xpi_template_path = os.path.join(test_packaging.static_files_path, |
|
19 'xpi-template') |
|
20 |
|
21 fake_manifest = '<RDF><!-- Extension metadata is here. --></RDF>' |
|
22 |
|
23 class PrefsTests(unittest.TestCase): |
|
24 def makexpi(self, pkg_name): |
|
25 self.xpiname = "%s.xpi" % pkg_name |
|
26 create_xpi(self.xpiname, pkg_name, 'preferences-files') |
|
27 self.xpi = zipfile.ZipFile(self.xpiname, 'r') |
|
28 options = self.xpi.read('harness-options.json') |
|
29 self.xpi_harness_options = json.loads(options) |
|
30 |
|
31 def setUp(self): |
|
32 self.xpiname = None |
|
33 self.xpi = None |
|
34 |
|
35 def tearDown(self): |
|
36 if self.xpi: |
|
37 self.xpi.close() |
|
38 if self.xpiname and os.path.exists(self.xpiname): |
|
39 os.remove(self.xpiname) |
|
40 |
|
41 def testPackageWithSimplePrefs(self): |
|
42 self.makexpi('simple-prefs') |
|
43 packageName = 'jid1-fZHqN9JfrDBa8A@jetpack' |
|
44 self.failUnless('options.xul' in self.xpi.namelist()) |
|
45 optsxul = self.xpi.read('options.xul').decode("utf-8") |
|
46 self.failUnlessEqual(self.xpi_harness_options["jetpackID"], packageName) |
|
47 self.failUnlessEqual(self.xpi_harness_options["preferencesBranch"], packageName) |
|
48 |
|
49 root = ElementTree.XML(optsxul.encode('utf-8')) |
|
50 |
|
51 xulNamespacePrefix = \ |
|
52 "{http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul}" |
|
53 |
|
54 settings = root.findall(xulNamespacePrefix + 'setting') |
|
55 |
|
56 def assertPref(setting, name, prefType, title): |
|
57 self.failUnlessEqual(setting.get('data-jetpack-id'), packageName) |
|
58 self.failUnlessEqual(setting.get('pref'), |
|
59 'extensions.' + packageName + '.' + name) |
|
60 self.failUnlessEqual(setting.get('pref-name'), name) |
|
61 self.failUnlessEqual(setting.get('type'), prefType) |
|
62 self.failUnlessEqual(setting.get('title'), title) |
|
63 |
|
64 assertPref(settings[0], 'test', 'bool', u't\u00EBst') |
|
65 assertPref(settings[1], 'test2', 'string', u't\u00EBst') |
|
66 assertPref(settings[2], 'test3', 'menulist', '"><test') |
|
67 assertPref(settings[3], 'test4', 'radio', u't\u00EBst') |
|
68 |
|
69 menuItems = settings[2].findall( |
|
70 '%(0)smenulist/%(0)smenupopup/%(0)smenuitem' % { "0": xulNamespacePrefix }) |
|
71 radios = settings[3].findall( |
|
72 '%(0)sradiogroup/%(0)sradio' % { "0": xulNamespacePrefix }) |
|
73 |
|
74 def assertOption(option, value, label): |
|
75 self.failUnlessEqual(option.get('value'), value) |
|
76 self.failUnlessEqual(option.get('label'), label) |
|
77 |
|
78 assertOption(menuItems[0], "0", "label1") |
|
79 assertOption(menuItems[1], "1", "label2") |
|
80 assertOption(radios[0], "red", "rouge") |
|
81 assertOption(radios[1], "blue", "bleu") |
|
82 |
|
83 prefsjs = self.xpi.read('defaults/preferences/prefs.js').decode("utf-8") |
|
84 exp = [u'pref("extensions.jid1-fZHqN9JfrDBa8A@jetpack.test", false);', |
|
85 u'pref("extensions.jid1-fZHqN9JfrDBa8A@jetpack.test2", "\u00FCnic\u00F8d\u00E9");', |
|
86 u'pref("extensions.jid1-fZHqN9JfrDBa8A@jetpack.test3", "1");', |
|
87 u'pref("extensions.jid1-fZHqN9JfrDBa8A@jetpack.test4", "red");', |
|
88 ] |
|
89 self.failUnlessEqual(prefsjs, "\n".join(exp)+"\n") |
|
90 |
|
91 def testPackageWithPreferencesBranch(self): |
|
92 self.makexpi('preferences-branch') |
|
93 self.failUnless('options.xul' in self.xpi.namelist()) |
|
94 optsxul = self.xpi.read('options.xul').decode("utf-8") |
|
95 self.failUnlessEqual(self.xpi_harness_options["preferencesBranch"], |
|
96 "human-readable") |
|
97 |
|
98 root = ElementTree.XML(optsxul.encode('utf-8')) |
|
99 xulNamespacePrefix = \ |
|
100 "{http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul}" |
|
101 |
|
102 setting = root.find(xulNamespacePrefix + 'setting') |
|
103 self.failUnlessEqual(setting.get('pref'), |
|
104 'extensions.human-readable.test42') |
|
105 |
|
106 prefsjs = self.xpi.read('defaults/preferences/prefs.js').decode("utf-8") |
|
107 self.failUnlessEqual(prefsjs, |
|
108 'pref("extensions.human-readable.test42", true);\n') |
|
109 |
|
110 def testPackageWithNoPrefs(self): |
|
111 self.makexpi('no-prefs') |
|
112 self.failIf('options.xul' in self.xpi.namelist()) |
|
113 self.failUnlessEqual(self.xpi_harness_options["jetpackID"], |
|
114 "jid1-fZHqN9JfrDBa8A@jetpack") |
|
115 prefsjs = self.xpi.read('defaults/preferences/prefs.js').decode("utf-8") |
|
116 self.failUnlessEqual(prefsjs, "") |
|
117 |
|
118 def testPackageWithInvalidPreferencesBranch(self): |
|
119 self.makexpi('curly-id') |
|
120 self.failIfEqual(self.xpi_harness_options["preferencesBranch"], |
|
121 "invalid^branch*name") |
|
122 self.failUnlessEqual(self.xpi_harness_options["preferencesBranch"], |
|
123 "{34a1eae1-c20a-464f-9b0e-000000000000}") |
|
124 |
|
125 def testPackageWithCurlyID(self): |
|
126 self.makexpi('curly-id') |
|
127 self.failUnlessEqual(self.xpi_harness_options["jetpackID"], |
|
128 "{34a1eae1-c20a-464f-9b0e-000000000000}") |
|
129 |
|
130 self.failUnless('options.xul' in self.xpi.namelist()) |
|
131 optsxul = self.xpi.read('options.xul').decode("utf-8") |
|
132 |
|
133 root = ElementTree.XML(optsxul.encode('utf-8')) |
|
134 xulNamespacePrefix = \ |
|
135 "{http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul}" |
|
136 |
|
137 setting = root.find(xulNamespacePrefix + 'setting') |
|
138 self.failUnlessEqual(setting.get('pref'), |
|
139 'extensions.{34a1eae1-c20a-464f-9b0e-000000000000}.test13') |
|
140 |
|
141 prefsjs = self.xpi.read('defaults/preferences/prefs.js').decode("utf-8") |
|
142 self.failUnlessEqual(prefsjs, |
|
143 'pref("extensions.{34a1eae1-c20a-464f-9b0e-000000000000}.test13", 26);\n') |
|
144 |
|
145 |
|
146 class Bug588119Tests(unittest.TestCase): |
|
147 def makexpi(self, pkg_name): |
|
148 self.xpiname = "%s.xpi" % pkg_name |
|
149 create_xpi(self.xpiname, pkg_name, 'bug-588119-files') |
|
150 self.xpi = zipfile.ZipFile(self.xpiname, 'r') |
|
151 options = self.xpi.read('harness-options.json') |
|
152 self.xpi_harness_options = json.loads(options) |
|
153 |
|
154 def setUp(self): |
|
155 self.xpiname = None |
|
156 self.xpi = None |
|
157 |
|
158 def tearDown(self): |
|
159 if self.xpi: |
|
160 self.xpi.close() |
|
161 if self.xpiname and os.path.exists(self.xpiname): |
|
162 os.remove(self.xpiname) |
|
163 |
|
164 def testPackageWithImplicitIcon(self): |
|
165 self.makexpi('implicit-icon') |
|
166 assert 'icon.png' in self.xpi.namelist() |
|
167 |
|
168 def testPackageWithImplicitIcon64(self): |
|
169 self.makexpi('implicit-icon') |
|
170 assert 'icon64.png' in self.xpi.namelist() |
|
171 |
|
172 def testPackageWithExplicitIcon(self): |
|
173 self.makexpi('explicit-icon') |
|
174 assert 'icon.png' in self.xpi.namelist() |
|
175 |
|
176 def testPackageWithExplicitIcon64(self): |
|
177 self.makexpi('explicit-icon') |
|
178 assert 'icon64.png' in self.xpi.namelist() |
|
179 |
|
180 def testPackageWithNoIcon(self): |
|
181 self.makexpi('no-icon') |
|
182 assert 'icon.png' not in self.xpi.namelist() |
|
183 |
|
184 def testIconPathNotInHarnessOptions(self): |
|
185 self.makexpi('implicit-icon') |
|
186 assert 'icon' not in self.xpi_harness_options |
|
187 |
|
188 def testIcon64PathNotInHarnessOptions(self): |
|
189 self.makexpi('implicit-icon') |
|
190 assert 'icon64' not in self.xpi_harness_options |
|
191 |
|
192 class ExtraHarnessOptions(unittest.TestCase): |
|
193 def setUp(self): |
|
194 self.xpiname = None |
|
195 self.xpi = None |
|
196 |
|
197 def tearDown(self): |
|
198 if self.xpi: |
|
199 self.xpi.close() |
|
200 if self.xpiname and os.path.exists(self.xpiname): |
|
201 os.remove(self.xpiname) |
|
202 |
|
203 def testOptions(self): |
|
204 pkg_name = "extra-options" |
|
205 self.xpiname = "%s.xpi" % pkg_name |
|
206 create_xpi(self.xpiname, pkg_name, "bug-669274-files", |
|
207 extra_harness_options={"builderVersion": "futuristic"}) |
|
208 self.xpi = zipfile.ZipFile(self.xpiname, 'r') |
|
209 options = self.xpi.read('harness-options.json') |
|
210 hopts = json.loads(options) |
|
211 self.failUnless("builderVersion" in hopts) |
|
212 self.failUnlessEqual(hopts["builderVersion"], "futuristic") |
|
213 |
|
214 def testBadOptionName(self): |
|
215 pkg_name = "extra-options" |
|
216 self.xpiname = "%s.xpi" % pkg_name |
|
217 self.failUnlessRaises(xpi.HarnessOptionAlreadyDefinedError, |
|
218 create_xpi, |
|
219 self.xpiname, pkg_name, "bug-669274-files", |
|
220 extra_harness_options={"main": "already in use"}) |
|
221 |
|
222 class SmallXPI(unittest.TestCase): |
|
223 def setUp(self): |
|
224 self.root = up(os.path.abspath(__file__), 4) |
|
225 def get_linker_files_dir(self, name): |
|
226 return os.path.join(up(os.path.abspath(__file__)), "linker-files", name) |
|
227 def get_pkg(self, name): |
|
228 d = self.get_linker_files_dir(name) |
|
229 return packaging.get_config_in_dir(d) |
|
230 |
|
231 def get_basedir(self): |
|
232 return os.path.join(".test_tmp", self.id()) |
|
233 def make_basedir(self): |
|
234 basedir = self.get_basedir() |
|
235 if os.path.isdir(basedir): |
|
236 here = os.path.abspath(os.getcwd()) |
|
237 assert os.path.abspath(basedir).startswith(here) # safety |
|
238 shutil.rmtree(basedir) |
|
239 os.makedirs(basedir) |
|
240 return basedir |
|
241 |
|
242 def test_contents(self): |
|
243 target_cfg = self.get_pkg("three") |
|
244 package_path = [self.get_linker_files_dir("three-deps")] |
|
245 pkg_cfg = packaging.build_config(self.root, target_cfg, |
|
246 packagepath=package_path) |
|
247 deps = packaging.get_deps_for_targets(pkg_cfg, |
|
248 [target_cfg.name, "addon-sdk"]) |
|
249 addon_sdk_dir = pkg_cfg.packages["addon-sdk"].lib[0] |
|
250 m = manifest.build_manifest(target_cfg, pkg_cfg, deps, scan_tests=False) |
|
251 used_files = list(m.get_used_files(True)) |
|
252 here = up(os.path.abspath(__file__)) |
|
253 def absify(*parts): |
|
254 fn = os.path.join(here, "linker-files", *parts) |
|
255 return os.path.abspath(fn) |
|
256 expected = [absify(*parts) for parts in |
|
257 [("three", "lib", "main.js"), |
|
258 ("three-deps", "three-a", "lib", "main.js"), |
|
259 ("three-deps", "three-a", "lib", "subdir", "subfile.js"), |
|
260 ("three", "data", "msg.txt"), |
|
261 ("three", "data", "subdir", "submsg.txt"), |
|
262 ("three-deps", "three-b", "lib", "main.js"), |
|
263 ("three-deps", "three-c", "lib", "main.js"), |
|
264 ("three-deps", "three-c", "lib", "sub", "foo.js") |
|
265 ]] |
|
266 |
|
267 add_addon_sdk= lambda path: os.path.join(addon_sdk_dir, path) |
|
268 expected.extend([add_addon_sdk(module) for module in [ |
|
269 os.path.join("sdk", "self.js"), |
|
270 os.path.join("sdk", "core", "promise.js"), |
|
271 os.path.join("sdk", "net", "url.js"), |
|
272 os.path.join("sdk", "util", "object.js"), |
|
273 os.path.join("sdk", "util", "array.js") |
|
274 ]]) |
|
275 |
|
276 missing = set(expected) - set(used_files) |
|
277 extra = set(used_files) - set(expected) |
|
278 |
|
279 self.failUnlessEqual(list(missing), []) |
|
280 self.failUnlessEqual(list(extra), []) |
|
281 used_deps = m.get_used_packages() |
|
282 |
|
283 build = packaging.generate_build_for_target(pkg_cfg, target_cfg.name, |
|
284 used_deps, |
|
285 include_tests=False) |
|
286 options = {'main': target_cfg.main} |
|
287 options.update(build) |
|
288 basedir = self.make_basedir() |
|
289 xpi_name = os.path.join(basedir, "contents.xpi") |
|
290 xpi.build_xpi(template_root_dir=xpi_template_path, |
|
291 manifest=fake_manifest, |
|
292 xpi_path=xpi_name, |
|
293 harness_options=options, |
|
294 limit_to=used_files) |
|
295 x = zipfile.ZipFile(xpi_name, "r") |
|
296 names = x.namelist() |
|
297 expected = ["components/", |
|
298 "components/harness.js", |
|
299 # the real template also has 'bootstrap.js', but the fake |
|
300 # one in tests/static-files/xpi-template doesn't |
|
301 "harness-options.json", |
|
302 "install.rdf", |
|
303 "defaults/preferences/prefs.js", |
|
304 "resources/", |
|
305 "resources/addon-sdk/", |
|
306 "resources/addon-sdk/lib/", |
|
307 "resources/addon-sdk/lib/sdk/", |
|
308 "resources/addon-sdk/lib/sdk/self.js", |
|
309 "resources/addon-sdk/lib/sdk/core/", |
|
310 "resources/addon-sdk/lib/sdk/util/", |
|
311 "resources/addon-sdk/lib/sdk/net/", |
|
312 "resources/addon-sdk/lib/sdk/core/promise.js", |
|
313 "resources/addon-sdk/lib/sdk/util/object.js", |
|
314 "resources/addon-sdk/lib/sdk/util/array.js", |
|
315 "resources/addon-sdk/lib/sdk/net/url.js", |
|
316 "resources/three/", |
|
317 "resources/three/lib/", |
|
318 "resources/three/lib/main.js", |
|
319 "resources/three/data/", |
|
320 "resources/three/data/msg.txt", |
|
321 "resources/three/data/subdir/", |
|
322 "resources/three/data/subdir/submsg.txt", |
|
323 "resources/three-a/", |
|
324 "resources/three-a/lib/", |
|
325 "resources/three-a/lib/main.js", |
|
326 "resources/three-a/lib/subdir/", |
|
327 "resources/three-a/lib/subdir/subfile.js", |
|
328 "resources/three-b/", |
|
329 "resources/three-b/lib/", |
|
330 "resources/three-b/lib/main.js", |
|
331 "resources/three-c/", |
|
332 "resources/three-c/lib/", |
|
333 "resources/three-c/lib/main.js", |
|
334 "resources/three-c/lib/sub/", |
|
335 "resources/three-c/lib/sub/foo.js", |
|
336 # notably absent: three-a/lib/unused.js |
|
337 "locale/", |
|
338 "locale/fr-FR.json", |
|
339 "locales.json", |
|
340 ] |
|
341 # showing deltas makes failures easier to investigate |
|
342 missing = set(expected) - set(names) |
|
343 extra = set(names) - set(expected) |
|
344 self.failUnlessEqual((list(missing), list(extra)), ([], [])) |
|
345 self.failUnlessEqual(sorted(names), sorted(expected)) |
|
346 |
|
347 # check locale files |
|
348 localedata = json.loads(x.read("locales.json")) |
|
349 self.failUnlessEqual(sorted(localedata["locales"]), sorted(["fr-FR"])) |
|
350 content = x.read("locale/fr-FR.json") |
|
351 locales = json.loads(content) |
|
352 # Locale files are merged into one. |
|
353 # Conflicts are silently resolved by taking last package translation, |
|
354 # so that we get "No" translation from three-c instead of three-b one. |
|
355 self.failUnlessEqual(locales, json.loads(u''' |
|
356 { |
|
357 "No": "Nein", |
|
358 "one": "un", |
|
359 "What?": "Quoi?", |
|
360 "Yes": "Oui", |
|
361 "plural": { |
|
362 "other": "other", |
|
363 "one": "one" |
|
364 }, |
|
365 "uft8_value": "\u00e9" |
|
366 }''')) |
|
367 |
|
368 def test_scantests(self): |
|
369 target_cfg = self.get_pkg("three") |
|
370 package_path = [self.get_linker_files_dir("three-deps")] |
|
371 pkg_cfg = packaging.build_config(self.root, target_cfg, |
|
372 packagepath=package_path) |
|
373 |
|
374 deps = packaging.get_deps_for_targets(pkg_cfg, |
|
375 [target_cfg.name, "addon-sdk"]) |
|
376 m = manifest.build_manifest(target_cfg, pkg_cfg, deps, scan_tests=True) |
|
377 self.failUnlessEqual(sorted(m.get_all_test_modules()), |
|
378 sorted(["three/tests/test-one", "three/tests/test-two"])) |
|
379 # the current __init__.py code omits limit_to=used_files for 'cfx |
|
380 # test', so all test files are included in the XPI. But the test |
|
381 # runner will only execute the tests that m.get_all_test_modules() |
|
382 # tells us about (which are put into the .allTestModules property of |
|
383 # harness-options.json). |
|
384 used_deps = m.get_used_packages() |
|
385 |
|
386 build = packaging.generate_build_for_target(pkg_cfg, target_cfg.name, |
|
387 used_deps, |
|
388 include_tests=True) |
|
389 options = {'main': target_cfg.main} |
|
390 options.update(build) |
|
391 basedir = self.make_basedir() |
|
392 xpi_name = os.path.join(basedir, "contents.xpi") |
|
393 xpi.build_xpi(template_root_dir=xpi_template_path, |
|
394 manifest=fake_manifest, |
|
395 xpi_path=xpi_name, |
|
396 harness_options=options, |
|
397 limit_to=None) |
|
398 x = zipfile.ZipFile(xpi_name, "r") |
|
399 names = x.namelist() |
|
400 self.failUnless("resources/addon-sdk/lib/sdk/deprecated/unit-test.js" in names, names) |
|
401 self.failUnless("resources/addon-sdk/lib/sdk/deprecated/unit-test-finder.js" in names, names) |
|
402 self.failUnless("resources/addon-sdk/lib/sdk/test/harness.js" in names, names) |
|
403 self.failUnless("resources/addon-sdk/lib/sdk/test/runner.js" in names, names) |
|
404 # all files are copied into the XPI, even the things that don't look |
|
405 # like tests. |
|
406 self.failUnless("resources/three/tests/test-one.js" in names, names) |
|
407 self.failUnless("resources/three/tests/test-two.js" in names, names) |
|
408 self.failUnless("resources/three/tests/nontest.js" in names, names) |
|
409 |
|
410 def test_scantests_filter(self): |
|
411 target_cfg = self.get_pkg("three") |
|
412 package_path = [self.get_linker_files_dir("three-deps")] |
|
413 pkg_cfg = packaging.build_config(self.root, target_cfg, |
|
414 packagepath=package_path) |
|
415 deps = packaging.get_deps_for_targets(pkg_cfg, |
|
416 [target_cfg.name, "addon-sdk"]) |
|
417 FILTER = ".*one.*" |
|
418 m = manifest.build_manifest(target_cfg, pkg_cfg, deps, scan_tests=True, |
|
419 test_filter_re=FILTER) |
|
420 self.failUnlessEqual(sorted(m.get_all_test_modules()), |
|
421 sorted(["three/tests/test-one"])) |
|
422 # the current __init__.py code omits limit_to=used_files for 'cfx |
|
423 # test', so all test files are included in the XPI. But the test |
|
424 # runner will only execute the tests that m.get_all_test_modules() |
|
425 # tells us about (which are put into the .allTestModules property of |
|
426 # harness-options.json). |
|
427 used_deps = m.get_used_packages() |
|
428 |
|
429 build = packaging.generate_build_for_target(pkg_cfg, target_cfg.name, |
|
430 used_deps, |
|
431 include_tests=True) |
|
432 options = {'main': target_cfg.main} |
|
433 options.update(build) |
|
434 basedir = self.make_basedir() |
|
435 xpi_name = os.path.join(basedir, "contents.xpi") |
|
436 xpi.build_xpi(template_root_dir=xpi_template_path, |
|
437 manifest=fake_manifest, |
|
438 xpi_path=xpi_name, |
|
439 harness_options=options, |
|
440 limit_to=None) |
|
441 x = zipfile.ZipFile(xpi_name, "r") |
|
442 names = x.namelist() |
|
443 self.failUnless("resources/addon-sdk/lib/sdk/deprecated/unit-test.js" in names, names) |
|
444 self.failUnless("resources/addon-sdk/lib/sdk/deprecated/unit-test-finder.js" in names, names) |
|
445 self.failUnless("resources/addon-sdk/lib/sdk/test/harness.js" in names, names) |
|
446 self.failUnless("resources/addon-sdk/lib/sdk/test/runner.js" in names, names) |
|
447 # get_all_test_modules() respects the filter. But all files are still |
|
448 # copied into the XPI. |
|
449 self.failUnless("resources/three/tests/test-one.js" in names, names) |
|
450 self.failUnless("resources/three/tests/test-two.js" in names, names) |
|
451 self.failUnless("resources/three/tests/nontest.js" in names, names) |
|
452 |
|
453 |
|
454 def document_dir(name): |
|
455 if name in ['packages', 'xpi-template']: |
|
456 dirname = os.path.join(test_packaging.static_files_path, name) |
|
457 document_dir_files(dirname) |
|
458 elif name == 'xpi-output': |
|
459 create_xpi('test-xpi.xpi') |
|
460 document_zip_file('test-xpi.xpi') |
|
461 os.remove('test-xpi.xpi') |
|
462 else: |
|
463 raise Exception('unknown dir: %s' % name) |
|
464 |
|
465 def normpath(path): |
|
466 """ |
|
467 Make a platform-specific relative path use '/' as a separator. |
|
468 """ |
|
469 |
|
470 return path.replace(os.path.sep, '/') |
|
471 |
|
472 def document_zip_file(path): |
|
473 zip = zipfile.ZipFile(path, 'r') |
|
474 for name in sorted(zip.namelist()): |
|
475 contents = zip.read(name) |
|
476 lines = contents.splitlines() |
|
477 if len(lines) == 1 and name.endswith('.json') and len(lines[0]) > 75: |
|
478 # Ideally we would json-decode this, but it results |
|
479 # in an annoying 'u' before every string literal, |
|
480 # since json decoding makes all strings unicode. |
|
481 contents = eval(contents) |
|
482 contents = pprint.pformat(contents) |
|
483 lines = contents.splitlines() |
|
484 contents = "\n ".join(lines) |
|
485 print "%s:\n %s" % (normpath(name), contents) |
|
486 zip.close() |
|
487 |
|
488 def document_dir_files(path): |
|
489 filename_contents_tuples = [] |
|
490 for dirpath, dirnames, filenames in os.walk(path): |
|
491 relpath = dirpath[len(path)+1:] |
|
492 for filename in filenames: |
|
493 abspath = os.path.join(dirpath, filename) |
|
494 contents = open(abspath, 'r').read() |
|
495 contents = "\n ".join(contents.splitlines()) |
|
496 relfilename = os.path.join(relpath, filename) |
|
497 filename_contents_tuples.append((normpath(relfilename), contents)) |
|
498 filename_contents_tuples.sort() |
|
499 for filename, contents in filename_contents_tuples: |
|
500 print "%s:" % filename |
|
501 print " %s" % contents |
|
502 |
|
503 def create_xpi(xpiname, pkg_name='aardvark', dirname='static-files', |
|
504 extra_harness_options={}): |
|
505 configs = test_packaging.get_configs(pkg_name, dirname) |
|
506 options = {'main': configs.target_cfg.main, |
|
507 'jetpackID': buildJID(configs.target_cfg), } |
|
508 options.update(configs.build) |
|
509 xpi.build_xpi(template_root_dir=xpi_template_path, |
|
510 manifest=fake_manifest, |
|
511 xpi_path=xpiname, |
|
512 harness_options=options, |
|
513 extra_harness_options=extra_harness_options) |
|
514 |
|
515 if __name__ == '__main__': |
|
516 unittest.main() |