Skip to content

Commit 1f8f94c

Browse files
committed
Merge pull request #43 from csantero/more-types
support more types
2 parents 9d3f1ce + 8d8b82f commit 1f8f94c

File tree

8 files changed

+364
-58
lines changed

8 files changed

+364
-58
lines changed
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
{
2+
"samples": [
3+
{
4+
"id": "1",
5+
"booleanField": false,
6+
"nullableBooleanField": false,
7+
"sByteField": 0,
8+
"nullableSByteField": null,
9+
"byteField": 0,
10+
"nullableByteField": null,
11+
"int16Field": 0,
12+
"nullableInt16Field": null,
13+
"uInt16Field": 0,
14+
"nullableUInt16Field": null,
15+
"int32Field": 0,
16+
"nullableInt32Field": null,
17+
"uInt32Field": 0,
18+
"nullableUInt32Field": null,
19+
"int64Field": 0,
20+
"nullableInt64Field": null,
21+
"uInt64Field": 0,
22+
"nullableUInt64Field": null,
23+
"doubleField": 0.0,
24+
"nullableDoubleField": null,
25+
"singleField": 0.0,
26+
"nullableSingleField": null,
27+
"decimalField": "0",
28+
"nullableDecimalField": null,
29+
"dateTimeField": "0001-01-01T00:00:00",
30+
"nullableDateTimeField": null,
31+
"dateTimeOffsetField": "0001-01-01T00:00:00+00:00",
32+
"nullableDateTimeOffsetField": null,
33+
"guidField": "00000000-0000-0000-0000-000000000000",
34+
"nullableGuidField": null,
35+
"stringField": null,
36+
"enumField": 0,
37+
"nullableEnumField": null
38+
}, {
39+
"id": "2",
40+
"booleanField": true,
41+
"nullableBooleanField": true,
42+
"sByteField": 123,
43+
"nullableSByteField": 123,
44+
"byteField": 253,
45+
"nullableByteField": 253,
46+
"int16Field": 32000,
47+
"nullableInt16Field": 32000,
48+
"uInt16Field": 64000,
49+
"nullableUInt16Field": 64000,
50+
"int32Field": 2000000000,
51+
"nullableInt32Field": 2000000000,
52+
"uInt32Field": 3000000000,
53+
"nullableUInt32Field": 3000000000,
54+
"int64Field": 9223372036854775807,
55+
"nullableInt64Field": 9223372036854775807,
56+
"uInt64Field": 9223372036854775808,
57+
"nullableUInt64Field": 9223372036854775808,
58+
"doubleField": 1056789.123,
59+
"nullableDoubleField": 1056789.123,
60+
"singleField": 1056789.13,
61+
"nullableSingleField": 1056789.13,
62+
"decimalField": "1056789.123",
63+
"nullableDecimalField": "1056789.123",
64+
"dateTimeField": "1776-07-04T00:00:00",
65+
"nullableDateTimeField": "1776-07-04T00:00:00",
66+
"dateTimeOffsetField": "1776-07-04T00:00:00-05:00",
67+
"nullableDateTimeOffsetField": "1776-07-04T00:00:00-05:00",
68+
"guidField": "6566f9b4-5245-40de-890d-98b40a4ad656",
69+
"nullableGuidField": "3d1fb81e-43ee-4d04-af91-c8a326341293",
70+
"stringField": "Some string 156",
71+
"enumField": 1,
72+
"nullableEnumField": 2
73+
}
74+
]
75+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
using System;
2+
using JSONAPI.Extensions;
3+
using Microsoft.VisualStudio.TestTools.UnitTesting;
4+
5+
namespace JSONAPI.Tests.Extensions
6+
{
7+
[TestClass]
8+
public class TypeExtensionsTests
9+
{
10+
private enum TestEnum
11+
{
12+
13+
}
14+
15+
[TestMethod]
16+
public void CanWriteAsJsonApiAttributeTest()
17+
{
18+
Assert.IsTrue(typeof(Byte).CanWriteAsJsonApiAttribute(), "CanWriteTypeAsAttribute returned wrong answer for Byte!");
19+
Assert.IsTrue(typeof(Byte?).CanWriteAsJsonApiAttribute(), "CanWriteTypeAsAttribute returned wrong answer for nullable Byte!");
20+
Assert.IsTrue(typeof(SByte).CanWriteAsJsonApiAttribute(), "CanWriteTypeAsAttribute returned wrong answer for SByte!");
21+
Assert.IsTrue(typeof(SByte?).CanWriteAsJsonApiAttribute(), "CanWriteTypeAsAttribute returned wrong answer for nullable SByte!");
22+
Assert.IsTrue(typeof(UInt16).CanWriteAsJsonApiAttribute(), "CanWriteTypeAsAttribute returned wrong answer for UInt16!");
23+
Assert.IsTrue(typeof(UInt16?).CanWriteAsJsonApiAttribute(), "CanWriteTypeAsAttribute returned wrong answer for nullable UInt16!");
24+
Assert.IsTrue(typeof(Int16).CanWriteAsJsonApiAttribute(), "CanWriteTypeAsAttribute returned wrong answer for Int16!");
25+
Assert.IsTrue(typeof(Int16?).CanWriteAsJsonApiAttribute(), "CanWriteTypeAsAttribute returned wrong answer for nullable Int16!");
26+
Assert.IsTrue(typeof(UInt32).CanWriteAsJsonApiAttribute(), "CanWriteTypeAsAttribute returned wrong answer for UInt32!");
27+
Assert.IsTrue(typeof(UInt32?).CanWriteAsJsonApiAttribute(), "CanWriteTypeAsAttribute returned wrong answer for nullable UInt32!");
28+
Assert.IsTrue(typeof(Int32).CanWriteAsJsonApiAttribute(), "CanWriteTypeAsAttribute returned wrong answer for Int32!");
29+
Assert.IsTrue(typeof(Int32?).CanWriteAsJsonApiAttribute(), "CanWriteTypeAsAttribute returned wrong answer for nullable Int32!");
30+
Assert.IsTrue(typeof(UInt64).CanWriteAsJsonApiAttribute(), "CanWriteTypeAsAttribute returned wrong answer for UInt64!");
31+
Assert.IsTrue(typeof(UInt64?).CanWriteAsJsonApiAttribute(), "CanWriteTypeAsAttribute returned wrong answer for nullable UInt64!");
32+
Assert.IsTrue(typeof(Int64).CanWriteAsJsonApiAttribute(), "CanWriteTypeAsAttribute returned wrong answer for Int64!");
33+
Assert.IsTrue(typeof(Int64?).CanWriteAsJsonApiAttribute(), "CanWriteTypeAsAttribute returned wrong answer for nullable Int64!");
34+
Assert.IsTrue(typeof(Double).CanWriteAsJsonApiAttribute(), "CanWriteTypeAsAttribute returned wrong answer for Double!");
35+
Assert.IsTrue(typeof(Double?).CanWriteAsJsonApiAttribute(), "CanWriteTypeAsAttribute returned wrong answer for nullable Double!");
36+
Assert.IsTrue(typeof(Single).CanWriteAsJsonApiAttribute(), "CanWriteTypeAsAttribute returned wrong answer for Single!");
37+
Assert.IsTrue(typeof(Single?).CanWriteAsJsonApiAttribute(), "CanWriteTypeAsAttribute returned wrong answer for nullable Single!");
38+
Assert.IsTrue(typeof(Decimal).CanWriteAsJsonApiAttribute(), "CanWriteTypeAsAttribute returned wrong answer for Decimal!");
39+
Assert.IsTrue(typeof(Decimal?).CanWriteAsJsonApiAttribute(), "CanWriteTypeAsAttribute returned wrong answer for nullable Decimal!");
40+
Assert.IsTrue(typeof(DateTime).CanWriteAsJsonApiAttribute(), "CanWriteTypeAsAttribute returned wrong answer for DateTime!");
41+
Assert.IsTrue(typeof(DateTime?).CanWriteAsJsonApiAttribute(), "CanWriteTypeAsAttribute returned wrong answer for nullable DateTime!");
42+
Assert.IsTrue(typeof(DateTimeOffset).CanWriteAsJsonApiAttribute(), "CanWriteTypeAsAttribute returned wrong answer for DateTimeOffset!");
43+
Assert.IsTrue(typeof(DateTimeOffset?).CanWriteAsJsonApiAttribute(), "CanWriteTypeAsAttribute returned wrong answer for nullable DateTimeOffset!");
44+
Assert.IsTrue(typeof(Guid).CanWriteAsJsonApiAttribute(), "CanWriteTypeAsAttribute returned wrong answer for Guid!");
45+
Assert.IsTrue(typeof(Guid?).CanWriteAsJsonApiAttribute(), "CanWriteTypeAsAttribute returned wrong answer for nullable Guid!");
46+
Assert.IsTrue(typeof(String).CanWriteAsJsonApiAttribute(), "CanWriteTypeAsAttribute returned wrong answer for String!");
47+
Assert.IsTrue(typeof(TestEnum).CanWriteAsJsonApiAttribute(), "CanWriteTypeAsAttribute returned wrong answer for enum!");
48+
Assert.IsTrue(typeof(TestEnum?).CanWriteAsJsonApiAttribute(), "CanWriteTypeAsAttribute returned wrong answer for nullable enum!");
49+
Assert.IsFalse(typeof(Object).CanWriteAsJsonApiAttribute(), "CanWriteTypeAsAttribute returned wrong answer for Object!");
50+
}
51+
52+
}
53+
}

JSONAPI.Tests/JSONAPI.Tests.csproj

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,13 @@
7878
<Compile Include="ActionFilters\EnableFilteringAttributeTests.cs" />
7979
<Compile Include="Core\MetadataManagerTests.cs" />
8080
<Compile Include="Core\ModelManagerTests.cs" />
81+
<Compile Include="Extensions\TypeExtensionsTests.cs" />
8182
<Compile Include="Json\ErrorSerializerTests.cs" />
8283
<Compile Include="Json\JsonApiMediaFormaterTests.cs" />
8384
<Compile Include="Json\LinkTemplateTests.cs" />
8485
<Compile Include="Models\Author.cs" />
8586
<Compile Include="Models\Comment.cs" />
87+
<Compile Include="Models\Sample.cs" />
8688
<Compile Include="Models\Post.cs" />
8789
<Compile Include="Properties\AssemblyInfo.cs" />
8890
</ItemGroup>
@@ -109,14 +111,17 @@
109111
<None Include="Data\NonStandardIdTest.json">
110112
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
111113
</None>
114+
<None Include="Data\AttributeSerializationTest.json">
115+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
116+
</None>
112117
<None Include="Data\SerializerIntegrationTest.json">
113118
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
114119
</None>
115120
<None Include="packages.config" />
116121
</ItemGroup>
117122
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
118123
<Import Project="$(SolutionDir)\.nuget\nuget.targets" />
119-
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
124+
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
120125
Other similar extension points exist, see Microsoft.Common.targets.
121126
<Target Name="BeforeBuild">
122127
</Target>

JSONAPI.Tests/Json/JsonApiMediaFormaterTests.cs

Lines changed: 111 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public class JsonApiMediaFormaterTests
2020
{
2121
Author a;
2222
Post p, p2, p3, p4;
23+
Sample s1, s2;
2324

2425
private class MockErrorSerializer : IErrorSerializer
2526
{
@@ -105,32 +106,80 @@ public void SetupModels()
105106
}
106107
};
107108

108-
}
109-
110-
private enum TestEnum
111-
{
112-
113-
}
114-
115-
[TestMethod]
116-
public void CanWritePrimitiveTest()
117-
{
118-
// Arrange
119-
JsonApiFormatter formatter = new JSONAPI.Json.JsonApiFormatter(new PluralizationService());
120-
// Act
121-
// Assert
122-
Assert.IsTrue(formatter.CanWriteTypeAsPrimitive(typeof(Int32)), "CanWriteTypeAsPrimitive returned wrong answer for Integer!");
123-
Assert.IsTrue(formatter.CanWriteTypeAsPrimitive(typeof(Double)), "CanWriteTypeAsPrimitive returned wrong answer for Double!");
124-
Assert.IsTrue(formatter.CanWriteTypeAsPrimitive(typeof(DateTime)), "CanWriteTypeAsPrimitive returned wrong answer for DateTime!");
125-
Assert.IsTrue(formatter.CanWriteTypeAsPrimitive(typeof(DateTimeOffset)), "CanWriteTypeAsPrimitive returned wrong answer for DateTimeOffset!");
126-
Assert.IsTrue(formatter.CanWriteTypeAsPrimitive(typeof(Guid)), "CanWriteTypeAsPrimitive returned wrong answer for Guid!");
127-
Assert.IsTrue(formatter.CanWriteTypeAsPrimitive(typeof(String)), "CanWriteTypeAsPrimitive returned wrong answer for String!");
128-
Assert.IsTrue(formatter.CanWriteTypeAsPrimitive(typeof(DateTime?)), "CanWriteTypeAsPrimitive returned wrong answer for nullable DateTime!");
129-
Assert.IsTrue(formatter.CanWriteTypeAsPrimitive(typeof(DateTimeOffset?)), "CanWriteTypeAsPrimitive returned wrong answer for nullable DateTimeOffset!");
130-
Assert.IsTrue(formatter.CanWriteTypeAsPrimitive(typeof(Guid?)), "CanWriteTypeAsPrimitive returned wrong answer for nullable Guid!");
131-
Assert.IsTrue(formatter.CanWriteTypeAsPrimitive(typeof(TestEnum)), "CanWriteTypeAsPrimitive returned wrong answer for enum!");
132-
Assert.IsTrue(formatter.CanWriteTypeAsPrimitive(typeof(TestEnum?)), "CanWriteTypeAsPrimitive returned wrong answer for nullable enum!");
133-
Assert.IsFalse(formatter.CanWriteTypeAsPrimitive(typeof(Object)), "CanWriteTypeAsPrimitive returned wrong answer for Object!");
109+
s1 = new Sample
110+
{
111+
Id = "1",
112+
BooleanField = false,
113+
NullableBooleanField = false,
114+
SByteField = default(SByte),
115+
NullableSByteField = null,
116+
ByteField = default(Byte),
117+
NullableByteField = null,
118+
Int16Field = default(Int16),
119+
NullableInt16Field = null,
120+
UInt16Field = default(UInt16),
121+
NullableUInt16Field = null,
122+
Int32Field = default(Int32),
123+
NullableInt32Field = null,
124+
UInt32Field = default(Int32),
125+
NullableUInt32Field = null,
126+
Int64Field = default(Int64),
127+
NullableInt64Field = null,
128+
UInt64Field = default(UInt64),
129+
NullableUInt64Field = null,
130+
DoubleField = default(Double),
131+
NullableDoubleField = null,
132+
SingleField = default(Single),
133+
NullableSingleField = null,
134+
DecimalField = default(Decimal),
135+
NullableDecimalField = null,
136+
DateTimeField = default(DateTime),
137+
NullableDateTimeField = null,
138+
DateTimeOffsetField = default(DateTimeOffset),
139+
NullableDateTimeOffsetField = null,
140+
GuidField = default(Guid),
141+
NullableGuidField = null,
142+
StringField = default(String),
143+
EnumField = default(SampleEnum),
144+
NullableEnumField = null,
145+
};
146+
s2 = new Sample
147+
{
148+
Id = "2",
149+
BooleanField = true,
150+
NullableBooleanField = true,
151+
SByteField = 123,
152+
NullableSByteField = 123,
153+
ByteField = 253,
154+
NullableByteField = 253,
155+
Int16Field = 32000,
156+
NullableInt16Field = 32000,
157+
UInt16Field = 64000,
158+
NullableUInt16Field = 64000,
159+
Int32Field = 2000000000,
160+
NullableInt32Field = 2000000000,
161+
UInt32Field = 3000000000,
162+
NullableUInt32Field = 3000000000,
163+
Int64Field = 9223372036854775807,
164+
NullableInt64Field = 9223372036854775807,
165+
UInt64Field = 9223372036854775808,
166+
NullableUInt64Field = 9223372036854775808,
167+
DoubleField = 1056789.123,
168+
NullableDoubleField = 1056789.123,
169+
SingleField = 1056789.123f,
170+
NullableSingleField = 1056789.123f,
171+
DecimalField = 1056789.123m,
172+
NullableDecimalField = 1056789.123m,
173+
DateTimeField = new DateTime(1776, 07, 04),
174+
NullableDateTimeField = new DateTime(1776, 07, 04),
175+
DateTimeOffsetField = new DateTimeOffset(new DateTime(1776, 07, 04), new TimeSpan(-5, 0, 0)),
176+
NullableDateTimeOffsetField = new DateTimeOffset(new DateTime(1776, 07, 04), new TimeSpan(-5, 0, 0)),
177+
GuidField = new Guid("6566F9B4-5245-40DE-890D-98B40A4AD656"),
178+
NullableGuidField = new Guid("3D1FB81E-43EE-4D04-AF91-C8A326341293"),
179+
StringField = "Some string 156",
180+
EnumField = SampleEnum.Value1,
181+
NullableEnumField = SampleEnum.Value2,
182+
};
134183
}
135184

