InteropTests.cs 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.ObjectModel;
  4. using System.Reflection;
  5. using Jint.Native;
  6. using Jint.Native.Object;
  7. using Jint.Tests.Runtime.Converters;
  8. using Jint.Tests.Runtime.Domain;
  9. using Shapes;
  10. using Xunit;
  11. namespace Jint.Tests.Runtime
  12. {
  13. public class InteropTests : IDisposable
  14. {
  15. private readonly Engine _engine;
  16. public InteropTests()
  17. {
  18. _engine = new Engine(cfg => cfg.AllowClr(
  19. typeof(Shape).GetTypeInfo().Assembly,
  20. typeof(System.IO.File).GetTypeInfo().Assembly))
  21. .SetValue("log", new Action<object>(Console.WriteLine))
  22. .SetValue("assert", new Action<bool>(Assert.True))
  23. .SetValue("equal", new Action<object, object>(Assert.Equal))
  24. ;
  25. }
  26. void IDisposable.Dispose()
  27. {
  28. }
  29. private void RunTest(string source)
  30. {
  31. _engine.Execute(source);
  32. }
  33. [Fact]
  34. public void PrimitiveTypesCanBeSet()
  35. {
  36. _engine.SetValue("x", 10);
  37. _engine.SetValue("y", true);
  38. _engine.SetValue("z", "foo");
  39. RunTest(@"
  40. assert(x === 10);
  41. assert(y === true);
  42. assert(z === 'foo');
  43. ");
  44. }
  45. [Fact]
  46. public void DelegatesCanBeSet()
  47. {
  48. _engine.SetValue("square", new Func<double, double>(x => x * x));
  49. RunTest(@"
  50. assert(square(10) === 100);
  51. ");
  52. }
  53. [Fact]
  54. public void DelegateWithNullableParameterCanBePassedANull()
  55. {
  56. _engine.SetValue("isnull", new Func<double?, bool>(x => x == null));
  57. RunTest(@"
  58. assert(isnull(null) === true);
  59. ");
  60. }
  61. [Fact]
  62. public void DelegateWithObjectParameterCanBePassedANull()
  63. {
  64. _engine.SetValue("isnull", new Func<object, bool>(x => x == null));
  65. RunTest(@"
  66. assert(isnull(null) === true);
  67. ");
  68. }
  69. [Fact]
  70. public void DelegateWithNullableParameterCanBePassedAnUndefined()
  71. {
  72. _engine.SetValue("isnull", new Func<double?, bool>(x => x == null));
  73. RunTest(@"
  74. assert(isnull(undefined) === true);
  75. ");
  76. }
  77. [Fact]
  78. public void DelegateWithObjectParameterCanBePassedAnUndefined()
  79. {
  80. _engine.SetValue("isnull", new Func<object, bool>(x => x == null));
  81. RunTest(@"
  82. assert(isnull(undefined) === true);
  83. ");
  84. }
  85. [Fact]
  86. public void DelegateWithNullableParameterCanBeExcluded()
  87. {
  88. _engine.SetValue("isnull", new Func<double?, bool>(x => x == null));
  89. RunTest(@"
  90. assert(isnull() === true);
  91. ");
  92. }
  93. [Fact]
  94. public void DelegateWithObjectParameterCanBeExcluded()
  95. {
  96. _engine.SetValue("isnull", new Func<object, bool>(x => x == null));
  97. RunTest(@"
  98. assert(isnull() === true);
  99. ");
  100. }
  101. [Fact]
  102. public void ExtraParametersAreIgnored()
  103. {
  104. _engine.SetValue("passNumber", new Func<int, int>(x => x));
  105. RunTest(@"
  106. assert(passNumber(123,'test',{},[],null) === 123);
  107. ");
  108. }
  109. private delegate string callParams(params object[] values);
  110. private delegate string callArgumentAndParams(string firstParam, params object[] values);
  111. [Fact]
  112. public void DelegatesWithParamsParameterCanBeInvoked()
  113. {
  114. var a = new A();
  115. _engine.SetValue("callParams", new callParams(a.Call13));
  116. _engine.SetValue("callArgumentAndParams", new callArgumentAndParams(a.Call14));
  117. RunTest(@"
  118. assert(callParams('1','2','3') === '1,2,3');
  119. assert(callParams('1') === '1');
  120. assert(callParams() === '');
  121. assert(callArgumentAndParams('a','1','2','3') === 'a:1,2,3');
  122. assert(callArgumentAndParams('a','1') === 'a:1');
  123. assert(callArgumentAndParams('a') === 'a:');
  124. assert(callArgumentAndParams() === ':');
  125. ");
  126. }
  127. [Fact]
  128. public void CanGetObjectProperties()
  129. {
  130. var p = new Person
  131. {
  132. Name = "Mickey Mouse"
  133. };
  134. _engine.SetValue("p", p);
  135. RunTest(@"
  136. assert(p.Name === 'Mickey Mouse');
  137. ");
  138. }
  139. [Fact]
  140. public void CanInvokeObjectMethods()
  141. {
  142. var p = new Person
  143. {
  144. Name = "Mickey Mouse"
  145. };
  146. _engine.SetValue("p", p);
  147. RunTest(@"
  148. assert(p.ToString() === 'Mickey Mouse');
  149. ");
  150. }
  151. [Fact]
  152. public void CanInvokeObjectMethodsWithPascalCase()
  153. {
  154. var p = new Person
  155. {
  156. Name = "Mickey Mouse"
  157. };
  158. _engine.SetValue("p", p);
  159. RunTest(@"
  160. assert(p.toString() === 'Mickey Mouse');
  161. ");
  162. }
  163. [Fact]
  164. public void CanSetObjectProperties()
  165. {
  166. var p = new Person
  167. {
  168. Name = "Mickey Mouse"
  169. };
  170. _engine.SetValue("p", p);
  171. RunTest(@"
  172. p.Name = 'Donald Duck';
  173. assert(p.Name === 'Donald Duck');
  174. ");
  175. Assert.Equal("Donald Duck", p.Name);
  176. }
  177. [Fact]
  178. public void CanGetIndexUsingStringKey()
  179. {
  180. var dictionary = new Dictionary<string, Person>();
  181. dictionary.Add("person1", new Person { Name = "Mickey Mouse" });
  182. dictionary.Add("person2", new Person { Name = "Goofy" });
  183. _engine.SetValue("dictionary", dictionary);
  184. RunTest(@"
  185. assert(dictionary['person1'].Name === 'Mickey Mouse');
  186. assert(dictionary['person2'].Name === 'Goofy');
  187. ");
  188. }
  189. [Fact]
  190. public void CanSetIndexUsingStringKey()
  191. {
  192. var dictionary = new Dictionary<string, Person>();
  193. dictionary.Add("person1", new Person { Name = "Mickey Mouse" });
  194. dictionary.Add("person2", new Person { Name = "Goofy" });
  195. _engine.SetValue("dictionary", dictionary);
  196. RunTest(@"
  197. dictionary['person2'].Name = 'Donald Duck';
  198. assert(dictionary['person2'].Name === 'Donald Duck');
  199. ");
  200. Assert.Equal("Donald Duck", dictionary["person2"].Name);
  201. }
  202. [Fact]
  203. public void CanGetIndexUsingIntegerKey()
  204. {
  205. var dictionary = new Dictionary<int, string>();
  206. dictionary.Add(1, "Mickey Mouse");
  207. dictionary.Add(2, "Goofy");
  208. _engine.SetValue("dictionary", dictionary);
  209. RunTest(@"
  210. assert(dictionary[1] === 'Mickey Mouse');
  211. assert(dictionary[2] === 'Goofy');
  212. ");
  213. }
  214. [Fact]
  215. public void CanSetIndexUsingIntegerKey()
  216. {
  217. var dictionary = new Dictionary<int, string>();
  218. dictionary.Add(1, "Mickey Mouse");
  219. dictionary.Add(2, "Goofy");
  220. _engine.SetValue("dictionary", dictionary);
  221. RunTest(@"
  222. dictionary[2] = 'Donald Duck';
  223. assert(dictionary[2] === 'Donald Duck');
  224. ");
  225. Assert.Equal("Mickey Mouse", dictionary[1]);
  226. Assert.Equal("Donald Duck", dictionary[2]);
  227. }
  228. private class DoubleIndexedClass
  229. {
  230. public int this[int index]
  231. {
  232. get { return index; }
  233. }
  234. public string this[string index]
  235. {
  236. get { return index; }
  237. }
  238. }
  239. [Fact]
  240. public void CanGetIndexUsingBothIntAndStringIndex()
  241. {
  242. var dictionary = new DoubleIndexedClass();
  243. _engine.SetValue("dictionary", dictionary);
  244. RunTest(@"
  245. assert(dictionary[1] === 1);
  246. assert(dictionary['test'] === 'test');
  247. ");
  248. }
  249. [Fact]
  250. public void CanUseGenericMethods()
  251. {
  252. var dictionary = new Dictionary<int, string>();
  253. dictionary.Add(1, "Mickey Mouse");
  254. _engine.SetValue("dictionary", dictionary);
  255. RunTest(@"
  256. dictionary.Add(2, 'Goofy');
  257. assert(dictionary[2] === 'Goofy');
  258. ");
  259. Assert.Equal("Mickey Mouse", dictionary[1]);
  260. Assert.Equal("Goofy", dictionary[2]);
  261. }
  262. [Fact]
  263. public void CanUseMultiGenericTypes()
  264. {
  265. RunTest(@"
  266. var type = System.Collections.Generic.Dictionary(System.Int32, System.String);
  267. var dictionary = new type();
  268. dictionary.Add(1, 'Mickey Mouse');
  269. dictionary.Add(2, 'Goofy');
  270. assert(dictionary[2] === 'Goofy');
  271. ");
  272. }
  273. [Fact]
  274. public void CanUseIndexOnCollection()
  275. {
  276. var collection = new System.Collections.ObjectModel.Collection<string>();
  277. collection.Add("Mickey Mouse");
  278. collection.Add("Goofy");
  279. _engine.SetValue("dictionary", collection);
  280. RunTest(@"
  281. dictionary[1] = 'Donald Duck';
  282. assert(dictionary[1] === 'Donald Duck');
  283. ");
  284. Assert.Equal("Mickey Mouse", collection[0]);
  285. Assert.Equal("Donald Duck", collection[1]);
  286. }
  287. [Fact]
  288. public void CanUseIndexOnList()
  289. {
  290. var list = new List<object>(2);
  291. list.Add("Mickey Mouse");
  292. list.Add("Goofy");
  293. _engine.SetValue("list", list);
  294. RunTest(@"
  295. list[1] = 'Donald Duck';
  296. assert(list[1] === 'Donald Duck');
  297. ");
  298. Assert.Equal("Mickey Mouse", list[0]);
  299. Assert.Equal("Donald Duck", list[1]);
  300. }
  301. [Fact]
  302. public void CanAccessAnonymousObject()
  303. {
  304. var p = new
  305. {
  306. Name = "Mickey Mouse",
  307. };
  308. _engine.SetValue("p", p);
  309. RunTest(@"
  310. assert(p.Name === 'Mickey Mouse');
  311. ");
  312. }
  313. [Fact]
  314. public void CanAccessAnonymousObjectProperties()
  315. {
  316. var p = new
  317. {
  318. Address = new
  319. {
  320. City = "Mouseton"
  321. }
  322. };
  323. _engine.SetValue("p", p);
  324. RunTest(@"
  325. assert(p.Address.City === 'Mouseton');
  326. ");
  327. }
  328. [Fact]
  329. public void PocosCanReturnJsValueDirectly()
  330. {
  331. var o = new
  332. {
  333. x = new JsValue(1),
  334. y = new JsValue("string"),
  335. };
  336. _engine.SetValue("o", o);
  337. RunTest(@"
  338. assert(o.x === 1);
  339. assert(o.y === 'string');
  340. ");
  341. }
  342. [Fact]
  343. public void PocosCanReturnObjectInstanceDirectly()
  344. {
  345. var x = new ObjectInstance(_engine) { Extensible = true};
  346. x.Put("foo", new JsValue("bar"), false);
  347. var o = new
  348. {
  349. x
  350. };
  351. _engine.SetValue("o", o);
  352. RunTest(@"
  353. assert(o.x.foo === 'bar');
  354. ");
  355. }
  356. [Fact]
  357. public void DateTimeIsConvertedToDate()
  358. {
  359. var o = new
  360. {
  361. z = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)
  362. };
  363. _engine.SetValue("o", o);
  364. RunTest(@"
  365. assert(o.z.valueOf() === 0);
  366. ");
  367. }
  368. [Fact]
  369. public void DateTimeOffsetIsConvertedToDate()
  370. {
  371. var o = new
  372. {
  373. z = new DateTimeOffset(1970, 1, 1, 0, 0, 0, new TimeSpan())
  374. };
  375. _engine.SetValue("o", o);
  376. RunTest(@"
  377. assert(o.z.valueOf() === 0);
  378. ");
  379. }
  380. [Fact]
  381. public void EcmaValuesAreAutomaticallyConvertedWhenSetInPoco()
  382. {
  383. var p = new Person
  384. {
  385. Name = "foo",
  386. };
  387. _engine.SetValue("p", p);
  388. RunTest(@"
  389. assert(p.Name === 'foo');
  390. assert(p.Age === 0);
  391. p.Name = 'bar';
  392. p.Age = 10;
  393. ");
  394. Assert.Equal("bar", p.Name);
  395. Assert.Equal(10, p.Age);
  396. }
  397. [Fact]
  398. public void EcmaValuesAreAutomaticallyConvertedToBestMatchWhenSetInPoco()
  399. {
  400. var p = new Person
  401. {
  402. Name = "foo",
  403. };
  404. _engine.SetValue("p", p);
  405. RunTest(@"
  406. p.Name = 10;
  407. p.Age = '20';
  408. ");
  409. Assert.Equal("10", p.Name);
  410. Assert.Equal(20, p.Age);
  411. }
  412. [Fact]
  413. public void ShouldCallInstanceMethodWithoutArgument()
  414. {
  415. _engine.SetValue("a", new A());
  416. RunTest(@"
  417. assert(a.Call1() === 0);
  418. ");
  419. }
  420. [Fact]
  421. public void ShouldCallInstanceMethodOverloadArgument()
  422. {
  423. _engine.SetValue("a", new A());
  424. RunTest(@"
  425. assert(a.Call1(1) === 1);
  426. ");
  427. }
  428. [Fact]
  429. public void ShouldCallInstanceMethodWithString()
  430. {
  431. var p = new Person();
  432. _engine.SetValue("a", new A());
  433. _engine.SetValue("p", p);
  434. RunTest(@"
  435. p.Name = a.Call2('foo');
  436. assert(p.Name === 'foo');
  437. ");
  438. Assert.Equal("foo", p.Name);
  439. }
  440. [Fact]
  441. public void CanUseTrim()
  442. {
  443. var p = new Person { Name = "Mickey Mouse "};
  444. _engine.SetValue("p", p);
  445. RunTest(@"
  446. assert(p.Name === 'Mickey Mouse ');
  447. p.Name = p.Name.trim();
  448. assert(p.Name === 'Mickey Mouse');
  449. ");
  450. Assert.Equal("Mickey Mouse", p.Name);
  451. }
  452. [Fact]
  453. public void CanUseMathFloor()
  454. {
  455. var p = new Person();
  456. _engine.SetValue("p", p);
  457. RunTest(@"
  458. p.Age = Math.floor(1.6);p
  459. assert(p.Age === 1);
  460. ");
  461. Assert.Equal(1, p.Age);
  462. }
  463. [Fact]
  464. public void CanUseDelegateAsFunction()
  465. {
  466. var even = new Func<int, bool>(x => x % 2 == 0);
  467. _engine.SetValue("even", even);
  468. RunTest(@"
  469. assert(even(2) === true);
  470. ");
  471. }
  472. private class TestClass
  473. {
  474. public int? NullableInt { get; set; }
  475. public DateTime? NullableDate { get; set; }
  476. public bool? NullableBool { get; set; }
  477. }
  478. [Fact]
  479. public void CanSetNullablePropertiesOnPocos()
  480. {
  481. var instance = new TestClass();
  482. _engine.SetValue("instance", instance);
  483. RunTest(@"
  484. instance.NullableInt = 2;
  485. instance.NullableDate = new Date();
  486. instance.NullableBool = true;
  487. assert(instance.NullableInt===2);
  488. assert(instance.NullableDate!=null);
  489. assert(instance.NullableBool===true);
  490. ");
  491. }
  492. [Fact]
  493. public void ShouldConvertArrayToArrayInstance()
  494. {
  495. var result = _engine
  496. .SetValue("values", new[] { 1, 2, 3, 4, 5, 6 })
  497. .Execute("values.filter(function(x){ return x % 2 == 0; })");
  498. var parts = result.GetCompletionValue().ToObject();
  499. Assert.True(parts.GetType().IsArray);
  500. Assert.Equal(3, ((object[])parts).Length);
  501. Assert.Equal(2d, ((object[])parts)[0]);
  502. Assert.Equal(4d, ((object[])parts)[1]);
  503. Assert.Equal(6d, ((object[])parts)[2]);
  504. }
  505. [Fact]
  506. public void ShouldConvertListsToArrayInstance()
  507. {
  508. var result = _engine
  509. .SetValue("values", new List<object> { 1, 2, 3, 4, 5, 6 })
  510. .Execute("new Array(values).filter(function(x){ return x % 2 == 0; })");
  511. var parts = result.GetCompletionValue().ToObject();
  512. Assert.True(parts.GetType().IsArray);
  513. Assert.Equal(3, ((object[])parts).Length);
  514. Assert.Equal(2d, ((object[])parts)[0]);
  515. Assert.Equal(4d, ((object[])parts)[1]);
  516. Assert.Equal(6d, ((object[])parts)[2]);
  517. }
  518. [Fact]
  519. public void ShouldConvertArrayInstanceToArray()
  520. {
  521. var result = _engine.Execute("'[email protected]'.split('@');");
  522. var parts = result.GetCompletionValue().ToObject();
  523. Assert.True(parts.GetType().IsArray);
  524. Assert.Equal(2, ((object[])parts).Length);
  525. Assert.Equal("foo", ((object[])parts)[0]);
  526. Assert.Equal("bar.com", ((object[])parts)[1]);
  527. }
  528. [Fact]
  529. public void ShouldConvertBooleanInstanceToBool()
  530. {
  531. var result = _engine.Execute("new Boolean(true)");
  532. var value = result.GetCompletionValue().ToObject();
  533. Assert.Equal(typeof(bool), value.GetType());
  534. Assert.Equal(true, value);
  535. }
  536. [Fact]
  537. public void ShouldConvertDateInstanceToDateTime()
  538. {
  539. var result = _engine.Execute("new Date(0)");
  540. var value = result.GetCompletionValue().ToObject();
  541. Assert.Equal(typeof(DateTime), value.GetType());
  542. Assert.Equal(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc), value);
  543. }
  544. [Fact]
  545. public void ShouldConvertNumberInstanceToDouble()
  546. {
  547. var result = _engine.Execute("new Number(10)");
  548. var value = result.GetCompletionValue().ToObject();
  549. Assert.Equal(typeof(double), value.GetType());
  550. Assert.Equal(10d, value);
  551. }
  552. [Fact]
  553. public void ShouldConvertStringInstanceToString()
  554. {
  555. var result = _engine.Execute("new String('foo')");
  556. var value = result.GetCompletionValue().ToObject();
  557. Assert.Equal(typeof(string), value.GetType());
  558. Assert.Equal("foo", value);
  559. }
  560. [Fact]
  561. public void ShouldConvertObjectInstanceToExpando()
  562. {
  563. _engine.Execute("var o = {a: 1, b: 'foo'}");
  564. var result = _engine.GetValue("o");
  565. dynamic value = result.ToObject();
  566. Assert.Equal(1, value.a);
  567. Assert.Equal("foo", value.b);
  568. var dic = (IDictionary<string, object>)result.ToObject();
  569. Assert.Equal(1d, dic["a"]);
  570. Assert.Equal("foo", dic["b"]);
  571. }
  572. [Fact]
  573. public void ShouldNotTryToConvertCompatibleTypes()
  574. {
  575. _engine.SetValue("a", new A());
  576. RunTest(@"
  577. assert(a.Call3('foo') === 'foo');
  578. assert(a.Call3(1) === '1');
  579. ");
  580. }
  581. [Fact]
  582. public void ShouldNotTryToConvertDerivedTypes()
  583. {
  584. _engine.SetValue("a", new A());
  585. _engine.SetValue("p", new Person { Name = "Mickey" });
  586. RunTest(@"
  587. assert(a.Call4(p) === 'Mickey');
  588. ");
  589. }
  590. [Fact]
  591. public void ShouldExecuteFunctionCallBackAsDelegate()
  592. {
  593. _engine.SetValue("a", new A());
  594. RunTest(@"
  595. assert(a.Call5(function(a,b){ return a+b }) === '1foo');
  596. ");
  597. }
  598. [Fact]
  599. public void ShouldExecuteFunctionCallBackAsFuncAndThisCanBeAssigned()
  600. {
  601. _engine.SetValue("a", new A());
  602. RunTest(@"
  603. assert(a.Call6(function(a,b){ return this+a+b }) === 'bar1foo');
  604. ");
  605. }
  606. [Fact]
  607. public void ShouldExecuteFunctionCallBackAsPredicate()
  608. {
  609. _engine.SetValue("a", new A());
  610. // Func<>
  611. RunTest(@"
  612. assert(a.Call8(function(){ return 'foo'; }) === 'foo');
  613. ");
  614. }
  615. [Fact]
  616. public void ShouldExecuteFunctionWithParameterCallBackAsPredicate()
  617. {
  618. _engine.SetValue("a", new A());
  619. // Func<,>
  620. RunTest(@"
  621. assert(a.Call7('foo', function(a){ return a === 'foo'; }) === true);
  622. ");
  623. }
  624. [Fact]
  625. public void ShouldExecuteActionCallBackAsPredicate()
  626. {
  627. _engine.SetValue("a", new A());
  628. // Action
  629. RunTest(@"
  630. var value;
  631. a.Call9(function(){ value = 'foo'; });
  632. assert(value === 'foo');
  633. ");
  634. }
  635. [Fact]
  636. public void ShouldExecuteActionWithParameterCallBackAsPredicate()
  637. {
  638. _engine.SetValue("a", new A());
  639. // Action<>
  640. RunTest(@"
  641. var value;
  642. a.Call10('foo', function(b){ value = b; });
  643. assert(value === 'foo');
  644. ");
  645. }
  646. [Fact]
  647. public void ShouldExecuteActionWithMultipleParametersCallBackAsPredicate()
  648. {
  649. _engine.SetValue("a", new A());
  650. // Action<,>
  651. RunTest(@"
  652. var value;
  653. a.Call11('foo', 'bar', function(a,b){ value = a + b; });
  654. assert(value === 'foobar');
  655. ");
  656. }
  657. [Fact]
  658. public void ShouldExecuteFunc()
  659. {
  660. _engine.SetValue("a", new A());
  661. // Func<int, int>
  662. RunTest(@"
  663. var result = a.Call12(42, function(a){ return a + a; });
  664. assert(result === 84);
  665. ");
  666. }
  667. [Fact]
  668. public void ShouldExecuteActionCallbackOnEventChanged()
  669. {
  670. var collection = new System.Collections.ObjectModel.ObservableCollection<string>();
  671. Assert.True(collection.Count == 0);
  672. _engine.SetValue("collection", collection);
  673. RunTest(@"
  674. var eventAction;
  675. collection.add_CollectionChanged(function(sender, eventArgs) { eventAction = eventArgs.Action; } );
  676. collection.Add('test');
  677. ");
  678. var eventAction = _engine.GetValue("eventAction").AsNumber();
  679. Assert.True(eventAction == 0);
  680. Assert.True(collection.Count == 1);
  681. }
  682. [Fact]
  683. public void ShouldUseSystemIO()
  684. {
  685. RunTest(@"
  686. var filename = System.IO.Path.GetTempFileName();
  687. var sw = System.IO.File.CreateText(filename);
  688. sw.Write('Hello World');
  689. sw.Dispose();
  690. var content = System.IO.File.ReadAllText(filename);
  691. System.Console.WriteLine(content);
  692. assert(content === 'Hello World');
  693. ");
  694. }
  695. [Fact]
  696. public void ShouldImportNamespace()
  697. {
  698. RunTest(@"
  699. var Shapes = importNamespace('Shapes');
  700. var circle = new Shapes.Circle();
  701. assert(circle.Radius === 0);
  702. assert(circle.Perimeter() === 0);
  703. ");
  704. }
  705. [Fact]
  706. public void ShouldConstructReferenceTypeWithParameters()
  707. {
  708. RunTest(@"
  709. var Shapes = importNamespace('Shapes');
  710. var circle = new Shapes.Circle(1);
  711. assert(circle.Radius === 1);
  712. assert(circle.Perimeter() === Math.PI);
  713. ");
  714. }
  715. [Fact]
  716. public void ShouldConstructValueTypeWithoutParameters()
  717. {
  718. RunTest(@"
  719. var guid = new System.Guid();
  720. assert('00000000-0000-0000-0000-000000000000' === guid.ToString());
  721. ");
  722. }
  723. [Fact]
  724. public void ShouldInvokeAFunctionByName()
  725. {
  726. RunTest(@"
  727. function add(x, y) { return x + y; }
  728. ");
  729. Assert.Equal(3, _engine.Invoke("add", 1, 2));
  730. }
  731. [Fact]
  732. public void ShouldNotInvokeNonFunctionValue()
  733. {
  734. RunTest(@"
  735. var x= 10;
  736. ");
  737. Assert.Throws<ArgumentException>(() => _engine.Invoke("x", 1, 2));
  738. }
  739. [Fact]
  740. public void CanGetField()
  741. {
  742. var o = new ClassWithField
  743. {
  744. Field = "Mickey Mouse"
  745. };
  746. _engine.SetValue("o", o);
  747. RunTest(@"
  748. assert(o.Field === 'Mickey Mouse');
  749. ");
  750. }
  751. [Fact]
  752. public void CanSetField()
  753. {
  754. var o = new ClassWithField();
  755. _engine.SetValue("o", o);
  756. RunTest(@"
  757. o.Field = 'Mickey Mouse';
  758. assert(o.Field === 'Mickey Mouse');
  759. ");
  760. Assert.Equal("Mickey Mouse", o.Field);
  761. }
  762. [Fact]
  763. public void CanGetStaticField()
  764. {
  765. RunTest(@"
  766. var domain = importNamespace('Jint.Tests.Runtime.Domain');
  767. var statics = domain.ClassWithStaticFields;
  768. assert(statics.Get == 'Get');
  769. ");
  770. }
  771. [Fact]
  772. public void CanSetStaticField()
  773. {
  774. RunTest(@"
  775. var domain = importNamespace('Jint.Tests.Runtime.Domain');
  776. var statics = domain.ClassWithStaticFields;
  777. statics.Set = 'hello';
  778. assert(statics.Set == 'hello');
  779. ");
  780. Assert.Equal(ClassWithStaticFields.Set, "hello");
  781. }
  782. [Fact]
  783. public void CanGetStaticAccessor()
  784. {
  785. RunTest(@"
  786. var domain = importNamespace('Jint.Tests.Runtime.Domain');
  787. var statics = domain.ClassWithStaticFields;
  788. assert(statics.Getter == 'Getter');
  789. ");
  790. }
  791. [Fact]
  792. public void CanSetStaticAccessor()
  793. {
  794. RunTest(@"
  795. var domain = importNamespace('Jint.Tests.Runtime.Domain');
  796. var statics = domain.ClassWithStaticFields;
  797. statics.Setter = 'hello';
  798. assert(statics.Setter == 'hello');
  799. ");
  800. Assert.Equal(ClassWithStaticFields.Setter, "hello");
  801. }
  802. [Fact]
  803. public void CantSetStaticReadonly()
  804. {
  805. RunTest(@"
  806. var domain = importNamespace('Jint.Tests.Runtime.Domain');
  807. var statics = domain.ClassWithStaticFields;
  808. statics.Readonly = 'hello';
  809. assert(statics.Readonly == 'Readonly');
  810. ");
  811. Assert.Equal(ClassWithStaticFields.Readonly, "Readonly");
  812. }
  813. [Fact]
  814. public void CanSetCustomConverters()
  815. {
  816. var engine1 = new Engine();
  817. engine1.SetValue("p", new { Test = true });
  818. engine1.Execute("var result = p.Test;");
  819. Assert.True((bool)engine1.GetValue("result").ToObject());
  820. var engine2 = new Engine(o => o.AddObjectConverter(new NegateBoolConverter()));
  821. engine2.SetValue("p", new { Test = true });
  822. engine2.Execute("var result = p.Test;");
  823. Assert.False((bool)engine2.GetValue("result").ToObject());
  824. }
  825. [Fact]
  826. public void CanConvertEnumsToString()
  827. {
  828. var engine1 = new Engine(o => o.AddObjectConverter(new EnumsToStringConverter()))
  829. .SetValue("assert", new Action<bool>(Assert.True));
  830. engine1.SetValue("p", new { Comparison = StringComparison.CurrentCulture });
  831. engine1.Execute("assert(p.Comparison === 'CurrentCulture');");
  832. engine1.Execute("var result = p.Comparison;");
  833. Assert.Equal("CurrentCulture", (string)engine1.GetValue("result").ToObject());
  834. }
  835. [Fact]
  836. public void CanUserIncrementOperator()
  837. {
  838. var p = new Person
  839. {
  840. Age = 1,
  841. };
  842. _engine.SetValue("p", p);
  843. RunTest(@"
  844. assert(++p.Age === 2);
  845. ");
  846. Assert.Equal(2, p.Age);
  847. }
  848. [Fact]
  849. public void CanOverwriteValues()
  850. {
  851. _engine.SetValue("x", 3);
  852. _engine.SetValue("x", 4);
  853. RunTest(@"
  854. assert(x === 4);
  855. ");
  856. }
  857. [Fact]
  858. public void ShouldCreateGenericType()
  859. {
  860. RunTest(@"
  861. var ListOfString = System.Collections.Generic.List(System.String);
  862. var list = new ListOfString();
  863. list.Add('foo');
  864. list.Add(1);
  865. assert(2 === list.Count);
  866. ");
  867. }
  868. [Fact]
  869. public void EnumComparesByName()
  870. {
  871. var o = new
  872. {
  873. r = Colors.Red,
  874. b = Colors.Blue,
  875. g = Colors.Green,
  876. b2 = Colors.Red
  877. };
  878. _engine.SetValue("o", o);
  879. _engine.SetValue("assertFalse", new Action<bool>(Assert.False));
  880. RunTest(@"
  881. var domain = importNamespace('Jint.Tests.Runtime.Domain');
  882. var colors = domain.Colors;
  883. assert(o.r === colors.Red);
  884. assert(o.g === colors.Green);
  885. assert(o.b === colors.Blue);
  886. assertFalse(o.b2 === colors.Blue);
  887. ");
  888. }
  889. [Fact]
  890. public void ShouldSetEnumProperty()
  891. {
  892. var s = new Circle
  893. {
  894. Color = Colors.Red,
  895. };
  896. _engine.SetValue("s", s);
  897. RunTest(@"
  898. var domain = importNamespace('Jint.Tests.Runtime.Domain');
  899. var colors = domain.Colors;
  900. s.Color = colors.Blue;
  901. assert(s.Color === colors.Blue);
  902. ");
  903. _engine.SetValue("s", s);
  904. RunTest(@"
  905. s.Color = colors.Blue | colors.Green;
  906. assert(s.Color === colors.Blue | colors.Green);
  907. ");
  908. Assert.Equal(Colors.Blue | Colors.Green, s.Color);
  909. }
  910. [Fact]
  911. public void EnumIsConvertedToNumber()
  912. {
  913. var o = new
  914. {
  915. r = Colors.Red,
  916. b = Colors.Blue,
  917. g = Colors.Green
  918. };
  919. _engine.SetValue("o", o);
  920. RunTest(@"
  921. assert(o.r === 0);
  922. assert(o.g === 1);
  923. assert(o.b === 10);
  924. ");
  925. }
  926. [Fact]
  927. public void ShouldConvertToEnum()
  928. {
  929. var s = new Circle
  930. {
  931. Color = Colors.Red,
  932. };
  933. _engine.SetValue("s", s);
  934. RunTest(@"
  935. assert(s.Color === 0);
  936. s.Color = 10;
  937. assert(s.Color === 10);
  938. ");
  939. _engine.SetValue("s", s);
  940. RunTest(@"
  941. s.Color = 11;
  942. assert(s.Color === 11);
  943. ");
  944. Assert.Equal(Colors.Blue | Colors.Green, s.Color);
  945. }
  946. [Fact]
  947. public void ShouldUseExplicitPropertyGetter()
  948. {
  949. _engine.SetValue("c", new Company("ACME"));
  950. RunTest(@"
  951. assert(c.Name === 'ACME');
  952. ");
  953. }
  954. [Fact]
  955. public void ShouldUseExplicitIndexerPropertyGetter()
  956. {
  957. var company = new Company("ACME");
  958. ((ICompany)company)["Foo"] = "Bar";
  959. _engine.SetValue("c", company);
  960. RunTest(@"
  961. assert(c.Foo === 'Bar');
  962. ");
  963. }
  964. [Fact]
  965. public void ShouldUseExplicitPropertySetter()
  966. {
  967. _engine.SetValue("c", new Company("ACME"));
  968. RunTest(@"
  969. c.Name = 'Foo';
  970. assert(c.Name === 'Foo');
  971. ");
  972. }
  973. [Fact]
  974. public void ShouldUseExplicitIndexerPropertySetter()
  975. {
  976. var company = new Company("ACME");
  977. ((ICompany)company)["Foo"] = "Bar";
  978. _engine.SetValue("c", company);
  979. RunTest(@"
  980. c.Foo = 'Baz';
  981. assert(c.Foo === 'Baz');
  982. ");
  983. }
  984. [Fact]
  985. public void ShouldUseExplicitMethod()
  986. {
  987. _engine.SetValue("c", new Company("ACME"));
  988. RunTest(@"
  989. assert(0 === c.CompareTo(c));
  990. ");
  991. }
  992. [Fact]
  993. public void ShouldCallInstanceMethodWithParams()
  994. {
  995. _engine.SetValue("a", new A());
  996. RunTest(@"
  997. assert(a.Call13('1','2','3') === '1,2,3');
  998. assert(a.Call13('1') === '1');
  999. assert(a.Call13(1) === '1');
  1000. assert(a.Call13() === '');
  1001. assert(a.Call14('a','1','2','3') === 'a:1,2,3');
  1002. assert(a.Call14('a','1') === 'a:1');
  1003. assert(a.Call14('a') === 'a:');
  1004. function call13wrapper(){ return a.Call13.apply(a, Array.prototype.slice.call(arguments)); }
  1005. assert(call13wrapper('1','2','3') === '1,2,3');
  1006. assert(a.Call13('1','2','3') === a.Call13(['1','2','3']));
  1007. ");
  1008. }
  1009. [Fact]
  1010. public void ShouldCallInstanceMethodWithJsValueParams()
  1011. {
  1012. _engine.SetValue("a", new A());
  1013. RunTest(@"
  1014. assert(a.Call16('1','2','3') === '1,2,3');
  1015. assert(a.Call16('1') === '1');
  1016. assert(a.Call16(1) === '1');
  1017. assert(a.Call16() === '');
  1018. assert(a.Call16('1','2','3') === a.Call16(['1','2','3']));
  1019. ");
  1020. }
  1021. [Fact]
  1022. public void NullValueAsArgumentShouldWork()
  1023. {
  1024. _engine.SetValue("a", new A());
  1025. RunTest(@"
  1026. var x = a.Call2(null);
  1027. assert(x === null);
  1028. ");
  1029. }
  1030. [Fact]
  1031. public void ShouldSetPropertyToNull()
  1032. {
  1033. var p = new Person { Name = "Mickey" };
  1034. _engine.SetValue("p", p);
  1035. RunTest(@"
  1036. assert(p.Name != null);
  1037. p.Name = null;
  1038. assert(p.Name == null);
  1039. ");
  1040. Assert.True(p.Name == null);
  1041. }
  1042. [Fact]
  1043. public void ShouldCallMethodWithNull()
  1044. {
  1045. _engine.SetValue("a", new A());
  1046. RunTest(@"
  1047. a.Call15(null);
  1048. var result = a.Call2(null);
  1049. assert(result == null);
  1050. ");
  1051. }
  1052. [Fact]
  1053. public void ShouldReturnUndefinedProperty()
  1054. {
  1055. _engine.SetValue("uo", new { foo = "bar" });
  1056. _engine.SetValue("ud", new Dictionary<string, object>() { {"foo", "bar"} });
  1057. _engine.SetValue("ul", new List<string>() { "foo", "bar" });
  1058. RunTest(@"
  1059. assert(!uo.undefinedProperty);
  1060. assert(!ul[5]);
  1061. assert(!ud.undefinedProperty);
  1062. ");
  1063. }
  1064. [Fact]
  1065. public void ShouldAutomaticallyConvertArraysToFindBestInteropResulution()
  1066. {
  1067. _engine.SetValue("a", new ArrayConverterTestClass());
  1068. _engine.SetValue("item1", new ArrayConverterItem(1));
  1069. _engine.SetValue("item2", new ArrayConverterItem(2));
  1070. RunTest(@"
  1071. assert(a.MethodAcceptsArrayOfInt([false, '1', 2]) === a.MethodAcceptsArrayOfInt([0, 1, 2]));
  1072. assert(a.MethodAcceptsArrayOfStrings(['1', 2]) === a.MethodAcceptsArrayOfStrings([1, 2]));
  1073. assert(a.MethodAcceptsArrayOfBool(['1', 0]) === a.MethodAcceptsArrayOfBool([true, false]));
  1074. assert(a.MethodAcceptsArrayOfStrings([item1, item2]) === a.MethodAcceptsArrayOfStrings(['1', '2']));
  1075. assert(a.MethodAcceptsArrayOfInt([item1, item2]) === a.MethodAcceptsArrayOfInt([1, 2]));
  1076. ");
  1077. }
  1078. [Fact]
  1079. public void ShouldImportNamespaceNestedType()
  1080. {
  1081. RunTest(@"
  1082. var shapes = importNamespace('Shapes.Circle');
  1083. var kinds = shapes.Kind;
  1084. assert(kinds.Unit === 0);
  1085. assert(kinds.Ellipse === 1);
  1086. assert(kinds.Round === 5);
  1087. ");
  1088. }
  1089. [Fact]
  1090. public void ShouldImportNamespaceNestedNestedType()
  1091. {
  1092. RunTest(@"
  1093. var meta = importNamespace('Shapes.Circle.Meta');
  1094. var usages = meta.Usage;
  1095. assert(usages.Public === 0);
  1096. assert(usages.Private === 1);
  1097. assert(usages.Internal === 11);
  1098. ");
  1099. }
  1100. [Fact]
  1101. public void ShouldGetNestedNestedProp()
  1102. {
  1103. RunTest(@"
  1104. var meta = importNamespace('Shapes.Circle');
  1105. var m = new meta.Meta();
  1106. assert(m.Description === 'descp');
  1107. ");
  1108. }
  1109. [Fact]
  1110. public void ShouldSetNestedNestedProp()
  1111. {
  1112. RunTest(@"
  1113. var meta = importNamespace('Shapes.Circle');
  1114. var m = new meta.Meta();
  1115. m.Description = 'hello';
  1116. assert(m.Description === 'hello');
  1117. ");
  1118. }
  1119. [Fact]
  1120. public void CanGetStaticNestedField()
  1121. {
  1122. RunTest(@"
  1123. var domain = importNamespace('Jint.Tests.Runtime.Domain.Nested');
  1124. var statics = domain.ClassWithStaticFields;
  1125. assert(statics.Get == 'Get');
  1126. ");
  1127. }
  1128. [Fact]
  1129. public void CanSetStaticNestedField()
  1130. {
  1131. RunTest(@"
  1132. var domain = importNamespace('Jint.Tests.Runtime.Domain.Nested');
  1133. var statics = domain.ClassWithStaticFields;
  1134. statics.Set = 'hello';
  1135. assert(statics.Set == 'hello');
  1136. ");
  1137. Assert.Equal(Nested.ClassWithStaticFields.Set, "hello");
  1138. }
  1139. [Fact]
  1140. public void CanGetStaticNestedAccessor()
  1141. {
  1142. RunTest(@"
  1143. var domain = importNamespace('Jint.Tests.Runtime.Domain.Nested');
  1144. var statics = domain.ClassWithStaticFields;
  1145. assert(statics.Getter == 'Getter');
  1146. ");
  1147. }
  1148. [Fact]
  1149. public void CanSetStaticNestedAccessor()
  1150. {
  1151. RunTest(@"
  1152. var domain = importNamespace('Jint.Tests.Runtime.Domain.Nested');
  1153. var statics = domain.ClassWithStaticFields;
  1154. statics.Setter = 'hello';
  1155. assert(statics.Setter == 'hello');
  1156. ");
  1157. Assert.Equal(Nested.ClassWithStaticFields.Setter, "hello");
  1158. }
  1159. [Fact]
  1160. public void CantSetStaticNestedReadonly()
  1161. {
  1162. RunTest(@"
  1163. var domain = importNamespace('Jint.Tests.Runtime.Domain.Nested');
  1164. var statics = domain.ClassWithStaticFields;
  1165. statics.Readonly = 'hello';
  1166. assert(statics.Readonly == 'Readonly');
  1167. ");
  1168. Assert.Equal(Nested.ClassWithStaticFields.Readonly, "Readonly");
  1169. }
  1170. [Fact]
  1171. public void ShouldExecuteFunctionWithValueTypeParameterCorrectly()
  1172. {
  1173. _engine.SetValue("a", new A());
  1174. // Func<int, int>
  1175. RunTest(@"
  1176. assert(a.Call17(function(value){ return value; }) === 17);
  1177. ");
  1178. }
  1179. [Fact]
  1180. public void ShouldExecuteActionWithValueTypeParameterCorrectly()
  1181. {
  1182. _engine.SetValue("a", new A());
  1183. // Action<int>
  1184. RunTest(@"
  1185. a.Call18(function(value){ assert(value === 18); });
  1186. ");
  1187. }
  1188. [Fact]
  1189. public void ShouldConvertToJsValue()
  1190. {
  1191. RunTest(@"
  1192. var now = System.DateTime.Now;
  1193. assert(new String(now) == now.toString());
  1194. var zero = System.Int32.MaxValue;
  1195. assert(new String(zero) == zero.toString());
  1196. ");
  1197. }
  1198. [Fact]
  1199. public void ShouldNotCatchClrExceptions()
  1200. {
  1201. var engine = new Engine()
  1202. .SetValue("throwMyException", new Action(() => { throw new NotSupportedException(); }))
  1203. .SetValue("Thrower", typeof(Thrower))
  1204. .Execute(@"
  1205. function throwException1(){
  1206. try {
  1207. throwMyException();
  1208. return;
  1209. }
  1210. catch(e) {
  1211. return;
  1212. }
  1213. }
  1214. function throwException2(){
  1215. try {
  1216. new Thrower().ThrowNotSupportedException();
  1217. return;
  1218. }
  1219. catch(e) {
  1220. return;
  1221. }
  1222. }
  1223. ");
  1224. Assert.ThrowsAny<NotSupportedException>(() => engine.Invoke("throwException1"));
  1225. Assert.ThrowsAny<NotSupportedException>(() => engine.Invoke("throwException2"));
  1226. }
  1227. [Fact]
  1228. public void ShouldCatchAllClrExceptions()
  1229. {
  1230. string exceptionMessage = "myExceptionMessage";
  1231. var engine = new Engine(o => o.CatchClrExceptions())
  1232. .SetValue("throwMyException", new Action(() => { throw new Exception(exceptionMessage); }))
  1233. .SetValue("Thrower", typeof(Thrower))
  1234. .Execute(@"
  1235. function throwException1(){
  1236. try {
  1237. throwMyException();
  1238. return '';
  1239. }
  1240. catch(e) {
  1241. return e.message;
  1242. }
  1243. }
  1244. function throwException2(){
  1245. try {
  1246. new Thrower().ThrowExceptionWithMessage('myExceptionMessage');
  1247. return;
  1248. }
  1249. catch(e) {
  1250. return e.message;
  1251. }
  1252. }
  1253. ");
  1254. Assert.Equal(engine.Invoke("throwException1").AsString(), exceptionMessage);
  1255. Assert.Equal(engine.Invoke("throwException2").AsString(), exceptionMessage);
  1256. }
  1257. [Fact]
  1258. public void ShouldCatchSomeExceptions()
  1259. {
  1260. string exceptionMessage = "myExceptionMessage";
  1261. var engine = new Engine(o => o.CatchClrExceptions(e => e is NotSupportedException))
  1262. .SetValue("throwMyException1", new Action(() => { throw new NotSupportedException(exceptionMessage); }))
  1263. .SetValue("throwMyException2", new Action(() => { throw new ArgumentNullException(); }))
  1264. .SetValue("Thrower", typeof(Thrower))
  1265. .Execute(@"
  1266. function throwException1(){
  1267. try {
  1268. throwMyException1();
  1269. return '';
  1270. }
  1271. catch(e) {
  1272. return e.message;
  1273. }
  1274. }
  1275. function throwException2(){
  1276. try {
  1277. throwMyException2();
  1278. return '';
  1279. }
  1280. catch(e) {
  1281. return e.message;
  1282. }
  1283. }
  1284. function throwException3(){
  1285. try {
  1286. new Thrower().ThrowNotSupportedExceptionWithMessage('myExceptionMessage');
  1287. return '';
  1288. }
  1289. catch(e) {
  1290. return e.message;
  1291. }
  1292. }
  1293. function throwException4(){
  1294. try {
  1295. new Thrower().ThrowArgumentNullException();
  1296. return '';
  1297. }
  1298. catch(e) {
  1299. return e.message;
  1300. }
  1301. }
  1302. ");
  1303. Assert.Equal(engine.Invoke("throwException1").AsString(), exceptionMessage);
  1304. Assert.Throws<ArgumentNullException>(() => engine.Invoke("throwException2"));
  1305. Assert.Equal(engine.Invoke("throwException3").AsString(), exceptionMessage);
  1306. Assert.Throws<ArgumentNullException>(() => engine.Invoke("throwException4"));
  1307. }
  1308. }
  1309. }