InteropTests.Dynamic.cs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. using System.Dynamic;
  2. using Jint.Native;
  3. using Jint.Native.Symbol;
  4. using Jint.Tests.Runtime.Domain;
  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 DebugView()
  20. {
  21. // allows displaying different local variables under debugger
  22. var engine = new Engine();
  23. var boolNet = true;
  24. var boolJint = (JsBoolean) boolNet;
  25. var doubleNet = 12.34;
  26. var doubleJint = (JsNumber) doubleNet;
  27. var integerNet = 42;
  28. var integerJint = (JsNumber) integerNet;
  29. var stringNet = "ABC";
  30. var stringJint = (JsString) stringNet;
  31. var arrayNet = new[] { 1, 2, 3 };
  32. var arrayListNet = new List<int> { 1, 2, 3 };
  33. var arrayJint = new JsArray(engine, arrayNet.Select(x => (JsNumber) x).ToArray());
  34. var objectNet = new Person { Name = "name", Age = 12 };
  35. var objectJint = new JsObject(engine);
  36. objectJint["name"] = "name";
  37. objectJint["age"] = 12;
  38. objectJint[GlobalSymbolRegistry.ToStringTag] = "Object";
  39. var dictionaryNet = new Dictionary<JsValue, JsValue>();
  40. dictionaryNet["name"] = "name";
  41. dictionaryNet["age"] = 12;
  42. dictionaryNet[GlobalSymbolRegistry.ToStringTag] = "Object";
  43. }
  44. [Fact]
  45. public void CanAccessMemberNamedItemThroughExpando()
  46. {
  47. var parent = (IDictionary<string, object>) new ExpandoObject();
  48. var child = (IDictionary<string, object>) new ExpandoObject();
  49. var values = (IDictionary<string, object>) new ExpandoObject();
  50. parent["child"] = child;
  51. child["item"] = values;
  52. values["title"] = "abc";
  53. _engine.SetValue("parent", parent);
  54. Assert.Equal("abc", _engine.Evaluate("parent.child.item.title"));
  55. }
  56. [Fact]
  57. public void ShouldForOfOnExpandoObject()
  58. {
  59. dynamic o = new ExpandoObject();
  60. o.a = 1;
  61. o.b = 2;
  62. _engine.SetValue("dynamic", o);
  63. var result = _engine.Evaluate("var l = ''; for (var x of dynamic) l += x; return l;").AsString();
  64. Assert.Equal("a,1b,2", result);
  65. }
  66. [Fact]
  67. public void ShouldConvertObjectInstanceToExpando()
  68. {
  69. _engine.Evaluate("var o = {a: 1, b: 'foo'}");
  70. var result = _engine.GetValue("o");
  71. dynamic value = result.ToObject();
  72. Assert.Equal(1, value.a);
  73. Assert.Equal("foo", value.b);
  74. var dic = (IDictionary<string, object>) result.ToObject();
  75. Assert.Equal(1d, dic["a"]);
  76. Assert.Equal("foo", dic["b"]);
  77. }
  78. [Fact]
  79. public void CanAccessDynamicObject()
  80. {
  81. var test = new DynamicClass();
  82. var engine = new Engine();
  83. engine.SetValue("test", test);
  84. Assert.Equal("a", engine.Evaluate("test.a").AsString());
  85. Assert.Equal("b", engine.Evaluate("test.b").AsString());
  86. engine.Evaluate("test.a = 5; test.b = 10; test.Name = 'Jint'");
  87. Assert.Equal(5, engine.Evaluate("test.a").AsNumber());
  88. Assert.Equal(10, engine.Evaluate("test.b").AsNumber());
  89. Assert.Equal("Jint", engine.Evaluate("test.Name").AsString());
  90. Assert.True(engine.Evaluate("test.ContainsKey('a')").AsBoolean());
  91. Assert.True(engine.Evaluate("test.ContainsKey('b')").AsBoolean());
  92. Assert.False(engine.Evaluate("test.ContainsKey('c')").AsBoolean());
  93. }
  94. private class DynamicClass : DynamicObject
  95. {
  96. private readonly Dictionary<string, object> _properties = new Dictionary<string, object>();
  97. public override bool TryGetMember(GetMemberBinder binder, out object result)
  98. {
  99. result = binder.Name;
  100. if (_properties.TryGetValue(binder.Name, out var value))
  101. {
  102. result = value;
  103. }
  104. return true;
  105. }
  106. public override bool TrySetMember(SetMemberBinder binder, object value)
  107. {
  108. _properties[binder.Name] = value;
  109. return true;
  110. }
  111. public string Name { get; set; }
  112. public bool ContainsKey(string key)
  113. {
  114. return _properties.ContainsKey(key);
  115. }
  116. }
  117. }
  118. }