mirror of
				https://github.com/mozilla/gecko-dev.git
				synced 2025-11-04 10:18:41 +02:00 
			
		
		
		
	# ignore-this-changeset Differential Revision: https://phabricator.services.mozilla.com/D172359
		
			
				
	
	
		
			537 lines
		
	
	
	
		
			19 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			537 lines
		
	
	
	
		
			19 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
# 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 itertools import chain
 | 
						|
 | 
						|
import mozunit
 | 
						|
import six
 | 
						|
 | 
						|
import mozpack.path as mozpath
 | 
						|
from mozpack.chrome.manifest import (
 | 
						|
    ManifestBinaryComponent,
 | 
						|
    ManifestComponent,
 | 
						|
    ManifestContent,
 | 
						|
    ManifestLocale,
 | 
						|
    ManifestResource,
 | 
						|
    ManifestSkin,
 | 
						|
)
 | 
						|
from mozpack.copier import FileRegistry
 | 
						|
from mozpack.errors import ErrorMessage
 | 
						|
from mozpack.files import GeneratedFile, ManifestFile
 | 
						|
from mozpack.packager.formats import FlatFormatter, JarFormatter, OmniJarFormatter
 | 
						|
from mozpack.test.test_files import bar_xpt, foo2_xpt, foo_xpt
 | 
						|
from test_errors import TestErrors
 | 
						|
 | 
						|
CONTENTS = {
 | 
						|
    "bases": {
 | 
						|
        # base_path: is_addon?
 | 
						|
        "": False,
 | 
						|
        "app": False,
 | 
						|
        "addon0": "unpacked",
 | 
						|
        "addon1": True,
 | 
						|
        "app/chrome/addons/addon2": True,
 | 
						|
    },
 | 
						|
    "manifests": [
 | 
						|
        ManifestContent("chrome/f", "oo", "oo/"),
 | 
						|
        ManifestContent("chrome/f", "bar", "oo/bar/"),
 | 
						|
        ManifestResource("chrome/f", "foo", "resource://bar/"),
 | 
						|
        ManifestBinaryComponent("components", "foo.so"),
 | 
						|
        ManifestContent("app/chrome", "content", "foo/"),
 | 
						|
        ManifestComponent("app/components", "{foo-id}", "foo.js"),
 | 
						|
        ManifestContent("addon0/chrome", "addon0", "foo/bar/"),
 | 
						|
        ManifestContent("addon1/chrome", "addon1", "foo/bar/"),
 | 
						|
        ManifestContent("app/chrome/addons/addon2/chrome", "addon2", "foo/bar/"),
 | 
						|
    ],
 | 
						|
    "files": {
 | 
						|
        "chrome/f/oo/bar/baz": GeneratedFile(b"foobarbaz"),
 | 
						|
        "chrome/f/oo/baz": GeneratedFile(b"foobaz"),
 | 
						|
        "chrome/f/oo/qux": GeneratedFile(b"fooqux"),
 | 
						|
        "components/foo.so": GeneratedFile(b"foo.so"),
 | 
						|
        "components/foo.xpt": foo_xpt,
 | 
						|
        "components/bar.xpt": bar_xpt,
 | 
						|
        "foo": GeneratedFile(b"foo"),
 | 
						|
        "app/chrome/foo/foo": GeneratedFile(b"appfoo"),
 | 
						|
        "app/components/foo.js": GeneratedFile(b"foo.js"),
 | 
						|
        "addon0/chrome/foo/bar/baz": GeneratedFile(b"foobarbaz"),
 | 
						|
        "addon0/components/foo.xpt": foo2_xpt,
 | 
						|
        "addon0/components/bar.xpt": bar_xpt,
 | 
						|
        "addon1/chrome/foo/bar/baz": GeneratedFile(b"foobarbaz"),
 | 
						|
        "addon1/components/foo.xpt": foo2_xpt,
 | 
						|
        "addon1/components/bar.xpt": bar_xpt,
 | 
						|
        "app/chrome/addons/addon2/chrome/foo/bar/baz": GeneratedFile(b"foobarbaz"),
 | 
						|
        "app/chrome/addons/addon2/components/foo.xpt": foo2_xpt,
 | 
						|
        "app/chrome/addons/addon2/components/bar.xpt": bar_xpt,
 | 
						|
    },
 | 
						|
}
 | 
						|
 | 
						|
