public void GenerateAndApplyReversePatch() { var initial = new PhoneBook() { Entries = new Dictionary <string, TestPerson>() { ["0800JOHNDOE"] = new TestPerson() { FirstName = "John", LastName = "Doe", IsAdult = true, }, ["0800JANEDOE"] = new TestPerson() { FirstName = "Jane", LastName = "Doe", IsAdult = true, }, }, }; using DraftScope scope = (DraftScope)DraftExtensions.CreateDraft(initial, out PhoneBook draft); var patchGenerator = new DictionaryPatchGenerator(); var patches = new JsonPatchDocument(); var inversePatches = new JsonPatchDocument(); draft.Entries.Remove("0800JANEDOE"); draft.Entries.Add("0800BABYDOE", new TestPerson() { FirstName = "Baby", LastName = "Doe", }); // trick the scope into thinking that is finishing and should not create proxies anymore. scope.IsFinishing = true; patchGenerator.Generate((IDraft)draft.Entries, "/Entries", patches, inversePatches); // inverse order of inverse patches. inversePatches.Operations.Reverse(); var final = scope.FinishDraft <PhoneBook, IPhoneBook>(draft); var result = IPhoneBook.Produce(initial, p => { patches.ApplyTo(p); }); result = result.Produce(p => { inversePatches.ApplyTo(p); }); Assert.Equal(2, result.Entries.Count); Assert.Same(initial.Entries["0800JOHNDOE"], result.Entries["0800JOHNDOE"]); Assert.Same(initial.Entries["0800JANEDOE"], result.Entries["0800JANEDOE"]); }
public void GenerateAndApplyPatch() { var initial = new TestPerson() { FirstName = "John", LastName = "Doe", IsAdult = true, }; using var scope = DraftExtensions.CreateDraft(initial, out TestPerson draft); draft.FirstName = "Jane"; draft.LastName = null; draft.FirstChild = new TestPerson() { FirstName = "Baby", LastName = "Doe", }; var patchGenerator = new ObjectPatchGenerator(); var patches = new JsonPatchDocument(); var inversePatches = new JsonPatchDocument(); patchGenerator.Generate((IDraft)draft, "/", patches, inversePatches); // inverse order of inverse patches. inversePatches.Operations.Reverse(); var final = scope.FinishDraft <TestPerson, ITestPerson>(draft); var result = ITestPerson.Produce(initial, p => { patches.ApplyTo(p); }); Assert.Equal(final.FirstName, result.FirstName); Assert.Equal(final.LastName, result.LastName); Assert.Equal(final.FirstChild.FirstName, result.FirstChild.FirstName); Assert.Equal(final.FirstChild.LastName, result.FirstChild.LastName); }
public void GenerateDictionaryPatch() { var initial = new PhoneBook() { Entries = new Dictionary <string, TestPerson>() { ["0800JOHNDOE"] = new TestPerson() { FirstName = "John", LastName = "Doe", IsAdult = true, }, ["0800JANEDOE"] = new TestPerson() { FirstName = "Jane", LastName = "Doe", IsAdult = true, }, }, }; using var scope = DraftExtensions.CreateDraft(initial, out PhoneBook draft); var patchGenerator = new DictionaryPatchGenerator(); var patches = new JsonPatchDocument(); var inversePatches = new JsonPatchDocument(); draft.Entries.Remove("0800JANEDOE"); draft.Entries.Add("0800BABYDOE", new TestPerson() { FirstName = "Baby", LastName = "Doe", }); patchGenerator.Generate((IDraft)draft.Entries, "/Entries", patches, inversePatches); // inverse order of inverse patches. inversePatches.Operations.Reverse(); JsonAssert.Equal( @" [ { 'path': '/Entries/0800JANEDOE', 'op': 'remove' }, { 'value': { 'Cars': null, 'FirstName': 'Baby', 'LastName': 'Doe', 'IsAdult': false, 'FirstChild': null, 'SecondChild': null }, 'path': '/Entries/0800BABYDOE', 'op': 'add' } ] ", JsonConvert.SerializeObject(patches)); JsonAssert.Equal( @" [ { 'path': '/Entries/0800BABYDOE', 'op': 'remove' }, { 'value': { 'FirstName': 'Jane', 'LastName': 'Doe', 'IsAdult': true, 'FirstChild': null, 'SecondChild': null, 'Cars': null }, 'path': '/Entries/0800JANEDOE', 'op': 'add' } ] ", JsonConvert.SerializeObject(inversePatches)); }
public void GenerateObjectPatch() { var initial = new TestPerson() { FirstName = "John", LastName = "Doe", IsAdult = true, }; using var scope = DraftExtensions.CreateDraft(initial, out TestPerson draft); draft.FirstName = "Jane"; draft.LastName = null; draft.FirstChild = new TestPerson() { FirstName = "Baby", LastName = "Doe", }; var patchGenerator = new ObjectPatchGenerator(); var patches = new JsonPatchDocument(); var inversePatches = new JsonPatchDocument(); patchGenerator.Generate((IDraft)draft, "/", patches, inversePatches); // inverse order of inverse patches. inversePatches.Operations.Reverse(); JsonAssert.Equal( @" [ { 'value': 'Jane', 'path': '/FirstName', 'op': 'replace' }, { 'path': '/LastName', 'op': 'remove' }, { 'value': { 'FirstName': 'Baby', 'LastName': 'Doe', 'IsAdult': false, 'FirstChild': null, 'SecondChild': null, 'Cars': null }, 'path': '/FirstChild', 'op': 'add' } ] ", JsonConvert.SerializeObject(patches)); JsonAssert.Equal( @" [ { 'path': '/FirstChild', 'op': 'remove' }, { 'value': 'Doe', 'path': '/LastName', 'op': 'add' }, { 'value': 'John', 'path': '/FirstName', 'op': 'replace' } ] ", JsonConvert.SerializeObject(inversePatches)); }
public void ApplyInverseComplexCollectionPatch() { var initial = new TestPerson() { FirstName = "John", LastName = "Doe", IsAdult = true, Cars = new List <Car>() { new Car { Make = "Ferrari", Model = "250 LM", }, new Car { Make = "Shelby", Model = "Daytona Cobra Coupe", }, new Car() { Make = "Rolls Royce", Model = "10 HP", }, new Car() { Make = "Mercedes-Benz", Model = "38/250 SSK", }, }, }; var patches = new JsonPatchDocument(); var inversePatches = new JsonPatchDocument(); ITestPerson testPerson; using (DraftScope scope = (DraftScope)DraftExtensions.CreateDraft(initial, out TestPerson draft)) { var patchGenerator = new CollectionPatchGenerator(new DynamicLargestCommonSubsequence()); draft.Cars.RemoveAt(3); draft.Cars.RemoveAt(0); draft.Cars.Add(new Car() { Make = "Bugatti", Model = "Type 57 SC Atalante", }); // trick the scope into thinking that is finishing and should not create proxies anymore. scope.IsFinishing = true; patchGenerator.Generate((IDraft)draft.Cars, "/Cars", patches, inversePatches); // inverse order of inverse patches. inversePatches.Operations.Reverse(); testPerson = scope.FinishDraft <ITestPerson, TestPerson>(draft); } var result = ITestPerson.Produce(initial, p => { patches.ApplyTo(p); }); result = result.Produce(p => { inversePatches.ApplyTo(p); }); Assert.Equal(4, result.Cars.Count); Assert.Equal("Ferrari", result.Cars[0].Make); Assert.Equal("250 LM", result.Cars[0].Model); Assert.Equal("Shelby", result.Cars[1].Make); Assert.Equal("Daytona Cobra Coupe", result.Cars[1].Model); Assert.Equal("Rolls Royce", result.Cars[2].Make); Assert.Equal("10 HP", result.Cars[2].Model); Assert.Equal("Mercedes-Benz", result.Cars[3].Make); Assert.Equal("38/250 SSK", result.Cars[3].Model); }
public void GenerateComplexCollectionPatch() { var initial = new TestPerson() { FirstName = "John", LastName = "Doe", IsAdult = true, Cars = new List <Car>() { new Car { Make = "Ferrari", Model = "250 LM", }, new Car { Make = "Shelby", Model = "Daytona Cobra Coupe", }, new Car() { Make = "Rolls Royce", Model = "10 HP", }, new Car() { Make = "Mercedes-Benz", Model = "38/250 SSK", }, }, }; using var scope = DraftExtensions.CreateDraft(initial, out TestPerson draft); var patchGenerator = new CollectionPatchGenerator(new DynamicLargestCommonSubsequence()); var patches = new JsonPatchDocument(); var inversePatches = new JsonPatchDocument(); draft.Cars.RemoveAt(3); draft.Cars.RemoveAt(0); draft.Cars.Add(new Car() { Make = "Bugatti", Model = "Type 57 SC Atalante", }); patchGenerator.Generate((IDraft)draft.Cars, "/Cars", patches, inversePatches); // inverse order of inverse patches. inversePatches.Operations.Reverse(); JsonAssert.Equal( @" [ { 'path': '/Cars/3', 'op': 'remove' }, { 'path': '/Cars/0', 'op': 'remove' }, { 'value': { 'Make': 'Bugatti', 'Model': 'Type 57 SC Atalante', 'Crashed': false }, 'path': '/Cars/-', 'op': 'add' } ] ", JsonConvert.SerializeObject(patches)); JsonAssert.Equal( @" [ { 'path': '/Cars/2', 'op': 'remove' }, { 'value': { 'Make': 'Ferrari', 'Model': '250 LM', 'Crashed': false }, 'path': '/Cars/0', 'op': 'add' }, { 'value': { 'Make': 'Mercedes-Benz', 'Model': '38/250 SSK', 'Crashed': false }, 'path': '/Cars/-', 'op': 'add' } ] ", JsonConvert.SerializeObject(inversePatches)); }
public void ApplyTrivialCollectionRemovalPatch() { var initial = new TestPerson() { FirstName = "John", LastName = "Doe", IsAdult = true, Cars = new List <Car>() { new Car { Make = "Ferrari", Model = "250 LM", }, new Car { Make = "Shelby", Model = "Daytona Cobra Coupe", }, new Car() { Make = "Rolls Royce", Model = "10 HP", }, new Car() { Make = "Mercedes-Benz", Model = "38/250 SSK", }, new Car() { Make = "Bugatti", Model = "Type 57 SC Atalante", }, }, }; var patches = new JsonPatchDocument(); var inversePatches = new JsonPatchDocument(); ITestPerson testPerson; using (var scope = DraftExtensions.CreateDraft(initial, out TestPerson draft)) { var patchGenerator = new CollectionPatchGenerator(new DynamicLargestCommonSubsequence()); draft.Cars.RemoveAt(2); draft.Cars.RemoveAt(2); draft.Cars.RemoveAt(2); patchGenerator.Generate((IDraft)draft.Cars, "/Cars", patches, inversePatches); // inverse order of inverse patches. inversePatches.Operations.Reverse(); testPerson = scope.FinishDraft <ITestPerson, TestPerson>(draft); } // inverse order of inverse patches. inversePatches.Operations.Reverse(); var result = ITestPerson.Produce(initial, p => { patches.ApplyTo(p); }); Assert.Equal(2, result.Cars.Count); Assert.Equal("Ferrari", result.Cars[0].Make); Assert.Equal("250 LM", result.Cars[0].Model); Assert.Equal("Shelby", result.Cars[1].Make); Assert.Equal("Daytona Cobra Coupe", result.Cars[1].Model); }
/// <summary> /// Initializes a new instance of the <see cref="ProxyListTests{T}"/> class. /// </summary> /// <param name="tCreator">The function to create a new T.</param> public ProxyListTests(Func <T> tCreator) { this.DraftScope = DraftExtensions.CreateDraft(new ProxyList <T>(), out var result); this.ProxyList = result; this.TCreator = tCreator; }
/// <summary> /// Initializes a new instance of the <see cref="ProxyDictionaryTests{TKey, TValue}"/> class. /// </summary> /// <param name="keyValuePairCreator">The function to create a new T.</param> public ProxyDictionaryTests(Func <KeyValuePair <TKey, TValue> > keyValuePairCreator) { this.DraftScope = DraftExtensions.CreateDraft(new ProxyDictionary <TKey, TValue>(), out var result); this.ProxyDictionary = result; this.KeyValuePairCreator = keyValuePairCreator; }