mirror of
https://github.com/alliedmodders/sourcemod.git
synced 2025-12-06 18:08:36 +00:00
- Added ObjectRotate and ArrayRotate methods for rotating key-value pairs in JSON objects and arrays, respectively - Introduced GetValCount method to retrieve the total number of values in immutable JSON documents - Renamed all Float-related methods to Double in C++ interface (IJsonManager) for better precision clarity - Fixed TypeAccess configuration in handle type registration to allow external extensions to create JSON handles by properly setting HTypeAccess_Create flag - Renamed GetHandleType to GetJsonHandleType for better clarity and consistency - Updated documentation to clarify usage and performance considerations for new methods - Enhanced tests to cover rotation functionality and value counting in various JSON structures
3380 lines
71 KiB
SourcePawn
Executable File
3380 lines
71 KiB
SourcePawn
Executable File
#include <sourcemod>
|
|
#include <json>
|
|
|
|
#pragma newdecls required
|
|
#pragma semicolon 1
|
|
|
|
public Plugin myinfo =
|
|
{
|
|
name = "JSON Test Suite",
|
|
author = "ProjectSky",
|
|
description = "test suite for JSON 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_json", Command_RunTests, "Run JSON 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')
|
|
{
|
|
FormatEx(buffer, sizeof(buffer), "%s (expected %d, got %d)", message, b, a);
|
|
}
|
|
else
|
|
{
|
|
FormatEx(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')
|
|
{
|
|
FormatEx(buffer, sizeof(buffer), "%s (values should not be equal: %d)", message, a);
|
|
}
|
|
else
|
|
{
|
|
FormatEx(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 (strcmp(a, b) != 0)
|
|
{
|
|
g_bCurrentTestFailed = true;
|
|
char buffer[512];
|
|
if (message[0] != '\0')
|
|
{
|
|
FormatEx(buffer, sizeof(buffer), "%s (expected \"%s\", got \"%s\")", message, b, a);
|
|
}
|
|
else
|
|
{
|
|
FormatEx(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')
|
|
{
|
|
FormatEx(buffer, sizeof(buffer), "%s (expected %.4f, got %.4f)", message, b, a);
|
|
}
|
|
else
|
|
{
|
|
FormatEx(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("JSON 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_Int64Operations();
|
|
Test_EdgeCases();
|
|
|
|
// Print results
|
|
PrintToServer("========================================");
|
|
PrintToServer("JSON 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");
|
|
{
|
|
JSON val = JSON.CreateBool(true);
|
|
AssertValidHandle(val);
|
|
AssertTrue(val.GetBool());
|
|
AssertEq(val.Type, JSON_TYPE_BOOL);
|
|
AssertTrue(val.IsBool);
|
|
AssertTrue(val.IsTrue);
|
|
AssertFalse(val.IsFalse);
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("BasicValues_CreateBool_False");
|
|
{
|
|
JSON val = JSON.CreateBool(false);
|
|
AssertValidHandle(val);
|
|
AssertFalse(val.GetBool());
|
|
AssertTrue(val.IsBool);
|
|
AssertFalse(val.IsTrue);
|
|
AssertTrue(val.IsFalse);
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test CreateInt & GetInt
|
|
TestStart("BasicValues_CreateInt_Positive");
|
|
{
|
|
JSON val = JSON.CreateInt(42);
|
|
AssertValidHandle(val);
|
|
AssertEq(val.GetInt(), 42);
|
|
AssertEq(val.Type, JSON_TYPE_NUM);
|
|
AssertTrue(val.IsInt);
|
|
AssertTrue(val.IsNum);
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("BasicValues_CreateInt_Negative");
|
|
{
|
|
JSON val = JSON.CreateInt(-123);
|
|
AssertValidHandle(val);
|
|
AssertEq(val.GetInt(), -123);
|
|
AssertTrue(val.IsSint);
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("BasicValues_CreateInt_Zero");
|
|
{
|
|
JSON val = JSON.CreateInt(0);
|
|
AssertValidHandle(val);
|
|
AssertEq(val.GetInt(), 0);
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test CreateFloat & GetFloat
|
|
TestStart("BasicValues_CreateFloat_Positive");
|
|
{
|
|
JSON val = JSON.CreateFloat(3.14159);
|
|
AssertValidHandle(val);
|
|
AssertFloatEq(val.GetFloat(), 3.14159);
|
|
AssertTrue(val.IsFloat);
|
|
AssertTrue(val.IsNum);
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("BasicValues_CreateFloat_Negative");
|
|
{
|
|
JSON val = JSON.CreateFloat(-2.71828);
|
|
AssertValidHandle(val);
|
|
AssertFloatEq(val.GetFloat(), -2.71828);
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("BasicValues_CreateFloat_Zero");
|
|
{
|
|
JSON val = JSON.CreateFloat(0.0);
|
|
AssertValidHandle(val);
|
|
AssertFloatEq(val.GetFloat(), 0.0);
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test CreateString & GetString
|
|
TestStart("BasicValues_CreateString_Regular");
|
|
{
|
|
JSON val = JSON.CreateString("Hello, World!");
|
|
AssertValidHandle(val);
|
|
char buffer[64];
|
|
AssertTrue(val.GetString(buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "Hello, World!");
|
|
AssertEq(val.Type, JSON_TYPE_STR);
|
|
AssertTrue(val.IsStr);
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("BasicValues_CreateString_Empty");
|
|
{
|
|
JSON val = JSON.CreateString("");
|
|
AssertValidHandle(val);
|
|
char buffer[64];
|
|
AssertTrue(val.GetString(buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "");
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("BasicValues_CreateString_Unicode");
|
|
{
|
|
JSON val = JSON.CreateString("测试字符串");
|
|
AssertValidHandle(val);
|
|
char buffer[64];
|
|
AssertTrue(val.GetString(buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "测试字符串");
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test CreateInt64 & GetInt64
|
|
TestStart("BasicValues_CreateInt64_Large");
|
|
{
|
|
JSON val = JSON.CreateInt64("9223372036854775807");
|
|
AssertValidHandle(val);
|
|
char buffer[32];
|
|
AssertTrue(val.GetInt64(buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "9223372036854775807");
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("BasicValues_CreateInt64_Negative");
|
|
{
|
|
JSON val = JSON.CreateInt64("-9223372036854775808");
|
|
AssertValidHandle(val);
|
|
char buffer[32];
|
|
AssertTrue(val.GetInt64(buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "-9223372036854775808");
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test CreateNull
|
|
TestStart("BasicValues_CreateNull");
|
|
{
|
|
JSON val = JSON.CreateNull();
|
|
AssertValidHandle(val);
|
|
AssertEq(val.Type, JSON_TYPE_NULL);
|
|
AssertTrue(val.IsNull);
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test GetTypeDesc
|
|
TestStart("BasicValues_GetTypeDesc");
|
|
{
|
|
JSON boolVal = JSON.CreateBool(true);
|
|
JSON intVal = JSON.CreateInt(42);
|
|
JSON floatVal = JSON.CreateFloat(3.14);
|
|
JSON strVal = JSON.CreateString("test");
|
|
JSON nullVal = JSON.CreateNull();
|
|
|
|
char buffer[32];
|
|
|
|
boolVal.GetTypeDesc(buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "true");
|
|
|
|
intVal.GetTypeDesc(buffer, sizeof(buffer));
|
|
AssertTrue(strcmp(buffer, "uint") == 0 || strcmp(buffer, "sint") == 0);
|
|
|
|
floatVal.GetTypeDesc(buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "real");
|
|
|
|
strVal.GetTypeDesc(buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "string");
|
|
|
|
nullVal.GetTypeDesc(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");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
AssertValidHandle(obj);
|
|
AssertTrue(obj.IsObject);
|
|
AssertEq(obj.Size, 0);
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test Set/Get methods
|
|
TestStart("Object_SetGetInt");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
AssertTrue(obj.SetInt("number", 42));
|
|
AssertEq(obj.GetInt("number"), 42);
|
|
AssertEq(obj.Size, 1);
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Object_SetGetFloat");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
AssertTrue(obj.SetFloat("pi", 3.14159));
|
|
AssertFloatEq(obj.GetFloat("pi"), 3.14159);
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Object_SetGetBool");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
AssertTrue(obj.SetBool("flag", true));
|
|
AssertTrue(obj.GetBool("flag"));
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Object_SetGetString");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
AssertTrue(obj.SetString("name", "test"));
|
|
char buffer[64];
|
|
AssertTrue(obj.GetString("name", buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "test");
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Object_SetGetInt64");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
AssertTrue(obj.SetInt64("bignum", "9223372036854775807"));
|
|
char buffer[32];
|
|
AssertTrue(obj.GetInt64("bignum", buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "9223372036854775807");
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Object_SetGetNull");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
AssertTrue(obj.SetNull("nullable"));
|
|
AssertTrue(obj.IsNull("nullable"));
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test HasKey
|
|
TestStart("Object_HasKey");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
obj.SetInt("exists", 1);
|
|
AssertTrue(obj.HasKey("exists"));
|
|
AssertFalse(obj.HasKey("notexists"));
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test GetKey and GetValueAt
|
|
TestStart("Object_GetKeyAndValueAt");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
obj.SetInt("first", 1);
|
|
obj.SetInt("second", 2);
|
|
|
|
char key[32];
|
|
AssertTrue(obj.GetKey(0, key, sizeof(key)));
|
|
AssertStrEq(key, "first");
|
|
|
|
JSON val = obj.GetValueAt(0);
|
|
AssertValidHandle(val);
|
|
AssertEq(val.GetInt(), 1);
|
|
|
|
delete val;
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test Remove
|
|
TestStart("Object_Remove");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
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");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
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");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
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");
|
|
{
|
|
JSONObject obj = JSONObject.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"};
|
|
JSONObject obj = JSONObject.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");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
obj.SetInt("zebra", 1);
|
|
obj.SetInt("alpha", 2);
|
|
obj.SetInt("beta", 3);
|
|
|
|
AssertTrue(obj.Sort(JSON_SORT_ASC));
|
|
|
|
char key[32];
|
|
obj.GetKey(0, key, sizeof(key));
|
|
AssertStrEq(key, "alpha");
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Object_Sort_Descending");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
obj.SetInt("alpha", 1);
|
|
obj.SetInt("beta", 2);
|
|
obj.SetInt("gamma", 3);
|
|
|
|
AssertTrue(obj.Sort(JSON_SORT_DESC));
|
|
|
|
char key[32];
|
|
obj.GetKey(0, key, sizeof(key));
|
|
AssertStrEq(key, "gamma");
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test Rotate
|
|
TestStart("Object_Rotate_Forward");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
obj.SetInt("a", 1);
|
|
obj.SetInt("b", 2);
|
|
obj.SetInt("c", 3);
|
|
obj.SetInt("d", 4);
|
|
|
|
AssertTrue(obj.Rotate(1));
|
|
|
|
char key[32];
|
|
obj.GetKey(0, key, sizeof(key));
|
|
AssertStrEq(key, "b", "First key should be 'b' after rotate 1");
|
|
obj.GetKey(3, key, sizeof(key));
|
|
AssertStrEq(key, "a", "Last key should be 'a' after rotate 1");
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Object_Rotate_Multiple");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
obj.SetInt("first", 1);
|
|
obj.SetInt("second", 2);
|
|
obj.SetInt("third", 3);
|
|
obj.SetInt("fourth", 4);
|
|
obj.SetInt("fifth", 5);
|
|
|
|
AssertTrue(obj.Rotate(2));
|
|
|
|
char key[32];
|
|
obj.GetKey(0, key, sizeof(key));
|
|
AssertStrEq(key, "third", "First key should be 'third' after rotate 2");
|
|
obj.GetKey(4, key, sizeof(key));
|
|
AssertStrEq(key, "second", "Last key should be 'second' after rotate 2");
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Object_Rotate_Zero");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
obj.SetInt("x", 1);
|
|
obj.SetInt("y", 2);
|
|
|
|
AssertTrue(obj.Rotate(0));
|
|
|
|
char key[32];
|
|
obj.GetKey(0, key, sizeof(key));
|
|
AssertStrEq(key, "x", "Order should not change after rotate 0");
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test Set with handle
|
|
TestStart("Object_SetWithHandle");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
JSON val = JSON.CreateInt(999);
|
|
|
|
AssertTrue(obj.Set("nested", val));
|
|
AssertEq(obj.GetInt("nested"), 999);
|
|
|
|
delete val;
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test Get with handle
|
|
TestStart("Object_GetHandle");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
obj.SetInt("value", 42);
|
|
|
|
JSON val = obj.Get("value");
|
|
AssertValidHandle(val);
|
|
AssertEq(val.GetInt(), 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");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
AssertValidHandle(arr);
|
|
AssertTrue(arr.IsArray);
|
|
AssertEq(arr.Length, 0);
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test Push methods
|
|
TestStart("Array_PushInt");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
AssertTrue(arr.PushInt(42));
|
|
AssertEq(arr.Length, 1);
|
|
AssertEq(arr.GetInt(0), 42);
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_PushFloat");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
AssertTrue(arr.PushFloat(3.14));
|
|
AssertFloatEq(arr.GetFloat(0), 3.14);
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_PushBool");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
AssertTrue(arr.PushBool(true));
|
|
AssertTrue(arr.GetBool(0));
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_PushString");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
AssertTrue(arr.PushString("test"));
|
|
char buffer[64];
|
|
AssertTrue(arr.GetString(0, buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "test");
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_PushInt64");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
AssertTrue(arr.PushInt64("9223372036854775807"));
|
|
char buffer[32];
|
|
arr.GetInt64(0, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "9223372036854775807");
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_PushNull");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
AssertTrue(arr.PushNull());
|
|
AssertTrue(arr.IsNull(0));
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test Set/Get methods
|
|
TestStart("Array_SetGetInt");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
arr.PushInt(0);
|
|
AssertTrue(arr.SetInt(0, 100));
|
|
AssertEq(arr.GetInt(0), 100);
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_SetGetFloat");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
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");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
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");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
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");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
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");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
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");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
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");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
arr.PushInt(10);
|
|
arr.PushInt(20);
|
|
arr.PushInt(30);
|
|
|
|
JSON first = arr.First;
|
|
JSON last = arr.Last;
|
|
|
|
AssertValidHandle(first);
|
|
AssertValidHandle(last);
|
|
AssertEq(first.GetInt(), 10);
|
|
AssertEq(last.GetInt(), 30);
|
|
|
|
delete first;
|
|
delete last;
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test IndexOf methods
|
|
TestStart("Array_IndexOfInt");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
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");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
arr.PushBool(false);
|
|
arr.PushBool(true);
|
|
arr.PushBool(false);
|
|
|
|
AssertEq(arr.IndexOfBool(true), 1);
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_IndexOfString");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
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");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
arr.PushFloat(1.1);
|
|
arr.PushFloat(2.2);
|
|
arr.PushFloat(3.3);
|
|
|
|
AssertEq(arr.IndexOfFloat(2.2), 1);
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_IndexOfInt64");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
arr.PushInt64("1000000000000");
|
|
arr.PushInt64("2000000000000");
|
|
|
|
AssertEq(arr.IndexOfInt64("2000000000000"), 1);
|
|
AssertEq(arr.IndexOfInt64("3000000000000"), -1);
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test FromString
|
|
TestStart("Array_FromString");
|
|
{
|
|
JSONArray arr = JSONArray.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"};
|
|
JSONArray arr = JSONArray.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");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
arr.PushInt(3);
|
|
arr.PushInt(1);
|
|
arr.PushInt(4);
|
|
arr.PushInt(1);
|
|
arr.PushInt(5);
|
|
|
|
AssertTrue(arr.Sort(JSON_SORT_ASC));
|
|
AssertEq(arr.GetInt(0), 1);
|
|
AssertEq(arr.GetInt(4), 5);
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_Sort_Descending");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
arr.PushInt(1);
|
|
arr.PushInt(2);
|
|
arr.PushInt(3);
|
|
arr.PushInt(4);
|
|
arr.PushInt(5);
|
|
|
|
AssertTrue(arr.Sort(JSON_SORT_DESC));
|
|
AssertEq(arr.GetInt(0), 5);
|
|
AssertEq(arr.GetInt(4), 1);
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test Rotate
|
|
TestStart("Array_Rotate_Forward");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
arr.PushInt(1);
|
|
arr.PushInt(2);
|
|
arr.PushInt(3);
|
|
arr.PushInt(4);
|
|
arr.PushInt(5);
|
|
|
|
AssertTrue(arr.Rotate(2));
|
|
AssertEq(arr.GetInt(0), 3, "First element should be 3 after rotate 2");
|
|
AssertEq(arr.GetInt(1), 4, "Second element should be 4");
|
|
AssertEq(arr.GetInt(2), 5, "Third element should be 5");
|
|
AssertEq(arr.GetInt(3), 1, "Fourth element should be 1");
|
|
AssertEq(arr.GetInt(4), 2, "Fifth element should be 2");
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_Rotate_Single");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
arr.PushString("a");
|
|
arr.PushString("b");
|
|
arr.PushString("c");
|
|
arr.PushString("d");
|
|
|
|
AssertTrue(arr.Rotate(1));
|
|
|
|
char buffer[32];
|
|
arr.GetString(0, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "b", "First element should be 'b' after rotate 1");
|
|
arr.GetString(3, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "a", "Last element should be 'a' after rotate 1");
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_Rotate_Zero");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
arr.PushInt(10);
|
|
arr.PushInt(20);
|
|
arr.PushInt(30);
|
|
|
|
AssertTrue(arr.Rotate(0));
|
|
AssertEq(arr.GetInt(0), 10, "Order should not change after rotate 0");
|
|
AssertEq(arr.GetInt(1), 20);
|
|
AssertEq(arr.GetInt(2), 30);
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_Rotate_LargeIndex");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
arr.PushInt(1);
|
|
arr.PushInt(2);
|
|
arr.PushInt(3);
|
|
|
|
// Rotate by array length or greater should fail (idx must be < length)
|
|
AssertFalse(arr.Rotate(3), "Rotate by array length should fail");
|
|
AssertFalse(arr.Rotate(10), "Rotate by value > length should fail");
|
|
|
|
// Values should remain unchanged
|
|
AssertEq(arr.GetInt(0), 1);
|
|
AssertEq(arr.GetInt(1), 2);
|
|
AssertEq(arr.GetInt(2), 3);
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test Push with handle
|
|
TestStart("Array_PushHandle");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
JSON val = JSON.CreateInt(999);
|
|
|
|
AssertTrue(arr.Push(val));
|
|
AssertEq(arr.GetInt(0), 999);
|
|
|
|
delete val;
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test Get with handle
|
|
TestStart("Array_GetHandle");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
arr.PushInt(42);
|
|
|
|
JSON val = arr.Get(0);
|
|
AssertValidHandle(val);
|
|
AssertEq(val.GetInt(), 42);
|
|
|
|
delete val;
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test FromInt
|
|
TestStart("Array_FromInt");
|
|
{
|
|
int values[] = {10, 20, 30, 40, 50};
|
|
JSONArray arr = JSONArray.FromInt(values, sizeof(values));
|
|
|
|
AssertValidHandle(arr);
|
|
AssertEq(arr.Length, 5);
|
|
AssertEq(arr.GetInt(0), 10);
|
|
AssertEq(arr.GetInt(2), 30);
|
|
AssertEq(arr.GetInt(4), 50);
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_FromInt_Negative");
|
|
{
|
|
int values[] = {-100, -50, 0, 50, 100};
|
|
JSONArray arr = JSONArray.FromInt(values, sizeof(values));
|
|
|
|
AssertValidHandle(arr);
|
|
AssertEq(arr.Length, 5);
|
|
AssertEq(arr.GetInt(0), -100);
|
|
AssertEq(arr.GetInt(2), 0);
|
|
AssertEq(arr.GetInt(4), 100);
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test FromInt64
|
|
TestStart("Array_FromInt64_Mixed");
|
|
{
|
|
char values[][] = {"9223372036854775807", "-9223372036854775808", "0", "18446744073709551615"};
|
|
JSONArray arr = JSONArray.FromInt64(values, sizeof(values));
|
|
|
|
AssertValidHandle(arr);
|
|
AssertEq(arr.Length, 4);
|
|
|
|
char buffer[32];
|
|
arr.GetInt64(0, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "9223372036854775807");
|
|
|
|
arr.GetInt64(1, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "-9223372036854775808");
|
|
|
|
arr.GetInt64(2, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "0");
|
|
|
|
arr.GetInt64(3, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "18446744073709551615");
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_FromInt64_LargeValues");
|
|
{
|
|
char values[][] = {"1234567890123456", "9876543210987654", "5555555555555555"};
|
|
JSONArray arr = JSONArray.FromInt64(values, sizeof(values));
|
|
|
|
AssertValidHandle(arr);
|
|
AssertEq(arr.Length, 3);
|
|
|
|
char buffer[32];
|
|
arr.GetInt64(1, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "9876543210987654");
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test FromBool
|
|
TestStart("Array_FromBool");
|
|
{
|
|
bool values[] = {true, false, true, true, false};
|
|
JSONArray arr = JSONArray.FromBool(values, sizeof(values));
|
|
|
|
AssertValidHandle(arr);
|
|
AssertEq(arr.Length, 5);
|
|
AssertTrue(arr.GetBool(0));
|
|
AssertFalse(arr.GetBool(1));
|
|
AssertTrue(arr.GetBool(2));
|
|
AssertTrue(arr.GetBool(3));
|
|
AssertFalse(arr.GetBool(4));
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_FromBool_AllTrue");
|
|
{
|
|
bool values[] = {true, true, true};
|
|
JSONArray arr = JSONArray.FromBool(values, sizeof(values));
|
|
|
|
AssertValidHandle(arr);
|
|
AssertEq(arr.Length, 3);
|
|
AssertTrue(arr.GetBool(0));
|
|
AssertTrue(arr.GetBool(1));
|
|
AssertTrue(arr.GetBool(2));
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test FromFloat
|
|
TestStart("Array_FromFloat");
|
|
{
|
|
float values[] = {1.1, 2.2, 3.3, 4.4, 5.5};
|
|
JSONArray arr = JSONArray.FromFloat(values, sizeof(values));
|
|
|
|
AssertValidHandle(arr);
|
|
AssertEq(arr.Length, 5);
|
|
AssertFloatEq(arr.GetFloat(0), 1.1);
|
|
AssertFloatEq(arr.GetFloat(2), 3.3, "", 0.01);
|
|
AssertFloatEq(arr.GetFloat(4), 5.5);
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_FromFloat_Negative");
|
|
{
|
|
float values[] = {-3.14, 0.0, 2.718, -1.414};
|
|
JSONArray arr = JSONArray.FromFloat(values, sizeof(values));
|
|
|
|
AssertValidHandle(arr);
|
|
AssertEq(arr.Length, 4);
|
|
AssertFloatEq(arr.GetFloat(0), -3.14);
|
|
AssertFloatEq(arr.GetFloat(1), 0.0);
|
|
AssertFloatEq(arr.GetFloat(2), 2.718);
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test Insert methods
|
|
TestStart("Array_InsertInt");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
arr.PushInt(1);
|
|
arr.PushInt(3);
|
|
arr.PushInt(4);
|
|
|
|
AssertTrue(arr.InsertInt(1, 2));
|
|
AssertEq(arr.Length, 4);
|
|
AssertEq(arr.GetInt(0), 1);
|
|
AssertEq(arr.GetInt(1), 2);
|
|
AssertEq(arr.GetInt(2), 3);
|
|
AssertEq(arr.GetInt(3), 4);
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_InsertBool");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
arr.PushBool(true);
|
|
arr.PushBool(true);
|
|
|
|
AssertTrue(arr.InsertBool(1, false));
|
|
AssertEq(arr.Length, 3);
|
|
AssertTrue(arr.GetBool(0));
|
|
AssertFalse(arr.GetBool(1));
|
|
AssertTrue(arr.GetBool(2));
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_InsertFloat");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
arr.PushFloat(1.1);
|
|
arr.PushFloat(3.3);
|
|
|
|
AssertTrue(arr.InsertFloat(1, 2.2));
|
|
AssertEq(arr.Length, 3);
|
|
AssertFloatEq(arr.GetFloat(0), 1.1);
|
|
AssertFloatEq(arr.GetFloat(1), 2.2);
|
|
AssertFloatEq(arr.GetFloat(2), 3.3, "", 0.01);
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_InsertString");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
arr.PushString("first");
|
|
arr.PushString("third");
|
|
|
|
AssertTrue(arr.InsertString(1, "second"));
|
|
AssertEq(arr.Length, 3);
|
|
|
|
char buffer[64];
|
|
arr.GetString(0, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "first");
|
|
|
|
arr.GetString(1, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "second");
|
|
|
|
arr.GetString(2, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "third");
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_InsertInt64");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
arr.PushInt64("1111111111111111");
|
|
arr.PushInt64("3333333333333333");
|
|
|
|
AssertTrue(arr.InsertInt64(1, "2222222222222222"));
|
|
AssertEq(arr.Length, 3);
|
|
|
|
char buffer[32];
|
|
arr.GetInt64(0, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "1111111111111111");
|
|
|
|
arr.GetInt64(1, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "2222222222222222");
|
|
|
|
arr.GetInt64(2, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "3333333333333333");
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_InsertNull");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
arr.PushInt(1);
|
|
arr.PushInt(2);
|
|
|
|
AssertTrue(arr.InsertNull(1));
|
|
AssertEq(arr.Length, 3);
|
|
AssertEq(arr.GetInt(0), 1);
|
|
AssertTrue(arr.IsNull(1));
|
|
AssertEq(arr.GetInt(2), 2);
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_InsertAtBeginning");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
arr.PushInt(2);
|
|
arr.PushInt(3);
|
|
|
|
AssertTrue(arr.InsertInt(0, 1));
|
|
AssertEq(arr.Length, 3);
|
|
AssertEq(arr.GetInt(0), 1);
|
|
AssertEq(arr.GetInt(1), 2);
|
|
AssertEq(arr.GetInt(2), 3);
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_InsertAtEnd");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
arr.PushInt(1);
|
|
arr.PushInt(2);
|
|
|
|
AssertTrue(arr.InsertInt(2, 3));
|
|
AssertEq(arr.Length, 3);
|
|
AssertEq(arr.GetInt(0), 1);
|
|
AssertEq(arr.GetInt(1), 2);
|
|
AssertEq(arr.GetInt(2), 3);
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_InsertHandle");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
arr.PushInt(1);
|
|
arr.PushInt(3);
|
|
|
|
JSON val = JSON.CreateInt(2);
|
|
AssertTrue(arr.Insert(1, val));
|
|
|
|
AssertEq(arr.Length, 3);
|
|
AssertEq(arr.GetInt(0), 1);
|
|
AssertEq(arr.GetInt(1), 2);
|
|
AssertEq(arr.GetInt(2), 3);
|
|
|
|
delete val;
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test Prepend methods
|
|
TestStart("Array_PrependInt");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
arr.PushInt(2);
|
|
arr.PushInt(3);
|
|
|
|
AssertTrue(arr.PrependInt(1));
|
|
AssertEq(arr.Length, 3);
|
|
AssertEq(arr.GetInt(0), 1);
|
|
AssertEq(arr.GetInt(1), 2);
|
|
AssertEq(arr.GetInt(2), 3);
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_PrependBool");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
arr.PushBool(false);
|
|
arr.PushBool(false);
|
|
|
|
AssertTrue(arr.PrependBool(true));
|
|
AssertEq(arr.Length, 3);
|
|
AssertTrue(arr.GetBool(0));
|
|
AssertFalse(arr.GetBool(1));
|
|
AssertFalse(arr.GetBool(2));
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_PrependFloat");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
arr.PushFloat(2.2);
|
|
arr.PushFloat(3.3);
|
|
|
|
AssertTrue(arr.PrependFloat(1.1));
|
|
AssertEq(arr.Length, 3);
|
|
AssertFloatEq(arr.GetFloat(0), 1.1);
|
|
AssertFloatEq(arr.GetFloat(1), 2.2);
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_PrependString");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
arr.PushString("second");
|
|
arr.PushString("third");
|
|
|
|
AssertTrue(arr.PrependString("first"));
|
|
AssertEq(arr.Length, 3);
|
|
|
|
char buffer[64];
|
|
arr.GetString(0, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "first");
|
|
|
|
arr.GetString(1, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "second");
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_PrependInt64");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
arr.PushInt64("2222222222222222");
|
|
arr.PushInt64("3333333333333333");
|
|
|
|
AssertTrue(arr.PrependInt64("1111111111111111"));
|
|
AssertEq(arr.Length, 3);
|
|
|
|
char buffer[32];
|
|
arr.GetInt64(0, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "1111111111111111");
|
|
|
|
arr.GetInt64(1, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "2222222222222222");
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_PrependNull");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
arr.PushInt(1);
|
|
arr.PushInt(2);
|
|
|
|
AssertTrue(arr.PrependNull());
|
|
AssertEq(arr.Length, 3);
|
|
AssertTrue(arr.IsNull(0));
|
|
AssertEq(arr.GetInt(1), 1);
|
|
AssertEq(arr.GetInt(2), 2);
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_PrependHandle");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
arr.PushInt(2);
|
|
arr.PushInt(3);
|
|
|
|
JSON val = JSON.CreateInt(1);
|
|
AssertTrue(arr.Prepend(val));
|
|
|
|
AssertEq(arr.Length, 3);
|
|
AssertEq(arr.GetInt(0), 1);
|
|
AssertEq(arr.GetInt(1), 2);
|
|
|
|
delete val;
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Array_PrependToEmpty");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
|
|
AssertTrue(arr.PrependInt(1));
|
|
AssertEq(arr.Length, 1);
|
|
AssertEq(arr.GetInt(0), 1);
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test combined Insert and Prepend
|
|
TestStart("Array_CombinedInsertPrepend");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
arr.PushInt(5);
|
|
arr.PrependInt(1);
|
|
arr.InsertInt(1, 3);
|
|
arr.InsertInt(1, 2);
|
|
arr.InsertInt(3, 4);
|
|
|
|
AssertEq(arr.Length, 5);
|
|
AssertEq(arr.GetInt(0), 1);
|
|
AssertEq(arr.GetInt(1), 2);
|
|
AssertEq(arr.GetInt(2), 3);
|
|
AssertEq(arr.GetInt(3), 4);
|
|
AssertEq(arr.GetInt(4), 5);
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
}
|
|
|
|
// ============================================================================
|
|
// 2.4 Parse & Serialize Tests
|
|
// ============================================================================
|
|
|
|
void Test_ParseAndSerialize()
|
|
{
|
|
PrintToServer("\n[Category] Parse & Serialize Tests");
|
|
|
|
// Test Parse string
|
|
TestStart("Parse_SimpleObject");
|
|
{
|
|
JSON json = JSON.Parse("{\"key\":\"value\",\"num\":42}");
|
|
AssertValidHandle(json);
|
|
AssertTrue(json.IsObject);
|
|
delete json;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Parse_SimpleArray");
|
|
{
|
|
JSON json = JSON.Parse("[1,2,3,4,5]");
|
|
AssertValidHandle(json);
|
|
AssertTrue(json.IsArray);
|
|
delete json;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Parse_NestedStructure");
|
|
{
|
|
JSON json = JSON.Parse("{\"user\":{\"name\":\"test\",\"age\":25},\"items\":[1,2,3]}");
|
|
AssertValidHandle(json);
|
|
delete json;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test mutable/immutable
|
|
TestStart("Parse_ImmutableDocument");
|
|
{
|
|
JSON json = JSON.Parse("{\"key\":\"value\"}");
|
|
AssertValidHandle(json);
|
|
AssertTrue(json.IsImmutable);
|
|
AssertFalse(json.IsMutable);
|
|
delete json;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Parse_MutableDocument");
|
|
{
|
|
JSON json = JSON.Parse("{\"key\":\"value\"}", .is_mutable_doc = true);
|
|
AssertValidHandle(json);
|
|
AssertTrue(json.IsMutable);
|
|
AssertFalse(json.IsImmutable);
|
|
delete json;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test ValCount (only works on immutable documents)
|
|
TestStart("Parse_ValCount_SimpleObject");
|
|
{
|
|
JSON json = JSON.Parse("{\"a\":1,\"b\":2,\"c\":3}");
|
|
AssertValidHandle(json);
|
|
int valCount = json.ValCount;
|
|
// Object has 7 values: 1 object + 3 keys ("a","b","c") + 3 integer values (1,2,3)
|
|
AssertEq(valCount, 7, "Simple object should have 7 values (object + keys + values)");
|
|
delete json;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Parse_ValCount_NestedStructure");
|
|
{
|
|
// {"user":{"name":"John","age":30},"items":[1,2,3]}
|
|
// Root object: 1
|
|
// "user" key + nested object: 2
|
|
// "name" key + "John" value: 2
|
|
// "age" key + 30 value: 2
|
|
// "items" key + array: 2
|
|
// Three integers in array: 3
|
|
// Total: 1 + 2 + 2 + 2 + 2 + 3 = 12
|
|
JSON json = JSON.Parse("{\"user\":{\"name\":\"John\",\"age\":30},\"items\":[1,2,3]}");
|
|
AssertValidHandle(json);
|
|
int valCount = json.ValCount;
|
|
AssertTrue(valCount > 0, "Nested structure should have multiple values");
|
|
delete json;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Parse_ValCount_Array");
|
|
{
|
|
JSON json = JSON.Parse("[1,2,3,4,5]");
|
|
AssertValidHandle(json);
|
|
int valCount = json.ValCount;
|
|
// Array itself + 5 integers = 6
|
|
AssertEq(valCount, 6, "Array with 5 elements should have 6 values");
|
|
delete json;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Parse_ValCount_MutableReturnsZero");
|
|
{
|
|
JSON json = JSON.Parse("{\"key\":\"value\"}", .is_mutable_doc = true);
|
|
AssertValidHandle(json);
|
|
int valCount = json.ValCount;
|
|
AssertEq(valCount, 0, "ValCount should return 0 for mutable documents");
|
|
delete json;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Parse_ValCount_CreatedObjectReturnsZero");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
obj.SetInt("a", 1);
|
|
obj.SetInt("b", 2);
|
|
int valCount = obj.ValCount;
|
|
AssertEq(valCount, 0, "ValCount should return 0 for created (mutable) objects");
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test ToString
|
|
TestStart("Serialize_ToString");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
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");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
obj.SetInt("a", 1);
|
|
obj.SetInt("b", 2);
|
|
|
|
char buffer[256];
|
|
int len = obj.ToString(buffer, sizeof(buffer), JSON_WRITE_PRETTY);
|
|
AssertTrue(len > 0);
|
|
Assert(StrContains(buffer, "\n") != -1, "Pretty output should contain newlines");
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test GetSerializedSize
|
|
TestStart("Serialize_GetSerializedSize");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
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");
|
|
{
|
|
JSON json = JSON.Parse("[1,2,3,]", .flag = JSON_READ_ALLOW_TRAILING_COMMAS);
|
|
AssertValidHandle(json);
|
|
delete json;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Parse_WithComments");
|
|
{
|
|
JSON json = JSON.Parse("/* comment */ {\"key\":\"value\"}", .flag = JSON_READ_ALLOW_COMMENTS);
|
|
AssertValidHandle(json);
|
|
delete json;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test file operations (create temporary test file)
|
|
TestStart("Parse_ToFile_FromFile");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
obj.SetInt("filetest", 999);
|
|
obj.SetString("name", "testfile");
|
|
|
|
// Write to file
|
|
AssertTrue(obj.ToFile("json_test_temp.json"));
|
|
|
|
// Read from file
|
|
JSONObject loaded = JSON.Parse("json_test_temp.json", true);
|
|
AssertValidHandle(loaded);
|
|
|
|
// Verify content
|
|
JSONObject 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("json_test_temp.json");
|
|
}
|
|
TestEnd();
|
|
|
|
// Test round-trip serialization
|
|
TestStart("Parse_RoundTrip");
|
|
{
|
|
char original[] = "{\"int\":42,\"float\":3.14,\"bool\":true,\"str\":\"test\",\"null\":null}";
|
|
JSON json1 = JSON.Parse(original);
|
|
|
|
char buffer[256];
|
|
json1.ToString(buffer, sizeof(buffer));
|
|
|
|
JSON json2 = JSON.Parse(buffer);
|
|
AssertTrue(JSON.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");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
obj.SetInt("a", 1);
|
|
obj.SetInt("b", 2);
|
|
obj.SetInt("c", 3);
|
|
|
|
int count = 0;
|
|
char key[32];
|
|
JSONObjIter iter = new JSONObjIter(obj);
|
|
|
|
while (iter.Next(key, sizeof(key)))
|
|
{
|
|
count++;
|
|
JSON value = iter.Value;
|
|
AssertValidHandle(value);
|
|
delete value;
|
|
}
|
|
AssertFalse(iter.HasNext);
|
|
AssertEq(count, 3);
|
|
|
|
AssertTrue(iter.Reset());
|
|
|
|
count = 0;
|
|
while (iter.Next(key, sizeof(key)))
|
|
{
|
|
count++;
|
|
JSON value = iter.Value;
|
|
AssertValidHandle(value);
|
|
delete value;
|
|
}
|
|
AssertEq(count, 3);
|
|
delete iter;
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test ForeachArray
|
|
TestStart("Iterator_ForeachArray");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
arr.PushInt(10);
|
|
arr.PushInt(20);
|
|
arr.PushInt(30);
|
|
|
|
int count = 0;
|
|
JSONArrIter iter = new JSONArrIter(arr);
|
|
|
|
while (iter.HasNext)
|
|
{
|
|
JSON value = iter.Next;
|
|
AssertValidHandle(value);
|
|
AssertEq(iter.Index, count);
|
|
delete value;
|
|
count++;
|
|
}
|
|
AssertFalse(iter.HasNext);
|
|
AssertEq(count, 3);
|
|
|
|
AssertTrue(iter.Reset());
|
|
|
|
count = 0;
|
|
while (iter.HasNext)
|
|
{
|
|
JSON value = iter.Next;
|
|
AssertValidHandle(value);
|
|
AssertEq(iter.Index, count);
|
|
delete value;
|
|
count++;
|
|
}
|
|
AssertEq(count, 3);
|
|
delete iter;
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test ForeachKey
|
|
TestStart("Iterator_ForeachKey");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
obj.SetInt("key1", 1);
|
|
obj.SetInt("key2", 2);
|
|
obj.SetInt("key3", 3);
|
|
|
|
int count = 0;
|
|
char key[32];
|
|
JSONObjIter iter = new JSONObjIter(obj);
|
|
|
|
while (iter.Next(key, sizeof(key)))
|
|
{
|
|
AssertTrue(strlen(key) > 0);
|
|
count++;
|
|
}
|
|
AssertFalse(iter.HasNext);
|
|
AssertEq(count, 3);
|
|
|
|
AssertTrue(iter.Reset());
|
|
|
|
count = 0;
|
|
while (iter.Next(key, sizeof(key)))
|
|
{
|
|
AssertTrue(strlen(key) > 0);
|
|
count++;
|
|
}
|
|
AssertEq(count, 3);
|
|
delete iter;
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test ForeachIndex
|
|
TestStart("Iterator_ForeachIndex");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
arr.PushInt(1);
|
|
arr.PushInt(2);
|
|
arr.PushInt(3);
|
|
|
|
int count = 0;
|
|
JSONArrIter iter = new JSONArrIter(arr);
|
|
|
|
while (iter.HasNext)
|
|
{
|
|
JSON value = iter.Next;
|
|
AssertEq(iter.Index, count);
|
|
delete value;
|
|
count++;
|
|
}
|
|
AssertFalse(iter.HasNext);
|
|
AssertEq(count, 3);
|
|
|
|
AssertTrue(iter.Reset());
|
|
|
|
count = 0;
|
|
while (iter.HasNext)
|
|
{
|
|
JSON value = iter.Next;
|
|
AssertEq(iter.Index, count);
|
|
delete value;
|
|
count++;
|
|
}
|
|
AssertEq(count, 3);
|
|
delete iter;
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test empty iterations
|
|
TestStart("Iterator_EmptyObject");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
char key[32];
|
|
JSONObjIter iter = new JSONObjIter(obj);
|
|
AssertFalse(iter.Next(key, sizeof(key)));
|
|
AssertTrue(iter.Reset());
|
|
AssertFalse(iter.Next(key, sizeof(key)));
|
|
delete iter;
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Iterator_EmptyArray");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
JSONArrIter iter = new JSONArrIter(arr);
|
|
AssertFalse(iter.HasNext);
|
|
AssertTrue(iter.Reset());
|
|
AssertFalse(iter.HasNext);
|
|
delete iter;
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
}
|
|
|
|
// ============================================================================
|
|
// 2.6 JSON Pointer Tests
|
|
// ============================================================================
|
|
|
|
void Test_JSONPointer()
|
|
{
|
|
PrintToServer("\n[Category] JSON Pointer Tests");
|
|
|
|
// Test PtrSet methods
|
|
TestStart("Pointer_PtrSetInt");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
AssertTrue(obj.PtrSetInt("/number", 42));
|
|
AssertEq(obj.PtrGetInt("/number"), 42);
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Pointer_PtrSetFloat");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
AssertTrue(obj.PtrSetFloat("/pi", 3.14159));
|
|
AssertFloatEq(obj.PtrGetFloat("/pi"), 3.14159);
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Pointer_PtrSetBool");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
AssertTrue(obj.PtrSetBool("/flag", true));
|
|
AssertTrue(obj.PtrGetBool("/flag"));
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Pointer_PtrSetString");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
AssertTrue(obj.PtrSetString("/name", "test"));
|
|
|
|
char buffer[64];
|
|
AssertTrue(obj.PtrGetString("/name", buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "test");
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Pointer_PtrSetInt64");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
AssertTrue(obj.PtrSetInt64("/bignum", "9223372036854775807"));
|
|
|
|
char buffer[32];
|
|
AssertTrue(obj.PtrGetInt64("/bignum", buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "9223372036854775807");
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Pointer_PtrSetNull");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
AssertTrue(obj.PtrSetNull("/nullable"));
|
|
AssertTrue(obj.PtrGetIsNull("/nullable"));
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test nested path creation
|
|
TestStart("Pointer_NestedPathCreation");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
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");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
obj.PtrSetInt("/test", 999);
|
|
|
|
JSON val = obj.PtrGet("/test");
|
|
AssertValidHandle(val);
|
|
AssertEq(val.GetInt(), 999);
|
|
|
|
delete val;
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test PtrAdd methods
|
|
TestStart("Pointer_PtrAddInt");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
obj.PtrSetInt("/arr/0", 1);
|
|
AssertTrue(obj.PtrAddInt("/arr/1", 2));
|
|
AssertEq(obj.PtrGetInt("/arr/1"), 2);
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Pointer_PtrAddString");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
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");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
obj.PtrSetInt("/remove_me", 1);
|
|
obj.PtrSetInt("/keep_me", 2);
|
|
|
|
AssertTrue(obj.PtrRemove("/remove_me"));
|
|
|
|
JSON val;
|
|
obj.PtrTryGetVal("/remove_me", val);
|
|
AssertNullHandle(val);
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test PtrGetLength
|
|
TestStart("Pointer_PtrGetLength");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
obj.PtrSetString("/text", "hello");
|
|
|
|
int len = obj.PtrGetLength("/text");
|
|
AssertEq(len, 6); // Including null terminator
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test PtrTryGet methods
|
|
TestStart("Pointer_PtrTryGetInt");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
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");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
obj.PtrSetBool("/flag", true);
|
|
|
|
bool value;
|
|
AssertTrue(obj.PtrTryGetBool("/flag", value));
|
|
AssertTrue(value);
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Pointer_PtrTryGetFloat");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
obj.PtrSetFloat("/pi", 3.14);
|
|
|
|
float value;
|
|
AssertTrue(obj.PtrTryGetFloat("/pi", value));
|
|
AssertFloatEq(value, 3.14);
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Pointer_PtrTryGetString");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
obj.PtrSetString("/name", "test");
|
|
|
|
char buffer[64];
|
|
AssertTrue(obj.PtrTryGetString("/name", buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "test");
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Pointer_PtrTryGetInt64");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
obj.PtrSetInt64("/bignum", "123456789012345");
|
|
|
|
char buffer[32];
|
|
AssertTrue(obj.PtrTryGetInt64("/bignum", buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "123456789012345");
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Pointer_PtrTryGetVal");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
obj.PtrSetInt("/test", 42);
|
|
|
|
JSON value;
|
|
AssertTrue(obj.PtrTryGetVal("/test", value));
|
|
AssertValidHandle(value);
|
|
AssertEq(value.GetInt(), 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");
|
|
{
|
|
JSONObject original = new JSONObject();
|
|
original.SetInt("num", 42);
|
|
original.SetString("str", "test");
|
|
|
|
JSONObject target = new JSONObject();
|
|
JSONObject copy = JSON.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");
|
|
{
|
|
JSONArray original = new JSONArray();
|
|
original.PushInt(1);
|
|
original.PushInt(2);
|
|
original.PushInt(3);
|
|
|
|
JSONArray target = new JSONArray();
|
|
JSONArray copy = JSON.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");
|
|
{
|
|
JSONObject obj1 = new JSONObject();
|
|
obj1.SetInt("a", 1);
|
|
obj1.SetString("b", "test");
|
|
|
|
JSONObject obj2 = new JSONObject();
|
|
obj2.SetInt("a", 1);
|
|
obj2.SetString("b", "test");
|
|
|
|
AssertTrue(JSON.Equals(obj1, obj2));
|
|
|
|
delete obj1;
|
|
delete obj2;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Advanced_Equals_False");
|
|
{
|
|
JSONObject obj1 = new JSONObject();
|
|
obj1.SetInt("a", 1);
|
|
|
|
JSONObject obj2 = new JSONObject();
|
|
obj2.SetInt("a", 2);
|
|
|
|
AssertFalse(JSON.Equals(obj1, obj2));
|
|
|
|
delete obj1;
|
|
delete obj2;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test ToMutable/ToImmutable
|
|
TestStart("Advanced_ToMutable");
|
|
{
|
|
JSON immutable = JSON.Parse("{\"key\":\"value\"}");
|
|
AssertTrue(immutable.IsImmutable);
|
|
|
|
JSON mutable = immutable.ToMutable();
|
|
AssertValidHandle(mutable);
|
|
AssertTrue(mutable.IsMutable);
|
|
|
|
delete immutable;
|
|
delete mutable;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Advanced_ToImmutable");
|
|
{
|
|
JSONObject mutable = new JSONObject();
|
|
mutable.SetInt("key", 42);
|
|
AssertTrue(mutable.IsMutable);
|
|
|
|
JSON immutable = mutable.ToImmutable();
|
|
AssertValidHandle(immutable);
|
|
AssertTrue(immutable.IsImmutable);
|
|
|
|
delete mutable;
|
|
delete immutable;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test ApplyJsonPatch (new value, immutable result)
|
|
TestStart("Advanced_ApplyJsonPatch");
|
|
{
|
|
JSONObject original = new JSONObject();
|
|
original.SetInt("score", 10);
|
|
original.SetString("name", "bot");
|
|
|
|
JSON patch = JSON.Parse("[{\"op\":\"replace\",\"path\":\"/score\",\"value\":42}]");
|
|
AssertValidHandle(patch);
|
|
|
|
JSON result = original.ApplyJsonPatch(patch);
|
|
AssertValidHandle(result);
|
|
AssertTrue(result.IsImmutable);
|
|
|
|
AssertEq(result.PtrGetInt("/score"), 42);
|
|
char buffer[32];
|
|
result.PtrGetString("/name", buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "bot");
|
|
|
|
// ensure original unchanged
|
|
AssertEq(original.GetInt("score"), 10);
|
|
|
|
delete result;
|
|
delete patch;
|
|
delete original;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test ApplyJsonPatch resultMutable = true
|
|
TestStart("Advanced_ApplyJsonPatch_MutableResult");
|
|
{
|
|
JSONObject original = new JSONObject();
|
|
original.SetInt("count", 1);
|
|
|
|
JSON patch = JSON.Parse("[{\"op\":\"add\",\"path\":\"/newField\",\"value\":\"hello\"}]");
|
|
AssertValidHandle(patch);
|
|
|
|
JSON result = original.ApplyJsonPatch(patch, true);
|
|
AssertValidHandle(result);
|
|
AssertTrue(result.IsMutable);
|
|
|
|
char buffer[16];
|
|
result.PtrGetString("/newField", buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "hello");
|
|
|
|
delete result;
|
|
delete patch;
|
|
delete original;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test JsonPatchInPlace
|
|
TestStart("Advanced_JsonPatchInPlace");
|
|
{
|
|
JSONObject target = new JSONObject();
|
|
target.SetInt("score", 5);
|
|
target.SetInt("lives", 3);
|
|
|
|
JSON patch = JSON.Parse("[{\"op\":\"remove\",\"path\":\"/lives\"},{\"op\":\"replace\",\"path\":\"/score\",\"value\":9}]");
|
|
AssertValidHandle(patch);
|
|
|
|
AssertTrue(target.JsonPatchInPlace(patch));
|
|
AssertEq(target.GetInt("score"), 9);
|
|
AssertFalse(target.HasKey("lives"));
|
|
|
|
delete patch;
|
|
delete target;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test ApplyMergePatch (immutable result)
|
|
TestStart("Advanced_ApplyMergePatch");
|
|
{
|
|
JSONObject original = new JSONObject();
|
|
original.PtrSetString("/settings/mode", "coop");
|
|
original.PtrSetInt("/settings/difficulty", 1);
|
|
|
|
JSON mergePatch = JSON.Parse("{\"settings\":{\"difficulty\":3,\"friendlyFire\":true}}");
|
|
AssertValidHandle(mergePatch);
|
|
|
|
JSON result = original.ApplyMergePatch(mergePatch);
|
|
AssertValidHandle(result);
|
|
AssertTrue(result.IsImmutable);
|
|
|
|
AssertEq(result.PtrGetInt("/settings/difficulty"), 3);
|
|
AssertTrue(result.PtrGetBool("/settings/friendlyFire"));
|
|
|
|
delete result;
|
|
delete mergePatch;
|
|
delete original;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test ApplyMergePatch resultMutable = true
|
|
TestStart("Advanced_ApplyMergePatch_MutableResult");
|
|
{
|
|
JSONObject original = new JSONObject();
|
|
original.PtrSetString("/profile/name", "player");
|
|
|
|
JSON mergePatch = JSON.Parse("{\"profile\":{\"rank\":10}}");
|
|
AssertValidHandle(mergePatch);
|
|
|
|
JSON result = original.ApplyMergePatch(mergePatch, true);
|
|
AssertValidHandle(result);
|
|
AssertTrue(result.IsMutable);
|
|
|
|
AssertEq(result.PtrGetInt("/profile/rank"), 10);
|
|
char buffer[16];
|
|
result.PtrGetString("/profile/name", buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "player");
|
|
|
|
delete result;
|
|
delete mergePatch;
|
|
delete original;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test MergePatchInPlace
|
|
TestStart("Advanced_MergePatchInPlace");
|
|
{
|
|
JSONObject target = new JSONObject();
|
|
target.PtrSetString("/config/mode", "coop");
|
|
target.PtrSetInt("/config/players", 4);
|
|
|
|
JSON mergePatch = JSON.Parse("{\"config\":{\"players\":6,\"region\":\"EU\"}}");
|
|
AssertValidHandle(mergePatch);
|
|
|
|
AssertTrue(target.MergePatchInPlace(mergePatch));
|
|
AssertEq(target.PtrGetInt("/config/players"), 6);
|
|
char buffer[16];
|
|
target.PtrGetString("/config/region", buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "EU");
|
|
|
|
delete mergePatch;
|
|
delete target;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test Pack
|
|
TestStart("Advanced_Pack_SimpleObject");
|
|
{
|
|
JSONObject json = JSON.Pack("{s:i,s:s,s:b}",
|
|
"num", 42,
|
|
"str", "test",
|
|
"bool", true
|
|
);
|
|
|
|
AssertValidHandle(json);
|
|
AssertTrue(json.IsObject);
|
|
|
|
JSONObject 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");
|
|
{
|
|
JSONArray json = JSON.Pack("[i,i,i]", 1, 2, 3);
|
|
|
|
AssertValidHandle(json);
|
|
AssertTrue(json.IsArray);
|
|
|
|
JSONArray arr = json;
|
|
AssertEq(arr.Length, 3);
|
|
AssertEq(arr.GetInt(0), 1);
|
|
AssertEq(arr.GetInt(2), 3);
|
|
|
|
delete json;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Advanced_Pack_Nested");
|
|
{
|
|
JSONObject json = JSON.Pack("{s:{s:s,s:i}}",
|
|
"user",
|
|
"name", "test",
|
|
"age", 25
|
|
);
|
|
|
|
AssertValidHandle(json);
|
|
|
|
char buffer[64];
|
|
JSONObject 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");
|
|
{
|
|
JSONArray json = JSON.Parse("[true, 42, \"hello\", 1.5, false]", .is_mutable_doc = true);
|
|
JSONArray arr = json;
|
|
|
|
AssertTrue(arr.Sort(JSON_SORT_ASC));
|
|
AssertEq(arr.Length, 5);
|
|
|
|
delete json;
|
|
}
|
|
TestEnd();
|
|
}
|
|
|
|
// ============================================================================
|
|
// 2.8 Int64 Operations Tests
|
|
// ============================================================================
|
|
|
|
void Test_Int64Operations()
|
|
{
|
|
PrintToServer("\n[Category] Int64 Operations Tests");
|
|
|
|
// Test JSON.SetInt64 - Modify value in-place
|
|
TestStart("Int64_SetInt64_Positive");
|
|
{
|
|
JSON val = JSON.CreateInt(100);
|
|
AssertTrue(val.SetInt64("123456789012345"));
|
|
|
|
char buffer[32];
|
|
AssertTrue(val.GetInt64(buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "123456789012345");
|
|
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Int64_SetInt64_Negative");
|
|
{
|
|
JSON val = JSON.CreateInt(100);
|
|
AssertTrue(val.SetInt64("-987654321098765"));
|
|
|
|
char buffer[32];
|
|
AssertTrue(val.GetInt64(buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "-987654321098765");
|
|
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Int64_SetInt64_Zero");
|
|
{
|
|
JSON val = JSON.CreateInt(999);
|
|
AssertTrue(val.SetInt64("0"));
|
|
|
|
char buffer[32];
|
|
AssertTrue(val.GetInt64(buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "0");
|
|
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test JSONArray.SetInt64 - Replace value in array
|
|
TestStart("Int64_Array_SetInt64");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
arr.PushInt(100);
|
|
arr.PushInt(200);
|
|
arr.PushInt(300);
|
|
|
|
AssertTrue(arr.SetInt64(1, "5555555555555555"));
|
|
|
|
char buffer[32];
|
|
arr.GetInt64(1, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "5555555555555555");
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Int64_Array_SetInt64_Negative");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
arr.PushInt64("1111111111111111");
|
|
|
|
AssertTrue(arr.SetInt64(0, "-2222222222222222"));
|
|
|
|
char buffer[32];
|
|
arr.GetInt64(0, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "-2222222222222222");
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test large unsigned int64 values
|
|
TestStart("Int64_Array_PushLargeUnsigned");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
AssertTrue(arr.PushInt64("18446744073709551615"));
|
|
|
|
char buffer[32];
|
|
arr.GetInt64(0, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "18446744073709551615");
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Int64_Array_IndexOfLargeValues");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
arr.PushInt64("11111111111111111");
|
|
arr.PushInt64("22222222222222222");
|
|
arr.PushInt64("33333333333333333");
|
|
|
|
AssertEq(arr.IndexOfInt64("22222222222222222"), 1);
|
|
AssertEq(arr.IndexOfInt64("99999999999999999"), -1);
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test PtrAddInt64
|
|
TestStart("Int64_Pointer_PtrAddInt64");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
obj.PtrSetInt("/numbers/0", 1);
|
|
AssertTrue(obj.PtrAddInt64("/numbers/1", "7777777777777777"));
|
|
|
|
char buffer[32];
|
|
AssertTrue(obj.PtrGetInt64("/numbers/1", buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "7777777777777777");
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Int64_Pointer_PtrAddInt64_Negative");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
obj.PtrSetInt("/data/0", 1);
|
|
AssertTrue(obj.PtrAddInt64("/data/1", "-8888888888888888"));
|
|
|
|
char buffer[32];
|
|
AssertTrue(obj.PtrGetInt64("/data/1", buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "-8888888888888888");
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test PtrAddInt64 with large unsigned value
|
|
TestStart("Int64_Pointer_PtrAddInt64_LargeUnsigned");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
obj.PtrSetInt("/bigvals/0", 1);
|
|
AssertTrue(obj.PtrAddInt64("/bigvals/1", "18446744073709551615"));
|
|
|
|
char buffer[32];
|
|
AssertTrue(obj.PtrGetInt64("/bigvals/1", buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "18446744073709551615");
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test mixed signed/unsigned values
|
|
TestStart("Int64_Mixed_SignedUnsigned_Array");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
arr.PushInt64("-9223372036854775808");
|
|
arr.PushInt64("18446744073709551615");
|
|
arr.PushInt64("0");
|
|
arr.PushInt64("9223372036854775807");
|
|
|
|
AssertEq(arr.Length, 4);
|
|
|
|
char buffer[32];
|
|
arr.GetInt64(0, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "-9223372036854775808");
|
|
|
|
arr.GetInt64(1, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "18446744073709551615");
|
|
|
|
arr.GetInt64(2, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "0");
|
|
|
|
arr.GetInt64(3, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "9223372036854775807");
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Int64_Mixed_SignedUnsigned_Object");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
obj.SetInt64("min_int64", "-9223372036854775808");
|
|
obj.SetInt64("max_int64", "9223372036854775807");
|
|
obj.SetInt64("max_uint64", "18446744073709551615");
|
|
|
|
char buffer[32];
|
|
|
|
AssertTrue(obj.GetInt64("min_int64", buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "-9223372036854775808");
|
|
|
|
AssertTrue(obj.GetInt64("max_int64", buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "9223372036854775807");
|
|
|
|
AssertTrue(obj.GetInt64("max_uint64", buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "18446744073709551615");
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test serialization with int64
|
|
TestStart("Int64_Serialization_ToString");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
obj.SetInt64("large_num", "9007199254740992");
|
|
obj.SetInt64("negative_num", "-9007199254740992");
|
|
|
|
char json[256];
|
|
int len = obj.ToString(json, sizeof(json));
|
|
AssertTrue(len > 0);
|
|
|
|
// Parse it back
|
|
JSONObject parsed = JSONObject.FromString(json);
|
|
AssertValidHandle(parsed);
|
|
|
|
char buffer[32];
|
|
AssertTrue(parsed.GetInt64("large_num", buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "9007199254740992");
|
|
|
|
AssertTrue(parsed.GetInt64("negative_num", buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "-9007199254740992");
|
|
|
|
delete obj;
|
|
delete parsed;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Int64_Serialization_Array");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
arr.PushInt64("1234567890123456");
|
|
arr.PushInt64("-9876543210987654");
|
|
arr.PushInt64("18000000000000000000");
|
|
|
|
char json[256];
|
|
int len = arr.ToString(json, sizeof(json));
|
|
AssertTrue(len > 0);
|
|
|
|
// Parse it back
|
|
JSONArray parsed = JSONArray.FromString(json);
|
|
AssertValidHandle(parsed);
|
|
AssertEq(parsed.Length, 3);
|
|
|
|
char buffer[32];
|
|
parsed.GetInt64(0, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "1234567890123456");
|
|
|
|
parsed.GetInt64(1, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "-9876543210987654");
|
|
|
|
parsed.GetInt64(2, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "18000000000000000000");
|
|
|
|
delete arr;
|
|
delete parsed;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test boundary values
|
|
TestStart("Int64_Boundary_JustAboveInt32Max");
|
|
{
|
|
JSON val = JSON.CreateInt64("2147483648");
|
|
AssertValidHandle(val);
|
|
|
|
char buffer[32];
|
|
AssertTrue(val.GetInt64(buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "2147483648");
|
|
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Int64_Boundary_JustBelowInt32Min");
|
|
{
|
|
JSON val = JSON.CreateInt64("-2147483649");
|
|
AssertValidHandle(val);
|
|
|
|
char buffer[32];
|
|
AssertTrue(val.GetInt64(buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "-2147483649");
|
|
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Int64_Boundary_UInt32Max");
|
|
{
|
|
JSON val = JSON.CreateInt64("4294967295");
|
|
AssertValidHandle(val);
|
|
|
|
char buffer[32];
|
|
AssertTrue(val.GetInt64(buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "4294967295");
|
|
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Int64_Boundary_JustAboveUInt32Max");
|
|
{
|
|
JSON val = JSON.CreateInt64("4294967296");
|
|
AssertValidHandle(val);
|
|
|
|
char buffer[32];
|
|
AssertTrue(val.GetInt64(buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "4294967296");
|
|
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test Int64 in nested structures
|
|
TestStart("Int64_Nested_ObjectInObject");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
obj.PtrSetInt64("/outer/inner/deep", "5432109876543210");
|
|
|
|
char buffer[32];
|
|
AssertTrue(obj.PtrGetInt64("/outer/inner/deep", buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "5432109876543210");
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Int64_Nested_ArrayInObject");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
obj.PtrSetInt64("/data/values/0", "1111111111111111");
|
|
obj.PtrAddInt64("/data/values/1", "2222222222222222");
|
|
obj.PtrAddInt64("/data/values/2", "3333333333333333");
|
|
|
|
char buffer[32];
|
|
AssertTrue(obj.PtrGetInt64("/data/values/0", buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "1111111111111111");
|
|
|
|
AssertTrue(obj.PtrGetInt64("/data/values/1", buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "2222222222222222");
|
|
|
|
AssertTrue(obj.PtrGetInt64("/data/values/2", buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "3333333333333333");
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test DeepCopy with int64
|
|
TestStart("Int64_DeepCopy_Object");
|
|
{
|
|
JSONObject original = new JSONObject();
|
|
original.SetInt64("bignum", "9999999999999999");
|
|
original.SetInt64("negative", "-8888888888888888");
|
|
|
|
JSONObject target = new JSONObject();
|
|
JSONObject copy = JSON.DeepCopy(target, original);
|
|
|
|
AssertValidHandle(copy);
|
|
|
|
char buffer[32];
|
|
AssertTrue(copy.GetInt64("bignum", buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "9999999999999999");
|
|
|
|
AssertTrue(copy.GetInt64("negative", buffer, sizeof(buffer)));
|
|
AssertStrEq(buffer, "-8888888888888888");
|
|
|
|
delete original;
|
|
delete target;
|
|
delete copy;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Int64_DeepCopy_Array");
|
|
{
|
|
JSONArray original = new JSONArray();
|
|
original.PushInt64("1111111111111111");
|
|
original.PushInt64("-2222222222222222");
|
|
original.PushInt64("18446744073709551615");
|
|
|
|
JSONArray target = new JSONArray();
|
|
JSONArray copy = JSON.DeepCopy(target, original);
|
|
|
|
AssertValidHandle(copy);
|
|
AssertEq(copy.Length, 3);
|
|
|
|
char buffer[32];
|
|
copy.GetInt64(0, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "1111111111111111");
|
|
|
|
copy.GetInt64(1, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "-2222222222222222");
|
|
|
|
copy.GetInt64(2, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "18446744073709551615");
|
|
|
|
delete original;
|
|
delete target;
|
|
delete copy;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test array sorting with int64 values
|
|
TestStart("Int64_Array_Sort_Ascending");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
arr.PushInt64("9999999999999999");
|
|
arr.PushInt64("1111111111111111");
|
|
arr.PushInt64("5555555555555555");
|
|
arr.PushInt64("3333333333333333");
|
|
|
|
AssertTrue(arr.Sort(JSON_SORT_ASC));
|
|
|
|
char buffer[32];
|
|
arr.GetInt64(0, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "1111111111111111");
|
|
|
|
arr.GetInt64(3, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "9999999999999999");
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Int64_Array_Sort_Descending");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
arr.PushInt64("1111111111111111");
|
|
arr.PushInt64("5555555555555555");
|
|
arr.PushInt64("3333333333333333");
|
|
arr.PushInt64("9999999999999999");
|
|
|
|
AssertTrue(arr.Sort(JSON_SORT_DESC));
|
|
|
|
char buffer[32];
|
|
arr.GetInt64(0, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "9999999999999999");
|
|
|
|
arr.GetInt64(3, buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "1111111111111111");
|
|
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test int64 with type checks
|
|
TestStart("Int64_TypeChecks");
|
|
{
|
|
JSON val = JSON.CreateInt64("9223372036854775807");
|
|
|
|
AssertTrue(val.IsNum);
|
|
AssertTrue(val.IsInt);
|
|
AssertFalse(val.IsFloat);
|
|
AssertFalse(val.IsStr);
|
|
AssertFalse(val.IsBool);
|
|
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Int64_TypeChecks_Signed");
|
|
{
|
|
JSON val = JSON.CreateInt64("-9223372036854775808");
|
|
|
|
AssertTrue(val.IsNum);
|
|
AssertTrue(val.IsInt);
|
|
AssertTrue(val.IsSint);
|
|
AssertFalse(val.IsUint);
|
|
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("Int64_TypeChecks_LargeUnsigned");
|
|
{
|
|
JSON val = JSON.CreateInt64("18446744073709551615");
|
|
|
|
AssertTrue(val.IsNum);
|
|
AssertTrue(val.IsInt);
|
|
// Large unsigned value should be detected as unsigned integer
|
|
AssertTrue(val.IsUint);
|
|
AssertFalse(val.IsSint);
|
|
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
}
|
|
|
|
// ============================================================================
|
|
// 2.9 Edge Cases & Error Handling Tests
|
|
// ============================================================================
|
|
|
|
void Test_EdgeCases()
|
|
{
|
|
PrintToServer("\n[Category] Edge Cases & Error Handling Tests");
|
|
|
|
// Test empty containers
|
|
TestStart("EdgeCase_EmptyObject");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
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");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
AssertEq(arr.Length, 0);
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test nonexistent keys/indices
|
|
TestStart("EdgeCase_NonexistentKey");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
obj.SetInt("exists", 1);
|
|
|
|
AssertTrue(obj.HasKey("exists"));
|
|
AssertFalse(obj.HasKey("notexists"));
|
|
|
|
delete obj;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("EdgeCase_ArrayOutOfBounds");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
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';
|
|
|
|
JSON val = JSON.CreateString(longStr);
|
|
AssertValidHandle(val);
|
|
|
|
char retrieved[1024];
|
|
AssertTrue(val.GetString(retrieved, sizeof(retrieved)));
|
|
AssertStrEq(retrieved, longStr);
|
|
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test deep nesting
|
|
TestStart("EdgeCase_DeepNesting");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
|
|
// 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");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
|
|
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");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
|
|
char key[32];
|
|
for (int i = 0; i < 100; i++)
|
|
{
|
|
FormatEx(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");
|
|
{
|
|
JSON val = JSON.CreateInt64("9223372036854775807");
|
|
AssertValidHandle(val);
|
|
|
|
char buffer[32];
|
|
val.GetInt64(buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "9223372036854775807");
|
|
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("EdgeCase_Int64_MinValue");
|
|
{
|
|
JSON val = JSON.CreateInt64("-9223372036854775808");
|
|
AssertValidHandle(val);
|
|
|
|
char buffer[32];
|
|
val.GetInt64(buffer, sizeof(buffer));
|
|
AssertStrEq(buffer, "-9223372036854775808");
|
|
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test special float values
|
|
TestStart("EdgeCase_Float_VerySmall");
|
|
{
|
|
JSON val = JSON.CreateFloat(0.000001);
|
|
AssertValidHandle(val);
|
|
AssertFloatEq(val.GetFloat(), 0.000001);
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
TestStart("EdgeCase_Float_VeryLarge");
|
|
{
|
|
JSON val = JSON.CreateFloat(999999.999999);
|
|
AssertValidHandle(val);
|
|
AssertFloatEq(val.GetFloat(), 999999.999999, "", 0.001);
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test special characters in strings
|
|
TestStart("EdgeCase_SpecialCharacters");
|
|
{
|
|
JSON val = JSON.CreateString("Line1\nLine2\tTabbed\"Quoted\"");
|
|
AssertValidHandle(val);
|
|
|
|
char buffer[128];
|
|
val.GetString(buffer, sizeof(buffer));
|
|
Assert(StrContains(buffer, "Line1") != -1);
|
|
|
|
delete val;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test removing from empty array
|
|
TestStart("EdgeCase_RemoveFromEmptyArray");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
AssertFalse(arr.RemoveFirst());
|
|
AssertFalse(arr.RemoveLast());
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test clearing already empty containers
|
|
TestStart("EdgeCase_ClearEmpty");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
AssertTrue(obj.Clear());
|
|
AssertEq(obj.Size, 0);
|
|
|
|
JSONArray arr = new JSONArray();
|
|
AssertTrue(arr.Clear());
|
|
AssertEq(arr.Length, 0);
|
|
|
|
delete obj;
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test IndexOf on empty array
|
|
TestStart("EdgeCase_IndexOfEmpty");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
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");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
|
|
// 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");
|
|
{
|
|
JSONObject obj = new JSONObject();
|
|
AssertTrue(obj.Sort());
|
|
|
|
JSONArray arr = new JSONArray();
|
|
AssertTrue(arr.Sort());
|
|
|
|
delete obj;
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
|
|
// Test single element operations
|
|
TestStart("EdgeCase_SingleElement");
|
|
{
|
|
JSONArray arr = new JSONArray();
|
|
arr.PushInt(42);
|
|
|
|
AssertTrue(arr.Sort());
|
|
AssertEq(arr.GetInt(0), 42);
|
|
|
|
AssertEq(arr.IndexOfInt(42), 0);
|
|
|
|
JSON first = arr.First;
|
|
JSON last = arr.Last;
|
|
AssertEq(first.GetInt(), last.GetInt());
|
|
|
|
delete first;
|
|
delete last;
|
|
delete arr;
|
|
}
|
|
TestEnd();
|
|
} |