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