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

/src/MongoDB.Driver.Tests/Linq/Translators/LegacyPredicateTranslatorTests.cs

http://github.com/mongodb/mongo-csharp-driver
C# | 1275 lines | 1058 code | 201 blank | 16 comment | 152 complexity | 500120f69a5d70e58516ba51246e0de1 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.Linq.Expressions;
  19. using System.Text.RegularExpressions;
  20. using FluentAssertions;
  21. using MongoDB.Bson;
  22. using MongoDB.Bson.Serialization;
  23. using MongoDB.Bson.Serialization.Attributes;
  24. using MongoDB.Driver.Linq.Translators;
  25. using NUnit.Framework;
  26. namespace MongoDB.Driver.Tests.Linq.Translators
  27. {
  28. [TestFixture]
  29. public class LegacyPredicateTranslatorTests
  30. {
  31. private IMongoDatabase _database;
  32. private IMongoCollection<C> _collection;
  33. private ObjectId _id1 = ObjectId.GenerateNewId();
  34. private ObjectId _id2 = ObjectId.GenerateNewId();
  35. private ObjectId _id3 = ObjectId.GenerateNewId();
  36. private ObjectId _id4 = ObjectId.GenerateNewId();
  37. private ObjectId _id5 = ObjectId.GenerateNewId();
  38. [TestFixtureSetUp]
  39. public void Setup()
  40. {
  41. _database = DriverTestConfiguration.Client.GetDatabase(DriverTestConfiguration.DatabaseNamespace.DatabaseName);
  42. _collection = _database.GetCollection<C>(DriverTestConfiguration.CollectionNamespace.CollectionName);
  43. // documents inserted deliberately out of order to test sorting
  44. _database.DropCollectionAsync(_collection.CollectionNamespace.CollectionName).GetAwaiter().GetResult();
  45. _collection.InsertManyAsync(new[]
  46. {
  47. new C { Id = _id2, X = 2, LX = 2, Y = 11, Date = new DateTime(2000, 1, 1, 1, 1, 1, 1, DateTimeKind.Utc), D = new D { Z = 22 }, NullableDouble = 2, A = new[] { 2, 3, 4 }, DA = new List<D> { new D { Y = 11, Z = 111 }, new D { Z = 222 } }, L = new List<int> { 2, 3, 4 } },
  48. new C { Id = _id1, X = 1, LX = 1, Y = 11, Date = new DateTime(2000, 2, 2, 2, 2, 2, 2, DateTimeKind.Utc), D = new D { Z = 11 }, NullableDouble = 2, S = "abc", SA = new string[] { "Tom", "Dick", "Harry" } },
  49. new C { Id = _id3, X = 3, LX = 3, Y = 33, Date = new DateTime(2001, 1, 1, 1, 1, 1, 1, DateTimeKind.Utc), D = new D { Z = 33 }, NullableDouble = 5, B = true, BA = new bool[] { true }, E = E.A, ENullable = E.A, EA = new E[] { E.A, E.B } },
  50. new C { Id = _id5, X = 5, LX = 5, Y = 44, Date = new DateTime(2001, 2, 2, 2, 2, 2, 2, DateTimeKind.Utc), D = new D { Z = 55 }, DBRef = new MongoDBRef("db", "c", 1), F = new F { G = new G { H = 10 } } },
  51. new C { Id = _id4, X = 4, LX = 4, Y = 44, Date = new DateTime(2001, 3, 3, 3, 3, 3, 3, DateTimeKind.Utc), D = new D { Z = 44 }, S = " xyz ", DA = new List<D> { new D { Y = 33, Z = 333 }, new D { Y = 44, Z = 444 } } }
  52. }).GetAwaiter().GetResult();
  53. }
  54. [Test]
  55. public void TestWhereAAny()
  56. {
  57. Assert<C>(c => c.A.Any(), 1, "{ \"a\" : { \"$ne\" : null, \"$not\" : { \"$size\" : 0 } } }");
  58. }
  59. [Test]
  60. public void TestWhereLocalIListContainsX()
  61. {
  62. IList<int> local = new[] { 1, 2, 3 };
  63. Assert<C>(c => local.Contains(c.X), 3, "{ \"x\" : { \"$in\" : [1, 2, 3] } }");
  64. }
  65. [Test]
  66. public void TestWhereLocalListContainsX()
  67. {
  68. var local = new List<int> { 1, 2, 3 };
  69. Assert<C>(c => local.Contains(c.X), 3, "{ \"x\" : { \"$in\" : [1, 2, 3] } }");
  70. }
  71. [Test]
  72. public void TestWhereLocalArrayContainsX()
  73. {
  74. var local = new[] { 1, 2, 3 };
  75. Assert<C>(c => local.Contains(c.X), 3, "{ \"x\" : { \"$in\" : [1, 2, 3] } }");
  76. }
  77. [Test]
  78. public void TestWhereAContains2()
  79. {
  80. Assert<C>(c => c.A.Contains(2), 1, "{ \"a\" : 2 }");
  81. }
  82. [Test]
  83. public void TestWhereAContains2Not()
  84. {
  85. Assert<C>(c => !c.A.Contains(2), 4, "{ \"a\" : { \"$ne\" : 2 } }");
  86. }
  87. [Test]
  88. public void TestWhereALengthEquals3()
  89. {
  90. Assert<C>(c => c.A.Length == 3, 1, "{ \"a\" : { \"$size\" : 3 } }");
  91. }
  92. [Test]
  93. public void TestWhereALengthEquals3Not()
  94. {
  95. Assert<C>(c => !(c.A.Length == 3), 4, "{ \"a\" : { \"$not\" : { \"$size\" : 3 } } }");
  96. }
  97. [Test]
  98. public void TestWhereALengthEquals3Reversed()
  99. {
  100. Assert<C>(c => 3 == c.A.Length, 1, "{ \"a\" : { \"$size\" : 3 } }");
  101. }
  102. [Test]
  103. public void TestWhereALengthNotEquals3()
  104. {
  105. Assert<C>(c => c.A.Length != 3, 4, "{ \"a\" : { \"$not\" : { \"$size\" : 3 } } }");
  106. }
  107. [Test]
  108. public void TestWhereALengthNotEquals3Not()
  109. {
  110. Assert<C>(c => !(c.A.Length != 3), 1, "{ \"a\" : { \"$size\" : 3 } }");
  111. }
  112. [Test]
  113. public void TestWhereASub1Equals3()
  114. {
  115. Assert<C>(c => c.A[1] == 3, 1, "{ \"a.1\" : 3 }");
  116. }
  117. [Test]
  118. public void TestWhereASub1Equals3Not()
  119. {
  120. Assert<C>(c => !(c.A[1] == 3), 4, "{ \"a.1\" : { \"$ne\" : 3 } }");
  121. }
  122. [Test]
  123. public void TestWhereASub1ModTwoEquals1()
  124. {
  125. Assert<C>(c => c.A[1] % 2 == 1, 1, "{ \"a.1\" : { \"$mod\" : [NumberLong(2), NumberLong(1)] } }");
  126. }
  127. [Test]
  128. public void TestWhereASub1ModTwoEquals1Not()
  129. {
  130. Assert<C>(c => !(c.A[1] % 2 == 1), 4, "{ \"a.1\" : { \"$not\" : { \"$mod\" : [NumberLong(2), NumberLong(1)] } } }");
  131. }
  132. [Test]
  133. public void TestWhereASub1ModTwoNotEquals1()
  134. {
  135. Assert<C>(c => c.A[1] % 2 != 1, 4, "{ \"a.1\" : { \"$not\" : { \"$mod\" : [NumberLong(2), NumberLong(1)] } } }");
  136. }
  137. [Test]
  138. public void TestWhereASub1ModTwoNotEquals1Not()
  139. {
  140. Assert<C>(c => !(c.A[1] % 2 != 1), 1, "{ \"a.1\" : { \"$mod\" : [NumberLong(2), NumberLong(1)] } }");
  141. }
  142. [Test]
  143. public void TestWhereASub1NotEquals3()
  144. {
  145. Assert<C>(c => c.A[1] != 3, 4, "{ \"a.1\" : { \"$ne\" : 3 } }");
  146. }
  147. [Test]
  148. public void TestWhereASub1NotEquals3Not()
  149. {
  150. Assert<C>(c => !(c.A[1] != 3), 1, "{ \"a.1\" : 3 }");
  151. }
  152. [Test]
  153. public void TestWhereB()
  154. {
  155. Assert<C>(c => c.B, 1, "{ \"b\" : true }");
  156. }
  157. [Test]
  158. public void TestWhereBASub0()
  159. {
  160. Assert<C>(c => c.BA[0], 1, "{ \"ba.0\" : true }");
  161. }
  162. [Test]
  163. public void TestWhereBASub0EqualsFalse()
  164. {
  165. Assert<C>(c => c.BA[0] == false, 0, "{ \"ba.0\" : false }");
  166. }
  167. [Test]
  168. public void TestWhereBASub0EqualsFalseNot()
  169. {
  170. Assert<C>(c => !(c.BA[0] == false), 5, "{ \"ba.0\" : { \"$ne\" : false } }");
  171. }
  172. [Test]
  173. public void TestWhereBASub0EqualsTrue()
  174. {
  175. Assert<C>(c => c.BA[0] == true, 1, "{ \"ba.0\" : true }");
  176. }
  177. [Test]
  178. public void TestWhereBASub0EqualsTrueNot()
  179. {
  180. Assert<C>(c => !(c.BA[0] == true), 4, "{ \"ba.0\" : { \"$ne\" : true } }");
  181. }
  182. [Test]
  183. public void TestWhereBASub0Not()
  184. {
  185. Assert<C>(c => !c.BA[0], 4, "{ \"ba.0\" : { \"$ne\" : true } }");
  186. }
  187. [Test]
  188. public void TestWhereBEqualsFalse()
  189. {
  190. Assert<C>(c => c.B == false, 4, "{ \"b\" : false }");
  191. }
  192. [Test]
  193. public void TestWhereBEqualsFalseNot()
  194. {
  195. Assert<C>(c => !(c.B == false), 1, "{ \"b\" : { \"$ne\" : false } }");
  196. }
  197. [Test]
  198. public void TestWhereBEqualsTrue()
  199. {
  200. Assert<C>(c => c.B == true, 1, "{ \"b\" : true }");
  201. }
  202. [Test]
  203. public void TestWhereBEqualsTrueNot()
  204. {
  205. Assert<C>(c => !(c.B == true), 4, "{ \"b\" : { \"$ne\" : true } }");
  206. }
  207. [Test]
  208. public void TestWhereBNot()
  209. {
  210. Assert<C>(c => !c.B, 4, "{ \"b\" : { \"$ne\" : true } }");
  211. }
  212. [Test]
  213. public void TestWhereDEquals11()
  214. {
  215. Assert<C>(c => c.D == new D { Z = 11 }, 1, "{ \"d\" : { \"z\" : 11 } }");
  216. }
  217. [Test]
  218. public void TestWhereDEquals11Not()
  219. {
  220. Assert<C>(c => !(c.D == new D { Z = 11 }), 4, "{ \"d\" : { \"$ne\" : { \"z\" : 11 } } }");
  221. }
  222. [Test]
  223. public void TestWhereDNotEquals11()
  224. {
  225. Assert<C>(c => c.D != new D { Z = 11 }, 4, "{ \"d\" : { \"$ne\" : { \"z\" : 11 } } }");
  226. }
  227. [Test]
  228. public void TestWhereDNotEquals11Not()
  229. {
  230. Assert<C>(c => !(c.D != new D { Z = 11 }), 1, "{ \"d\" : { \"z\" : 11 } }");
  231. }
  232. [Test]
  233. public void TestWhereDAAnyWithPredicate()
  234. {
  235. Assert<C>(c => c.DA.Any(d => d.Z == 333), 1, "{ \"da.z\" : 333 }");
  236. Assert<C>(c => c.DA.Any(d => d.Z >= 222 && d.Z <= 444), 2, "{ \"da\" : { \"$elemMatch\" : { \"z\" : { \"$gte\" : 222, \"$lte\" : 444 } } } }");
  237. }
  238. [Test]
  239. public void TestWhereEAContainsB()
  240. {
  241. Assert<C>(c => c.EA.Contains(E.B), 1, "{ \"ea\" : 2 }");
  242. }
  243. [Test]
  244. public void TestWhereEAContainsBNot()
  245. {
  246. Assert<C>(c => !c.EA.Contains(E.B), 4, "{ \"ea\" : { \"$ne\" : 2 } }");
  247. }
  248. [Test]
  249. public void TestWhereEASub0EqualsA()
  250. {
  251. Assert<C>(c => c.EA[0] == E.A, 1, "{ \"ea.0\" : 1 }");
  252. }
  253. [Test]
  254. public void TestWhereEASub0EqualsANot()
  255. {
  256. Assert<C>(c => !(c.EA[0] == E.A), 4, "{ \"ea.0\" : { \"$ne\" : 1 } }");
  257. }
  258. [Test]
  259. public void TestWhereEASub0NotEqualsA()
  260. {
  261. Assert<C>(c => c.EA[0] != E.A, 4, "{ \"ea.0\" : { \"$ne\" : 1 } }");
  262. }
  263. [Test]
  264. public void TestWhereEASub0NotEqualsANot()
  265. {
  266. Assert<C>(c => !(c.EA[0] != E.A), 1, "{ \"ea.0\" : 1 }");
  267. }
  268. [Test]
  269. public void TestWhereEEqualsA()
  270. {
  271. Assert<C>(c => c.E == E.A, 1, "{ \"e\" : \"A\" }");
  272. }
  273. [Test]
  274. public void TestWhereEEqualsANot()
  275. {
  276. Assert<C>(c => !(c.E == E.A), 4, "{ \"e\" : { \"$ne\" : \"A\" } }");
  277. }
  278. [Test]
  279. public void TestWhereEEqualsAReversed()
  280. {
  281. Assert<C>(c => E.A == c.E, 1, "{ \"e\" : \"A\" }");
  282. }
  283. [Test]
  284. public void TestWhereENotEqualsA()
  285. {
  286. Assert<C>(c => c.E != E.A, 4, "{ \"e\" : { \"$ne\" : \"A\" } }");
  287. }
  288. [Test]
  289. public void TestWhereENotEqualsANot()
  290. {
  291. Assert<C>(c => !(c.E != E.A), 1, "{ \"e\" : \"A\" }");
  292. }
  293. [Test]
  294. public void TestWhereENullableEqualsA()
  295. {
  296. Assert<C>(c => c.ENullable == E.A, 1, "{ \"en\" : \"A\" }");
  297. }
  298. [Test]
  299. public void TestWhereENullableEqualsNull()
  300. {
  301. Assert<C>(c => c.ENullable == null, 4, "{ \"en\" : null }");
  302. }
  303. [Test]
  304. public void TestWhereENullabeEqualsAReversed()
  305. {
  306. Assert<C>(c => E.A == c.ENullable, 1, "{ \"en\" : \"A\" }");
  307. }
  308. [Test]
  309. public void TestWhereENullabeEqualsNullReversed()
  310. {
  311. Assert<C>(c => null == c.ENullable, 4, "{ \"en\" : null }");
  312. }
  313. [Test]
  314. public void TestWhereLContains2()
  315. {
  316. Assert<C>(c => c.L.Contains(2), 1, "{ \"l\" : 2 }");
  317. }
  318. [Test]
  319. public void TestWhereLContains2Not()
  320. {
  321. Assert<C>(c => !c.L.Contains(2), 4, "{ \"l\" : { \"$ne\" : 2 } }");
  322. }
  323. [Test]
  324. public void TestWhereLCountMethodEquals3()
  325. {
  326. Assert<C>(c => c.L.Count() == 3, 1, "{ \"l\" : { \"$size\" : 3 } }");
  327. }
  328. [Test]
  329. public void TestWhereLCountMethodEquals3Not()
  330. {
  331. Assert<C>(c => !(c.L.Count() == 3), 4, "{ \"l\" : { \"$not\" : { \"$size\" : 3 } } }");
  332. }
  333. [Test]
  334. public void TestWhereLCountMethodEquals3Reversed()
  335. {
  336. Assert<C>(c => 3 == c.L.Count(), 1, "{ \"l\" : { \"$size\" : 3 } }");
  337. }
  338. [Test]
  339. public void TestWhereLCountPropertyEquals3()
  340. {
  341. Assert<C>(c => c.L.Count == 3, 1, "{ \"l\" : { \"$size\" : 3 } }");
  342. }
  343. [Test]
  344. public void TestWhereLCountPropertyEquals3Not()
  345. {
  346. Assert<C>(c => !(c.L.Count == 3), 4, "{ \"l\" : { \"$not\" : { \"$size\" : 3 } } }");
  347. }
  348. [Test]
  349. public void TestWhereLCountPropertyEquals3Reversed()
  350. {
  351. Assert<C>(c => 3 == c.L.Count, 1, "{ \"l\" : { \"$size\" : 3 } }");
  352. }
  353. [Test]
  354. public void TestWhereLCountPropertyNotEquals3()
  355. {
  356. Assert<C>(c => c.L.Count != 3, 4, "{ \"l\" : { \"$not\" : { \"$size\" : 3 } } }");
  357. }
  358. [Test]
  359. public void TestWhereLCountPropertyNotEquals3Not()
  360. {
  361. Assert<C>(c => !(c.L.Count != 3), 1, "{ \"l\" : { \"$size\" : 3 } }");
  362. }
  363. [Test]
  364. public void TestWhereLSub1Equals3()
  365. {
  366. Assert<C>(c => c.L[1] == 3, 1, "{ \"l.1\" : 3 }");
  367. }
  368. [Test]
  369. public void TestWhereLSub1Equals3Not()
  370. {
  371. Assert<C>(c => !(c.L[1] == 3), 4, "{ \"l.1\" : { \"$ne\" : 3 } }");
  372. }
  373. [Test]
  374. public void TestWhereLSub1ModTwoEquals1()
  375. {
  376. Assert<C>(c => c.L[1] % 2 == 1, 1, "{ \"l.1\" : { \"$mod\" : [NumberLong(2), NumberLong(1)] } }");
  377. }
  378. [Test]
  379. public void TestWhereLSub1ModTwoEquals1Not()
  380. {
  381. Assert<C>(c => !(c.L[1] % 2 == 1), 4, "{ \"l.1\" : { \"$not\" : { \"$mod\" : [NumberLong(2), NumberLong(1)] } } }");
  382. }
  383. [Test]
  384. public void TestWhereLSub1ModTwoNotEquals1()
  385. {
  386. Assert<C>(c => c.L[1] % 2 != 1, 4, "{ \"l.1\" : { \"$not\" : { \"$mod\" : [NumberLong(2), NumberLong(1)] } } }");
  387. }
  388. [Test]
  389. public void TestWhereLSub1ModTwoNotEquals1Not()
  390. {
  391. Assert<C>(c => !(c.L[1] % 2 != 1), 1, "{ \"l.1\" : { \"$mod\" : [NumberLong(2), NumberLong(1)] } }");
  392. }
  393. [Test]
  394. public void TestWhereLSub1NotEquals3()
  395. {
  396. Assert<C>(c => c.L[1] != 3, 4, "{ \"l.1\" : { \"$ne\" : 3 } }");
  397. }
  398. [Test]
  399. public void TestWhereLSub1NotEquals3Not()
  400. {
  401. Assert<C>(c => !(c.L[1] != 3), 1, "{ \"l.1\" : 3 }");
  402. }
  403. [Test]
  404. public void TestWhereLXModTwoEquals1()
  405. {
  406. Assert<C>(c => c.LX % 2 == 1, 3, "{ \"lx\" : { \"$mod\" : [NumberLong(2), NumberLong(1)] } }");
  407. }
  408. [Test]
  409. public void TestWhereLXModTwoEquals1Not()
  410. {
  411. Assert<C>(c => !(c.LX % 2 == 1), 2, "{ \"lx\" : { \"$not\" : { \"$mod\" : [NumberLong(2), NumberLong(1)] } } }");
  412. }
  413. [Test]
  414. public void TestWhereLXModTwoEquals1Reversed()
  415. {
  416. Assert<C>(c => 1 == c.LX % 2, 3, "{ \"lx\" : { \"$mod\" : [NumberLong(2), NumberLong(1)] } }");
  417. }
  418. [Test]
  419. public void TestWhereLXModTwoNotEquals1()
  420. {
  421. Assert<C>(c => c.LX % 2 != 1, 2, "{ \"lx\" : { \"$not\" : { \"$mod\" : [NumberLong(2), NumberLong(1)] } } }");
  422. }
  423. [Test]
  424. public void TestWhereLXModTwoNotEquals1Not()
  425. {
  426. Assert<C>(c => !(c.LX % 2 != 1), 3, "{ \"lx\" : { \"$mod\" : [NumberLong(2), NumberLong(1)] } }");
  427. }
  428. [Test]
  429. public void TestWhereSASub0ContainsO()
  430. {
  431. Assert<C>(c => c.SA[0].Contains("o"), 1, "{ \"sa.0\" : /o/s }");
  432. }
  433. [Test]
  434. public void TestWhereSASub0ContainsONot()
  435. {
  436. Assert<C>(c => !c.SA[0].Contains("o"), 4, "{ \"sa.0\" : { \"$not\" : /o/s } }");
  437. }
  438. [Test]
  439. public void TestWhereSASub0EndsWithM()
  440. {
  441. Assert<C>(c => c.SA[0].EndsWith("m"), 1, "{ \"sa.0\" : /m$/s }");
  442. }
  443. [Test]
  444. public void TestWhereSASub0EndsWithMNot()
  445. {
  446. Assert<C>(c => !c.SA[0].EndsWith("m"), 4, "{ \"sa.0\" : { \"$not\" : /m$/s } }");
  447. }
  448. [Test]
  449. public void TestWhereSASub0IsMatch()
  450. {
  451. var regex = new Regex(@"^T");
  452. Assert<C>(c => regex.IsMatch(c.SA[0]), 1, "{ \"sa.0\" : /^T/ }");
  453. }
  454. [Test]
  455. public void TestWhereSASub0IsMatchNot()
  456. {
  457. var regex = new Regex(@"^T");
  458. Assert<C>(c => !regex.IsMatch(c.SA[0]), 4, "{ \"sa.0\" : { \"$not\" : /^T/ } }");
  459. }
  460. [Test]
  461. public void TestWhereSASub0IsMatchStatic()
  462. {
  463. Assert<C>(c => Regex.IsMatch(c.SA[0], "^T"), 1, "{ \"sa.0\" : /^T/ }");
  464. }
  465. [Test]
  466. public void TestWhereSASub0IsMatchStaticNot()
  467. {
  468. Assert<C>(c => !Regex.IsMatch(c.SA[0], "^T"), 4, "{ \"sa.0\" : { \"$not\" : /^T/ } }");
  469. }
  470. [Test]
  471. public void TestWhereSASub0IsMatchStaticWithOptions()
  472. {
  473. Assert<C>(c => Regex.IsMatch(c.SA[0], "^t", RegexOptions.IgnoreCase), 1, "{ \"sa.0\" : /^t/i }");
  474. }
  475. [Test]
  476. public void TestWhereSASub0StartsWithT()
  477. {
  478. Assert<C>(c => c.SA[0].StartsWith("T"), 1, "{ \"sa.0\" : /^T/s }");
  479. }
  480. [Test]
  481. public void TestWhereSASub0StartsWithTNot()
  482. {
  483. Assert<C>(c => !c.SA[0].StartsWith("T"), 4, "{ \"sa.0\" : { \"$not\" : /^T/s } }");
  484. }
  485. [Test]
  486. public void TestWhereSContainsAbc()
  487. {
  488. Assert<C>(c => c.S.Contains("abc"), 1, "{ \"s\" : /abc/s }");
  489. }
  490. [Test]
  491. public void TestWhereSContainsAbcNot()
  492. {
  493. Assert<C>(c => !c.S.Contains("abc"), 4, "{ \"s\" : { \"$not\" : /abc/s } }");
  494. }
  495. [Test]
  496. public void TestWhereSContainsDot()
  497. {
  498. Assert<C>(c => c.S.Contains("."), 0, "{ \"s\" : /\\./s }");
  499. }
  500. [Test]
  501. public void TestWhereSCountEquals3()
  502. {
  503. Assert<C>(c => c.S.Count() == 3, 1, "{ \"s\" : /^.{3}$/s }");
  504. }
  505. [Test]
  506. public void TestWhereSEqualsAbc()
  507. {
  508. Assert<C>(c => c.S == "abc", 1, "{ \"s\" : \"abc\" }");
  509. }
  510. [Test]
  511. public void TestWhereSEqualsAbcNot()
  512. {
  513. Assert<C>(c => !(c.S == "abc"), 4, "{ \"s\" : { \"$ne\" : \"abc\" } }");
  514. }
  515. [Test]
  516. public void TestWhereSEqualsMethodAbc()
  517. {
  518. Assert<C>(c => c.S.Equals("abc"), 1, "{ \"s\" : \"abc\" }");
  519. }
  520. [Test]
  521. public void TestWhereSEqualsMethodAbcNot()
  522. {
  523. Assert<C>(c => !(c.S.Equals("abc")), 4, "{ \"s\" : { \"$ne\" : \"abc\" } }");
  524. }
  525. [Test]
  526. public void TestWhereSEqualsStaticMethodAbc()
  527. {
  528. Assert<C>(c => string.Equals(c.S, "abc"), 1, "{ \"s\" : \"abc\" }");
  529. }
  530. [Test]
  531. public void TestWhereSEqualsStaticMethodAbcNot()
  532. {
  533. Assert<C>(c => !string.Equals(c.S, "abc"), 4, "{ \"s\" : { \"$ne\" : \"abc\" } }");
  534. }
  535. [Test]
  536. public void TestWhereSEndsWithAbc()
  537. {
  538. Assert<C>(c => c.S.EndsWith("abc"), 1, "{ \"s\" : /abc$/s }");
  539. }
  540. [Test]
  541. public void TestWhereSEndsWithAbcNot()
  542. {
  543. Assert<C>(c => !c.S.EndsWith("abc"), 4, "{ \"s\" : { \"$not\" : /abc$/s } }");
  544. }
  545. [Test]
  546. public void TestWhereSIndexOfAnyBDashCEquals1()
  547. {
  548. Assert<C>(c => c.S.IndexOfAny(new char[] { 'b', '-', 'c' }) == 1, 1, "{ \"s\" : /^[^b\\-c]{1}[b\\-c]/s }");
  549. }
  550. [Test]
  551. public void TestWhereSIndexOfAnyBCStartIndex1Equals1()
  552. {
  553. Assert<C>(c => c.S.IndexOfAny(new char[] { 'b', '-', 'c' }, 1) == 1, 1, "{ \"s\" : /^.{1}[^b\\-c]{0}[b\\-c]/s }");
  554. }
  555. [Test]
  556. public void TestWhereSIndexOfAnyBCStartIndex1Count2Equals1()
  557. {
  558. Assert<C>(c => c.S.IndexOfAny(new char[] { 'b', '-', 'c' }, 1, 2) == 1, 1, "{ \"s\" : /^.{1}(?=.{2})[^b\\-c]{0}[b\\-c]/s }");
  559. }
  560. [Test]
  561. public void TestWhereSIndexOfBEquals1()
  562. {
  563. Assert<C>(c => c.S.IndexOf('b') == 1, 1, "{ \"s\" : /^[^b]{1}b/s }");
  564. }
  565. [Test]
  566. public void TestWhereSIndexOfBStartIndex1Equals1()
  567. {
  568. Assert<C>(c => c.S.IndexOf('b', 1) == 1, 1, "{ \"s\" : /^.{1}[^b]{0}b/s }");
  569. }
  570. [Test]
  571. public void TestWhereSIndexOfBStartIndex1Count2Equals1()
  572. {
  573. Assert<C>(c => c.S.IndexOf('b', 1, 2) == 1, 1, "{ \"s\" : /^.{1}(?=.{2})[^b]{0}b/s }");
  574. }
  575. [Test]
  576. public void TestWhereSIndexOfXyzEquals3()
  577. {
  578. Assert<C>(c => c.S.IndexOf("xyz") == 3, 1, "{ \"s\" : /^(?!.{0,2}xyz).{3}xyz/s }");
  579. }
  580. [Test]
  581. public void TestWhereSIndexOfXyzStartIndex1Equals3()
  582. {
  583. Assert<C>(c => c.S.IndexOf("xyz", 1) == 3, 1, "{ \"s\" : /^.{1}(?!.{0,1}xyz).{2}xyz/s }");
  584. }
  585. [Test]
  586. public void TestWhereSIndexOfXyzStartIndex1Count5Equals3()
  587. {
  588. Assert<C>(c => c.S.IndexOf("xyz", 1, 5) == 3, 1, "{ \"s\" : /^.{1}(?=.{5})(?!.{0,1}xyz).{2}xyz/s }");
  589. }
  590. [Test]
  591. public void TestWhereSIsMatch()
  592. {
  593. var regex = new Regex(@"^abc");
  594. Assert<C>(c => regex.IsMatch(c.S), 1, "{ \"s\" : /^abc/ }");
  595. }
  596. [Test]
  597. public void TestWhereSIsMatchNot()
  598. {
  599. var regex = new Regex(@"^abc");
  600. Assert<C>(c => !regex.IsMatch(c.S), 4, "{ \"s\" : { \"$not\" : /^abc/ } }");
  601. }
  602. [Test]
  603. public void TestWhereSIsMatchStatic()
  604. {
  605. Assert<C>(c => Regex.IsMatch(c.S, "^abc"), 1, "{ \"s\" : /^abc/ }");
  606. }
  607. [Test]
  608. public void TestWhereSIsMatchStaticNot()
  609. {
  610. Assert<C>(c => !Regex.IsMatch(c.S, "^abc"), 4, "{ \"s\" : { \"$not\" : /^abc/ } }");
  611. }
  612. [Test]
  613. public void TestWhereSIsMatchStaticWithOptions()
  614. {
  615. Assert<C>(c => Regex.IsMatch(c.S, "^abc", RegexOptions.IgnoreCase), 1, "{ \"s\" : /^abc/i }");
  616. }
  617. [Test]
  618. public void TestWhereSLengthEquals3()
  619. {
  620. Assert<C>(c => c.S.Length == 3, 1, "{ \"s\" : /^.{3}$/s }");
  621. }
  622. [Test]
  623. public void TestWhereSLengthEquals3Not()
  624. {
  625. Assert<C>(c => !(c.S.Length == 3), 4, "{ \"s\" : { \"$not\" : /^.{3}$/s } }");
  626. }
  627. [Test]
  628. public void TestWhereSLengthGreaterThan3()
  629. {
  630. Assert<C>(c => c.S.Length > 3, 1, "{ \"s\" : /^.{4,}$/s }");
  631. }
  632. [Test]
  633. public void TestWhereSLengthGreaterThanOrEquals3()
  634. {
  635. Assert<C>(c => c.S.Length >= 3, 2, "{ \"s\" : /^.{3,}$/s }");
  636. }
  637. [Test]
  638. public void TestWhereSLengthLessThan3()
  639. {
  640. Assert<C>(c => c.S.Length < 3, 0, "{ \"s\" : /^.{0,2}$/s }");
  641. }
  642. [Test]
  643. public void TestWhereSLengthLessThanOrEquals3()
  644. {
  645. Assert<C>(c => c.S.Length <= 3, 1, "{ \"s\" : /^.{0,3}$/s }");
  646. }
  647. [Test]
  648. public void TestWhereSLengthNotEquals3()
  649. {
  650. Assert<C>(c => c.S.Length != 3, 4, "{ \"s\" : { \"$not\" : /^.{3}$/s } }");
  651. }
  652. [Test]
  653. public void TestWhereSLengthNotEquals3Not()
  654. {
  655. Assert<C>(c => !(c.S.Length != 3), 1, "{ \"s\" : /^.{3}$/s }");
  656. }
  657. [Test]
  658. public void TestWhereSNotEqualsAbc()
  659. {
  660. Assert<C>(c => c.S != "abc", 4, "{ \"s\" : { \"$ne\" : \"abc\" } }");
  661. }
  662. [Test]
  663. public void TestWhereSNotEqualsAbcNot()
  664. {
  665. Assert<C>(c => !(c.S != "abc"), 1, "{ \"s\" : \"abc\" }");
  666. }
  667. [Test]
  668. public void TestWhereSStartsWithAbc()
  669. {
  670. Assert<C>(c => c.S.StartsWith("abc"), 1, "{ \"s\" : /^abc/s }");
  671. }
  672. [Test]
  673. public void TestWhereSStartsWithAbcNot()
  674. {
  675. Assert<C>(c => !c.S.StartsWith("abc"), 4, "{ \"s\" : { \"$not\" : /^abc/s } }");
  676. }
  677. [Test]
  678. public void TestWhereSSub1EqualsB()
  679. {
  680. Assert<C>(c => c.S[1] == 'b', 1, "{ \"s\" : /^.{1}b/s }");
  681. }
  682. [Test]
  683. public void TestWhereSSub1EqualsBNot()
  684. {
  685. Assert<C>(c => !(c.S[1] == 'b'), 4, "{ \"s\" : { \"$not\" : /^.{1}b/s } }");
  686. }
  687. [Test]
  688. public void TestWhereSSub1NotEqualsB()
  689. {
  690. Assert<C>(c => c.S[1] != 'b', 1, "{ \"s\" : /^.{1}[^b]/s }");
  691. }
  692. [Test]
  693. public void TestWhereSSub1NotEqualsBNot()
  694. {
  695. Assert<C>(c => !(c.S[1] != 'b'), 4, "{ \"s\" : { \"$not\" : /^.{1}[^b]/s } }");
  696. }
  697. [Test]
  698. public void TestWhereSTrimContainsXyz()
  699. {
  700. Assert<C>(c => c.S.Trim().Contains("xyz"), 1, "{ \"s\" : /^\\s*.*xyz.*\\s*$/s }");
  701. }
  702. [Test]
  703. public void TestWhereSTrimContainsXyzNot()
  704. {
  705. Assert<C>(c => !c.S.Trim().Contains("xyz"), 4, "{ \"s\" : { \"$not\" : /^\\s*.*xyz.*\\s*$/s } }");
  706. }
  707. [Test]
  708. public void TestWhereSTrimEndsWithXyz()
  709. {
  710. Assert<C>(c => c.S.Trim().EndsWith("xyz"), 1, "{ \"s\" : /^\\s*.*xyz\\s*$/s }");
  711. }
  712. [Test]
  713. public void TestWhereSTrimEndsWithXyzNot()
  714. {
  715. Assert<C>(c => !c.S.Trim().EndsWith("xyz"), 4, "{ \"s\" : { \"$not\" : /^\\s*.*xyz\\s*$/s } }");
  716. }
  717. [Test]
  718. public void TestWhereSTrimStartsWithXyz()
  719. {
  720. Assert<C>(c => c.S.Trim().StartsWith("xyz"), 1, "{ \"s\" : /^\\s*xyz.*\\s*$/s }");
  721. }
  722. [Test]
  723. public void TestWhereSTrimStartsWithXyzNot()
  724. {
  725. Assert<C>(c => !c.S.Trim().StartsWith("xyz"), 4, "{ \"s\" : { \"$not\" : /^\\s*xyz.*\\s*$/s } }");
  726. }
  727. [Test]
  728. public void TestWhereSTrimStartTrimEndToLowerContainsXyz()
  729. {
  730. Assert<C>(c => c.S.TrimStart(' ', '.', '-', '\t').TrimEnd().ToLower().Contains("xyz"), 1, "{ \"s\" : /^[\\ \\.\\-\\t]*.*xyz.*\\s*$/is }");
  731. }
  732. [Test]
  733. public void TestWhereSToLowerEqualsConstantLowerCaseValue()
  734. {
  735. Assert<C>(c => c.S.ToLower() == "abc", 1, "{ \"s\" : /^abc$/i }");
  736. }
  737. [Test]
  738. public void TestWhereSToLowerDoesNotEqualConstantLowerCaseValue()
  739. {
  740. Assert<C>(c => c.S.ToLower() != "abc", 4, "{ \"s\" : { \"$not\" : /^abc$/i } }");
  741. }
  742. [Test]
  743. public void TestWhereSToLowerEqualsConstantMixedCaseValue()
  744. {
  745. Assert<C>(c => c.S.ToLower() == "Abc", 0, "{ \"_id\" : { \"$type\" : -1 } }");
  746. }
  747. [Test]
  748. public void TestWhereSToLowerDoesNotEqualConstantMixedCaseValue()
  749. {
  750. Assert<C>(c => c.S.ToLower() != "Abc", 5, "{ }");
  751. }
  752. [Test]
  753. public void TestWhereSToLowerEqualsNullValue()
  754. {
  755. Assert<C>(c => c.S.ToLower() == null, 3, "{ \"s\" : null }");
  756. }
  757. [Test]
  758. public void TestWhereSToLowerDoesNotEqualNullValue()
  759. {
  760. Assert<C>(c => c.S.ToLower() != null, 2, "{ \"s\" : { \"$ne\" : null } }");
  761. }
  762. [Test]
  763. public void TestWhereSToUpperEqualsConstantLowerCaseValue()
  764. {
  765. Assert<C>(c => c.S.ToUpper() == "abc", 0, "{ \"_id\" : { \"$type\" : -1 } }");
  766. }
  767. [Test]
  768. public void TestWhereSToUpperDoesNotEqualConstantLowerCaseValue()
  769. {
  770. Assert<C>(c => c.S.ToUpper() != "abc", 5, "{ }");
  771. }
  772. [Test]
  773. public void TestWhereSToUpperEqualsConstantMixedCaseValue()
  774. {
  775. Assert<C>(c => c.S.ToUpper() == "Abc", 0, "{ \"_id\" : { \"$type\" : -1 } }");
  776. }
  777. [Test]
  778. public void TestWhereSToUpperDoesNotEqualConstantMixedCaseValue()
  779. {
  780. Assert<C>(c => c.S.ToUpper() != "Abc", 5, "{ }");
  781. }
  782. [Test]
  783. public void TestWhereSToUpperEqualsNullValue()
  784. {
  785. Assert<C>(c => c.S.ToUpper() == null, 3, "{ \"s\" : null }");
  786. }
  787. [Test]
  788. public void TestWhereSToUpperDoesNotEqualNullValue()
  789. {
  790. Assert<C>(c => c.S.ToUpper() != null, 2, "{ \"s\" : { \"$ne\" : null } }");
  791. }
  792. [Test]
  793. public void TestWhereTripleAnd()
  794. {
  795. // the query is a bit odd in order to force the built query to be promoted to $and form
  796. Assert<C>(c => c.X >= 0 && c.X >= 1 && c.Y == 11, 2, "{ \"$and\" : [{ \"x\" : { \"$gte\" : 0 } }, { \"x\" : { \"$gte\" : 1 } }, { \"y\" : 11 }] }");
  797. }
  798. [Test]
  799. public void TestWhereTripleOr()
  800. {
  801. Assert<C>(c => c.X == 1 || c.Y == 33 || c.S == "x is 1", 2, "{ \"$or\" : [{ \"x\" : 1 }, { \"y\" : 33 }, { \"s\" : \"x is 1\" }] }");
  802. }
  803. [Test]
  804. public void TestWhereXEquals1()
  805. {
  806. Assert<C>(c => c.X == 1, 1, "{ \"x\" : 1 }");
  807. }
  808. [Test]
  809. public void TestWhereXEquals1AndYEquals11()
  810. {
  811. Assert<C>(c => c.X == 1 & c.Y == 11, 1, "{ \"x\" : 1, \"y\" : 11 }");
  812. }
  813. [Test]
  814. public void TestWhereXEquals1AndAlsoYEquals11()
  815. {
  816. Assert<C>(c => c.X == 1 && c.Y == 11, 1, "{ \"x\" : 1, \"y\" : 11 }");
  817. }
  818. [Test]
  819. public void TestWhereXEquals1AndYEquals11Not()
  820. {
  821. Assert<C>(c => !(c.X == 1 && c.Y == 11), 4, "{ \"$nor\" : [{ \"x\" : 1, \"y\" : 11 }] }");
  822. }
  823. [Test]
  824. public void TestWhereXEquals1AndYEquals11AndZEquals11()
  825. {
  826. Assert<C>(c => c.X == 1 && c.Y == 11 && c.D.Z == 11, 1, "{ \"x\" : 1, \"y\" : 11, \"d.z\" : 11 }");
  827. }
  828. [Test]
  829. public void TestWhereXEquals1Not()
  830. {
  831. Assert<C>(c => !(c.X == 1), 4, "{ \"x\" : { \"$ne\" : 1 } }");
  832. }
  833. [Test]
  834. public void TestWhereXEquals1OrYEquals33()
  835. {
  836. Assert<C>(c => c.X == 1 | c.Y == 33, 2, "{ \"$or\" : [{ \"x\" : 1 }, { \"y\" : 33 }] }");
  837. }
  838. [Test]
  839. public void TestWhereXEquals1OrElseYEquals33()
  840. {
  841. Assert<C>(c => c.X == 1 || c.Y == 33, 2, "{ \"$or\" : [{ \"x\" : 1 }, { \"y\" : 33 }] }");
  842. }
  843. [Test]
  844. public void TestWhereXEquals1OrYEquals33Not()
  845. {
  846. Assert<C>(c => !(c.X == 1 || c.Y == 33), 3, "{ \"$nor\" : [{ \"x\" : 1 }, { \"y\" : 33 }] }");
  847. }
  848. [Test]
  849. public void TestWhereXEquals1OrYEquals33NotNot()
  850. {
  851. Assert<C>(c => !!(c.X == 1 || c.Y == 33), 2, "{ \"$or\" : [{ \"x\" : 1 }, { \"y\" : 33 }] }");
  852. }
  853. [Test]
  854. public void TestWhereXGreaterThan1()
  855. {
  856. Assert<C>(c => c.X > 1, 4, "{ \"x\" : { \"$gt\" : 1 } }");
  857. }
  858. [Test]
  859. public void TestWhereXGreaterThan1AndLessThan3()
  860. {
  861. Assert<C>(c => c.X > 1 && c.X < 3, 1, "{ \"x\" : { \"$gt\" : 1, \"$lt\" : 3 } }");
  862. }
  863. [Test]
  864. public void TestWhereXGreaterThan1AndLessThan3Not()
  865. {
  866. Assert<C>(c => !(c.X > 1 && c.X < 3), 4, "{ \"$nor\" : [{ \"x\" : { \"$gt\" : 1, \"$lt\" : 3 } }] }");
  867. }
  868. [Test]
  869. public void TestWhereXGreaterThan1Not()
  870. {
  871. Assert<C>(c => !(c.X > 1), 1, "{ \"x\" : { \"$not\" : { \"$gt\" : 1 } } }");
  872. }
  873. [Test]
  874. public void TestWhereXGreaterThan1Reversed()
  875. {
  876. Assert<C>(c => 1 < c.X, 4, "{ \"x\" : { \"$gt\" : 1 } }");
  877. }
  878. [Test]
  879. public void TestWhereXGreaterThanOrEquals1()
  880. {
  881. Assert<C>(c => c.X >= 1, 5, "{ \"x\" : { \"$gte\" : 1 } }");
  882. }
  883. [Test]
  884. public void TestWhereXGreaterThanOrEquals1Not()
  885. {
  886. Assert<C>(c => !(c.X >= 1), 0, "{ \"x\" : { \"$not\" : { \"$gte\" : 1 } } }");
  887. }
  888. [Test]
  889. public void TestWhereXGreaterThanOrEquals1Reversed()
  890. {
  891. Assert<C>(c => 1 <= c.X, 5, "{ \"x\" : { \"$gte\" : 1 } }");
  892. }
  893. [Test]
  894. public void TestWhereXLessThan1()
  895. {
  896. Assert<C>(c => c.X < 1, 0, "{ \"x\" : { \"$lt\" : 1 } }");
  897. }
  898. [Test]
  899. public void TestWhereXLessThan1Not()
  900. {
  901. Assert<C>(c => !(c.X < 1), 5, "{ \"x\" : { \"$not\" : { \"$lt\" : 1 } } }");
  902. }
  903. [Test]
  904. public void TestWhereXLessThan1Reversed()
  905. {
  906. Assert<C>(c => 1 > c.X, 0, "{ \"x\" : { \"$lt\" : 1 } }");
  907. }
  908. [Test]
  909. public void TestWhereXLessThanOrEquals1()
  910. {
  911. Assert<C>(c => c.X <= 1, 1, "{ \"x\" : { \"$lte\" : 1 } }");
  912. }
  913. [Test]
  914. public void TestWhereXLessThanOrEquals1Not()
  915. {
  916. Assert<C>(c => !(c.X <= 1), 4, "{ \"x\" : { \"$not\" : { \"$lte\" : 1 } } }");
  917. }
  918. [Test]
  919. public void TestWhereXLessThanOrEquals1Reversed()
  920. {
  921. Assert<C>(c => 1 >= c.X, 1, "{ \"x\" : { \"$lte\" : 1 } }");
  922. }
  923. [Test]
  924. public void TestWhereXModOneEquals0AndXModTwoEquals0()
  925. {
  926. Assert<C>(c => (c.X % 1 == 0) && (c.X % 2 == 0), 2, "{ \"$and\" : [{ \"x\" : { \"$mod\" : [NumberLong(1), NumberLong(0)] } }, { \"x\" : { \"$mod\" : [NumberLong(2), NumberLong(0)] } }] }");
  927. }
  928. [Test]
  929. public void TestWhereXModOneEquals0AndXModTwoEquals0Not()
  930. {
  931. Assert<C>(c => !((c.X % 1 == 0) && (c.X % 2 == 0)), 3, "{ \"$nor\" : [{ \"$and\" : [{ \"x\" : { \"$mod\" : [NumberLong(1), NumberLong(0)] } }, { \"x\" : { \"$mod\" : [NumberLong(2), NumberLong(0)] } }] }] }");
  932. }
  933. [Test]
  934. public void TestWhereXModOneEquals0AndXModTwoEquals0NotNot()
  935. {
  936. Assert<C>(c => !!((c.X % 1 == 0) && (c.X % 2 == 0)), 2, "{ \"$or\" : [{ \"$and\" : [{ \"x\" : { \"$mod\" : [NumberLong(1), NumberLong(0)] } }, { \"x\" : { \"$mod\" : [NumberLong(2), NumberLong(0)] } }] }] }");
  937. }
  938. [Test]
  939. public void TestWhereXModTwoEquals1()
  940. {
  941. Assert<C>(c => c.X % 2 == 1, 3, "{ \"x\" : { \"$mod\" : [NumberLong(2), NumberLong(1)] } }");
  942. }
  943. [Test]
  944. public void TestWhereXModTwoEquals1Not()
  945. {
  946. Assert<C>(c => !(c.X % 2 == 1), 2, "{ \"x\" : { \"$not\" : { \"$mod\" : [NumberLong(2), NumberLong(1)] } } }");
  947. }
  948. [Test]
  949. public void TestWhereXModTwoEquals1Reversed()
  950. {
  951. Assert<C>(c => 1 == c.X % 2, 3, "{ \"x\" : { \"$mod\" : [NumberLong(2), NumberLong(1)] } }");
  952. }
  953. [Test]
  954. public void TestWhereXModTwoNotEquals1()
  955. {
  956. Assert<C>(c => c.X % 2 != 1, 2, "{ \"x\" : { \"$not\" : { \"$mod\" : [NumberLong(2), NumberLong(1)] } } }");
  957. }
  958. [Test]
  959. public void TestWhereXModTwoNotEquals1Not()
  960. {
  961. Assert<C>(c => !(c.X % 2 != 1), 3, "{ \"x\" : { \"$mod\" : [NumberLong(2), NumberLong(1)] } }");
  962. }
  963. [Test]
  964. public void TestWhereXNotEquals1()
  965. {
  966. Assert<C>(c => c.X != 1, 4, "{ \"x\" : { \"$ne\" : 1 } }");
  967. }
  968. [Test]
  969. public void TestWhereXNotEquals1Not()
  970. {
  971. Assert<C>(c => !(c.X != 1), 1, "{ \"x\" : 1 }");
  972. }
  973. public void Assert<TDocument>(Expression<Func<TDocument, bool>> filter, int expectedCount, string expectedFilter)
  974. {
  975. var serializer = BsonSerializer.SerializerRegistry.GetSerializer<TDocument>();
  976. var filterDocument = PredicateTranslator.Translate(filter, serializer, BsonSerializer.SerializerRegistry);
  977. using (var cursor = _collection.FindAsync<TDocument>(filterDocument).GetAwaiter().GetResult())
  978. {
  979. var list = cursor.ToListAsync().GetAwaiter().GetResult();
  980. filterDocument.Should().Be(expectedFilter);
  981. list.Count.Should().Be(expectedCount);
  982. }
  983. }
  984. private enum E
  985. {
  986. None,
  987. A,
  988. B,
  989. C
  990. }
  991. private class C
  992. {
  993. public ObjectId Id { get; set; }
  994. [BsonElement("x")]
  995. public int X { get; set; }
  996. [BsonElement("lx")]
  997. public long LX { get; set; }
  998. [BsonElement("y")]
  999. public int Y { get; set; }
  1000. [BsonElement("d")]
  1001. public D D { get; set; }
  1002. [BsonElement("da")]
  1003. public List<D> DA { get; set; }
  1004. [BsonElement("s")]
  1005. [BsonIgnoreIfNull]
  1006. public string S { get; set; }
  1007. [BsonElement("a")]
  1008. [BsonIgnoreIfNull]
  1009. public int[] A { get; set; }
  1010. [BsonElement("b")]
  1011. public bool B { get; set; }
  1012. [BsonElement("l")]
  1013. [BsonIgnoreIfNull]
  1014. public List<int> L { get; set; }
  1015. [BsonElement("dbref")]
  1016. [BsonIgnoreIfNull]
  1017. public MongoDBRef DBRef { get; set; }
  1018. [BsonElement("e")]
  1019. [BsonIgnoreIfDefault]
  1020. [BsonRepresentation(BsonType.String)]
  1021. public E E { get; set; }
  1022. [BsonElement("en")]
  1023. [BsonRepresentation(BsonType.String)]
  1024. public E? ENullable { get; set; }
  1025. [BsonElement("ea")]
  1026. [BsonIgnoreIfNull]
  1027. public E[] EA { get; set; }
  1028. [BsonElement("f")]
  1029. public F F { get; set; }
  1030. [BsonElement("sa")]
  1031. [BsonIgnoreIfNull]
  1032. public string[] SA { get; set; }
  1033. [BsonElement("ba")]
  1034. [BsonIgnoreIfNull]
  1035. public bool[] BA { get; set; }
  1036. [BsonElement("date")]
  1037. public DateTime Date { get; set; }
  1038. [BsonElement("nuldub")]
  1039. public double? NullableDouble { get; set; }
  1040. }
  1041. private class D
  1042. {
  1043. [BsonElement("y")]
  1044. [BsonIgnoreIfNull]
  1045. [BsonDefaultValue(20)]
  1046. public int? Y;
  1047. [BsonElement("z")]
  1048. public int Z; // use field instead of property to test fields also
  1049. public override bool Equals(object obj)
  1050. {
  1051. if (obj == null || GetType() != obj.GetType()) { return false; }
  1052. return Z == ((D)obj).Z;
  1053. }
  1054. public override int GetHashCode()
  1055. {
  1056. return Z.GetHashCode();
  1057. }
  1058. public override string ToString()
  1059. {
  1060. return string.Format("new D {{ Y = {0}, Z = {1} }}", Y, Z);
  1061. }
  1062. }
  1063. private class F
  1064. {
  1065. [BsonElement("g")]
  1066. public G G { get; set; }
  1067. }
  1068. private class G
  1069. {
  1070. [BsonElement("h")]
  1071. public int H { get; set; }
  1072. }
  1073. }
  1074. }