#######
Testing
#######

This rst file is for testing the various Sphinx styles and class conversions 
that we'll find in a Sphinx rst file. Ideally we want to run through everything
pretty often.

The first tests
===============

Code
----

Here we're going to test some code blocks.

.. code-block:: python

    import os
    from xml.etree import ElementTree
    
    class AscDescBase(object):  # pylint: disable=R0903
        """Base class for most Asc XML type nodes, allows for infinite desc
    
        Description
        ~~~~~~~~~~~
    
        This class is meant to be inherited by any node type that uses description
        fields.
    
        **Attributes:**
    
            desc : [str]
                Since all Asc nodes which can contain a single description, can
                actually contain an infinite number of descriptions, the desc
                attribute is a list, allowing us to store every single description
                found during parsing.
    
                Setting desc directly will cause the value given to append to the
                end of the list, but desc can also be replaced by passing it a list
                or tuple. Desc can be emptied by passing it None, [] or ().
    
        **Public Methods:**
    
            parse_xml_descs()
                Parses an ElementTree Element for any Description tags and appends
                any text they contain to the ``desc``.
    
        """
        def __init__(self):
            super(AscDescBase, self).__init__()
            self._desc = []
    
        # Properties ==============================================================
    
        @property
        def desc(self):
            """Returns the list of descriptions"""
            return self._desc
    
        @desc.setter
        def desc(self, value):
            """Adds an entry to the descriptions"""
            if value is None:
                self._desc = []
            elif type(value) in [list, tuple]:
                self._desc = list(value)
            else:
                self._desc.append(value)
    
        # Public Methods ==========================================================
    
        def parse_xml_descs(self, xml_element):
            """Parses an ElementTree element to find & add any descriptions
    
            **Args:**
                xml_element : (``xml.etree.ElementTree.Element``)
                    The element to parse for Description elements. Any found
                    will be appended to the end of ``desc``
    
            **Returns:**
                None
    
            **Raises:**
                None
    
            """
            for desc_entry in xml_element.findall('Description'):
                if desc_entry.text:  # Don't attend if text returns none
                    self.desc.append(desc_entry.text)

Wow wasn't that a great code block! How about some console stuff now.

.. code-block:: console

    $ ls
    art		modules		octopress	thorium
    $ cd modules/
    $ ls
    animatedSnap3D	cardToTrack	iconPanel	viewerSync
    $ cd animatedSnap3D/
    $ tree
    .
    ├── LICENSE
    ├── MANIFEST.in
    ├── README.rst
    ├── animatedSnap3D
    │   ├── __init__.py
    │   └── animatedSnap3D.py
    └── setup.py
    
    1 directory, 6 files

Wow that was some more great code.

Line Numbered Code
~~~~~~~~~~~~~~~~~~

Let's try some basic line numbered code.

.. code-block:: python
    :linenos:

    if type(value) is float:
        # Rather than mess about with float -> Decimal conversion,
        # it suits our accuracy needs just fine to go straight to string.
        value = str(value)
    elif type(value) is int:
        # If we're giving an int, we need to add a '.0' behind it.
        value = str(value) + '.0'
    elif type(value) is Decimal:
        return value
    elif type(value) is str:
        if '.' not in value:
            value += '.0'

Marked Code
~~~~~~~~~~~

Now we're mark the code.

.. code-block:: python
    :linenos:
    :emphasize-lines: 3,5

    if type(value) is float:
        # Rather than mess about with float -> Decimal conversion,
        # it suits our accuracy needs just fine to go straight to string.
        value = str(value)
    elif type(value) is int:
        # If we're giving an int, we need to add a '.0' behind it.
        value = str(value) + '.0'
    elif type(value) is Decimal:
        return value
    elif type(value) is str:
        if '.' not in value:
            value += '.0'

Cross Referencing Python Objects
--------------------------------

:py:mod:`cdl_convert`

:py:func:`cdl_convert.main`

:py:data:`cdl_convert.__author__`

:py:const:`cdl_convert.__credits__`

:py:class:`cdl_convert.base.AscDescBase`

:py:meth:`cdl_convert.base.AscDescBase.parse_xml_descs`

:py:attr:`cdl_convert.base.AscDescBase.desc`

:py:exc:`TypeError`

:py:obj:`cdl_convert.banana`

More Tests!
===========

Even more tests now.
    
Paragraph Level Markup
----------------------

My favorite!

.. note::
    This stuff is important.
    
    I'm not kidding, it's critical.

Some great warnings coming up.