FILES = CONTENTS["files"]
 | 
						|
 | 
						|
RESULT_FLAT = {
 | 
						|
    "chrome.manifest": [
 | 
						|
        "manifest chrome/chrome.manifest",
 | 
						|
        "manifest components/components.manifest",
 | 
						|
    ],
 | 
						|
    "chrome/chrome.manifest": [
 | 
						|
        "manifest f/f.manifest",
 | 
						|
    ],
 | 
						|
    "chrome/f/f.manifest": [
 | 
						|
        "content oo oo/",
 | 
						|
        "content bar oo/bar/",
 | 
						|
        "resource foo resource://bar/",
 | 
						|
    ],
 | 
						|
    "chrome/f/oo/bar/baz": FILES["chrome/f/oo/bar/baz"],
 | 
						|
    "chrome/f/oo/baz": FILES["chrome/f/oo/baz"],
 | 
						|
    "chrome/f/oo/qux": FILES["chrome/f/oo/qux"],
 | 
						|
    "components/components.manifest": [
 | 
						|
        "binary-component foo.so",
 | 
						|
        "interfaces bar.xpt",
 | 
						|
        "interfaces foo.xpt",
 | 
						|
    ],
 | 
						|
    "components/foo.so": FILES["components/foo.so"],
 | 
						|
    "components/foo.xpt": foo_xpt,
 | 
						|
    "components/bar.xpt": bar_xpt,
 | 
						|
    "foo": FILES["foo"],
 | 
						|
    "app/chrome.manifest": [
 | 
						|
        "manifest chrome/chrome.manifest",
 | 
						|
        "manifest components/components.manifest",
 | 
						|
    ],
 | 
						|
    "app/chrome/chrome.manifest": [
 | 
						|
        "content content foo/",
 | 
						|
    ],
 | 
						|
    "app/chrome/foo/foo": FILES["app/chrome/foo/foo"],
 | 
						|
    "app/components/components.manifest": [
 | 
						|
        "component {foo-id} foo.js",
 | 
						|
    ],
 | 
						|
    "app/components/foo.js": FILES["app/components/foo.js"],
 | 
						|
}
 | 
						|
 | 
						|
for addon in ("addon0", "addon1", "app/chrome/addons/addon2"):
 | 
						|
    RESULT_FLAT.update(
 | 
						|
        {
 | 
						|
            mozpath.join(addon, p): f
 | 
						|
            for p, f in six.iteritems(
 | 
						|
                {
 | 
						|
                    "chrome.manifest": [
 | 
						|
                        "manifest chrome/chrome.manifest",
 | 
						|
                        "manifest components/components.manifest",
 | 
						|
                    ],
 | 
						|
                    "chrome/chrome.manifest": [
 | 
						|
                        "content %s foo/bar/" % mozpath.basename(addon),
 | 
						|
                    ],
 | 
						|
                    "chrome/foo/bar/baz": FILES[
 | 
						|
                        mozpath.join(addon, "chrome/foo/bar/baz")
 | 
						|
                    ],
 | 
						|
                    "components/components.manifest": [
 | 
						|
                        "interfaces bar.xpt",
 | 
						|
                        "interfaces foo.xpt",
 | 
						|
                    ],
 | 
						|
                    "components/bar.xpt": bar_xpt,
 | 
						|
                    "components/foo.xpt": foo2_xpt,
 | 
						|
                }
 | 
						|
            )
 | 
						|
        }
 | 
						|
    )
 | 
						|
 | 
						|
RESULT_JAR = {
 | 
						|
    p: RESULT_FLAT[p]
 | 
						|
    for p in (
 | 
						|
        "chrome.manifest",
 | 
						|
        "chrome/chrome.manifest",
 | 
						|
        "components/components.manifest",
 | 
						|
        "components/foo.so",
 | 
						|
        "components/foo.xpt",
 | 
						|
        "components/bar.xpt",
 | 
						|
        "foo",
 | 
						|
        "app/chrome.manifest",
 | 
						|
        "app/components/components.manifest",
 | 
						|
        "app/components/foo.js",
 | 
						|
        "addon0/chrome.manifest",
 | 
						|
        "addon0/components/components.manifest",
 | 
						|
        "addon0/components/foo.xpt",
 | 
						|
        "addon0/components/bar.xpt",
 | 
						|
    )
 | 
						|
}
 | 
						|
 | 
						|
