Skip to content

Commit 117f3a9

Browse files
committed
Refactor testing module to allow finer control over generating truthy/falsy values.
1 parent 481c796 commit 117f3a9

File tree

4 files changed

+159
-43
lines changed

4 files changed

+159
-43
lines changed

doc-source/conf.py

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -34,25 +34,25 @@
3434
package_root = "domdf_python_tools"
3535

3636
extensions = [
37-
'sphinx.ext.intersphinx',
38-
'sphinx.ext.autodoc',
39-
'sphinx.ext.mathjax',
40-
'sphinx.ext.viewcode',
41-
'sphinxcontrib.httpdomain',
42-
"sphinxcontrib.extras_require",
43-
"sphinx.ext.todo",
44-
"sphinxemoji.sphinxemoji",
45-
"notfound.extension",
46-
"sphinx_tabs.tabs",
47-
"sphinx-prompt",
48-
"sphinx_autodoc_typehints",
49-
"sphinx.ext.autosummary",
50-
"autodocsumm",
51-
"sphinx_copybutton",
52-
"sphinxcontrib.default_values",
53-
"sphinxcontrib.toctree_plus",
54-
# "sphinx_gitstamp",
55-
]
37+
'sphinx.ext.intersphinx',
38+
'sphinx.ext.autodoc',
39+
'sphinx.ext.mathjax',
40+
'sphinx.ext.viewcode',
41+
'sphinxcontrib.httpdomain',
42+
'sphinxcontrib.extras_require',
43+
'sphinx.ext.todo',
44+
'sphinxemoji.sphinxemoji',
45+
'notfound.extension',
46+
'sphinx_tabs.tabs',
47+
'sphinx-prompt',
48+
'sphinx.ext.autosummary',
49+
'autodocsumm',
50+
'sphinx_copybutton',
51+
'sphinxcontrib.default_values',
52+
'sphinxcontrib.toctree_plus',
53+
'seed_intersphinx_mapping',
54+
'sphinx_autodoc_typehints',
55+
]
5656

5757
sphinxemoji_style = 'twemoji'
5858
todo_include_todos = bool(os.environ.get("SHOW_TODOS", 0))
@@ -68,18 +68,11 @@
6868
pygments_style = 'default'
6969

7070
intersphinx_mapping = {
71-
'rtd': ('https://docs.readthedocs.io/en/latest/', None),
72-
'sphinx': ('https://www.sphinx-doc.org/en/stable/', None),
7371
'python': ('https://docs.python.org/3/', None),
74-
"NumPy": ('https://numpy.org/doc/stable/', None),
75-
"SciPy": ('https://docs.scipy.org/doc/scipy/reference', None),
76-
"Pandas": ('https://pandas.pydata.org/docs/', None),
77-
"matplotlib": ('https://matplotlib.org', None),
72+
'sphinx': ('https://www.sphinx-doc.org/en/stable/', None),
73+
'rtd': ('https://docs.readthedocs.io/en/latest/', None),
7874
"h5py": ('https://docs.h5py.org/en/latest/', None),
79-
"Sphinx": ('https://www.sphinx-doc.org/en/master/', None),
80-
"Django": ('https://docs.djangoproject.com/en/dev/', 'https://docs.djangoproject.com/en/dev/_objects/'),
8175
"sarge": ('https://sarge.readthedocs.io/en/latest/', None),
82-
"attrs": ('https://www.attrs.org/en/stable/', None),
8376
}
8477

8578
html_theme = 'domdf_sphinx_theme'
@@ -118,6 +111,12 @@
118111
"__parameters__",
119112
"__subclasshook__",
120113
"__init_subclass__",
114+
"__attrs_attrs__",
115+
"__init__",
116+
"__new__",
117+
"__getnewargs__",
118+
"__abstractmethods__",
119+
"__hash__",
121120
])
122121
}
123122

doc-source/requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
autodocsumm
2-
default_values>=0.0.6
2+
default_values>=0.0.7
33
domdf_sphinx_theme>=0.0.11
44
extras_require
55
pytz>=2019.1
6+
seed_intersphinx_mapping
67
sphinx>=3.0.3
78
sphinx-copybutton>=0.2.12
89
sphinx-notfound-page

domdf_python_tools/testing.py

Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
import itertools
3030
import random
3131
from functools import lru_cache
32-
from typing import List, Sequence
32+
from typing import Any, Iterator, List, Sequence
3333

3434
# 3rd party
3535
import pytest
@@ -39,22 +39,17 @@
3939
from domdf_python_tools.utils import Len
4040

4141

42-
def testing_boolean_values(
43-
extra_truthy: Sequence = (),
44-
extra_falsy: Sequence = (),
45-
) -> MarkDecorator:
42+
def generate_truthy_values(extra_truthy: Sequence = (), ratio: float = 1) -> Iterator[Any]:
4643
"""
47-
Returns a `pytest.mark.parametrize <https://docs.pytest.org/en/stable/parametrize.html>`_
48-
decorator that provides a list of strings, integers and booleans, and the boolean representations of them.
44+
Returns an iterator of strings, integers and booleans that should be considered :py:obj:`True`.
4945
50-
The parametrized arguments are ``boolean_string`` for the input value,
51-
and ``expected_boolean`` for the expected output.
46+
Optionally, a random selection of the values can be returned, using the ``ratio`` argument.
5247
5348
:param extra_truthy: Additional values that should be considered :py:obj:`True`.
54-
:param extra_falsy: Additional values that should be considered :py:obj:`False`.
49+
:param ratio: The ratio of the number of values to select to the total number of values.
5550
"""
5651

