PageRenderTime 51ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

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

http://github.com/mongodb/mongo-csharp-driver
C# | 529 lines | 393 code | 120 blank | 16 comment | 0 complexity | d2b54471aab8592111113688feb55a60 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 ByteBufferSliceTests
  29. {
  30. [Fact]
  31. public void AccessBackingBytes_should_adjust_count()
  32. {
  33. var bytes = new byte[4];
  34. var buffer = new ByteArrayBuffer(bytes, isReadOnly: true);
  35. var subject = new ByteBufferSlice(buffer, 1, 2);
  36. var result = subject.AccessBackingBytes(0);
  37. result.Count.Should().Be(2); // not 3
  38. }
  39. [Fact]
  40. public void AccessBackingBytes_should_adjust_count_when_multiple_chunks_are_present()
  41. {
  42. var arrays = new[] { new byte[] { 1, 2 }, new byte[] { 3, 4 } };
  43. var chunks = arrays.Select(a => new ByteArrayChunk(a));
  44. var buffer = new MultiChunkBuffer(chunks, isReadOnly: true);
  45. var subject = new ByteBufferSlice(buffer, 1, 2);
  46. var result = subject.AccessBackingBytes(0);
  47. result.Array.Should().BeSameAs(arrays[0]);
  48. result.Offset.Should().Be(1);
  49. result.Count.Should().Be(1); // not 2 or 3
  50. }
  51. [Fact]
  52. public void AccessBackingBytes_should_adjust_position()
  53. {
  54. var subject = CreateSubjectWithFakeBuffer();
  55. var mockBuffer = Mock.Get(subject.Buffer);
  56. mockBuffer.Setup(b => b.AccessBackingBytes(1)).Returns(new ArraySegment<byte>(new byte[3], 1, 2));
  57. subject.AccessBackingBytes(0);
  58. mockBuffer.Verify(b => b.AccessBackingBytes(1), Times.Once);
  59. }
  60. [Theory]
  61. [ParameterAttributeData]
  62. public void AccessBackingBytes_should_throw_when_position_is_out_of_range(
  63. [Values(-1, 3)]
  64. int position)
  65. {
  66. var subject = CreateSubject();
  67. Action action = () => subject.AccessBackingBytes(position);
  68. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("position");
  69. }
  70. [Fact]
  71. public void AccessBackingBytes_should_throw_when_subject_is_disposed()
  72. {
  73. var subject = CreateSubject();
  74. subject.Dispose();
  75. Action action = () => subject.AccessBackingBytes(0);
  76. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("ByteBufferSlice");
  77. }
  78. [Fact]
  79. public void Capacity_get_should_return_expected_result()
  80. {
  81. var subject = CreateSubject();
  82. var result = subject.Capacity;
  83. result.Should().Be(2);
  84. }
  85. [Fact]
  86. public void Capacity_get_should_throw_when_subject_is_disposed()
  87. {
  88. var subject = CreateSubject();
  89. subject.Dispose();
  90. Action action = () => { var _ = subject.Capacity; };
  91. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("ByteBufferSlice");
  92. }
  93. [Fact]
  94. public void Clear_should_adjust_position()
  95. {
  96. var subject = CreateSubjectWithFakeBuffer();
  97. var mockBuffer = Mock.Get(subject.Buffer);
  98. subject.Clear(0, 2);
  99. mockBuffer.Verify(b => b.Clear(1, 2), Times.Once);
  100. }
  101. [Theory]
  102. [InlineData(0, 3)]
  103. [InlineData(1, 2)]
  104. [InlineData(2, 1)]
  105. public void Clear_should_throw_when_count_is_out_of_range(int position, int count)
  106. {
  107. var subject = CreateSubject();
  108. Action action = () => subject.Clear(position, count);
  109. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("count");
  110. }
  111. [Theory]
  112. [ParameterAttributeData]
  113. public void Clear_should_throw_when_position_is_out_of_range(
  114. [Values(-1, 3)]
  115. int position)
  116. {
  117. var subject = CreateSubject();
  118. Action action = () => subject.Clear(position, 2);
  119. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("position");
  120. }
  121. [Fact]
  122. public void Clear_should_throw_when_subject_is_disposed()
  123. {
  124. var subject = CreateSubject();
  125. subject.Dispose();
  126. Action action = () => subject.Clear(0, 0);
  127. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("ByteBufferSlice");
  128. }
  129. [Fact]
  130. public void constructor_should_initialize_subject()
  131. {
  132. var buffer = new ByteArrayBuffer(new byte[3], isReadOnly: true);
  133. var subject = new ByteBufferSlice(buffer, 1, 2);
  134. var reflector = new Reflector(subject);
  135. subject.Buffer.Should().BeSameAs(buffer);
  136. reflector._disposed.Should().BeFalse();
  137. reflector._offset.Should().Be(1);
  138. reflector._length.Should().Be(2);
  139. }
  140. [Fact]
  141. public void constructor_should_throw_when_buffer_is_null()
  142. {
  143. Action action = () => new ByteBufferSlice(null, 0, 0);
  144. action.ShouldThrow<ArgumentNullException>().And.ParamName.Should().Be("buffer");
  145. }
  146. [Fact]
  147. public void constructor_should_throw_when_buffer_is_not_readonly()
  148. {
  149. var buffer = new ByteArrayBuffer(new byte[1], isReadOnly: false);
  150. Action action = () => new ByteBufferSlice(buffer, 0, 0);
  151. action.ShouldThrow<ArgumentException>().And.ParamName.Should().Be("buffer");
  152. }
  153. [Theory]
  154. [InlineData(0, 0, 1)]
  155. [InlineData(1, 0, 2)]
  156. [InlineData(1, 1, 1)]
  157. [InlineData(2, 0, 3)]
  158. [InlineData(2, 1, 2)]
  159. [InlineData(2, 2, 1)]
  160. public void constructor_should_throw_when_length_is_out_of_range(int size, int offset, int length)
  161. {
  162. var buffer = new ByteArrayBuffer(new byte[size], isReadOnly: true);
  163. Action action = () => new ByteBufferSlice(buffer, offset, length);
  164. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("length");
  165. }
  166. [Theory]
  167. [ParameterAttributeData]
  168. public void constructor_should_throw_when_offset_is_out_of_range(
  169. [Values(-1, 2)]
  170. int offset)
  171. {
  172. var buffer = new ByteArrayBuffer(new byte[1], isReadOnly: true);
  173. Action action = () => new ByteBufferSlice(buffer, offset, 0);
  174. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("offset");
  175. }
  176. [Fact]
  177. public void Dispose_can_be_called_more_than_once()
  178. {
  179. var subject = CreateSubject();
  180. subject.Dispose();
  181. subject.Dispose();
  182. }
  183. [Fact]
  184. public void Dispose_should_dispose_buffer()
  185. {
  186. var subject = CreateSubjectWithFakeBuffer();
  187. var mockBuffer = Mock.Get(subject.Buffer);
  188. subject.Dispose();
  189. mockBuffer.Verify(b => b.Dispose(), Times.Once);
  190. }
  191. [Fact]
  192. public void Dispose_should_dispose_subject()
  193. {
  194. var subject = CreateSubject();
  195. subject.Dispose();
  196. var reflector = new Reflector(subject);
  197. reflector._disposed.Should().BeTrue();
  198. }
  199. [Fact]
  200. public void EnsureCapacity_should_throw()
  201. {
  202. var subject = CreateSubject();
  203. Action action = () => subject.EnsureCapacity(0);
  204. action.ShouldThrow<NotSupportedException>();
  205. }
  206. [Fact]
  207. public void GetByte_should_adjust_position()
  208. {
  209. var subject = CreateSubjectWithFakeBuffer();
  210. var mockBuffer = Mock.Get(subject.Buffer);
  211. subject.GetByte(0);
  212. mockBuffer.Verify(b => b.GetByte(1), Times.Once);
  213. }
  214. [Theory]
  215. [ParameterAttributeData]
  216. public void GetByte_should_throw_when_position_is_out_of_range(
  217. [Values(-1, 3)]
  218. int position)
  219. {
  220. var subject = CreateSubject();
  221. Action action = () => subject.GetByte(position);
  222. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("position");
  223. }
  224. [Fact]
  225. public void GetByte_should_throw_when_subject_is_disposed()
  226. {
  227. var subject = CreateSubject();
  228. subject.Dispose();
  229. Action action = () => subject.GetByte(0);
  230. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("ByteBufferSlice");
  231. }
  232. [Fact]
  233. public void GetBytes_should_adjust_position()
  234. {
  235. var subject = CreateSubjectWithFakeBuffer();
  236. var mockBuffer = Mock.Get(subject.Buffer);
  237. var destination = new byte[1];
  238. subject.GetBytes(1, destination, 0, 1);
  239. mockBuffer.Verify(b => b.GetBytes(2, destination, 0, 1), Times.Once);
  240. }
  241. [Theory]
  242. [InlineData(0, 3)]
  243. [InlineData(1, 2)]
  244. [InlineData(2, 1)]
  245. public void GetBytes_should_throw_when_count_is_out_of_range(int position, int count)
  246. {
  247. var subject = CreateSubject();
  248. var destination = new byte[1];
  249. Action action = () => subject.GetBytes(position, destination, 0, count);
  250. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("count");
  251. }
  252. [Theory]
  253. [ParameterAttributeData]
  254. public void GetBytes_should_throw_when_position_is_out_of_range(
  255. [Values(-1, 3)]
  256. int position)
  257. {
  258. var subject = CreateSubject();
  259. var destination = new byte[1];
  260. Action action = () => subject.GetBytes(position, destination, 0, 0);
  261. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("position");
  262. }
  263. [Fact]
  264. public void GetBytes_should_throw_when_subject_is_disposed()
  265. {
  266. var subject = CreateSubject();
  267. var destination = new byte[1];
  268. subject.Dispose();
  269. Action action = () => subject.GetBytes(0, destination, 0, 0);
  270. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("ByteBufferSlice");
  271. }
  272. [Fact]
  273. public void GetSlice_should_adjust_position()
  274. {
  275. var subject = CreateSubjectWithFakeBuffer();
  276. var mockBuffer = Mock.Get(subject.Buffer);
  277. subject.GetSlice(1, 1);
  278. mockBuffer.Verify(b => b.GetSlice(2, 1), Times.Once);
  279. }
  280. [Theory]
  281. [InlineData(0, 3)]
  282. [InlineData(1, 2)]
  283. [InlineData(2, 1)]
  284. public void GetSlice_should_throw_when_length_is_out_of_range(int position, int length)
  285. {
  286. var subject = CreateSubject();
  287. Action action = () => subject.GetSlice(position, length);
  288. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("length");
  289. }
  290. [Theory]
  291. [ParameterAttributeData]
  292. public void GetSlice_should_throw_when_position_is_out_of_range(
  293. [Values(-1, 3)]
  294. int position)
  295. {
  296. var subject = CreateSubject();
  297. Action action = () => subject.GetSlice(position, 2);
  298. action.ShouldThrow<ArgumentOutOfRangeException>().And.ParamName.Should().Be("position");
  299. }
  300. [Fact]
  301. public void GetSlice_should_throw_when_subject_is_disposed()
  302. {
  303. var subject = CreateSubject();
  304. subject.Dispose();
  305. Action action = () => subject.GetSlice(0, 0);
  306. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("ByteBufferSlice");
  307. }
  308. [Fact]
  309. public void IsReadOnly_get_should_return_expected_result()
  310. {
  311. var subject = CreateSubject();
  312. var result = subject.IsReadOnly;
  313. result.Should().BeTrue();
  314. }
  315. [Fact]
  316. public void IsReadOnly_get_should_throw_when_subject_is_disposed()
  317. {
  318. var subject = CreateSubject();
  319. subject.Dispose();
  320. Action action = () => { var _ = subject.IsReadOnly; };
  321. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("ByteBufferSlice");
  322. }
  323. [Fact]
  324. public void Length_get_should_return_expected_result()
  325. {
  326. var subject = CreateSubject();
  327. var result = subject.Length;
  328. result.Should().Be(2);
  329. }
  330. [Fact]
  331. public void Length_get_should_throw_when_subject_is_disposed()
  332. {
  333. var subject = CreateSubject();
  334. subject.Dispose();
  335. Action action = () => { var _ = subject.Length; };
  336. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("ByteBufferSlice");
  337. }
  338. [Fact]
  339. public void MakeReadOnly_should_throw_when_subject_is_disposed()
  340. {
  341. var subject = CreateSubject();
  342. subject.Dispose();
  343. Action action = () => subject.MakeReadOnly();
  344. action.ShouldThrow<ObjectDisposedException>().And.ObjectName.Should().Be("ByteBufferSlice");
  345. }
  346. [Fact]
  347. public void SetByte_should_throw()
  348. {
  349. var subject = CreateSubject();
  350. Action action = () => subject.SetByte(0, 0);
  351. action.ShouldThrow<NotSupportedException>();
  352. }
  353. [Fact]
  354. public void SetBytes_should_throw()
  355. {
  356. var subject = CreateSubject();
  357. var source = new byte[1];
  358. subject.Dispose();
  359. Action action = () => subject.SetBytes(0, source, 0, 0);
  360. action.ShouldThrow<NotSupportedException>();
  361. }
  362. // helper methods
  363. public ByteBufferSlice CreateSubject(int size = 3, int offset = 1, int length = 2)
  364. {
  365. var buffer = new ByteArrayBuffer(new byte[size], isReadOnly: true);
  366. return new ByteBufferSlice(buffer, offset, length);
  367. }
  368. public ByteBufferSlice CreateSubjectWithFakeBuffer(int size = 3, int offset = 1, int length = 2)
  369. {
  370. var mockBuffer = new Mock<IByteBuffer>();
  371. mockBuffer.SetupGet(s => s.Length).Returns(size);
  372. mockBuffer.SetupGet(s => s.IsReadOnly).Returns(true);
  373. return new ByteBufferSlice(mockBuffer.Object, offset, length);
  374. }
  375. // nested types
  376. private class Reflector
  377. {
  378. private readonly ByteBufferSlice _instance;
  379. public Reflector(ByteBufferSlice instance)
  380. {
  381. _instance = instance;
  382. }
  383. public bool _disposed
  384. {
  385. get
  386. {
  387. var field = typeof(ByteBufferSlice).GetField("_disposed", BindingFlags.NonPublic | BindingFlags.Instance);
  388. return (bool)field.GetValue(_instance);
  389. }
  390. }
  391. public int _length
  392. {
  393. get
  394. {
  395. var field = typeof(ByteBufferSlice).GetField("_length", BindingFlags.NonPublic | BindingFlags.Instance);
  396. return (int)field.GetValue(_instance);
  397. }
  398. }
  399. public int _offset
  400. {
  401. get
  402. {
  403. var field = typeof(ByteBufferSlice).GetField("_offset", BindingFlags.NonPublic | BindingFlags.Instance);
  404. return (int)field.GetValue(_instance);
  405. }
  406. }
  407. }
  408. }
  409. }