136185
[TestMethod]
@@ -183,6 +232,24 @@ public void SerializeArrayIntegrationTest()
183232
//Assert.AreEqual("[2,3,4]", sw.ToString());
184233
}
185234

235+
[TestMethod]
236+
[DeploymentItem(@"Data\AttributeSerializationTest.json")]
237+
public void Serializes_attributes_properly()
238+
{
239+
// Arrang
240+
JsonApiFormatter formatter = new JsonApiFormatter(new PluralizationService());
241+
MemoryStream stream = new MemoryStream();
242+
243+
// Act
244+
formatter.WriteToStreamAsync(typeof(Sample), new[] { s1, s2 }, stream, null, null);
245+
246+
// Assert
247+
string output = System.Text.Encoding.ASCII.GetString(stream.ToArray());
248+
Trace.WriteLine(output);
249+
var expected = JsonHelpers.MinifyJson(File.ReadAllText("AttributeSerializationTest.json"));
250+
Assert.AreEqual(expected, output.Trim());
251+
}
252+
186253
[TestMethod]
187254
[DeploymentItem(@"Data\FormatterErrorSerializationTest.json")]
188255
public void Should_serialize_error()
@@ -246,6 +313,24 @@ public void DeserializeCollectionIntegrationTest()
246313
Assert.AreEqual(p.Id, posts[0].Id); // Order matters, right?
247314
}
248315

