Skip to content

Commit 2281ee7

Browse files
committed
CSHARP-1449: Added new extension methods for cursor and cursor sources. Added lots of tests.
1 parent fcc299c commit 2281ee7

28 files changed

+2940
-334
lines changed
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
/* Copyright 2015 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 System;
17+
using System.Linq;
18+
using System.Threading;
19+
using FluentAssertions;
20+
using MongoDB.Bson;
21+
using MongoDB.Bson.Serialization.Serializers;
22+
using MongoDB.Driver.Core.Bindings;
23+
using MongoDB.Driver.Core.WireProtocol.Messages.Encoders;
24+
using NSubstitute;
25+
using NUnit.Framework;
26+
27+
namespace MongoDB.Driver.Core.Operations
28+
{
29+
[TestFixture]
30+
public class AsyncCursorEnumeratorTests
31+
{
32+
// public methods
33+
[Test]
34+
public void constructor_should_throw_when_cursor_is_null()
35+
{
36+
Action action = () => new AsyncCursorEnumerator<BsonDocument>(null, CancellationToken.None);
37+
38+
action.ShouldThrow<ArgumentNullException>().And.ParamName.Should().Be("cursor");
39+
}
40+
41+
[Test]
42+
public void Current_should_return_expected_result()
43+
{
44+
var subject = CreateSubject(2);
45+
46+
subject.MoveNext();
47+
subject.Current.Should().Be(new BsonDocument("_id", 0));
48+
subject.MoveNext();
49+
subject.Current.Should().Be(new BsonDocument("_id", 1));
50+
}
51+
52+
[Test]
53+
public void Current_should_return_expected_result_when_there_are_two_batches()
54+
{
55+
var cursor = Substitute.For<IAsyncCursor<BsonDocument>>();
56+
var firstBatch = new[]
57+
{
58+
new BsonDocument("_id", 0),
59+
new BsonDocument("_id", 1)
60+
};
61+
var secondBatch = new[]
62+
{
63+
new BsonDocument("_id", 2)
64+
};
65+
cursor.MoveNext().Returns(true, true, false);
66+
cursor.Current.Returns(firstBatch, secondBatch);
67+
var subject = new AsyncCursorEnumerator<BsonDocument>(cursor, CancellationToken.None);
68+
69+
subject.MoveNext();
70+
subject.Current.Should().Be(new BsonDocument("_id", 0));
71+
subject.MoveNext();
72+
subject.Current.Should().Be(new BsonDocument("_id", 1));
73+
subject.MoveNext();
74+
subject.Current.Should().Be(new BsonDocument("_id", 2));
75+
}
76+
77+
[Test]
78+
public void Current_should_throw_when_MoveNext_has_not_been_called_first()
79+
{
80+
var subject = CreateSubject(1);
81+
82+
Action action = () => { var ignore = subject.Current; };
83+
84+
action.ShouldThrow<InvalidOperationException>();
85+
}
86+
87+
[Test]
88+
public void Current_should_throw_when_MoveNext_returns_false()
89+
{
90+
var subject = CreateSubject(0);
91+
subject.MoveNext();
92+
93+
Action action = () => { var ignore = subject.Current; };
94+
95+
action.ShouldThrow<InvalidOperationException>();
96+
}
97+
98+
[Test]
99+
public void Current_should_throw_when_subject_has_been_disposed()
100+
{
101+
var subject = CreateSubject(0);
102+
subject.Dispose();
103+
104+
Action action = () => { var ignore = subject.Current; };
105+
106+
action.ShouldThrow<ObjectDisposedException>();
107+
}
108+
109+
[Test]
110+
public void Dispose_should_dispose_cursor()
111+
{
112+
var cursor = Substitute.For<IAsyncCursor<BsonDocument>>();
113+
var subject = new AsyncCursorEnumerator<BsonDocument>(cursor, CancellationToken.None);
114+
115+
subject.Dispose();
116+
117+
cursor.Received(1).Dispose();
118+
}
119+
120+
[Test]
121+
public void MoveNext_should_return_expected_result()
122+
{
123+
var subject = CreateSubject(2);
124+
125+
subject.MoveNext().Should().BeTrue();
126+
subject.MoveNext().Should().BeTrue();
127+
subject.MoveNext().Should().BeFalse();
128+
}
129+
130+
[Test]
131+
public void MoveNext_should_return_expected_result_when_there_are_two_batches()
132+
{
133+
var cursor = Substitute.For<IAsyncCursor<BsonDocument>>();
134+
var firstBatch = new[]
135+
{
136+
new BsonDocument("_id", 0),
137+
new BsonDocument("_id", 1)
138+
};
139+
var secondBatch = new[]
140+
{
141+
new BsonDocument("_id", 2)
142+
};
143+
cursor.MoveNext().Returns(true, true, false);
144+
cursor.Current.Returns(firstBatch, secondBatch);
145+
var subject = new AsyncCursorEnumerator<BsonDocument>(cursor, CancellationToken.None);
146+
147+
subject.MoveNext().Should().BeTrue();
148+
subject.MoveNext().Should().BeTrue();
149+
subject.MoveNext().Should().BeTrue();
150+
subject.MoveNext().Should().BeFalse();
151+
}
152+
153+
[Test]
154+
public void MoveNext_should_throw_when_subject_has_been_disposed()
155+
{
156+
var subject = CreateSubject(0);
157+
subject.Dispose();
158+
159+
Action action = () => subject.MoveNext();
160+
161+
action.ShouldThrow<ObjectDisposedException>();
162+
}
163+
164+
[Test]
165+
public void Reset_should_throw()
166+
{
167+
var subject = CreateSubject(1);
168+
169+
Action action = () => subject.Reset();
170+
171+
action.ShouldThrow<NotSupportedException>();
172+
}
173+
174+
// private methods
175+
private AsyncCursorEnumerator<BsonDocument> CreateSubject(int count)
176+
{
177+
var firstBatch = Enumerable.Range(0, count)
178+
.Select(i => new BsonDocument("_id", i))
179+
.ToArray();
180+
181+
var cursor = new AsyncCursor<BsonDocument>(
182+
channelSource: Substitute.For<IChannelSource>(),
183+
collectionNamespace: new CollectionNamespace("foo", "bar"),
184+
query: new BsonDocument(),
185+
firstBatch: firstBatch,
186+
cursorId: 0,
187+
batchSize: null,
188+
limit: null,
189+
serializer: BsonDocumentSerializer.Instance,
190+
messageEncoderSettings: new MessageEncoderSettings());
191+
192+
return new AsyncCursorEnumerator<BsonDocument>(cursor, CancellationToken.None);
193+
}
194+
}
195+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/* Copyright 2015 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 System;
17+
using System.Threading;
18+
using FluentAssertions;
19+
using MongoDB.Bson;
20+
using NSubstitute;
21+
using NUnit.Framework;
22+
23+
namespace MongoDB.Driver.Core.Operations
24+
{
25+
[TestFixture]
26+
public class EnumerableAsyncCursorSourceTests
27+
{
28+
[Test]
29+
public void constructor_should_throw_when_source_is_null()
30+
{
31+
Action action = () => new EnumerableAsyncCursorSource<BsonDocument>(null, CancellationToken.None);
32+
33+
action.ShouldThrow<ArgumentNullException>().And.ParamName.Should().Be("source");
34+
}
35+
36+
[Test]
37+
public void GetEnumerator_should_call_ToCursor_each_time(
38+
[Values(1, 2)] int times)
39+
{
40+
var source = Substitute.For<IAsyncCursorSource<BsonDocument>>();
41+
var cursor = Substitute.For<IAsyncCursor<BsonDocument>>();
42+
source.ToCursor().Returns(cursor);
43+
var subject = new EnumerableAsyncCursorSource<BsonDocument>(source, CancellationToken.None);
44+
45+
for (var i = 0; i < times; i++)
46+
{
47+
subject.GetEnumerator();
48+
}
49+
50+
source.Received(times).ToCursor();
51+
}
52+
}
53+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/* Copyright 2015 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 System;
17+
using System.Threading;
18+
using FluentAssertions;
19+
using MongoDB.Bson;
20+
using NSubstitute;
21+
using NUnit.Framework;
22+
23+
namespace MongoDB.Driver.Core.Operations
24+
{
25+
[TestFixture]
26+
public class EnumerableOneTimeAsyncCursorTests
27+
{
28+
[Test]
29+
public void constructor_should_throw_when_cursor_is_null()
30+
{
31+
Action action = () => new EnumerableOneTimeAsyncCursor<BsonDocument>(null, CancellationToken.None);
32+
33+
action.ShouldThrow<ArgumentNullException>().And.ParamName.Should().Be("cursor");
34+
}
35+
36+
[Test]
37+
public void GetEnumerator_should_return_expected_result()
38+
{
39+
var cursor = Substitute.For<IAsyncCursor<BsonDocument>>();
40+
cursor.MoveNext().Returns(true, false);
41+
cursor.Current.Returns(new[] { new BsonDocument("_id", 0) });
42+
var subject = new EnumerableOneTimeAsyncCursor<BsonDocument>(cursor, CancellationToken.None);
43+
44+
var result = subject.GetEnumerator();
45+
46+
result.MoveNext().Should().BeTrue();
47+
result.Current.Should().Be(new BsonDocument("_id", 0));
48+
result.MoveNext().Should().BeFalse();
49+
}
50+
51+
[Test]
52+
public void GetEnumerator_should_throw_when_called_more_than_once()
53+
{
54+
var cursor = Substitute.For<IAsyncCursor<BsonDocument>>();
55+
var subject = new EnumerableOneTimeAsyncCursor<BsonDocument>(cursor, CancellationToken.None);
56+
subject.GetEnumerator();
57+
58+
Action action = () => subject.GetEnumerator();
59+
60+
action.ShouldThrow<InvalidOperationException>();
61+
}
62+
}
63+
}

0 commit comments

Comments
 (0)