CSLA.NET 6.0.0
CSLA .NET is a software development framework that helps you build a reusable, maintainable object-oriented business layer for your app.
GraphMergerTests.cs
Go to the documentation of this file.
1//-----------------------------------------------------------------------
2// <copyright file="GraphMergeTests.cs" company="Marimer LLC">
3// Copyright (c) Marimer LLC. All rights reserved.
4// Website: https://cslanet.com
5// </copyright>
6// <summary>no summary</summary>
7//-----------------------------------------------------------------------
8using System;
9using System.Collections.Generic;
10using System.Linq;
11using System.Text;
12using System.Threading.Tasks;
13using Csla.Core;
14using Csla.TestHelpers;
15
16#if NUNIT
17using NUnit.Framework;
18using TestClass = NUnit.Framework.TestFixtureAttribute;
19using TestInitialize = NUnit.Framework.SetUpAttribute;
20using TestCleanup = NUnit.Framework.TearDownAttribute;
21using TestMethod = NUnit.Framework.TestAttribute;
22#else
23using Microsoft.VisualStudio.TestTools.UnitTesting;
24#endif
25
27{
28 [TestClass]
29 public class GraphMergerTests
30 {
31 private static TestDIContext _testDIContext;
32
34 public static void ClassInitialize(TestContext context)
35 {
36 _testDIContext = TestDIContextFactory.CreateDefaultContext();
37 }
38
39 [TestMethod]
40 public void MergeInsert()
41 {
42 ApplicationContext applicationContext = _testDIContext.CreateTestApplicationContext();
43 IDataPortal<Foo> dataPortal = _testDIContext.CreateDataPortal<Foo>();
44
45 var obj = dataPortal.Create();
46 obj.Name = "1";
47 var cloned = obj.Clone();
48 cloned.Name = "2";
49 cloned.MockUpdated();
50
51 var changed = false;
52 obj.PropertyChanged += (o, e) => { changed = true; };
53
54 var merger = new GraphMerger(applicationContext);
55 merger.MergeGraph(obj, cloned);
56 Assert.AreEqual(cloned.Name, obj.Name);
57 Assert.AreEqual(cloned.IsDirty, obj.IsDirty);
58 Assert.AreEqual(cloned.IsNew, obj.IsNew);
59 Assert.IsFalse(obj.IsNew);
60 Assert.IsFalse(obj.IsDirty);
61 Assert.IsFalse(obj.IsValid);
62 Assert.IsTrue(changed);
63 }
64
65 [TestMethod]
66 public void MergeUpdate()
67 {
68 ApplicationContext applicationContext = _testDIContext.CreateTestApplicationContext();
69 IDataPortal<Foo> dataPortal = _testDIContext.CreateDataPortal<Foo>();
70
71 var obj = dataPortal.Create();
72 obj.Name = "1";
73 obj.MockUpdated();
74 var cloned = obj.Clone();
75 cloned.Name = "2";
76 cloned.MockUpdated();
77
78 var changed = false;
79 obj.PropertyChanged += (o, e) => { changed = true; };
80
81 var merger = new GraphMerger(applicationContext);
82 merger.MergeGraph(obj, cloned);
83 Assert.AreEqual(cloned.Name, obj.Name);
84 Assert.AreEqual(cloned.IsDirty, obj.IsDirty);
85 Assert.AreEqual(cloned.IsNew, obj.IsNew);
86 Assert.IsFalse(obj.IsDirty);
87 Assert.IsFalse(obj.IsValid);
88 Assert.IsTrue(changed);
89 }
90
91 [TestMethod]
92 public void MergeRuleUnbroken()
93 {
94 ApplicationContext applicationContext = _testDIContext.CreateTestApplicationContext();
95 IDataPortal<Foo> dataPortal = _testDIContext.CreateDataPortal<Foo>();
96
97 var obj = dataPortal.Create();
98 obj.Name = "2";
99 obj.MockUpdated();
100 var cloned = obj.Clone();
101 cloned.Name = "1";
102 cloned.MockUpdated();
103
104 var changed = false;
105 obj.PropertyChanged += (o, e) => { changed = true; };
106
107 var merger = new GraphMerger(applicationContext);
108 merger.MergeGraph(obj, cloned);
109 Assert.AreEqual(cloned.Name, obj.Name);
110 Assert.AreEqual(cloned.IsDirty, obj.IsDirty);
111 Assert.AreEqual(cloned.IsNew, obj.IsNew);
112 Assert.IsFalse(obj.IsDirty);
113 Assert.IsTrue(obj.IsValid);
114 Assert.IsTrue(changed);
115 }
116
117 [TestMethod]
118 public void MergeDelete()
119 {
120 ApplicationContext applicationContext = _testDIContext.CreateTestApplicationContext();
121 IDataPortal<Foo> dataPortal = _testDIContext.CreateDataPortal<Foo>();
122
123 var obj = dataPortal.Create();
124 obj.Name = "1";
125 obj.MockUpdated(); // make it an old object
126 obj.MarkForDelete(); // mark for deletion
127 var cloned = obj.Clone();
128 cloned.Name = "2";
129 cloned.MockDeleted(); // mock DP delete result
130
131 var changed = false;
132 obj.PropertyChanged += (o, e) => { changed = true; };
133
134 var merger = new GraphMerger(applicationContext);
135 merger.MergeGraph(obj, cloned);
136 Assert.AreEqual(cloned.Name, obj.Name);
137 Assert.IsTrue(obj.IsNew, "obj.IsTrue");
138 Assert.IsFalse(obj.IsDeleted, "obj.IsDeleted");
139 Assert.AreEqual(cloned.IsDeleted, obj.IsDeleted, "IsDeleted equal");
140 Assert.AreEqual(cloned.IsDirty, obj.IsDirty);
141 Assert.AreEqual(cloned.IsNew, obj.IsNew);
142 Assert.IsFalse(obj.IsValid);
143 Assert.IsTrue(changed);
144 }
145
146 [TestMethod]
147 public void MergeChildInsert()
148 {
149 ApplicationContext applicationContext = _testDIContext.CreateTestApplicationContext();
150 IDataPortal<Foo> dataPortal = _testDIContext.CreateDataPortal<Foo>();
151
152 var obj = dataPortal.Create();
153 obj.Name = "1";
154 obj.AddChild(dataPortal);
155 obj.Child.Name = "42";
156 var cloned = obj.Clone();
157 cloned.Name = "2";
158 cloned.Child.Name = "43";
159 cloned.MockUpdated();
160
161 var changed = false;
162 obj.PropertyChanged += (o, e) => { changed = true; };
163
164 var merger = new GraphMerger(applicationContext);
165 merger.MergeGraph(obj, cloned);
166 Assert.IsFalse(ReferenceEquals(obj.Child, cloned.Child), "ref");
167 Assert.AreEqual(cloned.Child.Name, obj.Child.Name, "name");
168 Assert.AreEqual(cloned.Child.IsDirty, obj.Child.IsDirty, "isdirty");
169 Assert.AreEqual(cloned.Child.IsNew, obj.Child.IsNew, "isnew");
170 Assert.IsFalse(obj.Child.IsNew, "isnew false");
171 Assert.IsFalse(obj.Child.IsDirty, "isdirty false");
172 Assert.IsTrue(obj.Child.IsValid, "isvalid true");
173 Assert.IsTrue(changed, "changed");
174 }
175
176 [TestMethod]
177 public void MergeChildUpdate()
178 {
179 ApplicationContext applicationContext = _testDIContext.CreateTestApplicationContext();
180 IDataPortal<Foo> dataPortal = _testDIContext.CreateDataPortal<Foo>();
181
182 var obj = dataPortal.Create();
183 obj.Name = "1";
184 obj.AddChild(dataPortal);
185 obj.Child.Name = "42";
186 obj.MockUpdated();
187 var cloned = obj.Clone();
188 cloned.Name = "2";
189 cloned.Child.Name = "2";
190 cloned.MockUpdated();
191
192 var changed = false;
193 obj.PropertyChanged += (o, e) => { changed = true; };
194
195 var merger = new GraphMerger(applicationContext);
196 merger.MergeGraph(obj, cloned);
197 Assert.IsFalse(ReferenceEquals(obj.Child, cloned.Child), "ref");
198 Assert.AreEqual(cloned.Child.Name, obj.Child.Name, "name");
199 Assert.AreEqual(cloned.Child.IsDirty, obj.Child.IsDirty, "isdirty");
200 Assert.AreEqual(cloned.Child.IsNew, obj.Child.IsNew, "isnew");
201 Assert.IsFalse(obj.Child.IsNew, "isnew false");
202 Assert.IsFalse(obj.Child.IsDirty, "isdirty false");
203 Assert.IsFalse(obj.Child.IsValid, "isvalid false");
204 Assert.IsTrue(changed, "changed");
205 }
206
207 [TestMethod]
209 {
210 ApplicationContext applicationContext = _testDIContext.CreateTestApplicationContext();
211 IDataPortal<Foo> dataPortal = _testDIContext.CreateDataPortal<Foo>();
212
213 var obj = dataPortal.Create();
214 obj.Name = "1";
215 obj.MockUpdated();
216 var cloned = obj.Clone();
217 cloned.AddChild(dataPortal);
218 cloned.Child.Name = "42";
219 cloned.MockUpdated();
220
221 new GraphMerger(applicationContext).MergeGraph(obj, cloned);
222
223 Assert.IsTrue(ReferenceEquals(obj.Child, cloned.Child), "ref");
224 Assert.IsTrue(ReferenceEquals(obj, obj.Child.Parent));
225 }
226
227 [TestMethod]
228 public void MergeChildDelete()
229 {
230 ApplicationContext applicationContext = _testDIContext.CreateTestApplicationContext();
231 IDataPortal<Foo> dataPortal = _testDIContext.CreateDataPortal<Foo>();
232
233 var obj = dataPortal.Create();
234 obj.Name = "1";
235 obj.AddChild(dataPortal);
236 obj.Child.Name = "42";
237 obj.MockUpdated();
238 obj.MarkForDelete();
239 var cloned = obj.Clone();
240 cloned.Name = "2";
241 cloned.Child.Name = "43";
242 cloned.MockDeleted();
243
244 var changed = false;
245 obj.PropertyChanged += (o, e) => { changed = true; };
246
247 var merger = new GraphMerger(applicationContext);
248 merger.MergeGraph(obj, cloned);
249 Assert.IsFalse(ReferenceEquals(obj.Child, cloned.Child), "ref");
250 Assert.AreEqual(cloned.Child.Name, obj.Child.Name, "name");
251 Assert.AreEqual(cloned.Child.IsDirty, obj.Child.IsDirty, "isdirty");
252 Assert.AreEqual(cloned.Child.IsNew, obj.Child.IsNew, "isnew");
253 Assert.IsTrue(obj.Child.IsNew, "isnew true");
254 Assert.IsTrue(obj.Child.IsDirty, "isdirty true");
255 Assert.IsTrue(obj.Child.IsValid, "isvalid true");
256 Assert.IsTrue(changed, "changed");
257 }
258
259 [TestMethod]
260
261 public void MergeList()
262 {
263 ApplicationContext applicationContext = _testDIContext.CreateTestApplicationContext();
264 IDataPortal<FooList> dataPortal = _testDIContext.CreateDataPortal<FooList>();
265
266 var obj = dataPortal.Create();
267 obj.AddNew().Name = "existing";
268 obj[0].MockUpdated();
269 obj.AddNew().Name = "to be deleted";
270 obj.Remove(obj[1]);
271 obj.AddNew().Name = "new";
272 obj.AddNew().Name = "remove in clone";
273 Assert.AreEqual(3, obj.Count, "preclone count");
274 var cloned = obj.Clone();
275 Assert.AreEqual(3, cloned.Count, "postclone count");
276 cloned.Remove(cloned.Where(_ => _.Name == "remove in clone").First());
277 Assert.AreEqual(2, cloned.Count, "postclone count after removed obj");
278 Assert.AreEqual(cloned[0].Name, obj[0].Name, "postclone [0]");
279 Assert.AreEqual(cloned[1].Name, obj[1].Name, "postclone [1]");
280 cloned[0].Name = "existing (cloned)";
281 cloned[1].Name = "new (cloned)";
282 cloned.AddNew().Name = "new in clone";
283 cloned.MockUpdated();
284
285 var merger = new GraphMerger(applicationContext);
286 merger.MergeBusinessListGraph<FooList, Foo>(obj, cloned);
287 Assert.AreEqual(cloned.Count, obj.Count, "count");
288 Assert.AreEqual(3, obj.Count, "count 3");
289 Assert.AreEqual(cloned[0].Name, obj[0].Name, "[0]");
290 Assert.AreEqual(cloned[1].Name, obj[1].Name, "[1]");
291 Assert.AreEqual(cloned[2].Name, obj[2].Name, "[2]");
292 Assert.AreEqual(cloned.IsDirty, obj.IsDirty);
293 Assert.IsFalse(obj.IsDirty);
294 }
295
296 [TestMethod]
297 public void MergeListNewChild()
298 {
299 ApplicationContext applicationContext = _testDIContext.CreateTestApplicationContext();
300 IDataPortal<FooList> dataPortal = _testDIContext.CreateDataPortal<FooList>();
301
302 var obj = dataPortal.Create();
303 var original = obj;
304 var newChild = obj.AddNew();
305 newChild.Name = "new";
306
307 var bo = (IBusinessObject)newChild;
308 Assert.IsTrue(bo.Identity >= 0, "bo needs identity");
309
310 var saved = obj.Save();
311 Assert.AreEqual(((IBusinessObject)newChild).Identity, ((IBusinessObject)saved[0]).Identity, "identity should survive save");
312
313 Assert.IsTrue(!ReferenceEquals(obj[0], saved[0]), "saved object is not original");
314
315 new GraphMerger(applicationContext).MergeBusinessListGraph<FooList, Foo>(obj, saved);
316
317 Assert.AreEqual(((IBusinessObject)newChild).Identity, ((IBusinessObject)obj[0]).Identity);
318 Assert.AreEqual(((IBusinessObject)newChild).Identity, ((IBusinessObject)saved[0]).Identity);
319 Assert.AreEqual(((IBusinessObject)obj[0]).Identity, ((IBusinessObject)saved[0]).Identity);
320
321 Assert.AreEqual(obj[0].IsNew, saved[0].IsNew);
322
323 Assert.IsFalse(ReferenceEquals(original, saved));
324 Assert.IsTrue(ReferenceEquals(original, obj));
325
326 Assert.IsTrue(ReferenceEquals(original[0], obj[0]));
327 Assert.IsTrue(ReferenceEquals(newChild, obj[0]));
328
329 obj[0].Name = "changed";
330 Assert.AreEqual(original[0].Name, obj[0].Name);
331 }
332
333 [TestMethod]
334 public void MergeChildList()
335 {
336 ApplicationContext applicationContext = _testDIContext.CreateTestApplicationContext();
337 IDataPortal<Foo> dataPortal = _testDIContext.CreateDataPortal<Foo>();
338
339 var obj = dataPortal.Create();
340 obj.ChildList.AddNew();
341 obj.ChildList[0].Name = "1";
342 obj.ChildList.AddNew();
343 obj.ChildList[1].Name = "12";
344 obj.MockUpdated();
345 var cloned = obj.Clone();
346 cloned.ChildList[0].Name = "2";
347 cloned.ChildList.RemoveAt(1);
348 cloned.ChildList.AddNew();
349 cloned.ChildList[1].Name = "42";
350 cloned.MockUpdated();
351
352 var merger = new GraphMerger(applicationContext);
353 merger.MergeGraph(obj, cloned);
354 Assert.IsFalse(ReferenceEquals(obj.ChildList, cloned.ChildList), "ref");
355 Assert.AreEqual(2, obj.ChildList.Count, "count");
356 Assert.IsFalse(obj.ChildList[0].IsValid, "[0] isvalid");
357 Assert.IsTrue(obj.ChildList[1].IsValid, "[1] isvalid");
358 Assert.IsFalse(obj.ChildList.IsValid, "isvalid");
359 Assert.AreEqual("2", obj.ChildList[0].Name, "[0] name");
360 Assert.AreEqual("42", obj.ChildList[1].Name, "[1] name");
361 Assert.IsFalse(ReferenceEquals(obj.ChildList[0], cloned.ChildList[0]), "[0] ref");
362 Assert.IsTrue(ReferenceEquals(obj.ChildList[1], cloned.ChildList[1]), "[1] ref");
363 Assert.IsTrue(ReferenceEquals(obj.ChildList, obj.ChildList[1].Parent), "parent ref");
364 }
365
366 }
367}
Provides consistent context information between the client and server DataPortal objects.
Implements behavior to merge one object graph into a clone of itself (typically post-serialization).
Definition: GraphMerger.cs:20
void MergeGraph(IEditableBusinessObject target, IEditableBusinessObject source)
Merges state from source graph into target graph.
Definition: GraphMerger.cs:33
static void ClassInitialize(TestContext context)
Type to carry context information for DI in unit tests
This is the core interface implemented by all CSLA .NET base classes.
Interface defining the members of the data portal type.
Definition: IDataPortalT.cs:17
object Create(params object[] criteria)
Called by a factory method in a business class to create a new object, which is loaded with default v...