"""develop tests
"""
import os
import types

import pytest

import pkg_resources
import setuptools.sandbox


class TestSandbox:
    def test_devnull(self, tmpdir):
        with setuptools.sandbox.DirectorySandbox(str(tmpdir)):
            self._file_writer(os.devnull)

    @staticmethod
    def _file_writer(path):
        def do_write():
            with open(path, 'w') as f:
                f.write('xxx')

        return do_write

    def test_setup_py_with_BOM(self):
        """
        It should be possible to execute a setup.py with a Byte Order Mark
        """
        target = pkg_resources.resource_filename(__name__,
            'script-with-bom.py')
        namespace = types.ModuleType('namespace')
        setuptools.sandbox._execfile(target, vars(namespace))
        assert namespace.result == 'passed'

    def test_setup_py_with_CRLF(self, tmpdir):
        setup_py = tmpdir / 'setup.py'
        with setup_py.open('wb') as stream:
            stream.write(b'"degenerate script"\r\n')
        setuptools.sandbox._execfile(str(setup_py), globals())


class TestExceptionSaver:
    def test_exception_trapped(self):
        with setuptools.sandbox.ExceptionSaver():
            raise ValueError("details")

    def test_exception_resumed(self):
        with setuptools.sandbox.ExceptionSaver() as saved_exc:
            raise ValueError("details")

        with pytest.raises(ValueError) as caught:
            saved_exc.resume()

        assert isinstance(caught.value, ValueError)
        assert str(caught.value) == 'details'

    def test_exception_reconstructed(self):
        orig_exc = ValueError("details")

        with setuptools.sandbox.ExceptionSaver() as saved_exc:
            raise orig_exc

        with pytest.raises(ValueError) as caught:
            saved_exc.resume()

        assert isinstance(caught.value, ValueError)
        assert caught.value is not orig_exc

    def test_no_exception_passes_quietly(self):
        with setuptools.sandbox.ExceptionSaver() as saved_exc:
            pass

        saved_exc.resume()

    def test_unpickleable_exception(self):
        class CantPickleThis(Exception):
            "This Exception is unpickleable because it's not in globals"
            def __repr__(self):
                return 'CantPickleThis%r' % (self.args,)

        with setuptools.sandbox.ExceptionSaver() as saved_exc:
            raise CantPickleThis('detail')

        with pytest.raises(setuptools.sandbox.UnpickleableException) as caught:
            saved_exc.resume()

        assert str(caught.value) == "CantPickleThis('detail',)"

    def test_unpickleable_exception_when_hiding_setuptools(self):
        """
        As revealed in #440, an infinite recursion can occur if an unpickleable
        exception while setuptools is hidden. Ensure this doesn't happen.
        """

        class ExceptionUnderTest(Exception):
            """
            An unpickleable exception (not in globals).
            """

        with pytest.raises(setuptools.sandbox.UnpickleableException) as caught:
            with setuptools.sandbox.save_modules():
                setuptools.sandbox.hide_setuptools()
                raise ExceptionUnderTest()

        msg, = caught.value.args
        assert msg == 'ExceptionUnderTest()'

    def test_sandbox_violation_raised_hiding_setuptools(self, tmpdir):
        """
        When in a sandbox with setuptools hidden, a SandboxViolation
        should reflect a proper exception and not be wrapped in
        an UnpickleableException.
        """

        def write_file():
            "Trigger a SandboxViolation by writing outside the sandbox"
            with open('/etc/foo', 'w'):
                pass

        with pytest.raises(setuptools.sandbox.SandboxViolation) as caught:
            with setuptools.sandbox.save_modules():
                setuptools.sandbox.hide_setuptools()
                with setuptools.sandbox.DirectorySandbox(str(tmpdir)):
                    write_file()

        cmd, args, kwargs = caught.value.args
        assert cmd == 'open'
        assert args == ('/etc/foo', 'w')
        assert kwargs == {}

        msg = str(caught.value)
        assert 'open' in msg
        assert "('/etc/foo', 'w')" in msg