RESULT_JAR.update(
 | 
						|
    {
 | 
						|
        "chrome/f/f.manifest": [
 | 
						|
            "content oo jar:oo.jar!/",
 | 
						|
            "content bar jar:oo.jar!/bar/",
 | 
						|
            "resource foo resource://bar/",
 | 
						|
        ],
 | 
						|
        "chrome/f/oo.jar": {
 | 
						|
            "bar/baz": FILES["chrome/f/oo/bar/baz"],
 | 
						|
            "baz": FILES["chrome/f/oo/baz"],
 | 
						|
            "qux": FILES["chrome/f/oo/qux"],
 | 
						|
        },
 | 
						|
        "app/chrome/chrome.manifest": [
 | 
						|
            "content content jar:foo.jar!/",
 | 
						|
        ],
 | 
						|
        "app/chrome/foo.jar": {
 | 
						|
            "foo": FILES["app/chrome/foo/foo"],
 | 
						|
        },
 | 
						|
        "addon0/chrome/chrome.manifest": [
 | 
						|
            "content addon0 jar:foo.jar!/bar/",
 | 
						|
        ],
 | 
						|
        "addon0/chrome/foo.jar": {
 | 
						|
            "bar/baz": FILES["addon0/chrome/foo/bar/baz"],
 | 
						|
        },
 | 
						|
        "addon1.xpi": {
 | 
						|
            mozpath.relpath(p, "addon1"): f
 | 
						|
            for p, f in six.iteritems(RESULT_FLAT)
 | 
						|
            if p.startswith("addon1/")
 | 
						|
        },
 | 
						|
        "app/chrome/addons/addon2.xpi": {
 | 
						|
            mozpath.relpath(p, "app/chrome/addons/addon2"): f
 | 
						|
            for p, f in six.iteritems(RESULT_FLAT)
 | 
						|
            if p.startswith("app/chrome/addons/addon2/")
 | 
						|
        },
 | 
						|
    }
 | 
						|
)
 | 
						|
 | 
						|
RESULT_OMNIJAR = {
 | 
						|
    p: RESULT_FLAT[p]
 | 
						|
    for p in (
 | 
						|
        "components/foo.so",
 | 
						|
        "foo",
 | 
						|
    )
 | 
						|
}
 | 
						|
 | 
						|
RESULT_OMNIJAR.update({p: RESULT_JAR[p] for p in RESULT_JAR if p.startswith("addon")})
 | 
						|
 | 
						|
RESULT_OMNIJAR.update(
 | 
						|
    {
 | 
						|
        "omni.foo": {
 | 
						|
            "components/components.manifest": [
 | 
						|
                "interfaces bar.xpt",
 | 
						|
                "interfaces foo.xpt",
 | 
						|
            ],
 | 
						|
        },
 | 
						|
        "chrome.manifest": [
 | 
						|
            "manifest components/components.manifest",
 | 
						|
        ],
 | 
						|
        "components/components.manifest": [
 | 
						|
            "binary-component foo.so",
 | 
						|
        ],
 | 
						|
        "app/omni.foo": {
 | 
						|
            p: RESULT_FLAT["app/" + p]
 | 
						|
            for p in chain(
 | 
						|
                (
 | 
						|
                    "chrome.manifest",
 | 
						|
                    "chrome/chrome.manifest",
 | 
						|
                    "chrome/foo/foo",
 | 
						|
                    "components/components.manifest",
 | 
						|
                    "components/foo.js",
 | 
						|
                ),
 | 
						|
                (
 | 
						|
                    mozpath.relpath(p, "app")
 | 
						|
                    for p in six.iterkeys(RESULT_FLAT)
 | 
						|
                    if p.startswith("app/chrome/addons/addon2/")
 | 
						|
                ),
 | 
						|
            )
 | 
						|
        },
 | 
						|
    }
 | 
						|
)
 | 
						|
 | 
						|
