From 16f231b46b844d421c22950e7ec21b4761a9381c Mon Sep 17 00:00:00 2001 From: adelinowona Date: Thu, 17 Jul 2025 03:18:30 -0400 Subject: [PATCH 1/2] CSHARP-5391: Add spec test for $$type operator with "number" --- .../operator-type-number_alias.json | 174 ++++++++++++++++++ .../valid-pass/operator-type-number_alias.yml | 61 ++++++ .../Matchers/UnifiedValueMatcher.cs | 20 +- 3 files changed, 250 insertions(+), 5 deletions(-) create mode 100644 specifications/unified-test-format/tests/valid-pass/operator-type-number_alias.json create mode 100644 specifications/unified-test-format/tests/valid-pass/operator-type-number_alias.yml diff --git a/specifications/unified-test-format/tests/valid-pass/operator-type-number_alias.json b/specifications/unified-test-format/tests/valid-pass/operator-type-number_alias.json new file mode 100644 index 00000000000..e628d0d7773 --- /dev/null +++ b/specifications/unified-test-format/tests/valid-pass/operator-type-number_alias.json @@ -0,0 +1,174 @@ +{ + "description": "operator-type-number_alias", + "schemaVersion": "1.0", + "createEntities": [ + { + "client": { + "id": "client0" + } + }, + { + "database": { + "id": "database0", + "client": "client0", + "databaseName": "test" + } + }, + { + "collection": { + "id": "collection0", + "database": "database0", + "collectionName": "coll0" + } + } + ], + "initialData": [ + { + "collectionName": "coll0", + "databaseName": "test", + "documents": [] + } + ], + "tests": [ + { + "description": "type number alias matches int32", + "operations": [ + { + "name": "insertOne", + "object": "collection0", + "arguments": { + "document": { + "_id": 1, + "x": { + "$numberInt": "2147483647" + } + } + } + }, + { + "name": "find", + "object": "collection0", + "arguments": { + "filter": { + "_id": 1 + }, + "limit": 1 + }, + "expectResult": [ + { + "_id": 1, + "x": { + "$$type": "number" + } + } + ] + } + ] + }, + { + "description": "type number alias matches int64", + "operations": [ + { + "name": "insertOne", + "object": "collection0", + "arguments": { + "document": { + "_id": 1, + "x": { + "$numberLong": "9223372036854775807" + } + } + } + }, + { + "name": "find", + "object": "collection0", + "arguments": { + "filter": { + "_id": 1 + }, + "limit": 1 + }, + "expectResult": [ + { + "_id": 1, + "x": { + "$$type": "number" + } + } + ] + } + ] + }, + { + "description": "type number alias matches double", + "operations": [ + { + "name": "insertOne", + "object": "collection0", + "arguments": { + "document": { + "_id": 1, + "x": { + "$numberDouble": "2.71828" + } + } + } + }, + { + "name": "find", + "object": "collection0", + "arguments": { + "filter": { + "_id": 1 + }, + "limit": 1 + }, + "expectResult": [ + { + "_id": 1, + "x": { + "$$type": "number" + } + } + ] + } + ] + }, + { + "description": "type number alias matches decimal128", + "operations": [ + { + "name": "insertOne", + "object": "collection0", + "arguments": { + "document": { + "_id": 1, + "x": { + "$numberDecimal": "3.14159" + } + } + } + }, + { + "name": "find", + "object": "collection0", + "arguments": { + "filter": { + "_id": 1 + }, + "limit": 1 + }, + "expectResult": [ + { + "_id": 1, + "x": { + "$$type": "number" + } + } + ] + } + ] + } + ] +} diff --git a/specifications/unified-test-format/tests/valid-pass/operator-type-number_alias.yml b/specifications/unified-test-format/tests/valid-pass/operator-type-number_alias.yml new file mode 100644 index 00000000000..04357a0242c --- /dev/null +++ b/specifications/unified-test-format/tests/valid-pass/operator-type-number_alias.yml @@ -0,0 +1,61 @@ +description: operator-type-number_alias + +schemaVersion: "1.0" + +createEntities: + - client: + id: &client0 client0 + - database: + id: &database0 database0 + client: *client0 + databaseName: &database0Name test + - collection: + id: &collection0 collection0 + database: *database0 + collectionName: &collection0Name coll0 + +initialData: + - collectionName: *collection0Name + databaseName: *database0Name + documents: [] + +tests: + - + description: type number alias matches int32 + operations: + - name: insertOne + object: *collection0 + arguments: + document: { _id: 1, x: { $numberInt: "2147483647" } } + - &find + name: find + object: *collection0 + arguments: + filter: { _id: 1 } + limit: 1 + expectResult: + - { _id: 1, x: { $$type: "number" } } + - + description: type number alias matches int64 + operations: + - name: insertOne + object: *collection0 + arguments: + document: { _id: 1, x: { $numberLong: "9223372036854775807" } } + - *find + - + description: type number alias matches double + operations: + - name: insertOne + object: *collection0 + arguments: + document: { _id: 1, x: { $numberDouble: "2.71828" } } + - *find + - + description: type number alias matches decimal128 + operations: + - name: insertOne + object: *collection0 + arguments: + document: { _id: 1, x: { $numberDecimal: "3.14159" } } + - *find diff --git a/tests/MongoDB.Driver.Tests/UnifiedTestOperations/Matchers/UnifiedValueMatcher.cs b/tests/MongoDB.Driver.Tests/UnifiedTestOperations/Matchers/UnifiedValueMatcher.cs index a31bb3ede08..ab68daa0a12 100644 --- a/tests/MongoDB.Driver.Tests/UnifiedTestOperations/Matchers/UnifiedValueMatcher.cs +++ b/tests/MongoDB.Driver.Tests/UnifiedTestOperations/Matchers/UnifiedValueMatcher.cs @@ -14,6 +14,7 @@ */ using System; +using System.Collections; using System.Collections.Generic; using System.Linq; using FluentAssertions; @@ -27,6 +28,7 @@ namespace MongoDB.Driver.Tests.UnifiedTestOperations.Matchers public class UnifiedValueMatcher { private UnifiedEntityMap _entityMap; + private static readonly HashSet NumericTypes = ["int", "long", "double", "decimal"]; public UnifiedValueMatcher(UnifiedEntityMap entityMap) { @@ -193,22 +195,30 @@ private void AssertValuesMatch(BsonValue actual, BsonValue expected, bool isRoot private void AssertExpectedType(BsonValue actual, BsonValue expectedTypes) { var actualTypeName = GetBsonTypeNameAsString(actual.BsonType); - List expectedTypeNames; if (expectedTypes.IsString) { - expectedTypeNames = new List { expectedTypes.AsString }; + var expectedType = expectedTypes.AsString; + if (expectedType == "number") + { + NumericTypes.Should().Contain(actualTypeName); + } + else + { + actualTypeName.Should().Be(expectedType); + } } else if (expectedTypes.IsBsonArray) { - expectedTypeNames = expectedTypes.AsBsonArray.Select(t => t.AsString).ToList(); + expectedTypes.AsBsonArray.Any(t => + t.AsString == actualTypeName || + (t.AsString == "number" && NumericTypes.Contains(actualTypeName))) + .Should().BeTrue(); } else { throw new FormatException($"Unexpected $$type value BsonType: '{expectedTypes.BsonType}'."); } - - actualTypeName.Should().BeOneOf(expectedTypeNames); } private string GetBsonTypeNameAsString(BsonType bsonType) From 7eb9140e4198a7ec38a788327997738e44a1496c Mon Sep 17 00:00:00 2001 From: adelinowona Date: Tue, 22 Jul 2025 13:15:59 -0400 Subject: [PATCH 2/2] address pr comments --- .../Matchers/UnifiedValueMatcher.cs | 20 +++++++------------ 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/tests/MongoDB.Driver.Tests/UnifiedTestOperations/Matchers/UnifiedValueMatcher.cs b/tests/MongoDB.Driver.Tests/UnifiedTestOperations/Matchers/UnifiedValueMatcher.cs index ab68daa0a12..a02f9df732c 100644 --- a/tests/MongoDB.Driver.Tests/UnifiedTestOperations/Matchers/UnifiedValueMatcher.cs +++ b/tests/MongoDB.Driver.Tests/UnifiedTestOperations/Matchers/UnifiedValueMatcher.cs @@ -27,8 +27,9 @@ namespace MongoDB.Driver.Tests.UnifiedTestOperations.Matchers { public class UnifiedValueMatcher { + private static readonly List __numericTypes = ["int", "long", "double", "decimal"]; + private UnifiedEntityMap _entityMap; - private static readonly HashSet NumericTypes = ["int", "long", "double", "decimal"]; public UnifiedValueMatcher(UnifiedEntityMap entityMap) { @@ -195,30 +196,23 @@ private void AssertValuesMatch(BsonValue actual, BsonValue expected, bool isRoot private void AssertExpectedType(BsonValue actual, BsonValue expectedTypes) { var actualTypeName = GetBsonTypeNameAsString(actual.BsonType); + List expectedTypeNames; if (expectedTypes.IsString) { var expectedType = expectedTypes.AsString; - if (expectedType == "number") - { - NumericTypes.Should().Contain(actualTypeName); - } - else - { - actualTypeName.Should().Be(expectedType); - } + expectedTypeNames = expectedType == "number" ? __numericTypes : [expectedType]; } else if (expectedTypes.IsBsonArray) { - expectedTypes.AsBsonArray.Any(t => - t.AsString == actualTypeName || - (t.AsString == "number" && NumericTypes.Contains(actualTypeName))) - .Should().BeTrue(); + expectedTypeNames = expectedTypes.AsBsonArray.Select(t => t.AsString).ToList(); } else { throw new FormatException($"Unexpected $$type value BsonType: '{expectedTypes.BsonType}'."); } + + actualTypeName.Should().BeOneOf(expectedTypeNames); } private string GetBsonTypeNameAsString(BsonType bsonType)