Unit tests. Moved functions out of main.py to eliminate infinite loops
This commit is contained in:
Родитель
d896f44721
Коммит
9a9e1cf9e0
|
@ -1,3 +1,5 @@
|
|||
locale basta resource
|
||||
subject predicate object
|
||||
#subject predicate whatever
|
||||
sub
|
||||
locale predicate resource
|
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0"?>
|
||||
<foo></foo>
|
|
@ -12,8 +12,7 @@ def test_open():
|
|||
manifest = ChromeManifest(chrome_data)
|
||||
assert manifest is not None
|
||||
|
||||
assert manifest.get_value("locale", "basta")["object"] == \
|
||||
"resource"
|
||||
assert manifest.get_value("locale", "basta")["object"] == "resource"
|
||||
|
||||
g_obj = list(manifest.get_objects("subject", "predicate"))
|
||||
|
||||
|
|
|
@ -37,7 +37,6 @@ def test_load_rdf_stringio():
|
|||
r = RDFParser(sio)
|
||||
assert r.rdf
|
||||
|
||||
|
||||
def test_namespacing():
|
||||
"""Tests that the RDF parser successfully creates namespaces."""
|
||||
|
||||
|
@ -47,7 +46,6 @@ def test_namespacing():
|
|||
assert str(r.uri("bar")) == "foo#bar"
|
||||
assert str(r.uri("bar", "abc")) == "abc#bar"
|
||||
|
||||
|
||||
def test_namespacing():
|
||||
"""Tests that the RDF parser successfully creates namespaces."""
|
||||
|
||||
|
@ -57,18 +55,18 @@ def test_namespacing():
|
|||
assert str(r.uri("bar")) == "foo#bar"
|
||||
assert str(r.uri("bar", "abc")) == "abc#bar"
|
||||
|
||||
|
||||
def test_get_root_subject():
|
||||
"Tests the integrity of the get_root_subject() function"
|
||||
|
||||
r = RDFParser(_load_rdf("tests/resources/rdf/pass.rdf"))
|
||||
type_uri = r.uri("type")
|
||||
|
||||
emtype = r.get_object(None, type_uri)
|
||||
assert emtype is not None
|
||||
|
||||
emtype = r.get_object(r.get_root_subject(), type_uri)
|
||||
assert emtype is not None
|
||||
|
||||
|
||||
def test_get_object():
|
||||
""""Tests the integrity of the get_object() and get_objects()
|
||||
functions."""
|
||||
|
@ -82,5 +80,3 @@ def test_get_object():
|
|||
emtests = r.get_objects(None, test_uri)
|
||||
assert len(emtests) == 3
|
||||
assert emtests[0] == emtest
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
import os
|
||||
|
||||
import validator.submain as submain
|
||||
from validator.errorbundler import ErrorBundle
|
||||
from validator.constants import *
|
||||
|
||||
def test_prepare_package():
|
||||
"Tests that the prepare_package function passes for valid data"
|
||||
|
||||
submain.test_package = lambda w,x,y,z: True
|
||||
|
||||
err = ErrorBundle(None, True)
|
||||
assert submain.prepare_package(err, "tests/resources/main/foo.xpi") == True
|
||||
|
||||
def test_prepare_package_missing():
|
||||
"Tests that the prepare_package function fails when file is not found"
|
||||
|
||||
err = ErrorBundle(None, True)
|
||||
submain.prepare_package(err, "foo/bar/asdf/qwerty.xyz")
|
||||
|
||||
assert err.failed()
|
||||
assert err.reject
|
||||
|
||||
def test_prepare_package_bad_file():
|
||||
"Tests that the prepare_package function fails for unknown files"
|
||||
|
||||
err = ErrorBundle(None, True)
|
||||
submain.prepare_package(err, "tests/resources/main/foo.bar")
|
||||
|
||||
assert err.failed()
|
||||
assert err.reject
|
||||
|
||||
def test_prepare_package_xml():
|
||||
"Tests that the prepare_package function passes with search providers"
|
||||
|
||||
submain.test_search = lambda err,y,z: True
|
||||
|
||||
err = ErrorBundle(None, True)
|
||||
submain.prepare_package(err, "tests/resources/main/foo.xml")
|
||||
|
||||
assert not err.failed()
|
||||
assert not err.reject
|
||||
|
||||
submain.test_search = lambda err,y,z: err.error(("x"), "Failed")
|
||||
submain.prepare_package(err, "tests/resources/main/foo.xml")
|
||||
|
||||
assert err.failed()
|
||||
assert err.reject
|
|
@ -5,8 +5,7 @@ import zipfile
|
|||
from StringIO import StringIO
|
||||
|
||||
import argparse
|
||||
from validator import decorator
|
||||
import typedetection
|
||||
import validator.submain as submain
|
||||
import validator.testcases.packagelayout
|
||||
import validator.testcases.installrdf
|
||||
import validator.testcases.library_blacklist
|
||||
|
@ -16,14 +15,16 @@ import validator.testcases.themes
|
|||
import validator.testcases.content
|
||||
import validator.testcases.targetapplication
|
||||
import validator.testcases.l10ncompleteness
|
||||
from validator.xpi import XPIManager
|
||||
from rdf import RDFParser
|
||||
from validator.submain import *
|
||||
from errorbundler import ErrorBundle
|
||||
from validator.constants import *
|
||||
|
||||
def main():
|
||||
def main(): # pragma: no cover
|
||||
"Main function. Handles delegation to other functions."
|
||||
|
||||
# We don't count the main towards code coverage because the code is
|
||||
# inherently tested by the function of the application.
|
||||
|
||||
expectations = {"any":PACKAGE_ANY,
|
||||
"extension":PACKAGE_EXTENSION,
|
||||
"theme":PACKAGE_THEME,
|
||||
|
@ -91,7 +92,7 @@ def main():
|
|||
|
||||
# Parse out the expected add-on type and run the tests.
|
||||
expectation = expectations[args.type]
|
||||
prepare_package(error_bundle, args.package, expectation)
|
||||
submain.prepare_package(error_bundle, args.package, expectation)
|
||||
|
||||
# Print the output of the tests based on the requested format.
|
||||
if args.output == "text":
|
||||
|
@ -107,216 +108,6 @@ def main():
|
|||
else:
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
def prepare_package(err, path, expectation=0):
|
||||
"Prepares a file-based package for validation."
|
||||
|
||||
# Test that the package actually exists. I consider this Tier 0
|
||||
# since we may not even be dealing with a real file.
|
||||
if not os.path.isfile(path):
|
||||
err.reject = True
|
||||
return err.error(("main",
|
||||
"prepare_package",
|
||||
"not_found"),
|
||||
"The package could not be found")
|
||||
|
||||
# Pop the package extension.
|
||||
package_extension = os.path.splitext(path)[1]
|
||||
package_extension = package_extension.lower()
|
||||
|
||||
if package_extension == ".xml":
|
||||
test_search(err, path, expectation)
|
||||
# If it didn't bork, it must be a valid provider!
|
||||
if not err.failed():
|
||||
return err
|
||||
|
||||
# Test that the package is an XPI.
|
||||
if not package_extension in (".xpi", ".jar"):
|
||||
err.reject = True
|
||||
err.error(("main",
|
||||
"prepare_package",
|
||||
"unrecognized"),
|
||||
"The package is not of a recognized type.")
|
||||
|
||||
package = open(path)
|
||||
output = test_package(err, package, path, expectation)
|
||||
package.close()
|
||||
|
||||
return output
|
||||
|
||||
def test_search(err, package, expectation=0):
|
||||
"Tests the package to see if it is a search provider."
|
||||
|
||||
expected_search_provider = expectation in (PACKAGE_ANY,
|
||||
PACKAGE_SEARCHPROV)
|
||||
|
||||
# If we're not expecting a search provider, warn the user and stop
|
||||
# testing it like a search provider.
|
||||
if not expected_search_provider:
|
||||
err.reject = True
|
||||
return err.warning(("main",
|
||||
"test_search",
|
||||
"extension"),
|
||||
"Unexpected file extension.")
|
||||
|
||||
# Is this a search provider?
|
||||
opensearch_results = \
|
||||
testcases.typedetection.detect_opensearch(package)
|
||||
|
||||
if opensearch_results["failure"]:
|
||||
# Failed OpenSearch validation
|
||||
error_mesg = "OpenSearch: %s" % opensearch_results["error"]
|
||||
err.error(("main",
|
||||
"test_search",
|
||||
"general_failure"),
|
||||
error_mesg)
|
||||
|
||||
# We want this to flow back into the rest of the program if
|
||||
# the error indicates that we're not sure whether it's an
|
||||
# OpenSearch document or not.
|
||||
|
||||
if not "decided" in opensearch_results or \
|
||||
opensearch_results["decided"]:
|
||||
err.reject = True
|
||||
return err
|
||||
|
||||
elif expected_search_provider:
|
||||
err.set_type(PACKAGE_SEARCHPROV)
|
||||
err.info(("main",
|
||||
"test_search",
|
||||
"confirmed"),
|
||||
"OpenSearch provider confirmed.")
|
||||
|
||||
return err
|
||||
|
||||
|
||||
def test_package(err, package, name, expectation=PACKAGE_ANY):
|
||||
"Begins tests for the package."
|
||||
|
||||
types = {0: "Unknown",
|
||||
1: "Extension/Multi-Extension",
|
||||
2: "Theme",
|
||||
3: "Dictionary",
|
||||
4: "Language Pack",
|
||||
5: "Search Provider"}
|
||||
|
||||
# Load up a new instance of an XPI.
|
||||
try:
|
||||
package = XPIManager(package, name)
|
||||
if package is None:
|
||||
# Die on this one because the file won't open.
|
||||
return err.error(("main",
|
||||
"test_package",
|
||||
"unopenable"),
|
||||
"The XPI could not be opened.")
|
||||
|
||||
except zipfile.BadZipfile:
|
||||
# This likely means that there is a problem with the zip file.
|
||||
return err.error(("main",
|
||||
"test_package",
|
||||
"bad_zip"),
|
||||
"The XPI file that was submitted is corrupt.")
|
||||
|
||||
except IOError:
|
||||
# This means that there was something wrong with the command.
|
||||
return err.error("We were unable to open the file for testing.")
|
||||
|
||||
# Test the XPI file for corruption.
|
||||
if not package.test():
|
||||
err.reject = True
|
||||
return err.error(("main",
|
||||
"test_package",
|
||||
"corrupt"),
|
||||
"XPI package appears to be corrupt.")
|
||||
|
||||
assumed_extensions = {"jar": PACKAGE_THEME,
|
||||
"xml": PACKAGE_SEARCHPROV}
|
||||
|
||||
if package.extension in assumed_extensions:
|
||||
assumed_type = assumed_extensions[package.extension]
|
||||
# Is the user expecting a different package type?
|
||||
if not expectation in (PACKAGE_ANY, assumed_type):
|
||||
err.error(("main",
|
||||
"test_package",
|
||||
"unexpected_type"),
|
||||
"Unexpected package type (found theme)")
|
||||
|
||||
# Cache a copy of the package contents.
|
||||
package_contents = package.get_file_data()
|
||||
|
||||
# Test the install.rdf file to see if we can get the type that way.
|
||||
has_install_rdf = "install.rdf" in package_contents
|
||||
err.save_resource("has_install_rdf", has_install_rdf)
|
||||
if has_install_rdf:
|
||||
# Load up the install.rdf file.
|
||||
install_rdf_data = package.read("install.rdf")
|
||||
install_rdf = RDFParser(install_rdf_data)
|
||||
|
||||
if install_rdf.rdf is None:
|
||||
return err.error(("main",
|
||||
"test_package",
|
||||
"cannot_parse_installrdf"),
|
||||
"Cannot Parse install.rdf",
|
||||
"The install.rdf file could not be parsed.")
|
||||
|
||||
# Save a copy for later tests.
|
||||
err.save_resource("install_rdf", install_rdf)
|
||||
|
||||
# Load up the results of the type detection
|
||||
results = typedetection.detect_type(err,
|
||||
install_rdf,
|
||||
package)
|
||||
|
||||
if results is None:
|
||||
return err.error(("main",
|
||||
"test_package",
|
||||
"undeterminable_type"),
|
||||
"Unable to determine addon type",
|
||||
"""The type detection algorithm could not
|
||||
determine the type of the add-on.""")
|
||||
else:
|
||||
err.set_type(results)
|
||||
|
||||
# Compare the results of the low-level type detection to
|
||||
# that of the expectation and the assumption.
|
||||
if not expectation in (PACKAGE_ANY, results):
|
||||
err.reject = True
|
||||
err.warning(("main",
|
||||
"test_package",
|
||||
"extension_type_mismatch"),
|
||||
"Extension Type Mismatch",
|
||||
'Type "%s" expected, found "%s")' % (
|
||||
types[expectation],
|
||||
types[results]))
|
||||
|
||||
return test_inner_package(err, package_contents, package)
|
||||
|
||||
|
||||
def test_inner_package(err, package_contents, package):
|
||||
"Tests a package's inner content."
|
||||
|
||||
# Iterate through each tier.
|
||||
for tier in sorted(decorator.get_tiers()):
|
||||
# Iterate through each test of our detected type
|
||||
for test in decorator.get_tests(tier, err.detected_type):
|
||||
test_func = test["test"]
|
||||
if test["simple"]:
|
||||
test_func(err)
|
||||
else:
|
||||
# Pass in:
|
||||
# - Error Bundler
|
||||
# - Package listing
|
||||
# - A copy of the package itself
|
||||
test_func(err, package_contents, package)
|
||||
|
||||
# Return any errors at the end of the tier.
|
||||
if err.failed():
|
||||
return err
|
||||
|
||||
|
||||
# Return the results.
|
||||
return err
|
||||
|
||||
# Start up the testing and return the output.
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
@ -51,9 +51,6 @@ class RDFParser(object):
|
|||
alternative."""
|
||||
|
||||
subjects = list(self.rdf.subjects())
|
||||
# No root if there aren't any nodes.
|
||||
if not subjects:
|
||||
return None
|
||||
|
||||
target = subjects[0]
|
||||
while True:
|
||||
|
|
|
@ -0,0 +1,221 @@
|
|||
import os
|
||||
|
||||
import zipfile
|
||||
|
||||
import validator.testcases as testcases
|
||||
import validator.typedetection as typedetection
|
||||
from validator.xpi import XPIManager
|
||||
from validator.rdf import RDFParser
|
||||
from validator import decorator
|
||||
from validator.constants import *
|
||||
|
||||
|
||||
def prepare_package(err, path, expectation=0):
|
||||
"Prepares a file-based package for validation."
|
||||
|
||||
# Test that the package actually exists. I consider this Tier 0
|
||||
# since we may not even be dealing with a real file.
|
||||
if not os.path.isfile(path):
|
||||
err.reject = True
|
||||
return err.error(("main",
|
||||
"prepare_package",
|
||||
"not_found"),
|
||||
"The package could not be found")
|
||||
|
||||
# Pop the package extension.
|
||||
package_extension = os.path.splitext(path)[1]
|
||||
package_extension = package_extension.lower()
|
||||
|
||||
if package_extension == ".xml":
|
||||
test_search(err, path, expectation)
|
||||
# If it didn't bork, it must be a valid provider!
|
||||
if not err.failed():
|
||||
return err
|
||||
|
||||
# Test that the package is an XPI.
|
||||
if not package_extension in (".xpi", ".jar"):
|
||||
err.reject = True
|
||||
err.error(("main",
|
||||
"prepare_package",
|
||||
"unrecognized"),
|
||||
"The package is not of a recognized type.")
|
||||
|
||||
package = open(path)
|
||||
output = test_package(err, package, path, expectation)
|
||||
package.close()
|
||||
|
||||
return output
|
||||
|
||||
def test_search(err, package, expectation=0):
|
||||
"Tests the package to see if it is a search provider."
|
||||
|
||||
expected_search_provider = expectation in (PACKAGE_ANY,
|
||||
PACKAGE_SEARCHPROV)
|
||||
|
||||
# If we're not expecting a search provider, warn the user and stop
|
||||
# testing it like a search provider.
|
||||
if not expected_search_provider:
|
||||
err.reject = True
|
||||
return err.warning(("main",
|
||||
"test_search",
|
||||
"extension"),
|
||||
"Unexpected file extension.")
|
||||
|
||||
# Is this a search provider?
|
||||
opensearch_results = typedetection.detect_opensearch(package)
|
||||
|
||||
if opensearch_results["failure"]:
|
||||
# Failed OpenSearch validation
|
||||
error_mesg = "OpenSearch: %s" % opensearch_results["error"]
|
||||
err.error(("main",
|
||||
"test_search",
|
||||
"general_failure"),
|
||||
error_mesg)
|
||||
|
||||
# We want this to flow back into the rest of the program if
|
||||
# the error indicates that we're not sure whether it's an
|
||||
# OpenSearch document or not.
|
||||
|
||||
if not "decided" in opensearch_results or \
|
||||
opensearch_results["decided"]:
|
||||
err.reject = True
|
||||
return err
|
||||
|
||||
elif expected_search_provider:
|
||||
err.set_type(PACKAGE_SEARCHPROV)
|
||||
err.info(("main",
|
||||
"test_search",
|
||||
"confirmed"),
|
||||
"OpenSearch provider confirmed.")
|
||||
|
||||
return err
|
||||
|
||||
|
||||
def test_package(err, package, name, expectation=PACKAGE_ANY):
|
||||
"Begins tests for the package."
|
||||
|
||||
types = {0: "Unknown",
|
||||
1: "Extension/Multi-Extension",
|
||||
2: "Theme",
|
||||
3: "Dictionary",
|
||||
4: "Language Pack",
|
||||
5: "Search Provider"}
|
||||
|
||||
# Load up a new instance of an XPI.
|
||||
try:
|
||||
package = XPIManager(package, name)
|
||||
if package is None:
|
||||
# Die on this one because the file won't open.
|
||||
return err.error(("main",
|
||||
"test_package",
|
||||
"unopenable"),
|
||||
"The XPI could not be opened.")
|
||||
|
||||
except zipfile.BadZipfile:
|
||||
# This likely means that there is a problem with the zip file.
|
||||
return err.error(("main",
|
||||
"test_package",
|
||||
"bad_zip"),
|
||||
"The XPI file that was submitted is corrupt.")
|
||||
|
||||
except IOError:
|
||||
# This means that there was something wrong with the command.
|
||||
return err.error(("main",
|
||||
"test_package",
|
||||
"unable_to_open_package"),
|
||||
"We were unable to open the file for testing.")
|
||||
|
||||
# Test the XPI file for corruption.
|
||||
if not package.test():
|
||||
err.reject = True
|
||||
return err.error(("main",
|
||||
"test_package",
|
||||
"corrupt"),
|
||||
"XPI package appears to be corrupt.")
|
||||
|
||||
assumed_extensions = {"jar": PACKAGE_THEME,
|
||||
"xml": PACKAGE_SEARCHPROV}
|
||||
|
||||
if package.extension in assumed_extensions:
|
||||
assumed_type = assumed_extensions[package.extension]
|
||||
# Is the user expecting a different package type?
|
||||
if not expectation in (PACKAGE_ANY, assumed_type):
|
||||
err.error(("main",
|
||||
"test_package",
|
||||
"unexpected_type"),
|
||||
"Unexpected package type (found theme)")
|
||||
|
||||
# Cache a copy of the package contents.
|
||||
package_contents = package.get_file_data()
|
||||
|
||||
# Test the install.rdf file to see if we can get the type that way.
|
||||
has_install_rdf = "install.rdf" in package_contents
|
||||
err.save_resource("has_install_rdf", has_install_rdf)
|
||||
if has_install_rdf:
|
||||
# Load up the install.rdf file.
|
||||
install_rdf_data = package.read("install.rdf")
|
||||
install_rdf = RDFParser(install_rdf_data)
|
||||
|
||||
if install_rdf.rdf is None:
|
||||
return err.error(("main",
|
||||
"test_package",
|
||||
"cannot_parse_installrdf"),
|
||||
"Cannot Parse install.rdf",
|
||||
"The install.rdf file could not be parsed.")
|
||||
|
||||
# Save a copy for later tests.
|
||||
err.save_resource("install_rdf", install_rdf)
|
||||
|
||||
# Load up the results of the type detection
|
||||
results = typedetection.detect_type(err,
|
||||
install_rdf,
|
||||
package)
|
||||
|
||||
if results is None:
|
||||
return err.error(("main",
|
||||
"test_package",
|
||||
"undeterminable_type"),
|
||||
"Unable to determine addon type",
|
||||
"""The type detection algorithm could not
|
||||
determine the type of the add-on.""")
|
||||
else:
|
||||
err.set_type(results)
|
||||
|
||||
# Compare the results of the low-level type detection to
|
||||
# that of the expectation and the assumption.
|
||||
if not expectation in (PACKAGE_ANY, results):
|
||||
err.reject = True
|
||||
err.warning(("main",
|
||||
"test_package",
|
||||
"extension_type_mismatch"),
|
||||
"Extension Type Mismatch",
|
||||
'Type "%s" expected, found "%s")' % (
|
||||
types[expectation],
|
||||
types[results]))
|
||||
|
||||
return test_inner_package(err, package_contents, package)
|
||||
|
||||
def test_inner_package(err, package_contents, package):
|
||||
"Tests a package's inner content."
|
||||
|
||||
# Iterate through each tier.
|
||||
for tier in sorted(decorator.get_tiers()):
|
||||
# Iterate through each test of our detected type
|
||||
for test in decorator.get_tests(tier, err.detected_type):
|
||||
test_func = test["test"]
|
||||
if test["simple"]:
|
||||
test_func(err)
|
||||
else:
|
||||
# Pass in:
|
||||
# - Error Bundler
|
||||
# - Package listing
|
||||
# - A copy of the package itself
|
||||
test_func(err, package_contents, package)
|
||||
|
||||
# Return any errors at the end of the tier.
|
||||
if err.failed():
|
||||
return err
|
||||
|
||||
|
||||
# Return the results.
|
||||
return err
|
|
@ -2,7 +2,7 @@
|
|||
from StringIO import StringIO
|
||||
|
||||
from validator import decorator
|
||||
import validator as testendpoint_validator
|
||||
from validator import submain as testendpoint_validator
|
||||
import validator.testcases.markup.markuptester as testendpoint_markup
|
||||
import validator.testcases.markup.csstester as testendpoint_css
|
||||
import validator.testcases.langpack as testendpoint_langpack
|
||||
|
@ -55,7 +55,7 @@ def test_packed_packages(err, package_contents=None, xpi_package=None):
|
|||
# Let the error bunder know we're in a sub-package.
|
||||
err.push_state(data["name_lower"])
|
||||
err.set_type(PACKAGE_SUBPACKAGE) # Subpackage
|
||||
testendpoint_validator.main.test_inner_package(err,
|
||||
testendpoint_validator.test_inner_package(err,
|
||||
temp_contents,
|
||||
sub_xpi)
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче