addon-sdk/source/python-lib/cuddlefish/tests/test_manifest.py

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/addon-sdk/source/python-lib/cuddlefish/tests/test_manifest.py	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,257 @@
     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 +
     1.9 +import unittest
    1.10 +from StringIO import StringIO
    1.11 +from cuddlefish.manifest import scan_module
    1.12 +
    1.13 +class Extra:
    1.14 +    def failUnlessKeysAre(self, d, keys):
    1.15 +        self.failUnlessEqual(sorted(d.keys()), sorted(keys))
    1.16 +
    1.17 +class Require(unittest.TestCase, Extra):
    1.18 +    def scan(self, text):
    1.19 +        lines = StringIO(text).readlines()
    1.20 +        requires, problems, locations = scan_module("fake.js", lines)
    1.21 +        self.failUnlessEqual(problems, False)
    1.22 +        return requires
    1.23 +
    1.24 +    def scan_locations(self, text):
    1.25 +        lines = StringIO(text).readlines()
    1.26 +        requires, problems, locations = scan_module("fake.js", lines)
    1.27 +        self.failUnlessEqual(problems, False)
    1.28 +        return requires, locations
    1.29 +
    1.30 +    def test_modules(self):
    1.31 +        mod = """var foo = require('one');"""
    1.32 +        requires = self.scan(mod)
    1.33 +        self.failUnlessKeysAre(requires, ["one"])
    1.34 +
    1.35 +        mod = """var foo = require(\"one\");"""
    1.36 +        requires = self.scan(mod)
    1.37 +        self.failUnlessKeysAre(requires, ["one"])
    1.38 +
    1.39 +        mod = """var foo=require(  'one' )  ;  """
    1.40 +        requires = self.scan(mod)
    1.41 +        self.failUnlessKeysAre(requires, ["one"])
    1.42 +
    1.43 +        mod = """var foo = require('o'+'ne'); // tricky, denied"""
    1.44 +        requires = self.scan(mod)
    1.45 +        self.failUnlessKeysAre(requires, [])
    1.46 +
    1.47 +        mod = """require('one').immediately.do().stuff();"""
    1.48 +        requires, locations = self.scan_locations(mod)
    1.49 +        self.failUnlessKeysAre(requires, ["one"])
    1.50 +        self.failUnlessEqual(locations, {"one": 1})
    1.51 +
    1.52 +        # these forms are commented out, and thus ignored
    1.53 +
    1.54 +        mod = """// var foo = require('one');"""
    1.55 +        requires = self.scan(mod)
    1.56 +        self.failUnlessKeysAre(requires, [])
    1.57 +
    1.58 +        mod = """/* var foo = require('one');"""
    1.59 +        requires = self.scan(mod)
    1.60 +        self.failUnlessKeysAre(requires, [])
    1.61 +
    1.62 +        mod = """ * var foo = require('one');"""
    1.63 +        requires = self.scan(mod)
    1.64 +        self.failUnlessKeysAre(requires, [])
    1.65 +
    1.66 +        mod = """ ' var foo = require('one');"""
    1.67 +        requires = self.scan(mod)
    1.68 +        self.failUnlessKeysAre(requires, ["one"])
    1.69 +
    1.70 +        mod = """ \" var foo = require('one');"""
    1.71 +        requires = self.scan(mod)
    1.72 +        self.failUnlessKeysAre(requires, ["one"])
    1.73 +
    1.74 +        # multiple requires
    1.75 +
    1.76 +        mod = """const foo = require('one');
    1.77 +        const foo = require('two');"""
    1.78 +        requires, locations = self.scan_locations(mod)
    1.79 +        self.failUnlessKeysAre(requires, ["one", "two"])
    1.80 +        self.failUnlessEqual(locations["one"], 1)
    1.81 +        self.failUnlessEqual(locations["two"], 2)
    1.82 +
    1.83 +        mod = """const foo = require('repeated');
    1.84 +        const bar = require('repeated');
    1.85 +        const baz = require('repeated');"""
    1.86 +        requires, locations = self.scan_locations(mod)
    1.87 +        self.failUnlessKeysAre(requires, ["repeated"])
    1.88 +        self.failUnlessEqual(locations["repeated"], 1) # first occurrence
    1.89 +
    1.90 +        mod = """const foo = require('one'); const foo = require('two');"""
    1.91 +        requires = self.scan(mod)
    1.92 +        self.failUnlessKeysAre(requires, ["one", "two"])
    1.93 +
    1.94 +        # define calls
    1.95 +
    1.96 +        mod = """define('one', ['two', 'numbers/three'], function(t, th) {});"""
    1.97 +        requires = self.scan(mod)
    1.98 +        self.failUnlessKeysAre(requires, ["two", "numbers/three"])
    1.99 +
   1.100 +        mod = """define(
   1.101 +        ['odd',
   1.102 +        "numbers/four"], function() {});"""
   1.103 +        requires = self.scan(mod)
   1.104 +        self.failUnlessKeysAre(requires, ["odd", "numbers/four"])
   1.105 +
   1.106 +        mod = """define(function(require, exports, module) {
   1.107 +                var a = require("some/module/a"),
   1.108 +                    b = require('b/v1');
   1.109 +                exports.a = a;
   1.110 +                //This is a fakeout: require('bad');
   1.111 +                /* And another var bad = require('bad2'); */
   1.112 +                require('foo').goFoo();
   1.113 +            });"""
   1.114 +        requires = self.scan(mod)
   1.115 +        self.failUnlessKeysAre(requires, ["some/module/a", "b/v1", "foo"])
   1.116 +
   1.117 +        mod = """define (
   1.118 +            "foo",
   1.119 +            ["bar"], function (bar) {
   1.120 +                var me = require("me");
   1.121 +            }
   1.122 +        )"""
   1.123 +        requires = self.scan(mod)
   1.124 +        self.failUnlessKeysAre(requires, ["bar", "me"])
   1.125 +
   1.126 +        mod = """define(['se' + 'ven', 'eight', nine], function () {});"""
   1.127 +        requires = self.scan(mod)
   1.128 +        self.failUnlessKeysAre(requires, ["eight"])
   1.129 +
   1.130 +        # async require calls
   1.131 +
   1.132 +        mod = """require(['one'], function(one) {var o = require("one");});"""
   1.133 +        requires = self.scan(mod)
   1.134 +        self.failUnlessKeysAre(requires, ["one"])
   1.135 +
   1.136 +        mod = """require([  'one' ], function(one) {var t = require("two");});"""
   1.137 +        requires = self.scan(mod)
   1.138 +        self.failUnlessKeysAre(requires, ["one", "two"])
   1.139 +
   1.140 +        mod = """require ( ['two', 'numbers/three'], function(t, th) {});"""
   1.141 +        requires = self.scan(mod)
   1.142 +        self.failUnlessKeysAre(requires, ["two", "numbers/three"])
   1.143 +
   1.144 +        mod = """require (
   1.145 +            ["bar", "fa" + 'ke'  ], function (bar) {
   1.146 +                var me = require("me");
   1.147 +                // require("bad").doBad();
   1.148 +            }
   1.149 +        )"""
   1.150 +        requires = self.scan(mod)
   1.151 +        self.failUnlessKeysAre(requires, ["bar", "me"])
   1.152 +
   1.153 +def scan2(text, fn="fake.js"):
   1.154 +    stderr = StringIO()
   1.155 +    lines = StringIO(text).readlines()
   1.156 +    requires, problems, locations = scan_module(fn, lines, stderr)
   1.157 +    stderr.seek(0)
   1.158 +    return requires, problems, stderr.readlines()
   1.159 +
   1.160 +class Chrome(unittest.TestCase, Extra):
   1.161 +
   1.162 +    def test_ignore_loader(self):
   1.163 +        # we specifically ignore the loader itself
   1.164 +        mod = """let {Cc,Ci} = require('chrome');"""
   1.165 +        requires, problems, err = scan2(mod, "blah/cuddlefish.js")
   1.166 +        self.failUnlessKeysAre(requires, ["chrome"])
   1.167 +        self.failUnlessEqual(problems, False)
   1.168 +        self.failUnlessEqual(err, [])
   1.169 +
   1.170 +    def test_chrome(self):
   1.171 +        mod = """let {Cc,Ci} = require('chrome');"""
   1.172 +        requires, problems, err = scan2(mod)
   1.173 +        self.failUnlessKeysAre(requires, ["chrome"])
   1.174 +        self.failUnlessEqual(problems, False)
   1.175 +        self.failUnlessEqual(err, [])
   1.176 +
   1.177 +        mod = """var foo = require('foo');
   1.178 +        let {Cc,Ci} = require('chrome');"""
   1.179 +        requires, problems, err = scan2(mod)
   1.180 +        self.failUnlessKeysAre(requires, ["foo", "chrome"])
   1.181 +        self.failUnlessEqual(problems, False)
   1.182 +        self.failUnlessEqual(err, [])
   1.183 +
   1.184 +        mod = """let c = require('chrome');"""
   1.185 +        requires, problems, err = scan2(mod)
   1.186 +        self.failUnlessKeysAre(requires, ["chrome"])
   1.187 +        self.failUnlessEqual(problems, False)
   1.188 +        self.failUnlessEqual(err, [])
   1.189 +
   1.190 +        mod = """var foo = require('foo');
   1.191 +        let c = require('chrome');"""
   1.192 +        requires, problems, err = scan2(mod)
   1.193 +        self.failUnlessKeysAre(requires, ["foo", "chrome"])
   1.194 +        self.failUnlessEqual(problems, False)
   1.195 +        self.failUnlessEqual(err, [])
   1.196 +
   1.197 +    def test_not_chrome(self):
   1.198 +        # from bug 596595
   1.199 +        mod = r'soughtLines: new RegExp("^\\s*(\\[[0-9 .]*\\])?\\s*\\(\\((EE|WW)\\)|.* [Cc]hipsets?: \\)|\\s*Backtrace")'
   1.200 +        requires, problems, err = scan2(mod)
   1.201 +        self.failUnlessKeysAre(requires, [])
   1.202 +        self.failUnlessEqual((problems,err), (False, []))
   1.203 +
   1.204 +    def test_not_chrome2(self):
   1.205 +        # from bug 655788
   1.206 +        mod = r"var foo = 'some stuff Cr';"
   1.207 +        requires, problems, err = scan2(mod)
   1.208 +        self.failUnlessKeysAre(requires, [])
   1.209 +        self.failUnlessEqual((problems,err), (False, []))
   1.210 +
   1.211 +class BadChrome(unittest.TestCase, Extra):
   1.212 +    def test_bad_alias(self):
   1.213 +        # using Components.* gets you an error, with a message that teaches
   1.214 +        # you the correct approach.
   1.215 +        mod = """let Cc = Components.classes;
   1.216 +        let Cu = Components.utils;
   1.217 +        """
   1.218 +        requires, problems, err = scan2(mod)
   1.219 +        self.failUnlessKeysAre(requires, [])
   1.220 +        self.failUnlessEqual(problems, True)
   1.221 +        self.failUnlessEqual(err[1], "The following lines from file fake.js:\n")
   1.222 +        self.failUnlessEqual(err[2], "   1: let Cc = Components.classes;\n")
   1.223 +        self.failUnlessEqual(err[3], "   2: let Cu = Components.utils;\n")
   1.224 +        self.failUnlessEqual(err[4], "use 'Components' to access chrome authority. To do so, you need to add a\n")
   1.225 +        self.failUnlessEqual(err[5], "line somewhat like the following:\n")
   1.226 +        self.failUnlessEqual(err[7], '  const {Cc,Cu} = require("chrome");\n')
   1.227 +        self.failUnlessEqual(err[9], "Then you can use any shortcuts to its properties that you import from the\n")
   1.228 +
   1.229 +    def test_bad_misc(self):
   1.230 +        # If it looks like you're using something that doesn't have an alias,
   1.231 +        # the warning also suggests a better way.
   1.232 +        mod = """if (Components.isSuccessCode(foo))
   1.233 +        """
   1.234 +        requires, problems, err = scan2(mod)
   1.235 +        self.failUnlessKeysAre(requires, [])
   1.236 +        self.failUnlessEqual(problems, True)
   1.237 +        self.failUnlessEqual(err[1], "The following lines from file fake.js:\n")
   1.238 +        self.failUnlessEqual(err[2], "   1: if (Components.isSuccessCode(foo))\n")
   1.239 +        self.failUnlessEqual(err[3], "use 'Components' to access chrome authority. To do so, you need to add a\n")
   1.240 +        self.failUnlessEqual(err[4], "line somewhat like the following:\n")
   1.241 +        self.failUnlessEqual(err[6], '  const {components} = require("chrome");\n')
   1.242 +        self.failUnlessEqual(err[8], "Then you can use any shortcuts to its properties that you import from the\n")
   1.243 +
   1.244 +    def test_chrome_components(self):
   1.245 +        # Bug 636145/774636: We no longer tolerate usages of "Components",
   1.246 +        # even when adding `require("chrome")` to your module.
   1.247 +        mod = """require("chrome");
   1.248 +        var ios = Components.classes['@mozilla.org/network/io-service;1'];"""
   1.249 +        requires, problems, err = scan2(mod)
   1.250 +        self.failUnlessKeysAre(requires, ["chrome"])
   1.251 +        self.failUnlessEqual(problems, True)
   1.252 +        self.failUnlessEqual(err[1], "The following lines from file fake.js:\n")
   1.253 +        self.failUnlessEqual(err[2], "   2: var ios = Components.classes['@mozilla.org/network/io-service;1'];\n")
   1.254 +        self.failUnlessEqual(err[3], "use 'Components' to access chrome authority. To do so, you need to add a\n")
   1.255 +        self.failUnlessEqual(err[4], "line somewhat like the following:\n")
   1.256 +        self.failUnlessEqual(err[6], '  const {Cc} = require("chrome");\n')
   1.257 +        self.failUnlessEqual(err[8], "Then you can use any shortcuts to its properties that you import from the\n")
   1.258 +
   1.259 +if __name__ == '__main__':
   1.260 +    unittest.main()

mercurial