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

/tests/MongoDB.Driver.Tests/Linq/Translators/AggregateProjectTranslatorTests.cs

http://github.com/mongodb/mongo-csharp-driver
C# | 1705 lines | 1174 code | 515 blank | 16 comment | 24 complexity | 70f5ad53dd0ab77f13500b1206d3cd0e MD5 | raw file
Possible License(s): Apache-2.0

Large files files are truncated, but you can click here to view the full file

  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 FluentAssertions;
  20. using MongoDB.Bson;
  21. using MongoDB.Bson.Serialization;
  22. using MongoDB.Driver.Core.Misc;
  23. using MongoDB.Driver.Core.TestHelpers.XunitExtensions;
  24. using MongoDB.Driver.Linq;
  25. using MongoDB.Driver.Linq.Translators;
  26. using Xunit;
  27. namespace MongoDB.Driver.Tests.Linq.Translators
  28. {
  29. public class AggregateProjectTranslatorTests : IntegrationTestBase
  30. {
  31. private readonly static ExpressionTranslationOptions __codePointTranslationOptions = new ExpressionTranslationOptions
  32. {
  33. StringTranslationMode = AggregateStringTranslationMode.CodePoints
  34. };
  35. [Fact]
  36. public void Should_translate_using_non_anonymous_type_with_default_constructor()
  37. {
  38. var result = Project(x => new RootView { Property = x.A, Field = x.B });
  39. result.Projection.Should().Be("{ Property: \"$A\", Field: \"$B\", _id: 0 }");
  40. result.Value.Property.Should().Be("Awesome");
  41. result.Value.Field.Should().Be("Balloon");
  42. }
  43. [Fact]
  44. public void Should_translate_using_non_anonymous_type_with_parameterized_constructor()
  45. {
  46. var result = Project(x => new RootView(x.A) { Field = x.B });
  47. result.Projection.Should().Be("{ Field: \"$B\", Property: \"$A\", _id: 0 }");
  48. result.Value.Property.Should().Be("Awesome");
  49. result.Value.Field.Should().Be("Balloon");
  50. }
  51. [SkippableFact]
  52. public void Should_translate_abs()
  53. {
  54. RequireServer.Check().VersionGreaterThanOrEqualTo("3.1.6");
  55. var result = Project(x => new { Result = Math.Abs(x.C.E.F) });
  56. result.Projection.Should().Be("{ Result: { \"$abs\": \"$C.E.F\" }, _id: 0 }");
  57. result.Value.Result.Should().Be(11);
  58. }
  59. [Fact]
  60. public void Should_translate_add()
  61. {
  62. var result = Project(x => new { Result = x.C.E.F + x.C.E.H });
  63. result.Projection.Should().Be("{ Result: { \"$add\": [\"$C.E.F\", \"$C.E.H\"] }, _id: 0 }");
  64. result.Value.Result.Should().Be(33);
  65. }
  66. [Fact]
  67. public void Should_translate_add_flattened()
  68. {
  69. var result = Project(x => new { Result = x.Id + x.C.E.F + x.C.E.H });
  70. result.Projection.Should().Be("{ Result: { \"$add\": [\"$_id\", \"$C.E.F\", \"$C.E.H\"] }, _id: 0 }");
  71. result.Value.Result.Should().Be(43);
  72. }
  73. [SkippableFact]
  74. public void Should_translate_allElementsTrue()
  75. {
  76. RequireServer.Check().VersionGreaterThanOrEqualTo("2.6.0");
  77. var result = Project(x => new { Result = x.G.All(g => g.E.F > 30) });
  78. result.Projection.Should().Be("{ Result: { \"$allElementsTrue\" : { \"$map\": { input: \"$G\", as: \"g\", in: { \"$gt\": [\"$$g.E.F\", 30 ] } } } }, _id: 0 }");
  79. result.Value.Result.Should().BeTrue();
  80. }
  81. [SkippableFact]
  82. public void Should_translate_anyElementTrue()
  83. {
  84. RequireServer.Check().VersionGreaterThanOrEqualTo("2.6.0");
  85. var result = Project(x => new { Result = x.G.Any() });
  86. result.Projection.Should().Be("{ Result: { \"$gt\" : [{ \"$size\" : \"$G\" }, 0] }, _id: 0 }");
  87. result.Value.Result.Should().BeTrue();
  88. }
  89. [SkippableFact]
  90. public void Should_translate_anyElementTrue_with_predicate()
  91. {
  92. RequireServer.Check().VersionGreaterThanOrEqualTo("2.6.0");
  93. var result = Project(x => new { Result = x.G.Any(g => g.E.F > 40) });
  94. result.Projection.Should().Be("{ Result: { \"$anyElementTrue\" : { \"$map\": { input: \"$G\", as: \"g\", in: { \"$gt\": [\"$$g.E.F\", 40 ] } } } }, _id: 0 }");
  95. result.Value.Result.Should().BeTrue();
  96. }
  97. [SkippableFact]
  98. public void Should_translate_anyElementTrue_using_Contains()
  99. {
  100. RequireServer.Check().VersionGreaterThanOrEqualTo("2.6.0");
  101. var result = Project(x => new { Result = x.L.Contains(5) });
  102. result.Projection.Should().Be("{ Result: { \"$anyElementTrue\": { $map: { input: \"$L\", as: \"x\", in: { $eq: [\"$$x\", 5 ] } } } }, _id: 0 }");
  103. result.Value.Result.Should().BeTrue();
  104. }
  105. [SkippableFact]
  106. public void Should_translate_anyElementTrue_using_Contains_on_a_local_collection()
  107. {
  108. RequireServer.Check().VersionGreaterThanOrEqualTo("2.6.0");
  109. var local = new[] { 11, 33, 55 };
  110. var result = Project(x => new { Result = local.Contains(x.C.E.F) });
  111. result.Projection.Should().Be("{ Result: { \"$anyElementTrue\": { $map: { input: [11, 33, 55], as: \"x\", in: { $eq: [\"$$x\", \"$C.E.F\" ] } } } }, _id: 0 }");
  112. result.Value.Result.Should().BeTrue();
  113. }
  114. [Fact]
  115. public void Should_translate_and()
  116. {
  117. var result = Project(x => new { Result = x.A == "yes" && x.B == "no" });
  118. result.Projection.Should().Be("{ Result: { \"$and\": [{ \"$eq\": [\"$A\", \"yes\"] }, { \"$eq\": [\"$B\", \"no\"] }] }, _id: 0 }");
  119. result.Value.Result.Should().BeFalse();
  120. }
  121. [Fact]
  122. public void Should_translate_and_flattened()
  123. {
  124. var result = Project(x => new { Result = x.A == "yes" && x.B == "no" && x.C.D == "maybe" });
  125. result.Projection.Should().Be("{ Result: { \"$and\": [{ \"$eq\": [\"$A\", \"yes\"] }, { \"$eq\": [\"$B\", \"no\"] }, { \"$eq\" : [\"$C.D\", \"maybe\"] } ] }, _id: 0 }");
  126. result.Value.Result.Should().BeFalse();
  127. }
  128. [SkippableFact]
  129. public void Should_translate_arrayElemAt_using_a_constant_ElementAt()
  130. {
  131. RequireServer.Check().VersionGreaterThanOrEqualTo("3.1.7");
  132. var result = Project(x => new { Result = x.M.ElementAt(1) });
  133. result.Projection.Should().Be("{ Result: { $arrayElemAt: [\"$M\", 1] }, _id: 0 }");
  134. result.Value.Result.Should().Be(4);
  135. }
  136. [SkippableFact]
  137. public void Should_translate_arrayElemAt_using_a_constant_indexer()
  138. {
  139. RequireServer.Check().VersionGreaterThanOrEqualTo("3.1.7");
  140. var result = Project(x => new { Result = x.M[1] });
  141. result.Projection.Should().Be("{ Result: { $arrayElemAt: [\"$M\", 1] }, _id: 0 }");
  142. result.Value.Result.Should().Be(4);
  143. }
  144. [SkippableFact]
  145. public void Should_translate_arrayElemAt_using_a_constant_get_Item()
  146. {
  147. RequireServer.Check().VersionGreaterThanOrEqualTo("3.1.7");
  148. var result = Project(x => new { Result = x.O[1] });
  149. result.Projection.Should().Be("{ Result: { $arrayElemAt: [\"$O\", 1] }, _id: 0 }");
  150. result.Value.Result.Should().Be(20);
  151. }
  152. [SkippableFact]
  153. public void Should_translate_arrayElemAt_using_a_variable_ElementAt()
  154. {
  155. RequireServer.Check().VersionGreaterThanOrEqualTo("3.1.7");
  156. var result = Project(x => new { Result = (int?)x.M.ElementAt(x.T["one"]) });
  157. result.Projection.Should().Be("{ Result: { $arrayElemAt: [\"$M\", \"$T.one\"] }, _id: 0 }");
  158. result.Value.Result.Should().Be(4);
  159. }
  160. [SkippableFact]
  161. public void Should_translate_arrayElemAt_using_a_variable_indexer()
  162. {
  163. RequireServer.Check().VersionGreaterThanOrEqualTo("3.1.7");
  164. var result = Project(x => new { Result = (int?)x.M[x.T["one"]] });
  165. result.Projection.Should().Be("{ Result: { $arrayElemAt: [\"$M\", \"$T.one\"] }, _id: 0 }");
  166. result.Value.Result.Should().Be(4);
  167. }
  168. [SkippableFact]
  169. public void Should_translate_arrayElemAt_using_a_variable_get_Item()
  170. {
  171. RequireServer.Check().VersionGreaterThanOrEqualTo("3.1.7");
  172. var result = Project(x => new { Result = (long?)x.O[x.T["one"]] });
  173. result.Projection.Should().Be("{ Result: { $arrayElemAt: [\"$O\", \"$T.one\"] }, _id: 0 }");
  174. result.Value.Result.Should().Be(20);
  175. }
  176. [SkippableFact]
  177. public void Should_translate_arrayElemAt_using_a_constant_ElementAt_followed_by_a_field()
  178. {
  179. RequireServer.Check().VersionGreaterThanOrEqualTo("3.1.7");
  180. var result = Project(x => new { Result = x.G.ElementAt(1).D });
  181. result.Projection.Should().Be("{ Result: { $let: { vars: { item: { \"$arrayElemAt\": [\"$G\", 1] } }, in: \"$$item.D\" } }, _id: 0 }");
  182. result.Value.Result.Should().Be("Dolphin");
  183. }
  184. [SkippableFact]
  185. public void Should_translate_arrayElemAt_using_a_variable_ElementAt_followed_by_a_field()
  186. {
  187. RequireServer.Check().VersionGreaterThanOrEqualTo("3.1.7");
  188. var result = Project(x => new { Result = x.G.ElementAt(x.T["one"]).D });
  189. result.Projection.Should().Be("{ Result: { $let: { vars: { item: { \"$arrayElemAt\": [\"$G\", \"$T.one\"] } }, in: \"$$item.D\" } }, _id: 0 }");
  190. result.Value.Result.Should().Be("Dolphin");
  191. }
  192. [SkippableFact]
  193. public void Should_translate_arrayElemAt_using_First()
  194. {
  195. RequireServer.Check().VersionGreaterThanOrEqualTo("3.1.7");
  196. var result = Project(x => new { Result = x.M.First() });
  197. result.Projection.Should().Be("{ Result: { \"$arrayElemAt\": [\"$M\", 0] }, _id: 0 }");
  198. result.Value.Result.Should().Be(2);
  199. }
  200. [SkippableFact]
  201. public void Should_translate_arrayElemAt_using_First_followed_by_a_field()
  202. {
  203. RequireServer.Check().VersionGreaterThanOrEqualTo("3.1.7");
  204. var result = Project(x => new { Result = x.G.First().D });
  205. result.Projection.Should().Be("{ Result: { $arrayElemAt: [\"$G.D\", 0] }, _id: 0 }");
  206. result.Value.Result.Should().Be("Don't");
  207. }
  208. [SkippableFact]
  209. public void Should_translate_arrayElemAt_using_Last()
  210. {
  211. RequireServer.Check().VersionGreaterThanOrEqualTo("3.1.7");
  212. var result = Project(x => new { Result = x.M.Last() });
  213. result.Projection.Should().Be("{ Result: { \"$arrayElemAt\": [\"$M\", -1] }, _id: 0 }");
  214. result.Value.Result.Should().Be(5);
  215. }
  216. [SkippableFact]
  217. public void Should_translate_arrayElemAt_using_Last_followed_by_a_field()
  218. {
  219. RequireServer.Check().VersionGreaterThanOrEqualTo("3.1.7");
  220. var result = Project(x => new { Result = x.G.Last().D });
  221. result.Projection.Should().Be("{ Result: { \"$arrayElemAt\": [\"$G.D\", -1] }, _id: 0 }");
  222. result.Value.Result.Should().Be("Dolphin");
  223. }
  224. [SkippableFact]
  225. public void Should_translate_avg()
  226. {
  227. RequireServer.Check().VersionGreaterThanOrEqualTo("3.1.7");
  228. var result = Project(x => new { Result = x.M.Average() });
  229. result.Projection.Should().Be("{ Result: { \"$avg\": \"$M\" }, _id: 0 }");
  230. result.Value.Result.Should().BeApproximately(3.66666667, .0001);
  231. }
  232. [SkippableFact]
  233. public void Should_translate_avg_with_selector()
  234. {
  235. RequireServer.Check().VersionGreaterThanOrEqualTo("3.1.7");
  236. var result = Project(x => new { Result = x.G.Average(g => g.E.F) });
  237. result.Projection.Should().Be("{ Result: { \"$avg\": \"$G.E.F\" }, _id: 0 }");
  238. result.Value.Result.Should().Be(44);
  239. }
  240. [SkippableFact]
  241. public void Should_translate_boolToString()
  242. {
  243. RequireServer.Check().Supports(Feature.AggregateToString);
  244. var result = Project(x => new { Result = x.K.ToString() });
  245. result.Projection.Should().Be("{ Result: { \"$toString\": \"$K\" }, _id: 0 }");
  246. result.Value.Result.Should().Be("true");
  247. }
  248. [SkippableFact]
  249. public void Should_translate_ceil()
  250. {
  251. RequireServer.Check().VersionGreaterThanOrEqualTo("3.1.6");
  252. var result = Project(x => new { Result = Math.Ceiling(x.U) });
  253. result.Projection.Should().Be("{ Result: { \"$ceil\": \"$U\" }, _id: 0 }");
  254. result.Value.Result.Should().Be(2);
  255. }
  256. [Fact]
  257. public void Should_translate_coalesce()
  258. {
  259. var result = Project(x => new { Result = x.A ?? "funny" });
  260. result.Projection.Should().Be("{ Result: { \"$ifNull\": [\"$A\", \"funny\"] }, _id: 0 }");
  261. result.Value.Result.Should().Be("Awesome");
  262. }
  263. [Fact]
  264. public void Should_translate_compare()
  265. {
  266. var result = Project(x => new { Result = x.A.CompareTo("Awesome") });
  267. result.Projection.Should().Be("{ Result: { \"$cmp\": [\"$A\", \"Awesome\"] }, _id: 0 }");
  268. result.Value.Result.Should().Be(0);
  269. }
  270. [SkippableFact]
  271. public void Should_translate_concat()
  272. {
  273. RequireServer.Check().VersionGreaterThanOrEqualTo("2.4.0");
  274. var result = Project(x => new { Result = x.A + x.B });
  275. result.Projection.Should().Be("{ Result: { \"$concat\": [\"$A\", \"$B\"] }, _id: 0 }");
  276. result.Value.Result.Should().Be("AwesomeBalloon");
  277. }
  278. [SkippableFact]
  279. public void Should_translate_concat_flattened()
  280. {
  281. RequireServer.Check().VersionGreaterThanOrEqualTo("2.4.0");
  282. var result = Project(x => new { Result = x.A + " " + x.B });
  283. result.Projection.Should().Be("{ Result: { \"$concat\": [\"$A\", \" \", \"$B\"] }, _id: 0 }");
  284. result.Value.Result.Should().Be("Awesome Balloon");
  285. }
  286. [SkippableFact]
  287. public void Should_translate_concatArrays()
  288. {
  289. RequireServer.Check().VersionGreaterThanOrEqualTo("3.1.6");
  290. var result = Project(x => new { Result = x.M.Concat(x.L) });
  291. result.Projection.Should().Be("{ Result: { \"$concatArrays\": [\"$M\", \"$L\"] }, _id: 0 }");
  292. result.Value.Result.Should().BeEquivalentTo(2, 4, 5, 1, 3, 5);
  293. }
  294. [Fact]
  295. public void Should_translate_condition()
  296. {
  297. var result = Project(x => new { Result = x.A == "funny" ? "a" : "b" });
  298. result.Projection.Should().Be("{ Result: { \"$cond\": [{ \"$eq\": [\"$A\", \"funny\"] }, \"a\", \"b\"] }, _id: 0 }");
  299. result.Value.Result.Should().Be("b");
  300. }
  301. [SkippableFact]
  302. public void Should_translate_dateTimeToString()
  303. {
  304. RequireServer.Check().Supports(Feature.AggregateToString);
  305. var result = Project(x => new { Result = x.J.ToString() }); // without a format argument
  306. result.Projection.Should().Be("{ Result: { \"$toString\": \"$J\" }, _id: 0 }");
  307. result.Value.Result.Should().Be("2012-12-01T13:14:15.016Z");
  308. }
  309. [SkippableFact]
  310. public void Should_translate_dateToString()
  311. {
  312. RequireServer.Check().VersionGreaterThanOrEqualTo("3.2.0");
  313. var result = Project(x => new { Result = x.J.ToString("%Y-%m-%d") });
  314. result.Projection.Should().Be("{ Result: { \"$dateToString\": {format: \"%Y-%m-%d\", date: \"$J\" } }, _id: 0 }");
  315. result.Value.Result.Should().Be("2012-12-01");
  316. }
  317. [Fact]
  318. public void Should_translate_day_of_month()
  319. {
  320. var result = Project(x => new { Result = x.J.Day });
  321. result.Projection.Should().Be("{ Result: { \"$dayOfMonth\": \"$J\" }, _id: 0 }");
  322. result.Value.Result.Should().Be(1);
  323. }
  324. [Fact]
  325. public void Should_translate_day_of_week()
  326. {
  327. var result = Project(x => new { Result = x.J.DayOfWeek });
  328. result.Projection.Should().Be("{ Result: { \"$subtract\" : [{ \"$dayOfWeek\": \"$J\" }, 1] }, _id: 0 }");
  329. result.Value.Result.Should().Be(DayOfWeek.Saturday);
  330. }
  331. [Fact]
  332. public void Should_translate_day_of_year()
  333. {
  334. var result = Project(x => new { Result = x.J.DayOfYear });
  335. result.Projection.Should().Be("{ Result: { \"$dayOfYear\": \"$J\" }, _id: 0 }");
  336. result.Value.Result.Should().Be(336);
  337. }
  338. [SkippableFact]
  339. public void Should_translate_decimalToString()
  340. {
  341. RequireServer.Check().Supports(Feature.AggregateToString);
  342. var result = Project(x => new { Result = x.Z.ToString() });
  343. result.Projection.Should().Be("{ Result: { \"$toString\": \"$Z\" }, _id: 0 }");
  344. result.Value.Result.Should().Be("11");
  345. }
  346. [Fact]
  347. public void Should_translate_divide()
  348. {
  349. var result = Project(x => new { Result = (double)x.C.E.F / x.C.E.H });
  350. result.Projection.Should().Be("{ Result: { \"$divide\": [\"$C.E.F\", \"$C.E.H\"] }, _id: 0 }");
  351. result.Value.Result.Should().Be(0.5);
  352. }
  353. [Fact]
  354. public void Should_translate_divide_3_numbers()
  355. {
  356. var result = Project(x => new { Result = (double)x.Id / x.C.E.F / x.C.E.H });
  357. result.Projection.Should().Be("{ Result: { \"$divide\": [{ \"$divide\": [\"$_id\", \"$C.E.F\"] }, \"$C.E.H\"] }, _id: 0 }");
  358. result.Value.Result.Should().BeApproximately(0.04, .01);
  359. }
  360. [SkippableFact]
  361. public void Should_translate_doubleToString()
  362. {
  363. RequireServer.Check().Supports(Feature.AggregateToString);
  364. var result = Project(x => new { Result = x.W.ToString() });
  365. result.Projection.Should().Be("{ Result: { \"$toString\": \"$W\" }, _id: 0 }");
  366. result.Value.Result.Should().Be("8");
  367. }
  368. [Fact]
  369. public void Should_translate_equals()
  370. {
  371. var result = Project(x => new { Result = x.C.E.F == 5 });
  372. result.Projection.Should().Be("{ Result: { \"$eq\": [\"$C.E.F\", 5] }, _id: 0 }");
  373. result.Value.Result.Should().BeFalse();
  374. }
  375. [Fact]
  376. public void Should_translate_equals_as_a_method_call()
  377. {
  378. var result = Project(x => new { Result = x.C.E.F.Equals(5) });
  379. result.Projection.Should().Be("{ Result: { \"$eq\": [\"$C.E.F\", 5] }, _id: 0 }");
  380. result.Value.Result.Should().BeFalse();
  381. }
  382. [SkippableFact]
  383. public void Should_translate_exp()
  384. {
  385. RequireServer.Check().VersionGreaterThanOrEqualTo("3.1.6");
  386. var result = Project(x => new { Result = Math.Exp(x.C.E.F) });
  387. result.Projection.Should().Be("{ Result: { \"$exp\": [\"$C.E.F\"] }, _id: 0 }");
  388. result.Value.Result.Should().BeApproximately(59874.1417151978, .0001);
  389. }
  390. [SkippableFact]
  391. public void Should_translate_floor()
  392. {
  393. RequireServer.Check().VersionGreaterThanOrEqualTo("3.1.6");
  394. var result = Project(x => new { Result = Math.Floor(x.U) });
  395. result.Projection.Should().Be("{ Result: { \"$floor\": \"$U\" }, _id: 0 }");
  396. result.Value.Result.Should().Be(1);
  397. }
  398. [Fact]
  399. public void Should_translate_greater_than()
  400. {
  401. var result = Project(x => new { Result = x.C.E.F > 5 });
  402. result.Projection.Should().Be("{ Result: { \"$gt\": [\"$C.E.F\", 5] }, _id: 0 }");
  403. result.Value.Result.Should().BeTrue();
  404. }
  405. [Fact]
  406. public void Should_translate_greater_than_or_equal()
  407. {
  408. var result = Project(x => new { Result = x.C.E.F >= 5 });
  409. result.Projection.Should().Be("{ Result: { \"$gte\": [\"$C.E.F\", 5] }, _id: 0 }");
  410. result.Value.Result.Should().BeTrue();
  411. }
  412. [Fact]
  413. public void Should_translate_hour()
  414. {
  415. var result = Project(x => new { Result = x.J.Hour });
  416. result.Projection.Should().Be("{ Result: { \"$hour\": \"$J\" }, _id: 0 }");
  417. result.Value.Result.Should().Be(13);
  418. }
  419. [SkippableFact]
  420. public void Should_translate_indexOfBytes()
  421. {
  422. RequireServer.Check().VersionGreaterThanOrEqualTo("3.3.6");
  423. var result = Project(x => new { Result = x.A.IndexOf('e') });
  424. result.Projection.Should().Be("{ Result: { \"$indexOfBytes\": [\"$A\", \"e\"] }, _id: 0 }");
  425. result.Value.Result.Should().Be(2);
  426. result = Project(x => new { Result = x.A.IndexOf("e") });
  427. result.Projection.Should().Be("{ Result: { \"$indexOfBytes\": [\"$A\", \"e\"] }, _id: 0 }");
  428. result.Value.Result.Should().Be(2);
  429. result = Project(x => new { Result = x.A.IndexOf('e', 4) });
  430. result.Projection.Should().Be("{ Result: { \"$indexOfBytes\": [\"$A\", \"e\", 4] }, _id: 0 }");
  431. result.Value.Result.Should().Be(6);
  432. result = Project(x => new { Result = x.A.IndexOf("e", 4) });
  433. result.Projection.Should().Be("{ Result: { \"$indexOfBytes\": [\"$A\", \"e\", 4] }, _id: 0 }");
  434. result.Value.Result.Should().Be(6);
  435. result = Project(x => new { Result = x.A.IndexOf('e', 4, 2) });
  436. result.Projection.Should().Be("{ Result: { \"$indexOfBytes\": [\"$A\", \"e\", 4, { $add: [4, 2] }] }, _id: 0 }");
  437. result.Value.Result.Should().Be(-1);
  438. result = Project(x => new { Result = x.A.IndexOf("e", 4, 2) });
  439. result.Projection.Should().Be("{ Result: { \"$indexOfBytes\": [\"$A\", \"e\", 4, { $add: [4, 2] }] }, _id: 0 }");
  440. result.Value.Result.Should().Be(-1);
  441. }
  442. [SkippableFact]
  443. public void Should_translate_indexOfCP()
  444. {
  445. RequireServer.Check().VersionGreaterThanOrEqualTo("3.3.6");
  446. var result = Project(x => new { Result = x.A.IndexOf('e') }, __codePointTranslationOptions);
  447. result.Projection.Should().Be("{ Result: { \"$indexOfCP\": [\"$A\", \"e\"] }, _id: 0 }");
  448. result.Value.Result.Should().Be(2);
  449. result = Project(x => new { Result = x.A.IndexOf("e") }, __codePointTranslationOptions);
  450. result.Projection.Should().Be("{ Result: { \"$indexOfCP\": [\"$A\", \"e\"] }, _id: 0 }");
  451. result.Value.Result.Should().Be(2);
  452. result = Project(x => new { Result = x.A.IndexOf('e', 4) }, __codePointTranslationOptions);
  453. result.Projection.Should().Be("{ Result: { \"$indexOfCP\": [\"$A\", \"e\", 4] }, _id: 0 }");
  454. result.Value.Result.Should().Be(6);
  455. result = Project(x => new { Result = x.A.IndexOf("e", 4) }, __codePointTranslationOptions);
  456. result.Projection.Should().Be("{ Result: { \"$indexOfCP\": [\"$A\", \"e\", 4] }, _id: 0 }");
  457. result.Value.Result.Should().Be(6);
  458. result = Project(x => new { Result = x.A.IndexOf('e', 4, 2) }, __codePointTranslationOptions);
  459. result.Projection.Should().Be("{ Result: { \"$indexOfCP\": [\"$A\", \"e\", 4, { $add: [4, 2] }] }, _id: 0 }");
  460. result.Value.Result.Should().Be(-1);
  461. result = Project(x => new { Result = x.A.IndexOf("e", 4, 2) }, __codePointTranslationOptions);
  462. result.Projection.Should().Be("{ Result: { \"$indexOfCP\": [\"$A\", \"e\", 4, { $add: [4, 2] }] }, _id: 0 }");
  463. result.Value.Result.Should().Be(-1);
  464. }
  465. [SkippableFact]
  466. public void Should_translate_intToString()
  467. {
  468. RequireServer.Check().Supports(Feature.AggregateToString);
  469. var result = Project(x => new { Result = x.Y.ToString() });
  470. result.Projection.Should().Be("{ Result: { \"$toString\": \"$Y\" }, _id: 0 }");
  471. result.Value.Result.Should().Be("10");
  472. }
  473. [Fact]
  474. public void Should_translate_less_than()
  475. {
  476. var result = Project(x => new { Result = x.C.E.F < 5 });
  477. result.Projection.Should().Be("{ Result: { \"$lt\": [\"$C.E.F\", 5] }, _id: 0 }");
  478. result.Value.Result.Should().BeFalse();
  479. }
  480. [Fact]
  481. public void Should_translate_less_than_or_equal()
  482. {
  483. var result = Project(x => new { Result = x.C.E.F <= 5 });
  484. result.Projection.Should().Be("{ Result: { \"$lte\": [\"$C.E.F\", 5] }, _id: 0 }");
  485. result.Value.Result.Should().BeFalse();
  486. }
  487. [SkippableFact]
  488. public void Should_translate_literal_when_a_constant_strings_begins_with_a_dollar()
  489. {
  490. RequireServer.Check().VersionGreaterThanOrEqualTo("2.6.0");
  491. var result = Project(x => new { Result = x.A == "$1" });
  492. result.Projection.Should().Be("{ Result: { \"$eq\": [\"$A\", { \"$literal\": \"$1\" }] }, _id: 0 }");
  493. result.Value.Result.Should().BeFalse();
  494. }
  495. [SkippableFact]
  496. public void Should_translate_ln()
  497. {
  498. RequireServer.Check().VersionGreaterThanOrEqualTo("3.1.6");
  499. var result = Project(x => new { Result = Math.Log(x.C.E.F) });
  500. result.Projection.Should().Be("{ Result: { \"$ln\": [\"$C.E.F\"] }, _id: 0 }");
  501. result.Value.Result.Should().BeApproximately(2.39789527279837, .0001);
  502. }
  503. [SkippableFact]
  504. public void Should_translate_log()
  505. {
  506. RequireServer.Check().VersionGreaterThanOrEqualTo("3.1.6");
  507. var result = Project(x => new { Result = Math.Log(x.C.E.F, 11) });
  508. result.Projection.Should().Be("{ Result: { \"$log\": [\"$C.E.F\", 11.0] }, _id: 0 }");
  509. result.Value.Result.Should().Be(1);
  510. }
  511. [SkippableFact]
  512. public void Should_translate_log10()
  513. {
  514. RequireServer.Check().VersionGreaterThanOrEqualTo("3.1.6");
  515. var result = Project(x => new { Result = Math.Log10(x.C.E.F) });
  516. result.Projection.Should().Be("{ Result: { \"$log10\": [\"$C.E.F\"] }, _id: 0 }");
  517. result.Value.Result.Should().BeApproximately(1.0413928515823, .0001);
  518. }
  519. [SkippableFact]
  520. public void Should_translate_longToString()
  521. {
  522. RequireServer.Check().Supports(Feature.AggregateToString);
  523. var result = Project(x => new { Result = x.X.ToString() });
  524. result.Projection.Should().Be("{ Result: { \"$toString\": \"$X\" }, _id: 0 }");
  525. result.Value.Result.Should().Be("9");
  526. }
  527. [SkippableFact]
  528. public void Should_translate_map_with_document()
  529. {
  530. RequireServer.Check().VersionGreaterThanOrEqualTo("2.6.0");
  531. var result = Project(x => new { Result = x.G.Select(g => g.D + "0") });
  532. result.Projection.Should().Be("{ Result: { \"$map\": { input: \"$G\", as: \"g\", in: { \"$concat\": [\"$$g.D\", \"0\"] } } }, _id: 0 }");
  533. result.Value.Result.Should().Equal("Don't0", "Dolphin0");
  534. }
  535. [SkippableFact]
  536. public void Should_translate_map_with_value()
  537. {
  538. RequireServer.Check().VersionGreaterThanOrEqualTo("2.6.0");
  539. var result = Project(x => new { Result = x.C.E.I.Select(i => i + "0") });
  540. result.Projection.Should().Be("{ Result: { \"$map\": { input: \"$C.E.I\", as: \"i\", in: { \"$concat\": [\"$$i\", \"0\"] } } }, _id: 0 }");
  541. result.Value.Result.Should().Equal("it0", "icky0");
  542. }
  543. [SkippableFact]
  544. public void Should_translate_max()
  545. {
  546. RequireServer.Check().VersionGreaterThanOrEqualTo("3.1.7");
  547. var result = Project(x => new { Result = x.M.Max() });
  548. result.Projection.Should().Be("{ Result: { \"$max\": \"$M\" }, _id: 0 }");
  549. result.Value.Result.Should().Be(5);
  550. }
  551. [SkippableFact]
  552. public void Should_translate_max_with_selector()
  553. {
  554. RequireServer.Check().VersionGreaterThanOrEqualTo("3.1.7");
  555. var result = Project(x => new { Result = x.G.Max(g => g.E.F) });
  556. result.Projection.Should().Be("{ Result: { \"$max\": \"$G.E.F\" }, _id: 0 }");
  557. result.Value.Result.Should().Be(55);
  558. }
  559. [SkippableFact]
  560. public void Should_translate_millisecond()
  561. {
  562. RequireServer.Check().VersionGreaterThanOrEqualTo("2.4.0");
  563. var result = Project(x => new { Result = x.J.Millisecond });
  564. result.Projection.Should().Be("{ Result: { \"$millisecond\": \"$J\" }, _id: 0 }");
  565. result.Value.Result.Should().Be(16);
  566. }
  567. [SkippableFact]
  568. public void Should_translate_min()
  569. {
  570. RequireServer.Check().VersionGreaterThanOrEqualTo("3.1.7");
  571. var result = Project(x => new { Result = x.M.Min() });
  572. result.Projection.Should().Be("{ Result: { \"$min\": \"$M\" }, _id: 0 }");
  573. result.Value.Result.Should().Be(2);
  574. }
  575. [SkippableFact]
  576. public void Should_translate_min_with_selector()
  577. {
  578. RequireServer.Check().VersionGreaterThanOrEqualTo("3.1.7");
  579. var result = Project(x => new { Result = x.G.Min(g => g.E.F) });
  580. result.Projection.Should().Be("{ Result: { \"$min\": \"$G.E.F\" }, _id: 0 }");
  581. result.Value.Result.Should().Be(33);
  582. }
  583. [Fact]
  584. public void Should_translate_minute()
  585. {
  586. var result = Project(x => new { Result = x.J.Minute });
  587. result.Projection.Should().Be("{ Result: { \"$minute\": \"$J\" }, _id: 0 }");
  588. result.Value.Result.Should().Be(14);
  589. }
  590. [Fact]
  591. public void Should_translate_modulo()
  592. {
  593. var result = Project(x => new { Result = x.C.E.F % 5 });
  594. result.Projection.Should().Be("{ Result: { \"$mod\": [\"$C.E.F\", 5] }, _id: 0 }");
  595. result.Value.Result.Should().Be(1);
  596. }
  597. [Fact]
  598. public void Should_translate_month()
  599. {
  600. var result = Project(x => new { Result = x.J.Month });
  601. result.Projection.Should().Be("{ Result: { \"$month\": \"$J\" }, _id: 0 }");
  602. result.Value.Result.Should().Be(12);
  603. }
  604. [Fact]
  605. public void Should_translate_multiply()
  606. {
  607. var result = Project(x => new { Result = x.C.E.F * x.C.E.H });
  608. result.Projection.Should().Be("{ Result: { \"$multiply\": [\"$C.E.F\", \"$C.E.H\"] }, _id: 0 }");
  609. result.Value.Result.Should().Be(242);
  610. }
  611. [Fact]
  612. public void Should_translate_multiply_flattened()
  613. {
  614. var result = Project(x => new { Result = x.Id * x.C.E.F * x.C.E.H });
  615. result.Projection.Should().Be("{ Result: { \"$multiply\": [\"$_id\", \"$C.E.F\", \"$C.E.H\"] }, _id: 0 }");
  616. result.Value.Result.Should().Be(2420);
  617. }
  618. [SkippableFact]
  619. public void Should_translate_new_DateTime()
  620. {
  621. RequireServer.Check().VersionGreaterThanOrEqualTo("3.6.0-rc0");
  622. var result = Project(x => new { Result = new DateTime(x.Id, 11, 12) });
  623. result.Projection.Should().Be("{ Result: { \"$dateFromParts\": { \"year\": \"$_id\", \"month\": 11, \"day\": 12 } }, _id: 0 }");
  624. result.Value.Result.Should().Be(new DateTime(10, 11, 12));
  625. result = Project(x => new { Result = new DateTime(x.Id, 11, 12, 1, 2, 3) });
  626. result.Projection.Should().Be("{ Result: { \"$dateFromParts\": { \"year\": \"$_id\", \"month\": 11, \"day\": 12, \"hour\": 1, \"minute\": 2, \"second\": 3 } }, _id: 0 }");
  627. result.Value.Result.Should().Be(new DateTime(10, 11, 12, 1, 2, 3));
  628. result = Project(x => new { Result = new DateTime(x.Id, 11, 12, 1, 2, 3, 4) });
  629. result.Projection.Should().Be("{ Result: { \"$dateFromParts\": { \"year\": \"$_id\", \"month\": 11, \"day\": 12, \"hour\": 1, \"minute\": 2, \"second\": 3, \"millisecond\": 4 } }, _id: 0 }");
  630. result.Value.Result.Should().Be(new DateTime(10, 11, 12, 1, 2, 3, 4));
  631. }
  632. [Fact]
  633. public void Should_translate_not()
  634. {
  635. var result = Project(x => new { Result = !x.K });
  636. result.Projection.Should().Be("{ Result: { \"$not\": [\"$K\"] }, _id: 0 }");
  637. result.Value.Result.Should().BeFalse();
  638. }
  639. [Fact]
  640. public void Should_translate_not_with_comparison()
  641. {
  642. var result = Project(x => new { Result = !(x.C.E.F < 3) });
  643. result.Projection.Should().Be("{ Result: { \"$not\": [{ \"$lt\": [\"$C.E.F\", 3] }] }, _id: 0 }");
  644. result.Value.Result.Should().BeTrue();
  645. }
  646. [Fact]
  647. public void Should_translate_not_equals()
  648. {
  649. var result = Project(x => new { Result = x.C.E.F != 5 });
  650. result.Projection.Should().Be("{ Result: { \"$ne\": [\"$C.E.F\", 5] }, _id: 0 }");
  651. result.Value.Result.Should().BeTrue();
  652. }
  653. [SkippableFact]
  654. public void Should_translate_objectIdToString()
  655. {
  656. RequireServer.Check().Supports(Feature.AggregateToString);
  657. var result = Project(x => new { Result = x.ObjectId.ToString() });
  658. result.Projection.Should().Be("{ Result: { \"$toString\": \"$ObjectId\" }, _id: 0 }");
  659. result.Value.Result.Should().Be("555925bfb69aa7d5be29126b");
  660. }
  661. [Fact]
  662. public void Should_translate_or()
  663. {
  664. var result = Project(x => new { Result = x.A == "yes" || x.B == "no" });
  665. result.Projection.Should().Be("{ Result: { \"$or\": [{ \"$eq\": [\"$A\", \"yes\"] }, { \"$eq\": [\"$B\", \"no\"] }] }, _id: 0 }");
  666. result.Value.Result.Should().BeFalse();
  667. }
  668. [Fact]
  669. public void Should_translate_or_flattened()
  670. {
  671. var result = Project(x => new { Result = x.A == "yes" || x.B == "no" || x.C.D == "maybe" });
  672. result.Projection.Should().Be("{ Result: { \"$or\": [{ \"$eq\": [\"$A\", \"yes\"] }, { \"$eq\": [\"$B\", \"no\"] }, { \"$eq\" : [\"$C.D\", \"maybe\"] } ] }, _id: 0 }");
  673. result.Value.Result.Should().BeFalse();
  674. }
  675. [SkippableFact]
  676. public void Should_translate_DateTime_parse()
  677. {
  678. RequireServer.Check().VersionGreaterThanOrEqualTo("3.6.0-rc0");
  679. var result = Project(x => new { Result = DateTime.Parse(x.V) });
  680. result.Projection.Should().Be("{ Result: { \"$dateFromString\": { \"dateString\": \"$V\" } }, _id: 0 }");
  681. result.Value.Result.Should().Be(new DateTime(2017, 2, 8, 12, 10, 40, 787, DateTimeKind.Utc));
  682. }
  683. [SkippableFact]
  684. public void Should_translate_pow()
  685. {
  686. RequireServer.Check().VersionGreaterThanOrEqualTo("3.1.6");
  687. var result = Project(x => new { Result = Math.Pow(x.C.E.F, 5) });
  688. result.Projection.Should().Be("{ Result: { \"$pow\": [\"$C.E.F\", 5.0] }, _id: 0 }");
  689. result.Value.Result.Should().Be(161051);
  690. }
  691. [SkippableFact]
  692. public void Should_translate_range()
  693. {
  694. RequireServer.Check().VersionGreaterThanOrEqualTo("3.3.4");
  695. var result = Project(x => new { Result = Enumerable.Range(x.C.E.F, 3) });
  696. result.Projection.Should().Be("{ Result: { \"$range\": [\"$C.E.F\", { \"$add\": [\"$C.E.F\", 3] } ] }, _id: 0 }");
  697. result.Value.Result.Should().BeEquivalentTo(11, 12, 13);
  698. }
  699. [SkippableFact]
  700. public void Should_translate_reduce()
  701. {
  702. RequireServer.Check().VersionGreaterThanOrEqualTo("3.3.5");
  703. var result = Project(x => new { Result = x.M.Aggregate((a, b) => a + b) });
  704. result.Projection.Should().Be("{ Result: { $reduce: { input: \"$M\", initialValue: 0, in: { $add: [\"$$value\", \"$$this\"] } } }, _id: 0 }");
  705. result.Value.Result.Should().Be(11);
  706. var arrayResult = Project(x => new { Result = x.M.Aggregate(new int[] { 0, 0 }, (a, b) => new int[] { a[0] + a[1], b }) });
  707. arrayResult.Projection.Should().Be("{ Result: { $reduce: { input: \"$M\", initialValue: [0,0], in: [{ $add: [{$arrayElemAt: [\"$$value\", 0]}, {$arrayElemAt: [\"$$value\", 1]}]},\"$$this\"]}}, _id: 0}");
  708. arrayResult.Value.Result.Should().BeEquivalentTo(6, 5);
  709. var arrayResultWithSelector = Project(x => new { Result = x.M.Aggregate(new int[] { 0, 0 }, (a, b) => new int[] { a[0] + a[1], b }, r => new { x = r[0], y = r[1] }) });
  710. arrayResultWithSelector.Projection.Should().Be("{ Result: { $let: { vars: { r: { $reduce: { input: \"$M\", initialValue: [0,0], in: [{ $add: [{$arrayElemAt: [\"$$value\", 0]}, {$arrayElemAt: [\"$$value\", 1]}]},\"$$this\"]}}}, in: { x: { $arrayElemAt: [\"$$r\", 0] }, y: { $arrayElemAt: [\"$$r\", 1] } } } }, _id: 0}");
  711. arrayResultWithSelector.Value.Result.x.Should().Be(6);
  712. arrayResultWithSelector.Value.Result.y.Should().Be(5);
  713. var typeResult = Project(x => new { Result = x.M.Aggregate(new { x = 0, y = 0 }, (a, b) => new { x = a.x + a.y, y = b }) });
  714. typeResult.Projection.Should().Be("{ Result: { $reduce: { input: \"$M\", initialValue: {x: 0, y: 0}, in: { x: { $add: [\"$$value.x\", \"$$value.y\"]}, y: \"$$this\"}}}, _id: 0}");
  715. typeResult.Value.Result.x.Should().Be(6);
  716. typeResult.Value.Result.y.Should().Be(5);
  717. }
  718. [SkippableFact]
  719. public void Should_translate_reverse()
  720. {
  721. RequireServer.Check().VersionGreaterThanOrEqualTo("3.3.4");
  722. var result = Project(x => new { Result = x.M.Reverse() });
  723. result.Projection.Should().Be("{ Result: { \"$reverseArray\": \"$M\" }, _id: 0 }");
  724. result.Value.Result.Should().BeEquivalentTo(5, 4, 2);
  725. }
  726. [Fact]
  727. public void Should_translate_second()
  728. {
  729. var result = Project(x => new { Result = x.J.Second });
  730. result.Projection.Should().Be("{ Result: { \"$second\": \"$J\" }, _id: 0 }");
  731. result.Value.Result.Should().Be(15);
  732. }
  733. [SkippableFact]
  734. public void Should_translate_size_greater_than_zero_from_any()
  735. {
  736. RequireServer.Check().VersionGreaterThanOrEqualTo("2.6.0");
  737. var result = Project(x => new { Result = x.M.Any() });
  738. result.Projection.Should().Be("{ Result: { \"$gt\": [{ \"$size\": \"$M\" }, 0] }, _id: 0 }");
  739. result.Value.Result.Should().BeTrue();
  740. }
  741. [SkippableFact]
  742. public void Should_translate_size_from_an_array()
  743. {
  744. RequireServer.Check().VersionGreaterThanOrEqualTo("2.6.0");
  745. var result = Project(x => new { Result = x.M.Length });
  746. result.Projection.Should().Be("{ Result: { \"$size\": \"$M\" }, _id: 0 }");
  747. result.Value.Result.Should().Be(3);
  748. }
  749. [SkippableFact]
  750. public void Should_translate_size_from_Count_extension_method()
  751. {
  752. RequireServer.Check().VersionGreaterThanOrEqualTo("2.6.0");
  753. var result = Project(x => new { Result = x.M.Count() });
  754. result.Projection.Should().Be("{ Result: { \"$size\": \"$M\" }, _id: 0 }");
  755. result.Value.Result.Should().Be(3);
  756. }
  757. [SkippableFact]
  758. public void Should_translate_size_from_LongCount_extension_method()
  759. {
  760. RequireServer.Check().VersionGreaterThanOrEqualTo("2.6.0");
  761. var result = Project(x => new { Result = x.M.LongCount() });
  762. result.Projection.Should().Be("{ Result: { \"$size\": \"$M\" }, _id: 0 }");
  763. result.Value.Result.Should().Be(3);
  764. }
  765. [SkippableFact]
  766. public void Should_translate_size_from_Count_property_on_Generic_ICollection()
  767. {
  768. RequireServer.Check().VersionGreaterThanOrEqualTo("2.6.0");
  769. var result = Project(x => new { Result = x.L.Count });
  770. result.Projection.Should().Be("{ Result: { \"$size\": \"$L\" }, _id: 0 }");
  771. result.Value.Result.Should().Be(3);
  772. }
  773. [SkippableFact]
  774. public void Should_translate_set_difference()
  775. {
  776. RequireServer.Check().VersionGreaterThanOrEqualTo("2.6.0");
  777. var result = Project(x => new { Result = x.C.E.I.Except(new[] { "it", "not in here" }) });
  778. result.Projection.Should().Be("{ Result: { \"$setDifference\": [\"$C.E.I\", [\"it\", \"not in here\"] ] }, _id: 0 }");
  779. result.Value.Result.Should().Equal("icky");
  780. }
  781. [SkippableFact]
  782. public void Should_translate_set_difference_reversed()
  783. {
  784. RequireServer.Check().VersionGreaterThanOrEqualTo("2.6.0");
  785. var result = Project(x => new { Result = new[] { "it", "not in here" }.Except(x.C.E.I) });
  786. result.Projection.Should().Be("{ Result: { \"$setDifference\": [[\"it\", \"not in here\"], \"$C.E.I\"] }, _id: 0 }");
  787. result.Value.Result.Should().Equal("not in here");
  788. }
  789. [SkippableFact]
  790. public void Should_translate_set_equals()
  791. {
  792. RequireServer.Check().VersionGreaterThanOrEqualTo("2.6.0");
  793. var result = Project(x => new { Result = x.L.SetEquals(new[] { 1, 3, 5 }) });
  794. result.Projection.Should().Be("{ Result: { \"$setEquals\": [\"$L\", [1, 3, 5]] }, _id: 0 }");
  795. result.Value.Result.Should().BeTrue();
  796. }
  797. [SkippableFact]
  798. public void Should_translate_set_equals_reversed()
  799. {
  800. RequireServer.Check().VersionGreaterThanOrEqualTo("2.6.0");
  801. var set = new HashSet<int>(new[] { 1, 3, 5 });
  802. var result = Project(x => new { Result = set.SetEquals(x.L) });
  803. result.Projection.Should().Be("{ Result: { \"$setEquals\": [[1, 3, 5], \"$L\"] }, _id: 0 }");
  804. result.Value.Result.Should().BeTrue();
  805. }
  806. [SkippableFact]
  807. public void Should_translate_set_intersection()
  808. {
  809. RequireServer.Check().VersionGreaterThanOrEqualTo("2.6.0");
  810. var result = Project(x => new { Result = x.C.E.I.Intersect(new[] { "it", "not in here" }) });
  811. result.Projection.Should().Be("{ Result: { \"$setIntersection\": [\"$C.E.I\", [\"it\", \"not in here\"] ] }, _id: 0 }");
  812. result.Value.Result.Should().Equal("it");
  813. }
  814. [SkippableFact]
  815. public void Should_translate_set_intersection_reversed()
  816. {
  817. RequireServer.Check().VersionGreaterThanOrEqualTo("2.6.0");
  818. var result = Project(x => new { Result = new[] { "it", "not in here" }.Intersect(x.C.E.I) });
  819. result.Projection.Should().Be("{ Result: { \"$setIntersection\": [[\"it\", \"not in here\"], \"$C.E.I\"] }, _id: 0 }");
  820. result.Value.Result.Should().Equal("it");
  821. }
  822. [SkippableFact]
  823. public void Should_translate_set_is_subset()
  824. {
  825. RequireServer.Check().VersionGreaterThanOrEqualTo("2.6.0");
  826. var result = Project(x => new { Result = x.L.IsSubsetOf(new[] { 1, 3, 5 }) });
  827. result.Projection.Should().Be("{ Result: { \"$setIsSubset\": [\"$L\", [1, 3, 5]] }, _id: 0 }");
  828. result.Value.Result.Should().BeTrue();
  829. }
  830. [SkippableFact]
  831. public void Should_translate_set_is_subset_reversed()
  832. {
  833. RequireServer.Check().VersionGreaterThanOrEqualTo("2.6.0");
  834. var set = new HashSet<int>(new[] { 1, 3, 5 });
  835. var result = Project(x => new { Result = set.IsSubsetOf(x.L) });
  836. result.Projection.Should().Be("{ Result: { \"$setIsSubset\": [[1, 3, 5], \"$L\"] }, _id: 0 }");
  837. result.Value.Result.Should().BeTrue();
  838. }
  839. [SkippableFact]
  840. public void Should_translate_set_union()
  841. {
  842. RequireServer.Check().VersionGreaterThanOrEqualTo("2.6.0");
  843. var result = Project(x => new { Result = x.C.E.I.Union(new[] { "it", "not in here" }) });
  844. result.Projection.Should().Be("{ Result: { \"$setUnion\": [\"$C.E.I\", [\"it\", \"not in here\"] ] }, _id: 0 }");
  845. result.Value.Result.Should().BeEquivalentTo("it", "icky", "not in here");
  846. }
  847. [SkippableFact]
  848. public void Should_translate_set_union_reversed()
  849. {
  850. RequireServer.Check().VersionGreaterThanOrEqualTo("2.6.0");
  851. var result = Project(x => new { Result = new[] { "it", "not in here" }.Union(x.C.E.I) });
  852. result.Projection.Should().Be("{ Result: { \"$setUnion\": [[\"it\", \"not in here\"], \"$C.E.I\"] }, _id: 0 }");
  853. result.Value.Result.Should().BeEquivalentTo("it", "icky", "not in here");
  854. }
  855. [SkippableFact]
  856. public void Should_translate_sqrt()
  857. {
  858. RequireServer.Check().VersionGreaterThanOrEqualTo("3.1.6");
  859. var result = Project(x => new { Result = Math.Sqrt(x.C.E.F) });
  860. result.Projection.Should().Be("{ Result: { \"$sqrt\": [\"$C.E.F\"] }, _id: 0 }");
  861. result.Value.Result.Should().BeApproximately(3.31662479, .0001);
  862. }
  863. [SkippableFact]
  864. public void Should_translate_stringToString()
  865. {
  866. RequireServer.Check().Supports(Feature.AggregateToString);
  867. var result = Project(x => new { Result = x.A.ToString() });
  868. result.Projection.Should().Be("{ Result: { \"$toString\": \"$A\" }, _id: 0 }");
  869. result.Value.Result.Should().Be("Awesome");
  870. }
  871. [SkippableFact]
  872. public void Should_translate_trunc()
  873. {
  874. RequireServer.Check().VersionGreaterThanOrEqualTo("3.1.6");
  875. var result = Project(x => new { Result = Math.Truncate(x.U) });
  876. result.Projection.Should().Be("{ Result: { \"$trunc\": \"$U\" }, _id: 0 }");
  877. result.Value.Result.Should().Be(1);
  878. }
  879. [SkippableFact]
  880. public void Should_translate_where_to_filter()
  881. {
  882. RequireServer.Check().VersionGreaterThanOrEqualTo("3.1.3");
  883. var result = Project(x => new { Result = x.G.Where(c => c.E.F == 33) });
  884. result.Projection.Should().Be("{ Result: { \"$filter\": { \"input\": \"$G\", \"as\": \"c\", \"cond\": { \"$eq\": [\"$$c.E.F\", 33] } } }, _id: 0 }");
  885. result.Value.Result.Should().HaveCount(1);
  886. result.Value.Result.Single().D.Should().Be("Don't");
  887. }
  888. [SkippableFact]
  889. public void Should_translate_where_then_select_to_filter_then_map()
  890. {
  891. RequireServer.Check().VersionGreaterThanOrEqualTo("3.1.3");
  892. var result = Project(x => new { Result = x.G.Where(c => c.E.F == 33).Select(c => c.D) });
  893. result.Projection.Should().Be("{ Result: { \"$map\": { \"input\": { \"$filter\": { \"input\": \"$G\", \"as\": \"c\", \"cond\": { \"$eq\": [\"$$c.E.F\", 33] } } }, \"as\": \"c\", \"in\": \"$$c.D\" } }, _id: 0 }");
  894. result.Value.Result.Should().HaveCount(1);
  895. result.Value.Result.Single().Should().Be("Don't");
  896. }
  897. [SkippableFact]
  898. public void Should_translate_select_then_where_to_map_then_filter()
  899. {
  900. RequireServer.Check().VersionGreaterThanOrEqualTo("3.1.3");
  901. var result = Project(x => new { Result = x.G.Select(c => c.D).Where(c => c == "Don't") });
  902. result.Projection.Should().Be("{ Result: { \"$filter\": { \"input\": \"$G.D\", \"as\": \"c\", \"cond\": { \"$eq\": [\"$$c\", \"Don't\"] } } }, _id: 0 }");
  903. result.Value.Result.Should().HaveCount(1);
  904. result.Value.Result.Single().Should().Be("Don't");
  905. }
  906. [SkippableFact]
  907. public void Should_translate_select_with_an_anonymous_type_then_where_to_map_then_filter()
  908. {
  909. RequireServer.Check().VersionGreaterThanOrEqualTo("3.1.3");
  910. var result = Project(x => new { Result = x.G.Select(c => new { c.D, c.E.F }).Where(c => c.F == 33) });
  911. result.Projection.Should().Be("{ Result: { \"$filter\": { \"input\": { \"$map\" : { \"input\": \"$G\", \"as\": \"c\", \"in\": { \"D\": \"$$c.D\", \"F\": \"$$c.E.F\" } } }, \"as\": \"c\", \"cond\": { \"$eq\": [\"$$c.F\", 33] } } }, _id: 0 }");
  912. result.Value.Result.Should().HaveCount(1);
  913. result.Value.Result.Single().D.Should().Be("Don't");
  914. result.Value.Result.Single().F.Should().Be(33);
  915. }
  916. [SkippableFact]
  917. public void Should_translate_strLenBytes()
  918. {
  919. RequireServer.Check().VersionGreaterThanOrEqualTo("3.3.4");
  920. var result = Project(x => new { Result = x.A.Length });
  921. result.Projection.Should().Be("{ Result: { \"$strLenBytes\": \"$A\" }, _id: 0 }");
  922. result.Value.Result.Should().Be(7);
  923. }
  924. [SkippableFact]
  925. public void Should_translate_strLenCP()
  926. {
  927. RequireServer.Check().VersionGreaterThanOrEqualTo("3.3.4");
  928. var result = Project(

Large files files are truncated, but you can click here to view the full file