# 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/.

from __future__ import unicode_literals

import os
import unittest

from mozunit import main

from mozbuild.frontend.context import (
    ObjDirPath,
)
from mozbuild.frontend.data import (
    AndroidResDirs,
    BrandingFiles,
    ChromeManifestEntry,
    ConfigFileSubstitution,
    Defines,
    DirectoryTraversal,
    Exports,
    FinalTargetPreprocessedFiles,
    GeneratedFile,
    GeneratedSources,
    HostDefines,
    HostSources,
    IPDLFile,
    JARManifest,
    LocalInclude,
    Program,
    SharedLibrary,
    SimpleProgram,
    Sources,
    StaticLibrary,
    TestHarnessFiles,
    TestManifest,
    UnifiedSources,
    VariablePassthru,
)
from mozbuild.frontend.emitter import TreeMetadataEmitter
from mozbuild.frontend.reader import (
    BuildReader,
    BuildReaderError,
    SandboxValidationError,
)
from mozpack.chrome import manifest

from mozbuild.test.common import MockConfig

import mozpack.path as mozpath


data_path = mozpath.abspath(mozpath.dirname(__file__))
data_path = mozpath.join(data_path, 'data')


class TestEmitterBasic(unittest.TestCase):
    def setUp(self):
        self._old_env = dict(os.environ)
        os.environ.pop('MOZ_OBJDIR', None)

    def tearDown(self):
        os.environ.clear()
        os.environ.update(self._old_env)

    def reader(self, name):
        config = MockConfig(mozpath.join(data_path, name), extra_substs=dict(
            ENABLE_TESTS='1',
            BIN_SUFFIX='.prog',
            OS_TARGET='WINNT',
        ))

        return BuildReader(config)

    def read_topsrcdir(self, reader, filter_common=True):
        emitter = TreeMetadataEmitter(reader.config)
        objs = list(emitter.emit(reader.read_topsrcdir()))
        self.assertGreater(len(objs), 0)

        filtered = []
        for obj in objs:
            if filter_common and isinstance(obj, DirectoryTraversal):
                continue

            filtered.append(obj)

        return filtered

    def test_dirs_traversal_simple(self):
        reader = self.reader('traversal-simple')
        objs = self.read_topsrcdir(reader, filter_common=False)
        self.assertEqual(len(objs), 4)

        for o in objs:
            self.assertIsInstance(o, DirectoryTraversal)
            self.assertEqual(o.test_dirs, [])
            self.assertTrue(os.path.isabs(o.context_main_path))
            self.assertEqual(len(o.context_all_paths), 1)

        reldirs = [o.relativedir for o in objs]
        self.assertEqual(reldirs, ['', 'foo', 'foo/biz', 'bar'])

        self.assertEqual(objs[3].affected_tiers, {'misc'})

        dirs = [[d.full_path for d in o.dirs] for o in objs]
        self.assertEqual(dirs, [
            [
                mozpath.join(reader.config.topsrcdir, 'foo'),
                mozpath.join(reader.config.topsrcdir, 'bar')
            ], [
                mozpath.join(reader.config.topsrcdir, 'foo', 'biz')
            ], [], []])

    def test_traversal_all_vars(self):
        reader = self.reader('traversal-all-vars')
        objs = self.read_topsrcdir(reader, filter_common=False)
        self.assertEqual(len(objs), 3)

        for o in objs:
            self.assertIsInstance(o, DirectoryTraversal)

        reldirs = set([o.relativedir for o in objs])
        self.assertEqual(reldirs, set(['', 'regular', 'test']))

        for o in objs:
            reldir = o.relativedir

            if reldir == '':
                self.assertEqual([d.full_path for d in o.dirs], [
                    mozpath.join(reader.config.topsrcdir, 'regular')])
                self.assertEqual([d.full_path for d in o.test_dirs], [
                    mozpath.join(reader.config.topsrcdir, 'test')])

    def test_config_file_substitution(self):
        reader = self.reader('config-file-substitution')
        objs = self.read_topsrcdir(reader)
        self.assertEqual(len(objs), 2)

        self.assertIsInstance(objs[0], ConfigFileSubstitution)
        self.assertIsInstance(objs[1], ConfigFileSubstitution)

        topobjdir = mozpath.abspath(reader.config.topobjdir)
        self.assertEqual(objs[0].relpath, 'foo')
        self.assertEqual(mozpath.normpath(objs[0].output_path),
            mozpath.normpath(mozpath.join(topobjdir, 'foo')))
        self.assertEqual(mozpath.normpath(objs[1].output_path),
            mozpath.normpath(mozpath.join(topobjdir, 'bar')))

    def test_variable_passthru(self):
        reader = self.reader('variable-passthru')
        objs = self.read_topsrcdir(reader)

        self.assertEqual(len(objs), 1)
        self.assertIsInstance(objs[0], VariablePassthru)

        wanted = {
            'ALLOW_COMPILER_WARNINGS': True,
            'DISABLE_STL_WRAPPING': True,
            'NO_DIST_INSTALL': True,
            'VISIBILITY_FLAGS': '',
            'RCFILE': 'foo.rc',
            'RESFILE': 'bar.res',
            'RCINCLUDE': 'bar.rc',
            'DEFFILE': 'baz.def',
            'USE_STATIC_LIBS': True,
            'MOZBUILD_CFLAGS': ['-fno-exceptions', '-w'],
            'MOZBUILD_CXXFLAGS': ['-fcxx-exceptions', '-include foo.h'],
            'MOZBUILD_LDFLAGS': ['-framework Foo', '-x', '-DELAYLOAD:foo.dll',
                                 '-DELAYLOAD:bar.dll'],
            'MOZBUILD_HOST_CFLAGS': ['-funroll-loops', '-wall'],
            'MOZBUILD_HOST_CXXFLAGS': ['-funroll-loops-harder',
                                       '-wall-day-everyday'],
            'WIN32_EXE_LDFLAGS': ['-subsystem:console'],
        }

        variables = objs[0].variables
        maxDiff = self.maxDiff
        self.maxDiff = None
        self.assertEqual(wanted, variables)
        self.maxDiff = maxDiff

    def test_generated_files(self):
        reader = self.reader('generated-files')
        objs = self.read_topsrcdir(reader)

        self.assertEqual(len(objs), 2)
        for o in objs:
            self.assertIsInstance(o, GeneratedFile)

        expected = ['bar.c', 'foo.c']
        for o, expected_filename in zip(objs, expected):
            self.assertEqual(o.output, expected_filename)
            self.assertEqual(o.script, None)
            self.assertEqual(o.method, None)
            self.assertEqual(o.inputs, [])

    def test_generated_files_method_names(self):
        reader = self.reader('generated-files-method-names')
        objs = self.read_topsrcdir(reader)

        self.assertEqual(len(objs), 2)
        for o in objs:
            self.assertIsInstance(o, GeneratedFile)

        expected = ['bar.c', 'foo.c']
        expected_method_names = ['make_bar', 'main']
        for o, expected_filename, expected_method in zip(objs, expected, expected_method_names):
            self.assertEqual(o.output, expected_filename)
            self.assertEqual(o.method, expected_method)
            self.assertEqual(o.inputs, [])

    def test_generated_files_absolute_script(self):
        reader = self.reader('generated-files-absolute-script')
        objs = self.read_topsrcdir(reader)

        self.assertEqual(len(objs), 1)

        o = objs[0]
        self.assertIsInstance(o, GeneratedFile)
        self.assertEqual(o.output, 'bar.c')
        self.assertRegexpMatches(o.script, 'script.py$')
        self.assertEqual(o.method, 'make_bar')
        self.assertEqual(o.inputs, [])

    def test_generated_files_no_script(self):
        reader = self.reader('generated-files-no-script')
        with self.assertRaisesRegexp(SandboxValidationError,
            'Script for generating bar.c does not exist'):
            objs = self.read_topsrcdir(reader)

    def test_generated_files_no_inputs(self):
        reader = self.reader('generated-files-no-inputs')
        with self.assertRaisesRegexp(SandboxValidationError,
            'Input for generating foo.c does not exist'):
            objs = self.read_topsrcdir(reader)

    def test_generated_files_no_python_script(self):
        reader = self.reader('generated-files-no-python-script')
        with self.assertRaisesRegexp(SandboxValidationError,
            'Script for generating bar.c does not end in .py'):
            objs = self.read_topsrcdir(reader)

    def test_exports(self):
        reader = self.reader('exports')
        objs = self.read_topsrcdir(reader)

        self.assertEqual(len(objs), 1)
        self.assertIsInstance(objs[0], Exports)

        expected = [
            ('', ['foo.h', 'bar.h', 'baz.h']),
            ('mozilla', ['mozilla1.h', 'mozilla2.h']),
            ('mozilla/dom', ['dom1.h', 'dom2.h', 'dom3.h']),
            ('mozilla/gfx', ['gfx.h']),
            ('nspr/private', ['pprio.h', 'pprthred.h']),
            ('vpx', ['mem.h', 'mem2.h']),
        ]
        for (expect_path, expect_headers), (actual_path, actual_headers) in \
                zip(expected, [(path, list(seq)) for path, seq in objs[0].files.walk()]):
            self.assertEqual(expect_path, actual_path)
            self.assertEqual(expect_headers, actual_headers)

    def test_exports_missing(self):
        '''
        Missing files in EXPORTS is an error.
        '''
        reader = self.reader('exports-missing')
        with self.assertRaisesRegexp(SandboxValidationError,
             'File listed in EXPORTS does not exist:'):
            objs = self.read_topsrcdir(reader)

    def test_exports_missing_generated(self):
        '''
        An objdir file in EXPORTS that is not in GENERATED_FILES is an error.
        '''
        reader = self.reader('exports-missing-generated')
        with self.assertRaisesRegexp(SandboxValidationError,
             'Objdir file listed in EXPORTS not in GENERATED_FILES:'):
            objs = self.read_topsrcdir(reader)

    def test_exports_generated(self):
        reader = self.reader('exports-generated')
        objs = self.read_topsrcdir(reader)

        self.assertEqual(len(objs), 2)
        self.assertIsInstance(objs[0], GeneratedFile)
        self.assertIsInstance(objs[1], Exports)
        exports = [(path, list(seq)) for path, seq in objs[1].files.walk()]
        self.assertEqual(exports,
                         [('', ['foo.h']),
                          ('mozilla', ['mozilla1.h', '!mozilla2.h'])])
        path, files = exports[1]
        self.assertIsInstance(files[1], ObjDirPath)

    def test_test_harness_files(self):
        reader = self.reader('test-harness-files')
        objs = self.read_topsrcdir(reader)

        self.assertEqual(len(objs), 1)
        self.assertIsInstance(objs[0], TestHarnessFiles)

        expected = {
            'mochitest': ['runtests.py', 'utils.py'],
            'testing/mochitest': ['mochitest.py', 'mochitest.ini'],
        }

        for path, strings in objs[0].srcdir_files.iteritems():
            self.assertTrue(path in expected)
            basenames = sorted(mozpath.basename(s) for s in strings)
            self.assertEqual(sorted(expected[path]), basenames)

    def test_test_harness_files_root(self):
        reader = self.reader('test-harness-files-root')
        with self.assertRaisesRegexp(SandboxValidationError,
            'Cannot install files to the root of TEST_HARNESS_FILES'):
            objs = self.read_topsrcdir(reader)

    def test_branding_files(self):
        reader = self.reader('branding-files')
        objs = self.read_topsrcdir(reader)

        self.assertEqual(len(objs), 1)
        self.assertIsInstance(objs[0], BrandingFiles)

        files = objs[0].files

        self.assertEqual(files._strings, ['bar.ico', 'baz.png', 'foo.xpm'])

        self.assertIn('icons', files._children)
        icons = files._children['icons']

        self.assertEqual(icons._strings, ['quux.icns'])

    def test_program(self):
        reader = self.reader('program')
        objs = self.read_topsrcdir(reader)

        self.assertEqual(len(objs), 3)
        self.assertIsInstance(objs[0], Program)
        self.assertIsInstance(objs[1], SimpleProgram)
        self.assertIsInstance(objs[2], SimpleProgram)

        self.assertEqual(objs[0].program, 'test_program.prog')
        self.assertEqual(objs[1].program, 'test_program1.prog')
        self.assertEqual(objs[2].program, 'test_program2.prog')

    def test_test_manifest_missing_manifest(self):
        """A missing manifest file should result in an error."""
        reader = self.reader('test-manifest-missing-manifest')

        with self.assertRaisesRegexp(SandboxValidationError, 'IOError: Missing files'):
            self.read_topsrcdir(reader)

    def test_empty_test_manifest_rejected(self):
        """A test manifest without any entries is rejected."""
        reader = self.reader('test-manifest-empty')

        with self.assertRaisesRegexp(SandboxValidationError, 'Empty test manifest'):
            self.read_topsrcdir(reader)


    def test_test_manifest_just_support_files(self):
        """A test manifest with no tests but support-files is supported."""
        reader = self.reader('test-manifest-just-support')

        objs = self.read_topsrcdir(reader)
        self.assertEqual(len(objs), 1)
        o = objs[0]
        self.assertEqual(len(o.installs), 2)
        paths = sorted([k[len(o.directory)+1:] for k in o.installs.keys()])
        self.assertEqual(paths, ["foo.txt", "just-support.ini"])

    def test_test_manifest_absolute_support_files(self):
        """Support files starting with '/' are placed relative to the install root"""
        reader = self.reader('test-manifest-absolute-support')

        objs = self.read_topsrcdir(reader)
        self.assertEqual(len(objs), 1)
        o = objs[0]
        self.assertEqual(len(o.installs), 2)
        expected = [
            mozpath.normpath(mozpath.join(o.install_prefix, "../.well-known/foo.txt")),
            mozpath.join(o.install_prefix, "absolute-support.ini"),
        ]
        paths = sorted([v[0] for v in o.installs.values()])
        self.assertEqual(paths, expected)

    def test_test_manifest_install_to_subdir(self):
        """ """
        reader = self.reader('test-manifest-install-subdir')

        objs = self.read_topsrcdir(reader)
        self.assertEqual(len(objs), 1)
        o = objs[0]
        self.assertEqual(len(o.installs), 3)
        self.assertEqual(o.manifest_relpath, "subdir.ini")
        self.assertEqual(o.manifest_obj_relpath, "subdir/subdir.ini")
        expected = [
            mozpath.normpath(mozpath.join(o.install_prefix, "subdir/subdir.ini")),
            mozpath.normpath(mozpath.join(o.install_prefix, "subdir/support.txt")),
            mozpath.normpath(mozpath.join(o.install_prefix, "subdir/test_foo.html")),
        ]
        paths = sorted([v[0] for v in o.installs.values()])
        self.assertEqual(paths, expected)

    def test_test_manifest_install_includes(self):
        """Ensure that any [include:foo.ini] are copied to the objdir."""
        reader = self.reader('test-manifest-install-includes')

        objs = self.read_topsrcdir(reader)
        self.assertEqual(len(objs), 1)
        o = objs[0]
        self.assertEqual(len(o.installs), 3)
        self.assertEqual(o.manifest_relpath, "mochitest.ini")
        self.assertEqual(o.manifest_obj_relpath, "subdir/mochitest.ini")
        expected = [
            mozpath.normpath(mozpath.join(o.install_prefix, "subdir/common.ini")),
            mozpath.normpath(mozpath.join(o.install_prefix, "subdir/mochitest.ini")),
            mozpath.normpath(mozpath.join(o.install_prefix, "subdir/test_foo.html")),
        ]
        paths = sorted([v[0] for v in o.installs.values()])
        self.assertEqual(paths, expected)

    def test_test_manifest_includes(self):
        """Ensure that manifest objects from the emitter list a correct manifest.
        """
        reader = self.reader('test-manifest-emitted-includes')
        [obj] = self.read_topsrcdir(reader)

        # Expected manifest leafs for our tests.
        expected_manifests = {
            'reftest1.html': 'reftest.list',
            'reftest1-ref.html': 'reftest.list',
            'reftest2.html': 'included-reftest.list',
            'reftest2-ref.html': 'included-reftest.list',
        }

        for t in obj.tests:
            self.assertTrue(t['manifest'].endswith(expected_manifests[t['name']]))


    def test_test_manifest_keys_extracted(self):
        """Ensure all metadata from test manifests is extracted."""
        reader = self.reader('test-manifest-keys-extracted')

        objs = [o for o in self.read_topsrcdir(reader)
                if isinstance(o, TestManifest)]

        self.assertEqual(len(objs), 8)

        metadata = {
            'a11y.ini': {
                'flavor': 'a11y',
                'installs': {
                    'a11y.ini': False,
                    'test_a11y.js': True,
                },
                'pattern-installs': 1,
            },
            'browser.ini': {
                'flavor': 'browser-chrome',
                'installs': {
                    'browser.ini': False,
                    'test_browser.js': True,
                    'support1': False,
                    'support2': False,
                },
            },
            'metro.ini': {
                'flavor': 'metro-chrome',
                'installs': {
                    'metro.ini': False,
                    'test_metro.js': True,
                },
            },
            'mochitest.ini': {
                'flavor': 'mochitest',
                'installs': {
                    'mochitest.ini': False,
                    'test_mochitest.js': True,
                },
                'external': {
                    'external1',
                    'external2',
                },
            },
            'chrome.ini': {
                'flavor': 'chrome',
                'installs': {
                    'chrome.ini': False,
                    'test_chrome.js': True,
                },
            },
            'xpcshell.ini': {
                'flavor': 'xpcshell',
                'dupe': True,
                'installs': {
                    'xpcshell.ini': False,
                    'test_xpcshell.js': True,
                    'head1': False,
                    'head2': False,
                    'tail1': False,
                    'tail2': False,
                },
            },
            'reftest.list': {
                'flavor': 'reftest',
                'installs': {},
            },
            'crashtest.list': {
                'flavor': 'crashtest',
                'installs': {},
            },
        }

        for o in objs:
            m = metadata[mozpath.basename(o.manifest_relpath)]

            self.assertTrue(o.path.startswith(o.directory))
            self.assertEqual(o.flavor, m['flavor'])
            self.assertEqual(o.dupe_manifest, m.get('dupe', False))

            external_normalized = set(mozpath.basename(p) for p in
                    o.external_installs)
            self.assertEqual(external_normalized, m.get('external', set()))

            self.assertEqual(len(o.installs), len(m['installs']))
            for path in o.installs.keys():
                self.assertTrue(path.startswith(o.directory))
                relpath = path[len(o.directory)+1:]

                self.assertIn(relpath, m['installs'])
                self.assertEqual(o.installs[path][1], m['installs'][relpath])

            if 'pattern-installs' in m:
                self.assertEqual(len(o.pattern_installs), m['pattern-installs'])

    def test_test_manifest_unmatched_generated(self):
        reader = self.reader('test-manifest-unmatched-generated')

        with self.assertRaisesRegexp(SandboxValidationError,
            'entry in generated-files not present elsewhere'):
            self.read_topsrcdir(reader),

    def test_test_manifest_parent_support_files_dir(self):
        """support-files referencing a file in a parent directory works."""
        reader = self.reader('test-manifest-parent-support-files-dir')

        objs = [o for o in self.read_topsrcdir(reader)
                if isinstance(o, TestManifest)]

        self.assertEqual(len(objs), 1)

        o = objs[0]

        expected = mozpath.join(o.srcdir, 'support-file.txt')
        self.assertIn(expected, o.installs)
        self.assertEqual(o.installs[expected],
            ('testing/mochitest/tests/child/support-file.txt', False))

    def test_test_manifest_missing_test_error(self):
        """Missing test files should result in error."""
        reader = self.reader('test-manifest-missing-test-file')

        with self.assertRaisesRegexp(SandboxValidationError,
            'lists test that does not exist: test_missing.html'):
            self.read_topsrcdir(reader)

    def test_test_manifest_missing_test_error_unfiltered(self):
        """Missing test files should result in error, even when the test list is not filtered."""
        reader = self.reader('test-manifest-missing-test-file-unfiltered')

        with self.assertRaisesRegexp(SandboxValidationError,
            'lists test that does not exist: missing.js'):
            self.read_topsrcdir(reader)

    def test_ipdl_sources(self):
        reader = self.reader('ipdl_sources')
        objs = self.read_topsrcdir(reader)

        ipdls = []
        for o in objs:
            if isinstance(o, IPDLFile):
                ipdls.append('%s/%s' % (o.relativedir, o.basename))

        expected = [
            'bar/bar.ipdl',
            'bar/bar2.ipdlh',
            'foo/foo.ipdl',
            'foo/foo2.ipdlh',
        ]

        self.assertEqual(ipdls, expected)

    def test_local_includes(self):
        """Test that LOCAL_INCLUDES is emitted correctly."""
        reader = self.reader('local_includes')
        objs = self.read_topsrcdir(reader)

        local_includes = [o.path for o in objs if isinstance(o, LocalInclude)]
        expected = [
            '/bar/baz',
            'foo',
        ]

        self.assertEqual(local_includes, expected)

        local_includes = [o.path.full_path
                          for o in objs if isinstance(o, LocalInclude)]
        expected = [
            mozpath.join(reader.config.topsrcdir, 'bar/baz'),
            mozpath.join(reader.config.topsrcdir, 'foo'),
        ]

        self.assertEqual(local_includes, expected)

    def test_generated_includes(self):
        """Test that GENERATED_INCLUDES is emitted correctly."""
        reader = self.reader('generated_includes')
        objs = self.read_topsrcdir(reader)

        generated_includes = [o.path for o in objs if isinstance(o, LocalInclude)]
        expected = [
            '!/bar/baz',
            '!foo',
        ]

        self.assertEqual(generated_includes, expected)

        generated_includes = [o.path.full_path
                              for o in objs if isinstance(o, LocalInclude)]
        expected = [
            mozpath.join(reader.config.topobjdir, 'bar/baz'),
            mozpath.join(reader.config.topobjdir, 'foo'),
        ]

        self.assertEqual(generated_includes, expected)

    def test_defines(self):
        reader = self.reader('defines')
        objs = self.read_topsrcdir(reader)

        defines = {}
        for o in objs:
            if isinstance(o, Defines):
                defines = o.defines

        expected = {
            'BAR': 7,
            'BAZ': '"abcd"',
            'FOO': True,
            'VALUE': 'xyz',
            'QUX': False,
        }

        self.assertEqual(defines, expected)

    def test_host_defines(self):
        reader = self.reader('host-defines')
        objs = self.read_topsrcdir(reader)

        defines = {}
        for o in objs:
            if isinstance(o, HostDefines):
                defines = o.defines

        expected = {
            'BAR': 7,
            'BAZ': '"abcd"',
            'FOO': True,
            'VALUE': 'xyz',
            'QUX': False,
        }

        self.assertEqual(defines, expected)

    def test_jar_manifests(self):
        reader = self.reader('jar-manifests')
        objs = self.read_topsrcdir(reader)

        self.assertEqual(len(objs), 1)
        for obj in objs:
            self.assertIsInstance(obj, JARManifest)
            self.assertTrue(os.path.isabs(obj.path))

    def test_jar_manifests_multiple_files(self):
        with self.assertRaisesRegexp(SandboxValidationError, 'limited to one value'):
            reader = self.reader('jar-manifests-multiple-files')
            self.read_topsrcdir(reader)

    def test_xpidl_module_no_sources(self):
        """XPIDL_MODULE without XPIDL_SOURCES should be rejected."""
        with self.assertRaisesRegexp(SandboxValidationError, 'XPIDL_MODULE '
            'cannot be defined'):
            reader = self.reader('xpidl-module-no-sources')
            self.read_topsrcdir(reader)

    def test_missing_local_includes(self):
        """LOCAL_INCLUDES containing non-existent directories should be rejected."""
        with self.assertRaisesRegexp(SandboxValidationError, 'Path specified in '
            'LOCAL_INCLUDES does not exist'):
            reader = self.reader('missing-local-includes')
            self.read_topsrcdir(reader)

    def test_library_defines(self):
        """Test that LIBRARY_DEFINES is propagated properly."""
        reader = self.reader('library-defines')
        objs = self.read_topsrcdir(reader)

        libraries = [o for o in objs if isinstance(o,StaticLibrary)]
        expected = {
            'liba': '-DIN_LIBA',
            'libb': '-DIN_LIBA -DIN_LIBB',
            'libc': '-DIN_LIBA -DIN_LIBB',
            'libd': ''
        }
        defines = {}
        for lib in libraries:
            defines[lib.basename] = ' '.join(lib.defines.get_defines())
        self.assertEqual(expected, defines)

    def test_sources(self):
        """Test that SOURCES works properly."""
        reader = self.reader('sources')
        objs = self.read_topsrcdir(reader)

        self.assertEqual(len(objs), 6)
        for o in objs:
            self.assertIsInstance(o, Sources)

        suffix_map = {obj.canonical_suffix: obj for obj in objs}
        self.assertEqual(len(suffix_map), 6)

        expected = {
            '.cpp': ['a.cpp', 'b.cc', 'c.cxx'],
            '.c': ['d.c'],
            '.m': ['e.m'],
            '.mm': ['f.mm'],
            '.S': ['g.S'],
            '.s': ['h.s', 'i.asm'],
        }
        for suffix, files in expected.items():
            sources = suffix_map[suffix]
            self.assertEqual(
                sources.files,
                [mozpath.join(reader.config.topsrcdir, f) for f in files])

    def test_generated_sources(self):
        """Test that GENERATED_SOURCES works properly."""
        reader = self.reader('generated-sources')
        objs = self.read_topsrcdir(reader)

        self.assertEqual(len(objs), 6)

        generated_sources = [o for o in objs if isinstance(o, GeneratedSources)]
        self.assertEqual(len(generated_sources), 6)

        suffix_map = {obj.canonical_suffix: obj for obj in generated_sources}
        self.assertEqual(len(suffix_map), 6)

        expected = {
            '.cpp': ['a.cpp', 'b.cc', 'c.cxx'],
            '.c': ['d.c'],
            '.m': ['e.m'],
            '.mm': ['f.mm'],
            '.S': ['g.S'],
            '.s': ['h.s', 'i.asm'],
        }
        for suffix, files in expected.items():
            sources = suffix_map[suffix]
            self.assertEqual(
                sources.files,
                [mozpath.join(reader.config.topobjdir, f) for f in files])

    def test_host_sources(self):
        """Test that HOST_SOURCES works properly."""
        reader = self.reader('host-sources')
        objs = self.read_topsrcdir(reader)

        self.assertEqual(len(objs), 3)
        for o in objs:
            self.assertIsInstance(o, HostSources)

        suffix_map = {obj.canonical_suffix: obj for obj in objs}
        self.assertEqual(len(suffix_map), 3)

        expected = {
            '.cpp': ['a.cpp', 'b.cc', 'c.cxx'],
            '.c': ['d.c'],
            '.mm': ['e.mm', 'f.mm'],
        }
        for suffix, files in expected.items():
            sources = suffix_map[suffix]
            self.assertEqual(
                sources.files,
                [mozpath.join(reader.config.topsrcdir, f) for f in files])

    def test_unified_sources(self):
        """Test that UNIFIED_SOURCES works properly."""
        reader = self.reader('unified-sources')
        objs = self.read_topsrcdir(reader)

        self.assertEqual(len(objs), 3)
        for o in objs:
            self.assertIsInstance(o, UnifiedSources)

        suffix_map = {obj.canonical_suffix: obj for obj in objs}
        self.assertEqual(len(suffix_map), 3)

        expected = {
            '.cpp': ['bar.cxx', 'foo.cpp', 'quux.cc'],
            '.mm': ['objc1.mm', 'objc2.mm'],
            '.c': ['c1.c', 'c2.c'],
        }
        for suffix, files in expected.items():
            sources = suffix_map[suffix]
            self.assertEqual(
                sources.files,
                [mozpath.join(reader.config.topsrcdir, f) for f in files])
            self.assertTrue(sources.have_unified_mapping)

    def test_unified_sources_non_unified(self):
        """Test that UNIFIED_SOURCES with FILES_PER_UNIFIED_FILE=1 works properly."""
        reader = self.reader('unified-sources-non-unified')
        objs = self.read_topsrcdir(reader)

        self.assertEqual(len(objs), 3)
        for o in objs:
            self.assertIsInstance(o, UnifiedSources)

        suffix_map = {obj.canonical_suffix: obj for obj in objs}
        self.assertEqual(len(suffix_map), 3)

        expected = {
            '.cpp': ['bar.cxx', 'foo.cpp', 'quux.cc'],
            '.mm': ['objc1.mm', 'objc2.mm'],
            '.c': ['c1.c', 'c2.c'],
        }
        for suffix, files in expected.items():
            sources = suffix_map[suffix]
            self.assertEqual(
                sources.files,
                [mozpath.join(reader.config.topsrcdir, f) for f in files])
            self.assertFalse(sources.have_unified_mapping)

    def test_final_target_pp_files(self):
        """Test that FINAL_TARGET_PP_FILES works properly."""
        reader = self.reader('dist-files')
        objs = self.read_topsrcdir(reader)

        self.assertEqual(len(objs), 1)
        self.assertIsInstance(objs[0], FinalTargetPreprocessedFiles)

        # Ideally we'd test hierarchies, but that would just be testing
        # the HierarchicalStringList class, which we test separately.
        for path, files in objs[0].files.walk():
            self.assertEqual(path, '')
            self.assertEqual(len(files), 2)

            expected = {'install.rdf', 'main.js'}
            for f in files:
                self.assertTrue(unicode(f) in expected)

    def test_missing_final_target_pp_files(self):
        """Test that FINAL_TARGET_PP_FILES with missing files throws errors."""
        with self.assertRaisesRegexp(SandboxValidationError, 'File listed in '
            'FINAL_TARGET_PP_FILES does not exist'):
            reader = self.reader('dist-files-missing')
            self.read_topsrcdir(reader)

    def test_final_target_pp_files_non_srcdir(self):
        '''Test that non-srcdir paths in FINAL_TARGET_PP_FILES throws errors.'''
        reader = self.reader('final-target-pp-files-non-srcdir')
        with self.assertRaisesRegexp(SandboxValidationError,
             'Only source directory paths allowed in FINAL_TARGET_PP_FILES:'):
            objs = self.read_topsrcdir(reader)

    def test_android_res_dirs(self):
        """Test that ANDROID_RES_DIRS works properly."""
        reader = self.reader('android-res-dirs')
        objs = self.read_topsrcdir(reader)

        self.assertEqual(len(objs), 1)
        self.assertIsInstance(objs[0], AndroidResDirs)

        # Android resource directories are ordered.
        expected = [
            mozpath.join(reader.config.topsrcdir, 'dir1'),
            mozpath.join(reader.config.topobjdir, 'dir2'),
            '/dir3',
        ]
        self.assertEquals([p.full_path for p in objs[0].paths], expected)

    def test_binary_components(self):
        """Test that IS_COMPONENT/NO_COMPONENTS_MANIFEST work properly."""
        reader = self.reader('binary-components')
        objs = self.read_topsrcdir(reader)

        self.assertEqual(len(objs), 3)
        self.assertIsInstance(objs[0], ChromeManifestEntry)
        self.assertEqual(objs[0].path,
                         'dist/bin/components/components.manifest')
        self.assertIsInstance(objs[0].entry, manifest.ManifestBinaryComponent)
        self.assertEqual(objs[0].entry.base, 'dist/bin/components')
        self.assertEqual(objs[0].entry.relpath, objs[1].lib_name)
        self.assertIsInstance(objs[1], SharedLibrary)
        self.assertEqual(objs[1].basename, 'foo')
        self.assertIsInstance(objs[2], SharedLibrary)
        self.assertEqual(objs[2].basename, 'bar')


if __name__ == '__main__':
    main()
