Skip to content

Commit

Permalink
Fix ExpandoObject serialization (#996)
Browse files Browse the repository at this point in the history
Fixes #995
  • Loading branch information
sebastienros committed Nov 3, 2021
1 parent c117c5e commit c110428
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 5 deletions.
25 changes: 25 additions & 0 deletions Jint.Tests/Runtime/InteropTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,31 @@ public void EngineShouldStringifyAnExpandoObjectCorrectly()
Assert.Equal("{\"foo\":5,\"bar\":\"A string\"}", result);
}

[Fact]
public void EngineShouldStringifyAnExpandoObjectWithValuesCorrectly()
{
// https://github.com/sebastienros/jint/issues/995
var engine = new Engine();

dynamic expando = new ExpandoObject();
expando.Values = 1;
engine.SetValue("expando", expando);

Assert.Equal("{\"Values\":1}", engine.Evaluate($"JSON.stringify(expando)").AsString());
}

[Fact]
public void EngineShouldStringifyADictionary()
{
var engine = new Engine();

var d = new Hashtable();
d["Values"] = 1;
engine.SetValue("d", d);

Assert.Equal("{\"Values\":1}", engine.Evaluate($"JSON.stringify(d)").AsString());
}

[Fact]
public void EngineShouldStringifyADictionaryOfStringAndObjectCorrectly()
{
Expand Down
8 changes: 4 additions & 4 deletions Jint/Native/Json/JsonSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -270,13 +270,13 @@ private string SerializeArray(JsValue value)
if (_gap == "")
{
var separator = ",";
var properties = System.String.Join(separator, partial.ToArray());
var properties = string.Join(separator, partial.ToArray());
final = "[" + properties + "]";
}
else
{
var separator = ",\n" + _indent;
var properties = System.String.Join(separator, partial.ToArray());
var properties = string.Join(separator, partial.ToArray());
final = "[\n" + _indent + properties + "\n" + stepback + "]";
}

Expand Down Expand Up @@ -322,13 +322,13 @@ private string SerializeObject(ObjectInstance value)
if (_gap == "")
{
var separator = ",";
var properties = System.String.Join(separator, partial.ToArray());
var properties = string.Join(separator, partial.ToArray());
final = "{" + properties + "}";
}
else
{
var separator = ",\n" + _indent;
var properties = System.String.Join(separator, partial.ToArray());
var properties = string.Join(separator, partial.ToArray());
final = "{\n" + _indent + properties + "\n" + stepback + "}";
}
}
Expand Down
10 changes: 10 additions & 0 deletions Jint/Runtime/Interop/ObjectWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,16 @@ public override JsValue Get(JsValue property, JsValue receiver)
if (property is JsString stringKey)
{
var member = stringKey.ToString();

// expando object for instance
if (Target is IDictionary<string, object> stringKeyedDictionary)
{
if (stringKeyedDictionary.TryGetValue(member, out var value))
{
return FromObject(_engine, value);
}
}

var result = Engine.Options.Interop.MemberAccessor?.Invoke(Engine, Target, member);
if (result is not null)
{
Expand Down
2 changes: 1 addition & 1 deletion Jint/Runtime/Interop/TypeDescriptor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public static TypeDescriptor Get(Type type)

private static bool DetermineIfObjectIsArrayLikeClrCollection(Type type)
{
if (typeof(IDictionary).IsAssignableFrom(type))
if (typeof(IDictionary).IsAssignableFrom(type) || typeof(IDictionary<string, object>).IsAssignableFrom(type))
{
// dictionaries are considered normal-object-like
return false;
Expand Down

0 comments on commit c110428

Please sign in to comment.