# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
# For details: https://bitbucket.org/ned/coveragepy/src/default/NOTICE.txt

"""Tests for XML reports from coverage.py."""

import os
import re

import coverage

from tests.coveragetest import CoverageTest


class XmlTestHelpers(CoverageTest):
    """Methods to use from XML tests."""

    def run_mycode(self):
        """Run mycode.py, so we can report on it."""
        self.make_file("mycode.py", "print('hello')\n")
        self.run_command("coverage run mycode.py")

    def run_doit(self):
        """Construct a simple sub-package."""
        self.make_file("sub/__init__.py")
        self.make_file("sub/doit.py", "print('doit!')")
        self.make_file("main.py", "import sub.doit")
        cov = coverage.Coverage()
        self.start_import_stop(cov, "main")
        return cov

    def make_tree(self, width, depth, curdir="."):
        """Make a tree of packages.

        Makes `width` directories, named d0 .. d{width-1}. Each directory has
        __init__.py, and `width` files, named f0.py .. f{width-1}.py.  Each
        directory also has `width` sub-directories, in the same fashion, until
        a depth of `depth` is reached.

        """
        if depth == 0:
            return

        def here(p):
            """A path for `p` in our currently interesting directory."""
            return os.path.join(curdir, p)

        for i in range(width):
            next_dir = here("d{0}".format(i))
            self.make_tree(width, depth-1, next_dir)
        if curdir != ".":
            self.make_file(here("__init__.py"), "")
            for i in range(width):
                filename = here("f{0}.py".format(i))
                self.make_file(filename, "# {0}\n".format(filename))


class XmlReportTest(XmlTestHelpers, CoverageTest):
    """Tests of the XML reports from coverage.py."""

    def test_default_file_placement(self):
        self.run_mycode()
        self.run_command("coverage xml")
        self.assert_exists("coverage.xml")

    def test_argument_affects_xml_placement(self):
        self.run_mycode()
        self.run_command("coverage xml -o put_it_there.xml")
        self.assert_doesnt_exist("coverage.xml")
        self.assert_exists("put_it_there.xml")

    def test_config_file_directory_does_not_exist(self):
        self.run_mycode()
        self.run_command("coverage xml -o nonexistent/put_it_there.xml")
        self.assert_doesnt_exist("coverage.xml")
        self.assert_doesnt_exist("put_it_there.xml")
        self.assert_exists("nonexistent/put_it_there.xml")

    def test_config_affects_xml_placement(self):
        self.run_mycode()
        self.make_file(".coveragerc", "[xml]\noutput = xml.out\n")
        self.run_command("coverage xml")
        self.assert_doesnt_exist("coverage.xml")
        self.assert_exists("xml.out")

    def test_no_data(self):
        # https://bitbucket.org/ned/coveragepy/issue/210
        self.run_command("coverage xml")
        self.assert_doesnt_exist("coverage.xml")

    def test_no_source(self):
        # Written while investigating a bug, might as well keep it.
        # https://bitbucket.org/ned/coveragepy/issue/208
        self.make_file("innocuous.py", "a = 4")
        cov = coverage.Coverage()
        self.start_import_stop(cov, "innocuous")
        os.remove("innocuous.py")
        cov.xml_report(ignore_errors=True)
        self.assert_exists("coverage.xml")

    def test_filename_format_showing_everything(self):
        cov = self.run_doit()