Skip to content

Commit 00a0c72

Browse files
authored
CSHARP-4799: Pipeline stage with BsonDocumentSearchDefinition can be rendered only once (#1188)
1 parent fa22217 commit 00a0c72

File tree

3 files changed

+95
-4
lines changed

3 files changed

+95
-4
lines changed

src/MongoDB.Driver/Search/SearchDefinition.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public BsonDocumentSearchDefinition(BsonDocument document)
7676

7777
/// <inheritdoc />
7878
public override BsonDocument Render(SearchDefinitionRenderContext<TDocument> renderContext) =>
79-
Document;
79+
(BsonDocument)Document.Clone();
8080
}
8181

8282
/// <summary>
@@ -86,7 +86,7 @@ public override BsonDocument Render(SearchDefinitionRenderContext<TDocument> ren
8686
public sealed class JsonSearchDefinition<TDocument> : SearchDefinition<TDocument>
8787
{
8888
/// <summary>
89-
/// Initializes a new instance of the <see cref="BsonDocumentSearchDefinition{TDocument}"/> class.
89+
/// Initializes a new instance of the <see cref="JsonSearchDefinition{TDocument}"/> class.
9090
/// </summary>
9191
/// <param name="json">The JSON string specifying the search definition.</param>
9292
public JsonSearchDefinition(string json)

tests/MongoDB.Driver.Tests/Search/SearchDefinitionBuilderTests.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ public void Equals_should_render_supported_type<T>(
306306
};
307307

308308
[Theory]
309-
[MemberData(nameof(EqualsUnsupporteddTypesTestData))]
309+
[MemberData(nameof(EqualsUnsupportedTypesTestData))]
310310
public void Equals_should_throw_on_unsupported_type<T>(T value, Expression<Func<Person, T>> fieldExpression) where T : struct, IComparable<T>
311311
{
312312
var subject = CreateSubject<BsonDocument>();
@@ -316,7 +316,7 @@ public void Equals_should_throw_on_unsupported_type<T>(T value, Expression<Func<
316316
Record.Exception(() => subjectTyped.Equals(fieldExpression, value)).Should().BeOfType<InvalidCastException>();
317317
}
318318

319-
public static object[][] EqualsUnsupporteddTypesTestData => new[]
319+
public static object[][] EqualsUnsupportedTypesTestData => new[]
320320
{
321321
new object[] { (ulong)1, Exp(p => p.UInt64) },
322322
new object[] { TimeSpan.Zero, Exp(p => p.TimeSpan) },
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
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+
using FluentAssertions;
17+
using MongoDB.Bson;
18+
using MongoDB.Bson.Serialization;
19+
using MongoDB.Driver.Search;
20+
using Xunit;
21+
22+
namespace MongoDB.Driver.Tests.Search
23+
{
24+
public class SearchDefinitionTests
25+
{
26+
[Theory]
27+
[InlineData(null)]
28+
[InlineData("{ operator: 'parameter' }")]
29+
public void BsonDocument_implicit_cast_should_create_BsonSearchDefinition(string searchDefinitionJson)
30+
{
31+
var searchDefinitionDocument = searchDefinitionJson != null ? BsonDocument.Parse(searchDefinitionJson) : null;
32+
var searchDefinition = (SearchDefinition<BsonDocument>)searchDefinitionDocument;
33+
34+
if (searchDefinitionJson == null)
35+
{
36+
searchDefinition.Should().BeNull();
37+
}
38+
else
39+
{
40+
var subject = searchDefinition.Should().BeOfType<BsonDocumentSearchDefinition<BsonDocument>>().Subject;
41+
subject.Document.Should().Be(searchDefinitionDocument);
42+
}
43+
}
44+
45+
[Fact]
46+
public void Pipeline_with_BsonDocumentSearchDefinition_should_render_correctly_multiple_times()
47+
{
48+
var searchOptions = new SearchOptions<BsonDocument>()
49+
{
50+
IndexName = "test",
51+
ScoreDetails = true,
52+
};
53+
54+
var document = new BsonDocument("operator", "parameter");
55+
var searchDefinition = (BsonDocumentSearchDefinition<BsonDocument>)document;
56+
57+
var pipeline = (new EmptyPipelineDefinition<BsonDocument>()).Search(searchDefinition, searchOptions);
58+
59+
var renderedPipeline = pipeline.Render(BsonSerializer.SerializerRegistry.GetSerializer<BsonDocument>(), BsonSerializer.SerializerRegistry);
60+
AssertStages();
61+
62+
renderedPipeline = pipeline.Render(BsonSerializer.SerializerRegistry.GetSerializer<BsonDocument>(), BsonSerializer.SerializerRegistry);
63+
AssertStages();
64+
65+
void AssertStages()
66+
{
67+
var stages = renderedPipeline.Documents;
68+
stages.Count.Should().Be(1);
69+
stages[0].Should().Be("{ $search: { operator: 'parameter', index: 'test', scoreDetails: true} }");
70+
}
71+
}
72+
73+
[Theory]
74+
[InlineData(null)]
75+
[InlineData("{ operator: 'parameter' }")]
76+
public void String_implicit_cast_should_create_JsonSearchDefinition(string searchDefinitionJson)
77+
{
78+
var searchDefinition = (SearchDefinition<BsonDocument>)searchDefinitionJson;
79+
80+
if (searchDefinitionJson == null)
81+
{
82+
searchDefinition.Should().BeNull();
83+
}
84+
else
85+
{
86+
var subject = searchDefinition.Should().BeOfType<JsonSearchDefinition<BsonDocument>>().Subject;
87+
subject.Json.Should().Be(searchDefinitionJson);
88+
}
89+
}
90+
}
91+
}

0 commit comments

Comments
 (0)