Skip to content

Commit

Permalink
presents general improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
gabrielfalcao committed Jan 4, 2024
1 parent f7d5b45 commit b1e3ee1
Show file tree
Hide file tree
Showing 39 changed files with 845 additions and 329 deletions.
12 changes: 4 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -54,31 +54,27 @@ html-docs: clean-docs
docs: html-docs
$(OPEN_COMMAND) docs/build/html/index.html

test tests: clean | $(VENV)/bin/pytest # $(VENV)/bin/nosetests # @$(VENV)/bin/nosetests --rednose --immediate -vv --with-coverage --cover-package=sure
test tests: clean | $(VENV)/bin/pytest # $(VENV)/bin/sure
@$(VENV)/bin/pytest --cov=sure --ignore tests/crashes tests

# run main command-line tool
# runs main command-line tool
run: | $(MAIN_CLI_PATH)
$(MAIN_CLI_PATH) --reporter=test tests/crashes || true
$(MAIN_CLI_PATH) --special-syntax --with-coverage --cover-branches --cover-module=sure.core --cover-module=sure tests/runner
$(MAIN_CLI_PATH) --special-syntax --with-coverage --cover-branches --cover-module=sure.core --cover-module=sure tests/runner
$(MAIN_CLI_PATH) --special-syntax --with-coverage --cover-branches --cover-module=sure --immediate --cover-module=sure tests

