public override object ApplyUndoRedoDiff(object diff) { ObjectDiff[] data = (ObjectDiff[])diff; XmlElement status = UndoManager.GetObjectStatus(this); XmlElement oldElem = (XmlElement)status.CloneNode(true); ObjectDiff propsDiff = data [0]; if (propsDiff != null) { propDiffGenerator.ApplyDiff(status, propsDiff); ReadProperties(new ObjectReader(Project, FileFormat.Native), status); data [0] = propDiffGenerator.GetDiff(status, oldElem); } ObjectDiff actionsDiff = data [1]; if (actionsDiff != null) { LocalActionGroups.ApplyDiff(Project, actionsDiff); data [1] = LocalActionGroups.GetDiff(Project, oldElem); } return(data); }
public void ReadWithSchemaFirst() { string json = @"{ 'StringProperty': 'Text', 'IntProperty': 42, 'DoubleProperty': 10.2, 'NullableIntProperty': null, 'BoolProperty': true, 'DateProperty': '2020-12-26', 'StringArray':['a1','a2'], 'IntArray':[1,2], '$metadata.schema.compact': [ 'StringProperty@type=string', 'IntProperty@type=int', 'DoubleProperty@type=double', 'NullableIntProperty@type=int?', 'BoolProperty @type = bool', 'DateProperty@type=LocalDate', 'StringArray@type=string[]', 'IntArray@type=int[]' ] }"; var initialContainer = CreateTestContainer(); var restoredContainer = json.DeserializeWithNewtonsoftJson <IPropertyContainer>(configureSerialization: options => options.ReadSchemaFirst = true); ObjectDiff objectDiff = MetadataComparer.GetDiff(restoredContainer, initialContainer); objectDiff.Diffs.Should().BeEmpty(); // container will lose types var restoredContainer2 = json.DeserializeWithNewtonsoftJson <IPropertyContainer>(configureSerialization: options => options.ReadSchemaFirst = false); ObjectDiff objectDiff2 = MetadataComparer.GetDiff(restoredContainer2, initialContainer); objectDiff2.Diffs.Should().NotBeNullOrEmpty(); }
public void OnlyMismatchedRemain() { var obj = new ObjectDiff() { BaseValue = 1, EvaluatedValue = 1, Items = new List <BaseDiff>() { new BaseDiff() { BaseValue = 2, EvaluatedValue = 2 }, new BaseDiff() { BaseValue = 3, EvaluatedValue = 1 } } }; var result = obj.WithoutMatching(); Assert.Equal(1, result.Count); Assert.Equal(false, result.First().ValuesMatch); }
public void EnumerateProperties_JObject() { GameThread.IgnoreThreadRestrictions = true; using (var ge = new GameEngine(null)) { ge.EngineInitialized.WaitOne(); var objs = new List <object>(); var adders = new { a = 12, b = 14, c = new { d = 15 } }; var obj = JObject.FromObject(adders); var props = ObjectDiff.EnumerateProperties(obj).ToDictionary(x => x.Name, x => x.Value); Assert.AreEqual(12, ((JValue)props["a"]).Value); Assert.AreEqual(14, ((JValue)props["b"]).Value); } }
public void DiffKeysWithArrays() { using (var engine = new JavascriptEngine()) { engine.Execute("var a = {};"); var startObj = engine.ExecuteAndReturn("a"); engine.Execute("var a = {};"); engine.Execute("a.users = []"); var endObj = engine.ExecuteAndReturn("a"); // Added var diff = new ObjectDiff(); diff.Diff(startObj, endObj, "a"); Assert.AreEqual(1, diff.Added.Count); Assert.AreEqual("a.users", diff.Added.Keys.First(), "It actually equals " + diff.Added.Keys.First()); var val = JsonConvert.SerializeObject(diff.Added.First().Value); Assert.AreEqual("[]", val); } using (var engine = new JavascriptEngine()) { engine.Execute("var a = {};"); engine.Execute("a.users = []"); var startObj = engine.ExecuteAndReturn("a"); engine.Execute("var a = {};"); engine.Execute("a.users = []"); engine.Execute("a.users[1] = 12"); var endObj = engine.ExecuteAndReturn("a"); // Added var diff = new ObjectDiff(); diff.Diff(startObj, endObj, "a"); Assert.AreEqual(2, diff.Added.Count); Assert.True(diff.Added.ContainsKey("a.users[0]")); Assert.True(diff.Added.ContainsKey("a.users[1]")); // Deleted diff = new ObjectDiff(); diff.Diff(endObj, startObj, "a"); Assert.AreEqual(2, diff.Deleted.Count); Assert.True(diff.Deleted.Contains("a.users[0]")); Assert.True(diff.Deleted.Contains("a.users[1]")); // Modified engine.Execute("var a = {};"); engine.Execute("a.users = []"); engine.Execute("a.users[1] = 14"); var changedObj = engine.ExecuteAndReturn("a"); diff = new ObjectDiff(); diff.Diff(endObj, changedObj, "a"); Assert.AreEqual(1, diff.Modified.Count); Assert.AreEqual("a.users[1]", diff.Modified.Keys.First(), "It actually equals " + diff.Modified.Keys.First()); } }
public async Task DiffSizeDoNotMatchRightLongerTest() { int id = 2; HttpResponseMessage httpResponseMessage; //set left property using (httpResponseMessage = HttpClient.PutAsJsonAsync(String.Format(PutLeftUrl, id), new ObjectData { data = "AQA=" }).Result) { Assert.AreEqual(HttpStatusCode.Created, httpResponseMessage.StatusCode); } //set right property using (httpResponseMessage = HttpClient.PutAsJsonAsync(String.Format(PutRightUrl, id), new ObjectData { data = "AQABAQ==" }).Result) { Assert.AreEqual(HttpStatusCode.Created, httpResponseMessage.StatusCode); } //get diff using (httpResponseMessage = HttpClient.GetAsync(String.Format(GetDiffUrl, id)).Result) { Assert.AreEqual(HttpStatusCode.OK, httpResponseMessage.StatusCode); ObjectDiff objectDiff = await httpResponseMessage.Content.ReadAsAsync <ObjectDiff>(); Assert.AreEqual(objectDiff.diffResultType, DiffResultType.SizeDoNotMatch); } }
public void SerializeDeserializePropertyContainer() { var initialContainer = CreateTestContainer(); var propertyContainerContract = initialContainer.ToContract(new DefaultMapperSettings()); propertyContainerContract.Should().NotBeNull(); var contractJson = propertyContainerContract.ToJsonWithSystemTextJson(); var json1 = initialContainer.ToJsonWithSystemTextJson(); var jsonOptions = new JsonSerializerOptions().ConfigureJsonOptions(); DeserializeAndCompare <IPropertyContainer>(); DeserializeAndCompare <PropertyContainer>(); DeserializeAndCompare <IMutablePropertyContainer>(); DeserializeAndCompare <MutablePropertyContainer>(); DeserializeAndCompare <PropertyContainer <TestMeta> >(); var json2 = initialContainer.ToJsonWithNewtonsoftJson(); var container2 = json2.DeserializeWithNewtonsoftJson <IPropertyContainer>(); ObjectDiff objectDiff = MetadataComparer.GetDiff(initialContainer, container2); objectDiff.Diffs.Should().BeEmpty(); void DeserializeAndCompare <TContainer>() where TContainer : IPropertyContainer { TContainer?restored = JsonSerializer.Deserialize <TContainer>(json1, jsonOptions); ObjectDiff objectDiff = MetadataComparer.GetDiff(restored, initialContainer); objectDiff.Diffs.Should().BeEmpty(); } }
public void Patch() { var po = ObjectDiff.ToJObject(new { a = 1, b = 2, c = new { d = 3 } }); var co = ObjectDiff.ToJObject(new { a = 1, b = 2, c = new { d = 3 } }); co["a"] = 2; (co["c"] as JObject).Add("e", 4); ((JObject)co).Remove("b"); var diff = new ObjectDiff(po, co); var patch = diff.Patch(po) as JObject; Assert.AreEqual(((JValue)co["a"]).Value, ((JValue)patch["a"]).Value); Assert.IsNull(patch.Property("b")); Assert.AreEqual(4, ((JValue)((JObject)patch["c"])["e"]).Value); }
private static string ToTextDiff(Diff diff) { return(diff switch { TypeDiff typeDiff => ToTypeTextDiff(typeDiff), ValueDiff valueDiff => ToValueTypeTextDiff(valueDiff), ArrayDiff arrayDiff => ToArrayTextDiff(arrayDiff), ObjectDiff objectDiff => ToObjectTextDiff(objectDiff), _ => throw new Exception("Unknown diff type") });
internal void UpdateState(ObjectDiff diff) { lock (this) { _state.Add(diff.Id, diff); _fullState = diff.Patch(_fullState); _client.UIRPC.FireStateUpdated(diff); } }
public override object GetUndoDiff() { XmlElement oldElem = UndoManager.GetObjectStatus(this); UndoWriter writer = new UndoWriter(oldElem.OwnerDocument, UndoManager); XmlElement newElem = Write(writer); ObjectDiff actionsDiff = GetDiffGenerator().GetDiff(this, oldElem); UndoManager.UpdateObjectStatus(this, newElem); return(actionsDiff); }
public void StateChange(int id, ObjectDiff diff) { if (id != _lastState + 1) { //TODO should check to see if we missed a state change // Cause we know they'll happen in order throw new NotImplementedException(); } _lastState = id; _state.UpdateState(diff); }
public void LeftIs1ByteLongAndRightIs2ByteLongTest() { byte[] left = { 0, 0 }; byte[] right = { 0 }; ObjectDiff objectDiff = _differ.GetDiff(left, right); Assert.IsNotNull(objectDiff); Assert.AreEqual(DiffResultType.SizeDoNotMatch, objectDiff.diffResultType); Assert.IsNull(objectDiff.diffs); }
public void LeftAndRightAre2ByteLongEqualsTest() { byte[] left = { 0, 0 }; byte[] right = { 0, 0 }; ObjectDiff objectDiff = _differ.GetDiff(left, right); Assert.IsNotNull(objectDiff); Assert.AreEqual(DiffResultType.Equals, objectDiff.diffResultType); Assert.IsNull(objectDiff.diffs); }
public void LeftAndRightAreEmptyTest() { byte[] left = new byte[0]; byte[] right = new byte[0]; ObjectDiff objectDiff = _differ.GetDiff(left, right); Assert.IsNotNull(objectDiff); Assert.AreEqual(DiffResultType.Equals, objectDiff.diffResultType); Assert.IsNull(objectDiff.diffs); }
public void FireStateUpdated(ObjectDiff obj) { dynamic[] cs = new dynamic[0]; lock (_clients) { cs = _clients.ToArray(); } foreach (var c in cs) { c.FireStateUpdated(obj); } }
public void LeftAndRightAreDifferentInEveryByteTest() { byte[] left = { 1, 1, 1, 1 }; byte[] right = { 0, 0, 0, 0 }; ObjectDiff objectDiff = _differ.GetDiff(left, right); Assert.IsNotNull(objectDiff); Assert.AreEqual(DiffResultType.ContentDoNotMatch, objectDiff.diffResultType); Assert.IsNotNull(objectDiff.diffs); Assert.AreEqual(objectDiff.diffs.Count, 1); Assert.AreEqual(objectDiff.diffs[0].offset, 0); Assert.AreEqual(objectDiff.diffs[0].length, 4); }
public ObjectDiff ProcessChanges() { var diff = new ObjectDiff(); if (diff.Diff(_prevObject, _object)) { diff.Id = ++_prevId; // Store those changes(patch) _changes.Add(diff.Id, diff); // Update the _objectProps object with new object _prevObject = ObjectDiff.ToJObject(_object); } return(diff); }
public override object ApplyUndoRedoDiff(object diff) { ObjectDiff actionsDiff = (ObjectDiff)diff; XmlElement status = UndoManager.GetObjectStatus(this); DiffGenerator differ = GetDiffGenerator(); differ.ApplyDiff(this, actionsDiff); actionsDiff = differ.GetDiff(this, status); UndoWriter writer = new UndoWriter(status.OwnerDocument, UndoManager); XmlElement newElem = Write(writer); UndoManager.UpdateObjectStatus(this, newElem); return(actionsDiff); }
public override object GetUndoDiff() { XmlElement oldElem = UndoManager.GetObjectStatus(this); XmlElement newElem = WriteProperties(new ObjectWriter(oldElem.OwnerDocument, FileFormat.Native)); ObjectDiff propsDiff = propDiffGenerator.GetDiff(newElem, oldElem); ObjectDiff actionsDiff = LocalActionGroups.GetDiff(Project, oldElem); UndoManager.UpdateObjectStatus(this, newElem); if (propsDiff == null && actionsDiff == null) { return(null); } else { return new ObjectDiff[] { propsDiff, actionsDiff } }; }
public void IsArray() { var js = new JavascriptEngine(); var arrays = new object[] { js.ExecuteAndReturn("[\"a\"]"), new string[1] { "a" }, }; var notArrays = new object[] { js.ExecuteAndReturn("\"a\""), new ExpandoObject(), new Dictionary <int, string>() }; for (var i = 0; i < arrays.Length; i++) { try { Assert.True(ObjectDiff.IsArray(arrays[i]), "Item {0} is an array", i); } catch (Exception e) { throw new Exception($"Item {i} in arrays threw an exception", e); } } for (var i = 0; i < notArrays.Length; i++) { try { Assert.False(ObjectDiff.IsArray(notArrays[i]), "Item {0} is not an array", i); } catch (Exception e) { throw new Exception($"Item {i} in notArrays threw an exception", e); } } }
public async Task DiffContentDoNotMatchTest() { int id = 2; HttpResponseMessage httpResponseMessage; //set left property using (httpResponseMessage = HttpClient.PutAsJsonAsync(String.Format(PutLeftUrl, id), new ObjectData { data = "AAAAAA==" }).Result) { Assert.AreEqual(HttpStatusCode.Created, httpResponseMessage.StatusCode); } //set right property using (httpResponseMessage = HttpClient.PutAsJsonAsync(String.Format(PutRightUrl, id), new ObjectData { data = "AQABAQ==" }).Result) { Assert.AreEqual(HttpStatusCode.Created, httpResponseMessage.StatusCode); } //get diff using (httpResponseMessage = HttpClient.GetAsync(String.Format(GetDiffUrl, id)).Result) { Assert.AreEqual(HttpStatusCode.OK, httpResponseMessage.StatusCode); ObjectDiff objectDiff = await httpResponseMessage.Content.ReadAsAsync <ObjectDiff>(); Assert.AreEqual(objectDiff.diffResultType, DiffResultType.ContentDoNotMatch); Assert.AreEqual(objectDiff.diffs.Count, 2); //expect 2 contents diffs Assert.AreEqual(objectDiff.diffs[0].offset, 0); //1 diff Assert.AreEqual(objectDiff.diffs[0].length, 1); Assert.AreEqual(objectDiff.diffs[1].offset, 2); //2 diff Assert.AreEqual(objectDiff.diffs[1].length, 2); } }
public void EmptyIfMatching() { var obj = new ObjectDiff() { BaseValue = 1, EvaluatedValue = 1, Items = new List <BaseDiff>() { new BaseDiff() { BaseValue = 2, EvaluatedValue = 2 }, new BaseDiff() { BaseValue = 3, EvaluatedValue = 3 } } }; var result = obj.WithoutMatching(); Assert.Equal(0, result.Count); }
/// <summary> /// . Obtains the difference between two JSON objects, either an Entity or a Structure. . /// </summary> /// <param name="ssOriginalObject">. Object in its original state (no change). .</param> /// <param name="ssModifiedObject">. Object in its modified state (with change). .</param> /// <param name="ssIgnoreItems">. List of items / attributes to be ignored by the comparison...</param> /// <param name="ssResultProcessing">. Object containing attributes that have different values between the Original and Modified states or when there is an error, it returns true and the error message.</param> public void MssGetDiff(string ssOriginalObject, string ssModifiedObject, RLIgnoreItemRecordList ssIgnoreItems, out RCObjectChangedErrorRecord ssResultProcessing) { int TrackChanges_Version = 2; RCObjectChangedErrorRecord rCObjectChangedErrorRecord = new RCObjectChangedErrorRecord(null); try { List <string> ignoreAttrib = new List <string>(); foreach (RCIgnoreItemRecord rCIgnoreItemRecord in ssIgnoreItems.Data) { ignoreAttrib.Add(rCIgnoreItemRecord.ssSTIgnoreItem.ssItem); } switch (TrackChanges_Version) { case 1: TrackChangesInvok trackChangesInvok = new TrackChangesInvok(ssOriginalObject, ssModifiedObject, ignoreAttrib); ObjectDiff objectDiff = trackChangesInvok.DiffJSON(); rCObjectChangedErrorRecord.ssSTObjectChanged.ssName = objectDiff.ObjectName; objectDiff.Items.ForEach(delegate(ItemDiff itemDiff) { RCItemChangedRecord rCItemChangedRecord = new RCItemChangedRecord(); rCItemChangedRecord.ssSTItemChanged.ssAttribute = itemDiff.AttributeName; rCItemChangedRecord.ssSTItemChanged.ssOriginalValue = itemDiff.Values[0]; rCItemChangedRecord.ssSTItemChanged.ssModifieldValue = itemDiff.Values[1]; rCObjectChangedErrorRecord.ssSTObjectChanged.ssAttributies.Append(record: rCItemChangedRecord); }); break; case 2: TrackChangesV2.TrackChanges trackChangesV2 = new TrackChangesV2.TrackChanges(originalOjbectJSON: ssOriginalObject, modifieldObjectJSON: ssModifiedObject, ignoreFields: ignoreAttrib); trackChangesV2.ProcessTrackChanges().ForEach(delegate(TrackChangesV2.ItemMerge itemMerge) { RCItemChangedRecord rCItemChangedRecord = new RCItemChangedRecord(); rCItemChangedRecord.ssSTItemChanged.ssAttribute = itemMerge.Name; rCItemChangedRecord.ssSTItemChanged.ssOriginalValue = itemMerge.ActualValue; rCItemChangedRecord.ssSTItemChanged.ssModifieldValue = itemMerge.NewValue; rCObjectChangedErrorRecord.ssSTObjectChanged.ssAttributies.Append(record: rCItemChangedRecord); }); break; } ssResultProcessing = rCObjectChangedErrorRecord; } catch (Exception e) { rCObjectChangedErrorRecord.ssSTError.ssIsError = true; rCObjectChangedErrorRecord.ssSTError.ssErrorMessage = string.Concat(e.Message); ssResultProcessing = rCObjectChangedErrorRecord; } // TODO: Write implementation for action } // MssGetDiff
internal void ApplyDiff(IProject prj, ObjectDiff diff) { GetDiffGenerator(prj).ApplyDiff(this, diff); }
public void Diff() { GameThread.IgnoreThreadRestrictions = true; using (var ge = new GameEngine(null)) { ge.EngineInitialized.WaitOne(); var diff = new ObjectDiff(); dynamic sobj = new ExpandoObject(); dynamic eobj = new ExpandoObject(); eobj.Tim = new ExpandoObject(); eobj.Tim.bill = 12; diff.Diff(sobj, eobj); Assert.AreEqual(diff.Added["Tim"], ObjectDiff.ToJObject(eobj.Tim)); Assert.IsEmpty(diff.Deleted); Assert.IsEmpty(diff.Modified); // Equal diff = new ObjectDiff(); sobj = eobj; eobj = new ExpandoObject(); eobj.Tim = new ExpandoObject(); eobj.Tim.bill = 12; diff.Diff(sobj, eobj); Assert.IsEmpty(diff.Added); Assert.IsEmpty(diff.Deleted); Assert.IsEmpty(diff.Modified); // Modify diff = new ObjectDiff(); sobj = eobj; eobj = new ExpandoObject(); eobj.Tim = new ExpandoObject(); eobj.Tim.bill = "chicken"; diff.Diff(sobj, eobj); Assert.IsEmpty(diff.Added); Assert.IsEmpty(diff.Deleted); Assert.AreEqual(((JValue)diff.Modified["Tim.bill"]).Value, "chicken"); // Delete diff = new ObjectDiff(); sobj = eobj; eobj = new ExpandoObject(); eobj.Tim = new ExpandoObject(); diff.Diff(sobj, eobj); Assert.IsEmpty(diff.Added); Assert.IsEmpty(diff.Modified); Assert.Contains("Tim.bill", diff.Deleted); eobj = new ExpandoObject(); diff.Diff(sobj, eobj); Assert.IsEmpty(diff.Added); Assert.IsEmpty(diff.Modified); Assert.Contains("Tim", diff.Deleted); } }
public void TestPropertiesDiffEquality() { var diff = new ObjectDiff(new DiffPoint("$", new JsonObject(new Dictionary <string, JsonValue> { { "author", new JsonString("William Kent") }, { "title", new JsonString("Data and Reality") } }), new JsonObject(new Dictionary <string, JsonValue> { { "author", new JsonString("William Kent") }, { "title", new JsonString("Data and Reality") }, { "edition", new JsonString("2nd") } })), new PropertyMismatch[] { new RightOnlyProperty("edition", new JsonString("2nd")) } ); var sameDiff = new ObjectDiff(new DiffPoint("$", new JsonObject(new Dictionary <string, JsonValue> { { "author", new JsonString("William Kent") }, { "title", new JsonString("Data and Reality") } }), new JsonObject(new Dictionary <string, JsonValue> { { "author", new JsonString("William Kent") }, { "title", new JsonString("Data and Reality") }, { "edition", new JsonString("2nd") } })), new PropertyMismatch[] { new RightOnlyProperty("edition", new JsonString("2nd")) } ); var anotherDiff = new ObjectDiff(new DiffPoint("$.books[0]", new JsonObject(new Dictionary <string, JsonValue> { { "author", new JsonString("William Kent") }, { "title", new JsonString("Data and Reality") } }), new JsonObject(new Dictionary <string, JsonValue> { { "author", new JsonString("William Kent") }, { "title", new JsonString("Data and Reality") }, { "edition", new JsonString("2nd") } })), new PropertyMismatch[] { new RightOnlyProperty("edition", new JsonString("2nd")) } ); var yetAnotherDiff = new ObjectDiff(new DiffPoint("$", new JsonObject(new Dictionary <string, JsonValue> { { "author", new JsonString("William Kent") }, { "title", new JsonString("Data and Reality") } }), new JsonObject(new Dictionary <string, JsonValue> { { "author", new JsonString("William Kent") }, { "title", new JsonString("Data and Reality") }, { "edition", new JsonString("3rd") } })), new PropertyMismatch[] { new RightOnlyProperty("edition", new JsonString("3rd")) } ); Assert.Equal(diff, sameDiff); Assert.NotEqual(diff, anotherDiff); Assert.NotEqual((Diff)diff, anotherDiff); Assert.NotEqual((object)diff, anotherDiff); Assert.NotEqual(diff, yetAnotherDiff); Assert.NotEqual(anotherDiff, yetAnotherDiff); Assert.Equal("ObjectDiff { Path = $, Left = Object {2 properties}, Right = Object {3 properties} }", diff.ToString()); }
public void IsValue_True([Values(null, "asdf", "", 12, 1.2)] object obj) { Assert.True(ObjectDiff.IsValue(obj)); }
public void EnumerateProperties() { GameThread.IgnoreThreadRestrictions = true; using (var ge = new GameEngine(null)) { ge.EngineInitialized.WaitOne(); var objs = new List <object>(); var adders = new { a = 12, b = 14, c = new { d = 15 } }; var adderProps = adders.GetType().GetProperties(); IDictionary <string, object> adderPropsDick = adderProps.ToDictionary(x => x.Name, x => x.GetValue(adders)); { dynamic obj = new ExpandoObject(); foreach (var prop in adderPropsDick) { (obj as IDictionary <string, object>).Add(prop.Key, prop.Value); } objs.Add(obj); } { StateClass obj = new StateClass(ge); foreach (var prop in adderPropsDick) { Dynamic.InvokeSet(obj, prop.Key, prop.Value); } objs.Add(obj); } { objs.Add(adders); objs.Add(adderPropsDick); objs.Add(adderPropsDick.AsEnumerable()); } foreach (var obj in objs) { var objProps = ObjectDiff.EnumerateProperties(obj) .Where(x => x.Name != "users") .ToArray(); foreach (var prop in objProps) { Assert.Contains(prop.Name, adderPropsDick.Keys.ToArray()); Assert.AreEqual(prop.Value, adderPropsDick[prop.Name]); } foreach (var prop in adderPropsDick) { Assert.Contains(prop.Key, objProps.Select(x => x.Name).ToArray()); Assert.AreEqual(prop.Value, objProps.First(x => x.Name == prop.Key).Value); } } } }
public void IsValue_False() { Assert.False(ObjectDiff.IsValue(new object())); }