From dd4ea70ba37a965255a75bf15f5e1e4006d46a13 Mon Sep 17 00:00:00 2001 From: tpluscode Date: Thu, 12 Jan 2017 20:17:14 +0100 Subject: [PATCH 1/9] add test for serializing expanded XSD types --- .../Bindings/SerializingSteps.cs | 9 +++ .../Entities/AllPrimitives.cs | 39 ++++++++++ .../JsonLD.Entities.Tests.csproj | 2 + src/JsonLD.Entities.Tests/Serializing.feature | 47 +++++++++++- .../Serializing.feature.cs | 75 ++++++++++++++++++- .../SpecflowHelpers/TableExtensions.cs | 24 ++++++ 6 files changed, 193 insertions(+), 3 deletions(-) create mode 100644 src/JsonLD.Entities.Tests/Entities/AllPrimitives.cs create mode 100644 src/JsonLD.Entities.Tests/SpecflowHelpers/TableExtensions.cs diff --git a/src/JsonLD.Entities.Tests/Bindings/SerializingSteps.cs b/src/JsonLD.Entities.Tests/Bindings/SerializingSteps.cs index f98c055..d622e98 100644 --- a/src/JsonLD.Entities.Tests/Bindings/SerializingSteps.cs +++ b/src/JsonLD.Entities.Tests/Bindings/SerializingSteps.cs @@ -2,9 +2,11 @@ using FakeItEasy; using ImpromptuInterface; using JsonLD.Entities.Tests.Entities; +using JsonLD.Entities.Tests.SpecflowHelpers; using Newtonsoft.Json.Linq; using NUnit.Framework; using TechTalk.SpecFlow; +using TechTalk.SpecFlow.Assist; namespace JsonLD.Entities.Tests.Bindings { @@ -37,6 +39,13 @@ public void GivenModelOfType(string typeName) this.context.Object = Activator.CreateInstance(model); } + [Given(@"model of type '(.*)'")] + public void GivenModelOfType(string typeName, Table table) + { + var modelType = Type.GetType(typeName, true); + this.context.Object = table.CreateInstance(modelType); + } + [Given(@"model has interest '(.*)'")] public void GivenModelInterestsRDF(string value) { diff --git a/src/JsonLD.Entities.Tests/Entities/AllPrimitives.cs b/src/JsonLD.Entities.Tests/Entities/AllPrimitives.cs new file mode 100644 index 0000000..d132865 --- /dev/null +++ b/src/JsonLD.Entities.Tests/Entities/AllPrimitives.cs @@ -0,0 +1,39 @@ +// ReSharper disable InconsistentNaming +#pragma warning disable SA1300 // Element must begin with upper-case letter +using System; + +namespace JsonLD.Entities.Tests.Entities +{ + public class AllPrimitives + { + public string @string { get; set; } + + public bool? @bool { get; set; } + + public double? @double { get; set; } + + public DateTime? date { get; set; } + + public decimal? @decimal { get; set; } + + public long? @long { get; set; } + + public ulong? @ulong { get; set; } + + public int? @int { get; set; } + + public uint? @uint { get; set; } + + public short? @short { get; set; } + + public ushort? @ushort { get; set; } + + public byte? @byte { get; set; } + + public sbyte? @sbyte { get; set; } + + public float? @float { get; set; } + + public TimeSpan? timeSpan { get; set; } + } +} \ No newline at end of file diff --git a/src/JsonLD.Entities.Tests/JsonLD.Entities.Tests.csproj b/src/JsonLD.Entities.Tests/JsonLD.Entities.Tests.csproj index 9ac7285..52e9388 100644 --- a/src/JsonLD.Entities.Tests/JsonLD.Entities.Tests.csproj +++ b/src/JsonLD.Entities.Tests/JsonLD.Entities.Tests.csproj @@ -68,6 +68,7 @@ True DeserializingRDF.feature + @@ -91,6 +92,7 @@ True Serializing.feature + diff --git a/src/JsonLD.Entities.Tests/Serializing.feature b/src/JsonLD.Entities.Tests/Serializing.feature index 29218af..a7309a9 100644 --- a/src/JsonLD.Entities.Tests/Serializing.feature +++ b/src/JsonLD.Entities.Tests/Serializing.feature @@ -69,4 +69,49 @@ Scenario: Serialize model with prefixed name in ClassAttribute { "@type": "ex:Person" } - """ \ No newline at end of file + """ + +Scenario: Serializing primitive values should produce short literals for Boolean, Double and String + Given model of type 'JsonLD.Entities.Tests.Entities.AllPrimitives' + | Property | Value | + | string | Hello | + | double | 3.14 | + | bool | true | + When the object is serialized + Then the resulting JSON-LD should be: + """ + { + "string": "Hello", + "double": 3.14, + "bool": true + } + """ + +Scenario Outline: Serializing primitive values should produce typed literals + Given model of type 'JsonLD.Entities.Tests.Entities.AllPrimitives' + | Property | Value | + | | | + When the object is serialized + Then the resulting JSON-LD should be: + """ + { + "": { + "@value": "", + "@type": "http://www.w3.org/2001/XMLSchema#" + } + } + """ + Examples: + | Property | Value | JsonValue | XsdType | + | date | 2016-01-03 | 2016-01-03T00:00:00 | dateTime | + | decimal | 3.4 | 3.4 | decimal | + | long | 100 | 100 | long | + | ulong | 100 | 100 | unsignedLong | + | int | 1567 | 1567 | int | + | uint | 15 | 15 | unsignedInt | + | short | 17 | 17 | short | + | ushort | 3 | 3 | unsignedShort | + | byte | 20 | 20 | unsignedByte | + | sbyte | -3 | -3 | byte | + | float | 2.3456 | 2.3456 | float | + | timeSpan | 100 | 100 | duration | \ No newline at end of file diff --git a/src/JsonLD.Entities.Tests/Serializing.feature.cs b/src/JsonLD.Entities.Tests/Serializing.feature.cs index 447ea62..1331e22 100644 --- a/src/JsonLD.Entities.Tests/Serializing.feature.cs +++ b/src/JsonLD.Entities.Tests/Serializing.feature.cs @@ -1,7 +1,7 @@ // ------------------------------------------------------------------------------ // // This code was generated by SpecFlow (http://www.specflow.org/). -// SpecFlow Version:2.0.0.0 +// SpecFlow Version:2.1.0.0 // SpecFlow Generator Version:2.0.0.0 // // Changes to this file may cause incorrect behavior and will be lost if @@ -15,7 +15,7 @@ namespace JsonLD.Entities.Tests using TechTalk.SpecFlow; - [System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "2.0.0.0")] + [System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "2.1.0.0")] [System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [NUnit.Framework.TestFixtureAttribute()] [NUnit.Framework.DescriptionAttribute("Serializing")] @@ -164,6 +164,77 @@ public virtual void SerializeModelWithPrefixedNameInClassAttribute() #line hidden #line 67 testRunner.Then("the resulting JSON-LD should be:", "{\r\n \"@type\": \"ex:Person\"\r\n}", ((TechTalk.SpecFlow.Table)(null)), "Then "); +#line hidden + this.ScenarioCleanup(); + } + + [NUnit.Framework.TestAttribute()] + [NUnit.Framework.DescriptionAttribute("Serializing primitive values should produce short literals for Boolean, Double an" + + "d String")] + public virtual void SerializingPrimitiveValuesShouldProduceShortLiteralsForBooleanDoubleAndString() + { + TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Serializing primitive values should produce short literals for Boolean, Double an" + + "d String", ((string[])(null))); +#line 74 +this.ScenarioSetup(scenarioInfo); +#line hidden + TechTalk.SpecFlow.Table table1 = new TechTalk.SpecFlow.Table(new string[] { + "Property", + "Value"}); + table1.AddRow(new string[] { + "string", + "Hello"}); + table1.AddRow(new string[] { + "double", + "3.14"}); + table1.AddRow(new string[] { + "bool", + "true"}); +#line 75 + testRunner.Given("model of type \'JsonLD.Entities.Tests.Entities.AllPrimitives\'", ((string)(null)), table1, "Given "); +#line 80 + testRunner.When("the object is serialized", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); +#line hidden +#line 81 + testRunner.Then("the resulting JSON-LD should be:", "{\r\n\"string\": \"Hello\",\r\n\"double\": 3.14,\r\n\"bool\": true\r\n}", ((TechTalk.SpecFlow.Table)(null)), "Then "); +#line hidden + this.ScenarioCleanup(); + } + + [NUnit.Framework.TestAttribute()] + [NUnit.Framework.DescriptionAttribute("Serializing primitive values should produce typed literals")] + [NUnit.Framework.TestCaseAttribute("date", "2016-01-03", "2016-01-03T00:00:00", "dateTime", new string[0])] + [NUnit.Framework.TestCaseAttribute("decimal", "3.4", "3.4", "decimal", new string[0])] + [NUnit.Framework.TestCaseAttribute("long", "100", "100", "long", new string[0])] + [NUnit.Framework.TestCaseAttribute("ulong", "100", "100", "unsignedLong", new string[0])] + [NUnit.Framework.TestCaseAttribute("int", "1567", "1567", "int", new string[0])] + [NUnit.Framework.TestCaseAttribute("uint", "15", "15", "unsignedInt", new string[0])] + [NUnit.Framework.TestCaseAttribute("short", "17", "17", "short", new string[0])] + [NUnit.Framework.TestCaseAttribute("ushort", "3", "3", "unsignedShort", new string[0])] + [NUnit.Framework.TestCaseAttribute("byte", "20", "20", "unsignedByte", new string[0])] + [NUnit.Framework.TestCaseAttribute("sbyte", "-3", "-3", "byte", new string[0])] + [NUnit.Framework.TestCaseAttribute("float", "2.3456", "2.3456", "float", new string[0])] + [NUnit.Framework.TestCaseAttribute("timeSpan", "100", "100", "duration", new string[0])] + public virtual void SerializingPrimitiveValuesShouldProduceTypedLiterals(string property, string value, string jsonValue, string xsdType, string[] exampleTags) + { + TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Serializing primitive values should produce typed literals", exampleTags); +#line 90 +this.ScenarioSetup(scenarioInfo); +#line hidden + TechTalk.SpecFlow.Table table2 = new TechTalk.SpecFlow.Table(new string[] { + "Property", + "Value"}); + table2.AddRow(new string[] { + string.Format("{0}", property), + string.Format("{0}", value)}); +#line 91 + testRunner.Given("model of type \'JsonLD.Entities.Tests.Entities.AllPrimitives\'", ((string)(null)), table2, "Given "); +#line 94 + testRunner.When("the object is serialized", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); +#line hidden +#line 95 + testRunner.Then("the resulting JSON-LD should be:", string.Format("{{\r\n\"{0}\": {{\r\n\"@value\": \"{1}\",\r\n\"@type\": \"http://www.w3.org/2001/XMLSchema#{0}\"\r" + + "\n}}\r\n}}", property, jsonValue), ((TechTalk.SpecFlow.Table)(null)), "Then "); #line hidden this.ScenarioCleanup(); } diff --git a/src/JsonLD.Entities.Tests/SpecflowHelpers/TableExtensions.cs b/src/JsonLD.Entities.Tests/SpecflowHelpers/TableExtensions.cs new file mode 100644 index 0000000..744f793 --- /dev/null +++ b/src/JsonLD.Entities.Tests/SpecflowHelpers/TableExtensions.cs @@ -0,0 +1,24 @@ +using System; +using System.Reflection; +using TechTalk.SpecFlow; +using TechTalk.SpecFlow.Assist; + +namespace JsonLD.Entities.Tests.SpecflowHelpers +{ + public static class TableExtensions + { + private static readonly MethodInfo RealCreateInstance; + + static TableExtensions() + { + RealCreateInstance = typeof(TableHelperExtensionMethods).GetMethod("CreateInstance", new[] { typeof(Table) }); + } + + public static object CreateInstance(this Table table, Type objecType) + { + var createInstance = RealCreateInstance.MakeGenericMethod(objecType); + + return createInstance.Invoke(null, new object[] { table }); + } + } +} \ No newline at end of file From 0268047dc2d7af56706f3a441b0f8f28a4466b3c Mon Sep 17 00:00:00 2001 From: tpluscode Date: Thu, 12 Jan 2017 21:26:09 +0100 Subject: [PATCH 2/9] fix up tests and implement serializing --- paket.dependencies | 1 + paket.lock | 4 +- .../Bindings/SerializingSteps.cs | 13 ++-- src/JsonLD.Entities.Tests/Entities/Person.cs | 2 - .../JsonLD.Entities.Tests.csproj | 11 ++++ src/JsonLD.Entities.Tests/Serializing.feature | 7 +-- .../Serializing.feature.cs | 63 +++++++++---------- src/JsonLD.Entities.Tests/paket.references | 3 +- .../Converters/JsonLdLiteralConverter.cs | 26 +++++++- src/JsonLD.Entities/JsonLD.Entities.csproj | 11 ++++ src/JsonLD.Entities/JsonLdKeywords.cs | 5 ++ src/JsonLD.Entities/TypeExtension.cs | 49 +++++++++++++++ src/JsonLD.Entities/paket.references | 3 +- 13 files changed, 148 insertions(+), 50 deletions(-) diff --git a/paket.dependencies b/paket.dependencies index 76c60bd..bf85741 100644 --- a/paket.dependencies +++ b/paket.dependencies @@ -21,5 +21,6 @@ nuget Costura.Fody nuget Rdf.Vocabularies nuget OpenCover nuget Newtonsoft.Json ~> 9 +nuget JsonDiffPatch.Net gist tpluscode/a285267d2543466fc35c3a168c846f9f \ No newline at end of file diff --git a/paket.lock b/paket.lock index bd05778..ea98f8c 100644 --- a/paket.lock +++ b/paket.lock @@ -17,6 +17,8 @@ NUGET ImpromptuInterface (6.2.2) InfoOf.Fody (1.0.4) Fody (>= 1.29.2) + JsonDiffPatch.Net (1.0.5) + Newtonsoft.Json (>= 8.0.2) json-ld.net (1.0.5) Newtonsoft.Json (>= 6.0.4) MethodTimer.Fody (1.16) @@ -32,4 +34,4 @@ NUGET VDS.Common (1.6.4) GIST remote: tpluscode/a285267d2543466fc35c3a168c846f9f - FULLPROJECT (eac8af5adfdcfc43b63a5d5edf88c082e83761e0) \ No newline at end of file + FULLPROJECT (c9b7a831e53e929f2ecce09b14a61e28007b669f) \ No newline at end of file diff --git a/src/JsonLD.Entities.Tests/Bindings/SerializingSteps.cs b/src/JsonLD.Entities.Tests/Bindings/SerializingSteps.cs index d622e98..93ee80b 100644 --- a/src/JsonLD.Entities.Tests/Bindings/SerializingSteps.cs +++ b/src/JsonLD.Entities.Tests/Bindings/SerializingSteps.cs @@ -1,12 +1,12 @@ using System; using FakeItEasy; using ImpromptuInterface; +using JsonDiffPatchDotNet; using JsonLD.Entities.Tests.Entities; using JsonLD.Entities.Tests.SpecflowHelpers; using Newtonsoft.Json.Linq; using NUnit.Framework; using TechTalk.SpecFlow; -using TechTalk.SpecFlow.Assist; namespace JsonLD.Entities.Tests.Bindings { @@ -25,11 +25,10 @@ public SerializingSteps(SerializerTestContext context) public void GivenAPersonWithoutId() { this.context.Object = new Person - { - Name = "Tomasz", - Surname = "Pluskiewicz", - BirthDate = new DateTime(1972, 9, 4) - }; + { + Name = "Tomasz", + Surname = "Pluskiewicz" + }; } [Given(@"model of type '(.*)'")] @@ -62,7 +61,7 @@ public void WhenTheObjectIsSerialized() public void ThenTheResultingJsonLdShouldBe(string jObject) { var expected = JObject.Parse(jObject); - Assert.That(JToken.DeepEquals(this.context.JsonLdObject, expected), "Actual object was: {0}", this.context.JsonLdObject); + Assert.That(JToken.DeepEquals(this.context.JsonLdObject, expected), "Diff: {0}", new JsonDiffPatch().Diff(expected, this.context.JsonLdObject)); } } } diff --git a/src/JsonLD.Entities.Tests/Entities/Person.cs b/src/JsonLD.Entities.Tests/Entities/Person.cs index f961003..c5ac49d 100644 --- a/src/JsonLD.Entities.Tests/Entities/Person.cs +++ b/src/JsonLD.Entities.Tests/Entities/Person.cs @@ -9,7 +9,5 @@ public class Person public string Name { get; set; } public string Surname { get; set; } - - public DateTime BirthDate { get; set; } } } diff --git a/src/JsonLD.Entities.Tests/JsonLD.Entities.Tests.csproj b/src/JsonLD.Entities.Tests/JsonLD.Entities.Tests.csproj index 52e9388..0be3a92 100644 --- a/src/JsonLD.Entities.Tests/JsonLD.Entities.Tests.csproj +++ b/src/JsonLD.Entities.Tests/JsonLD.Entities.Tests.csproj @@ -204,6 +204,17 @@ + + + + + ..\..\packages\JsonDiffPatch.Net\lib\net45\JsonDiffPatchDotNet.dll + True + True + + + + diff --git a/src/JsonLD.Entities.Tests/Serializing.feature b/src/JsonLD.Entities.Tests/Serializing.feature index a7309a9..6f0e158 100644 --- a/src/JsonLD.Entities.Tests/Serializing.feature +++ b/src/JsonLD.Entities.Tests/Serializing.feature @@ -8,8 +8,7 @@ Scenario: Serialize simple model with blank id """ { "name": "Tomasz", - "surname": "Pluskiewicz", - "birthDate": "1972-09-04T00:00:00" + "surname": "Pluskiewicz" } """ @@ -97,7 +96,7 @@ Scenario Outline: Serializing primitive values should produce typed literals { "": { "@value": "", - "@type": "http://www.w3.org/2001/XMLSchema#" + "@type": "http://www.w3.org/2001/XMLSchema#" } } """ @@ -114,4 +113,4 @@ Scenario Outline: Serializing primitive values should produce typed literals | byte | 20 | 20 | unsignedByte | | sbyte | -3 | -3 | byte | | float | 2.3456 | 2.3456 | float | - | timeSpan | 100 | 100 | duration | \ No newline at end of file + | timeSpan | 50.08:20:17 | P50DT8H20M17S | duration | \ No newline at end of file diff --git a/src/JsonLD.Entities.Tests/Serializing.feature.cs b/src/JsonLD.Entities.Tests/Serializing.feature.cs index 1331e22..247f8a7 100644 --- a/src/JsonLD.Entities.Tests/Serializing.feature.cs +++ b/src/JsonLD.Entities.Tests/Serializing.feature.cs @@ -76,8 +76,7 @@ public virtual void SerializeSimpleModelWithBlankId() testRunner.When("the object is serialized", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); #line hidden #line 7 - testRunner.Then("the resulting JSON-LD should be:", "{\r\n \"name\": \"Tomasz\",\r\n \"surname\": \"Pluskiewicz\",\r\n \"birthDate\": \"1972-0" + - "9-04T00:00:00\"\r\n}", ((TechTalk.SpecFlow.Table)(null)), "Then "); + testRunner.Then("the resulting JSON-LD should be:", "{\r\n \"name\": \"Tomasz\",\r\n \"surname\": \"Pluskiewicz\"\r\n}", ((TechTalk.SpecFlow.Table)(null)), "Then "); #line hidden this.ScenarioCleanup(); } @@ -92,16 +91,16 @@ public virtual void SerializeSimpleModelWithBlankId() public virtual void SerializeModelWithSingleElementInSet(string type, string[] exampleTags) { TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Serialize model with single element in set", exampleTags); -#line 16 +#line 15 this.ScenarioSetup(scenarioInfo); -#line 17 +#line 16 testRunner.Given(string.Format("model of type \'{0}\'", type), ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Given "); -#line 18 +#line 17 testRunner.And("model has interest \'RDF\'", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line 19 +#line 18 testRunner.When("the object is serialized", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); #line hidden -#line 20 +#line 19 testRunner.Then("the resulting JSON-LD should be:", "{\r\n \"interests\": [ \"RDF\" ]\r\n}", ((TechTalk.SpecFlow.Table)(null)), "Then "); #line hidden this.ScenarioCleanup(); @@ -112,16 +111,16 @@ public virtual void SerializeModelWithSingleElementInSet(string type, string[] e public virtual void SerializeModelWithSingleElementInList() { TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Serialize model with single element in list", ((string[])(null))); -#line 34 +#line 33 this.ScenarioSetup(scenarioInfo); -#line 35 +#line 34 testRunner.Given("model of type \'JsonLD.Entities.Tests.Entities.HasInterestsList\'", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Given "); -#line 36 +#line 35 testRunner.And("model has interest \'RDF\'", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); -#line 37 +#line 36 testRunner.When("the object is serialized", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); #line hidden -#line 38 +#line 37 testRunner.Then("the resulting JSON-LD should be:", "{\r\n \"interests\": [ \"RDF\" ]\r\n}", ((TechTalk.SpecFlow.Table)(null)), "Then "); #line hidden this.ScenarioCleanup(); @@ -134,14 +133,14 @@ public virtual void SerializeModelWithSingleElementInList() public virtual void SerializeModelWithEmptyCollection(string type, string[] exampleTags) { TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Serialize model with empty collection", exampleTags); -#line 45 +#line 44 this.ScenarioSetup(scenarioInfo); -#line 46 +#line 45 testRunner.Given(string.Format("model of type \'{0}\'", type), ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Given "); -#line 47 +#line 46 testRunner.When("the object is serialized", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); #line hidden -#line 48 +#line 47 testRunner.Then("the resulting JSON-LD should be:", "{\r\n}", ((TechTalk.SpecFlow.Table)(null)), "Then "); #line hidden this.ScenarioCleanup(); @@ -152,17 +151,17 @@ public virtual void SerializeModelWithEmptyCollection(string type, string[] exam public virtual void SerializeModelWithPrefixedNameInClassAttribute() { TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Serialize model with prefixed name in ClassAttribute", ((string[])(null))); -#line 58 +#line 57 this.ScenarioSetup(scenarioInfo); -#line 59 +#line 58 testRunner.Given("model of type \'JsonLD.Entities.Tests.Entities.PersonWithPrefixedClass\'", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Given "); #line hidden -#line 60 +#line 59 testRunner.And("@context is:", "{\r\n \"ex\": \"http://example.com/ontology#\"\r\n}", ((TechTalk.SpecFlow.Table)(null)), "And "); -#line 66 +#line 65 testRunner.When("the object is serialized", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); #line hidden -#line 67 +#line 66 testRunner.Then("the resulting JSON-LD should be:", "{\r\n \"@type\": \"ex:Person\"\r\n}", ((TechTalk.SpecFlow.Table)(null)), "Then "); #line hidden this.ScenarioCleanup(); @@ -175,7 +174,7 @@ public virtual void SerializingPrimitiveValuesShouldProduceShortLiteralsForBoole { TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Serializing primitive values should produce short literals for Boolean, Double an" + "d String", ((string[])(null))); -#line 74 +#line 73 this.ScenarioSetup(scenarioInfo); #line hidden TechTalk.SpecFlow.Table table1 = new TechTalk.SpecFlow.Table(new string[] { @@ -190,12 +189,12 @@ public virtual void SerializingPrimitiveValuesShouldProduceShortLiteralsForBoole table1.AddRow(new string[] { "bool", "true"}); -#line 75 +#line 74 testRunner.Given("model of type \'JsonLD.Entities.Tests.Entities.AllPrimitives\'", ((string)(null)), table1, "Given "); -#line 80 +#line 79 testRunner.When("the object is serialized", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); #line hidden -#line 81 +#line 80 testRunner.Then("the resulting JSON-LD should be:", "{\r\n\"string\": \"Hello\",\r\n\"double\": 3.14,\r\n\"bool\": true\r\n}", ((TechTalk.SpecFlow.Table)(null)), "Then "); #line hidden this.ScenarioCleanup(); @@ -214,11 +213,11 @@ public virtual void SerializingPrimitiveValuesShouldProduceShortLiteralsForBoole [NUnit.Framework.TestCaseAttribute("byte", "20", "20", "unsignedByte", new string[0])] [NUnit.Framework.TestCaseAttribute("sbyte", "-3", "-3", "byte", new string[0])] [NUnit.Framework.TestCaseAttribute("float", "2.3456", "2.3456", "float", new string[0])] - [NUnit.Framework.TestCaseAttribute("timeSpan", "100", "100", "duration", new string[0])] + [NUnit.Framework.TestCaseAttribute("timeSpan", "50.08:20:17", "P50DT8H20M17S", "duration", new string[0])] public virtual void SerializingPrimitiveValuesShouldProduceTypedLiterals(string property, string value, string jsonValue, string xsdType, string[] exampleTags) { TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Serializing primitive values should produce typed literals", exampleTags); -#line 90 +#line 89 this.ScenarioSetup(scenarioInfo); #line hidden TechTalk.SpecFlow.Table table2 = new TechTalk.SpecFlow.Table(new string[] { @@ -227,14 +226,14 @@ public virtual void SerializingPrimitiveValuesShouldProduceTypedLiterals(string table2.AddRow(new string[] { string.Format("{0}", property), string.Format("{0}", value)}); -#line 91 +#line 90 testRunner.Given("model of type \'JsonLD.Entities.Tests.Entities.AllPrimitives\'", ((string)(null)), table2, "Given "); -#line 94 +#line 93 testRunner.When("the object is serialized", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); #line hidden -#line 95 - testRunner.Then("the resulting JSON-LD should be:", string.Format("{{\r\n\"{0}\": {{\r\n\"@value\": \"{1}\",\r\n\"@type\": \"http://www.w3.org/2001/XMLSchema#{0}\"\r" + - "\n}}\r\n}}", property, jsonValue), ((TechTalk.SpecFlow.Table)(null)), "Then "); +#line 94 + testRunner.Then("the resulting JSON-LD should be:", string.Format("{{\r\n\"{0}\": {{\r\n\"@value\": \"{1}\",\r\n\"@type\": \"http://www.w3.org/2001/XMLSchema#{2}\"\r" + + "\n}}\r\n}}", property, jsonValue, xsdType), ((TechTalk.SpecFlow.Table)(null)), "Then "); #line hidden this.ScenarioCleanup(); } diff --git a/src/JsonLD.Entities.Tests/paket.references b/src/JsonLD.Entities.Tests/paket.references index ebcf370..d6c55b9 100644 --- a/src/JsonLD.Entities.Tests/paket.references +++ b/src/JsonLD.Entities.Tests/paket.references @@ -6,4 +6,5 @@ ImpromptuInterface FakeItEasy json-ld.net StyleCop.Analyzers -Rdf.Vocabularies \ No newline at end of file +Rdf.Vocabularies +JsonDiffPatch.Net \ No newline at end of file diff --git a/src/JsonLD.Entities/Converters/JsonLdLiteralConverter.cs b/src/JsonLD.Entities/Converters/JsonLdLiteralConverter.cs index b7b5fe2..a343b48 100644 --- a/src/JsonLD.Entities/Converters/JsonLdLiteralConverter.cs +++ b/src/JsonLD.Entities/Converters/JsonLdLiteralConverter.cs @@ -1,4 +1,5 @@ using System; +using System.Xml; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using NullGuard; @@ -28,7 +29,28 @@ static JsonLdLiteralConverter() /// public override void WriteJson(JsonWriter writer, [AllowNull] object value, JsonSerializer serializer) { - writer.WriteValue(value); + var type = value?.GetType(); + if (type?.HasImplicitlyTypedJsonType() == true) + { + writer.WriteValue(value); + return; + } + + writer.WriteStartObject(); + writer.WritePropertyName(JsonLdKeywords.Value); + + if (value is TimeSpan) + { + writer.WriteValue(XmlConvert.ToString((TimeSpan)value)); + } + else + { + var valueString = JsonConvert.ToString(value); + writer.WriteValue(valueString.Trim('"')); // for the weirdest of reasons, DateTime is double-quoted + } + + writer.WritePropertyName(JsonLdKeywords.Type); + writer.WriteValue(type.GetXsdType()); } /// @@ -50,7 +72,7 @@ public sealed override object ReadJson( { reader.Read(); - if (reader.TokenType == JsonToken.PropertyName && Equals(reader.Value, "@value")) + if (reader.TokenType == JsonToken.PropertyName && Equals(reader.Value, JsonLdKeywords.Value)) { reader.Read(); value = this.DeserializeLiteral(reader, objectType, serializer); diff --git a/src/JsonLD.Entities/JsonLD.Entities.csproj b/src/JsonLD.Entities/JsonLD.Entities.csproj index 1c80555..9368006 100644 --- a/src/JsonLD.Entities/JsonLD.Entities.csproj +++ b/src/JsonLD.Entities/JsonLD.Entities.csproj @@ -177,6 +177,17 @@ + + + + + ..\..\packages\Rdf.Vocabularies\lib\portable-net4+sl5+netcore45+wpa81+wp8+MonoAndroid1+MonoTouch1\Rdf.Vocabularies.dll + True + True + + + + diff --git a/src/JsonLD.Entities/JsonLdKeywords.cs b/src/JsonLD.Entities/JsonLdKeywords.cs index bc5a586..6bc7aa6 100644 --- a/src/JsonLD.Entities/JsonLdKeywords.cs +++ b/src/JsonLD.Entities/JsonLdKeywords.cs @@ -59,6 +59,11 @@ public static class JsonLdKeywords /// public const string Index = "@index"; + /// + /// @value keyword + /// + public const string Value = "@value"; + private static readonly IDictionary KnownPropertyNames = new Dictionary(); static JsonLdKeywords() diff --git a/src/JsonLD.Entities/TypeExtension.cs b/src/JsonLD.Entities/TypeExtension.cs index 2b4aad1..c773b9a 100644 --- a/src/JsonLD.Entities/TypeExtension.cs +++ b/src/JsonLD.Entities/TypeExtension.cs @@ -1,5 +1,8 @@ using System; +using System.Collections.Generic; using System.Linq; +using NullGuard; +using Vocab; namespace JsonLD.Entities { @@ -8,6 +11,27 @@ namespace JsonLD.Entities /// internal static class TypeExtension { + private static readonly IDictionary XsdDatatypeMappings; + + static TypeExtension() + { + XsdDatatypeMappings = new Dictionary + { + [typeof(int)] = Xsd.@int, + [typeof(uint)] = Xsd.unsignedInt, + [typeof(long)] = Xsd.@long, + [typeof(ulong)] = Xsd.unsignedLong, + [typeof(short)] = Xsd.@short, + [typeof(ushort)] = Xsd.unsignedShort, + [typeof(sbyte)] = Xsd.@byte, + [typeof(byte)] = Xsd.unsignedByte, + [typeof(DateTime)] = Xsd.dateTime, + [typeof(TimeSpan)] = Xsd.duration, + [typeof(float)] = Xsd.@float, + [typeof(decimal)] = Xsd.@decimal, + }; + } + /// /// Determines whether the should be compacted after serialization. /// @@ -15,5 +39,30 @@ internal static bool IsMarkedForCompaction(this Type type) { return type.GetCustomAttributes(typeof(SerializeCompactedAttribute), true).Any(); } + + /// + /// Determines whether the type has implicit type in JSON (ie. doesn't require explicit JSON-LD typing) + /// + internal static bool HasImplicitlyTypedJsonType([AllowNull] this Type type) + { + return type == null + || type == typeof(bool) + || type == typeof(double) + || type == typeof(string); + } + + /// + /// Gets the URI of an XSD datatype for + /// + internal static string GetXsdType(this Type type) + { + string xsdTypeName; + if (XsdDatatypeMappings.TryGetValue(type, out xsdTypeName) == false) + { + throw new ArgumentOutOfRangeException(nameof(type), $"Type {type.Name} doesn't have an XSD equivalent"); + } + + return xsdTypeName; + } } } diff --git a/src/JsonLD.Entities/paket.references b/src/JsonLD.Entities/paket.references index 51a7af9..9b88160 100644 --- a/src/JsonLD.Entities/paket.references +++ b/src/JsonLD.Entities/paket.references @@ -4,4 +4,5 @@ NullGuard.Fody InfoOf.Fody ImpromptuInterface Costura.Fody -StyleCop.Analyzers \ No newline at end of file +StyleCop.Analyzers +Rdf.Vocabularies \ No newline at end of file From adcaac2619628ebbb6fb89d631a373c353e2ba5b Mon Sep 17 00:00:00 2001 From: tpluscode Date: Thu, 12 Jan 2017 21:30:29 +0100 Subject: [PATCH 3/9] shouldn't have remove that property --- src/JsonLD.Entities.Tests/Entities/Person.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/JsonLD.Entities.Tests/Entities/Person.cs b/src/JsonLD.Entities.Tests/Entities/Person.cs index c5ac49d..bb52d34 100644 --- a/src/JsonLD.Entities.Tests/Entities/Person.cs +++ b/src/JsonLD.Entities.Tests/Entities/Person.cs @@ -9,5 +9,7 @@ public class Person public string Name { get; set; } public string Surname { get; set; } + + public DateTime? BirthDate { get; set; } } } From 37c320a424119817cda66cb0b514dc0898f94b86 Mon Sep 17 00:00:00 2001 From: tpluscode Date: Thu, 12 Jan 2017 21:44:46 +0100 Subject: [PATCH 4/9] fix tests, which failed on JToken comparison --- src/JsonLD.Entities.Tests/Bindings/SerializingSteps.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/JsonLD.Entities.Tests/Bindings/SerializingSteps.cs b/src/JsonLD.Entities.Tests/Bindings/SerializingSteps.cs index 93ee80b..26fb181 100644 --- a/src/JsonLD.Entities.Tests/Bindings/SerializingSteps.cs +++ b/src/JsonLD.Entities.Tests/Bindings/SerializingSteps.cs @@ -60,8 +60,10 @@ public void WhenTheObjectIsSerialized() [Then(@"the resulting JSON-LD should be:")] public void ThenTheResultingJsonLdShouldBe(string jObject) { + // round-trip serialize/parse to remove typed JTokens + var jsonLdObject = JObject.Parse(this.context.JsonLdObject.ToString()); var expected = JObject.Parse(jObject); - Assert.That(JToken.DeepEquals(this.context.JsonLdObject, expected), "Diff: {0}", new JsonDiffPatch().Diff(expected, this.context.JsonLdObject)); + Assert.That(JToken.DeepEquals(jsonLdObject, expected), "Diff: {0}", new JsonDiffPatch().Diff(expected, jsonLdObject)); } } } From 017939baafc6953b774cc48962d026da74a62f99 Mon Sep 17 00:00:00 2001 From: tpluscode Date: Fri, 13 Jan 2017 20:05:33 +0100 Subject: [PATCH 5/9] also support DateTimeOffset as xsd:dateTime --- .../Bindings/SerializingSteps.cs | 9 +++++ .../Entities/AllPrimitives.cs | 2 + src/JsonLD.Entities.Tests/Serializing.feature | 40 +++++++++++++------ .../Serializing.feature.cs | 23 ++++++++++- src/JsonLD.Entities/TypeExtension.cs | 1 + 5 files changed, 61 insertions(+), 14 deletions(-) diff --git a/src/JsonLD.Entities.Tests/Bindings/SerializingSteps.cs b/src/JsonLD.Entities.Tests/Bindings/SerializingSteps.cs index 26fb181..1f208be 100644 --- a/src/JsonLD.Entities.Tests/Bindings/SerializingSteps.cs +++ b/src/JsonLD.Entities.Tests/Bindings/SerializingSteps.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; using FakeItEasy; using ImpromptuInterface; using JsonDiffPatchDotNet; @@ -45,6 +46,14 @@ public void GivenModelOfType(string typeName, Table table) this.context.Object = table.CreateInstance(modelType); } + [Scope(Scenario = "Serializing DateTimeOffset value should produce typed literal")] + [Given(@"model has dateOff property equal to '(.*)'")] + public void GivenModelHasDateOff(string dateTimeOffset) + { + var allPrimitives = (AllPrimitives)this.context.Object; + allPrimitives.dateOff = DateTimeOffset.ParseExact(dateTimeOffset, "O", CultureInfo.InvariantCulture); + } + [Given(@"model has interest '(.*)'")] public void GivenModelInterestsRDF(string value) { diff --git a/src/JsonLD.Entities.Tests/Entities/AllPrimitives.cs b/src/JsonLD.Entities.Tests/Entities/AllPrimitives.cs index d132865..153ecef 100644 --- a/src/JsonLD.Entities.Tests/Entities/AllPrimitives.cs +++ b/src/JsonLD.Entities.Tests/Entities/AllPrimitives.cs @@ -14,6 +14,8 @@ public class AllPrimitives public DateTime? date { get; set; } + public DateTimeOffset? dateOff { get; set; } + public decimal? @decimal { get; set; } public long? @long { get; set; } diff --git a/src/JsonLD.Entities.Tests/Serializing.feature b/src/JsonLD.Entities.Tests/Serializing.feature index 6f0e158..6e3509a 100644 --- a/src/JsonLD.Entities.Tests/Serializing.feature +++ b/src/JsonLD.Entities.Tests/Serializing.feature @@ -101,16 +101,30 @@ Scenario Outline: Serializing primitive values should produce typed literals } """ Examples: - | Property | Value | JsonValue | XsdType | - | date | 2016-01-03 | 2016-01-03T00:00:00 | dateTime | - | decimal | 3.4 | 3.4 | decimal | - | long | 100 | 100 | long | - | ulong | 100 | 100 | unsignedLong | - | int | 1567 | 1567 | int | - | uint | 15 | 15 | unsignedInt | - | short | 17 | 17 | short | - | ushort | 3 | 3 | unsignedShort | - | byte | 20 | 20 | unsignedByte | - | sbyte | -3 | -3 | byte | - | float | 2.3456 | 2.3456 | float | - | timeSpan | 50.08:20:17 | P50DT8H20M17S | duration | \ No newline at end of file + | Property | Value | JsonValue | XsdType | + | date | 2016-01-03 10:40 AM | 2016-01-03T10:40:00 | dateTime | + | decimal | 3.4 | 3.4 | decimal | + | long | 100 | 100 | long | + | ulong | 100 | 100 | unsignedLong | + | int | 1567 | 1567 | int | + | uint | 15 | 15 | unsignedInt | + | short | 17 | 17 | short | + | ushort | 3 | 3 | unsignedShort | + | byte | 20 | 20 | unsignedByte | + | sbyte | -3 | -3 | byte | + | float | 2.3456 | 2.3456 | float | + | timeSpan | 50.08:20:17 | P50DT8H20M17S | duration | + +Scenario: Serializing DateTimeOffset value should produce typed literal + Given model of type 'JsonLD.Entities.Tests.Entities.AllPrimitives' + And model has dateOff property equal to '2009-06-15T13:45:30.0000000-07:00' + When the object is serialized + Then the resulting JSON-LD should be: + """ + { + "dateOff": { + "@value": "2009-06-15T13:45:30-07:00", + "@type": "http://www.w3.org/2001/XMLSchema#dateTime" + } + } + """ diff --git a/src/JsonLD.Entities.Tests/Serializing.feature.cs b/src/JsonLD.Entities.Tests/Serializing.feature.cs index 247f8a7..106f1cd 100644 --- a/src/JsonLD.Entities.Tests/Serializing.feature.cs +++ b/src/JsonLD.Entities.Tests/Serializing.feature.cs @@ -202,7 +202,7 @@ public virtual void SerializingPrimitiveValuesShouldProduceShortLiteralsForBoole [NUnit.Framework.TestAttribute()] [NUnit.Framework.DescriptionAttribute("Serializing primitive values should produce typed literals")] - [NUnit.Framework.TestCaseAttribute("date", "2016-01-03", "2016-01-03T00:00:00", "dateTime", new string[0])] + [NUnit.Framework.TestCaseAttribute("date", "2016-01-03 10:40 AM", "2016-01-03T10:40:00", "dateTime", new string[0])] [NUnit.Framework.TestCaseAttribute("decimal", "3.4", "3.4", "decimal", new string[0])] [NUnit.Framework.TestCaseAttribute("long", "100", "100", "long", new string[0])] [NUnit.Framework.TestCaseAttribute("ulong", "100", "100", "unsignedLong", new string[0])] @@ -234,6 +234,27 @@ public virtual void SerializingPrimitiveValuesShouldProduceTypedLiterals(string #line 94 testRunner.Then("the resulting JSON-LD should be:", string.Format("{{\r\n\"{0}\": {{\r\n\"@value\": \"{1}\",\r\n\"@type\": \"http://www.w3.org/2001/XMLSchema#{2}\"\r" + "\n}}\r\n}}", property, jsonValue, xsdType), ((TechTalk.SpecFlow.Table)(null)), "Then "); +#line hidden + this.ScenarioCleanup(); + } + + [NUnit.Framework.TestAttribute()] + [NUnit.Framework.DescriptionAttribute("Serializing DateTimeOffset value should produce typed literal")] + public virtual void SerializingDateTimeOffsetValueShouldProduceTypedLiteral() + { + TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Serializing DateTimeOffset value should produce typed literal", ((string[])(null))); +#line 118 +this.ScenarioSetup(scenarioInfo); +#line 119 + testRunner.Given("model of type \'JsonLD.Entities.Tests.Entities.AllPrimitives\'", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Given "); +#line 120 + testRunner.And("model has dateOff property equal to \'2009-06-15T13:45:30.0000000-07:00\'", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); +#line 121 + testRunner.When("the object is serialized", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); +#line hidden +#line 122 + testRunner.Then("the resulting JSON-LD should be:", "{\r\n\"dateOff\": {\r\n\"@value\": \"2009-06-15T13:45:30-07:00\",\r\n\"@type\": \"http://www.w3." + + "org/2001/XMLSchema#dateTime\"\r\n}\r\n}", ((TechTalk.SpecFlow.Table)(null)), "Then "); #line hidden this.ScenarioCleanup(); } diff --git a/src/JsonLD.Entities/TypeExtension.cs b/src/JsonLD.Entities/TypeExtension.cs index c773b9a..ec8770e 100644 --- a/src/JsonLD.Entities/TypeExtension.cs +++ b/src/JsonLD.Entities/TypeExtension.cs @@ -26,6 +26,7 @@ static TypeExtension() [typeof(sbyte)] = Xsd.@byte, [typeof(byte)] = Xsd.unsignedByte, [typeof(DateTime)] = Xsd.dateTime, + [typeof(DateTimeOffset)] = Xsd.dateTime, [typeof(TimeSpan)] = Xsd.duration, [typeof(float)] = Xsd.@float, [typeof(decimal)] = Xsd.@decimal, From be729f28764b2a0ddf6a9938b82265468eed23ef Mon Sep 17 00:00:00 2001 From: tpluscode Date: Sat, 14 Jan 2017 09:50:18 +0100 Subject: [PATCH 6/9] weird typo --- src/Documentation/Serializing/WorkingWithURIs/Readme.cs | 2 +- src/Documentation/Serializing/WorkingWithURIs/Readme.mkd | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Documentation/Serializing/WorkingWithURIs/Readme.cs b/src/Documentation/Serializing/WorkingWithURIs/Readme.cs index cda8bfa..332fa56 100644 --- a/src/Documentation/Serializing/WorkingWithURIs/Readme.cs +++ b/src/Documentation/Serializing/WorkingWithURIs/Readme.cs @@ -52,7 +52,7 @@ would be interpreted as simple string and [upon removing the context](http://tin } ``` -Let's see hot handle this in JsonLd.Entities: +Let's see how to handle this in JsonLd.Entities: **/ using System; diff --git a/src/Documentation/Serializing/WorkingWithURIs/Readme.mkd b/src/Documentation/Serializing/WorkingWithURIs/Readme.mkd index 66d5651..d47fe7b 100644 --- a/src/Documentation/Serializing/WorkingWithURIs/Readme.mkd +++ b/src/Documentation/Serializing/WorkingWithURIs/Readme.mkd @@ -51,7 +51,7 @@ would be interpreted as simple string and [upon removing the context](http://tin } ``` -Let's see hot handle this in JsonLd.Entities: +Let's see how to handle this in JsonLd.Entities: ``` c# using System; From bc82fda73fecddfb83389518ad56bc7a996ea86b Mon Sep 17 00:00:00 2001 From: tpluscode Date: Sat, 14 Jan 2017 11:41:43 +0100 Subject: [PATCH 7/9] add readme for serializing custom literals --- paket.dependencies | 1 + paket.lock | 4 + .../Deserializing/LiteralValues/Readme.cs | 16 ++- .../Deserializing/LiteralValues/Readme.mkd | 16 ++- src/Documentation/Documentation.csproj | 34 +++++ .../Helpers/BuildingContext/Readme.cs | 2 +- .../Helpers/BuildingContext/Readme.mkd | 2 +- .../Serializing/LiteralValues/Readme.cs | 128 ++++++++++++++++++ .../Serializing/LiteralValues/Readme.mkd | 124 +++++++++++++++++ src/Documentation/paket.references | 4 +- .../BuiltInTypesLiteralConverter.cs | 50 +++++++ .../Converters/JsonLdLiteralConverter.cs | 53 +++++--- src/JsonLD.Entities/JsonLD.Entities.csproj | 1 + src/JsonLD.Entities/JsonLdContractResolver.cs | 2 +- 14 files changed, 405 insertions(+), 32 deletions(-) create mode 100644 src/Documentation/Serializing/LiteralValues/Readme.cs create mode 100644 src/Documentation/Serializing/LiteralValues/Readme.mkd create mode 100644 src/JsonLD.Entities/Converters/BuiltInTypesLiteralConverter.cs diff --git a/paket.dependencies b/paket.dependencies index bf85741..5df60dd 100644 --- a/paket.dependencies +++ b/paket.dependencies @@ -22,5 +22,6 @@ nuget Rdf.Vocabularies nuget OpenCover nuget Newtonsoft.Json ~> 9 nuget JsonDiffPatch.Net +nuget NodaTime.Serialization.JsonNet gist tpluscode/a285267d2543466fc35c3a168c846f9f \ No newline at end of file diff --git a/paket.lock b/paket.lock index ea98f8c..6a51a8d 100644 --- a/paket.lock +++ b/paket.lock @@ -24,6 +24,10 @@ NUGET MethodTimer.Fody (1.16) Fody (>= 1.29.2) Newtonsoft.Json (9.0.1) + NodaTime (1.3.2) + NodaTime.Serialization.JsonNet (1.3.2) + Newtonsoft.Json (>= 4.5.11) + NodaTime (>= 1.3) NullGuard.Fody (1.4.6) Fody (>= 1.29.2) NUnit (2.6.4) diff --git a/src/Documentation/Deserializing/LiteralValues/Readme.cs b/src/Documentation/Deserializing/LiteralValues/Readme.cs index 12f73c1..137ff02 100644 --- a/src/Documentation/Deserializing/LiteralValues/Readme.cs +++ b/src/Documentation/Deserializing/LiteralValues/Readme.cs @@ -1,7 +1,7 @@ /** # Documentation -## Working with literal values +## Deserializing literal values As always, here are the required namespace imports. **/ @@ -114,12 +114,17 @@ derived from the deafult `JsonConverter` it would fail to deserialize such liter public class IPAddressConverter : JsonLdLiteralConverter { - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + protected override bool ShouldSerializeAsCompactLiteral(object value) + { + return true; + } + + protected override void WriteJsonLdValue(JsonWriter writer, object value, JsonSerializer serializer) { writer.WriteValue(value.ToString()); } - protected override object DeserializeLiteral(JsonReader reader, Type objectType, JsonSerializer serializer) + protected override object ReadJsonLdLiteral(JsonReader reader, Type objectType, JsonSerializer serializer) { return IPAddress.Parse((string)reader.Value); } @@ -179,8 +184,9 @@ public void Can_deserialize_class_from_expanded_literal() } /** -And lastly it is possible to serialize such an object to literal. Note that compacted value will always be produced, so it's important to -create a fitting `@context` so that the JSON-LD document is valid and correct. +And lastly it is possible to serialize such an object to literal. Note that the converter implementation +always produces compacted value, so it's important to create a fitting `@context` so that the JSON-LD +document is valid and correct. **/ [Test] diff --git a/src/Documentation/Deserializing/LiteralValues/Readme.mkd b/src/Documentation/Deserializing/LiteralValues/Readme.mkd index 44b59e7..939da9f 100644 --- a/src/Documentation/Deserializing/LiteralValues/Readme.mkd +++ b/src/Documentation/Deserializing/LiteralValues/Readme.mkd @@ -1,6 +1,6 @@ # Documentation -## Working with literal values +## Deserializing literal values As always, here are the required namespace imports. @@ -113,12 +113,17 @@ derived from the deafult `JsonConverter` it would fail to deserialize such liter ``` c# public class IPAddressConverter : JsonLdLiteralConverter { - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + protected override bool ShouldSerializeAsCompactLiteral(object value) + { + return true; + } + + protected override void WriteJsonLdValue(JsonWriter writer, object value, JsonSerializer serializer) { writer.WriteValue(value.ToString()); } - protected override object DeserializeLiteral(JsonReader reader, Type objectType, JsonSerializer serializer) + protected override object ReadJsonLdLiteral(JsonReader reader, Type objectType, JsonSerializer serializer) { return IPAddress.Parse((string)reader.Value); } @@ -178,8 +183,9 @@ public void Can_deserialize_class_from_expanded_literal() } ``` -And lastly it is possible to serialize such an object to literal. Note that compacted value will always be produced, so it's important to -create a fitting `@context` so that the JSON-LD document is valid and correct. +And lastly it is possible to serialize such an object to literal. Note that the converter implementation +always produces compacted value, so it's important to create a fitting `@context` so that the JSON-LD +document is valid and correct. ``` c# [Test] diff --git a/src/Documentation/Documentation.csproj b/src/Documentation/Documentation.csproj index 8df75df..9db2023 100644 --- a/src/Documentation/Documentation.csproj +++ b/src/Documentation/Documentation.csproj @@ -51,6 +51,7 @@ Code + @@ -107,6 +108,28 @@ + + + + + ..\..\packages\NodaTime\lib\net35-Client\NodaTime.dll + True + True + + + + + + + + + ..\..\packages\NodaTime.Serialization.JsonNet\lib\net35-Client\NodaTime.Serialization.JsonNet.dll + True + True + + + + @@ -118,5 +141,16 @@ + + + + + ..\..\packages\Rdf.Vocabularies\lib\portable-net4+sl5+netcore45+wpa81+wp8+MonoAndroid1+MonoTouch1\Rdf.Vocabularies.dll + True + True + + + + \ No newline at end of file diff --git a/src/Documentation/Helpers/BuildingContext/Readme.cs b/src/Documentation/Helpers/BuildingContext/Readme.cs index 3fba680..375799f 100644 --- a/src/Documentation/Helpers/BuildingContext/Readme.cs +++ b/src/Documentation/Helpers/BuildingContext/Readme.cs @@ -64,7 +64,7 @@ public void BuildComplexContextSimply() // when var context = new JObject( Base.Is("http://example.com/"), - Vocab.Is(new Uri("http://schema.org/")), + JsonLD.Entities.Context.Vocab.Is(new Uri("http://schema.org/")), "dcterms".IsPrefixOf("http://purl.org/dc/terms/"), "xsd".IsPrefixOf(new Uri("http://www.w3.org/2001/XMLSchema#")), "title".IsProperty("dcterms:title"), diff --git a/src/Documentation/Helpers/BuildingContext/Readme.mkd b/src/Documentation/Helpers/BuildingContext/Readme.mkd index 85486a3..a4c166a 100644 --- a/src/Documentation/Helpers/BuildingContext/Readme.mkd +++ b/src/Documentation/Helpers/BuildingContext/Readme.mkd @@ -64,7 +64,7 @@ public void BuildComplexContextSimply() // when var context = new JObject( Base.Is("http://example.com/"), - Vocab.Is(new Uri("http://schema.org/")), + JsonLD.Entities.Context.Vocab.Is(new Uri("http://schema.org/")), "dcterms".IsPrefixOf("http://purl.org/dc/terms/"), "xsd".IsPrefixOf(new Uri("http://www.w3.org/2001/XMLSchema#")), "title".IsProperty("dcterms:title"), diff --git a/src/Documentation/Serializing/LiteralValues/Readme.cs b/src/Documentation/Serializing/LiteralValues/Readme.cs new file mode 100644 index 0000000..dda8d81 --- /dev/null +++ b/src/Documentation/Serializing/LiteralValues/Readme.cs @@ -0,0 +1,128 @@ +using JsonLD.Entities.Converters; +using Newtonsoft.Json; +using NodaTime.Serialization.JsonNet; +using NUnit.Framework; + +/** +# Documentation + +Related topic: [deserializing literals][deserialize-literals] + +## Serializing literal values + +In JSON-LD a literal value (ie. not a URI) are represented as JS objects, which +contains the value as string and that value's type URI. For example a date +would be represented as: + +``` json +{ + "@context": "http://example.com/vocab/", + "arrivalDate": { + "@value": "2017-01-14T14:50Z", + "@type": "http://www.w3.org/2001/XMLSchema#dateTime" + } +} +``` + +### Serializing framework types + +JsonLd.Entities serializer will choose an appropriate [XSD data type][xsd] for +matching .NET Framework primitive types and will output a JSON-LD object like the one +shown above. + +**/ + +public class TrainSchedule +{ + public System.DateTime ArrivalDate => new System.DateTime(2017, 1, 14, 14, 50, 0); +} + +public class SerializingFrameworkTypes +{ + [Test] + public void Serializes_builtin_types_as_expanded_literal() + { + // given + var serializer = new JsonLD.Entities.EntitySerializer(); + + // when + dynamic schedule = serializer.Serialize(new TrainSchedule()); + + // then + Assert.That((string)schedule.arrivalDate["@value"], Is.EqualTo("2017-01-14T14:50:00")); + Assert.That((string)schedule.arrivalDate["@type"], Is.EqualTo("http://www.w3.org/2001/XMLSchema#dateTime")); + } +} + +/** + +The above works for all .NET numeric types, `DateTime`, `DateTimeOffset` and `TimeSpan`. + +The exceptions are `double` and `string` which all have their implicit typing in JSON and +so they are serialized accoring to their default JavaScript rules while retaining the +correct RDF typing (`xsd:double`, `xsd:boolean` and `xsd:string` accordingly). See the +[JSON-LD spec](https://www.w3.org/TR/json-ld/#conversion-of-native-data-types). + +Note that integers are excempt from this rule, because as a generic term for all integral +numbers, such datatype does not exist in .NET. + +### Serializing other types as literal + +It may be required to serialize instances of other classes as JSON-LD literals. +Sticking to dates, one may prefer to use the `Instant` type from Jon Skeet's [NodaTime library][noda]. + +To serialize any arbitrary type as an expanded literal one has to derive from +`JsonLdLiteralConverter` and set it as the coverter for [property][prop-conv] or [class][class-conv]. + +The converter class has one abstract and a number of virtual methods, which control +the serialization output. In this example we use NodaTime's converter to write the `Instant` to +JSON and set the `@type` to `xsd:dateTime`. Do have a look at this [deserialization page][deserialize-literals] +for more examples. + +**/ + +public class JsonLdNodaInstantConverter : JsonLdLiteralConverter +{ + protected override void WriteJsonLdValue(JsonWriter writer, object value, JsonSerializer serializer) + { + NodaConverters.InstantConverter.WriteJson(writer, value, serializer); + } + + protected override string GetJsonLdType(object value) + { + return Vocab.Xsd.dateTime; + } +} + +public class NodaTimeTrainSchedule +{ + [JsonConverter(typeof(JsonLdNodaInstantConverter))] + public NodaTime.Instant ArrivalDate => NodaTime.Instant.FromUtc(2017, 1, 14, 14, 50); +} + +public class SerializingCustomTypesAsLiterals +{ + [Test] + public void Serializes_NodaTime_as_expanded_literal() + { + // given + var serializer = new JsonLD.Entities.EntitySerializer(); + + // when + dynamic schedule = serializer.Serialize(new NodaTimeTrainSchedule()); + + // then + Assert.That((string)schedule.arrivalDate["@value"], Is.EqualTo("2017-01-14T14:50:00Z")); + Assert.That((string)schedule.arrivalDate["@type"], Is.EqualTo("http://www.w3.org/2001/XMLSchema#dateTime")); + } +} + +/** + +[deserialize-literals]: /wikibus/JsonLD.Entities/tree/master/src/Documentation/Deserializing/LiteralValues +[xsd]: https://www.w3.org/TR/xmlschema-2/#built-in-datatypes +[noda]: https://www.nuget.org/packages/NodaTime +[class-conv]: http://www.newtonsoft.com/json/help/html/JsonConverterAttributeClass.htm +[prop-conv]: http://www.newtonsoft.com/json/help/html/JsonConverterAttributeProperty.htm + +**/ diff --git a/src/Documentation/Serializing/LiteralValues/Readme.mkd b/src/Documentation/Serializing/LiteralValues/Readme.mkd new file mode 100644 index 0000000..00a12b9 --- /dev/null +++ b/src/Documentation/Serializing/LiteralValues/Readme.mkd @@ -0,0 +1,124 @@ +``` c# +using JsonLD.Entities.Converters; +using Newtonsoft.Json; +using NodaTime.Serialization.JsonNet; +using NUnit.Framework; +``` + +# Documentation + +Related topic: [deserializing literals][deserialize-literals] + +## Serializing literal values + +In JSON-LD a literal value (ie. not a URI) are represented as JS objects, which +contains the value as string and that value's type URI. For example a date +would be represented as: + +``` json +{ + "@context": "http://example.com/vocab/", + "arrivalDate": { + "@value": "2017-01-14T14:50Z", + "@type": "http://www.w3.org/2001/XMLSchema#dateTime" + } +} +``` + +### Serializing framework types + +JsonLd.Entities serializer will choose an appropriate [XSD data type][xsd] for +matching .NET Framework primitive types and will output a JSON-LD object like the one +shown above. + +``` c# +public class TrainSchedule +{ + public System.DateTime ArrivalDate => new System.DateTime(2017, 1, 14, 14, 50, 0); +} + +public class SerializingFrameworkTypes +{ + [Test] + public void Serializes_builtin_types_as_expanded_literal() + { + // given + var serializer = new JsonLD.Entities.EntitySerializer(); + + // when + dynamic schedule = serializer.Serialize(new TrainSchedule()); + + // then + Assert.That((string)schedule.arrivalDate["@value"], Is.EqualTo("2017-01-14T14:50:00")); + Assert.That((string)schedule.arrivalDate["@type"], Is.EqualTo("http://www.w3.org/2001/XMLSchema#dateTime")); + } +} +``` + +The above works for all .NET numeric types, `DateTime`, `DateTimeOffset` and `TimeSpan`. + +The exceptions are `double` and `string` which all have their implicit typing in JSON and +so they are serialized accoring to their default JavaScript rules while retaining the +correct RDF typing (`xsd:double`, `xsd:boolean` and `xsd:string` accordingly). See the +[JSON-LD spec](https://www.w3.org/TR/json-ld/#conversion-of-native-data-types). + +Note that integers are excempt from this rule, because as a generic term for all integral +numbers, such datatype does not exist in .NET. + +### Serializing other types as literal + +It may be required to serialize instances of other classes as JSON-LD literals. +Sticking to dates, one may prefer to use the `Instant` type from Jon Skeet's [NodaTime library][noda]. + +To serialize any arbitrary type as an expanded literal one has to derive from +`JsonLdLiteralConverter` and set it as the coverter for [property][prop-conv] or [class][class-conv]. + +The converter class has one abstract and a number of virtual methods, which control +the serialization output. In this example we use NodaTime's converter to write the `Instant` to +JSON and set the `@type` to `xsd:dateTime`. Do have a look at this [deserialization page][deserialize-literals] +for more examples. + +``` c# +public class JsonLdNodaInstantConverter : JsonLdLiteralConverter +{ + protected override void WriteJsonLdValue(JsonWriter writer, object value, JsonSerializer serializer) + { + NodaConverters.InstantConverter.WriteJson(writer, value, serializer); + } + + protected override string GetJsonLdType(object value) + { + return Vocab.Xsd.dateTime; + } +} + +public class NodaTimeTrainSchedule +{ + [JsonConverter(typeof(JsonLdNodaInstantConverter))] + public NodaTime.Instant ArrivalDate => NodaTime.Instant.FromUtc(2017, 1, 14, 14, 50); +} + +public class SerializingCustomTypesAsLiterals +{ + [Test] + public void Serializes_NodaTime_as_expanded_literal() + { + // given + var serializer = new JsonLD.Entities.EntitySerializer(); + + // when + dynamic schedule = serializer.Serialize(new NodaTimeTrainSchedule()); + + // then + Assert.That((string)schedule.arrivalDate["@value"], Is.EqualTo("2017-01-14T14:50:00Z")); + Assert.That((string)schedule.arrivalDate["@type"], Is.EqualTo("http://www.w3.org/2001/XMLSchema#dateTime")); + } +} +``` + + +[deserialize-literals]: /wikibus/JsonLD.Entities/tree/master/src/Documentation/Deserializing/LiteralValues +[xsd]: https://www.w3.org/TR/xmlschema-2/#built-in-datatypes +[noda]: https://www.nuget.org/packages/NodaTime +[class-conv]: http://www.newtonsoft.com/json/help/html/JsonConverterAttributeClass.htm +[prop-conv]: http://www.newtonsoft.com/json/help/html/JsonConverterAttributeProperty.htm diff --git a/src/Documentation/paket.references b/src/Documentation/paket.references index 7089c7f..aeff78a 100644 --- a/src/Documentation/paket.references +++ b/src/Documentation/paket.references @@ -1,4 +1,6 @@ Newtonsoft.Json NUnit json-ld.net -GitVersionTask \ No newline at end of file +GitVersionTask +NodaTime.Serialization.JsonNet +Rdf.Vocabularies \ No newline at end of file diff --git a/src/JsonLD.Entities/Converters/BuiltInTypesLiteralConverter.cs b/src/JsonLD.Entities/Converters/BuiltInTypesLiteralConverter.cs new file mode 100644 index 0000000..d9e4be5 --- /dev/null +++ b/src/JsonLD.Entities/Converters/BuiltInTypesLiteralConverter.cs @@ -0,0 +1,50 @@ +using System; +using System.Xml; +using Newtonsoft.Json; +using NullGuard; + +namespace JsonLD.Entities.Converters +{ + /// + /// Converts .NET framework data types as expanded literals typed with XSD data types accordingly + /// + public class BuiltInTypesLiteralConverter : JsonLdLiteralConverter + { + /// + /// Implicitly typed JS values are serialized as compact literals. + /// + protected override bool ShouldSerializeAsCompactLiteral(object value) + { + return value?.GetType().HasImplicitlyTypedJsonType() == true; + } + + /// + /// Writes the RDF string representation of XSD types to JSON. + /// + protected override void WriteJsonLdValue(JsonWriter writer, object value, JsonSerializer serializer) + { + if (value?.GetType().HasImplicitlyTypedJsonType() == true) + { + writer.WriteValue(value); + } + else if (value is TimeSpan) + { + writer.WriteValue(XmlConvert.ToString((TimeSpan)value)); + } + else + { + var valueString = JsonConvert.ToString(value); + writer.WriteValue(valueString.Trim('"')); // for the weirdest of reasons, DateTime is double-quoted + } + } + + /// + /// Gets the XSD data type URI matching the value. + /// + protected override string GetJsonLdType([AllowNull] object value) + { + var type = value?.GetType(); + return type.GetXsdType(); + } + } +} \ No newline at end of file diff --git a/src/JsonLD.Entities/Converters/JsonLdLiteralConverter.cs b/src/JsonLD.Entities/Converters/JsonLdLiteralConverter.cs index a343b48..7ee3184 100644 --- a/src/JsonLD.Entities/Converters/JsonLdLiteralConverter.cs +++ b/src/JsonLD.Entities/Converters/JsonLdLiteralConverter.cs @@ -1,5 +1,4 @@ using System; -using System.Xml; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using NullGuard; @@ -9,7 +8,7 @@ namespace JsonLD.Entities.Converters /// /// pending doc /// - public class JsonLdLiteralConverter : JsonConverter + public abstract class JsonLdLiteralConverter : JsonConverter { private static readonly JsonLdSerializer LiteralSerializer; @@ -29,28 +28,19 @@ static JsonLdLiteralConverter() /// public override void WriteJson(JsonWriter writer, [AllowNull] object value, JsonSerializer serializer) { - var type = value?.GetType(); - if (type?.HasImplicitlyTypedJsonType() == true) + if (this.ShouldSerializeAsCompactLiteral(value)) { - writer.WriteValue(value); + this.WriteJsonLdValue(writer, value, serializer); return; } writer.WriteStartObject(); writer.WritePropertyName(JsonLdKeywords.Value); - if (value is TimeSpan) - { - writer.WriteValue(XmlConvert.ToString((TimeSpan)value)); - } - else - { - var valueString = JsonConvert.ToString(value); - writer.WriteValue(valueString.Trim('"')); // for the weirdest of reasons, DateTime is double-quoted - } + this.WriteJsonLdValue(writer, value, serializer); writer.WritePropertyName(JsonLdKeywords.Type); - writer.WriteValue(type.GetXsdType()); + writer.WriteValue(this.GetJsonLdType(value)); } /// @@ -64,7 +54,7 @@ public sealed override object ReadJson( { if (reader.TokenType != JsonToken.StartObject) { - return this.DeserializeLiteral(reader, objectType, serializer); + return this.ReadJsonLdLiteral(reader, objectType, serializer); } object value = null; @@ -75,7 +65,7 @@ public sealed override object ReadJson( if (reader.TokenType == JsonToken.PropertyName && Equals(reader.Value, JsonLdKeywords.Value)) { reader.Read(); - value = this.DeserializeLiteral(reader, objectType, serializer); + value = this.ReadJsonLdLiteral(reader, objectType, serializer); } else { @@ -94,12 +84,39 @@ public override bool CanConvert(Type objectType) return true; } + /// + /// When overriden in derived classes, it returns a value to determine + /// whether a compacted or expanded JSON-LD should be produced + /// + protected virtual bool ShouldSerializeAsCompactLiteral(object value) + { + return false; + } + + /// + /// When implemented in derived class, returns an RDF data type name for the value + /// + protected virtual string GetJsonLdType(object value) + { + throw new NotImplementedException("To serialize as expanded literals it is necessary to override the JsonLdLiteralConverter#GetJsonLdType method"); + } + /// /// When implemented in derived classes can be used to customize deserialization logic for literal value /// - protected virtual object DeserializeLiteral(JsonReader reader, Type objectType, JsonSerializer serializer) + protected virtual object ReadJsonLdLiteral(JsonReader reader, Type objectType, JsonSerializer serializer) { return LiteralSerializer.Deserialize(reader, objectType); } + + /// + /// When implemented in derived class writes the RDF string representation + /// of + /// + /// + /// should only use the + /// method for writing the RDF value + /// + protected abstract void WriteJsonLdValue(JsonWriter writer, object value, JsonSerializer serializer); } } diff --git a/src/JsonLD.Entities/JsonLD.Entities.csproj b/src/JsonLD.Entities/JsonLD.Entities.csproj index 9368006..4c3b926 100644 --- a/src/JsonLD.Entities/JsonLD.Entities.csproj +++ b/src/JsonLD.Entities/JsonLD.Entities.csproj @@ -59,6 +59,7 @@ + diff --git a/src/JsonLD.Entities/JsonLdContractResolver.cs b/src/JsonLD.Entities/JsonLdContractResolver.cs index 77ca019..065c591 100644 --- a/src/JsonLD.Entities/JsonLdContractResolver.cs +++ b/src/JsonLD.Entities/JsonLdContractResolver.cs @@ -65,7 +65,7 @@ public override JsonContract ResolveContract(Type type) } else if (contract is JsonPrimitiveContract && contract.Converter == null) { - contract.Converter = new JsonLdLiteralConverter(); + contract.Converter = new BuiltInTypesLiteralConverter(); } return contract; From 72eb1822f62a5d495f039f6a227056847ffeac88 Mon Sep 17 00:00:00 2001 From: tpluscode Date: Sat, 14 Jan 2017 12:05:32 +0100 Subject: [PATCH 8/9] fix codefactor issues --- .../Serializing/LiteralValues/Readme.cs | 40 +++++++++---------- .../Serializing/LiteralValues/Readme.mkd | 38 +++++++++--------- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/src/Documentation/Serializing/LiteralValues/Readme.cs b/src/Documentation/Serializing/LiteralValues/Readme.cs index dda8d81..33198b5 100644 --- a/src/Documentation/Serializing/LiteralValues/Readme.cs +++ b/src/Documentation/Serializing/LiteralValues/Readme.cs @@ -32,13 +32,13 @@ shown above. **/ -public class TrainSchedule -{ - public System.DateTime ArrivalDate => new System.DateTime(2017, 1, 14, 14, 50, 0); -} - public class SerializingFrameworkTypes { + private class TrainSchedule + { + public System.DateTime ArrivalDate => new System.DateTime(2017, 1, 14, 14, 50, 0); + } + [Test] public void Serializes_builtin_types_as_expanded_literal() { @@ -81,27 +81,27 @@ the serialization output. In this example we use NodaTime's converter to write t **/ -public class JsonLdNodaInstantConverter : JsonLdLiteralConverter +public class SerializingCustomTypesAsLiterals { - protected override void WriteJsonLdValue(JsonWriter writer, object value, JsonSerializer serializer) + public class JsonLdNodaInstantConverter : JsonLdLiteralConverter { - NodaConverters.InstantConverter.WriteJson(writer, value, serializer); + protected override void WriteJsonLdValue(JsonWriter writer, object value, JsonSerializer serializer) + { + NodaConverters.InstantConverter.WriteJson(writer, value, serializer); + } + + protected override string GetJsonLdType(object value) + { + return Vocab.Xsd.dateTime; + } } - protected override string GetJsonLdType(object value) + public class NodaTimeTrainSchedule { - return Vocab.Xsd.dateTime; + [JsonConverter(typeof(JsonLdNodaInstantConverter))] + public NodaTime.Instant ArrivalDate => NodaTime.Instant.FromUtc(2017, 1, 14, 14, 50); } -} - -public class NodaTimeTrainSchedule -{ - [JsonConverter(typeof(JsonLdNodaInstantConverter))] - public NodaTime.Instant ArrivalDate => NodaTime.Instant.FromUtc(2017, 1, 14, 14, 50); -} -public class SerializingCustomTypesAsLiterals -{ [Test] public void Serializes_NodaTime_as_expanded_literal() { @@ -125,4 +125,4 @@ public void Serializes_NodaTime_as_expanded_literal() [class-conv]: http://www.newtonsoft.com/json/help/html/JsonConverterAttributeClass.htm [prop-conv]: http://www.newtonsoft.com/json/help/html/JsonConverterAttributeProperty.htm -**/ +**/ \ No newline at end of file diff --git a/src/Documentation/Serializing/LiteralValues/Readme.mkd b/src/Documentation/Serializing/LiteralValues/Readme.mkd index 00a12b9..bd7b9bd 100644 --- a/src/Documentation/Serializing/LiteralValues/Readme.mkd +++ b/src/Documentation/Serializing/LiteralValues/Readme.mkd @@ -32,13 +32,13 @@ matching .NET Framework primitive types and will output a JSON-LD object like th shown above. ``` c# -public class TrainSchedule -{ - public System.DateTime ArrivalDate => new System.DateTime(2017, 1, 14, 14, 50, 0); -} - public class SerializingFrameworkTypes { + private class TrainSchedule + { + public System.DateTime ArrivalDate => new System.DateTime(2017, 1, 14, 14, 50, 0); + } + [Test] public void Serializes_builtin_types_as_expanded_literal() { @@ -79,27 +79,27 @@ JSON and set the `@type` to `xsd:dateTime`. Do have a look at this [deserializat for more examples. ``` c# -public class JsonLdNodaInstantConverter : JsonLdLiteralConverter +public class SerializingCustomTypesAsLiterals { - protected override void WriteJsonLdValue(JsonWriter writer, object value, JsonSerializer serializer) + public class JsonLdNodaInstantConverter : JsonLdLiteralConverter { - NodaConverters.InstantConverter.WriteJson(writer, value, serializer); + protected override void WriteJsonLdValue(JsonWriter writer, object value, JsonSerializer serializer) + { + NodaConverters.InstantConverter.WriteJson(writer, value, serializer); + } + + protected override string GetJsonLdType(object value) + { + return Vocab.Xsd.dateTime; + } } - protected override string GetJsonLdType(object value) + public class NodaTimeTrainSchedule { - return Vocab.Xsd.dateTime; + [JsonConverter(typeof(JsonLdNodaInstantConverter))] + public NodaTime.Instant ArrivalDate => NodaTime.Instant.FromUtc(2017, 1, 14, 14, 50); } -} - -public class NodaTimeTrainSchedule -{ - [JsonConverter(typeof(JsonLdNodaInstantConverter))] - public NodaTime.Instant ArrivalDate => NodaTime.Instant.FromUtc(2017, 1, 14, 14, 50); -} -public class SerializingCustomTypesAsLiterals -{ [Test] public void Serializes_NodaTime_as_expanded_literal() { From e30dcbf243ba7fb38e61696a6c0b993ceb58314e Mon Sep 17 00:00:00 2001 From: tpluscode Date: Sat, 14 Jan 2017 12:14:06 +0100 Subject: [PATCH 9/9] apply analyzer to Release build --- src/Documentation/Documentation.csproj | 3 +++ src/JsonLD.Entities.Tests/JsonLD.Entities.Tests.csproj | 2 ++ src/JsonLD.Entities/JsonLD.Entities.csproj | 2 ++ 3 files changed, 7 insertions(+) diff --git a/src/Documentation/Documentation.csproj b/src/Documentation/Documentation.csproj index 9db2023..9e92f73 100644 --- a/src/Documentation/Documentation.csproj +++ b/src/Documentation/Documentation.csproj @@ -23,6 +23,7 @@ prompt 4 true + ..\..\paket-files\tpluscode\a285267d2543466fc35c3a168c846f9f\UnitTests.ruleset pdbonly @@ -31,6 +32,8 @@ TRACE prompt 4 + true + ..\..\paket-files\tpluscode\a285267d2543466fc35c3a168c846f9f\UnitTests.ruleset diff --git a/src/JsonLD.Entities.Tests/JsonLD.Entities.Tests.csproj b/src/JsonLD.Entities.Tests/JsonLD.Entities.Tests.csproj index 0be3a92..235d746 100644 --- a/src/JsonLD.Entities.Tests/JsonLD.Entities.Tests.csproj +++ b/src/JsonLD.Entities.Tests/JsonLD.Entities.Tests.csproj @@ -37,6 +37,8 @@ prompt 4 false + true + ..\..\paket-files\tpluscode\a285267d2543466fc35c3a168c846f9f\UnitTests.ruleset diff --git a/src/JsonLD.Entities/JsonLD.Entities.csproj b/src/JsonLD.Entities/JsonLD.Entities.csproj index 4c3b926..8ce7c3e 100644 --- a/src/JsonLD.Entities/JsonLD.Entities.csproj +++ b/src/JsonLD.Entities/JsonLD.Entities.csproj @@ -35,6 +35,8 @@ prompt 4 bin\Release\JsonLD.Entities.XML + true + ..\..\paket-files\tpluscode\a285267d2543466fc35c3a168c846f9f\Library.ruleset