PageRenderTime 57ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/tests/MongoDB.Bson.Tests/IO/BsonStreamExtensionsTests.cs

http://github.com/mongodb/mongo-csharp-driver
C# | 774 lines | 624 code | 135 blank | 15 comment | 4 complexity | 345952ef1f8d9b0236bd825f63c7726f MD5 | raw file
Possible License(s): Apache-2.0
  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. using System;
  16. using System.IO;
  17. using System.Linq;
  18. using System.Reflection;
  19. using FluentAssertions;
  20. using MongoDB.Bson.IO;
  21. using MongoDB.Bson.TestHelpers.XunitExtensions;
  22. using Moq;
  23. using Xunit;
  24. namespace MongoDB.Bson.Tests.IO
  25. {
  26. public class BsonStreamExtensionsTests
  27. {
  28. [Theory]
  29. [ParameterAttributeData]
  30. public void BackpatchSize_should_backpatch_the_size(
  31. [Values(0, 1, 5)]
  32. int startPosition)
  33. {
  34. var bytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
  35. var length = bytes.Length - startPosition;
  36. var expectedBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
  37. Array.Copy(BitConverter.GetBytes(length), 0, expectedBytes, startPosition, 4);
  38. using (var memoryStream = new MemoryStream())
  39. using (var stream = new BsonStreamAdapter(memoryStream))
  40. {
  41. stream.WriteBytes(bytes, 0, bytes.Length);
  42. var position = stream.Position;
  43. stream.BackpatchSize(startPosition);
  44. memoryStream.ToArray().Should().Equal(expectedBytes);
  45. stream.Position.Should().Be(position);
  46. }
  47. }
  48. [Fact]
  49. public void BackpatchSize_should_throw_when_size_is_larger_than_2GB()
  50. {
  51. var mockStream = new Mock<BsonStream>();
  52. var position = (long)int.MaxValue + 1;
  53. mockStream.SetupGet(s => s.Position).Returns(position);
  54. mockStream.SetupGet(s => s.Length).Returns(position);
  55. using (var stream = mockStream.Object)
  56. {
  57. Action action = () => stream.BackpatchSize(0);
  58. action.ShouldThrow<FormatException>();
  59. }
  60. }
  61. [Theory]
  62. [ParameterAttributeData]
  63. public void BackpatchSize_should_throw_when_startPosition_is_out_of_range(
  64. [Values(-1, 4)]
  65. int startPosition)
  66. {
  67. var mockStream = new Mock<BsonStream>();
  68. mockStream.SetupGet(s => s.Length).Returns(3);
  69. using (var stream = mockStream.Object)
  70. {
  71. Action action = () => stream.BackpatchSize(startPosition);
  72. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("startPosition");
  73. }
  74. }
  75. [Fact]
  76. public void BackpatchSize_should_throw_when_stream_is_null()
  77. {
  78. BsonStream stream = null;
  79. Action action = () => stream.BackpatchSize(0);
  80. action.ShouldThrow<ArgumentNullException>().And.ParamName.Should().Be("stream");
  81. }
  82. [Theory]
  83. [InlineData(0, BsonBinarySubType.Binary)]
  84. [InlineData(1, BsonBinarySubType.Function)]
  85. #pragma warning disable 618
  86. [InlineData(2, BsonBinarySubType.OldBinary)]
  87. #pragma warning restore
  88. [InlineData(3, BsonBinarySubType.UuidLegacy)]
  89. [InlineData(4, BsonBinarySubType.UuidStandard)]
  90. [InlineData(5, BsonBinarySubType.MD5)]
  91. [InlineData(0x80, BsonBinarySubType.UserDefined)]
  92. public void ReadBinarySubType_should_return_expected_result(int n, BsonBinarySubType expectedResult)
  93. {
  94. var bytes = new byte[] { (byte)n };
  95. using (var memoryStream = new MemoryStream(bytes))
  96. using (var stream = new BsonStreamAdapter(memoryStream))
  97. {
  98. var result = stream.ReadBinarySubType();
  99. result.Should().Be(expectedResult);
  100. }
  101. }
  102. [Fact]
  103. public void ReadBinarySubType_should_throw_when_at_end_of_stream()
  104. {
  105. using (var memoryStream = new MemoryStream())
  106. using (var stream = new BsonStreamAdapter(memoryStream))
  107. {
  108. Action action = () => stream.ReadBinarySubType();
  109. action.ShouldThrow<EndOfStreamException>();
  110. }
  111. }
  112. [Fact]
  113. public void ReadBinarySubType_should_throw_when_stream_is_null()
  114. {
  115. BsonStream stream = null;
  116. Action action = () => stream.ReadBinarySubType();
  117. action.ShouldThrow<ArgumentNullException>().And.ParamName.Should().Be("stream");
  118. }
  119. [Theory]
  120. [InlineData(0, false)]
  121. [InlineData(1, true)]
  122. public void ReadBoolean_should_return_expected_result(int n, bool expectedResult)
  123. {
  124. var bytes = new byte[] { (byte)n };
  125. using (var memoryStream = new MemoryStream(bytes))
  126. using (var stream = new BsonStreamAdapter(memoryStream))
  127. {
  128. var result = stream.ReadBoolean();
  129. result.Should().Be(expectedResult);
  130. }
  131. }
  132. [Fact]
  133. public void ReadBoolean_should_throw_when_at_end_of_stream()
  134. {
  135. using (var memoryStream = new MemoryStream())
  136. using (var stream = new BsonStreamAdapter(memoryStream))
  137. {
  138. Action action = () => stream.ReadBoolean();
  139. action.ShouldThrow<EndOfStreamException>();
  140. }
  141. }
  142. [Fact]
  143. public void ReadBoolean_should_throw_when_stream_is_null()
  144. {
  145. BsonStream stream = null;
  146. Action action = () => stream.ReadBoolean();
  147. action.ShouldThrow<ArgumentNullException>().And.ParamName.Should().Be("stream");
  148. }
  149. [Theory]
  150. [InlineData(0x00, BsonType.EndOfDocument)]
  151. [InlineData(0x01, BsonType.Double)]
  152. [InlineData(0x02, BsonType.String)]
  153. [InlineData(0x03, BsonType.Document)]
  154. [InlineData(0x04, BsonType.Array)]
  155. [InlineData(0x05, BsonType.Binary)]
  156. [InlineData(0x06, BsonType.Undefined)]
  157. [InlineData(0x07, BsonType.ObjectId)]
  158. [InlineData(0x08, BsonType.Boolean)]
  159. [InlineData(0x09, BsonType.DateTime)]
  160. [InlineData(0x0a, BsonType.Null)]
  161. [InlineData(0x0b, BsonType.RegularExpression)]
  162. [InlineData(0x0d, BsonType.JavaScript)]
  163. [InlineData(0x0e, BsonType.Symbol)]
  164. [InlineData(0x0f, BsonType.JavaScriptWithScope)]
  165. [InlineData(0x10, BsonType.Int32)]
  166. [InlineData(0x11, BsonType.Timestamp)]
  167. [InlineData(0x12, BsonType.Int64)]
  168. [InlineData(0xff, BsonType.MinKey)]
  169. [InlineData(0x7f, BsonType.MaxKey)]
  170. public void ReadBsonType_should_return_expected_result(int n, BsonType expectedResult)
  171. {
  172. var bytes = new byte[] { (byte)n };
  173. using (var memoryStream = new MemoryStream(bytes))
  174. using (var stream = new BsonStreamAdapter(memoryStream))
  175. {
  176. var result = stream.ReadBsonType();
  177. result.Should().Be(expectedResult);
  178. }
  179. }
  180. [Fact]
  181. public void ReadBsonType_should_throw_when_at_end_of_stream()
  182. {
  183. using (var memoryStream = new MemoryStream())
  184. using (var stream = new BsonStreamAdapter(memoryStream))
  185. {
  186. Action action = () => stream.ReadBsonType();
  187. action.ShouldThrow<EndOfStreamException>();
  188. }
  189. }
  190. [Fact]
  191. public void ReadBsonType_should_throw_when_stream_is_null()
  192. {
  193. BsonStream stream = null;
  194. Action action = () => stream.ReadBsonType();
  195. action.ShouldThrow<ArgumentNullException>().And.ParamName.Should().Be("stream");
  196. }
  197. [Theory]
  198. [InlineData(0x0c)]
  199. [InlineData(0x14)]
  200. [InlineData(0xfe)]
  201. public void ReadBsonType_should_throw_when_value_is_invalid(int n)
  202. {
  203. var bytes = new byte[] { (byte)n };
  204. using (var memoryStream = new MemoryStream(bytes))
  205. using (var stream = new BsonStreamAdapter(memoryStream))
  206. {
  207. Action action = () => stream.ReadBsonType();
  208. var hexBsonType = string.Format("{0:x2}", n);
  209. var expectedMessage = $"Detected unknown BSON type \"\\x{hexBsonType}\". Are you using the latest driver version?";
  210. action.ShouldThrow<FormatException>().WithMessage(expectedMessage);
  211. }
  212. }
  213. [Fact]
  214. public void ReadBytes_with_buffer_should_handle_partial_reads()
  215. {
  216. var mockBaseStream = new Mock<BsonStream>();
  217. var buffer = new byte[3];
  218. mockBaseStream.Setup(s => s.Read(It.IsAny<byte[]>(), 0, 3)).Returns((byte[] b, int o, int c) => { b[0] = 1; return 1; });
  219. mockBaseStream.Setup(s => s.Read(It.IsAny<byte[]>(), 1, 2)).Returns((byte[] b, int o, int c) => { b[1] = 2; b[2] = 3; return 2; });
  220. using (var baseStream = mockBaseStream.Object)
  221. using (var stream = new BsonStreamAdapter(baseStream))
  222. {
  223. stream.ReadBytes(buffer, 0, 3);
  224. buffer.Should().Equal(new byte[] { 1, 2, 3 });
  225. mockBaseStream.Verify(s => s.Read(buffer, 0, 3), Times.Once);
  226. mockBaseStream.Verify(s => s.Read(buffer, 1, 2), Times.Once);
  227. }
  228. }
  229. [Fact]
  230. public void ReadBytes_with_buffer_should_optimize_count_of_one()
  231. {
  232. var mockBaseStream = new Mock<BsonStream>();
  233. mockBaseStream.Setup(s => s.ReadByte()).Returns(1);
  234. using (var baseStream = mockBaseStream.Object)
  235. using (var stream = new BsonStreamAdapter(baseStream))
  236. {
  237. var buffer = new byte[1];
  238. stream.ReadBytes(buffer, 0, 1);
  239. buffer.Should().Equal(new byte[] { 1 });
  240. mockBaseStream.Verify(s => s.ReadByte(), Times.Once);
  241. }
  242. }
  243. [Theory]
  244. [ParameterAttributeData]
  245. public void ReadBytes_with_buffer_should_return_expected_result(
  246. [Values(0, 1, 2, 16)]
  247. int length)
  248. {
  249. var bytes = Enumerable.Range(0, length).Select(n => (byte)n).ToArray();
  250. using (var memoryStream = new MemoryStream(bytes))
  251. using (var stream = new BsonStreamAdapter(memoryStream))
  252. {
  253. var buffer = new byte[length];
  254. stream.ReadBytes(buffer, 0, length);
  255. buffer.Should().Equal(bytes);
  256. stream.Position.Should().Be(length);
  257. }
  258. }
  259. [Theory]
  260. [ParameterAttributeData]
  261. public void ReadBytes_with_buffer_should_throw_when_at_end_of_stream(
  262. [Values(0, 1, 2, 16)]
  263. int length)
  264. {
  265. var bytes = Enumerable.Range(0, length).Select(n => (byte)n).ToArray();
  266. using (var memoryStream = new MemoryStream(bytes))
  267. using (var stream = new BsonStreamAdapter(memoryStream))
  268. {
  269. var buffer = new byte[length + 1];
  270. Action action = () => stream.ReadBytes(buffer, 0, length + 1);
  271. action.ShouldThrow<EndOfStreamException>();
  272. }
  273. }
  274. [Fact]
  275. public void ReadBytes_with_buffer_should_throw_when_buffer_is_null()
  276. {
  277. var mockStream = new Mock<BsonStream>();
  278. Action action = () => mockStream.Object.ReadBytes(null, 0, 0);
  279. action.ShouldThrow<ArgumentNullException>().And.ParamName.Should().Be("buffer");
  280. }
  281. [Theory]
  282. [InlineData(0, 0, 1)]
  283. [InlineData(1, 0, 2)]
  284. [InlineData(1, 1, 1)]
  285. [InlineData(2, 0, 3)]
  286. [InlineData(2, 1, 2)]
  287. [InlineData(2, 2, 1)]
  288. public void ReadBytes_with_buffer_should_throw_when_count_extends_beyond_end_of_buffer(
  289. int length,
  290. int offset,
  291. int count)
  292. {
  293. var mockStream = new Mock<BsonStream>();
  294. using (var stream = mockStream.Object)
  295. {
  296. var buffer = new byte[length];
  297. Action action = () => stream.ReadBytes(buffer, offset, count);
  298. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("count");
  299. }
  300. }
  301. [Theory]
  302. [InlineData(0, 0, 1)]
  303. [InlineData(1, 0, 2)]
  304. [InlineData(1, 1, 1)]
  305. [InlineData(2, 0, 3)]
  306. [InlineData(2, 1, 2)]
  307. [InlineData(2, 2, 1)]
  308. public void ReadBytes_with_buffer_should_throw_when_count_is_out_of_range(int length, int offset, int count)
  309. {
  310. var mockStream = new Mock<BsonStream>();
  311. using (var stream = mockStream.Object)
  312. {
  313. var buffer = new byte[length];
  314. Action action = () => stream.ReadBytes(buffer, offset, count);
  315. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("count");
  316. }
  317. }
  318. [Theory]
  319. [InlineData(0, -1)]
  320. [InlineData(0, 1)]
  321. [InlineData(1, -1)]
  322. [InlineData(1, 2)]
  323. [InlineData(2, -1)]
  324. [InlineData(2, 3)]
  325. public void ReadBytes_with_buffer_should_throw_when_offset_is_out_of_range(int length, int count)
  326. {
  327. var mockStream = new Mock<BsonStream>();
  328. using (var stream = mockStream.Object)
  329. {
  330. var buffer = new byte[length];
  331. Action action = () => stream.ReadBytes(buffer, count, 0);
  332. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("offset");
  333. }
  334. }
  335. [Fact]
  336. public void ReadBytes_with_buffer_should_throw_when_stream_is_null()
  337. {
  338. BsonStream stream = null;
  339. var buffer = new byte[0];
  340. Action action = () => stream.ReadBytes(buffer, 0, 0);
  341. action.ShouldThrow<ArgumentNullException>().And.ParamName.Should().Be("stream");
  342. }
  343. [Theory]
  344. [ParameterAttributeData]
  345. public void ReadBytes_with_count_should_return_expected_result(
  346. [Values(0, 1, 2, 16)]
  347. int length)
  348. {
  349. var bytes = Enumerable.Range(0, length).Select(n => (byte)n).ToArray();
  350. using (var memoryStream = new MemoryStream(bytes))
  351. using (var stream = new BsonStreamAdapter(memoryStream))
  352. {
  353. var result = stream.ReadBytes(length);
  354. result.Should().Equal(bytes);
  355. stream.Position.Should().Be(length);
  356. }
  357. }
  358. [Fact]
  359. public void ReadBytes_with_count_should_throw_when_at_end_of_stream()
  360. {
  361. using (var memoryStream = new MemoryStream())
  362. using (var stream = new BsonStreamAdapter(memoryStream))
  363. {
  364. Action action = () => stream.ReadBytes(1);
  365. action.ShouldThrow<EndOfStreamException>();
  366. }
  367. }
  368. [Fact]
  369. public void ReadBytes_with_count_should_throw_when_count_is_negative()
  370. {
  371. var mockStream = new Mock<BsonStream>();
  372. using (var stream = mockStream.Object)
  373. {
  374. Action action = () => stream.ReadBytes(-1);
  375. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("count");
  376. }
  377. }
  378. [Fact]
  379. public void ReadBytes_with_count_should_throw_when_stream_is_null()
  380. {
  381. BsonStream stream = null;
  382. Action action = () => stream.ReadBytes(1);
  383. action.ShouldThrow<ArgumentNullException>().And.ParamName.Should().Be("stream");
  384. }
  385. [Fact]
  386. public void static_constructor_should_initialize_validBsonTypes()
  387. {
  388. var validBsonTypes = Reflector.__validBsonTypes;
  389. validBsonTypes.Should().HaveCount(256);
  390. for (var n = 0; n < 256; n++)
  391. {
  392. var expectedValue = Enum.IsDefined(typeof(BsonType), n);
  393. validBsonTypes[n].Should().Be(expectedValue);
  394. }
  395. }
  396. [Theory]
  397. [InlineData(BsonBinarySubType.Binary, 0)]
  398. [InlineData(BsonBinarySubType.Function, 1)]
  399. #pragma warning disable 618
  400. [InlineData(BsonBinarySubType.OldBinary, 2)]
  401. #pragma warning restore
  402. [InlineData(BsonBinarySubType.UuidLegacy, 3)]
  403. [InlineData(BsonBinarySubType.UuidStandard, 4)]
  404. [InlineData(BsonBinarySubType.MD5, 5)]
  405. [InlineData(BsonBinarySubType.UserDefined, 0x80)]
  406. public void WriteBinarySubType_should_have_expected_effect(
  407. BsonBinarySubType value,
  408. byte expectedByte)
  409. {
  410. using (var memoryStream = new MemoryStream())
  411. using (var stream = new BsonStreamAdapter(memoryStream))
  412. {
  413. var expectedBytes = new byte[] { expectedByte };
  414. stream.WriteBinarySubType(value);
  415. memoryStream.ToArray().Should().Equal(expectedBytes);
  416. }
  417. }
  418. [Fact]
  419. public void WriteBinarySubType_should_throw_when_stream_is_null()
  420. {
  421. BsonStream stream = null;
  422. Action action = () => stream.WriteBinarySubType(0);
  423. action.ShouldThrow<ArgumentNullException>().And.ParamName.Should().Be("stream");
  424. }
  425. [Theory]
  426. [InlineData(false, 0)]
  427. [InlineData(true, 1)]
  428. public void WriteBoolean_should_have_expected_effect(
  429. bool value,
  430. byte expectedByte)
  431. {
  432. using (var memoryStream = new MemoryStream())
  433. using (var stream = new BsonStreamAdapter(memoryStream))
  434. {
  435. var expectedBytes = new byte[] { expectedByte };
  436. stream.WriteBoolean(value);
  437. memoryStream.ToArray().Should().Equal(expectedBytes);
  438. }
  439. }
  440. [Fact]
  441. public void WriteBoolean_should_throw_when_stream_is_null()
  442. {
  443. BsonStream stream = null;
  444. Action action = () => stream.WriteBoolean(false);
  445. action.ShouldThrow<ArgumentNullException>().And.ParamName.Should().Be("stream");
  446. }
  447. [Theory]
  448. [InlineData(BsonType.EndOfDocument, 0x00)]
  449. [InlineData(BsonType.Double, 0x01)]
  450. [InlineData(BsonType.String, 0x02)]
  451. [InlineData(BsonType.Document, 0x03)]
  452. [InlineData(BsonType.Array, 0x04)]
  453. [InlineData(BsonType.Binary, 0x05)]
  454. [InlineData(BsonType.Undefined, 0x06)]
  455. [InlineData(BsonType.ObjectId, 0x07)]
  456. [InlineData(BsonType.Boolean, 0x08)]
  457. [InlineData(BsonType.DateTime, 0x09)]
  458. [InlineData(BsonType.Null, 0x0a)]
  459. [InlineData(BsonType.RegularExpression, 0x0b)]
  460. [InlineData(BsonType.JavaScript, 0x0d)]
  461. [InlineData(BsonType.Symbol, 0x0e)]
  462. [InlineData(BsonType.JavaScriptWithScope, 0x0f)]
  463. [InlineData(BsonType.Int32, 0x10)]
  464. [InlineData(BsonType.Timestamp, 0x11)]
  465. [InlineData(BsonType.Int64, 0x12)]
  466. [InlineData(BsonType.MinKey, 0xff)]
  467. [InlineData(BsonType.MaxKey, 0x7f)]
  468. public void WriteBsonType_should_have_expected_effect(
  469. BsonType value,
  470. byte expectedByte)
  471. {
  472. using (var memoryStream = new MemoryStream())
  473. using (var stream = new BsonStreamAdapter(memoryStream))
  474. {
  475. var expectedBytes = new byte[] { expectedByte };
  476. stream.WriteBsonType(value);
  477. memoryStream.ToArray().Should().Equal(expectedBytes);
  478. }
  479. }
  480. [Fact]
  481. public void WriteBsonType_should_throw_when_stream_is_null()
  482. {
  483. BsonStream stream = null;
  484. Action action = () => stream.WriteBsonType(0);
  485. action.ShouldThrow<ArgumentNullException>().And.ParamName.Should().Be("stream");
  486. }
  487. [Theory]
  488. [InlineData(0, 0, 0)]
  489. [InlineData(1, 0, 0)]
  490. [InlineData(1, 0, 1)]
  491. [InlineData(1, 1, 0)]
  492. [InlineData(2, 0, 0)]
  493. [InlineData(2, 0, 1)]
  494. [InlineData(2, 0, 2)]
  495. [InlineData(2, 1, 1)]
  496. [InlineData(2, 2, 0)]
  497. public void WriteBytes_should_have_expected_effect(
  498. int length,
  499. int offset,
  500. int count)
  501. {
  502. using (var memoryStream = new MemoryStream())
  503. using (var stream = new BsonStreamAdapter(memoryStream))
  504. {
  505. var buffer = Enumerable.Range(0, length).Select(n => (byte)n).ToArray();
  506. stream.WriteBytes(buffer, offset, count);
  507. memoryStream.ToArray().Should().Equal(buffer.Skip(offset).Take(count));
  508. }
  509. }
  510. [Fact]
  511. public void WriteBytes_should_optimize_count_of_one()
  512. {
  513. var mockBaseStream = new Mock<Stream>();
  514. using (var baseStream = mockBaseStream.Object)
  515. using (var stream = new BsonStreamAdapter(baseStream))
  516. {
  517. var buffer = new byte[] { 1 };
  518. stream.WriteBytes(buffer, 0, 1);
  519. mockBaseStream.Verify(s => s.WriteByte(1), Times.Once);
  520. }
  521. }
  522. [Fact]
  523. public void WriteBytes_should_throw_when_buffer_is_null()
  524. {
  525. var mockStream = new Mock<BsonStream>();
  526. using (var stream = mockStream.Object)
  527. {
  528. byte[] buffer = null;
  529. var offset = 0;
  530. var count = 0;
  531. Action action = () => stream.WriteBytes(buffer, offset, count);
  532. action.ShouldThrow<ArgumentNullException>().And.ParamName.Should().Be("buffer");
  533. }
  534. }
  535. [Theory]
  536. [InlineData(0, 0, 1)]
  537. [InlineData(1, 0, 2)]
  538. [InlineData(1, 1, 1)]
  539. public void WriteBytes_should_throw_when_count_is_out_of_range(
  540. int length,
  541. int offset,
  542. int count)
  543. {
  544. var mockStream = new Mock<BsonStream>();
  545. using (var stream = mockStream.Object)
  546. {
  547. var buffer = new byte[length];
  548. Action action = () => stream.WriteBytes(buffer, offset, count);
  549. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("count");
  550. }
  551. }
  552. [Theory]
  553. [InlineData(0, -1)]
  554. [InlineData(0, 1)]
  555. [InlineData(1, -1)]
  556. [InlineData(1, 2)]
  557. public void WriteBytes_should_throw_when_offset_is_out_of_range(
  558. int length,
  559. int offset)
  560. {
  561. var mockStream = new Mock<BsonStream>();
  562. using (var stream = mockStream.Object)
  563. {
  564. var buffer = new byte[length];
  565. var count = 0;
  566. Action action = () => stream.WriteBytes(buffer, offset, count);
  567. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("offset");
  568. }
  569. }
  570. [Fact]
  571. public void WriteBytes_should_throw_when_stream_is_null()
  572. {
  573. BsonStream stream = null;
  574. var buffer = new byte[0];
  575. var offset = 0;
  576. var count = 0;
  577. Action action = () => stream.WriteBytes(buffer, offset, count);
  578. action.ShouldThrow<ArgumentNullException>().And.ParamName.Should().Be("stream");
  579. }
  580. [Theory]
  581. [ParameterAttributeData]
  582. public void WriteSlice_should_have_expected_effect(
  583. [Values(0, 1, 2, 16)]
  584. int length,
  585. [Values(1, 2, 3)]
  586. int numberOfChunks)
  587. {
  588. numberOfChunks = length == 0 ? 1 : length < numberOfChunks ? length : numberOfChunks;
  589. using (var memoryStream = new MemoryStream())
  590. using (var stream = new BsonStreamAdapter(memoryStream))
  591. {
  592. IByteBuffer slice;
  593. var bytes = Enumerable.Range(0, length).Select(n => (byte)n).ToArray();
  594. if (numberOfChunks == 1)
  595. {
  596. slice = new ByteArrayBuffer(bytes, isReadOnly: true);
  597. }
  598. else
  599. {
  600. var chunkSize = length / numberOfChunks;
  601. var chunks = Enumerable.Range(0, numberOfChunks)
  602. .Select(i => bytes.Skip(i * chunkSize).Take(i < numberOfChunks - 1 ? chunkSize : int.MaxValue).ToArray())
  603. .Select(b => new ByteArrayChunk(b));
  604. slice = new MultiChunkBuffer(chunks);
  605. }
  606. stream.WriteSlice(slice);
  607. memoryStream.ToArray().Should().Equal(bytes);
  608. }
  609. }
  610. [Fact]
  611. public void WriteSlice_should_throw_when_slice_is_null()
  612. {
  613. var mockStream = new Mock<BsonStream>();
  614. IByteBuffer slice = null;
  615. Action action = () => mockStream.Object.WriteSlice(slice);
  616. action.ShouldThrow<ArgumentNullException>().And.ParamName.Should().Be("slice");
  617. }
  618. [Fact]
  619. public void WriteSlice_should_throw_when_stream_is_null()
  620. {
  621. BsonStream stream = null;
  622. IByteBuffer slice = null;
  623. Action action = () => stream.WriteSlice(slice);
  624. action.ShouldThrow<ArgumentNullException>().And.ParamName.Should().Be("stream");
  625. }
  626. // nested types
  627. private class Reflector
  628. {
  629. public static bool[] __validBsonTypes
  630. {
  631. get
  632. {
  633. var field = typeof(BsonStreamExtensions).GetField("__validBsonTypes", BindingFlags.Static | BindingFlags.NonPublic);
  634. return (bool[])field.GetValue(null);
  635. }
  636. }
  637. }
  638. }
  639. }