.. warning:: 
    Pay head to this warning, it could save your life.
    
    Or it could kill you even.

Versions
~~~~~~~~

.. versionadded:: 6.7.4.3
    The ability to kill people with warnings.
    
    More things `added`:
        - Things
        - More things
        - Even more things.

Holy cow! what a list.

.. versionchanged:: 1.5
    Things got shifted around, and removed.
    
    Removing `things` was important.

.. deprecated:: 6.4
    Hey don't use this `anymore`
    
    Or if you do, don't use it a lot.

Paragraph Level Markup With Code
--------------------------------

My favorite!

.. note::
    This stuff is important.
    
    I'm not kidding, it's critical.

    .. code-block:: python
        :linenos:
        :emphasize-lines: 3,5
    
        if type(value) is float:
            # Rather than mess about with float -> Decimal conversion,
            # it suits our accuracy needs just fine to go straight to string.
            value = str(value)
        elif type(value) is int:
            # If we're giving an int, we need to add a '.0' behind it.
            value = str(value) + '.0'
        elif type(value) is Decimal:
            return value
        elif type(value) is str:
            if '.' not in value:
                value += '.0'

Some great warnings coming up.

.. warning:: 
    Pay head to this warning, it could save your life.

    .. code-block:: python
        :linenos:
        :emphasize-lines: 3,5
    
        if type(value) is float:
            # Rather than mess about with float -> Decimal conversion,
            # it suits our accuracy needs just fine to go straight to string.
            value = str(value)
        elif type(value) is int:
            # If we're giving an int, we need to add a '.0' behind it.
            value = str(value) + '.0'
        elif type(value) is Decimal:
            return value
        elif type(value) is str:
            if '.' not in value:
                value += '.0'

    Or it could kill you even.

Versions with Code
~~~~~~~~~~~~~~~~~~

.. versionadded:: 6.7.4.3
    The ability to kill people with warnings.
    
    More things `added`:
        - Things
        - More things
        - Even more things.

    .. code-block:: python
        :linenos:
        :emphasize-lines: 3,5
    
        if type(value) is float:
            # Rather than mess about with float -> Decimal conversion,
            # it suits our accuracy needs just fine to go straight to string.
            value = str(value)
        elif type(value) is int:
            # If we're giving an int, we need to add a '.0' behind it.
            value = str(value) + '.0'
        elif type(value) is Decimal:
            return value
        elif type(value) is str:
            if '.' not in value:
                value += '.0'

Holy cow! what a list.

.. versionchanged:: 1.5
    Things got shifted around, and removed.
    
    Removing `things` was important.

    .. code-block:: python
        :linenos:
        :emphasize-lines: 3,5
    
        if type(value) is float:
            # Rather than mess about with float -> Decimal conversion,
            # it suits our accuracy needs just fine to go straight to string.
            value = str(value)
        elif type(value) is int:
            # If we're giving an int, we need to add a '.0' behind it.
            value = str(value) + '.0'
        elif type(value) is Decimal:
            return value
        elif type(value) is str:
            if '.' not in value:
                value += '.0'

.. deprecated:: 6.4
    Hey don't use this `anymore`

    .. code-block:: python
        :linenos:
        :emphasize-lines: 3,5
    
        if type(value) is float:
            # Rather than mess about with float -> Decimal conversion,
            # it suits our accuracy needs just fine to go straight to string.
            value = str(value)
        elif type(value) is int:
            # If we're giving an int, we need to add a '.0' behind it.
            value = str(value) + '.0'
        elif type(value) is Decimal:
            return value
        elif type(value) is str:
            if '.' not in value:
                value += '.0'

    Or if you do, don't use it a lot.

Other
-----

.. seealso::

   Module :py:mod:`zipfile`
      Documentation of the :py:mod:`zipfile` standard module.

   `GNU tar manual, Basic Tar Format <http://link>`_
      Documentation for tar archive files, including GNU tar extensions.

Last Tests
==========

AUTODOCS, ENGAGE

Autodoc Stuff
-------------

cdl_convert
~~~~~~~~~~~

.. automodule:: cdl_convert 

Wow what a great module.

ColorCollection
~~~~~~~~~~~~~~~

.. autoclass:: cdl_convert.collection.ColorCollection 

I've seen better.

ValueError
~~~~~~~~~~

.. autoexception:: ValueError 

to_decimal
~~~~~~~~~~

.. autofunction:: cdl_convert.utils.to_decimal 

`__url__`
~~~~~~~~~

.. autodata:: cdl_convert.__url__ 

append_child
~~~~~~~~~~~~

