InteropTests.Dynamic.cs 4.9 KB

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