.. _contributing:

Contributing to bitmath
#######################

This section describes the guidelines for contributing to bitmath.

.. contents::
   :depth: 3
   :local:


.. _contributing_issue_reporting:

Issue Reporting
***************

If you are encounter an issue with the bitmath library, please use the
provided template.

* `Open a new issue <https://github.com/tbielawa/bitmath/issues/new>`_
* `View open issues <https://github.com/tbielawa/bitmath/issues>`_


Code Style/Formatting
*********************

Please conform to :pep:`0008` for code formatting. This specification
outlines the style that is required for patches.

Your code must follow this (or note why it can't) before patches will
be accepted. There is one consistent exception to this rule:

**E501**
   Line too long

The ``pycodestyle`` tests for bitmath include a ``--ignore`` option to
automatically exclude **E501** errors from the tests.


Commit Messages
***************

Please write `intelligent commit messages
<http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html>`_.

For example::

   Capitalized, short (50 chars or less) summary

   More detailed explanatory text, if necessary.  Wrap it to about 72
   characters or so.  In some contexts, the first line is treated as
   the subject of an email and the rest of the text as the body.  The
   blank line separating the summary from the body is critical (unless
   you omit the body entirely); tools like rebase can get confused if
   you run the two together.

   Write your commit message in the imperative: "Fix bug" and not
   "Fixed bug" or "Fixes bug."  This convention matches up with commit
   messages generated by commands like git merge and git revert.

   Further paragraphs come after blank lines.

   - Bullet points are okay, too

   - Typically a hyphen or asterisk is used for the bullet, followed
     by a single space, with blank lines in between, but conventions
     vary here

   - Use a hanging indent


Pull Requests
*************

After a `pull request <https://github.com/tbielawa/bitmath/pulls>`_ is
submitted on GitHub two automatic processes are started:

#. `Travis-CI <https://travis-ci.org/tbielawa/bitmath>`_ clones the
   new pull request and runs the :ref:`automated test suite
   <contributing_automated_tests>`.
#. `Coveralls <https://coveralls.io/github/tbielawa/bitmath>`_ clones
   the new pull request and determines if the request would increase
   or decrease the overall code test coverage.

Please check back shortly after submitting a pull request to verify
that the Travis-CI process passes.


What Happens If The Build Breaks
================================

Pull requests which break the build will be looked at closely and you
may be asked to fix the tests.

The bitmath project **welcomes all contributors** so **it's OK** if
you're unable to fix the tests yourself. Just leave a comment in the
pull request explaining so if that is the case.

Likewise, if Coveralls indicates the pull request would decrease the
overall test-coverage, and you aren't able to fix it yourself, just
leave a comment in the pull request.


.. _contributing_automated_tests:

Automated Tests
***************

Write `unittests <https://docs.python.org/2/library/unittest.html>`_
for any new functionality, `if you are up to the task`. This is not a
requirement, but it does get you a lot of karma.

All bitmath code includes unit tests to verify expected
functionality. In the rest of this section we'll learn how the unit
tests are put together and how to interact with them.

Components
==========

bitmath unit tests are integrated with/depend on the following items:

* `Travis CI <https://travis-ci.org/>`_ - Free online service
  providing `continuous integration` functionality for open source
  projects. Tests are ran automatically on every git
  commit. Integrates with GitHub to notify you if a pull request
  passes or fails all unitests.

* `Coveralls <https://coveralls.io/github/tbielawa/bitmath>`_ - Free
  online service providing code test coverage reporting. Integrates
  with GitHub to notify you if a pull-request would improve/decrease
  overall code test coverage.

* `unittest <https://docs.python.org/2/library/unittest.html>`_ -
  Python unit testing framework. All bitmath tests are written using
  this framework.

* `nose <https://nose.readthedocs.io/en/latest/>`_ - Per the **nose**
  website: "`extends unittest to make testing easier`". **nose** is
  used to run our unit tests.

* `coverage <http://coverage.readthedocs.io/en/latest/>`_ - A tool for
  measuring code coverage of Python programs. For bitmath we require a
  minimum test coverage of **90%**. This is invoked by **nose**
  automatically.

* `pycodestyle <https://pypi.python.org/pypi/pycodestyle>`_ - A tool to check Python
  code against some of the style conventions in :pep:`0008`.

* `pyflakes <https://pypi.python.org/pypi/pyflakes>`_ - A simple
  program which checks Python source files for errors.

* `virtualenv <https://virtualenv.pypa.io/en/latest/>`_ - A tool to
  create isolated Python environments. Allows us to install additional
  package dependencies without requiring access to the system
  site-packages directory.

* `Makefiles <http://www.gnu.org/software/make/>`_ - Utility scripts
  used for project building and testing. How bitmath uses
  **Makefiles** is described later in this section.


Targets
=======

In the scope of this document, we use the term `target` in the context
of `makefile targets`. For the purpose of this documentation, we can
think of these `targets` as pre-defined commands coded in a
makefile. bitmath testing targets include:

* ``ci`` - Run the tests exactly how they are ran in Travis-CI. The
  ``ci`` target automatically calls the ``pycodestyle``, ``pyflakes``,
  ``uniquetestnames``, and ``unittests`` targets.
* ``ci3`` - Is the same as the ``ci`` target, except it runs using the
  Python 3.x interpreter.
* ``unittests`` - Run the functional test suite.
* ``pycodestyle`` - Run :pep:`0008` syntax checks.
* ``pyflakes`` - Run `pyflakes` error checks.
* ``clean`` - Remove temporary files and build artifacts from the
  checked-out repository.
* ``uniquetestnames`` - Ensures no unit tests have the same name.
* ``tests`` - A quicker version of ``ci``. Different from ``ci`` in
  that ``tests`` uses libraries installed on the local development
  workstation. ``tests`` runs the ``unittests``, ``pycodestyle``,
  ``uniquetestnames``, and ``pyflakes`` tests automatically.

To ensure the highest degree of confidence in test results you should
**always use** the ``ci`` and ``ci3`` targets.

When Travis-CI runs an integration test, it calls the ``ci`` and
``ci3`` targets.

Running the Tests
=================

The bitmath test suite is invoked via the Makefile. The following is
an example of how to run the ``ci`` test target manually:

.. code-block:: console
   :linenos:
   :emphasize-lines: 2

   [~/Projects/bitmath] 17:22:21  (master)
   $ make ci
   #############################################
   # Running Unique TestCase checker
   #############################################
   ./tests/test_unique_testcase_names.sh
   #############################################
   # Creating a virtualenv
   #############################################
   virtualenv bitmathenv
   New python executable in bitmathenv/bin/python
   Installing setuptools, pip...done.
   . bitmathenv/bin/activate && pip install -r requirements.txt
   Downloading/unpacking python-coveralls (from -r requirements.txt (line 1))
     Downloading python_coveralls-2.4.3-py2.py3-none-any.whl
   Downloading/unpacking nose (from -r requirements.txt (line 2))

   ... snip ...

   Convert a bitmath GiB into a Tb ... ok
   Convert a bitmath PiB into a TiB ... ok
   Convert a bitmath GiB into a Tib ... ok
   Convert to kb ... ok
   Convert a bitmath Bit into a MiB ... ok
   bitmath type converted to the same unit is properly converted ... ok
   float(bitmath) returns a float ... ok
   int(bitmath) returns an int ... ok
   long(bitmath) returns a long ... ok

   Name      Stmts   Miss  Cover   Missing
   ---------------------------------------
   bitmath     440      1    99%   1152
   ----------------------------------------------------------------------
   Ran 163 tests in 0.035s

   OK
   :

On line **2** we see how to call a makefile target. In this case it's
quite straightforward: ``make ci``. Other targets are called in the
same way. For example, to run the ``clean`` target, you run the
command ``make clean``. To run the Python 3.x test suite, you would
run the command ``make ci3``.


Troubleshooting
===============

If you find yourself unable to run the unit tests:

#. `Search <https://www.google.com>`_ for relevant error messages

#. **Read** the error message closely. The solution could be hidden in
   the error message output. The problem could be as simple as a
   missing dependency

#. If you are unable to figure out all the necessary dependencies to
   run the tests, file an issue on that specific projects GitHub issue
   tracker. Include the full error message.
