Skip to content

Commit f92340b

Browse files
authored
Merge pull request #117 from justinhachemeister/master
Update Feature constructor definition to use interface instead of con…
2 parents 53e12d6 + 80e2d79 commit f92340b

File tree

4 files changed

+298
-4
lines changed

4 files changed

+298
-4
lines changed

src/GeoJSON.Net.Tests/Feature/FeatureTests.cs

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,28 @@ public void Can_Serialize_MultiPolygon_Feature()
167167
JsonAssert.AreEqual(expectedJson, actualJson);
168168
}
169169

170+
[Test]
171+
public void Can_Serialize_Dictionary_Subclass()
172+
{
173+
var properties =
174+
new TestFeaturePropertyDictionary()
175+
{
176+
BooleanProperty = true,
177+
DoubleProperty = 1.2345d,
178+
EnumProperty = TestFeatureEnum.Value1,
179+
IntProperty = -1,
180+
StringProperty = "Hello, GeoJSON !"
181+
};
182+
183+
Net.Feature.Feature feature = new Net.Feature.Feature(new Point(new Position(10, 10)), properties);
184+
185+
var expectedJson = this.GetExpectedJson();
186+
var actualJson = JsonConvert.SerializeObject(feature);
187+
188+
Assert.False(string.IsNullOrEmpty(expectedJson));
189+
JsonAssert.AreEqual(expectedJson, actualJson);
190+
}
191+
170192
[Test]
171193
public void Ctor_Can_Add_Properties_Using_Object()
172194
{
@@ -187,6 +209,31 @@ public void Ctor_Can_Add_Properties_Using_Object()
187209
Assert.AreEqual(feature.Properties.Count, 6);
188210
}
189211

212+
[Test]
213+
public void Ctor_Can_Add_Properties_Using_Object_Inheriting_Dictionary()
214+
{
215+
int expectedProperties = 6;
216+
217+
var properties = new TestFeaturePropertyDictionary()
218+
{
219+
BooleanProperty = true,
220+
DateTimeProperty = DateTime.Now,
221+
DoubleProperty = 1.2345d,
222+
EnumProperty = TestFeatureEnum.Value1,
223+
IntProperty = -1,
224+
StringProperty = "Hello, GeoJSON !"
225+
};
226+
227+
Net.Feature.Feature feature = new Net.Feature.Feature(new Point(new Position(10, 10)), properties);
228+
229+
Assert.IsNotNull(feature.Properties);
230+
Assert.IsTrue(feature.Properties.Count > 1);
231+
Assert.AreEqual(
232+
feature.Properties.Count,
233+
expectedProperties,
234+
$"Expected: {expectedProperties} Actual: {feature.Properties.Count}");
235+
}
236+
190237
[Test]
191238
public void Ctor_Creates_Properties_Collection_When_Passed_Null_Proper_Object()
192239
{
@@ -437,7 +484,7 @@ private IGeometryObject GetGeometry()
437484
return multiLine;
438485
}
439486

