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

/src/MongoDB.Bson.Tests/IO/SingleChunkBufferTests.cs

http://github.com/mongodb/mongo-csharp-driver
C# | 853 lines | 635 code | 202 blank | 16 comment | 0 complexity | 0b98d6253e225cd9ac0b84863801db80 MD5 | raw file
Possible License(s): Apache-2.0
  1. /* Copyright 2010-2014 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.Linq;
  18. using System.Reflection;
  19. using System.Text;
  20. using System.Threading.Tasks;
  21. using FluentAssertions;
  22. using MongoDB.Bson.IO;
  23. using NSubstitute;
  24. using NUnit.Framework;
  25. namespace MongoDB.Bson.Tests.IO
  26. {
  27. [TestFixture]
  28. public class SingleChunkBufferTests
  29. {
  30. [TestCase(0, 0)]
  31. [TestCase(1, 1)]
  32. [TestCase(2, 2)]
  33. public void AccessBackingBytes_should_return_expected_result_for_length(int length, int expectedCount)
  34. {
  35. var bytes = new byte[2];
  36. var subject = CreateSubject(bytes, length);
  37. var result = subject.AccessBackingBytes(0);
  38. result.Array.Should().BeSameAs(bytes);
  39. result.Offset.Should().Be(0);
  40. result.Count.Should().Be(expectedCount);
  41. }
  42. [TestCase(0, 0, 2)]
  43. [TestCase(1, 1, 1)]
  44. [TestCase(2, 2, 0)]
  45. public void AccessBackingBytes_should_return_expected_result_for_position(int position, int expectedOffset, int expectedCount)
  46. {
  47. var bytes = new byte[2];
  48. var subject = CreateSubject(bytes);
  49. var result = subject.AccessBackingBytes(position);
  50. result.Array.Should().BeSameAs(bytes);
  51. result.Offset.Should().Be(expectedOffset);
  52. result.Count.Should().Be(expectedCount);
  53. }
  54. [Test]
  55. public void AccessBackingBytes_should_throw_when_position_is_invalid(
  56. [Values(-1, 3)]
  57. int position)
  58. {
  59. var subject = CreateSubject(2);
  60. Action action = () => subject.AccessBackingBytes(position);
  61. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("position");
  62. }
  63. [Test]
  64. public void AccessBackingBytes_should_throw_when_subject_is_disposed()
  65. {
  66. var subject = CreateDisposedSubject();
  67. Action action = () => subject.AccessBackingBytes(0);
  68. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("SingleChunkBuffer");
  69. }
  70. [TestCase(false, 2)]
  71. [TestCase(true, 1)]
  72. public void Capacity_get_should_return_expected_result(bool isReadOnly, int expectedResult)
  73. {
  74. var subject = CreateSubject(2, 1, isReadOnly);
  75. var result = subject.Capacity;
  76. result.Should().Be(expectedResult);
  77. }
  78. [Test]
  79. public void Capacity_get_should_throw_when_subject_is_disposed()
  80. {
  81. var subject = CreateDisposedSubject();
  82. Action action = () => { var _ = subject.Capacity; };
  83. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("SingleChunkBuffer");
  84. }
  85. [TestCase(0, new byte[] { 1, 2 })]
  86. [TestCase(1, new byte[] { 0, 2 })]
  87. [TestCase(2, new byte[] { 0, 0 })]
  88. public void Clear_should_have_expected_effect_for_count(int count, byte[] expectedBytes)
  89. {
  90. var bytes = new byte[] { 1, 2 };
  91. var subject = CreateSubject(bytes);
  92. subject.Clear(0, count);
  93. bytes.Should().Equal(expectedBytes);
  94. }
  95. [TestCase(1, new byte[] { 1, 0, 3 })]
  96. [TestCase(2, new byte[] { 1, 2, 0 })]
  97. public void Clear_should_have_expected_effect_for_position(int position, byte[] expectedBytes)
  98. {
  99. var bytes = new byte[] { 1, 2, 3 };
  100. var subject = CreateSubject(bytes);
  101. subject.Clear(position, 1);
  102. bytes.Should().Equal(expectedBytes);
  103. }
  104. [TestCase(0, -1)]
  105. [TestCase(0, 3)]
  106. [TestCase(1, 2)]
  107. [TestCase(2, 1)]
  108. public void Clear_should_throw_when_count_is_invalid(int position, int count)
  109. {
  110. var subject = CreateSubject(2);
  111. Action action = () => subject.Clear(position, count);
  112. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("count");
  113. }
  114. [Test]
  115. public void Clear_should_throw_when_position_is_invalid(
  116. [Values(-1, 3)]
  117. int position)
  118. {
  119. var subject = CreateSubject(2);
  120. Action action = () => subject.Clear(position, 0);
  121. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("position");
  122. }
  123. [Test]
  124. public void Clear_should_throw_when_subject_is_disposed()
  125. {
  126. var subject = CreateDisposedSubject();
  127. Action action = () => subject.Clear(0, 0);
  128. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("SingleChunkBuffer");
  129. }
  130. [Test]
  131. public void Clear_should_throw_when_subject_is_read_only()
  132. {
  133. var subject = CreateSubject(isReadOnly: true);
  134. Action action = () => subject.Clear(0, 0);
  135. action.ShouldThrow<InvalidOperationException>();
  136. }
  137. [Test]
  138. public void constructor_should_initialize_subject(
  139. [Values(1, 2)]
  140. int length,
  141. [Values(false, true)]
  142. bool isReadOnly)
  143. {
  144. var chunk = CreateFakeChunk(length);
  145. var subject = new SingleChunkBuffer(chunk, length, isReadOnly);
  146. var reflector = new Reflector(subject);
  147. subject.IsReadOnly.Should().Be(isReadOnly);
  148. subject.Length.Should().Be(length);
  149. reflector._chunk.Should().BeSameAs(chunk);
  150. reflector._disposed.Should().BeFalse();
  151. }
  152. [Test]
  153. public void constructor_should_throw_when_chunk_is_null()
  154. {
  155. Action action = () => new SingleChunkBuffer(null, 0);
  156. action.ShouldThrow<ArgumentNullException>().And.ParamName.Should().Be("chunk");
  157. }
  158. [Test]
  159. public void constructor_should_throw_when_length_is_invalid(
  160. [Values(-1, 3)]
  161. int length)
  162. {
  163. var chunk = CreateFakeChunk(2);
  164. Action action = () => new SingleChunkBuffer(chunk, length);
  165. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("length");
  166. }
  167. [Test]
  168. public void Dispose_can_be_called_multiple_times()
  169. {
  170. var subject = CreateSubject();
  171. subject.Dispose();
  172. subject.Dispose();
  173. }
  174. [Test]
  175. public void Dispose_should_dispose_subject()
  176. {
  177. var subject = CreateSubject();
  178. subject.Dispose();
  179. var reflector = new Reflector(subject);
  180. reflector._disposed.Should().BeTrue();
  181. }
  182. [Test]
  183. public void EnsureCapacity_should_do_nothing_when_minimumCapacity_is_less_than_or_equal_to_capacity(
  184. [Values(0, 1, 2)]
  185. int minimumCapacity)
  186. {
  187. var subject = CreateSubject(2);
  188. subject.EnsureCapacity(minimumCapacity);
  189. subject.Capacity.Should().Be(2);
  190. }
  191. [Test]
  192. public void EnsureCapacity_should_throw_when_minimumCapacity_is_greater_than_capacity()
  193. {
  194. var subject = CreateSubject(2);
  195. Action action = () => subject.EnsureCapacity(3);
  196. action.ShouldThrow<NotSupportedException>();
  197. }
  198. [Test]
  199. public void EnsureCapacity_should_throw_when_minimumCapacity_is_invalid()
  200. {
  201. var subject = CreateSubject(2);
  202. Action action = () => subject.EnsureCapacity(-1);
  203. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("minimumCapacity");
  204. }
  205. [Test]
  206. public void EnsureCapacity_should_throw_when_subject_is_disposed()
  207. {
  208. var subject = CreateDisposedSubject();
  209. Action action = () => subject.EnsureCapacity(1);
  210. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("SingleChunkBuffer");
  211. }
  212. [Test]
  213. public void EnsureCapacity_should_throw_when_subject_is_read_only()
  214. {
  215. var subject = CreateSubject(isReadOnly: true);
  216. Action action = () => subject.EnsureCapacity(0);
  217. action.ShouldThrow<InvalidOperationException>();
  218. }
  219. [TestCase(1, 2)]
  220. [TestCase(2, 3)]
  221. public void GetByte_should_return_expected_result(int position, byte expectedResult)
  222. {
  223. var bytes = new byte[] { 1, 2, 3 };
  224. var subject = CreateSubject(bytes);
  225. var result = subject.GetByte(position);
  226. result.Should().Be(expectedResult);
  227. }
  228. [Test]
  229. public void GetByte_should_throw_when_position_is_invalid(
  230. [Values(-1, 3)]
  231. int position)
  232. {
  233. var subject = CreateSubject(2);
  234. Action action = () => subject.GetByte(position);
  235. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("position");
  236. }
  237. [Test]
  238. public void GetByte_should_throw_when_subject_is_disposed()
  239. {
  240. var subject = CreateDisposedSubject();
  241. Action action = () => subject.GetByte(0);
  242. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("SingleChunkBuffer");
  243. }
  244. [TestCase(0, new byte[] { 0, 0 })]
  245. [TestCase(1, new byte[] { 1, 0 })]
  246. [TestCase(2, new byte[] { 1, 2 })]
  247. public void GetBytes_should_have_expected_effect_for_count(int count, byte[] expectedBytes)
  248. {
  249. var bytes = new byte[] { 1, 2 };
  250. var subject = CreateSubject(bytes);
  251. var destination = new byte[2];
  252. subject.GetBytes(0, destination, 0, count);
  253. destination.Should().Equal(expectedBytes);
  254. }
  255. [TestCase(1, new byte[] { 0, 1, 2, 0 })]
  256. [TestCase(2, new byte[] { 0, 0, 1, 2 })]
  257. public void GetBytes_should_have_expected_effect_for_offset(int offset, byte[] expectedBytes)
  258. {
  259. var bytes = new byte[] { 1, 2 };
  260. var subject = CreateSubject(bytes);
  261. var destination = new byte[4];
  262. subject.GetBytes(0, destination, offset, 2);
  263. destination.Should().Equal(expectedBytes);
  264. }
  265. [TestCase(1, new byte[] { 2, 3 })]
  266. [TestCase(2, new byte[] { 3, 4 })]
  267. public void GetBytes_should_have_expected_effect_for_position(int position, byte[] expectedBytes)
  268. {
  269. var bytes = new byte[] { 1, 2, 3, 4 };
  270. var subject = CreateSubject(bytes);
  271. var destination = new byte[2];
  272. subject.GetBytes(position, destination, 0, 2);
  273. destination.Should().Equal(expectedBytes);
  274. }
  275. [TestCase(0, -1)]
  276. [TestCase(0, 3)]
  277. [TestCase(1, 2)]
  278. [TestCase(2, 1)]
  279. public void GetBytes_should_throw_when_count_is_invalid_for_buffer(int position, int count)
  280. {
  281. var subject = CreateSubject(2);
  282. var destination = new byte[3];
  283. Action action = () => subject.GetBytes(position, destination, 0, count);
  284. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("count");
  285. }
  286. [TestCase(0, -1)]
  287. [TestCase(0, 3)]
  288. [TestCase(1, 2)]
  289. [TestCase(2, 1)]
  290. public void GetBytes_should_throw_when_count_is_invalid_for_destination(int offset, int count)
  291. {
  292. var subject = CreateSubject(3);
  293. var destination = new byte[2];
  294. Action action = () => subject.GetBytes(0, destination, offset, count);
  295. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("count");
  296. }
  297. [Test]
  298. public void GetBytes_should_throw_when_destination_is_null()
  299. {
  300. var subject = CreateSubject();
  301. Action action = () => subject.GetBytes(0, null, 0, 0);
  302. action.ShouldThrow<ArgumentNullException>().And.ParamName.Should().Be("destination");
  303. }
  304. [Test]
  305. public void GetBytes_should_throw_when_offset_is_invalid(
  306. [Values(-1, 3)]
  307. int offset)
  308. {
  309. var subject = CreateSubject(4);
  310. var destination = new byte[2];
  311. Action action = () => subject.GetBytes(0, destination, offset, 0);
  312. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("offset");
  313. }
  314. [Test]
  315. public void GetBytes_should_throw_when_position_is_invalid(
  316. [Values(-1, 3)]
  317. int position)
  318. {
  319. var subject = CreateSubject(2);
  320. var destination = new byte[0];
  321. Action action = () => subject.GetBytes(position, destination, 0, 0);
  322. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("position");
  323. }
  324. [Test]
  325. public void GetBytes_should_throw_when_subject_is_disposed()
  326. {
  327. var subject = CreateDisposedSubject();
  328. var destination = new byte[0];
  329. Action action = () => subject.GetBytes(0, destination, 0, 0);
  330. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("SingleChunkBuffer");
  331. }
  332. [TestCase(0, 2)]
  333. [TestCase(1, 1)]
  334. [TestCase(2, 0)]
  335. public void GetSlice_should_return_expected_result(int position, int length)
  336. {
  337. var bytes = new byte[2];
  338. var subject = CreateSubject(bytes, isReadOnly: true);
  339. var result = subject.GetSlice(position, length);
  340. result.AccessBackingBytes(0).Array.Should().BeSameAs(bytes);
  341. result.AccessBackingBytes(0).Offset.Should().Be(position);
  342. result.AccessBackingBytes(0).Count.Should().Be(length);
  343. }
  344. [Test]
  345. public void GetSlice_should_return_slice_that_does_not_dispose_subject_when_slice_is_disposed()
  346. {
  347. var bytes = new byte[] { 1, 2, 3 };
  348. var subject = CreateSubject(bytes, isReadOnly: true);
  349. var slice = subject.GetSlice(1, 1);
  350. slice.Dispose();
  351. subject.GetByte(1).Should().Be(2);
  352. }
  353. [Test]
  354. public void GetSlice_should_return_slice_that_is_not_disposed_when_subject_is_disposed()
  355. {
  356. var bytes = new byte[] { 1, 2, 3 };
  357. var subject = CreateSubject(bytes, isReadOnly: true);
  358. var slice = subject.GetSlice(1, 1);
  359. subject.Dispose();
  360. slice.GetByte(0).Should().Be(2);
  361. }
  362. [TestCase(0, -1)]
  363. [TestCase(0, 3)]
  364. [TestCase(1, 2)]
  365. [TestCase(2, 1)]
  366. public void GetSlice_should_throw_when_length_is_invalid(int position, int length)
  367. {
  368. var subject = CreateSubject(2, isReadOnly: true);
  369. Action action = () => subject.GetSlice(position, length);
  370. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("length");
  371. }
  372. [Test]
  373. public void GetSlice_should_throw_when_position_is_invalid(
  374. [Values(-1, 3)]
  375. int position)
  376. {
  377. var subject = CreateSubject(2, isReadOnly: true);
  378. Action action = () => subject.GetSlice(position, 0);
  379. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("position");
  380. }
  381. [Test]
  382. public void GetSlice_should_throw_when_subject_is_disposed()
  383. {
  384. var subject = CreateDisposedSubject();
  385. Action action = () => subject.GetSlice(0, 0);
  386. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("SingleChunkBuffer");
  387. }
  388. [Test]
  389. public void GetSlice_should_throw_when_subject_is_not_read_only()
  390. {
  391. var subject = CreateSubject(isReadOnly: false);
  392. Action action = () => subject.GetSlice(0, 0);
  393. action.ShouldThrow<InvalidOperationException>();
  394. }
  395. [Test]
  396. public void IsReadOnly_get_should_return_expected_result(
  397. [Values(false, true)]
  398. bool isReadOnly)
  399. {
  400. var subject = CreateSubject(0, isReadOnly: isReadOnly);
  401. var result = subject.IsReadOnly;
  402. result.Should().Be(isReadOnly);
  403. }
  404. [Test]
  405. public void IsReadOnly_get_should_throw_when_subject_is_disposed()
  406. {
  407. var subject = CreateDisposedSubject();
  408. Action action = () => { var _ = subject.IsReadOnly; };
  409. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("SingleChunkBuffer");
  410. }
  411. [Test]
  412. public void Length_get_should_return_expected_result(
  413. [Values(1, 2)]
  414. int length)
  415. {
  416. var subject = CreateSubject(2, length);
  417. var result = subject.Length;
  418. result.Should().Be(length);
  419. }
  420. [Test]
  421. public void Length_get_should_throw_when_subject_is_disposed()
  422. {
  423. var subject = CreateDisposedSubject();
  424. Action action = () => { var _ = subject.Length; };
  425. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("SingleChunkBuffer");
  426. }
  427. [Test]
  428. public void Length_set_should_have_expected_effect(
  429. [Values(1, 2)]
  430. int length)
  431. {
  432. var subject = CreateSubject(2, 0);
  433. subject.Length = length;
  434. subject.Length.Should().Be(length);
  435. }
  436. [Test]
  437. public void Length_set_should_throw_when_subject_is_read_only()
  438. {
  439. var subject = CreateSubject(0, 0, isReadOnly: true);
  440. Action action = () => subject.Length = 0;
  441. action.ShouldThrow<InvalidOperationException>();
  442. }
  443. [TestCase(0, -1)]
  444. [TestCase(0, 1)]
  445. [TestCase(1, 2)]
  446. [TestCase(2, 3)]
  447. public void Length_set_should_throw_when_value_is_invalid(int size, int value)
  448. {
  449. var subject = CreateSubject(size, 0);
  450. Action action = () => subject.Length = value;
  451. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("value");
  452. }
  453. [Test]
  454. public void Length_set_should_throw_when_subject_is_disposed()
  455. {
  456. var subject = CreateDisposedSubject();
  457. Action action = () => subject.Length = 0;
  458. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("SingleChunkBuffer");
  459. }
  460. [Test]
  461. public void MakeReadOnly_should_have_expected_effect(
  462. [Values(false, true)]
  463. bool isReadOnly)
  464. {
  465. var subject = CreateSubject(isReadOnly: isReadOnly);
  466. subject.MakeReadOnly();
  467. subject.IsReadOnly.Should().BeTrue();
  468. }
  469. [Test]
  470. public void MakeReadOnly_should_throw_when_subject_is_disposed()
  471. {
  472. var subject = CreateDisposedSubject();
  473. Action action = () => subject.MakeReadOnly();
  474. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("SingleChunkBuffer");
  475. }
  476. [TestCase(1, new byte[] { 0, 1, 0 })]
  477. [TestCase(2, new byte[] { 0, 0, 1 })]
  478. public void SetByte_should_have_expected_effect(int position, byte[] expectedBytes)
  479. {
  480. var bytes = new byte[3];
  481. var subject = CreateSubject(bytes);
  482. subject.SetByte(position, 1);
  483. bytes.Should().Equal(expectedBytes);
  484. }
  485. [Test]
  486. public void SetByte_should_throw_when_position_is_invalid(
  487. [Values(-1, 3)]
  488. int position)
  489. {
  490. var subject = CreateSubject(2);
  491. Action action = () => subject.SetByte(position, 0);
  492. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("position");
  493. }
  494. [Test]
  495. public void SetByte_should_throw_when_subject_is_disposed()
  496. {
  497. var subject = CreateDisposedSubject();
  498. Action action = () => subject.SetByte(0, 0);
  499. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("SingleChunkBuffer");
  500. }
  501. [Test]
  502. public void SetByte_should_throw_when_subject_is_read_only()
  503. {
  504. var subject = CreateSubject(isReadOnly: true);
  505. Action action = () => subject.SetByte(0, 0);
  506. action.ShouldThrow<InvalidOperationException>();
  507. }
  508. [TestCase(1, new byte[] { 1, 0 })]
  509. [TestCase(2, new byte[] { 1, 2 })]
  510. public void SetBytes_should_have_expected_effect_for_count(int count, byte[] expectedBytes)
  511. {
  512. var bytes = new byte[2];
  513. var subject = CreateSubject(bytes);
  514. var source = new byte[] { 1, 2 };
  515. subject.SetBytes(0, source, 0, count);
  516. bytes.Should().Equal(expectedBytes);
  517. }
  518. [TestCase(1, new byte[] { 2 })]
  519. [TestCase(2, new byte[] { 3 })]
  520. public void SetBytes_should_have_expected_effect_for_offset(int offset, byte[] expectedBytes)
  521. {
  522. var bytes = new byte[1];
  523. var subject = CreateSubject(bytes);
  524. var source = new byte[] { 1, 2, 3 };
  525. subject.SetBytes(0, source, offset, 1);
  526. bytes.Should().Equal(expectedBytes);
  527. }
  528. [TestCase(1, new byte[] { 0, 1, 0 })]
  529. [TestCase(2, new byte[] { 0, 0, 1 })]
  530. public void SetBytes_should_have_expected_effect_for_position(int position, byte[] expectedBytes)
  531. {
  532. var bytes = new byte[3];
  533. var subject = CreateSubject(bytes);
  534. var source = new byte[] { 1 };
  535. subject.SetBytes(position, source, 0, 1);
  536. bytes.Should().Equal(expectedBytes);
  537. }
  538. [TestCase(0, -1)]
  539. [TestCase(1, 2)]
  540. [TestCase(2, 1)]
  541. public void SetBytes_should_throw_when_count_is_invalid_for_buffer(int position, int count)
  542. {
  543. var subject = CreateSubject(2);
  544. var source = new byte[4];
  545. Action action = () => subject.SetBytes(position, source, 0, count);
  546. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("count");
  547. }
  548. [TestCase(0, -1)]
  549. [TestCase(1, 2)]
  550. [TestCase(2, 1)]
  551. public void SetBytes_should_throw_when_count_is_invalid_for_source(int offset, int count)
  552. {
  553. var subject = CreateSubject(2);
  554. var source = new byte[2];
  555. Action action = () => subject.SetBytes(0, source, offset, count);
  556. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("count");
  557. }
  558. [Test]
  559. public void SetBytes_should_throw_when_offset_is_invalid(
  560. [Values(-1, 3)]
  561. int offset)
  562. {
  563. var subject = CreateSubject(0);
  564. var source = new byte[2];
  565. Action action = () => subject.SetBytes(0, source, offset, 0);
  566. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("offset");
  567. }
  568. [Test]
  569. public void SetBytes_should_throw_when_position_is_invalid(
  570. [Values(-1, 3)]
  571. int position)
  572. {
  573. var subject = CreateSubject(2);
  574. var source = new byte[0];
  575. Action action = () => subject.SetBytes(position, source, 0, 0);
  576. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("position");
  577. }
  578. [Test]
  579. public void SetBytes_should_throw_when_source_is_null()
  580. {
  581. var subject = CreateSubject();
  582. Action action = () => subject.SetBytes(0, null, 0, 0);
  583. action.ShouldThrow<ArgumentNullException>().And.ParamName.Should().Be("source");
  584. }
  585. [Test]
  586. public void SetBytes_should_throw_when_subject_is_disposed()
  587. {
  588. var subject = CreateDisposedSubject();
  589. var source = new byte[0];
  590. Action action = () => subject.SetBytes(0, source, 0, 0);
  591. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("SingleChunkBuffer");
  592. }
  593. [Test]
  594. public void SetBytes_should_throw_when_subject_is_read_only()
  595. {
  596. var subject = CreateSubject(isReadOnly: true);
  597. var source = new byte[0];
  598. Action action = () => subject.SetBytes(0, source, 0, 0);
  599. action.ShouldThrow<InvalidOperationException>();
  600. }
  601. // helper methods
  602. private SingleChunkBuffer CreateDisposedSubject()
  603. {
  604. var subject = CreateSubject();
  605. subject.Dispose();
  606. return subject;
  607. }
  608. private IBsonChunk CreateFakeChunk(int size, int? length = null)
  609. {
  610. var bytes = new byte[size];
  611. var chunk = Substitute.For<IBsonChunk>();
  612. chunk.Bytes.Returns(new ArraySegment<byte>(bytes, 0, length ?? size));
  613. return chunk;
  614. }
  615. private SingleChunkBuffer CreateSubject(byte[] bytes, int? length = null, bool isReadOnly = false)
  616. {
  617. var chunk = new ByteArrayChunk(bytes);
  618. return new SingleChunkBuffer(chunk, length ?? bytes.Length, isReadOnly);
  619. }
  620. private SingleChunkBuffer CreateSubject(int size = 0, int? length = null, bool isReadOnly = false)
  621. {
  622. var chunk = new ByteArrayChunk(size);
  623. return new SingleChunkBuffer(chunk, length ?? size, isReadOnly);
  624. }
  625. // nested types
  626. private class Reflector
  627. {
  628. private readonly SingleChunkBuffer _instance;
  629. public Reflector(SingleChunkBuffer instance)
  630. {
  631. _instance = instance;
  632. }
  633. public IBsonChunk _chunk
  634. {
  635. get
  636. {
  637. var field = typeof(SingleChunkBuffer).GetField("_chunk", BindingFlags.NonPublic | BindingFlags.Instance);
  638. return (IBsonChunk)field.GetValue(_instance);
  639. }
  640. }
  641. public bool _disposed
  642. {
  643. get
  644. {
  645. var field = typeof(SingleChunkBuffer).GetField("_disposed", BindingFlags.NonPublic | BindingFlags.Instance);
  646. return (bool)field.GetValue(_instance);
  647. }
  648. }
  649. }
  650. }
  651. }