ScriptTest.cpp 23 KB

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