Skip to content

Commit

Permalink
CR Changes.
Browse files Browse the repository at this point in the history
  • Loading branch information
craiggwilson committed Mar 2, 2015
1 parent 100cdfc commit 531e7b6
Show file tree
Hide file tree
Showing 13 changed files with 194 additions and 33 deletions.
2 changes: 1 addition & 1 deletion src/MongoDB.Driver.Tests/FilterBuilderTests.cs
Expand Up @@ -179,7 +179,7 @@ public void Exists_Typed()
public void Expression()
{
var subject = CreateSubject<Person>();
Assert(subject.Expression(x => x.FirstName == "Jack" && x.Age > 10), "{fn: 'Jack', age: {$gt: 10}}");
Assert(subject.Where(x => x.FirstName == "Jack" && x.Age > 10), "{fn: 'Jack', age: {$gt: 10}}");
}

[Test]
Expand Down
23 changes: 17 additions & 6 deletions src/MongoDB.Driver.Tests/IndexDefinitionBuilderTests.cs
Expand Up @@ -13,6 +13,7 @@
* limitations under the License.
*/

using System;
using FluentAssertions;
using MongoDB.Bson;
using MongoDB.Bson.Serialization;
Expand Down Expand Up @@ -62,7 +63,9 @@ public void Combine_with_repeated_fields()
"{a: 1, b: -1}",
subject.Descending("a"));

Assert(definition, "{b: -1, a: -1}");
Action act = () => Render(definition);

act.ShouldThrow<MongoException>();
}

[Test]
Expand All @@ -83,11 +86,14 @@ public void Combine_with_repeated_fields_using_extension_methods()
{
var subject = CreateSubject<BsonDocument>();

var sort = subject.Ascending("a")
.Descending("b")
var definition = subject.Ascending("a")
.Ascending("b")
.Descending("c")
.Descending("a");

Assert(sort, "{b: -1, a: -1}");
Action act = () => Render(definition);

act.ShouldThrow<MongoException>();
}

[Test]
Expand Down Expand Up @@ -181,12 +187,17 @@ public void Text_Typed()

private void Assert<TDocument>(IndexDefinition<TDocument> definition, string expectedJson)
{
var documentSerializer = BsonSerializer.SerializerRegistry.GetSerializer<TDocument>();
var renderedSort = definition.Render(documentSerializer, BsonSerializer.SerializerRegistry);
var renderedSort = Render<TDocument>(definition);

renderedSort.Should().Be(expectedJson);
}

private BsonDocument Render<TDocument>(IndexDefinition<TDocument> definition)
{
var documentSerializer = BsonSerializer.SerializerRegistry.GetSerializer<TDocument>();
return definition.Render(documentSerializer, BsonSerializer.SerializerRegistry);
}

