punit 1.4.8__tar.gz → 1.5.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {punit-1.4.8/src/pUnit.egg-info → punit-1.5.2}/PKG-INFO +2 -2
- {punit-1.4.8 → punit-1.5.2}/README.md +1 -1
- {punit-1.4.8 → punit-1.5.2}/pyproject.toml +1 -1
- {punit-1.4.8 → punit-1.5.2/src/pUnit.egg-info}/PKG-INFO +2 -2
- {punit-1.4.8 → punit-1.5.2}/src/pUnit.egg-info/SOURCES.txt +1 -0
- punit-1.5.2/src/punit/__init__.py +26 -0
- {punit-1.4.8 → punit-1.5.2}/src/punit/__main__.py +8 -4
- {punit-1.4.8 → punit-1.5.2}/src/punit/assertions/__init__.py +2 -1
- {punit-1.4.8 → punit-1.5.2}/src/punit/assertions/collections.py +44 -21
- {punit-1.4.8 → punit-1.5.2}/src/punit/assertions/exceptions.py +7 -7
- punit-1.5.2/src/punit/assertions/numeric.py +651 -0
- punit-1.5.2/src/punit/assertions/strings.py +98 -0
- {punit-1.4.8 → punit-1.5.2}/src/punit/cli.py +36 -38
- punit-1.4.8/src/punit/__init__.py +0 -23
- punit-1.4.8/src/punit/assertions/strings.py +0 -55
- {punit-1.4.8 → punit-1.5.2}/LICENSE +0 -0
- {punit-1.4.8 → punit-1.5.2}/setup.cfg +0 -0
- {punit-1.4.8 → punit-1.5.2}/src/pUnit.egg-info/dependency_links.txt +0 -0
- {punit-1.4.8 → punit-1.5.2}/src/pUnit.egg-info/entry_points.txt +0 -0
- {punit-1.4.8 → punit-1.5.2}/src/pUnit.egg-info/requires.txt +0 -0
- {punit-1.4.8 → punit-1.5.2}/src/pUnit.egg-info/top_level.txt +0 -0
- {punit-1.4.8 → punit-1.5.2}/src/punit/TestResult.py +0 -0
- {punit-1.4.8 → punit-1.5.2}/src/punit/discovery/TestModuleDiscovery.py +0 -0
- {punit-1.4.8 → punit-1.5.2}/src/punit/discovery/__init__.py +0 -0
- {punit-1.4.8 → punit-1.5.2}/src/punit/facts/Fact.py +0 -0
- {punit-1.4.8 → punit-1.5.2}/src/punit/facts/FactManager.py +0 -0
- {punit-1.4.8 → punit-1.5.2}/src/punit/facts/__init__.py +0 -0
- {punit-1.4.8 → punit-1.5.2}/src/punit/filters/Filter.py +0 -0
- {punit-1.4.8 → punit-1.5.2}/src/punit/filters/FilterManager.py +0 -0
- {punit-1.4.8 → punit-1.5.2}/src/punit/filters/__init__.py +0 -0
- {punit-1.4.8 → punit-1.5.2}/src/punit/metadata/CallableMetadata.py +0 -0
- {punit-1.4.8 → punit-1.5.2}/src/punit/metadata/__init__.py +0 -0
- {punit-1.4.8 → punit-1.5.2}/src/punit/py.typed +0 -0
- {punit-1.4.8 → punit-1.5.2}/src/punit/reports/HtmlReportGenerator.py +0 -0
- {punit-1.4.8 → punit-1.5.2}/src/punit/reports/JUnitReportGenerator.py +0 -0
- {punit-1.4.8 → punit-1.5.2}/src/punit/reports/JsonReportGenerator.py +0 -0
- {punit-1.4.8 → punit-1.5.2}/src/punit/reports/__init__.py +0 -0
- {punit-1.4.8 → punit-1.5.2}/src/punit/runner.py +0 -0
- {punit-1.4.8 → punit-1.5.2}/src/punit/theories/Theory.py +0 -0
- {punit-1.4.8 → punit-1.5.2}/src/punit/theories/TheoryManager.py +0 -0
- {punit-1.4.8 → punit-1.5.2}/src/punit/theories/__init__.py +0 -0
- {punit-1.4.8 → punit-1.5.2}/src/punit/traits/Trait.py +0 -0
- {punit-1.4.8 → punit-1.5.2}/src/punit/traits/TraitManager.py +0 -0
- {punit-1.4.8 → punit-1.5.2}/src/punit/traits/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pUnit
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.5.2
|
|
4
4
|
Summary: A modernized unit-test framework for Python.
|
|
5
5
|
Author-email: Shaun Wilson <mrshaunwilson@msn.com>
|
|
6
6
|
License: MIT License
|
|
@@ -114,7 +114,7 @@ Options:
|
|
|
114
114
|
Default: '*.py'
|
|
115
115
|
-e, --exclude PATTERN
|
|
116
116
|
Exclude test files matching PATTERN, overriding --include
|
|
117
|
-
Default: '__*__' (
|
|
117
|
+
Default: '__*__' (dunders)
|
|
118
118
|
-f, --filter PATTERN|@FILEPATH
|
|
119
119
|
Only execute tests matching PATTERN
|
|
120
120
|
Default: '*'
|
|
@@ -70,7 +70,7 @@ Options:
|
|
|
70
70
|
Default: '*.py'
|
|
71
71
|
-e, --exclude PATTERN
|
|
72
72
|
Exclude test files matching PATTERN, overriding --include
|
|
73
|
-
Default: '__*__' (
|
|
73
|
+
Default: '__*__' (dunders)
|
|
74
74
|
-f, --filter PATTERN|@FILEPATH
|
|
75
75
|
Only execute tests matching PATTERN
|
|
76
76
|
Default: '*'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pUnit
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.5.2
|
|
4
4
|
Summary: A modernized unit-test framework for Python.
|
|
5
5
|
Author-email: Shaun Wilson <mrshaunwilson@msn.com>
|
|
6
6
|
License: MIT License
|
|
@@ -114,7 +114,7 @@ Options:
|
|
|
114
114
|
Default: '*.py'
|
|
115
115
|
-e, --exclude PATTERN
|
|
116
116
|
Exclude test files matching PATTERN, overriding --include
|
|
117
|
-
Default: '__*__' (
|
|
117
|
+
Default: '__*__' (dunders)
|
|
118
118
|
-f, --filter PATTERN|@FILEPATH
|
|
119
119
|
Only execute tests matching PATTERN
|
|
120
120
|
Default: '*'
|
|
@@ -16,6 +16,7 @@ src/punit/runner.py
|
|
|
16
16
|
src/punit/assertions/__init__.py
|
|
17
17
|
src/punit/assertions/collections.py
|
|
18
18
|
src/punit/assertions/exceptions.py
|
|
19
|
+
src/punit/assertions/numeric.py
|
|
19
20
|
src/punit/assertions/strings.py
|
|
20
21
|
src/punit/discovery/TestModuleDiscovery.py
|
|
21
22
|
src/punit/discovery/__init__.py
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: © 2024 Shaun Wilson
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
|
|
4
|
+
from .assertions import collections, exceptions, numeric, strings
|
|
5
|
+
from .facts import fact
|
|
6
|
+
from .theories import theory, inlinedata
|
|
7
|
+
from .traits import trait
|
|
8
|
+
|
|
9
|
+
from .assertions.exceptions import raises
|
|
10
|
+
from .assertions.numeric import approx
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
__version__ = '1.5.2'
|
|
14
|
+
__commit__ = '19ca1ae'
|
|
15
|
+
__all__ = [
|
|
16
|
+
'__version__', '__commit__',
|
|
17
|
+
'assertions',
|
|
18
|
+
'collections',
|
|
19
|
+
'exceptions', 'raises',
|
|
20
|
+
'numeric', 'approx',
|
|
21
|
+
'strings',
|
|
22
|
+
'fact',
|
|
23
|
+
'metadata',
|
|
24
|
+
'theory', 'inlinedata',
|
|
25
|
+
'trait'
|
|
26
|
+
]
|
|
@@ -5,6 +5,8 @@ import asyncio
|
|
|
5
5
|
import os
|
|
6
6
|
import sys
|
|
7
7
|
import time
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
8
10
|
from .cli import CommandLineInterface
|
|
9
11
|
from .discovery import TestModuleDiscovery
|
|
10
12
|
from .reports import HtmlReportGenerator, JUnitReportGenerator, JsonReportGenerator
|
|
@@ -22,10 +24,12 @@ async def async_main() -> None:
|
|
|
22
24
|
cli.printVersion()
|
|
23
25
|
os.chdir(cli.workdir)
|
|
24
26
|
if cli.no_pathfix is not True:
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
if
|
|
28
|
-
sys.path.append(
|
|
27
|
+
pathbase = str(Path.cwd())
|
|
28
|
+
srcbase = os.path.join(pathbase, 'src')
|
|
29
|
+
if os.path.exists(srcbase) and srcbase not in sys.path:
|
|
30
|
+
sys.path.append(srcbase)
|
|
31
|
+
if pathbase not in sys.path:
|
|
32
|
+
sys.path.append(pathbase)
|
|
29
33
|
testModuleDiscovery = TestModuleDiscovery(
|
|
30
34
|
os.path.join(cli.workdir, cli.testPackageName),
|
|
31
35
|
cli.includePatterns,
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
# SPDX-FileCopyrightText: © 2024 Shaun Wilson
|
|
2
2
|
# SPDX-License-Identifier: MIT
|
|
3
3
|
|
|
4
|
-
from . import collections, exceptions, strings
|
|
4
|
+
from . import collections, exceptions, numeric, strings
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
__all__ = [
|
|
8
8
|
'collections',
|
|
9
9
|
'exceptions',
|
|
10
|
+
'numeric',
|
|
10
11
|
'strings'
|
|
11
12
|
]
|
|
@@ -4,12 +4,14 @@
|
|
|
4
4
|
from typing import Any, Callable, Optional, Sequence, cast
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
def
|
|
7
|
+
def are_same(actual: Sequence[Any] | set[Any] | dict[Any, Any] | None, expected: Sequence[Any] | set[Any] | dict[Any, Any] | None, sort: bool = False, sort_function: Optional[Callable[[Any], Any]] = None) -> bool:
|
|
8
8
|
"""
|
|
9
9
|
Check if two sequences contain the same elements in the same order.
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
|
|
11
|
+
Can optionally specify *sort* so that differences in order do not cause failure.
|
|
12
|
+
|
|
13
|
+
:param actual: The sequence to check.
|
|
14
|
+
:param expected: The sequence to compare against.
|
|
13
15
|
:param sort: Sort sequences before performing comparisons.
|
|
14
16
|
:param sort_function: Custom function to use when sorting.
|
|
15
17
|
:returns bool: True if the sequences contain the same elements in the same order, False otherwise.
|
|
@@ -27,44 +29,48 @@ def areSame(actual: Sequence[Any] | set[Any] | dict[Any, Any] | None, expected:
|
|
|
27
29
|
if sort:
|
|
28
30
|
if isinstance(actual, dict) or isinstance(expected, dict):
|
|
29
31
|
sort_function = sort_function if sort_function is not None else lambda e: e[0]
|
|
30
|
-
actual = sorted(cast(dict, actual).items(), key=sort_function)
|
|
31
|
-
expected = sorted(cast(dict, expected).items(), key=sort_function)
|
|
32
|
+
actual = sorted(cast(dict[Any, Any], actual).items(), key=sort_function)
|
|
33
|
+
expected = sorted(cast(dict[Any, Any], expected).items(), key=sort_function)
|
|
32
34
|
else:
|
|
33
35
|
sort_function = sort_function if sort_function is not None else lambda e: e
|
|
34
36
|
actual = sorted(actual, key=sort_function)
|
|
35
37
|
expected = sorted(expected, key=sort_function)
|
|
36
38
|
|
|
37
39
|
if isinstance(actual, dict) or isinstance(expected, dict):
|
|
38
|
-
for pairs in zip(cast(dict, actual).items(), cast(dict, expected).items()):
|
|
40
|
+
for pairs in zip(cast(dict[Any, Any], actual).items(), cast(dict[Any, Any], expected).items()):
|
|
39
41
|
if not areSame(pairs[0], pairs[1]):
|
|
40
|
-
return False
|
|
42
|
+
return False
|
|
41
43
|
else:
|
|
42
44
|
for pairs in zip(actual, expected):
|
|
43
45
|
if isinstance(pairs[0], dict) or isinstance(pairs[1], dict):
|
|
44
46
|
if not areSame(pairs[0], pairs[1]):
|
|
45
|
-
return False
|
|
46
|
-
elif pairs[0] != pairs[1]:
|
|
47
47
|
return False
|
|
48
|
+
elif pairs[0] != pairs[1]:
|
|
49
|
+
return False
|
|
48
50
|
return True
|
|
49
51
|
|
|
50
|
-
|
|
52
|
+
|
|
53
|
+
def has_length(actual: Sequence[Any] | set[Any] | dict[Any, Any] | None, min: Optional[int] = None, max: Optional[int] = None) -> bool:
|
|
51
54
|
"""
|
|
52
55
|
Check if actual value has the expected number of elements.
|
|
53
|
-
|
|
56
|
+
|
|
54
57
|
:param actual: The actual value to check.
|
|
55
58
|
:param int|None expected: The expected number of elements
|
|
56
|
-
|
|
59
|
+
|
|
57
60
|
:returns bool: True if the sequence has exactly the expected number of elements, False otherwise
|
|
58
61
|
"""
|
|
59
|
-
if actual is None
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
return
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
62
|
+
if actual is None:
|
|
63
|
+
if ((min is None or min == 0) and (max is None or max == 0)):
|
|
64
|
+
return True
|
|
65
|
+
return not ((min is not None and min != 0) or (max is not None or max != 0))
|
|
66
|
+
else:
|
|
67
|
+
if ((min is None) and (max is None)):
|
|
68
|
+
return False
|
|
69
|
+
len_actual = len(actual)
|
|
70
|
+
return (min is None or len_actual >= min) and (max is None or len_actual <= max)
|
|
71
|
+
|
|
66
72
|
|
|
67
|
-
def
|
|
73
|
+
def is_none_or_empty(actual: Sequence[Any] | set[Any] | dict[Any, Any] | None) -> bool:
|
|
68
74
|
"""
|
|
69
75
|
Check if actual value is None or empty.
|
|
70
76
|
|
|
@@ -74,3 +80,20 @@ def isNoneOrEmpty(actual: Sequence[Any] | set[Any] | dict[Any, Any] | None) -> b
|
|
|
74
80
|
if actual is None:
|
|
75
81
|
return True
|
|
76
82
|
return len(actual) == 0
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
# DEPRECATIONS
|
|
86
|
+
areSame = are_same
|
|
87
|
+
hasLength = has_length
|
|
88
|
+
isNoneOrEmpty = is_none_or_empty
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
__all__ = [
|
|
92
|
+
'are_same',
|
|
93
|
+
'has_length',
|
|
94
|
+
'is_none_or_empty',
|
|
95
|
+
# deprecated (do not use):
|
|
96
|
+
'areSame',
|
|
97
|
+
'hasLength',
|
|
98
|
+
'isNoneOrEmpty'
|
|
99
|
+
]
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText: ©
|
|
1
|
+
# SPDX-FileCopyrightText: © 2024 Shaun Wilson
|
|
2
2
|
# SPDX-License-Identifier: MIT
|
|
3
3
|
|
|
4
4
|
from typing import Any, Callable, Generic, Optional, TypeVar, cast, get_args
|
|
@@ -8,12 +8,12 @@ TError = TypeVar('TError', bound=Exception)
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
class raises(Generic[TError]):
|
|
11
|
-
|
|
12
|
-
__action:Callable
|
|
13
|
-
__exact:bool
|
|
14
|
-
__expect:Optional[TError|type]
|
|
15
11
|
|
|
16
|
-
|
|
12
|
+
__action: Callable[[], Any]
|
|
13
|
+
__exact: bool
|
|
14
|
+
__expect: Optional[TError | type]
|
|
15
|
+
|
|
16
|
+
def __init__(self, action: Callable[[], Any], *, exact: bool = False, expect: Optional[TError | type] = None) -> None:
|
|
17
17
|
self.__action = action
|
|
18
18
|
self.__exact = exact
|
|
19
19
|
self.__expect = expect
|
|
@@ -28,7 +28,7 @@ class raises(Generic[TError]):
|
|
|
28
28
|
if self.__exact:
|
|
29
29
|
return type(ex) is expected
|
|
30
30
|
elif expected is not None:
|
|
31
|
-
return issubclass(type(ex), cast(Any,expected))
|
|
31
|
+
return issubclass(type(ex), cast(Any, expected))
|
|
32
32
|
return False
|
|
33
33
|
|
|
34
34
|
|