ExtensionMethodsTest.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. using Jint.Native;
  2. using Jint.Tests.Runtime.Domain;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using Xunit;
  7. namespace Jint.Tests.Runtime.ExtensionMethods
  8. {
  9. public class ExtensionMethodsTest
  10. {
  11. [Fact]
  12. public void ShouldInvokeObjectExtensionMethod()
  13. {
  14. var person = new Person();
  15. person.Name = "Mickey Mouse";
  16. person.Age = 35;
  17. var options = new Options();
  18. options.AddExtensionMethods(typeof(PersonExtensions));
  19. var engine = new Engine(options);
  20. engine.SetValue("person", person);
  21. var age = engine.Execute("person.MultiplyAge(2)").GetCompletionValue().AsInteger();
  22. Assert.Equal(70, age);
  23. }
  24. [Fact]
  25. public void ShouldInvokeStringExtensionMethod()
  26. {
  27. var options = new Options();
  28. options.AddExtensionMethods(typeof(CustomStringExtensions));
  29. var engine = new Engine(options);
  30. var result = engine.Execute("\"Hello World!\".Backwards()").GetCompletionValue().AsString();
  31. Assert.Equal("!dlroW olleH", result);
  32. }
  33. [Fact]
  34. public void ShouldInvokeNumberExtensionMethod()
  35. {
  36. var options = new Options();
  37. options.AddExtensionMethods(typeof(DoubleExtensions));
  38. var engine = new Engine(options);
  39. var result = engine.Execute("let numb = 27; numb.Add(13)").GetCompletionValue().AsInteger();
  40. Assert.Equal(40, result);
  41. }
  42. [Fact]
  43. public void ShouldPrioritizingNonGenericMethod()
  44. {
  45. var options = new Options();
  46. options.AddExtensionMethods(typeof(CustomStringExtensions));
  47. var engine = new Engine(options);
  48. var result = engine.Execute("\"{'name':'Mickey'}\".DeserializeObject()").GetCompletionValue().ToObject() as dynamic;
  49. Assert.Equal("Mickey", result.name);
  50. }
  51. [Fact]
  52. public void PrototypeFunctionsShouldNotBeOverridden()
  53. {
  54. var engine = new Engine(opts =>
  55. {
  56. opts.AddExtensionMethods(typeof(CustomStringExtensions));
  57. });
  58. //uses split function from StringPrototype
  59. var arr = engine.Execute("'yes,no'.split(',')").GetCompletionValue().AsArray();
  60. Assert.Equal("yes", arr[0]);
  61. Assert.Equal("no", arr[1]);
  62. //uses split function from CustomStringExtensions
  63. var arr2 = engine.Execute("'yes,no'.split(2)").GetCompletionValue().AsArray();
  64. Assert.Equal("ye", arr2[0]);
  65. Assert.Equal("s,no", arr2[1]);
  66. }
  67. [Fact]
  68. public void OverridePrototypeFunctions()
  69. {
  70. var engine = new Engine(opts =>
  71. {
  72. opts.AddExtensionMethods(typeof(OverrideStringPrototypeExtensions));
  73. });
  74. //uses the overridden split function from OverrideStringPrototypeExtensions
  75. var arr = engine.Execute("'yes,no'.split(',')").GetCompletionValue().AsArray();
  76. Assert.Equal("YES", arr[0]);
  77. Assert.Equal("NO", arr[1]);
  78. }
  79. [Fact]
  80. public void HasOwnPropertyShouldWorkCorrectlyInPresenceOfExtensionMethods()
  81. {
  82. var person = new Person();
  83. var options = new Options();
  84. options.AddExtensionMethods(typeof(PersonExtensions));
  85. var engine = new Engine(options);
  86. engine.SetValue("person", person);
  87. var isBogusInPerson = engine.Execute("'bogus' in person").GetCompletionValue().AsBoolean();
  88. Assert.False(isBogusInPerson);
  89. var propertyValue = engine.Execute("person.bogus").GetCompletionValue();
  90. Assert.Equal(JsValue.Undefined, propertyValue);
  91. }
  92. private Engine GetLinqEngine()
  93. {
  94. return new Engine(opts =>
  95. {
  96. opts.AddExtensionMethods(typeof(Enumerable));
  97. });
  98. }
  99. [Fact]
  100. public void LinqExtensionMethodWithoutGenericParameter()
  101. {
  102. var engine = GetLinqEngine();
  103. var intList = new List<int>() { 0, 1, 2, 3 };
  104. engine.SetValue("intList", intList);
  105. var intSumRes = engine.Execute("intList.Sum()").GetCompletionValue().AsNumber();
  106. Assert.Equal(6, intSumRes);
  107. }
  108. [Fact]
  109. public void LinqExtensionMethodWithSingleGenericParameter()
  110. {
  111. var engine = GetLinqEngine();
  112. var stringList = new List<string>() { "working", "linq" };
  113. engine.SetValue("stringList", stringList);
  114. var stringSumRes = engine.Execute("stringList.Sum(x => x.length)").GetCompletionValue().AsNumber();
  115. Assert.Equal(11, stringSumRes);
  116. }
  117. [Fact]
  118. public void LinqExtensionMethodWithMultipleGenericParameters()
  119. {
  120. var engine = GetLinqEngine();
  121. var stringList = new List<string>() { "working", "linq" };
  122. engine.SetValue("stringList", stringList);
  123. var stringRes = engine.Execute("stringList.Select((x) => x + 'a').ToArray().join()").GetCompletionValue().AsString();
  124. Assert.Equal("workinga,linqa", stringRes);
  125. // The method ambiguity resolver is not so smart to choose the Select method with the correct number of parameters
  126. // Thus, the following script will not work as expected.
  127. // stringList.Select((x, i) => x + i).ToArray().join()
  128. }
  129. }
  130. }