440-
public static Dictionary<string, object> GetPropertiesInRandomOrder()
487+
public static IDictionary<string, object> GetPropertiesInRandomOrder()
441488
{
442489
var properties = new Dictionary<string, object>()
443490
{
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"type":"Feature",
3+
"geometry":{
4+
"type":"Point",
5+
"coordinates":[
6+
10.0,
7+
10.0
8+
]
9+
},
10+
"properties":{
11+
"BooleanProperty":true,
12+
"DoubleProperty":1.2345,
13+
"EnumProperty":1,
14+
"IntProperty":-1,
15+
"StringProperty":"Hello, GeoJSON !"
16+
}
17+
}
Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
namespace GeoJSON.Net.Tests.Feature
2+
{
3+
using System;
4+
using System.Collections;
5+
using System.Collections.Generic;
6+
7+
/// <summary>
8+
/// The Test Property Dictionary object.
9+
/// </summary>
10+
internal class TestFeaturePropertyDictionary : IDictionary<string, object>
11+
{
12+
/// <summary>
13+
/// The internal dictionary this implementation is wrapping for testing purposes.
14+
/// </summary>
15+
private readonly IDictionary<string, object> internalDictionary;
16+
17+
/// <summary>
18+
/// Initializes a new instance of the <see cref="TestFeaturePropertyDictionary"/> class.
19+
/// </summary>
20+
public TestFeaturePropertyDictionary()
21+
{
22+
this.internalDictionary = new Dictionary<string, object>();
23+
}
24+
25+
public bool BooleanProperty
26+
{
27+
get
28+
{
29+
return this.GetKeyOrDefault<bool>(nameof(this.BooleanProperty));
30+
}
31+
32+
set
33+
{
34+
this.internalDictionary[nameof(this.BooleanProperty)] = value;
35+
}
36+
}
37+
38+
public DateTime DateTimeProperty
39+
{
40+
get
41+
{
42+
return this.GetKeyOrDefault<DateTime>(nameof(this.DateTimeProperty));
43+
}
44+
45+
set
46+
{
47+
this.internalDictionary[nameof(this.DateTimeProperty)] = value;
48+
}
49+
}
50+
51+
public double DoubleProperty
52+
{
53+
get
54+
{
55+
return this.GetKeyOrDefault<double>(nameof(this.DoubleProperty));
56+
}
57+
58+
set
59+
{
60+
this.internalDictionary[nameof(this.DoubleProperty)] = value;
61+
}
62+
}
63+
64+
public TestFeatureEnum EnumProperty
65+
{
66+
get
67+
{
68+
return this.GetKeyOrDefault<TestFeatureEnum>(nameof(this.EnumProperty));
69+
}
70+
71+
set
72+
{
73+
this.internalDictionary[nameof(this.EnumProperty)] = value;
74+
}
75+
}
76+
77+
public int IntProperty
78+
{
79+
get
80+
{
81+
return this.GetKeyOrDefault<int>(nameof(this.IntProperty));
82+
}
83+
84+
set
85+
{
86+
this.internalDictionary[nameof(this.IntProperty)] = value;
87+
}
88+
}
89+
90+
public string StringProperty
91+
{
92+
get
93+
{
94+
return this.GetKeyOrDefault<string>(nameof(this.StringProperty));
95+
}
96+
97+
set
98+
{
99+
this.internalDictionary[nameof(this.StringProperty)] = value;
100+
}
101+
}
102+
103+
/// <inheritdoc/>
104+
public int Count
105+
{
106+
get
107+
{
108+
return this.internalDictionary.Count;
109+
}
110+
}
111+
112+
/// <inheritdoc/>
113+
public bool IsReadOnly
114+
{
115+
get
116+
{
117+
return this.internalDictionary.IsReadOnly;
118+
}
119+
}
120+
121+
/// <inheritdoc/>
122+
public ICollection<string> Keys
123+
{
124+
get
125+
{
126+
return this.internalDictionary.Keys;
127+
}
128+
}
129+
130+
/// <inheritdoc/>
131+
public ICollection<object> Values
132+
{
133+
get
134+
{
135+
return this.internalDictionary.Values;
136+
}
137+
}
138+
139+
/// <inheritdoc/>
140+
public object this[string key]
141+
{
142+
get
143+
{
144+
return this.internalDictionary[key];
145+
}
146+
147+
set
148+
{
149+
this.internalDictionary[key] = value;
150+
}
151+
}
152+
153+
/// <inheritdoc/>
154+
public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
155+
{
156+
return this.internalDictionary.GetEnumerator();
157+
}
158+
159+
/// <inheritdoc/>
160+
IEnumerator IEnumerable.GetEnumerator()
161+
{
162+
return this.GetEnumerator();
163+
}
164+
165+
/// <inheritdoc/>
166+
public void Add(KeyValuePair<string, object> item)
167+
{
168+
this.internalDictionary.Add(item);
169+
}
170+
171+
/// <inheritdoc/>
172+
public void Clear()
173+
{
174+
this.internalDictionary.Clear();
175+
}
176+
177+
/// <inheritdoc/>
178+
public bool Contains(KeyValuePair<string, object> item)
179+
{
180+
return this.internalDictionary.Contains(item);
181+
}
182+
183+
/// <inheritdoc/>
184+
public void CopyTo(KeyValuePair<string, object>[] array, int arrayIndex)
185+
{
186+
this.internalDictionary.CopyTo(array, arrayIndex);
187+
}
188+
189+
/// <inheritdoc/>
190+
public bool Remove(KeyValuePair<string, object> item)
191+
{
192+
return this.internalDictionary.Remove(item);
193+
}
194+
195+
/// <inheritdoc/>
196+
public bool ContainsKey(string key)
197+
{
198+
return this.internalDictionary.ContainsKey(key);
199+
}
200+
201+
/// <inheritdoc/>
202+
public void Add(string key, object value)
203+
{
204+
this.internalDictionary.Add(key, value);
205+
}
206+
207+
/// <inheritdoc/>
208+
public bool Remove(string key)
209+
{
210+
return this.internalDictionary.Remove(key);
211+
}
212+
213+
/// <inheritdoc/>
214+
public bool TryGetValue(string key, out object value)
215+
{
216+
return this.internalDictionary.TryGetValue(key, out value);
217+
}
218+
219+
private T GetKeyOrDefault<T>(string keyName)
220+
{
221+
object value;
222+
if (this.TryGetValue(keyName, out value))
223+
{
224+
return (T)value;
225+
}
226+
227+
return default(T);
228+
}
229+
}
230+
}

src/GeoJSON.Net/Feature/Feature.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ public override int GetHashCode()
105105
public class Feature : Feature<IGeometryObject>
106106
{
107107
[JsonConstructor]
108-
public Feature(IGeometryObject geometry, Dictionary<string, object> properties = null, string id = null)
108+
public Feature(IGeometryObject geometry, IDictionary<string, object> properties = null, string id = null)
109109
: base(geometry, properties, id)
110110
{
111111
}
@@ -122,7 +122,7 @@ public Feature(IGeometryObject geometry, object properties, string id = null)
122122
/// </summary>
123123
/// <remarks>Returns correctly typed Geometry property</remarks>
124124
/// <typeparam name="TGeometry"></typeparam>
125-
public class Feature<TGeometry> : Feature<TGeometry, Dictionary<string, object>>, IEquatable<Feature<TGeometry>> where TGeometry : IGeometryObject
125+
public class Feature<TGeometry> : Feature<TGeometry, IDictionary<string, object>>, IEquatable<Feature<TGeometry>> where TGeometry : IGeometryObject
126126
{
127127

128128
/// <summary>
@@ -132,7 +132,7 @@ public class Feature<TGeometry> : Feature<TGeometry, Dictionary<string, object>>
132132
/// <param name="properties">The properties.</param>
133133
/// <param name="id">The (optional) identifier.</param>
134134
[JsonConstructor]
135-
public Feature(TGeometry geometry, Dictionary<string, object> properties = null, string id = null)
135+
public Feature(TGeometry geometry, IDictionary<string, object> properties = null, string id = null)
136136
: base(geometry, properties ?? new Dictionary<string, object>(), id)
137137
{
138138
}

0 commit comments

Comments
 (0)