Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | # This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 2 | # License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/. |
michael@0 | 4 | |
michael@0 | 5 | |
michael@0 | 6 | import unittest |
michael@0 | 7 | from StringIO import StringIO |
michael@0 | 8 | from cuddlefish.manifest import scan_module |
michael@0 | 9 | |
michael@0 | 10 | class Extra: |
michael@0 | 11 | def failUnlessKeysAre(self, d, keys): |
michael@0 | 12 | self.failUnlessEqual(sorted(d.keys()), sorted(keys)) |
michael@0 | 13 | |
michael@0 | 14 | class Require(unittest.TestCase, Extra): |
michael@0 | 15 | def scan(self, text): |
michael@0 | 16 | lines = StringIO(text).readlines() |
michael@0 | 17 | requires, problems, locations = scan_module("fake.js", lines) |
michael@0 | 18 | self.failUnlessEqual(problems, False) |
michael@0 | 19 | return requires |
michael@0 | 20 | |
michael@0 | 21 | def scan_locations(self, text): |
michael@0 | 22 | lines = StringIO(text).readlines() |
michael@0 | 23 | requires, problems, locations = scan_module("fake.js", lines) |
michael@0 | 24 | self.failUnlessEqual(problems, False) |
michael@0 | 25 | return requires, locations |
michael@0 | 26 | |
michael@0 | 27 | def test_modules(self): |
michael@0 | 28 | mod = """var foo = require('one');""" |
michael@0 | 29 | requires = self.scan(mod) |
michael@0 | 30 | self.failUnlessKeysAre(requires, ["one"]) |
michael@0 | 31 | |
michael@0 | 32 | mod = """var foo = require(\"one\");""" |
michael@0 | 33 | requires = self.scan(mod) |
michael@0 | 34 | self.failUnlessKeysAre(requires, ["one"]) |
michael@0 | 35 | |
michael@0 | 36 | mod = """var foo=require( 'one' ) ; """ |
michael@0 | 37 | requires = self.scan(mod) |
michael@0 | 38 | self.failUnlessKeysAre(requires, ["one"]) |
michael@0 | 39 | |
michael@0 | 40 | mod = """var foo = require('o'+'ne'); // tricky, denied""" |
michael@0 | 41 | requires = self.scan(mod) |
michael@0 | 42 | self.failUnlessKeysAre(requires, []) |
michael@0 | 43 | |
michael@0 | 44 | mod = """require('one').immediately.do().stuff();""" |
michael@0 | 45 | requires, locations = self.scan_locations(mod) |
michael@0 | 46 | self.failUnlessKeysAre(requires, ["one"]) |
michael@0 | 47 | self.failUnlessEqual(locations, {"one": 1}) |
michael@0 | 48 | |
michael@0 | 49 | # these forms are commented out, and thus ignored |
michael@0 | 50 | |
michael@0 | 51 | mod = """// var foo = require('one');""" |
michael@0 | 52 | requires = self.scan(mod) |
michael@0 | 53 | self.failUnlessKeysAre(requires, []) |
michael@0 | 54 | |
michael@0 | 55 | mod = """/* var foo = require('one');""" |
michael@0 | 56 | requires = self.scan(mod) |
michael@0 | 57 | self.failUnlessKeysAre(requires, []) |
michael@0 | 58 | |
michael@0 | 59 | mod = """ * var foo = require('one');""" |
michael@0 | 60 | requires = self.scan(mod) |
michael@0 | 61 | self.failUnlessKeysAre(requires, []) |
michael@0 | 62 | |
michael@0 | 63 | mod = """ ' var foo = require('one');""" |
michael@0 | 64 | requires = self.scan(mod) |
michael@0 | 65 | self.failUnlessKeysAre(requires, ["one"]) |
michael@0 | 66 | |
michael@0 | 67 | mod = """ \" var foo = require('one');""" |
michael@0 | 68 | requires = self.scan(mod) |
michael@0 | 69 | self.failUnlessKeysAre(requires, ["one"]) |
michael@0 | 70 | |
michael@0 | 71 | # multiple requires |
michael@0 | 72 | |
michael@0 | 73 | mod = """const foo = require('one'); |
michael@0 | 74 | const foo = require('two');""" |
michael@0 | 75 | requires, locations = self.scan_locations(mod) |
michael@0 | 76 | self.failUnlessKeysAre(requires, ["one", "two"]) |
michael@0 | 77 | self.failUnlessEqual(locations["one"], 1) |
michael@0 | 78 | self.failUnlessEqual(locations["two"], 2) |
michael@0 | 79 | |
michael@0 | 80 | mod = """const foo = require('repeated'); |
michael@0 | 81 | const bar = require('repeated'); |
michael@0 | 82 | const baz = require('repeated');""" |
michael@0 | 83 | requires, locations = self.scan_locations(mod) |
michael@0 | 84 | self.failUnlessKeysAre(requires, ["repeated"]) |
michael@0 | 85 | self.failUnlessEqual(locations["repeated"], 1) # first occurrence |
michael@0 | 86 | |
michael@0 | 87 | mod = """const foo = require('one'); const foo = require('two');""" |
michael@0 | 88 | requires = self.scan(mod) |
michael@0 | 89 | self.failUnlessKeysAre(requires, ["one", "two"]) |
michael@0 | 90 | |
michael@0 | 91 | # define calls |
michael@0 | 92 | |
michael@0 | 93 | mod = """define('one', ['two', 'numbers/three'], function(t, th) {});""" |
michael@0 | 94 | requires = self.scan(mod) |
michael@0 | 95 | self.failUnlessKeysAre(requires, ["two", "numbers/three"]) |
michael@0 | 96 | |
michael@0 | 97 | mod = """define( |
michael@0 | 98 | ['odd', |
michael@0 | 99 | "numbers/four"], function() {});""" |
michael@0 | 100 | requires = self.scan(mod) |
michael@0 | 101 | self.failUnlessKeysAre(requires, ["odd", "numbers/four"]) |
michael@0 | 102 | |
michael@0 | 103 | mod = """define(function(require, exports, module) { |
michael@0 | 104 | var a = require("some/module/a"), |
michael@0 | 105 | b = require('b/v1'); |
michael@0 | 106 | exports.a = a; |
michael@0 | 107 | //This is a fakeout: require('bad'); |
michael@0 | 108 | /* And another var bad = require('bad2'); */ |
michael@0 | 109 | require('foo').goFoo(); |
michael@0 | 110 | });""" |
michael@0 | 111 | requires = self.scan(mod) |
michael@0 | 112 | self.failUnlessKeysAre(requires, ["some/module/a", "b/v1", "foo"]) |
michael@0 | 113 | |
michael@0 | 114 | mod = """define ( |
michael@0 | 115 | "foo", |
michael@0 | 116 | ["bar"], function (bar) { |
michael@0 | 117 | var me = require("me"); |
michael@0 | 118 | } |
michael@0 | 119 | )""" |
michael@0 | 120 | requires = self.scan(mod) |
michael@0 | 121 | self.failUnlessKeysAre(requires, ["bar", "me"]) |
michael@0 | 122 | |
michael@0 | 123 | mod = """define(['se' + 'ven', 'eight', nine], function () {});""" |
michael@0 | 124 | requires = self.scan(mod) |
michael@0 | 125 | self.failUnlessKeysAre(requires, ["eight"]) |
michael@0 | 126 | |
michael@0 | 127 | # async require calls |
michael@0 | 128 | |
michael@0 | 129 | mod = """require(['one'], function(one) {var o = require("one");});""" |
michael@0 | 130 | requires = self.scan(mod) |
michael@0 | 131 | self.failUnlessKeysAre(requires, ["one"]) |
michael@0 | 132 | |
michael@0 | 133 | mod = """require([ 'one' ], function(one) {var t = require("two");});""" |
michael@0 | 134 | requires = self.scan(mod) |
michael@0 | 135 | self.failUnlessKeysAre(requires, ["one", "two"]) |
michael@0 | 136 | |
michael@0 | 137 | mod = """require ( ['two', 'numbers/three'], function(t, th) {});""" |
michael@0 | 138 | requires = self.scan(mod) |
michael@0 | 139 | self.failUnlessKeysAre(requires, ["two", "numbers/three"]) |
michael@0 | 140 | |
michael@0 | 141 | mod = """require ( |
michael@0 | 142 | ["bar", "fa" + 'ke' ], function (bar) { |
michael@0 | 143 | var me = require("me"); |
michael@0 | 144 | // require("bad").doBad(); |
michael@0 | 145 | } |
michael@0 | 146 | )""" |
michael@0 | 147 | requires = self.scan(mod) |
michael@0 | 148 | self.failUnlessKeysAre(requires, ["bar", "me"]) |
michael@0 | 149 | |
michael@0 | 150 | def scan2(text, fn="fake.js"): |
michael@0 | 151 | stderr = StringIO() |
michael@0 | 152 | lines = StringIO(text).readlines() |
michael@0 | 153 | requires, problems, locations = scan_module(fn, lines, stderr) |
michael@0 | 154 | stderr.seek(0) |
michael@0 | 155 | return requires, problems, stderr.readlines() |
michael@0 | 156 | |
michael@0 | 157 | class Chrome(unittest.TestCase, Extra): |
michael@0 | 158 | |
michael@0 | 159 | def test_ignore_loader(self): |
michael@0 | 160 | # we specifically ignore the loader itself |
michael@0 | 161 | mod = """let {Cc,Ci} = require('chrome');""" |
michael@0 | 162 | requires, problems, err = scan2(mod, "blah/cuddlefish.js") |
michael@0 | 163 | self.failUnlessKeysAre(requires, ["chrome"]) |
michael@0 | 164 | self.failUnlessEqual(problems, False) |
michael@0 | 165 | self.failUnlessEqual(err, []) |
michael@0 | 166 | |
michael@0 | 167 | def test_chrome(self): |
michael@0 | 168 | mod = """let {Cc,Ci} = require('chrome');""" |
michael@0 | 169 | requires, problems, err = scan2(mod) |
michael@0 | 170 | self.failUnlessKeysAre(requires, ["chrome"]) |
michael@0 | 171 | self.failUnlessEqual(problems, False) |
michael@0 | 172 | self.failUnlessEqual(err, []) |
michael@0 | 173 | |
michael@0 | 174 | mod = """var foo = require('foo'); |
michael@0 | 175 | let {Cc,Ci} = require('chrome');""" |
michael@0 | 176 | requires, problems, err = scan2(mod) |
michael@0 | 177 | self.failUnlessKeysAre(requires, ["foo", "chrome"]) |
michael@0 | 178 | self.failUnlessEqual(problems, False) |
michael@0 | 179 | self.failUnlessEqual(err, []) |
michael@0 | 180 | |
michael@0 | 181 | mod = """let c = require('chrome');""" |
michael@0 | 182 | requires, problems, err = scan2(mod) |
michael@0 | 183 | self.failUnlessKeysAre(requires, ["chrome"]) |
michael@0 | 184 | self.failUnlessEqual(problems, False) |
michael@0 | 185 | self.failUnlessEqual(err, []) |
michael@0 | 186 | |
michael@0 | 187 | mod = """var foo = require('foo'); |
michael@0 | 188 | let c = require('chrome');""" |
michael@0 | 189 | requires, problems, err = scan2(mod) |
michael@0 | 190 | self.failUnlessKeysAre(requires, ["foo", "chrome"]) |
michael@0 | 191 | self.failUnlessEqual(problems, False) |
michael@0 | 192 | self.failUnlessEqual(err, []) |
michael@0 | 193 | |
michael@0 | 194 | def test_not_chrome(self): |
michael@0 | 195 | # from bug 596595 |
michael@0 | 196 | mod = r'soughtLines: new RegExp("^\\s*(\\[[0-9 .]*\\])?\\s*\\(\\((EE|WW)\\)|.* [Cc]hipsets?: \\)|\\s*Backtrace")' |
michael@0 | 197 | requires, problems, err = scan2(mod) |
michael@0 | 198 | self.failUnlessKeysAre(requires, []) |
michael@0 | 199 | self.failUnlessEqual((problems,err), (False, [])) |
michael@0 | 200 | |
michael@0 | 201 | def test_not_chrome2(self): |
michael@0 | 202 | # from bug 655788 |
michael@0 | 203 | mod = r"var foo = 'some stuff Cr';" |
michael@0 | 204 | requires, problems, err = scan2(mod) |
michael@0 | 205 | self.failUnlessKeysAre(requires, []) |
michael@0 | 206 | self.failUnlessEqual((problems,err), (False, [])) |
michael@0 | 207 | |
michael@0 | 208 | class BadChrome(unittest.TestCase, Extra): |
michael@0 | 209 | def test_bad_alias(self): |
michael@0 | 210 | # using Components.* gets you an error, with a message that teaches |
michael@0 | 211 | # you the correct approach. |
michael@0 | 212 | mod = """let Cc = Components.classes; |
michael@0 | 213 | let Cu = Components.utils; |
michael@0 | 214 | """ |
michael@0 | 215 | requires, problems, err = scan2(mod) |
michael@0 | 216 | self.failUnlessKeysAre(requires, []) |
michael@0 | 217 | self.failUnlessEqual(problems, True) |
michael@0 | 218 | self.failUnlessEqual(err[1], "The following lines from file fake.js:\n") |
michael@0 | 219 | self.failUnlessEqual(err[2], " 1: let Cc = Components.classes;\n") |
michael@0 | 220 | self.failUnlessEqual(err[3], " 2: let Cu = Components.utils;\n") |
michael@0 | 221 | self.failUnlessEqual(err[4], "use 'Components' to access chrome authority. To do so, you need to add a\n") |
michael@0 | 222 | self.failUnlessEqual(err[5], "line somewhat like the following:\n") |
michael@0 | 223 | self.failUnlessEqual(err[7], ' const {Cc,Cu} = require("chrome");\n') |
michael@0 | 224 | self.failUnlessEqual(err[9], "Then you can use any shortcuts to its properties that you import from the\n") |
michael@0 | 225 | |
michael@0 | 226 | def test_bad_misc(self): |
michael@0 | 227 | # If it looks like you're using something that doesn't have an alias, |
michael@0 | 228 | # the warning also suggests a better way. |
michael@0 | 229 | mod = """if (Components.isSuccessCode(foo)) |
michael@0 | 230 | """ |
michael@0 | 231 | requires, problems, err = scan2(mod) |
michael@0 | 232 | self.failUnlessKeysAre(requires, []) |
michael@0 | 233 | self.failUnlessEqual(problems, True) |
michael@0 | 234 | self.failUnlessEqual(err[1], "The following lines from file fake.js:\n") |
michael@0 | 235 | self.failUnlessEqual(err[2], " 1: if (Components.isSuccessCode(foo))\n") |
michael@0 | 236 | self.failUnlessEqual(err[3], "use 'Components' to access chrome authority. To do so, you need to add a\n") |
michael@0 | 237 | self.failUnlessEqual(err[4], "line somewhat like the following:\n") |
michael@0 | 238 | self.failUnlessEqual(err[6], ' const {components} = require("chrome");\n') |
michael@0 | 239 | self.failUnlessEqual(err[8], "Then you can use any shortcuts to its properties that you import from the\n") |
michael@0 | 240 | |
michael@0 | 241 | def test_chrome_components(self): |
michael@0 | 242 | # Bug 636145/774636: We no longer tolerate usages of "Components", |
michael@0 | 243 | # even when adding `require("chrome")` to your module. |
michael@0 | 244 | mod = """require("chrome"); |
michael@0 | 245 | var ios = Components.classes['@mozilla.org/network/io-service;1'];""" |
michael@0 | 246 | requires, problems, err = scan2(mod) |
michael@0 | 247 | self.failUnlessKeysAre(requires, ["chrome"]) |
michael@0 | 248 | self.failUnlessEqual(problems, True) |
michael@0 | 249 | self.failUnlessEqual(err[1], "The following lines from file fake.js:\n") |
michael@0 | 250 | self.failUnlessEqual(err[2], " 2: var ios = Components.classes['@mozilla.org/network/io-service;1'];\n") |
michael@0 | 251 | self.failUnlessEqual(err[3], "use 'Components' to access chrome authority. To do so, you need to add a\n") |
michael@0 | 252 | self.failUnlessEqual(err[4], "line somewhat like the following:\n") |
michael@0 | 253 | self.failUnlessEqual(err[6], ' const {Cc} = require("chrome");\n') |
michael@0 | 254 | self.failUnlessEqual(err[8], "Then you can use any shortcuts to its properties that you import from the\n") |
michael@0 | 255 | |
michael@0 | 256 | if __name__ == '__main__': |
michael@0 | 257 | unittest.main() |