ClassBinding.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702
  1. //
  2. // Copyright (c) 2009 Brandon Jones
  3. //
  4. // This software is provided 'as-is', without any express or implied
  5. // warranty. In no event will the authors be held liable for any damages
  6. // arising from the use of this software.
  7. //
  8. // Permission is granted to anyone to use this software for any purpose,
  9. // including commercial applications, and to alter it and redistribute it
  10. // freely, subject to the following restrictions:
  11. //
  12. // 1. The origin of this software must not be misrepresented; you must not
  13. // claim that you wrote the original software. If you use this software
  14. // in a product, an acknowledgment in the product documentation would be
  15. // appreciated but is not required.
  16. //
  17. // 2. Altered source versions must be plainly marked as such, and must not be
  18. // misrepresented as being the original software.
  19. //
  20. // 3. This notice may not be removed or altered from any source
  21. // distribution.
  22. //
  23. #include <gtest/gtest.h>
  24. #include <sqrat.h>
  25. #include "Vector.h"
  26. #include "Fixture.h"
  27. using namespace Sqrat;
  28. class C
  29. {
  30. void default_values()
  31. {
  32. i = -1;
  33. s = _SC("uninitialized");
  34. f = -2.0;
  35. s2 = _SC("not initialized");
  36. }
  37. public:
  38. int i;
  39. string s;
  40. float f;
  41. string s2;
  42. C() // default constructor in code
  43. {
  44. default_values();
  45. #ifndef SQUNICODE
  46. std::cout << i << " " << s << " " << f << " " << s2 << std::endl;
  47. #endif
  48. }
  49. C(int i_)
  50. {
  51. default_values();
  52. i = i_;
  53. #ifndef SQUNICODE
  54. std::cout << i << " " << s << " " << f << " " << s2 << std::endl;
  55. #endif
  56. }
  57. C(int i_, const SQChar *s_)
  58. {
  59. default_values();
  60. i = i_;
  61. s = string(s_);
  62. #ifndef SQUNICODE
  63. std::cout << i << " " << s << " " << f << " " << s2 << std::endl;
  64. #endif
  65. }
  66. C(const SQChar *s2_, float f_)
  67. {
  68. default_values();
  69. s2 = string(s2_);
  70. f = f_;
  71. #ifndef SQUNICODE
  72. std::cout << i << " " << s << " " << f << " " << s2 << std::endl;
  73. #endif
  74. }
  75. C(int i_, const SQChar *s_, float f_)
  76. {
  77. default_values();
  78. i = i_;
  79. s = string(s_);
  80. f = f_;
  81. #ifndef SQUNICODE
  82. std::cout << i << " " << s << " " << f << " " << s2 << std::endl;
  83. #endif
  84. }
  85. C(int i_, const SQChar *s_, float f_, const SQChar *s2_): i(i_), s(s_), f(f_), s2(s2_)
  86. {
  87. #ifndef SQUNICODE
  88. std::cout << i << " " << s << " " << f << " " << s2 << std::endl;
  89. #endif
  90. }
  91. };
  92. class C1
  93. {
  94. // no default constructor in code
  95. C1(int x, int y, char z)
  96. {
  97. }
  98. };
  99. class C2
  100. {
  101. //private:
  102. public:
  103. C2() {}
  104. };
  105. class C3
  106. {
  107. // no default constructor in code
  108. public:
  109. C3(int _x, int _y, char _z) : x(_x), y(_y), z(_z)
  110. {
  111. }
  112. int x, y;
  113. char z;
  114. };
  115. TEST_F(SqratTest, Constructors)
  116. {
  117. DefaultVM::Set(vm);
  118. Class<C> c_class(vm, _SC("C"));
  119. c_class
  120. .Var(_SC("i"), &C::i)
  121. .Var(_SC("s"), &C::s)
  122. .Var(_SC("f"), &C::f)
  123. .Var(_SC("s2"), &C::s2)
  124. .Ctor()
  125. .Ctor<int>()
  126. .Ctor<int, const SQChar * >()
  127. //Ctor<const SQChar *, float >("make")
  128. .Ctor<int, const SQChar *, float >()
  129. .Ctor<int, const SQChar *, float, const SQChar * >();
  130. RootTable().Bind(_SC("C"), c_class);
  131. Class<C1> c1_class(vm, _SC("C1"));
  132. RootTable().Bind(_SC("C1"), c1_class);
  133. Class<C2> c2_class(vm, _SC("C2"));
  134. c2_class.Ctor();
  135. RootTable().Bind(_SC("C2"), c2_class);
  136. Class<C3> c3_class(vm, _SC("C3"));
  137. c3_class.Ctor<int, int, char>();
  138. RootTable().Bind(_SC("C3"), c3_class);
  139. Class<C3, Sqrat::NoCopy<C3> > c3_class2(vm, _SC("C32"));
  140. c3_class2.Ctor<int, int, char>();
  141. c3_class2.Var(_SC("x"), &C3::x)
  142. .Var(_SC("y"), &C3::y)
  143. .Var(_SC("z"), &C3::z);
  144. RootTable().Bind(_SC("C32"), c3_class2);
  145. Script script;
  146. script.CompileString(_SC(" \
  147. c0 <- C(); \
  148. c1 <- C(6); \
  149. c2 <- C(12, \"test\"); \
  150. c3 <- C(23, \"test2\", 33.5); \
  151. c4 <- C(123, \"test3\", 133.5, \"second string\"); \
  152. \
  153. gTest.EXPECT_INT_EQ(c0.i, -1); \
  154. gTest.EXPECT_FLOAT_EQ(c0.f, -2.0); \
  155. gTest.EXPECT_STR_EQ(c0.s, \"uninitialized\"); \
  156. gTest.EXPECT_STR_EQ(c0.s2, \"not initialized\"); \
  157. \
  158. gTest.EXPECT_INT_EQ(c1.i, 6); \
  159. gTest.EXPECT_FLOAT_EQ(c1.f, -2.0); \
  160. gTest.EXPECT_STR_EQ(c1.s, \"uninitialized\"); \
  161. gTest.EXPECT_STR_EQ(c1.s2, \"not initialized\"); \
  162. \
  163. gTest.EXPECT_INT_EQ(c2.i, 12); \
  164. gTest.EXPECT_FLOAT_EQ(c2.f, -2.0); \
  165. gTest.EXPECT_STR_EQ(c2.s, \"test\"); \
  166. gTest.EXPECT_STR_EQ(c2.s2, \"not initialized\"); \
  167. print(c2 + \"\\n\");\
  168. \
  169. gTest.EXPECT_INT_EQ(c3.i, 23); \
  170. gTest.EXPECT_FLOAT_EQ(c3.f, 33.5); \
  171. gTest.EXPECT_STR_EQ(c3.s, \"test2\"); \
  172. gTest.EXPECT_STR_EQ(c3.s2, \"not initialized\"); \
  173. \
  174. gTest.EXPECT_INT_EQ(c4.i, 123); \
  175. gTest.EXPECT_FLOAT_EQ(c4.f, 133.5); \
  176. gTest.EXPECT_STR_EQ(c4.s, \"test3\"); \
  177. gTest.EXPECT_STR_EQ(c4.s2, \"second string\"); \
  178. \
  179. //c22 <-make(\"abc\", 101.0) ;\
  180. gTest.EXPECT_INT_EQ(c22.i, -1); \
  181. gTest.EXPECT_FLOAT_EQ(c22.f, 101.0); \
  182. gTest.EXPECT_STR_EQ(c22.s, \"uninitialized\"); \
  183. gTest.EXPECT_STR_EQ(c22.s2, \"abc\"); \
  184. \
  185. c1 <- C1();\
  186. c2 <- C2(); \
  187. c32 <- C32(100, 202. 'c');\
  188. gTest.EXPECT_INT_EQ(c32.x, 100); \
  189. gTest.EXPECT_INT_EQ(c32.y, 202); \
  190. gTest.EXPECT_INT_EQ(c32.z, 'c'; \
  191. \
  192. "));
  193. if (Sqrat::Error::Occurred(vm))
  194. {
  195. FAIL() << _SC("Compile Failed: ") << Sqrat::Error::Message(vm);
  196. }
  197. script.Run();
  198. if (Sqrat::Error::Occurred(vm))
  199. {
  200. FAIL() << _SC("Run Failed: ") << Sqrat::Error::Message(vm);
  201. }
  202. }
  203. const Sqrat::string Vec2ToString(const Vec2* v)
  204. {
  205. std::basic_stringstream<SQChar> out;
  206. out << _SC("Vec2(") << v->x << _SC(", ") << v->y << _SC(")");
  207. return out.str();
  208. }
  209. TEST_F(SqratTest, SimpleClassBinding)
  210. {
  211. DefaultVM::Set(vm);
  212. Class<Vec2> vec2(vm, _SC("Vec2"));
  213. vec2
  214. // Variables
  215. .Var(_SC("x"), &Vec2::x)
  216. .Var(_SC("y"), &Vec2::y)
  217. // Operators
  218. .Func(_SC("_add"), &Vec2::operator +)
  219. .Func(_SC("_mul"), &Vec2::operator *)
  220. .Func(_SC("_div"), &Vec2::operator /)
  221. // Function Disambiguation
  222. .Func<Vec2 (Vec2::*)(void) const>(_SC("_unm"), &Vec2::operator -)
  223. .Func<Vec2 (Vec2::*)(const Vec2&) const>(_SC("_sub"), &Vec2::operator -)
  224. // Member Functions
  225. .Func(_SC("Length"), &Vec2::Length)
  226. .Func(_SC("Distance"), &Vec2::Distance)
  227. .Func(_SC("Normalize"), &Vec2::Normalize)
  228. .Func(_SC("Dot"), &Vec2::Dot)
  229. // Global Static Function bound as a member function
  230. .GlobalFunc(_SC("_tostring"), &Vec2ToString)
  231. ;
  232. RootTable().Bind(_SC("Vec2"), vec2);
  233. Script script;
  234. script.CompileString(_SC(" \
  235. v <- Vec2(); \
  236. v.x = 1.2; \
  237. v.y = 3.4; \
  238. v *= 2.0; \
  239. gTest.EXPECT_FLOAT_EQ(2.4, v.x); \
  240. gTest.EXPECT_FLOAT_EQ(v.x, 2.4); \
  241. gTest.EXPECT_INT_EQ(2, v.x); \
  242. gTest.EXPECT_TRUE(v.x); \
  243. gTest.EXPECT_INT_EQ(v.x, 2); \
  244. gTest.EXPECT_TRUE(v.y); \
  245. gTest.EXPECT_INT_EQ(6, v.y); \
  246. gTest.EXPECT_FLOAT_EQ(6.8, v.y); \
  247. gTest.EXPECT_STR_EQ(\"\" + v, \"Vec2(2.4, 6.8)\"); \
  248. gTest.EXPECT_FLOAT_EQ(v.Length(), 7.211103); \
  249. "));
  250. if (Sqrat::Error::Occurred(vm))
  251. {
  252. FAIL() << _SC("Compile Failed: ") << Sqrat::Error::Message(vm);
  253. }
  254. script.Run();
  255. if (Sqrat::Error::Occurred(vm))
  256. {
  257. FAIL() << _SC("Run Failed: ") << Sqrat::Error::Message(vm);
  258. }
  259. }
  260. class Animal
  261. {
  262. public:
  263. virtual ~Animal() {}
  264. virtual string Speak()
  265. {
  266. return _SC("[Silent]");
  267. }
  268. };
  269. class Cat : public Animal
  270. {
  271. public:
  272. virtual ~Cat() {}
  273. virtual string Speak()
  274. {
  275. return _SC("Meow!");
  276. }
  277. };
  278. class Dog : public Animal
  279. {
  280. public:
  281. virtual ~Dog() {}
  282. virtual string Speak()
  283. {
  284. return _SC("Woof!");
  285. }
  286. };
  287. string MakeSpeak(Animal* a)
  288. {
  289. return a->Speak();
  290. }
  291. TEST_F(SqratTest, InheritedClassBinding)
  292. {
  293. DefaultVM::Set(vm);
  294. // Defining class definitions inline
  295. RootTable().Bind(_SC("Animal"),
  296. Class<Animal>(vm, _SC("Animal"))
  297. .Func(_SC("Speak"), &Animal::Speak)
  298. );
  299. RootTable().Bind(_SC("Cat"),
  300. DerivedClass<Cat, Animal>(vm, _SC("Cat"))
  301. .Func(_SC("Speak"), &Cat::Speak)
  302. );
  303. RootTable().Bind(_SC("Dog"),
  304. DerivedClass<Dog, Animal>(vm, _SC("Dog"))
  305. .Func(_SC("Speak"), &Dog::Speak)
  306. );
  307. RootTable().Func(_SC("MakeSpeak"), &MakeSpeak);
  308. Script script;
  309. script.CompileString(_SC(" \
  310. class Mouse extends Animal { \
  311. function Speak() { \
  312. return \"Squeak!\"; \
  313. } \
  314. } \
  315. \
  316. c <- Cat(); \
  317. d <- Dog(); \
  318. m <- Mouse(); \
  319. \
  320. gTest.EXPECT_STR_EQ(c.Speak(), \"Meow!\"); \
  321. gTest.EXPECT_STR_EQ(d.Speak(), \"Woof!\"); \
  322. gTest.EXPECT_STR_EQ(m.Speak(), \"Squeak!\"); \
  323. \
  324. gTest.EXPECT_STR_EQ(MakeSpeak(c), \"Meow!\"); \
  325. gTest.EXPECT_STR_EQ(MakeSpeak(d), \"Woof!\"); \
  326. /*gTest.EXPECT_STR_EQ(MakeSpeak(m), \"Squeak!\");*/ /* This will fail! Classes overridden in squirrel will be exposed as their base native class to C++ */ \
  327. "));
  328. if (Sqrat::Error::Occurred(vm))
  329. {
  330. FAIL() << _SC("Compile Failed: ") << Sqrat::Error::Message(vm);
  331. }
  332. script.Run();
  333. if (Sqrat::Error::Occurred(vm))
  334. {
  335. FAIL() << _SC("Run Failed: ") << Sqrat::Error::Message(vm);
  336. }
  337. }
  338. class NativeObj
  339. {
  340. public:
  341. int Id()
  342. {
  343. return 42;
  344. }
  345. };
  346. TEST_F(SqratTest, WeakRef)
  347. {
  348. //
  349. // Ensure that weak referenceing work with Sqrat-bound classes
  350. // Created in response to a bug reported by emeyex
  351. //
  352. DefaultVM::Set(vm);
  353. // Defining class definitions inline
  354. RootTable().Bind(_SC("NativeObj"),
  355. Class<NativeObj>(vm, _SC("NativeObj"))
  356. .Func(_SC("Id"), &NativeObj::Id)
  357. );
  358. Script script;
  359. script.CompileString(_SC(" \
  360. class SqObj { \
  361. function Id() { \
  362. return 3.14; \
  363. } \
  364. } \
  365. \
  366. local obj1 = SqObj(); \
  367. local ref1 = obj1.weakref(); \
  368. local obj2 = NativeObj(); \
  369. local ref2 = obj2.weakref(); \
  370. \
  371. gTest.EXPECT_FLOAT_EQ(3.14, ref1.ref().Id()); \
  372. gTest.EXPECT_INT_EQ(42, ref2.ref().Id()); \
  373. "));
  374. if (Sqrat::Error::Occurred(vm))
  375. {
  376. FAIL() << _SC("Script Compile Failed: ") << Sqrat::Error::Message(vm);
  377. }
  378. script.Run();
  379. if (Sqrat::Error::Occurred(vm))
  380. {
  381. FAIL() << _SC("Script Run Failed: ") << Sqrat::Error::Message(vm);
  382. }
  383. }
  384. class NumTypes
  385. {
  386. public:
  387. int g_int()
  388. {
  389. return 3;
  390. }
  391. double g_float()
  392. {
  393. return 7.8;
  394. }
  395. bool g_true()
  396. {
  397. return true;
  398. }
  399. bool g_false()
  400. {
  401. return false;
  402. }
  403. };
  404. static const SQChar *num_conversions = _SC("\
  405. local numtypes = NumTypes();\
  406. local i = numtypes.g_int();\
  407. local d = numtypes.g_float();\
  408. local t = numtypes.g_true();\
  409. local f = numtypes.g_false();\
  410. gTest.EXPECT_TRUE(i); \
  411. gTest.EXPECT_INT_EQ(i, 3); \
  412. gTest.EXPECT_FLOAT_EQ(i, 3.0); \
  413. gTest.EXPECT_INT_EQ(3, i); \
  414. gTest.EXPECT_FLOAT_EQ(3.0, i); \
  415. \
  416. gTest.EXPECT_TRUE(d); \
  417. gTest.EXPECT_INT_EQ(d, 7); \
  418. gTest.EXPECT_FLOAT_EQ(d, 7.8); \
  419. gTest.EXPECT_INT_EQ(7, d); \
  420. gTest.EXPECT_FLOAT_EQ(7.8, d); \
  421. \
  422. gTest.EXPECT_TRUE(t); \
  423. gTest.EXPECT_INT_EQ(t, 1); \
  424. gTest.EXPECT_FLOAT_EQ(t, 1.0); \
  425. gTest.EXPECT_INT_EQ(1, t); \
  426. \
  427. gTest.EXPECT_FALSE(f); \
  428. gTest.EXPECT_INT_EQ(f, 0); \
  429. gTest.EXPECT_FLOAT_EQ(f, 0.0); \
  430. gTest.EXPECT_INT_EQ(0, f); \
  431. gTest.EXPECT_FLOAT_EQ(0.0, f); \
  432. \
  433. ");
  434. TEST_F(SqratTest, NumConversion)
  435. {
  436. DefaultVM::Set(vm);
  437. Sqrat::Class<NumTypes> numtypes(vm, _SC("NumTypes"));
  438. numtypes.Func(_SC("g_int"), &NumTypes::g_int);
  439. numtypes.Func(_SC("g_float"), &NumTypes::g_float);
  440. numtypes.Func(_SC("g_true"), &NumTypes::g_true);
  441. numtypes.Func(_SC("g_false"), &NumTypes::g_false);
  442. Sqrat::RootTable(vm).Bind(_SC("NumTypes"), numtypes);
  443. Script script;
  444. script.CompileString(num_conversions);
  445. if (Sqrat::Error::Occurred(vm))
  446. {
  447. FAIL() << _SC("Compile Failed: ") << Sqrat::Error::Message(vm);
  448. }
  449. script.Run();
  450. if (Sqrat::Error::Occurred(vm))
  451. {
  452. FAIL() << _SC("Run Failed: ") << Sqrat::Error::Message(vm);
  453. }
  454. }
  455. enum foo { BAR = 123, CAR, DEAR, EAR };
  456. class F
  457. {
  458. public:
  459. static int bar;
  460. int fn(foo foo_value)
  461. {
  462. return (int) foo_value;
  463. }
  464. };
  465. TEST_F(SqratTest, CEnumBinding)
  466. {
  467. DefaultVM::Set(vm);
  468. Class<F> f_class(vm, _SC("F"));
  469. int i = (int) BAR;
  470. f_class.SetStaticValue(_SC("bar"), i);
  471. ASSERT_TRUE(1);
  472. f_class.SetStaticValue(_SC("bar"), BAR);
  473. ASSERT_TRUE(1);
  474. f_class.Func(_SC("fn"), &F::fn);
  475. RootTable().Bind(_SC("F"), f_class);
  476. Script script;
  477. script.CompileString(_SC(" \
  478. gTest.EXPECT_INT_EQ(F.bar, 123); \
  479. f <- F(); \
  480. gTest.EXPECT_INT_EQ(124, f.fn(124)); \
  481. gTest.EXPECT_INT_EQ(125, f.fn(125)); \
  482. gTest.EXPECT_INT_EQ(126, f.fn(126)); \
  483. gTest.EXPECT_INT_EQ(300, f.fn(300)); \
  484. local raised = false ; \
  485. try {\
  486. local a = []; /* an aerray */ \
  487. f.fn(a); \
  488. gTest.EXPECT_INT_EQ(0, 1); \
  489. }\
  490. catch (ex) {\
  491. raised = true;\
  492. print(ex + \"\\n\"); \
  493. }\
  494. gTest.EXPECT_TRUE(raised); \
  495. raised = false ; \
  496. try {\
  497. local a =\"a string\"; \
  498. f.fn(a); \
  499. gTest.EXPECT_INT_EQ(0, 1); \
  500. }\
  501. catch (ex) {\
  502. raised = true;\
  503. print(ex + \"\\n\"); \
  504. }\
  505. gTest.EXPECT_TRUE(raised); \
  506. "));
  507. if (Sqrat::Error::Occurred(vm))
  508. {
  509. FAIL() << _SC("Compile Failed: ") << Sqrat::Error::Message(vm);
  510. }
  511. script.Run();
  512. if (Sqrat::Error::Occurred(vm))
  513. {
  514. FAIL() << _SC("Run Failed: ") << Sqrat::Error::Message(vm);
  515. }
  516. }
  517. class NoDefaultConstructor
  518. {
  519. public:
  520. NoDefaultConstructor(const char *s) {}
  521. void f() {}
  522. void fa(int b) {}
  523. int v;
  524. static int sv;
  525. };
  526. class NoDefaultConstructor2: public NoDefaultConstructor
  527. {
  528. public:
  529. NoDefaultConstructor2(const char *s, const char *s1) : NoDefaultConstructor(s) { }
  530. void f2() {}
  531. };
  532. TEST_F(SqratTest, NoDefaultConstructorClasses)
  533. {
  534. DefaultVM::Set(vm);
  535. NoDefaultConstructor n1("test");
  536. Class<NoDefaultConstructor> N(vm, _SC("N"));
  537. N.Ctor<char *>();
  538. N.Func(_SC("f"), &NoDefaultConstructor::f);
  539. N.Func(_SC("fa"), &NoDefaultConstructor::fa);
  540. N.Var(_SC("v"), &NoDefaultConstructor::v);
  541. RootTable().Bind(_SC("N"), N);
  542. DerivedClass<NoDefaultConstructor2, NoDefaultConstructor> N2(vm, _SC("N2"));
  543. N2.Ctor<char *, char *>();
  544. N2.Func(_SC("f2"), &NoDefaultConstructor2::f2);
  545. RootTable().Bind(_SC("N2"), N2);
  546. N.SetStaticValue(_SC("sv"), BAR);
  547. if (Sqrat::Error::Occurred(vm))
  548. {
  549. #ifndef SQUNICODE
  550. std::cerr << _SC("set static var failed, ") << Sqrat::Error::Message(vm);
  551. #endif
  552. }
  553. Script script;
  554. script.CompileString(_SC(" \
  555. class SC {} \
  556. /* note n <- N() would crash, no argument checking in this case, to do */ \
  557. n <- N(\"t\");\
  558. n2 <- N2(\"t\", \"t2\"); \
  559. n3 <- n2; \
  560. \
  561. n.f();\
  562. n2.f();\
  563. n2.f2(); \
  564. i <- 3; \
  565. n2.v = i; \
  566. \
  567. local sc = SC(); \
  568. local raised = false;\
  569. try { \
  570. n.v = n2; \
  571. gTest.EXPECT_INT_EQ(0, 1); \
  572. }\
  573. catch (ex) {\
  574. raised = true;\
  575. print(ex + \"\\n\"); \
  576. }\
  577. gTest.EXPECT_TRUE(raised); \
  578. \
  579. raised = false;\
  580. try { \
  581. n22 <- N2(\"t\", \"t2\", 3); \
  582. gTest.EXPECT_INT_EQ(0, 1); \
  583. }\
  584. catch (ex) {\
  585. raised = true;\
  586. print(ex + \"\\n\"); \
  587. }\
  588. gTest.EXPECT_TRUE(raised); \
  589. "));
  590. if (Sqrat::Error::Occurred(vm))
  591. {
  592. FAIL() << _SC("Compile Failed: ") << Sqrat::Error::Message(vm);
  593. }
  594. script.Run();
  595. if (Sqrat::Error::Occurred(vm))
  596. {
  597. FAIL() << _SC("Run Failed: ") << Sqrat::Error::Message(vm);
  598. }
  599. }