316+
[TestMethod]
317+
public async Task Deserializes_attributes_properly()
318+
{
319+
// Arrange
320+
JsonApiFormatter formatter = new JsonApiFormatter(new PluralizationService());
321+
MemoryStream stream = new MemoryStream();
322+
323+
await formatter.WriteToStreamAsync(typeof(Sample), new List<Sample> { s1, s2 }, stream, null, null);
324+
stream.Seek(0, SeekOrigin.Begin);
325+
326+
var deserialized = (IList<Sample>)await formatter.ReadFromStreamAsync(typeof(Sample), stream, null, null);
327+
328+
// Assert
329+
deserialized.Count.Should().Be(2);
330+
deserialized[0].ShouldBeEquivalentTo(s1);
331+
deserialized[1].ShouldBeEquivalentTo(s2);
332+
}
333+
249334
[TestMethod]
250335
[DeploymentItem(@"Data\DeserializeRawJsonTest.json")]
251336
public async Task DeserializeRawJsonTest()

JSONAPI.Tests/Models/Sample.cs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using System;
2+
3+
namespace JSONAPI.Tests.Models
4+
{
5+
enum SampleEnum
6+
{
7+
Value1 = 1,
8+
Value2 = 2
9+
}
10+
11+
class Sample
12+
{
13+
public string Id { get; set; }
14+
public Boolean BooleanField { get; set; }
15+
public Boolean? NullableBooleanField { get; set; }
16+
public SByte SByteField { get; set; }
17+
public SByte? NullableSByteField { get; set; }
18+
public Byte ByteField { get; set; }
19+
public Byte? NullableByteField { get; set; }
20+
public Int16 Int16Field { get; set; }
21+
public Int16? NullableInt16Field { get; set; }
22+
public UInt16 UInt16Field { get; set; }
23+
public UInt16? NullableUInt16Field { get; set; }
24+
public Int32 Int32Field { get; set; }
25+
public Int32? NullableInt32Field { get; set; }
26+
public UInt32 UInt32Field { get; set; }
27+
public UInt32? NullableUInt32Field { get; set; }
28+
public Int64 Int64Field { get; set; }
29+
public Int64? NullableInt64Field { get; set; }
30+
public UInt64 UInt64Field { get; set; }
31+
public UInt64? NullableUInt64Field { get; set; }
32+
public Double DoubleField { get; set; }
33+
public Double? NullableDoubleField { get; set; }
34+
public Single SingleField { get; set; }
35+
public Single? NullableSingleField { get; set; }
36+
public Decimal DecimalField { get; set; }
37+
public Decimal? NullableDecimalField { get; set; }
38+
public DateTime DateTimeField { get; set; }
39+
public DateTime? NullableDateTimeField { get; set; }
40+
public DateTimeOffset DateTimeOffsetField { get; set; }
41+
public DateTimeOffset? NullableDateTimeOffsetField { get; set; }
42+
public Guid GuidField { get; set; }
43+
public Guid? NullableGuidField { get; set; }
44+
public string StringField { get; set; }
45+
public SampleEnum EnumField { get; set; }
46+
public SampleEnum? NullableEnumField { get; set; }
47+
}
48+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using System;
2+
3+
namespace JSONAPI.Extensions
4+
{
5+
internal static class TypeExtensions
6+
{
7+
internal static bool CanWriteAsJsonApiAttribute(this Type objectType)
8+
{
9+
if (objectType.IsGenericType && objectType.GetGenericTypeDefinition() == typeof (Nullable<>))
10+
objectType = objectType.GetGenericArguments()[0];
11+
12+
return objectType.IsPrimitive
13+
|| typeof (Decimal).IsAssignableFrom(objectType)
14+
|| typeof (Guid).IsAssignableFrom(objectType)
15+
|| typeof (DateTime).IsAssignableFrom(objectType)
16+
|| typeof (DateTimeOffset).IsAssignableFrom(objectType)
17+
|| typeof (String).IsAssignableFrom(objectType)
18+
|| objectType.IsEnum;
19+
}
20+
21+
}
22+
}

0 commit comments

Comments
 (0)