-
Notifications
You must be signed in to change notification settings - Fork 34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use pytest, put tests into separate dir #70
Open
alisianoi
wants to merge
19
commits into
bastikr:master
Choose a base branch
from
alisianoi:unit-tests
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
23c8828
Change py36 to py361 due to a pyenv-virtualenv minor bug
9ef27de
Add pytest, pytest-cov and pytest-xdist
5313d14
Change README.md to README.rst, adjust setup.py
ce41fb3
Factor test_boolean.py out into new tests directory
46a60c5
Make `python setup.py test` use pytest
00200ea
Move AdvancedAlgebra into separate mock module
5f50736
Move CustomAlgebra into separate mock module
7f8b037
Remove misleading test_init in SymbolTestCase
39c2c7a
Improve Symbol tests for __eq__ and __ne__
7deb053
Convert SymbolTestCase to pytest TestSymbol
d4717e6
Convert BaseElementTestCase to TestBaseElement, use pytest
0cdbfee
Convert NOTTestCase to TestNOT, use pytest
775d8e4
Add an expansion of OtherTestCase.test_parse as test_parse.py
c27119a
Remove unused maxDiff variable
25ee2d8
Drop specific versions from test-requirements.txt
29e66f0
Improve .cancel() tests as per [1]
d5eee7e
Use parentheses if an expression has 'not' in front
747764a
Make it clear which BaseElement and Symbol calls work
ac88b91
Squash spaces between tildas in .cancel(), reposition TODO comment
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
graft docs | ||
graft tests | ||
graft boolean | ||
|
||
include LICENSE.txt | ||
|
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
========== | ||
boolean.py | ||
========== | ||
|
||
.. image:: https://img.shields.io/travis/bastikr/boolean.py.svg | ||
:target: https://travis-ci.org/bastikr/boolean.py | ||
.. image:: https://img.shields.io/pypi/wheel/boolean.py.svg | ||
:target: https://pypi.python.org/pypi/boolean.py/ | ||
.. image:: https://img.shields.io/pypi/v/boolean.py.svg | ||
:target: https://pypi.python.org/pypi/boolean.py/ | ||
.. image:: https://img.shields.io/pypi/pyversions/boolean.py.svg | ||
:target: https://pypi.python.org/pypi/boolean.py/ | ||
.. image:: https://img.shields.io/badge/license-BSD-blue.svg | ||
:target: https://raw.githubusercontent.com/bastikr/boolean.py/master/LICENSE.txt | ||
|
||
This python package implements `Boolean algebra`_. It defines two base elements, | ||
:code:`TRUE` and :code:`FALSE`, and a :code:`Symbol` class. Expressions are | ||
built in terms of :code:`AND`, :code:`OR` and :code:`NOT`. Other functions, like | ||
:code:`XOR` and :code:`NAND`, are not implemented but can be emulated with | ||
:code:`AND` or and :code:`NOT`. Expressions are constructed from parsed strings | ||
or in Python. | ||
|
||
.. _`Boolean algebra`: https://en.wikipedia.org/wiki/Boolean_algebra | ||
|
||
Example | ||
======= | ||
|
||
.. code-block:: python | ||
|
||
>>> import boolean | ||
>>> algebra = boolean.BooleanAlgebra() | ||
>>> expression1 = algebra.parse(u'apple and (oranges or banana) and not banana', simplify=False) | ||
>>> expression1 | ||
AND(Symbol('apple'), OR(Symbol('oranges'), Symbol('banana')), NOT(Symbol('banana'))) | ||
|
||
>>> expression2 = algebra.parse(u'(oranges | banana) and not banana & apple', simplify=True) | ||
>>> expression2 | ||
AND(Symbol('apple'), NOT(Symbol('banana')), Symbol('oranges')) | ||
|
||
>>> expression1 == expression2 | ||
False | ||
>>> expression1.simplify() == expression2 | ||
True | ||
|
||
Documentation | ||
============= | ||
|
||
http://readthedocs.org/docs/booleanpy/en/latest/ | ||
|
||
Installation | ||
============ | ||
|
||
.. code-block:: shell | ||
|
||
pip install boolean.py | ||
|
||
Testing | ||
======= | ||
|
||
Test :code:`boolean.py` with your current Python environment: | ||
|
||
.. code-block:: shell | ||
|
||
python setup.py test | ||
|
||
Test with all of the supported Python environments using :code:`tox`: | ||
|
||
.. code-block:: shell | ||
|
||
pip install -r test-requirements.txt | ||
tox | ||
|
||
If :code:`tox` throws :code:`InterpreterNotFound`, limit it to python | ||
interpreters that are actually installed on your machine: | ||
|
||
.. code-block:: shell | ||
|
||
tox -e py27,py36 | ||
|
||
License | ||
======= | ||
|
||
Simplified BSD License |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,40 +5,23 @@ | |
from setuptools import find_packages | ||
from setuptools import setup | ||
|
||
|
||
long_desc = ''' | ||
This library helps you deal with boolean expressions and algebra with variables | ||
and the boolean functions AND, OR, NOT. | ||
|
||
You can parse expressions from strings and simplify and compare expressions. | ||
You can also easily create your custom algreba and mini DSL and create custom | ||
tokenizers to handle custom expressions. | ||
|
||
For extensive documentation look either into the docs directory or view it online, at | ||
https://booleanpy.readthedocs.org/en/latest/ | ||
|
||
https://github.com/bastikr/boolean.py | ||
|
||
Copyright (c) 2009-2017 Sebastian Kraemer, [email protected] and others | ||
|
||
Released under revised BSD license. | ||
''' | ||
|
||
with open('README.rst') as readme: | ||
long_description = readme.read() | ||
|
||
setup( | ||
name='boolean.py', | ||
version='3.4', | ||
license='revised BSD license', | ||
license='Simplified BSD license', | ||
description='Define boolean algebras, create and parse boolean expressions and create custom boolean DSL.', | ||
long_description=long_desc, | ||
long_description=long_description, | ||
author='Sebastian Kraemer', | ||
author_email='[email protected]', | ||
url='https://github.com/bastikr/boolean.py', | ||
packages=find_packages(), | ||
include_package_data=True, | ||
zip_safe=False, | ||
test_loader='unittest:TestLoader', | ||
test_suite='boolean.test_boolean', | ||
setup_requires=['pytest-runner'], | ||
tests_require=['pytest'], | ||
keywords='boolean expression, boolean algebra, logic, expression parser', | ||
classifiers=[ | ||
'Development Status :: 4 - Beta', | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,4 @@ | ||
tox==2.7.0 | ||
tox | ||
pytest | ||
pytest-cov | ||
pytest-xdist |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
import tokenize | ||
|
||
try: | ||
# Python 2 | ||
basestring | ||
except NameError: | ||
# Python 3 | ||
basestring = str | ||
|
||
try: | ||
from io import StringIO | ||
except ImportError: | ||
try: | ||
from cStringIO import StringIO | ||
except ImportError: | ||
from StringIO import StringIO | ||
|
||
from boolean import BooleanAlgebra, Symbol | ||
from boolean import TOKEN_LPAR, TOKEN_RPAR | ||
from boolean import TOKEN_TRUE, TOKEN_FALSE | ||
from boolean import TOKEN_AND, TOKEN_OR, TOKEN_NOT | ||
|
||
class PlainVar(Symbol): | ||
"Plain boolean variable" | ||
|
||
class ColonDotVar(Symbol): | ||
"Colon and dot-separated string boolean variable" | ||
|
||
class AdvancedAlgebra(BooleanAlgebra): | ||
def tokenize(self, expr): | ||
""" | ||
Example custom tokenizer derived from the standard Python tokenizer | ||
with a few extra features: #-style comments are supported and a | ||
colon- and dot-separated string is recognized and stored in custom | ||
symbols. In contrast with the standard tokenizer, only these | ||
boolean operators are recognized : & | ! and or not. | ||
|
||
For more advanced tokenization you could also consider forking the | ||
`tokenize` standard library module. | ||
""" | ||
|
||
if not isinstance(expr, basestring): | ||
raise TypeError('expr must be string but it is %s.' % type(expr)) | ||
|
||
# mapping of lowercase token strings to a token object instance for | ||
# standard operators, parens and common true or false symbols | ||
TOKENS = { | ||
'&': TOKEN_AND, | ||
'and': TOKEN_AND, | ||
'|': TOKEN_OR, | ||
'or': TOKEN_OR, | ||
'!': TOKEN_NOT, | ||
'not': TOKEN_NOT, | ||
'(': TOKEN_LPAR, | ||
')': TOKEN_RPAR, | ||
'true': TOKEN_TRUE, | ||
'1': TOKEN_TRUE, | ||
'false': TOKEN_FALSE, | ||
'0': TOKEN_FALSE, | ||
'none': TOKEN_FALSE, | ||
} | ||
|
||
ignored_token_types = ( | ||
tokenize.NL, tokenize.NEWLINE, tokenize.COMMENT, | ||
tokenize.INDENT, tokenize.DEDENT, | ||
tokenize.ENDMARKER | ||
) | ||
|
||
# note: an unbalanced expression may raise a TokenError here. | ||
tokens = ((toktype, tok, row, col,) for toktype, tok, (row, col,), _, _ | ||
in tokenize.generate_tokens(StringIO(expr).readline) | ||
if tok and tok.strip()) | ||
|
||
COLON_DOT = (':', '.',) | ||
|
||
def build_symbol(current_dotted): | ||
if current_dotted: | ||
if any(s in current_dotted for s in COLON_DOT): | ||
sym = ColonDotVar(current_dotted) | ||
else: | ||
sym = PlainVar(current_dotted) | ||
return sym | ||
|
||
# accumulator for dotted symbols that span several `tokenize` tokens | ||
dotted, srow, scol = '', None, None | ||
|
||
for toktype, tok, row, col in tokens: | ||
if toktype in ignored_token_types: | ||
# we reached a break point and should yield the current dotted | ||
symbol = build_symbol(dotted) | ||
if symbol is not None: | ||
yield symbol, dotted, (srow, scol) | ||
dotted, srow, scol = '', None, None | ||
|
||
continue | ||
|
||
std_token = TOKENS.get(tok.lower()) | ||
if std_token is not None: | ||
# we reached a break point and should yield the current dotted | ||
symbol = build_symbol(dotted) | ||
if symbol is not None: | ||
yield symbol, dotted, (srow, scol) | ||
dotted, srow, scol = '', 0, 0 | ||
|
||
yield std_token, tok, (row, col) | ||
|
||
continue | ||
|
||
if toktype == tokenize.NAME or (toktype == tokenize.OP and tok in COLON_DOT): | ||
if not dotted: | ||
srow = row | ||
scol = col | ||
dotted += tok | ||
|
||
else: | ||
raise TypeError('Unknown token: %(tok)r at line: %(row)r, column: %(col)r' % locals()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
from boolean import BooleanAlgebra, Symbol | ||
|
||
from boolean import TOKEN_SYMBOL | ||
from boolean import TOKEN_LPAR, TOKEN_RPAR | ||
from boolean import TOKEN_AND, TOKEN_OR, TOKEN_NOT | ||
|
||
class CustomSymbol(Symbol): | ||
pass | ||
|
||
class CustomAlgebra(BooleanAlgebra): | ||
def __init__(self, Symbol_class=CustomSymbol): | ||
super(CustomAlgebra, self).__init__(Symbol_class=CustomSymbol) | ||
|
||
def tokenize(self, s): | ||
"Sample tokenizer using custom operators and symbols" | ||
ops = { | ||
'WHY_NOT': TOKEN_OR, | ||
'ALSO': TOKEN_AND, | ||
'NEITHER': TOKEN_NOT, | ||
'(': TOKEN_LPAR, | ||
')': TOKEN_RPAR, | ||
} | ||
|
||
for row, line in enumerate(s.splitlines(False)): | ||
for col, tok in enumerate(line.split()): | ||
if tok in ops: | ||
yield ops[tok], tok, (row, col) | ||
elif tok == 'Custom': | ||
yield self.Symbol(tok), tok, (row, col) | ||
else: | ||
yield TOKEN_SYMBOL, tok, (row, col) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The previous test suite could run equally well with or without pytest. Any special reason to make py.test a hard requirement for tests?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to force everybody to use the same thing. The more options you have, the more (compatibility?) things you have to keep in mind. With just one thing there is only one way:
pip install -r requirements.txt; pytest
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(I know this is a very old PR, but...)
The use of
@pytest
decorators makes pytest a hard requirement, full stop. (And I agree with @alisianoi: it's better not to support multiple test frameworks, which lead to everyone executing the tests in subtly different ways. Do that, you've stopped testing your code; now you're compatibility-testing the frameworks instead.)pytest-runner
is deprecated. (As are any use oftest_runner
,test_suite
,tests_require
, etc. insetup.py
.setup.py
as a whole is deprecated, of course, but its test args are "super double deprecated".) These days,tox
would be a better choice as test runner.