bean-test 0.1.0__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.
- bean_test-0.1.0/LICENSE +21 -0
- bean_test-0.1.0/PKG-INFO +282 -0
- bean_test-0.1.0/README.md +230 -0
- bean_test-0.1.0/pyproject.toml +52 -0
- bean_test-0.1.0/setup.cfg +4 -0
- bean_test-0.1.0/src/bean/test.py +1573 -0
- bean_test-0.1.0/src/bean_test.egg-info/PKG-INFO +282 -0
- bean_test-0.1.0/src/bean_test.egg-info/SOURCES.txt +8 -0
- bean_test-0.1.0/src/bean_test.egg-info/dependency_links.txt +1 -0
- bean_test-0.1.0/src/bean_test.egg-info/top_level.txt +1 -0
bean_test-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) `2026` `numen-0`
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
7
|
+
the Software without restriction, including without limitation the rights to
|
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
9
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
|
10
|
+
so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
bean_test-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: bean-test
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Tiny test framework
|
|
5
|
+
Author-email: numen-0 <numen.0x1dea@gmail.com>
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) `2026` `numen-0`
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
11
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
12
|
+
the Software without restriction, including without limitation the rights to
|
|
13
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
14
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
|
15
|
+
so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
|
|
28
|
+
Project-URL: homepage, https://github.com/numen-0/bean
|
|
29
|
+
Project-URL: repository, https://github.com/numen-0/bean
|
|
30
|
+
Project-URL: issues, https://github.com/numen-0/bean/issues
|
|
31
|
+
Project-URL: documentation, https://github.com/numen-0/bean/bean-http/src/bean/test.py
|
|
32
|
+
Keywords: bean,bean.test
|
|
33
|
+
Classifier: Development Status :: 2 - Pre-Alpha
|
|
34
|
+
Classifier: Environment :: Console
|
|
35
|
+
Classifier: Intended Audience :: Developers
|
|
36
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
37
|
+
Classifier: Operating System :: OS Independent
|
|
38
|
+
Classifier: Programming Language :: Python
|
|
39
|
+
Classifier: Programming Language :: Python :: 3
|
|
40
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
41
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
42
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
43
|
+
Classifier: Topic :: Scientific/Engineering
|
|
44
|
+
Classifier: Topic :: Software Development
|
|
45
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
46
|
+
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
47
|
+
Classifier: Typing :: Typed
|
|
48
|
+
Requires-Python: >=3.14
|
|
49
|
+
Description-Content-Type: text/markdown
|
|
50
|
+
License-File: LICENSE
|
|
51
|
+
Dynamic: license-file
|
|
52
|
+
|
|
53
|
+
# bean.test
|
|
54
|
+
|
|
55
|
+
`bean.test` is a tiny test framework.
|
|
56
|
+
|
|
57
|
+
> Just enough to pick apart rotten beans.
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Overview
|
|
62
|
+
|
|
63
|
+
With `bean.test` you get:
|
|
64
|
+
|
|
65
|
+
- A small, fluent assertion API.
|
|
66
|
+
- Test data generation helpers.
|
|
67
|
+
- Simple test registration and reporting.
|
|
68
|
+
- test discovery
|
|
69
|
+
|
|
70
|
+
```py
|
|
71
|
+
from bean import test
|
|
72
|
+
|
|
73
|
+
@test.register()
|
|
74
|
+
def test_something():
|
|
75
|
+
test.expect(1 + 1).Equal(2)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
> **Note**:
|
|
79
|
+
>
|
|
80
|
+
> To quickly inspect the public API:
|
|
81
|
+
>
|
|
82
|
+
> ```sh
|
|
83
|
+
> python -c "
|
|
84
|
+
> import bean.test as bean
|
|
85
|
+
> for v in sorted(dir(bean)):
|
|
86
|
+
> print(f'- {v}')
|
|
87
|
+
> "
|
|
88
|
+
> ```
|
|
89
|
+
|
|
90
|
+
## Installation
|
|
91
|
+
|
|
92
|
+
Using `pip`:
|
|
93
|
+
|
|
94
|
+
```sh
|
|
95
|
+
pip install --upgrade bean-test
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Using `curl` (direct download):
|
|
99
|
+
|
|
100
|
+
```sh
|
|
101
|
+
curl -Ls \
|
|
102
|
+
https://raw.githubusercontent.com/numen-0/bean/main/bean-test/src/bean/test.py
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Command Line
|
|
106
|
+
|
|
107
|
+
`bean.test` can be used directly as a test runner.
|
|
108
|
+
|
|
109
|
+
```sh
|
|
110
|
+
python -m bean.test tests/
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
By default, files matching `*.py` are discovered. Use `--pattern` to change the
|
|
114
|
+
pattern:
|
|
115
|
+
|
|
116
|
+
```sh
|
|
117
|
+
python -m bean.test tests/ --pattern "test_*.py"
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Run only specific namespaces:
|
|
121
|
+
|
|
122
|
+
```sh
|
|
123
|
+
python -m bean.test tests/ -n unit integration
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
> **Note**:
|
|
127
|
+
>
|
|
128
|
+
> For more information, run:
|
|
129
|
+
>
|
|
130
|
+
> ```sh
|
|
131
|
+
> python -m bean.test --help
|
|
132
|
+
> ```
|
|
133
|
+
|
|
134
|
+
## API
|
|
135
|
+
|
|
136
|
+
This is a quick reference for the main `API`.
|
|
137
|
+
|
|
138
|
+
For full details, see the [source code](/bean-test/src/bean/test.py).
|
|
139
|
+
|
|
140
|
+
### Test Registration
|
|
141
|
+
|
|
142
|
+
Tests can be registered under different namespaces.
|
|
143
|
+
|
|
144
|
+
```py
|
|
145
|
+
@register("math")
|
|
146
|
+
def test_addition(): ...
|
|
147
|
+
|
|
148
|
+
@register("http")
|
|
149
|
+
def test_request(): ...
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Data Generation
|
|
153
|
+
|
|
154
|
+
`rand` provides small helpers for generating and composing random test data.
|
|
155
|
+
|
|
156
|
+
```py
|
|
157
|
+
from bean.test import rand
|
|
158
|
+
|
|
159
|
+
list(rand.cases( # generator for tuple[bool, tuple[str, int]]
|
|
160
|
+
rand(bool), # <- retrieve bool
|
|
161
|
+
rand.choice(*rand.product( # <- chose a tuple[str, int]
|
|
162
|
+
("a", "b", "c"),
|
|
163
|
+
(1, 2, 3),
|
|
164
|
+
)),
|
|
165
|
+
count=5,
|
|
166
|
+
seed=42,
|
|
167
|
+
))
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### The Lab
|
|
171
|
+
|
|
172
|
+
`Lab` is the singleton responsible for running tests and generating reports
|
|
173
|
+
|
|
174
|
+
| member | descrition |
|
|
175
|
+
|:-------------------------:|:-------------------------------------------------|
|
|
176
|
+
| `report(ns)` | Generate report for all or the given namespaces |
|
|
177
|
+
| `print(ns)` | Generate a report and write it to stdout |
|
|
178
|
+
|
|
179
|
+
### Expect Assertions
|
|
180
|
+
|
|
181
|
+
Fluent assertions for inspecting values.
|
|
182
|
+
|
|
183
|
+
| **Method** | **Descrition** |
|
|
184
|
+
|:--------------------------|:-------------------------------------------------|
|
|
185
|
+
| *misc* | - |
|
|
186
|
+
| `Set(value)` | Replace asserted value |
|
|
187
|
+
| `Map(fn)` | Transform asserted value |
|
|
188
|
+
| `MapEach(fn)` | Transform asserted value items |
|
|
189
|
+
| `Check(predicate)` | Assert value satisfies predicate |
|
|
190
|
+
| *context* | - |
|
|
191
|
+
| `Raises(exception)` | Context manager asserting that an exception is raised |
|
|
192
|
+
| *turthiness* | - |
|
|
193
|
+
| `Truthy()` | Assert value is truthy |
|
|
194
|
+
| `Falsy()` | Assert value is falsy |
|
|
195
|
+
| `Empty()` | Assert value has length zero |
|
|
196
|
+
| `NotEmpty()` | Assert value has non-zero length |
|
|
197
|
+
| *equality* | - |
|
|
198
|
+
| `Equal(expected)` | Assert value == expected |
|
|
199
|
+
| `NotEqual(expected)` | Assert value != expected |
|
|
200
|
+
| `Greater(expected)` | Assert value < expected |
|
|
201
|
+
| `GreaterEqual(expected)` | Assert value <= expected |
|
|
202
|
+
| `Less(expected)` | Assert value > expected |
|
|
203
|
+
| `LessEqual(expected)` | Assert value >= expected |
|
|
204
|
+
| `AlmostEqual(expected)` | Assert numeric values are approximately equal |
|
|
205
|
+
| `NotAlmostEqual(expected)` | Assert numeric values are not approximately equal |
|
|
206
|
+
| *type* identity | - |
|
|
207
|
+
| `Is(expected)` | Assert value is expected |
|
|
208
|
+
| `IsNot(expected)` | Assert value is not expected |
|
|
209
|
+
| `IsNone()` | Assert value is `None` |
|
|
210
|
+
| `IsNotNone()` | Assert value is not `None` |
|
|
211
|
+
| `IsInstance(cls)` | Assert value is an instance of a type |
|
|
212
|
+
| `IsNotInstance(cls)` | Assert value is not an instance of a type |
|
|
213
|
+
| `IsNumeric()` | Assert value is numeric |
|
|
214
|
+
| `IsString()` | Assert value is a string |
|
|
215
|
+
| `IsEnum()` | Assert value is a enum |
|
|
216
|
+
| `IsIterable()` | Assert value is iterable |
|
|
217
|
+
| *strings* | - |
|
|
218
|
+
| `StartsWith(expected)` | Assert value starts with given prefix |
|
|
219
|
+
| `NotStartsWith(expected)` | Assert value doesn't start with given prefix |
|
|
220
|
+
| `EndsWith(expected)` | Assert value ends with given suffix |
|
|
221
|
+
| `NotEndsWith(expected)` | Assert value doesn't end with given suffix |
|
|
222
|
+
| `Regex(expected)` | Assert value matches regular expression |
|
|
223
|
+
| `NotRegex(expected)` | Assert value doesn't matche regular expression |
|
|
224
|
+
| *quantifiers* | - |
|
|
225
|
+
| `All(predicate)` | Assert every item satisfies predicate |
|
|
226
|
+
| `Any(predicate)` | Assert at least one item satisfies predicate |
|
|
227
|
+
| `NotAny(predicate)` | Assert no item satisfies predicate |
|
|
228
|
+
| `IsSorted()` | Assert value is sorted |
|
|
229
|
+
| *quantifiers* | - |
|
|
230
|
+
| `In(expected)` | Assert value is contained in expected |
|
|
231
|
+
| `NotIn(expected)` | Assert value isn't contained in expected |
|
|
232
|
+
| `HasAttr(expected)` | Assert value has an attribute |
|
|
233
|
+
| `NotHasAttr(expected)` | Assert value hasn't an attribute |
|
|
234
|
+
| *collections* | - |
|
|
235
|
+
| `SequenceEqual(expected)` | Assert equal items in the same order |
|
|
236
|
+
| `ContainerEqual(expected)` | Assert equal items, ignoring order and preserving multiplicity |
|
|
237
|
+
| `SetEqual(expected)` | Assert equal items using set semantics |
|
|
238
|
+
| `NotSetEqual(expected)` | Assert containers are not set-equal |
|
|
239
|
+
| `Subset(expected)` | Assert every item is contained in expected |
|
|
240
|
+
| `NotSubset(expected)` | Assert at least one item is outside expected |
|
|
241
|
+
| `Superset(expected)` | Assert value contains every expected item |
|
|
242
|
+
| `NotSuperset(expected)` | Assert at least one expected item is missing |
|
|
243
|
+
| `Intersects(expected)` | Assert containers have no items in common |
|
|
244
|
+
| `Disjoint(expected)` | Assert containers have at least one item in common |
|
|
245
|
+
|
|
246
|
+
> **Note**: Every method returns `self`, so multiple assertions can be chained
|
|
247
|
+
|
|
248
|
+
## Example
|
|
249
|
+
|
|
250
|
+
```py
|
|
251
|
+
from bean import test
|
|
252
|
+
|
|
253
|
+
@test.register()
|
|
254
|
+
def test_addition():
|
|
255
|
+
test.expect(1 + 1).Equal(2)
|
|
256
|
+
|
|
257
|
+
@test.register()
|
|
258
|
+
def test_string():
|
|
259
|
+
test.expect("hello world") \
|
|
260
|
+
.IsString() \
|
|
261
|
+
.NotEmpty() \
|
|
262
|
+
.StartsWith("hello") \
|
|
263
|
+
.EndsWith("world")
|
|
264
|
+
|
|
265
|
+
@test.register()
|
|
266
|
+
def test_collections():
|
|
267
|
+
test.expect([1, 2, 3]).SequenceEqual([1, 2, 3])
|
|
268
|
+
test.expect([3, 1, 2]).SetEqual([1, 2, 3])
|
|
269
|
+
test.expect([1, 2]).Subset([1, 2, 3])
|
|
270
|
+
|
|
271
|
+
@test.register()
|
|
272
|
+
def test_exception():
|
|
273
|
+
with test.expect.Raises(ValueError):
|
|
274
|
+
int("bean")
|
|
275
|
+
|
|
276
|
+
test.Lab.print()
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
## License
|
|
280
|
+
|
|
281
|
+
All the repo falls under the [MIT License](/LICENSE).
|
|
282
|
+
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
# bean.test
|
|
2
|
+
|
|
3
|
+
`bean.test` is a tiny test framework.
|
|
4
|
+
|
|
5
|
+
> Just enough to pick apart rotten beans.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
With `bean.test` you get:
|
|
12
|
+
|
|
13
|
+
- A small, fluent assertion API.
|
|
14
|
+
- Test data generation helpers.
|
|
15
|
+
- Simple test registration and reporting.
|
|
16
|
+
- test discovery
|
|
17
|
+
|
|
18
|
+
```py
|
|
19
|
+
from bean import test
|
|
20
|
+
|
|
21
|
+
@test.register()
|
|
22
|
+
def test_something():
|
|
23
|
+
test.expect(1 + 1).Equal(2)
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
> **Note**:
|
|
27
|
+
>
|
|
28
|
+
> To quickly inspect the public API:
|
|
29
|
+
>
|
|
30
|
+
> ```sh
|
|
31
|
+
> python -c "
|
|
32
|
+
> import bean.test as bean
|
|
33
|
+
> for v in sorted(dir(bean)):
|
|
34
|
+
> print(f'- {v}')
|
|
35
|
+
> "
|
|
36
|
+
> ```
|
|
37
|
+
|
|
38
|
+
## Installation
|
|
39
|
+
|
|
40
|
+
Using `pip`:
|
|
41
|
+
|
|
42
|
+
```sh
|
|
43
|
+
pip install --upgrade bean-test
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Using `curl` (direct download):
|
|
47
|
+
|
|
48
|
+
```sh
|
|
49
|
+
curl -Ls \
|
|
50
|
+
https://raw.githubusercontent.com/numen-0/bean/main/bean-test/src/bean/test.py
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Command Line
|
|
54
|
+
|
|
55
|
+
`bean.test` can be used directly as a test runner.
|
|
56
|
+
|
|
57
|
+
```sh
|
|
58
|
+
python -m bean.test tests/
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
By default, files matching `*.py` are discovered. Use `--pattern` to change the
|
|
62
|
+
pattern:
|
|
63
|
+
|
|
64
|
+
```sh
|
|
65
|
+
python -m bean.test tests/ --pattern "test_*.py"
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Run only specific namespaces:
|
|
69
|
+
|
|
70
|
+
```sh
|
|
71
|
+
python -m bean.test tests/ -n unit integration
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
> **Note**:
|
|
75
|
+
>
|
|
76
|
+
> For more information, run:
|
|
77
|
+
>
|
|
78
|
+
> ```sh
|
|
79
|
+
> python -m bean.test --help
|
|
80
|
+
> ```
|
|
81
|
+
|
|
82
|
+
## API
|
|
83
|
+
|
|
84
|
+
This is a quick reference for the main `API`.
|
|
85
|
+
|
|
86
|
+
For full details, see the [source code](/bean-test/src/bean/test.py).
|
|
87
|
+
|
|
88
|
+
### Test Registration
|
|
89
|
+
|
|
90
|
+
Tests can be registered under different namespaces.
|
|
91
|
+
|
|
92
|
+
```py
|
|
93
|
+
@register("math")
|
|
94
|
+
def test_addition(): ...
|
|
95
|
+
|
|
96
|
+
@register("http")
|
|
97
|
+
def test_request(): ...
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Data Generation
|
|
101
|
+
|
|
102
|
+
`rand` provides small helpers for generating and composing random test data.
|
|
103
|
+
|
|
104
|
+
```py
|
|
105
|
+
from bean.test import rand
|
|
106
|
+
|
|
107
|
+
list(rand.cases( # generator for tuple[bool, tuple[str, int]]
|
|
108
|
+
rand(bool), # <- retrieve bool
|
|
109
|
+
rand.choice(*rand.product( # <- chose a tuple[str, int]
|
|
110
|
+
("a", "b", "c"),
|
|
111
|
+
(1, 2, 3),
|
|
112
|
+
)),
|
|
113
|
+
count=5,
|
|
114
|
+
seed=42,
|
|
115
|
+
))
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### The Lab
|
|
119
|
+
|
|
120
|
+
`Lab` is the singleton responsible for running tests and generating reports
|
|
121
|
+
|
|
122
|
+
| member | descrition |
|
|
123
|
+
|:-------------------------:|:-------------------------------------------------|
|
|
124
|
+
| `report(ns)` | Generate report for all or the given namespaces |
|
|
125
|
+
| `print(ns)` | Generate a report and write it to stdout |
|
|
126
|
+
|
|
127
|
+
### Expect Assertions
|
|
128
|
+
|
|
129
|
+
Fluent assertions for inspecting values.
|
|
130
|
+
|
|
131
|
+
| **Method** | **Descrition** |
|
|
132
|
+
|:--------------------------|:-------------------------------------------------|
|
|
133
|
+
| *misc* | - |
|
|
134
|
+
| `Set(value)` | Replace asserted value |
|
|
135
|
+
| `Map(fn)` | Transform asserted value |
|
|
136
|
+
| `MapEach(fn)` | Transform asserted value items |
|
|
137
|
+
| `Check(predicate)` | Assert value satisfies predicate |
|
|
138
|
+
| *context* | - |
|
|
139
|
+
| `Raises(exception)` | Context manager asserting that an exception is raised |
|
|
140
|
+
| *turthiness* | - |
|
|
141
|
+
| `Truthy()` | Assert value is truthy |
|
|
142
|
+
| `Falsy()` | Assert value is falsy |
|
|
143
|
+
| `Empty()` | Assert value has length zero |
|
|
144
|
+
| `NotEmpty()` | Assert value has non-zero length |
|
|
145
|
+
| *equality* | - |
|
|
146
|
+
| `Equal(expected)` | Assert value == expected |
|
|
147
|
+
| `NotEqual(expected)` | Assert value != expected |
|
|
148
|
+
| `Greater(expected)` | Assert value < expected |
|
|
149
|
+
| `GreaterEqual(expected)` | Assert value <= expected |
|
|
150
|
+
| `Less(expected)` | Assert value > expected |
|
|
151
|
+
| `LessEqual(expected)` | Assert value >= expected |
|
|
152
|
+
| `AlmostEqual(expected)` | Assert numeric values are approximately equal |
|
|
153
|
+
| `NotAlmostEqual(expected)` | Assert numeric values are not approximately equal |
|
|
154
|
+
| *type* identity | - |
|
|
155
|
+
| `Is(expected)` | Assert value is expected |
|
|
156
|
+
| `IsNot(expected)` | Assert value is not expected |
|
|
157
|
+
| `IsNone()` | Assert value is `None` |
|
|
158
|
+
| `IsNotNone()` | Assert value is not `None` |
|
|
159
|
+
| `IsInstance(cls)` | Assert value is an instance of a type |
|
|
160
|
+
| `IsNotInstance(cls)` | Assert value is not an instance of a type |
|
|
161
|
+
| `IsNumeric()` | Assert value is numeric |
|
|
162
|
+
| `IsString()` | Assert value is a string |
|
|
163
|
+
| `IsEnum()` | Assert value is a enum |
|
|
164
|
+
| `IsIterable()` | Assert value is iterable |
|
|
165
|
+
| *strings* | - |
|
|
166
|
+
| `StartsWith(expected)` | Assert value starts with given prefix |
|
|
167
|
+
| `NotStartsWith(expected)` | Assert value doesn't start with given prefix |
|
|
168
|
+
| `EndsWith(expected)` | Assert value ends with given suffix |
|
|
169
|
+
| `NotEndsWith(expected)` | Assert value doesn't end with given suffix |
|
|
170
|
+
| `Regex(expected)` | Assert value matches regular expression |
|
|
171
|
+
| `NotRegex(expected)` | Assert value doesn't matche regular expression |
|
|
172
|
+
| *quantifiers* | - |
|
|
173
|
+
| `All(predicate)` | Assert every item satisfies predicate |
|
|
174
|
+
| `Any(predicate)` | Assert at least one item satisfies predicate |
|
|
175
|
+
| `NotAny(predicate)` | Assert no item satisfies predicate |
|
|
176
|
+
| `IsSorted()` | Assert value is sorted |
|
|
177
|
+
| *quantifiers* | - |
|
|
178
|
+
| `In(expected)` | Assert value is contained in expected |
|
|
179
|
+
| `NotIn(expected)` | Assert value isn't contained in expected |
|
|
180
|
+
| `HasAttr(expected)` | Assert value has an attribute |
|
|
181
|
+
| `NotHasAttr(expected)` | Assert value hasn't an attribute |
|
|
182
|
+
| *collections* | - |
|
|
183
|
+
| `SequenceEqual(expected)` | Assert equal items in the same order |
|
|
184
|
+
| `ContainerEqual(expected)` | Assert equal items, ignoring order and preserving multiplicity |
|
|
185
|
+
| `SetEqual(expected)` | Assert equal items using set semantics |
|
|
186
|
+
| `NotSetEqual(expected)` | Assert containers are not set-equal |
|
|
187
|
+
| `Subset(expected)` | Assert every item is contained in expected |
|
|
188
|
+
| `NotSubset(expected)` | Assert at least one item is outside expected |
|
|
189
|
+
| `Superset(expected)` | Assert value contains every expected item |
|
|
190
|
+
| `NotSuperset(expected)` | Assert at least one expected item is missing |
|
|
191
|
+
| `Intersects(expected)` | Assert containers have no items in common |
|
|
192
|
+
| `Disjoint(expected)` | Assert containers have at least one item in common |
|
|
193
|
+
|
|
194
|
+
> **Note**: Every method returns `self`, so multiple assertions can be chained
|
|
195
|
+
|
|
196
|
+
## Example
|
|
197
|
+
|
|
198
|
+
```py
|
|
199
|
+
from bean import test
|
|
200
|
+
|
|
201
|
+
@test.register()
|
|
202
|
+
def test_addition():
|
|
203
|
+
test.expect(1 + 1).Equal(2)
|
|
204
|
+
|
|
205
|
+
@test.register()
|
|
206
|
+
def test_string():
|
|
207
|
+
test.expect("hello world") \
|
|
208
|
+
.IsString() \
|
|
209
|
+
.NotEmpty() \
|
|
210
|
+
.StartsWith("hello") \
|
|
211
|
+
.EndsWith("world")
|
|
212
|
+
|
|
213
|
+
@test.register()
|
|
214
|
+
def test_collections():
|
|
215
|
+
test.expect([1, 2, 3]).SequenceEqual([1, 2, 3])
|
|
216
|
+
test.expect([3, 1, 2]).SetEqual([1, 2, 3])
|
|
217
|
+
test.expect([1, 2]).Subset([1, 2, 3])
|
|
218
|
+
|
|
219
|
+
@test.register()
|
|
220
|
+
def test_exception():
|
|
221
|
+
with test.expect.Raises(ValueError):
|
|
222
|
+
int("bean")
|
|
223
|
+
|
|
224
|
+
test.Lab.print()
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## License
|
|
228
|
+
|
|
229
|
+
All the repo falls under the [MIT License](/LICENSE).
|
|
230
|
+
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "bean-test"
|
|
3
|
+
description = "Tiny test framework"
|
|
4
|
+
dynamic = ["version"]
|
|
5
|
+
dependencies = []
|
|
6
|
+
requires-python = ">=3.14"
|
|
7
|
+
|
|
8
|
+
authors = [
|
|
9
|
+
{ name = "numen-0", email = "numen.0x1dea@gmail.com" },
|
|
10
|
+
]
|
|
11
|
+
readme = "README.md"
|
|
12
|
+
license = { file = "LICENSE" }
|
|
13
|
+
|
|
14
|
+
keywords = [
|
|
15
|
+
"bean",
|
|
16
|
+
"bean.test",
|
|
17
|
+
]
|
|
18
|
+
classifiers = [
|
|
19
|
+
"Development Status :: 2 - Pre-Alpha",
|
|
20
|
+
"Environment :: Console",
|
|
21
|
+
"Intended Audience :: Developers",
|
|
22
|
+
"License :: OSI Approved :: MIT License",
|
|
23
|
+
"Operating System :: OS Independent",
|
|
24
|
+
"Programming Language :: Python",
|
|
25
|
+
"Programming Language :: Python :: 3",
|
|
26
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
27
|
+
"Programming Language :: Python :: 3.14",
|
|
28
|
+
"Programming Language :: Python :: 3.15",
|
|
29
|
+
"Topic :: Scientific/Engineering",
|
|
30
|
+
"Topic :: Software Development",
|
|
31
|
+
"Topic :: Software Development :: Libraries",
|
|
32
|
+
"Topic :: Software Development :: Libraries :: Application Frameworks",
|
|
33
|
+
"Typing :: Typed",
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
[project.urls]
|
|
37
|
+
homepage = "https://github.com/numen-0/bean"
|
|
38
|
+
repository = "https://github.com/numen-0/bean"
|
|
39
|
+
issues = "https://github.com/numen-0/bean/issues"
|
|
40
|
+
documentation = "https://github.com/numen-0/bean/bean-http/src/bean/test.py"
|
|
41
|
+
|
|
42
|
+
[build-system]
|
|
43
|
+
requires = ["setuptools>=64", "wheel"]
|
|
44
|
+
build-backend = "setuptools.build_meta"
|
|
45
|
+
|
|
46
|
+
[tool.setuptools.dynamic]
|
|
47
|
+
version = { attr = "bean.test.__version__" }
|
|
48
|
+
|
|
49
|
+
[tool.setuptools.packages.find]
|
|
50
|
+
where = ["src"]
|
|
51
|
+
include = ["bean*"]
|
|
52
|
+
namespaces = true
|