PageRenderTime 26ms CodeModel.GetById 11ms RepoModel.GetById 1ms app.codeStats 0ms

/src/MongoDB.Driver.Tests/UpdateDefinitionBuilderTests.cs

http://github.com/mongodb/mongo-csharp-driver
C# | 577 lines | 440 code | 123 blank | 14 comment | 9 complexity | 8d20d4311cefba397796becdfe376491 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 FluentAssertions;
  19. using MongoDB.Bson;
  20. using MongoDB.Bson.Serialization;
  21. using MongoDB.Bson.Serialization.Attributes;
  22. using NUnit.Framework;
  23. namespace MongoDB.Driver.Tests
  24. {
  25. [TestFixture]
  26. public class UpdateDefinitionBuilderTests
  27. {
  28. [Test]
  29. public void AddToSet()
  30. {
  31. var subject = CreateSubject<BsonDocument>();
  32. Assert(subject.AddToSet("a", 1), "{$addToSet: {a: 1}}");
  33. Assert(subject.AddToSet("a", new[] { 1, 2 }), "{$addToSet: {a: [1, 2]}}");
  34. }
  35. [Test]
  36. public void AddToSet_Typed()
  37. {
  38. var subject = CreateSubject<Person>();
  39. Assert(subject.AddToSet(x => x.FavoriteColors, "green"), "{$addToSet: {colors: 'green'}}");
  40. Assert(subject.AddToSet("FavoriteColors", "green"), "{$addToSet: {colors: 'green'}}");
  41. }
  42. [Test]
  43. public void AddToSetEach()
  44. {
  45. var subject = CreateSubject<BsonDocument>();
  46. Assert(subject.AddToSetEach("a", new[] { 1, 2 }), "{$addToSet: {a: {$each: [1, 2]}}}");
  47. Assert(subject.AddToSetEach("a", new[] { new[] { 1, 2 }, new[] { 3, 4 } }), "{$addToSet: {a: {$each: [[1, 2], [3, 4]]}}}");
  48. }
  49. [Test]
  50. public void AddToSetEach_Typed()
  51. {
  52. var subject = CreateSubject<Person>();
  53. Assert(subject.AddToSetEach(x => x.FavoriteColors, new[] { "green", "violet" }), "{$addToSet: {colors: {$each: ['green', 'violet']}}}");
  54. Assert(subject.AddToSetEach("FavoriteColors", new[] { "green", "violet" }), "{$addToSet: {colors: {$each: ['green', 'violet']}}}");
  55. }
  56. [Test]
  57. public void BitwiseAnd()
  58. {
  59. var subject = CreateSubject<BsonDocument>();
  60. Assert(subject.BitwiseAnd("a", 1), "{$bit: {a: {and: 1}}}");
  61. }
  62. [Test]
  63. public void BitwiseAnd_Typed()
  64. {
  65. var subject = CreateSubject<Person>();
  66. Assert(subject.BitwiseAnd(x => x.Age, 1), "{$bit: {age: {and: 1}}}");
  67. Assert(subject.BitwiseAnd("Age", 1), "{$bit: {age: {and: 1}}}");
  68. }
  69. [Test]
  70. public void BitwiseOr()
  71. {
  72. var subject = CreateSubject<BsonDocument>();
  73. Assert(subject.BitwiseOr("a", 1), "{$bit: {a: {or: 1}}}");
  74. }
  75. [Test]
  76. public void BitwiseOr_Typed()
  77. {
  78. var subject = CreateSubject<Person>();
  79. Assert(subject.BitwiseOr(x => x.Age, 1), "{$bit: {age: {or: 1}}}");
  80. Assert(subject.BitwiseOr("Age", 1), "{$bit: {age: {or: 1}}}");
  81. }
  82. [Test]
  83. public void BitwiseXor()
  84. {
  85. var subject = CreateSubject<BsonDocument>();
  86. Assert(subject.BitwiseXor("a", 1), "{$bit: {a: {xor: 1}}}");
  87. }
  88. [Test]
  89. public void BitwiseXor_Typed()
  90. {
  91. var subject = CreateSubject<Person>();
  92. Assert(subject.BitwiseXor(x => x.Age, 1), "{$bit: {age: {xor: 1}}}");
  93. Assert(subject.BitwiseXor("Age", 1), "{$bit: {age: {xor: 1}}}");
  94. }
  95. [Test]
  96. public void Combine()
  97. {
  98. var subject = CreateSubject<BsonDocument>();
  99. var update = subject.Combine(
  100. "{$set: {a: 1, b: 2}}",
  101. "{$inc: {c: 1}}");
  102. Assert(update, "{$set: {a: 1, b: 2}, $inc: {c: 1}}");
  103. }
  104. [Test]
  105. public void Combine_with_overlapping_operators()
  106. {
  107. var subject = CreateSubject<BsonDocument>();
  108. var update = subject.Combine(
  109. "{$set: {a: 1, b: 2}}",
  110. "{$set: {c: 3}}");
  111. Assert(update, "{$set: {a: 1, b: 2, c: 3}}");
  112. }
  113. [Test]
  114. public void Combine_with_overlapping_operators_and_duplicate_elements()
  115. {
  116. var subject = CreateSubject<BsonDocument>();
  117. var update = subject.Combine(
  118. "{$set: {a: 1, b: 2}}",
  119. "{$set: {a: 4}}");
  120. Assert(update, "{$set: {a: 4, b: 2}}");
  121. }
  122. [Test]
  123. public void Combine_with_overlapping_operators_and_duplicate_elements_using_extension_methods()
  124. {
  125. var subject = CreateSubject<BsonDocument>();
  126. var update = subject.Set("a", 1).Set("b", 2).Set("a", 4);
  127. Assert(update, "{$set: {a: 4, b: 2}}");
  128. }
  129. [Test]
  130. public void CurrentDate()
  131. {
  132. var subject = CreateSubject<BsonDocument>();
  133. Assert(subject.CurrentDate("a"), "{$currentDate: {a: true}}");
  134. }
  135. [Test]
  136. public void CurrentDate_with_date_type()
  137. {
  138. var subject = CreateSubject<BsonDocument>();
  139. Assert(subject.CurrentDate("a", UpdateDefinitionCurrentDateType.Date), "{$currentDate: {a: {$type: 'date'}}}");
  140. }
  141. [Test]
  142. public void CurrentDate_with_timestamp_type()
  143. {
  144. var subject = CreateSubject<BsonDocument>();
  145. Assert(subject.CurrentDate("a", UpdateDefinitionCurrentDateType.Timestamp), "{$currentDate: {a: {$type: 'timestamp'}}}");
  146. }
  147. [Test]
  148. public void CurrentDate_Typed()
  149. {
  150. var subject = CreateSubject<Person>();
  151. Assert(subject.CurrentDate(x => x.LastUpdated), "{$currentDate: {last_updated: true}}");
  152. Assert(subject.CurrentDate("LastUpdated"), "{$currentDate: {last_updated: true}}");
  153. }
  154. [Test]
  155. public void CurrentDate_Typed_with_date_type()
  156. {
  157. var subject = CreateSubject<Person>();
  158. Assert(subject.CurrentDate(x => x.LastUpdated, UpdateDefinitionCurrentDateType.Date), "{$currentDate: {last_updated: {$type: 'date'}}}}");
  159. Assert(subject.CurrentDate("LastUpdated", UpdateDefinitionCurrentDateType.Date), "{$currentDate: {last_updated: {$type: 'date'}}}}");
  160. }
  161. [Test]
  162. public void CurrentDate_Typed_with_timestamp_type()
  163. {
  164. var subject = CreateSubject<Person>();
  165. Assert(subject.CurrentDate(x => x.LastUpdated, UpdateDefinitionCurrentDateType.Timestamp), "{$currentDate: {last_updated: {$type: 'timestamp'}}}}");
  166. Assert(subject.CurrentDate("LastUpdated", UpdateDefinitionCurrentDateType.Timestamp), "{$currentDate: {last_updated: {$type: 'timestamp'}}}}");
  167. }
  168. [Test]
  169. public void Inc()
  170. {
  171. var subject = CreateSubject<BsonDocument>();
  172. Assert(subject.Inc("a", 1), "{$inc: {a: 1}}");
  173. }
  174. [Test]
  175. public void Inc_Typed()
  176. {
  177. var subject = CreateSubject<Person>();
  178. Assert(subject.Inc(x => x.Age, 1), "{$inc: {age: 1}}");
  179. Assert(subject.Inc("Age", 1), "{$inc: {age: 1}}");
  180. }
  181. [Test]
  182. public void Indexed_Typed()
  183. {
  184. var subject = CreateSubject<Person>();
  185. Assert(subject.Set(x => x.FavoriteColors[2], "yellow"), "{$set: {'colors.2': 'yellow'}}");
  186. Assert(subject.Set(x => x.Pets[2].Name, "Fluffencutters"), "{$set: {'pets.2.name': 'Fluffencutters'}}");
  187. Assert(subject.Set(x => x.Pets.ElementAt(2).Name, "Fluffencutters"), "{$set: {'pets.2.name': 'Fluffencutters'}}");
  188. var index = 2;
  189. Assert(subject.Set(x => x.FavoriteColors[index], "yellow"), "{$set: {'colors.2': 'yellow'}}");
  190. Assert(subject.Set(x => x.Pets[index].Name, "Fluffencutters"), "{$set: {'pets.2.name': 'Fluffencutters'}}");
  191. Assert(subject.Set(x => x.Pets.ElementAt(index).Name, "Fluffencutters"), "{$set: {'pets.2.name': 'Fluffencutters'}}");
  192. }
  193. [Test]
  194. public void Indexed_Positional_Typed()
  195. {
  196. var subject = CreateSubject<Person>();
  197. #pragma warning disable
  198. Assert(subject.Set(x => x.FavoriteColors[-1], "yellow"), "{$set: {'colors.$': 'yellow'}}");
  199. #pragma warning restore
  200. Assert(subject.Set(x => x.Pets[-1].Name, "Fluffencutters"), "{$set: {'pets.$.name': 'Fluffencutters'}}");
  201. Assert(subject.Set(x => x.Pets.ElementAt(-1).Name, "Fluffencutters"), "{$set: {'pets.$.name': 'Fluffencutters'}}");
  202. }
  203. [Test]
  204. public void Max()
  205. {
  206. var subject = CreateSubject<BsonDocument>();
  207. Assert(subject.Max("a", 1), "{$max: {a: 1}}");
  208. }
  209. [Test]
  210. public void Max_Typed()
  211. {
  212. var subject = CreateSubject<Person>();
  213. Assert(subject.Max(x => x.Age, 1), "{$max: {age: 1}}");
  214. Assert(subject.Max("Age", 1), "{$max: {age: 1}}");
  215. }
  216. [Test]
  217. public void Min()
  218. {
  219. var subject = CreateSubject<BsonDocument>();
  220. Assert(subject.Min("a", 1), "{$min: {a: 1}}");
  221. }
  222. [Test]
  223. public void Min_Typed()
  224. {
  225. var subject = CreateSubject<Person>();
  226. Assert(subject.Min(x => x.Age, 1), "{$min: {age: 1}}");
  227. Assert(subject.Min("Age", 1), "{$min: {age: 1}}");
  228. }
  229. [Test]
  230. public void Mul()
  231. {
  232. var subject = CreateSubject<BsonDocument>();
  233. Assert(subject.Mul("a", 2), "{$mul: {a: 2}}");
  234. }
  235. [Test]
  236. public void Mul_Typed()
  237. {
  238. var subject = CreateSubject<Person>();
  239. Assert(subject.Mul(x => x.Age, 2), "{$mul: {age: 2}}");
  240. Assert(subject.Mul("Age", 2), "{$mul: {age: 2}}");
  241. }
  242. [Test]
  243. public void PopFirst()
  244. {
  245. var subject = CreateSubject<BsonDocument>();
  246. Assert(subject.PopFirst("a"), "{$pop: {a: -1}}");
  247. }
  248. [Test]
  249. public void PopFirst_Typed()
  250. {
  251. var subject = CreateSubject<Person>();
  252. Assert(subject.PopFirst(x => x.FavoriteColors), "{$pop: {colors: -1}}");
  253. Assert(subject.PopFirst("FavoriteColors"), "{$pop: {colors: -1}}");
  254. }
  255. [Test]
  256. public void PopLast()
  257. {
  258. var subject = CreateSubject<BsonDocument>();
  259. Assert(subject.PopLast("a"), "{$pop: {a: 1}}");
  260. }
  261. [Test]
  262. public void PopLast_Typed()
  263. {
  264. var subject = CreateSubject<Person>();
  265. Assert(subject.PopLast(x => x.FavoriteColors), "{$pop: {colors: 1}}");
  266. Assert(subject.PopLast("FavoriteColors"), "{$pop: {colors: 1}}");
  267. }
  268. [Test]
  269. public void Pull()
  270. {
  271. var subject = CreateSubject<BsonDocument>();
  272. Assert(subject.Pull("a", 1), "{$pull: {a: 1}}");
  273. Assert(subject.Pull("a", new[] { 1, 2 }), "{$pull: {a: [1, 2]}}");
  274. }
  275. [Test]
  276. public void Pull_Typed()
  277. {
  278. var subject = CreateSubject<Person>();
  279. Assert(subject.Pull(x => x.FavoriteColors, "green"), "{$pull: {colors: 'green'}}");
  280. Assert(subject.Pull("FavoriteColors", "green"), "{$pull: {colors: 'green'}}");
  281. }
  282. [Test]
  283. public void PullAll()
  284. {
  285. var subject = CreateSubject<BsonDocument>();
  286. Assert(subject.PullAll("a", new[] { 1, 2 }), "{$pullAll: {a: [1, 2]}}");
  287. Assert(subject.PullAll("a", new[] { new[] { 1, 2 }, new[] { 3, 4 } }), "{$pullAll: {a: [[1, 2], [3, 4]]}}");
  288. }
  289. [Test]
  290. public void PullAll_Typed()
  291. {
  292. var subject = CreateSubject<Person>();
  293. Assert(subject.PullAll(x => x.FavoriteColors, new[] { "green", "violet" }), "{$pullAll: {colors: ['green', 'violet']}}");
  294. Assert(subject.PullAll("FavoriteColors", new[] { "green", "violet" }), "{$pullAll: {colors: ['green', 'violet']}}");
  295. }
  296. [Test]
  297. public void PullFilter()
  298. {
  299. var subject = CreateSubject<BsonDocument>();
  300. Assert(subject.PullFilter<BsonDocument>("a", "{b: {$gt: 1}}"), "{$pull: {a: {b: {$gt: 1}}}}");
  301. }
  302. [Test]
  303. public void PullFilter_Typed()
  304. {
  305. var subject = CreateSubject<Person>();
  306. Assert(subject.PullFilter(x => x.Pets, x => x.Name == "Fluffy"), "{$pull: {pets: {name: 'Fluffy'}}}}");
  307. Assert(subject.PullFilter<Pet>("Pets", "{ Name: 'Fluffy'}"), "{$pull: {pets: {Name: 'Fluffy'}}}}");
  308. }
  309. [Test]
  310. public void Push()
  311. {
  312. var subject = CreateSubject<BsonDocument>();
  313. Assert(subject.Push("a", 1), "{$push: {a: 1}}");
  314. Assert(subject.Push("a", new[] { 1, 2 }), "{$push: {a: [1, 2]}}");
  315. }
  316. [Test]
  317. public void Push_Typed()
  318. {
  319. var subject = CreateSubject<Person>();
  320. Assert(subject.Push(x => x.FavoriteColors, "green"), "{$push: {colors: 'green'}}");
  321. Assert(subject.Push("FavoriteColors", "green"), "{$push: {colors: 'green'}}");
  322. }
  323. [Test]
  324. public void PushEach(
  325. [Values(null, 10)] int? slice,
  326. [Values(null, 20)] int? position,
  327. [Values(null, "{b: 1}")] string sort)
  328. {
  329. var subject = CreateSubject<BsonDocument>();
  330. var expectedPushValue = BsonDocument.Parse("{$each: [1, 2]}");
  331. if (slice.HasValue)
  332. {
  333. expectedPushValue.Add("$slice", slice.Value);
  334. }
  335. if (position.HasValue)
  336. {
  337. expectedPushValue.Add("$position", position.Value);
  338. }
  339. if (sort != null)
  340. {
  341. expectedPushValue.Add("$sort", BsonDocument.Parse(sort));
  342. }
  343. var expectedPush = new BsonDocument("$push", new BsonDocument("a", expectedPushValue));
  344. Assert(subject.PushEach("a", new[] { 1, 2 }, slice, position, sort), expectedPush);
  345. }
  346. [Test]
  347. public void PushEach_Typed(
  348. [Values(null, 10)] int? slice,
  349. [Values(null, 20)] int? position,
  350. [Values(null, "{b: 1}")] string sort)
  351. {
  352. var subject = CreateSubject<Person>();
  353. var expectedPushValue = BsonDocument.Parse("{$each: ['green', 'violet']}");
  354. if (slice.HasValue)
  355. {
  356. expectedPushValue.Add("$slice", slice.Value);
  357. }
  358. if (position.HasValue)
  359. {
  360. expectedPushValue.Add("$position", position.Value);
  361. }
  362. if (sort != null)
  363. {
  364. expectedPushValue.Add("$sort", BsonDocument.Parse(sort));
  365. }
  366. var expectedPush = new BsonDocument("$push", new BsonDocument("colors", expectedPushValue));
  367. Assert(subject.PushEach(x => x.FavoriteColors, new[] { "green", "violet" }, slice, position, sort), expectedPush);
  368. }
  369. [Test]
  370. public void Rename()
  371. {
  372. var subject = CreateSubject<BsonDocument>();
  373. Assert(subject.Rename("a", "b"), "{$rename: {a: 'b'}}");
  374. }
  375. [Test]
  376. public void Rename_Typed()
  377. {
  378. var subject = CreateSubject<Person>();
  379. Assert(subject.Rename(x => x.Age, "birthDate"), "{$rename: {age: 'birthDate'}}");
  380. Assert(subject.Rename("Age", "birthDate"), "{$rename: {age: 'birthDate'}}");
  381. }
  382. [Test]
  383. public void Set()
  384. {
  385. var subject = CreateSubject<BsonDocument>();
  386. Assert(subject.Set("a", 1), "{$set: {a: 1}}");
  387. }
  388. [Test]
  389. public void Set_Typed()
  390. {
  391. var subject = CreateSubject<Person>();
  392. Assert(subject.Set(x => x.Age, 1), "{$set: {age: 1}}");
  393. Assert(subject.Set("Age", 1), "{$set: {age: 1}}");
  394. }
  395. [Test]
  396. public void SetOnInsert()
  397. {
  398. var subject = CreateSubject<BsonDocument>();
  399. Assert(subject.SetOnInsert("a", 1), "{$setOnInsert: {a: 1}}");
  400. }
  401. [Test]
  402. public void SetOnInsert_Typed()
  403. {
  404. var subject = CreateSubject<Person>();
  405. Assert(subject.SetOnInsert(x => x.Age, 1), "{$setOnInsert: {age: 1}}");
  406. Assert(subject.SetOnInsert("Age", 1), "{$setOnInsert: {age: 1}}");
  407. }
  408. [Test]
  409. public void Unset()
  410. {
  411. var subject = CreateSubject<BsonDocument>();
  412. Assert(subject.Unset("a"), "{$unset: {a: 1}}");
  413. }
  414. [Test]
  415. public void Unset_Typed()
  416. {
  417. var subject = CreateSubject<Person>();
  418. Assert(subject.Unset(x => x.Age), "{$unset: {age: 1}}");
  419. Assert(subject.Unset("Age"), "{$unset: {age: 1}}");
  420. }
  421. private void Assert<TDocument>(UpdateDefinition<TDocument> update, BsonDocument expected)
  422. {
  423. var documentSerializer = BsonSerializer.SerializerRegistry.GetSerializer<TDocument>();
  424. var renderedUpdate = update.Render(documentSerializer, BsonSerializer.SerializerRegistry);
  425. renderedUpdate.Should().Be(expected);
  426. }
  427. private void Assert<TDocument>(UpdateDefinition<TDocument> update, string expected)
  428. {
  429. Assert(update, BsonDocument.Parse(expected));
  430. }
  431. private UpdateDefinitionBuilder<TDocument> CreateSubject<TDocument>()
  432. {
  433. return new UpdateDefinitionBuilder<TDocument>();
  434. }
  435. private class Person
  436. {
  437. [BsonElement("fn")]
  438. public string FirstName { get; set; }
  439. [BsonElement("colors")]
  440. public string[] FavoriteColors { get; set; }
  441. [BsonElement("age")]
  442. public int Age { get; set; }
  443. [BsonElement("last_updated")]
  444. public DateTime LastUpdated { get; set; }
  445. [BsonElement("pets")]
  446. public List<Pet> Pets { get; set; }
  447. }
  448. private class Pet
  449. {
  450. [BsonElement("name")]
  451. public string Name { get; set; }
  452. }
  453. }
  454. }