初始化内容
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
/log
|
||||
/*.ilk
|
||||
/*.pdb
|
||||
/*.exe
|
||||
/memory_leak_report.txt
|
||||
/vld.ini
|
||||
/temp
|
||||
/binary
|
||||
/dl
|
||||
/Microsoft.DTfW.DHL.manifest
|
||||
/out
|
||||
@@ -0,0 +1,13 @@
|
||||
cmake_minimum_required (VERSION 3.12)
|
||||
project ("dl_unit_test")
|
||||
|
||||
set (PATH_SRC ${PROJECT_SOURCE_DIR})
|
||||
set (PATH_RES ${PROJECT_SOURCE_DIR}/res)
|
||||
set (USE_RENDER ON)
|
||||
set (USE_CRASH_RPT false)
|
||||
include ("../project.cmake")
|
||||
|
||||
# 链接 GoogleTest
|
||||
target_link_libraries(${PROJECT_NAME} GTest::gtest)
|
||||
# 链接 OpenXLSX(用于 Language 测试读写 xlsx)
|
||||
target_link_libraries(${PROJECT_NAME} OpenXLSX::OpenXLSX)
|
||||
@@ -0,0 +1 @@
|
||||
#include <dl_main.h>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<!-- $Id -->
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
<noInheritable />
|
||||
<assemblyIdentity type="win32" name="Microsoft.DTfW.DHL" version="6.11.1.404" processorArchitecture="amd64" />
|
||||
<file name="dbghelp.dll" />
|
||||
</assembly>
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,198 @@
|
||||
{
|
||||
"__desc": "2d粒子配置",
|
||||
"__name": "2d粒子配置",
|
||||
"emitter": {
|
||||
"__desc": "发射器设置",
|
||||
"__name": "发射器",
|
||||
"offset": {
|
||||
"__desc": "位置偏移",
|
||||
"__name": "位置偏移",
|
||||
"type": "array<float, 2>",
|
||||
"value": [
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
"offset1": {
|
||||
"__desc": "位置偏移1,作为line模式的结束点",
|
||||
"__name": "位置偏移1,作为line模式的结束点",
|
||||
"type": "array<float, 2>",
|
||||
"value": [
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
"rate": {
|
||||
"__desc": "发射速率,每秒多少个",
|
||||
"__name": "发射速率",
|
||||
"type": "uint",
|
||||
"value": 20
|
||||
},
|
||||
"shape": {
|
||||
"__desc": "发射区域类型(point、circle、box、line)",
|
||||
"__name": "发射区域类型",
|
||||
"type": "string",
|
||||
"value": "circle"
|
||||
},
|
||||
"size": {
|
||||
"__desc": "区域大小(半径)",
|
||||
"__name": "区域大小",
|
||||
"type": "array<float, 2>",
|
||||
"value": [
|
||||
100.0,
|
||||
100.0
|
||||
]
|
||||
}
|
||||
},
|
||||
"node": {
|
||||
"__desc": "粒子参数",
|
||||
"__name": "粒子参数",
|
||||
"alpha": {
|
||||
"__desc": "透明度(范围)",
|
||||
"__name": "透明度(范围)",
|
||||
"type": "array<float, 2>",
|
||||
"value": [
|
||||
1.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
"angle": {
|
||||
"__desc": "方向角度(范围)",
|
||||
"__name": "方向角度(范围)",
|
||||
"type": "array<float, 2>",
|
||||
"value": [
|
||||
0.0,
|
||||
360.0
|
||||
]
|
||||
},
|
||||
"color_beg": {
|
||||
"__desc": "起始颜色(RGB)",
|
||||
"__name": "起始颜色(RGB)",
|
||||
"type": "array<float, 3>",
|
||||
"value": [
|
||||
1.0,
|
||||
1.0,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"color_end": {
|
||||
"__desc": "结束颜色(RGB)",
|
||||
"__name": "结束颜色(RGB)",
|
||||
"type": "array<float, 3>",
|
||||
"value": [
|
||||
1.0,
|
||||
1.0,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"lifetime": {
|
||||
"__desc": "存活时间(范围)",
|
||||
"__name": "存活时间(范围)",
|
||||
"type": "array<float, 2>",
|
||||
"value": [
|
||||
1.0,
|
||||
2.0
|
||||
]
|
||||
},
|
||||
"rotate_angle": {
|
||||
"__desc": "初始旋转角度(范围)",
|
||||
"__name": "初始旋转角度(范围)",
|
||||
"type": "array<float, 2>",
|
||||
"value": [
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
"rotate_speed": {
|
||||
"__desc": "旋转速度(范围)",
|
||||
"__name": "旋转速度(范围)",
|
||||
"type": "array<float, 2>",
|
||||
"value": [
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
"rotate_to_dir": {
|
||||
"__desc": "旋转至运动方向(启用后,其他旋转控制失效)",
|
||||
"__name": "旋转至运动方向",
|
||||
"type": "bool",
|
||||
"value": false
|
||||
},
|
||||
"scale_x_beg": {
|
||||
"__desc": "起始缩放比例x轴(范围)",
|
||||
"__name": "起始缩放比例x轴(范围)",
|
||||
"type": "array<float, 2>",
|
||||
"value": [
|
||||
1.0,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"scale_x_end": {
|
||||
"__desc": "结束缩放比例x轴(范围)",
|
||||
"__name": "结束缩放比例x轴(范围)",
|
||||
"type": "array<float, 2>",
|
||||
"value": [
|
||||
1.0,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"scale_y_beg": {
|
||||
"__desc": "起始缩放比例y轴(范围)",
|
||||
"__name": "起始缩放比例y轴(范围)",
|
||||
"type": "array<float, 2>",
|
||||
"value": [
|
||||
1.0,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"scale_y_end": {
|
||||
"__desc": "结束缩放比例y轴(范围)",
|
||||
"__name": "结束缩放比例y轴(范围)",
|
||||
"type": "array<float, 2>",
|
||||
"value": [
|
||||
1.0,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
"speed": {
|
||||
"__desc": "速度(范围)",
|
||||
"__name": "速度(范围)",
|
||||
"type": "array<float, 2>",
|
||||
"value": [
|
||||
100.0,
|
||||
200.0
|
||||
]
|
||||
}
|
||||
},
|
||||
"system": {
|
||||
"__desc": "主要参数",
|
||||
"__name": "主要参数",
|
||||
"delay": {
|
||||
"__desc": "启动延时",
|
||||
"__name": "启动延时",
|
||||
"type": "float",
|
||||
"value": 0.0
|
||||
},
|
||||
"duration": {
|
||||
"__desc": "持续时间(单位秒)",
|
||||
"__name": "持续时间",
|
||||
"type": "float",
|
||||
"value": 0.0
|
||||
},
|
||||
"gravity": {
|
||||
"__desc": "重力方向和大小",
|
||||
"__name": "重力方向和大小",
|
||||
"type": "array<float, 2>",
|
||||
"value": [
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
"max_num": {
|
||||
"__desc": "粒子数量上限",
|
||||
"__name": "粒子数量上限",
|
||||
"type": "uint",
|
||||
"value": 1024
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,9 @@
|
||||
( 0.818393886089325, 0.856512069702148, 0.979097247123718); // L00, irradiance, pre-scaled base
|
||||
( 0.376601099967957, 0.388774126768112, 0.445391833782196); // L1-1, irradiance, pre-scaled base
|
||||
( 0.367425948381424, 0.295479565858841, 0.251522302627563); // L10, irradiance, pre-scaled base
|
||||
(-0.259449630975723, -0.213349714875221, -0.181993708014488); // L11, irradiance, pre-scaled base
|
||||
(-0.096955023705959, -0.073478810489178, -0.059210501611233); // L2-2, irradiance, pre-scaled base
|
||||
( 0.112052068114281, 0.086938507854939, 0.069391325116158); // L2-1, irradiance, pre-scaled base
|
||||
( 0.005669212900102, 0.005782041233033, 0.003940611612052); // L20, irradiance, pre-scaled base
|
||||
(-0.137584298849106, -0.123443752527237, -0.111519888043404); // L21, irradiance, pre-scaled base
|
||||
(-0.029301593080163, -0.024162670597434, -0.029466325417161); // L22, irradiance, pre-scaled base
|
||||
Binary file not shown.
@@ -0,0 +1,122 @@
|
||||
Visual Leak Detector Version 2.5.1 installed.
|
||||
Outputting the report to the debugger and to D:\dl\out\build\x64-debug\project\dl_unit_test\bin\memory_leak_report.txt
|
||||
WARNING: Visual Leak Detector detected memory leaks!
|
||||
---------- Block 15582 at 0x00000000D918C5F0: 64 bytes ----------
|
||||
Leak Hash: 0x6D8807E3, Count: 1, Total 64 bytes
|
||||
Call Stack (TID 43668):
|
||||
Data:
|
||||
F0 C5 18 D9 58 01 00 00 F0 C5 18 D9 58 01 00 00 ....X... ....X...
|
||||
F0 C5 18 D9 58 01 00 00 01 01 CD CD CD CD CD CD ....X... ........
|
||||
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
|
||||
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
|
||||
|
||||
|
||||
---------- Block 15579 at 0x00000000D95AF540: 40 bytes ----------
|
||||
Leak Hash: 0x36765E5B, Count: 1, Total 40 bytes
|
||||
Call Stack (TID 43668):
|
||||
ntdll.dll!RtlAllocateHeap()
|
||||
D:\a\_work\1\s\src\vctools\crt\vcstartup\src\heap\new_scalar.cpp (36): dl_unit_test.exe!operator new() + 0xA bytes
|
||||
D:\dl\third\googletest\googletest\src\gtest-port.cc (413): dl_unit_test.exe!testing::internal::Mutex::ThreadSafeLazyInit() + 0xA bytes
|
||||
D:\dl\third\googletest\googletest\src\gtest-port.cc (342): dl_unit_test.exe!testing::internal::Mutex::lock()
|
||||
D:\dl\third\googletest\googletest\include\gtest\internal\gtest-port.h (1478): dl_unit_test.exe!testing::internal::GTestMutexLock::GTestMutexLock() + 0x29 bytes
|
||||
D:\dl\third\googletest\googletest\src\gtest-port.cc (552): dl_unit_test.exe!testing::internal::ThreadLocalRegistryImpl::OnThreadLocalDestroyed() + 0x11 bytes
|
||||
D:\dl\third\googletest\googletest\src\gtest-port.cc (691): dl_unit_test.exe!testing::internal::ThreadLocalRegistry::OnThreadLocalDestroyed() + 0xA bytes
|
||||
D:\dl\third\googletest\googletest\include\gtest\internal\gtest-port.h (1612): dl_unit_test.exe!testing::internal::ThreadLocal<std::vector<testing::internal::TraceInfo,std::allocator<testing::internal::TraceInfo> > >::~ThreadLocal<std::vector<testing::internal::TraceInfo,std::allocator<testing::internal::TraceInfo> > >() + 0x23 bytes
|
||||
D:\dl\third\googletest\googletest\src\gtest.cc (5740): dl_unit_test.exe!testing::internal::UnitTestImpl::~UnitTestImpl() + 0x13 bytes
|
||||
dl_unit_test.exe!testing::internal::UnitTestImpl::`scalar deleting destructor'() + 0x18 bytes
|
||||
D:\dl\third\googletest\googletest\src\gtest.cc (5685): dl_unit_test.exe!testing::UnitTest::~UnitTest() + 0x4D bytes
|
||||
dl_unit_test.exe!`testing::UnitTest::GetInstance'::`2'::`dynamic atexit destructor for 'instance''() + 0x12 bytes
|
||||
minkernel\crts\ucrt\src\appcrt\startup\onexit.cpp (206): dl_unit_test.exe!<lambda_d121dba8a4adeaf3a9819e48611155df>::operator()()
|
||||
VCCRT\vcruntime\inc\internal_shared.h (204): dl_unit_test.exe!__crt_seh_guarded_call<int>::operator()<<lambda_6a47f4c8fd0152770a780fc1d70204eb>,<lambda_d121dba8a4adeaf3a9819e48611155df> &,<lambda_6aaa2265f5b6a89667e7d7630012e97a> >() + 0xA bytes
|
||||
minkernel\crts\ucrt\inc\corecrt_internal.h (983): dl_unit_test.exe!__acrt_lock_and_call<<lambda_d121dba8a4adeaf3a9819e48611155df> >() + 0x41 bytes
|
||||
minkernel\crts\ucrt\src\appcrt\startup\onexit.cpp (231): dl_unit_test.exe!_execute_onexit_table()
|
||||
minkernel\crts\ucrt\src\appcrt\startup\exit.cpp (225): dl_unit_test.exe!<lambda_6e4b09c48022b2350581041d5f6b0c4c>::operator()()
|
||||
VCCRT\vcruntime\inc\internal_shared.h (224): dl_unit_test.exe!__crt_seh_guarded_call<void>::operator()<<lambda_d80eeec6fff315bfe5c115232f3240e3>,<lambda_6e4b09c48022b2350581041d5f6b0c4c> &,<lambda_2358e3775559c9db80273638284d5e45> >() + 0xA bytes
|
||||
minkernel\crts\ucrt\inc\corecrt_internal.h (983): dl_unit_test.exe!__acrt_lock_and_call<<lambda_6e4b09c48022b2350581041d5f6b0c4c> >() + 0x41 bytes
|
||||
minkernel\crts\ucrt\src\appcrt\startup\exit.cpp (259): dl_unit_test.exe!common_exit()
|
||||
minkernel\crts\ucrt\src\appcrt\startup\exit.cpp (302): dl_unit_test.exe!exit()
|
||||
D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl (295): dl_unit_test.exe!__scrt_common_main_seh() + 0x9 bytes
|
||||
D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl (331): dl_unit_test.exe!__scrt_common_main()
|
||||
D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_main.cpp (17): dl_unit_test.exe!mainCRTStartup()
|
||||
KERNEL32.DLL!BaseThreadInitThunk() + 0x14 bytes
|
||||
ntdll.dll!RtlUserThreadStart() + 0x21 bytes
|
||||
Data:
|
||||
FF FF FF FF FF FF FF FF FF FF FF FF 00 00 00 00 ........ ........
|
||||
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
|
||||
D0 07 00 02 00 00 00 00 ........ ........
|
||||
|
||||
|
||||
---------- Block 15581 at 0x00000000D95D2B50: 16 bytes ----------
|
||||
Leak Hash: 0x40E41FAB, Count: 1, Total 16 bytes
|
||||
Call Stack (TID 43668):
|
||||
ntdll.dll!RtlAllocateHeap()
|
||||
D:\a\_work\1\s\src\vctools\crt\vcstartup\src\heap\new_scalar.cpp (36): dl_unit_test.exe!operator new() + 0xA bytes
|
||||
D:\vs_2026\VC\Tools\MSVC\14.51.36231\include\xmemory (137): dl_unit_test.exe!std::_Default_allocate_traits::_Allocate()
|
||||
D:\vs_2026\VC\Tools\MSVC\14.51.36231\include\xmemory (258): dl_unit_test.exe!std::_Allocate<16,std::_Default_allocate_traits>()
|
||||
D:\vs_2026\VC\Tools\MSVC\14.51.36231\include\xmemory (995): dl_unit_test.exe!std::allocator<std::_Container_proxy>::allocate()
|
||||
D:\vs_2026\VC\Tools\MSVC\14.51.36231\include\xmemory (1495): dl_unit_test.exe!std::_Container_proxy_ptr12<std::allocator<std::_Container_proxy> >::_Container_proxy_ptr12<std::allocator<std::_Container_proxy> >() + 0xF bytes
|
||||
D:\vs_2026\VC\Tools\MSVC\14.51.36231\include\xtree (1967): dl_unit_test.exe!std::_Tree<std::_Tmap_traits<unsigned long,std::map<testing::internal::ThreadLocalBase const *,std::shared_ptr<testing::internal::ThreadLocalValueHolderBase>,std::less<testing::internal::ThreadLocalBase const *>,std::allocator<std::pair<testing::internal:() + 0x14 bytes
|
||||
D:\vs_2026\VC\Tools\MSVC\14.51.36231\include\xtree (916): dl_unit_test.exe!std::_Tree<std::_Tmap_traits<unsigned long,std::map<testing::internal::ThreadLocalBase const *,std::shared_ptr<testing::internal::ThreadLocalValueHolderBase>,std::less<testing::internal::ThreadLocalBase const *>,std::allocator<std::pair<testing::internal:() + 0xA bytes
|
||||
D:\vs_2026\VC\Tools\MSVC\14.51.36231\include\map (106): dl_unit_test.exe!std::map<unsigned long,std::map<testing::internal::ThreadLocalBase const *,std::shared_ptr<testing::internal::ThreadLocalValueHolderBase>,std::less<testing::internal::ThreadLocalBase const *>,std::allocator<std::pair<testing::internal::ThreadLocalBase con() + 0x19 bytes
|
||||
D:\dl\third\googletest\googletest\src\gtest-port.cc (669): dl_unit_test.exe!testing::internal::ThreadLocalRegistryImpl::GetThreadLocalsMapLocked() + 0x54 bytes
|
||||
D:\dl\third\googletest\googletest\src\gtest-port.cc (553): dl_unit_test.exe!testing::internal::ThreadLocalRegistryImpl::OnThreadLocalDestroyed() + 0x5 bytes
|
||||
D:\dl\third\googletest\googletest\src\gtest-port.cc (691): dl_unit_test.exe!testing::internal::ThreadLocalRegistry::OnThreadLocalDestroyed() + 0xA bytes
|
||||
D:\dl\third\googletest\googletest\include\gtest\internal\gtest-port.h (1612): dl_unit_test.exe!testing::internal::ThreadLocal<std::vector<testing::internal::TraceInfo,std::allocator<testing::internal::TraceInfo> > >::~ThreadLocal<std::vector<testing::internal::TraceInfo,std::allocator<testing::internal::TraceInfo> > >() + 0x23 bytes
|
||||
D:\dl\third\googletest\googletest\src\gtest.cc (5740): dl_unit_test.exe!testing::internal::UnitTestImpl::~UnitTestImpl() + 0x13 bytes
|
||||
dl_unit_test.exe!testing::internal::UnitTestImpl::`scalar deleting destructor'() + 0x18 bytes
|
||||
D:\dl\third\googletest\googletest\src\gtest.cc (5685): dl_unit_test.exe!testing::UnitTest::~UnitTest() + 0x4D bytes
|
||||
dl_unit_test.exe!`testing::UnitTest::GetInstance'::`2'::`dynamic atexit destructor for 'instance''() + 0x12 bytes
|
||||
minkernel\crts\ucrt\src\appcrt\startup\onexit.cpp (206): dl_unit_test.exe!<lambda_d121dba8a4adeaf3a9819e48611155df>::operator()()
|
||||
VCCRT\vcruntime\inc\internal_shared.h (204): dl_unit_test.exe!__crt_seh_guarded_call<int>::operator()<<lambda_6a47f4c8fd0152770a780fc1d70204eb>,<lambda_d121dba8a4adeaf3a9819e48611155df> &,<lambda_6aaa2265f5b6a89667e7d7630012e97a> >() + 0xA bytes
|
||||
minkernel\crts\ucrt\inc\corecrt_internal.h (983): dl_unit_test.exe!__acrt_lock_and_call<<lambda_d121dba8a4adeaf3a9819e48611155df> >() + 0x41 bytes
|
||||
minkernel\crts\ucrt\src\appcrt\startup\onexit.cpp (231): dl_unit_test.exe!_execute_onexit_table()
|
||||
minkernel\crts\ucrt\src\appcrt\startup\exit.cpp (225): dl_unit_test.exe!<lambda_6e4b09c48022b2350581041d5f6b0c4c>::operator()()
|
||||
VCCRT\vcruntime\inc\internal_shared.h (224): dl_unit_test.exe!__crt_seh_guarded_call<void>::operator()<<lambda_d80eeec6fff315bfe5c115232f3240e3>,<lambda_6e4b09c48022b2350581041d5f6b0c4c> &,<lambda_2358e3775559c9db80273638284d5e45> >() + 0xA bytes
|
||||
minkernel\crts\ucrt\inc\corecrt_internal.h (983): dl_unit_test.exe!__acrt_lock_and_call<<lambda_6e4b09c48022b2350581041d5f6b0c4c> >() + 0x41 bytes
|
||||
minkernel\crts\ucrt\src\appcrt\startup\exit.cpp (259): dl_unit_test.exe!common_exit()
|
||||
minkernel\crts\ucrt\src\appcrt\startup\exit.cpp (302): dl_unit_test.exe!exit()
|
||||
D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl (295): dl_unit_test.exe!__scrt_common_main_seh() + 0x9 bytes
|
||||
D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl (331): dl_unit_test.exe!__scrt_common_main()
|
||||
D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_main.cpp (17): dl_unit_test.exe!mainCRTStartup()
|
||||
KERNEL32.DLL!BaseThreadInitThunk() + 0x14 bytes
|
||||
ntdll.dll!RtlUserThreadStart() + 0x21 bytes
|
||||
Data:
|
||||
10 55 5E D9 58 01 00 00 00 00 00 00 00 00 00 00 .U^.X... ........
|
||||
|
||||
|
||||
---------- Block 15580 at 0x00000000D95E5510: 24 bytes ----------
|
||||
Leak Hash: 0x976A4DFF, Count: 1, Total 24 bytes
|
||||
Call Stack (TID 43668):
|
||||
ntdll.dll!RtlAllocateHeap()
|
||||
D:\a\_work\1\s\src\vctools\crt\vcstartup\src\heap\new_scalar.cpp (36): dl_unit_test.exe!operator new() + 0xA bytes
|
||||
D:\dl\third\googletest\googletest\src\gtest-port.cc (669): dl_unit_test.exe!testing::internal::ThreadLocalRegistryImpl::GetThreadLocalsMapLocked() + 0x3D bytes
|
||||
D:\dl\third\googletest\googletest\src\gtest-port.cc (553): dl_unit_test.exe!testing::internal::ThreadLocalRegistryImpl::OnThreadLocalDestroyed() + 0x5 bytes
|
||||
D:\dl\third\googletest\googletest\src\gtest-port.cc (691): dl_unit_test.exe!testing::internal::ThreadLocalRegistry::OnThreadLocalDestroyed() + 0xA bytes
|
||||
D:\dl\third\googletest\googletest\include\gtest\internal\gtest-port.h (1612): dl_unit_test.exe!testing::internal::ThreadLocal<std::vector<testing::internal::TraceInfo,std::allocator<testing::internal::TraceInfo> > >::~ThreadLocal<std::vector<testing::internal::TraceInfo,std::allocator<testing::internal::TraceInfo> > >() + 0x23 bytes
|
||||
D:\dl\third\googletest\googletest\src\gtest.cc (5740): dl_unit_test.exe!testing::internal::UnitTestImpl::~UnitTestImpl() + 0x13 bytes
|
||||
dl_unit_test.exe!testing::internal::UnitTestImpl::`scalar deleting destructor'() + 0x18 bytes
|
||||
D:\dl\third\googletest\googletest\src\gtest.cc (5685): dl_unit_test.exe!testing::UnitTest::~UnitTest() + 0x4D bytes
|
||||
dl_unit_test.exe!`testing::UnitTest::GetInstance'::`2'::`dynamic atexit destructor for 'instance''() + 0x12 bytes
|
||||
minkernel\crts\ucrt\src\appcrt\startup\onexit.cpp (206): dl_unit_test.exe!<lambda_d121dba8a4adeaf3a9819e48611155df>::operator()()
|
||||
VCCRT\vcruntime\inc\internal_shared.h (204): dl_unit_test.exe!__crt_seh_guarded_call<int>::operator()<<lambda_6a47f4c8fd0152770a780fc1d70204eb>,<lambda_d121dba8a4adeaf3a9819e48611155df> &,<lambda_6aaa2265f5b6a89667e7d7630012e97a> >() + 0xA bytes
|
||||
minkernel\crts\ucrt\inc\corecrt_internal.h (983): dl_unit_test.exe!__acrt_lock_and_call<<lambda_d121dba8a4adeaf3a9819e48611155df> >() + 0x41 bytes
|
||||
minkernel\crts\ucrt\src\appcrt\startup\onexit.cpp (231): dl_unit_test.exe!_execute_onexit_table()
|
||||
minkernel\crts\ucrt\src\appcrt\startup\exit.cpp (225): dl_unit_test.exe!<lambda_6e4b09c48022b2350581041d5f6b0c4c>::operator()()
|
||||
VCCRT\vcruntime\inc\internal_shared.h (224): dl_unit_test.exe!__crt_seh_guarded_call<void>::operator()<<lambda_d80eeec6fff315bfe5c115232f3240e3>,<lambda_6e4b09c48022b2350581041d5f6b0c4c> &,<lambda_2358e3775559c9db80273638284d5e45> >() + 0xA bytes
|
||||
minkernel\crts\ucrt\inc\corecrt_internal.h (983): dl_unit_test.exe!__acrt_lock_and_call<<lambda_6e4b09c48022b2350581041d5f6b0c4c> >() + 0x41 bytes
|
||||
minkernel\crts\ucrt\src\appcrt\startup\exit.cpp (259): dl_unit_test.exe!common_exit()
|
||||
minkernel\crts\ucrt\src\appcrt\startup\exit.cpp (302): dl_unit_test.exe!exit()
|
||||
D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl (295): dl_unit_test.exe!__scrt_common_main_seh() + 0x9 bytes
|
||||
D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl (331): dl_unit_test.exe!__scrt_common_main()
|
||||
D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_main.cpp (17): dl_unit_test.exe!mainCRTStartup()
|
||||
KERNEL32.DLL!BaseThreadInitThunk() + 0x14 bytes
|
||||
ntdll.dll!RtlUserThreadStart() + 0x21 bytes
|
||||
Data:
|
||||
50 2B 5D D9 58 01 00 00 F0 C5 18 D9 58 01 00 00 P+].X... ....X...
|
||||
00 00 00 00 00 00 00 00 ........ ........
|
||||
|
||||
|
||||
Visual Leak Detector detected 4 memory leaks (436 bytes).
|
||||
Largest number used: 15898751 bytes.
|
||||
Total allocations: 18236619 bytes.
|
||||
Visual Leak Detector is now exiting.
|
||||
@@ -0,0 +1,4 @@
|
||||
; dl_unit_test 单元测试专用 VLD 配置
|
||||
; 关闭 VLD:gtest 单例在进程退出 atexit 析构时会产生 VLD 误报泄漏(官方 issue #2255)
|
||||
[Options]
|
||||
VLD = off
|
||||
@@ -0,0 +1,535 @@
|
||||
/**
|
||||
* @file test_base.cpp
|
||||
* @brief base 模块单元测试(Array、String)
|
||||
*
|
||||
*
|
||||
* @version 1.0
|
||||
* @author CodeBuddy
|
||||
* @date 26-09-03
|
||||
*
|
||||
* @note
|
||||
*/
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "dl_type.h"
|
||||
#include "base/dl_string.h"
|
||||
#include "base/dl_range_find.h"
|
||||
#include "base/dl_range_select.h"
|
||||
#include "base/dl_range_every.h"
|
||||
#include "base/dl_range_erase.h"
|
||||
#include "base/dl_tree.h"
|
||||
#include "base/dl_vector2.h"
|
||||
|
||||
//------------------------------Array------------------------------
|
||||
TEST(ArrayTest, Position)
|
||||
{
|
||||
dl::Position p;
|
||||
p.x = 1.0f;
|
||||
p.y = 2.0f;
|
||||
EXPECT_FLOAT_EQ(p.x, 1.0f);
|
||||
EXPECT_FLOAT_EQ(p.y, 2.0f);
|
||||
EXPECT_FLOAT_EQ(p[0], 1.0f);
|
||||
EXPECT_FLOAT_EQ(p[1], 2.0f);
|
||||
}
|
||||
|
||||
TEST(ArrayTest, Position3)
|
||||
{
|
||||
dl::Position3 p;
|
||||
p.x = 1.0f;
|
||||
p.y = 2.0f;
|
||||
p.z = 3.0f;
|
||||
EXPECT_FLOAT_EQ(p[0], 1.0f);
|
||||
EXPECT_FLOAT_EQ(p[1], 2.0f);
|
||||
EXPECT_FLOAT_EQ(p[2], 3.0f);
|
||||
}
|
||||
|
||||
TEST(ArrayTest, Size)
|
||||
{
|
||||
dl::Size s;
|
||||
s.w = 800;
|
||||
s.h = 600;
|
||||
EXPECT_EQ(s.w, 800u);
|
||||
EXPECT_EQ(s.h, 600u);
|
||||
EXPECT_EQ(s[0], 800u);
|
||||
EXPECT_EQ(s[1], 600u);
|
||||
}
|
||||
|
||||
TEST(ArrayTest, InitList)
|
||||
{
|
||||
dl::Position p{ 10.0f, 20.0f };
|
||||
EXPECT_FLOAT_EQ(p.x, 10.0f);
|
||||
EXPECT_FLOAT_EQ(p.y, 20.0f);
|
||||
}
|
||||
|
||||
//------------------------------String------------------------------
|
||||
TEST(StringTest, SplitView)
|
||||
{
|
||||
auto vec = dl::String::SplitView("a,b,c", ',');
|
||||
ASSERT_EQ(vec.size(), 3u);
|
||||
EXPECT_EQ(vec[0], "a");
|
||||
EXPECT_EQ(vec[1], "b");
|
||||
EXPECT_EQ(vec[2], "c");
|
||||
}
|
||||
|
||||
TEST(StringTest, SplitViewNoEmpty)
|
||||
{
|
||||
auto vec = dl::String::SplitViewNoEmpty("a,,b,", ',');
|
||||
ASSERT_EQ(vec.size(), 2u);
|
||||
EXPECT_EQ(vec[0], "a");
|
||||
EXPECT_EQ(vec[1], "b");
|
||||
}
|
||||
|
||||
TEST(StringTest, ToLowerUpper)
|
||||
{
|
||||
EXPECT_EQ(dl::String::ToLower("ABC"), "abc");
|
||||
EXPECT_EQ(dl::String::ToUpper("abc"), "ABC");
|
||||
}
|
||||
|
||||
TEST(StringTest, ToInt)
|
||||
{
|
||||
EXPECT_EQ(dl::String::toInt("123"), 123);
|
||||
EXPECT_EQ(dl::String::toInt("abc", -1), -1);
|
||||
}
|
||||
|
||||
TEST(StringTest, ToFloat)
|
||||
{
|
||||
EXPECT_FLOAT_EQ(dl::String::toFloat("1.5"), 1.5f);
|
||||
EXPECT_FLOAT_EQ(dl::String::toFloat("abc", 0.0f), 0.0f);
|
||||
}
|
||||
|
||||
TEST(StringTest, EraseBlankBoth)
|
||||
{
|
||||
EXPECT_EQ(dl::String::EraseBlankBoth(" hello "), "hello");
|
||||
}
|
||||
|
||||
TEST(StringTest, ReplaceExtension)
|
||||
{
|
||||
EXPECT_EQ(dl::String::ReplaceExtension("a/b/c.txt", "png"), "a/b/c.png");
|
||||
}
|
||||
|
||||
TEST(StringTest, EraseFilename)
|
||||
{
|
||||
EXPECT_EQ(dl::String::EraseFilename("a/b/c.txt"), "a/b/");
|
||||
}
|
||||
|
||||
TEST(StringTest, IsRelativePath)
|
||||
{
|
||||
EXPECT_TRUE(dl::String::IsRelativePath("a/b/c.txt"));
|
||||
EXPECT_FALSE(dl::String::IsRelativePath("/a/b/c.txt"));
|
||||
}
|
||||
|
||||
TEST(StringTest, ToBool)
|
||||
{
|
||||
EXPECT_TRUE(dl::String::toBool("1"));
|
||||
EXPECT_FALSE(dl::String::toBool("0"));
|
||||
EXPECT_FALSE(dl::String::toBool("abc"));
|
||||
EXPECT_TRUE(dl::String::toBool("abc", true));
|
||||
}
|
||||
|
||||
TEST(StringTest, ToBoolEx)
|
||||
{
|
||||
EXPECT_TRUE(dl::String::toBoolEx("true"));
|
||||
EXPECT_FALSE(dl::String::toBoolEx("false"));
|
||||
EXPECT_TRUE(dl::String::toBoolEx("TRUE"));
|
||||
EXPECT_TRUE(dl::String::toBoolEx("1"));
|
||||
EXPECT_FALSE(dl::String::toBoolEx("abc"));
|
||||
}
|
||||
|
||||
TEST(StringTest, AddQuotes)
|
||||
{
|
||||
EXPECT_EQ(dl::String::AddQuotes("hello"), "\"hello\"");
|
||||
}
|
||||
|
||||
TEST(StringTest, IsBegin)
|
||||
{
|
||||
EXPECT_TRUE(dl::String::IsBegin("hello world", "hello"));
|
||||
EXPECT_FALSE(dl::String::IsBegin("hello", "hello world"));
|
||||
}
|
||||
|
||||
TEST(StringTest, ErasePath)
|
||||
{
|
||||
EXPECT_EQ(dl::String::ErasePath("a/b/c.txt", "a/"), "b/c.txt");
|
||||
}
|
||||
|
||||
TEST(StringTest, SplitViewSub)
|
||||
{
|
||||
auto vec = dl::String::SplitView("a-b-c", "-");
|
||||
ASSERT_EQ(vec.size(), 3u);
|
||||
EXPECT_EQ(vec[0], "a");
|
||||
EXPECT_EQ(vec[1], "b");
|
||||
EXPECT_EQ(vec[2], "c");
|
||||
}
|
||||
|
||||
TEST(StringTest, Range)
|
||||
{
|
||||
EXPECT_EQ(dl::String::Range("a[1,2]b", '[', ']'), "1,2");
|
||||
}
|
||||
|
||||
//------------------------------Array 运算符------------------------------
|
||||
TEST(ArrayTest, OperatorAddSub)
|
||||
{
|
||||
dl::Position a{ 1.0f, 2.0f };
|
||||
dl::Position b{ 3.0f, 4.0f };
|
||||
auto c = a + b;
|
||||
EXPECT_FLOAT_EQ(c[0], 4.0f);
|
||||
EXPECT_FLOAT_EQ(c[1], 6.0f);
|
||||
|
||||
auto d = a - b;
|
||||
EXPECT_FLOAT_EQ(d[0], -2.0f);
|
||||
EXPECT_FLOAT_EQ(d[1], -2.0f);
|
||||
}
|
||||
|
||||
TEST(ArrayTest, OperatorMulDivScalar)
|
||||
{
|
||||
dl::Position a{ 2.0f, 4.0f };
|
||||
auto c = a * 3.0f;
|
||||
EXPECT_FLOAT_EQ(c[0], 6.0f);
|
||||
EXPECT_FLOAT_EQ(c[1], 12.0f);
|
||||
|
||||
auto d = a / 2.0f;
|
||||
EXPECT_FLOAT_EQ(d[0], 1.0f);
|
||||
EXPECT_FLOAT_EQ(d[1], 2.0f);
|
||||
}
|
||||
|
||||
TEST(ArrayTest, OperatorMulArray)
|
||||
{
|
||||
dl::Position a{ 2.0f, 3.0f };
|
||||
dl::Position b{ 4.0f, 5.0f };
|
||||
auto c = a * b;
|
||||
EXPECT_FLOAT_EQ(c[0], 8.0f);
|
||||
EXPECT_FLOAT_EQ(c[1], 15.0f);
|
||||
}
|
||||
|
||||
TEST(ArrayTest, OperatorNeg)
|
||||
{
|
||||
dl::Position a{ 1.0f, -2.0f };
|
||||
auto c = -a;
|
||||
EXPECT_FLOAT_EQ(c[0], -1.0f);
|
||||
EXPECT_FLOAT_EQ(c[1], 2.0f);
|
||||
}
|
||||
|
||||
//------------------------------Find------------------------------
|
||||
TEST(FindTest, FirstIndex)
|
||||
{
|
||||
std::vector<int> v = { 10, 20, 30, 40 };
|
||||
EXPECT_EQ(dl::Find::FirstIndex(v, 30), 2u);
|
||||
EXPECT_EQ(dl::Find::FirstIndex(v, 10), 0u);
|
||||
EXPECT_EQ(dl::Find::FirstIndex(v, 99), (size_t)-1);
|
||||
}
|
||||
|
||||
TEST(FindTest, FirstYes)
|
||||
{
|
||||
std::vector<int> v = { 1, 3, 5, 8 };
|
||||
auto* p = dl::Find::FirstYes(v, [](int x) { return x % 2 == 0; });
|
||||
ASSERT_NE(p, nullptr);
|
||||
EXPECT_EQ(*p, 8);
|
||||
|
||||
auto* p2 = dl::Find::FirstYes(v, [](int x) { return x > 100; });
|
||||
EXPECT_EQ(p2, nullptr);
|
||||
}
|
||||
|
||||
//------------------------------Select------------------------------
|
||||
TEST(SelectTest, MaxMin)
|
||||
{
|
||||
std::vector<int> v = { 3, 7, 2, 9, 5 };
|
||||
EXPECT_EQ(dl::Select::Max(v), 9);
|
||||
EXPECT_EQ(dl::Select::Min(v), 2);
|
||||
}
|
||||
|
||||
TEST(SelectTest, MaxMinFunc)
|
||||
{
|
||||
std::vector<int> v = { 1, -2, 3, -4 };
|
||||
EXPECT_EQ(dl::Select::Max(v, [](int x) { return x * x; }), 16);
|
||||
EXPECT_EQ(dl::Select::Min(v, [](int x) { return x * x; }), 1);
|
||||
}
|
||||
|
||||
TEST(SelectTest, MaxRef)
|
||||
{
|
||||
std::vector<std::string> v = { "a", "hello", "abc" };
|
||||
auto& ref = dl::Select::MaxRef(v, [](std::string& s) { return s.size(); });
|
||||
EXPECT_EQ(ref, "hello");
|
||||
}
|
||||
|
||||
TEST(SelectTest, CreateIfEmpty)
|
||||
{
|
||||
std::vector<int> v = { 1, 2 };
|
||||
auto& ref = dl::Select::CreateIfEmpty(v, 4);
|
||||
ref = 99;
|
||||
ASSERT_EQ(v.size(), 5u);
|
||||
EXPECT_EQ(v[4], 99);
|
||||
EXPECT_EQ(v[0], 1); // 旧元素不变
|
||||
EXPECT_EQ(v[1], 2);
|
||||
}
|
||||
|
||||
//------------------------------NTree------------------------------
|
||||
TEST(NTreeTest, AddAndGet)
|
||||
{
|
||||
dl::NTree<int> tree;
|
||||
auto* root = tree.AddRoot(1);
|
||||
ASSERT_NE(root, nullptr);
|
||||
EXPECT_EQ(root->GetValue(), 1);
|
||||
|
||||
auto* n2 = tree.Add(2, root);
|
||||
auto* n3 = tree.Add(3, root);
|
||||
ASSERT_NE(n2, nullptr);
|
||||
ASSERT_NE(n3, nullptr);
|
||||
|
||||
EXPECT_EQ(tree.GetSize(), 3u);
|
||||
EXPECT_EQ(tree.GetRoot(), root);
|
||||
EXPECT_EQ(tree.Get(2), n2);
|
||||
EXPECT_EQ(tree.Get(99), nullptr);
|
||||
|
||||
ASSERT_EQ(root->GetChild().size(), 2u);
|
||||
EXPECT_EQ(root->GetChild()[0], n2);
|
||||
EXPECT_EQ(root->GetChild()[1], n3);
|
||||
EXPECT_EQ(n2->GetParent(), root);
|
||||
}
|
||||
|
||||
TEST(NTreeTest, PushBack)
|
||||
{
|
||||
dl::NTree<int> tree;
|
||||
auto* r = tree.PushBack(1);
|
||||
auto* a = tree.PushBack(2);
|
||||
auto* b = tree.PushBack(3);
|
||||
EXPECT_EQ(tree.GetSize(), 3u);
|
||||
EXPECT_EQ(a->GetParent(), r);
|
||||
EXPECT_EQ(b->GetParent(), r);
|
||||
}
|
||||
|
||||
TEST(NTreeTest, Del)
|
||||
{
|
||||
dl::NTree<int> tree;
|
||||
auto* root = tree.AddRoot(1);
|
||||
auto* n2 = tree.Add(2, root);
|
||||
auto* n3 = tree.Add(3, n2);
|
||||
|
||||
EXPECT_TRUE(tree.Del(n2));
|
||||
EXPECT_EQ(tree.GetSize(), 2u);
|
||||
EXPECT_EQ(tree.Get(2), nullptr);
|
||||
EXPECT_EQ(n3->GetParent(), root); // 子节点上移到 root
|
||||
}
|
||||
|
||||
TEST(NTreeTest, ForEach)
|
||||
{
|
||||
dl::NTree<int> tree;
|
||||
auto* root = tree.AddRoot(1);
|
||||
tree.Add(2, root);
|
||||
tree.Add(3, root);
|
||||
|
||||
std::vector<int> order;
|
||||
tree.ForEach([&](int v) { order.push_back(v); });
|
||||
ASSERT_EQ(order.size(), 3u);
|
||||
EXPECT_EQ(order[0], 1); // 根先遍历
|
||||
EXPECT_EQ(order[1], 2);
|
||||
EXPECT_EQ(order[2], 3);
|
||||
}
|
||||
|
||||
//------------------------------Accumulate------------------------------
|
||||
TEST(AccumulateTest, Add)
|
||||
{
|
||||
std::vector<int> v = { 1, 2, 3, 4 };
|
||||
EXPECT_EQ(dl::Accumulate::Add(v), 10);
|
||||
EXPECT_EQ(dl::Accumulate::Add(std::vector<int>{}), 0);
|
||||
}
|
||||
|
||||
TEST(AccumulateTest, Mul)
|
||||
{
|
||||
std::vector<int> v = { 1, 2, 3, 4 };
|
||||
EXPECT_EQ(dl::Accumulate::Mul(v), 24);
|
||||
EXPECT_EQ(dl::Accumulate::Mul(std::vector<int>{}), 0);
|
||||
}
|
||||
|
||||
//------------------------------Vector2------------------------------
|
||||
TEST(Vector2Test, Basic)
|
||||
{
|
||||
dl::Vector2<int> v({ 3, 2 }); // 宽3,高2
|
||||
EXPECT_EQ(v.GetWidth(), 3u);
|
||||
EXPECT_EQ(v.GetHeight(), 2u);
|
||||
EXPECT_EQ(v.GetSizeMul(), 6u);
|
||||
|
||||
v.Set(0, 0, 1);
|
||||
v.Set(0, 1, 2);
|
||||
v.Set(0, 2, 3);
|
||||
v.Set(1, 0, 4);
|
||||
v.Set(1, 1, 5);
|
||||
v.Set(1, 2, 6);
|
||||
|
||||
EXPECT_EQ(v.Get(0, 0), 1);
|
||||
EXPECT_EQ(v.Get(1, 2), 6);
|
||||
|
||||
// 按行访问
|
||||
auto row = v[0];
|
||||
EXPECT_EQ(row[0], 1);
|
||||
EXPECT_EQ(row[2], 3);
|
||||
}
|
||||
|
||||
TEST(Vector2Test, Fill)
|
||||
{
|
||||
dl::Vector2<int> v({ 2, 2 });
|
||||
v.Fill(7);
|
||||
EXPECT_EQ(v.Get(0, 0), 7);
|
||||
EXPECT_EQ(v.Get(1, 1), 7);
|
||||
}
|
||||
|
||||
TEST(Vector2Test, RotateRightAngle1)
|
||||
{
|
||||
dl::Vector2<int> v({ 2, 2 });
|
||||
v.Set(0, 0, 1);
|
||||
v.Set(0, 1, 2);
|
||||
v.Set(1, 0, 3);
|
||||
v.Set(1, 1, 4);
|
||||
|
||||
auto r = dl::Vector2<int>::RotateRightAngle1(v);
|
||||
// 原 1 2 顺时针旋转90度 3 1
|
||||
// 3 4 4 2
|
||||
EXPECT_EQ(r.Get(0, 0), 3);
|
||||
EXPECT_EQ(r.Get(0, 1), 1);
|
||||
EXPECT_EQ(r.Get(1, 0), 4);
|
||||
EXPECT_EQ(r.Get(1, 1), 2);
|
||||
}
|
||||
|
||||
//------------------------------Every------------------------------
|
||||
TEST(EveryTest, AddSubMul)
|
||||
{
|
||||
std::vector<int> v = { 1, 2, 3 };
|
||||
dl::Every::Add(v, 10);
|
||||
EXPECT_EQ(v[0], 11);
|
||||
EXPECT_EQ(v[2], 13);
|
||||
|
||||
dl::Every::Sub(v, 1);
|
||||
EXPECT_EQ(v[0], 10);
|
||||
|
||||
dl::Every::Mul(v, 2);
|
||||
EXPECT_EQ(v[0], 20);
|
||||
}
|
||||
|
||||
TEST(EveryTest, RoundFloorCeil)
|
||||
{
|
||||
std::vector<float> v = { 1.4f, 1.5f, -1.5f };
|
||||
dl::Every::Round(v);
|
||||
EXPECT_FLOAT_EQ(v[0], 1.0f);
|
||||
EXPECT_FLOAT_EQ(v[1], 2.0f);
|
||||
EXPECT_FLOAT_EQ(v[2], -2.0f);
|
||||
|
||||
std::vector<float> f = { 1.7f, -1.2f };
|
||||
dl::Every::Floor(f);
|
||||
EXPECT_FLOAT_EQ(f[0], 1.0f);
|
||||
EXPECT_FLOAT_EQ(f[1], -2.0f);
|
||||
|
||||
std::vector<float> c = { 1.2f, -1.7f };
|
||||
dl::Every::Ceil(c);
|
||||
EXPECT_FLOAT_EQ(c[0], 2.0f);
|
||||
EXPECT_FLOAT_EQ(c[1], -1.0f);
|
||||
}
|
||||
|
||||
TEST(EveryTest, ClampSaturate)
|
||||
{
|
||||
std::vector<float> v = { -1.0f, 0.5f, 2.0f };
|
||||
dl::Every::Clamp(v, 0.0f, 1.0f);
|
||||
EXPECT_FLOAT_EQ(v[0], 0.0f);
|
||||
EXPECT_FLOAT_EQ(v[1], 0.5f);
|
||||
EXPECT_FLOAT_EQ(v[2], 1.0f);
|
||||
|
||||
std::vector<float> s = { -1.0f, 0.5f, 2.0f };
|
||||
dl::Every::Saturate(s);
|
||||
EXPECT_FLOAT_EQ(s[0], 0.0f);
|
||||
EXPECT_FLOAT_EQ(s[2], 1.0f);
|
||||
}
|
||||
|
||||
TEST(EveryTest, EqualZero)
|
||||
{
|
||||
std::vector<int> v = { 5, 5, 5 };
|
||||
EXPECT_TRUE(dl::Every::Equal(v, 5));
|
||||
EXPECT_TRUE(dl::Every::NotEqual(v, 3));
|
||||
|
||||
std::vector<int> z = { 0, 0, 0 };
|
||||
EXPECT_TRUE(dl::Every::Zero(z));
|
||||
}
|
||||
|
||||
TEST(EveryTest, EraseReplace)
|
||||
{
|
||||
std::vector<int> v = { 1, 2, 3, 2, 4 };
|
||||
dl::Every::Erase(v, 2);
|
||||
ASSERT_EQ(v.size(), 3u);
|
||||
EXPECT_EQ(v[0], 1);
|
||||
EXPECT_EQ(v[1], 3);
|
||||
EXPECT_EQ(v[2], 4);
|
||||
|
||||
std::vector<int> r = { 1, 2, 3 };
|
||||
dl::Every::Replace(r, 2, 99);
|
||||
EXPECT_EQ(r[1], 99);
|
||||
}
|
||||
|
||||
//------------------------------Erase------------------------------
|
||||
TEST(EraseTest, HeadFromLast)
|
||||
{
|
||||
std::string s = "data/image/cat.png";
|
||||
EXPECT_TRUE(dl::Erase::HeadFromLast(s, '/'));
|
||||
EXPECT_EQ(s, "cat.png");
|
||||
}
|
||||
|
||||
TEST(EraseTest, TailFromLast)
|
||||
{
|
||||
std::string s = "data/image/cat.png";
|
||||
EXPECT_TRUE(dl::Erase::TailFromLast(s, '.'));
|
||||
EXPECT_EQ(s, "data/image/cat.");
|
||||
}
|
||||
|
||||
TEST(EraseTest, TailFromFirst)
|
||||
{
|
||||
std::string s = "data/image/cat.png";
|
||||
EXPECT_TRUE(dl::Erase::TailFromFirst(s, '.'));
|
||||
EXPECT_EQ(s, "data/image/cat");
|
||||
}
|
||||
|
||||
TEST(EraseTest, HeadSubAllSub)
|
||||
{
|
||||
std::string s = "hello world hello";
|
||||
EXPECT_TRUE(dl::Erase::HeadSub(s, std::string("hello ")));
|
||||
EXPECT_EQ(s, "world hello");
|
||||
|
||||
std::string s2 = "aXbXcX";
|
||||
EXPECT_EQ(dl::Erase::AllSub(s2, std::string("X")), 3u);
|
||||
EXPECT_EQ(s2, "abc");
|
||||
}
|
||||
|
||||
TEST(EraseTest, First)
|
||||
{
|
||||
std::vector<int> v = { 1, 2, 3, 2 };
|
||||
EXPECT_TRUE(dl::Erase::First(v, 2));
|
||||
ASSERT_EQ(v.size(), 3u);
|
||||
EXPECT_EQ(v[0], 1);
|
||||
EXPECT_EQ(v[1], 3);
|
||||
EXPECT_EQ(v[2], 2);
|
||||
}
|
||||
|
||||
//------------------------------Any------------------------------
|
||||
TEST(AnyTest, Equal)
|
||||
{
|
||||
std::vector<int> v = { 1, 2, 3 };
|
||||
EXPECT_TRUE(dl::Any::Equal(v, 2));
|
||||
EXPECT_FALSE(dl::Any::Equal(v, 5));
|
||||
}
|
||||
|
||||
TEST(AnyTest, Zero)
|
||||
{
|
||||
std::vector<int> v = { 1, 0, 3 };
|
||||
EXPECT_TRUE(dl::Any::Zero(v));
|
||||
|
||||
std::vector<int> v2 = { 1, 2, 3 };
|
||||
EXPECT_FALSE(dl::Any::Zero(v2));
|
||||
}
|
||||
|
||||
TEST(AnyTest, Yes)
|
||||
{
|
||||
std::vector<int> v = { 1, 3, 5, 8 };
|
||||
EXPECT_TRUE(dl::Any::Yes(v, [](int x) { return x % 2 == 0; }));
|
||||
EXPECT_FALSE(dl::Any::Yes(v, [](int x) { return x > 100; }));
|
||||
}
|
||||
|
||||
TEST(AnyTest, Less)
|
||||
{
|
||||
std::vector<int> v = { 5, 10, 15 };
|
||||
EXPECT_TRUE(dl::Any::Less(v, 10));
|
||||
EXPECT_FALSE(dl::Any::Less(v, 5));
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
* @file test_crypto.cpp
|
||||
* @brief memory 模块单元测试(Crypto 加密哈希)
|
||||
*
|
||||
*
|
||||
* @version 1.0
|
||||
* @author CodeBuddy
|
||||
* @date 26-09-03
|
||||
*
|
||||
* @note
|
||||
*/
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "memory/dl_crypto.h"
|
||||
#include "base/dl_string.h"
|
||||
|
||||
TEST(CryptoTest, HashMd5)
|
||||
{
|
||||
std::string str = "abc";
|
||||
dl::Buffer hash = dl::Crypto::HashMd5(dl::CreateBufferView(str));
|
||||
EXPECT_EQ(dl::to_string_hex(dl::CreateBufferView(hash)), "900150983cd24fb0d6963f7d28e17f72");
|
||||
}
|
||||
|
||||
TEST(CryptoTest, HashSha256)
|
||||
{
|
||||
std::string str = "abc";
|
||||
dl::Buffer hash = dl::Crypto::HashSha256(dl::CreateBufferView(str));
|
||||
EXPECT_EQ(dl::to_string_hex(dl::CreateBufferView(hash)),
|
||||
"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad");
|
||||
}
|
||||
|
||||
TEST(CryptoTest, HashSha512)
|
||||
{
|
||||
std::string str = "abc";
|
||||
dl::Buffer hash = dl::Crypto::HashSha512(dl::CreateBufferView(str));
|
||||
// sha512 结果固定长度 64 字节
|
||||
EXPECT_EQ(hash.size(), 64u);
|
||||
}
|
||||
|
||||
TEST(CryptoTest, HashCrc32)
|
||||
{
|
||||
std::string str = "abc";
|
||||
uint32_t crc = dl::Crypto::HashCrc32(dl::CreateBufferView(str));
|
||||
EXPECT_NE(crc, 0u);
|
||||
// 同一数据结果一致
|
||||
EXPECT_EQ(crc, dl::Crypto::HashCrc32(dl::CreateBufferView(str)));
|
||||
}
|
||||
|
||||
TEST(CryptoTest, Base64)
|
||||
{
|
||||
std::string str = "hello world";
|
||||
std::string enc = dl::Crypto::EncodeBase64(dl::CreateBufferView(str));
|
||||
EXPECT_EQ(enc, "aGVsbG8gd29ybGQ=");
|
||||
|
||||
dl::Buffer dec;
|
||||
EXPECT_TRUE(dl::Crypto::DecodeBase64(enc, dec));
|
||||
EXPECT_EQ(dl::to_string(dec), str);
|
||||
}
|
||||
|
||||
TEST(CryptoTest, Xor)
|
||||
{
|
||||
std::string str = "hello dl";
|
||||
dl::Buffer buf = dl::CreateBuffer(dl::CreateBufferView(str));
|
||||
dl::BufferView view = dl::CreateBufferView(buf);
|
||||
|
||||
dl::Crypto::EncryptXor(view);
|
||||
EXPECT_NE(dl::to_string(view), str); // 加密后应不同
|
||||
|
||||
dl::Crypto::DecryptXor(view);
|
||||
EXPECT_EQ(dl::to_string(view), str); // 解密后还原
|
||||
}
|
||||
|
||||
TEST(CryptoTest, Aes256)
|
||||
{
|
||||
std::string str = "hello dl aes256";
|
||||
dl::Crypto::Aes256Key key = dl::Crypto::GenerateKeyAes256();
|
||||
|
||||
dl::Buffer enc = dl::Crypto::EncryptAes256(dl::CreateBufferView(str), key);
|
||||
EXPECT_FALSE(enc.empty());
|
||||
|
||||
dl::Buffer dec = dl::Crypto::DecryptAes256(enc, key);
|
||||
EXPECT_EQ(dl::to_string(dec), str);
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
/**
|
||||
* @file test_io.cpp
|
||||
* @brief io 模块单元测试(Json)
|
||||
*
|
||||
*
|
||||
* @version 1.0
|
||||
* @author CodeBuddy
|
||||
* @date 26-09-03
|
||||
*
|
||||
* @note
|
||||
*/
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "io/dl_json.h"
|
||||
#include "io/dl_file.h"
|
||||
#include "memory/dl_code_cvt.h"
|
||||
#include "render/dl_factory.h"
|
||||
|
||||
TEST(JsonTest, ParseArray)
|
||||
{
|
||||
auto j = dl::Json::ParseString("[1,2,3]");
|
||||
ASSERT_TRUE(j.is_array());
|
||||
ASSERT_EQ(j.size(), 3u);
|
||||
EXPECT_EQ(j[0], 1);
|
||||
EXPECT_EQ(j[1], 2);
|
||||
EXPECT_EQ(j[2], 3);
|
||||
}
|
||||
|
||||
TEST(JsonTest, ParseObject)
|
||||
{
|
||||
auto j = dl::Json::ParseString(R"({"a": 123, "b": "hello"})");
|
||||
ASSERT_TRUE(j.is_object());
|
||||
EXPECT_EQ(j["a"], 123);
|
||||
EXPECT_EQ(j["b"], "hello");
|
||||
}
|
||||
|
||||
TEST(JsonTest, ParseNested)
|
||||
{
|
||||
auto j = dl::Json::ParseString(R"({"outer": {"inner": [true, false, null]}})");
|
||||
ASSERT_TRUE(j.is_object());
|
||||
EXPECT_TRUE(j["outer"]["inner"][0]);
|
||||
EXPECT_FALSE(j["outer"]["inner"][1]);
|
||||
EXPECT_TRUE(j["outer"]["inner"][2].is_null());
|
||||
}
|
||||
|
||||
TEST(JsonTest, Get)
|
||||
{
|
||||
auto j = dl::Json::ParseString(R"({"key": 456})");
|
||||
int v = 0;
|
||||
EXPECT_TRUE(dl::Json::Get(j, "key", v));
|
||||
EXPECT_EQ(v, 456);
|
||||
}
|
||||
|
||||
TEST(JsonTest, GetMissing)
|
||||
{
|
||||
auto j = dl::Json::ParseString(R"({"key": 456})");
|
||||
int v = 0;
|
||||
EXPECT_FALSE(dl::Json::Get(j, "nokey", v));
|
||||
}
|
||||
|
||||
TEST(JsonTest, ParseInvalid)
|
||||
{
|
||||
auto j = dl::Json::ParseString("{invalid json");
|
||||
EXPECT_TRUE(j.is_null());
|
||||
}
|
||||
|
||||
TEST(JsonTest, SaveFileDump)
|
||||
{
|
||||
json j = dl::Json::ParseString(R"({"a": 1, "b": "hello"})");
|
||||
|
||||
// Dump 成字符串
|
||||
std::string dump = dl::Json::Dump(j);
|
||||
EXPECT_NE(dump.find("\"a\""), std::string::npos);
|
||||
EXPECT_NE(dump.find("1"), std::string::npos);
|
||||
|
||||
// SaveFile + ParseFile 往返
|
||||
std::string path = dl::g_factory->GetPathTemp() + "dl_json_save_test.json";
|
||||
ASSERT_TRUE(dl::Json::SaveFile(j, path));
|
||||
|
||||
json j2 = dl::Json::ParseFile(path);
|
||||
EXPECT_EQ(j2["a"], 1);
|
||||
EXPECT_EQ(j2["b"], "hello");
|
||||
|
||||
dl::File::Delete(path);
|
||||
}
|
||||
|
||||
//------------------------------File------------------------------
|
||||
TEST(FileTest, GetExtension)
|
||||
{
|
||||
EXPECT_EQ(dl::File::GetExtension("a/b/c.txt"), "txt");
|
||||
EXPECT_EQ(dl::File::GetExtension("a/b/c.txt", true), ".txt");
|
||||
EXPECT_EQ(dl::File::GetExtension("a/b/c"), "");
|
||||
}
|
||||
|
||||
TEST(FileTest, GetFileName)
|
||||
{
|
||||
EXPECT_EQ(dl::File::GetFileName("a/b/c.txt"), "c.txt");
|
||||
EXPECT_EQ(dl::File::GetFileName("a/b/"), "");
|
||||
}
|
||||
|
||||
TEST(FileTest, GetStem)
|
||||
{
|
||||
EXPECT_EQ(dl::File::GetStem("a/b/c.txt"), "c");
|
||||
}
|
||||
|
||||
TEST(FileTest, GetFilePath)
|
||||
{
|
||||
EXPECT_EQ(dl::File::GetFilePath("a/b/c.txt"), "a/b/");
|
||||
EXPECT_EQ(dl::File::GetFilePath("a/b/"), "a/b/");
|
||||
EXPECT_EQ(dl::File::GetFilePath("c.txt"), "");
|
||||
}
|
||||
|
||||
TEST(FileTest, GetFolderName)
|
||||
{
|
||||
EXPECT_EQ(dl::File::GetFolderName("a/b/c.txt"), "b");
|
||||
}
|
||||
|
||||
//------------------------------CodeCvt------------------------------
|
||||
TEST(CodeCvtTest, Utf8Check)
|
||||
{
|
||||
EXPECT_EQ(dl::CodeCvt::Utf8::Check("hello"), 1); // ascii
|
||||
EXPECT_EQ(dl::CodeCvt::Utf8::Check("你好"), 2); // utf-8
|
||||
}
|
||||
|
||||
TEST(CodeCvtTest, Utf8Sub)
|
||||
{
|
||||
std::string s = "你好世界"; // 每个字 3 字节,共 12 字节
|
||||
EXPECT_EQ(dl::CodeCvt::Utf8::Sub(s, 0), 0u);
|
||||
EXPECT_EQ(dl::CodeCvt::Utf8::Sub(s, 4), 3u); // 截断到"你"(3 字节边界)
|
||||
EXPECT_EQ(dl::CodeCvt::Utf8::Sub(s, 12), 12u); // 足够时返回全部
|
||||
}
|
||||
|
||||
TEST(CodeCvtTest, WideCharRoundtrip)
|
||||
{
|
||||
std::string u8 = "hello 你好";
|
||||
std::wstring wc = dl::CodeCvt::Utf8ToWideChar(u8);
|
||||
std::string back = dl::CodeCvt::WideCharToUtf8(wc);
|
||||
EXPECT_EQ(back, u8);
|
||||
}
|
||||
|
||||
TEST(CodeCvtTest, Utf32Roundtrip)
|
||||
{
|
||||
std::string u8 = "hello 你好";
|
||||
std::u32string u32 = dl::CodeCvt::Utf8ToUtf32(u8);
|
||||
std::string back = dl::CodeCvt::Utf32ToUtf8(u32);
|
||||
EXPECT_EQ(back, u8);
|
||||
}
|
||||
|
||||
//------------------------------File 文件操作------------------------------
|
||||
TEST(FileTest, CreateReadDelete)
|
||||
{
|
||||
std::string dir = dl::g_factory->GetPathTemp() + "dl_file_test/";
|
||||
dl::File::Delete(dir, true);
|
||||
|
||||
ASSERT_TRUE(dl::File::CreateFolder(dir));
|
||||
EXPECT_TRUE(dl::File::IsExist(dir));
|
||||
|
||||
std::string file = dir + "a.txt";
|
||||
ASSERT_TRUE(dl::File::SaveString("hello", file));
|
||||
EXPECT_TRUE(dl::File::IsExist(file));
|
||||
EXPECT_FALSE(dl::File::IsExist(dir + "none.txt"));
|
||||
|
||||
EXPECT_EQ(dl::File::GetString(file), "hello");
|
||||
|
||||
EXPECT_TRUE(dl::File::Delete(file));
|
||||
EXPECT_FALSE(dl::File::IsExist(file));
|
||||
|
||||
dl::File::Delete(dir, true);
|
||||
}
|
||||
|
||||
TEST(FileTest, CopyRename)
|
||||
{
|
||||
std::string dir = dl::g_factory->GetPathTemp() + "dl_file_test/";
|
||||
dl::File::Delete(dir, true);
|
||||
ASSERT_TRUE(dl::File::CreateFolder(dir));
|
||||
|
||||
std::string src = dir + "src.txt";
|
||||
std::string dst = dir + "dst.txt";
|
||||
ASSERT_TRUE(dl::File::SaveString("data", src));
|
||||
|
||||
EXPECT_TRUE(dl::File::Copy(src, dst));
|
||||
EXPECT_TRUE(dl::File::IsExist(dst));
|
||||
EXPECT_EQ(dl::File::GetString(dst), "data");
|
||||
|
||||
std::string dst2 = dir + "dst2.txt";
|
||||
EXPECT_TRUE(dl::File::Rename(dst, dst2));
|
||||
EXPECT_TRUE(dl::File::IsExist(dst2));
|
||||
EXPECT_FALSE(dl::File::IsExist(dst));
|
||||
|
||||
dl::File::Delete(dir, true);
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
/**
|
||||
* @file test_main.cpp
|
||||
* @brief dl 单元测试入口(Main 函数,由 dl_main 调用)
|
||||
*
|
||||
*
|
||||
* @version 1.0
|
||||
* @author CodeBuddy
|
||||
* @date 26-09-03
|
||||
*
|
||||
* @note 复用 dl_main 的 main 入口,这里提供 Main() 跑 GoogleTest
|
||||
*/
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "system/dl_engine.h"
|
||||
#include "system/dl_system.h"
|
||||
#include "io/dl_log.h"
|
||||
#include "io/dl_file.h"
|
||||
#include "render/dl_factory.h"
|
||||
|
||||
//! 用 dl 日志打印 gtest 结果(dl 日志会同时写入日志文件,控制台滚动后仍可查完整结果)
|
||||
class DlLogListener : public ::testing::EmptyTestEventListener
|
||||
{
|
||||
//! 用 dl::Output 直接输出(纯字符串,同时写入 stdout/VS/日志文件)
|
||||
static void Print(std::string_view str)
|
||||
{
|
||||
dl::Output(str);
|
||||
dl::Output("\n");
|
||||
}
|
||||
static std::string FileName(const char* path)
|
||||
{
|
||||
return dl::File::GetFileName(path);
|
||||
}
|
||||
|
||||
public:
|
||||
void OnTestProgramStart(const ::testing::UnitTest& unit_test) override
|
||||
{
|
||||
Print(fmt::format("[==========] 运行 {} 个测试", unit_test.test_to_run_count()));
|
||||
}
|
||||
|
||||
void OnTestStart(const ::testing::TestInfo& test_info) override
|
||||
{
|
||||
Print(fmt::format("[ RUN ] {}.{} ({}:{})",
|
||||
test_info.test_suite_name(), test_info.name(),
|
||||
FileName(test_info.file()), test_info.line()));
|
||||
}
|
||||
|
||||
void OnTestPartResult(const ::testing::TestPartResult& result) override
|
||||
{
|
||||
if (result.failed())
|
||||
Print(fmt::format("{}:{}: {}", result.file_name(), result.line_number(), result.message()));
|
||||
}
|
||||
|
||||
void OnTestEnd(const ::testing::TestInfo& test_info) override
|
||||
{
|
||||
if (test_info.result()->Passed())
|
||||
Print(fmt::format("[ OK ] {}.{}", test_info.test_suite_name(), test_info.name()));
|
||||
else
|
||||
Print(fmt::format("[ FAILED ] {}.{} ({}:{})",
|
||||
test_info.test_suite_name(), test_info.name(),
|
||||
FileName(test_info.file()), test_info.line()));
|
||||
}
|
||||
|
||||
void OnTestProgramEnd(const ::testing::UnitTest& unit_test) override
|
||||
{
|
||||
Print(fmt::format("[==========] {} 通过,{} 失败,{} 跳过",
|
||||
unit_test.successful_test_count(),
|
||||
unit_test.failed_test_count(),
|
||||
unit_test.skipped_test_count()));
|
||||
}
|
||||
};
|
||||
|
||||
int Main()
|
||||
{
|
||||
// 测试结果写入 dl 日志文件
|
||||
dl::g_log->SetLogFile("log/", "unit_test.txt");
|
||||
// 按正常使用方式初始化引擎(log_err/log_warn 依赖的 g_log 等全局对象在此初始化)
|
||||
dl::Engine::GetParamRef()._test = false; // 关闭引擎内置测试
|
||||
dl::Engine::GetParamRef()._showInfo = false; // 关闭引擎信息输出
|
||||
dl::Engine::Init();
|
||||
|
||||
// 初始化 g_factory 路径(正常在 System::Start 时调用 _init_path,测试环境手动设置)
|
||||
dl::g_factory->SetPath();
|
||||
dl::File::CreateFolder(dl::g_factory->GetPathTemp());
|
||||
|
||||
// 关闭 err 日志的 MessageBox 弹窗(单元测试触发 log_err 不应中断等待点击)
|
||||
dl::g_log->SetLevelMsgBox(dl::LogSystem::Level::DAMAGE);
|
||||
|
||||
// gtest 命令行参数(dl_main_init 已通过 Engine::_init_cmd 保存)
|
||||
const auto& cmd = dl::Engine::GetCmd();
|
||||
std::vector<char*> argv;
|
||||
if (cmd.empty())
|
||||
{
|
||||
static std::string exe = "dl_unit_test";
|
||||
argv.push_back(const_cast<char*>(exe.c_str()));
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto& c : cmd)
|
||||
argv.push_back(const_cast<char*>(c.c_str()));
|
||||
}
|
||||
|
||||
int argc = (int)argv.size();
|
||||
::testing::InitGoogleTest(&argc, argv.data());
|
||||
|
||||
// 用 dl 日志打印测试结果(替换 gtest 默认输出,避免控制台刷屏)
|
||||
auto& listeners = ::testing::UnitTest::GetInstance()->listeners();
|
||||
delete listeners.Release(listeners.default_result_printer());
|
||||
listeners.Append(new DlLogListener);
|
||||
|
||||
int ret = RUN_ALL_TESTS();
|
||||
|
||||
// 测试完成后暂停,方便观察结果
|
||||
dl::g_system->Pause();
|
||||
|
||||
dl::Engine::Release();
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
/**
|
||||
* @file test_math.cpp
|
||||
* @brief math 模块单元测试(Math 命名空间)
|
||||
*
|
||||
*
|
||||
* @version 1.0
|
||||
* @author CodeBuddy
|
||||
* @date 26-09-03
|
||||
*
|
||||
* @note
|
||||
*/
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "math/dl_math.h"
|
||||
#include "math/dl_random.h"
|
||||
#include "math/dl_texture_pack.h"
|
||||
|
||||
TEST(MathTest, Pow)
|
||||
{
|
||||
EXPECT_EQ(dl::Math::Pow(2, 10), 1024);
|
||||
EXPECT_EQ(dl::Math::Pow64(2, 10), 1024ull);
|
||||
EXPECT_EQ(dl::Math::Pow32(2, 10), 1024u);
|
||||
}
|
||||
|
||||
TEST(MathTest, SubU)
|
||||
{
|
||||
EXPECT_EQ(dl::Math::SubU(5u, 3u), 2u);
|
||||
EXPECT_EQ(dl::Math::SubU(3u, 5u), 0u);
|
||||
}
|
||||
|
||||
TEST(MathTest, DisU)
|
||||
{
|
||||
EXPECT_EQ(dl::Math::DisU(3u, 5u), 2u);
|
||||
EXPECT_EQ(dl::Math::DisU(5u, 3u), 2u);
|
||||
}
|
||||
|
||||
TEST(MathTest, IsPow2)
|
||||
{
|
||||
EXPECT_TRUE(dl::Math::IsPow2(8));
|
||||
EXPECT_TRUE(dl::Math::IsPow2(1));
|
||||
EXPECT_FALSE(dl::Math::IsPow2(0));
|
||||
EXPECT_FALSE(dl::Math::IsPow2(6));
|
||||
}
|
||||
|
||||
TEST(MathTest, AlignPow2)
|
||||
{
|
||||
EXPECT_EQ(dl::Math::AlignPow2(5u, 4u), 8u);
|
||||
EXPECT_EQ(dl::Math::AlignPow2(8u, 4u), 8u);
|
||||
EXPECT_EQ(dl::Math::AlignPow2(1u, 4u), 4u);
|
||||
// 非 2 的幂返回 0
|
||||
EXPECT_EQ(dl::Math::AlignPow2(5u, 3u), 0u);
|
||||
}
|
||||
|
||||
TEST(MathTest, DistancePow2)
|
||||
{
|
||||
dl::Position a{ 0.0f, 0.0f };
|
||||
dl::Position b{ 3.0f, 4.0f };
|
||||
EXPECT_FLOAT_EQ(dl::Math::DistancePow2(a, b), 25.0f);
|
||||
EXPECT_FLOAT_EQ(dl::Math::Distance(b - a), 5.0f);
|
||||
}
|
||||
|
||||
TEST(MathTest, DotProduct)
|
||||
{
|
||||
dl::Position a{ 1.0f, 2.0f };
|
||||
dl::Position b{ 3.0f, 4.0f };
|
||||
EXPECT_FLOAT_EQ(dl::Math::DotProduct(a, b), 11.0f); // 1*3 + 2*4
|
||||
}
|
||||
|
||||
TEST(MathTest, CrossProduct)
|
||||
{
|
||||
dl::Position2 a{ 1.0f, 0.0f };
|
||||
dl::Position2 b{ 0.0f, 1.0f };
|
||||
EXPECT_FLOAT_EQ(dl::Math::CrossProduct(a, b), 1.0f);
|
||||
}
|
||||
|
||||
TEST(MathTest, IsLeapYear)
|
||||
{
|
||||
EXPECT_TRUE(dl::Math::IsLeapYear(2000));
|
||||
EXPECT_TRUE(dl::Math::IsLeapYear(2024));
|
||||
EXPECT_FALSE(dl::Math::IsLeapYear(1900));
|
||||
EXPECT_FALSE(dl::Math::IsLeapYear(2023));
|
||||
}
|
||||
|
||||
TEST(MathTest, GetMouthDayNum)
|
||||
{
|
||||
EXPECT_EQ(dl::Math::GetMouthDayNum(2024, 2), 29); // 闰年二月
|
||||
EXPECT_EQ(dl::Math::GetMouthDayNum(2023, 2), 28); // 平年二月
|
||||
EXPECT_EQ(dl::Math::GetMouthDayNum(2024, 1), 31);
|
||||
EXPECT_EQ(dl::Math::GetMouthDayNum(2024, 4), 30);
|
||||
}
|
||||
|
||||
//------------------------------算法------------------------------
|
||||
TEST(MathTest, Clamp)
|
||||
{
|
||||
EXPECT_EQ(dl::clamp(5, 1, 3), 3); // 上界
|
||||
EXPECT_EQ(dl::clamp(0, 1, 3), 1); // 下界
|
||||
EXPECT_EQ(dl::clamp(2, 1, 3), 2); // 中间
|
||||
EXPECT_FLOAT_EQ(dl::clamp(1.5f, 0.0f, 1.0f), 1.0f);
|
||||
EXPECT_FLOAT_EQ(dl::clamp(-0.5f, 0.0f, 1.0f), 0.0f);
|
||||
}
|
||||
|
||||
TEST(MathTest, Saturate)
|
||||
{
|
||||
EXPECT_FLOAT_EQ(dl::saturate(0.5f), 0.5f);
|
||||
EXPECT_FLOAT_EQ(dl::saturate(2.0f), 1.0f);
|
||||
EXPECT_FLOAT_EQ(dl::saturate(-1.0f), 0.0f);
|
||||
EXPECT_TRUE(dl::is_saturate(0.5f));
|
||||
EXPECT_FALSE(dl::is_saturate(1.5f));
|
||||
}
|
||||
|
||||
TEST(MathTest, Sign)
|
||||
{
|
||||
EXPECT_EQ(dl::sign(5), 1);
|
||||
EXPECT_EQ(dl::sign(-5), -1);
|
||||
EXPECT_EQ(dl::sign(0), 0);
|
||||
}
|
||||
|
||||
TEST(MathTest, Cross3)
|
||||
{
|
||||
dl::Position3 a{ 1.0f, 0.0f, 0.0f };
|
||||
dl::Position3 b{ 0.0f, 1.0f, 0.0f };
|
||||
auto c = dl::cross(a, b);
|
||||
EXPECT_FLOAT_EQ(c[0], 0.0f);
|
||||
EXPECT_FLOAT_EQ(c[1], 0.0f);
|
||||
EXPECT_FLOAT_EQ(c[2], 1.0f);
|
||||
}
|
||||
|
||||
TEST(MathTest, InsertPerNum)
|
||||
{
|
||||
EXPECT_EQ(dl::insert_per_num(std::string("1234567890"), ',', 3), "123,456,789,0");
|
||||
EXPECT_EQ(dl::r_insert_per_num(std::string("123456789"), ',', 3), "123,456,789");
|
||||
}
|
||||
|
||||
TEST(MathTest, MakeSequence)
|
||||
{
|
||||
std::vector<int> v;
|
||||
dl::make_sequence<std::vector<int>, int>(v, { {0, 3}, {5, 7} });
|
||||
ASSERT_EQ(v.size(), 5u);
|
||||
EXPECT_EQ(v[0], 0);
|
||||
EXPECT_EQ(v[1], 1);
|
||||
EXPECT_EQ(v[2], 2);
|
||||
EXPECT_EQ(v[3], 5);
|
||||
EXPECT_EQ(v[4], 6);
|
||||
}
|
||||
|
||||
//------------------------------Random------------------------------
|
||||
TEST(RandomTest, SetSeed)
|
||||
{
|
||||
dl::Random::SetSeed(42);
|
||||
int a = dl::Random::Int(0, 100);
|
||||
dl::Random::SetSeed(42);
|
||||
int b = dl::Random::Int(0, 100);
|
||||
EXPECT_EQ(a, b); // 同种子结果一致
|
||||
}
|
||||
|
||||
TEST(RandomTest, IntRange)
|
||||
{
|
||||
dl::Random::SetSeed(1);
|
||||
for (int i = 0; i < 100; ++i)
|
||||
{
|
||||
int v = dl::Random::Int(10, 20);
|
||||
EXPECT_GE(v, 10);
|
||||
EXPECT_LE(v, 20);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(RandomTest, FloatRange)
|
||||
{
|
||||
dl::Random::SetSeed(1);
|
||||
for (int i = 0; i < 100; ++i)
|
||||
{
|
||||
float v = dl::Random::Float(0.0f, 1.0f);
|
||||
EXPECT_GE(v, 0.0f);
|
||||
EXPECT_LT(v, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(RandomTest, Percent)
|
||||
{
|
||||
dl::Random::SetSeed(1);
|
||||
EXPECT_TRUE(dl::Random::Percent(100));
|
||||
EXPECT_FALSE(dl::Random::Percent(0));
|
||||
}
|
||||
|
||||
TEST(RandomTest, Select)
|
||||
{
|
||||
std::vector<int> v = { 1, 2, 3, 4, 5 };
|
||||
dl::Random::SetSeed(1);
|
||||
int sel = dl::Random::Select(v);
|
||||
EXPECT_GE(sel, 1);
|
||||
EXPECT_LE(sel, 5);
|
||||
}
|
||||
|
||||
//------------------------------TexturePack------------------------------
|
||||
TEST(TexturePackTest, Dynamic)
|
||||
{
|
||||
dl::TexturePack::Dynamic<2> pack;
|
||||
pack.Reset({ 100, 100 });
|
||||
|
||||
dl::RectU r1;
|
||||
EXPECT_TRUE(pack.Add({ 30, 30 }, r1));
|
||||
EXPECT_EQ(r1[0], 0u);
|
||||
EXPECT_EQ(r1[1], 0u);
|
||||
EXPECT_EQ(r1[2], 30u);
|
||||
EXPECT_EQ(r1[3], 30u);
|
||||
|
||||
dl::RectU r2;
|
||||
EXPECT_TRUE(pack.Add({ 30, 30 }, r2));
|
||||
EXPECT_EQ(r2[0], 30u); // 同一行,x 偏移
|
||||
EXPECT_EQ(r2[1], 0u);
|
||||
|
||||
dl::RectU r3;
|
||||
EXPECT_TRUE(pack.Add({ 30, 30 }, r3));
|
||||
EXPECT_EQ(r3[0], 60u);
|
||||
EXPECT_EQ(r3[1], 0u);
|
||||
|
||||
dl::RectU r4;
|
||||
EXPECT_TRUE(pack.Add({ 30, 30 }, r4));
|
||||
EXPECT_EQ(r4[0], 0u); // 换行
|
||||
EXPECT_EQ(r4[1], 30u);
|
||||
}
|
||||
|
||||
TEST(TexturePackTest, Static)
|
||||
{
|
||||
dl::TexturePack::Static pack;
|
||||
pack.SetSize({ 100, 100 });
|
||||
|
||||
std::list<dl::Size> boxes = { {50, 50}, {50, 50}, {100, 50} };
|
||||
std::vector<dl::PointU> results;
|
||||
pack.Calc(boxes,
|
||||
[](const dl::Size& s) { return s; },
|
||||
[&](const dl::Size& s, const dl::PointU& lt) { results.push_back(lt); });
|
||||
|
||||
// 3 个箱子总面积 10000 = 100*100,能全部放下
|
||||
EXPECT_TRUE(boxes.empty());
|
||||
EXPECT_EQ(results.size(), 3u);
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
/**
|
||||
* @file test_memory.cpp
|
||||
* @brief memory 模块单元测试(压缩)
|
||||
*
|
||||
*
|
||||
* @version 1.0
|
||||
* @author CodeBuddy
|
||||
* @date 26-09-03
|
||||
*
|
||||
* @note
|
||||
*/
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "memory/dl_memory.h"
|
||||
#include "memory/dl_stream_output.h"
|
||||
#include "memory/dl_stream_input.h"
|
||||
#include "base/dl_string.h"
|
||||
|
||||
TEST(MemoryTest, CompressLz4)
|
||||
{
|
||||
std::string str("abcabcabcabcabc");
|
||||
dl::BufferView buf = dl::CreateBufferView(str);
|
||||
dl::Buffer zip = dl::Memory::CompressLz4(buf);
|
||||
EXPECT_FALSE(zip.empty());
|
||||
|
||||
dl::Buffer unzip = dl::Memory::DecompressLz4(zip);
|
||||
EXPECT_EQ(dl::to_string(unzip), str);
|
||||
}
|
||||
|
||||
TEST(MemoryTest, DecompressLz4WithSize)
|
||||
{
|
||||
std::string str("hello world hello world");
|
||||
dl::BufferView buf = dl::CreateBufferView(str);
|
||||
dl::Buffer zip = dl::Memory::CompressLz4(buf);
|
||||
|
||||
dl::Buffer unzip = dl::Memory::DecompressLz4(zip, str.size());
|
||||
EXPECT_EQ(dl::to_string(unzip), str);
|
||||
}
|
||||
|
||||
TEST(MemoryTest, CompressZip)
|
||||
{
|
||||
std::string str("abcabcabcabcabc");
|
||||
dl::BufferView buf = dl::CreateBufferView(str);
|
||||
dl::Buffer zip = dl::Memory::CompressZip(buf);
|
||||
EXPECT_FALSE(zip.empty());
|
||||
|
||||
dl::Buffer unzip = dl::Memory::DecompressZip(zip);
|
||||
EXPECT_EQ(dl::to_string(unzip), str);
|
||||
}
|
||||
|
||||
TEST(MemoryTest, CompressEmpty)
|
||||
{
|
||||
std::string str;
|
||||
dl::BufferView buf = dl::CreateBufferView(str);
|
||||
dl::Buffer zip = dl::Memory::CompressLz4(buf);
|
||||
dl::Buffer unzip = dl::Memory::DecompressLz4(zip);
|
||||
EXPECT_EQ(dl::to_string(unzip), str);
|
||||
}
|
||||
|
||||
//------------------------------Stream 序列化往返------------------------------
|
||||
TEST(StreamTest, WriteReadBasic)
|
||||
{
|
||||
dl::StreamOutput s;
|
||||
int a = 42;
|
||||
float b = 3.14f;
|
||||
double c = 2.718;
|
||||
s.Write(&a);
|
||||
s.Write(&b);
|
||||
s.Write(&c);
|
||||
|
||||
dl::Buffer buf = s.ToBuffer();
|
||||
dl::StreamInput in;
|
||||
in.LoadFromMemory(buf);
|
||||
|
||||
int a2 = 0;
|
||||
float b2 = 0;
|
||||
double c2 = 0;
|
||||
in.Read(&a2);
|
||||
in.Read(&b2);
|
||||
in.Read(&c2);
|
||||
|
||||
EXPECT_EQ(a2, 42);
|
||||
EXPECT_FLOAT_EQ(b2, 3.14f);
|
||||
EXPECT_DOUBLE_EQ(c2, 2.718);
|
||||
}
|
||||
|
||||
TEST(StreamTest, WriteRead64)
|
||||
{
|
||||
dl::StreamOutput s;
|
||||
size_t v = 123456789;
|
||||
s.Write64(&v);
|
||||
|
||||
dl::Buffer buf = s.ToBuffer();
|
||||
dl::StreamInput in;
|
||||
in.LoadFromMemory(buf);
|
||||
|
||||
size_t v2 = 0;
|
||||
in.Read64(&v2);
|
||||
EXPECT_EQ(v2, 123456789u);
|
||||
}
|
||||
|
||||
TEST(StreamTest, WriteReadString)
|
||||
{
|
||||
dl::StreamOutput s;
|
||||
std::string str = "hello world";
|
||||
s.Write(&str);
|
||||
|
||||
dl::Buffer buf = s.ToBuffer();
|
||||
dl::StreamInput in;
|
||||
in.LoadFromMemory(buf);
|
||||
|
||||
std::string str2;
|
||||
in.Read(&str2);
|
||||
EXPECT_EQ(str2, "hello world");
|
||||
}
|
||||
|
||||
TEST(StreamTest, WriteReadVector)
|
||||
{
|
||||
dl::StreamOutput s;
|
||||
std::vector<int> vec = { 1, 2, 3, 4, 5 };
|
||||
s.Write(&vec);
|
||||
|
||||
dl::Buffer buf = s.ToBuffer();
|
||||
dl::StreamInput in;
|
||||
in.LoadFromMemory(buf);
|
||||
|
||||
std::vector<int> vec2;
|
||||
in.Read(&vec2);
|
||||
ASSERT_EQ(vec2.size(), 5u);
|
||||
EXPECT_EQ(vec2[0], 1);
|
||||
EXPECT_EQ(vec2[4], 5);
|
||||
}
|
||||
|
||||
TEST(StreamTest, WriteReadMap)
|
||||
{
|
||||
dl::StreamOutput s;
|
||||
std::map<std::string, int> m = { {"a", 1}, {"b", 2} };
|
||||
s.Write(&m);
|
||||
|
||||
dl::Buffer buf = s.ToBuffer();
|
||||
dl::StreamInput in;
|
||||
in.LoadFromMemory(buf);
|
||||
|
||||
std::map<std::string, int> m2;
|
||||
in.Read(&m2);
|
||||
ASSERT_EQ(m2.size(), 2u);
|
||||
EXPECT_EQ(m2["a"], 1);
|
||||
EXPECT_EQ(m2["b"], 2);
|
||||
}
|
||||
|
||||
TEST(StreamTest, WriteReadUnorderedMap)
|
||||
{
|
||||
dl::StreamOutput s;
|
||||
std::unordered_map<std::string, int> m = { {"x", 10}, {"y", 20} };
|
||||
s.Write(&m);
|
||||
|
||||
dl::Buffer buf = s.ToBuffer();
|
||||
dl::StreamInput in;
|
||||
in.LoadFromMemory(buf);
|
||||
|
||||
std::unordered_map<std::string, int> m2;
|
||||
in.Read(&m2);
|
||||
ASSERT_EQ(m2.size(), 2u);
|
||||
EXPECT_EQ(m2["x"], 10);
|
||||
EXPECT_EQ(m2["y"], 20);
|
||||
}
|
||||
|
||||
//------------------------------Buffer------------------------------
|
||||
TEST(BufferTest, Hex)
|
||||
{
|
||||
// "Hello" 的十六进制
|
||||
dl::Buffer buf = dl::CreateBufferHex("48656c6c6f");
|
||||
ASSERT_EQ(buf.size(), 5u);
|
||||
EXPECT_EQ(dl::to_string(buf), "Hello");
|
||||
EXPECT_EQ(dl::to_string_hex(buf), "48656c6c6f");
|
||||
EXPECT_EQ(dl::to_string_hex(buf, false, true), "0x48656c6c6f");
|
||||
}
|
||||
|
||||
TEST(BufferTest, Append)
|
||||
{
|
||||
dl::Buffer buf = dl::CreateBuffer(dl::CreateBufferView(std::string("hello")));
|
||||
dl::BufferAppend(buf, dl::CreateBufferView(std::string(" world")));
|
||||
EXPECT_EQ(dl::to_string(buf), "hello world");
|
||||
}
|
||||
|
||||
TEST(BufferTest, Basic)
|
||||
{
|
||||
dl::Buffer buf;
|
||||
EXPECT_TRUE(buf.empty());
|
||||
|
||||
buf.resize(10);
|
||||
EXPECT_EQ(buf.size(), 10u);
|
||||
EXPECT_FALSE(buf.empty());
|
||||
|
||||
buf.clear();
|
||||
EXPECT_TRUE(buf.empty());
|
||||
EXPECT_EQ(buf.size(), 0u);
|
||||
}
|
||||
@@ -0,0 +1,589 @@
|
||||
/**
|
||||
* @file test_misc.cpp
|
||||
* @brief misc 模块单元测试(Value、Locator、Timer、Layout、AStar、CodeWriter)
|
||||
*
|
||||
*
|
||||
* @version 1.0
|
||||
* @author CodeBuddy
|
||||
* @date 26-09-03
|
||||
*
|
||||
* @note
|
||||
*/
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "dl_type.h"
|
||||
#include "misc/dl_value.h"
|
||||
#include "misc/dl_locator.h"
|
||||
#include "misc/dl_layout.h"
|
||||
#include "misc/dl_timer.h"
|
||||
#include "misc/dl_astar.h"
|
||||
#include "misc/dl_code_writer.h"
|
||||
#include "misc/dl_tilemap.h"
|
||||
#include "misc/dl_json_config.h"
|
||||
#include "misc/dl_language.h"
|
||||
#include "io/dl_file.h"
|
||||
#include "render/dl_factory.h"
|
||||
|
||||
#include <OpenXLSX.hpp>
|
||||
|
||||
//------------------------------Value------------------------------
|
||||
TEST(ValueTest, DefaultNone)
|
||||
{
|
||||
dl::Value v;
|
||||
EXPECT_EQ(v.GetType(), dl::ValueType::NONE);
|
||||
EXPECT_FALSE(v);
|
||||
EXPECT_EQ(v.GetString(), "null");
|
||||
}
|
||||
|
||||
TEST(ValueTest, Bool)
|
||||
{
|
||||
dl::Value v(true);
|
||||
EXPECT_EQ(v.GetType(), dl::ValueType::BOOL);
|
||||
EXPECT_TRUE(v.ToBool());
|
||||
EXPECT_EQ(v.GetString(), "true");
|
||||
|
||||
dl::Value vf(false);
|
||||
EXPECT_FALSE(vf.ToBool());
|
||||
EXPECT_EQ(vf.GetString(), "false");
|
||||
}
|
||||
|
||||
TEST(ValueTest, Int)
|
||||
{
|
||||
dl::Value v(42);
|
||||
EXPECT_EQ(v.GetType(), dl::ValueType::INT);
|
||||
EXPECT_EQ(v.ToInt(), 42);
|
||||
EXPECT_FLOAT_EQ(v.ToFloat(), 42.0f);
|
||||
EXPECT_DOUBLE_EQ(v.ToDouble(), 42.0);
|
||||
EXPECT_EQ(v.GetString(), "42");
|
||||
}
|
||||
|
||||
TEST(ValueTest, FloatDouble)
|
||||
{
|
||||
dl::Value vf(3.14f);
|
||||
EXPECT_EQ(vf.GetType(), dl::ValueType::FLOAT);
|
||||
EXPECT_FLOAT_EQ(vf.ToFloat(), 3.14f);
|
||||
|
||||
dl::Value vd(3.14);
|
||||
EXPECT_EQ(vd.GetType(), dl::ValueType::DOUBLE);
|
||||
EXPECT_DOUBLE_EQ(vd.ToDouble(), 3.14);
|
||||
}
|
||||
|
||||
TEST(ValueTest, String)
|
||||
{
|
||||
dl::Value v("hello");
|
||||
EXPECT_EQ(v.GetType(), dl::ValueType::STRING);
|
||||
EXPECT_EQ(v.ToString(), "hello");
|
||||
EXPECT_EQ(v.GetString(), "\"hello\"");
|
||||
EXPECT_EQ(v.GetString(false), "hello");
|
||||
}
|
||||
|
||||
TEST(ValueTest, CopyString)
|
||||
{
|
||||
dl::Value a(std::string("hello"));
|
||||
dl::Value b = a;
|
||||
EXPECT_EQ(b.GetType(), dl::ValueType::STRING);
|
||||
EXPECT_EQ(b.ToString(), "hello");
|
||||
}
|
||||
|
||||
TEST(ValueTest, Vector)
|
||||
{
|
||||
dl::ValueVector vec(dl::ValueType::INT);
|
||||
vec.PushBack(1);
|
||||
vec.PushBack(2);
|
||||
vec.PushBack(3);
|
||||
|
||||
dl::Value v(vec);
|
||||
EXPECT_EQ(v.GetType(), dl::ValueType::VECTOR);
|
||||
EXPECT_EQ(v.GetString(), "{ 1, 2, 3 }");
|
||||
|
||||
auto j = v.GetJson();
|
||||
ASSERT_TRUE(j.is_array());
|
||||
ASSERT_EQ(j.size(), 3u);
|
||||
EXPECT_EQ(j[0], 1);
|
||||
EXPECT_EQ(j[2], 3);
|
||||
}
|
||||
|
||||
TEST(ValueTest, Array)
|
||||
{
|
||||
dl::Value v(std::array<int, 3>{10, 20, 30});
|
||||
EXPECT_EQ(v.GetType(), dl::ValueType::ARRAY);
|
||||
auto arr = v.ToArray<3>();
|
||||
EXPECT_EQ(arr[0].ToInt(), 10);
|
||||
EXPECT_EQ(arr[1].ToInt(), 20);
|
||||
EXPECT_EQ(arr[2].ToInt(), 30);
|
||||
}
|
||||
|
||||
TEST(ValueTest, Struct)
|
||||
{
|
||||
dl::ValueStruct s("student");
|
||||
dl::Value v_id(100);
|
||||
dl::Value v_name("tom");
|
||||
s.AddMember("id", v_id);
|
||||
s.AddMember("name", v_name);
|
||||
|
||||
EXPECT_EQ(s.GetName(), "student");
|
||||
EXPECT_EQ(s["id"].ToInt(), 100);
|
||||
EXPECT_EQ(s.GetMember("name").ToString(), "tom");
|
||||
}
|
||||
|
||||
TEST(ValueTest, CastFailed)
|
||||
{
|
||||
dl::Value v("hello");
|
||||
EXPECT_EQ(v.ToInt(), 0);
|
||||
EXPECT_FLOAT_EQ(v.ToFloat(), 0.0f);
|
||||
EXPECT_FALSE(v.ToBool());
|
||||
}
|
||||
|
||||
TEST(ValueTest, OperatorBool)
|
||||
{
|
||||
dl::Value v_none;
|
||||
EXPECT_FALSE(v_none);
|
||||
|
||||
dl::Value v_false(false);
|
||||
EXPECT_FALSE(v_false);
|
||||
|
||||
dl::Value v_true(true);
|
||||
EXPECT_TRUE(v_true);
|
||||
|
||||
dl::Value v_int(0);
|
||||
EXPECT_TRUE(v_int); // 非 NONE/BOOL 恒为真
|
||||
}
|
||||
|
||||
//------------------------------类型转换------------------------------
|
||||
TEST(ValueTest, String2ValueType)
|
||||
{
|
||||
EXPECT_EQ(dl::String2ValueType("bool"), dl::ValueType::BOOL);
|
||||
EXPECT_EQ(dl::String2ValueType("int"), dl::ValueType::INT);
|
||||
EXPECT_EQ(dl::String2ValueType("uint"), dl::ValueType::UINT);
|
||||
EXPECT_EQ(dl::String2ValueType("int64"), dl::ValueType::INT64);
|
||||
EXPECT_EQ(dl::String2ValueType("float"), dl::ValueType::FLOAT);
|
||||
EXPECT_EQ(dl::String2ValueType("double"), dl::ValueType::DOUBLE);
|
||||
EXPECT_EQ(dl::String2ValueType("string"), dl::ValueType::STRING);
|
||||
EXPECT_EQ(dl::String2ValueType("array<int, 3>"), dl::ValueType::ARRAY);
|
||||
EXPECT_EQ(dl::String2ValueType("vector<int>"), dl::ValueType::VECTOR);
|
||||
EXPECT_EQ(dl::String2ValueType("MyStruct"), dl::ValueType::STRUCT);
|
||||
}
|
||||
|
||||
TEST(ValueTest, String2ValueTypeEx)
|
||||
{
|
||||
auto info = dl::String2ValueTypeEx("array<int, 3>");
|
||||
EXPECT_EQ(info._type0, dl::ValueType::ARRAY);
|
||||
EXPECT_EQ(info._type1, dl::ValueType::INT);
|
||||
EXPECT_EQ(info._length, 3u);
|
||||
EXPECT_EQ(info._strType1, "int");
|
||||
|
||||
auto info2 = dl::String2ValueTypeEx("vector<float>");
|
||||
EXPECT_EQ(info2._type0, dl::ValueType::VECTOR);
|
||||
EXPECT_EQ(info2._type1, dl::ValueType::FLOAT);
|
||||
EXPECT_EQ(info2._length, 0u);
|
||||
}
|
||||
|
||||
TEST(ValueTest, ToStringType)
|
||||
{
|
||||
EXPECT_EQ(dl::to_string(dl::ValueType::NONE), "null");
|
||||
EXPECT_EQ(dl::to_string(dl::ValueType::INT), "int");
|
||||
EXPECT_EQ(dl::to_string(dl::ValueType::STRING), "string");
|
||||
EXPECT_EQ(dl::to_string(dl::ValueType::ARRAY), "array");
|
||||
EXPECT_EQ(dl::to_string(dl::ValueType::MAP), "map");
|
||||
}
|
||||
|
||||
TEST(ValueTest, Type2CppType)
|
||||
{
|
||||
EXPECT_EQ(dl::Type2CppType(dl::ValueType::INT), "int");
|
||||
EXPECT_EQ(dl::Type2CppType(dl::ValueType::UINT), "unsigned");
|
||||
EXPECT_EQ(dl::Type2CppType(dl::ValueType::UCHAR), "unsigned char");
|
||||
EXPECT_EQ(dl::Type2CppType(dl::ValueType::STRING), "std::string");
|
||||
EXPECT_EQ(dl::Type2CppType(dl::ValueType::ARRAY), "std::array");
|
||||
EXPECT_EQ(dl::Type2CppType(dl::ValueType::VECTOR), "std::vector");
|
||||
EXPECT_EQ(dl::Type2CppType(dl::ValueType::POINTER), "void*");
|
||||
EXPECT_EQ(dl::Type2CppTypeEx(dl::ValueType::ARRAY, dl::ValueType::INT, 3), "std::array<int, 3>");
|
||||
}
|
||||
|
||||
//------------------------------Layout------------------------------
|
||||
TEST(LayoutTest, String2Layout)
|
||||
{
|
||||
EXPECT_EQ(dl::String2Layout("x"), dl::Layout::X);
|
||||
EXPECT_EQ(dl::String2Layout("y"), dl::Layout::Y);
|
||||
EXPECT_EQ(dl::String2Layout("xy"), dl::Layout::XY);
|
||||
EXPECT_EQ(dl::String2Layout("origin"), dl::Layout::ORIGIN);
|
||||
EXPECT_EQ(dl::String2Layout("X"), dl::Layout::X);
|
||||
EXPECT_EQ(dl::String2Layout("XY"), dl::Layout::XY);
|
||||
}
|
||||
|
||||
//------------------------------Locator------------------------------
|
||||
TEST(LocatorTest, DirectX)
|
||||
{
|
||||
auto loc = dl::createLocatorX(10.0f);
|
||||
EXPECT_FLOAT_EQ(loc.Get(0)[0], 0.0f);
|
||||
EXPECT_FLOAT_EQ(loc.Get(0)[1], 0.0f);
|
||||
EXPECT_FLOAT_EQ(loc.Get(1)[0], 10.0f);
|
||||
EXPECT_FLOAT_EQ(loc.Get(2)[0], 20.0f);
|
||||
}
|
||||
|
||||
TEST(LocatorTest, DirectXWrap)
|
||||
{
|
||||
auto loc = dl::createLocatorX(10.0f, 3);
|
||||
EXPECT_FLOAT_EQ(loc.Get(0)[0], 0.0f);
|
||||
EXPECT_FLOAT_EQ(loc.Get(1)[0], 10.0f);
|
||||
EXPECT_FLOAT_EQ(loc.Get(2)[0], 20.0f);
|
||||
auto p3 = loc.Get(3);
|
||||
EXPECT_FLOAT_EQ(p3[0], 0.0f);
|
||||
EXPECT_FLOAT_EQ(p3[1], 32.0f);
|
||||
}
|
||||
|
||||
TEST(LocatorTest, DirectY)
|
||||
{
|
||||
auto loc = dl::createLocatorY(10.0f);
|
||||
EXPECT_FLOAT_EQ(loc.Get(0)[1], 0.0f);
|
||||
EXPECT_FLOAT_EQ(loc.Get(1)[1], 10.0f);
|
||||
EXPECT_FLOAT_EQ(loc.Get(2)[1], 20.0f);
|
||||
}
|
||||
|
||||
TEST(LocatorTest, DirectXY)
|
||||
{
|
||||
dl::Locator::SL sl;
|
||||
sl._dt = { 10.0f, 20.0f };
|
||||
sl._layout = dl::Layout::XY;
|
||||
dl::Locator loc(sl);
|
||||
auto p = loc.Get(3);
|
||||
EXPECT_FLOAT_EQ(p[0], 30.0f);
|
||||
EXPECT_FLOAT_EQ(p[1], 60.0f);
|
||||
}
|
||||
|
||||
TEST(LocatorTest, Origin)
|
||||
{
|
||||
auto loc = dl::createLocatorZero();
|
||||
auto p = loc.Get(5);
|
||||
EXPECT_FLOAT_EQ(p[0], 0.0f);
|
||||
EXPECT_FLOAT_EQ(p[1], 0.0f);
|
||||
}
|
||||
|
||||
TEST(LocatorTest, AdaptX)
|
||||
{
|
||||
auto loc = dl::createLocatorX(10.0f, 0, 32.0f, dl::Locator::Mode::ADAPT);
|
||||
dl::Size s{ 10, 10 };
|
||||
auto p0 = loc.Get(s);
|
||||
EXPECT_FLOAT_EQ(p0[0], 0.0f);
|
||||
auto p1 = loc.Get(s);
|
||||
EXPECT_FLOAT_EQ(p1[0], 20.0f);
|
||||
}
|
||||
|
||||
TEST(LocatorTest, ExGet)
|
||||
{
|
||||
auto loc = dl::createLocatorX(10.0f);
|
||||
dl::Position pos{ 5.0f, 5.0f };
|
||||
EXPECT_TRUE(loc.ExGet(2, dl::Size{}, pos));
|
||||
EXPECT_FLOAT_EQ(pos[0], 25.0f);
|
||||
EXPECT_FLOAT_EQ(pos[1], 5.0f);
|
||||
}
|
||||
|
||||
//------------------------------Timer------------------------------
|
||||
TEST(TimerTest, Regular)
|
||||
{
|
||||
dl::TimerRegular t(2.0f);
|
||||
EXPECT_FALSE(t.Run(1.0f));
|
||||
EXPECT_FALSE(t.Run(0.5f));
|
||||
EXPECT_TRUE(t.Run(0.5f));
|
||||
EXPECT_FALSE(t.Run(0.1f));
|
||||
}
|
||||
|
||||
TEST(TimerTest, Reverse)
|
||||
{
|
||||
dl::TimerReverse t(1.0f);
|
||||
EXPECT_FALSE(t.Run(0.5f));
|
||||
EXPECT_TRUE(t.Run(0.5f));
|
||||
EXPECT_TRUE(t.Run(0.5f));
|
||||
EXPECT_FALSE(t.Run(0.5f));
|
||||
}
|
||||
|
||||
//------------------------------AStar------------------------------
|
||||
TEST(AStarTest, Search)
|
||||
{
|
||||
auto g = [](const dl::Point& a, const dl::Point& b) -> int { return 10; };
|
||||
dl::AStar<dl::Point, int> astar(dl::Point{}, g);
|
||||
astar.SetSize({ 5, 5 });
|
||||
|
||||
std::list<dl::Point> path;
|
||||
EXPECT_TRUE(astar.Search({ 0, 0 }, { 4, 4 }, false, path));
|
||||
EXPECT_FALSE(path.empty());
|
||||
EXPECT_EQ(path.front(), (dl::Point{ 0, 0 }));
|
||||
EXPECT_EQ(path.back(), (dl::Point{ 4, 4 }));
|
||||
}
|
||||
|
||||
TEST(AStarTest, SearchBlocked)
|
||||
{
|
||||
auto g = [](const dl::Point& a, const dl::Point& b) -> int
|
||||
{
|
||||
if (b.x == 2)
|
||||
return 0; // x=2 整列不可通行
|
||||
return 10;
|
||||
};
|
||||
dl::AStar<dl::Point, int> astar(dl::Point{}, g);
|
||||
astar.SetSize({ 5, 5 });
|
||||
|
||||
std::list<dl::Point> path;
|
||||
EXPECT_FALSE(astar.Search({ 0, 0 }, { 4, 4 }, false, path));
|
||||
}
|
||||
|
||||
//------------------------------CodeWriter------------------------------
|
||||
TEST(CodeWriterTest, IsStdType)
|
||||
{
|
||||
EXPECT_TRUE(dl::CodeWriter::IsStdType("string"));
|
||||
EXPECT_FALSE(dl::CodeWriter::IsStdType("int"));
|
||||
}
|
||||
|
||||
TEST(CodeWriterTest, AddStdNamespace)
|
||||
{
|
||||
std::string s = "string";
|
||||
dl::CodeWriter::AddStdNamespace(s);
|
||||
EXPECT_EQ(s, "std::string");
|
||||
|
||||
std::string i = "int";
|
||||
dl::CodeWriter::AddStdNamespace(i);
|
||||
EXPECT_EQ(i, "int");
|
||||
}
|
||||
|
||||
TEST(CodeWriterTest, ReplaceType)
|
||||
{
|
||||
std::string s = "uchar";
|
||||
dl::CodeWriter::ReplaceType(s);
|
||||
EXPECT_EQ(s, "unsigned char");
|
||||
|
||||
std::string i = "int64";
|
||||
dl::CodeWriter::ReplaceType(i);
|
||||
EXPECT_EQ(i, "int64_t");
|
||||
|
||||
std::string i2 = "int32";
|
||||
dl::CodeWriter::ReplaceType(i2);
|
||||
EXPECT_EQ(i2, "int32_t");
|
||||
}
|
||||
|
||||
TEST(CodeWriterTest, StructGetVariable)
|
||||
{
|
||||
dl::CodeWriter::Struct s;
|
||||
s._name = "Student";
|
||||
s._value = "stu";
|
||||
dl::CodeWriter::Variable v;
|
||||
v._name = "id";
|
||||
v._type = "int";
|
||||
s._allVariable.push_back(v);
|
||||
|
||||
auto* p = s.GetVariable("id");
|
||||
ASSERT_NE(p, nullptr);
|
||||
EXPECT_EQ(p->_type, "int");
|
||||
EXPECT_EQ(s.GetVariable("none"), nullptr);
|
||||
}
|
||||
|
||||
TEST(CodeWriterTest, SegmentGetStruct)
|
||||
{
|
||||
dl::CodeWriter::Segment seg;
|
||||
dl::CodeWriter::Struct s;
|
||||
s._name = "Student";
|
||||
s._value = "stu";
|
||||
dl::CodeWriter::Variable v;
|
||||
v._name = "id";
|
||||
v._type = "int";
|
||||
s._allVariable.push_back(v);
|
||||
seg._allStruct.push_back(s);
|
||||
|
||||
auto* ps = seg.GetStruct("Student");
|
||||
ASSERT_NE(ps, nullptr);
|
||||
EXPECT_EQ(ps->_value, "stu");
|
||||
|
||||
auto* pv = seg.GetVariable("Student", "id");
|
||||
ASSERT_NE(pv, nullptr);
|
||||
EXPECT_EQ(pv->_type, "int");
|
||||
|
||||
EXPECT_EQ(seg.GetStruct("None"), nullptr);
|
||||
EXPECT_EQ(seg.GetVariable("Student", "none"), nullptr);
|
||||
}
|
||||
|
||||
TEST(CodeWriterTest, StructFormatVariable)
|
||||
{
|
||||
dl::CodeWriter::Struct s;
|
||||
s._name = "Test";
|
||||
s._value = "t";
|
||||
dl::CodeWriter::Variable v1;
|
||||
v1._name = "a";
|
||||
v1._type = "int";
|
||||
dl::CodeWriter::Variable v2;
|
||||
v2._name = "long_name";
|
||||
v2._type = "std::string";
|
||||
s._allVariable.push_back(v1);
|
||||
s._allVariable.push_back(v2);
|
||||
|
||||
s.FormatVariable();
|
||||
// 对齐后,短的名字/类型会被补 tab,长度不小于 4
|
||||
EXPECT_GE(s._allVariable[0]._name.size(), 4u);
|
||||
EXPECT_GE(s._allVariable[1]._name.size(), 4u);
|
||||
EXPECT_GE(s._allVariable[0]._type.size(), 4u);
|
||||
EXPECT_GE(s._allVariable[1]._type.size(), 4u);
|
||||
EXPECT_EQ(s._allVariable[0]._name.back(), '\t');
|
||||
EXPECT_EQ(s._allVariable[1]._name.back(), '\t');
|
||||
EXPECT_EQ(s._allVariable[0]._type.back(), '\t');
|
||||
EXPECT_EQ(s._allVariable[1]._type.back(), '\t');
|
||||
}
|
||||
|
||||
//------------------------------TileMap------------------------------
|
||||
TEST(TileMapTest, Rectangle)
|
||||
{
|
||||
dl::TileMap::Rectangle<dl::Position{32.0f, 32.0f}> map;
|
||||
auto world = map.Map2World(dl::Point{1, 2});
|
||||
EXPECT_FLOAT_EQ(world[0], 32.0f);
|
||||
EXPECT_FLOAT_EQ(world[1], 64.0f);
|
||||
|
||||
auto mp = map.World2Map(dl::Position{32.0f, 64.0f});
|
||||
EXPECT_EQ(mp[0], 1);
|
||||
EXPECT_EQ(mp[1], 2);
|
||||
}
|
||||
|
||||
TEST(TileMapTest, DiamondSlant)
|
||||
{
|
||||
dl::TileMap::DiamondSlant<dl::Position{32.0f, 32.0f}> map;
|
||||
auto world = map.Map2World(dl::Point{0, 0});
|
||||
EXPECT_FLOAT_EQ(world[0], 0.0f);
|
||||
EXPECT_FLOAT_EQ(world[1], 0.0f);
|
||||
|
||||
auto world2 = map.Map2World(dl::Point{1, 0});
|
||||
EXPECT_FLOAT_EQ(world2[0], 16.0f);
|
||||
EXPECT_FLOAT_EQ(world2[1], -16.0f);
|
||||
}
|
||||
|
||||
//------------------------------JsonConfig------------------------------
|
||||
TEST(JsonConfigTest, LoadFailed)
|
||||
{
|
||||
dl::JsonConfig cfg;
|
||||
EXPECT_FALSE(cfg.Load("/nonexistent/path/file.json"));
|
||||
}
|
||||
|
||||
TEST(JsonConfigTest, LoadGenerateCode)
|
||||
{
|
||||
std::string path = dl::g_factory->GetPathTemp() + "dl_json_config_test.json";
|
||||
std::string json_str = R"({
|
||||
"name": "测试配置",
|
||||
"desc": "配置描述",
|
||||
"type": "config",
|
||||
"value": {
|
||||
"speed": {
|
||||
"name": "速度",
|
||||
"desc": "移动速度",
|
||||
"type": "int",
|
||||
"value": 100
|
||||
},
|
||||
"title": {
|
||||
"name": "标题",
|
||||
"type": "string",
|
||||
"value": "hello"
|
||||
}
|
||||
}
|
||||
})";
|
||||
ASSERT_TRUE(dl::File::SaveString(json_str, path));
|
||||
|
||||
dl::JsonConfig cfg;
|
||||
ASSERT_TRUE(cfg.Load(path));
|
||||
|
||||
dl::JsonConfig::GenerateParam p;
|
||||
p._filename = "test.h";
|
||||
p._brief = "测试";
|
||||
p._author = "tester";
|
||||
p._date = "2026";
|
||||
p._logFunction = "log_err";
|
||||
p._namespace = "test";
|
||||
std::string code = cfg.GenerateCode(p);
|
||||
EXPECT_FALSE(code.empty());
|
||||
EXPECT_NE(code.find("struct config"), std::string::npos);
|
||||
EXPECT_NE(code.find("int speed"), std::string::npos);
|
||||
|
||||
dl::File::Delete(path);
|
||||
}
|
||||
|
||||
TEST(JsonConfigTest, GenerateConfigUser)
|
||||
{
|
||||
std::string path = dl::g_factory->GetPathTemp() + "dl_json_config_test.json";
|
||||
std::string json_str = R"({
|
||||
"name": "测试配置",
|
||||
"type": "config",
|
||||
"value": {
|
||||
"speed": {
|
||||
"type": "int",
|
||||
"value": 100
|
||||
}
|
||||
}
|
||||
})";
|
||||
ASSERT_TRUE(dl::File::SaveString(json_str, path));
|
||||
|
||||
dl::JsonConfig cfg;
|
||||
ASSERT_TRUE(cfg.Load(path));
|
||||
|
||||
std::string user = cfg.GenerateConfigUser();
|
||||
EXPECT_FALSE(user.empty());
|
||||
EXPECT_NE(user.find("speed"), std::string::npos);
|
||||
EXPECT_NE(user.find("100"), std::string::npos);
|
||||
|
||||
dl::File::Delete(path);
|
||||
}
|
||||
|
||||
//------------------------------Language------------------------------
|
||||
TEST(LanguageTest, LoadGet)
|
||||
{
|
||||
std::string path = dl::g_factory->GetPathTemp() + "dl_language_test.xlsx";
|
||||
// 用 OpenXLSX 写临时 xlsx:第0列 tag、第1列 name、第2+列语言
|
||||
{
|
||||
OpenXLSX::XLDocument doc;
|
||||
doc.create(path);
|
||||
auto wks = doc.workbook().worksheet("Sheet1");
|
||||
wks.cell(1, 1).value() = "tag";
|
||||
wks.cell(1, 2).value() = "name";
|
||||
wks.cell(1, 3).value() = "English";
|
||||
wks.cell(1, 4).value() = "简体中文";
|
||||
wks.cell(2, 1).value() = "menu";
|
||||
wks.cell(2, 2).value() = "start";
|
||||
wks.cell(2, 3).value() = "Start";
|
||||
wks.cell(2, 4).value() = "开始";
|
||||
wks.cell(3, 1).value() = "menu";
|
||||
wks.cell(3, 2).value() = "exit";
|
||||
wks.cell(3, 3).value() = "Exit";
|
||||
wks.cell(3, 4).value() = "退出";
|
||||
doc.save();
|
||||
doc.close();
|
||||
}
|
||||
|
||||
dl::Language lang;
|
||||
lang.LoadXlsx(path);
|
||||
|
||||
// 英文
|
||||
lang.SetLangCurrent(dl::Language::E_ENGLISH);
|
||||
EXPECT_EQ(lang.Get("menu", "start"), "Start");
|
||||
EXPECT_EQ(lang.Get("menu", "exit"), "Exit");
|
||||
|
||||
// 中文
|
||||
lang.SetLangCurrent(dl::Language::E_CHINESE);
|
||||
EXPECT_EQ(lang.Get("menu", "start"), "开始");
|
||||
EXPECT_EQ(lang.Get("menu", "exit"), "退出");
|
||||
|
||||
// 失败返回特定字符串
|
||||
EXPECT_EQ(lang.Get("nottag", "start"), "not_find_tag");
|
||||
EXPECT_EQ(lang.Get("menu", "notname"), "not_find");
|
||||
|
||||
// GetCheck
|
||||
auto check = lang.GetCheck("menu", "start");
|
||||
ASSERT_TRUE(check.has_value());
|
||||
EXPECT_EQ(*check, "开始");
|
||||
EXPECT_FALSE(lang.GetCheck("menu", "none").has_value());
|
||||
|
||||
// GetTagSize
|
||||
EXPECT_EQ(lang.GetTagSize("menu"), 2u);
|
||||
|
||||
// GetTagMap
|
||||
auto m = lang.GetTagMap("menu");
|
||||
EXPECT_EQ(m.size(), 2u);
|
||||
EXPECT_EQ(m["start"], "开始");
|
||||
EXPECT_EQ(m["exit"], "退出");
|
||||
|
||||
// GetLangAll
|
||||
const auto& langs = lang.GetLangAll();
|
||||
ASSERT_EQ(langs.size(), 2u);
|
||||
EXPECT_EQ(langs[0], "English");
|
||||
|
||||
dl::File::Delete(path);
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
/**
|
||||
* @file test_tool.cpp
|
||||
* @brief tool 模块单元测试(Archiver 归档器)
|
||||
*
|
||||
*
|
||||
* @version 1.0
|
||||
* @author CodeBuddy
|
||||
* @date 26-09-03
|
||||
*
|
||||
* @note
|
||||
*/
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "tool/dl_tool_archiver.h"
|
||||
#include "io/dl_file.h"
|
||||
#include "render/dl_factory.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
//! 构造一个测试用的临时源目录(含 a.txt 与 sub/b.txt)
|
||||
bool CreateTestSrc(const std::string& dir_src)
|
||||
{
|
||||
if (!dl::File::CreateFolder(dir_src))
|
||||
return false;
|
||||
if (!dl::File::CreateFolder(dir_src + "sub/"))
|
||||
return false;
|
||||
if (!dl::File::SaveString("hello world", dir_src + "a.txt"))
|
||||
return false;
|
||||
if (!dl::File::SaveString("second file", dir_src + "sub/b.txt"))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(ArchiverTest, CompressDecompress)
|
||||
{
|
||||
std::string dir_src = dl::g_factory->GetPathTemp() + "dl_archiver_src/";
|
||||
std::string dir_out = dl::g_factory->GetPathTemp() + "dl_archiver_out/";
|
||||
std::string file_arc = dl::g_factory->GetPathTemp() + "dl_archiver.bin";
|
||||
|
||||
dl::File::Delete(dir_src, true);
|
||||
dl::File::Delete(dir_out, true);
|
||||
dl::File::Delete(file_arc);
|
||||
|
||||
ASSERT_TRUE(CreateTestSrc(dir_src));
|
||||
|
||||
dl::Tool::Archiver::Param p;
|
||||
p._src = dir_src;
|
||||
p._out = file_arc;
|
||||
p._compressMode = dl::Memory::E_NONE;
|
||||
p._bCrc = false;
|
||||
dl::Tool::Archiver::Compress(p);
|
||||
ASSERT_TRUE(dl::File::IsExist(file_arc));
|
||||
|
||||
ASSERT_TRUE(dl::Tool::Archiver::Decompress(file_arc, dir_out));
|
||||
EXPECT_TRUE(dl::File::IsExist(dir_out + "a.txt"));
|
||||
EXPECT_TRUE(dl::File::IsExist(dir_out + "sub/b.txt"));
|
||||
EXPECT_EQ(dl::File::GetString(dir_out + "a.txt"), "hello world");
|
||||
EXPECT_EQ(dl::File::GetString(dir_out + "sub/b.txt"), "second file");
|
||||
|
||||
dl::File::Delete(dir_src, true);
|
||||
dl::File::Delete(dir_out, true);
|
||||
dl::File::Delete(file_arc);
|
||||
}
|
||||
|
||||
TEST(ArchiverTest, CompressDecompressLz4)
|
||||
{
|
||||
std::string dir_src = dl::g_factory->GetPathTemp() + "dl_archiver_src/";
|
||||
std::string dir_out = dl::g_factory->GetPathTemp() + "dl_archiver_out/";
|
||||
std::string file_arc = dl::g_factory->GetPathTemp() + "dl_archiver.bin";
|
||||
|
||||
dl::File::Delete(dir_src, true);
|
||||
dl::File::Delete(dir_out, true);
|
||||
dl::File::Delete(file_arc);
|
||||
|
||||
ASSERT_TRUE(CreateTestSrc(dir_src));
|
||||
|
||||
dl::Tool::Archiver::Param p;
|
||||
p._src = dir_src;
|
||||
p._out = file_arc;
|
||||
p._compressMode = dl::Memory::E_LZ4;
|
||||
p._bCrc = false;
|
||||
dl::Tool::Archiver::Compress(p);
|
||||
ASSERT_TRUE(dl::File::IsExist(file_arc));
|
||||
|
||||
ASSERT_TRUE(dl::Tool::Archiver::Decompress(file_arc, dir_out));
|
||||
EXPECT_TRUE(dl::File::IsExist(dir_out + "a.txt"));
|
||||
EXPECT_TRUE(dl::File::IsExist(dir_out + "sub/b.txt"));
|
||||
EXPECT_EQ(dl::File::GetString(dir_out + "a.txt"), "hello world");
|
||||
EXPECT_EQ(dl::File::GetString(dir_out + "sub/b.txt"), "second file");
|
||||
|
||||
dl::File::Delete(dir_src, true);
|
||||
dl::File::Delete(dir_out, true);
|
||||
dl::File::Delete(file_arc);
|
||||
}
|
||||
|
||||
TEST(ArchiverTest, GetFileList)
|
||||
{
|
||||
std::string dir_src = dl::g_factory->GetPathTemp() + "dl_archiver_src/";
|
||||
std::string file_arc = dl::g_factory->GetPathTemp() + "dl_archiver.bin";
|
||||
|
||||
dl::File::Delete(dir_src, true);
|
||||
dl::File::Delete(file_arc);
|
||||
|
||||
ASSERT_TRUE(CreateTestSrc(dir_src));
|
||||
|
||||
dl::Tool::Archiver::Param p;
|
||||
p._src = dir_src;
|
||||
p._out = file_arc;
|
||||
p._compressMode = dl::Memory::E_NONE;
|
||||
p._bCrc = false;
|
||||
dl::Tool::Archiver::Compress(p);
|
||||
|
||||
dl::Buffer buf = dl::File::GetBuffer(file_arc);
|
||||
ASSERT_FALSE(buf.empty());
|
||||
|
||||
dl::Tool::Archiver::FileList list;
|
||||
ASSERT_TRUE(dl::Tool::Archiver::GetFileList(buf, list));
|
||||
EXPECT_EQ(list.size(), 2u);
|
||||
|
||||
bool found_a = false;
|
||||
bool found_b = false;
|
||||
for (auto& [name, info] : list)
|
||||
{
|
||||
if (name.find("a.txt") != std::string::npos)
|
||||
found_a = true;
|
||||
if (name.find("b.txt") != std::string::npos)
|
||||
found_b = true;
|
||||
}
|
||||
EXPECT_TRUE(found_a);
|
||||
EXPECT_TRUE(found_b);
|
||||
|
||||
dl::File::Delete(dir_src, true);
|
||||
dl::File::Delete(file_arc);
|
||||
}
|
||||
|
||||
TEST(ArchiverTest, DecompressBadType)
|
||||
{
|
||||
std::string bad = "this is not an archiver file";
|
||||
dl::Buffer buf = dl::CreateBuffer(dl::CreateBufferView(bad));
|
||||
|
||||
std::string dir_out = dl::g_factory->GetPathTemp() + "dl_archiver_bad/";
|
||||
dl::File::Delete(dir_out, true);
|
||||
EXPECT_FALSE(dl::Tool::Archiver::Decompress(buf, dir_out));
|
||||
dl::File::Delete(dir_out, true);
|
||||
}
|
||||
Reference in New Issue
Block a user