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()