.. automethod:: cdl_convert.collection.ColorCollection.append_child 

xml attribute
~~~~~~~~~~~~~

.. autoattribute:: cdl_convert.collection.ColorCollection.xml 

Changelog
=========

Version 0.7
-----------

The biggest change in 0.7 is the addition of collection format support.
``.ccc``, Color Correction Collections, can now be parsed and written. ``.cdl``,
Color Decision Lists, can now be parsed and written. ``.ale``
and ``.flex`` files now return a collection.

- New script flags:
    - Adds ``--check`` flag to script, which checks all parsed :class:`ColorCorrects` for sane values, and prints warnings to shell
    - Adds ``-d``, ``--destination`` flag to the script, which allows user to specify the output directory converted files will be written to.
    - Adds ``--no-ouput`` flag to the script, which goes through the entire conversion process but doesn't actually write anything to disk. Useful for troubleshooting, especially when combined with ``--check``
    - Adds ``--halt`` flag to the script, which halts on errors that can be resolved safely (such as negative slope or power values)
- Renames :class:`ColorCollectionBase` to :class:`ColorCollection` , since it will be used directly by both ``ccc`` and ``cdl``.
- Adds ``parse_ccc`` which returns a :class:`ColorCollection` .
- Adds ``write_ccc`` which writes a :class:`ColorCollection` as a ``ccc`` file.
- Adds ``parse_cdl`` which returns a :class:`ColorCollection` .
- Adds ``write_cdl`` which returns a :class:`ColorCollection` as a ``cdl`` file.
- :class:`ColorCollection` is now a fully functional container class, with many attributes and methods.
- Added :class:`ColorDecision` , which stores either a :class:`ColorCorrection` or :class:`ColorCorrectionRef` , and an optional :class:`MediaRef`
- Added :class:`ColorCorrectionRef` , which stores a reference to a :class:`ColorCorrection`
- Added ``parent`` attribute to :class:`ColorCorrection` .
- Calling ``sop_node`` or ``sat_node`` on a :class:`ColorCorrection` before attempting to set a SOP or Sat power now works.
- :class:`ColorCorrection` ``cdl_file`` init argument renamed to ``input_file``, which is now optional and able to be set after init.
- ``parse_cc`` and ``parse_rnh_cdl`` now only yield a single :class:`ColorCorrection` , not a single member list.
- Added dev-requirements.txt (contains ``mock``)
- All ``determine_dest`` methods now take a second ``directory`` argument, which determines the output directory.
- Adds ``sanity_check`` function which prints values which might be unusual to stdout.
- ``parse_cdl`` and ``write_cdl`` renamed to ``parse_rnh_cdl`` and ``write_rnh_cdl`` respectively.
- ``member_reset`` methods:
    - :class:`ColorCorrection` now has a ``reset_members`` method, which resets the class level member's dictionary.
    - :class:`MediaRef` also has a ``reset_members`` method, as does :class:`ColorCollection`
    - ``reset_all`` function calls all of the above ``reset_members`` methods at once.
- Renamed ``cdl_file`` argument:
    - ``parse_cc`` ``cdl_file`` arg renamed to ``input_file`` and now accepts a either a raw string or an ``ElementTree`` ``Element`` as ``input_file``.
    - ``parse_rnh_cdl`` ``cdl_file`` arg renamed to ``input_file``.
    - ``parse_ale`` ``edl_file`` arg renamed to ``input_file``.
    - ``parse_flex`` ``edl_file`` arg renamed to ``input_file``.
- Python Structure Refactoring
    - Moved ``HALT_ON_ERROR`` into the ``config`` module, which should now be referenced and set by importing the entire ``config`` module, and referencing or setting ``config.HALT_ON_ERROR``
    - Script functionality remains in ``cdl_convert.cdl_convert``, but everything else has been moved out.
    - :class:`AscColorSpaceBase` , :class:`AscDescBase` , :class:`AscXMLBase` and :class:`ColorNodeBase` now live under ``cdl_convert.base``
    - :class:`ColorCollection` now lives in ``cdl_convert.collection``
    - :class:`ColorCorrection` , :class:`SatNode` and :class:`SopNode` now live under ``cdl_convert.correction``
    - :class:`ColorDecision` , :class:`ColorCorrectionRef` and :class:`MediaRef` now live under ``cdl_convert.decision``
    - All parse functions now live under ``cdl_convert.parse``
    - All write functions now live under ``cdl_convert.write``
    - ``sanity_check`` now live under ``cdl_convert.utils``
    - ``reset_all`` now lives under the main module