From 167c0c263f53bc8d4d18e37cb9dd713a299694d6 Mon Sep 17 00:00:00 2001 From: Ruth Lu <39782319+erasedbird@users.noreply.github.com> Date: Tue, 14 Jul 2026 20:47:12 -0400 Subject: [PATCH] Add initial bitOr tests (29 total, covering empty array inputs, null inputs, non-numerical, floats/doubles, nested, and field paths) Signed-off-by: Ruth Lu <39782319+erasedbird@users.noreply.github.com> --- .../bitwise/bitOr/test_bitOr_core.py | 101 ++++++++++++++++++ .../bitwise/bitOr/test_bitOr_input_forms.py | 88 +++++++++++++++ .../bitwise/bitOr/test_bitOr_non_numeric.py | 70 ++++++++++++ .../bitwise/bitOr/test_bitOr_null.py | 34 ++++++ .../bitwise/bitOr/test_bitOr_return_type.py | 47 ++++++++ .../bitwise/bitOr/utils/bitOr_common.py | 13 +++ 6 files changed, 353 insertions(+) create mode 100644 documentdb_tests/compatibility/tests/core/operator/expressions/bitwise/bitOr/test_bitOr_core.py create mode 100644 documentdb_tests/compatibility/tests/core/operator/expressions/bitwise/bitOr/test_bitOr_input_forms.py create mode 100644 documentdb_tests/compatibility/tests/core/operator/expressions/bitwise/bitOr/test_bitOr_non_numeric.py create mode 100644 documentdb_tests/compatibility/tests/core/operator/expressions/bitwise/bitOr/test_bitOr_null.py create mode 100644 documentdb_tests/compatibility/tests/core/operator/expressions/bitwise/bitOr/test_bitOr_return_type.py create mode 100644 documentdb_tests/compatibility/tests/core/operator/expressions/bitwise/bitOr/utils/bitOr_common.py diff --git a/documentdb_tests/compatibility/tests/core/operator/expressions/bitwise/bitOr/test_bitOr_core.py b/documentdb_tests/compatibility/tests/core/operator/expressions/bitwise/bitOr/test_bitOr_core.py new file mode 100644 index 000000000..d116d3f5b --- /dev/null +++ b/documentdb_tests/compatibility/tests/core/operator/expressions/bitwise/bitOr/test_bitOr_core.py @@ -0,0 +1,101 @@ +# handles all int types and inf/nan +from __future__ import annotations + +import pytest +from bson import Int64 + +from documentdb_tests.compatibility.tests.core.operator.expressions.bitwise.bitOr.utils.bitOr_common import ( # noqa: E501 + BitOrTest, +) +from documentdb_tests.compatibility.tests.core.operator.expressions.utils.utils import ( + assert_expression_result, + execute_expression, +) +from documentdb_tests.framework.parametrize import pytest_params + +BITOR_CORE_TESTS: list[BitOrTest] = [ + BitOrTest( + "core_single_int32", + args=42, + expected=42, + msg="$bitOr of a single int32 should return that value as an integer", + ), + BitOrTest( + "core_single_int64", + args=Int64(42), + expected=Int64(42), + msg="$bitOr of a single int64 should return that value as an integer", + ), + BitOrTest( + "core_two_equal", + args=[42, 42], + expected=42, + msg="$bitOr of two equal int32 values should return that value", + ), + BitOrTest( + "core_two_distinct", + args=[3, 5], + expected=7, + msg="$bitOr of two distinct int32 values should return the correct bitwise OR result", + ), + BitOrTest( + "core_empty_array", + args=[], + expected=0, + msg="$bitOr of an empty array should return 0", + ), + BitOrTest( + "core_int32_and_int64", + args=[3, Int64(5)], + expected=Int64(7), + msg="$bitOr of Int32 and Int64 returns an Int64", + ), + BitOrTest( + "core_negative", + args=[-1, -6], + expected=-1, + msg="$bitOr of negative numbers", + ), + BitOrTest( + "core_six_ints", + args=[1, 2, 3, 4, 5, 6], + expected=7, + msg="$bitOr of [1,2,3,4,5,6] should return 7", + ), + BitOrTest( + "core_four_ints", + args=[111, 222, 333, 444], + expected=511, + msg="$bitOr of [111,222,333,444] should return 511", + ), + BitOrTest( + "core_six_larger_ints", + args=[349, 1234, 44, 129308, 33, 2309], + expected=130559, + msg="$bitOr of [349,1234,44,129308,33,2309] should return 130559", + ), + BitOrTest( + "core_five_ints", + args=[2342, 23, 104, 253, 1035], + expected=3583, + msg="$bitOr of [2342,23,104,253,1035] should return 3583", + ), + BitOrTest( + "core_range_1_to_100", + args=list(range(1, 101)), + expected=127, + msg="$bitOr of integers 1 through 100 should return 127", + ), +] + + +@pytest.mark.parametrize("test_case", pytest_params(BITOR_CORE_TESTS)) +def test_bitOr_core(collection, test_case: BitOrTest): + """Test $bitOr cases.""" + result = execute_expression(collection, {"$bitOr": test_case.args}) + assert_expression_result( + result, + expected=test_case.expected, + error_code=test_case.error_code, + msg=test_case.msg, + ) diff --git a/documentdb_tests/compatibility/tests/core/operator/expressions/bitwise/bitOr/test_bitOr_input_forms.py b/documentdb_tests/compatibility/tests/core/operator/expressions/bitwise/bitOr/test_bitOr_input_forms.py new file mode 100644 index 000000000..260bb88a4 --- /dev/null +++ b/documentdb_tests/compatibility/tests/core/operator/expressions/bitwise/bitOr/test_bitOr_input_forms.py @@ -0,0 +1,88 @@ +# handle nested lists or literal evals to arrays +from __future__ import annotations + +import pytest + +from documentdb_tests.compatibility.tests.core.operator.expressions.bitwise.bitOr.utils.bitOr_common import ( # noqa: E501 + BitOrTest, +) +from documentdb_tests.compatibility.tests.core.operator.expressions.utils.expression_test_case import ( # noqa: E501 + ExpressionTestCase, +) +from documentdb_tests.compatibility.tests.core.operator.expressions.utils.utils import ( + assert_expression_result, + execute_expression, + execute_expression_with_insert, +) +from documentdb_tests.framework.error_codes import TYPE_MISMATCH_ERROR +from documentdb_tests.framework.parametrize import pytest_params + +FIELD_PATH_TESTS = [ + ExpressionTestCase( + "simple_field_refs", + expression={"$bitOr": ["$x", "$y", "$a", "$b"]}, + doc={"x": 23, "y": 1093, "a": 130942, "b": 90}, + expected=130943, + msg="$bitOr of simple field references should return the correct OR", + ), + ExpressionTestCase( + "nested_field_paths", + expression={"$bitOr": ["$x.y", "$a.b"]}, + doc={"x": {"y": 1093}, "a": {"b": 19304}}, + expected=20333, + msg="$bitOr of nested field paths should return the correct OR", + ), + ExpressionTestCase( + "array_index_path", + expression={"$bitOr": ["$a", "$b.0"]}, + doc={"a": 10, "b": [1, 2, 3, 4, 5]}, + expected=11, + msg="$bitOr with $b.0 should resolve to the first array element", + ), + ExpressionTestCase( + "field_is_array", + expression={"$bitOr": "$a"}, + doc={"a": [2043, 21, 940282, 1]}, + error_code=TYPE_MISMATCH_ERROR, + msg="$bitOr of an array leads to a mismatch", + ), +] + +NESTED_EXPR_TESTS: list[BitOrTest] = [ + BitOrTest( + "nested_bitor_args", + args=[{"$bitOr": [1, 2]}, {"$bitOr": [3, 4]}], + expected=7, + msg="$bitOr whose operands are themselves $bitOr expressions should return 7", + ), + BitOrTest( + "nested_bitor_mixed", + args=[10, {"$bitOr": [4, 6, 8, 22]}], + expected=30, + msg="$bitOr of a literal and a nested $bitOr should return 30", + ), +] + + +@pytest.mark.parametrize("test_case", pytest_params(FIELD_PATH_TESTS)) +def test_bitOr_field_paths(collection, test_case: ExpressionTestCase): + """Test $bitOr with field path inputs.""" + result = execute_expression_with_insert(collection, test_case.expression, test_case.doc) + assert_expression_result( + result, + expected=test_case.expected, + error_code=test_case.error_code, + msg=test_case.msg, + ) + + +@pytest.mark.parametrize("test_case", pytest_params(NESTED_EXPR_TESTS)) +def test_bitOr_nested_expressions(collection, test_case: BitOrTest): + """Test $bitOr with nested $bitOr expressions.""" + result = execute_expression(collection, {"$bitOr": test_case.args}) + assert_expression_result( + result, + expected=test_case.expected, + error_code=test_case.error_code, + msg=test_case.msg, + ) diff --git a/documentdb_tests/compatibility/tests/core/operator/expressions/bitwise/bitOr/test_bitOr_non_numeric.py b/documentdb_tests/compatibility/tests/core/operator/expressions/bitwise/bitOr/test_bitOr_non_numeric.py new file mode 100644 index 000000000..e8f1e091c --- /dev/null +++ b/documentdb_tests/compatibility/tests/core/operator/expressions/bitwise/bitOr/test_bitOr_non_numeric.py @@ -0,0 +1,70 @@ +# handle non numerics +from __future__ import annotations + +import math + +import pytest + +from documentdb_tests.compatibility.tests.core.operator.expressions.bitwise.bitOr.utils.bitOr_common import ( # noqa: E501 + BitOrTest, +) +from documentdb_tests.compatibility.tests.core.operator.expressions.utils.utils import ( + assert_expression_result, + execute_expression, +) +from documentdb_tests.framework.error_codes import TYPE_MISMATCH_ERROR +from documentdb_tests.framework.parametrize import pytest_params + +# In mongosh, whole-number literals (1.0) are sent as Int32; explicit Double types +# and fractional doubles are rejected. In Python, float values are always BSON Double, +# so all float inputs trigger TypeMismatch regardless of whether the value is whole. +BITOR_NON_NUMERIC_TESTS: list[BitOrTest] = [ + BitOrTest( + "strings_error", + args=["error", "should", "occur", 1], + error_code=TYPE_MISMATCH_ERROR, + msg="$bitOr with string operands should raise TypeMismatch", + ), + BitOrTest( + "double_whole_error", + args=[7.0, 8], + error_code=TYPE_MISMATCH_ERROR, + msg="$bitOr with a BSON Double operand should raise TypeMismatch", + ), + BitOrTest( + "double_fractional_error", + args=[1.0, 2.0, 3.1], + error_code=TYPE_MISMATCH_ERROR, + msg="$bitOr with a fractional double should raise TypeMismatch", + ), + BitOrTest( + "nan_error", + args=[1, 2, 3, math.nan], + error_code=TYPE_MISMATCH_ERROR, + msg="$bitOr with NaN should raise TypeMismatch", + ), + BitOrTest( + "inf_error", + args=[1, 2, 3, math.inf], + error_code=TYPE_MISMATCH_ERROR, + msg="$bitOr with positive infinity should raise TypeMismatch", + ), + BitOrTest( + "negative_inf_error", + args=[1, 2, 3, -math.inf], + error_code=TYPE_MISMATCH_ERROR, + msg="$bitOr with negative infinity should raise TypeMismatch", + ), +] + + +@pytest.mark.parametrize("test_case", pytest_params(BITOR_NON_NUMERIC_TESTS)) +def test_bitOr_non_numeric(collection, test_case: BitOrTest): + """Test $bitOr non-numeric input handling.""" + result = execute_expression(collection, {"$bitOr": test_case.args}) + assert_expression_result( + result, + expected=test_case.expected, + error_code=test_case.error_code, + msg=test_case.msg, + ) diff --git a/documentdb_tests/compatibility/tests/core/operator/expressions/bitwise/bitOr/test_bitOr_null.py b/documentdb_tests/compatibility/tests/core/operator/expressions/bitwise/bitOr/test_bitOr_null.py new file mode 100644 index 000000000..4ea18fb3a --- /dev/null +++ b/documentdb_tests/compatibility/tests/core/operator/expressions/bitwise/bitOr/test_bitOr_null.py @@ -0,0 +1,34 @@ +# handle null by returning null +from __future__ import annotations + +import pytest + +from documentdb_tests.compatibility.tests.core.operator.expressions.bitwise.bitOr.utils.bitOr_common import ( # noqa: E501 + BitOrTest, +) +from documentdb_tests.compatibility.tests.core.operator.expressions.utils.utils import ( + assert_expression_result, + execute_expression, +) +from documentdb_tests.framework.parametrize import pytest_params + +BITOR_NULL_TESTS: list[BitOrTest] = [ + BitOrTest( + "null_in_array", + args=[1, 2, 3, None], + expected=None, + msg="$bitOr with null in the operand array should return null", + ), +] + + +@pytest.mark.parametrize("test_case", pytest_params(BITOR_NULL_TESTS)) +def test_bitOr_null(collection, test_case: BitOrTest): + """Test $bitOr null handling.""" + result = execute_expression(collection, {"$bitOr": test_case.args}) + assert_expression_result( + result, + expected=test_case.expected, + error_code=test_case.error_code, + msg=test_case.msg, + ) diff --git a/documentdb_tests/compatibility/tests/core/operator/expressions/bitwise/bitOr/test_bitOr_return_type.py b/documentdb_tests/compatibility/tests/core/operator/expressions/bitwise/bitOr/test_bitOr_return_type.py new file mode 100644 index 000000000..2d3204e28 --- /dev/null +++ b/documentdb_tests/compatibility/tests/core/operator/expressions/bitwise/bitOr/test_bitOr_return_type.py @@ -0,0 +1,47 @@ +# handle returning ints or longs +from __future__ import annotations + +import pytest +from bson import Int64 + +from documentdb_tests.compatibility.tests.core.operator.expressions.bitwise.bitOr.utils.bitOr_common import ( # noqa: E501 + BitOrTest, +) +from documentdb_tests.compatibility.tests.core.operator.expressions.utils.utils import ( + assert_expression_result, + execute_expression, +) +from documentdb_tests.framework.parametrize import pytest_params + +BITOR_RETURN_TYPE_TESTS: list[BitOrTest] = [ + BitOrTest( + "return_type_int32", + args=[3, 5], + expected=7, + msg="$bitOr of Int32 values should return Int32", + ), + BitOrTest( + "return_type_all_int64", + args=[Int64(23), Int64(24), Int64(12), Int64(14)], + expected=Int64(31), + msg="$bitOr of all Int64 values should return Int64", + ), + BitOrTest( + "return_type_mixed_int32_int64", + args=[43, 13, 2498, Int64(55)], + expected=Int64(2559), + msg="$bitOr of mixed Int32 and Int64 values should return Int64", + ), +] + + +@pytest.mark.parametrize("test_case", pytest_params(BITOR_RETURN_TYPE_TESTS)) +def test_bitOr_return_type(collection, test_case: BitOrTest): + """Test $bitOr return type.""" + result = execute_expression(collection, {"$bitOr": test_case.args}) + assert_expression_result( + result, + expected=test_case.expected, + error_code=test_case.error_code, + msg=test_case.msg, + ) diff --git a/documentdb_tests/compatibility/tests/core/operator/expressions/bitwise/bitOr/utils/bitOr_common.py b/documentdb_tests/compatibility/tests/core/operator/expressions/bitwise/bitOr/utils/bitOr_common.py new file mode 100644 index 000000000..f9bbd415d --- /dev/null +++ b/documentdb_tests/compatibility/tests/core/operator/expressions/bitwise/bitOr/utils/bitOr_common.py @@ -0,0 +1,13 @@ +from __future__ import annotations + +from dataclasses import dataclass +from typing import Any + +from documentdb_tests.framework.test_case import BaseTestCase + + +@dataclass(frozen=True) +class BitOrTest(BaseTestCase): + """Test case for $bitOr operator.""" + + args: Any = None