зеркало из https://github.com/mozilla/FlightDeck.git
remove cuddlefish tests - these were part of jetpack-sdk CLI tests
This commit is contained in:
Родитель
4c13aeb251
Коммит
c700259502
|
@ -1,61 +0,0 @@
|
|||
import os
|
||||
import unittest
|
||||
import doctest
|
||||
import glob
|
||||
|
||||
env_root = os.environ['CUDDLEFISH_ROOT']
|
||||
|
||||
def get_tests():
|
||||
import cuddlefish
|
||||
import cuddlefish.tests
|
||||
|
||||
tests = []
|
||||
packages = [cuddlefish, cuddlefish.tests]
|
||||
for package in packages:
|
||||
path = os.path.abspath(package.__path__[0])
|
||||
pynames = glob.glob(os.path.join(path, '*.py'))
|
||||
for filename in pynames:
|
||||
basename = os.path.basename(filename)
|
||||
module_name = os.path.splitext(basename)[0]
|
||||
full_name = "%s.%s" % (package.__name__, module_name)
|
||||
module = __import__(full_name, fromlist=[package.__name__])
|
||||
|
||||
loader = unittest.TestLoader()
|
||||
suite = loader.loadTestsFromModule(module)
|
||||
for test in suite:
|
||||
tests.append(test)
|
||||
|
||||
finder = doctest.DocTestFinder()
|
||||
doctests = finder.find(module)
|
||||
for test in doctests:
|
||||
if len(test.examples) > 0:
|
||||
tests.append(doctest.DocTestCase(test))
|
||||
|
||||
md_dir = os.path.join(env_root, 'static-files', 'md')
|
||||
doctest_opts = (doctest.NORMALIZE_WHITESPACE |
|
||||
doctest.REPORT_UDIFF)
|
||||
for dirpath, dirnames, filenames in os.walk(md_dir):
|
||||
for filename in filenames:
|
||||
if filename.endswith('.md'):
|
||||
absname = os.path.join(dirpath, filename)
|
||||
tests.append(doctest.DocFileTest(
|
||||
absname,
|
||||
module_relative=False,
|
||||
optionflags=doctest_opts
|
||||
))
|
||||
|
||||
return tests
|
||||
|
||||
def run(verbose=False):
|
||||
if verbose:
|
||||
verbosity = 2
|
||||
else:
|
||||
verbosity = 1
|
||||
|
||||
tests = get_tests()
|
||||
suite = unittest.TestSuite(tests)
|
||||
runner = unittest.TextTestRunner(verbosity=verbosity)
|
||||
return runner.run(suite)
|
||||
|
||||
if __name__ == '__main__':
|
||||
run()
|
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"loader": "lib/bar-loader.js"
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
{
|
||||
"loader": "lib/foo-loader.js",
|
||||
"dependencies": ["bar"]
|
||||
}
|
|
@ -1,82 +0,0 @@
|
|||
# Title #
|
||||
|
||||
Some text here
|
||||
|
||||
<api name="test">
|
||||
@method
|
||||
This is a function which does nothing in particular.
|
||||
@returns {object}
|
||||
@prop firststring {string} First string
|
||||
@prop firsturl {url} First URL
|
||||
@param argOne {string} This is the first argument.
|
||||
@param [argTwo] {bool} This is the second argument.
|
||||
@param [argThree=default] {uri}
|
||||
This is the third and final argument. And this is
|
||||
a test of the ability to do multiple lines of
|
||||
text.
|
||||
@param [options] Options Bag
|
||||
@prop [style] {string} Some style information.
|
||||
@prop [secondToLastOption=True] {bool} The last property.
|
||||
@prop [lastOption] {uri}
|
||||
And this time we have
|
||||
A multiline description
|
||||
Written as haiku
|
||||
</api>
|
||||
|
||||
This text appears between the API blocks.
|
||||
|
||||
<api name="append">
|
||||
@method
|
||||
This is a list of options to specify modifications to your slideBar instance.
|
||||
@param options
|
||||
Pass in all of your options here.
|
||||
@prop [icon] {uri} The HREF of an icon to show as the method of accessing your features slideBar
|
||||
@prop [html] {string/xml}
|
||||
The content of the feature, either as an HTML string,
|
||||
or an E4X document fragment (e.g., <><h1>Hi!</h1></>)
|
||||
@prop [url] {uri} The url to load into the content area of the feature
|
||||
@prop [width] {int} Width of the content area and the selected slide size
|
||||
@prop [persist] {bool}
|
||||
Default slide behavior when being selected as follows:
|
||||
If true: blah; If false: double blah.
|
||||
@prop [autoReload] {bool} Automatically reload content on select
|
||||
@prop [onClick] {function} Callback when the icon is clicked
|
||||
@prop [onSelect] {function} Callback when the feature is selected
|
||||
@prop [onReady] {function} Callback when featured is loaded
|
||||
</api>
|
||||
|
||||
Wooo, more text.
|
||||
|
||||
<api name="cool-func.dot">
|
||||
@constructor
|
||||
@returns {string} A value telling you just how cool you are.
|
||||
A boa-constructor!
|
||||
This description can go on for a while, and can even contain
|
||||
some **realy** fancy things. Like `code`, or even
|
||||
~~~~{.javascript}
|
||||
// Some code!
|
||||
~~~~
|
||||
@param howMuch {string} How much cool it is.
|
||||
@param [double=true] {bool}
|
||||
In case you just really need to double it.
|
||||
@param [options] An object-bag of goodies.
|
||||
@prop callback {function} The callback
|
||||
@prop [random] {bool} Do something random?
|
||||
@param [onemore] {bool} One more paramater
|
||||
@param [options2]
|
||||
This is a full description of something
|
||||
that really sucks. Because I now have a multiline
|
||||
description of this thingy.
|
||||
@prop monkey {string} You heard me right
|
||||
@prop [freak=true] {bool}
|
||||
Yes, you are a freak.
|
||||
</api>
|
||||
|
||||
<api name="random">
|
||||
@method
|
||||
A function that returns a random integer between 0 and 10.
|
||||
@returns {int} The random number.
|
||||
</api>
|
||||
|
||||
Some more text here.
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
exports.main = function(options, callbacks) {
|
||||
console.log("1 + 1 =", require("bar-module").add(1, 1));
|
||||
callbacks.quit();
|
||||
};
|
|
@ -1,4 +0,0 @@
|
|||
{
|
||||
"description": "A package w/ a main module; can be built into an extension.",
|
||||
"dependencies": ["jetpack-core", "barbeque"]
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
exports.add = function add(a, b) {
|
||||
return a + b;
|
||||
};
|
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"description": "A package used by 'aardvark' as a library."
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
// This module will be imported by the XPCOM harness/boostrapper
|
||||
// via Components.utils.import() and is responsible for creating a
|
||||
// CommonJS module loader.
|
|
@ -1,4 +0,0 @@
|
|||
{
|
||||
"description": "A foundational package that provides a CommonJS module loader implementation.",
|
||||
"loader": "lib/loader.js"
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
// This file contains XPCOM code that bootstraps a
|
||||
// Jetpack-based extension by loading its harness-options.json,
|
||||
// registering all its resource directories, executing its loader,
|
||||
// and then executing its main module's main() function.
|
|
@ -1,394 +0,0 @@
|
|||
|
||||
import os
|
||||
import unittest
|
||||
from cuddlefish.apiparser import parse_hunks, ParseError
|
||||
|
||||
tests_path = os.path.abspath(os.path.dirname(__file__))
|
||||
static_files_path = os.path.join(tests_path, "static-files")
|
||||
|
||||
class ParserTests(unittest.TestCase):
|
||||
def pathname(self, filename):
|
||||
return os.path.join(static_files_path, "docs", filename)
|
||||
|
||||
def parse_text(self, text):
|
||||
return list(parse_hunks(text))
|
||||
|
||||
def parse(self, pathname):
|
||||
return self.parse_text(open(pathname).read())
|
||||
|
||||
def test_parser(self):
|
||||
parsed = self.parse(self.pathname("APIsample.md"))
|
||||
#for i,h in enumerate(parsed):
|
||||
# print i, h
|
||||
self.assertEqual(parsed[0],
|
||||
("markdown", "# Title #\n\nSome text here\n\n"))
|
||||
self.assertEqual(parsed[1][0], "api-json")
|
||||
p_test = parsed[1][1]
|
||||
self.assertEqual(p_test["name"], "test")
|
||||
self.assertEqual(p_test["type"], "method")
|
||||
self.assertEqual(p_test["description"],
|
||||
"This is a function which does nothing in particular.")
|
||||
r = p_test["returns"]
|
||||
self.assertEqual(r["type"], "object")
|
||||
self.assertEqual(r["description"], "")
|
||||
self.assertEqual(len(r["props"]), 2)
|
||||
self.assertEqual(r["props"][0]["type"], "string")
|
||||
self.assertEqual(r["props"][0]["description"], "First string")
|
||||
self.assertEqual(r["props"][1]["type"], "url")
|
||||
self.assertEqual(r["props"][1]["description"], "First URL")
|
||||
|
||||
self.assertEqual(p_test["params"][0],
|
||||
{"name": "argOne",
|
||||
"required": True,
|
||||
"type": "string",
|
||||
"description": "This is the first argument.",
|
||||
"line_number": 11,
|
||||
})
|
||||
|
||||
self.assertEqual(p_test["params"][1],
|
||||
{"name": "argTwo",
|
||||
"required": False,
|
||||
"type": "bool",
|
||||
"description": "This is the second argument.",
|
||||
"line_number": 12,
|
||||
})
|
||||
|
||||
self.assertEqual(p_test["params"][2],
|
||||
{"name": "argThree",
|
||||
"required": False,
|
||||
"default": "default",
|
||||
"type": "uri",
|
||||
"line_number": 13,
|
||||
"description": """\
|
||||
This is the third and final argument. And this is
|
||||
a test of the ability to do multiple lines of
|
||||
text.""",
|
||||
})
|
||||
p3 = p_test["params"][3]
|
||||
self.assertEqual(p3["name"], "options")
|
||||
self.assertEqual(p3["required"], False)
|
||||
self.failIf("type" in p3)
|
||||
self.assertEqual(p3["description"], "Options Bag")
|
||||
self.assertEqual(p3["props"][0],
|
||||
{"name": "style",
|
||||
"required": False,
|
||||
"type": "string",
|
||||
"description": "Some style information.",
|
||||
"line_number": 18,
|
||||
})
|
||||
self.assertEqual(p3["props"][1],
|
||||
{"name": "secondToLastOption",
|
||||
"required": False,
|
||||
"default": "True",
|
||||
"type": "bool",
|
||||
"description": "The last property.",
|
||||
"line_number": 19,
|
||||
})
|
||||
self.assertEqual(p3["props"][2]["name"], "lastOption")
|
||||
self.assertEqual(p3["props"][2]["required"], False)
|
||||
self.assertEqual(p3["props"][2]["type"], "uri")
|
||||
self.assertEqual(p3["props"][2]["description"], """\
|
||||
And this time we have
|
||||
A multiline description
|
||||
Written as haiku""")
|
||||
|
||||
self.assertEqual(parsed[2][0], "markdown")
|
||||
self.assertEqual(parsed[2][1], "\n\nThis text appears between the API blocks.\n\n")
|
||||
|
||||
self.assertEqual(parsed[3][0], "api-json")
|
||||
p_test = parsed[3][1]
|
||||
|
||||
expected = {'description': 'This is a list of options to specify modifications to your slideBar instance.',
|
||||
"line_number": 28,
|
||||
'name': 'append',
|
||||
'params': [{'description': 'Pass in all of your options here.',
|
||||
'name': 'options',
|
||||
"line_number": 31,
|
||||
'props': [{'description': 'The HREF of an icon to show as the method of accessing your features slideBar',
|
||||
'name': 'icon',
|
||||
"line_number": 33,
|
||||
'required': False,
|
||||
'type': 'uri'},
|
||||
{'description': 'The content of the feature, either as an HTML string,\nor an E4X document fragment (e.g., <><h1>Hi!</h1></>)',
|
||||
'name': 'html',
|
||||
"line_number": 34,
|
||||
'required': False,
|
||||
'type': 'string/xml'},
|
||||
{'description': 'The url to load into the content area of the feature',
|
||||
'name': 'url',
|
||||
"line_number": 37,
|
||||
'required': False,
|
||||
'type': 'uri'},
|
||||
{'description': 'Width of the content area and the selected slide size',
|
||||
'name': 'width',
|
||||
"line_number": 38,
|
||||
'required': False,
|
||||
'type': 'int'},
|
||||
{'description': 'Default slide behavior when being selected as follows:\nIf true: blah; If false: double blah.',
|
||||
'name': 'persist',
|
||||
"line_number": 39,
|
||||
'required': False,
|
||||
'type': 'bool'},
|
||||
{'description': 'Automatically reload content on select',
|
||||
'name': 'autoReload',
|
||||
"line_number": 42,
|
||||
'required': False,
|
||||
'type': 'bool'},
|
||||
{'description': 'Callback when the icon is clicked',
|
||||
'name': 'onClick',
|
||||
"line_number": 43,
|
||||
'required': False,
|
||||
'type': 'function'},
|
||||
{'description': 'Callback when the feature is selected',
|
||||
'name': 'onSelect',
|
||||
"line_number": 44,
|
||||
'required': False,
|
||||
'type': 'function'},
|
||||
{'description': 'Callback when featured is loaded',
|
||||
'name': 'onReady',
|
||||
"line_number": 45,
|
||||
'required': False,
|
||||
'type': 'function'}],
|
||||
'required': True}],
|
||||
'type': 'method'}
|
||||
self.assertEqual(p_test, expected)
|
||||
|
||||
self.assertEqual(parsed[5][0], "api-json")
|
||||
p_test = parsed[5][1]
|
||||
self.assertEqual(p_test["name"], "cool-func.dot")
|
||||
self.assertEqual(p_test["returns"]["description"],
|
||||
"""\
|
||||
A value telling you just how cool you are.
|
||||
A boa-constructor!
|
||||
This description can go on for a while, and can even contain
|
||||
some **realy** fancy things. Like `code`, or even
|
||||
~~~~{.javascript}
|
||||
// Some code!
|
||||
~~~~""")
|
||||
self.assertEqual(p_test["params"][2]["props"][0],
|
||||
{"name": "callback",
|
||||
"required": True,
|
||||
"type": "function",
|
||||
"line_number": 63,
|
||||
"description": "The callback",
|
||||
})
|
||||
self.assertEqual(p_test["params"][2]["props"][1],
|
||||
{"name": "random",
|
||||
"required": False,
|
||||
"type": "bool",
|
||||
"line_number": 64,
|
||||
"description": "Do something random?",
|
||||
})
|
||||
|
||||
self.assertEqual(parsed[8][0], "markdown")
|
||||
self.assertEqual(parsed[8][1], "\n\nSome more text here.\n\n")
|
||||
|
||||
def test_missing_return_propname(self):
|
||||
md = '''\
|
||||
<api name="test">
|
||||
@method
|
||||
This is a function which does nothing in particular.
|
||||
@returns {object}
|
||||
@prop {string} First string, but the property name is missing
|
||||
@prop {url} First URL, same problem
|
||||
@param argOne {string} This is the first argument.
|
||||
</api>
|
||||
'''
|
||||
self.assertRaises(ParseError, self.parse_text, md)
|
||||
|
||||
def test_missing_return_proptype(self):
|
||||
md = '''\
|
||||
<api name="test">
|
||||
@method
|
||||
This is a function which does nothing in particular.
|
||||
@returns {object}
|
||||
@prop untyped It is an error to omit the type of a return property.
|
||||
@param argOne {string} This is the first argument.
|
||||
@param [argTwo=True] {bool} This is the second argument.
|
||||
</api>
|
||||
'''
|
||||
self.assertRaises(ParseError, self.parse_text, md)
|
||||
|
||||
def test_return_propnames(self):
|
||||
md = '''\
|
||||
<api name="test">
|
||||
@method
|
||||
This is a function which does nothing in particular.
|
||||
@returns {object}
|
||||
@prop firststring {string} First string.
|
||||
@prop [firsturl] {url} First URL, not always provided.
|
||||
@param argOne {string} This is the first argument.
|
||||
@param [argTwo=True] {bool} This is the second argument.
|
||||
</api>
|
||||
'''
|
||||
parsed = self.parse_text(md)
|
||||
r = parsed[0][1]["returns"]
|
||||
self.assertEqual(r["props"][0]["name"], "firststring")
|
||||
self.assertEqual(r["props"][0],
|
||||
{"name": "firststring",
|
||||
"type": "string",
|
||||
"description": "First string.",
|
||||
"required": True,
|
||||
"line_number": 5, # 1-indexed
|
||||
})
|
||||
self.assertEqual(r["props"][1],
|
||||
{"name": "firsturl",
|
||||
"type": "url",
|
||||
"description": "First URL, not always provided.",
|
||||
"required": False,
|
||||
"line_number": 6,
|
||||
})
|
||||
|
||||
def test_return_description_1(self):
|
||||
md = '''\
|
||||
<api name="test">
|
||||
@method
|
||||
This is a function which does nothing in particular.
|
||||
@returns {object} A one-line description.
|
||||
@prop firststring {string} First string.
|
||||
@prop [firsturl] {url} First URL, not always provided.
|
||||
@param argOne {string} This is the first argument.
|
||||
@param [argTwo=True] {bool} This is the second argument.
|
||||
</api>
|
||||
'''
|
||||
parsed = self.parse_text(md)
|
||||
r = parsed[0][1]["returns"]
|
||||
self.assertEqual(r["description"], "A one-line description.")
|
||||
|
||||
def test_return_description_2(self):
|
||||
md = '''\
|
||||
<api name="test">
|
||||
@method
|
||||
This is a function which does nothing in particular.
|
||||
@returns {object} A six-line description
|
||||
which is consistently indented by two spaces
|
||||
except for this line
|
||||
and preserves the following empty line
|
||||
|
||||
from which a two-space indentation will be removed.
|
||||
@prop firststring {string} First string.
|
||||
@prop [firsturl] {url} First URL, not always provided.
|
||||
@param argOne {string} This is the first argument.
|
||||
@param [argTwo=True] {bool} This is the second argument.
|
||||
</api>
|
||||
'''
|
||||
parsed = self.parse_text(md)
|
||||
r = parsed[0][1]["returns"]
|
||||
self.assertEqual(r["description"],
|
||||
"A six-line description\n"
|
||||
"which is consistently indented by two spaces\n"
|
||||
" except for this line\n"
|
||||
"and preserves the following empty line\n"
|
||||
"\n"
|
||||
"from which a two-space indentation will be removed.")
|
||||
|
||||
def test_return_description_3(self):
|
||||
md = '''\
|
||||
<api name="test">
|
||||
@method
|
||||
This is a function which does nothing in particular.
|
||||
@returns A one-line untyped description.
|
||||
@param argOne {string} This is the first argument.
|
||||
@param [argTwo=True] {bool} This is the second argument.
|
||||
</api>
|
||||
'''
|
||||
parsed = self.parse_text(md)
|
||||
r = parsed[0][1]["returns"]
|
||||
self.assertEqual(r["description"], "A one-line untyped description.")
|
||||
|
||||
# if the return value was supposed to be an array, the correct syntax
|
||||
# would not have any @prop tags:
|
||||
# @returns {array}
|
||||
# Array consists of two elements, a string and a url...
|
||||
|
||||
def test_return_array(self):
|
||||
md = '''\
|
||||
<api name="test">
|
||||
@method
|
||||
This is a function which returns an array.
|
||||
@returns {array}
|
||||
Array consists of two elements, a string and a url.
|
||||
@param argOne {string} This is the first argument.
|
||||
@param [argTwo=True] {bool} This is the second argument.
|
||||
</api>
|
||||
'''
|
||||
parsed = self.parse_text(md)
|
||||
r = parsed[0][1]["returns"]
|
||||
self.assertEqual(r["description"],
|
||||
"Array consists of two elements, a string and a url.")
|
||||
|
||||
def test_bad_default_on_required_parameter(self):
|
||||
md = '''\
|
||||
<api name="test">
|
||||
@method
|
||||
This is a function which does nothing in particular.
|
||||
@returns something
|
||||
@param argOne=ILLEGAL {string} Mandatory parameters do not take defaults.
|
||||
@param [argTwo=Chicago] {string} This is the second argument.
|
||||
</api>
|
||||
'''
|
||||
self.assertRaises(ParseError, self.parse_text, md)
|
||||
|
||||
def test_missing_apitype(self):
|
||||
md = '''\
|
||||
<api name="test">
|
||||
Sorry, you must have a @method or something before the description.
|
||||
Putting it after the description is not good enough
|
||||
@method
|
||||
@returns something
|
||||
</api>
|
||||
'''
|
||||
self.assertRaises(ParseError, self.parse_text, md)
|
||||
|
||||
def test_missing_param_propname(self):
|
||||
md = '''\
|
||||
<api name="test">
|
||||
@method
|
||||
This is a function which does nothing in particular.
|
||||
@param p1 {object} This is a parameter.
|
||||
@prop {string} Oops, props must have a name.
|
||||
</api>
|
||||
'''
|
||||
self.assertRaises(ParseError, self.parse_text, md)
|
||||
|
||||
def test_missing_param_proptype(self):
|
||||
md = '''\
|
||||
<api name="test">
|
||||
@method
|
||||
This is a function which does nothing in particular.
|
||||
@param p1 {object} This is a parameter.
|
||||
@prop name Oops, props must have a type.
|
||||
</api>
|
||||
'''
|
||||
self.assertRaises(ParseError, self.parse_text, md)
|
||||
|
||||
def test_property(self):
|
||||
md = '''\
|
||||
<api name="test">
|
||||
@property {foo}
|
||||
An object property named test of type foo.
|
||||
</api>
|
||||
'''
|
||||
parsed = self.parse_text(md)
|
||||
self.assertEqual(parsed[0][0], 'api-json')
|
||||
actual_api_json_obj = parsed[0][1]
|
||||
expected_api_json_obj = {
|
||||
'line_number': 1,
|
||||
'property_type': 'foo',
|
||||
'type': 'property',
|
||||
'name': 'test',
|
||||
'description': "An object property named test of type foo."
|
||||
}
|
||||
self.assertEqual(actual_api_json_obj, expected_api_json_obj)
|
||||
|
||||
def test_property_no_type(self):
|
||||
md = '''\
|
||||
<api name="test">
|
||||
@property
|
||||
This property needs to specify a type!
|
||||
</api>
|
||||
'''
|
||||
self.assertRaises(ParseError, self.parse_text, md)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
|
@ -1,206 +0,0 @@
|
|||
|
||||
import os
|
||||
import unittest
|
||||
from StringIO import StringIO
|
||||
from cuddlefish.manifest import scan_module, scan_package
|
||||
|
||||
class Require(unittest.TestCase):
|
||||
def scan(self, text):
|
||||
lines = StringIO(text).readlines()
|
||||
requires, chrome, problems = scan_module("fake.js", lines)
|
||||
self.failUnlessEqual(problems, False)
|
||||
return requires, chrome
|
||||
|
||||
def test_modules(self):
|
||||
mod = """var foo = require('one');"""
|
||||
requires, chrome = self.scan(mod)
|
||||
self.failUnlessEqual(requires, ["one"])
|
||||
self.failUnlessEqual(chrome, False)
|
||||
|
||||
mod = """var foo = require(\"one\");"""
|
||||
requires, chrome = self.scan(mod)
|
||||
self.failUnlessEqual(requires, ["one"])
|
||||
self.failUnlessEqual(chrome, False)
|
||||
|
||||
mod = """var foo=require( 'one' ) ; """
|
||||
requires, chrome = self.scan(mod)
|
||||
self.failUnlessEqual(requires, ["one"])
|
||||
self.failUnlessEqual(chrome, False)
|
||||
|
||||
mod = """var foo = require('o'+'ne'); // tricky, denied"""
|
||||
requires, chrome = self.scan(mod)
|
||||
self.failUnlessEqual(requires, [])
|
||||
self.failUnlessEqual(chrome, False)
|
||||
|
||||
mod = """require('one').immediately.do().stuff();"""
|
||||
requires, chrome = self.scan(mod)
|
||||
self.failUnlessEqual(requires, ["one"])
|
||||
self.failUnlessEqual(chrome, False)
|
||||
|
||||
# these forms are commented out, and thus ignored
|
||||
|
||||
mod = """// var foo = require('one');"""
|
||||
requires, chrome = self.scan(mod)
|
||||
self.failUnlessEqual(requires, [])
|
||||
self.failUnlessEqual(chrome, False)
|
||||
|
||||
mod = """/* var foo = require('one');"""
|
||||
requires, chrome = self.scan(mod)
|
||||
self.failUnlessEqual(requires, [])
|
||||
self.failUnlessEqual(chrome, False)
|
||||
|
||||
mod = """ * var foo = require('one');"""
|
||||
requires, chrome = self.scan(mod)
|
||||
self.failUnlessEqual(requires, [])
|
||||
self.failUnlessEqual(chrome, False)
|
||||
|
||||
mod = """ ' var foo = require('one');"""
|
||||
requires, chrome = self.scan(mod)
|
||||
self.failUnlessEqual(requires, [])
|
||||
self.failUnlessEqual(chrome, False)
|
||||
|
||||
mod = """ \" var foo = require('one');"""
|
||||
requires, chrome = self.scan(mod)
|
||||
self.failUnlessEqual(requires, [])
|
||||
self.failUnlessEqual(chrome, False)
|
||||
|
||||
# multiple requires
|
||||
|
||||
mod = """const foo = require('one');
|
||||
const foo = require('two');"""
|
||||
requires, chrome = self.scan(mod)
|
||||
self.failUnlessEqual(requires, ["one", "two"])
|
||||
self.failUnlessEqual(chrome, False)
|
||||
|
||||
mod = """const foo = require('one'); const foo = require('two');"""
|
||||
requires, chrome = self.scan(mod)
|
||||
self.failUnlessEqual(requires, ["one", "two"])
|
||||
self.failUnlessEqual(chrome, False)
|
||||
|
||||
def scan2(text, fn="fake.js"):
|
||||
stderr = StringIO()
|
||||
lines = StringIO(text).readlines()
|
||||
requires, chrome, problems = scan_module(fn, lines, stderr)
|
||||
stderr.seek(0)
|
||||
return requires, chrome, problems, stderr.readlines()
|
||||
|
||||
class Chrome(unittest.TestCase):
|
||||
|
||||
def test_ignore_loader(self):
|
||||
# we specifically ignore the two loader files
|
||||
mod = """let {Cc,Ci} = require('chrome');"""
|
||||
requires, chrome, problems, err = scan2(mod, "blah/cuddlefish.js")
|
||||
self.failUnlessEqual(requires, [])
|
||||
self.failUnlessEqual(chrome, False)
|
||||
self.failUnlessEqual(problems, False)
|
||||
self.failUnlessEqual(err, [])
|
||||
|
||||
mod = """let {Cc,Ci} = require('chrome');"""
|
||||
requires, chrome, problems, err = scan2(mod, "securable-module.js")
|
||||
self.failUnlessEqual(requires, [])
|
||||
self.failUnlessEqual(chrome, False)
|
||||
self.failUnlessEqual(problems, False)
|
||||
self.failUnlessEqual(err, [])
|
||||
|
||||
def test_chrome(self):
|
||||
mod = """let {Cc,Ci} = require('chrome');"""
|
||||
requires, chrome, problems, err = scan2(mod)
|
||||
self.failUnlessEqual(requires, [])
|
||||
self.failUnlessEqual(chrome, True)
|
||||
self.failUnlessEqual(problems, False)
|
||||
self.failUnlessEqual(err, [])
|
||||
|
||||
mod = """var foo = require('foo');
|
||||
let {Cc,Ci} = require('chrome');"""
|
||||
requires, chrome, problems, err = scan2(mod)
|
||||
self.failUnlessEqual(requires, ["foo"])
|
||||
self.failUnlessEqual(chrome, True)
|
||||
self.failUnlessEqual(problems, False)
|
||||
self.failUnlessEqual(err, [])
|
||||
|
||||
mod = """let c = require('chrome');"""
|
||||
requires, chrome, problems, err = scan2(mod)
|
||||
self.failUnlessEqual(requires, [])
|
||||
self.failUnlessEqual(chrome, True)
|
||||
self.failUnlessEqual(problems, False)
|
||||
self.failUnlessEqual(err, [])
|
||||
|
||||
mod = """var foo = require('foo');
|
||||
let c = require('chrome');"""
|
||||
requires, chrome, problems, err = scan2(mod)
|
||||
self.failUnlessEqual(requires, ["foo"])
|
||||
self.failUnlessEqual(chrome, True)
|
||||
self.failUnlessEqual(problems, False)
|
||||
self.failUnlessEqual(err, [])
|
||||
|
||||
class BadChrome(unittest.TestCase):
|
||||
def test_bad_alias(self):
|
||||
# using Components.* gets you a warning. If it looks like you're
|
||||
# using it to build an alias, the warning suggests a better way.
|
||||
mod = """let Cc = Components.classes;"""
|
||||
requires, chrome, problems, err = scan2(mod)
|
||||
self.failUnlessEqual(requires, [])
|
||||
self.failUnlessEqual(chrome, False)
|
||||
self.failUnlessEqual(problems, True)
|
||||
self.failUnlessEqual(err[1], "To use chrome authority, as in:\n")
|
||||
self.failUnlessEqual(err[-1], ' const {Cc} = require("chrome");\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, chrome, problems, err = scan2(mod)
|
||||
self.failUnlessEqual(requires, [])
|
||||
self.failUnlessEqual(chrome, False)
|
||||
self.failUnlessEqual(problems, True)
|
||||
self.failUnlessEqual(err[1], "To use chrome authority, as in:\n")
|
||||
self.failUnlessEqual(err[-1],
|
||||
' const {components} = require("chrome");\n')
|
||||
|
||||
mod = """let CID = Components.ID""" # not one of the usual aliases
|
||||
requires, chrome, problems, err = scan2(mod)
|
||||
self.failUnlessEqual(requires, [])
|
||||
self.failUnlessEqual(chrome, False)
|
||||
self.failUnlessEqual(problems, True)
|
||||
self.failUnlessEqual(err[1], "To use chrome authority, as in:\n")
|
||||
self.failUnlessEqual(err[-1],
|
||||
' const {components} = require("chrome");\n')
|
||||
|
||||
def test_use_too_much(self):
|
||||
# if you use more than you ask for, you also get a warning
|
||||
mod = """let {Cc,Ci} = require('chrome');
|
||||
Cu.something();"""
|
||||
requires, chrome, problems, err = scan2(mod)
|
||||
self.failUnlessEqual(requires, [])
|
||||
self.failUnlessEqual(chrome, True)
|
||||
self.failUnlessEqual(problems, True)
|
||||
err = "".join(err)
|
||||
self.failUnless("To use chrome authority, as in:" in err, err)
|
||||
self.failUnless("2> Cu.something()" in err, err)
|
||||
self.failUnless("You must enable it with something like:" in err, err)
|
||||
self.failUnless('const {Cc,Ci,Cu} = require("chrome");' in err, err)
|
||||
|
||||
class Package(unittest.TestCase):
|
||||
def test_bug_596573(self):
|
||||
jp_tests = "packages/jetpack-core/tests"
|
||||
manifest, has_problems = scan_package("tests", jp_tests)
|
||||
found = [modname
|
||||
for pkgname, modname, deps, needschrome in manifest
|
||||
if modname == "interoperablejs-read-only/compliance/" +
|
||||
"nested/a/b/c/d"]
|
||||
self.failUnless(len(found) == 1)
|
||||
|
||||
def test_jetpack_core(self):
|
||||
# this has a side-effect of asserting that all the SDK's jetpack-core
|
||||
# modules are clean.
|
||||
jp_core = "packages/jetpack-core/lib"
|
||||
assert os.path.isdir(jp_core) # we expect to be run from the SDK top
|
||||
stderr = StringIO()
|
||||
manifest, has_problems = scan_package("jetpack-core", jp_core, stderr)
|
||||
stderr.seek(0)
|
||||
err = stderr.readlines()
|
||||
self.failUnlessEqual(err, [], "".join(err))
|
||||
self.failUnlessEqual(has_problems, False)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
|
@ -1,40 +0,0 @@
|
|||
import os
|
||||
import unittest
|
||||
|
||||
from cuddlefish import packaging
|
||||
from cuddlefish.bunch import Bunch
|
||||
|
||||
tests_path = os.path.abspath(os.path.dirname(__file__))
|
||||
static_files_path = os.path.join(tests_path, 'static-files')
|
||||
|
||||
def get_configs(pkg_name, dirname='static-files'):
|
||||
root_path = os.path.join(tests_path, dirname)
|
||||
pkg_path = os.path.join(root_path, 'packages', pkg_name)
|
||||
if not (os.path.exists(pkg_path) and os.path.isdir(pkg_path)):
|
||||
raise Exception('path does not exist: %s' % pkg_path)
|
||||
target_cfg = packaging.get_config_in_dir(pkg_path)
|
||||
pkg_cfg = packaging.build_config(root_path, target_cfg)
|
||||
deps = packaging.get_deps_for_targets(pkg_cfg, [pkg_name])
|
||||
build = packaging.generate_build_for_target(
|
||||
pkg_cfg=pkg_cfg,
|
||||
target=pkg_name,
|
||||
deps=deps,
|
||||
prefix='guid-'
|
||||
)
|
||||
return Bunch(target_cfg=target_cfg, pkg_cfg=pkg_cfg, build=build)
|
||||
|
||||
class PackagingTests(unittest.TestCase):
|
||||
def test_bug_588661(self):
|
||||
configs = get_configs('foo', 'bug-588661-files')
|
||||
self.assertEqual(configs.build.loader,
|
||||
'resource://guid-foo-lib/foo-loader.js')
|
||||
|
||||
def test_basic(self):
|
||||
configs = get_configs('aardvark')
|
||||
packages = configs.pkg_cfg.packages
|
||||
|
||||
self.assertTrue('jetpack-core' in packages)
|
||||
self.assertTrue('aardvark' in packages)
|
||||
self.assertTrue('jetpack-core' in packages.aardvark.dependencies)
|
||||
self.assertEqual(packages['jetpack-core'].loader, 'lib/loader.js')
|
||||
self.assertTrue(packages.aardvark.main == 'main')
|
|
@ -1,162 +0,0 @@
|
|||
|
||||
import os, shutil
|
||||
import simplejson as json
|
||||
import unittest
|
||||
import hashlib
|
||||
import base64
|
||||
from cuddlefish import preflight
|
||||
from StringIO import StringIO
|
||||
|
||||
class Util(unittest.TestCase):
|
||||
def get_basedir(self):
|
||||
return os.path.join("_test_tmp", self.id())
|
||||
def make_basedir(self):
|
||||
basedir = self.get_basedir()
|
||||
if os.path.isdir(basedir):
|
||||
here = os.path.abspath(os.getcwd())
|
||||
assert os.path.abspath(basedir).startswith(here) # safety
|
||||
shutil.rmtree(basedir)
|
||||
os.makedirs(basedir)
|
||||
return basedir
|
||||
|
||||
def test_base32(self):
|
||||
for l in range(1, 100):
|
||||
text = "a" * l
|
||||
encoded = preflight.my_b32encode(text)
|
||||
decoded = preflight.my_b32decode(encoded)
|
||||
self.assertEqual(text, decoded, (text, encoded, decoded))
|
||||
|
||||
def test_base62(self):
|
||||
for i in range(1000):
|
||||
h = hashlib.sha1(str(i)).digest()
|
||||
s1 = base64.b64encode(h, "AB").strip("=")
|
||||
s2 = base64.b64encode(h).strip("=").replace("+","A").replace("/","B")
|
||||
self.failUnlessEqual(s1, s2)
|
||||
|
||||
def test_remove_prefix(self):
|
||||
self.assertEqual(preflight.remove_prefix("jid0-stuff", "jid0-", "err"),
|
||||
"stuff")
|
||||
self.assertRaises(ValueError, preflight.remove_prefix,
|
||||
"missing-prefix", "jid0-", "errmsg")
|
||||
|
||||
def write(self, config):
|
||||
basedir = self.get_basedir()
|
||||
fn = os.path.join(basedir, "package.json")
|
||||
open(fn,"w").write(config)
|
||||
def read(self):
|
||||
basedir = self.get_basedir()
|
||||
fn = os.path.join(basedir, "package.json")
|
||||
return open(fn,"r").read()
|
||||
|
||||
def get_cfg(self):
|
||||
cfg = json.loads(self.read())
|
||||
if "name" not in cfg:
|
||||
# the cfx parser always provides a name, even if package.json
|
||||
# doesn't contain one
|
||||
cfg["name"] = "pretend name"
|
||||
return cfg
|
||||
|
||||
def parse(self, keydata):
|
||||
fields = {}
|
||||
fieldnames = []
|
||||
for line in keydata.split("\n"):
|
||||
if line.strip():
|
||||
k,v = line.split(":", 1)
|
||||
k = k.strip() ; v = v.strip()
|
||||
fields[k] = v
|
||||
fieldnames.append(k)
|
||||
return fields, fieldnames
|
||||
|
||||
def test_no_name(self):
|
||||
basedir = self.make_basedir()
|
||||
fn = os.path.join(basedir, "package.json")
|
||||
keydir = os.path.join(basedir, "keys")
|
||||
|
||||
# empty config is not ok: need id (name is automatically supplied)
|
||||
config_orig = "{}"
|
||||
self.write(config_orig)
|
||||
out = StringIO()
|
||||
cfg = self.get_cfg()
|
||||
config_was_ok, modified = preflight.preflight_config(cfg, fn,
|
||||
stderr=out,
|
||||
keydir=keydir)
|
||||
self.failUnlessEqual(config_was_ok, False)
|
||||
self.failUnlessEqual(modified, True)
|
||||
backup_fn = os.path.join(basedir, "package.json.backup")
|
||||
config_backup = open(backup_fn,"r").read()
|
||||
self.failUnlessEqual(config_backup, config_orig)
|
||||
config = json.loads(self.read())
|
||||
self.failIf("name" in config)
|
||||
self.failUnless("id" in config)
|
||||
self.failUnlessEqual(out.getvalue().strip(),
|
||||
"No 'id' in package.json: creating a new keypair for you.")
|
||||
jid = str(config["id"])
|
||||
keyfile = os.path.join(keydir, jid)
|
||||
fields, fieldnames = self.parse(open(keyfile).read())
|
||||
self.failUnlessEqual(fieldnames[0], "private-key")
|
||||
privkey = fields["private-key"]
|
||||
self.failUnless(privkey.startswith("private-jid0-"), privkey)
|
||||
self.failUnlessEqual(fields["jid"], jid)
|
||||
self.failUnlessEqual(fields["name"], "pretend name")
|
||||
os.unlink(backup_fn)
|
||||
|
||||
# just a name? we add the id
|
||||
config_orig = '{"name": "my-awesome-package"}'
|
||||
self.write(config_orig)
|
||||
out = StringIO()
|
||||
cfg = self.get_cfg()
|
||||
config_was_ok, modified = preflight.preflight_config(cfg, fn,
|
||||
stderr=out,
|
||||
keydir=keydir)
|
||||
self.failUnlessEqual(config_was_ok, False)
|
||||
self.failUnlessEqual(modified, True)
|
||||
backup_fn = os.path.join(basedir, "package.json.backup")
|
||||
config_backup = open(backup_fn,"r").read()
|
||||
self.failUnlessEqual(config_backup, config_orig)
|
||||
config = json.loads(self.read())
|
||||
self.failUnlessEqual(config["name"], "my-awesome-package")
|
||||
self.failUnless("id" in config)
|
||||
self.failUnlessEqual(out.getvalue().strip(),
|
||||
"No 'id' in package.json: creating a new keypair for you.")
|
||||
jid = str(config["id"])
|
||||
keyfile = os.path.join(keydir, jid)
|
||||
fields, fieldnames = self.parse(open(keyfile).read())
|
||||
privkey = fields["private-key"]
|
||||
self.failUnless(privkey.startswith("private-jid0-"), privkey)
|
||||
self.failUnlessEqual(fields["jid"], jid)
|
||||
self.failUnlessEqual(fields["name"], "my-awesome-package")
|
||||
|
||||
# name and valid id? great! ship it!
|
||||
config2 = '{"name": "my-awesome-package", "id": "%s"}' % jid
|
||||
self.write(config2)
|
||||
out = StringIO()
|
||||
cfg = self.get_cfg()
|
||||
config_was_ok, modified = preflight.preflight_config(cfg, fn,
|
||||
stderr=out,
|
||||
keydir=keydir)
|
||||
self.failUnlessEqual(config_was_ok, True)
|
||||
self.failUnlessEqual(modified, False)
|
||||
config2a = self.read()
|
||||
self.failUnlessEqual(config2a, config2)
|
||||
self.failUnlessEqual(out.getvalue().strip(), "")
|
||||
|
||||
# name and invalid id? tell them to get a new one
|
||||
os.unlink(keyfile)
|
||||
self.write(config2)
|
||||
out = StringIO()
|
||||
cfg = self.get_cfg()
|
||||
config_was_ok, modified = preflight.preflight_config(cfg, fn,
|
||||
stderr=out,
|
||||
keydir=keydir)
|
||||
self.failUnlessEqual(config_was_ok, False)
|
||||
self.failUnlessEqual(modified, False)
|
||||
out = out.getvalue().strip()
|
||||
self.failUnless("Your package.json says our ID is" in out, out)
|
||||
self.failUnless("But I don't have a corresponding private key in"
|
||||
in out, out)
|
||||
self.failUnless("If you are the original developer" in out, out)
|
||||
self.failUnless("Otherwise, if you are a new developer" in out, out)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
|
@ -1,15 +0,0 @@
|
|||
import unittest
|
||||
import xml.dom.minidom
|
||||
|
||||
from cuddlefish import rdf
|
||||
|
||||
|
||||
class RDFTests(unittest.TestCase):
|
||||
def testBug567660(self):
|
||||
obj = rdf.RDF()
|
||||
data = u'\u2026'.encode('utf-8')
|
||||
x = '<?xml version="1.0" encoding="utf-8"?><blah>%s</blah>' % data
|
||||
obj.dom = xml.dom.minidom.parseString(x)
|
||||
self.assertEqual(obj.dom.documentElement.firstChild.nodeValue,
|
||||
u'\u2026')
|
||||
self.assertEqual(str(obj), x)
|
|
@ -1,24 +0,0 @@
|
|||
import sys
|
||||
|
||||
from cuddlefish import runner
|
||||
|
||||
def xulrunner_app_runner_doctests():
|
||||
"""
|
||||
>>> runner.XulrunnerAppRunner(binary='foo')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
Exception: Binary path does not exist foo
|
||||
|
||||
>>> runner.XulrunnerAppRunner(binary=sys.executable)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: application.ini not found in cmdargs
|
||||
|
||||
>>> runner.XulrunnerAppRunner(binary=sys.executable,
|
||||
... cmdargs=['application.ini'])
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: file does not exist: 'application.ini'
|
||||
"""
|
||||
|
||||
pass
|
|
@ -1,69 +0,0 @@
|
|||
import os
|
||||
import unittest
|
||||
|
||||
from cuddlefish import server
|
||||
from cuddlefish.tests import env_root
|
||||
|
||||
class ServerTests(unittest.TestCase):
|
||||
def test_generate_static_docs_does_not_smoke(self):
|
||||
filename = 'testdocs.tgz'
|
||||
if os.path.exists(filename):
|
||||
os.remove(filename)
|
||||
server.generate_static_docs(env_root, tgz_filename=filename)
|
||||
self.assertTrue(os.path.exists(filename))
|
||||
os.remove(filename)
|
||||
|
||||
class UnprivilegedServerTests(unittest.TestCase):
|
||||
def request(self, path, method='GET'):
|
||||
app = server.make_wsgi_app(env_root, task_queue=None,
|
||||
expose_privileged_api=False)
|
||||
|
||||
def start_response(code, headers):
|
||||
pass
|
||||
|
||||
environ = {'PATH_INFO': path,
|
||||
'REQUEST_METHOD': method}
|
||||
|
||||
responses = [string for string in app(environ, start_response)]
|
||||
return ''.join(responses)
|
||||
|
||||
def test_privileged_api_returns_404(self):
|
||||
self.assertEqual(self.request('/api/blah'),
|
||||
'404 Not Found')
|
||||
|
||||
def test_privileged_api_returns_501(self):
|
||||
self.assertEqual(self.request('/api/idle'),
|
||||
'501 Not Implemented')
|
||||
self.assertEqual(self.request('/api/task-queue'),
|
||||
'501 Not Implemented')
|
||||
|
||||
def test_404(self):
|
||||
self.assertEqual(self.request('/bleh'), '404 Not Found')
|
||||
|
||||
def test_api_404(self):
|
||||
self.assertEqual(self.request('/api/bleh'), '404 Not Found')
|
||||
|
||||
def test_unknown_package_404(self):
|
||||
self.assertEqual(self.request('/packages/bleh'), '404 Not Found')
|
||||
|
||||
def test_package_file_404(self):
|
||||
self.assertEqual(self.request('/packages/jetpack-core/bleh'),
|
||||
'404 Not Found')
|
||||
|
||||
def test_package_file_200(self):
|
||||
readme = self.request('/packages/jetpack-core/README.md')
|
||||
self.assertTrue('Jetpack Core' in readme)
|
||||
|
||||
def test_packages_index_json_200(self):
|
||||
info = server.json.loads(self.request('/packages/index.json'))
|
||||
self.assertEqual(type(info), dict)
|
||||
self.assertTrue('jetpack-core' in info)
|
||||
|
||||
def test_404_on_blank_path(self):
|
||||
self.assertEqual(self.request(''), '404 Not Found')
|
||||
|
||||
def test_ensure_index_returned_on_root_path(self):
|
||||
self.assertTrue('<html>' in self.request('/'))
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
|
@ -1,71 +0,0 @@
|
|||
import os
|
||||
import unittest
|
||||
import zipfile
|
||||
import pprint
|
||||
|
||||
from cuddlefish import xpi
|
||||
from cuddlefish.tests import test_packaging
|
||||
|
||||
xpi_template_path = os.path.join(test_packaging.static_files_path,
|
||||
'xpi-template')
|
||||
|
||||
fake_manifest = '<RDF><!-- Extension metadata is here. --></RDF>'
|
||||
|
||||
def document_dir(name):
|
||||
if name in ['packages', 'xpi-template']:
|
||||
dirname = os.path.join(test_packaging.static_files_path, name)
|
||||
document_dir_files(dirname)
|
||||
elif name == 'xpi-output':
|
||||
create_xpi('test-xpi.xpi')
|
||||
document_zip_file('test-xpi.xpi')
|
||||
os.remove('test-xpi.xpi')
|
||||
else:
|
||||
raise Exception('unknown dir: %s' % name)
|
||||
|
||||
def normpath(path):
|
||||
"""
|
||||
Make a platform-specific relative path use '/' as a separator.
|
||||
"""
|
||||
|
||||
return path.replace(os.path.sep, '/')
|
||||
|
||||
def document_zip_file(path):
|
||||
zip = zipfile.ZipFile(path, 'r')
|
||||
for name in zip.namelist():
|
||||
contents = zip.read(name)
|
||||
lines = contents.splitlines()
|
||||
if len(lines) == 1 and name.endswith('.json') and len(lines[0]) > 75:
|
||||
# Ideally we would json-decode this, but it results
|
||||
# in an annoying 'u' before every string literal,
|
||||
# since json decoding makes all strings unicode.
|
||||
contents = eval(contents)
|
||||
contents = pprint.pformat(contents)
|
||||
lines = contents.splitlines()
|
||||
contents = "\n ".join(lines)
|
||||
print "%s:\n %s" % (normpath(name), contents)
|
||||
zip.close()
|
||||
|
||||
def document_dir_files(path):
|
||||
filename_contents_tuples = []
|
||||
for dirpath, dirnames, filenames in os.walk(path):
|
||||
relpath = dirpath[len(path)+1:]
|
||||
for filename in filenames:
|
||||
abspath = os.path.join(dirpath, filename)
|
||||
contents = open(abspath, 'r').read()
|
||||
contents = "\n ".join(contents.splitlines())
|
||||
relfilename = os.path.join(relpath, filename)
|
||||
filename_contents_tuples.append((normpath(relfilename), contents))
|
||||
filename_contents_tuples.sort()
|
||||
for filename, contents in filename_contents_tuples:
|
||||
print "%s:" % filename
|
||||
print " %s" % contents
|
||||
|
||||
def create_xpi(xpiname):
|
||||
configs = test_packaging.get_configs('aardvark')
|
||||
options = {'main': configs.target_cfg.main}
|
||||
options.update(configs.build)
|
||||
xpi.build_xpi(template_root_dir=xpi_template_path,
|
||||
manifest=fake_manifest,
|
||||
xpi_name=xpiname,
|
||||
harness_options=options,
|
||||
xpts=[])
|
Загрузка…
Ссылка в новой задаче