2
0

InteropTests.Dynamic.cs 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. using System.Collections.Generic;
  2. using System.Dynamic;
  3. using System.Linq;
  4. using Xunit;
  5. namespace Jint.Tests.Runtime
  6. {
  7. public partial class InteropTests
  8. {
  9. [Fact]
  10. public void CanAccessExpandoObject()
  11. {
  12. var engine = new Engine();
  13. dynamic expando = new ExpandoObject();
  14. expando.Name = "test";
  15. engine.SetValue("expando", expando);
  16. Assert.Equal("test", engine.Evaluate("expando.Name").ToString());
  17. }
  18. [Fact]
  19. public void CanAccessMemberNamedItemThroughExpando()
  20. {
  21. var parent = (IDictionary<string, object>) new ExpandoObject();
  22. var child = (IDictionary<string, object>) new ExpandoObject();
  23. var values = (IDictionary<string, object>) new ExpandoObject();
  24. parent["child"] = child;
  25. child["item"] = values;
  26. values["title"] = "abc";
  27. _engine.SetValue("parent", parent);
  28. Assert.Equal("abc", _engine.Evaluate("parent.child.item.title"));
  29. }
  30. [Fact]
  31. public void EngineShouldStringifyAnExpandoObjectCorrectly()
  32. {
  33. var engine = new Engine();
  34. dynamic expando = new ExpandoObject();
  35. expando.foo = 5;
  36. expando.bar = "A string";
  37. engine.SetValue(nameof(expando), expando);
  38. var result = engine.Evaluate($"JSON.stringify({nameof(expando)})").AsString();
  39. Assert.Equal("{\"foo\":5,\"bar\":\"A string\"}", result);
  40. }
  41. [Fact]
  42. public void EngineShouldStringifyAnExpandoObjectWithValuesCorrectly()
  43. {
  44. // https://github.com/sebastienros/jint/issues/995
  45. var engine = new Engine();
  46. dynamic expando = new ExpandoObject();
  47. expando.Values = 1;
  48. engine.SetValue("expando", expando);
  49. Assert.Equal("{\"Values\":1}", engine.Evaluate($"JSON.stringify(expando)").AsString());
  50. }
  51. [Fact]
  52. public void ShouldForOfOnExpandoObject()
  53. {
  54. dynamic o = new ExpandoObject();
  55. o.a = 1;
  56. o.b = 2;
  57. _engine.SetValue("dynamic", o);
  58. var result = _engine.Evaluate("var l = ''; for (var x of dynamic) l += x; return l;").AsString();
  59. Assert.Equal("a,1b,2", result);
  60. }
  61. [Fact]
  62. public void ShouldConvertObjectInstanceToExpando()
  63. {
  64. _engine.Evaluate("var o = {a: 1, b: 'foo'}");
  65. var result = _engine.GetValue("o");
  66. dynamic value = result.ToObject();
  67. Assert.Equal(1, value.a);
  68. Assert.Equal("foo", value.b);
  69. var dic = (IDictionary<string, object>) result.ToObject();
  70. Assert.Equal(1d, dic["a"]);
  71. Assert.Equal("foo", dic["b"]);
  72. }
  73. [Fact]
  74. public void EngineShouldStringifyAnJObjectArrayWithValuesCorrectly()
  75. {
  76. //https://github.com/OrchardCMS/OrchardCore/issues/10648
  77. var engine = new Engine();
  78. var queryResults = new List<dynamic>();
  79. queryResults.Add(new { Text = "Text1", Value = 1 });
  80. queryResults.Add(new { Text = "Text2", Value = 2 });
  81. engine.SetValue("testSubject", queryResults.ToArray());
  82. var fromEngine2 = engine.Evaluate("return JSON.stringify(testSubject);");
  83. var result2 = fromEngine2.ToString();
  84. Assert.Equal("[{\"Text\":\"Text1\",\"Value\":1},{\"Text\":\"Text2\",\"Value\":2}]", result2);
  85. }
  86. [Fact]
  87. public void EngineShouldStringifyDynamicObjectListWithValuesCorrectly()
  88. {
  89. var engine = new Engine();
  90. var source = new dynamic[] { new { Text = "Text1", Value = 1 }, new { Text = "Text2", Value = 2 } };
  91. var objects = source.ToList();
  92. engine.SetValue("testSubject", objects);
  93. var fromEngine = engine.Evaluate("return JSON.stringify(testSubject);");
  94. var result = fromEngine.ToString();
  95. Assert.Equal("[{\"Text\":\"Text1\",\"Value\":1},{\"Text\":\"Text2\",\"Value\":2}]", result);
  96. }
  97. [Fact]
  98. public void EngineShouldStringifyDynamicObjectArrayWithValuesCorrectly()
  99. {
  100. var engine = new Engine();
  101. var source = new dynamic[] { new { Text = "Text1", Value = 1 }, new { Text = "Text2", Value = 2 } };
  102. engine.SetValue("testSubject", source.AsEnumerable());
  103. var fromEngine = engine.Evaluate("return JSON.stringify(testSubject);");
  104. var result = fromEngine.ToString();
  105. Assert.Equal("[{\"Text\":\"Text1\",\"Value\":1},{\"Text\":\"Text2\",\"Value\":2}]", result);
  106. }
  107. [Fact]
  108. public void CanAccessDynamicObject()
  109. {
  110. var test = new DynamicClass();
  111. var engine = new Engine();
  112. engine.SetValue("test", test);
  113. Assert.Equal("a", engine.Evaluate("test.a").AsString());
  114. Assert.Equal("b", engine.Evaluate("test.b").AsString());
  115. engine.Evaluate("test.a = 5; test.b = 10; test.Name = 'Jint'");
  116. Assert.Equal(5, engine.Evaluate("test.a").AsNumber());
  117. Assert.Equal(10, engine.Evaluate("test.b").AsNumber());
  118. Assert.Equal("Jint", engine.Evaluate("test.Name").AsString());
  119. Assert.True(engine.Evaluate("test.ContainsKey('a')").AsBoolean());
  120. Assert.True(engine.Evaluate("test.ContainsKey('b')").AsBoolean());
  121. Assert.False(engine.Evaluate("test.ContainsKey('c')").AsBoolean());
  122. }
  123. private class DynamicClass : DynamicObject
  124. {
  125. private readonly Dictionary<string, object> _properties = new Dictionary<string, object>();
  126. public override bool TryGetMember(GetMemberBinder binder, out object result)
  127. {
  128. result = binder.Name;
  129. if (_properties.TryGetValue(binder.Name, out var value))
  130. {
  131. result = value;
  132. }
  133. return true;
  134. }
  135. public override bool TrySetMember(SetMemberBinder binder, object value)
  136. {
  137. _properties[binder.Name] = value;
  138. return true;
  139. }
  140. public string Name { get; set; }
  141. public bool ContainsKey(string key)
  142. {
  143. return _properties.ContainsKey(key);
  144. }
  145. }
  146. }
  147. }