#include #include #include "data.h" #include "episodelistview.h" #include "pl.h" #include "util.h" #include "win.h" extern CfgA& g_cfg; struct Test { const char* name = {0}; char error[64] = {0}; Test(const char* name) : name(name) {} }; #define TESTS struct UNUSED #define TEST(id) }; struct id : public Test { id() : Test(#id) #define FAIL(...) do { Sprintf(error, __VA_ARGS__); return; } while (0) TESTS { TEST(StrcpyWithSmallerDestination) { char src[15], dst[10]; Sprintf(src, "abcdefghijklmn"); Strcpy(dst, src); if (dst[8] != 'i') FAIL("dst[8] is not 'i', but '%c'", dst[8]); if (dst[9] != 0) FAIL("dst is not NUL-terminated"); } TEST(EpisodeDataFromWeb) { ElvDataA e; DlvDataA d; FromWeb(10, e, d); if (wcscmp(e.title, L"Pro Soccer Player Blackmail Case") != 0) FAIL("title is not correct"); if (wcscmp(d.date, L"March 11, 1996") != 0) FAIL("date is not correct"); } TEST(EpisodeDataFromProlog) { ElvDataA e; DlvDataA d; FromProlog(10, e); FromProlog(10, d); if (wcscmp(e.title, L"Pro Soccer Player Blackmail Case") != 0) FAIL("title is not correct"); if (wcscmp(d.date, L"March 11, 1996") != 0) FAIL("date is not correct"); } TEST(IO) { ElvDataA e1_0, e2_0; FromProlog(6, e1_0); FromProlog(10, e2_0); /* Write two ElvDataA structs to disk. */ { FileView fv(L"tmp.dat", 2); memcpy(fv+0, &e1_0, sizeof(e1_0)); memcpy(fv+1, &e2_0, sizeof(e2_0)); } /* Read first ElvDataA struct from disk using * ElvDataA-typed FileView. */ { FileView fv(L"tmp.dat", 2); const ElvDataA& e1 = *fv; if (e1.version != 'a') FAIL("version is different"); if (e1_0.rating != e1.rating) FAIL("rating is different (%d/%d)", e1_0.rating, e1.rating); if (e1_0.bWatched != e1.bWatched) FAIL("bWatched is different"); if (e1_0.bTVOriginal != e1.bTVOriginal) FAIL("bTVOriginal is different"); if (wcscmp(e1_0.sRating, e1.sRating) != 0) FAIL("sRating is different"); if (wcscmp(e1_0.siEp, e1.siEp) != 0) FAIL("siEp is different"); if (wcscmp(e1_0.title, e1.title) != 0) FAIL("title is different"); } /* Read second ElvDataA struct from disk using * unsigned char-typed FileView. */ { FileView fv(L"tmp.dat", 2*sizeof(ElvDataA)); ElvDataA& e2 = *reinterpret_cast(&fv.At(sizeof(ElvDataA))); if (e2_0.rating != e2.rating) FAIL("rating is different (%d/%d)", e2_0.rating, e2.rating); if (e2_0.bWatched != e2.bWatched) FAIL("bWatched is different"); if (e2_0.bTVOriginal != e2.bTVOriginal) FAIL("bTVOriginal is different"); if (wcscmp(e2_0.sRating, e2.sRating) != 0) FAIL("sRating is different"); if (wcscmp(e2_0.siEp, e2.siEp) != 0) FAIL("siEp is different"); if (wcscmp(e2_0.title, e2.title) != 0) FAIL("title is different"); } //DeleteFile(L"tmp.dat"); } TEST(MigrateElvDataFromPrologToDisk) { int cEp; if (!Pl("episode_data","episode_count",&cEp)) return; { FileView fv(L"tmp.dat", g_cfg.cEp+128u); ElvDataA* p = fv; for (int iEp = 1; iEp <= cEp; iEp++) { ElvDataA e; FromProlog(iEp, e); memcpy(p, &e, sizeof(e)); p++; } } { FileView fv(L"tmp.dat", g_cfg.cEp+128u); ElvDataA& e = fv.At(9); if (wcscmp(e.title, L"Pro Soccer Player Blackmail Case") != 0) FAIL("title is not correct"); } //DeleteFile(L"tmp.dat"); } TEST(SampleConfigurationToDisk) { CfgA cfg_0; { FileView fv(L"tmp.dat", 1); Wcscpy(cfg_0.url, L"https://animixplay.to/v1/detective-conan/ep"); memcpy(fv, &cfg_0, sizeof(cfg_0)); } { FileView fv(L"tmp.dat", 1); const CfgA& cfg = fv.At(0); if (cfg_0.bViewWatched != cfg.bViewWatched) FAIL("bViewWatched is different"); if (wcscmp(cfg_0.url, cfg.url) != 0) FAIL("url is not correct"); } //DeleteFile(L"tmp.dat"); } // TEST(MigrateCfg) // { // FileView fva(L"cfga.dat", 1); // FileView fvb = FileView::Initialized(L"cfgb.dat", 1); // fvb->bViewWatched = fva->bViewWatched; // fvb->bViewTVOriginal = fva->bViewTVOriginal; // fvb->iSortCol = fva->iSortCol; // fvb->iFocus = fva->iFocus; // fvb->heightDlv = fva->heightDlv; // Wcscpy(fvb->limitScreenwriter, fva->limitScreenwriter); // Wcscpy(fvb->root, fva->root); // Wcscpy(fvb->glob, fva->glob); // Wcscpy(fvb->url, fva->url); // } TEST(MigrateDlvDataFromPrologToDisk) { int cEp; if (!Pl("episode_data","episode_count",&cEp)) return; { FileView fv(L"tmp.dat", g_cfg.cEp+128u); DlvDataA* p = fv; for (int iEp = 1; iEp <= cEp; iEp++) { DlvDataA d; FromProlog(iEp, d); memcpy(p, &d, sizeof(d)); p++; } } { FileView fv(L"tmp.dat", g_cfg.cEp+128u); DlvDataA& e = fv.At(9); if (wcscmp(e.date, L"March 11, 1996") != 0) FAIL("date is not correct"); } //DeleteFile(L"tmp.dat"); } TEST(DownloadDataViaProlog) { WcharPtr title, wiki, date, source, hint; int i = 1053; /* This is slow. */ while(Pl("episode_data","fetch_episode_data",++i,&title,&wiki,&date,&source,&hint)) { extern FileView g_fvElv; extern FileView g_fvDlv; ElvDataA& e = g_fvElv.At(i-1); Wcscpy(e.title, title); if (!e.siEp[0]) Swprintf(e.siEp, L"%d", i); DlvDataA& d = g_fvDlv.At(i-1); Wcscpy(d.wiki, wiki); Wcscpy(d.date, date); Wcscpy(d.source, source); Wcscpy(d.hint, hint); } extern CfgA& g_cfg; g_cfg.cEp = i; } TEST(Fetch) { bool bDone = false; std::thread(WaitFetchData, &bDone).detach(); } }; int RunTests() { const Test tests[] = { StrcpyWithSmallerDestination(), //EpisodeDataFromWeb(), //EpisodeDataFromProlog(), //IO(), //MigrateElvDataFromPrologToDisk(), //SampleConfigurationToDisk(), //MigrateCfg() //MigrateDlvDataFromPrologToDisk(), //DownloadDataViaProlog(), //Fetch(), }; printf("Results (%llu tests):\n", sizeof(tests)/sizeof(*tests)); int cFailed = 0; for (const Test& t : tests) { const char* msg; if (t.error[0]) { msg = t.error; cFailed++; } else msg = const_cast("SUCCESS"); printf("%s: %s\n", t.name, msg); } printf("%d tests failed.\n", cFailed); return cFailed; }