PageRenderTime 52ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/Xtensive.Core/Xtensive.Core.Tests/ObjectMapping/MapperGeneralTests.cs

https://code.google.com/p/dataobjectsdotnet/
C# | 594 lines | 556 code | 33 blank | 5 comment | 33 complexity | 8b0d667d26859c0ca8422d39aadc230f MD5 | raw file
Possible License(s): AGPL-3.0
  1. // Copyright (C) 2003-2010 Xtensive LLC.
  2. // All rights reserved.
  3. // For conditions of distribution and use, see license.
  4. // Created by: Alexander Nikolaev
  5. // Created: 2009.12.09
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Linq;
  9. using NUnit.Framework;
  10. using Xtensive.Core.Collections;
  11. using Xtensive.Core.ObjectMapping;
  12. using Xtensive.Core.ObjectMapping.Model;
  13. using Xtensive.Core.Testing;
  14. using Xtensive.Core.Tests.ObjectMapping.SourceModel;
  15. using Xtensive.Core.Tests.ObjectMapping.TargetModel;
  16. namespace Xtensive.Core.Tests.ObjectMapping
  17. {
  18. [TestFixture]
  19. public sealed class MapperGeneralTests : MapperTestBase
  20. {
  21. [Test]
  22. public void DefaultTransformationOfPrimitivePropertiesTest()
  23. {
  24. var source = GetSourcePerson();
  25. var mapper = GetPersonOrderMapper();
  26. var target = (PersonDto) mapper.Transform(source);
  27. Assert.IsNotNull(target);
  28. AssertAreEqual(source, target);
  29. }
  30. [Test]
  31. public void DefaultTransformationOfComplexPropertiesTest()
  32. {
  33. var source = GetSourceOrder();
  34. var mapper = GetPersonOrderMapper();
  35. var target = (OrderDto) mapper.Transform(source);
  36. Assert.IsNotNull(target);
  37. Assert.AreEqual(source.Id.ToString(), target.Id);
  38. Assert.AreEqual(source.ShipDate, target.ShipDate);
  39. AssertAreEqual(source.Customer, target.Customer);
  40. }
  41. [Test]
  42. public void ComparisonOfObjectsContainingPrimitivePropertiesOnlyTest()
  43. {
  44. var source = GetSourcePerson();
  45. var mapper = GetPersonOrderMapper();
  46. var target = (PersonDto) mapper.Transform(source);
  47. var clone = (PersonDto) target.Clone();
  48. var modifiedDate = clone.BirthDate.AddDays(23);
  49. clone.BirthDate = modifiedDate;
  50. var modifiedFirstName = clone.FirstName + "!";
  51. clone.FirstName = modifiedFirstName;
  52. var eventRaisingCount = 0;
  53. Action<Operation> validator = descriptor => {
  54. eventRaisingCount++;
  55. switch (descriptor.PropertyPath[0].SystemProperty.Name) {
  56. case "BirthDate":
  57. Assert.AreEqual(modifiedDate, descriptor.Value);
  58. break;
  59. case "FirstName":
  60. Assert.AreEqual(modifiedFirstName, descriptor.Value);
  61. break;
  62. default:
  63. Assert.Fail();
  64. break;
  65. }
  66. };
  67. ((DefaultOperationLog) mapper.Compare(target, clone).Operations).ForEach(validator);
  68. Assert.AreEqual(2, eventRaisingCount);
  69. }
  70. [Test]
  71. public void ComparisonOfObjectsWhenOnlyPrimitivePropertiesHaveBeenModifiedTest()
  72. {
  73. var source = GetSourceOrder();
  74. var mapper = GetPersonOrderMapper();
  75. var target = (OrderDto) mapper.Transform(source);
  76. var clone = (OrderDto) target.Clone();
  77. var modifiedShipDate = clone.ShipDate.AddDays(-5);
  78. clone.ShipDate = modifiedShipDate;
  79. var modifiedFirstName = clone.Customer.FirstName + "!";
  80. clone.Customer.FirstName = modifiedFirstName;
  81. var eventRaisingCount = 0;
  82. Action<Operation> validator = descriptor => {
  83. eventRaisingCount++;
  84. if (ReferenceEquals(target, descriptor.Object)) {
  85. Assert.AreEqual("ShipDate", descriptor.PropertyPath[0].SystemProperty.Name);
  86. Assert.AreEqual(modifiedShipDate, descriptor.Value);
  87. }
  88. else if (ReferenceEquals(target.Customer, descriptor.Object)) {
  89. Assert.AreEqual("FirstName", descriptor.PropertyPath[0].SystemProperty.Name);
  90. Assert.AreEqual(modifiedFirstName, descriptor.Value);
  91. }
  92. else
  93. Assert.Fail();
  94. };
  95. ((DefaultOperationLog) mapper.Compare(target, clone).Operations).ForEach(validator);
  96. Assert.AreEqual(2, eventRaisingCount);
  97. }
  98. [Test]
  99. public void ComparisonOfObjectsWhenReferencedObjectHasBeenReplacedTest()
  100. {
  101. var source = GetSourceOrder();
  102. var mapper = GetPersonOrderMapper();
  103. var target = (OrderDto) mapper.Transform(source);
  104. var clone = (OrderDto) target.Clone();
  105. var modifiedShipDate = clone.ShipDate.AddDays(-5);
  106. clone.ShipDate = modifiedShipDate;
  107. var modifiedCustomer = new PersonDto {
  108. BirthDate = DateTime.Now.AddYears(25), FirstName = "Stewart", LastName = "Smith", Id = 4
  109. };
  110. clone.Customer = modifiedCustomer;
  111. ValidateComparisonOfObjectsWhenReferencedObjectHasBeenReplaced(mapper, target, clone, modifiedShipDate,
  112. modifiedCustomer);
  113. }
  114. [Test]
  115. public void TransformationUsingCustomMappingTest()
  116. {
  117. var source = GetSourceAuthor();
  118. var mapper = GetAuthorBookMapper();
  119. var target = (AuthorDto) mapper.Transform(source);
  120. Assert.IsNotNull(target);
  121. Assert.AreEqual(source.Name + "!!!", target.Name);
  122. Assert.AreEqual(source.Book.ISBN, target.Book.ISBN);
  123. Assert.AreEqual(source.Book.Title.Text, target.Book.TitleText);
  124. Assert.AreEqual(source.Book.Title.Id, target.Book.Title.Id);
  125. }
  126. [Test]
  127. public void MappingBuildingWhenTypesHavePropertyWhichShouldBeIgnoredTest()
  128. {
  129. var mapper = GetIgnorableMapper();
  130. var auxiliaryProperty = GetTargetProperty(mapper, typeof (IgnorableDto), "Auxiliary");
  131. var ignoredTargetProperty = GetTargetProperty(mapper, typeof (IgnorableDto), "Ignored");
  132. Assert.IsNull(auxiliaryProperty.SourceProperty);
  133. Assert.IsTrue(auxiliaryProperty.IsIgnored);
  134. Assert.IsNull(ignoredTargetProperty.SourceProperty);
  135. Assert.IsTrue(ignoredTargetProperty.IsIgnored);
  136. }
  137. [Test]
  138. public void TransformationWhenTypesHavePropertiesWhichShouldBeIgnoredTest()
  139. {
  140. var mapper = GetIgnorableMapper();
  141. var source = GetIgnorableSource();
  142. var target = (IgnorableDto) mapper.Transform(source);
  143. Assert.IsNotNull(target);
  144. Assert.AreEqual(source.Id, target.Id);
  145. Assert.AreNotEqual(source.Ignored, target.Ignored);
  146. Assert.IsNull(target.Ignored);
  147. Assert.IsNull(target.Auxiliary);
  148. Assert.AreEqual(source.IncludedReference.Id, target.IncludedReference.Id);
  149. Assert.AreEqual(source.IncludedReference.Date, target.IncludedReference.Date);
  150. Assert.IsNotNull(source.IgnoredReference);
  151. Assert.IsNull(target.IgnoredReference);
  152. }
  153. [Test]
  154. public void ComparisonWhenTypesHavePropertiesWhichShouldBeIgnoredTest()
  155. {
  156. var mapper = GetIgnorableMapper();
  157. var source = GetIgnorableSource();
  158. var original = (IgnorableDto) mapper.Transform(source);
  159. original.Ignored = "I";
  160. original.Auxiliary = "A";
  161. original.IgnoredReference = new IgnorableSubordinateDto {Date = DateTime.Now, Id = Guid.NewGuid()};
  162. var modified = (IgnorableDto) original.Clone();
  163. modified.Ignored = "1";
  164. modified.Auxiliary = "2";
  165. modified.IgnoredReference = new IgnorableSubordinateDto {Date = DateTime.Now.AddDays(1),
  166. Id = Guid.NewGuid()};
  167. var operations = mapper.Compare(original, modified).Operations;
  168. Assert.IsTrue(operations.Count==0);
  169. var newDate = modified.IncludedReference.Date.AddYears(20);
  170. modified.IncludedReference.Date = newDate;
  171. operations = mapper.Compare(original, modified).Operations;
  172. Assert.IsFalse(operations.Count==0);
  173. var operation = ((DefaultOperationLog) operations).Single();
  174. Assert.AreEqual(original.IncludedReference, operation.Object);
  175. Assert.AreEqual("Date", operation.PropertyPath[0].SystemProperty.Name);
  176. Assert.AreEqual(OperationType.SetProperty, operation.Type);
  177. Assert.AreEqual(newDate, operation.Value);
  178. Assert.AreNotEqual(original.IgnoredReference.Id, modified.IgnoredReference.Id);
  179. Assert.AreNotEqual(original.IgnoredReference.Date, modified.IgnoredReference.Date);
  180. Assert.AreNotEqual(original.Auxiliary, modified.Auxiliary);
  181. Assert.AreNotEqual(original.Ignored, modified.Ignored);
  182. }
  183. [Test]
  184. public void TransformationWhenGraphRootIsCollectionTest()
  185. {
  186. var mapper = GetAuthorBookMapper();
  187. var source = new HashSet<Author>();
  188. for (int i = 0; i < 5; i++) {
  189. var author = GetSourceAuthor();
  190. author.Name += i;
  191. author.Book.Price += i * 100;
  192. author.Book.Title.Text += i;
  193. source.Add(author);
  194. }
  195. var transformedList = (List<object>) mapper.Transform(source);
  196. var target = transformedList.Cast<AuthorDto>().ToList();
  197. Assert.AreEqual(source.Count, target.Count);
  198. EnumerableExtensions.ForEach(target, ta => Assert.IsTrue(source.Any(sa => sa.Id == ta.Id && sa.Name + "!!!" == ta.Name
  199. && sa.Book.ISBN == ta.Book.ISBN && sa.Book.Price == ta.Book.Price
  200. && sa.Book.Title.Id == ta.Book.Title.Id && sa.Book.Title.Text == ta.Book.Title.Text
  201. && sa.Book.Title.Text == ta.Book.TitleText)));
  202. }
  203. [Test]
  204. public void ComparisonWhenGraphRootIsCollectionTest()
  205. {
  206. var mapper = GetAuthorBookMapper();
  207. var source = new HashSet<Author>();
  208. for (int i = 0; i < 5; i++) {
  209. var author = GetSourceAuthor();
  210. author.Name += i;
  211. author.Book.Price += i * 100;
  212. author.Book.Title.Text += i;
  213. source.Add(author);
  214. }
  215. var transformedList = (List<object>) mapper.Transform(source);
  216. var original = transformedList.Cast<AuthorDto>().ToList();
  217. var modified = original.Select(a => a.Clone()).Cast<AuthorDto>().ToList();
  218. var removedAuthor = original[1];
  219. modified.RemoveAt(1);
  220. var createdAuthor = (AuthorDto) mapper.Transform(GetSourceAuthor());
  221. modified.Add(createdAuthor);
  222. var operations = (DefaultOperationLog) mapper.Compare(original, modified).Operations;
  223. Assert.AreEqual(9, operations.Count());
  224. ValidateObjectCreation(createdAuthor, operations.First());
  225. ValidateObjectCreation(createdAuthor.Book, operations.Skip(1).First());
  226. ValidateObjectCreation(createdAuthor.Book.Title, operations.Skip(2).First());
  227. ValidatePropertySettingOperation(createdAuthor, operations.Skip(3).First(),
  228. typeof (AuthorDto).GetProperty("Book"), createdAuthor.Book);
  229. ValidatePropertySettingOperation(createdAuthor.Book, operations.Skip(4).First(),
  230. typeof (BookDto).GetProperty("Price"), createdAuthor.Book.Price);
  231. ValidatePropertySettingOperation(createdAuthor.Book.Title, operations.Skip(5).First(),
  232. typeof (TitleDto).GetProperty("Text"), createdAuthor.Book.Title.Text);
  233. ValidateObjectRemoval(removedAuthor, operations.Skip(6).First());
  234. ValidateObjectRemoval(removedAuthor.Book, operations.Skip(7).First());
  235. ValidateObjectRemoval(removedAuthor.Book.Title, operations.Skip(8).First());
  236. }
  237. [Test]
  238. public void ComparisonWhenOriginalIsCollectionButModifiedIsNotTest()
  239. {
  240. var mapper = GetPersonOrderMapper();
  241. var source = new List<Person> {GetSourcePerson(1), GetSourcePerson(2)};
  242. var original = (List<object>) mapper.Transform(source);
  243. var modified = new PersonDto {BirthDate = DateTime.Now, Id = 3};
  244. var operations = (DefaultOperationLog) mapper.Compare(original, modified).Operations;
  245. Assert.AreEqual(6, operations.Count());
  246. ValidateObjectCreation(modified, operations.First());
  247. ValidatePropertySettingOperation(modified, operations.Skip(1).First(), FirstNameProperty,
  248. modified.FirstName);
  249. ValidatePropertySettingOperation(modified, operations.Skip(2).First(), LastNameProperty,
  250. modified.LastName);
  251. ValidatePropertySettingOperation(modified, operations.Skip(3).First(), BirthDateProperty,
  252. modified.BirthDate);
  253. ValidateObjectRemoval(original[0], operations.Skip(4).First());
  254. ValidateObjectRemoval(original[1], operations.Skip(5).First());
  255. }
  256. [Test]
  257. public void ComparisonWhenModifiedIsCollectionButOriginalIsNotTest()
  258. {
  259. var mapper = GetPersonOrderMapper();
  260. var source = new Person {BirthDate = DateTime.Now, Id = 3};
  261. var original = (PersonDto) mapper.Transform(source);
  262. var modified = new List<PersonDto> {
  263. new PersonDto {BirthDate = DateTime.Now, Id = 1, FirstName = "A"},
  264. new PersonDto {BirthDate = DateTime.Now, Id = 2, FirstName = "B"}
  265. };
  266. var operations = (DefaultOperationLog) mapper.Compare(original, modified).Operations;
  267. Assert.AreEqual(9, operations.Count());
  268. ValidateObjectCreation(modified[0], operations.First());
  269. ValidateObjectCreation(modified[1], operations.Skip(1).First());
  270. ValidatePropertySettingOperation(modified[0], operations.Skip(2).First(), FirstNameProperty,
  271. modified[0].FirstName);
  272. ValidatePropertySettingOperation(modified[0], operations.Skip(3).First(), LastNameProperty,
  273. modified[0].LastName);
  274. ValidatePropertySettingOperation(modified[0], operations.Skip(4).First(), BirthDateProperty,
  275. modified[0].BirthDate);
  276. ValidatePropertySettingOperation(modified[1], operations.Skip(5).First(), FirstNameProperty,
  277. modified[1].FirstName);
  278. ValidatePropertySettingOperation(modified[1], operations.Skip(6).First(), LastNameProperty,
  279. modified[1].LastName);
  280. ValidatePropertySettingOperation(modified[1], operations.Skip(7).First(), BirthDateProperty,
  281. modified[1].BirthDate);
  282. ValidateObjectRemoval(original, operations.Skip(8).Single());
  283. }
  284. [Test]
  285. public void InheritedPropertyConverterMappingTest()
  286. {
  287. var mapper = GetCreatureHeirsMapperWithCustomConverters();
  288. var source = GetSourceCreatures();
  289. var target = ((List<object>) mapper.Transform(source)).Cast<CreatureDto>().ToList();
  290. Assert.AreEqual(source.Count, target.Count);
  291. for (var i = 0; i < target.Count; i++) {
  292. Assert.AreEqual(source[i].Id, target[i].Id);
  293. if (typeof (Mammal).IsAssignableFrom(source[i].GetType()))
  294. Assert.AreEqual(source[i].Name + inheritedFromMammal, target[i].Name);
  295. else if (typeof (FlyingInsect).IsAssignableFrom(source[i].GetType()))
  296. Assert.AreEqual(source[i].Name + inheritedFlyingInsect, target[i].Name);
  297. else
  298. Assert.AreEqual(source[i].Name + inherited, target[i].Name);
  299. }
  300. var sourceMammal = (Mammal) source[0];
  301. var targetMammal = (MammalDto) target[0];
  302. Assert.AreEqual(sourceMammal.Color, targetMammal.Color);
  303. Assert.AreEqual(sourceMammal.HasHair, targetMammal.HasHair);
  304. var sourceInsect = (Insect) source[1];
  305. var targetInsect = (InsectDto) target[1];
  306. Assert.AreEqual(sourceInsect.LegPairCount, targetInsect.LegPairCount);
  307. var sourceFlyingInsect = (FlyingInsect) source[3];
  308. var targetFlyingInsect = (FlyingInsectDto) target[3];
  309. Assert.AreEqual(sourceFlyingInsect.LegPairCount, targetFlyingInsect.LegPairCount);
  310. Assert.AreEqual(sourceFlyingInsect.WingPairCount, targetFlyingInsect.WingPairCount);
  311. var sourceLongBee = (LongBee) source[4];
  312. var targetLongBee = (LongBeeDto) target[4];
  313. Assert.AreEqual(sourceLongBee.LegPairCount, targetLongBee.LegPairCount);
  314. Assert.AreEqual(sourceLongBee.WingPairCount, targetLongBee.WingPairCount);
  315. Assert.AreEqual(sourceLongBee.Length, targetLongBee.Length);
  316. Assert.AreEqual(sourceLongBee.StripCount, targetLongBee.StripCount);
  317. var sourceCat = (Cat) source[5];
  318. var targetCat = (CatDto) target[5];
  319. Assert.AreEqual(sourceCat.Breed, targetCat.Breed);
  320. Assert.AreEqual(sourceCat.Color, targetCat.Color);
  321. Assert.AreEqual(sourceCat.HasHair, targetCat.HasHair);
  322. var sourceDolphin = (Dolphin) source[6];
  323. var targetDolphin = (DolphinDto) target[6];
  324. Assert.AreEqual(sourceDolphin.Color, targetDolphin.Color);
  325. Assert.AreEqual(sourceDolphin.HasHair, targetDolphin.HasHair);
  326. Assert.AreEqual(sourceDolphin.OceanAreal, targetDolphin.OceanAreal);
  327. }
  328. [Test]
  329. public void InheritedPropertyAttributesModelBuildingTest()
  330. {
  331. var mapper = GetCreatureHeirsMapperWithAttributesMapper();
  332. var model = mapper.MappingDescription;
  333. Func<Type, TargetPropertyDescription> namePropertyGetter =
  334. type => (TargetPropertyDescription) model.GetTargetType(type).Properties[type.GetProperty("Name")];
  335. Func<Type, TargetPropertyDescription> legPairCountPropertyGetter =
  336. type => (TargetPropertyDescription) model.GetTargetType(type)
  337. .Properties[type.GetProperty("LegPairCount")];
  338. var creatureDtoType = typeof (CreatureDto);
  339. var namePropertyDescription = namePropertyGetter.Invoke(creatureDtoType);
  340. Assert.IsFalse(namePropertyDescription.IsIgnored);
  341. Assert.IsTrue(namePropertyDescription.IsChangeTrackingDisabled);
  342. var mammalDtoType = typeof (MammalDto);
  343. namePropertyDescription = namePropertyGetter.Invoke(mammalDtoType);
  344. Assert.IsTrue(namePropertyDescription.IsIgnored);
  345. Assert.IsFalse(namePropertyDescription.IsChangeTrackingDisabled);
  346. namePropertyDescription = namePropertyGetter.Invoke(typeof (CatDto));
  347. Assert.IsTrue(namePropertyDescription.IsIgnored);
  348. Assert.IsFalse(namePropertyDescription.IsChangeTrackingDisabled);
  349. namePropertyDescription = namePropertyGetter.Invoke(typeof (DolphinDto));
  350. Assert.IsTrue(namePropertyDescription.IsIgnored);
  351. Assert.IsFalse(namePropertyDescription.IsChangeTrackingDisabled);
  352. namePropertyDescription = namePropertyGetter.Invoke(typeof (InsectDto));
  353. Assert.IsFalse(namePropertyDescription.IsIgnored);
  354. Assert.IsTrue(namePropertyDescription.IsChangeTrackingDisabled);
  355. namePropertyDescription = namePropertyGetter.Invoke(typeof (FlyingInsectDto));
  356. Assert.IsFalse(namePropertyDescription.IsIgnored);
  357. Assert.IsTrue(namePropertyDescription.IsChangeTrackingDisabled);
  358. namePropertyDescription = namePropertyGetter.Invoke(typeof (LongBeeDto));
  359. Assert.IsFalse(namePropertyDescription.IsIgnored);
  360. Assert.IsTrue(namePropertyDescription.IsChangeTrackingDisabled);
  361. var legPairCountPropertyDescription = legPairCountPropertyGetter.Invoke(typeof (InsectDto));
  362. Assert.IsFalse(legPairCountPropertyDescription.IsIgnored);
  363. Assert.IsTrue(legPairCountPropertyDescription.IsChangeTrackingDisabled);
  364. legPairCountPropertyDescription = legPairCountPropertyGetter.Invoke(typeof (FlyingInsectDto));
  365. Assert.IsFalse(legPairCountPropertyDescription.IsIgnored);
  366. Assert.IsTrue(legPairCountPropertyDescription.IsChangeTrackingDisabled);
  367. legPairCountPropertyDescription = legPairCountPropertyGetter.Invoke(typeof (LongBeeDto));
  368. Assert.IsFalse(legPairCountPropertyDescription.IsIgnored);
  369. Assert.IsTrue(legPairCountPropertyDescription.IsChangeTrackingDisabled);
  370. }
  371. [Test]
  372. public void ThrowWhenLimitOfGraphDepthHasBeenExceededTest()
  373. {
  374. const int depthLimit = 2;
  375. var mapper = GetRecursiveCompositionMapperWithGraphDepthLimit(depthLimit, GraphTruncationType.Throw);
  376. var source = new RecursiveComposition();
  377. source.Compose(3);
  378. AssertEx.ThrowsInvalidOperationException(() => mapper.Transform(source));
  379. source = new RecursiveComposition();
  380. source.Compose(2);
  381. var target = (RecursiveCompositionDto) mapper.Transform(source);
  382. Assert.AreEqual(source.Id, target.Id);
  383. Assert.AreEqual(source.Level, target.Level);
  384. Assert.AreEqual(source.Child.Id, target.Child.Id);
  385. Assert.AreEqual(source.Child.Level, target.Child.Level);
  386. Assert.AreEqual(source.Child.Child.Id, target.Child.Child.Id);
  387. Assert.AreEqual(source.Child.Child.Level, target.Child.Child.Level);
  388. mapper = GetRecursiveCompositionMapperWithGraphDepthLimit(0, GraphTruncationType.Throw);
  389. source = new RecursiveComposition();
  390. source.Compose(0);
  391. target = (RecursiveCompositionDto) mapper.Transform(source);
  392. Assert.AreEqual(source.Id, target.Id);
  393. Assert.AreEqual(source.Level, target.Level);
  394. Assert.AreEqual(source.Child, target.Child);
  395. }
  396. [Test]
  397. public void SetDefaultValueWhenLimitOfGraphDepthHasBeenExceededTest()
  398. {
  399. const int depthLimit = 2;
  400. var mapper = GetRecursiveCompositionMapperWithGraphDepthLimit(depthLimit,
  401. GraphTruncationType.SetDefaultValue);
  402. var source = new RecursiveComposition();
  403. source.Compose(3);
  404. var target = (RecursiveCompositionDto) mapper.Transform(source);
  405. Assert.IsNotNull(source.Child.Child.Child);
  406. Assert.IsNull(target.Child.Child.Child);
  407. }
  408. [Test]
  409. public void SkipDetectionOfPropertyChangeTest()
  410. {
  411. var mapping = new MappingBuilder()
  412. .MapType<Person, PersonDto, int>(p => p.Id, p => p.Id).TrackChanges(p => p.FirstName, false)
  413. .Build();
  414. var mapper = new DefaultMapper(mapping);
  415. var source = GetSourcePerson(1);
  416. var target = (PersonDto) mapper.Transform(source);
  417. var modified = (PersonDto) target.Clone();
  418. modified.FirstName += "!";
  419. var operations = mapper.Compare(target, modified).Operations;
  420. Assert.IsTrue(operations.Count==0);
  421. mapping = new MappingBuilder()
  422. .MapType<Person, PersonDto, int>(p => p.Id, p => p.Id)
  423. .TrackChanges(p => p.FirstName, false)
  424. .IgnoreProperty(p => p.FirstName).Build();
  425. mapper = new DefaultMapper(mapping);
  426. target = (PersonDto) mapper.Transform(source);
  427. modified = (PersonDto) target.Clone();
  428. modified.FirstName += "!";
  429. operations = mapper.Compare(target, modified).Operations;
  430. Assert.IsTrue(operations.Count==0);
  431. }
  432. [Test]
  433. public void SkipSettingIgnoredPropertiesWhenObjectHasBeenCreatedTest()
  434. {
  435. var mapping = new MappingBuilder()
  436. .MapType<Person, PersonDto, int>(p => p.Id, p => p.Id)
  437. .IgnoreProperty(p => p.FirstName).Build();
  438. var mapper = new DefaultMapper(mapping);
  439. var createdObject = new PersonDto {
  440. BirthDate = DateTime.Now, FirstName = "FirstName", LastName = "LastName"
  441. };
  442. var operations = ((DefaultOperationLog) mapper.Compare(null, createdObject).Operations).ToList();
  443. Assert.AreEqual(3, operations.Count);
  444. ValidateObjectCreation(createdObject, operations[0]);
  445. ValidatePropertyOperation(createdObject, operations[1], p => p.LastName,
  446. createdObject.LastName, OperationType.SetProperty);
  447. ValidatePropertyOperation(createdObject, operations[2], p => p.BirthDate,
  448. createdObject.BirthDate, OperationType.SetProperty);
  449. }
  450. [Test]
  451. public void DynamicExpansionOfSourceHierarchyTest()
  452. {
  453. var settings = new MapperSettings {EnableDynamicSourceHierarchies = true};
  454. var mapping = new MappingBuilder()
  455. .MapType<CreatureBase, CreatureDto, Guid>(c => c.Id, c => c.Id).Build();
  456. var source = new List<Creature> {
  457. new Creature {Id = Guid.NewGuid(), Name = "Name0"}, new LongBee {Id = Guid.NewGuid(), Name = "Name1"},
  458. new Mammal {Id = Guid.NewGuid(), Name = "Name2"}
  459. };
  460. var target = ((List<object>) new DefaultMapper(mapping, settings).Transform(source))
  461. .Cast<CreatureDto>().ToList();
  462. for (var i = 0; i < source.Count; i++) {
  463. Assert.AreEqual(source[i].Id, target[i].Id);
  464. Assert.AreEqual(source[i].Name, target[i].Name);
  465. }
  466. }
  467. [Test]
  468. public void NullablePropertyTransformationTest()
  469. {
  470. var mapping = new MappingBuilder()
  471. .MapType<NullableDateTimeContainer, NullableDateTimeContainerDto, Guid>(n => n.Id, n => n.Id)
  472. .Build();
  473. var source = new NullableDateTimeContainer {NullableDateTime = DateTime.Now};
  474. var target = (NullableDateTimeContainerDto) new DefaultMapper(mapping).Transform(source);
  475. Assert.AreEqual(source.Id, target.Id);
  476. Assert.AreEqual(source.NullableDateTime, target.NullableDateTime);
  477. }
  478. [Test]
  479. public void NullablePropertyComparisonTest()
  480. {
  481. var mapping = new MappingBuilder()
  482. .MapType<NullableDateTimeContainer, NullableDateTimeContainerDto, Guid>(n => n.Id, n => n.Id)
  483. .Build();
  484. var source = new NullableDateTimeContainer {NullableDateTime = DateTime.Now};
  485. var original = (NullableDateTimeContainerDto) new DefaultMapper(mapping).Transform(source);
  486. var newValue = original.NullableDateTime.Value.AddDays(5);
  487. var modified = new NullableDateTimeContainerDto {
  488. Id = original.Id,
  489. NullableDateTime = newValue
  490. };
  491. var operations = ((DefaultOperationLog) new DefaultMapper(mapping)
  492. .Compare(original, modified).Operations).ToList();
  493. Assert.AreEqual(1, operations.Count);
  494. ValidatePropertyOperation(original, operations[0], n => n.NullableDateTime,
  495. newValue, OperationType.SetProperty);
  496. }
  497. private static void ValidateComparisonOfObjectsWhenReferencedObjectHasBeenReplaced(DefaultMapper mapper,
  498. OrderDto target, OrderDto clone, DateTime modifiedShipDate, PersonDto modifiedCustomer)
  499. {
  500. var shipDateModified = false;
  501. var customerModified = false;
  502. var newCustomerCreated = false;
  503. var oldCustomerRemoved = false;
  504. var eventRaisingCount = 0;
  505. var customerPropertyCounts = CreateCountsForMutableProperties(typeof (PersonDto), mapper);
  506. Action<Operation> validator = descriptor => {
  507. eventRaisingCount++;
  508. if (ReferenceEquals(target, descriptor.Object)) {
  509. Assert.AreSame(target, descriptor.Object);
  510. switch (descriptor.PropertyPath[0].SystemProperty.Name) {
  511. case "ShipDate":
  512. shipDateModified = true;
  513. Assert.AreEqual(modifiedShipDate, descriptor.Value);
  514. break;
  515. case "Customer":
  516. customerModified = true;
  517. Assert.AreSame(modifiedCustomer, descriptor.Value);
  518. var descriptorCustomer = (PersonDto) descriptor.Value;
  519. Assert.AreEqual(modifiedCustomer.BirthDate, descriptorCustomer.BirthDate);
  520. Assert.AreEqual(modifiedCustomer.FirstName, descriptorCustomer.FirstName);
  521. Assert.AreEqual(modifiedCustomer.Id, descriptorCustomer.Id);
  522. Assert.AreEqual(modifiedCustomer.LastName, descriptorCustomer.LastName);
  523. break;
  524. default:
  525. Assert.Fail();
  526. break;
  527. }
  528. }
  529. else if (ReferenceEquals(modifiedCustomer, descriptor.Object)) {
  530. if (!newCustomerCreated) {
  531. newCustomerCreated = true;
  532. Assert.AreEqual(OperationType.CreateObject, descriptor.Type);
  533. Assert.IsNull(descriptor.PropertyPath);
  534. Assert.IsNull(descriptor.Value);
  535. }
  536. else {
  537. customerPropertyCounts[descriptor.PropertyPath[0].SystemProperty.Name] += 1;
  538. var expectedValue = descriptor.PropertyPath[0].SystemProperty.GetValue(modifiedCustomer, null);
  539. Assert.AreEqual(expectedValue, descriptor.Value);
  540. Assert.AreEqual(OperationType.SetProperty, descriptor.Type);
  541. }
  542. }
  543. else if (ReferenceEquals(target.Customer, descriptor.Object)) {
  544. oldCustomerRemoved = true;
  545. Assert.AreEqual(OperationType.RemoveObject, descriptor.Type);
  546. Assert.IsNull(descriptor.PropertyPath);
  547. Assert.IsNull(descriptor.Value);
  548. }
  549. else
  550. Assert.Fail();
  551. };
  552. ((DefaultOperationLog) mapper.Compare(target, clone).Operations).ForEach(validator);
  553. Assert.AreEqual(7, eventRaisingCount);
  554. Assert.IsTrue(customerPropertyCounts.All(pair => pair.Value == 1));
  555. Assert.IsTrue(shipDateModified);
  556. Assert.IsTrue(customerModified);
  557. Assert.IsTrue(newCustomerCreated);
  558. Assert.IsTrue(oldCustomerRemoved);
  559. }
  560. }
  561. }