Skip to content

Commit 92591e1

Browse files
authored
DiffBuilder not handling added key in Dictionary - fix #35 (#36)
* fix DiffBuilder not handling added key in Dictionary #35
1 parent 16fcde1 commit 92591e1

File tree

4 files changed

+288
-6
lines changed

4 files changed

+288
-6
lines changed
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
using System.Collections.Generic;
2+
using Morcatko.AspNetCore.JsonMergePatch.Builders;
3+
using Newtonsoft.Json.Linq;
4+
using Xunit;
5+
6+
namespace Morcatko.AspNetCore.JsonMergePatch.Tests.Builders.Diff
7+
{
8+
public class Dictionary
9+
{
10+
class SimpleModelWithDictionary
11+
{
12+
public Dictionary<string, string> Dic { get; set; } = new Dictionary<string, string>();
13+
}
14+
15+
[Fact]
16+
public void NoChange()
17+
{
18+
var source = new SimpleModelWithDictionary();
19+
var patched = new SimpleModelWithDictionary();
20+
21+
var diff = DiffBuilder.Build(source, patched);
22+
23+
Assert.Null(diff);
24+
}
25+
26+
[Fact]
27+
public void EmptyToNull()
28+
{
29+
var source = new SimpleModelWithDictionary();
30+
var patched = new SimpleModelWithDictionary() { Dic = null };
31+
32+
var diff = DiffBuilder.Build(source, patched);
33+
34+
Assert.True(JObject.DeepEquals(
35+
JObject.Parse("{Dic:null}"),
36+
diff));
37+
}
38+
39+
[Fact]
40+
public void NullToEmpty()
41+
{
42+
var source = new SimpleModelWithDictionary() { Dic = null };
43+
var patched = new SimpleModelWithDictionary();
44+
45+
var diff = DiffBuilder.Build(source, patched);
46+
47+
Assert.True(JObject.DeepEquals(
48+
JObject.Parse("{Dic:{}}"),
49+
diff));
50+
}
51+
52+
[Fact]
53+
public void KeyAdded()
54+
{
55+
var source = new SimpleModelWithDictionary();
56+
var patched = new SimpleModelWithDictionary()
57+
{
58+
Dic = new Dictionary<string, string>()
59+
{
60+
{ "key1", "val1" }
61+
}
62+
};
63+
64+
var diff = DiffBuilder.Build(source, patched);
65+
66+
Assert.True(JObject.DeepEquals(
67+
JObject.Parse("{Dic:{\"key1\": \"val1\"}}"),
68+
diff));
69+
}
70+
71+
[Fact]
72+
public void KeyMissing()
73+
{
74+
var source = new SimpleModelWithDictionary()
75+
{
76+
Dic = new Dictionary<string, string>()
77+
{
78+
{ "key1", "val1" }
79+
}
80+
};
81+
var patched = new SimpleModelWithDictionary();
82+
83+
var diff = DiffBuilder.Build(source, patched);
84+
85+
Assert.True(JObject.DeepEquals(
86+
JObject.Parse("{Dic:{\"key1\": null}}"),
87+
diff));
88+
}
89+
90+
[Fact]
91+
public void ValueSetToNull()
92+
{
93+
var source = new SimpleModelWithDictionary()
94+
{
95+
Dic = new Dictionary<string, string>()
96+
{
97+
{ "key1", "val1" }
98+
}
99+
};
100+
var patched = new SimpleModelWithDictionary()
101+
{
102+
Dic = new Dictionary<string, string>()
103+
{
104+
{ "key1", null }
105+
}
106+
};
107+
108+
var diff = DiffBuilder.Build(source, patched);
109+
110+
Assert.True(JObject.DeepEquals(
111+
JObject.Parse("{Dic:{\"key1\": null}}"),
112+
diff));
113+
}
114+
115+
[Fact]
116+
public void ValueChanged()
117+
{
118+
var source = new SimpleModelWithDictionary()
119+
{
120+
Dic = new Dictionary<string, string>()
121+
{
122+
{ "key1", "val1" }
123+
}
124+
};
125+
var patched = new SimpleModelWithDictionary()
126+
{
127+
Dic = new Dictionary<string, string>()
128+
{
129+
{ "key1", "val_changed" }
130+
}
131+
};
132+
133+
var diff = DiffBuilder.Build(source, patched);
134+
135+
Assert.True(JObject.DeepEquals(
136+
JObject.Parse("{Dic:{\"key1\": \"val_changed\"}}"),
137+
diff));
138+
}
139+
}
140+
}

