consoleTest.cpp
Engine/source/console/test/consoleTest.cpp
Detailed Description
1 2#ifdef TORQUE_TESTS_ENABLED 3#include "testing/unitTesting.h" 4#include "platform/platform.h" 5#include "console/simBase.h" 6#include "console/consoleTypes.h" 7#include "console/simBase.h" 8#include "console/engineAPI.h" 9#include "math/mMath.h" 10#include "console/stringStack.h" 11 12TEST(Con, executef) 13{ 14 char buffer[128]; 15 Con::evaluate("if (isObject(TestConExec)) {\r\nTestConExec.delete();\r\n}\r\nfunction testExecutef(%a,%b,%c,%d,%e,%f,%g,%h,%i,%j,%k){return %a SPC %b SPC %c SPC %d SPC %e SPC %f SPC %g SPC %h SPC %i SPC %j SPC %k;}\r\nfunction TestConExec::testThisFunction(%this,%a,%b,%c,%d,%e,%f,%g,%h,%i,%j){ return %a SPC %b SPC %c SPC %d SPC %e SPC %f SPC %g SPC %h SPC %i SPC %j;}\r\nnew ScriptObject(TestConExec);\r\n", false, "test"); 16 17 SimObject *testObject = NULL; 18 Sim::findObject("TestConExec", testObject); 19 20 EXPECT_TRUE(testObject != NULL) 21 << "TestConExec object should exist"; 22 23 // Check basic calls with SimObject. We'll do this for every single possible call just to make sure. 24 const char *returnValue = NULL; 25 26 returnValue = Con::executef(testObject, "testThisFunction"); 27 EXPECT_TRUE(dStricmp(returnValue, " ") == 0) << 28 "All values should be printed in the correct order"; 29 30 returnValue = Con::executef(testObject, "testThisFunction", "a"); 31 EXPECT_TRUE(dStricmp(returnValue, "a ") == 0) << 32 "All values should be printed in the correct order"; 33 34 returnValue = Con::executef(testObject, "testThisFunction", "a", "b"); 35 EXPECT_TRUE(dStricmp(returnValue, "a b ") == 0) << 36 "All values should be printed in the correct order"; 37 38 returnValue = Con::executef(testObject, "testThisFunction", "a", "b", "c"); 39 EXPECT_TRUE(dStricmp(returnValue, "a b c ") == 0) << 40 "All values should be printed in the correct order"; 41 42 returnValue = Con::executef(testObject, "testThisFunction", "a", "b", "c", "d"); 43 EXPECT_TRUE(dStricmp(returnValue, "a b c d ") == 0) << 44 "All values should be printed in the correct order"; 45 46 returnValue = Con::executef(testObject, "testThisFunction", "a", "b", "c", "d", "e"); 47 EXPECT_TRUE(dStricmp(returnValue, "a b c d e ") == 0) << 48 "All values should be printed in the correct order"; 49 50 returnValue = Con::executef(testObject, "testThisFunction", "a", "b", "c", "d", "e", "f"); 51 EXPECT_TRUE(dStricmp(returnValue, "a b c d e f ") == 0) << 52 "All values should be printed in the correct order"; 53 54 returnValue = Con::executef(testObject, "testThisFunction", "a", "b", "c", "d", "e", "f", "g"); 55 EXPECT_TRUE(dStricmp(returnValue, "a b c d e f g ") == 0) << 56 "All values should be printed in the correct order"; 57 58 returnValue = Con::executef(testObject, "testThisFunction", "a", "b", "c", "d", "e", "f", "g", "h"); 59 EXPECT_TRUE(dStricmp(returnValue, "a b c d e f g h ") == 0) << 60 "All values should be printed in the correct order"; 61 62 returnValue = Con::executef(testObject, "testThisFunction", "a", "b", "c", "d", "e", "f", "g", "h", "i"); 63 EXPECT_TRUE(dStricmp(returnValue, "a b c d e f g h i ") == 0) << 64 "All values should be printed in the correct order"; 65 66 // Now test without the object 67 68 returnValue = Con::executef("testExecutef"); 69 EXPECT_TRUE(dStricmp(returnValue, " ") == 0) << 70 "All values should be printed in the correct order"; 71 72 returnValue = Con::executef("testExecutef", "a"); 73 EXPECT_TRUE(dStricmp(returnValue, "a ") == 0) << 74 "All values should be printed in the correct order"; 75 76 returnValue = Con::executef("testExecutef", "a", "b"); 77 EXPECT_TRUE(dStricmp(returnValue, "a b ") == 0) << 78 "All values should be printed in the correct order"; 79 80 returnValue = Con::executef("testExecutef", "a", "b", "c"); 81 EXPECT_TRUE(dStricmp(returnValue, "a b c ") == 0) << 82 "All values should be printed in the correct order"; 83 84 returnValue = Con::executef("testExecutef", "a", "b", "c", "d"); 85 EXPECT_TRUE(dStricmp(returnValue, "a b c d ") == 0) << 86 "All values should be printed in the correct order"; 87 88 returnValue = Con::executef("testExecutef", "a", "b", "c", "d", "e"); 89 EXPECT_TRUE(dStricmp(returnValue, "a b c d e ") == 0) << 90 "All values should be printed in the correct order"; 91 92 returnValue = Con::executef("testExecutef", "a", "b", "c", "d", "e", "f"); 93 EXPECT_TRUE(dStricmp(returnValue, "a b c d e f ") == 0) << 94 "All values should be printed in the correct order"; 95 96 returnValue = Con::executef("testExecutef", "a", "b", "c", "d", "e", "f", "g"); 97 EXPECT_TRUE(dStricmp(returnValue, "a b c d e f g ") == 0) << 98 "All values should be printed in the correct order"; 99 100 returnValue = Con::executef("testExecutef", "a", "b", "c", "d", "e", "f", "g", "h"); 101 EXPECT_TRUE(dStricmp(returnValue, "a b c d e f g h ") == 0) << 102 "All values should be printed in the correct order"; 103 104 returnValue = Con::executef("testExecutef", "a", "b", "c", "d", "e", "f", "g", "h", "i"); 105 EXPECT_TRUE(dStricmp(returnValue, "a b c d e f g h i ") == 0) << 106 "All values should be printed in the correct order"; 107 108 returnValue = Con::executef("testExecutef", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j"); 109 EXPECT_TRUE(dStricmp(returnValue, "a b c d e f g h i j ") == 0) << 110 "All values should be printed in the correct order"; 111 112 // Test type conversions with and without SimObject... 113 114 // Integer 115 returnValue = Con::executef(testObject, "testThisFunction", 123); 116 EXPECT_TRUE(dStricmp(returnValue, "123 ") == 0) << 117 "Integer should be converted"; 118 returnValue = Con::executef("testExecutef", 123); 119 EXPECT_TRUE(dStricmp(returnValue, "123 ") == 0) << 120 "Integer should be converted"; 121 122 // Float 123 returnValue = Con::executef(testObject, "testThisFunction", (F32)123.4); 124 EXPECT_TRUE(dStricmp(returnValue, "123.4 ") == 0) << 125 "Float should be converted"; 126 returnValue = Con::executef("testExecutef", (F32)123.4); 127 EXPECT_TRUE(dStricmp(returnValue, "123.4 ") == 0) << 128 "Float should be converted"; 129 130 // SimObject 131 dSprintf(buffer, sizeof(buffer), "%i ", testObject->getId()); 132 returnValue = Con::executef(testObject, "testThisFunction", testObject); 133 EXPECT_TRUE(dStricmp(returnValue, buffer) == 0) << 134 "SimObject should be converted"; 135 dSprintf(buffer, sizeof(buffer), "%i ", testObject->getId()); 136 returnValue = Con::executef("testExecutef", testObject); 137 EXPECT_TRUE(dStricmp(returnValue, buffer) == 0) << 138 "SimObject should be converted"; 139 140 // Point3F 141 Point3F point(1,2,3); 142 returnValue = Con::executef(testObject, "testThisFunction", point); 143 EXPECT_TRUE(dStricmp(returnValue, "1 2 3 ") == 0) << 144 "Point3F should be converted"; 145 returnValue = Con::executef("testExecutef", point); 146 EXPECT_TRUE(dStricmp(returnValue, "1 2 3 ") == 0) << 147 "Point3F should be converted"; 148 149 // Finally test the function arg offset. This should be consistently 0 after each call 150 151 EXPECT_TRUE(STR.mFunctionOffset == 0) << 152 "Function offset should be 0"; 153 154 const char *floatArg = Con::getFloatArg(1.23); 155 EXPECT_TRUE(STR.mFunctionOffset > 0) << 156 "Function offset should not be 0"; 157 158 Con::executef("testExecutef", floatArg); 159 160 EXPECT_TRUE(STR.mFunctionOffset == 0) << 161 "Function offset should be 0"; 162 163 floatArg = Con::getFloatArg(1.23); 164 EXPECT_TRUE(STR.mFunctionOffset > 0) << 165 "Function offset should not be 0"; 166 167 Con::executef("testImaginaryFunction_", floatArg); 168 169 EXPECT_TRUE(STR.mFunctionOffset == 0) << 170 "Function offset should be 0"; 171} 172 173TEST(Con, execute) 174{ 175 Con::evaluate("if (isObject(TestConExec)) {\r\nTestConExec.delete();\r\n}\r\nfunction testScriptExecuteFunction(%a,%b) {return %a SPC %b;}\nfunction TestConExec::testScriptExecuteFunction(%this, %a,%b) {return %a SPC %b;}new ScriptObject(TestConExec);\r\n", false, "testExecute"); 176 177 U32 startStackPos = CSTK.mStackPos; 178 U32 startStringStackPos = STR.mStart; 179 U32 startStackFrame = CSTK.mFrame; 180 181 SimObject *testObject = NULL; 182 Sim::findObject("TestConExec", testObject); 183 184 EXPECT_TRUE(testObject != NULL) 185 << "TestConExec object should exist"; 186 187 // const char* versions of execute should maintain stack 188 const char *argv[] = {"testScriptExecuteFunction", "1", "2"}; 189 const char *argvObject[] = {"testScriptExecuteFunction", "", "1", "2"}; 190 const char *returnValue = Con::execute(3, argv); 191 192 EXPECT_TRUE(dStricmp(returnValue, "1 2") == 0) << 193 "execute should return 1 2"; 194 195 EXPECT_TRUE(CSTK.mStackPos == startStackPos) << 196 "execute should restore stack"; 197 198 returnValue = Con::execute(testObject, 4, argvObject); 199 200 EXPECT_TRUE(dStricmp(returnValue, "1 2") == 0) << 201 "execute should return 1 2"; 202 203 EXPECT_TRUE(CSTK.mStackPos == startStackPos) << 204 "execute should restore stack"; 205 206 // ConsoleValueRef versions of execute should not restore stack 207 CSTK.pushFrame(); 208 STR.pushFrame(); 209 210 ConsoleValue valueArg[4]; 211 ConsoleValueRef refArg[4]; 212 ConsoleValue valueArgObject[4]; 213 ConsoleValueRef refArgObject[4]; 214 for (U32 i=0; i<4; i++) 215 { 216 refArg[i].value = &valueArg[i]; 217 refArgObject[i].value = &valueArgObject[i]; 218 valueArgObject[i].init(); 219 valueArg[i].init(); 220 } 221 222 refArg[0] = "testScriptExecuteFunction"; 223 refArg[1] = "1"; 224 refArg[2] = "2"; 225 226 refArgObject[0] = "testScriptExecuteFunction"; 227 refArgObject[2] = "1"; 228 refArgObject[3] = "2"; 229 230 returnValue = Con::execute(3, refArg); 231 232 EXPECT_TRUE(dStricmp(returnValue, "1 2") == 0) << 233 "execute should return 1 2"; 234 235 EXPECT_TRUE(CSTK.mStackPos == startStackPos) << 236 "execute should restore stack"; 237 238 CSTK.popFrame(); 239 STR.popFrame(); 240 241 CSTK.pushFrame(); 242 STR.pushFrame(); 243 244 returnValue = Con::execute(testObject, 4, refArgObject); 245 246 EXPECT_TRUE(dStricmp(returnValue, "1 2") == 0) << 247 "execute should return 1 2"; 248 249 EXPECT_TRUE(CSTK.mStackPos == startStackPos) << 250 "execute should restore stack"; 251 252 CSTK.popFrame(); 253 STR.popFrame(); 254} 255 256static U32 gConsoleStackFrame = 0; 257 258ConsoleFunction(testConsoleStackFrame, S32, 1, 1, "") 259{ 260 gConsoleStackFrame = CSTK.mFrame; 261 return (U32)Con::executef("testScriptEvalFunction"); // execute a sub function which manipulates the stack 262} 263 264TEST(Con, evaluate) 265{ 266 U32 startStackPos = CSTK.mStackPos; 267 U32 startStringStackPos = STR.mStart; 268 S32 returnValue = Con::evaluate("function testScriptEvalFunction() {return \"1\"@\"2\"@\"3\";}\nreturn testConsoleStackFrame();", false, "testEvaluate"); 269 U32 frame = CSTK.mFrame; 270 271 EXPECT_TRUE(returnValue == 123) << 272 "Evaluate should return 123"; 273 274 EXPECT_TRUE(gConsoleStackFrame == (frame+2)) << 275 "Console stack frame inside function should be +2"; 276 277 EXPECT_TRUE(CSTK.mFrame == frame) << 278 "Console stack frame outside function should be the same as before"; 279 280 EXPECT_TRUE(STR.mStart == startStringStackPos) << 281 "Console string stack should not be changed"; 282 283 EXPECT_TRUE(CSTK.mStackPos == startStackPos) << 284 "Console stack should not be changed"; 285 286} 287 288#endif 289