57-
truthy = [
52+
truthy_values = [
5853
True,
5954
"True",
6055
"true",
@@ -72,7 +67,23 @@ def testing_boolean_values(
7267
*extra_truthy,
7368
]
7469

75-
falsy = [
70+
if ratio < 1:
71+
truthy_values = random.sample(truthy_values, int(len(truthy_values) * ratio))
72+
73+
yield from truthy_values
74+
75+
76+
def generate_falsy_values(extra_falsy: Sequence = (), ratio: float = 1) -> Iterator[Any]:
77+
"""
78+
Returns an iterator of strings, integers and booleans that should be considered :py:obj:`False`.
79+
80+
Optionally, a random selection of the values can be returned, using the ``ratio`` argument.
81+
82+
:param extra_falsy: Additional values that should be considered :py:obj:`True`.
83+
:param ratio: The ratio of the number of values to select to the total number of values.
84+
"""
85+
86+
falsy_values = [
7687
False,
7788
"False",
7889
"false",
@@ -90,6 +101,34 @@ def testing_boolean_values(
90101
*extra_falsy,
91102
]
92103

104+
if ratio < 1:
105+
falsy_values = random.sample(falsy_values, int(len(falsy_values) * ratio))
106+
107+
yield from falsy_values
108+
109+
110+
def testing_boolean_values(
111+
extra_truthy: Sequence = (),
112+
extra_falsy: Sequence = (),
113+
ratio: float = 1,
114+
) -> MarkDecorator:
115+
"""
116+
Returns a `pytest.mark.parametrize <https://docs.pytest.org/en/stable/parametrize.html>`_
117+
decorator that provides a list of strings, integers and booleans, and the boolean representations of them.
118+
119+
The parametrized arguments are ``boolean_string`` for the input value,
120+
and ``expected_boolean`` for the expected output.
121+
122+
Optionally, a random selection of the values can be returned, using the ``ratio`` argument.
123+
124+
:param extra_truthy: Additional values that should be considered :py:obj:`True`.
125+
:param extra_falsy: Additional values that should be considered :py:obj:`False`.
126+
:param ratio: The ratio of the number of values to select to the total number of values.
127+
"""
128+
129+
truthy = generate_truthy_values(extra_truthy, ratio)
130+
falsy = generate_falsy_values(extra_falsy, ratio)
131+
93132
boolean_strings = [
94133
*itertools.zip_longest(truthy, [], fillvalue=True),
95134
*itertools.zip_longest(falsy, [], fillvalue=False),

tests/test_testing.py

Lines changed: 79 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
# stdlib
22
import random
3+
import re
34

45
# 3rd party
56
from _pytest.mark import Mark, MarkDecorator
67

78
# this package
8-
from domdf_python_tools.testing import count, testing_boolean_values, whitespace_perms
9+
from domdf_python_tools.testing import (
10+
count,
11+
generate_falsy_values,
12+
generate_truthy_values,
13+
testing_boolean_values,
14+
whitespace_perms,
15+
)
916
from domdf_python_tools.utils import strtobool
1017

1118

@@ -36,7 +43,9 @@ def test_whitespace_perms():
3643
assert isinstance(whitespace_perms(.1).mark.args[1][0], str)
3744

3845
assert whitespace_perms(.1).mark.args[1] == ['\n\t\r', '\r\t', '\t \n', '\n\r']
39-
# TODO: some test that they're all whitespace
46+
47+
for string in whitespace_perms().mark.args[1]:
48+
assert re.match(r"^\s*$", string)
4049

4150

4251
def test_testing_boolean_strings():
@@ -53,3 +62,71 @@ def test_testing_boolean_strings():
5362

5463
for value, expects in testing_boolean_values().mark.args[1]:
5564
assert strtobool(value) is expects
65+
66+
67+
def test_generate_truthy():
68+
random.seed(1234)
69+
70+
assert list(generate_truthy_values()) == [
71+
True,
72+
"True",
73+
"true",
74+
"tRUe",
75+
'y',
76+
'Y',
77+
"YES",
78+
"yes",
79+
"Yes",
80+
"yEs",
81+
"ON",
82+
"on",
83+
'1',
84+
1,
85+
]
86+
87+
assert list(generate_truthy_values(["bar"])) == [
88+
True,
89+
"True",
90+
"true",
91+
"tRUe",
92+
'y',
93+
'Y',
94+
"YES",
95+
"yes",
96+
"Yes",
97+
"yEs",
98+
"ON",
99+
"on",
100+
'1',
101+
1,
102+
"bar",
103+
]
104+
105+
assert list(generate_truthy_values(ratio=.3)) == ['1', 'yes', 'True', True]
106+
107+
108+
def test_generate_falsy():
109+
random.seed(1234)
110+
111+
assert list(generate_falsy_values()) == [
112+
False,
113+
"False",
114+
"false",
115+
"falSE",
116+
'n',
117+
'N',
118+
"NO",
119+
"no",
120+
"nO",
121+
"OFF",
122+
"off",
123+
"oFF",
124+
'0',
125+
0,
126+
]
127+
128+
assert list(generate_falsy_values(["bar"])) == [
129+
False, "False", "false", "falSE", 'n', 'N', "NO", "no", "nO", "OFF", "off", "oFF", '0', 0, "bar"
130+
]
131+
132+
assert list(generate_falsy_values(ratio=.3)) == ['0', 'no', 'False', False]

0 commit comments

Comments
 (0)