public async Task BsonDocumentTypeProjectionTest() { string lookupName = $"NotFirst_{1}"; var query = new Pipeline() + new Projection(new string[] { nameof(TestDocument.FirstName), nameof(TestDocument.LastName) }) + new OrderBy(DirectionType.Descending, nameof(TestDocument.FirstName)); var findResult = await Utility.Database.GetCollection <BsonDocument>(Utility.CollectionName).Find(_workContext, query); List <BsonDocument> resultDocuments = findResult.ToList(); resultDocuments.Should().NotBeNull(); resultDocuments.Count.Should().Be(Utility.Count); int index = 0; foreach (var item in Utility.TestDocuments.OrderByDescending(x => x.Index)) { BsonValue value = resultDocuments[index++][nameof(TestDocument.FirstName)]; value.Should().NotBeNull(); value.AsString.Should().Be(item.FirstName); } }
//[DebuggerHidden] public static void ExpectJson(this BsonValue value, string expectJson) { value.Should().Be((JsonSerializer.Deserialize(expectJson))); }
//[DebuggerHidden] public static void ExpectArray(this BsonValue value, params BsonValue[] args) { value.Should().Be(new BsonArray(args)); }
//[DebuggerHidden] public static void ExpectValue(this BsonValue value, BsonValue expect) { value.Should().Be(expect); }
private void AssertValuesMatch(BsonValue actual, BsonValue expected, bool isRoot, bool isRecursiveCall = true) { if (expected.IsBsonDocument && expected.AsBsonDocument.ElementCount == 1 && expected.AsBsonDocument.GetElement(0).Name.StartsWith("$$")) { var specialOperatorDocument = expected.AsBsonDocument; var operatorName = specialOperatorDocument.GetElement(0).Name; var operatorValue = specialOperatorDocument[0]; switch (operatorName) { case "$$exists": actual.Should().NotBeNull(); break; case "$$type": AssertExpectedType(actual, operatorValue); break; case "$$matchesHexBytes": AssertValuesMatch(actual, operatorValue, true); break; case "$$unsetOrMatches": if (actual != null) { AssertValuesMatch(actual, operatorValue, true); } break; default: throw new FormatException($"Unrecognized root level special operator: '{operatorName}'."); } return; } if (expected.IsBsonDocument) { actual.BsonType.Should().Be(BsonType.Document); var expectedDocument = expected.AsBsonDocument; var actualDocument = actual.AsBsonDocument; foreach (var expectedElement in expectedDocument) { var expectedName = expectedElement.Name; var expectedValue = expectedElement.Value; if (expectedValue.IsBsonDocument && expectedValue.AsBsonDocument.ElementCount == 1 && expectedValue.AsBsonDocument.GetElement(0).Name.StartsWith("$$")) { var specialOperatorDocument = expectedValue.AsBsonDocument; var operatorName = specialOperatorDocument.GetElement(0).Name; var operatorValue = specialOperatorDocument[0]; switch (operatorName) { case "$$exists": if (operatorValue.AsBoolean) { actualDocument.Names.Should().Contain(expectedName); } else { actualDocument.Names.Should().NotContain(expectedName); } continue; case "$$type": actualDocument.Names.Should().Contain(expectedName); AssertExpectedType(actualDocument[expectedName], operatorValue); continue; case "$$matchesEntity": var resultId = operatorValue.AsString; expectedValue = _entityMap.GetResult(resultId); break; case "$$matchesHexBytes": expectedValue = operatorValue; break; case "$$unsetOrMatches": if (!actualDocument.Contains(expectedName)) { continue; } expectedValue = operatorValue; break; case "$$sessionLsid": var sessionId = operatorValue.AsString; expectedValue = _entityMap.GetSessionId(sessionId); break; default: throw new FormatException($"Unrecognized special operator: '{operatorName}'."); } } actualDocument.Names.Should().Contain(expectedName); AssertValuesMatch(actualDocument[expectedName], expectedValue, isRoot: false); } if (!isRoot) { actualDocument.Names.Should().BeSubsetOf(expectedDocument.Names); } } else if (expected.IsBsonArray) { actual.BsonType.Should().Be(BsonType.Array); actual.AsBsonArray.Values.Should().HaveSameCount(expected.AsBsonArray.Values); var expectedArray = expected.AsBsonArray; var actualArray = actual.AsBsonArray; for (int i = 0; i < expectedArray.Count; i++) { AssertValuesMatch(actualArray[i], expectedArray[i], isRoot: isRoot && !isRecursiveCall); } } else if (expected.IsNumeric) { actual.IsNumeric.Should().BeTrue(); actual.ToDouble().Should().Be(expected.ToDouble()); } else { actual.BsonType.Should().Be(expected.BsonType); actual.Should().Be(expected); } }