PageRenderTime 63ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

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

http://github.com/mongodb/mongo-csharp-driver
C# | 1676 lines | 1317 code | 343 blank | 16 comment | 10 complexity | ae667313338c7aa3f4aef8f94dc1d008 MD5 | raw file
Possible License(s): Apache-2.0

Large files files are truncated, but you can click here to view the full file

  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.Collections.Generic;
  17. using System.IO;
  18. using System.Linq;
  19. using System.Reflection;
  20. using FluentAssertions;
  21. using MongoDB.Bson.IO;
  22. using MongoDB.Bson.TestHelpers.XunitExtensions;
  23. using Moq;
  24. using Xunit;
  25. namespace MongoDB.Bson.Tests.IO
  26. {
  27. public class ByteBufferStreamTests
  28. {
  29. [Fact]
  30. public void Buffer_get_should_return_expected_result()
  31. {
  32. var mockBuffer = new Mock<IByteBuffer>();
  33. var subject = new ByteBufferStream(mockBuffer.Object);
  34. var result = subject.Buffer;
  35. result.Should().BeSameAs(mockBuffer.Object);
  36. }
  37. [Fact]
  38. public void Buffer_get_should_throw_when_subject_is_disposed()
  39. {
  40. var subject = CreateDisposedSubject();
  41. Action action = () => { var _ = subject.Buffer; };
  42. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("ByteBufferStream");
  43. }
  44. [Theory]
  45. [InlineData(false, true)]
  46. [InlineData(true, false)]
  47. public void CanRead_get_should_return_expected_result(bool disposed, bool expectedResult)
  48. {
  49. var subject = CreateSubject();
  50. if (disposed)
  51. {
  52. subject.Dispose();
  53. }
  54. var result = subject.CanRead;
  55. result.Should().Be(expectedResult);
  56. }
  57. [Theory]
  58. [InlineData(false, true)]
  59. [InlineData(true, false)]
  60. public void CanSeek_get_should_return_expected_result(bool disposed, bool expectedResult)
  61. {
  62. var subject = CreateSubject();
  63. if (disposed)
  64. {
  65. subject.Dispose();
  66. }
  67. var result = subject.CanSeek;
  68. result.Should().Be(expectedResult);
  69. }
  70. [Theory]
  71. [ParameterAttributeData]
  72. public void CanTimeout_get_should_return_expected_result(
  73. [Values(false, true)]
  74. bool disposed)
  75. {
  76. var subject = CreateSubject();
  77. if (disposed)
  78. {
  79. subject.Dispose();
  80. }
  81. var result = subject.CanTimeout;
  82. result.Should().BeFalse();
  83. }
  84. [Theory]
  85. [InlineData(false, false, true)]
  86. [InlineData(false, true, false)]
  87. [InlineData(true, false, false)]
  88. [InlineData(true, true, false)]
  89. public void CanWrite_get_should_return_expected_result(bool bufferIsReadOnly, bool disposed, bool expectedResult)
  90. {
  91. var subject = CreateSubject();
  92. var mockBuffer = Mock.Get(subject.Buffer);
  93. mockBuffer.SetupGet(b => b.IsReadOnly).Returns(bufferIsReadOnly);
  94. if (disposed)
  95. {
  96. subject.Dispose();
  97. }
  98. var result = subject.CanWrite;
  99. result.Should().Be(expectedResult);
  100. }
  101. [Theory]
  102. [ParameterAttributeData]
  103. public void constructor_should_initialize_subject(
  104. [Values(false, true)]
  105. bool ownsBuffer)
  106. {
  107. var length = 123;
  108. var mockBuffer = new Mock<IByteBuffer>();
  109. mockBuffer.SetupGet(s => s.Length).Returns(length);
  110. var subject = new ByteBufferStream(mockBuffer.Object, ownsBuffer);
  111. var reflector = new Reflector(subject);
  112. subject.Buffer.Should().BeSameAs(mockBuffer.Object);
  113. subject.Length.Should().Be(length);
  114. subject.Position.Should().Be(0);
  115. reflector._disposed.Should().BeFalse();
  116. reflector._ownsBuffer.Should().Be(ownsBuffer);
  117. }
  118. [Fact]
  119. public void constructor_should_throw_when_buffer_is_null()
  120. {
  121. Action action = () => new ByteBufferStream(null);
  122. action.ShouldThrow<ArgumentNullException>().And.ParamName.Should().Be("buffer");
  123. }
  124. [Fact]
  125. public void Dispose_can_be_called_more_than_once()
  126. {
  127. var subject = CreateSubject();
  128. subject.Dispose();
  129. subject.Dispose();
  130. }
  131. [Fact]
  132. public void Dispose_should_dispose_subject()
  133. {
  134. var subject = CreateSubject();
  135. subject.Dispose();
  136. var reflector = new Reflector(subject);
  137. reflector._disposed.Should().BeTrue();
  138. }
  139. [Theory]
  140. [ParameterAttributeData]
  141. public void Dispose_should_dispose_buffer_if_it_owns_it(
  142. [Values(false, true)]
  143. bool ownsBuffer)
  144. {
  145. var mockBuffer = new Mock<IByteBuffer>();
  146. var subject = new ByteBufferStream(mockBuffer.Object, ownsBuffer: ownsBuffer);
  147. subject.Dispose();
  148. mockBuffer.Verify(s => s.Dispose(), Times.Exactly(ownsBuffer ? 1 : 0));
  149. }
  150. [Fact]
  151. public void Flush_should_do_nothing()
  152. {
  153. var subject = CreateSubject();
  154. subject.Flush();
  155. }
  156. [Fact]
  157. public void Flush_should_throw_when_subject_is_disposed()
  158. {
  159. var subject = CreateDisposedSubject();
  160. Action action = () => subject.Flush();
  161. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("ByteBufferStream");
  162. }
  163. [Fact]
  164. public void Length_get_should_return_expected_result()
  165. {
  166. var subject = CreateSubject(new byte[1]);
  167. var result = subject.Length;
  168. result.Should().Be(1);
  169. }
  170. [Fact]
  171. public void Length_get_should_throw_when_subject_is_disposed()
  172. {
  173. var subject = CreateDisposedSubject();
  174. Action action = () => { var _ = subject.Length; };
  175. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("ByteBufferStream");
  176. }
  177. [Fact]
  178. public void Position_get_should_return_expected_result()
  179. {
  180. var subject = CreateSubject();
  181. subject.Position = 1;
  182. var result = subject.Position;
  183. result.Should().Be(1);
  184. }
  185. [Fact]
  186. public void Position_get_should_throw_when_subject_is_disposed()
  187. {
  188. var subject = CreateDisposedSubject();
  189. Action action = () => { var _ = subject.Position; };
  190. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("ByteBufferStream");
  191. }
  192. [Fact]
  193. public void Position_set_should_have_expected_effect()
  194. {
  195. var subject = CreateSubject();
  196. subject.Position = 1;
  197. subject.Position.Should().Be(1);
  198. }
  199. [Theory]
  200. [ParameterAttributeData]
  201. public void Position_set_should_throw_when_value_is_invalid(
  202. [Values(-1L, (long)int.MaxValue + 1)]
  203. long value)
  204. {
  205. var subject = CreateSubject();
  206. Action action = () => subject.Position = value;
  207. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("value");
  208. }
  209. [Fact]
  210. public void Position_set_should_throw_when_subject_is_disposed()
  211. {
  212. var subject = CreateDisposedSubject();
  213. Action action = () => subject.Position = 1;
  214. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("ByteBufferStream");
  215. }
  216. [SkippableFact]
  217. public void PrepareToWrite_should_throw_when_stream_would_exceed_2GB()
  218. {
  219. RequireProcess.Check().Bits(64);
  220. using (var buffer = new MultiChunkBuffer(BsonChunkPool.Default))
  221. using (var subject = new ByteBufferStream(buffer))
  222. {
  223. var bytes = new byte[int.MaxValue / 2 + 1024];
  224. subject.Write(bytes, 0, bytes.Length);
  225. Action action = () => subject.Write(bytes, 0, bytes.Length); // indirectly calls private PrepareToWrite method
  226. action.ShouldThrow<IOException>();
  227. }
  228. }
  229. [Theory]
  230. [InlineData(1, 0)]
  231. [InlineData(2, 0)]
  232. [InlineData(2, 1)]
  233. [InlineData(3, 0)]
  234. [InlineData(3, 1)]
  235. [InlineData(3, 2)]
  236. public void Read_should_return_available_bytes_when_available_bytes_is_less_than_count(long length, long position)
  237. {
  238. var subject = CreateSubject();
  239. var mockBuffer = Mock.Get(subject.Buffer);
  240. mockBuffer.SetupGet(b => b.Capacity).Returns((int)length);
  241. subject.SetLength(length);
  242. subject.Position = position;
  243. var available = (int)(length - position);
  244. var destination = new byte[available + 1];
  245. var result = subject.Read(destination, 0, available + 1);
  246. result.Should().Be(available);
  247. subject.Position.Should().Be(position + available);
  248. mockBuffer.Verify(b => b.GetBytes((int)position, destination, 0, available), Times.Once);
  249. }
  250. [Theory]
  251. [InlineData(1, 0, 1)]
  252. [InlineData(2, 0, 2)]
  253. [InlineData(2, 1, 1)]
  254. [InlineData(3, 0, 3)]
  255. [InlineData(3, 1, 2)]
  256. [InlineData(3, 2, 1)]
  257. public void Read_should_return_count_bytes_when_count_is_less_than_or_equal_to_available_bytes(long length, long position, int count)
  258. {
  259. var subject = CreateSubject();
  260. var mockBuffer = Mock.Get(subject.Buffer);
  261. mockBuffer.SetupGet(b => b.Capacity).Returns((int)length);
  262. subject.SetLength(length);
  263. subject.Position = position;
  264. var destination = new byte[count];
  265. var result = subject.Read(destination, 0, count);
  266. result.Should().Be(count);
  267. subject.Position.Should().Be(position + count);
  268. mockBuffer.Verify(b => b.GetBytes((int)position, destination, 0, count), Times.Once);
  269. }
  270. [Theory]
  271. [InlineData(0, 0)]
  272. [InlineData(0, 1)]
  273. [InlineData(1, 2)]
  274. [InlineData(2, 2)]
  275. public void Read_should_return_zero_when_position_is_greater_than_or_equal_to_length(long length, long position)
  276. {
  277. var subject = CreateSubject();
  278. var mockBuffer = Mock.Get(subject.Buffer);
  279. mockBuffer.SetupGet(b => b.Capacity).Returns((int)length);
  280. subject.SetLength(length);
  281. subject.Position = position;
  282. var destination = new byte[1];
  283. var result = subject.Read(destination, 0, 1);
  284. result.Should().Be(0);
  285. subject.Position.Should().Be(position);
  286. }
  287. [Fact]
  288. public void Read_should_throw_when_buffer_is_null()
  289. {
  290. var subject = CreateSubject();
  291. Action action = () => subject.Read(null, 0, 0);
  292. action.ShouldThrow<ArgumentNullException>().And.ParamName.Should().Be("buffer");
  293. }
  294. [Theory]
  295. [InlineData(1, 0, -1)]
  296. [InlineData(1, 0, 2)]
  297. [InlineData(2, 0, -1)]
  298. [InlineData(2, 0, 3)]
  299. [InlineData(2, 1, 2)]
  300. [InlineData(2, 2, 1)]
  301. public void Read_should_throw_when_count_is_out_of_range(int destinationSize, int offset, int count)
  302. {
  303. var subject = CreateSubject();
  304. var destination = new byte[destinationSize];
  305. Action action = () => subject.Read(destination, offset, count);
  306. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("count");
  307. }
  308. [Theory]
  309. [InlineData(1, -1)]
  310. [InlineData(1, 2)]
  311. [InlineData(2, -1)]
  312. [InlineData(2, 3)]
  313. public void Read_should_throw_when_offset_is_out_of_range(int destinationSize, int offset)
  314. {
  315. var subject = CreateSubject();
  316. var destination = new byte[destinationSize];
  317. Action action = () => subject.Read(destination, offset, 0);
  318. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("offset");
  319. }
  320. [Fact]
  321. public void Read_should_throw_when_subject_is_disposed()
  322. {
  323. var subject = CreateDisposedSubject();
  324. var destination = new byte[1];
  325. Action action = () => subject.Read(destination, 0, 1);
  326. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("ByteBufferStream");
  327. }
  328. [Theory]
  329. [InlineData(1, 0, 1)]
  330. [InlineData(2, 0, 1)]
  331. [InlineData(2, 1, 2)]
  332. [InlineData(3, 0, 1)]
  333. [InlineData(3, 1, 2)]
  334. [InlineData(3, 2, 3)]
  335. public void ReadByte_should_return_expected_result(long length, long position, byte expectedResult)
  336. {
  337. var subject = CreateSubject();
  338. var mockBuffer = Mock.Get(subject.Buffer);
  339. mockBuffer.SetupGet(b => b.Capacity).Returns((int)length);
  340. mockBuffer.Setup(b => b.GetByte((int)position)).Returns(expectedResult);
  341. subject.SetLength(length);
  342. subject.Position = position;
  343. var result = subject.ReadByte();
  344. result.Should().Be(expectedResult);
  345. subject.Position.Should().Be(position + 1);
  346. }
  347. [Theory]
  348. [InlineData(0, 0)]
  349. [InlineData(0, 1)]
  350. [InlineData(1, 1)]
  351. [InlineData(1, 2)]
  352. [InlineData(2, 2)]
  353. [InlineData(2, 3)]
  354. public void ReadByte_should_return_minus_one_when_position_is_greater_than_or_equal_to_length(long length, long position)
  355. {
  356. var subject = CreateSubject();
  357. var mockBuffer = Mock.Get(subject.Buffer);
  358. mockBuffer.SetupGet(b => b.Capacity).Returns((int)length);
  359. subject.SetLength(length);
  360. subject.Position = position;
  361. var result = subject.ReadByte();
  362. result.Should().Be(-1);
  363. }
  364. [Fact]
  365. public void ReadByte_should_throw_when_subject_is_disposed()
  366. {
  367. var subject = CreateDisposedSubject();
  368. Action action = () => subject.ReadByte();
  369. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("ByteBufferStream");
  370. }
  371. [Theory]
  372. [InlineData(1, 1, new byte[] { 0 }, "")]
  373. [InlineData(1, 2, new byte[] { 0 }, "")]
  374. [InlineData(2, 1, new byte[] { 97, 0 }, "a")]
  375. [InlineData(2, 2, new byte[] { 97, 0 }, "a")]
  376. [InlineData(3, 1, new byte[] { 97, 98, 0 }, "ab")]
  377. [InlineData(3, 2, new byte[] { 97, 98, 0 }, "ab")]
  378. [InlineData(4, 1, new byte[] { 97, 98, 99, 0 }, "abc")]
  379. [InlineData(4, 2, new byte[] { 97, 98, 99, 0 }, "abc")]
  380. public void ReadCString_should_return_expected_result(int length, int numberOfChunks, byte[] bytes, string expectedResult)
  381. {
  382. var subject = CreateSubject(bytes, numberOfChunks);
  383. var expectedPosition = length;
  384. var result = subject.ReadCString(Utf8Encodings.Strict);
  385. result.Should().Be(expectedResult);
  386. subject.Position.Should().Be(expectedPosition);
  387. }
  388. [Fact]
  389. public void ReadCString_should_throw_when_encoding_is_null()
  390. {
  391. var subject = CreateSubject();
  392. Action action = () => subject.ReadCString(null);
  393. action.ShouldThrow<ArgumentNullException>().And.ParamName.Should().Be("encoding");
  394. }
  395. [Fact]
  396. public void ReadCString_should_throw_when_subject_is_disposed()
  397. {
  398. var subject = CreateDisposedSubject();
  399. Action action = () => subject.ReadCString(Utf8Encodings.Strict);
  400. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("ByteBufferStream");
  401. }
  402. [Theory]
  403. [InlineData(1, 1, new byte[] { 0 }, new byte[] { })]
  404. [InlineData(2, 1, new byte[] { 97, 0 }, new byte[] { 97 })]
  405. [InlineData(2, 2, new byte[] { 97, 0 }, new byte[] { 97 })]
  406. [InlineData(3, 1, new byte[] { 97, 98, 0 }, new byte[] { 97, 98 })]
  407. [InlineData(3, 2, new byte[] { 97, 98, 0 }, new byte[] { 97, 98 })]
  408. [InlineData(4, 1, new byte[] { 97, 98, 99, 0 }, new byte[] { 97, 98, 99 })]
  409. [InlineData(4, 2, new byte[] { 97, 98, 99, 0 }, new byte[] { 97, 98, 99 })]
  410. public void ReadCStringBytes_should_return_expected_result(int length, int numberOfChunks, byte[] bytes, byte[] expectedResult)
  411. {
  412. var subject = CreateSubject(bytes, numberOfChunks);
  413. var expectedPosition = length;
  414. var result = subject.ReadCStringBytes();
  415. result.Should().Equal(expectedResult);
  416. subject.Position.Should().Be(expectedPosition);
  417. }
  418. [Theory]
  419. [InlineData(0, 1, new byte[] { })]
  420. [InlineData(1, 1, new byte[] { 97 })]
  421. [InlineData(2, 1, new byte[] { 97, 98 })]
  422. [InlineData(2, 2, new byte[] { 97, 98 })]
  423. [InlineData(3, 1, new byte[] { 97, 98, 99 })]
  424. [InlineData(3, 2, new byte[] { 97, 98, 99 })]
  425. public void ReadCStringBytes_should_throw_when_end_of_stream_is_reached(int length, int numberOfChunks, byte[] bytes)
  426. {
  427. var subject = CreateSubject(bytes, numberOfChunks);
  428. Action action = () => subject.ReadCStringBytes();
  429. action.ShouldThrow<EndOfStreamException>();
  430. }
  431. [Fact]
  432. public void ReadCStringBytes_should_throw_when_subject_is_disposed()
  433. {
  434. var subject = CreateDisposedSubject();
  435. Action action = () => subject.ReadCStringBytes();
  436. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("ByteBufferStream");
  437. }
  438. [Theory]
  439. [ParameterAttributeData]
  440. public void ReadDecimal18_should_return_expected_result(
  441. [Values(1, 2)]
  442. int numberOfChunks,
  443. [Values("-1.0", "0.0", "1.0", "NaN", "-Infinity", "Infinity")]
  444. string valueString)
  445. {
  446. var value = Decimal128.Parse(valueString);
  447. var bytes = new byte[16];
  448. Buffer.BlockCopy(BitConverter.GetBytes(value.GetIEEELowBits()), 0, bytes, 0, 8);
  449. Buffer.BlockCopy(BitConverter.GetBytes(value.GetIEEEHighBits()), 0, bytes, 8, 8);
  450. var subject = CreateSubject(bytes, numberOfChunks);
  451. var result = subject.ReadDecimal128();
  452. result.Should().Be(value);
  453. subject.Position.Should().Be(16);
  454. }
  455. [Theory]
  456. [ParameterAttributeData]
  457. public void ReadDecimal128_should_throw_when_at_end_of_stream(
  458. [Values(1, 2)]
  459. int numberOfChunks,
  460. [Values(0, 1, 7)]
  461. int length)
  462. {
  463. var subject = CreateSubject(length, numberOfChunks);
  464. Action action = () => subject.ReadDecimal128();
  465. action.ShouldThrow<EndOfStreamException>();
  466. }
  467. [Fact]
  468. public void ReadDecimal128_should_throw_when_subject_is_disposed()
  469. {
  470. var subject = CreateDisposedSubject();
  471. Action action = () => subject.ReadDecimal128();
  472. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("ByteBufferStream");
  473. }
  474. [Theory]
  475. [ParameterAttributeData]
  476. public void ReadDouble_should_return_expected_result(
  477. [Values(1, 2)]
  478. int numberOfChunks,
  479. [Values(-1.0, 0.0, 1.0, double.Epsilon, double.MaxValue, double.MinValue, double.NaN, double.NegativeInfinity, double.PositiveInfinity)]
  480. double value)
  481. {
  482. var bytes = BitConverter.GetBytes(value);
  483. var subject = CreateSubject(bytes, numberOfChunks);
  484. var result = subject.ReadDouble();
  485. result.Should().Be(value);
  486. subject.Position.Should().Be(8);
  487. }
  488. [Theory]
  489. [ParameterAttributeData]
  490. public void ReadDouble_should_throw_when_at_end_of_stream(
  491. [Values(1, 2)]
  492. int numberOfChunks,
  493. [Values(0, 1, 7)]
  494. int length)
  495. {
  496. var subject = CreateSubject(length, numberOfChunks);
  497. Action action = () => subject.ReadDouble();
  498. action.ShouldThrow<EndOfStreamException>();
  499. }
  500. [Fact]
  501. public void ReadDouble_should_throw_when_subject_is_disposed()
  502. {
  503. var subject = CreateDisposedSubject();
  504. Action action = () => subject.ReadDouble();
  505. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("ByteBufferStream");
  506. }
  507. [Fact]
  508. public void ReadInt32_should_be_little_endian()
  509. {
  510. var bytes = new byte[] { 4, 3, 2, 1 };
  511. var subject = CreateSubject(bytes);
  512. var result = subject.ReadInt32();
  513. result.Should().Be(0x01020304);
  514. }
  515. [Theory]
  516. [ParameterAttributeData]
  517. public void ReadInt32_should_return_expected_result(
  518. [Values(1, 2)]
  519. int numberOfChunks,
  520. [Values(-1, 0, 1, int.MaxValue, int.MinValue)]
  521. int value)
  522. {
  523. var bytes = BitConverter.GetBytes(value);
  524. var subject = CreateSubject(bytes, numberOfChunks);
  525. var result = subject.ReadInt32();
  526. result.Should().Be(value);
  527. subject.Position.Should().Be(4);
  528. }
  529. [Theory]
  530. [ParameterAttributeData]
  531. public void ReadInt32_should_throw_when_at_end_of_stream(
  532. [Values(1, 2)]
  533. int numberOfChunks,
  534. [Values(0, 1, 3)]
  535. int length)
  536. {
  537. var subject = CreateSubject(length, numberOfChunks);
  538. Action action = () => subject.ReadInt32();
  539. action.ShouldThrow<EndOfStreamException>();
  540. }
  541. [Fact]
  542. public void ReadInt32_should_throw_when_subject_is_disposed()
  543. {
  544. var subject = CreateDisposedSubject();
  545. Action action = () => subject.ReadInt32();
  546. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("ByteBufferStream");
  547. }
  548. [Fact]
  549. public void ReadInt64_should_be_little_endian()
  550. {
  551. var bytes = new byte[] { 8, 7, 6, 5, 4, 3, 2, 1 };
  552. var subject = CreateSubject(bytes);
  553. var result = subject.ReadInt64();
  554. result.Should().Be(0x0102030405060708);
  555. }
  556. [Theory]
  557. [ParameterAttributeData]
  558. public void ReadInt64_should_return_expected_result(
  559. [Values(1, 2)]
  560. int numberOfChunks,
  561. [Values(-1, 0, 1, long.MaxValue, long.MinValue)]
  562. long value)
  563. {
  564. var bytes = BitConverter.GetBytes(value);
  565. var subject = CreateSubject(bytes, numberOfChunks);
  566. var result = subject.ReadInt64();
  567. result.Should().Be(value);
  568. subject.Position.Should().Be(8);
  569. }
  570. [Theory]
  571. [ParameterAttributeData]
  572. public void ReadInt64_should_throw_when_at_end_of_stream(
  573. [Values(1, 2)]
  574. int numberOfChunks,
  575. [Values(0, 1, 7)]
  576. int length)
  577. {
  578. var subject = CreateSubject(length, numberOfChunks);
  579. Action action = () => subject.ReadInt64();
  580. action.ShouldThrow<EndOfStreamException>();
  581. }
  582. [Fact]
  583. public void ReadInt64_should_throw_when_subject_is_disposed()
  584. {
  585. var subject = CreateDisposedSubject();
  586. Action action = () => subject.ReadInt64();
  587. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("ByteBufferStream");
  588. }
  589. [Fact]
  590. public void ReadObjectId_should_be_big_endian()
  591. {
  592. var bytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
  593. var subject = CreateSubject(bytes);
  594. var result = subject.ReadObjectId();
  595. result.Timestamp.Should().Be(0x01020304);
  596. result._a().Should().Be(0x01020304);
  597. result._b().Should().Be(0x05060708);
  598. result._c().Should().Be(0x090a0b0c);
  599. }
  600. [Theory]
  601. [ParameterAttributeData]
  602. public void ReadObjectId_should_return_expected_result(
  603. [Values(1, 2)]
  604. int numberOfChunks)
  605. {
  606. var bytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
  607. var subject = CreateSubject(bytes, numberOfChunks);
  608. var expectedResult = ObjectIdReflector.Create(0x01020304, 0x0506070809, 0x0a0b0c);
  609. var result = subject.ReadObjectId();
  610. result.Should().Be(expectedResult);
  611. subject.Position.Should().Be(12);
  612. }
  613. [Theory]
  614. [ParameterAttributeData]
  615. public void ReadObjectId_should_throw_when_at_end_of_stream(
  616. [Values(1, 2)]
  617. int numberOfChunks,
  618. [Values(0, 1, 11)]
  619. int length)
  620. {
  621. var subject = CreateSubject(length, numberOfChunks);
  622. Action action = () => subject.ReadObjectId();
  623. action.ShouldThrow<EndOfStreamException>();
  624. }
  625. [Fact]
  626. public void ReadObjectId_should_throw_when_subject_is_disposed()
  627. {
  628. var subject = CreateDisposedSubject();
  629. Action action = () => subject.ReadObjectId();
  630. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("ByteBufferStream");
  631. }
  632. [Theory]
  633. [InlineData(4, new byte[] { 4, 0, 0, 0 })]
  634. [InlineData(5, new byte[] { 5, 0, 0, 0, 1 })]
  635. [InlineData(6, new byte[] { 6, 0, 0, 0, 1, 2 })]
  636. [InlineData(7, new byte[] { 7, 0, 0, 0, 1, 2, 3 })]
  637. public void ReadSlice_should_return_expected_result(int length, byte[] bytes)
  638. {
  639. var mockBuffer = new Mock<IByteBuffer>();
  640. mockBuffer.Setup(s => s.AccessBackingBytes(It.IsAny<int>())).Returns((int p) => { return new ArraySegment<byte>(bytes, p, bytes.Length - p); });
  641. mockBuffer.SetupGet(s => s.IsReadOnly).Returns(true);
  642. mockBuffer.SetupGet(s => s.Length).Returns(bytes.Length);
  643. var subject = new ByteBufferStream(mockBuffer.Object);
  644. var expectedPosition = length;
  645. subject.ReadSlice();
  646. subject.Position.Should().Be(expectedPosition);
  647. mockBuffer.Verify(b => b.GetSlice(0, bytes.Length), Times.Once);
  648. }
  649. [Theory]
  650. [InlineData(1, new byte[] { })]
  651. [InlineData(2, new byte[] { 6 })]
  652. [InlineData(3, new byte[] { 6, 0 })]
  653. [InlineData(4, new byte[] { 6, 0, 0 })]
  654. [InlineData(5, new byte[] { 6, 0, 0, 0 })]
  655. [InlineData(6, new byte[] { 6, 0, 0, 0, 1 })]
  656. public void ReadSlice_should_throw_when_at_end_of_stream(int length, byte[] bytes)
  657. {
  658. var subject = CreateSubject(bytes);
  659. Action action = () => subject.ReadSlice();
  660. action.ShouldThrow<EndOfStreamException>();
  661. }
  662. [Fact]
  663. public void ReadSlice_should_throw_when_subject_is_disposed()
  664. {
  665. var subject = CreateDisposedSubject();
  666. Action action = () => subject.ReadSlice();
  667. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("ByteBufferStream");
  668. }
  669. [Theory]
  670. [InlineData(5, 1, new byte[] { 1, 0, 0, 0, 0 }, "")]
  671. [InlineData(6, 1, new byte[] { 2, 0, 0, 0, 97, 0 }, "a")]
  672. [InlineData(6, 2, new byte[] { 2, 0, 0, 0, 97, 0 }, "a")]
  673. [InlineData(7, 1, new byte[] { 3, 0, 0, 0, 97, 98, 0 }, "ab")]
  674. [InlineData(7, 2, new byte[] { 3, 0, 0, 0, 97, 98, 0 }, "ab")]
  675. [InlineData(8, 1, new byte[] { 4, 0, 0, 0, 97, 98, 99, 0 }, "abc")]
  676. [InlineData(8, 2, new byte[] { 4, 0, 0, 0, 97, 98, 99, 0 }, "abc")]
  677. public void ReadString_should_return_expected_result(int length, int numberOfAdditionalChunks, byte[] bytes, string expectedResult)
  678. {
  679. var subject = CreateSubject(bytes, 4, CalculateChunkSizes(length - 4, numberOfAdditionalChunks));
  680. var result = subject.ReadString(Utf8Encodings.Strict);
  681. result.Should().Be(expectedResult);
  682. subject.Position.Should().Be(length);
  683. }
  684. [Fact]
  685. public void ReadString_should_throw_when_encoding_is_null()
  686. {
  687. var subject = CreateSubject();
  688. Action action = () => subject.ReadString(null);
  689. action.ShouldThrow<ArgumentNullException>().And.ParamName.Should().Be("encoding");
  690. }
  691. [Theory]
  692. [InlineData(4, 1, new byte[] { 1, 0, 0, 0 })]
  693. [InlineData(5, 1, new byte[] { 2, 0, 0, 0, 97 })]
  694. [InlineData(6, 1, new byte[] { 3, 0, 0, 0, 97, 98 })]
  695. [InlineData(6, 2, new byte[] { 3, 0, 0, 0, 97, 98 })]
  696. [InlineData(7, 1, new byte[] { 4, 0, 0, 0, 97, 98, 99 })]
  697. [InlineData(7, 2, new byte[] { 4, 0, 0, 0, 97, 98, 99 })]
  698. public void ReadString_should_throw_when_at_end_of_stream(int length, int numberOfAdditionalChunks, byte[] bytes)
  699. {
  700. var subject = CreateSubject(bytes, 4, CalculateChunkSizes(length - 4, numberOfAdditionalChunks));
  701. Action action = () => subject.ReadString(Utf8Encodings.Strict);
  702. action.ShouldThrow<EndOfStreamException>();
  703. }
  704. [Fact]
  705. public void ReadString_should_throw_when_length_is_less_than_zero()
  706. {
  707. var bytes = BitConverter.GetBytes(-1);
  708. var subject = CreateSubject(bytes);
  709. Action action = () => subject.ReadString(Utf8Encodings.Strict);
  710. action.ShouldThrow<FormatException>();
  711. }
  712. [Fact]
  713. public void ReadString_should_throw_when_subject_is_disposed()
  714. {
  715. var subject = CreateDisposedSubject();
  716. Action action = () => subject.ReadString(Utf8Encodings.Strict);
  717. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("ByteBufferStream");
  718. }
  719. [Theory]
  720. [InlineData(5, 1, new byte[] { 1, 0, 0, 0, 1 })]
  721. [InlineData(6, 1, new byte[] { 2, 0, 0, 0, 97, 1 })]
  722. [InlineData(6, 2, new byte[] { 2, 0, 0, 0, 97, 1 })]
  723. [InlineData(7, 1, new byte[] { 3, 0, 0, 0, 97, 98, 1 })]
  724. [InlineData(7, 2, new byte[] { 3, 0, 0, 0, 97, 98, 1 })]
  725. [InlineData(8, 1, new byte[] { 4, 0, 0, 0, 97, 98, 99, 1 })]
  726. [InlineData(8, 2, new byte[] { 4, 0, 0, 0, 97, 98, 99, 1 })]
  727. public void ReadString_should_throw_when_terminating_null_byte_is_missing(int length, int numberOfAdditionalChunks, byte[] bytes)
  728. {
  729. var subject = CreateSubject(bytes, 4, CalculateChunkSizes(length - 4, numberOfAdditionalChunks));
  730. Action action = () => subject.ReadString(Utf8Encodings.Strict);
  731. action.ShouldThrow<FormatException>();
  732. }
  733. [Theory]
  734. [InlineData(SeekOrigin.Begin, 1, 0, 0)]
  735. [InlineData(SeekOrigin.Begin, 1, 1, 1)]
  736. [InlineData(SeekOrigin.Current, 1, -1, 0)]
  737. [InlineData(SeekOrigin.Current, 1, 0, 1)]
  738. [InlineData(SeekOrigin.Current, 1, 1, 2)]
  739. [InlineData(SeekOrigin.End, 1, -1, 2)]
  740. [InlineData(SeekOrigin.End, 1, 0, 3)]
  741. public void Seek_should_return_expected_result(SeekOrigin origin, long position, long offset, int expectedPosition)
  742. {
  743. var subject = CreateSubject();
  744. var mockBuffer = Mock.Get(subject.Buffer);
  745. mockBuffer.SetupGet(b => b.Capacity).Returns(3);
  746. subject.SetLength(3);
  747. subject.Position = position;
  748. var result = subject.Seek(offset, origin);
  749. result.Should().Be(expectedPosition);
  750. subject.Position.Should().Be(expectedPosition);
  751. }
  752. [Fact]
  753. public void Seek_should_throw_when_origin_is_invalid()
  754. {
  755. var subject = CreateSubject();
  756. Action action = () => subject.Seek(0, (SeekOrigin)(-1));
  757. action.ShouldThrow<ArgumentException>().And.ParamName.Should().Be("origin");
  758. }
  759. [Theory]
  760. [InlineData(SeekOrigin.Begin, -1)]
  761. [InlineData(SeekOrigin.Begin, (long)int.MaxValue + 1)]
  762. [InlineData(SeekOrigin.Current, -2)]
  763. [InlineData(SeekOrigin.Current, int.MaxValue)]
  764. [InlineData(SeekOrigin.End, -3)]
  765. [InlineData(SeekOrigin.End, int.MaxValue - 1)]
  766. public void Seek_should_throw_when_new_position_is_invalid(SeekOrigin origin, long offset)
  767. {
  768. var subject = CreateSubject();
  769. var mockBuffer = Mock.Get(subject.Buffer);
  770. mockBuffer.SetupGet(b => b.Capacity).Returns(2);
  771. subject.SetLength(2);
  772. subject.Position = 1;
  773. Action action = () => subject.Seek(offset, origin);
  774. action.ShouldThrow<IOException>();
  775. }
  776. [Fact]
  777. public void Seek_should_throw_when_subject_is_disposed()
  778. {
  779. var subject = CreateDisposedSubject();
  780. Action action = () => subject.Seek(0, SeekOrigin.Begin);
  781. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("ByteBufferStream");
  782. }
  783. [Fact]
  784. public void SetLength_should_throw_when_buffer_is_not_writable()
  785. {
  786. var subject = CreateSubject();
  787. var mockBuffer = Mock.Get(subject.Buffer);
  788. mockBuffer.SetupGet(b => b.IsReadOnly).Returns(true);
  789. Action action = () => subject.SetLength(0);
  790. action.ShouldThrow<NotSupportedException>();
  791. }
  792. [Theory]
  793. [ParameterAttributeData]
  794. public void SetLength_should_set_length(
  795. [Values(0, 1, 2, 3)]
  796. long length)
  797. {
  798. var subject = CreateSubject();
  799. var mockBuffer = Mock.Get(subject.Buffer);
  800. subject.SetLength(length);
  801. subject.Length.Should().Be(length);
  802. mockBuffer.Verify(b => b.EnsureCapacity((int)length), Times.Once);
  803. }
  804. [Theory]
  805. [ParameterAttributeData]
  806. public void SetLength_should_set_position_when_position_is_greater_than_new_length(
  807. [Values(0, 1, 2, 3)]
  808. long length)
  809. {
  810. var subject = CreateSubject();
  811. subject.Position = length + 1;
  812. subject.SetLength(length);
  813. subject.Position.Should().Be(length);
  814. }
  815. [Theory]
  816. [ParameterAttributeData]
  817. public void SetLength_should_throw_when_length_is_out_of_range(
  818. [Values(-1, (long)int.MaxValue + 1)]
  819. long length)
  820. {
  821. var subject = CreateSubject();
  822. Action action = () => subject.SetLength(length);
  823. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("value");
  824. }
  825. [Fact]
  826. public void SetLength_should_throw_when_subject_is_disposed()
  827. {
  828. var subject = CreateDisposedSubject();
  829. Action action = () => subject.SetLength(0);
  830. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("ByteBufferStream");
  831. }
  832. [Theory]
  833. [InlineData(1, 1, new byte[] { 0 }, 1)]
  834. [InlineData(1, 2, new byte[] { 0 }, 1)]
  835. [InlineData(2, 1, new byte[] { 97, 0 }, 2)]
  836. [InlineData(2, 2, new byte[] { 97, 0 }, 2)]
  837. [InlineData(3, 2, new byte[] { 97, 98, 0 }, 3)]
  838. [InlineData(3, 1, new byte[] { 97, 98, 0 }, 3)]
  839. [InlineData(4, 1, new byte[] { 97, 98, 99, 0 }, 4)]
  840. [InlineData(4, 2, new byte[] { 97, 98, 99, 0 }, 4)]
  841. public void SkiCString_should_have_expected_effect(int length, int numberOfChunks, byte[] bytes, long expectedPosition)
  842. {
  843. var subject = CreateSubject(bytes, numberOfChunks);
  844. subject.SkipCString();
  845. subject.Position.Should().Be(expectedPosition);
  846. }
  847. [Theory]
  848. [InlineData(0, 1, new byte[] { })]
  849. [InlineData(1, 1, new byte[] { 97 })]
  850. [InlineData(2, 1, new byte[] { 97, 98 })]
  851. [InlineData(2, 2, new byte[] { 97, 98 })]
  852. [InlineData(3, 1, new byte[] { 97, 98, 99 })]
  853. [InlineData(3, 2, new byte[] { 97, 98, 99 })]
  854. public void SkipCString_should_throw_when_end_of_stream_is_reached(int length, int numberOfChunks, byte[] bytes)
  855. {
  856. var subject = CreateSubject(bytes);
  857. Action action = () => subject.SkipCString();
  858. action.ShouldThrow<EndOfStreamException>();
  859. }
  860. [Fact]
  861. public void SkipCString_should_throw_when_subject_is_disposed()
  862. {
  863. var subject = CreateDisposedSubject();
  864. Action action = () => subject.SkipCString();
  865. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("ByteBufferStream");
  866. }
  867. [Fact]
  868. public void ThrowIfEndOfStream_should_throw_when_position_plus_length_exceeds_2GB()
  869. {
  870. using (var buffer = new ByteArrayBuffer(new byte[1024]))
  871. using (var subject = new ByteBufferStream(buffer))
  872. {
  873. subject.Position = 1024;
  874. subject.WriteInt32(int.MaxValue - 128);
  875. subject.Position = 1024;
  876. Action action = () => subject.ReadSlice(); // indirectly calls private ThrowIfEndOfStream method
  877. action.ShouldThrow<EndOfStreamException>();
  878. }
  879. }
  880. [Fact]
  881. public void Write_should_clear_bytes_between_length_and_position()
  882. {
  883. var subject = CreateSubject();
  884. var mockBuffer = Mock.Get(subject.Buffer);
  885. subject.Position = 1;
  886. subject.Write(new byte[3], 1, 2);
  887. mockBuffer.Verify(b => b.Clear(0, 1), Times.Once);
  888. }
  889. [Fact]
  890. public void Write_should_ensure_capacity()
  891. {
  892. var subject = CreateSubject();
  893. var mockBuffer = Mock.Get(subject.Buffer);
  894. var capacity = 0;
  895. mockBuffer.SetupGet(b => b.Capacity).Returns(() => capacity);
  896. mockBuffer.Setup(b => b.EnsureCapacity(It.IsAny<int>())).Callback((int minimumCapacity) => capacity = minimumCapacity);
  897. mockBuffer.SetupProperty(b => b.Length);
  898. subject.Position = 1;
  899. subject.Write(new byte[3], 1, 2);
  900. mockBuffer.Verify(b => b.EnsureCapacity(3), Times.Once);
  901. subject.Buffer.Length.Should().Be(3);
  902. }
  903. [Theory]
  904. [InlineData(1, 0, 1, 0, 1)]
  905. [InlineData(4, 1, 2, 1, 3)]
  906. public void Write_should_have_expected_effect(int sourceSize, int offset, int count, long initialPosition, long expectedPosition)
  907. {
  908. var subject = CreateSubject();
  909. var mockBuffer = Mock.Get(subject.Buffer);
  910. subject.Position = initialPosition;
  911. var source = new byte[sourceSize];
  912. subject.Write(source, offset, count);
  913. subject.Position.Should().Be(expectedPosition);
  914. subject.Length.Should().Be(expectedPosition);
  915. mockBuffer.Verify(b => b.SetBytes((int)initialPosition, source, offset, count), Times.Once);
  916. }
  917. [Fact]
  918. public void Write_should_throw_when_buffer_is_null()
  919. {
  920. var subject = CreateSubject();
  921. Action action = () => subject.Write(null, 0, 0);
  922. action.ShouldThrow<ArgumentNullException>().And.ParamName.Should().Be("buffer");
  923. }
  924. [Theory]
  925. [InlineData(0, 0, -1)]
  926. [InlineData(0, 0, 1)]
  927. [InlineData(1, 0, -1)]
  928. [InlineData(1, 0, 2)]
  929. [InlineData(1, 1, -2)]
  930. [InlineData(1, 1, 1)]
  931. [InlineData(2, 0, -1)]
  932. [InlineData(2, 0, 3)]
  933. [InlineData(2, 1, -2)]
  934. [InlineData(2, 1, 2)]
  935. [InlineData(2, 2, -3)]
  936. [InlineData(2, 2, 1)]
  937. public void Write_should_throw_when_count_is_out_of_range(int sourceSize, int offset, int count)
  938. {
  939. var subject = CreateSubject();
  940. var source = new byte[sourceSize];
  941. Action action = () => subject.Write(source, offset, count);
  942. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("count");
  943. }
  944. [Fact]
  945. public void Write_should_throw_when_not_writable()
  946. {
  947. var subject = CreateSubject();
  948. var mockBuffer = Mock.Get(subject.Buffer);
  949. mockBuffer.SetupGet(b => b.IsReadOnly).Returns(true);
  950. var source = new byte[1];
  951. Action action = () => subject.Write(source, 0, 0);
  952. action.ShouldThrow<NotSupportedException>();
  953. }
  954. [Theory]
  955. [ParameterAttributeData]
  956. public void Write_should_throw_when_offset_is_out_of_range(
  957. [Values(-1, 2)]
  958. int offset)
  959. {
  960. var subject = CreateSubject();
  961. var source = new byte[1];
  962. Action action = () => subject.Write(source, offset, 0);
  963. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("offset");
  964. }
  965. [Fact]
  966. public void Write_should_throw_when_subject_is_disposed()
  967. {
  968. var subject = CreateDisposedSubject();
  969. var source = new byte[1];
  970. Action action = () => subject.Write(source, 0, 0);
  971. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("ByteBufferStream");
  972. }
  973. [Theory]
  974. [InlineData(0, 1)]
  975. [InlineData(1, 2)]
  976. public void WriteByte_should_have_expected_effect(long initialPosition, long expectedPosition)
  977. {
  978. var subject = CreateSubject();
  979. var mockBuffer = Mock.Get(subject.Buffer);
  980. subject.Position = initialPosition;
  981. subject.WriteByte(4);
  982. subject.Position.Should().Be(expectedPosition);
  983. subject.Length.Should().Be(expectedPosition);
  984. mockBuffer.Verify(b => b.SetByte((int)initialPosition, 4), Times.Once);
  985. }
  986. [Fact]
  987. public void WriteByte_should_throw_when_subject_is_disposed()
  988. {
  989. var subject = CreateDisposedSubject();
  990. Action action = () => subject.WriteByte(0);
  991. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("ByteBufferStream");
  992. }
  993. [Theory]
  994. [InlineData(1, 1, "", new byte[] { 0 })]
  995. [InlineData(2, 1, "a", new byte[] { 97, 0 })]
  996. [InlineData(2, 2, "a", new byte[] { 97, 0 })]
  997. [InlineData(3, 1, "ab", new byte[] { 97, 98, 0 })]
  998. [InlineData(3, 2, "ab", new byte[] { 97, 98, 0 })]
  999. [InlineData(4, 1, "abc", new byte[] { 97, 98, 99, 0 })]
  1000. [InlineData(4, 2, "abc", new byte[] { 97, 98, 99, 0 })]
  1001. public void WriteCString_should_have_expected_effect(int length, int numberOfChunks, string value, byte[] expectedBytes)
  1002. {
  1003. var maxLength = Utf8Encodings.Strict.GetMaxByteCount(value.Length) + 1;
  1004. var subject = CreateSubject(0, CalculateChunkSizes(maxLength, numberOfChunks));
  1005. subject.WriteCString(value);
  1006. subject.Position = 0;
  1007. subject.ReadBytes((int)subject.Length).Should().Equal(expectedBytes);
  1008. }
  1009. [Fact]
  1010. public void WriteCString_should_have_expected_effect_when_tempUtf8_is_not_used()
  1011. {
  1012. var value = new string('a', 1024);
  1013. var maxLength = Utf8Encodings.Strict.GetMaxByteCount(value.Length) + 1;
  1014. var subject = CreateSubject(0, CalculateChunkSizes(maxLength, 2));
  1015. var expectedBytes = Utf8Encodings.Strict.GetBytes(value).Concat(new byte[] { 0 }).ToArray();
  1016. subject.WriteCString(value);
  1017. subject.Position = 0;
  1018. subject.ReadBytes((int)subject.Length).Should().Equal(expectedBytes);
  1019. }
  1020. [Fact]
  1021. public void WriteCString_should_throw_when_subject_is_disposed()
  1022. {
  1023. var subject = CreateDisposedSubject();
  1024. Action action = () => subject.WriteCString("");
  1025. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("ByteBufferStream");
  1026. }
  1027. [Fact]
  1028. public void WriteCString_should_throw_when_value_is_null()
  1029. {
  1030. var subject = CreateSubject();
  1031. Action action = () => subject.WriteCString(null);
  1032. action.ShouldThrow<ArgumentNullException>().And.ParamName.Should().Be("value");
  1033. }
  1034. [Theory]
  1035. [ParameterAttributeData]
  1036. public void WriteCString_should_throw_when_value_contains_nulls(
  1037. [Values(1, 2)]
  1038. int numberOfChunks,
  1039. [Values("\0", "a\0", "a\0b")]
  1040. string value)
  1041. {
  1042. var maxLength = Utf8Encodings.Strict.GetMaxByteCount(value.Length) + 1;
  1043. var subject = CreateSubject(0, CalculateChunkSizes(maxLength, numberOfChunks));
  1044. Action action = () => subject.WriteCString(value);
  1045. action.ShouldThrow<ArgumentException>().And.ParamName.Should().Be("value");
  1046. }
  1047. [Fact]
  1048. public void WriteCString_should_throw_when_value_contains_nulls_and_tempUtf8_is_not_used()
  1049. {
  1050. var value = new string('a', 1024) + '\0';
  1051. var maxLength = Utf8Encodings.Strict.GetMaxByteCount(value.Length) + 1;
  1052. var subject = CreateSubject(0, CalculateChunkSizes(maxLength, 2));
  1053. var expectedBytes = Utf8Encodings.Strict.GetBytes(value).Concat(new byte[] { 0 }).ToArray();
  1054. Action action = () => subject.WriteCString(value);
  1055. action.ShouldThrow<ArgumentException>().And.ParamName.Should().Be("value");
  1056. }
  1057. [Fact]
  1058. public void WriteCStringBytes_should_have_expected_effect()
  1059. {
  1060. var subject = CreateSubject();
  1061. var mockBuffer = Mock.Get(subject.Buffer);
  1062. var value = new byte[] { 97, 98, 99 };
  1063. subject.WriteCStringBytes(value);
  1064. subject.Position.Should().Be(4);
  1065. subject.Length.Should().Be(4);
  1066. mockBuffer.Verify(b => b.SetBytes(0, value, 0, 3), Times.Once);
  1067. mockBuffer.Verify(b => b.SetByte(3, 0), Times.Once);
  1068. }
  1069. [Fact]
  1070. public void WriteCStringBytes_should_throw_when_subject_is_disposed()
  1071. {
  1072. var subject = CreateDisposedSubject();
  1073. Action action = () => subject.WriteCStringBytes(new byte[0]);
  1074. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("ByteBufferStream");
  1075. }
  1076. [Fact]
  1077. public void WriteCStringBytes_should_throw_when_value_is_null()
  1078. {
  1079. var subject = CreateSubject();
  1080. Action action = () => subject.WriteCStringBytes(null);
  1081. action.ShouldThrow<ArgumentNullException>().And.ParamName.Should().Be("value");
  1082. }
  1083. [Theory]
  1084. [ParameterAttributeData]
  1085. public void WriteDecimal128_should_have_expected_effect(
  1086. [Values("-1.0", "0.0", "1.0", "NaN", "-Infinity", "Infinity")]
  1087. string valueString)
  1088. {
  1089. var value = Decimal128.Parse(valueString);
  1090. var subject = CreateSubject();
  1091. var mockBuffer = Mock.Get(subject.Buffer);
  1092. var expectedBytes = new byte[16];
  1093. Buffer.BlockCopy(BitConverter.GetBytes(value.GetIEEELowBits()), 0, expectedBytes, 0, 8);
  1094. Buffer.BlockCopy(BitConverter.GetBytes(value.GetIEEEHighBits()), 0, expectedBytes, 8, 8);
  1095. subject.WriteDecimal128(value);
  1096. subject.Position.Should().Be(16);
  1097. subject.Length.Should().Be(16);
  1098. mockBuffer.Verify(b => b.SetBytes(0, It.Is<byte[]>(x => x.SequenceEqual(expectedBytes.Take(8))), 0, 8), Times.Once);
  1099. mockBuffer.Verify(b => b.SetBytes(8, It.Is<byte[]>(x => x.SequenceEqual(expectedBytes.Skip(8))), 0, 8), Times.Once);
  1100. }
  1101. [Fact]
  1102. public void WriteDecimal128_should_throw_when_subject_is_disposed()
  1103. {
  1104. var subject = CreateDisposedSubject();
  1105. Action action = () => subject.WriteDecimal128(Decimal128.Zero);
  1106. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("ByteBufferStream");
  1107. }
  1108. [Theory]
  1109. [ParameterAttributeData]
  1110. public void WriteDouble_should_have_expected_effect(
  1111. [Values(-1.0, 0.0, 1.0, double.Epsilon, double.MaxValue, double.MinValue, double.NaN, double.NegativeInfinity, double.PositiveInfinity)]
  1112. double value)
  1113. {
  1114. var subject = CreateSubject();
  1115. var mockBuffer = Mock.Get(subject.Buffer);
  1116. var bytes = BitConverter.GetBytes(value);
  1117. subject.WriteDouble(value);
  1118. subject.Position.Should().Be(8);
  1119. subject.Length.Should().Be(8);
  1120. mockBuffer.Verify(b => b.SetBytes(0, It.Is<byte[]>(x => x.SequenceEqual(bytes)), 0, 8), Times.Once);
  1121. }
  1122. [Fact]
  1123. public void WriteDouble_should_throw_when_subject_is_disposed()
  1124. {
  1125. var subject = CreateDisposedSubject();
  1126. Action action = () => subject.WriteDouble(0.0);
  1127. action.ShouldThrow<ObjectDisposedExcept

Large files files are truncated, but you can click here to view the full file