open source
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
#ifdef _TEST_
|
||||
#include "../JCTestManager.h"
|
||||
#include "../../JSWrapper/JSInterface/V8/JSArrayBuffer.h"
|
||||
using namespace laya;
|
||||
|
||||
#ifdef JS_V8
|
||||
/*
|
||||
* 这里的namespace并没有特殊要求,因为是全局函数,为了防止冲突,才加上一个namespace,对最终的测试没有影响。
|
||||
*/
|
||||
namespace arrayBufferAllocTest{
|
||||
void test1(){
|
||||
/*
|
||||
ArrayBufferAllocator* pAlloc = ArrayBufferAllocator::getInstance();
|
||||
void* pPtr = pAlloc->Allocate(100);
|
||||
int idx = pAlloc->_testGetID(pPtr);
|
||||
VERIFYEQ(idx, 0, "ArrayBuffer分配后,要保存id");
|
||||
void* pPtr1 = pAlloc->Allocate(10);
|
||||
VERIFYEQ(pAlloc->_testGetID(pPtr1), 1, "arraybuffer的id要正确维护");
|
||||
pAlloc->Free(pPtr,100);
|
||||
VERIFYEQ(pAlloc->_testGetID(pPtr1), 0, "删除后,需要修改被挪动的buffer的id");
|
||||
void* pPtr3 = pAlloc->Allocate(100);
|
||||
VERIFYEQ(pAlloc->_testGetID(pPtr3), 1, "有删除后的id分配。");
|
||||
pAlloc->FreeAllAlive();
|
||||
VERIFYEQ(pAlloc->getAliveBufferNum(), 0, "FreeAllAlive.");
|
||||
*/
|
||||
}
|
||||
|
||||
//这个是主测试函数,要在这里调用所有的测试函数
|
||||
void testMain(){
|
||||
test1();
|
||||
}
|
||||
//添加测试用例,第一个参数是主函数,第二个是测试用例的说明,也可以可以用来执行测试用例的过滤。
|
||||
ADDTESTCASE(testMain,"ArrayBufferAllocTests");
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifdef _TEST_
|
||||
#include "../JCTestManager.h"
|
||||
#include <util/JCCommonMethod.h>
|
||||
|
||||
using namespace laya;
|
||||
|
||||
/*
|
||||
* 这里的namespace并没有特殊要求,因为是全局函数,为了防止冲突,才加上一个namespace,对最终的测试没有影响。
|
||||
*/
|
||||
namespace testBuffer{
|
||||
void testBuffer(){
|
||||
|
||||
}
|
||||
|
||||
//这个是主测试函数,要在这里调用所有的测试函数
|
||||
void testMain(){
|
||||
testBuffer();
|
||||
}
|
||||
//添加测试用例,第一个参数是主函数,第二个是测试用例的说明,也可以可以用来执行测试用例的过滤。
|
||||
ADDTESTCASE(testMain,"测试Buffer");
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,376 @@
|
||||
#ifdef _TEST_
|
||||
#include "../JCTestManager.h"
|
||||
#include <util/JCCommonMethod.h>
|
||||
#include <downloadCache/JCServerFileCache.h>
|
||||
#include <resource/JCFileResManager.h>
|
||||
#include <downloadMgr/JCDownloadMgr.h>
|
||||
#include <downloadMgr/JCHttpHeader.h>
|
||||
#include <fileSystem/JCFileSystem.h>
|
||||
#include <chrono>
|
||||
|
||||
using namespace std::chrono;
|
||||
/*
|
||||
. 没有缓存的测试
|
||||
|
||||
. 资源在dcc表中的测试
|
||||
校验正确
|
||||
校验错误
|
||||
|
||||
. 第一次读取,没有内容
|
||||
更新一个不在dcc的特定扩展名的文件,也保存到缓存目录
|
||||
再次读取指定文件,能返回内容,且知道不属于dcc
|
||||
|
||||
. 非dcc文件,每次启动都会重新下载。例如sessionid
|
||||
. 非dcc文件只有特定文件才要放到缓存中:要根据扩展名+文件内容
|
||||
. 一个dcc文件转成非dcc文件
|
||||
*/
|
||||
|
||||
using namespace laya;
|
||||
|
||||
/*
|
||||
* 这里的namespace并没有特殊要求,因为是全局函数,为了防止冲突,才加上一个namespace,对最终的测试没有影响。
|
||||
*/
|
||||
namespace cacheTest{
|
||||
JCFileRes* createFileRes(const char* pFile, const char* pData, int len) {
|
||||
JCServerFileCache svc;
|
||||
svc.setCachePath("d:/temp/cache/");
|
||||
svc.switchToApp("http://localhost/app/");
|
||||
JCFileRes* pRes = new JCFileRes(nullptr,nullptr);
|
||||
pRes->m_nLocalFileID = svc.hashURLFull(pFile);
|
||||
pRes->m_nLength = len;
|
||||
pRes->m_pBuffer = std::shared_ptr<char>(new char[len], std::default_delete<char[]>());// std::shared_array<char>(new char[len]);
|
||||
return pRes;
|
||||
}
|
||||
void testSessionID() {
|
||||
/*
|
||||
JCServerFileCache svc;
|
||||
svc.setCachePath("d:/temp/cache/");
|
||||
svc.switchToApp("http://localhost/app/");
|
||||
svc.rmSessionID();
|
||||
svc.switchToApp("http://localhost/app/");
|
||||
int id1 = svc.getSessionID();
|
||||
VERIFYEQ(id1, 1, "第一次,id为1");
|
||||
svc.switchToApp("http://localhost/app/");
|
||||
id1 = svc.getSessionID();
|
||||
VERIFYEQ(id1, 2, "第二次,id为2");
|
||||
*/
|
||||
}
|
||||
void testLoadCached() {
|
||||
JCFileRes res(nullptr,nullptr);
|
||||
JCBuffer buff;
|
||||
bool bret = res.loadFromCache(buff,false);
|
||||
VERIFYEQ(bret, false, "");
|
||||
|
||||
}
|
||||
void testSessionFileGet(){
|
||||
JCServerFileCache svc;
|
||||
svc.setCachePath("d:/temp/cache/");
|
||||
svc.switchToApp("http://localhost/app/");
|
||||
//没有dcc的情况下,无法获得资源
|
||||
unsigned int fid = svc.hashURLFull("http://localhost/app/test.png");
|
||||
VERIFYEQ(fid, 0xf7859e1b, "计算url的hash");
|
||||
svc.clearAllCachedFile();
|
||||
JCSharedBuffer buf;
|
||||
unsigned int chksum = 0;
|
||||
bool bret = svc.load(fid, chksum, buf,false,true);
|
||||
VERIFYEQ(bret, false, "没有dcc,第一次就没有缓存文件");
|
||||
|
||||
JCFileRes *fres = new JCFileRes(nullptr,nullptr);
|
||||
fres->m_nLocalFileID = 0xf7859e1b;
|
||||
fres->m_pBuffer = std::shared_ptr<char>(new char[100],std::default_delete<char[]>()) ;
|
||||
fres->m_nLength = 100;
|
||||
chksum = 0;
|
||||
//保存临时文件。这里调用 onFileDownloaded 就是直接保存,不判断是否应该保存。
|
||||
svc.updateAFile(fres->m_nLocalFileID, fres->m_pBuffer.get(),fres->m_nLength, chksum,false,0,false);
|
||||
//再次加载,应该能获得session文件
|
||||
JCBuffer bufsession;
|
||||
bool b = svc.load(fres->m_nLocalFileID, bufsession);
|
||||
VERIFYEQ(b, true, "session文件也要保存");
|
||||
//再次进入,还要重新下载
|
||||
svc.switchToApp("http://localhost/app/");
|
||||
b = svc.load(fres->m_nLocalFileID, bufsession);
|
||||
VERIFYEQ(b, false, "上次保存的session文件不能在这次使用。");
|
||||
|
||||
svc.updateAFile(fres->m_nLocalFileID, fres->m_pBuffer.get(), fres->m_nLength, chksum, false, 0, false);
|
||||
b = svc.load(fres->m_nLocalFileID, bufsession);
|
||||
VERIFYEQ(b, true, "再次更新的可以使用。");
|
||||
}
|
||||
|
||||
/*
|
||||
在什么情况下应该保存session文件
|
||||
*/
|
||||
void testSessionFileUpdate() {
|
||||
class TestDownloadMgr :public JCDownloadMgr {
|
||||
public:
|
||||
virtual void download(const char* p_pszURL, int p_nPriority,
|
||||
onProgressFunc p_ProgCb,
|
||||
onEndFunc p_CompleteCb,
|
||||
int p_nOptTimeout) {
|
||||
JCBuffer buf;
|
||||
buf.create(100);
|
||||
memset(buf.m_pPtr, 1, 100);
|
||||
buf.m_pPtr[1] = 2;//校验值0x300
|
||||
int aa = JCCachedFileSys::getChkSum(buf.m_pPtr,100);
|
||||
p_CompleteCb(buf, "", "",0,200,"");
|
||||
int a = 0;
|
||||
}
|
||||
};
|
||||
|
||||
JCServerFileCache svc;
|
||||
svc.setCachePath("d:/temp/cache/");
|
||||
svc.switchToApp("http://localhost/app/");
|
||||
svc.clearAllCachedFile();
|
||||
JCDownloadMgr* pDmgr = new TestDownloadMgr();
|
||||
JCFileResManager fmgr(pDmgr);
|
||||
/*
|
||||
HELP
|
||||
Q: 怎么设置需要缓存的文件?
|
||||
A: 现在只能通过扩展名来判断文件是否需要缓存。如果文件没有在dcc中管理,又希望能缓存,
|
||||
就需要设置m_vExtNeedSave。注意这种缓存是非持久的,每次启动后都会丢失。
|
||||
*/
|
||||
fmgr.m_vExtNeedSave = { ".png",".jpg"};
|
||||
fmgr.setFileCache(&svc);
|
||||
|
||||
JCFileRes* pFR = new JCFileRes(pDmgr,&fmgr);
|
||||
pFR->load("http://localhost/app/test.png",nullptr);
|
||||
VERIFYEQ((pFR->m_nLastAction == JCFileRes::UPDATECACHE), true, "png文件要保存。");
|
||||
pFR->load("http://localhost/app/test.jpg",nullptr);
|
||||
//注意:这里是测试下载,会立即完成,所以可以立即查询本地文件,实际项目中需要在真正下载完了才能查询。
|
||||
VERIFYEQ((pFR->m_nLastAction == JCFileRes::UPDATECACHE), true, "jpg文件要保存。");
|
||||
pFR->load("http://localhost/app/test.png",nullptr);
|
||||
VERIFYEQ((pFR->m_nLastAction == JCFileRes::LOADFROMCACHE), true, "第二次要从缓存取。");
|
||||
pFR->load("http://localhost/app/test.png1",nullptr);
|
||||
VERIFYEQ((pFR->m_nLastAction == JCFileRes::UPDATECACHE), true, "png1文件不要保存。");
|
||||
//pFR->getlo
|
||||
//外部版本号控制
|
||||
JCFileRes::s_strExtVersion = "ver";
|
||||
pFR->load("http://localhost/app/testev.png?ver=10", nullptr);
|
||||
VERIFYEQ((pFR->m_nLastAction == JCFileRes::UPDATECACHE), true, "带版本号的文件第一次要保存。");
|
||||
pFR->load("http://localhost/app/testev.png?ver=10", nullptr);
|
||||
VERIFYEQ((pFR->m_nLastAction == JCFileRes::LOADFROMCACHE), true, "带版本号的文件第2次要读缓存。");
|
||||
pFR->load("http://localhost/app/testev.png?ver=1", nullptr);
|
||||
VERIFYEQ((pFR->m_nLastAction == JCFileRes::UPDATECACHE), true, "版本号变了要重新下载。");
|
||||
JCBuffer ret;
|
||||
pFR->loadFromCache(ret, false);
|
||||
VERIFYEQ(ret.m_nLen != 0, true, "忽略校验值要能获得内容");
|
||||
|
||||
int a = 0;
|
||||
|
||||
pFR->m_strURL = "";
|
||||
}
|
||||
|
||||
void testDCC() {
|
||||
class TestDownloadMgr :public JCDownloadMgr {
|
||||
public:
|
||||
virtual void download(const char* p_pszURL, int p_nPriority,
|
||||
onProgressFunc p_ProgCb,
|
||||
onEndFunc p_CompleteCb,
|
||||
int p_nOptTimeout) {
|
||||
JCBuffer buf;
|
||||
buf.create(100);
|
||||
memset(buf.m_pPtr, 1, 100);
|
||||
buf.m_pPtr[1] = 2;
|
||||
//现在的校验值是0x300
|
||||
p_CompleteCb(buf, "", "",0,200,"");
|
||||
int a = 0;
|
||||
}
|
||||
};
|
||||
|
||||
JCDownloadMgr* pDmgr = new TestDownloadMgr();
|
||||
JCServerFileCache svc;
|
||||
svc.setCachePath("d:/temp/cache");
|
||||
svc.switchToApp("http://localhost/app/");
|
||||
svc.clearAllCachedFile();
|
||||
std::string dccf = svc.getDccFile();
|
||||
const char* buf = "f7859e1b 300\n" //
|
||||
"2 2\n"
|
||||
"3 3\n";
|
||||
int buflen = strlen(buf);
|
||||
bool bwret = writeFileSync1(dccf.c_str(), (char*)buf,buflen,JCBuffer::utf8);
|
||||
VERIFYEQ(bwret, true, "");
|
||||
int dccnum = svc.reloadDccFile();
|
||||
VERIFYEQ(dccnum, 3, "");
|
||||
JCFileResManager fmgr(pDmgr);
|
||||
fmgr.setFileCache(&svc);
|
||||
JCFileRes* pFR = new JCFileRes(pDmgr, &fmgr);
|
||||
pFR->load("http://localhost/app/test.png",nullptr);
|
||||
VERIFYEQ((pFR->m_nLastAction == JCFileRes::UPDATECACHE), true, "dcc中的文件必须缓存");
|
||||
//第二次要能直接读缓存。
|
||||
pFR->load("http://localhost/app/test.png",nullptr);
|
||||
VERIFYEQ((pFR->m_nLastAction == JCFileRes::LOADFROMCACHE), true, "dcc第二次要能直接读缓存");
|
||||
}
|
||||
|
||||
bool end = false;
|
||||
std::string retHeader = "";
|
||||
void onEnd1(JCBuffer& buff, const std::string& locaddr, const std::string& svaddr,
|
||||
int curlret, int httpret, const std::string& header) {
|
||||
end = true;
|
||||
retHeader = header;
|
||||
}
|
||||
void testDownload() {
|
||||
JCDownloadMgr* pNL = JCDownloadMgr::getInstance();
|
||||
pNL->init(3);
|
||||
pNL->download("http://www.baidu.com/index.html",0,
|
||||
pNL->defProgressFunc,
|
||||
onEnd1,
|
||||
0);
|
||||
WaitUtil(&end, 10000);
|
||||
bool lenok = retHeader.length() > 0;
|
||||
VERIFYEQ(lenok, true, "下载必须能得到header。");
|
||||
end = false;
|
||||
retHeader = "";
|
||||
|
||||
pNL->download("https://www.baidu.com/index.html", 0,
|
||||
pNL->defProgressFunc,
|
||||
onEnd1,
|
||||
0);
|
||||
WaitUtil(&end, 10000);
|
||||
lenok = retHeader.length() > 0;
|
||||
VERIFYEQ(lenok, true, "下载https必须能得到header。");
|
||||
end = false;
|
||||
retHeader = "";
|
||||
|
||||
pNL->getHeader("http://www.baidu.com/index.html", onEnd1, 0, 0);
|
||||
WaitUtil(&end, 10000);
|
||||
end = false;
|
||||
retHeader = "";
|
||||
JCDownloadMgr::delInstance();
|
||||
}
|
||||
|
||||
void testPost() {
|
||||
JCDownloadMgr* pNL = JCDownloadMgr::getInstance();
|
||||
pNL->init(3);
|
||||
//while (true) {//测试 内存
|
||||
pNL->postData("http://10.10.20.19:9999/payapp", "1234567890", 10, onEnd1);
|
||||
WaitUtil(&end, 10000);
|
||||
end = false;
|
||||
retHeader = "";
|
||||
//}
|
||||
JCDownloadMgr::delInstance();
|
||||
}
|
||||
|
||||
int onProg1(unsigned int total, unsigned int now, float speed) {
|
||||
if (speed == 0)return 0;
|
||||
|
||||
printf("%d/%d:%d%% %fK\n",now,total,(int)(now*1.0f/total*100),speed);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void testDownloadBigfile() {
|
||||
JCDownloadMgr* pNL = JCDownloadMgr::getInstance();
|
||||
pNL->init(3);
|
||||
int st = tmGetCurms();
|
||||
pNL->downloadBigFile("http://ldc.layabox.com/download/LayaAir/runtime/download.zip", "d:/temp/download.zip",
|
||||
onProg1, onEnd1, 0, 999999);
|
||||
WaitUtil(&end, 100000);
|
||||
int dt = tmGetCurms() - st;
|
||||
|
||||
int a = 0;
|
||||
}
|
||||
|
||||
void testHeader() {
|
||||
char* strHeader = R"(HTTP/1.1 200 OK
|
||||
Server: bfe/1.0.8.14
|
||||
Date: Fri, 02 Sep 2016 10:54:06 GMT
|
||||
Content-Type: text/html
|
||||
Last-Modified: Mon, 13 Jun 2016 02:50:04 GMT
|
||||
Connection: Keep-Alive
|
||||
Cache-Control: max-age=100, private, no-cache, no-store, proxy-revalidate, no-transform
|
||||
Pragma: no-cache
|
||||
Content-Encoding: gzip
|
||||
|
||||
)";
|
||||
RequestHeader Header;
|
||||
JCHttpHeader::request_header_parse(&Header, strHeader, strlen(strHeader));
|
||||
|
||||
JCHttpHeader httph(strHeader);
|
||||
JCHttpHeader::CacheContrl* pCC = httph.getCacheContrl();
|
||||
|
||||
VERIFYEQ(pCC->maxage, 100, "max-age");
|
||||
int a = 10;
|
||||
}
|
||||
|
||||
void testTime() {
|
||||
auto t1 = steady_clock::now();
|
||||
int a = 10;
|
||||
}
|
||||
|
||||
void testImgCache() {
|
||||
class TestDownloadMgr :public JCDownloadMgr {
|
||||
public:
|
||||
virtual void download(const char* p_pszURL, int p_nPriority,
|
||||
onProgressFunc p_ProgCb,
|
||||
onEndFunc p_CompleteCb,
|
||||
int p_nOptTimeout) {
|
||||
JCBuffer buf;
|
||||
buf.create(100);
|
||||
char* pBuf = buf.m_pPtr;
|
||||
pBuf[0] = 0x89; pBuf[1] = 0x50; pBuf[2] = 0x4e; pBuf[3] = 0x47;
|
||||
pBuf[4] = 0x0d; pBuf[5] = 0x0a; pBuf[6] = 0x1a; pBuf[7] = 0x0a;
|
||||
p_CompleteCb(buf, "", "", 0, 200, "");
|
||||
int a = 0;
|
||||
}
|
||||
};
|
||||
|
||||
JCServerFileCache svc;
|
||||
svc.setCachePath("d:/temp/cache/");
|
||||
svc.switchToApp("http://localhost/app/");
|
||||
svc.clearAllCachedFile();
|
||||
|
||||
JCDownloadMgr* pDmgr = new TestDownloadMgr();
|
||||
JCFileResManager fmgr(pDmgr);
|
||||
fmgr.setFileCache(&svc);
|
||||
JCServerFileCache::s_bSessionCacheType = JCServerFileCache::CT_AllwaysReload;
|
||||
JCFileRes* pFR = new JCFileRes(pDmgr, &fmgr);
|
||||
pFR->load("http://localhost/app/test", nullptr);
|
||||
VERIFYEQ((pFR->m_nLastAction == JCFileRes::UPDATECACHE), true, "png类型的图片文件要保存。");
|
||||
pFR->load("http://localhost/app/test", nullptr);
|
||||
VERIFYEQ((pFR->m_nLastAction == JCFileRes::UPDATECACHE), true, "临时图片文件再次请求还要下载。");
|
||||
JCServerFileCache::s_bSessionCacheType = JCServerFileCache::CT_ValidInCurProcess;
|
||||
}
|
||||
|
||||
void testreplaceurl() {
|
||||
JCDownloadMgr* pNL = JCDownloadMgr::getInstance();
|
||||
pNL->init(1);
|
||||
std::string strf = pNL->getFinalUrl("http://203.107.1.1/145720/d?host=httpdns.cs.nxagame.com");
|
||||
VERIFYEQ(strf, std::string("http://203.107.1.1/145720/d?host=httpdns.cs.nxagame.com"), "简单情况下不变");
|
||||
|
||||
strf = pNL->getFinalUrl("http://203.107.1.1/145720/d.png?host=httpdns.cs.nxagame.com");
|
||||
VERIFYEQ(strf, std::string("http://203.107.1.1/145720/d.png?host=httpdns.cs.nxagame.com"), "有扩展名的简单情况下不变");
|
||||
|
||||
pNL->setFinalReplacePath("vel", "6");
|
||||
strf = pNL->getFinalUrl("http://203.107.1.1/145720/d?host=httpdns.cs.nxagame.com");
|
||||
VERIFYEQ(strf, std::string("http://203.107.1.1/145720/d?host=httpdns.cs.nxagame.com"), "设置替换的情况下不变");
|
||||
|
||||
strf = pNL->getFinalUrl("http://203.107.1.1/145720/d.png?host=httpdns.cs.nxagame.com");
|
||||
VERIFYEQ(strf, std::string("http://203.107.1.1/145720/d.png?host=httpdns.cs.nxagame.com"), "设置替换且有扩展名的情况下不变");
|
||||
|
||||
pNL->setFinalReplacePath("vel", "6");
|
||||
strf = pNL->getFinalUrl("http://203.107.1.1/145720/vel/d?host=httpdns.cs.nxagame.com");
|
||||
VERIFYEQ(strf, std::string("http://203.107.1.1/145720/6/d?host=httpdns.cs.nxagame.com"), "设置替换的情况下不变");
|
||||
|
||||
strf = pNL->getFinalUrl("http://203.107.1.1/145720/vel/d.png?host=httpdns.cs.nxagame.com");
|
||||
VERIFYEQ(strf, std::string("http://203.107.1.1/145720/6/d.png?host=httpdns.cs.nxagame.com"), "");
|
||||
|
||||
JCDownloadMgr::delInstance();
|
||||
}
|
||||
|
||||
//这个是主测试函数,要在这里调用所有的测试函数
|
||||
void testMain(){
|
||||
testreplaceurl();
|
||||
testHeader();
|
||||
testDownload();
|
||||
testPost();
|
||||
testDownloadBigfile();
|
||||
|
||||
testDCC();
|
||||
testLoadCached();
|
||||
testSessionID();
|
||||
testSessionFileUpdate();
|
||||
testSessionFileUpdate();
|
||||
testImgCache();
|
||||
}
|
||||
//添加测试用例,第一个参数是主函数,第二个是测试用例的说明,也可以可以用来执行测试用例的过滤。
|
||||
ADDTESTCASE(testMain,"cache测试");
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,21 @@
|
||||
#ifdef _TEST_
|
||||
#include "../JCTestManager.h"
|
||||
#include <util/JCCommonMethod.h>
|
||||
|
||||
using namespace laya;
|
||||
|
||||
/*
|
||||
* 这里的namespace并没有特殊要求,因为是全局函数,为了防止冲突,才加上一个namespace,对最终的测试没有影响。
|
||||
*/
|
||||
namespace cmdDispTest{
|
||||
void test1(){
|
||||
}
|
||||
|
||||
//这个是主测试函数,要在这里调用所有的测试函数
|
||||
void testMain(){
|
||||
test1();
|
||||
}
|
||||
//添加测试用例,第一个参数是主函数,第二个是测试用例的说明,也可以可以用来执行测试用例的过滤。
|
||||
ADDTESTCASE(testMain,"cmdDispatcherTest");
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,52 @@
|
||||
#ifdef _TEST_
|
||||
#include "../JCTestManager.h"
|
||||
#include <SaveData/JCContextSaveData.h>
|
||||
#include <util/Log.h>
|
||||
|
||||
using namespace laya;
|
||||
|
||||
/*
|
||||
* 这里的namespace并没有特殊要求,因为是全局函数,为了防止冲突,才加上一个namespace,对最终的测试没有影响。
|
||||
*/
|
||||
namespace testContextData{
|
||||
void test1()
|
||||
{
|
||||
/*
|
||||
int ret = hexStringToInt("ff");
|
||||
VERIFYEQ(ret, 0xff, "hexStringToInt 0xff");
|
||||
int ret1 = hexStringToInt("0xff");
|
||||
VERIFYEQ(ret1, 0, "不允许包含0x");
|
||||
*/
|
||||
JCContextSaveData* pSaveData = new JCContextSaveData();
|
||||
pSaveData->save();
|
||||
pSaveData->m_pCurrentContextData->nLineWidth = 100;
|
||||
|
||||
pSaveData->save();
|
||||
pSaveData->m_pCurrentContextData->nFillStyle = 85;
|
||||
pSaveData->save();
|
||||
pSaveData->m_pCurrentContextData->nAlpha = 0.5;
|
||||
|
||||
pSaveData->restore();
|
||||
|
||||
VERIFYEQ(pSaveData->m_pCurrentContextData->nAlpha, 1.0f, "restore第一次后 alpha = 0");
|
||||
VERIFYEQ(pSaveData->m_pCurrentContextData->nFillStyle, 85, "restore第一次后 fillStyle = 85");
|
||||
VERIFYEQ(pSaveData->m_pCurrentContextData->nLineWidth, 100, "restore第一次后 lineWidth = 100");
|
||||
|
||||
pSaveData->restore();
|
||||
|
||||
VERIFYEQ(pSaveData->m_pCurrentContextData->nFillStyle, (int)0xffffffff, "restore第一次后 fillStyle = 0xffffffff");
|
||||
VERIFYEQ(pSaveData->m_pCurrentContextData->nLineWidth, 100, "restore后 lineWidth = 100");
|
||||
|
||||
pSaveData->restore();
|
||||
VERIFYEQ(pSaveData->m_pCurrentContextData->nLineWidth, 1, "restore后 lineWidth = 1");
|
||||
|
||||
}
|
||||
|
||||
//这个是主测试函数,要在这里调用所有的测试函数
|
||||
void testMain(){
|
||||
test1();
|
||||
}
|
||||
//添加测试用例,第一个参数是主函数,第二个是测试用例的说明,也可以可以用来执行测试用例的过滤。
|
||||
ADDTESTCASE(testMain,"ContextSave");
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,105 @@
|
||||
#ifdef _TEST_
|
||||
#include "../JCTestManager.h"
|
||||
#include <util/JCCommonMethod.h>
|
||||
#include <fileSystem/JCFileSystem.h>
|
||||
#include <util/Log.h>
|
||||
|
||||
using namespace laya;
|
||||
|
||||
/*
|
||||
* 这里的namespace并没有特殊要求,因为是全局函数,为了防止冲突,才加上一个namespace,对最终的测试没有影响。
|
||||
*/
|
||||
namespace diskRWTest{
|
||||
std::string getAFile(const char*& pDt) {
|
||||
std::string ret;
|
||||
while ((*pDt == '\r' || *pDt == '\n') && *pDt != 0) {
|
||||
pDt++;
|
||||
}
|
||||
const char* pSt = pDt;
|
||||
while (*pDt != '\r' && *pDt != '\n' && *pDt != 0 ) { pDt++; }
|
||||
if (pDt - pSt >= 1) {
|
||||
ret.append(pSt, pDt - pSt);
|
||||
return ret;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
void readSomeFile(const char* idx, const char* base,bool bRead) {
|
||||
std::string fb = readFileSync1(idx, NULL);
|
||||
const char* pDt = fb.c_str();
|
||||
std::string absfn = base;
|
||||
std::vector<std::string> allfiles;
|
||||
char* pReadBuff = nullptr;
|
||||
static const int bufsz =1024 * 1024;
|
||||
if (bRead) {
|
||||
pReadBuff = new char[bufsz];
|
||||
}
|
||||
while (*pDt != 0) {
|
||||
|
||||
std::string fn = getAFile(pDt);
|
||||
if (fn.length() > 0) {
|
||||
absfn = base;
|
||||
allfiles.push_back(absfn + fn);
|
||||
}
|
||||
}
|
||||
long readsz = 0;
|
||||
int fc1 = 0;
|
||||
for (int n = 0; n < (bRead?1:4); n++){
|
||||
int num = 0, opennum = 0;
|
||||
auto sttm = tmGetCurms();
|
||||
for (auto i : allfiles) {
|
||||
FILE* fp = fopen(i.c_str(), "rb");
|
||||
if (fp) {
|
||||
opennum++;
|
||||
if (bRead) {
|
||||
fseek(fp, 0, SEEK_END);
|
||||
int len = ftell(fp);
|
||||
readsz += len;
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
while (len > 0) {
|
||||
len -= fread(pReadBuff, 1, bufsz, fp);
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
else {
|
||||
LOGE("Failed:%s", i.c_str());
|
||||
}
|
||||
num++;
|
||||
}
|
||||
if (bRead) {
|
||||
int dt = (int)(tmGetCurms() - sttm);
|
||||
LOGE("Read:%dK,TM:%d,%fM/s", (int)(readsz/1024),dt,(float)(readsz/1024/1.024f/dt));
|
||||
}
|
||||
else {
|
||||
LOGE("NUM:%d,OPENED:%d,TM:%d", num, opennum, (int)(tmGetCurms() - sttm));
|
||||
}
|
||||
}
|
||||
if (pReadBuff) {
|
||||
delete[] pReadBuff;
|
||||
}
|
||||
}
|
||||
void test1(){
|
||||
LOGE("普通:");
|
||||
readSomeFile("/sdcard/temp/testdisk/1/allfiles.txt", "/sdcard/temp/testdisk/1",false);
|
||||
LOGE("单目录:");
|
||||
readSomeFile("/sdcard/temp/testdisk/2/allfiles.txt", "/sdcard/temp/testdisk/2",false);
|
||||
LOGE("单文件:");
|
||||
readSomeFile("/sdcard/temp/testdisk/3/allfiles.txt", "/sdcard/temp/testdisk/3", false);
|
||||
LOGE("分层目录:");
|
||||
readSomeFile("/sdcard/temp/testdisk/4/allfiles.txt", "/sdcard/temp/testdisk/4", false);
|
||||
LOGE("普通读取:");
|
||||
//while(true)
|
||||
readSomeFile("/sdcard/temp/testdisk/1/allfiles.txt", "/sdcard/temp/testdisk/1", true);
|
||||
LOGE("大文件读取:");
|
||||
readSomeFile("/sdcard/temp/testdisk/3/allfiles.txt", "/sdcard/temp/testdisk/3", true);
|
||||
}
|
||||
|
||||
//这个是主测试函数,要在这里调用所有的测试函数
|
||||
void testMain(){
|
||||
test1();
|
||||
}
|
||||
//添加测试用例,第一个参数是主函数,第二个是测试用例的说明,也可以可以用来执行测试用例的过滤。
|
||||
ADDTESTCASE(testMain,"diskrw");
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,39 @@
|
||||
#ifdef _TEST_
|
||||
#include "../JCTestManager.h"
|
||||
#include <util/JCCommonMethod.h>
|
||||
#include <resource/text/JCFontInfo.h>
|
||||
|
||||
using namespace laya;
|
||||
|
||||
/*
|
||||
* 这里的namespace并没有特殊要求,因为是全局函数,为了防止冲突,才加上一个namespace,对最终的测试没有影响。
|
||||
*/
|
||||
namespace fontParserTest{
|
||||
void test1(){
|
||||
JCFontInfo fi;
|
||||
fi.parse("normal 100 32px Arial 1 #00ff00 1 #ff0000");
|
||||
bool bfok = (strcmp(fi.m_sFamily, "Arial")==0);
|
||||
VERIFYEQ(bfok, true, "");
|
||||
VERIFYEQ((int)fi.m_nWeight, 100, "");
|
||||
VERIFYEQ(fi.m_nBorderSize, 1, "");
|
||||
|
||||
fi.parse("normal 100 16px Arial b 1 #ff0000 1 #00ff00 ");
|
||||
VERIFYEQ((int)fi.m_nWeight, 100, "");
|
||||
VERIFYEQ((int)fi.m_nFontSize, 16, "");
|
||||
fi.parse(" ");
|
||||
fi.parse("");
|
||||
fi.parse("normal 1300 28px Microsoft_YaHei 1 #444444 0");
|
||||
VERIFYEQ((int)fi.m_nWeight, 400, "weight必须是固定的几种。");
|
||||
fi.parse("normal normal 18px 宋体 2 #000000 0 #000000");
|
||||
VERIFYEQ(strcmp(fi.m_sFamily, "宋体"), 0, "");
|
||||
VERIFYEQ((int)fi.m_nFontSize, 18, "");
|
||||
}
|
||||
|
||||
//这个是主测试函数,要在这里调用所有的测试函数
|
||||
void testMain(){
|
||||
test1();
|
||||
}
|
||||
//添加测试用例,第一个参数是主函数,第二个是测试用例的说明,也可以可以用来执行测试用例的过滤。
|
||||
ADDTESTCASE(testMain,"testFontParser");
|
||||
}
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,65 @@
|
||||
#ifdef _TEST_
|
||||
/*
|
||||
渲染流程的测试。
|
||||
渲染流程是可拆分的
|
||||
|
||||
用来拆分项目
|
||||
*/
|
||||
|
||||
#include "../JCTestManager.h"
|
||||
#include <Windows.h>
|
||||
#include "../../WindowsEnv/winWindows.h"
|
||||
#include "../../WindowsEnv/gles.h"
|
||||
#include <misc/JCWorkerThread.h>
|
||||
#include <JCIGLRender.h>
|
||||
#include <functional>
|
||||
|
||||
/*
|
||||
1.能在主线程创建一个gles环境,进行原始的渲染
|
||||
2.能在一个新开的线程中打开一个gles渲染
|
||||
3.能渲染3D场景
|
||||
4.能获得渲染结果
|
||||
*/
|
||||
|
||||
using namespace laya;
|
||||
|
||||
namespace renderFrameTest{
|
||||
void _1_testRender_GLTread(){
|
||||
class TestRender:public JCIGLRender{
|
||||
public:
|
||||
float fR = 0.0f;
|
||||
int nFrmNum = 0;
|
||||
std::function<void()> funcExit;
|
||||
TestRender(std::function<void()> f) {
|
||||
funcExit = f;
|
||||
}
|
||||
virtual void onGLReady(){
|
||||
}
|
||||
|
||||
virtual int renderFrame(long p_nCurrentFrame,bool){
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
fR += 0.1f;
|
||||
if (fR > 1.0f)fR = 0.0f;
|
||||
glClearColor(fR,1.0f,1.0f,1.0f);
|
||||
nFrmNum++;
|
||||
if (nFrmNum > 100) {
|
||||
funcExit();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
virtual void freeGLRes() {
|
||||
}
|
||||
};
|
||||
|
||||
GLEnvThread gl;
|
||||
TestRender render([&gl](){ gl.m_pWindows->close(); });
|
||||
gl.init(&render,800,600);
|
||||
winWindows::handleMessage(NULL);
|
||||
}
|
||||
void testMain(){
|
||||
_1_testRender_GLTread();
|
||||
}
|
||||
|
||||
ADDTESTCASE(testMain,"renderFrameTest");
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,185 @@
|
||||
#ifdef _TEST_
|
||||
/*
|
||||
渲染流程的测试。
|
||||
渲染流程是可拆分的
|
||||
|
||||
用来拆分项目
|
||||
*/
|
||||
|
||||
#include "../JCTestManager.h"
|
||||
#include <Windows.h>
|
||||
#include "../../WindowsEnv/winWindows.h"
|
||||
#include "../../WindowsEnv/gles.h"
|
||||
#include <misc/JCWorkerThread.h>
|
||||
#include <JCIGLRender.h>
|
||||
#include <functional>
|
||||
#include "MonkVG/include/MonkVG/openvg.h"
|
||||
#include "MonkVG/include/MonkVG/vgext.h"
|
||||
#include "MonkVG/include/MonkVG/vgu.h"
|
||||
#include <util/Log.h>
|
||||
#include "mkContext.h"
|
||||
/*
|
||||
*/
|
||||
|
||||
using namespace laya;
|
||||
|
||||
namespace renderSVGTest{
|
||||
void _1_testSVGRender_fillcolor(){
|
||||
class TestSVGRender:public JCIGLRender{
|
||||
public:
|
||||
float fR = 0.0f;
|
||||
int nFrmNum = 0;
|
||||
VGPaint m_Paint;
|
||||
VGPaint m_StrokePaint;
|
||||
VGPath m_Path;
|
||||
MkVGContext* vg = nullptr;
|
||||
std::function<void()> funcExit;
|
||||
TestSVGRender(std::function<void()> f) {
|
||||
funcExit = f;
|
||||
}
|
||||
|
||||
void init() {
|
||||
vg = new MkVGContext(800, 600, VG_RENDERING_BACKEND_TYPE_OPENGLES20,NULL,NULL,NULL);
|
||||
m_Paint = vg->CreatePaint();
|
||||
vg->SetPaint(m_Paint, VG_FILL_PATH);//填充
|
||||
VGfloat color[4] = {1.0f,0.0f,0.0f,1.0f};
|
||||
vg->SetParameterfv(m_Paint, VG_PAINT_COLOR, 4, color);
|
||||
|
||||
m_StrokePaint = vg->CreatePaint();
|
||||
vg->SetPaint(m_StrokePaint, VG_STROKE_PATH);
|
||||
VGfloat colstroke[4] = { 0,1.0f,0,1.0f };
|
||||
vg->SetParameterfv(m_StrokePaint, VG_PAINT_COLOR, 4, colstroke);
|
||||
|
||||
m_Path = vg->CreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1, 0, 0, 0, VG_PATH_CAPABILITY_ALL);
|
||||
//vguRoundRect(m_Path, 10, 10, 100, 300,10,10);
|
||||
//VGfloat pts[] = { 155, 231, 485, 85, 617, 473, 865, 340,155, 231 }; //简单交叉
|
||||
//复杂形状,不交叉
|
||||
VGfloat pts[] = {241,150,362,151,356,180,265,187,270,205,349,202,349,230,262,231,267,306,235,309};
|
||||
//vguPolygon(m_Path, pts, sizeof(pts)/sizeof(float)/2, VG_TRUE);
|
||||
int a = 0;
|
||||
}
|
||||
|
||||
virtual void onGLReady(){
|
||||
init();
|
||||
}
|
||||
|
||||
virtual void renderFrame(long p_nCurrentFrame,bool){
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glClearColor(0.5,.5f,.5f,1.0f);
|
||||
//render path
|
||||
auto sttm = tmGetCurms();
|
||||
for (int i = 0; i < 100000; i++) {
|
||||
vg->Seti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
|
||||
vg->LoadIdentity();
|
||||
VGfloat mat[] = {1,0,0, 0,-1.0f,600, 0,0,1};
|
||||
vg->LoadMatrix(mat);
|
||||
vg->SetPaint(m_Paint, VG_FILL_PATH);
|
||||
vg->SetPaint(m_StrokePaint, VG_STROKE_PATH);
|
||||
vg->Setf(VG_STROKE_LINE_WIDTH, 3.0f);
|
||||
vg->DrawPath(m_Path, VG_FILL_PATH | VG_STROKE_PATH);
|
||||
}
|
||||
//目前是<1000
|
||||
LOGE("---dt=%d",(int)(tmGetCurms()-sttm));
|
||||
nFrmNum++;
|
||||
if (nFrmNum > 1000) {
|
||||
funcExit();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void invalidGLRes() {
|
||||
}
|
||||
virtual void freeGLRes() {
|
||||
}
|
||||
};
|
||||
|
||||
GLEnvThread gl;
|
||||
TestSVGRender render([&gl](){ gl.m_pWindows->close(); });
|
||||
gl.init(&render,800,600);
|
||||
winWindows::handleMessage(NULL);
|
||||
}
|
||||
|
||||
void _1_testSVGRender_fillLinearG() {
|
||||
class TestSVGRender :public JCIGLRender {
|
||||
public:
|
||||
int nFrmNum = 0;
|
||||
VGPaint m_Paint;
|
||||
VGPaint m_StrokePaint;
|
||||
VGPath m_Path;
|
||||
MkVGContext* vg = nullptr;
|
||||
std::function<void()> funcExit;
|
||||
TestSVGRender(std::function<void()> f) {
|
||||
funcExit = f;
|
||||
}
|
||||
|
||||
void init() {
|
||||
vg = new MkVGContext(800, 600, VG_RENDERING_BACKEND_TYPE_OPENGLES20,NULL,NULL,NULL);
|
||||
m_Paint = vg->CreatePaint();
|
||||
vg->SetPaint(m_Paint, VG_FILL_PATH);//填充
|
||||
VGfloat pos[4] = { 100,0,200,0};//x0,y0,x1,y1。 如果是放射性的话,就是 cx,cy,fx,fy,r
|
||||
const static int NUM_STOPS = 2;
|
||||
VGfloat stops[5*NUM_STOPS];
|
||||
vg->SetParameterfv(m_Paint, VG_PAINT_LINEAR_GRADIENT, 4, pos);
|
||||
vg->SetParameterfv(m_Paint, VG_PAINT_COLOR_RAMP_STOPS, 5 * NUM_STOPS, stops);
|
||||
//vgSetParameteri(m_Paint, VG_PAINT_COLOR_RAMP_SPREAD_MODE, VG_SPREAD_MODE_PAD);
|
||||
|
||||
|
||||
m_StrokePaint = vg->CreatePaint();
|
||||
vg->SetPaint(m_StrokePaint, VG_STROKE_PATH);
|
||||
VGfloat colstroke[4] = { 0,1.0f,0,1.0f };
|
||||
vg->SetParameterfv(m_StrokePaint, VG_PAINT_COLOR, 4, colstroke);
|
||||
|
||||
m_Path = vg->CreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1, 0, 0, 0, VG_PATH_CAPABILITY_ALL);
|
||||
//vguRoundRect(m_Path, 10, 10, 100, 300,10,10);
|
||||
//VGfloat pts[] = { 155, 231, 485, 85, 617, 473, 865, 340,155, 231 }; //简单交叉
|
||||
//复杂形状,不交叉
|
||||
VGfloat pts[] = { 241,150,362,151,356,180,265,187,270,205,349,202,349,230,262,231,267,306,235,309 };
|
||||
//vguPolygon(m_Path, pts, sizeof(pts) / sizeof(float) / 2, VG_TRUE);
|
||||
int a = 0;
|
||||
}
|
||||
|
||||
virtual void onGLReady() {
|
||||
init();
|
||||
}
|
||||
|
||||
virtual void renderFrame(long p_nCurrentFrame, bool) {
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glClearColor(0.5, .5f, .5f, 1.0f);
|
||||
//render path
|
||||
auto sttm = tmGetCurms();
|
||||
for (int i = 0; i < 100000; i++) {
|
||||
vg->Seti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
|
||||
vg->LoadIdentity();
|
||||
VGfloat mat[] = { 1,0,0, 0,-1.0f,600, 0,0,1 };
|
||||
vg->LoadMatrix(mat);
|
||||
vg->SetPaint(m_Paint, VG_FILL_PATH);
|
||||
vg->SetPaint(m_StrokePaint, VG_STROKE_PATH);
|
||||
vg->Setf(VG_STROKE_LINE_WIDTH, 3.0f);
|
||||
vg->DrawPath(m_Path, VG_FILL_PATH | VG_STROKE_PATH);
|
||||
}
|
||||
//目前是<1000
|
||||
LOGE("---dt=%d", (int)(tmGetCurms() - sttm));
|
||||
nFrmNum++;
|
||||
if (nFrmNum > 1000) {
|
||||
funcExit();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void invalidGLRes() {
|
||||
}
|
||||
virtual void freeGLRes() {
|
||||
}
|
||||
};
|
||||
|
||||
GLEnvThread gl;
|
||||
TestSVGRender render([&gl]() { gl.m_pWindows->close(); });
|
||||
gl.init(&render, 800, 600);
|
||||
winWindows::handleMessage(NULL);
|
||||
}
|
||||
void testMain(){
|
||||
_1_testSVGRender_fillLinearG();
|
||||
_1_testSVGRender_fillcolor();
|
||||
}
|
||||
|
||||
ADDTESTCASE(testMain,"renderSVGTest");
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,25 @@
|
||||
#ifdef _TEST_
|
||||
#include "../JCTestManager.h"
|
||||
#include <util/JCCommonMethod.h>
|
||||
|
||||
using namespace laya;
|
||||
|
||||
/*
|
||||
* 这里的namespace并没有特殊要求,因为是全局函数,为了防止冲突,才加上一个namespace,对最终的测试没有影响。
|
||||
*/
|
||||
namespace urlTest{
|
||||
void test1(){
|
||||
int ret = hexStringToInt("ff");
|
||||
VERIFYEQ(ret, 0xff, "hexStringToInt 0xff");
|
||||
int ret1 = hexStringToInt("0xff");
|
||||
VERIFYEQ(ret1, 0, "不允许包含0x");
|
||||
}
|
||||
|
||||
//这个是主测试函数,要在这里调用所有的测试函数
|
||||
void testMain(){
|
||||
test1();
|
||||
}
|
||||
//添加测试用例,第一个参数是主函数,第二个是测试用例的说明,也可以可以用来执行测试用例的过滤。
|
||||
ADDTESTCASE(testMain,"简单测试用例");
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,173 @@
|
||||
#ifdef _TEST_
|
||||
#include "../JCTestManager.h"
|
||||
#include <util/JCLayaUrl.h>
|
||||
|
||||
/*
|
||||
标准
|
||||
resolve 函数
|
||||
如果第二个参数带?则不能被去掉。
|
||||
TODO
|
||||
url要先encode么,例如空格怎么办
|
||||
*/
|
||||
|
||||
using namespace laya;
|
||||
|
||||
namespace urlTest1 {
|
||||
/*
|
||||
*/
|
||||
/*
|
||||
void testURL1(){
|
||||
JCUrl url;
|
||||
//url.parsePath("abc");
|
||||
//VERIFYEQ((int)url.m_vPath.size(),1,"");
|
||||
url.parse("http://a.b.c/a b.html");//不要非法
|
||||
url.parse("http://a.b.c/a.html");//不要非法
|
||||
|
||||
url.parsePath("./b/c/../d/a.txt");
|
||||
VERIFYEQ(url.m_vPath[0],std::string("b"),".被忽略");
|
||||
url.parsePath("../b/c/../d/a.txt");
|
||||
VERIFYEQ(url.m_vPath[0],std::string(".."),"..不能被忽略");
|
||||
VERIFYEQ(url.m_strPath,std::string("../b/d/a.txt"),"");
|
||||
url.parsePath("a/b/c/../d/a.txt");
|
||||
VERIFYEQ(url.m_strPath,std::string("a/b/d/a.txt"),"");
|
||||
url.parsePath("/a/b/c/../d/a.txt");
|
||||
VERIFYEQ(url.m_vPath[0],std::string(""),"从根目录开始的路径,第一个路径为空");
|
||||
VERIFYEQ(url.m_strPath,std::string("/a/b/d/a.txt"),"");
|
||||
|
||||
url.parse(" http://guo:zh@laya.com:8888/a/b.c/a.html?xx=xx#s");
|
||||
VERIFYEQ(url.m_Pass,std::string("zh"),"");
|
||||
VERIFYEQ(url.m_Port,std::string("8888"),"");
|
||||
url.parse(" http://guo@laya.com/a/b.c/a.html?xx=xx#s");
|
||||
VERIFYEQ(url.m_User,std::string("guo"),"");
|
||||
VERIFYEQ(url.m_Port,std::string(""),"");
|
||||
|
||||
url.parse(" http://guo:zh@laya.com:8888/a/b.c/a.html?xx=xx#s&p=a/index.html");
|
||||
VERIFYEQ(url.m_Query, std::string("?xx=xx#s&p=a/index.html"),"");
|
||||
VERIFYEQ((int)url.m_vPath.size(),3,"");
|
||||
|
||||
url.parse("http://a.b.c/../.././p/q/r.a.txt");
|
||||
url.parse("http://a.b.c/a/b/../../p/q/r.a.txt");
|
||||
url.parse(" http://guo:zh@laya.com/a/b.c/a.html?xx=xx#s");
|
||||
VERIFYEQ(url.m_Query, std::string("?xx=xx#s"),"search的内容需要包含?");
|
||||
url.parse("http://guo@k.k.com/a.b.c/c/?");
|
||||
VERIFYEQ((int)url.m_Query.size(),1,"?后面没有内容,长度应该为1,即?");
|
||||
VERIFYEQ(url.m_vPath[url.m_vPath.size()-1],std::string(""),"如果没有文件,则路径的最后一个为空");
|
||||
//VERIFYEQ((int)url.m_Query.len,0,"?后面没有内容,长度应该为0");
|
||||
url.parse("https://a.b.c/a.txt");
|
||||
VERIFYEQ(url.toString(),std::string("https://a.b.c/a.txt"),"需要支持https");
|
||||
|
||||
url.parse("klksdl");
|
||||
url.parse("");
|
||||
url.parse(NULL);
|
||||
url.parse("ftp://k.com/a.txt");
|
||||
VERIFYEQ((int)url.m_vPath[0].length(),5,"a.txt的长度应该为5");
|
||||
url.parse("file:///c:/a.txt");
|
||||
VERIFYEQ( url.m_vPath[0],std::string("c:"),"");
|
||||
VERIFYEQ( url.m_vPath[1],std::string("a.txt"),"");
|
||||
url.parse("file:///data/data/v.txt");
|
||||
VERIFYEQ( url.m_vPath[0],std::string("data"),"有协议的都是从/开始,不用考虑根目录的问题。");
|
||||
VERIFYEQ( url.m_vPath[1],std::string("data"),"");
|
||||
VERIFYEQ( url.m_vPath[2],std::string("v.txt"),"");
|
||||
url.parse("file://10.10.20.31/share/a.txt");
|
||||
VERIFYEQ( url.m_Host, std::string("10.10.20.31"),"");
|
||||
VERIFYEQ( url.m_vPath[0], std::string("share"),"");
|
||||
url.parse("file://guo@10.10.20.31/share/a.txt");
|
||||
VERIFYEQ( url.m_User, std::string("guo"),"");
|
||||
VERIFYEQ( url.m_Host, std::string("10.10.20.31"),"");
|
||||
|
||||
url.parse("file:///C:\\a\\b\\c.html");
|
||||
VERIFYEQ( url.m_vPath[0],std::string("C:"),"要支持\\");
|
||||
VERIFYEQ( url.m_vPath[1],std::string("a"),"要支持\\");
|
||||
VERIFYEQ( url.m_vPath[2],std::string("b"),"要支持\\");
|
||||
url.parse("file:///C:\\c.html");
|
||||
VERIFYEQ( url.m_vPath[0],std::string("C:"),"要支持\\");
|
||||
VERIFYEQ( url.m_vPath[1],std::string("c.html"),"要支持\\");
|
||||
url.parse("file:///C:\\a\\\\b\\c.html");
|
||||
VERIFYEQ( url.m_vPath[0],std::string("C:"),"要支持\\\\");
|
||||
VERIFYEQ( url.m_vPath[1],std::string("a"),"要支持\\\\");
|
||||
VERIFYEQ( url.m_vPath[2],std::string("b"),"要支持\\\\");
|
||||
|
||||
|
||||
url.parse("c:/a/b/c.txt");
|
||||
VERIFYEQ(url.m_strPath,std::string("file:///c:/a/b"),"需要支持直接写目录没有file://的url");
|
||||
url.parse("/a/b/c.txt");
|
||||
VERIFYEQ(url.m_strPath,std::string("file:///a/b"),"需要支持直接写目录没有file://的url");
|
||||
url.parse("c:/a.txt");
|
||||
VERIFYEQ(url.m_strPath,std::string("file:///c:"),"需要支持直接写目录没有file://的url");
|
||||
url.parse("/a.txt");
|
||||
VERIFYEQ(url.m_strPath,std::string("file:///"),"需要支持直接写目录没有file://的url");
|
||||
}
|
||||
|
||||
void testResolve1(){
|
||||
std::string ret;
|
||||
JCUrl url;
|
||||
url.parse("http://laya.com:8888/a/b/c/d.html");
|
||||
ret = url.resolve("d/e/f.html");
|
||||
VERIFYEQ( ret, std::string("http://laya.com:8888/a/b/c/d/e/f.html"),"");
|
||||
ret = url.resolve("/d/e/f.html");
|
||||
VERIFYEQ( ret, std::string("http://laya.com:8888/d/e/f.html"),"");
|
||||
|
||||
ret = url.resolve("f.html");
|
||||
VERIFYEQ( ret, std::string("http://laya.com:8888/a/b/c/f.html"),"");
|
||||
|
||||
url.parse("http://laya.com:8888/d.html");
|
||||
ret = url.resolve("f.html");
|
||||
VERIFYEQ( ret, std::string("http://laya.com:8888/f.html"),"");
|
||||
|
||||
url.parse("file:///c:/a/b.html");
|
||||
ret = url.resolve("c.html");
|
||||
VERIFYEQ( ret, std::string("file:///c:/a/c.html"),"");
|
||||
|
||||
url.parse("file:///c:/b.html");
|
||||
ret = url.resolve("c.html");
|
||||
VERIFYEQ( ret, std::string("file:///c:/c.html"),"");
|
||||
|
||||
url.parse("file:///c:/b.html");
|
||||
ret = url.resolve("d:/c.html");
|
||||
VERIFYEQ( ret, std::string("file:///d:/c.html"),"");
|
||||
|
||||
url.parse("file:///c:/a/b.html");
|
||||
ret = url.resolve("/c.html");
|
||||
VERIFYEQ( ret, std::string("file:///c:/c.html"),"");
|
||||
|
||||
url.parse("file:///c:/a/b.html");
|
||||
ret = url.resolve("../c.html");
|
||||
VERIFYEQ( ret, std::string("file:///c:/a/../c.html"),"第一级就是..的现在还没做。应该不会有什么影响吧?");
|
||||
|
||||
url.parse("file:///c:/a/b.html");
|
||||
ret = url.resolve("file:///d:/c.html");
|
||||
VERIFYEQ( ret, std::string("file:///d:/c.html"),"");
|
||||
|
||||
url.parse("c:/a/b.txt");
|
||||
ret = url.resolve("c.txt");
|
||||
VERIFYEQ( ret, std::string("file:///c:/a/c.txt"),"");
|
||||
|
||||
url.parse("file:///C:\\c.html");
|
||||
ret = url.resolve("file:///C:\\a\\\\b\\c.html");
|
||||
VERIFYEQ( ret , std::string("file:///C:/a/b/c.html"),"即使是绝对路径,也要整理一下");
|
||||
|
||||
url.parse("http://a.b.c/a/b.html");
|
||||
ret = url.resolve("http://a.b/a.html?a=b");
|
||||
VERIFYEQ(ret, std::string("http://a.b/a.html?a=b"),"");
|
||||
|
||||
ret = url.resolve("c.html?b=c");
|
||||
VERIFYEQ( ret, std::string("http://a.b.c/a/c.html?b=c"),"");
|
||||
}
|
||||
void testResolve2(){
|
||||
}
|
||||
|
||||
void testJSLocation(){
|
||||
}
|
||||
|
||||
void testMain(){
|
||||
//这个执行的时候,会调用所有的测试函数
|
||||
testURL1();
|
||||
testResolve1();
|
||||
testResolve2();
|
||||
testJSLocation();
|
||||
}
|
||||
|
||||
ADDTESTCASE(testMain,"URL相关测试");
|
||||
*/
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,110 @@
|
||||
#ifdef _TEST_
|
||||
#include "JCTestManager.h"
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include <stdarg.h>
|
||||
#include <thread>
|
||||
#include <util/JCCommonMethod.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
template<>
|
||||
std::string JCTestMgr::toString(char t){
|
||||
char str[8];
|
||||
sprintf(str,"%d",(int)t);
|
||||
return str;
|
||||
}
|
||||
|
||||
template<>
|
||||
std::string JCTestMgr::toString(short t){
|
||||
char str[8];
|
||||
sprintf(str,"%d",(int)t);
|
||||
return str;
|
||||
}
|
||||
|
||||
template<>
|
||||
std::string JCTestMgr::toString(int t){
|
||||
char str[16];
|
||||
sprintf(str,"%d",(int)t);
|
||||
return str;
|
||||
}
|
||||
|
||||
template<>
|
||||
std::string JCTestMgr::toString(unsigned int t) {
|
||||
char str[16];
|
||||
sprintf(str, "%d", (int)t);
|
||||
return str;
|
||||
}
|
||||
|
||||
template<>
|
||||
std::string JCTestMgr::toString(float t){
|
||||
char str[32];
|
||||
sprintf(str,"%f",t);
|
||||
return str;
|
||||
}
|
||||
|
||||
template<>
|
||||
std::string JCTestMgr::toString(bool t){
|
||||
char str[32];
|
||||
sprintf(str,"%s",t?"true":"false");
|
||||
return str;
|
||||
}
|
||||
|
||||
template<>
|
||||
std::string JCTestMgr::toString(std::string t){
|
||||
return t;
|
||||
}
|
||||
|
||||
void JCTestMgr::output(const char* szFormat, ...){
|
||||
char szBuff[1024];
|
||||
va_list arg;
|
||||
va_start(arg, szFormat);
|
||||
#ifdef WIN32
|
||||
_vsnprintf(szBuff, sizeof(szBuff), szFormat, arg);
|
||||
#else
|
||||
vsnprintf(szBuff, sizeof(szBuff), szFormat, arg);
|
||||
#endif
|
||||
va_end(arg);
|
||||
#ifdef WIN32
|
||||
OutputDebugString(szBuff);
|
||||
#endif
|
||||
printf(szBuff);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void JCTestMgr::printResult( RunContext& p_RunCtx ){
|
||||
if( p_RunCtx.bOK){
|
||||
output("OK:%s\n", p_RunCtx.strDesc.c_str());//ÂÌÉ«
|
||||
}else{
|
||||
output("%s(%d): error: %s\n", p_RunCtx.pszFile?p_RunCtx.pszFile:"unkown file", p_RunCtx.nLine, p_RunCtx.strDesc.c_str());//ºìÉ«
|
||||
}
|
||||
}
|
||||
|
||||
void JCTestMgr::run(const char* pRunTestCase){
|
||||
for( int i=0,sz=m_AllTestCases.size(); i<sz; i++){
|
||||
JCTestCase& curTest= m_AllTestCases[i];
|
||||
if(pRunTestCase && strcmp(pRunTestCase, curTest.strDesc.c_str())!=0)
|
||||
continue;
|
||||
output(" %s\n",curTest.strDesc.c_str());
|
||||
output("=============================================\n");
|
||||
curTest.testFunc();
|
||||
}
|
||||
|
||||
//´òÓ¡×îÖÕ½á¹û
|
||||
output("²âÊÔ½á¹û:%d/%d\n", m_nOKNum, m_nTotalNum );
|
||||
}
|
||||
|
||||
void Sleep(int ms) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
|
||||
}
|
||||
|
||||
void WaitUtil(bool* pCond, int timeout) {
|
||||
auto tm = laya::tmGetCurms();
|
||||
while (!*pCond) {
|
||||
if (timeout > 0 && (laya::tmGetCurms() - tm) > timeout)
|
||||
break;
|
||||
Sleep(100);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,143 @@
|
||||
#ifdef _TEST_
|
||||
#ifndef __TESTMANAGER_H_0115__
|
||||
#define __TESTMANAGER_H_0115__
|
||||
|
||||
#define _RUN_TEST_
|
||||
#ifdef _RUN_TEST_
|
||||
#define ADDTESTCASE(func,desc) JCTest gCTest##func(func,desc);
|
||||
#else
|
||||
#define ADDTESTCASE()
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/*
|
||||
执行测试并且打印结果
|
||||
*/
|
||||
class JCTestMgr{
|
||||
public:
|
||||
struct JCTestCase{
|
||||
typedef void (*TESTFUNC)();
|
||||
TESTFUNC testFunc;
|
||||
std::string strDesc;
|
||||
};
|
||||
|
||||
struct RunContext{
|
||||
const char* pszFile;
|
||||
int nLine;
|
||||
std::string strDesc;
|
||||
bool bOK;
|
||||
RunContext(){
|
||||
pszFile = NULL;
|
||||
bOK=false;
|
||||
nLine = 0;
|
||||
}
|
||||
};
|
||||
|
||||
static JCTestMgr* getInstance(){
|
||||
static JCTestMgr gTestMgr;
|
||||
return &gTestMgr;
|
||||
}
|
||||
|
||||
JCTestMgr(){
|
||||
m_nTotalNum = 0;
|
||||
m_nOKNum = 0;
|
||||
}
|
||||
|
||||
void addTestCase(JCTestCase::TESTFUNC func, const char* desc ){
|
||||
JCTestCase tc = {func, desc};
|
||||
m_AllTestCases.push_back(tc);
|
||||
}
|
||||
|
||||
void run(const char* pRunTestCase);
|
||||
|
||||
void output(const char* szFormat, ...);
|
||||
|
||||
void printResult( RunContext& p_RunCtx );
|
||||
|
||||
template<class T>
|
||||
std::string toString(T t);
|
||||
|
||||
template<class T>
|
||||
void verifyEq(T t1, T t2, const char* pDesc, const char* pFile, int pnLine ){
|
||||
m_nTotalNum++;
|
||||
m_runCtx.pszFile = pFile;
|
||||
m_runCtx.nLine = pnLine;
|
||||
m_runCtx.strDesc = pDesc;
|
||||
if( t1!=t2 ){
|
||||
std::string desc = "Error!";
|
||||
desc += pDesc;
|
||||
desc = desc+ "。期望值是:"+toString(t2)+",实际是:"+toString(t1)+"\n";
|
||||
m_runCtx.strDesc=desc;
|
||||
m_runCtx.bOK = false;
|
||||
}else{
|
||||
m_nOKNum++;
|
||||
m_runCtx.bOK = true;
|
||||
}
|
||||
printResult(m_runCtx);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void verifyEqRange(T t1, T t2, T range, const char* pDesc, const char* pFile, int pnLine ){
|
||||
m_nTotalNum++;
|
||||
m_runCtx.pszFile = pFile;
|
||||
m_runCtx.nLine = pnLine;
|
||||
m_runCtx.strDesc = pDesc;
|
||||
if( (t1-t2)>range ||(t2-t1)>range ){
|
||||
std::string desc = "Error!";
|
||||
desc += pDesc;
|
||||
desc = desc+ "。期望值是范围:"+toString(t2)+"+"+toString(range)+",实际是:"+toString(t1)+"\n";
|
||||
m_runCtx.strDesc=desc;
|
||||
m_runCtx.bOK = false;
|
||||
}else{
|
||||
m_nOKNum++;
|
||||
m_runCtx.bOK = true;
|
||||
}
|
||||
printResult(m_runCtx);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void verifyNEq(T t1, T t2, const char* pDesc, const char* pFile, int pnLine ){
|
||||
m_nTotalNum++;
|
||||
m_runCtx.pszFile = pFile;
|
||||
m_runCtx.nLine = pnLine;
|
||||
m_runCtx.strDesc = pDesc;
|
||||
if( t1==t2 ){
|
||||
std::string desc = "Error!";
|
||||
desc += pDesc;
|
||||
desc = desc+ "。期望值是不要等于:"+toString(t2)+",实际是:"+toString(t1)+"\n";
|
||||
m_runCtx.strDesc=desc;
|
||||
m_runCtx.bOK = false;
|
||||
}else{
|
||||
m_nOKNum++;
|
||||
m_runCtx.bOK = true;
|
||||
}
|
||||
printResult(m_runCtx);
|
||||
}
|
||||
|
||||
protected:
|
||||
RunContext m_runCtx;
|
||||
int m_nTotalNum;
|
||||
int m_nOKNum;
|
||||
std::vector<JCTestCase> m_AllTestCases;
|
||||
};
|
||||
|
||||
|
||||
class JCTest{
|
||||
public:
|
||||
JCTest( JCTestMgr::JCTestCase::TESTFUNC func, const char* desc){
|
||||
JCTestMgr::getInstance()->addTestCase(func,desc);
|
||||
}
|
||||
};
|
||||
|
||||
#define VERIFYEQ(v,s,desc) JCTestMgr::getInstance()->verifyEq(v,s,desc,__FILE__,__LINE__);
|
||||
#define VERIFYNEQ(v,ns,desc) JCTestMgr::getInstance()->verifyNEq(v,ns,desc,__FILE__,__LINE__);
|
||||
#define VERIFYEQR(v,s,r,desc) JCTestMgr::getInstance()->verifyEqRange(v,s,r,desc,__FILE__,__LINE__);
|
||||
|
||||
void Sleep(int ms);
|
||||
|
||||
void WaitUtil(bool* pCond, int timeout);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,19 @@
|
||||
1. 写测试用例
|
||||
参考testSample.cpp
|
||||
测试用例只需要写一个cpp文件,不用.h文件。
|
||||
这个文件的最后用 ADDTESTCASE 添加到测试集中。
|
||||
|
||||
2. 编译conch项目
|
||||
其他项目不受影响。因为只测试其他项目的导出部分。
|
||||
需要保证已经加上 _TEST_ 宏了。
|
||||
3. 执行测试
|
||||
把vs的Debugging 参数加 -test。
|
||||
执行后输出结果为:
|
||||
简单测试用例
|
||||
=============================================
|
||||
OK:hexStringToInt 0xff
|
||||
OK:不允许包含0x
|
||||
测试结果:2/2
|
||||
|
||||
这个表示一共有一个测试文件,里面包含两个测试,都通过了。
|
||||
如果只希望执行一个测试文件,可以在调试参数中指定,例如 "-test简单测试用例", 则表示只执行通过 ADDTESTCASE 添加的测试用例中的描述为"简单测试用例"的那个。
|
||||
Reference in New Issue
Block a user