EngineTests.cs 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. using System;
  2. using System.IO;
  3. using System.Reflection;
  4. using Xunit;
  5. using Xunit.Extensions;
  6. namespace Jint.Tests.Runtime
  7. {
  8. public class EngineTests
  9. {
  10. private Engine RunTest(string source)
  11. {
  12. var engine = new Engine(cfg => cfg
  13. .WithDelegate("log", new Action<object>(Console.WriteLine))
  14. .WithDelegate("assert", new Action<bool>(Assert.True))
  15. );
  16. engine.Execute(source);
  17. return engine;
  18. }
  19. [Theory]
  20. [InlineData("Scratch.js")]
  21. public void ShouldInterpretScriptFile(string file)
  22. {
  23. const string prefix = "Jint.Tests.Runtime.Scripts.";
  24. var assembly = Assembly.GetExecutingAssembly();
  25. var scriptPath = prefix + file;
  26. using (var stream = assembly.GetManifestResourceStream(scriptPath))
  27. if (stream != null)
  28. using (var sr = new StreamReader(stream))
  29. {
  30. var source = sr.ReadToEnd();
  31. RunTest(source);
  32. }
  33. }
  34. [Theory]
  35. [InlineData(42d, "42")]
  36. [InlineData("Hello", "'Hello'")]
  37. public void ShouldInterpretLiterals(object expected, string source)
  38. {
  39. var engine = new Engine();
  40. var result = engine.GetValue(engine.Execute(source));
  41. Assert.Equal(expected, result);
  42. }
  43. [Fact]
  44. public void ShouldInterpretVariableDeclaration()
  45. {
  46. var engine = new Engine();
  47. var result = engine.GetValue(engine.Execute("var foo = 'bar'; foo;"));
  48. Assert.Equal("bar", result);
  49. }
  50. [Theory]
  51. [InlineData(4d, "1 + 3")]
  52. [InlineData(-2d, "1 - 3")]
  53. [InlineData(3d, "1 * 3")]
  54. [InlineData(2d, "6 / 3")]
  55. [InlineData(9, "15 & 9")]
  56. [InlineData(15, "15 | 9")]
  57. [InlineData(6, "15 ^ 9")]
  58. [InlineData(36, "9 << 2")]
  59. [InlineData(2, "9 >> 2")]
  60. [InlineData((uint)4, "19 >>> 2")]
  61. public void ShouldInterpretBinaryExpression(object expected, string source)
  62. {
  63. var engine = new Engine();
  64. var result = engine.GetValue(engine.Execute(source));
  65. Assert.Equal(expected, result);
  66. }
  67. [Fact]
  68. public void ShouldEvaluateHasOwnProperty()
  69. {
  70. RunTest(@"
  71. var x = {};
  72. x.Bar = 42;
  73. assert(x.hasOwnProperty('Bar'));
  74. ");
  75. }
  76. [Fact]
  77. public void FunctionConstructorsShouldCreateNewObjects()
  78. {
  79. RunTest(@"
  80. var Vehicle = function () {};
  81. var vehicle = new Vehicle();
  82. assert(vehicle != undefined);
  83. ");
  84. }
  85. [Fact]
  86. public void NewObjectsInheritFunctionConstructorProperties()
  87. {
  88. RunTest(@"
  89. var Vehicle = function () {};
  90. var vehicle = new Vehicle();
  91. Vehicle.prototype.wheelCount = 4;
  92. assert(vehicle.wheelCount == 4);
  93. assert((new Vehicle()).wheelCount == 4);
  94. ");
  95. }
  96. [Fact]
  97. public void NewObjectsShouldUsePrivateProperties()
  98. {
  99. RunTest(@"
  100. var Vehicle = function (color) {
  101. this.color = color;
  102. };
  103. var vehicle = new Vehicle('tan');
  104. assert(vehicle.color == 'tan');
  105. ");
  106. }
  107. [Fact]
  108. public void FunctionConstructorsShouldDefinePrototypeChain()
  109. {
  110. RunTest(@"
  111. function Vehicle() {};
  112. var vehicle = new Vehicle();
  113. assert(vehicle.hasOwnProperty('constructor') == false);
  114. ");
  115. }
  116. [Fact]
  117. public void NewObjectsConstructorIsObject()
  118. {
  119. RunTest(@"
  120. var o = new Object();
  121. assert(o instanceof Object);
  122. assert(o.constructor == Object);
  123. ");
  124. }
  125. [Fact]
  126. public void NewObjectsConstructorShouldBeConstructorObject()
  127. {
  128. RunTest(@"
  129. var Vehicle = function () {};
  130. var vehicle = new Vehicle();
  131. assert(vehicle.constructor == Vehicle);
  132. ");
  133. }
  134. [Fact]
  135. public void NewObjectsIntanceOfConstructorObject()
  136. {
  137. RunTest(@"
  138. var Vehicle = function () {};
  139. var vehicle = new Vehicle();
  140. assert(vehicle instanceof Vehicle);
  141. ");
  142. }
  143. [Fact]
  144. public void ShouldEvaluateForLoops()
  145. {
  146. RunTest(@"
  147. var foo = 0;
  148. for (var i = 0; i < 5; i++) {
  149. foo += i;
  150. }
  151. assert(foo == 10);
  152. ");
  153. }
  154. [Fact]
  155. public void ShouldEvaluateRecursiveFunctions()
  156. {
  157. RunTest(@"
  158. function fib(n) {
  159. if (n < 2) {
  160. return n;
  161. }
  162. return fib(n - 1) + fib(n - 2);
  163. }
  164. var result = fib(6);
  165. assert(result == 8);
  166. ");
  167. }
  168. [Fact]
  169. public void ShouldAccessObjectProperties()
  170. {
  171. RunTest(@"
  172. var o = {};
  173. o.Foo = 'bar';
  174. o.Baz = 42;
  175. o.Blah = o.Foo + o.Baz;
  176. assert(o.Blah == 'bar42');
  177. ");
  178. }
  179. [Fact]
  180. public void ShouldConstructArray()
  181. {
  182. RunTest(@"
  183. var o = [];
  184. assert(o.length == 0);
  185. ");
  186. }
  187. [Fact]
  188. public void ArrayPushShouldIncrementLength()
  189. {
  190. RunTest(@"
  191. var o = [];
  192. o.push(1);
  193. assert(o.length == 1);
  194. ");
  195. }
  196. [Fact]
  197. public void ArrayPopShouldDecrementLength()
  198. {
  199. RunTest(@"
  200. var o = [42, 'foo'];
  201. var pop = o.pop();
  202. assert(o.length == 1);
  203. assert(pop == 'foo');
  204. ");
  205. }
  206. [Fact]
  207. public void ArrayConstructor()
  208. {
  209. RunTest(@"
  210. var o = [];
  211. assert(o.constructor == Array);
  212. assert(o.hasOwnProperty('constructor') == false);
  213. ");
  214. }
  215. [Fact]
  216. public void DateConstructor()
  217. {
  218. RunTest(@"
  219. var o = new Date();
  220. assert(o.constructor == Date);
  221. assert(o.hasOwnProperty('constructor') == false);
  222. ");
  223. }
  224. [Fact]
  225. public void MathObjectIsDefined()
  226. {
  227. RunTest(@"
  228. var o = Math.abs(-1)
  229. assert(o == 1);
  230. ");
  231. }
  232. [Fact]
  233. public void VoidShouldReturnUndefined()
  234. {
  235. RunTest(@"
  236. assert(void 0 === undefined);
  237. var x = '1';
  238. assert(void x === undefined);
  239. x = 'x';
  240. assert (isNaN(void x) === true);
  241. x = new String('-1');
  242. assert (void x === undefined);
  243. ");
  244. }
  245. [Fact]
  246. public void TypeofObjectShouldReturnString()
  247. {
  248. RunTest(@"
  249. assert(typeof x === 'undefined');
  250. assert(typeof 0 === 'number');
  251. var x = 0;
  252. assert (typeof x === 'number');
  253. var x = new Object();
  254. assert (typeof x === 'object');
  255. ");
  256. }
  257. [Fact]
  258. public void MathAbsReturnsAbsolute()
  259. {
  260. RunTest(@"
  261. assert(1 == Math.abs(-1));
  262. ");
  263. }
  264. [Fact]
  265. public void NaNIsNan()
  266. {
  267. RunTest(@"
  268. var x = NaN;
  269. assert(isNaN(NaN));
  270. assert(isNaN(Math.abs(x)));
  271. ");
  272. }
  273. [Fact]
  274. public void Scratch()
  275. {
  276. RunTest(@"
  277. ");
  278. }
  279. /*
  280. [Fact]
  281. public void ()
  282. {
  283. RunTest(@"
  284. ");
  285. }
  286. */
  287. }
  288. }