/** @file test_xml.cpp — XML C接口全覆盖 */
#include "myXml.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 const char*X="<?xml version=\"1.0\"?>\n<root><item n=\"i1\" v=\"100\"/><item n=\"i2\" v=\"3.14\"/><g id=\"1\"><e k=\"k1\"/></g></root>\n";

static void t1(){T("load+root");FILE*fp=fopen("/tmp/txml1.xml","w");fputs(X,fp);fclose(fp);myXmlDoc_t d=myXml_load_file("/tmp/txml1.xml");CK(d,"load");myXmlElem_t r=myXml_root_elem(d);CK(r,"root");myXml_free_doc(d);remove("/tmp/txml1.xml");OK();}
static void t2(){T("new+save+reload");myXmlDoc_t d=myXml_new_doc("test");CK(d,"new");myXmlElem_t r=myXml_root_elem(d);myXmlElem_t c=myXml_new_child(r,"item");myXml_set_attr(c,"name","t");myXml_set_attr_int(c,"val",42);CK(myXml_save_file(d,"/tmp/txml2.xml")==0,"save");myXmlDoc_t d2=myXml_load_file("/tmp/txml2.xml");CK(d2,"reload");myXmlElem_t it=myXml_first_child(myXml_root_elem(d2),"item");CK(it,"item");CK(!strcmp(myXml_attr_str(it,"name",""),"t"),"name");CK(myXml_attr_int(it,"val",0)==42,"val");myXml_free_doc(d);myXml_free_doc(d2);remove("/tmp/txml2.xml");OK();}
static void t3(){T("first_child + next_sibling");FILE*fp=fopen("/tmp/txml3.xml","w");fputs(X,fp);fclose(fp);myXmlDoc_t d=myXml_load_file("/tmp/txml3.xml");myXmlElem_t r=myXml_root_elem(d);myXmlElem_t i1=myXml_first_child(r,"item");CK(i1,"i1");myXmlElem_t i2=myXml_next_sibling(i1,"item");CK(i2,"i2");myXmlElem_t i3=myXml_next_sibling(i2,"item");CK(!i3,"no i3");myXml_free_doc(d);remove("/tmp/txml3.xml");OK();}
static void t4(){T("attr defaults");FILE*fp=fopen("/tmp/txml4.xml","w");fputs("<r><item/></r>",fp);fclose(fp);myXmlDoc_t d=myXml_load_file("/tmp/txml4.xml");myXmlElem_t it=myXml_first_child(myXml_root_elem(d),"item");CK(!strcmp(myXml_attr_str(it,"miss","DEF"),"DEF"),"str");CK(myXml_attr_int(it,"miss",-1)==-1,"int");CK(myXml_attr_float(it,"miss",99.9f)==99.9f,"flt");myXml_free_doc(d);remove("/tmp/txml4.xml");OK();}
static void t5(){T("set_attr_float");myXmlDoc_t d=myXml_new_doc("r");myXmlElem_t c=myXml_new_child(myXml_root_elem(d),"i");myXml_set_attr_float(c,"f",2.5f);CK(myXml_save_file(d,"/tmp/txml5.xml")==0,"s");myXmlDoc_t d2=myXml_load_file("/tmp/txml5.xml");float f=myXml_attr_float(myXml_first_child(myXml_root_elem(d2),"i"),"f",0);CK(f>2.4&&f<2.6,"flt");myXml_free_doc(d);myXml_free_doc(d2);remove("/tmp/txml5.xml");OK();}
static void t6(){T("load nonexistent");CK(!myXml_load_file("/no_xml_xyz.xml"),"null");OK();}

int main(){printf("\n=== libxml ===\n\n");t1();t2();t3();t4();t5();t6();printf("\n========\n  %d pass, %d fail\n========\n",P,F);return F>0?1:0;}
