Skip to content

Commit 2873762

Browse files
committed
CSHARP-4332: Verify that the examples work in LINQ3 to the extent possible.
1 parent 4852bb4 commit 2873762

File tree

1 file changed

+160
-0
lines changed

1 file changed

+160
-0
lines changed
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
/* Copyright 2010-present MongoDB Inc.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
#if NET6_0_OR_GREATER // because tests use readonly record struct
17+
using System;
18+
using System.Collections.Generic;
19+
using System.Linq;
20+
using System.Linq.Expressions;
21+
using FluentAssertions;
22+
using MongoDB.Bson;
23+
using MongoDB.Bson.Serialization;
24+
using MongoDB.Bson.Serialization.Attributes;
25+
using MongoDB.Bson.Serialization.Serializers;
26+
using MongoDB.Driver.Linq;
27+
using Xunit;
28+
29+
namespace MongoDB.Driver.Tests.Linq.Linq3ImplementationTests.Jira
30+
{
31+
public class CSharp4332Tests : Linq3IntegrationTest
32+
{
33+
private static readonly (Expression<Func<Document, bool>> Predicate, string ExpectedFilter)[] __testCases;
34+
35+
static CSharp4332Tests()
36+
{
37+
var guid = Guid.Parse("0102030405060708090a0b0c0d0e0f10");
38+
var invoiceId = new InvoiceId(guid);
39+
var guidNullable = (Guid?)guid;
40+
var invoiceIdNullable = (InvoiceId?)invoiceId;
41+
42+
__testCases = new (Expression<Func<Document, bool>> Predicate, string ExpectedFilter)[]
43+
{
44+
(c => c.Guid == guid, "{ Guid : '01020304-0506-0708-090a-0b0c0d0e0f10' }"),
45+
(c => c.GuidNullable == guid, "{ GuidNullable : '01020304-0506-0708-090a-0b0c0d0e0f10' }"),
46+
(c => c.Guid == invoiceId, "{ Guid : '01020304-0506-0708-090a-0b0c0d0e0f10' }"),
47+
(c => c.GuidNullable == invoiceId, "{ GuidNullable : '01020304-0506-0708-090a-0b0c0d0e0f10' }"),
48+
(c => c.InvoiceId == invoiceId, "{ InvoiceId : '01020304-0506-0708-090a-0b0c0d0e0f10' }"),
49+
(c => c.InvoiceIdNullable == invoiceId, "{ InvoiceIdNullable : '01020304-0506-0708-090a-0b0c0d0e0f10' }"),
50+
51+
(c => c.Guid == guidNullable, "{ Guid : '01020304-0506-0708-090a-0b0c0d0e0f10' }"),
52+
(c => c.GuidNullable == guidNullable, "{ GuidNullable : '01020304-0506-0708-090a-0b0c0d0e0f10' }"),
53+
(c => c.Guid == invoiceIdNullable, "{ Guid : '01020304-0506-0708-090a-0b0c0d0e0f10' }"),
54+
(c => c.GuidNullable == invoiceIdNullable, "{ GuidNullable : '01020304-0506-0708-090a-0b0c0d0e0f10' }"),
55+
(c => c.InvoiceId == invoiceIdNullable, "{ InvoiceId : '01020304-0506-0708-090a-0b0c0d0e0f10' }"),
56+
(c => c.InvoiceIdNullable == invoiceIdNullable, "{ InvoiceIdNullable : '01020304-0506-0708-090a-0b0c0d0e0f10' }"),
57+
58+
(c => c.InvoiceId == new InvoiceId(guidNullable.Value), "{ InvoiceId : '01020304-0506-0708-090a-0b0c0d0e0f10' }"),
59+
(c => c.InvoiceIdNullable == (guidNullable.HasValue ? new InvoiceId(guidNullable.Value) : null), "{ InvoiceIdNullable : '01020304-0506-0708-090a-0b0c0d0e0f10' }"),
60+
(c => c.InvoiceId == new InvoiceId(guid), "{ InvoiceId : '01020304-0506-0708-090a-0b0c0d0e0f10' }"),
61+
(c => c.InvoiceIdNullable == new InvoiceId(guid), "{ InvoiceIdNullable : '01020304-0506-0708-090a-0b0c0d0e0f10' }"),
62+
};
63+
}
64+
65+
[Theory]
66+
[MemberData(nameof(GetTestCases))]
67+
public void Where_expression_should_work(string predicateAsString, string expectedFilter, int i)
68+
{
69+
var collection = CreateCollection();
70+
var predicate = __testCases[i].Predicate;
71+
72+
var queryable = collection.AsQueryable().Where(predicate);
73+
74+
var stages = Translate(collection, queryable);
75+
var filter = stages.Single()["$match"];
76+
filter.Should().Be(expectedFilter);
77+
78+
var results = queryable.ToList();
79+
results.Single().Id.Should().Be(1);
80+
}
81+
82+
public static IEnumerable<object[]> GetTestCases()
83+
{
84+
for (var i = 0; i < __testCases.Length; i++)
85+
{
86+
var predicateAsString = __testCases[0].Predicate.ToString();
87+
var expectedFilter = __testCases[i].ExpectedFilter;
88+
yield return new object[] { predicateAsString, expectedFilter, i };
89+
}
90+
}
91+
92+
private IMongoCollection<Document> CreateCollection()
93+
{
94+
var collection = GetCollection<Document>("C") ;
95+
96+
var guid = Guid.Parse("0102030405060708090a0b0c0d0e0f10");
97+
var invoiceId = new InvoiceId(guid);
98+
var guidNullable = (Guid?)guid;
99+
var invoiceIdNullable = (InvoiceId?)invoiceId;
100+
101+
CreateCollection(
102+
collection,
103+
new Document
104+
{
105+
Id = 1,
106+
Guid = guid,
107+
GuidNullable = guidNullable,
108+
InvoiceId = invoiceId,
109+
InvoiceIdNullable = invoiceIdNullable
110+
});
111+
112+
return collection;
113+
}
114+
115+
public class Document
116+
{
117+
public int Id { get; set; }
118+
119+
[BsonRepresentation(BsonType.String)]
120+
public Guid Guid { get; set; }
121+
122+
[BsonRepresentation(BsonType.String)]
123+
public Guid? GuidNullable { get; set; }
124+
125+
public InvoiceId InvoiceId { get; set; }
126+
public InvoiceId? InvoiceIdNullable { get; set; }
127+
}
128+
129+
[BsonSerializer(typeof(InvoiceIdSerializer))]
130+
public readonly record struct InvoiceId(Guid Value)
131+
{
132+
public static implicit operator Guid(InvoiceId s) => s.Value;
133+
}
134+
135+
public class InvoiceIdSerializer : SerializerBase<InvoiceId>
136+
{
137+
public override InvoiceId Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
138+
{
139+
if (context.Reader.CurrentBsonType == BsonType.Null)
140+
{
141+
context.Reader.ReadNull();
142+
return default;
143+
}
144+
145+
if (Guid.TryParse(context.Reader.ReadString(), out var guid))
146+
{
147+
return new InvoiceId(guid);
148+
}
149+
150+
return new InvoiceId(default);
151+
}
152+
153+
public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, InvoiceId value)
154+
{
155+
context.Writer.WriteString(value.Value.ToString());
156+
}
157+
}
158+
}
159+
}
160+
#endif

0 commit comments

Comments
 (0)