# Pushes release of this package to pypi
push-release: dist # pushes distribution tarballs of the current version
$(VENV)/bin/twine upload dist/*.tar.gz

# Prepares release of this package prior to pushing to pypi
build-release:
$(VENV)/bin/python setup.py build sdist
$(VENV)/bin/twine check dist/*.tar.gz

# Convenience target that runs all tests then builds and pushes a release to pypi
release: tests
@./.release
$(MAKE) build-release
$(MAKE) push-release

# Convenience target to delete the virtualenv
clean:
@rm -rf .coverage

Expand Down Expand Up @@ -123,7 +119,7 @@ $(VENV)/bin/flake8: | $(VENV)/bin/pip

# installs this package in "edit" mode after ensuring its requirements are installed

$(VENV)/bin/nosetests $(VENV)/bin/pytest $(MAIN_CLI_PATH): | $(VENV) $(VENV)/bin/pip $(VENV)/bin/python $(REQUIREMENTS_PATH)
$(VENV)/bin/sure $(VENV)/bin/pytest $(MAIN_CLI_PATH): | $(VENV) $(VENV)/bin/pip $(VENV)/bin/python $(REQUIREMENTS_PATH)
$(VENV)/bin/pip install -r $(REQUIREMENTS_PATH)
$(VENV)/bin/pip install -e .

Expand Down
25 changes: 17 additions & 8 deletions docs/source/api-reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ API Reference

.. automodule:: sure
.. autofunction:: sure.enable_special_syntax
.. autoclass:: sure.VariablesBag
.. autoclass:: sure.StagingArea
.. autoclass:: sure.CallBack
.. autofunction:: sure.that_with_context
.. autofunction:: sure.scenario
.. autofunction:: sure.within
.. autofunction:: sure.word_to_number
.. autofunction:: sure.assertionmethod
Expand All @@ -36,20 +36,29 @@ API Reference
``sure.runner``
---------------

.. py:module:: sure.runner
.. automodule:: sure.runner
.. autoclass:: sure.runner.Runner


``sure.loader``
-----------------
---------------

.. py:module:: sure.loader
.. automodule:: sure.loader
.. autoclass:: sure.loader.loader
.. autofunction:: sure.loader.resolve_path
.. autofunction:: sure.loader.get_package
.. autofunction:: sure.loader.name_appears_to_indicate_test
.. autofunction:: sure.loader.appears_to_be_test_class
.. autofunction:: sure.loader.read_file_from_path


``sure.loader.astutil``
-----------------------

.. automodule:: sure.loader.astutil
.. autofunction:: sure.loader.astutil.is_classdef
.. autofunction:: sure.loader.astutil.resolve_base_names
.. autofunction:: sure.loader.astutil.gather_class_definitions_node
.. autofunction:: sure.loader.astutil.gather_class_definitions_from_module_path


``sure.reporter``
Expand All @@ -69,7 +78,7 @@ API Reference
-----------------

.. automodule:: sure.original
.. autofunction:: sure.original.identify_callable_location
.. autofunction:: sure.original.identify_caller_location
.. autofunction:: sure.original.is_iterable
.. autofunction:: sure.original.all_integers
.. autofunction:: sure.original.explanation
Expand All @@ -80,7 +89,7 @@ API Reference
.. automodule:: sure.doubles
.. autofunction:: sure.doubles.stub
.. autoclass:: sure.doubles.FakeOrderedDict
.. autoattribute:: sure.doubles.anything
.. autoattribute:: sure.doubles.dummies.anything


``sure.doubles.dummies``
Expand Down
7 changes: 5 additions & 2 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
source_suffix = ".rst"
master_doc = "index"
project = "sure"
copyright = "2015-2023, Gabriel Falcão"
copyright = "2010-2024, Gabriel Falcão"
author = "Gabriel Falcão"
version = "3.0dev0"
release = "3.0dev0"
Expand Down Expand Up @@ -63,8 +63,11 @@
epub_publisher = author
epub_copyright = copyright
epub_exclude_files = ["search.html"]
intersphinx_disabled_reftypes = []
intersphinx_mapping = {
"python": ("https://docs.python.org/", None),
"python": ("https://docs.python.org/3/", None),
"mock": ("https://mock.readthedocs.io/en/latest/", None),
"psycopg2": ("https://www.psycopg.org/docs/", None),
"coverage": ("https://coverage.readthedocs.io/en/7.3.3/", None),
}
pygments_style = 'xcode'
1 change: 0 additions & 1 deletion docs/source/definitions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
Definitions
===========


This section defines terms used across :ref:`Sure`'s documentation,
code and run-time error messages and must be interpreted accordingly
as to prevent confusion, misunderstanding and abuse of any manner,
Expand Down
5 changes: 2 additions & 3 deletions docs/source/getting-started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,13 @@ Behavior` is likely to work well.
expect("this".replace("is", "at")).to.equal("that")
:ref:`Special Syntax` Example (cpython-only)
--------------------------------------------
:ref:`Special Syntax` Example
-----------------------------

.. code:: python
"this".replace("is", "at").should.equal("that")
.. note::
The :ref:`Special Syntax` can be enabled via command-line with the
``--special-syntax`` flag or programmatically with the statement
Expand Down
204 changes: 181 additions & 23 deletions docs/source/how-it-works.rst
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
.. _How Sure Works:

How it :ref:`Sure` works
========================
How :ref:`Sure` Works
=====================

As an automated testing library
-------------------------------
Automated Testing Library
-------------------------

.. _Standard Behavior:

Expand Down Expand Up @@ -121,12 +121,115 @@ Special Syntax

The :ref:`sure` module presents the concept of "special syntax"
defined as the optional feature of, during runtime, extending every
:class:`object` with assertion methods with the purpose of enabling
a kind of fluent writing of automated tests.


First, a bit of history
.......................
:class:`object` in Python's runtime with properties that are
themselves instances of :class:`AssertionBuilder` binding the object
in case as its "source" object. That effectively allows performing
assertions directly on values with the purpose of enabling a kind of
fluent writing of automated tests.

The sequence of instructions below demonstrate in practical terms how
enabling the special syntax changes the behavior of Python during runtime (and hopefully bring to light some initial evidence of why this feature could cause unintended consequences if used in production code)

.. doctest::

>>> value = 3.14
>>> [attr for attr in dir(value) if not attr.startswith('__')]
['as_integer_ratio', 'conjugate', 'fromhex', 'hex', 'imag', 'is_integer', 'real']

>>> import sure
>>> sure.enable_special_syntax()
>>> del value
>>> value = 3.14
>>> [attr for attr in dir(value) if not attr.startswith('__')]
['do', 'do_not', 'does', 'does_not', 'doesnt', 'dont', 'must', 'must_not', 'mustnt', 'should', 'should_not', 'shouldnt', 'when']


As can be observed in the examples above, there are two kinds of
properties: positives and negatives


Positive Assertion Properties
.............................

Used for building assertions wherewith the comparison to a
"destination" object resolves to ``True``

The list of properties presently available upon enabling the special
syntax are:

- ``do``
- ``does``
- ``must``
- ``should``
- ``when``

Example:

.. doctest::

>>> import sure
>>> sure.enable_special_syntax()
>>> source = {
... "structured information": [
... "string",
... {
... "first key": 75,
... "second key": 107,
... },
... [0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, {
... "outmost": "list",
... }],
... ]
... }
>>> destination = {
... "structured information": [
... "string",
... {
... "first key": 107,
... "second key": 75,
... },
... [0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, {
... "outmost": "list",
... }],
... ]
... }
>>> source.should.equal(destination)
AssertionError:
X = {'structured information': ['string', [110, 117, 109, 98, 101, 114, {'outmost': 'list'}], {'first key': 75, 'second key': 107}]}
and
Y = {'structured information': ['string', [110, 117, 109, 98, 101, 114, {'outmost': 'list'}], {'first key': 76, 'second key': 107}]}
X['structured information'][1]['first key'] is 75 whereas Y['structured information'][1]['first key'] is 107


Negative Assertion Properties
.............................

Used for building assertions wherewith the comparison to a
"destination" object resolves to ``False``

The list of properties presently available upon enabling the special
syntax are:

- ``do_not``
- ``dont``
- ``does_not``
- ``doesnt``
- ``must_not``
- ``mustnt``
- ``should_not``
- ``shouldnt``

.. doctest::

>>> import sure
>>> sure.enable_special_syntax()
>>>
>>> (42).should_not.equal(42)
AssertionError: expecting 42 to be different of 42


A bit of history
................

From Sure's absolute ideation, its original author - Gabriel Falcão -
had envisioned to somehow expand Python's :class:`object` with
Expand Down Expand Up @@ -180,7 +283,7 @@ and recruited two colleagues, one of whom was Lincoln Clarete which
had been known to Gabriel to know quite a bit about the internals of
the Python language. Then Gabriel not so much as asked whether it was
possible to inject methods into :class:`object` during runtime but
actually challenged Lincoln to do try and do so.
actually challenged Lincoln to try and do so.

As Gabriel imagined, it wouldn't take long for Lincoln Clarete to
achieve that goal, he then presently wrote most if not all the code
Expand All @@ -206,19 +309,74 @@ available to other implementations of Python such as `Jython
the features required by Sure.


Chainability
............
Test Runner
-----------

Some specific assertion methods are chainable, it can be useful for
short assertions like:
Sure provides the command-line tool ``sure`` which takes one or more
test paths as positional arguments, locates ``test*.py`` files in
those paths, then load loads and executes all functions matching the
regular expression ``^(Ensure|Test|Spec|Scenario)[\w_]+$``.

.. code:: python
Example:


.. code:: sh
sure --special-syntax --immediate path/to/tests
The option ``-s`` or ``--special-syntax`` enables the :ref:`Special Syntax`

The option ``-i`` or ``--immediate`` causes the session to fail fast which can
be particularly useful, for example, when testing large codebases or slow tests.


.. code:: sh
sure --special-syntax --immediate path/to/tests
Use the ``--help`` option for a full list of options


Coverage Support
~~~~~~~~~~~~~~~~

Test coverage is supported through the :mod:`coverage` and can be
enabled adwith the option ``--with-coverage``

The options ``--cover-branches`` and ``--cover-module=<module_name>`` further configures the test execution.

Example:


.. code:: sh
sure --with-coverage --cover-branches --cover-module=yourmodulename tests
Further Help
~~~~~~~~~~~~


.. code:: sh
sure --help
.. code:: sh
PERSON = {
"name": "John",
"facebook_info": {
"token": "abcd"
}
}
Usage: sure [OPTIONS] [PATHS]...
PERSON.should.have.key("facebook_info").being.a(dict)
Options:
-c, --with-coverage
-s, --special-syntax
-f, --log-file TEXT path to a log file. Default to SURE_LOG_FILE
-l, --log-level [debug|info|warning|error]
default='info'
-i, --immediate
-r, --reporter [logger|feature|test]
default=feature
--cover-branches
--cover-module TEXT specify module names to cover
--help Show this message and exit.

0 comments on commit b1e3ee1

Please sign in to comment.