RESULT_OMNIJAR["omni.foo"].update(
 | 
						|
    {
 | 
						|
        p: RESULT_FLAT[p]
 | 
						|
        for p in (
 | 
						|
            "chrome.manifest",
 | 
						|
            "chrome/chrome.manifest",
 | 
						|
            "chrome/f/f.manifest",
 | 
						|
            "chrome/f/oo/bar/baz",
 | 
						|
            "chrome/f/oo/baz",
 | 
						|
            "chrome/f/oo/qux",
 | 
						|
            "components/foo.xpt",
 | 
						|
            "components/bar.xpt",
 | 
						|
        )
 | 
						|
    }
 | 
						|
)
 | 
						|
 | 
						|
RESULT_OMNIJAR_WITH_SUBPATH = {
 | 
						|
    k.replace("omni.foo", "bar/omni.foo"): v for k, v in RESULT_OMNIJAR.items()
 | 
						|
}
 | 
						|
 | 
						|
CONTENTS_WITH_BASE = {
 | 
						|
    "bases": {
 | 
						|
        mozpath.join("base/root", b) if b else "base/root": a
 | 
						|
        for b, a in six.iteritems(CONTENTS["bases"])
 | 
						|
    },
 | 
						|
    "manifests": [
 | 
						|
        m.move(mozpath.join("base/root", m.base)) for m in CONTENTS["manifests"]
 | 
						|
    ],
 | 
						|
    "files": {
 | 
						|
        mozpath.join("base/root", p): f for p, f in six.iteritems(CONTENTS["files"])
 | 
						|
    },
 | 
						|
}
 | 
						|
 | 
						|
EXTRA_CONTENTS = {
 | 
						|
    "extra/file": GeneratedFile(b"extra file"),
 | 
						|
}
 | 
						|
 | 
						|
CONTENTS_WITH_BASE["files"].update(EXTRA_CONTENTS)
 | 
						|
 | 
						|
 | 
						|
def result_with_base(results):
 | 
						|
    result = {mozpath.join("base/root", p): v for p, v in six.iteritems(results)}
 | 
						|
    result.update(EXTRA_CONTENTS)
 | 
						|
    return result
 | 
						|
 | 
						|
 | 
						|
RESULT_FLAT_WITH_BASE = result_with_base(RESULT_FLAT)
 | 
						|
RESULT_JAR_WITH_BASE = result_with_base(RESULT_JAR)
 | 
						|
RESULT_OMNIJAR_WITH_BASE = result_with_base(RESULT_OMNIJAR)
 | 
						|
 | 
						|
 | 
						|
def fill_formatter(formatter, contents):
 | 
						|
    for base, is_addon in sorted(contents["bases"].items()):
 | 
						|
        formatter.add_base(base, is_addon)
 | 
						|
 | 
						|
    for manifest in contents["manifests"]:
 | 
						|
        formatter.add_manifest(manifest)
 | 
						|
 | 
						|
    for k, v in sorted(six.iteritems(contents["files"])):
 | 
						|
        if k.endswith(".xpt"):
 | 
						|
            formatter.add_interfaces(k, v)
 | 
						|
        else:
 | 
						|
            formatter.add(k, v)
 | 
						|
 | 
						|
 | 
						|
def get_contents(registry, read_all=False, mode="rt"):
 | 
						|
    result = {}
 | 
						|
    for k, v in registry:
 | 
						|
        if isinstance(v, FileRegistry):
 | 
						|
            result[k] = get_contents(v)
 | 
						|
        elif isinstance(v, ManifestFile) or read_all:
 | 
						|
            if "b" in mode:
 | 
						|
                result[k] = v.open().read()
 | 
						|
            else:
 | 
						|
                result[k] = six.ensure_text(v.open().read()).splitlines()
 | 
						|
        else:
 | 
						|
            result[k] = v
 | 
						|
    return result
 | 
						|
 | 
						|
 | 
						|
