PageRenderTime 47ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

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

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