00001
00006
00007
00008
00009
00010
00011
00012
00013 #include <cstdarg>
00014 #include <iostream>
00015 #include <iomanip>
00016 #include <string>
00017 #include <sstream>
00018 #include <memory>
00019 #include <map>
00020 #include <vector>
00021 #include <set>
00022 #include <dae.h>
00023 #include <dom/domConstants.h>
00024 #include <dom/domCOLLADA.h>
00025 #include <dom/domProfile_common.h>
00026 #include <dae/daeSIDResolver.h>
00027 #include <dom/domInstance_controller.h>
00028 #include <dae/domAny.h>
00029 #include <dae/daeErrorHandler.h>
00030 #include <dae/daeUtils.h>
00031 #include <dom/domImage.h>
00032 #include <modules/stdErrPlugin.h>
00033 #include <dom/domEllipsoid.h>
00034 #include <dom/domInput_global.h>
00035 #include <dom/domAsset.h>
00036 #include <dom/domLimits_sub.h>
00037 #include "domTest.h"
00038
00039
00040 #if defined _MSC_VER && defined _DEBUG
00041 #define _CRTDBG_MAP_ALLOC
00042 #include <stdlib.h>
00043 #include <crtdbg.h>
00044 #endif
00045
00046 namespace fs = boost::filesystem;
00047 using namespace std;
00048 using namespace cdom;
00049
00050 float toFloat(const string& s) {
00051 istringstream stream(s);
00052 float f;
00053 stream >> f;
00054 return f;
00055 }
00056
00057 #define CheckResultWithMsg(val, msg) \
00058 if (!(val)) { \
00059 return testResult(false, __FILE__, __LINE__, msg); \
00060 }
00061
00062 #define CompareDocs(dae, file1, file2) \
00063 { \
00064 domCOLLADA *root1 = (dae).getRoot(file1), \
00065 *root2 = (dae).getRoot(file2); \
00066 daeElement::compareResult result = daeElement::compareWithFullResult(*root1, *root2); \
00067 if (result.compareValue != 0) { \
00068 return testResult(false, __FILE__, __LINE__, result.format()); \
00069 } \
00070 }
00071
00072 map<string, domTest*>& registeredTests() {
00073 static map<string, domTest*> tests;
00074 return tests;
00075 }
00076
00077 fs::path& dataPath() {
00078 static fs::path dataPath_;
00079 return dataPath_;
00080 }
00081
00082 fs::path& tmpPath() {
00083 static fs::path tmpPath_;
00084 return tmpPath_;
00085 }
00086
00087 #define RunTest(testName) \
00088 { \
00089 map<string, domTest*>::iterator iter = registeredTests().find(#testName); \
00090 CheckResult(iter != registeredTests().end()); \
00091 CheckResult(iter->second->run()); \
00092 }
00093
00094
00095 string lookupTestFile(const string& fileName) {
00096 return (dataPath() / fileName).native_file_string();
00097 }
00098
00099 string getTmpFile(const string& fileName) {
00100 return (tmpPath() / fileName).native_file_string();
00101 }
00102
00103
00104 string chopWS(const string& s) {
00105 string ws = " \t\n\r";
00106 size_t beginPos = s.find_first_not_of(ws);
00107 size_t endPos = s.find_last_not_of(ws);
00108 if (beginPos == string::npos)
00109 return "";
00110 return s.substr(beginPos, endPos-beginPos+1);
00111 }
00112
00113 DefineTest(chopWS) {
00114 CheckResult(chopWS("") == "");
00115 CheckResult(chopWS("") == "");
00116 CheckResult(chopWS(" ") == "");
00117 CheckResult(chopWS(" test") == "test");
00118 CheckResult(chopWS("test ") == "test");
00119 CheckResult(chopWS(" test ") == "test");
00120 CheckResult(chopWS(" a ") == "a");
00121 return testResult(true);
00122 }
00123
00124
00125 DefineTest(utils) {
00126 CheckResult(replace("abc", "abc", "def") == "def");
00127 CheckResult(replace("abc", "a", "1") == "1bc");
00128 CheckResult(replace("abc", "c", "1") == "ab1");
00129 CheckResult(replace("abc123", "bc12", "b") == "ab3");
00130 CheckResult(replace("abracadabra", "a", "") == "brcdbr");
00131
00132 CheckResult(tokenize("1|2|3|4", "|") == makeStringList("1", "2", "3", "4", 0));
00133 CheckResult(tokenize("|1|", "|") == makeStringList("1", 0));
00134 CheckResult(tokenize("1|||2||3|", "|") == makeStringList("1", "2", "3", 0));
00135 CheckResult(tokenize("1|||2||3|", "|", true) ==
00136 makeStringList("1", "|", "|", "|", "2", "|", "|", "3", "|", 0));
00137 CheckResult(tokenize("this/is some#text", "/#", true) ==
00138 makeStringList("this", "/", "is some", "#", "text", 0));
00139 CheckResult(tokenize("this/is some#text", "/# ", false) ==
00140 makeStringList("this", "is", "some", "text", 0));
00141
00142 CheckResult(toString(5) == "5");
00143 CheckResult(toFloat(toString(4.0f)) == 4.0f);
00144
00145 return testResult(true);
00146 }
00147
00148
00149 DefineTest(elementAddFunctions) {
00150 DAE dae;
00151 const char* uri = "file.dae";
00152
00153
00154 daeElement* root = dae.add(uri);
00155 CheckResult(root);
00156 daeElement* geomLib = root->add("library_geometries");
00157 CheckResult(geomLib);
00158 daeElement* effectLib = root->add("library_effects", 0);
00159 CheckResult(effectLib && root->getChildren()[0] == effectLib);
00160 root->addBefore(geomLib, effectLib);
00161 CheckResult(root->getChildren()[0] == geomLib);
00162 CheckResult(root->removeChildElement(geomLib));
00163 root->addAfter(geomLib, effectLib);
00164 CheckResult(root->getChildren()[1] == geomLib);
00165 CheckResult(root->removeChildElement(geomLib));
00166 root->add(geomLib);
00167 CheckResult(root->getDescendant("library_geometries"));
00168 daeElement* instanceGeom = root->add("library_nodes node instance_geometry");
00169 CheckResult(instanceGeom && instanceGeom->typeID() == domInstance_geometry::ID());
00170 CheckResult(root->add("library_materials material blah") == NULL);
00171 CheckResult(root->getDescendant("library_materials") == NULL);
00172
00173
00174 dae.close(uri);
00175 root = dae.add(uri);
00176 CheckResult(root);
00177 geomLib = root->createAndPlace("library_geometries");
00178 CheckResult(geomLib);
00179 effectLib = root->createAndPlaceAt(0, "library_effects");
00180 CheckResult(effectLib && root->getChildren()[0] == effectLib);
00181 root->placeElementBefore(effectLib, geomLib);
00182 CheckResult(root->getChildren()[0] == geomLib);
00183 CheckResult(root->removeChildElement(geomLib));
00184 root->placeElementAfter(effectLib, geomLib);
00185 CheckResult(root->getChildren()[1] == geomLib);
00186 CheckResult(root->removeChildElement(geomLib));
00187 root->placeElement(geomLib);
00188 CheckResult(root->getDescendant("library_geometries"));
00189
00190 return testResult(true);
00191 }
00192
00193
00194 DefineTest(loadClipPlane) {
00195 DAE dae;
00196 CheckResult(dae.open(lookupTestFile("clipPlane.dae")));
00197 return testResult(true);
00198 }
00199
00200
00201 DefineTest(renderStates) {
00202 string memoryUri = "renderStates_create.dae";
00203 string file = getTmpFile("renderStates.dae");
00204
00205 DAE dae;
00206 daeElement* root = dae.add(memoryUri);
00207 CheckResult(root);
00208 daeElement* pass = root->add("library_effects effect profile_CG technique pass");
00209 CheckResult(pass);
00210
00211 domCg_pass::domEvaluate* evaluate = daeSafeCast<domCg_pass::domEvaluate>(pass->add("evaluate"));
00212 evaluate->add("color_clear")->setCharData("0 0 0 0");
00213
00214 domCg_pass::domStates* states = daeSafeCast<domCg_pass::domStates>(pass->add("states"));
00215 states->add("depth_mask")->setAttribute("value", "true");
00216 states->add("cull_face_enable")->setAttribute("value", "true");
00217 states->add("blend_enable")->setAttribute("value", "true");
00218 states->add("blend_func_separate")->setAttribute("value", "true");
00219 states->add("cull_face")->setAttribute("value", "FRONT");
00220 states->add("polygon_offset_fill_enable")->setAttribute("value", "true");
00221
00222
00223 CheckResult(dae.writeTo(memoryUri, file));
00224
00225
00226 root = dae.open(file);
00227 CheckResult(root);
00228 CompareDocs(dae, memoryUri, file);
00229
00230
00231 CheckResult(root->getDescendant("depth_mask")->isAttributeSet("value") == false);
00232 CheckResult(root->getDescendant("color_clear")->getCharData() != "");
00233 CheckResult(root->getDescendant("polygon_offset_fill_enable")->isAttributeSet("value"));
00234
00235 return testResult(true);
00236 }
00237
00238
00239 DefineTest(compareElements) {
00240 string memoryUri = "file.dae";
00241
00242 DAE dae;
00243 daeElement* root = dae.add(memoryUri);
00244 CheckResult(root);
00245
00246 daeElement* technique = root->add("extra technique");
00247 CheckResult(technique);
00248
00249
00250 daeElement* elt1 = technique->add("elt");
00251 daeElement* elt2 = technique->add("elt");
00252 CheckResult(elt1 && elt2);
00253
00254 elt1->setAttribute("attr1", "val1");
00255 elt1->setAttribute("attr2", "val2");
00256 elt2->setAttribute("attr2", "val2");
00257 elt2->setAttribute("attr1", "val1");
00258
00259 CheckResult(daeElement::compare(*elt1, *elt2) == 0);
00260
00261
00262 elt2->setAttribute("attr3", "val3");
00263 CheckResult(daeElement::compare(*elt1, *elt2) < 0);
00264
00265 return testResult(true);
00266 }
00267
00268
00269 DefineTest(writeCamera) {
00270 string memoryUri = "camera_create.dae";
00271 string file = getTmpFile("camera.dae");
00272
00273 DAE dae;
00274 daeElement* elt = dae.add(memoryUri);
00275 CheckResult(elt);
00276 elt = elt->add("library_cameras camera optics technique_common perspective xfov");
00277 CheckResult(elt);
00278 elt->setCharData("1.0");
00279
00280 CheckResult(dae.writeTo(memoryUri, file));
00281 domCOLLADA* root = dae.open(file);
00282 CheckResult(root);
00283 CompareDocs(dae, memoryUri, file);
00284 CheckResult(toFloat(root->getDescendant("xfov")->getCharData()) == 1.0f);
00285
00286 return testResult(true);
00287 }
00288
00289
00290 string getRoundTripFile(const string& name) {
00291 return getTmpFile(fs::basename(fs::path(name)) + "_roundTrip.dae");
00292 }
00293
00294 bool roundTrip(const string& file) {
00295 DAE dae;
00296 if (!dae.open(file))
00297 return false;
00298 return dae.writeTo(file, getRoundTripFile(file));
00299 }
00300
00301 DefineTest(roundTripSeymour) {
00302 string file1 = lookupTestFile("Seymour.dae"),
00303 file2 = getRoundTripFile(file1);
00304 DAE dae;
00305 CheckResult(dae.open(file1));
00306 CheckResult(dae.writeTo(file1, file2));
00307 CheckResult(dae.open(file2));
00308 CompareDocs(dae, file1, file2);
00309 return testResult(true);
00310 }
00311
00312
00313 DefineTest(rawSupport) {
00314 string seymourOrig = lookupTestFile("Seymour.dae"),
00315 seymourRaw = getTmpFile("Seymour_raw.dae");
00316 DAE dae;
00317
00318 CheckResult(dae.open(seymourOrig));
00319 dae.getIOPlugin()->setOption("saveRawBinary", "true");
00320 CheckResult(dae.writeTo(seymourOrig, seymourRaw));
00321 dae.clear();
00322
00323
00324 CheckResult(fs::exists(fs::path(seymourRaw + ".raw")));
00325
00326 daeElement* seymourRawRoot = dae.open(seymourRaw);
00327 CheckResult(seymourRawRoot);
00328 CheckResult(dae.getDatabase()->idLookup("l_hip_rotateY_l_hip_rotateY_ANGLE-input",
00329 seymourRawRoot->getDocument()));
00330 domAccessor* accessor = dae.getDatabase()->typeLookup<domAccessor>().at(0);
00331 daeURI& uri = accessor->getSource();
00332 CheckResult(uri.pathExt().find(".raw") != string::npos);
00333 CheckResult(uri.getElement());
00334
00335 return testResult(true);
00336 }
00337
00338 DefineTest(extraTypeTest) {
00339 DAE dae;
00340 string file = lookupTestFile("extraTest.dae");
00341 daeElement* root = dae.open(file);
00342 CheckResult(root);
00343
00344 daeElement *technique = root->getDescendant("technique"),
00345 *expectedTypesElt = root->getDescendant("expected_types");
00346 CheckResult(technique && expectedTypesElt);
00347
00348
00349 istringstream expectedTypesStream(expectedTypesElt->getCharData());
00350 vector<string> expectedTypes;
00351 string tmp;
00352 while (expectedTypesStream >> tmp)
00353 expectedTypes.push_back(tmp);
00354
00355 daeElementRefArray elements = technique->getChildren();
00356
00357
00358 CheckResult(expectedTypes.size() == elements.getCount()-1);
00359 for (size_t i = 0; i < elements.getCount()-1; i++) {
00360 ostringstream msg;
00361 msg << "Actual type - " << elements[i]->getTypeName() << ", Expected type - " << expectedTypes[i];
00362 CheckResultWithMsg(expectedTypes[i] == elements[i]->getTypeName(), msg.str());
00363 }
00364
00365 return testResult(true);
00366 }
00367
00368 #if defined(TINYXML)
00369 #include <dae/daeTinyXMLPlugin.h>
00370 DefineTest(tinyXmlLoad) {
00371 string seymourOrig = lookupTestFile("Seymour.dae"),
00372 seymourTinyXml = getTmpFile("Seymour_tinyXml.dae");
00373
00374
00375
00376 DAE dae;
00377 CheckResult(dae.open(seymourOrig));
00378 auto_ptr<daeTinyXMLPlugin> tinyXmlPlugin(new daeTinyXMLPlugin);
00379 dae.setIOPlugin(tinyXmlPlugin.get());
00380 CheckResult(dae.writeTo(seymourOrig, seymourTinyXml));
00381 CheckResult(dae.open(seymourTinyXml));
00382 CompareDocs(dae, seymourOrig, seymourTinyXml);
00383
00384 return testResult(true);
00385 }
00386 #endif
00387
00388
00389 string resolveResultToString(const string& sidRef, daeElement* refElt) {
00390 daeSidRef::resolveData rd = daeSidRef(sidRef, refElt).resolve();
00391 if (rd.scalar) return "scalar";
00392 else if (rd.array) return "array";
00393 else if (rd.elt) return "element";
00394 else return "failed";
00395 }
00396
00397 DefineTest(sidResolve) {
00398 DAE dae;
00399 daeElement* root = dae.open(lookupTestFile("sidResolveTest.dae"));
00400 CheckResult(root);
00401 daeDatabase& database = *dae.getDatabase();
00402 daeDocument* doc = root->getDocument();
00403
00404 daeElement *effect = database.idLookup("myEffect", doc),
00405 *effectExtra = database.idLookup("effectExtra", doc);
00406 CheckResult(effect && effectExtra);
00407
00408 istringstream stream(effectExtra->getCharData());
00409 string sidRef, expectedResult;
00410 while (stream >> sidRef >> expectedResult) {
00411 string result = resolveResultToString(sidRef, effect);
00412 CheckResultWithMsg(result == expectedResult,
00413 string("sid ref=") + sidRef + ", expectedResult=" + expectedResult + ", actualResult=" + result);
00414 }
00415
00416 daeElement* nodeSidRefExtra = database.idLookup("nodeSidRefExtra", doc);
00417 CheckResult(nodeSidRefExtra);
00418
00419 stream.clear();
00420 stream.str(nodeSidRefExtra->getCharData());
00421 while (stream >> sidRef >> expectedResult) {
00422 string result = resolveResultToString(sidRef, root);
00423 CheckResultWithMsg(result == expectedResult,
00424 string("sid ref=") + sidRef + ", expectedResult=" + expectedResult + ", actualResult=" + result);
00425 }
00426
00427 nodeSidRefExtra = database.idLookup("nodeSidRefExtra2", doc);
00428 CheckResult(nodeSidRefExtra);
00429
00430 stream.clear();
00431 stream.str(nodeSidRefExtra->getCharData());
00432 while (stream >> sidRef >> expectedResult) {
00433 daeElement* elt = daeSidRef(sidRef, root).resolve().elt;
00434 string result = elt ? elt->getAttribute("id") : "failed";
00435 CheckResultWithMsg(result == expectedResult,
00436 string("sid ref=") + sidRef + ", expectedResult=" + expectedResult + ", actualResult=" + result);
00437 }
00438
00439 nodeSidRefExtra = database.idLookup("nodeSidRefExtra3", doc);
00440 CheckResult(nodeSidRefExtra);
00441
00442 stream.clear();
00443 stream.str(nodeSidRefExtra->getCharData());
00444 string profile;
00445 while (stream >> sidRef >> profile >> expectedResult) {
00446 daeElement* elt = daeSidRef(sidRef, root, profile).resolve().elt;
00447 string result = elt ? elt->getAttribute("id") : "failed";
00448 CheckResultWithMsg(result == expectedResult,
00449 string("sid ref=") + sidRef + ", profile=" + profile +
00450 ", expectedResult=" + expectedResult + ", actualResult=" + result);
00451 }
00452
00453
00454 return testResult(true);
00455 }
00456
00457 daeElement* findChildByName(daeElement* el, daeString name) {
00458 if (!el)
00459 return 0;
00460
00461 daeElementRefArray children = el->getChildren();
00462 for (size_t i = 0; i < children.getCount(); i++)
00463 if (strcmp(children[i]->getElementName(), name) == 0)
00464 return children[i];
00465
00466 return 0;
00467 }
00468
00469 daeElement* findAncestorByType(daeElement* el, daeString type) {
00470 if (el == 0 || strcmp(el->getTypeName(), type) == 0)
00471 return el;
00472 return findAncestorByType(el->getParentElement(), type);
00473 }
00474
00475 daeElement* resolveID(daeString id, daeDocument& document) {
00476 return document.getDatabase()->idLookup(id, &document);
00477 }
00478
00479 daeElement* resolveSid(const string& sid, daeElement& refElt) {
00480 return daeSidRef(sid, &refElt).resolve().elt;
00481 }
00482
00483 string getCharData(daeElement* el) {
00484 return el ? el->getCharData() : "";
00485 }
00486
00487 daeURI* getTextureUri(const string& samplerSid, daeElement& effect) {
00488 daeElement* sampler = findChildByName(resolveSid(samplerSid, effect), "sampler2D");
00489 daeElement* instanceImage = findChildByName(sampler, "instance_image");
00490 xsAnyURI imageUrl = daeSafeCast<domInstance_image>(instanceImage)->getUrl();
00491 domImage* image = daeSafeCast<domImage>(imageUrl.getElement());
00492 if (image && image->getInit_from() && image->getInit_from()->getRef())
00493 return &image->getInit_from()->getRef()->getValue();
00494 return 0;
00495 }
00496
00497 DefineTest(getTexture) {
00498 DAE dae;
00499 CheckResult(dae.open(lookupTestFile("Seymour.dae")));
00500
00501 daeElement* effect = dae.getDatabase()->idLookup("face-fx").at(0);
00502 daeElement* texture = effect->getDescendant("texture");
00503 CheckResult(texture);
00504
00505 daeURI* uri = getTextureUri(texture->getAttribute("texture"), *effect);
00506 CheckResult(uri);
00507 CheckResult(uri->pathFile() == "boy_10.tga");
00508
00509 return testResult(true);
00510 }
00511
00512
00513 DefineTest(removeElement) {
00514 DAE dae;
00515 daeElement* collada = dae.open(lookupTestFile("Seymour.dae"));
00516 CheckResult(collada);
00517
00518 daeElement *animLib = dae.getDatabase()->typeLookup(domLibrary_animations::ID()).at(0),
00519 *asset = dae.getDatabase()->typeLookup(domAsset::ID()).at(0);
00520
00521 collada->removeChildElement(asset);
00522 daeElement::removeFromParent(animLib);
00523
00524 CheckResult(collada->getDescendant("asset") == NULL);
00525 CheckResult(collada->getDescendant("library_animations") == NULL);
00526
00527 CheckResult(dae.writeTo(lookupTestFile("Seymour.dae"),
00528 getTmpFile("Seymour_removeElements.dae")));
00529 return testResult(true);
00530 }
00531
00532 void nameArraySet(domList_of_names& names, size_t index, const char* name) {
00533 *(daeStringRef*)&names[index] = name;
00534 }
00535
00536 void nameArrayAppend(domList_of_names& names, const char* name) {
00537 names.append(NULL);
00538 nameArraySet(names, names.getCount()-1, name);
00539 }
00540
00541 DefineTest(nameArray) {
00542 domList_of_names names;
00543 for (int i = 0; i < 10; i++)
00544 nameArrayAppend(names, (string("name") + toString(i)).c_str());
00545 for (int i = 0; i < 10; i++) {
00546 CheckResult(string("name") + toString(i) == string(names[i]));
00547 }
00548
00549 return testResult(true);
00550 }
00551
00552 daeTArray<int> makeIntArray(int i, ...) {
00553 va_list args;
00554 va_start(args, i);
00555 daeTArray<int> result;
00556 while (i != INT_MAX) {
00557 result.append(i);
00558 i = va_arg(args, int);
00559 }
00560 va_end(args);
00561 return result;
00562 }
00563
00564 DefineTest(arrayOps) {
00565 daeTArray<int> zeroToFour = makeIntArray(0, 1, 2, 3, 4, INT_MAX);
00566
00567
00568 daeTArray<int> array = zeroToFour;
00569 array.removeIndex(2);
00570 CheckResult(array == makeIntArray(0, 1, 3, 4, INT_MAX));
00571
00572
00573 array = zeroToFour;
00574 array.insert(3, 5, 9);
00575 CheckResult(array == makeIntArray(0, 1, 2, 9, 9, 9, 9, 9, 3, 4, INT_MAX));
00576
00577
00578 array = zeroToFour;
00579 array.insert(7, 2, 5);
00580 CheckResult(array == makeIntArray(0, 1, 2, 3, 4, 5, 5, 5, 5, INT_MAX));
00581
00582 return testResult(true);
00583 }
00584
00585
00586 void printMemoryToStringResult(daeAtomicType& type, daeMemoryRef value) {
00587 ostringstream buffer;
00588 type.memoryToString(value, buffer);
00589 cout << buffer.str() << endl;
00590 }
00591
00592 string toString(daeAtomicType& type, daeMemoryRef value) {
00593 ostringstream buffer;
00594 type.memoryToString(value, buffer);
00595 return buffer.str();
00596 }
00597
00598 DefineTest(atomicTypeOps) {
00599 DAE dae;
00600 daeUIntType UIntType(dae);
00601 daeIntType IntType(dae);
00602 daeLongType LongType(dae);
00603 daeShortType ShortType(dae);
00604 daeULongType ULongType(dae);
00605 daeFloatType FloatType(dae);
00606 daeDoubleType DoubleType(dae);
00607 daeStringRefType StringRefType(dae);
00608 daeElementRefType ElementRefType(dae);
00609 daeEnumType EnumType(dae);
00610 daeResolverType ResolverType(dae);
00611 daeIDResolverType IDResolverType(dae);
00612 daeBoolType BoolType(dae);
00613 daeTokenType TokenType(dae);
00614
00615 EnumType._values = new daeEnumArray;
00616 EnumType._strings = new daeStringRefArray;
00617 EnumType._values->append(0);
00618 EnumType._strings->append("myEnumValue");
00619
00620 daeUInt UInt(1);
00621 daeInt Int(2);
00622 daeLong Long(3);
00623 daeShort Short(4);
00624 daeULong ULong(5);
00625 daeFloat Float(6.123f);
00626 daeDouble Double(7.456);
00627 daeStringRef StringRef("StringRef");
00628
00629 daeEnum Enum(0);
00630 daeURI uri(dae, "http://www.example.com/#fragment");
00631 daeIDRef IDRef("sampleID");
00632 daeBool Bool(false);
00633 daeStringRef Token("token");
00634
00635
00636 CheckResult(toString(UIntType, (daeMemoryRef)&UInt) == "1");
00637 CheckResult(toString(IntType, (daeMemoryRef)&Int) == "2");
00638 CheckResult(toString(LongType, (daeMemoryRef)&Long) == "3");
00639 CheckResult(toString(ShortType, (daeMemoryRef)&Short) == "4");
00640 CheckResult(toString(ULongType, (daeMemoryRef)&ULong) == "5");
00641 CheckResult(toString(FloatType, (daeMemoryRef)&Float) == "6.123");
00642 CheckResult(toString(DoubleType, (daeMemoryRef)&Double) == "7.456");
00643 CheckResult(toString(StringRefType, (daeMemoryRef)&StringRef) == "StringRef");
00644
00645 CheckResult(toString(EnumType, (daeMemoryRef)&Enum) == "myEnumValue");
00646 CheckResult(toString(ResolverType, (daeMemoryRef)&uri) == "http://www.example.com/#fragment");
00647 CheckResult(toString(IDResolverType, (daeMemoryRef)&IDRef) == "sampleID");
00648 CheckResult(toString(BoolType, (daeMemoryRef)&Bool) == "false");
00649 CheckResult(toString(TokenType, (daeMemoryRef)&Token) == "token");
00650
00651 return testResult(true);
00652 }
00653
00654
00655 DefineTest(clone) {
00656 DAE dae;
00657 CheckResult(dae.open(lookupTestFile("Seymour.dae")));
00658
00659 daeElement* el = dae.getDatabase()->idLookup("l_ulna").at(0);
00660 daeElementRef clone = el->clone("-foo", "-bar");
00661 el->getParentElement()->placeElement(clone);
00662
00663 CheckResult(dae.writeTo(lookupTestFile("Seymour.dae"), getTmpFile("cloneTest.dae")));
00664
00665 return testResult(true);
00666 }
00667
00668
00669 DefineTest(genericOps) {
00670 string file = lookupTestFile("cube.dae");
00671 DAE dae;
00672 CheckResult(dae.open(file));
00673 daeDatabase& database = *dae.getDatabase();
00674
00675
00676 daeElement* el = database.idLookup("box-lib-positions-array").at(0);
00677
00678 CheckResult(el->hasAttribute("digits"));
00679 CheckResult(el->getAttribute("count") == "24");
00680 CheckResult(el->setAttribute("blah", "hey") == false);
00681 CheckResult(el->setAttribute("magnitude", "30"));
00682
00683 el = database.idLookup("Blue-fx").at(0);
00684 CheckResult(el->hasAttribute("name"));
00685 CheckResult(el->isAttributeSet("name") == false);
00686 CheckResult(el->isAttributeSet("hello") == false);
00687
00688
00689 el = database.typeLookup(domAsset::domUp_axis::ID()).at(0);
00690
00691 CheckResult(el->getCharData() == "Y_UP");
00692 el->setCharData("X_UP");
00693
00694 el = database.idLookup("PerspCamera").at(0);
00695 CheckResult(!el->hasCharData());
00696
00697
00698 el = database.idLookup("my_test_element").at(0);
00699 daeElementRef clone = el->clone("-clone", "-clone");
00700
00701 CheckResult(el->getAttribute("attr1") == "value1" &&
00702 el->getAttribute("attr2") == "value2");
00703 CheckResult(el->setAttribute("attr1", "value_1"));
00704 CheckResult(el->setAttribute("attr3", "value3"));
00705
00706 CheckResult(chopWS(el->getCharData()) == "this is some text");
00707 el->setCharData("reset text");
00708
00709
00710 el->getParentElement()->placeElementAfter(el, clone);
00711 domAny* any = (domAny*)clone.cast();
00712 CheckResult(any);
00713 CheckResult(any->getAttributeCount() == 3);
00714 CheckResult(string(any->getAttributeName(0)) == "id");
00715 CheckResult(string(any->getAttributeValue(1)) == "value1");
00716 CheckResult(chopWS(any->getValue()) == "this is some text");
00717 any->setValue("reset text 2");
00718
00719
00720 for (size_t i = 0; i < 50; i++) {
00721 ostringstream name, value;
00722 name << "attr" << static_cast<unsigned int>(i);
00723 value << "value" << static_cast<unsigned int>(i);
00724 any->setAttribute(name.str().c_str(), value.str().c_str());
00725 }
00726
00727 CheckResult(dae.writeTo(file, getTmpFile(fs::basename(fs::path(file)) + "_genericOps.dae")));
00728
00729 return testResult(true);
00730 }
00731
00732
00733 daeArray* getSkewArray(daeElement* node, const string& sid) {
00734 if (!node)
00735 return NULL;
00736
00737 daeElement* skew = resolveSid(sid, *node);
00738 if (!skew || skew->getElementType() != COLLADA_TYPE::SKEW)
00739 return NULL;
00740
00741 return (daeArray*)skew->getCharDataObject()->get(skew);
00742 }
00743
00744 DefineTest(badSkew) {
00745 DAE dae;
00746 CheckResult(dae.open(lookupTestFile("badSkew.dae")));
00747
00748 daeElement* node = dae.getDatabase()->idLookup("my-node").at(0);
00749
00750 daeArray* array1 = getSkewArray(node, "tooFew");
00751 daeArray* array2 = getSkewArray(node, "justRight");
00752 daeArray* array3 = getSkewArray(node, "tooMany");
00753 CheckResult(array1 && array2 && array3);
00754
00755 CheckResult(array1->getCount() == 4);
00756 CheckResult(array2->getCount() == 7);
00757 CheckResult(array3->getCount() == 11);
00758
00759 return testResult(true);
00760 }
00761
00762
00763 DefineTest(stringTable) {
00764 daeStringTable stringTable;
00765 stringTable.allocString("hello");
00766
00767 stringTable.clear();
00768 stringTable.allocString("goodbye");
00769 return testResult(true);
00770 }
00771
00772
00773
00774 #if 0
00775 DefineTest(sidResolveSpeed) {
00776 DAE dae;
00777 string file = lookupTestFile("crankarm.dae");
00778 domCOLLADA* root = dae.open(file);
00779 CheckResult(root);
00780
00781 vector<domSIDREF_array*> sidRefArrays = dae.getDatabase()->typeLookup<domSIDREF_array>();
00782 for (size_t i = 0; i < sidRefArrays.size(); i++) {
00783 domListOfNames& sidRefs = sidRefArrays[i]->getValue();
00784 for (size_t j = 0; j < sidRefs.getCount(); j++) {
00785 CheckResult(resolveSid(sidRefs[i], root));
00786 }
00787 }
00788
00789 return testResult(true);
00790 }
00791 #endif
00792
00793
00794 DefineTest(seymourSidResolve) {
00795 DAE dae;
00796 string file = lookupTestFile("Seymour.dae");
00797 CheckResult(dae.open(file));
00798
00799 vector<daeElement*> nodes = dae.getDatabase()->typeLookup(domNode::ID());
00800 for (size_t i = 0; i < nodes.size(); i++) {
00801 daeElementRefArray children = nodes[i]->getChildren();
00802 for (size_t j = 0; j < children.getCount(); j++) {
00803 string sid = children[j]->getAttribute("sid");
00804 if (!sid.empty()) {
00805 CheckResult(daeSidRef(sid, nodes[i]).resolve().elt);
00806 }
00807 }
00808 }
00809
00810 return testResult(true);
00811 }
00812
00813
00814 vector<string> getChildNames(daeElement* elt) {
00815 vector<string> result;
00816 if (!elt)
00817 return result;
00818
00819 daeElementRefArray children = elt->getChildren();
00820 for (size_t i = 0; i < children.getCount(); i++)
00821 result.push_back(children[i]->getElementName());
00822
00823 return result;
00824 }
00825
00826 DefineTest(placeElement) {
00827 DAE dae;
00828 CheckResult(dae.open(lookupTestFile("cube.dae")));
00829
00830 daeElement* node = dae.getDatabase()->idLookup("Box").at(0);
00831
00832 CheckResult(getChildNames(node) == makeStringArray(
00833 "rotate", "rotate", "rotate", "instance_geometry", 0));
00834
00835
00836
00837 node->placeElementAfter(node->getChildren()[0], node->createElement("translate"));
00838 CheckResult(getChildNames(node) == makeStringArray(
00839 "rotate", "translate", "rotate", "rotate", "instance_geometry", 0));
00840
00841 node->placeElementBefore(node->getChildren()[0], node->createElement("scale"));
00842 CheckResult(getChildNames(node) == makeStringArray(
00843 "scale", "rotate", "translate", "rotate", "rotate", "instance_geometry", 0));
00844
00845 return testResult(true);
00846 };
00847
00848
00849 DefineTest(nativePathConversion) {
00850
00851 CheckResult(cdom::nativePathToUri("C:\\myFolder\\myFile.dae", cdom::Windows) == "/C:/myFolder/myFile.dae");
00852 CheckResult(cdom::nativePathToUri("\\myFolder\\myFile.dae", cdom::Windows) == "/myFolder/myFile.dae");
00853 CheckResult(cdom::nativePathToUri("..\\myFolder\\myFile.dae", cdom::Windows) == "../myFolder/myFile.dae");
00854 CheckResult(cdom::nativePathToUri("\\\\otherComputer\\myFile.dae", cdom::Windows) == "//otherComputer/myFile.dae");
00855
00856
00857 CheckResult(cdom::nativePathToUri("/myFolder/myFile.dae", cdom::Posix) == "/myFolder/myFile.dae");
00858 CheckResult(cdom::nativePathToUri("../myFolder/myFile.dae", cdom::Posix) == "../myFolder/myFile.dae");
00859 CheckResult(cdom::nativePathToUri("/my folder/my file.dae", cdom::Posix) == "/my%20folder/my%20file.dae");
00860
00861
00862 CheckResult(cdom::uriToNativePath("../folder/file.dae", cdom::Windows) == "..\\folder\\file.dae");
00863 CheckResult(cdom::uriToNativePath("/C:/folder/file.dae", cdom::Windows) == "C:\\folder\\file.dae");
00864 CheckResult(cdom::uriToNativePath("file:///C:/folder/file.dae", cdom::Windows) == "C:\\folder\\file.dae");
00865 CheckResult(cdom::uriToNativePath("//otherComputer/file.dae", cdom::Windows) == "\\\\otherComputer\\file.dae");
00866 CheckResult(cdom::uriToNativePath("file://///otherComputer/file.dae", cdom::Windows) == "\\\\otherComputer\\file.dae");
00867 CheckResult(cdom::uriToNativePath("http://www.slashdot.org", cdom::Windows) == "");
00868
00869
00870 CheckResult(cdom::uriToNativePath("../folder/file.dae", cdom::Posix) == "../folder/file.dae");
00871 CheckResult(cdom::uriToNativePath("/folder/file.dae", cdom::Posix) == "/folder/file.dae");
00872 CheckResult(cdom::uriToNativePath("file:///folder/file.dae", cdom::Posix) == "/folder/file.dae");
00873 CheckResult(cdom::uriToNativePath("http://www.slashdot.org", cdom::Posix) == "");
00874
00875 return testResult(true);
00876 }
00877
00878
00879 DefineTest(libxmlUriBugWorkaround) {
00880 if (cdom::getSystemType() == cdom::Posix) {
00881
00882 CheckResult(cdom::fixUriForLibxml("file:/folder/file.dae") == "file:///folder/file.dae");
00883 }
00884 else if (cdom::getSystemType() == cdom::Windows) {
00885
00886 CheckResult(cdom::fixUriForLibxml("file:/c:/folder/file.dae") == "file:///c:/folder/file.dae");
00887
00888 CheckResult(cdom::fixUriForLibxml("file://otherComputer/file.dae") == "file://///otherComputer/file.dae");
00889
00890
00891 CheckResult(cdom::fixUriForLibxml("file:/folder/file.dae") == "file:////folder/file.dae");
00892 }
00893
00894 return testResult(true);
00895 }
00896
00897
00898
00899
00900
00901
00902 #if 0
00903 DefineTest(uriOpen) {
00904 DAE dae;
00905 CheckResult(dae.open("file:/c:/models/cube.dae"));
00906 CheckResult(dae.open("/c:/models/cube.dae"));
00907 CheckResult(dae.open("/models/cube.dae"));
00908 CheckResult(dae.open("file:////models/cube.dae"));
00909 CheckResult(dae.open("file://isis/sceard/COLLADA/forsteve/cube.dae"));
00910 CheckResult(dae.open("file://///isis/sceard/COLLADA/forsteve/cube.dae"));
00911 return testResult(true);
00912 }
00913 #endif
00914
00915
00916 DefineTest(uriOps) {
00917 DAE dae;
00918
00919
00920 CheckResult(daeURI(dae, "file:///home/sthomas/file.txt").str() == "file:/home/sthomas/file.txt");
00921 CheckResult(daeURI(dae, "http://www.example.com/path").str() == "http://www.example.com/path");
00922 CheckResult(daeURI(dae, "file:home/sthomas/file.txt").str() == "file:home/sthomas/file.txt");
00923 CheckResult(daeURI(dae, "file:file.txt#fragment", true).str() == "file:file.txt");
00924
00925
00926 {
00927 daeURI base(dae, "file:/home/sthomas/file.txt?baseQuery#baseFragment");
00928 CheckResult(base.str() == "file:/home/sthomas/file.txt?baseQuery#baseFragment");
00929 CheckResult(daeURI(base, "file:/home/sthomas").str() == "file:/home/sthomas");
00930 CheckResult(daeURI(base, "//authority").str() == "file://authority");
00931 CheckResult(daeURI(base, "//authority/path").str() == "file://authority/path");
00932 CheckResult(daeURI(base, "/home/johnny").str() == "file:/home/johnny");
00933 CheckResult(daeURI(base, "myFile.txt").str() == "file:/home/sthomas/myFile.txt");
00934 CheckResult(daeURI(base, "?query#fragment").str() == "file:/home/sthomas/file.txt?query#fragment");
00935 CheckResult(daeURI(base, "?query").str() == "file:/home/sthomas/file.txt?query");
00936 CheckResult(daeURI(base, "").str() == "file:/home/sthomas/file.txt?baseQuery");
00937 CheckResult(daeURI(daeURI(dae, "http://www.example.com/path"), "myFolder/file.txt").str() == "http://www.example.com/myFolder/file.txt");
00938 CheckResult(daeURI(daeURI(dae, "http://www.example.com/path/"), "myFolder/file.txt").str() == "http://www.example.com/path/myFolder/file.txt");
00939 CheckResult(daeURI(daeURI(dae, "http://www.example.com"), "myFolder/file.txt").str() == "http://www.example.com/myFolder/file.txt");
00940 }
00941
00942
00943 {
00944 daeURI base(dae, "http://a/b/c/d;p?q");
00945
00946 CheckResult(daeURI(base, "g:h").str() == "g:h");
00947 CheckResult(daeURI(base, "g").str() == "http://a/b/c/g");
00948 CheckResult(daeURI(base, "./g").str() == "http://a/b/c/g");
00949 CheckResult(daeURI(base, "g/").str() == "http://a/b/c/g/");
00950 CheckResult(daeURI(base, "/g").str() == "http://a/g");
00951 CheckResult(daeURI(base, "//g").str() == "http://g");
00952 CheckResult(daeURI(base, "?y").str() == "http://a/b/c/d;p?y");
00953 CheckResult(daeURI(base, "g?y").str() == "http://a/b/c/g?y");
00954 CheckResult(daeURI(base, "#s").str() == "http://a/b/c/d;p?q#s");
00955 CheckResult(daeURI(base, "g#s").str() == "http://a/b/c/g#s");
00956 CheckResult(daeURI(base, "g?y#s").str() == "http://a/b/c/g?y#s");
00957 CheckResult(daeURI(base, ";x").str() == "http://a/b/c/;x");
00958 CheckResult(daeURI(base, "g;x").str() == "http://a/b/c/g;x");
00959 CheckResult(daeURI(base, "g;x?y#s").str() == "http://a/b/c/g;x?y#s");
00960 CheckResult(daeURI(base, "").str() == "http://a/b/c/d;p?q");
00961 CheckResult(daeURI(base, ".").str() == "http://a/b/c/");
00962 CheckResult(daeURI(base, "./").str() == "http://a/b/c/");
00963 CheckResult(daeURI(base, "..").str() == "http://a/b/");
00964 CheckResult(daeURI(base, "../").str() == "http://a/b/");
00965 CheckResult(daeURI(base, "../g").str() == "http://a/b/g");
00966 CheckResult(daeURI(base, "../..").str() == "http://a/");
00967 CheckResult(daeURI(base, "../../").str() == "http://a/");
00968 CheckResult(daeURI(base, "../../g").str() == "http://a/g");
00969
00970 CheckResult(daeURI(base, "../../../g").str() == "http://a/g");
00971 CheckResult(daeURI(base, "../../../../g").str() == "http://a/g");
00972 CheckResult(daeURI(base, "/./g").str() == "http://a/g");
00973 CheckResult(daeURI(base, "/../g").str() == "http://a/g");
00974 CheckResult(daeURI(base, "g.").str() == "http://a/b/c/g.");
00975 CheckResult(daeURI(base, ".g").str() == "http://a/b/c/.g");
00976 CheckResult(daeURI(base, "g..").str() == "http://a/b/c/g..");
00977 CheckResult(daeURI(base, "..g").str() == "http://a/b/c/..g");
00978
00979 CheckResult(daeURI(base, "./../g").str() == "http://a/b/g");
00980 CheckResult(daeURI(base, "./g/.").str() == "http://a/b/c/g/");
00981 CheckResult(daeURI(base, "g/./h").str() == "http://a/b/c/g/h");
00982 CheckResult(daeURI(base, "g/../h").str() == "http://a/b/c/h");
00983 CheckResult(daeURI(base, "g;x=1/./y").str() == "http://a/b/c/g;x=1/y");
00984 CheckResult(daeURI(base, "g;x=1/../y").str() == "http://a/b/c/y");
00985
00986
00987 CheckResult(daeURI(base, "g?y/./x").str() == "http://a/b/c/g?y/./x");
00988 CheckResult(daeURI(base, "g?y/../x").str() == "http://a/b/c/g?y/../x");
00989 CheckResult(daeURI(base, "g#s/./x").str() == "http://a/b/c/g#s/./x");
00990 CheckResult(daeURI(base, "g#s/../x").str() == "http://a/b/c/g#s/../x");
00991
00992 CheckResult(daeURI(base, "http:g").str() == "http:g");
00993 }
00994
00995
00996 CheckResult(daeURI(dae, "relPath/file.txt").originalStr() == "relPath/file.txt");
00997
00998
00999 {
01000 daeURI uri(dae);
01001 uri.set("file:/path/file.txt");
01002 CheckResult(uri.str() == "file:/path/file.txt");
01003 uri.set("http", "www.example.com", "/path", "q", "f");
01004 CheckResult(uri.str() == "http://www.example.com/path?q#f");
01005 }
01006
01007
01008 CheckResult(daeURI(dae, "file:/home/sthomas/file.txt").scheme() == "file");
01009 CheckResult(daeURI(dae, "http://www.example.com").authority() == "www.example.com");
01010 CheckResult(daeURI(dae, "file:/home/sthomas/file.txt").path() == "/home/sthomas/file.txt");
01011 CheckResult(daeURI(dae, "file:/home/sthomas/file.txt?query").query() == "query");
01012 CheckResult(daeURI(dae, "file:/home/sthomas/file.txt?query#fragment").fragment() == "fragment");
01013 CheckResult(daeURI(dae, "file:/home/sthomas/file.txt?query#fragment").id() == "fragment");
01014
01015
01016 {
01017 daeURI uri(dae);
01018 uri.scheme("file");
01019 uri.authority("myAuth");
01020 uri.path("/home/sthomas/file.txt");
01021 uri.query("q");
01022 uri.fragment("f");
01023 CheckResult(uri.str() == "file://myAuth/home/sthomas/file.txt?q#f");
01024 uri.id("id");
01025 CheckResult(uri.str() == "file://myAuth/home/sthomas/file.txt?q#id");
01026 }
01027
01028
01029 {
01030 daeURI uri(dae, "file:/home/sthomas/file.txt");
01031 CheckResult(uri.str() == "file:/home/sthomas/file.txt");
01032 string dir, base, ext;
01033 uri.pathComponents(dir, base, ext);
01034 CheckResult(dir == "/home/sthomas/");
01035 CheckResult(base == "file");
01036 CheckResult(ext == ".txt");
01037 CheckResult(uri.pathDir() == "/home/sthomas/");
01038 CheckResult(uri.pathFileBase() == "file");
01039 CheckResult(uri.pathExt() == ".txt");
01040 CheckResult(uri.pathFile() == "file.txt");
01041 }
01042
01043
01044 {
01045 daeURI uri(dae, "file:");
01046 CheckResult(uri.str() == "file:");
01047 uri.path("/home/sthomas/", "file", ".txt");
01048 CheckResult(uri.str() == "file:/home/sthomas/file.txt");
01049 uri.pathDir("/home/johnny");
01050 uri.pathFileBase("otherFile");
01051 uri.pathExt(".dae");
01052 CheckResult(uri.str() == "file:/home/johnny/otherFile.dae");
01053 uri.pathFile("file.txt");
01054 CheckResult(uri.str() == "file:/home/johnny/file.txt");
01055 }
01056
01057
01058 CheckResult(daeURI(dae, "file:/d1/d2/d3/../../d4/./file.txt").str() == "file:/d1/d4/file.txt");
01059
01060
01061 CheckResult(strcmp(daeURI(dae, "file:/dir/file.txt").getURI(), "file:/dir/file.txt") == 0);
01062 CheckResult(strcmp(daeURI(dae, "dir/file.txt").getOriginalURI(), "dir/file.txt") == 0);
01063 {
01064 daeURI uri(dae), base(dae);
01065 base.setURI("http://www.example.com");
01066 uri.setURI("dir/file.txt", &base);
01067 CheckResult(uri.str() == "http://www.example.com/dir/file.txt");
01068 uri.setURI("http://www.example.com/dir/file.txt?q#f");
01069 CheckResult(strcmp(uri.getScheme(), "http") == 0);
01070 CheckResult(strcmp(uri.getProtocol(), "http") == 0);
01071 CheckResult(strcmp(uri.getAuthority(), "www.example.com") == 0);
01072 CheckResult(strcmp(uri.getPath(), "/dir/file.txt") == 0);
01073 CheckResult(strcmp(uri.getQuery(), "q") == 0);
01074 CheckResult(strcmp(uri.getFragment(), "f") == 0);
01075 CheckResult(strcmp(uri.getID(), "f") == 0);
01076 char buffer1[4], buffer2[32];
01077 CheckResult(!uri.getPath(buffer1, sizeof(buffer1)));
01078 CheckResult(uri.getPath(buffer2, sizeof(buffer2)));
01079 CheckResult(strcmp(buffer2, "/dir/file.txt") == 0);
01080 }
01081
01082
01083 {
01084 daeURI base(dae, "file:/home/sthomas/");
01085 daeURI uri1(base, "folder1/file.dae");
01086 daeURI uri2(base, "folder2/file.dae");
01087 uri2.makeRelativeTo(&uri1);
01088 CheckResult(uri2.originalStr() == "../folder2/file.dae");
01089 CheckResult(uri2.str() == "file:/home/sthomas/folder2/file.dae");
01090 }
01091
01092
01093
01094 {
01095 string scheme, authority, path, query, fragment;
01096 cdom::parseUriRef("file:////models/cube.dae", scheme, authority, path, query, fragment);
01097 CheckResult(cdom::assembleUri(scheme, authority, path, query, fragment) == "file:////models/cube.dae");
01098 }
01099
01100 return testResult(true);
01101 }
01102
01103
01104 DefineTest(uriBase) {
01105 DAE dae;
01106 daeURI uri(dae, cdom::nativePathToUri(lookupTestFile("uri.dae")));
01107 CheckResult(dae.open(uri.str()));
01108 domImage::domInit_from* initFrom = dae.getDatabase()->typeLookup<domImage::domInit_from>().at(0);
01109 CheckResult(initFrom->getRef()->getValue().pathDir() == uri.pathDir());
01110 return testResult(true);
01111 }
01112
01113
01114 DefineTest(xmlNavigation) {
01115 DAE dae;
01116 string file = lookupTestFile("cube.dae");
01117 domCOLLADA* root = dae.open(file);
01118 CheckResult(root);
01119
01120 CheckResult(root->getChild("library_cameras"));
01121 CheckResult(root->getChild("contributor") == 0);
01122 CheckResult(root->getDescendant("steveT") == 0);
01123 daeElement* upAxis = root->getDescendant("up_axis");
01124 CheckResult(upAxis);
01125 CheckResult(upAxis->getParent());
01126 CheckResult(upAxis->getAncestor("asset"));
01127 CheckResult(upAxis->getAncestor("library_geometries") == 0);
01128
01129 CheckResult(root->getChild(daeElement::matchType(domLibrary_cameras::ID())));
01130 CheckResult(root->getChild(daeElement::matchType(domAsset::domContributor::ID())) == 0);
01131 CheckResult(root->getDescendant(daeElement::matchType(-10)) == 0);
01132 upAxis = root->getDescendant(daeElement::matchType(domAsset::domUp_axis::ID()));
01133 CheckResult(upAxis);
01134 CheckResult(upAxis->getParent());
01135 CheckResult(upAxis->getAncestor(daeElement::matchType(domAsset::ID())));
01136 CheckResult(upAxis->getAncestor(daeElement::matchType(domLibrary_geometries::ID())) == 0);
01137
01138 return testResult(true);
01139 }
01140
01141
01142 DefineTest(multipleDae) {
01143
01144
01145 DAE dae1;
01146 DAE dae2;
01147 CheckResult(dae2.open(lookupTestFile("cube.dae")));
01148 CheckResult(dae1.open(lookupTestFile("duck.dae")));
01149 return testResult(true);
01150 }
01151
01152
01153 DefineTest(unusedTypeCheck) {
01154 DAE dae;
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165 set<int> expectedUnusedTypes;
01166 expectedUnusedTypes.insert(domEllipsoid::ID());
01167 expectedUnusedTypes.insert(domEllipsoid::domSize::ID());
01168 expectedUnusedTypes.insert(domInput_global::ID());
01169 expectedUnusedTypes.insert(domAny::ID());
01170
01171
01172 expectedUnusedTypes.insert(domImage_source::ID());
01173 expectedUnusedTypes.insert(domFx_sampler::ID());
01174 expectedUnusedTypes.insert(domFx_rendertarget::ID());
01175 expectedUnusedTypes.insert(domGles2_newparam::ID());
01176 expectedUnusedTypes.insert(domLimits_sub::ID());
01177 expectedUnusedTypes.insert(domTargetable_float4::ID());
01178 expectedUnusedTypes.insert(domCommon_int_or_param::ID());
01179
01180
01181 set<int> actualUnusedTypes;
01182 const daeMetaElementRefArray &metas = dae.getAllMetas();
01183 for (size_t i = 0; i < metas.getCount(); i++)
01184 if (!metas[i])
01185 actualUnusedTypes.insert((int)i);
01186
01187
01188 return testResult(expectedUnusedTypes == actualUnusedTypes);
01189 }
01190
01191
01192 DefineTest(domFx_common_transparent) {
01193
01194 DAE dae;
01195 CheckResult(dae.open(lookupTestFile("cube.dae")));
01196
01197 domFx_common_transparent* transparent =
01198 dae.getDatabase()->typeLookup<domFx_common_transparent>().at(0);
01199
01200 CheckResult(transparent->getColor() != NULL);
01201 CheckResult(transparent->getParam() == NULL);
01202 CheckResult(transparent->getTexture() == NULL);
01203 CheckResult(transparent->getOpaque() == FX_OPAQUE_A_ONE);
01204
01205 return testResult(true);
01206 };
01207
01208
01209 DefineTest(autoResolve) {
01210
01211
01212 DAE dae;
01213 daeDatabase& database = *dae.getDatabase();
01214 CheckResult(dae.open(lookupTestFile("Seymour.dae")));
01215
01216 {
01217
01218 xsIDREFS& idRefs = database.typeLookup<domIdref_array>().at(0)->getValue();
01219 for (size_t i = 0; i < idRefs.getCount(); i++) {
01220 CheckResult(idRefs[i].getElement());
01221 }
01222
01223 domInstance_controller& ic = *database.typeLookup<domInstance_controller>().at(0);
01224 CheckResult(ic.getUrl().getElement());
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237 }
01238
01239
01240
01241 dae.clear();
01242 domCOLLADA* root = dae.add("tmp.dae");
01243 CheckResult(root);
01244
01245
01246 CheckResult(root->add("library_geometries geometry mesh source IDREF_array"));
01247 daeElement* geom = root->getDescendant("geometry");
01248 geom->setAttribute("id", "myGeom");
01249 xsIDREFS& idRefs = database.typeLookup<domIdref_array>().at(0)->getValue();
01250 idRefs.append(daeIDRef("myGeom"));
01251
01252
01253 daeElement* node1 = root->add("library_nodes node");
01254 node1->setAttribute("id", "myNode");
01255
01256
01257 daeElement* node2 = root->getDescendant("library_nodes")->add("node");
01258 domInstance_node& instanceNode = *daeSafeCast<domInstance_node>(node2->add("instance_node"));
01259 domInstance_geometry& instanceGeom = *daeSafeCast<domInstance_geometry>(
01260 node2->add("instance_geometry"));
01261 instanceNode.setUrl("#myNode");
01262 instanceGeom.setUrl("#myGeom");
01263
01264
01265 domImage_source::domRef* ref = daeSafeCast<domImage_source::domRef>(
01266 root->add("library_images image init_from ref"));
01267 ref->setValue("myGeom");
01268
01269
01270 CheckResult(idRefs[0].getElement() == geom);
01271 CheckResult(instanceGeom.getUrl().getElement() == geom);
01272
01273
01274 CheckResult(instanceNode.getUrl().getElement() == node1);
01275
01276 return testResult(true);
01277 }
01278
01279
01280 DefineTest(baseURI) {
01281 DAE dae1, dae2;
01282 dae1.setBaseURI("http://www.example.com/");
01283 daeURI uri1(dae1, "myFolder/myFile.dae");
01284 daeURI uri2(dae2, "myFolder/myFile.dae");
01285 CheckResult(uri1.str() != uri2.str());
01286 CheckResult(uri1.str() == "http://www.example.com/myFolder/myFile.dae");
01287 return testResult(true);
01288 }
01289
01290
01291 DefineTest(databaseLookup) {
01292 DAE dae;
01293 CheckResult(dae.open(lookupTestFile("cube.dae")));
01294 daeDatabase& database = *dae.getDatabase();
01295 daeDocument* doc = database.getDoc(0);
01296 CheckResult(doc);
01297
01298
01299 CheckResult(database.idLookup("light-lib").size() == 1);
01300 CheckResult(database.idLookup("light-lib", doc));
01301 CheckResult(database.typeLookup(domNode::ID()).size() == 5);
01302 vector<daeElement*> elts;
01303 database.typeLookup(domRotate::ID(), elts, doc);
01304 CheckResult(elts.size() == 15);
01305 CheckResult(database.typeLookup<domNode>().size() == 5);
01306 vector<domRotate*> rotateElts;
01307 database.typeLookup(rotateElts);
01308 CheckResult(rotateElts.size() == 15);
01309
01310
01311 CheckResult(database.getElementCount("light-lib") == 1);
01312 daeElement* elt = NULL;
01313 database.getElement(&elt, 0, "light-lib", NULL, doc->getDocumentURI()->getURI());
01314 CheckResult(elt);
01315 CheckResult(database.getElementCount(NULL, "node") == 5);
01316 database.getElement(&elt, 8, NULL, "rotate");
01317 CheckResult(elt);
01318
01319 return testResult(true);
01320 }
01321
01322
01323 DefineTest(fileExtension) {
01324
01325
01326
01327 DAE dae;
01328 CheckResult(dae.open(lookupTestFile("cube.cstm")));
01329 CheckResult(dae.getDatabase()->typeLookup<domAccessor>().at(0)->getSource().getElement());
01330 CheckResult(dae.writeTo(lookupTestFile("cube.cstm"), getTmpFile("cube_roundTrip.cstm")));
01331 return testResult(true);
01332 }
01333
01334
01335 DefineTest(zipFile) {
01336
01337 DAE dae;
01338 CheckResult(dae.open(lookupTestFile("cube.dae.gz")));
01339 CheckResult(dae.getDatabase()->typeLookup(domAsset::ID()).size() == 1);
01340 return testResult(true);
01341 }
01342
01343
01344 DefineTest(charEncoding) {
01345
01346 string file = getTmpFile("charEncoding.dae");
01347 DAE dae;
01348 dae.setCharEncoding(DAE::Latin1);
01349 daeElement* elt = dae.add(file)->add("asset contributor comments");
01350 CheckResult(elt);
01351 elt->setCharData("æ ø å ü ä ö");
01352 CheckResult(dae.writeAll());
01353 dae.clear();
01354 CheckResult(dae.open(file));
01355 return testResult(true);
01356 }
01357
01358
01359 DefineTest(getElementBug) {
01360 DAE dae;
01361 CheckResult(dae.open(lookupTestFile("cube.dae")));
01362
01363
01364 domInstance_geometry* geomInst = dae.getDatabase()->typeLookup<domInstance_geometry>().at(0);
01365 CheckResult(geomInst->getUrl().getElement());
01366 daeElement::removeFromParent(geomInst->getUrl().getElement());
01367 CheckResult(geomInst->getUrl().getElement() == 0);
01368
01369
01370 daeIDRef idRef(*geomInst);
01371 idRef.setID("PerspCamera");
01372 CheckResult(idRef.getElement());
01373 daeElement::removeFromParent(idRef.getElement());
01374 CheckResult(idRef.getElement() == 0);
01375
01376
01377 daeSidRefCache& cache = dae.getSidRefCache();
01378 daeElement* effect = dae.getDatabase()->typeLookup(domEffect::ID()).at(0);
01379 daeSidRef sidRef("common", effect);
01380
01381 CheckResult(cache.empty() && cache.hits() == 0 && cache.misses() == 0);
01382 daeElement* technique = sidRef.resolve().elt;
01383 CheckResult(technique && cache.misses() == 1 && !cache.empty());
01384 sidRef.resolve();
01385 CheckResult(cache.misses() == 1 && cache.hits() == 1);
01386 daeElement::removeFromParent(technique);
01387 CheckResult(cache.empty() && cache.misses() == 0 && cache.hits() == 0);
01388 CheckResult(sidRef.resolve().elt == NULL);
01389 CheckResult(cache.empty() && cache.misses() == 1);
01390
01391 return testResult(true);
01392 }
01393
01394
01395 DefineTest(externalRef) {
01396 DAE dae;
01397 CheckResult(dae.open(lookupTestFile("externalRef.dae")));
01398 domInstance_geometry* geomInst = dae.getDatabase()->typeLookup<domInstance_geometry>().at(0);
01399 daeURI& uri = geomInst->getUrl();
01400 CheckResult(uri.isExternalReference() == true);
01401 CheckResult(uri.getReferencedDocument() == NULL);
01402 CheckResult(uri.getElement());
01403 CheckResult(uri.getReferencedDocument());
01404 return testResult(true);
01405 }
01406
01407
01408 DefineTest(charEncodingSetting) {
01409 DAE dae;
01410 dae.setGlobalCharEncoding(DAE::Utf8);
01411 CheckResult(dae.getCharEncoding() == DAE::Utf8);
01412 dae.setCharEncoding(DAE::Latin1);
01413 CheckResult(dae.getCharEncoding() == DAE::Latin1);
01414 DAE dae2;
01415 CheckResult(dae2.getCharEncoding() == DAE::Utf8);
01416 return testResult(true);
01417 }
01418
01419
01420 DefineTest(uriCopy) {
01421 DAE dae;
01422 CheckResult(dae.open(lookupTestFile("cube.dae")));
01423 domInstance_geometry* geomInst = dae.getDatabase()->typeLookup<domInstance_geometry>().at(0);
01424 daeURI& uri = geomInst->getUrl();
01425 CheckResult(uri.getElement());
01426 daeURI uriCopy = geomInst->getUrl();
01427 CheckResult(uriCopy.getElement());
01428 return testResult(true);
01429 }
01430
01431
01432 DefineTest(badFileLoad) {
01433 DAE dae;
01434 CheckResult(!dae.open(lookupTestFile("badFile.dae")));
01435 return testResult(true);
01436 }
01437
01438
01439 DefineTest(spuriousQuotes) {
01440 DAE dae;
01441 CheckResult(!dae.open(lookupTestFile("quotesProblem.dae")));
01442 return testResult(true);
01443 }
01444
01445
01446 DefineTest(zaeLoading) {
01447 DAE dae;
01448
01449
01450 std::string testFile = lookupTestFile("duck.zae");
01451 domCOLLADA* root = dae.open(testFile);
01452 CheckResult(root);
01453
01454
01455 domInstance_with_extra* instanceVisualScene = daeSafeCast<domInstance_with_extra>(root->getDescendant("instance_visual_scene"));
01456 CheckResult(instanceVisualScene);
01457 daeURI visualSceneURI = instanceVisualScene->getUrl();
01458 domVisual_scene* visualScene = daeSafeCast<domVisual_scene>(visualSceneURI.getElement());
01459 CheckResult(visualScene);
01460
01461
01462 domInstance_image* instanceImage = daeSafeCast<domInstance_image>(visualScene->getDocument()->getDomRoot()->getDescendant("instance_image"));
01463 CheckResult(instanceImage);
01464 daeURI imageURI = instanceImage->getUrl();
01465 domImage* image = daeSafeCast<domImage>(imageURI.getElement());
01466 CheckResult(image);
01467
01468
01469 domImage_source::domRef* ref = daeSafeCast<domImage_source::domRef>(image->getDescendant("ref"));
01470 xsAnyURI imageFileURI = ref->getValue();
01471 bool imageFileExists = boost::filesystem::exists( cdom::uriToNativePath( imageFileURI.str() ) );
01472 CheckResult(imageFileExists);
01473
01474
01475 domInstance_geometry* instanceGeometry = daeSafeCast<domInstance_geometry>(visualScene->getDocument()->getDomRoot()->getDescendant("instance_geometry"));
01476 CheckResult(instanceGeometry);
01477 daeURI geometryURI = instanceGeometry->getUrl();
01478 domGeometry* geometry = daeSafeCast<domGeometry>(geometryURI.getElement());
01479 CheckResult(geometry);
01480
01481 return testResult(true);
01482 }
01483
01484 DefineTest(zaeIllegalArchive) {
01485 DAE dae;
01486
01487
01488 std::string testFile = lookupTestFile("illegal_archive.zae");
01489 domCOLLADA* root = dae.open(testFile);
01490 CheckResult(!root);
01491
01492 return testResult(true);
01493 }
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503 bool checkTests(const set<string>& tests) {
01504 bool invalidTestFound = false;
01505 for (set<string>::const_iterator iter = tests.begin(); iter != tests.end(); iter++) {
01506 if (registeredTests().find(*iter) == registeredTests().end()) {
01507 if (!invalidTestFound)
01508 cout << "Invalid arguments:\n";
01509 cout << " " << *iter << endl;
01510 invalidTestFound = true;
01511 }
01512 }
01513
01514 return !invalidTestFound;
01515 }
01516
01517
01518 map<string, testResult> runTests(const set<string>& tests) {
01519 map<string, testResult> failedTests;
01520 for (set<string>::const_iterator iter = tests.begin(); iter != tests.end(); iter++) {
01521 testResult result = registeredTests()[*iter]->run();
01522 if (!result.passed)
01523 failedTests[*iter] = result;
01524 }
01525 return failedTests;
01526 }
01527
01528
01529
01530 bool printTestResults(const map<string, testResult>& failedTests) {
01531 if (!failedTests.empty()) {
01532 cout << "Failed tests:\n";
01533 for (map<string, testResult>::const_iterator iter = failedTests.begin();
01534 iter != failedTests.end();
01535 iter++) {
01536 cout << " " << iter->first;
01537 if (!iter->second.file.empty()) {
01538 cout << " (file " << fs::path(iter->second.file).leaf();
01539 if (iter->second.line != -1)
01540 cout << ", line " << iter->second.line << ")";
01541 else
01542 cout << ")";
01543 }
01544 cout << endl;
01545 if (!iter->second.msg.empty())
01546 cout << " " << replace(iter->second.msg, "\n", "\n ") << "\n";
01547 }
01548 return false;
01549 }
01550 else {
01551 cout << "All tests passed.\n";
01552 return true;
01553 }
01554 }
01555
01556 struct tmpDir {
01557 fs::path path;
01558 bool deleteWhenDone;
01559
01560 tmpDir(fs::path& path, bool deleteWhenDone)
01561 : path(path),
01562 deleteWhenDone(deleteWhenDone) {
01563 fs::create_directories(path);
01564 }
01565
01566 ~tmpDir() {
01567 if (deleteWhenDone)
01568 fs::remove_all(path);
01569 }
01570 };
01571
01572
01573 int main(int argc, char* argv[]) {
01574
01575 #if defined _MSC_VER && defined _DEBUG
01576 _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF | _CRTDBG_CHECK_EVERY_1024_DF);
01577 #endif
01578
01579 if (argc == 1) {
01580 cout << "Usage:\n"
01581 " -printTests - Print the names of all available tests\n"
01582 " -all - Run all tests\n"
01583 " -leaveTmpFiles - Don't delete the tmp folder containing the generated test files\n"
01584 " test1 test2 ... - Run the named tests\n";
01585 return 0;
01586 }
01587
01588 bool printTests = false;
01589 bool allTests = false;
01590 bool leaveTmpFiles = false;
01591 set<string> tests;
01592 for (int i = 1; i < argc; i++) {
01593 if (string(argv[i]) == "-printTests")
01594 printTests = true;
01595 else if (string(argv[i]) == "-all")
01596 allTests = true;
01597 else if (string(argv[i]) == "-leaveTmpFiles")
01598 leaveTmpFiles = true;
01599 else
01600 tests.insert(argv[i]);
01601 }
01602
01603 #ifdef __CELLOS_LV2__
01604
01605
01606
01607 leaveTmpFiles = true;
01608 #endif
01609
01610
01611 daeErrorHandler::setErrorHandler(&quietErrorHandler::getInstance());
01612
01613 dataPath() = (fs::path(argv[0]).branch_path()/"domTestData/").normalize();
01614 if (!fs::exists(dataPath()))
01615 dataPath() = (fs::path(argv[0]).branch_path()/"../../test/1.5/data/").normalize();
01616 tmpPath() = dataPath() / "tmp";
01617 tmpDir tmp(tmpPath(), !leaveTmpFiles);
01618
01619 if (checkTests(tests) == false)
01620 return 0;
01621
01622
01623 if (printTests) {
01624 map<string, domTest*>::iterator iter;
01625 for (iter = registeredTests().begin(); iter != registeredTests().end(); iter++)
01626 cout << iter->second->name << endl;
01627 return 0;
01628 }
01629
01630
01631 if (allTests) {
01632 map<string, domTest*>::iterator iter;
01633 for (iter = registeredTests().begin(); iter != registeredTests().end(); iter++)
01634 tests.insert(iter->first);
01635 }
01636
01637
01638 return printTestResults(runTests(tests)) ? 0 : 1;
01639 }