class TestFormatters(TestErrors, unittest.TestCase):
 | 
						|
    maxDiff = None
 | 
						|
 | 
						|
    def test_bases(self):
 | 
						|
        formatter = FlatFormatter(FileRegistry())
 | 
						|
        formatter.add_base("")
 | 
						|
        formatter.add_base("addon0", addon=True)
 | 
						|
        formatter.add_base("browser")
 | 
						|
        self.assertEqual(formatter._get_base("platform.ini"), ("", "platform.ini"))
 | 
						|
        self.assertEqual(
 | 
						|
            formatter._get_base("browser/application.ini"),
 | 
						|
            ("browser", "application.ini"),
 | 
						|
        )
 | 
						|
        self.assertEqual(
 | 
						|
            formatter._get_base("addon0/install.rdf"), ("addon0", "install.rdf")
 | 
						|
        )
 | 
						|
 | 
						|
    def do_test_contents(self, formatter, contents):
 | 
						|
        for f in contents["files"]:
 | 
						|
            # .xpt files are merged, so skip them.
 | 
						|
            if not f.endswith(".xpt"):
 | 
						|
                self.assertTrue(formatter.contains(f))
 | 
						|
 | 
						|
    def test_flat_formatter(self):
 | 
						|
        registry = FileRegistry()
 | 
						|
        formatter = FlatFormatter(registry)
 | 
						|
 | 
						|
        fill_formatter(formatter, CONTENTS)
 | 
						|
        self.assertEqual(get_contents(registry), RESULT_FLAT)
 | 
						|
        self.do_test_contents(formatter, CONTENTS)
 | 
						|
 | 
						|
    def test_jar_formatter(self):
 | 
						|
        registry = FileRegistry()
 | 
						|
        formatter = JarFormatter(registry)
 | 
						|
 | 
						|
        fill_formatter(formatter, CONTENTS)
 | 
						|
        self.assertEqual(get_contents(registry), RESULT_JAR)
 | 
						|
        self.do_test_contents(formatter, CONTENTS)
 | 
						|
 | 
						|
    def test_omnijar_formatter(self):
 | 
						|
        registry = FileRegistry()
 | 
						|
        formatter = OmniJarFormatter(registry, "omni.foo")
 | 
						|
 | 
						|
        fill_formatter(formatter, CONTENTS)
 | 
						|
        self.assertEqual(get_contents(registry), RESULT_OMNIJAR)
 | 
						|
        self.do_test_contents(formatter, CONTENTS)
 | 
						|
 | 
						|
    def test_flat_formatter_with_base(self):
 | 
						|
        registry = FileRegistry()
 | 
						|
        formatter = FlatFormatter(registry)
 | 
						|
 | 
						|
        fill_formatter(formatter, CONTENTS_WITH_BASE)
 | 
						|
        self.assertEqual(get_contents(registry), RESULT_FLAT_WITH_BASE)
 | 
						|
        self.do_test_contents(formatter, CONTENTS_WITH_BASE)
 | 
						|
 | 
						|
    def test_jar_formatter_with_base(self):
 | 
						|
        registry = FileRegistry()
 | 
						|
        formatter = JarFormatter(registry)
 | 
						|
 | 
						|
        fill_formatter(formatter, CONTENTS_WITH_BASE)
 | 
						|
        self.assertEqual(get_contents(registry), RESULT_JAR_WITH_BASE)
 | 
						|
        self.do_test_contents(formatter, CONTENTS_WITH_BASE)
 | 
						|
 | 
						|
    def test_omnijar_formatter_with_base(self):
 | 
						|
        registry = FileRegistry()
 | 
						|
        formatter = OmniJarFormatter(registry, "omni.foo")
 | 
						|
 | 
						|
        fill_formatter(formatter, CONTENTS_WITH_BASE)
 | 
						|
        self.assertEqual(get_contents(registry), RESULT_OMNIJAR_WITH_BASE)
 | 
						|
        self.do_test_contents(formatter, CONTENTS_WITH_BASE)
 | 
						|
 | 
						|
    def test_omnijar_formatter_with_subpath(self):
 | 
						|
        registry = FileRegistry()
 | 
						|
        formatter = OmniJarFormatter(registry, "bar/omni.foo")
 | 
						|
 | 
						|
        fill_formatter(formatter, CONTENTS)
 | 
						|
        self.assertEqual(get_contents(registry), RESULT_OMNIJAR_WITH_SUBPATH)
 | 
						|
        self.do_test_contents(formatter, CONTENTS)
 | 
						|
 | 
						|
    def test_omnijar_is_resource(self):
 | 
						|
        def is_resource(base, path):
 | 
						|
            registry = FileRegistry()
 | 
						|
            f = OmniJarFormatter(
 | 
						|
                registry,
 | 
						|
                "omni.foo",
 | 
						|
                non_resources=[
 | 
						|
                    "defaults/messenger/mailViews.dat",
 | 
						|
                    "defaults/foo/*",
 | 
						|
                    "*/dummy",
 | 
						|
                ],
 | 
						|
            )
 | 
						|
            f.add_base("")
 | 
						|
            f.add_base("app")
 | 
						|
            f.add(mozpath.join(base, path), GeneratedFile(b""))
 | 
						|
            if f.copier.contains(mozpath.join(base, path)):
 | 
						|
                return False
 | 
						|
            self.assertTrue(f.copier.contains(mozpath.join(base, "omni.foo")))
 | 
						|
            self.assertTrue(f.copier[mozpath.join(base, "omni.foo")].contains(path))
 | 
						|
            return True
 | 
						|
 | 
						|
        for base in ["", "app/"]:
 | 
						|
            self.assertTrue(is_resource(base, "chrome"))
 | 
						|
            self.assertTrue(is_resource(base, "chrome/foo/bar/baz.properties"))
 | 
						|
            self.assertFalse(is_resource(base, "chrome/icons/foo.png"))
 | 
						|
            self.assertTrue(is_resource(base, "components/foo.js"))
 | 
						|
            self.assertFalse(is_resource(base, "components/foo.so"))
 | 
						|
            self.assertTrue(is_resource(base, "res/foo.css"))
 | 
						|
            self.assertFalse(is_resource(base, "res/cursors/foo.png"))
 | 
						|
            self.assertFalse(is_resource(base, "res/MainMenu.nib/foo"))
 | 
						|
            self.assertTrue(is_resource(base, "defaults/pref/foo.js"))
 | 
						|
            self.assertFalse(is_resource(base, "defaults/pref/channel-prefs.js"))
 | 
						|
            self.assertTrue(is_resource(base, "defaults/preferences/foo.js"))
 | 
						|
            self.assertFalse(is_resource(base, "defaults/preferences/channel-prefs.js"))
 | 
						|
            self.assertTrue(is_resource(base, "modules/foo.jsm"))
 | 
						|
            self.assertTrue(is_resource(base, "greprefs.js"))
 | 
						|
            self.assertTrue(is_resource(base, "hyphenation/foo"))
 | 
						|
            self.assertTrue(is_resource(base, "update.locale"))
 | 
						|
            self.assertFalse(is_resource(base, "foo"))
 | 
						|
            self.assertFalse(is_resource(base, "foo/bar/greprefs.js"))
 | 
						|
            self.assertTrue(is_resource(base, "defaults/messenger/foo.dat"))
 | 
						|
            self.assertFalse(is_resource(base, "defaults/messenger/mailViews.dat"))
 | 
						|
            self.assertTrue(is_resource(base, "defaults/pref/foo.js"))
 | 
						|
            self.assertFalse(is_resource(base, "defaults/foo/bar.dat"))
 | 
						|
            self.assertFalse(is_resource(base, "defaults/foo/bar/baz.dat"))
 | 
						|
            self.assertTrue(is_resource(base, "chrome/foo/bar/baz/dummy_"))
 | 
						|
            self.assertFalse(is_resource(base, "chrome/foo/bar/baz/dummy"))
 | 
						|
            self.assertTrue(is_resource(base, "chrome/foo/bar/dummy_"))
 | 
						|
            self.assertFalse(is_resource(base, "chrome/foo/bar/dummy"))
 | 
						|
 | 
						|
    def test_chrome_override(self):
 | 
						|
        registry = FileRegistry()
 | 
						|
        f = FlatFormatter(registry)
 | 
						|
        f.add_base("")
 | 
						|
        f.add_manifest(ManifestContent("chrome", "foo", "foo/unix"))
 | 
						|
        # A more specific entry for a given chrome name can override a more
 | 
						|
        # generic one.
 | 
						|
        f.add_manifest(ManifestContent("chrome", "foo", "foo/win", "os=WINNT"))
 | 
						|
        f.add_manifest(ManifestContent("chrome", "foo", "foo/osx", "os=Darwin"))
 | 
						|
 | 
						|
        # Chrome with the same name overrides the previous registration.
 | 
						|
        with self.assertRaises(ErrorMessage) as e:
 | 
						|
            f.add_manifest(ManifestContent("chrome", "foo", "foo/"))
 | 
						|
 | 
						|
        self.assertEqual(
 | 
						|
            str(e.exception),
 | 
						|
            'error: "content foo foo/" overrides ' '"content foo foo/unix"',
 | 
						|
        )
 | 
						|
 | 
						|
        # Chrome with the same name and same flags overrides the previous
 | 
						|
        # registration.
 | 
						|
        with self.assertRaises(ErrorMessage) as e:
 | 
						|
            f.add_manifest(ManifestContent("chrome", "foo", "foo/", "os=WINNT"))
 | 
						|
 | 
						|
        self.assertEqual(
 | 
						|
            str(e.exception),
 | 
						|
            'error: "content foo foo/ os=WINNT" overrides '
 | 
						|
            '"content foo foo/win os=WINNT"',
 | 
						|
        )
 | 
						|
 | 
						|
        # We may start with the more specific entry first
 | 
						|
        f.add_manifest(ManifestContent("chrome", "bar", "bar/win", "os=WINNT"))
 | 
						|
        # Then adding a more generic one overrides it.
 | 
						|
        with self.assertRaises(ErrorMessage) as e:
 | 
						|
            f.add_manifest(ManifestContent("chrome", "bar", "bar/unix"))
 | 
						|
 | 
						|
        self.assertEqual(
 | 
						|
            str(e.exception),
 | 
						|
            'error: "content bar bar/unix" overrides ' '"content bar bar/win os=WINNT"',
 | 
						|
        )
 | 
						|
 | 
						|
        # Adding something more specific still works.
 | 
						|
        f.add_manifest(
 | 
						|
            ManifestContent("chrome", "bar", "bar/win", "os=WINNT osversion>=7.0")
 | 
						|
        )
 | 
						|
 | 
						|
        # Variations of skin/locales are allowed.
 | 
						|
        f.add_manifest(
 | 
						|
            ManifestSkin("chrome", "foo", "classic/1.0", "foo/skin/classic/")
 | 
						|
        )
 | 
						|
        f.add_manifest(ManifestSkin("chrome", "foo", "modern/1.0", "foo/skin/modern/"))
 | 
						|
 | 
						|
        f.add_manifest(ManifestLocale("chrome", "foo", "en-US", "foo/locale/en-US/"))
 | 
						|
        f.add_manifest(ManifestLocale("chrome", "foo", "ja-JP", "foo/locale/ja-JP/"))
 | 
						|
 | 
						|
        # But same-skin/locale still error out.
 | 
						|
        with self.assertRaises(ErrorMessage) as e:
 | 
						|
            f.add_manifest(
 | 
						|
                ManifestSkin("chrome", "foo", "classic/1.0", "foo/skin/classic/foo")
 | 
						|
            )
 | 
						|
 | 
						|
        self.assertEqual(
 | 
						|
            str(e.exception),
 | 
						|
            'error: "skin foo classic/1.0 foo/skin/classic/foo" overrides '
 | 
						|
            '"skin foo classic/1.0 foo/skin/classic/"',
 | 
						|
        )
 | 
						|
 | 
						|
        with self.assertRaises(ErrorMessage) as e:
 | 
						|
            f.add_manifest(
 | 
						|
                ManifestLocale("chrome", "foo", "en-US", "foo/locale/en-US/foo")
 | 
						|
            )
 | 
						|
 | 
						|
        self.assertEqual(
 | 
						|
            str(e.exception),
 | 
						|
            'error: "locale foo en-US foo/locale/en-US/foo" overrides '
 | 
						|
            '"locale foo en-US foo/locale/en-US/"',
 | 
						|
        )
 | 
						|
 | 
						|
        # Duplicating existing manifest entries is not an error.
 | 
						|
        f.add_manifest(ManifestContent("chrome", "foo", "foo/unix"))
 | 
						|
 | 
						|
        self.assertEqual(
 | 
						|
            self.get_output(),
 | 
						|
            [
 | 
						|
                'warning: "content foo foo/unix" is duplicated. Skipping.',
 | 
						|
            ],
 | 
						|
        )
 | 
						|
 | 
						|
 | 
						|
if __name__ == "__main__":
 | 
						|
    mozunit.main()
 |