PageRenderTime 36ms CodeModel.GetById 8ms RepoModel.GetById 0ms app.codeStats 1ms

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

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