Browse Source

Create a sample for System.Text.Json interop (#1663)

Marko Lahma 1 year ago
parent
commit
e125c62de0
2 changed files with 84 additions and 0 deletions
  1. 1 0
      Jint.Tests/Jint.Tests.csproj
  2. 83 0
      Jint.Tests/Runtime/InteropTests.SystemTextJson.cs

+ 1 - 0
Jint.Tests/Jint.Tests.csproj

@@ -30,6 +30,7 @@
     <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.2" />
     <PackageReference Include="MongoDB.Bson.signed" Version="2.19.0" />
     <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
+    <PackageReference Include="System.Text.Json" Version="6.0.8" />
     <PackageReference Include="xunit" Version="2.5.0" />
     <PackageReference Include="xunit.runner.visualstudio" Version="2.5.0">
       <PrivateAssets>all</PrivateAssets>

+ 83 - 0
Jint.Tests/Runtime/InteropTests.SystemTextJson.cs

@@ -0,0 +1,83 @@
+using System.Reflection;
+using System.Text.Json.Nodes;
+using Jint.Runtime.Interop;
+
+namespace Jint.Tests.Runtime;
+
+public partial class InteropTests
+{
+    [Fact]
+    public void AccessingJsonNodeShouldWork()
+    {
+        const string Json = """
+        {
+            "employees": {
+                "type": "array",
+                "value": [
+                    {
+                        "firstName": "John",
+                        "lastName": "Doe"
+                    },
+                    {
+                        "firstName": "Jane",
+                        "lastName": "Doe"
+                    }
+                ]
+            }
+        }
+        """;
+
+        var variables = JsonNode.Parse(Json);
+
+        var engine = new Engine(options =>
+        {
+            // JsonArray behave like JS array
+            options.Interop.WrapObjectHandler = static (e, target, type) =>
+            {
+                var wrapped = new ObjectWrapper(e, target);
+                if (target is JsonArray)
+                {
+                    wrapped.SetPrototypeOf(e.Realm.Intrinsics.Array.PrototypeObject);
+                }
+                return wrapped;
+            };
+
+            // we cannot access this[string] with anything else than JsonObject, otherwise itw will throw
+            options.Interop.TypeResolver = new TypeResolver
+            {
+                MemberFilter = static info =>
+                {
+                    if (info.DeclaringType != typeof(JsonObject) && info.Name == "Item" && info is PropertyInfo p)
+                    {
+                        var parameters = p.GetIndexParameters();
+                        return parameters.Length != 1 || parameters[0].ParameterType != typeof(string);
+                    }
+
+                    return true;
+                }
+            };
+        });
+
+        engine
+            .SetValue("variables", variables)
+            .Execute("""
+                 function populateFullName() {
+                     return variables['employees'].value.map(item => {
+                         var newItem =
+                         {
+                             "firstName": item.firstName,
+                             "lastName": item.lastName,
+                             "fullName": item.firstName + ' ' + item.lastName
+                         };
+
+                         return newItem;
+                     });
+                 }
+             """);
+
+        var result = engine.Evaluate("populateFullName()").AsArray();
+        Assert.Equal((uint) 2, result.Length);
+        Assert.Equal("John Doe", result[0].AsObject()["fullName"]);
+        Assert.Equal("Jane Doe", result[1].AsObject()["fullName"]);
+    }
+}