private IndexDefinitionBuilder<TDocument> CreateSubject<TDocument>()
{
return new IndexDefinitionBuilder<TDocument>();
Expand Down
1 change: 1 addition & 0 deletions src/MongoDB.Driver.Tests/MongoDB.Driver.Tests.csproj
Expand Up @@ -95,6 +95,7 @@
<Compile Include="Linq\Translators\LegacyPredicateTranslatorTests.cs" />
<Compile Include="Linq\Translators\TranslatorTestBase.cs" />
<Compile Include="Linq\Translators\PredicateTranslatorTests.cs" />
<Compile Include="PipelineTests.cs" />
<Compile Include="ProjectionBuilderTests.cs" />
<Compile Include="IndexDefinitionBuilderTests.cs" />
<Compile Include="SortBuilderTests.cs" />
Expand Down
86 changes: 86 additions & 0 deletions src/MongoDB.Driver.Tests/PipelineTests.cs
@@ -0,0 +1,86 @@
/* Copyright 2010-2014 MongoDB Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

using System;
using FluentAssertions;
using MongoDB.Bson;
using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Attributes;
using NUnit.Framework;

namespace MongoDB.Driver.Tests
{
[TestFixture]
public class PipelineStagePipelineTests
{
[Test]
public void Constructor_should_verify_the_inputs_and_outputs_of_the_stages_and_throw_when_invalid()
{
var stages = new IPipelineStage[]
{
new BsonDocumentPipelineStage<Person, BsonDocument>(new BsonDocument()),
new BsonDocumentPipelineStage<BsonDocument, Pet>(new BsonDocument()),
new BsonDocumentPipelineStage<BsonDocument, Person>(new BsonDocument())
};

Action act = () => new PipelineStagePipeline<Person, Person>(stages);

act.ShouldThrow<ArgumentException>();
}

[Test]
public void Constructor_should_verify_the_inputs_and_outputs_of_the_stages()
{
var stages = new IPipelineStage[]
{
new BsonDocumentPipelineStage<Person, BsonDocument>(new BsonDocument()),
new BsonDocumentPipelineStage<BsonDocument, Pet>(new BsonDocument()),
new BsonDocumentPipelineStage<Pet, Person>(new BsonDocument())
};

Action act = () => new PipelineStagePipeline<Person, Person>(stages);

act.ShouldNotThrow<ArgumentException>();
}

private void Assert<TDocument>(Projection<TDocument> projection, string expectedJson)
{
var documentSerializer = BsonSerializer.SerializerRegistry.GetSerializer<TDocument>();
var renderedProjection = projection.Render(documentSerializer, BsonSerializer.SerializerRegistry);

renderedProjection.Should().Be(expectedJson);
}

private ProjectionBuilder<TDocument> CreateSubject<TDocument>()
{
return new ProjectionBuilder<TDocument>();
}

private class Person
{
[BsonElement("fn")]
public string FirstName { get; set; }

[BsonElement("pets")]
public Pet[] Pets { get; set; }
}

private class Pet
{
[BsonElement("name")]
public string Name { get; set; }
}
}
}
6 changes: 3 additions & 3 deletions src/MongoDB.Driver.Tests/ProjectionBuilderTests.cs
Expand Up @@ -100,16 +100,16 @@ public void FirstMatchingElement()
{
var subject = CreateSubject<BsonDocument>();

Assert(subject.FirstMatchingElement("a"), "{'a.$': 1}");
Assert(subject.ElemMatch("a"), "{'a.$': 1}");
}

[Test]
public void FirstMatchingElement_Typed()
{
var subject = CreateSubject<Person>();

Assert(subject.FirstMatchingElement(x => x.Pets), "{'pets.$': 1}");
Assert(subject.FirstMatchingElement("Pets"), "{'Pets.$': 1}");
Assert(subject.ElemMatch(x => x.Pets), "{'pets.$': 1}");
Assert(subject.ElemMatch("Pets"), "{'Pets.$': 1}");
}

[Test]
Expand Down
20 changes: 10 additions & 10 deletions src/MongoDB.Driver/FilterBuilder.cs
Expand Up @@ -194,16 +194,6 @@ public Filter<TDocument> Exists(Expression<Func<TDocument, object>> fieldName, b
return Exists(new ExpressionFieldName<TDocument>(fieldName), exists);
}

/// <summary>
/// Creates a filter based on the expression.
/// </summary>
/// <param name="expression">The expression.</param>
/// <returns>An expression filter.</returns>
public Filter<TDocument> Expression(Expression<Func<TDocument, bool>> expression)
{
return new ExpressionFilter<TDocument>(expression);
}

/// <summary>
/// Creates a geo intersects filter.
/// </summary>
Expand Down Expand Up @@ -917,6 +907,16 @@ public Filter<TDocument> Type(Expression<Func<TDocument, object>> fieldName, Bso
{
return Type(new ExpressionFieldName<TDocument>(fieldName), type);
}

/// <summary>
/// Creates a filter based on the expression.
/// </summary>
/// <param name="expression">The expression.</param>
/// <returns>An expression filter.</returns>
public Filter<TDocument> Where(Expression<Func<TDocument, bool>> expression)
{
return new ExpressionFilter<TDocument>(expression);
}
}

internal sealed class AndFilter<TDocument> : Filter<TDocument>
Expand Down
1 change: 1 addition & 0 deletions src/MongoDB.Driver/FindFluent.cs
Expand Up @@ -39,6 +39,7 @@ public FindFluent(IReadOnlyMongoCollection<TDocument> collection, Filter<TDocume
public override Filter<TDocument> Filter
{
get { return _filter; }
set { _filter = Ensure.IsNotNull(value, "value"); }
}

public override FindOptions<TDocument, TResult> Options
Expand Down
2 changes: 1 addition & 1 deletion src/MongoDB.Driver/FindFluentBase.cs
Expand Up @@ -26,7 +26,7 @@ namespace MongoDB.Driver
public abstract class FindFluentBase<TDocument, TResult> : IOrderedFindFluent<TDocument, TResult>
{
/// <inheritdoc />
public abstract Filter<TDocument> Filter { get; }
public abstract Filter<TDocument> Filter { get; set; }

/// <inheritdoc />
public abstract FindOptions<TDocument, TResult> Options { get; }
Expand Down
2 changes: 1 addition & 1 deletion src/MongoDB.Driver/IFindFluent.cs
Expand Up @@ -35,7 +35,7 @@ public interface IFindFluent<TDocument, TResult> : IAsyncCursorSource<TResult>
/// <summary>
/// Gets or sets the filter.
/// </summary>
Filter<TDocument> Filter { get; }
Filter<TDocument> Filter { get; set; }

/// <summary>
/// Gets the options.
Expand Down
11 changes: 8 additions & 3 deletions src/MongoDB.Driver/IndexDefinitionBuilder.cs
Expand Up @@ -440,8 +440,13 @@ public override BsonDocument Render(IBsonSerializer<TDocument> documentSerialize

foreach (var element in renderedDefinition.Elements)
{
// the last element name always wins, and we need to make sure that order is preserved.
document.Remove(element.Name);
if (document.Contains(element.Name))
{
var message = string.Format(
"The index definition contains multiple values for the field '{0}'.",
element.Name);
throw new MongoException(message);
}
document.Add(element);
}
}
Expand All @@ -466,7 +471,7 @@ public override BsonDocument Render(IBsonSerializer<TDocument> documentSerialize
var renderedFieldName = _fieldName.Render(documentSerializer, serializerRegistry);

BsonValue value;
switch(_direction)
switch (_direction)
{
case SortDirection.Ascending:
value = 1;
Expand Down
33 changes: 32 additions & 1 deletion src/MongoDB.Driver/Pipeline.cs
Expand Up @@ -13,6 +13,7 @@
* limitations under the License.
*/

using System;
using System.Collections.Generic;
using System.Linq;
using MongoDB.Bson;
Expand Down Expand Up @@ -125,7 +126,7 @@ public sealed class PipelineStagePipeline<TInput, TOutput> : Pipeline<TInput, TO
/// <param name="outputSerializer">The output serializer.</param>
public PipelineStagePipeline(IEnumerable<IPipelineStage> stages, IBsonSerializer<TOutput> outputSerializer = null)
{
_stages = Ensure.IsNotNull(stages, "stages").ToList();
_stages = VerifyStages(Ensure.IsNotNull(stages, "stages").ToList());
_outputSerializer = outputSerializer;
}

Expand Down Expand Up @@ -162,5 +163,35 @@ public override RenderedPipeline<TOutput> Render(IBsonSerializer<TInput> inputSe
pipeline,
_outputSerializer ?? (currentSerializer as IBsonSerializer<TOutput>) ?? serializerRegistry.GetSerializer<TOutput>());
}

