|
@@ -2,9 +2,59 @@ using System.Reflection;
|
|
using System.Text.Json.Nodes;
|
|
using System.Text.Json.Nodes;
|
|
using Jint.Native;
|
|
using Jint.Native;
|
|
using Jint.Runtime.Interop;
|
|
using Jint.Runtime.Interop;
|
|
-
|
|
|
|
|
|
+using System.Text.Json;
|
|
namespace Jint.Tests.PublicInterface;
|
|
namespace Jint.Tests.PublicInterface;
|
|
|
|
|
|
|
|
+#if NET8_0_OR_GREATER
|
|
|
|
+public class TestJsonValueConverter : IObjectConverter
|
|
|
|
+{
|
|
|
|
+ public bool TryConvert(Engine engine, object value, out JsValue result)
|
|
|
|
+ {
|
|
|
|
+ if (value is JsonValue jsonValue)
|
|
|
|
+ {
|
|
|
|
+ var valueKind = jsonValue.GetValueKind();
|
|
|
|
+ switch (valueKind)
|
|
|
|
+ {
|
|
|
|
+ case JsonValueKind.Object:
|
|
|
|
+ case JsonValueKind.Array:
|
|
|
|
+ result = JsValue.FromObject(engine, jsonValue);
|
|
|
|
+ break;
|
|
|
|
+ case JsonValueKind.String:
|
|
|
|
+ result = jsonValue.ToString();
|
|
|
|
+ break;
|
|
|
|
+ case JsonValueKind.Number:
|
|
|
|
+ if (jsonValue.TryGetValue<double>(out var doubleValue))
|
|
|
|
+ {
|
|
|
|
+ result = JsNumber.Create(doubleValue);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ result = JsValue.Undefined;
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ case JsonValueKind.True:
|
|
|
|
+ result = JsBoolean.True;
|
|
|
|
+ break;
|
|
|
|
+ case JsonValueKind.False:
|
|
|
|
+ result = JsBoolean.False;
|
|
|
|
+ break;
|
|
|
|
+ case JsonValueKind.Undefined:
|
|
|
|
+ result = JsValue.Undefined;
|
|
|
|
+ break;
|
|
|
|
+ case JsonValueKind.Null:
|
|
|
|
+ result = JsValue.Null;
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ result = JsValue.Undefined;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ result = JsValue.Undefined;
|
|
|
|
+ return false;
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+}
|
|
public partial class InteropTests
|
|
public partial class InteropTests
|
|
{
|
|
{
|
|
[Fact]
|
|
[Fact]
|
|
@@ -12,9 +62,14 @@ public partial class InteropTests
|
|
{
|
|
{
|
|
const string Json = """
|
|
const string Json = """
|
|
{
|
|
{
|
|
|
|
+ "falseValue": false,
|
|
"employees": {
|
|
"employees": {
|
|
- "boolean": true,
|
|
|
|
|
|
+ "trueValue": true,
|
|
|
|
+ "falseValue": false,
|
|
"number": 123.456,
|
|
"number": 123.456,
|
|
|
|
+ "zeroNumber": 0,
|
|
|
|
+ "emptyString":"",
|
|
|
|
+ "nullValue":null,
|
|
"other": "abc",
|
|
"other": "abc",
|
|
"type": "array",
|
|
"type": "array",
|
|
"value": [
|
|
"value": [
|
|
@@ -45,24 +100,10 @@ public partial class InteropTests
|
|
return wrapped;
|
|
return wrapped;
|
|
}
|
|
}
|
|
|
|
|
|
- if (target is JsonValue jsonValue)
|
|
|
|
- {
|
|
|
|
- if (jsonValue.TryGetValue<bool>(out var boolValue))
|
|
|
|
- {
|
|
|
|
- return e.Construct("Boolean", boolValue ? JsBoolean.True : JsBoolean.False);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (jsonValue.TryGetValue<double>(out var doubleValue))
|
|
|
|
- {
|
|
|
|
- return e.Construct("Number", JsNumber.Create(doubleValue));
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return e.Construct("String", (JsString)jsonValue.ToString());
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
return new ObjectWrapper(e, target);
|
|
return new ObjectWrapper(e, target);
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+ options.AddObjectConverter(new TestJsonValueConverter());
|
|
// we cannot access this[string] with anything else than JsonObject, otherwise itw will throw
|
|
// we cannot access this[string] with anything else than JsonObject, otherwise itw will throw
|
|
options.Interop.TypeResolver = new TypeResolver
|
|
options.Interop.TypeResolver = new TypeResolver
|
|
{
|
|
{
|
|
@@ -80,6 +121,7 @@ public partial class InteropTests
|
|
});
|
|
});
|
|
|
|
|
|
engine
|
|
engine
|
|
|
|
+ .SetValue("falseValue", false)
|
|
.SetValue("variables", variables)
|
|
.SetValue("variables", variables)
|
|
.Execute("""
|
|
.Execute("""
|
|
function populateFullName() {
|
|
function populateFullName() {
|
|
@@ -101,7 +143,7 @@ public partial class InteropTests
|
|
Assert.Equal((uint) 2, result.Length);
|
|
Assert.Equal((uint) 2, result.Length);
|
|
Assert.Equal("John Doe", result[0].AsObject()["fullName"]);
|
|
Assert.Equal("John Doe", result[0].AsObject()["fullName"]);
|
|
Assert.Equal("Jane Doe", result[1].AsObject()["fullName"]);
|
|
Assert.Equal("Jane Doe", result[1].AsObject()["fullName"]);
|
|
- Assert.True(engine.Evaluate("variables.employees.boolean == true").AsBoolean());
|
|
|
|
|
|
+ Assert.True(engine.Evaluate("variables.employees.trueValue == true").AsBoolean());
|
|
Assert.True(engine.Evaluate("variables.employees.number == 123.456").AsBoolean());
|
|
Assert.True(engine.Evaluate("variables.employees.number == 123.456").AsBoolean());
|
|
Assert.True(engine.Evaluate("variables.employees.other == 'abc'").AsBoolean());
|
|
Assert.True(engine.Evaluate("variables.employees.other == 'abc'").AsBoolean());
|
|
|
|
|
|
@@ -115,8 +157,27 @@ public partial class InteropTests
|
|
Assert.Equal((uint) 2, result.Length);
|
|
Assert.Equal((uint) 2, result.Length);
|
|
Assert.Equal("Jake Doe", result[0].AsObject()["fullName"]);
|
|
Assert.Equal("Jake Doe", result[0].AsObject()["fullName"]);
|
|
|
|
|
|
|
|
+ // Validate boolean value in the if condition.
|
|
|
|
+ Assert.Equal(1, engine.Evaluate("if(!falseValue){ return 1 ;} else {return 0;}").AsNumber());
|
|
|
|
+ Assert.Equal(1, engine.Evaluate("if(falseValue===false){ return 1 ;} else {return 0;}").AsNumber());
|
|
|
|
+ Assert.True(engine.Evaluate("!variables.zeroNumber").AsBoolean());
|
|
|
|
+ Assert.True(engine.Evaluate("!variables.emptyString").AsBoolean());
|
|
|
|
+ Assert.True(engine.Evaluate("!variables.nullValue").AsBoolean());
|
|
|
|
+ var result2 = engine.Evaluate("!variables.falseValue");
|
|
|
|
+ var result3 = engine.Evaluate("!falseValue");
|
|
|
|
+ var result4 = engine.Evaluate("variables.falseValue");
|
|
|
|
+ var result5 = engine.Evaluate("falseValue");
|
|
|
|
+ Assert.NotNull(result2);
|
|
|
|
+
|
|
|
|
+ Assert.Equal(1, engine.Evaluate("if(variables.falseValue===false){ return 1 ;} else {return 0;}").AsNumber());
|
|
|
|
+ Assert.Equal(1, engine.Evaluate("if(falseValue===variables.falseValue){ return 1 ;} else {return 0;}").AsNumber());
|
|
|
|
+ Assert.Equal(1, engine.Evaluate("if(!variables.falseValue){ return 1 ;} else {return 0;}").AsNumber());
|
|
|
|
+ Assert.Equal(1, engine.Evaluate("if(!variables.employees.falseValue){ return 1 ;} else {return 0;}").AsNumber());
|
|
|
|
+ Assert.Equal(0, engine.Evaluate("if(!variables.employees.trueValue) return 1 ; else return 0;").AsNumber());
|
|
|
|
+
|
|
|
|
+
|
|
// mutating original object that is wrapped inside the engine
|
|
// mutating original object that is wrapped inside the engine
|
|
- variables["employees"]["boolean"] = false;
|
|
|
|
|
|
+ variables["employees"]["trueValue"] = false;
|
|
variables["employees"]["number"] = 456.789;
|
|
variables["employees"]["number"] = 456.789;
|
|
variables["employees"]["other"] = "def";
|
|
variables["employees"]["other"] = "def";
|
|
variables["employees"]["type"] = "array";
|
|
variables["employees"]["type"] = "array";
|
|
@@ -127,8 +188,9 @@ public partial class InteropTests
|
|
result = engine.Evaluate("populateFullName()").AsArray();
|
|
result = engine.Evaluate("populateFullName()").AsArray();
|
|
Assert.Equal((uint) 2, result.Length);
|
|
Assert.Equal((uint) 2, result.Length);
|
|
Assert.Equal("John Doe", result[0].AsObject()["fullName"]);
|
|
Assert.Equal("John Doe", result[0].AsObject()["fullName"]);
|
|
- Assert.True(engine.Evaluate("variables.employees.boolean == false").AsBoolean());
|
|
|
|
|
|
+ Assert.True(engine.Evaluate("variables.employees.trueValue == false").AsBoolean());
|
|
Assert.True(engine.Evaluate("variables.employees.number == 456.789").AsBoolean());
|
|
Assert.True(engine.Evaluate("variables.employees.number == 456.789").AsBoolean());
|
|
Assert.True(engine.Evaluate("variables.employees.other == 'def'").AsBoolean());
|
|
Assert.True(engine.Evaluate("variables.employees.other == 'def'").AsBoolean());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+#endif
|