schemathesis 4.0.0a9__py3-none-any.whl → 4.0.0a10__py3-none-any.whl
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.
- schemathesis/cli/commands/run/handlers/junitxml.py +1 -1
- schemathesis/core/__init__.py +1 -0
- schemathesis/generation/coverage.py +23 -13
- schemathesis/generation/hypothesis/__init__.py +7 -1
- {schemathesis-4.0.0a9.dist-info → schemathesis-4.0.0a10.dist-info}/METADATA +1 -1
- {schemathesis-4.0.0a9.dist-info → schemathesis-4.0.0a10.dist-info}/RECORD +9 -9
- {schemathesis-4.0.0a9.dist-info → schemathesis-4.0.0a10.dist-info}/WHEEL +0 -0
- {schemathesis-4.0.0a9.dist-info → schemathesis-4.0.0a10.dist-info}/entry_points.txt +0 -0
- {schemathesis-4.0.0a9.dist-info → schemathesis-4.0.0a10.dist-info}/licenses/LICENSE +0 -0
@@ -23,7 +23,7 @@ class JunitXMLHandler(EventHandler):
|
|
23
23
|
label = event.recorder.label
|
24
24
|
test_case = self.get_or_create_test_case(label)
|
25
25
|
test_case.elapsed_sec += event.elapsed_time
|
26
|
-
if event.status == Status.FAILURE:
|
26
|
+
if event.status == Status.FAILURE and label in ctx.statistic.failures:
|
27
27
|
add_failure(test_case, ctx.statistic.failures[label].values(), ctx)
|
28
28
|
elif event.status == Status.SKIP and event.skip_reason is not None:
|
29
29
|
test_case.add_skipped_info(output=event.skip_reason)
|
schemathesis/core/__init__.py
CHANGED
@@ -16,7 +16,7 @@ from hypothesis_jsonschema import from_schema
|
|
16
16
|
from hypothesis_jsonschema._canonicalise import canonicalish
|
17
17
|
from hypothesis_jsonschema._from_schema import STRING_FORMATS as BUILT_IN_STRING_FORMATS
|
18
18
|
|
19
|
-
from schemathesis.core import NOT_SET
|
19
|
+
from schemathesis.core import INTERNAL_BUFFER_SIZE, NOT_SET
|
20
20
|
from schemathesis.core.compat import RefResolutionError
|
21
21
|
from schemathesis.core.transforms import deepclone
|
22
22
|
from schemathesis.core.validation import has_invalid_characters, is_latin_1_encodable
|
@@ -36,7 +36,6 @@ def json_recursive_strategy(strategy: st.SearchStrategy) -> st.SearchStrategy:
|
|
36
36
|
return st.lists(strategy, max_size=3) | st.dictionaries(st.text(), strategy, max_size=3)
|
37
37
|
|
38
38
|
|
39
|
-
BUFFER_SIZE = 8 * 1024
|
40
39
|
NEGATIVE_MODE_MAX_LENGTH_WITH_PATTERN = 100
|
41
40
|
NEGATIVE_MODE_MAX_ITEMS = 15
|
42
41
|
FLOAT_STRATEGY: st.SearchStrategy = st.floats(allow_nan=False, allow_infinity=False).map(_replace_zero_with_nonzero)
|
@@ -161,7 +160,7 @@ class CoverageContext:
|
|
161
160
|
def generate_from_schema(self, schema: dict | bool) -> Any:
|
162
161
|
if isinstance(schema, bool):
|
163
162
|
return 0
|
164
|
-
keys = sorted([k for k in schema if not k.startswith("x-") and k not in ["description", "example"]])
|
163
|
+
keys = sorted([k for k in schema if not k.startswith("x-") and k not in ["description", "example", "examples"]])
|
165
164
|
if keys == ["type"] and isinstance(schema["type"], str) and schema["type"] in STRATEGIES_FOR_TYPE:
|
166
165
|
return cached_draw(STRATEGIES_FOR_TYPE[schema["type"]])
|
167
166
|
if keys == ["format", "type"]:
|
@@ -393,7 +392,7 @@ def cover_schema_iter(
|
|
393
392
|
if k not in seen:
|
394
393
|
yield value_
|
395
394
|
seen.add(k)
|
396
|
-
elif key == "minLength" and 0 < value <
|
395
|
+
elif key == "minLength" and 0 < value < INTERNAL_BUFFER_SIZE:
|
397
396
|
if value == 1:
|
398
397
|
# In this case, the only possible negative string is an empty one
|
399
398
|
# The `pattern` value may require an non-empty one and the generation will fail
|
@@ -427,7 +426,7 @@ def cover_schema_iter(
|
|
427
426
|
value, description="String smaller than minLength", location=ctx.current_path
|
428
427
|
)
|
429
428
|
seen.add(k)
|
430
|
-
elif key == "maxLength" and value <
|
429
|
+
elif key == "maxLength" and value < INTERNAL_BUFFER_SIZE:
|
431
430
|
try:
|
432
431
|
min_length = max_length = value + 1
|
433
432
|
new_schema = {**schema, "minLength": min_length, "maxLength": max_length}
|
@@ -461,7 +460,7 @@ def cover_schema_iter(
|
|
461
460
|
elif key == "required":
|
462
461
|
template = template or ctx.generate_from_schema(_get_template_schema(schema, "object"))
|
463
462
|
yield from _negative_required(ctx, template, value)
|
464
|
-
elif key == "maxItems" and isinstance(value, int) and value <
|
463
|
+
elif key == "maxItems" and isinstance(value, int) and value < INTERNAL_BUFFER_SIZE:
|
465
464
|
if value > NEGATIVE_MODE_MAX_ITEMS:
|
466
465
|
# It could be extremely slow to generate large arrays
|
467
466
|
# Generate values up to the limit and reuse them to construct the final array
|
@@ -471,7 +470,18 @@ def cover_schema_iter(
|
|
471
470
|
"maxItems": NEGATIVE_MODE_MAX_ITEMS,
|
472
471
|
"type": "array",
|
473
472
|
}
|
474
|
-
|
473
|
+
if "items" in schema and isinstance(schema["items"], dict):
|
474
|
+
# The schema may have another large array nested, therefore generate covering cases
|
475
|
+
# and use them to build an array for the current schema
|
476
|
+
negative = [case.value for case in cover_schema_iter(ctx, schema["items"])]
|
477
|
+
positive = [case.value for case in cover_schema_iter(ctx.with_positive(), schema["items"])]
|
478
|
+
# Interleave positive & negative values
|
479
|
+
array_value = [value for pair in zip(positive, negative) for value in pair][
|
480
|
+
:NEGATIVE_MODE_MAX_ITEMS
|
481
|
+
]
|
482
|
+
else:
|
483
|
+
array_value = ctx.generate_from_schema(new_schema)
|
484
|
+
|
475
485
|
# Extend the array to be of length value + 1 by repeating its own elements
|
476
486
|
diff = value + 1 - len(array_value)
|
477
487
|
if diff > 0:
|
@@ -606,7 +616,7 @@ def _positive_string(ctx: CoverageContext, schema: dict) -> Generator[GeneratedV
|
|
606
616
|
|
607
617
|
seen = set()
|
608
618
|
|
609
|
-
if min_length is not None and min_length <
|
619
|
+
if min_length is not None and min_length < INTERNAL_BUFFER_SIZE:
|
610
620
|
# Exactly the minimum length
|
611
621
|
yield PositiveValue(
|
612
622
|
ctx.generate_from_schema({**schema, "maxLength": min_length}), description="Minimum length string"
|
@@ -615,7 +625,7 @@ def _positive_string(ctx: CoverageContext, schema: dict) -> Generator[GeneratedV
|
|
615
625
|
|
616
626
|
# One character more than minimum if possible
|
617
627
|
larger = min_length + 1
|
618
|
-
if larger <
|
628
|
+
if larger < INTERNAL_BUFFER_SIZE and larger not in seen and (not max_length or larger <= max_length):
|
619
629
|
yield PositiveValue(
|
620
630
|
ctx.generate_from_schema({**schema, "minLength": larger, "maxLength": larger}),
|
621
631
|
description="Near-boundary length string",
|
@@ -624,7 +634,7 @@ def _positive_string(ctx: CoverageContext, schema: dict) -> Generator[GeneratedV
|
|
624
634
|
|
625
635
|
if max_length is not None:
|
626
636
|
# Exactly the maximum length
|
627
|
-
if max_length <
|
637
|
+
if max_length < INTERNAL_BUFFER_SIZE and max_length not in seen:
|
628
638
|
yield PositiveValue(
|
629
639
|
ctx.generate_from_schema({**schema, "minLength": max_length}), description="Maximum length string"
|
630
640
|
)
|
@@ -633,7 +643,7 @@ def _positive_string(ctx: CoverageContext, schema: dict) -> Generator[GeneratedV
|
|
633
643
|
# One character less than maximum if possible
|
634
644
|
smaller = max_length - 1
|
635
645
|
if (
|
636
|
-
smaller <
|
646
|
+
smaller < INTERNAL_BUFFER_SIZE
|
637
647
|
and smaller not in seen
|
638
648
|
and (smaller > 0 and (min_length is None or smaller >= min_length))
|
639
649
|
):
|
@@ -765,7 +775,7 @@ def _positive_array(ctx: CoverageContext, schema: dict, template: list) -> Gener
|
|
765
775
|
yield PositiveValue(value, description="Near-boundary items array")
|
766
776
|
|
767
777
|
if max_items is not None:
|
768
|
-
if max_items <
|
778
|
+
if max_items < INTERNAL_BUFFER_SIZE and max_items not in seen:
|
769
779
|
value = ctx.generate_from_schema({**schema, "minItems": max_items})
|
770
780
|
key = _to_hashable_key(value)
|
771
781
|
if key not in seen:
|
@@ -775,7 +785,7 @@ def _positive_array(ctx: CoverageContext, schema: dict, template: list) -> Gener
|
|
775
785
|
# One item smaller than maximum if possible
|
776
786
|
smaller = max_items - 1
|
777
787
|
if (
|
778
|
-
smaller <
|
788
|
+
smaller < INTERNAL_BUFFER_SIZE
|
779
789
|
and smaller > 0
|
780
790
|
and smaller not in seen
|
781
791
|
and (min_items is None or smaller >= min_items)
|
@@ -5,11 +5,14 @@ DEFAULT_DEADLINE = 15000
|
|
5
5
|
|
6
6
|
|
7
7
|
def setup() -> None:
|
8
|
+
from hypothesis import core as root_core
|
9
|
+
from hypothesis.internal.conjecture import engine
|
8
10
|
from hypothesis.internal.entropy import deterministic_PRNG
|
9
11
|
from hypothesis.internal.reflection import is_first_param_referenced_in_function
|
10
|
-
from hypothesis.strategies._internal import core
|
12
|
+
from hypothesis.strategies._internal import collections, core
|
11
13
|
from hypothesis_jsonschema import _from_schema, _resolve
|
12
14
|
|
15
|
+
from schemathesis.core import INTERNAL_BUFFER_SIZE
|
13
16
|
from schemathesis.core.transforms import deepclone
|
14
17
|
|
15
18
|
# Forcefully initializes Hypothesis' global PRNG to avoid races that initialize it
|
@@ -28,3 +31,6 @@ def setup() -> None:
|
|
28
31
|
core.is_first_param_referenced_in_function = _is_first_param_referenced_in_function # type: ignore
|
29
32
|
_resolve.deepcopy = deepclone # type: ignore
|
30
33
|
_from_schema.deepcopy = deepclone # type: ignore
|
34
|
+
root_core.BUFFER_SIZE = INTERNAL_BUFFER_SIZE # type: ignore
|
35
|
+
engine.BUFFER_SIZE = INTERNAL_BUFFER_SIZE
|
36
|
+
collections.BUFFER_SIZE = INTERNAL_BUFFER_SIZE # type: ignore
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: schemathesis
|
3
|
-
Version: 4.0.
|
3
|
+
Version: 4.0.0a10
|
4
4
|
Summary: Property-based testing framework for Open API and GraphQL based apps
|
5
5
|
Project-URL: Documentation, https://schemathesis.readthedocs.io/en/stable/
|
6
6
|
Project-URL: Changelog, https://schemathesis.readthedocs.io/en/stable/changelog.html
|
@@ -25,7 +25,7 @@ schemathesis/cli/commands/run/validation.py,sha256=cpGG5hFc4lHVemXrQXRvrlNlqBmMq
|
|
25
25
|
schemathesis/cli/commands/run/handlers/__init__.py,sha256=TPZ3KdGi8m0fjlN0GjA31MAXXn1qI7uU4FtiDwroXZI,1915
|
26
26
|
schemathesis/cli/commands/run/handlers/base.py,sha256=yDsTtCiztLksfk7cRzg8JlaAVOfS-zwK3tsJMOXAFyc,530
|
27
27
|
schemathesis/cli/commands/run/handlers/cassettes.py,sha256=SVk13xPhsQduCpgvvBwzEMDNTju-SHQCW90xTQ6iL1U,18525
|
28
|
-
schemathesis/cli/commands/run/handlers/junitxml.py,sha256=
|
28
|
+
schemathesis/cli/commands/run/handlers/junitxml.py,sha256=OhBS8JY4DXQGsQ0JjaHp19QDBR2hye30a-XulVzs-rg,2386
|
29
29
|
schemathesis/cli/commands/run/handlers/output.py,sha256=n25QDGvYMXPKRPHBDckkDVwkkieY3Gq4HHSG0h3paTA,58800
|
30
30
|
schemathesis/cli/ext/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
31
31
|
schemathesis/cli/ext/fs.py,sha256=OA3mRzra4rq3NyDTcBvlRh0WJrh4ByN-QQ8loI04m88,408
|
@@ -34,7 +34,7 @@ schemathesis/cli/ext/options.py,sha256=gBjfYPoiSoxCymWq41x0oKcQ2frv1fQnweETVpYiI
|
|
34
34
|
schemathesis/contrib/__init__.py,sha256=wxpX86xrEGRAS3f7eugQfKVbnqV6ZfOqFBS_DmWxOok,120
|
35
35
|
schemathesis/contrib/openapi/__init__.py,sha256=-7mBZ9RQj0EGzzmC-HKiT5ZslwHcoWFqCVpRG0GHO_o,162
|
36
36
|
schemathesis/contrib/openapi/fill_missing_examples.py,sha256=BfBpuy3vCKbE_uILqPXnm7kxEDopAr5tNQwP5E9xX8A,585
|
37
|
-
schemathesis/core/__init__.py,sha256=
|
37
|
+
schemathesis/core/__init__.py,sha256=s1Td4mecrTr31BjBSdnxPSWPPGQERkAAAEPZBBK_9AE,1794
|
38
38
|
schemathesis/core/compat.py,sha256=Lflo6z-nQ6S4uKZINc4Fr90pd3LTN6cIG9HJJmmaHeY,754
|
39
39
|
schemathesis/core/control.py,sha256=IzwIc8HIAEMtZWW0Q0iXI7T1niBpjvcLlbuwOSmy5O8,130
|
40
40
|
schemathesis/core/curl.py,sha256=yuaCe_zHLGwUjEeloQi6W3tOA3cGdnHDNI17-5jia0o,1723
|
@@ -74,12 +74,12 @@ schemathesis/engine/phases/unit/_pool.py,sha256=9OgmFd-ov1AAvcZGquK40PXkGLp7f2qC
|
|
74
74
|
schemathesis/experimental/__init__.py,sha256=jYY3Mq6okqTRTMudPzcaT0JVjzJW5IN_ZVJdGU0stBs,2011
|
75
75
|
schemathesis/generation/__init__.py,sha256=sWTRPTh-qDNkSfpM9rYI3v8zskH8_wFKUuPRg18fZI8,1627
|
76
76
|
schemathesis/generation/case.py,sha256=Rt5MCUtPVYVQzNyjUx8magocPJpHV1svyuqQSTwUE-I,7306
|
77
|
-
schemathesis/generation/coverage.py,sha256=
|
77
|
+
schemathesis/generation/coverage.py,sha256=0iQZfm6yECy_nXatU3dCDCFI4lZW-IsiGZAiljptGUE,46362
|
78
78
|
schemathesis/generation/meta.py,sha256=36h6m4E7jzLGa8TCvl7eBl_xUWLiRul3qxzexl5cB58,2515
|
79
79
|
schemathesis/generation/modes.py,sha256=t_EvKr2aOXYMsEfdMu4lLF4KCGcX1LVVyvzTkcpJqhk,663
|
80
80
|
schemathesis/generation/overrides.py,sha256=FhqcFoliEvgW6MZyFPYemfLgzKt3Miy8Cud7OMOCb7g,3045
|
81
81
|
schemathesis/generation/targets.py,sha256=_rN2qgxTE2EfvygiN-Fy3WmDnRH0ERohdx3sKRDaYhU,2120
|
82
|
-
schemathesis/generation/hypothesis/__init__.py,sha256=
|
82
|
+
schemathesis/generation/hypothesis/__init__.py,sha256=SVwM-rx07jPZzms0idWYACgUtWAxh49HRuTnaQ__zf0,1549
|
83
83
|
schemathesis/generation/hypothesis/builder.py,sha256=QDfZRpFjQ0KYFPgu2BVSlxop0TQL7fQc201jOMR4rSQ,30472
|
84
84
|
schemathesis/generation/hypothesis/examples.py,sha256=6eGaKUEC3elmKsaqfKj1sLvM8EHc-PWT4NRBq4NI0Rs,1409
|
85
85
|
schemathesis/generation/hypothesis/given.py,sha256=sTZR1of6XaHAPWtHx2_WLlZ50M8D5Rjux0GmWkWjDq4,2337
|
@@ -146,8 +146,8 @@ schemathesis/transport/prepare.py,sha256=qQ6zXBw5NN2AIM0bzLAc5Ryc3dmMb0R6xN14lnR
|
|
146
146
|
schemathesis/transport/requests.py,sha256=j5wI1Uo_PnVuP1eV8l6ddsXosyxAPQ1mLSyWEZmTI9I,8747
|
147
147
|
schemathesis/transport/serialization.py,sha256=jIMra1LqRGav0OX3Hx7mvORt38ll4cd2DKit2D58FN0,10531
|
148
148
|
schemathesis/transport/wsgi.py,sha256=RWSuUXPrl91GxAy8a4jyNNozOWVMRBxKx_tljlWA_Lo,5697
|
149
|
-
schemathesis-4.0.
|
150
|
-
schemathesis-4.0.
|
151
|
-
schemathesis-4.0.
|
152
|
-
schemathesis-4.0.
|
153
|
-
schemathesis-4.0.
|
149
|
+
schemathesis-4.0.0a10.dist-info/METADATA,sha256=goxBn_HTzqqh7sSkqXpopuF5lT2tMxNJNcwyso9QtEQ,10428
|
150
|
+
schemathesis-4.0.0a10.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
151
|
+
schemathesis-4.0.0a10.dist-info/entry_points.txt,sha256=hiK3un-xfgPdwj9uj16YVDtTNpO128bmk0U82SMv8ZQ,152
|
152
|
+
schemathesis-4.0.0a10.dist-info/licenses/LICENSE,sha256=2Ve4J8v5jMQAWrT7r1nf3bI8Vflk3rZVQefiF2zpxwg,1121
|
153
|
+
schemathesis-4.0.0a10.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|