Skip to content

Commit

Permalink
Use System.Text.Json instead of Newtonsoft
Browse files Browse the repository at this point in the history
  • Loading branch information
MarkMpn committed Nov 15, 2023
1 parent ccf8cec commit 3f87b05
Show file tree
Hide file tree
Showing 7 changed files with 433 additions and 108 deletions.
75 changes: 75 additions & 0 deletions MarkMpn.Sql4Cds.Engine.Tests/AdoProviderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1607,5 +1607,80 @@ DECLARE @json NVARCHAR(4000) = N'{
}
}
}

[TestMethod]
public void OpenJsonExplicitSchema()
{
using (var con = new Sql4CdsConnection(_localDataSource))
using (var cmd = con.CreateCommand())
{
cmd.CommandText = @"
DECLARE @json NVARCHAR(MAX) = N'[
{
""Order"": {
""Number"":""SO43659"",
""Date"":""2011-05-31T00:00:00""
},
""AccountNumber"":""AW29825"",
""Item"": {
""Price"":2024.9940,
""Quantity"":1
}
},
{
""Order"": {
""Number"":""SO43661"",
""Date"":""2011-06-01T00:00:00""
},
""AccountNumber"":""AW73565"",
""Item"": {
""Price"":2024.9940,
""Quantity"":3
}
}
]'
SELECT *
FROM OPENJSON ( @json )
WITH (
Number VARCHAR(200) '$.Order.Number',
Date DATETIME '$.Order.Date',
Customer VARCHAR(200) '$.AccountNumber',
Quantity INT '$.Item.Quantity',
[Order] NVARCHAR(MAX) AS JSON
)";

using (var reader = cmd.ExecuteReader())
{
Assert.AreEqual("Number", reader.GetName(0));
Assert.AreEqual("Date", reader.GetName(1));
Assert.AreEqual("Customer", reader.GetName(2));
Assert.AreEqual("Quantity", reader.GetName(3));
Assert.AreEqual("Order", reader.GetName(4));

Assert.IsTrue(reader.Read());
Assert.AreEqual("SO43659", reader.GetString(0));
Assert.AreEqual(new DateTime(2011, 5, 31), reader.GetDateTime(1));
Assert.AreEqual("AW29825", reader.GetString(2));
Assert.AreEqual(1, reader.GetInt32(3));
Assert.AreEqual(@"{
""Number"": ""SO43659"",
""Date"": ""2011-05-31T00:00:00""
}", reader.GetString(4));

Assert.IsTrue(reader.Read());
Assert.AreEqual("SO43661", reader.GetString(0));
Assert.AreEqual(new DateTime(2011, 6, 1), reader.GetDateTime(1));
Assert.AreEqual("AW73565", reader.GetString(2));
Assert.AreEqual(3, reader.GetInt32(3));
Assert.AreEqual(@"{
""Number"": ""SO43661"",
""Date"": ""2011-06-01T00:00:00""
}", reader.GetString(4));

Assert.IsFalse(reader.Read());
}
}
}
}
}
226 changes: 226 additions & 0 deletions MarkMpn.Sql4Cds.Engine.Tests/JsonPathTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace MarkMpn.Sql4Cds.Engine.Tests
{
[TestClass]
public class JsonPathTests
{
[TestMethod]
public void DollarOnly()
{
var path = new JsonPath("$");

var json = JsonDocument.Parse(@"
{
""path"": {
""to"": {
""sub-object"": ""hello world""
}
}
}");

var value = path.Evaluate(json.RootElement);
Assert.AreEqual(value, json.RootElement);
}

[TestMethod]
public void QuotedPropertyName()
{
var path = new JsonPath("$.path.to.\"sub-object\"");

var json = JsonDocument.Parse(@"
{
""path"": {
""to"": {
""sub-object"": ""hello world""
}
}
}");

var value = path.Evaluate(json.RootElement);
Assert.AreEqual("hello world", value.Value.GetString());
}

[TestMethod]
public void DuplicatePathsReturnsFirstMatch()
{
var path = new JsonPath("$.person.name");

var json = JsonDocument.Parse(@"
{
""person"": {
""name"": ""Mark"",
""name"": ""Carrington""
}
}");

var value = path.Evaluate(json.RootElement);
Assert.AreEqual("Mark", value.Value.GetString());
}

[TestMethod]
public void DefaultModeLax()
{
var path = new JsonPath("$.path.to.\"sub-object\"");
Assert.AreEqual(JsonPathMode.Lax, path.Mode);
}

[TestMethod]
public void ExplicitModeLax()
{
var path = new JsonPath("lax $.path.to.\"sub-object\"");
Assert.AreEqual(JsonPathMode.Lax, path.Mode);
}

[TestMethod]
public void ExplicitModeStrict()
{
var path = new JsonPath("strict $.path.to.\"sub-object\"");
Assert.AreEqual(JsonPathMode.Lax, path.Mode);
}

[TestMethod]
[ExpectedException(typeof(JsonException))]
public void FailsOnUnknownMode()
{
new JsonPath("laxtrict $.path.to.\"sub-object\"");
}

[TestMethod]
[ExpectedException(typeof(JsonException))]
public void FailsOnExtraQuotes()
{
new JsonPath("laxtrict $.path.to.\"\"sub-object\"\"");
}

[TestMethod]
[ExpectedException(typeof(JsonException))]
public void FailsOnMissingLeadingDollar()
{
new JsonPath("path.to.\"sub-object\"");
}

[TestMethod]
[ExpectedException(typeof(JsonException))]
public void FailsOnDoublePeriod()
{
new JsonPath("$.path..to.\"sub-object\"");
}

[TestMethod]
[ExpectedException(typeof(JsonException))]
public void FailsOnTrailingPeriod()
{
new JsonPath("$.path.to.\"sub-object\".");
}

[TestMethod]
public void ArrayIndexer()
{
var path = new JsonPath("$.path.to.\"sub-object\"[1]");

var json = JsonDocument.Parse(@"
{
""path"": {
""to"": {
""sub-object"": [ ""hello"", ""world"" ]
}
}
}");

var value = path.Evaluate(json.RootElement);
Assert.AreEqual("world", value.Value.GetString());
}

[TestMethod]
[ExpectedException(typeof(JsonException))]
public void FailsOnNegativeIndexer()
{
new JsonPath("$.path.to.\"sub-object\"[-1]");
}

[TestMethod]
[ExpectedException(typeof(JsonException))]
public void FailsOnAlphaIndexer()
{
new JsonPath("$.path.to.\"sub-object\"[x]");
}

[TestMethod]
[ExpectedException(typeof(JsonException))]
public void FailsOnMissingCloseBracket()
{
new JsonPath("$.path.to.\"sub-object\"[1");
}

[TestMethod]
[ExpectedException(typeof(JsonException))]
public void FailsOnMissingOpeningBracket()
{
new JsonPath("$.path.to1]");
}

[TestMethod]
public void NestedArrayIndexer()
{
var path = new JsonPath("$.path.to.\"sub-object\"[1][0]");

var json = JsonDocument.Parse(@"
{
""path"": {
""to"": {
""sub-object"": [ [ ""hel"", ""lo"" ], [ ""wor"", ""ld"" ] ]
}
}
}");

var value = path.Evaluate(json.RootElement);
Assert.AreEqual("wor", value.Value.GetString());
}

[TestMethod]
[ExpectedException(typeof(JsonException))]
public void FailsOnDollarNotAtStart()
{
new JsonPath("$.path.$.to");
}

[TestMethod]
[ExpectedException(typeof(JsonException))]
public void FailsOnUnquotedDollar()
{
new JsonPath("$.path$");
}

[TestMethod]
[ExpectedException(typeof(JsonException))]
public void FailsOnLeadingNumber()
{
new JsonPath("$.1path");
}

[TestMethod]
public void TrailingNumber()
{
var path = new JsonPath("$.path1.to2.\"sub-object\"");

var json = JsonDocument.Parse(@"
{
""path1"": {
""to2"": {
""sub-object"": ""hello world""
}
}
}");

var value = path.Evaluate(json.RootElement);
Assert.AreEqual("hello world", value.Value.GetString());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
<Compile Include="ExecutionPlanTests.cs" />
<Compile Include="ExpressionTests.cs" />
<Compile Include="FakeXrmEasyTestsBase.cs" />
<Compile Include="JsonPathTests.cs" />
<Compile Include="Metadata\Audit.cs" />
<Compile Include="Metadata\New_CustomEntity.cs" />
<Compile Include="Metadata\Contact.cs" />
Expand Down Expand Up @@ -124,6 +125,12 @@
<PackageReference Include="MSTest.TestFramework">
<Version>3.0.2</Version>
</PackageReference>
<PackageReference Include="System.Runtime.CompilerServices.Unsafe">
<Version>6.0.0</Version>
</PackageReference>
<PackageReference Include="System.Text.Json">
<Version>6.0.7</Version>
</PackageReference>
</ItemGroup>
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
Expand Down
2 changes: 1 addition & 1 deletion MarkMpn.Sql4Cds.Engine.Tests/app.config
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0"/>
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="6.0.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Text.Json" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral"/>
Expand Down
Loading

0 comments on commit 3f87b05

Please sign in to comment.