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

/test/EntityFramework/UnitTests/Core/Common/Internal/Materialization/ShaperTests.cs

#
C# | 202 lines | 170 code | 32 blank | 0 comment | 3 complexity | a2482ca7679ea794eec93dfda01eed25 MD5 | raw file
  1. namespace System.Data.Entity.Core.Common.Internal.Materialization
  2. {
  3. using System.Collections.Generic;
  4. using System.Data.Common;
  5. using System.Data.Entity.Core.Objects;
  6. using System.Data.Entity.Internal;
  7. using System.Linq;
  8. using System.Threading;
  9. using System.Threading.Tasks;
  10. using Moq;
  11. using Xunit;
  12. public class ShaperTests
  13. {
  14. [Fact]
  15. public void GetEnumerator_returns_SimpleEnumerator_for_simple_CoordinatorFactory_sync()
  16. {
  17. GetEnumerator_returns_SimpleEnumerator_for_simple_CoordinatorFactory(SetupReadSync, e => e.ToList());
  18. }
  19. [Fact]
  20. public void GetEnumerator_returns_SimpleEnumerator_for_simple_CoordinatorFactory_async()
  21. {
  22. GetEnumerator_returns_SimpleEnumerator_for_simple_CoordinatorFactory(SetupReadAsync, e => e.ToListAsync().Result);
  23. }
  24. private void GetEnumerator_returns_SimpleEnumerator_for_simple_CoordinatorFactory(Action<Mock<DbDataReader>, IEnumerator<object>> setupRead,
  25. Func<IDbEnumerator<object>, List<object>> toList)
  26. {
  27. var sourceEnumerable = new[] { new object[] { 1 }, new object[] { 2 } };
  28. var underlyingEnumerator = ((IEnumerable<object[]>)sourceEnumerable).GetEnumerator();
  29. var dbDataReaderMock = new Mock<DbDataReader>();
  30. setupRead(dbDataReaderMock, underlyingEnumerator);
  31. dbDataReaderMock.Setup(m => m.GetValue(It.IsAny<int>())).Returns((int ordinal) => underlyingEnumerator.Current[ordinal]);
  32. var coordinatorFactory = Objects.MockHelper.CreateCoordinatorFactory<object>(shaper => shaper.Reader.GetValue(0));
  33. var shaperMock = new Mock<Shaper<object>>(dbDataReaderMock.Object, /*context*/ null, /*workspace*/ null,
  34. MergeOption.AppendOnly, /*stateCount*/ 1, coordinatorFactory, /*checkPermissions*/ null,
  35. /*readerOwned*/ false) { CallBase = true };
  36. var actualEnumerator = shaperMock.Object.GetEnumerator();
  37. Assert.Equal(sourceEnumerable.SelectMany(e => e).ToList(), toList(actualEnumerator));
  38. }
  39. [Fact]
  40. public void GetEnumerator_returns_ObjectQueryNestedEnumerator_for_nested_coordinatorFactories_sync()
  41. {
  42. GetEnumerator_returns_ObjectQueryNestedEnumerator_for_nested_coordinatorFactories(SetupReadSync, e => e.ToList());
  43. }
  44. [Fact]
  45. public void GetEnumerator_returns_ObjectQueryNestedEnumerator_for_nested_coordinatorFactories_async()
  46. {
  47. GetEnumerator_returns_ObjectQueryNestedEnumerator_for_nested_coordinatorFactories(SetupReadAsync, e => e.ToListAsync().Result);
  48. }
  49. private void GetEnumerator_returns_ObjectQueryNestedEnumerator_for_nested_coordinatorFactories(Action<Mock<DbDataReader>, IEnumerator<object>> setupRead,
  50. Func<IDbEnumerator<object>, List<object>> toList)
  51. {
  52. var sourceEnumerable = new[]
  53. {
  54. new object[] { 1, "A", null },
  55. new object[] { 2, null, "X" },
  56. new object[] { 3, "B", "Z" }, // Should stop reading at "B", since the coordinators are at the same depth
  57. new object[] { 4, "C", null },
  58. new object[] { 4, "D", null } // 4 shouldn't be added as it's repeated
  59. };
  60. var underlyingEnumerator = ((IEnumerable<object[]>)sourceEnumerable).GetEnumerator();
  61. var dbDataReaderMock = new Mock<DbDataReader>();
  62. setupRead(dbDataReaderMock, underlyingEnumerator);
  63. dbDataReaderMock.Setup(m => m.GetValue(It.IsAny<int>())).Returns((int ordinal) => underlyingEnumerator.Current[ordinal]);
  64. var actualValuesFromNestedCoordinatorOne = new List<string>();
  65. var nestedCoordinatorFactoryOne = Objects.MockHelper.CreateCoordinatorFactory<string, string>(
  66. depth: 1,
  67. stateSlot: 1,
  68. ordinal: 1,
  69. nestedCoordinators: new CoordinatorFactory[0],
  70. producedValues: actualValuesFromNestedCoordinatorOne);
  71. var actualValuesFromNestedCoordinatorTwo = new List<string>();
  72. var nestedCoordinatorFactoryTwo = Objects.MockHelper.CreateCoordinatorFactory<string, string>(
  73. depth: 1,
  74. stateSlot: 2,
  75. ordinal: 2,
  76. nestedCoordinators: new CoordinatorFactory[0],
  77. producedValues: actualValuesFromNestedCoordinatorTwo);
  78. var actualValuesFromRootCoordinator = new List<object>();
  79. var rootCoordinatorFactory = Objects.MockHelper.CreateCoordinatorFactory<int, object>(
  80. depth: 0,
  81. stateSlot: 0,
  82. ordinal: 0,
  83. nestedCoordinators: new[] { nestedCoordinatorFactoryOne, nestedCoordinatorFactoryTwo },
  84. producedValues: actualValuesFromRootCoordinator);
  85. var shaperMock = new Mock<Shaper<object>>(dbDataReaderMock.Object, /*context*/ null, /*workspace*/ null,
  86. MergeOption.AppendOnly, /*stateCount*/ 3, rootCoordinatorFactory, /*checkPermissions*/ null,
  87. /*readerOwned*/ false) { CallBase = true };
  88. var actualEnumerator = shaperMock.Object.GetEnumerator();
  89. Assert.Equal(new object[] { 1, 2, 3, 4 }.ToList(), toList(actualEnumerator));
  90. Assert.Equal(new object[] { 1, 2, 3, 4 }.ToList(), actualValuesFromRootCoordinator);
  91. Assert.Equal(new[] { "A", "B", "C", "D" }.ToList(), actualValuesFromNestedCoordinatorOne);
  92. Assert.Equal(new[] { "X" }.ToList(), actualValuesFromNestedCoordinatorTwo);
  93. }
  94. [Fact]
  95. public void GetEnumerator_returns_RecordStateEnumerator_for_nested_coordinatorFactories_of_RecordState_sync()
  96. {
  97. GetEnumerator_returns_RecordStateEnumerator_for_nested_coordinatorFactories_of_RecordState(SetupReadSync,
  98. e =>
  99. {
  100. var actualValues = new List<object>();
  101. while (e.MoveNext())
  102. {
  103. actualValues.Add(e.Current.PendingColumnValues[0]);
  104. }
  105. return actualValues;
  106. });
  107. }
  108. [Fact]
  109. public void GetEnumerator_returns_RecordStateEnumerator_for_nested_coordinatorFactories_of_RecordState_async()
  110. {
  111. GetEnumerator_returns_RecordStateEnumerator_for_nested_coordinatorFactories_of_RecordState(SetupReadAsync,
  112. e =>
  113. {
  114. var actualValues = new List<object>();
  115. while (e.MoveNextAsync(CancellationToken.None).Result)
  116. {
  117. actualValues.Add(e.Current.PendingColumnValues[0]);
  118. }
  119. return actualValues;
  120. });
  121. }
  122. private void GetEnumerator_returns_RecordStateEnumerator_for_nested_coordinatorFactories_of_RecordState(Action<Mock<DbDataReader>, IEnumerator<object>> setupRead,
  123. Func<IDbEnumerator<RecordState>, List<object>> toList)
  124. {
  125. var sourceEnumerable = new[]
  126. {
  127. new object[] { 1, "A", null },
  128. new object[] { 2, null, "X" },
  129. new object[] { 3, "B", "Z" }, // Should stop reading at "B", since the coordinators are at the same depth
  130. new object[] { 4, "C", null },
  131. new object[] { 4, "D", null } // 4 shouldn't be added as it's repeated
  132. };
  133. var underlyingEnumerator = ((IEnumerable<object[]>)sourceEnumerable).GetEnumerator();
  134. var dbDataReaderMock = new Mock<DbDataReader>();
  135. setupRead(dbDataReaderMock, underlyingEnumerator);
  136. dbDataReaderMock.Setup(m => m.GetValue(It.IsAny<int>())).Returns((int ordinal) => underlyingEnumerator.Current[ordinal]);
  137. dbDataReaderMock.Setup(m => m.IsDBNull(It.IsAny<int>())).Returns((int ordinal) => underlyingEnumerator.Current[ordinal] == null);
  138. var nestedCoordinatorFactoryOne = Objects.MockHelper.CreateCoordinatorFactory<string, RecordState>(
  139. depth: 1,
  140. stateSlot: 2,
  141. ordinal: 1,
  142. nestedCoordinators: new CoordinatorFactory[0],
  143. producedValues: null);
  144. var nestedCoordinatorFactoryTwo = Objects.MockHelper.CreateCoordinatorFactory<string, RecordState>(
  145. depth: 1,
  146. stateSlot: 4,
  147. ordinal: 2,
  148. nestedCoordinators: new CoordinatorFactory[0],
  149. producedValues: null);
  150. var rootCoordinatorFactory = Objects.MockHelper.CreateCoordinatorFactory<int, RecordState>(
  151. depth: 0,
  152. stateSlot: 0,
  153. ordinal: 0,
  154. nestedCoordinators: new[] { nestedCoordinatorFactoryOne, nestedCoordinatorFactoryTwo },
  155. producedValues: null);
  156. var shaperMock = new Mock<Shaper<RecordState>>(dbDataReaderMock.Object, /*context*/ null, /*workspace*/ null,
  157. MergeOption.AppendOnly, /*stateCount*/ 6, rootCoordinatorFactory, /*checkPermissions*/ null,
  158. /*readerOwned*/ false) { CallBase = true };
  159. Assert.Equal(new object[] { 1, "A", 2, "X", 3, "B", 4, "C", "D" }.ToList(), toList(shaperMock.Object.RootEnumerator));
  160. }
  161. private void SetupReadSync(Mock<DbDataReader> dbDataReaderMock, IEnumerator<object> underlyingEnumerator)
  162. {
  163. dbDataReaderMock.Setup(m => m.Read()).Returns(underlyingEnumerator.MoveNext);
  164. }
  165. private void SetupReadAsync(Mock<DbDataReader> dbDataReaderMock, IEnumerator<object> underlyingEnumerator)
  166. {
  167. dbDataReaderMock.Setup(m => m.ReadAsync(It.IsAny<CancellationToken>())).Returns((CancellationToken ct) => Task.FromResult(underlyingEnumerator.MoveNext()));
  168. }
  169. }
  170. }