ScriptTest.cpp 23 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "testing/unitTesting.h"
  23. #include "platform/platform.h"
  24. #include "console/simBase.h"
  25. #include "console/consoleTypes.h"
  26. #include "console/simBase.h"
  27. #include "console/engineAPI.h"
  28. #include "math/mMath.h"
  29. #include "console/script.h"
  30. #include "console/stringStack.h"
  31. #include "gui/buttons/guiIconButtonCtrl.h"
  32. inline ConsoleValue RunScript(const char* str)
  33. {
  34. return std::move(Con::evaluate(str, false, NULL).value);
  35. }
  36. using ::testing::Matcher;
  37. using ::testing::TypedEq;
  38. class ScriptTest : public ::testing::Test
  39. {
  40. protected:
  41. ScriptTest()
  42. {
  43. }
  44. void SetUp() override
  45. {
  46. }
  47. };
  48. TEST_F(ScriptTest, Basic_Arithmetic)
  49. {
  50. ConsoleValue add = RunScript(R"(
  51. return 1.0 + 1;
  52. )");
  53. ASSERT_EQ(add.getInt(), 2);
  54. ConsoleValue sub = RunScript(R"(
  55. return 10 - 1.0;
  56. )");
  57. ASSERT_EQ(sub.getInt(), 9);
  58. ConsoleValue mult = RunScript(R"(
  59. return 10 * 2.5;
  60. )");
  61. ASSERT_EQ(mult.getInt(), 25);
  62. ConsoleValue div = RunScript(R"(
  63. return 10.0 / 2;
  64. )");
  65. ASSERT_EQ(div.getInt(), 5);
  66. ConsoleValue mod = RunScript(R"(
  67. return 4 % 5;
  68. )");
  69. ASSERT_EQ(mod.getInt(), 4);
  70. ConsoleValue add2 = RunScript(R"(
  71. $a = 0;
  72. $a += 2;
  73. return $a;
  74. )");
  75. ASSERT_EQ(add2.getInt(), 2);
  76. ConsoleValue sub2 = RunScript(R"(
  77. $a = 0;
  78. $a -= 2;
  79. return $a;
  80. )");
  81. ASSERT_EQ(sub2.getInt(), -2);
  82. ConsoleValue mult2 = RunScript(R"(
  83. $a = 2;
  84. $a *= 3;
  85. return $a;
  86. )");
  87. ASSERT_EQ(mult2.getInt(), 6);
  88. ConsoleValue div2 = RunScript(R"(
  89. $a = 10;
  90. $a /= 2;
  91. return $a;
  92. )");
  93. ASSERT_EQ(div2.getInt(), 5);
  94. ConsoleValue pp = RunScript(R"(
  95. $a = 0;
  96. $a++;
  97. return $a;
  98. )");
  99. ASSERT_EQ(pp.getInt(), 1);
  100. ConsoleValue mm = RunScript(R"(
  101. $a = 2;
  102. $a--;
  103. return $a;
  104. )");
  105. ASSERT_EQ(mm.getInt(), 1);
  106. }
  107. TEST_F(ScriptTest, Complex_Arithmetic)
  108. {
  109. ConsoleValue result = RunScript(R"(
  110. return 1 * 2 - (0.5 * 2);
  111. )");
  112. ASSERT_EQ(result.getInt(), 1);
  113. ConsoleValue result2 = RunScript(R"(
  114. return 1 * 2 * 3 % 2;
  115. )");
  116. ASSERT_EQ(result2.getInt(), 0);
  117. }
  118. TEST_F(ScriptTest, Basic_Concatination)
  119. {
  120. ConsoleValue result1 = RunScript(R"(
  121. return "a" @ "b";
  122. )");
  123. ASSERT_STREQ(result1.getString(), "ab");
  124. ConsoleValue result2 = RunScript(R"(
  125. return "a" SPC "b";
  126. )");
  127. ASSERT_STREQ(result2.getString(), "a b");
  128. ConsoleValue result3 = RunScript(R"(
  129. return "a" TAB "b";
  130. )");
  131. ASSERT_STREQ(result3.getString(), "a\tb");
  132. ConsoleValue result4 = RunScript(R"(
  133. return "a" NL "b";
  134. )");
  135. ASSERT_STREQ(result4.getString(), "a\nb");
  136. ConsoleValue complex = RunScript(R"(
  137. return "a" @ "b" @ "c" @ "d";
  138. )");
  139. ASSERT_STREQ(complex.getString(), "abcd");
  140. }
  141. TEST_F(ScriptTest, Basic_Global_Variable_Tests)
  142. {
  143. ConsoleValue value = RunScript(R"(
  144. $a = 1;
  145. return $a;
  146. )");
  147. ASSERT_EQ(value.getInt(), 1);
  148. }
  149. TEST_F(ScriptTest, Variable_Chaining_And_Usage)
  150. {
  151. ConsoleValue value = RunScript(R"(
  152. function t()
  153. {
  154. %a = %b = 2;
  155. return %a;
  156. }
  157. return t();
  158. )");
  159. ASSERT_EQ(value.getInt(), 2);
  160. ConsoleValue valueGlobal = RunScript(R"(
  161. function t()
  162. {
  163. $a = %b = 2;
  164. }
  165. t();
  166. return $a;
  167. )");
  168. ASSERT_EQ(valueGlobal.getInt(), 2);
  169. ConsoleValue value2 = RunScript(R"(
  170. function t(%a)
  171. {
  172. if ((%b = 2 * %a) != 5)
  173. return %b;
  174. return 5;
  175. }
  176. return t(2);
  177. )");
  178. ASSERT_EQ(value2.getInt(), 4);
  179. }
  180. TEST_F(ScriptTest, Basic_Function_Call_And_Local_Variable_Testing)
  181. {
  182. ConsoleValue value = RunScript(R"(
  183. function t() { %a = 2; return %a; }
  184. return t();
  185. )");
  186. ASSERT_EQ(value.getInt(), 2);
  187. ConsoleValue value2 = RunScript(R"(
  188. function add(%a, %b) { return %a + %b; }
  189. return add(2, 4);
  190. )");
  191. ASSERT_EQ(value2.getInt(), 6);
  192. ConsoleValue value3 = RunScript(R"(
  193. function fib(%a) {
  194. if (%a == 0)
  195. return 0;
  196. if (%a == 1)
  197. return 1;
  198. return fib(%a - 1) + fib(%a - 2);
  199. }
  200. return fib(15);
  201. )");
  202. ASSERT_EQ(value3.getInt(), 610);
  203. ConsoleValue staticCall = RunScript(R"(
  204. function SimObject::bar(%a, %b) {
  205. return %a + %b;
  206. }
  207. return SimObject::bar(1, 2);
  208. )");
  209. ASSERT_EQ(staticCall.getInt(), 3);
  210. }
  211. TEST_F(ScriptTest, Basic_Conditional_Statements)
  212. {
  213. ConsoleValue value = RunScript(R"(
  214. $a = "hello";
  215. if ($a $= "hello")
  216. return 1;
  217. return 2;
  218. )");
  219. ASSERT_EQ(value.getInt(), 1);
  220. ConsoleValue ternaryValue = RunScript(R"(
  221. return $a $= "hello" ? "World" : "No U";
  222. )");
  223. ASSERT_STREQ(ternaryValue.getString(), "World");
  224. }
  225. TEST_F(ScriptTest, Basic_Loop_Statements)
  226. {
  227. ConsoleValue whileValue = RunScript(R"(
  228. $count = 0;
  229. while ($count < 5)
  230. $count++;
  231. return $count;
  232. )");
  233. ASSERT_EQ(whileValue.getInt(), 5);
  234. ConsoleValue forValue = RunScript(R"(
  235. function t(%times)
  236. {
  237. %result = "";
  238. for (%i = 0; %i < %times; %i++)
  239. %result = %result @ "a";
  240. return %result;
  241. }
  242. return t(3);
  243. )");
  244. ASSERT_STREQ(forValue.getString(), "aaa");
  245. ConsoleValue forReverseLoop = RunScript(R"(
  246. function t(%times)
  247. {
  248. %result = "";
  249. for (%i = %times - 1; %i >= 0; %i--)
  250. %result = %result @ "b";
  251. return %result;
  252. }
  253. return t(3);
  254. )");
  255. ASSERT_STREQ(forReverseLoop.getString(), "bbb");
  256. ConsoleValue forIfValue = RunScript(R"(
  257. function t()
  258. {
  259. %str = "";
  260. for (%i = 0; %i < 5; %i++)
  261. {
  262. %loopValue = %i;
  263. if (%str $= "")
  264. %str = %loopValue;
  265. else
  266. %str = %str @ "," SPC %loopValue;
  267. }
  268. return %str;
  269. }
  270. return t();
  271. )");
  272. ASSERT_STREQ(forIfValue.getString(), "0, 1, 2, 3, 4");
  273. }
  274. TEST_F(ScriptTest, ForEachLoop)
  275. {
  276. ConsoleValue forEach1 = RunScript(R"(
  277. $theSimSet = new SimSet();
  278. $theSimSet.add(new SimObject());
  279. $theSimSet.add(new SimObject());
  280. $counter = 0;
  281. foreach ($obj in $theSimSet)
  282. {
  283. $counter++;
  284. }
  285. $theSimSet.delete();
  286. return $counter;
  287. )");
  288. ASSERT_EQ(forEach1.getInt(), 2);
  289. ConsoleValue forEach2 = RunScript(R"(
  290. $counter = 0;
  291. foreach$ ($word in "a b c d")
  292. {
  293. $counter++;
  294. }
  295. return $counter;
  296. )");
  297. ASSERT_EQ(forEach2.getInt(), 4);
  298. ConsoleValue forEach3 = RunScript(R"(
  299. function SimObject::addOne(%this)
  300. {
  301. return 1;
  302. }
  303. function test()
  304. {
  305. %set = new SimSet();
  306. %set.add(new SimObject());
  307. %set.add(new SimObject());
  308. %count = 0;
  309. foreach (%obj in %set)
  310. %count += %obj.addOne();
  311. %set.delete();
  312. return %count;
  313. }
  314. return test();
  315. )");
  316. ASSERT_EQ(forEach3.getInt(), 2);
  317. ConsoleValue forEach4 = RunScript(R"(
  318. function test()
  319. {
  320. %string = "a b c d e";
  321. %count = 0;
  322. foreach$ (%word in %string)
  323. %count++;
  324. return %count;
  325. }
  326. return test();
  327. )");
  328. ASSERT_EQ(forEach4.getInt(), 5);
  329. ConsoleValue forEach5 = RunScript(R"(
  330. function SimObject::ret1(%this)
  331. {
  332. return 1;
  333. }
  334. function SimSet::doForeach5(%this)
  335. {
  336. %count = 0;
  337. foreach (%obj in %this)
  338. {
  339. %count += %obj.ret1();
  340. }
  341. return %count;
  342. }
  343. function a()
  344. {
  345. %set = new SimSet();
  346. %set.add(new SimObject());
  347. %set.add(new SimObject());
  348. %set.add(new SimObject());
  349. return %set.doForeach5();
  350. }
  351. return a();
  352. )");
  353. ASSERT_EQ(forEach5.getInt(), 3);
  354. ConsoleValue forEachContinue = RunScript(R"(
  355. function SimSet::foreach6(%this)
  356. {
  357. %count = 0;
  358. foreach (%obj in %this)
  359. {
  360. if (%obj.getName() $= "A_FEC")
  361. continue;
  362. %count++;
  363. }
  364. return %count;
  365. }
  366. function a()
  367. {
  368. %set = new SimSet();
  369. %set.add(new SimObject(A_FEC));
  370. %set.add(new SimObject());
  371. %set.add(new SimObject());
  372. return %set.foreach6();
  373. }
  374. return a();
  375. )");
  376. ASSERT_EQ(forEachContinue.getInt(), 2);
  377. ConsoleValue forEachReturn = RunScript(R"(
  378. function SimSet::findA(%this)
  379. {
  380. foreach (%obj in %this)
  381. {
  382. if (%obj.getName() $= "A_FER")
  383. return 76;
  384. }
  385. return 0;
  386. }
  387. function a()
  388. {
  389. %set = new SimSet();
  390. %set.add(new SimObject(A_FER));
  391. %set.add(new SimObject());
  392. %set.add(new SimObject());
  393. return %set.findA();
  394. }
  395. return a();
  396. )");
  397. ASSERT_EQ(forEachReturn.getInt(), 76);
  398. ConsoleValue forEachNestedReturn = RunScript(R"(
  399. function SimSet::findA(%this)
  400. {
  401. foreach (%obj in %this)
  402. {
  403. foreach (%innerObj in %this)
  404. {
  405. if (%innerObj.getName() $= "A_FENR")
  406. return 42;
  407. }
  408. }
  409. return 0;
  410. }
  411. function a()
  412. {
  413. %set = new SimSet();
  414. %set.add(new SimObject(A_FENR));
  415. %set.add(new SimObject());
  416. %set.add(new SimObject());
  417. %group = new SimGroup();
  418. %group.add(%set);
  419. return %set.findA();
  420. }
  421. return a();
  422. )");
  423. ASSERT_EQ(forEachNestedReturn.getInt(), 42);
  424. }
  425. TEST_F(ScriptTest, TorqueScript_Array_Testing)
  426. {
  427. ConsoleValue value = RunScript(R"(
  428. function t(%idx) { %a[%idx] = 2; return %a[%idx]; }
  429. return t(5);
  430. )");
  431. ASSERT_EQ(value.getInt(), 2);
  432. ConsoleValue value2 = RunScript(R"(
  433. function t(%idx) { %a[%idx, 0] = 2; return %a[%idx, 0]; }
  434. return t(5);
  435. )");
  436. ASSERT_EQ(value2.getInt(), 2);
  437. }
  438. TEST_F(ScriptTest, SimObject_Tests)
  439. {
  440. ConsoleValue object = RunScript(R"(
  441. return new SimObject(FudgeCollector)
  442. {
  443. fudge = "Chocolate";
  444. };
  445. )");
  446. ASSERT_NE(Sim::findObject(object), (SimObject*)NULL);
  447. ConsoleValue propertyValue = RunScript(R"(
  448. return FudgeCollector.fudge;
  449. )");
  450. ASSERT_STREQ(propertyValue.getString(), "Chocolate");
  451. ConsoleValue funcReturn = RunScript(R"(
  452. function SimObject::fooFunc(%this)
  453. {
  454. return "Bar";
  455. }
  456. return FudgeCollector.fooFunc();
  457. )");
  458. ASSERT_STREQ(funcReturn.getString(), "Bar");
  459. ConsoleValue parentFn = RunScript(R"(
  460. new SimObject(Hello);
  461. function SimObject::fooFunc2(%this)
  462. {
  463. return "Bar";
  464. }
  465. function Hello::fooFunc2(%this)
  466. {
  467. %bar = Parent::fooFunc2(%this);
  468. return "Foo" @ %bar;
  469. }
  470. return Hello.fooFunc2();
  471. )");
  472. ASSERT_STREQ(parentFn.getString(), "FooBar");
  473. ConsoleValue simpleFieldTest = RunScript(R"(
  474. function a()
  475. {
  476. FudgeCollector.field = "A";
  477. return FudgeCollector.field;
  478. }
  479. return a();
  480. )");
  481. ASSERT_STREQ(simpleFieldTest.getString(), "A");
  482. ConsoleValue grp = RunScript(R"(
  483. new SimGroup(FudgeCollectorGroup)
  484. {
  485. theName = "fudge";
  486. new SimObject(ChocolateFudge)
  487. {
  488. type = "Chocolate";
  489. };
  490. new SimObject(PeanutButterFudge)
  491. {
  492. type = "Peanut Butter";
  493. field["a"] = "Yes";
  494. };
  495. };
  496. return FudgeCollectorGroup.getId();
  497. )");
  498. SimGroup* simGroup = dynamic_cast<SimGroup*>(Sim::findObject(grp));
  499. ASSERT_NE(simGroup, (SimGroup*)NULL);
  500. ASSERT_EQ(simGroup->size(), 2);
  501. simGroup->deleteObject();
  502. ConsoleValue fieldTest = RunScript(R"(
  503. function a()
  504. {
  505. %obj = new SimObject();
  506. %obj.field = "A";
  507. %obj.val[%obj.field] = "B";
  508. %value = %obj.val["A"];
  509. %obj.delete();
  510. return %value;
  511. }
  512. return a();
  513. )");
  514. ASSERT_STREQ(fieldTest.getString(), "B");
  515. ConsoleValue fieldOpTest = RunScript(R"(
  516. function a()
  517. {
  518. %obj = new SimObject();
  519. %obj.field = 1;
  520. %obj.field += 2;
  521. %value = %obj.field;
  522. %obj.delete();
  523. return %value;
  524. }
  525. return a();
  526. )");
  527. ASSERT_EQ(fieldOpTest.getInt(), 3);
  528. ConsoleValue inheritedObjectTest = RunScript(R"(
  529. function SimObject::testClass(%this)
  530. {
  531. return 4;
  532. }
  533. function SuperFooBar::doSuperTest(%this)
  534. {
  535. return 5;
  536. }
  537. function FooBar::test(%this)
  538. {
  539. return 2;
  540. }
  541. new SimObject(GrandFooBar)
  542. {
  543. superClass = "SuperFooBar";
  544. };
  545. new SimObject(Foo : GrandFooBar)
  546. {
  547. class = "FooBar";
  548. };
  549. new SimObject(Bar : Foo);
  550. function Bar::doTheAddition(%this)
  551. {
  552. return %this.testClass() + %this.test() + %this.doSuperTest();
  553. }
  554. return Bar.doTheAddition();
  555. )");
  556. ASSERT_EQ(inheritedObjectTest.getInt(), 11);
  557. }
  558. TEST_F(ScriptTest, Internal_Name)
  559. {
  560. ConsoleValue value = RunScript(R"(
  561. function TheFirstInner::_internalCall(%this)
  562. {
  563. return 5;
  564. }
  565. function a()
  566. {
  567. %grp = new SimGroup();
  568. %obj = new SimObject(TheFirstInner)
  569. {
  570. internalName = "Yay";
  571. };
  572. %grp.add(%obj);
  573. %val = %grp->Yay._internalCall();
  574. %grp.delete();
  575. return %val;
  576. }
  577. return a();
  578. )");
  579. ASSERT_EQ(value.getInt(), 5);
  580. ConsoleValue recursiveValue = RunScript(R"(
  581. function SimGroup::doTheInternalCall(%this)
  582. {
  583. return %this-->Yeah._internalCall2();
  584. }
  585. function TheAnotherObject::_internalCall2(%this)
  586. {
  587. return %this.property;
  588. }
  589. function a()
  590. {
  591. %grp = new SimGroup();
  592. %obj = new SimGroup()
  593. {
  594. internalName = "Yay2";
  595. new SimObject(TheAnotherObject)
  596. {
  597. internalName = "Yeah";
  598. property = 12;
  599. };
  600. };
  601. %grp.add(%obj);
  602. %val = %grp.doTheInternalCall();
  603. %grp.delete();
  604. return %val;
  605. }
  606. return a();
  607. )");
  608. ASSERT_EQ(recursiveValue.getInt(), 12);
  609. }
  610. TEST_F(ScriptTest, Basic_Package)
  611. {
  612. ConsoleValue value = RunScript(R"(
  613. function a() { return 3; }
  614. package overrides
  615. {
  616. function a() { return 5; }
  617. };
  618. return a();
  619. )");
  620. ASSERT_EQ(value.getInt(), 3);
  621. ConsoleValue overrideValue = RunScript(R"(
  622. activatePackage(overrides);
  623. return a();
  624. )");
  625. ASSERT_EQ(overrideValue.getInt(), 5);
  626. ConsoleValue deactivatedValue = RunScript(R"(
  627. deactivatePackage(overrides);
  628. return a();
  629. )");
  630. ASSERT_EQ(deactivatedValue.getInt(), 3);
  631. }
  632. TEST_F(ScriptTest, Sugar_Syntax)
  633. {
  634. ConsoleValue value = RunScript(R"(
  635. function a()
  636. {
  637. %vector = "1 2 3";
  638. return %vector.y;
  639. }
  640. return a();
  641. )");
  642. ASSERT_EQ(value.getInt(), 2);
  643. ConsoleValue setValue = RunScript(R"(
  644. function a()
  645. {
  646. %vector = "1 2 3";
  647. %vector.y = 4;
  648. return %vector.y;
  649. }
  650. return a();
  651. )");
  652. ASSERT_EQ(setValue.getInt(), 4);
  653. ConsoleValue valueArray = RunScript(R"(
  654. function a()
  655. {
  656. %vector[0] = "1 2 3";
  657. return %vector[0].y;
  658. }
  659. return a();
  660. )");
  661. ASSERT_EQ(valueArray.getInt(), 2);
  662. ConsoleValue valueSetArray = RunScript(R"(
  663. function a()
  664. {
  665. %vector[0] = "1 2 3";
  666. %vector[0].z = 5;
  667. return %vector[0].z;
  668. }
  669. return a();
  670. )");
  671. ASSERT_EQ(valueSetArray.getInt(), 5);
  672. ConsoleValue valueStoreCalculated = RunScript(R"(
  673. function a()
  674. {
  675. %extent = 10 SPC 20;
  676. %scaling = 1;
  677. %size = %extent.x * %scaling;
  678. return %size;
  679. }
  680. return a();
  681. )");
  682. ASSERT_EQ(valueStoreCalculated.getInt(), 10);
  683. ConsoleValue globalValueGet = RunScript(R"(
  684. new SimObject(AAAA);
  685. AAAA.doSomething = false;
  686. $vec = "1 2 3";
  687. return $vec.x * 4;
  688. )");
  689. ASSERT_EQ(globalValueGet.getFloat(), 4);
  690. ConsoleValue globalValueSet = RunScript(R"(
  691. new SimObject(AAAAB);
  692. AAAAB.doSomething = false;
  693. $vec2 = "1 2 3";
  694. $vec2.x *= 4;
  695. return $vec2.x;
  696. )");
  697. ASSERT_EQ(globalValueSet.getFloat(), 4);
  698. }
  699. TEST_F(ScriptTest, InnerObjectTests)
  700. {
  701. ConsoleValue theObject = RunScript(R"(
  702. function a()
  703. {
  704. %obj = new SimObject(TheOuterObject)
  705. {
  706. innerObject = new SimObject(TheInnerObject)
  707. {
  708. testField = 123;
  709. position = "1 2 3";
  710. };
  711. };
  712. return %obj;
  713. }
  714. return a();
  715. )");
  716. SimObject* outerObject = Sim::findObject("TheOuterObject");
  717. ASSERT_NE(outerObject, (SimObject*)NULL);
  718. if (outerObject)
  719. {
  720. ASSERT_EQ(theObject.getInt(), Sim::findObject("TheOuterObject")->getId());
  721. }
  722. ASSERT_NE(Sim::findObject("TheInnerObject"), (SimObject*)NULL);
  723. ConsoleValue positionValue = RunScript(R"(
  724. function TheOuterObject::getInnerPosition(%this)
  725. {
  726. return %this.innerObject.position;
  727. }
  728. function a()
  729. {
  730. %position = TheOuterObject.getInnerPosition();
  731. return %position.y;
  732. }
  733. return a();
  734. )");
  735. ASSERT_EQ(positionValue.getInt(), 2);
  736. ConsoleValue nestedFuncCall = RunScript(R"(
  737. function TheInnerObject::test(%this)
  738. {
  739. return %this.testField;
  740. }
  741. return TheOuterObject.innerObject.test();
  742. )");
  743. ASSERT_EQ(nestedFuncCall.getInt(), 123);
  744. }
  745. TEST_F(ScriptTest, MiscTesting)
  746. {
  747. ConsoleValue test1 = RunScript(R"(
  748. function testNotPassedInParameters(%a, %b, %c, %d)
  749. {
  750. if (%d $= "")
  751. return true;
  752. return false;
  753. }
  754. return testNotPassedInParameters(1, 2); // skip passing in %c and %d
  755. )");
  756. ASSERT_EQ(test1.getBool(), true);
  757. ConsoleValue test2 = RunScript(R"(
  758. function SimObject::concatNameTest(%this)
  759. {
  760. return true;
  761. }
  762. new SimObject(WeirdTestObject1);
  763. function testObjectNameConcatination(%i)
  764. {
  765. return (WeirdTestObject @ %i).concatNameTest();
  766. }
  767. return testObjectNameConcatination(1);
  768. )");
  769. ASSERT_EQ(test2.getBool(), true);
  770. }
  771. TEST_F(ScriptTest, RegressionInt)
  772. {
  773. ConsoleValue regression1 = RunScript(R"(
  774. new SimObject(TheRegressionObject);
  775. function doTest()
  776. {
  777. TheRegressionObject.hidden = false;
  778. %previewSize = 100 SPC 100;
  779. %previewScaleSize = 2;
  780. %size = %previewSize.x * %previewScaleSize;
  781. return %size;
  782. }
  783. return doTest();
  784. )");
  785. ASSERT_EQ(regression1.getInt(), 200);
  786. ConsoleValue regression2 = RunScript(R"(
  787. new SimObject(TheRegressionObject2)
  788. {
  789. extent = "100 200";
  790. };
  791. function doTest()
  792. {
  793. %scale = 2;
  794. %position = TheRegressionObject2.extent.x SPC TheRegressionObject2.extent.y * %scale;
  795. return %position.y;
  796. }
  797. return doTest();
  798. )");
  799. ASSERT_EQ(regression2.getInt(), 400);
  800. ConsoleValue regression3 = RunScript(R"(
  801. function noOpInc()
  802. {
  803. %count = 0;
  804. %var[%count++] = 2;
  805. return %var[1];
  806. }
  807. return noOpInc();
  808. )");
  809. ASSERT_EQ(regression3.getInt(), 2);
  810. }
  811. TEST_F(ScriptTest, RegressionFloat)
  812. {
  813. ConsoleValue regression = RunScript(R"(
  814. function doTest()
  815. {
  816. %slider = new GuiSliderCtrl()
  817. {
  818. range = "0 2";
  819. ticks = 5;
  820. active = true;
  821. };
  822. %slider.setValue(0.5);
  823. return %slider.getValue();
  824. }
  825. return doTest();
  826. )");
  827. ASSERT_EQ(regression.getFloat(), 0.5);
  828. }
  829. TEST_F(ScriptTest, RegressionBool)
  830. {
  831. ConsoleValue regression = RunScript(R"(
  832. function SimObject::burnBool(%this, %line)
  833. {
  834. return %line @ "1";
  835. }
  836. function doTest()
  837. {
  838. %obj = new SimObject();
  839. for (%i = 0; %i < 100; %i++)
  840. {
  841. %function = "burnBool";
  842. if (%obj.isMethod(%function))
  843. {
  844. %line = "abcdefg";
  845. %output = %obj.call(%function, %line);
  846. }
  847. }
  848. return true;
  849. }
  850. return doTest();
  851. )");
  852. ASSERT_EQ(regression.getBool(), true);
  853. }
  854. TEST_F(ScriptTest, RegressionString)
  855. {
  856. ConsoleValue regression = RunScript(R"(
  857. function Tween::vectorAdd(%v1, %v2)
  858. {
  859. %temp = "";
  860. for (%i = 0; %i < getWordCount(%v1); %i++) {
  861. %e = getWord(%v1, %i) + getWord(%v2, %i);
  862. %temp = %i == 0 ? %e : %temp SPC %e;
  863. }
  864. return %temp;
  865. }
  866. return Tween::vectorAdd("1 2 3", "4 5 6");
  867. )");
  868. ASSERT_STREQ(regression.getString(), "5 7 9");
  869. ConsoleValue regression2 = RunScript(R"(
  870. function doTest()
  871. {
  872. %button = new GuiIconButtonCtrl()
  873. {
  874. active = true;
  875. };
  876. %button.setExtent(120, 20);
  877. %button.setExtent("120 20");
  878. %button.extent = "120 20";
  879. %button.extent.x = 120;
  880. %button.extent.y = 20;
  881. return %button.extent;
  882. }
  883. return doTest();
  884. )");
  885. ASSERT_STREQ(regression2.getString(), "120 20");
  886. }