🗃 tdir - create and fill a temporary directory 🗃
======================================================

Creates a temporary directory using tempfile.TemporaryDirectory and then
fills it with files.  Great for tests!

``tdir()`` is a context manager and decorator that runs functions or test
suites in a temporary directory filled with files.

``fill()`` recursively fills a directory (temporary or not).

EXAMPLE: as a context manager

.. code-block:: python

    import tdir

    with tdir('hello'):
        # Run in a tempdir
        assert Path('hello').read_text() = 'hello\n'
        Path('junk.txt').write_text('hello, world\n')

    # The directory and the files are gone

    # A more complex example:
    with tdir(
        'one.txt',
        three='some information',
        four=Path('existing/file'),  # Copy a file into the tempdir
        sub1={
            'file.txt': 'blank lines\n\n\n\n',
            'sub2': [
                'a', 'b', 'c'
            ]
        },
    ):
        assert Path('one.txt').exists()
        assert Path('four').read_text() == Path('/existing/file').read_text()
        assert Path('sub1/sub2/a').exists()

    # All files gone!

EXAMPLE: as a decorator

.. code-block:: python

    from pathlib import Path
    import unittest

    @tdir
    def my_function():
        pass  # my_function() always operates in a temporary directory


    # Decorate a TestCase so each test runs in a new temporary directory
    @tdir('a', foo='bar')
    class MyTest(unittest.TestCast):
        def test_something(self):
            assert Path('a').read_text() = 'a\n'

        def test_something_else(self):
            assert Path('foo').read_text() = 'bar\n'


    # Decorate single test in a unitttest
    class MyTest2(unittest.TestCast):
        @tdir(foo='bar', baz=bytes(range(4)))  # binary files are possible
        def test_something(self):
            assert Path('foo').read_text() = 'bar\n'
            assert Path('baz').read_bytes() = bytes(range(4)))

        # Run in an empty temporary directory
        @tdir
        def test_something_else(self):
            assert not Path('a').exists()
            assert Path().absolute() != self.ORIGINAL_PATH

        ORIGINAL_PATH = Path().absolute()

API
---

Class ``tdir``
~~~~~~~~~~~~~~~~~

(`tdir.py, 95-163 <https://github.com/rec/tdir/blob/master/tdir.py#L95-L163>`_)

Set up a temporary directory, fill it with files, then tear it down at
the end of an operation.

``tdir`` can be used either as a context manager, or a decorator that
works on functions or classes.

ARGUMENTS
  args, kwargs:
    Files to put into the temporary directory.
    See the documentation for ``tdir.fill()``

  chdir:
    If True (the default), change the working directory to the tdir at
    the start of the operation and restore the original working directory
    at the end.

  methods:
    How to decorate classes.  The default only decorates class methods that
    start with the string ``test`` just like e.g. ``unittest.mock.patch``
    does.  See https://github.com/rec/dek/blob/master/README.rst#dekdekdecorator-deferfalse-methodsnone

``tdir.fill(root, *args, **kwargs)``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

(`tdir.py, 165-227 <https://github.com/rec/tdir/blob/master/tdir.py#L165-L227>`_)

Recursively fills a directory.

ARGUMENTS
  root:
    The root directory to fill

  args:
    A list of strings, dictionaries or Paths.

    For strings, a file is created with that string as name and contents.

    For dictionaries, the contents are used to recursively create and fill
    the directory.

    For Paths, the file is copied into the target directory

  kwargs:
    A dictionary mapping file or directory names to values.

    If the key's value is a string it is used to file a file of that name.

    If it's a dictionary, its contents are used to recursively create and
    fill a subdirectory.

    If it's a Path, that file is copied to the target directory.

(automatically generated by `doks <https://github.com/rec/doks/>`_ on 2020-07-21T20:00:25.006413)