private static List<IPipelineStage> VerifyStages(List<IPipelineStage> stages)
{
var nextInputType = typeof(TInput);
for (int i = 0; i < stages.Count; i++)
{
if (stages[i].InputType != nextInputType)
{
var message = string.Format(
"The input type to stage[{0}] was expected to be {1}, but was {2}.",
i,
nextInputType,
stages[i].InputType);
throw new ArgumentException(message, "stages");
}

nextInputType = stages[i].OutputType;
}

if (nextInputType != typeof(TOutput))
{
var message = string.Format(
"The output type to the last stage was expected to be {1}, but was {2}.",
nextInputType,
stages.Last().OutputType);
throw new ArgumentException(message, "stages");
}

return stages;
}
}
}
26 changes: 26 additions & 0 deletions src/MongoDB.Driver/PipelineStage.cs
Expand Up @@ -98,11 +98,21 @@ IBsonSerializer IRenderedPipelineStage.OutputSerializer
/// </summary>
public interface IPipelineStage
{
/// <summary>
/// Gets the type of the input.
/// </summary>
Type InputType { get; }

/// <summary>
/// Gets the name of the pipeline operator.
/// </summary>
string OperatorName { get; }

/// <summary>
/// Gets the type of the output.
/// </summary>
Type OutputType { get; }

/// <summary>
/// Renders the specified document serializer.
/// </summary>
Expand All @@ -117,9 +127,25 @@ public interface IPipelineStage
/// </summary>
public abstract class PipelineStage<TInput, TOutput> : IPipelineStage
{
/// <summary>
/// Gets the type of the input.
/// </summary>
Type IPipelineStage.InputType
{
get { return typeof(TInput); }
}

/// <inheritdoc />
public abstract string OperatorName { get; }

/// <summary>
/// Gets the type of the output.
/// </summary>
Type IPipelineStage.OutputType
{
get { return typeof(TOutput); }
}

/// <summary>
/// Renders the specified document serializer.
/// </summary>
Expand Down

0 comments on commit 531e7b6

Please sign in to comment.