summaryrefslogtreecommitdiffstats
path: root/addon-sdk/source/python-lib/cuddlefish/tests/test_manifest.py
diff options
context:
space:
mode:
Diffstat (limited to 'addon-sdk/source/python-lib/cuddlefish/tests/test_manifest.py')
-rw-r--r--addon-sdk/source/python-lib/cuddlefish/tests/test_manifest.py257
1 files changed, 257 insertions, 0 deletions
diff --git a/addon-sdk/source/python-lib/cuddlefish/tests/test_manifest.py b/addon-sdk/source/python-lib/cuddlefish/tests/test_manifest.py
new file mode 100644
index 000000000..1bced1234
--- /dev/null
+++ b/addon-sdk/source/python-lib/cuddlefish/tests/test_manifest.py
@@ -0,0 +1,257 @@
+# 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
+from StringIO import StringIO
+from cuddlefish.manifest import scan_module
+
+class Extra:
+ def failUnlessKeysAre(self, d, keys):
+ self.failUnlessEqual(sorted(d.keys()), sorted(keys))
+
+class Require(unittest.TestCase, Extra):
+ def scan(self, text):
+ lines = StringIO(text).readlines()
+ requires, problems, locations = scan_module("fake.js", lines)
+ self.failUnlessEqual(problems, False)
+ return requires
+
+ def scan_locations(self, text):
+ lines = StringIO(text).readlines()
+ requires, problems, locations = scan_module("fake.js", lines)
+ self.failUnlessEqual(problems, False)
+ return requires, locations
+
+ def test_modules(self):
+ mod = """var foo = require('one');"""
+ requires = self.scan(mod)
+ self.failUnlessKeysAre(requires, ["one"])
+
+ mod = """var foo = require(\"one\");"""
+ requires = self.scan(mod)
+ self.failUnlessKeysAre(requires, ["one"])
+
+ mod = """var foo=require( 'one' ) ; """
+ requires = self.scan(mod)
+ self.failUnlessKeysAre(requires, ["one"])
+
+ mod = """var foo = require('o'+'ne'); // tricky, denied"""
+ requires = self.scan(mod)
+ self.failUnlessKeysAre(requires, [])
+
+ mod = """require('one').immediately.do().stuff();"""
+ requires, locations = self.scan_locations(mod)
+ self.failUnlessKeysAre(requires, ["one"])
+ self.failUnlessEqual(locations, {"one": 1})
+
+ # these forms are commented out, and thus ignored
+
+ mod = """// var foo = require('one');"""
+ requires = self.scan(mod)
+ self.failUnlessKeysAre(requires, [])
+
+ mod = """/* var foo = require('one');"""
+ requires = self.scan(mod)
+ self.failUnlessKeysAre(requires, [])
+
+ mod = """ * var foo = require('one');"""
+ requires = self.scan(mod)
+ self.failUnlessKeysAre(requires, [])
+
+ mod = """ ' var foo = require('one');"""
+ requires = self.scan(mod)
+ self.failUnlessKeysAre(requires, ["one"])
+
+ mod = """ \" var foo = require('one');"""
+ requires = self.scan(mod)
+ self.failUnlessKeysAre(requires, ["one"])
+
+ # multiple requires
+
+ mod = """const foo = require('one');
+ const foo = require('two');"""
+ requires, locations = self.scan_locations(mod)
+ self.failUnlessKeysAre(requires, ["one", "two"])
+ self.failUnlessEqual(locations["one"], 1)
+ self.failUnlessEqual(locations["two"], 2)
+
+ mod = """const foo = require('repeated');
+ const bar = require('repeated');
+ const baz = require('repeated');"""
+ requires, locations = self.scan_locations(mod)
+ self.failUnlessKeysAre(requires, ["repeated"])
+ self.failUnlessEqual(locations["repeated"], 1) # first occurrence
+
+ mod = """const foo = require('one'); const foo = require('two');"""
+ requires = self.scan(mod)
+ self.failUnlessKeysAre(requires, ["one", "two"])
+
+ # define calls
+
+ mod = """define('one', ['two', 'numbers/three'], function(t, th) {});"""
+ requires = self.scan(mod)
+ self.failUnlessKeysAre(requires, ["two", "numbers/three"])
+
+ mod = """define(
+ ['odd',
+ "numbers/four"], function() {});"""
+ requires = self.scan(mod)
+ self.failUnlessKeysAre(requires, ["odd", "numbers/four"])
+
+ mod = """define(function(require, exports, module) {
+ var a = require("some/module/a"),
+ b = require('b/v1');
+ exports.a = a;
+ //This is a fakeout: require('bad');
+ /* And another var bad = require('bad2'); */
+ require('foo').goFoo();
+ });"""
+ requires = self.scan(mod)
+ self.failUnlessKeysAre(requires, ["some/module/a", "b/v1", "foo"])
+
+ mod = """define (
+ "foo",
+ ["bar"], function (bar) {
+ var me = require("me");
+ }
+ )"""
+ requires = self.scan(mod)
+ self.failUnlessKeysAre(requires, ["bar", "me"])
+
+ mod = """define(['se' + 'ven', 'eight', nine], function () {});"""
+ requires = self.scan(mod)
+ self.failUnlessKeysAre(requires, ["eight"])
+
+ # async require calls
+
+ mod = """require(['one'], function(one) {var o = require("one");});"""
+ requires = self.scan(mod)
+ self.failUnlessKeysAre(requires, ["one"])
+
+ mod = """require([ 'one' ], function(one) {var t = require("two");});"""
+ requires = self.scan(mod)
+ self.failUnlessKeysAre(requires, ["one", "two"])
+
+ mod = """require ( ['two', 'numbers/three'], function(t, th) {});"""
+ requires = self.scan(mod)
+ self.failUnlessKeysAre(requires, ["two", "numbers/three"])
+
+ mod = """require (
+ ["bar", "fa" + 'ke' ], function (bar) {
+ var me = require("me");
+ // require("bad").doBad();
+ }
+ )"""
+ requires = self.scan(mod)
+ self.failUnlessKeysAre(requires, ["bar", "me"])
+
+def scan2(text, fn="fake.js"):
+ stderr = StringIO()
+ lines = StringIO(text).readlines()
+ requires, problems, locations = scan_module(fn, lines, stderr)
+ stderr.seek(0)
+ return requires, problems, stderr.readlines()
+
+class Chrome(unittest.TestCase, Extra):
+
+ def test_ignore_loader(self):
+ # we specifically ignore the loader itself
+ mod = """let {Cc,Ci} = require('chrome');"""
+ requires, problems, err = scan2(mod, "blah/cuddlefish.js")
+ self.failUnlessKeysAre(requires, ["chrome"])
+ self.failUnlessEqual(problems, False)
+ self.failUnlessEqual(err, [])
+
+ def test_chrome(self):
+ mod = """let {Cc,Ci} = require('chrome');"""
+ requires, problems, err = scan2(mod)
+ self.failUnlessKeysAre(requires, ["chrome"])
+ self.failUnlessEqual(problems, False)
+ self.failUnlessEqual(err, [])
+
+ mod = """var foo = require('foo');
+ let {Cc,Ci} = require('chrome');"""
+ requires, problems, err = scan2(mod)
+ self.failUnlessKeysAre(requires, ["foo", "chrome"])
+ self.failUnlessEqual(problems, False)
+ self.failUnlessEqual(err, [])
+
+ mod = """let c = require('chrome');"""
+ requires, problems, err = scan2(mod)
+ self.failUnlessKeysAre(requires, ["chrome"])
+ self.failUnlessEqual(problems, False)
+ self.failUnlessEqual(err, [])
+
+ mod = """var foo = require('foo');
+ let c = require('chrome');"""
+ requires, problems, err = scan2(mod)
+ self.failUnlessKeysAre(requires, ["foo", "chrome"])
+ self.failUnlessEqual(problems, False)
+ self.failUnlessEqual(err, [])
+
+ def test_not_chrome(self):
+ # from bug 596595
+ mod = r'soughtLines: new RegExp("^\\s*(\\[[0-9 .]*\\])?\\s*\\(\\((EE|WW)\\)|.* [Cc]hipsets?: \\)|\\s*Backtrace")'
+ requires, problems, err = scan2(mod)
+ self.failUnlessKeysAre(requires, [])
+ self.failUnlessEqual((problems,err), (False, []))
+
+ def test_not_chrome2(self):
+ # from bug 655788
+ mod = r"var foo = 'some stuff Cr';"
+ requires, problems, err = scan2(mod)
+ self.failUnlessKeysAre(requires, [])
+ self.failUnlessEqual((problems,err), (False, []))
+
+class BadChrome(unittest.TestCase, Extra):
+ def test_bad_alias(self):
+ # using Components.* gets you an error, with a message that teaches
+ # you the correct approach.
+ mod = """let Cc = Components.classes;
+ let Cu = Components.utils;
+ """
+ requires, problems, err = scan2(mod)
+ self.failUnlessKeysAre(requires, [])
+ self.failUnlessEqual(problems, True)
+ self.failUnlessEqual(err[1], "The following lines from file fake.js:\n")
+ self.failUnlessEqual(err[2], " 1: let Cc = Components.classes;\n")
+ self.failUnlessEqual(err[3], " 2: let Cu = Components.utils;\n")
+ self.failUnlessEqual(err[4], "use 'Components' to access chrome authority. To do so, you need to add a\n")
+ self.failUnlessEqual(err[5], "line somewhat like the following:\n")
+ self.failUnlessEqual(err[7], ' const {Cc,Cu} = require("chrome");\n')
+ self.failUnlessEqual(err[9], "Then you can use any shortcuts to its properties that you import from the\n")
+
+ def test_bad_misc(self):
+ # If it looks like you're using something that doesn't have an alias,
+ # the warning also suggests a better way.
+ mod = """if (Components.isSuccessCode(foo))
+ """
+ requires, problems, err = scan2(mod)
+ self.failUnlessKeysAre(requires, [])
+ self.failUnlessEqual(problems, True)
+ self.failUnlessEqual(err[1], "The following lines from file fake.js:\n")
+ self.failUnlessEqual(err[2], " 1: if (Components.isSuccessCode(foo))\n")
+ self.failUnlessEqual(err[3], "use 'Components' to access chrome authority. To do so, you need to add a\n")
+ self.failUnlessEqual(err[4], "line somewhat like the following:\n")
+ self.failUnlessEqual(err[6], ' const {components} = require("chrome");\n')
+ self.failUnlessEqual(err[8], "Then you can use any shortcuts to its properties that you import from the\n")
+
+ def test_chrome_components(self):
+ # Bug 636145/774636: We no longer tolerate usages of "Components",
+ # even when adding `require("chrome")` to your module.
+ mod = """require("chrome");
+ var ios = Components.classes['@mozilla.org/network/io-service;1'];"""
+ requires, problems, err = scan2(mod)
+ self.failUnlessKeysAre(requires, ["chrome"])
+ self.failUnlessEqual(problems, True)
+ self.failUnlessEqual(err[1], "The following lines from file fake.js:\n")
+ self.failUnlessEqual(err[2], " 2: var ios = Components.classes['@mozilla.org/network/io-service;1'];\n")
+ self.failUnlessEqual(err[3], "use 'Components' to access chrome authority. To do so, you need to add a\n")
+ self.failUnlessEqual(err[4], "line somewhat like the following:\n")
+ self.failUnlessEqual(err[6], ' const {Cc} = require("chrome");\n')
+ self.failUnlessEqual(err[8], "Then you can use any shortcuts to its properties that you import from the\n")
+
+if __name__ == '__main__':
+ unittest.main()