mirror of
https://github.com/alliedmodders/sourcemod.git
synced 2025-12-07 10:28:34 +00:00
2041 lines
42 KiB
SourcePawn
Executable File
2041 lines
42 KiB
SourcePawn
Executable File
#include <sourcemod>
|
|
#include <yyjson>
|
|
|
|
#pragma newdecls required
|
|
#pragma semicolon 1
|
|
|
|
public Plugin myinfo =
|
|
{
|
|
name = "YYJSON Test Suite",
|
|
author = "ProjectSky",
|
|
description = "test suite for YYJSON functions",
|
|
version = "1.0.0",
|
|
url = "https://github.com/ProjectSky/sm-ext-yyjson"
|
|
};
|
|
|
|
// Test statistics
|
|
int g_iTotalTests = 0;
|
|
int g_iPassedTests = 0;
|
|
int g_iFailedTests = 0;
|
|
char g_sCurrentTest[128];
|
|
bool g_bCurrentTestFailed = false;
|
|
|
|
public void OnPluginStart()
|
|
{
|
|
RegServerCmd("test_yyjson", Command_RunTests, "Run YYJSON test suite");
|
|
}
|
|
|
|
// ============================================================================
|
|
// Test Framework - Assertion Functions
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Start a new test case
|
|
*/
|
|
void TestStart(const char[] name)
|
|
{
|
|
g_iTotalTests++;
|
|
strcopy(g_sCurrentTest, sizeof(g_sCurrentTest), name);
|
|
g_bCurrentTestFailed = false;
|
|
}
|
|
|
|
/**
|
|
* End current test case
|
|
*/
|
|
void TestEnd()
|
|
{
|
|
if (!g_bCurrentTestFailed)
|
|
{
|
|
g_iPassedTests++;
|
|
PrintToServer("[PASS] %s", g_sCurrentTest);
|
|
}
|
|
else
|
|
{
|
|
g_iFailedTests++;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Assert a condition is true
|
|
*/
|
|
void Assert(bool condition, const char[] message = "")
|
|
{
|
|
if (!condition)
|
|
{
|
|
g_bCurrentTestFailed = true;
|
|
PrintToServer("[FAIL] %s - %s", g_sCurrentTest, message);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Assert two integers are equal
|
|
*/
|
|
void AssertEq(int a, int b, const char[] message = "")
|
|
{
|
|
if (a != b)
|
|
{
|
|
g_bCurrentTestFailed = true;
|
|
char buffer[256];
|
|
if (message[0] != '\0')
|
|
{
|
|
Format(buffer, sizeof(buffer), "%s (expected %d, got %d)", message, b, a);
|
|
}
|
|
else
|
|
{
|
|
Format(buffer, sizeof(buffer), "Expected %d, got %d", b, a);
|
|
}
|
|
PrintToServer("[FAIL] %s - %s", g_sCurrentTest, buffer);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Assert two integers are not equal
|
|
*/
|
|
stock void AssertNeq(int a, int b, const char[] message = "")
|
|
{
|
|
if (a == b)
|
|
{
|
|
g_bCurrentTestFailed = true;
|
|
char buffer[256];
|
|
if (message[0] != '\0')
|
|
{
|
|
Format(buffer, sizeof(buffer), "%s (values should not be equal: %d)", message, a);
|
|
}
|
|
else
|
|
{
|
|
Format(buffer, sizeof(buffer), "Values should not be equal: %d", a);
|
|
}
|
|
PrintToServer("[FAIL] %s - %s", g_sCurrentTest, buffer);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Assert condition is true
|
|
*/
|
|
void AssertTrue(bool condition, const char[] message = "")
|
|
{
|
|
Assert(condition, message[0] != '\0' ? message : "Expected true, got false");
|
|
}
|
|
|
|
/**
|
|
* Assert condition is false
|
|
*/
|
|
void AssertFalse(bool condition, const char[] message = "")
|
|
{
|
|
Assert(!condition, message[0] != '\0' ? message : "Expected false, got true");
|
|
}
|
|
|
|
/**
|
|
* Assert two strings are equal
|
|
*/
|
|
void AssertStrEq(const char[] a, const char[] b, const char[] message = "")
|
|
{
|
|
if (!StrEqual(a, b))
|
|
{
|
|
g_bCurrentTestFailed = true;
|
|
char buffer[512];
|
|
if (message[0] != '\0')
|
|
{
|
|
Format(buffer, sizeof(buffer), "%s (expected \"%s\", got \"%s\")", message, b, a);
|
|
}
|
|
else
|
|
{
|
|
Format(buffer, sizeof(buffer), "Expected \"%s\", got \"%s\"", b, a);
|
|
}
|
|
PrintToServer("[FAIL] %s - %s", g_sCurrentTest, buffer);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Assert two floats are equal within epsilon
|
|
*/
|
|
void AssertFloatEq(float a, float b, const char[] message = "", float epsilon = 0.0001)
|
|
{
|
|
if (FloatAbs(a - b) > epsilon)
|
|
{
|
|
g_bCurrentTestFailed = true;
|
|
char buffer[256];
|
|
if (message[0] != '\0')
|
|
{
|
|
Format(buffer, sizeof(buffer), "%s (expected %.4f, got %.4f)", message, b, a);
|
|
}
|
|
else
|
|
{
|
|
Format(buffer, sizeof(buffer), "Expected %.4f, got %.4f", b, a);
|
|
}
|
|
PrintToServer("[FAIL] %s - %s", g_sCurrentTest, buffer);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Assert handle is valid
|
|
*/
|
|
void AssertValidHandle(Handle handle, const char[] message = "")
|
|
{
|
|
Assert(handle != null, message[0] != '\0' ? message : "Handle should not be null");
|
|
}
|
|
|
|
/**
|
|
* Assert handle is null
|
|
*/
|
|
void AssertNullHandle(Handle handle, const char[] message = "")
|
|
{
|
|
Assert(handle == null, message[0] != '\0' ? message : "Handle should be null");
|
|
}
|
|
|
|
// ============================================================================
|
|
// Test Command
|
|
// ============================================================================
|
|
|
|
public Action Command_RunTests(int args)
|
|
{
|
|
PrintToServer("========================================");
|
|
PrintToServer("YYJSON Test Suite");
|
|
PrintToServer("========================================");
|
|
|
|
// Reset statistics
|
|
g_iTotalTests = 0;
|
|
g_iPassedTests = 0;
|
|
g_iFailedTests = 0;
|
|
|
|
// Run all test categories
|
|
Test_BasicValues();
|
|
Test_ObjectOperations();
|
|
Test_ArrayOperations();
|
|
Test_ParseAndSerialize();
|
|
Test_Iterators();
|
|
Test_JSONPointer();
|
|
Test_AdvancedFeatures();
|
|
Test_EdgeCases();
|
|
|
|
// Print results
|
|
PrintToServer("========================================");
|
|
PrintToServer("YYJSON Test Suite Results");
|
|
PrintToServer("========================================");
|
|
PrintToServer("Total Tests: %d", g_iTotalTests);
|
|
PrintToServer("Passed: %d", g_iPassedTests);
|
|
PrintToServer("Failed: %d", g_iFailedTests);
|
|
|
|
if (g_iTotalTests > 0)
|
|
{
|
|
float successRate = (float(g_iPassedTests) / float(g_iTotalTests)) * 100.0;
|
|
PrintToServer("Success Rate: %.2f%%", successRate);
|
|
}
|
|
|
|
PrintToServer("========================================");
|
|
|
|
return Plugin_Handled;
|
|
}
|
|
|
|
// ============================================================================
|
|
// 2.1 Basic Value Tests
|
|
// ============================================================================
|
|
|
|
void Test_BasicValues()
|
|
{
|
|
PrintToServer("\n[Category] Basic Value Tests");
|
|
|
|
// Test CreateBool & GetBool
|
|
TestStart("BasicValues_CreateBool_True");
|
|
{
|
|
YYJSON val = YYJSON.CreateBool(true);
|
|
AssertValidHandle(val);
|
|
AssertTrue(YYJSON.GetBool(val));
|
|
AssertEq(val.Type, YYJSON_TYPE_BOOL);
|
|
AssertTrue(val.IsBool);
|
|
AssertTrue(val.IsTrue);
|
|
AssertFalse(val.IsFalse);
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("BasicValues_CreateBool_False");
|
|
{
|
|
YYJSON val = YYJSON.CreateBool(false);
|
|
AssertValidHandle(val);
|
|
AssertFalse(YYJSON.GetBool(val));
|
|
AssertTrue(val.IsBool);
|
|
AssertFalse(val.IsTrue);
|
|
AssertTrue(val.IsFalse);
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test CreateInt & GetInt
|
|
TestStart("BasicValues_CreateInt_Positive");
|
|
{
|
|
YYJSON val = YYJSON.CreateInt(42);
|
|
AssertValidHandle(val);
|
|
AssertEq(YYJSON.GetInt(val), 42);
|
|
AssertEq(val.Type, YYJSON_TYPE_NUM);
|
|
AssertTrue(val.IsInt);
|
|
AssertTrue(val.IsNum);
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("BasicValues_CreateInt_Negative");
|
|
{
|
|
YYJSON val = YYJSON.CreateInt(-123);
|
|
AssertValidHandle(val);
|
|
AssertEq(YYJSON.GetInt(val), -123);
|
|
AssertTrue(val.IsSint);
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("BasicValues_CreateInt_Zero");
|
|
{
|
|
YYJSON val = YYJSON.CreateInt(0);
|
|
AssertValidHandle(val);
|
|
AssertEq(YYJSON.GetInt(val), 0);
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test CreateFloat & GetFloat
|
|
TestStart("BasicValues_CreateFloat_Positive");
|
|
{
|
|
YYJSON val = YYJSON.CreateFloat(3.14159);
|
|
AssertValidHandle(val);
|
|
AssertFloatEq(YYJSON.GetFloat(val), 3.14159);
|
|
AssertTrue(val.IsFloat);
|
|
AssertTrue(val.IsNum);
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("BasicValues_CreateFloat_Negative");
|
|
{
|
|
YYJSON val = YYJSON.CreateFloat(-2.71828);
|
|
AssertValidHandle(val);
|
|
AssertFloatEq(YYJSON.GetFloat(val), -2.71828);
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("BasicValues_CreateFloat_Zero");
|
|
{
|
|
YYJSON val = YYJSON.CreateFloat(0.0);
|
|
AssertValidHandle(val);
|
|
AssertFloatEq(YYJSON.GetFloat(val), 0.0);
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test CreateString & GetString
|
|
TestStart("BasicValues_CreateString_Regular");
|
|
{
|
|
YYJSON val = YYJSON.CreateString("Hello, World!");
|
|
AssertValidHandle(val);
|
|
char buffer[64];
|
|
AssertTrue(YYJSON.GetString(val, buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "Hello, World!");
|
|
AssertEq(val.Type, YYJSON_TYPE_STR);
|
|
AssertTrue(val.IsStr);
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("BasicValues_CreateString_Empty");
|
|
{
|
|
YYJSON val = YYJSON.CreateString("");
|
|
AssertValidHandle(val);
|
|
char buffer[64];
|
|
AssertTrue(YYJSON.GetString(val, buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "");
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("BasicValues_CreateString_Unicode");
|
|
{
|
|
YYJSON val = YYJSON.CreateString("测试字符串");
|
|
AssertValidHandle(val);
|
|
char buffer[64];
|
|
AssertTrue(YYJSON.GetString(val, buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "测试字符串");
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test CreateInt64 & GetInt64
|
|
TestStart("BasicValues_CreateInt64_Large");
|
|
{
|
|
YYJSON val = YYJSON.CreateInt64("9223372036854775807");
|
|
AssertValidHandle(val);
|
|
char buffer[32];
|
|
AssertTrue(YYJSON.GetInt64(val, buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "9223372036854775807");
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("BasicValues_CreateInt64_Negative");
|
|
{
|
|
YYJSON val = YYJSON.CreateInt64("-9223372036854775808");
|
|
AssertValidHandle(val);
|
|
char buffer[32];
|
|
AssertTrue(YYJSON.GetInt64(val, buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "-9223372036854775808");
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test CreateNull
|
|
TestStart("BasicValues_CreateNull");
|
|
{
|
|
YYJSON val = YYJSON.CreateNull();
|
|
AssertValidHandle(val);
|
|
AssertEq(val.Type, YYJSON_TYPE_NULL);
|
|
AssertTrue(val.IsNull);
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test GetTypeDesc
|
|
TestStart("BasicValues_GetTypeDesc");
|
|
{
|
|
YYJSON boolVal = YYJSON.CreateBool(true);
|
|
YYJSON intVal = YYJSON.CreateInt(42);
|
|
YYJSON floatVal = YYJSON.CreateFloat(3.14);
|
|
YYJSON strVal = YYJSON.CreateString("test");
|
|
YYJSON nullVal = YYJSON.CreateNull();
|
|
|
|
char buffer[32];
|
|
|
|
YYJSON.GetTypeDesc(boolVal, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "true");
|
|
|
|
YYJSON.GetTypeDesc(intVal, buffer, sizeof(buffer));
|
|
AssertTrue(StrEqual(buffer, "uint") || StrEqual(buffer, "sint"));
|
|
|
|
YYJSON.GetTypeDesc(floatVal, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "real");
|
|
|
|
YYJSON.GetTypeDesc(strVal, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "string");
|
|
|
|
YYJSON.GetTypeDesc(nullVal, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "null");
|
|
|
|
delete boolVal;
|
|
delete intVal;
|
|
delete floatVal;
|
|
delete strVal;
|
|
delete nullVal;
|
|
}
|
|
TestEnd();
|
|
}
|
|
|
|
// ============================================================================
|
|
// 2.2 Object Operations Tests
|
|
// ============================================================================
|
|
|
|
void Test_ObjectOperations()
|
|
{
|
|
PrintToServer("\n[Category] Object Operations Tests");
|
|
|
|
// Test object creation
|
|
TestStart("Object_Constructor");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
AssertValidHandle(obj);
|
|
AssertTrue(obj.IsObject);
|
|
AssertEq(obj.Size, 0);
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test Set/Get methods
|
|
TestStart("Object_SetGetInt");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
AssertTrue(obj.SetInt("number", 42));
|
|
AssertEq(obj.GetInt("number"), 42);
|
|
AssertEq(obj.Size, 1);
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Object_SetGetFloat");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
AssertTrue(obj.SetFloat("pi", 3.14159));
|
|
AssertFloatEq(obj.GetFloat("pi"), 3.14159);
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Object_SetGetBool");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
AssertTrue(obj.SetBool("flag", true));
|
|
AssertTrue(obj.GetBool("flag"));
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Object_SetGetString");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
AssertTrue(obj.SetString("name", "test"));
|
|
char buffer[64];
|
|
AssertTrue(obj.GetString("name", buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "test");
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Object_SetGetInt64");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
AssertTrue(obj.SetInt64("bignum", "9223372036854775807"));
|
|
char buffer[32];
|
|
AssertTrue(obj.GetInt64("bignum", buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "9223372036854775807");
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Object_SetGetNull");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
AssertTrue(obj.SetNull("nullable"));
|
|
AssertTrue(obj.IsNull("nullable"));
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test HasKey
|
|
TestStart("Object_HasKey");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
obj.SetInt("exists", 1);
|
|
AssertTrue(obj.HasKey("exists"));
|
|
AssertFalse(obj.HasKey("notexists"));
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test GetKey and GetValueAt
|
|
TestStart("Object_GetKeyAndValueAt");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
obj.SetInt("first", 1);
|
|
obj.SetInt("second", 2);
|
|
|
|
char key[32];
|
|
AssertTrue(obj.GetKey(0, key, sizeof(key)));
|
|
AssertStrEq(key, "first");
|
|
|
|
YYJSON val = obj.GetValueAt(0);
|
|
AssertValidHandle(val);
|
|
AssertEq(YYJSON.GetInt(val), 1);
|
|
|
|
delete val;
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test Remove
|
|
TestStart("Object_Remove");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
obj.SetInt("remove_me", 1);
|
|
obj.SetInt("keep_me", 2);
|
|
AssertEq(obj.Size, 2);
|
|
|
|
AssertTrue(obj.Remove("remove_me"));
|
|
AssertEq(obj.Size, 1);
|
|
AssertFalse(obj.HasKey("remove_me"));
|
|
AssertTrue(obj.HasKey("keep_me"));
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test Clear
|
|
TestStart("Object_Clear");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
obj.SetInt("a", 1);
|
|
obj.SetInt("b", 2);
|
|
obj.SetInt("c", 3);
|
|
AssertEq(obj.Size, 3);
|
|
|
|
AssertTrue(obj.Clear());
|
|
AssertEq(obj.Size, 0);
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test RenameKey
|
|
TestStart("Object_RenameKey");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
obj.SetInt("oldname", 42);
|
|
|
|
AssertTrue(obj.RenameKey("oldname", "newname"));
|
|
AssertFalse(obj.HasKey("oldname"));
|
|
AssertTrue(obj.HasKey("newname"));
|
|
AssertEq(obj.GetInt("newname"), 42);
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test FromString
|
|
TestStart("Object_FromString");
|
|
{
|
|
YYJSONObject obj = YYJSONObject.FromString("{\"key\":\"value\",\"num\":123}");
|
|
AssertValidHandle(obj);
|
|
|
|
char buffer[64];
|
|
AssertTrue(obj.GetString("key", buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "value");
|
|
AssertEq(obj.GetInt("num"), 123);
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test FromStrings
|
|
TestStart("Object_FromStrings");
|
|
{
|
|
char pairs[][] = {"name", "test", "type", "demo", "version", "1.0"};
|
|
YYJSONObject obj = YYJSONObject.FromStrings(pairs, sizeof(pairs));
|
|
AssertValidHandle(obj);
|
|
AssertEq(obj.Size, 3);
|
|
|
|
char buffer[64];
|
|
AssertTrue(obj.GetString("name", buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "test");
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test Sort
|
|
TestStart("Object_Sort_Ascending");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
obj.SetInt("zebra", 1);
|
|
obj.SetInt("alpha", 2);
|
|
obj.SetInt("beta", 3);
|
|
|
|
AssertTrue(obj.Sort(YYJSON_SORT_ASC));
|
|
|
|
char key[32];
|
|
obj.GetKey(0, key, sizeof(key));
|
|
AssertStrEq(key, "alpha");
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Object_Sort_Descending");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
obj.SetInt("alpha", 1);
|
|
obj.SetInt("beta", 2);
|
|
obj.SetInt("gamma", 3);
|
|
|
|
AssertTrue(obj.Sort(YYJSON_SORT_DESC));
|
|
|
|
char key[32];
|
|
obj.GetKey(0, key, sizeof(key));
|
|
AssertStrEq(key, "gamma");
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test Set with handle
|
|
TestStart("Object_SetWithHandle");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
YYJSON val = YYJSON.CreateInt(999);
|
|
|
|
AssertTrue(obj.Set("nested", val));
|
|
AssertEq(obj.GetInt("nested"), 999);
|
|
|
|
delete val;
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test Get with handle
|
|
TestStart("Object_GetHandle");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
obj.SetInt("value", 42);
|
|
|
|
YYJSON val = obj.Get("value");
|
|
AssertValidHandle(val);
|
|
AssertEq(YYJSON.GetInt(val), 42);
|
|
|
|
delete val;
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
}
|
|
|
|
// ============================================================================
|
|
// 2.3 Array Operations Tests
|
|
// ============================================================================
|
|
|
|
void Test_ArrayOperations()
|
|
{
|
|
PrintToServer("\n[Category] Array Operations Tests");
|
|
|
|
// Test array creation
|
|
TestStart("Array_Constructor");
|
|
{
|
|
YYJSONArray arr = new YYJSONArray();
|
|
AssertValidHandle(arr);
|
|
AssertTrue(arr.IsArray);
|
|
AssertEq(arr.Length, 0);
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test Push methods
|
|
TestStart("Array_PushInt");
|
|
{
|
|
YYJSONArray arr = new YYJSONArray();
|
|
AssertTrue(arr.PushInt(42));
|
|
AssertEq(arr.Length, 1);
|
|
AssertEq(arr.GetInt(0), 42);
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_PushFloat");
|
|
{
|
|
YYJSONArray arr = new YYJSONArray();
|
|
AssertTrue(arr.PushFloat(3.14));
|
|
AssertFloatEq(arr.GetFloat(0), 3.14);
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_PushBool");
|
|
{
|
|
YYJSONArray arr = new YYJSONArray();
|
|
AssertTrue(arr.PushBool(true));
|
|
AssertTrue(arr.GetBool(0));
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_PushString");
|
|
{
|
|
YYJSONArray arr = new YYJSONArray();
|
|
AssertTrue(arr.PushString("test"));
|
|
char buffer[64];
|
|
AssertTrue(arr.GetString(0, buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "test");
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_PushInt64");
|
|
{
|
|
YYJSONArray arr = new YYJSONArray();
|
|
AssertTrue(arr.PushInt64("9223372036854775807"));
|
|
char buffer[32];
|
|
arr.GetInt64(0, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "9223372036854775807");
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_PushNull");
|
|
{
|
|
YYJSONArray arr = new YYJSONArray();
|
|
AssertTrue(arr.PushNull());
|
|
AssertTrue(arr.IsNull(0));
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test Set/Get methods
|
|
TestStart("Array_SetGetInt");
|
|
{
|
|
YYJSONArray arr = new YYJSONArray();
|
|
arr.PushInt(0);
|
|
AssertTrue(arr.SetInt(0, 100));
|
|
AssertEq(arr.GetInt(0), 100);
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_SetGetFloat");
|
|
{
|
|
YYJSONArray arr = new YYJSONArray();
|
|
arr.PushFloat(0.0);
|
|
AssertTrue(arr.SetFloat(0, 2.718));
|
|
AssertFloatEq(arr.GetFloat(0), 2.718);
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test Remove methods
|
|
TestStart("Array_Remove");
|
|
{
|
|
YYJSONArray arr = new YYJSONArray();
|
|
arr.PushInt(1);
|
|
arr.PushInt(2);
|
|
arr.PushInt(3);
|
|
AssertEq(arr.Length, 3);
|
|
|
|
AssertTrue(arr.Remove(1));
|
|
AssertEq(arr.Length, 2);
|
|
AssertEq(arr.GetInt(0), 1);
|
|
AssertEq(arr.GetInt(1), 3);
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_RemoveFirst");
|
|
{
|
|
YYJSONArray arr = new YYJSONArray();
|
|
arr.PushInt(1);
|
|
arr.PushInt(2);
|
|
arr.PushInt(3);
|
|
|
|
AssertTrue(arr.RemoveFirst());
|
|
AssertEq(arr.Length, 2);
|
|
AssertEq(arr.GetInt(0), 2);
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_RemoveLast");
|
|
{
|
|
YYJSONArray arr = new YYJSONArray();
|
|
arr.PushInt(1);
|
|
arr.PushInt(2);
|
|
arr.PushInt(3);
|
|
|
|
AssertTrue(arr.RemoveLast());
|
|
AssertEq(arr.Length, 2);
|
|
AssertEq(arr.GetInt(1), 2);
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_RemoveRange");
|
|
{
|
|
YYJSONArray arr = new YYJSONArray();
|
|
for (int i = 0; i < 10; i++)
|
|
{
|
|
arr.PushInt(i);
|
|
}
|
|
|
|
AssertTrue(arr.RemoveRange(2, 5));
|
|
AssertEq(arr.Length, 5);
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_Clear");
|
|
{
|
|
YYJSONArray arr = new YYJSONArray();
|
|
arr.PushInt(1);
|
|
arr.PushInt(2);
|
|
arr.PushInt(3);
|
|
|
|
AssertTrue(arr.Clear());
|
|
AssertEq(arr.Length, 0);
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test First/Last properties
|
|
TestStart("Array_FirstLast");
|
|
{
|
|
YYJSONArray arr = new YYJSONArray();
|
|
arr.PushInt(10);
|
|
arr.PushInt(20);
|
|
arr.PushInt(30);
|
|
|
|
YYJSON first = arr.First;
|
|
YYJSON last = arr.Last;
|
|
|
|
AssertValidHandle(first);
|
|
AssertValidHandle(last);
|
|
AssertEq(YYJSON.GetInt(first), 10);
|
|
AssertEq(YYJSON.GetInt(last), 30);
|
|
|
|
delete first;
|
|
delete last;
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test IndexOf methods
|
|
TestStart("Array_IndexOfInt");
|
|
{
|
|
YYJSONArray arr = new YYJSONArray();
|
|
arr.PushInt(10);
|
|
arr.PushInt(20);
|
|
arr.PushInt(30);
|
|
|
|
AssertEq(arr.IndexOfInt(20), 1);
|
|
AssertEq(arr.IndexOfInt(999), -1);
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_IndexOfBool");
|
|
{
|
|
YYJSONArray arr = new YYJSONArray();
|
|
arr.PushBool(false);
|
|
arr.PushBool(true);
|
|
arr.PushBool(false);
|
|
|
|
AssertEq(arr.IndexOfBool(true), 1);
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_IndexOfString");
|
|
{
|
|
YYJSONArray arr = new YYJSONArray();
|
|
arr.PushString("apple");
|
|
arr.PushString("banana");
|
|
arr.PushString("cherry");
|
|
|
|
AssertEq(arr.IndexOfString("banana"), 1);
|
|
AssertEq(arr.IndexOfString("orange"), -1);
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_IndexOfFloat");
|
|
{
|
|
YYJSONArray arr = new YYJSONArray();
|
|
arr.PushFloat(1.1);
|
|
arr.PushFloat(2.2);
|
|
arr.PushFloat(3.3);
|
|
|
|
AssertEq(arr.IndexOfFloat(2.2), 1);
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_IndexOfInt64");
|
|
{
|
|
YYJSONArray arr = new YYJSONArray();
|
|
arr.PushInt64("1000000000000");
|
|
arr.PushInt64("2000000000000");
|
|
|
|
AssertEq(arr.IndexOfInt64("2000000000000"), 1);
|
|
AssertEq(arr.IndexOfInt64("3000000000000"), -1);
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test FromString
|
|
TestStart("Array_FromString");
|
|
{
|
|
YYJSONArray arr = YYJSONArray.FromString("[1,2,3,4,5]");
|
|
AssertValidHandle(arr);
|
|
AssertEq(arr.Length, 5);
|
|
AssertEq(arr.GetInt(0), 1);
|
|
AssertEq(arr.GetInt(4), 5);
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test FromStrings
|
|
TestStart("Array_FromStrings");
|
|
{
|
|
char strings[][] = {"apple", "banana", "cherry"};
|
|
YYJSONArray arr = YYJSONArray.FromStrings(strings, sizeof(strings));
|
|
AssertValidHandle(arr);
|
|
AssertEq(arr.Length, 3);
|
|
|
|
char buffer[64];
|
|
arr.GetString(1, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "banana");
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test Sort
|
|
TestStart("Array_Sort_Ascending");
|
|
{
|
|
YYJSONArray arr = new YYJSONArray();
|
|
arr.PushInt(3);
|
|
arr.PushInt(1);
|
|
arr.PushInt(4);
|
|
arr.PushInt(1);
|
|
arr.PushInt(5);
|
|
|
|
AssertTrue(arr.Sort(YYJSON_SORT_ASC));
|
|
AssertEq(arr.GetInt(0), 1);
|
|
AssertEq(arr.GetInt(4), 5);
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_Sort_Descending");
|
|
{
|
|
YYJSONArray arr = new YYJSONArray();
|
|
arr.PushInt(1);
|
|
arr.PushInt(2);
|
|
arr.PushInt(3);
|
|
arr.PushInt(4);
|
|
arr.PushInt(5);
|
|
|
|
AssertTrue(arr.Sort(YYJSON_SORT_DESC));
|
|
AssertEq(arr.GetInt(0), 5);
|
|
AssertEq(arr.GetInt(4), 1);
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test Push with handle
|
|
TestStart("Array_PushHandle");
|
|
{
|
|
YYJSONArray arr = new YYJSONArray();
|
|
YYJSON val = YYJSON.CreateInt(999);
|
|
|
|
AssertTrue(arr.Push(val));
|
|
AssertEq(arr.GetInt(0), 999);
|
|
|
|
delete val;
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test Get with handle
|
|
TestStart("Array_GetHandle");
|
|
{
|
|
YYJSONArray arr = new YYJSONArray();
|
|
arr.PushInt(42);
|
|
|
|
YYJSON val = arr.Get(0);
|
|
AssertValidHandle(val);
|
|
AssertEq(YYJSON.GetInt(val), 42);
|
|
|
|
delete val;
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
}
|
|
|
|
// ============================================================================
|
|
// 2.4 Parse & Serialize Tests
|
|
// ============================================================================
|
|
|
|
void Test_ParseAndSerialize()
|
|
{
|
|
PrintToServer("\n[Category] Parse & Serialize Tests");
|
|
|
|
// Test Parse string
|
|
TestStart("Parse_SimpleObject");
|
|
{
|
|
YYJSON json = YYJSON.Parse("{\"key\":\"value\",\"num\":42}");
|
|
AssertValidHandle(json);
|
|
AssertTrue(json.IsObject);
|
|
delete json;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Parse_SimpleArray");
|
|
{
|
|
YYJSON json = YYJSON.Parse("[1,2,3,4,5]");
|
|
AssertValidHandle(json);
|
|
AssertTrue(json.IsArray);
|
|
delete json;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Parse_NestedStructure");
|
|
{
|
|
YYJSON json = YYJSON.Parse("{\"user\":{\"name\":\"test\",\"age\":25},\"items\":[1,2,3]}");
|
|
AssertValidHandle(json);
|
|
delete json;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test mutable/immutable
|
|
TestStart("Parse_ImmutableDocument");
|
|
{
|
|
YYJSON json = YYJSON.Parse("{\"key\":\"value\"}");
|
|
AssertValidHandle(json);
|
|
AssertTrue(json.IsImmutable);
|
|
AssertFalse(json.IsMutable);
|
|
delete json;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Parse_MutableDocument");
|
|
{
|
|
YYJSON json = YYJSON.Parse("{\"key\":\"value\"}", false, true);
|
|
AssertValidHandle(json);
|
|
AssertTrue(json.IsMutable);
|
|
AssertFalse(json.IsImmutable);
|
|
delete json;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test ToString
|
|
TestStart("Serialize_ToString");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
obj.SetInt("num", 42);
|
|
obj.SetString("str", "test");
|
|
|
|
char buffer[256];
|
|
int len = obj.ToString(buffer, sizeof(buffer));
|
|
AssertTrue(len > 0);
|
|
Assert(StrContains(buffer, "num") != -1);
|
|
Assert(StrContains(buffer, "test") != -1);
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Serialize_ToString_Pretty");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
obj.SetInt("a", 1);
|
|
obj.SetInt("b", 2);
|
|
|
|
char buffer[256];
|
|
int len = obj.ToString(buffer, sizeof(buffer), YYJSON_WRITE_PRETTY);
|
|
AssertTrue(len > 0);
|
|
Assert(StrContains(buffer, "\n") != -1, "Pretty output should contain newlines");
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test GetSerializedSize
|
|
TestStart("Serialize_GetSerializedSize");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
obj.SetInt("test", 123);
|
|
|
|
int size = obj.GetSerializedSize();
|
|
AssertTrue(size > 0);
|
|
|
|
char[] buffer = new char[size];
|
|
int written = obj.ToString(buffer, size);
|
|
AssertEq(written, size);
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test read flags
|
|
TestStart("Parse_WithTrailingCommas");
|
|
{
|
|
YYJSON json = YYJSON.Parse("[1,2,3,]", false, false, YYJSON_READ_ALLOW_TRAILING_COMMAS);
|
|
AssertValidHandle(json);
|
|
delete json;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Parse_WithComments");
|
|
{
|
|
YYJSON json = YYJSON.Parse("/* comment */ {\"key\":\"value\"}", false, false, YYJSON_READ_ALLOW_COMMENTS);
|
|
AssertValidHandle(json);
|
|
delete json;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test file operations (create temporary test file)
|
|
TestStart("Parse_ToFile_FromFile");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
obj.SetInt("filetest", 999);
|
|
obj.SetString("name", "testfile");
|
|
|
|
// Write to file
|
|
AssertTrue(obj.ToFile("yyjson_test_temp.json"));
|
|
|
|
// Read from file
|
|
YYJSONObject loaded = YYJSON.Parse("yyjson_test_temp.json", true);
|
|
AssertValidHandle(loaded);
|
|
|
|
// Verify content
|
|
YYJSONObject loadedObj = loaded;
|
|
AssertEq(loadedObj.GetInt("filetest"), 999);
|
|
|
|
char buffer[64];
|
|
loadedObj.GetString("name", buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "testfile");
|
|
|
|
delete obj;
|
|
delete loaded;
|
|
|
|
// Cleanup
|
|
DeleteFile("yyjson_test_temp.json");
|
|
}
|
|
TestEnd();
|
|
|
|
// Test round-trip serialization
|
|
TestStart("Parse_RoundTrip");
|
|
{
|
|
char original[] = "{\"int\":42,\"float\":3.14,\"bool\":true,\"str\":\"test\",\"null\":null}";
|
|
YYJSON json1 = YYJSON.Parse(original);
|
|
|
|
char buffer[256];
|
|
json1.ToString(buffer, sizeof(buffer));
|
|
|
|
YYJSON json2 = YYJSON.Parse(buffer);
|
|
AssertTrue(YYJSON.Equals(json1, json2));
|
|
|
|
delete json1;
|
|
delete json2;
|
|
}
|
|
TestEnd();
|
|
}
|
|
|
|
// ============================================================================
|
|
// 2.5 Iterator Tests
|
|
// ============================================================================
|
|
|
|
void Test_Iterators()
|
|
{
|
|
PrintToServer("\n[Category] Iterator Tests");
|
|
|
|
// Test ForeachObject
|
|
TestStart("Iterator_ForeachObject");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
obj.SetInt("a", 1);
|
|
obj.SetInt("b", 2);
|
|
obj.SetInt("c", 3);
|
|
|
|
int count = 0;
|
|
char key[32];
|
|
YYJSON value;
|
|
|
|
while (obj.ForeachObject(key, sizeof(key), value))
|
|
{
|
|
count++;
|
|
AssertValidHandle(value);
|
|
delete value;
|
|
}
|
|
|
|
AssertEq(count, 3);
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test ForeachArray
|
|
TestStart("Iterator_ForeachArray");
|
|
{
|
|
YYJSONArray arr = new YYJSONArray();
|
|
arr.PushInt(10);
|
|
arr.PushInt(20);
|
|
arr.PushInt(30);
|
|
|
|
int count = 0;
|
|
int index;
|
|
YYJSON value;
|
|
|
|
while (arr.ForeachArray(index, value))
|
|
{
|
|
AssertEq(index, count);
|
|
AssertValidHandle(value);
|
|
delete value;
|
|
count++;
|
|
}
|
|
|
|
AssertEq(count, 3);
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test ForeachKey
|
|
TestStart("Iterator_ForeachKey");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
obj.SetInt("key1", 1);
|
|
obj.SetInt("key2", 2);
|
|
obj.SetInt("key3", 3);
|
|
|
|
int count = 0;
|
|
char key[32];
|
|
|
|
while (obj.ForeachKey(key, sizeof(key)))
|
|
{
|
|
AssertTrue(strlen(key) > 0);
|
|
count++;
|
|
}
|
|
|
|
AssertEq(count, 3);
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test ForeachIndex
|
|
TestStart("Iterator_ForeachIndex");
|
|
{
|
|
YYJSONArray arr = new YYJSONArray();
|
|
arr.PushInt(1);
|
|
arr.PushInt(2);
|
|
arr.PushInt(3);
|
|
|
|
int count = 0;
|
|
int index;
|
|
|
|
while (arr.ForeachIndex(index))
|
|
{
|
|
AssertEq(index, count);
|
|
count++;
|
|
}
|
|
|
|
AssertEq(count, 3);
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test empty iterations
|
|
TestStart("Iterator_EmptyObject");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
|
|
char key[32];
|
|
YYJSON value;
|
|
AssertFalse(obj.ForeachObject(key, sizeof(key), value));
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Iterator_EmptyArray");
|
|
{
|
|
YYJSONArray arr = new YYJSONArray();
|
|
|
|
int index;
|
|
YYJSON value;
|
|
AssertFalse(arr.ForeachArray(index, value));
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
}
|
|
|
|
// ============================================================================
|
|
// 2.6 JSON Pointer Tests
|
|
// ============================================================================
|
|
|
|
void Test_JSONPointer()
|
|
{
|
|
PrintToServer("\n[Category] JSON Pointer Tests");
|
|
|
|
// Test PtrSet methods
|
|
TestStart("Pointer_PtrSetInt");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
AssertTrue(obj.PtrSetInt("/number", 42));
|
|
AssertEq(obj.PtrGetInt("/number"), 42);
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Pointer_PtrSetFloat");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
AssertTrue(obj.PtrSetFloat("/pi", 3.14159));
|
|
AssertFloatEq(obj.PtrGetFloat("/pi"), 3.14159);
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Pointer_PtrSetBool");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
AssertTrue(obj.PtrSetBool("/flag", true));
|
|
AssertTrue(obj.PtrGetBool("/flag"));
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Pointer_PtrSetString");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
AssertTrue(obj.PtrSetString("/name", "test"));
|
|
|
|
char buffer[64];
|
|
AssertTrue(obj.PtrGetString("/name", buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "test");
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Pointer_PtrSetInt64");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
AssertTrue(obj.PtrSetInt64("/bignum", "9223372036854775807"));
|
|
|
|
char buffer[32];
|
|
AssertTrue(obj.PtrGetInt64("/bignum", buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "9223372036854775807");
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Pointer_PtrSetNull");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
AssertTrue(obj.PtrSetNull("/nullable"));
|
|
AssertTrue(obj.PtrGetIsNull("/nullable"));
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test nested path creation
|
|
TestStart("Pointer_NestedPathCreation");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
AssertTrue(obj.PtrSetInt("/a/b/c/d", 123));
|
|
AssertEq(obj.PtrGetInt("/a/b/c/d"), 123);
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test PtrGet with handle
|
|
TestStart("Pointer_PtrGet");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
obj.PtrSetInt("/test", 999);
|
|
|
|
YYJSON val = obj.PtrGet("/test");
|
|
AssertValidHandle(val);
|
|
AssertEq(YYJSON.GetInt(val), 999);
|
|
|
|
delete val;
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test PtrAdd methods
|
|
TestStart("Pointer_PtrAddInt");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
obj.PtrSetInt("/arr/0", 1);
|
|
AssertTrue(obj.PtrAddInt("/arr/1", 2));
|
|
AssertEq(obj.PtrGetInt("/arr/1"), 2);
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Pointer_PtrAddString");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
obj.PtrSetString("/items/0", "first");
|
|
AssertTrue(obj.PtrAddString("/items/1", "second"));
|
|
|
|
char buffer[64];
|
|
obj.PtrGetString("/items/1", buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "second");
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test PtrRemove
|
|
TestStart("Pointer_PtrRemove");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
obj.PtrSetInt("/remove_me", 1);
|
|
obj.PtrSetInt("/keep_me", 2);
|
|
|
|
AssertTrue(obj.PtrRemove("/remove_me"));
|
|
|
|
YYJSON val;
|
|
obj.PtrTryGetVal("/remove_me", val);
|
|
AssertNullHandle(val);
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test PtrGetLength
|
|
TestStart("Pointer_PtrGetLength");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
obj.PtrSetString("/text", "hello");
|
|
|
|
int len = obj.PtrGetLength("/text");
|
|
AssertEq(len, 6); // Including null terminator
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test PtrTryGet methods
|
|
TestStart("Pointer_PtrTryGetInt");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
obj.PtrSetInt("/value", 42);
|
|
|
|
int value;
|
|
AssertTrue(obj.PtrTryGetInt("/value", value));
|
|
AssertEq(value, 42);
|
|
|
|
AssertFalse(obj.PtrTryGetInt("/nonexistent", value));
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Pointer_PtrTryGetBool");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
obj.PtrSetBool("/flag", true);
|
|
|
|
bool value;
|
|
AssertTrue(obj.PtrTryGetBool("/flag", value));
|
|
AssertTrue(value);
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Pointer_PtrTryGetFloat");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
obj.PtrSetFloat("/pi", 3.14);
|
|
|
|
float value;
|
|
AssertTrue(obj.PtrTryGetFloat("/pi", value));
|
|
AssertFloatEq(value, 3.14);
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Pointer_PtrTryGetString");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
obj.PtrSetString("/name", "test");
|
|
|
|
char buffer[64];
|
|
AssertTrue(obj.PtrTryGetString("/name", buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "test");
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Pointer_PtrTryGetInt64");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
obj.PtrSetInt64("/bignum", "123456789012345");
|
|
|
|
char buffer[32];
|
|
AssertTrue(obj.PtrTryGetInt64("/bignum", buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "123456789012345");
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Pointer_PtrTryGetVal");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
obj.PtrSetInt("/test", 42);
|
|
|
|
YYJSON value;
|
|
AssertTrue(obj.PtrTryGetVal("/test", value));
|
|
AssertValidHandle(value);
|
|
AssertEq(YYJSON.GetInt(value), 42);
|
|
|
|
delete value;
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
}
|
|
|
|
// ============================================================================
|
|
// 2.7 Advanced Features Tests
|
|
// ============================================================================
|
|
|
|
void Test_AdvancedFeatures()
|
|
{
|
|
PrintToServer("\n[Category] Advanced Features Tests");
|
|
|
|
// Test DeepCopy
|
|
TestStart("Advanced_DeepCopy_Object");
|
|
{
|
|
YYJSONObject original = new YYJSONObject();
|
|
original.SetInt("num", 42);
|
|
original.SetString("str", "test");
|
|
|
|
YYJSONObject target = new YYJSONObject();
|
|
YYJSONObject copy = YYJSON.DeepCopy(target, original);
|
|
|
|
AssertValidHandle(copy);
|
|
AssertEq(copy.GetInt("num"), 42);
|
|
|
|
char buffer[64];
|
|
copy.GetString("str", buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "test");
|
|
|
|
delete original;
|
|
delete target;
|
|
delete copy;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Advanced_DeepCopy_Array");
|
|
{
|
|
YYJSONArray original = new YYJSONArray();
|
|
original.PushInt(1);
|
|
original.PushInt(2);
|
|
original.PushInt(3);
|
|
|
|
YYJSONArray target = new YYJSONArray();
|
|
YYJSONArray copy = YYJSON.DeepCopy(target, original);
|
|
|
|
AssertValidHandle(copy);
|
|
AssertEq(copy.Length, 3);
|
|
AssertEq(copy.GetInt(0), 1);
|
|
AssertEq(copy.GetInt(2), 3);
|
|
|
|
delete original;
|
|
delete target;
|
|
delete copy;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test Equals
|
|
TestStart("Advanced_Equals_True");
|
|
{
|
|
YYJSONObject obj1 = new YYJSONObject();
|
|
obj1.SetInt("a", 1);
|
|
obj1.SetString("b", "test");
|
|
|
|
YYJSONObject obj2 = new YYJSONObject();
|
|
obj2.SetInt("a", 1);
|
|
obj2.SetString("b", "test");
|
|
|
|
AssertTrue(YYJSON.Equals(obj1, obj2));
|
|
|
|
delete obj1;
|
|
delete obj2;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Advanced_Equals_False");
|
|
{
|
|
YYJSONObject obj1 = new YYJSONObject();
|
|
obj1.SetInt("a", 1);
|
|
|
|
YYJSONObject obj2 = new YYJSONObject();
|
|
obj2.SetInt("a", 2);
|
|
|
|
AssertFalse(YYJSON.Equals(obj1, obj2));
|
|
|
|
delete obj1;
|
|
delete obj2;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test ToMutable/ToImmutable
|
|
TestStart("Advanced_ToMutable");
|
|
{
|
|
YYJSON immutable = YYJSON.Parse("{\"key\":\"value\"}");
|
|
AssertTrue(immutable.IsImmutable);
|
|
|
|
YYJSON mutable = immutable.ToMutable();
|
|
AssertValidHandle(mutable);
|
|
AssertTrue(mutable.IsMutable);
|
|
|
|
delete immutable;
|
|
delete mutable;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Advanced_ToImmutable");
|
|
{
|
|
YYJSONObject mutable = new YYJSONObject();
|
|
mutable.SetInt("key", 42);
|
|
AssertTrue(mutable.IsMutable);
|
|
|
|
YYJSON immutable = mutable.ToImmutable();
|
|
AssertValidHandle(immutable);
|
|
AssertTrue(immutable.IsImmutable);
|
|
|
|
delete mutable;
|
|
delete immutable;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test Pack
|
|
TestStart("Advanced_Pack_SimpleObject");
|
|
{
|
|
YYJSONObject json = YYJSON.Pack("{s:i,s:s,s:b}",
|
|
"num", 42,
|
|
"str", "test",
|
|
"bool", true
|
|
);
|
|
|
|
AssertValidHandle(json);
|
|
AssertTrue(json.IsObject);
|
|
|
|
YYJSONObject obj = json;
|
|
AssertEq(obj.GetInt("num"), 42);
|
|
|
|
char buffer[64];
|
|
obj.GetString("str", buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "test");
|
|
|
|
AssertTrue(obj.GetBool("bool"));
|
|
|
|
delete json;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Advanced_Pack_Array");
|
|
{
|
|
YYJSONArray json = YYJSON.Pack("[i,i,i]", 1, 2, 3);
|
|
|
|
AssertValidHandle(json);
|
|
AssertTrue(json.IsArray);
|
|
|
|
YYJSONArray arr = json;
|
|
AssertEq(arr.Length, 3);
|
|
AssertEq(arr.GetInt(0), 1);
|
|
AssertEq(arr.GetInt(2), 3);
|
|
|
|
delete json;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Advanced_Pack_Nested");
|
|
{
|
|
YYJSONObject json = YYJSON.Pack("{s:{s:s,s:i}}",
|
|
"user",
|
|
"name", "test",
|
|
"age", 25
|
|
);
|
|
|
|
AssertValidHandle(json);
|
|
|
|
char buffer[64];
|
|
YYJSONObject obj = json;
|
|
obj.PtrGetString("/user/name", buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "test");
|
|
AssertEq(obj.PtrGetInt("/user/age"), 25);
|
|
|
|
delete json;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test mixed type array sorting
|
|
TestStart("Advanced_MixedTypeSort");
|
|
{
|
|
YYJSONArray json = YYJSON.Parse("[true, 42, \"hello\", 1.5, false]", false, true);
|
|
YYJSONArray arr = json;
|
|
|
|
AssertTrue(arr.Sort(YYJSON_SORT_ASC));
|
|
AssertEq(arr.Length, 5);
|
|
|
|
delete json;
|
|
}
|
|
TestEnd();
|
|
}
|
|
|
|
// ============================================================================
|
|
// 2.8 Edge Cases & Error Handling Tests
|
|
// ============================================================================
|
|
|
|
void Test_EdgeCases()
|
|
{
|
|
PrintToServer("\n[Category] Edge Cases & Error Handling Tests");
|
|
|
|
// Test empty containers
|
|
TestStart("EdgeCase_EmptyObject");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
AssertEq(obj.Size, 0);
|
|
AssertFalse(obj.HasKey("anything"));
|
|
|
|
char buffer[64];
|
|
int len = obj.ToString(buffer, sizeof(buffer));
|
|
AssertTrue(len > 0);
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("EdgeCase_EmptyArray");
|
|
{
|
|
YYJSONArray arr = new YYJSONArray();
|
|
AssertEq(arr.Length, 0);
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test nonexistent keys/indices
|
|
TestStart("EdgeCase_NonexistentKey");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
obj.SetInt("exists", 1);
|
|
|
|
AssertTrue(obj.HasKey("exists"));
|
|
AssertFalse(obj.HasKey("notexists"));
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("EdgeCase_ArrayOutOfBounds");
|
|
{
|
|
YYJSONArray arr = new YYJSONArray();
|
|
arr.PushInt(1);
|
|
|
|
// Verify array bounds
|
|
AssertEq(arr.Length, 1);
|
|
AssertEq(arr.GetInt(0), 1);
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test very long strings
|
|
TestStart("EdgeCase_LongString");
|
|
{
|
|
char longStr[1024];
|
|
for (int i = 0; i < sizeof(longStr) - 1; i++)
|
|
{
|
|
longStr[i] = 'A' + (i % 26);
|
|
}
|
|
longStr[sizeof(longStr) - 1] = '\0';
|
|
|
|
YYJSON val = YYJSON.CreateString(longStr);
|
|
AssertValidHandle(val);
|
|
|
|
char retrieved[1024];
|
|
AssertTrue(YYJSON.GetString(val, retrieved, sizeof(retrieved)));
|
|
AssertStrEq(retrieved, longStr);
|
|
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test deep nesting
|
|
TestStart("EdgeCase_DeepNesting");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
|
|
// Create deeply nested structure
|
|
obj.PtrSetInt("/a/b/c/d/e/f/g/h/i/j", 42);
|
|
AssertEq(obj.PtrGetInt("/a/b/c/d/e/f/g/h/i/j"), 42);
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test large arrays
|
|
TestStart("EdgeCase_LargeArray");
|
|
{
|
|
YYJSONArray arr = new YYJSONArray();
|
|
|
|
for (int i = 0; i < 1000; i++)
|
|
{
|
|
arr.PushInt(i);
|
|
}
|
|
|
|
AssertEq(arr.Length, 1000);
|
|
AssertEq(arr.GetInt(0), 0);
|
|
AssertEq(arr.GetInt(999), 999);
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test large objects
|
|
TestStart("EdgeCase_LargeObject");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
|
|
char key[32];
|
|
for (int i = 0; i < 100; i++)
|
|
{
|
|
Format(key, sizeof(key), "key_%d", i);
|
|
obj.SetInt(key, i);
|
|
}
|
|
|
|
AssertEq(obj.Size, 100);
|
|
AssertEq(obj.GetInt("key_0"), 0);
|
|
AssertEq(obj.GetInt("key_99"), 99);
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test int64 boundaries
|
|
TestStart("EdgeCase_Int64_MaxValue");
|
|
{
|
|
YYJSON val = YYJSON.CreateInt64("9223372036854775807");
|
|
AssertValidHandle(val);
|
|
|
|
char buffer[32];
|
|
YYJSON.GetInt64(val, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "9223372036854775807");
|
|
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("EdgeCase_Int64_MinValue");
|
|
{
|
|
YYJSON val = YYJSON.CreateInt64("-9223372036854775808");
|
|
AssertValidHandle(val);
|
|
|
|
char buffer[32];
|
|
YYJSON.GetInt64(val, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "-9223372036854775808");
|
|
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test special float values
|
|
TestStart("EdgeCase_Float_VerySmall");
|
|
{
|
|
YYJSON val = YYJSON.CreateFloat(0.000001);
|
|
AssertValidHandle(val);
|
|
AssertFloatEq(YYJSON.GetFloat(val), 0.000001);
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("EdgeCase_Float_VeryLarge");
|
|
{
|
|
YYJSON val = YYJSON.CreateFloat(999999.999999);
|
|
AssertValidHandle(val);
|
|
AssertFloatEq(YYJSON.GetFloat(val), 999999.999999, "", 0.001);
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test special characters in strings
|
|
TestStart("EdgeCase_SpecialCharacters");
|
|
{
|
|
YYJSON val = YYJSON.CreateString("Line1\nLine2\tTabbed\"Quoted\"");
|
|
AssertValidHandle(val);
|
|
|
|
char buffer[128];
|
|
YYJSON.GetString(val, buffer, sizeof(buffer));
|
|
Assert(StrContains(buffer, "Line1") != -1);
|
|
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test removing from empty array
|
|
TestStart("EdgeCase_RemoveFromEmptyArray");
|
|
{
|
|
YYJSONArray arr = new YYJSONArray();
|
|
AssertFalse(arr.RemoveFirst());
|
|
AssertFalse(arr.RemoveLast());
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test clearing already empty containers
|
|
TestStart("EdgeCase_ClearEmpty");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
AssertTrue(obj.Clear());
|
|
AssertEq(obj.Size, 0);
|
|
|
|
YYJSONArray arr = new YYJSONArray();
|
|
AssertTrue(arr.Clear());
|
|
AssertEq(arr.Length, 0);
|
|
|
|
delete obj;
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test IndexOf on empty array
|
|
TestStart("EdgeCase_IndexOfEmpty");
|
|
{
|
|
YYJSONArray arr = new YYJSONArray();
|
|
AssertEq(arr.IndexOfInt(42), -1);
|
|
AssertEq(arr.IndexOfString("test"), -1);
|
|
AssertEq(arr.IndexOfBool(true), -1);
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test pointer to nonexistent path
|
|
TestStart("EdgeCase_PointerNonexistentPath");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
|
|
// Note: PtrGet throws exception for nonexistent paths (expected behavior)
|
|
// Use PtrTryGet methods for safe access
|
|
int intVal;
|
|
AssertFalse(obj.PtrTryGetInt("/does/not/exist", intVal));
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test sorting empty containers
|
|
TestStart("EdgeCase_SortEmpty");
|
|
{
|
|
YYJSONObject obj = new YYJSONObject();
|
|
AssertTrue(obj.Sort());
|
|
|
|
YYJSONArray arr = new YYJSONArray();
|
|
AssertTrue(arr.Sort());
|
|
|
|
delete obj;
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test single element operations
|
|
TestStart("EdgeCase_SingleElement");
|
|
{
|
|
YYJSONArray arr = new YYJSONArray();
|
|
arr.PushInt(42);
|
|
|
|
AssertTrue(arr.Sort());
|
|
AssertEq(arr.GetInt(0), 42);
|
|
|
|
AssertEq(arr.IndexOfInt(42), 0);
|
|
|
|
YYJSON first = arr.First;
|
|
YYJSON last = arr.Last;
|
|
AssertEq(YYJSON.GetInt(first), YYJSON.GetInt(last));
|
|
|
|
delete first;
|
|
delete last;
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
} |