/** @file test_cjson.cpp — cJSON 解析/生成全覆盖 */
#include "cJSON.h"
#include <cstdio>
#include <cstring>
static int P=0,F=0;
#define T(n) do{printf("  %s ... ",n);}while(0)
#define OK() do{printf("OK\n");P++;}while(0)
#define FL(m) do{printf("FAIL: %s\n",m);F++;return;}while(0)
#define CK(c,m) do{if(!(c))FL(m);}while(0)
static void t1(){T("null");cJSON*j=cJSON_Parse("null");CK(j&&j->type==cJSON_NULL,"null");cJSON_Delete(j);OK();}
static void t2(){T("true");cJSON*j=cJSON_Parse("true");CK(j&&j->type==cJSON_True,"t");cJSON_Delete(j);OK();}
static void t3(){T("false");cJSON*j=cJSON_Parse("false");CK(j&&j->type==cJSON_False,"f");cJSON_Delete(j);OK();}
static void t4(){T("int");cJSON*j=cJSON_Parse("42");CK(j&&j->valueint==42,"42");cJSON_Delete(j);OK();}
static void t5(){T("float");cJSON*j=cJSON_Parse("3.14");CK(j&&j->valuedouble>3&&j->valuedouble<3.2,"3.14");cJSON_Delete(j);OK();}
static void t6(){T("string");cJSON*j=cJSON_Parse("\"hello\"");CK(j&&!strcmp(j->valuestring,"hello"),"str");cJSON_Delete(j);OK();}
static void t7(){T("array");cJSON*j=cJSON_Parse("[1,2,3]");CK(j&&cJSON_GetArraySize(j)==3,"sz");CK(cJSON_GetArrayItem(j,0)->valueint==1,"[0]");cJSON_Delete(j);OK();}
static void t8(){T("object");cJSON*j=cJSON_Parse("{\"k\":\"v\"}");CK(j,"p");CK(!strcmp(cJSON_GetObjectItem(j,"k")->valuestring,"v"),"k");cJSON_Delete(j);OK();}
static void t9(){T("nested");cJSON*j=cJSON_Parse("{\"a\":[{\"x\":2}]}");CK(j,"p");cJSON*a=cJSON_GetObjectItem(j,"a");CK(a&&cJSON_GetArraySize(a)==1,"arr");cJSON*x=cJSON_GetObjectItem(cJSON_GetArrayItem(a,0),"x");CK(x&&x->valueint==2,"x");cJSON_Delete(j);OK();}
static void t10(){T("print unformatted");cJSON*j=cJSON_CreateObject();cJSON_AddStringToObject(j,"k","v");char*s=cJSON_PrintUnformatted(j);CK(!strcmp(s,"{\"k\":\"v\"}"),"print");cJSON_free(s);cJSON_Delete(j);OK();}
static void t11(){T("print formatted");cJSON*j=cJSON_CreateObject();cJSON_AddNumberToObject(j,"n",42);char*s=cJSON_Print(j);CK(s&&strstr(s,"n"),"p");cJSON_free(s);cJSON_Delete(j);OK();}
static void t12(){T("parse error");CK(!cJSON_Parse("{bad}"), "{bad}");CK(!cJSON_Parse("[1,}"), "[1,}");OK();}
static void t13(){
    T("roundtrip");cJSON*o=cJSON_CreateObject();cJSON_AddStringToObject(o,"s","hi");cJSON_AddNumberToObject(o,"n",42);
    cJSON*a=cJSON_CreateArray();cJSON_AddItemToArray(a,cJSON_CreateNumber(1));cJSON_AddItemToObject(o,"arr",a);
    char*ps=cJSON_Print(o);cJSON*p=cJSON_Parse(ps);CK(p,"reparse");CK(!strcmp(cJSON_GetObjectItem(p,"s")->valuestring,"hi"),"s");
    CK(cJSON_GetObjectItem(p,"n")->valueint==42,"n");CK(cJSON_GetArraySize(cJSON_GetObjectItem(p,"arr"))==1,"arr");
    cJSON_free(ps);cJSON_Delete(o);cJSON_Delete(p);OK();
}
int main(){printf("\n=== libcJSON ===\n\n");t1();t2();t3();t4();t5();t6();t7();t8();t9();t10();t11();t12();t13();printf("\n========\n  %d pass, %d fail\n========\n",P,F);return F>0?1:0;}