src/2.1-JsonMergePatch/Builders/DiffBuilder.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,11 @@ private static JToken BuildDiff(JToken original, JToken patched)
4242
private static JToken BuildObjectDiff(JObject original, JObject patched)
4343
{
4444
JObject result = new JObject();
45-
var properties = original?.Properties() ?? patched.Properties();
46-
foreach (var property in properties)
45+
var propertyNames = original.Properties()
46+
.Union(patched.Properties())
47+
.Select(p => p.Name).Distinct();
48+
foreach (var propertyName in propertyNames)
4749
{
48-
var propertyName = property.Name;
4950
var originalJToken = original?.GetValue(propertyName);
5051
var patchedJToken = patched?.GetValue(propertyName);
5152

src/3.0-JsonMergePatch.NewtonsoftJson/Builders/DiffBuilder.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,11 @@ private static JToken BuildDiff(JToken original, JToken patched)
4242
private static JToken BuildObjectDiff(JObject original, JObject patched)
4343
{
4444
JObject result = new JObject();
45-
var properties = original?.Properties() ?? patched.Properties();
46-
foreach (var property in properties)
45+
var propertyNames = original.Properties()
46+
.Union(patched.Properties())
47+
.Select(p => p.Name).Distinct();
48+
foreach (var propertyName in propertyNames)
4749
{
48-
var propertyName = property.Name;
4950
var originalJToken = original?.GetValue(propertyName);
5051
var patchedJToken = patched?.GetValue(propertyName);
5152

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
using System.Collections.Generic;
2+
using Morcatko.AspNetCore.JsonMergePatch.NewtonsoftJson.Builders;
3+
using Newtonsoft.Json.Linq;
4+
using Xunit;
5+
6+
namespace Morcatko.AspNetCore.JsonMergePatch.Tests.NewtonsoftJson.Builders.Diff
7+
{
8+
public class Dictionary
9+
{
10+
class SimpleModelWithDictionary
11+
{
12+
public Dictionary<string, string> Dic { get; set; } = new Dictionary<string, string>();
13+
}
14+
15+
[Fact]
16+
public void NoChange()
17+
{
18+
var source = new SimpleModelWithDictionary();
19+
var patched = new SimpleModelWithDictionary();
20+
21+
var diff = DiffBuilder.Build(source, patched);
22+
23+
Assert.Null(diff);
24+
}
25+
26+
[Fact]
27+
public void EmptyToNull()
28+
{
29+
var source = new SimpleModelWithDictionary();
30+
var patched = new SimpleModelWithDictionary() { Dic = null };
31+
32+
var diff = DiffBuilder.Build(source, patched);
33+
34+
Assert.True(JObject.DeepEquals(
35+
JObject.Parse("{Dic:null}"),
36+
diff));
37+
}
38+
39+
[Fact]
40+
public void NullToEmpty()
41+
{
42+
var source = new SimpleModelWithDictionary() { Dic = null };
43+
var patched = new SimpleModelWithDictionary();
44+
45+
var diff = DiffBuilder.Build(source, patched);
46+
47+
Assert.True(JObject.DeepEquals(
48+
JObject.Parse("{Dic:{}}"),
49+
diff));
50+
}
51+
52+
[Fact]
53+
public void KeyAdded()
54+
{
55+
var source = new SimpleModelWithDictionary();
56+
var patched = new SimpleModelWithDictionary()
57+
{
58+
Dic = new Dictionary<string, string>()
59+
{
60+
{ "key1", "val1" }
61+
}
62+
};
63+
64+
var diff = DiffBuilder.Build(source, patched);
65+
66+
Assert.True(JObject.DeepEquals(
67+
JObject.Parse("{Dic:{\"key1\": \"val1\"}}"),
68+
diff));
69+
}
70+
71+
[Fact]
72+
public void KeyMissing()
73+
{
74+
var source = new SimpleModelWithDictionary()
75+
{
76+
Dic = new Dictionary<string, string>()
77+
{
78+
{ "key1", "val1" }
79+
}
80+
};
81+
var patched = new SimpleModelWithDictionary();
82+
83+
var diff = DiffBuilder.Build(source, patched);
84+
85+
Assert.True(JObject.DeepEquals(
86+
JObject.Parse("{Dic:{\"key1\": null}}"),
87+
diff));
88+
}
89+
90+
[Fact]
91+
public void ValueSetToNull()
92+
{
93+
var source = new SimpleModelWithDictionary()
94+
{
95+
Dic = new Dictionary<string, string>()
96+
{
97+
{ "key1", "val1" }
98+
}
99+
};
100+
var patched = new SimpleModelWithDictionary()
101+
{
102+
Dic = new Dictionary<string, string>()
103+
{
104+
{ "key1", null }
105+
}
106+
};
107+
108+
var diff = DiffBuilder.Build(source, patched);
109+
110+
Assert.True(JObject.DeepEquals(
111+
JObject.Parse("{Dic:{\"key1\": null}}"),
112+
diff));
113+
}
114+
115+
[Fact]
116+
public void ValueChanged()
117+
{
118+
var source = new SimpleModelWithDictionary()
119+
{
120+
Dic = new Dictionary<string, string>()
121+
{
122+
{ "key1", "val1" }
123+
}
124+
};
125+
var patched = new SimpleModelWithDictionary()
126+
{
127+
Dic = new Dictionary<string, string>()
128+
{
129+
{ "key1", "val_changed" }
130+
}
131+
};
132+
133+
var diff = DiffBuilder.Build(source, patched);
134+
135+
Assert.True(JObject.DeepEquals(
136+
JObject.Parse("{Dic:{\"key1\": \"val_changed\"}}"),
137+
diff));
138+
}
139+
}
140+
}

0 commit comments

Comments
 (0)