PageRenderTime 56ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/tests/MongoDB.Driver.Tests/FieldDefinitionTests.cs

http://github.com/mongodb/mongo-csharp-driver
C# | 321 lines | 237 code | 70 blank | 14 comment | 0 complexity | a40820ab815a6ca06ff0d91d761fc4e7 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.Linq.Expressions;
  19. using System.Text;
  20. using System.Threading.Tasks;
  21. using FluentAssertions;
  22. using MongoDB.Bson;
  23. using MongoDB.Bson.Serialization;
  24. using MongoDB.Bson.Serialization.Attributes;
  25. using MongoDB.Bson.Serialization.Serializers;
  26. using Xunit;
  27. namespace MongoDB.Driver.Tests
  28. {
  29. public class FieldDefinitionTests
  30. {
  31. [Fact]
  32. public void Should_resolve_from_a_non_IBsonDocumentSerializer()
  33. {
  34. var subject = new StringFieldDefinition<string, string>("test");
  35. var renderedField = subject.Render(new StringSerializer(), BsonSerializer.SerializerRegistry);
  36. renderedField.FieldName.Should().Be("test");
  37. renderedField.UnderlyingSerializer.Should().BeNull();
  38. renderedField.FieldSerializer.Should().BeNull();
  39. renderedField.ValueSerializer.Should().BeOfType<StringSerializer>();
  40. }
  41. [Fact]
  42. public void Should_resolve_from_a_BsonDocumentSerializer()
  43. {
  44. var subject = new StringFieldDefinition<BsonDocument, BsonValue>("test");
  45. var renderedField = subject.Render(BsonDocumentSerializer.Instance, BsonSerializer.SerializerRegistry);
  46. renderedField.FieldName.Should().Be("test");
  47. renderedField.UnderlyingSerializer.Should().BeNull();
  48. renderedField.FieldSerializer.Should().BeNull();
  49. renderedField.ValueSerializer.Should().BeOfType<BsonValueSerializer>();
  50. }
  51. [Fact]
  52. public void Should_resolve_from_a_BsonDocumentSerializer_with_dots()
  53. {
  54. var subject = new StringFieldDefinition<BsonDocument, BsonValue>("test.one.two.three");
  55. var renderedField = subject.Render(BsonDocumentSerializer.Instance, BsonSerializer.SerializerRegistry);
  56. renderedField.FieldName.Should().Be("test.one.two.three");
  57. renderedField.UnderlyingSerializer.Should().BeNull();
  58. renderedField.FieldSerializer.Should().BeNull();
  59. renderedField.ValueSerializer.Should().BeOfType<BsonValueSerializer>();
  60. }
  61. [Fact]
  62. public void Should_resolve_top_level_field()
  63. {
  64. var subject = new StringFieldDefinition<Person, Name>("Name");
  65. var renderedField = subject.Render(BsonSerializer.SerializerRegistry.GetSerializer<Person>(), BsonSerializer.SerializerRegistry);
  66. renderedField.FieldName.Should().Be("name");
  67. renderedField.UnderlyingSerializer.Should().BeOfType<BsonClassMapSerializer<Name>>();
  68. renderedField.FieldSerializer.Should().BeSameAs(renderedField.UnderlyingSerializer);
  69. renderedField.ValueSerializer.Should().BeSameAs(renderedField.FieldSerializer);
  70. }
  71. [Fact]
  72. public void Should_resolve_a_nested_field()
  73. {
  74. var subject = new StringFieldDefinition<Person, string>("Name.First");
  75. var renderedField = subject.Render(BsonSerializer.SerializerRegistry.GetSerializer<Person>(), BsonSerializer.SerializerRegistry);
  76. renderedField.FieldName.Should().Be("name.fn");
  77. renderedField.UnderlyingSerializer.Should().BeOfType<StringSerializer>();
  78. renderedField.FieldSerializer.Should().BeSameAs(renderedField.UnderlyingSerializer);
  79. renderedField.ValueSerializer.Should().BeSameAs(renderedField.FieldSerializer);
  80. }
  81. [Fact]
  82. public void Should_resolve_a_nested_field_that_does_not_exist()
  83. {
  84. var subject = new StringFieldDefinition<Person, string>("Name.NoExisty");
  85. var renderedField = subject.Render(BsonSerializer.SerializerRegistry.GetSerializer<Person>(), BsonSerializer.SerializerRegistry);
  86. renderedField.FieldName.Should().Be("name.NoExisty");
  87. renderedField.UnderlyingSerializer.Should().BeNull();
  88. renderedField.FieldSerializer.Should().BeNull();
  89. renderedField.ValueSerializer.Should().BeOfType<StringSerializer>();
  90. }
  91. [Fact]
  92. public void Should_resolve_array_name()
  93. {
  94. var subject = new StringFieldDefinition<Person, string>("Pets.Type");
  95. var renderedField = subject.Render(BsonSerializer.SerializerRegistry.GetSerializer<Person>(), BsonSerializer.SerializerRegistry);
  96. renderedField.FieldName.Should().Be("pets.type");
  97. renderedField.UnderlyingSerializer.Should().BeOfType<StringSerializer>();
  98. renderedField.FieldSerializer.Should().BeSameAs(renderedField.UnderlyingSerializer);
  99. renderedField.ValueSerializer.Should().BeSameAs(renderedField.FieldSerializer);
  100. }
  101. [Fact]
  102. public void Should_resolve_array_name_with_multiple_dots()
  103. {
  104. var subject = new StringFieldDefinition<Person, string>("Pets.Name.First");
  105. var renderedField = subject.Render(BsonSerializer.SerializerRegistry.GetSerializer<Person>(), BsonSerializer.SerializerRegistry);
  106. renderedField.FieldName.Should().Be("pets.name.fn");
  107. renderedField.UnderlyingSerializer.Should().BeOfType<StringSerializer>();
  108. renderedField.FieldSerializer.Should().BeSameAs(renderedField.UnderlyingSerializer);
  109. renderedField.ValueSerializer.Should().BeSameAs(renderedField.FieldSerializer);
  110. }
  111. [Fact]
  112. public void Should_resolve_array_name_with_single_digit_indexer()
  113. {
  114. var subject = new StringFieldDefinition<Person, string>("Pets.3.Type");
  115. var renderedField = subject.Render(BsonSerializer.SerializerRegistry.GetSerializer<Person>(), BsonSerializer.SerializerRegistry);
  116. renderedField.FieldName.Should().Be("pets.3.type");
  117. renderedField.UnderlyingSerializer.Should().BeOfType<StringSerializer>();
  118. renderedField.FieldSerializer.Should().BeSameAs(renderedField.UnderlyingSerializer);
  119. renderedField.ValueSerializer.Should().BeSameAs(renderedField.FieldSerializer);
  120. }
  121. [Fact]
  122. public void Should_resolve_array_name_with_a_multi_digit_indexer()
  123. {
  124. var subject = new StringFieldDefinition<Person, string>("Pets.42.Type");
  125. var renderedField = subject.Render(BsonSerializer.SerializerRegistry.GetSerializer<Person>(), BsonSerializer.SerializerRegistry);
  126. renderedField.FieldName.Should().Be("pets.42.type");
  127. renderedField.UnderlyingSerializer.Should().BeOfType<StringSerializer>();
  128. renderedField.FieldSerializer.Should().BeSameAs(renderedField.UnderlyingSerializer);
  129. renderedField.ValueSerializer.Should().BeSameAs(renderedField.FieldSerializer);
  130. }
  131. [Fact]
  132. public void Should_resolve_array_name_with_positional_operator()
  133. {
  134. var subject = new StringFieldDefinition<Person, string>("Pets.$.Type");
  135. var renderedField = subject.Render(BsonSerializer.SerializerRegistry.GetSerializer<Person>(), BsonSerializer.SerializerRegistry);
  136. renderedField.FieldName.Should().Be("pets.$.type");
  137. renderedField.UnderlyingSerializer.Should().BeOfType<StringSerializer>();
  138. renderedField.FieldSerializer.Should().BeSameAs(renderedField.UnderlyingSerializer);
  139. renderedField.ValueSerializer.Should().BeSameAs(renderedField.FieldSerializer);
  140. }
  141. [Fact]
  142. public void Should_resolve_array_name_with_positional_operator_with_multiple_dots()
  143. {
  144. var subject = new StringFieldDefinition<Person, string>("Pets.$.Name.Last");
  145. var renderedField = subject.Render(BsonSerializer.SerializerRegistry.GetSerializer<Person>(), BsonSerializer.SerializerRegistry);
  146. renderedField.FieldName.Should().Be("pets.$.name.ln");
  147. renderedField.UnderlyingSerializer.Should().BeOfType<StringSerializer>();
  148. renderedField.FieldSerializer.Should().BeSameAs(renderedField.UnderlyingSerializer);
  149. renderedField.ValueSerializer.Should().BeSameAs(renderedField.FieldSerializer);
  150. }
  151. [Fact]
  152. public void Should_resolve_an_enum_with_field_type()
  153. {
  154. var subject = new ExpressionFieldDefinition<Person, Gender>(x => x.Gender);
  155. var renderedField = subject.Render(BsonSerializer.SerializerRegistry.GetSerializer<Person>(), BsonSerializer.SerializerRegistry);
  156. renderedField.FieldName.Should().Be("g");
  157. renderedField.UnderlyingSerializer.Should().BeOfType<EnumSerializer<Gender>>();
  158. renderedField.FieldSerializer.Should().BeSameAs(renderedField.UnderlyingSerializer);
  159. renderedField.ValueSerializer.Should().BeSameAs(renderedField.FieldSerializer);
  160. }
  161. [Fact]
  162. public void Should_resolve_an_enum_without_field_type()
  163. {
  164. Expression<Func<Person, object>> exp = x => x.Gender;
  165. var subject = new ExpressionFieldDefinition<Person>(exp);
  166. var renderedField = subject.Render(BsonSerializer.SerializerRegistry.GetSerializer<Person>(), BsonSerializer.SerializerRegistry);
  167. renderedField.FieldName.Should().Be("g");
  168. renderedField.FieldSerializer.Should().BeOfType<EnumSerializer<Gender>>();
  169. }
  170. [Fact]
  171. public void Should_assign_a_non_typed_field_definition_from_a_typed_field_definition()
  172. {
  173. FieldDefinition<Person, Gender> subject = new ExpressionFieldDefinition<Person, Gender>(x => x.Gender);
  174. FieldDefinition<Person> subject2 = subject;
  175. var renderedField = subject2.Render(BsonSerializer.SerializerRegistry.GetSerializer<Person>(), BsonSerializer.SerializerRegistry);
  176. renderedField.FieldName.Should().Be("g");
  177. renderedField.FieldSerializer.Should().BeOfType<EnumSerializer<Gender>>();
  178. }
  179. [Fact]
  180. public void Should_resolve_an_array_field_with_field_lambda()
  181. {
  182. FieldDefinition<Person, IEnumerable<Gender>> subject = new ExpressionFieldDefinition<Person, IEnumerable<Gender>>(x => x.Genders);
  183. var renderedField = subject.Render(BsonSerializer.SerializerRegistry.GetSerializer<Person>(), BsonSerializer.SerializerRegistry);
  184. renderedField.FieldName.Should().Be("gs");
  185. renderedField.UnderlyingSerializer.Should().BeOfType<ImpliedImplementationInterfaceSerializer<IEnumerable<Gender>, List<Gender>>>();
  186. renderedField.FieldSerializer.Should().BeSameAs(renderedField.UnderlyingSerializer);
  187. renderedField.ValueSerializer.Should().BeSameAs(renderedField.FieldSerializer);
  188. }
  189. [Fact]
  190. public void Should_resolve_an_array_field_with_field_name()
  191. {
  192. FieldDefinition<Person, IEnumerable<Gender>> subject = new StringFieldDefinition<Person, IEnumerable<Gender>>("Genders");
  193. var renderedField = subject.Render(BsonSerializer.SerializerRegistry.GetSerializer<Person>(), BsonSerializer.SerializerRegistry);
  194. renderedField.FieldName.Should().Be("gs");
  195. renderedField.UnderlyingSerializer.Should().BeOfType<ImpliedImplementationInterfaceSerializer<IEnumerable<Gender>, List<Gender>>>();
  196. renderedField.FieldSerializer.Should().BeSameAs(renderedField.UnderlyingSerializer);
  197. renderedField.ValueSerializer.Should().BeSameAs(renderedField.FieldSerializer);
  198. }
  199. [Fact]
  200. public void Should_resolve_an_array_field_with_field_name_and_scalar_value_and_scalar_value_is_allowed()
  201. {
  202. FieldDefinition<Person, Gender> subject = new StringFieldDefinition<Person, Gender>("Genders");
  203. var renderedField = subject.Render(BsonSerializer.SerializerRegistry.GetSerializer<Person>(), BsonSerializer.SerializerRegistry, allowScalarValueForArrayField: true);
  204. renderedField.FieldName.Should().Be("gs");
  205. renderedField.UnderlyingSerializer.Should().BeOfType<ImpliedImplementationInterfaceSerializer<IEnumerable<Gender>, List<Gender>>>();
  206. renderedField.FieldSerializer.Should().BeNull();
  207. renderedField.ValueSerializer.Should().BeOfType<EnumSerializer<Gender>>();
  208. }
  209. [Fact]
  210. public void Should_resolve_an_array_field_with_field_name_and_scalar_value_and_scalar_value_is_not_allowed()
  211. {
  212. FieldDefinition<Person, Gender> subject = new StringFieldDefinition<Person, Gender>("Genders");
  213. var renderedField = subject.Render(BsonSerializer.SerializerRegistry.GetSerializer<Person>(), BsonSerializer.SerializerRegistry, allowScalarValueForArrayField: false);
  214. renderedField.FieldName.Should().Be("gs");
  215. renderedField.UnderlyingSerializer.Should().BeOfType<ImpliedImplementationInterfaceSerializer<IEnumerable<Gender>, List<Gender>>>();
  216. renderedField.FieldSerializer.Should().BeNull();
  217. renderedField.ValueSerializer.ValueType.Should().Be(typeof(Gender));
  218. renderedField.ValueSerializer.GetType().Name.Should().Be("ConvertIfPossibleSerializer`2");
  219. }
  220. private class Person
  221. {
  222. [BsonElement("name")]
  223. public Name Name { get; set; }
  224. [BsonElement("pets")]
  225. public IEnumerable<Pet> Pets { get; set; }
  226. [BsonElement("g")]
  227. public Gender Gender { get; set; }
  228. [BsonElement("gs")]
  229. public IEnumerable<Gender> Genders { get; set; }
  230. }
  231. private class Name
  232. {
  233. [BsonElement("fn")]
  234. public string First { get; set; }
  235. [BsonElement("ln")]
  236. public string Last { get; set; }
  237. }
  238. private class Pet
  239. {
  240. [BsonElement("type")]
  241. public string Type { get; set; }
  242. [BsonElement("name")]
  243. public Name Name { get; set; }
  244. }
  245. private enum Gender
  246. {
  247. Male,
  248. Female
  249. }
  250. }
  251. }