-
Notifications
You must be signed in to change notification settings - Fork 97
LCORE-2400: tests for exclusiveMinimum and anyOf #1834
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -90,6 +90,107 @@ def test_recursive_recurse_into_subdicts() -> None: | |
| assert result is not original | ||
|
|
||
|
|
||
| def test_exclusive_minimum_handling_positive_value() -> None: | ||
| """Test how minimum integer value description is transformed by recursive_update function.""" | ||
| original = { | ||
| "type": "object", | ||
| "properties": { | ||
| "name": {"type": "string"}, | ||
| "age": {"type": "integer", "exclusiveMinimum": 100}, | ||
| }, | ||
| } | ||
| expected = { | ||
| "type": "object", | ||
| "properties": { | ||
| "name": {"type": "string"}, | ||
| "age": {"type": "integer", "minimum": 100}, | ||
| }, | ||
| } | ||
|
|
||
| # perform the update | ||
| result = recursive_update(original) | ||
|
|
||
| # non-empty dict with known content should be returned | ||
| assert result == expected | ||
|
|
||
| # ensure a new dict is returned, not the same object | ||
| assert result is not original | ||
|
|
||
|
|
||
| def test_exclusive_minimum_handling_zero_value() -> None: | ||
| """Test how minimum integer value description is transformed by recursive_update function.""" | ||
| original = { | ||
| "type": "object", | ||
| "properties": { | ||
| "name": {"type": "string"}, | ||
| "age": {"type": "integer", "exclusiveMinimum": 0}, | ||
| }, | ||
| } | ||
| expected = { | ||
| "type": "object", | ||
| "properties": { | ||
| "name": {"type": "string"}, | ||
| "age": {"type": "integer", "minimum": 0}, | ||
| }, | ||
| } | ||
|
|
||
| # perform the update | ||
| result = recursive_update(original) | ||
|
|
||
| # non-empty dict with known content should be returned | ||
| assert result == expected | ||
|
|
||
| # ensure a new dict is returned, not the same object | ||
| assert result is not original | ||
|
|
||
|
|
||
| def test_exclusive_minimum_handling_negative_value() -> None: | ||
| """Test how minimum integer value description is transformed by recursive_update function.""" | ||
| original = { | ||
| "type": "object", | ||
| "properties": { | ||
| "name": {"type": "string"}, | ||
| "age": {"type": "integer", "exclusiveMinimum": -100}, | ||
| }, | ||
| } | ||
| expected = { | ||
| "type": "object", | ||
| "properties": { | ||
| "name": {"type": "string"}, | ||
| "age": {"type": "integer", "minimum": -100}, | ||
| }, | ||
| } | ||
|
|
||
| # perform the update | ||
| result = recursive_update(original) | ||
|
|
||
| # non-empty dict with known content should be returned | ||
| assert result == expected | ||
|
|
||
| # ensure a new dict is returned, not the same object | ||
| assert result is not original | ||
|
|
||
|
|
||
| def test_anyof_with_null_transformed_to_nullable() -> None: | ||
| """Test how the de-facto Optional type is transformed.""" | ||
| original = { | ||
| "anyOf": [ | ||
| {"type": "string"}, | ||
| {"type": "null"}, | ||
| ] | ||
| } | ||
| expected = { | ||
| "type": "string", | ||
| "nullable": True, | ||
| } | ||
|
|
||
| # perform the update | ||
| result = recursive_update(original) | ||
|
|
||
| # non-empty dict with known content should be returned | ||
| assert result == expected | ||
|
|
||
|
Comment on lines
+174
to
+192
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add missing immutability assertion. Unlike the other tests in this file (lines 117, 144, 171), this test is missing the assertion 📝 Proposed fix # non-empty dict with known content should be returned
assert result == expected
+
+ # ensure a new dict is returned, not the same object
+ assert result is not original🤖 Prompt for AI Agents |
||
|
|
||
| def test_handles_none_values() -> None: | ||
| """None values should be preserved.""" | ||
| original = {"key": None} | ||
|
|
||
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.
🧹 Nitpick | 🔵 Trivial | ⚡ Quick win
Consider using
pytest.mark.parametrizeto reduce code duplication.The three
exclusiveMinimumtests differ only by the test value (100, 0, -100). You can consolidate them into a single parametrized test to improve maintainability and make it easier to add more test cases.♻️ Proposed refactor using parametrization
📝 Committable suggestion
🤖 Prompt for AI Agents
🧩 Analysis chain
🏁 Script executed:
Repository: lightspeed-core/lightspeed-stack
Length of output: 9608
🏁 Script executed:
Repository: lightspeed-core/lightspeed-stack
Length of output: 119
🏁 Script executed:
Repository: lightspeed-core/lightspeed-stack
Length of output: 3512
🏁 Script executed:
Repository: lightspeed-core/lightspeed-stack
Length of output: 2434
🏁 Script executed:
Repository: lightspeed-core/lightspeed-stack
Length of output: 2745
🏁 Script executed:
Repository: lightspeed-core/lightspeed-stack
Length of output: 6836
🏁 Script executed:
Repository: lightspeed-core/lightspeed-stack
Length of output: 2735
🏁 Script executed:
Repository: lightspeed-core/lightspeed-stack
Length of output: 4848
🌐 Web query:
OpenAPI 3.0 exclusiveMinimum boolean or number semantics💡 Result:
In OpenAPI 3.0, the
exclusiveMinimumandexclusiveMaximumkeywords are defined as boolean values [1][2]. To use them correctly in OpenAPI 3.0: -exclusiveMinimum: trueindicates that the value must be strictly greater than the value specified byminimum[1][3]. - IfexclusiveMinimumisfalseor omitted, the constraint is inclusive, meaning the value must be greater than or equal tominimum[1][3]. This behavior differs significantly from OpenAPI 3.1, whereexclusiveMinimumandexclusiveMaximumare defined as numbers rather than booleans [2][4][5]. In OpenAPI 3.1, these fields replace the separateminimum/maximumkeywords to specify the exclusive boundary directly (e.g.,exclusiveMinimum: 0means the value must be greater than 0) [4][5]. If you are working with OpenAPI 3.0, you must continue to use bothminimum(to set the threshold) andexclusiveMinimum: true(to change the behavior to exclusive) [1][5]. Using a number forexclusiveMinimumin an OpenAPI 3.0 document will often cause validation errors in tools that strictly adhere to the 3.0 specification [2][5].Citations:
🏁 Script executed:
Repository: lightspeed-core/lightspeed-stack
Length of output: 1476
Fix
exclusiveMinimumtransformation to preserve strict bounds in OpenAPI/JSON Schemasrc/utils/schema_dumper.pyreplacesexclusiveMinimumwithminimum(recursive_update:new["minimum"] = value) without applying OpenAPI 3.0’sexclusiveMinimum: trueflag or adjusting the numeric boundary, which changes validation semantics from strict (> N) to inclusive (>= N).tests/unit/utils/test_schema_dumper.py(lines 93-172) encode this direct mapping (exclusiveMinimum: X→minimum: X), locking in the semantic mismatch.test_anyof_with_null_transformed_to_nullable(lines 174-192) is missing theassert result is not originalimmutability assertion present in the other tests.🤖 Prompt for AI Agents