sourcemod/plugins/testsuite/yyjson_test.sp
2025-10-18 20:58:40 +08:00

566 lines
14 KiB
SourcePawn
Executable File

#include <sourcemod>
#include <yyjson>
public Plugin myinfo =
{
name = "YYJSON Test Suite",
author = "ProjectSky",
description = "Test suite for YYJSON extension",
version = "1.0.2",
url = "https://github.com/ProjectSky/sm-ext-yyjson"
};
public void OnPluginStart()
{
RegServerCmd("sm_yyjson_test", Command_RunTests, "Run YYJSON test suite");
}
Action Command_RunTests(int args)
{
// Run all test cases
TestBasicOperations();
TestArrayOperations();
TestObjectOperations();
TestSortOperations();
TestSearchOperations();
TestPointerOperations();
TestIterationOperations();
TestTypeOperations();
TestFileOperations();
TestImmutabilityOperations();
TestPackOperations();
TestFromStringsOperations();
PrintToServer("[YYJSON] All tests completed!");
return Plugin_Handled;
}
void TestBasicOperations()
{
PrintToServer("[YYJSON] Testing basic operations...");
// Test creation and parsing
YYJSONObject obj = new YYJSONObject();
obj.SetInt("int", 42);
obj.SetFloat("float", 3.14);
obj.SetBool("bool", true);
obj.SetString("string", "hello");
obj.SetNull("null");
// Test serialization
char buffer[1024];
obj.ToString(buffer, sizeof(buffer));
PrintToServer("Serialized: %s", buffer);
// Test type checking
PrintToServer("Type of 'int': %d", obj.Type);
PrintToServer("SubType of 'int': %d", obj.SubType);
PrintToServer("Is object: %d", obj.IsObject);
// Test value existence
PrintToServer("Has 'int': %d", obj.HasKey("int"));
PrintToServer("Has 'nonexistent': %d", obj.HasKey("nonexistent"));
// Test value retrieval
PrintToServer("Int value: %d", obj.GetInt("int"));
PrintToServer("Float value: %f", obj.GetFloat("float"));
PrintToServer("Bool value: %d", obj.GetBool("bool"));
char strBuffer[64];
obj.GetString("string", strBuffer, sizeof(strBuffer));
PrintToServer("String value: %s", strBuffer);
PrintToServer("Is 'null' null: %d", obj.IsNull("null"));
// Test parsing
YYJSONObject parsed = YYJSON.Parse(buffer);
// Test equality
PrintToServer("Objects are equal: %d", YYJSON.Equals(obj, parsed));
// Test deep copy
YYJSONObject copy = new YYJSONObject();
YYJSONObject copyResult = YYJSON.DeepCopy(copy, obj);
PrintToServer("Copy equals original: %d", YYJSON.Equals(copyResult, obj));
// Test size and read size
PrintToServer("Object size: %d", obj.Size);
PrintToServer("Read size: %d", obj.ReadSize);
// Test type description
char typeDesc[64];
YYJSON.GetTypeDesc(obj, typeDesc, sizeof(typeDesc));
PrintToServer("Type description: %s", typeDesc);
delete obj;
delete parsed;
delete copy;
delete copyResult;
}
void TestArrayOperations()
{
PrintToServer("[YYJSON] Testing array operations...");
YYJSONArray arr = new YYJSONArray();
// Test push operations
arr.PushInt(1);
arr.PushFloat(2.5);
arr.PushBool(true);
arr.PushString("test");
arr.PushNull();
PrintToServer("Array after push operations:");
PrintJson(arr);
// Test get operations
PrintToServer("First element: %d", arr.GetInt(0));
PrintToServer("Second element: %f", arr.GetFloat(1));
PrintToServer("Third element: %d", arr.GetBool(2));
char strBuffer[64];
arr.GetString(3, strBuffer, sizeof(strBuffer));
PrintToServer("Fourth element: %s", strBuffer);
PrintToServer("Fifth element is null: %d", arr.IsNull(4));
YYJSON first = arr.First;
YYJSON last = arr.Last;
// Test array properties
PrintToServer("Array length: %d", arr.Length);
PrintToServer("First value: %x", first);
PrintToServer("Last value: %x", last);
// Test set operations
arr.SetInt(0, 100);
arr.SetFloat(1, 3.14);
arr.SetBool(2, false);
arr.SetString(3, "modified");
arr.SetNull(4);
PrintToServer("Array after set operations:");
PrintJson(arr);
// Test remove operations
arr.RemoveFirst();
PrintToServer("After RemoveFirst:");
PrintJson(arr);
arr.RemoveLast();
PrintToServer("After RemoveLast:");
PrintJson(arr);
arr.Remove(1);
PrintToServer("After Remove(1):");
PrintJson(arr);
arr.RemoveRange(0, 1);
PrintToServer("After RemoveRange(0, 1):");
PrintJson(arr);
arr.Clear();
PrintToServer("Array length after Clear: %d", arr.Length);
delete arr;
delete first;
delete last;
}
void TestObjectOperations()
{
PrintToServer("[YYJSON] Testing object operations...");
YYJSONObject obj = new YYJSONObject();
// Test set operations
obj.SetInt("int", 123);
obj.SetFloat("float", 3.14);
obj.SetBool("bool", true);
obj.SetString("string", "test");
obj.SetNull("null");
PrintToServer("Object after set operations:");
PrintJson(obj);
// Test get operations
PrintToServer("Int value: %d", obj.GetInt("int"));
PrintToServer("Float value: %f", obj.GetFloat("float"));
PrintToServer("Bool value: %d", obj.GetBool("bool"));
char strBuffer[64];
obj.GetString("string", strBuffer, sizeof(strBuffer));
PrintToServer("String value: %s", strBuffer);
PrintToServer("Is null value null: %d", obj.IsNull("null"));
// Test key operations
char key[64];
for (int i = 0; i < obj.Size; i++)
{
obj.GetKey(i, key, sizeof(key));
PrintToServer("Key at %d: %s", i, key);
YYJSON value = obj.GetValueAt(i);
PrintToServer("Value type at %d: %d", i, value.Type);
delete value;
}
// Test rename key
obj.RenameKey("int", "number");
PrintToServer("After renaming 'int' to 'number':");
PrintJson(obj);
// Test remove operations
obj.Remove("number");
PrintToServer("After removing 'number':");
PrintJson(obj);
obj.Clear();
PrintToServer("Object size after Clear: %d", obj.Size);
delete obj;
}
void TestSortOperations()
{
PrintToServer("[YYJSON] Testing sort operations...");
// Test array sorting
YYJSONArray arr = YYJSON.Parse("[3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]", .is_mutable_doc = true);
PrintToServer("Original array:");
PrintJson(arr);
arr.Sort();
PrintToServer("After ascending sort:");
PrintJson(arr);
arr.Sort(YYJSON_SORT_DESC);
PrintToServer("After descending sort:");
PrintJson(arr);
arr.Sort(YYJSON_SORT_RANDOM);
PrintToServer("After random sort:");
PrintJson(arr);
// Test mixed type array sorting
YYJSONArray mixed = YYJSON.Parse("[true, 42, \"hello\", 1.23, false, \"world\"]", .is_mutable_doc = true);
PrintToServer("Original mixed array:");
PrintJson(mixed);
mixed.Sort();
PrintToServer("After sorting mixed array:");
PrintJson(mixed);
// Test object sorting
YYJSONObject obj = YYJSON.Parse("{\"zebra\": 1, \"alpha\": 2, \"beta\": 3}", .is_mutable_doc = true);
PrintToServer("Original object:");
PrintJson(obj);
obj.Sort();
PrintToServer("After ascending sort:");
PrintJson(obj);
obj.Sort(YYJSON_SORT_DESC);
PrintToServer("After descending sort:");
PrintJson(obj);
obj.Sort(YYJSON_SORT_RANDOM);
PrintToServer("After random sort:");
PrintJson(obj);
delete arr;
delete mixed;
delete obj;
}
void TestSearchOperations()
{
PrintToServer("[YYJSON] Testing search operations...");
YYJSONArray arr = YYJSON.Parse("[42, true, \"hello\", 3.14, \"world\", false, 42]");
PrintToServer("Test array:");
PrintJson(arr);
// Test all search methods
PrintToServer("Search results:");
PrintToServer("IndexOfInt(42): %d", arr.IndexOfInt(42));
PrintToServer("IndexOfInt(999): %d", arr.IndexOfInt(999));
PrintToServer("IndexOfBool(true): %d", arr.IndexOfBool(true));
PrintToServer("IndexOfBool(false): %d", arr.IndexOfBool(false));
PrintToServer("IndexOfString(\"hello\"): %d", arr.IndexOfString("hello"));
PrintToServer("IndexOfString(\"missing\"): %d", arr.IndexOfString("missing"));
PrintToServer("IndexOfFloat(3.14): %d", arr.IndexOfFloat(3.14));
PrintToServer("IndexOfFloat(2.718): %d", arr.IndexOfFloat(2.718));
delete arr;
}
void TestPointerOperations()
{
PrintToServer("[YYJSON] Testing JSON pointer operations...");
YYJSONObject obj = new YYJSONObject();
// Test setting nested values
obj.PtrSetInt("/a/b/c", 1);
obj.PtrSetString("/a/b/name", "test");
obj.PtrSetBool("/a/flag", true);
obj.PtrSetFloat("/a/b/pi", 3.14);
obj.PtrSetNull("/a/b/empty");
PrintToServer("After setting values:");
PrintJson(obj);
// Test getting values
PrintToServer("Pointer get operations:");
PrintToServer("/a/b/c: %d", obj.PtrGetInt("/a/b/c"));
char strBuffer[64];
obj.PtrGetString("/a/b/name", strBuffer, sizeof(strBuffer));
PrintToServer("/a/b/name: %s", strBuffer);
PrintToServer("/a/flag: %d", obj.PtrGetBool("/a/flag"));
PrintToServer("/a/b/pi: %f", obj.PtrGetFloat("/a/b/pi"));
PrintToServer("/a/b/empty is null: %d", obj.PtrGetIsNull("/a/b/empty"));
// Test adding values
obj.PtrAddInt("/a/b/numbers/0", 1);
obj.PtrAddInt("/a/b/numbers/1", 2);
obj.PtrAddString("/a/b/strings", "append");
PrintToServer("After adding values:");
PrintJson(obj);
// Test length
PrintToServer("Length of /a/b/numbers: %d", obj.PtrGetLength("/a/b/numbers"));
// Test removing values
obj.PtrRemove("/a/b/c");
PrintToServer("After removing /a/b/c:");
PrintJson(obj);
delete obj;
}
void TestIterationOperations()
{
PrintToServer("[YYJSON] Testing iteration operations...");
// Test object iteration
YYJSONObject obj = YYJSON.Parse("{\"a\": 1, \"b\": 2, \"c\": 3}");
char key[64];
YYJSON value;
while (obj.ForeachObject(key, sizeof(key), value))
{
PrintToServer("Key: %s", key);
delete value;
}
// Test array iteration
YYJSONArray arr = YYJSON.Parse("[1, 2, 3, 4, 5]");
int index;
while (arr.ForeachArray(index, value))
{
PrintToServer("Index: %d", index);
delete value;
}
delete obj;
delete arr;
}
void TestTypeOperations()
{
PrintToServer("[YYJSON] Testing type operations...");
// Test value creation
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();
// Test value types
PrintToServer("Value types:");
PrintToServer("Bool type: %d", boolVal.Type);
PrintToServer("Int type: %d", intVal.Type);
PrintToServer("Float type: %d", floatVal.Type);
PrintToServer("String type: %d", strVal.Type);
PrintToServer("Null type: %d", nullVal.Type);
// Test value retrieval
PrintToServer("Value contents:");
PrintToServer("Bool value: %d", YYJSON.GetBool(boolVal));
PrintToServer("Int value: %d", YYJSON.GetInt(intVal));
PrintToServer("Float value: %f", YYJSON.GetFloat(floatVal));
char strBuffer[64];
YYJSON.GetString(strVal, strBuffer, sizeof(strBuffer));
PrintToServer("String value: %s", strBuffer);
delete boolVal;
delete intVal;
delete floatVal;
delete strVal;
delete nullVal;
}
void TestFileOperations()
{
PrintToServer("[YYJSON] Testing file operations...");
// Create test data
YYJSONObject obj = new YYJSONObject();
obj.SetInt("id", 1);
obj.SetString("name", "test");
obj.SetBool("active", true);
// Test file writing
PrintToServer("Writing to file...");
obj.ToFile("test.json", YYJSON_WRITE_PRETTY_TWO_SPACES);
// Test file reading
PrintToServer("Reading from file...");
YYJSONObject loaded = YYJSON.Parse("test.json", true);
PrintToServer("File content:");
PrintJson(loaded);
delete loaded;
delete obj;
}
void TestImmutabilityOperations()
{
PrintToServer("[YYJSON] Testing immutability operations...");
// Test immutable document creation
YYJSONObject immutable = YYJSON.Parse("{\"key\": 123, \"str\": \"test\"}");
PrintToServer("Created immutable document:");
PrintJson(immutable);
// Test property checks
PrintToServer("Is mutable: %d", immutable.IsMutable);
PrintToServer("Is immutable: %d", immutable.IsImmutable);
// Test read operations (should succeed)
PrintToServer("Read operations on immutable document:");
PrintToServer("Int value: %d", immutable.GetInt("key"));
char buffer[64];
immutable.GetString("str", buffer, sizeof(buffer));
PrintToServer("String value: %s", buffer);
// Test conversion to mutable
YYJSONObject mutable = immutable.ToMutable();
PrintToServer("\nConverted to mutable document:");
PrintToServer("Is mutable: %d", mutable.IsMutable);
PrintToServer("Is immutable: %d", mutable.IsImmutable);
// Now modifications should work
mutable.SetInt("key", 456)
PrintToServer("Successfully modified mutable document:");
PrintJson(mutable);
// Test conversion back to immutable
YYJSONObject backToImmutable = mutable.ToImmutable();
PrintToServer("\nConverted back to immutable:");
PrintToServer("Is mutable: %d", backToImmutable.IsMutable);
PrintToServer("Is immutable: %d", backToImmutable.IsImmutable);
delete backToImmutable;
delete mutable;
delete immutable;
// Test file operations with immutability
PrintToServer("\nTesting file operations with immutability...");
// Create and write a mutable document
YYJSONObject writeObj = new YYJSONObject();
writeObj.SetInt("test", 123);
writeObj.ToFile("test_immutable.json");
delete writeObj;
// Read as immutable
YYJSONObject readImmutable = YYJSON.Parse("test_immutable.json", true);
PrintToServer("Read as immutable document:");
PrintJson(readImmutable);
PrintToServer("Is mutable: %d", readImmutable.IsMutable);
PrintToServer("Is immutable: %d", readImmutable.IsImmutable);
delete readImmutable;
}
void TestPackOperations()
{
PrintToServer("[YYJSON] Testing pack operations...");
// Test basic pack operation with different types
YYJSON packed = YYJSON.Pack("{s:s,s:i,s:f,s:b,s:n}",
"name", "test",
"age", 25,
"height", 1.75,
"active", true,
"extra"
);
PrintToServer("Packed JSON:");
PrintJson(packed);
// Test nested object packing
YYJSON nested = YYJSON.Pack("{s:{s:s,s:[i,i,i]}}",
"user",
"name", "test",
"scores", 85, 90, 95
);
PrintToServer("Nested packed JSON:");
PrintJson(nested);
// Test array packing with mixed types
YYJSON array = YYJSON.Pack("[s,i,f,b,n]",
"test", 42, 3.14, true
);
PrintToServer("Array packed JSON:");
PrintJson(array);
delete packed;
delete nested;
delete array;
}
void TestFromStringsOperations()
{
PrintToServer("[YYJSON] Testing FromStrings operations...");
// Test object creation from key-value string arrays
char pairs[][] = {"name", "test", "type", "demo", "version", "1.0.0"};
YYJSONObject obj = YYJSONObject.FromStrings(pairs, sizeof(pairs));
PrintToServer("Object from strings:");
PrintJson(obj);
// Test array creation from string array
char items[][] = {"apple", "banana", "orange", "grape"};
YYJSONArray arr = YYJSONArray.FromStrings(items, sizeof(items));
PrintToServer("Array from strings:");
PrintJson(arr);
delete obj;
delete arr;
}
// Helper function to print json contents
void PrintJson(YYJSON data)
{
int len = data.GetSerializedSize(YYJSON_WRITE_PRETTY_TWO_SPACES);
char[] buffer = new char[len];
data.ToString(buffer, len, YYJSON_WRITE_PRETTY_TWO_SPACES);
PrintToServer("%s", buffer);
}