Saving progress. Wrote tests for json
This commit is contained in:
parent
ff3edd6426
commit
11de21a90b
@ -7,6 +7,7 @@
|
||||
|
||||
/* Points to some string (BIN segment) + contains decoded json object */
|
||||
typedef struct {
|
||||
U32 version;
|
||||
Json gltf;
|
||||
/* If length is 0, BIN segment is absent */
|
||||
SpanU8 bin_segment;
|
||||
@ -26,6 +27,7 @@ int glb_file_get_segments(SpanU8 file, GLBFileSegments* ret){
|
||||
if (*(const U32*)file.data != 0x46546C67) {
|
||||
return 2;
|
||||
}
|
||||
U32 version = *(const U32*)(file.data + 4);
|
||||
/* Nobody cares about version */
|
||||
if (*(const U32*)(file.data + 8) != file.len) {
|
||||
return 3;
|
||||
@ -54,17 +56,18 @@ int glb_file_get_segments(SpanU8 file, GLBFileSegments* ret){
|
||||
}
|
||||
bin_segment = cur_segment;
|
||||
}
|
||||
cur += 8 + chunk_length;
|
||||
}
|
||||
if (json_segment.len == 0) {
|
||||
/* Illegal, no json segment */
|
||||
return 8;
|
||||
}
|
||||
// if (json_segment.len == 0) {
|
||||
// /* Illegal, no json segment */
|
||||
// return 8;
|
||||
// }
|
||||
OptionJson parsed_json = json_decode(json_segment, 15);
|
||||
if (parsed_json.variant == Option_None) {
|
||||
return 9;
|
||||
}
|
||||
/* Everything is correct */
|
||||
*ret = (GLBFileSegments){.gltf = parsed_json.some, .bin_segment = bin_segment};
|
||||
*ret = (GLBFileSegments){.version = version, .gltf = parsed_json.some, .bin_segment = bin_segment};
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -127,7 +127,7 @@ int json_decoding_parse_string(SpanU8* rem, VecU8* ret_str){
|
||||
} else if (ch == 'f') {
|
||||
VecU8_append(&res, '\f');
|
||||
} else if (ch == 'n') {
|
||||
VecU8_append(&res, '\b');
|
||||
VecU8_append(&res, '\n');
|
||||
} else if (ch == 'r') {
|
||||
VecU8_append(&res, '\r');
|
||||
} else if (ch == 't') {
|
||||
@ -173,14 +173,16 @@ OptionJson json_decoding_h_no_spaces(SpanU8* rem, U32 depth_rem){
|
||||
if (depth_rem == 0) {
|
||||
return None_Json();
|
||||
}
|
||||
float fl_value;
|
||||
int fl_code = SpanU8_read_float(rem, &fl_value);
|
||||
if (fl_code == 0)
|
||||
return Some_Json(Json_from_float(fl_value));
|
||||
S64 int_value;
|
||||
int int_code = SpanU8_read_S64(rem, &int_value);
|
||||
if (int_code == 0)
|
||||
return Some_Json(Json_from_int(int_value));
|
||||
|
||||
float fl_value;
|
||||
int fl_code = SpanU8_read_float(rem, &fl_value);
|
||||
if (fl_code == 0)
|
||||
return Some_Json(Json_from_float(fl_value));
|
||||
|
||||
bool false_code = SpanU8_parsing_try_read_prefix(rem, cstr("false"));
|
||||
if (false_code)
|
||||
return Some_Json(Json_False);
|
||||
@ -234,30 +236,31 @@ OptionJson json_decoding_h_no_spaces(SpanU8* rem, U32 depth_rem){
|
||||
RBTree_MapVecU8ToJson_drop(dict);
|
||||
return None_Json();
|
||||
}
|
||||
VecU8 key;
|
||||
int key_code = json_decoding_parse_string(rem, &key);
|
||||
if (key_code) {
|
||||
RBTree_MapVecU8ToJson_drop(dict);
|
||||
return None_Json();
|
||||
}
|
||||
SpanU8_parsing_skip_spaces(rem);
|
||||
if (!SpanU8_parsing_try_read_char(rem, ':')) {
|
||||
RBTree_MapVecU8ToJson_drop(dict);
|
||||
VecU8_drop(key);
|
||||
return None_Json();
|
||||
}
|
||||
OptionJson x = json_decoding_h(rem, depth_rem - 1);
|
||||
if (x.variant == Option_None) {
|
||||
RBTree_MapVecU8ToJson_drop(dict);
|
||||
VecU8_drop(key);
|
||||
return None_Json();
|
||||
}
|
||||
bool iret = RBTree_MapVecU8ToJson_insert(&dict, key, x.some);
|
||||
if (!iret) {
|
||||
/* Two elements of dictionary share the same key. Very illegal */
|
||||
RBTree_MapVecU8ToJson_drop(dict);
|
||||
return None_Json();
|
||||
}
|
||||
}
|
||||
SpanU8_parsing_skip_spaces(rem);
|
||||
VecU8 key;
|
||||
int key_code = json_decoding_parse_string(rem, &key);
|
||||
if (key_code) {
|
||||
RBTree_MapVecU8ToJson_drop(dict);
|
||||
return None_Json();
|
||||
}
|
||||
SpanU8_parsing_skip_spaces(rem);
|
||||
if (!SpanU8_parsing_try_read_char(rem, ':')) {
|
||||
RBTree_MapVecU8ToJson_drop(dict);
|
||||
VecU8_drop(key);
|
||||
return None_Json();
|
||||
}
|
||||
OptionJson x = json_decoding_h(rem, depth_rem - 1);
|
||||
if (x.variant == Option_None) {
|
||||
RBTree_MapVecU8ToJson_drop(dict);
|
||||
VecU8_drop(key);
|
||||
return None_Json();
|
||||
}
|
||||
bool iret = RBTree_MapVecU8ToJson_insert(&dict, key, x.some);
|
||||
if (!iret) {
|
||||
/* Two elements of dictionary share the same key. Very illegal */
|
||||
RBTree_MapVecU8ToJson_drop(dict);
|
||||
return None_Json();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -165,13 +165,17 @@ void tt15(){
|
||||
test_s64_reading_with_good_inp(cstr("0-"), 0, 1);
|
||||
}
|
||||
|
||||
void test_float_near(float right_val, float val, float eps){
|
||||
check((right_val >= +1e60 && val >= +1e60) || (right_val <= -1e60 && val <= -1e60) || fabsf(right_val - val) < eps);
|
||||
}
|
||||
|
||||
void test_float_reading_with_good_inp(SpanU8 str, float right_val, float eps, U64 lo){
|
||||
SpanU8 rem = str;
|
||||
float val;
|
||||
int c = SpanU8_read_float(&rem, &val);
|
||||
check(c == 0);
|
||||
check(rem.data == str.data + str.len - lo && rem.len == lo);
|
||||
check((right_val >= +1e60 && val >= +1e60) || (right_val <= -1e60 && val <= -1e60) || fabsf(right_val - val) < eps);
|
||||
test_float_near(right_val, val, eps);
|
||||
}
|
||||
|
||||
void tt16(){
|
||||
@ -321,18 +325,69 @@ void test_json_equal(const Json* a, const Json* b){
|
||||
if (a->variant == Json_integer) {
|
||||
check(a->integer == b->integer);
|
||||
} else if (a->variant == Json_float) {
|
||||
check(fabsf(a->float_num - b->float_num))
|
||||
test_float_near(a->float_num, b->float_num, 0.01f);
|
||||
} else if (a->variant == Json_str) {
|
||||
check(VecU8_equal_VecU8(&a->str, &b->str));
|
||||
} else if (a->variant == Json_arr) {
|
||||
const VecJson* A = &a->arr;
|
||||
const VecJson* B = &b->arr;
|
||||
check(A->len == B->len);
|
||||
for (size_t i = 0; i < A->len; i++) {
|
||||
test_json_equal(&A->buf[i], &B->buf[i]);
|
||||
}
|
||||
} else if (a->variant == Json_dict) {
|
||||
const json_dictionary_t* A = &a->dict;
|
||||
const json_dictionary_t* B = &b->dict;
|
||||
RBTreeNode_KVPVecU8ToJson* i_a = RBTree_MapVecU8ToJson_find_min(A);
|
||||
RBTreeNode_KVPVecU8ToJson* i_b = RBTree_MapVecU8ToJson_find_min(B);
|
||||
while (i_a != NULL && i_b != NULL) {
|
||||
check(VecU8_equal_VecU8(&i_a->key, &i_b->key));
|
||||
test_json_equal(&i_a->value, &i_b->value);
|
||||
i_a = RBTree_MapVecU8ToJson_find_next(A, i_a);
|
||||
i_b = RBTree_MapVecU8ToJson_find_next(B, i_b);
|
||||
}
|
||||
check(i_a == NULL);
|
||||
check(i_b == NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void test_json_decoding_ok(const char* str_lit, Json right_ans){
|
||||
|
||||
OptionJson my_ans = json_decode(SpanU8_from_cstr(str_lit), 10);
|
||||
check(my_ans.variant == Option_Some);
|
||||
test_json_equal(&my_ans.some, &right_ans);
|
||||
Json_drop(my_ans.some);
|
||||
Json_drop(right_ans);
|
||||
}
|
||||
|
||||
void tt27(){
|
||||
test_json_decoding_ok("true", Json_True);
|
||||
test_json_decoding_ok("\n\n1233", Json_from_int(1233));
|
||||
test_json_decoding_ok("false\r \t ", Json_False);
|
||||
test_json_decoding_ok(" none", Json_None);
|
||||
test_json_decoding_ok("999999999999999999999999999999999999999", Json_from_float(1e100));
|
||||
test_json_decoding_ok(" [ \t\r\r\n ]", Json_from_VecJson(VecJson_new()));
|
||||
test_json_decoding_ok(" { } ", Json_from_MapVecU8ToJson(RBTree_MapVecU8ToJson_new()));
|
||||
test_json_decoding_ok(" \"7\" ", Json_from_SpanU8(cstr("7")));
|
||||
test_json_decoding_ok(" \"XXX\" ", Json_from_SpanU8(cstr("XXX")));
|
||||
{
|
||||
VecJson x = VecJson_new();
|
||||
VecJson_append(&x, Json_from_int(12));
|
||||
VecJson_append(&x, Json_from_int(23));
|
||||
VecJson_append(&x, Json_from_int(34));
|
||||
test_json_decoding_ok("[ 12,23 , \n 34 ]", Json_from_VecJson(x));
|
||||
}
|
||||
{
|
||||
json_dictionary_t x = RBTree_MapVecU8ToJson_new();
|
||||
RBTree_MapVecU8ToJson_insert(&x, vcstr("XXX"), Json_from_int(9990));
|
||||
test_json_decoding_ok(" { \"XXX\" : 9990 }", Json_from_MapVecU8ToJson(x));
|
||||
}
|
||||
}
|
||||
|
||||
void tt28(){
|
||||
json_dictionary_t x = RBTree_MapVecU8ToJson_new();
|
||||
RBTree_MapVecU8ToJson_insert(&x, vcstr("9\u0449AB-"), Json_from_bool(false));
|
||||
RBTree_MapVecU8ToJson_insert(&x, vcstr("9\u0449A"), Json_from_int(999));
|
||||
test_json_decoding_ok(" { \"9\u0449A\" : 999 , \"9\\u0449AB-\" : false }", Json_from_MapVecU8ToJson(x));
|
||||
}
|
||||
|
||||
void test_json_decoding_with_ill_formed_inp(const char* str_lit){
|
||||
@ -340,11 +395,14 @@ void test_json_decoding_with_ill_formed_inp(const char* str_lit){
|
||||
check(res.variant == Option_None);
|
||||
}
|
||||
|
||||
void tt28(){
|
||||
void tt29(){
|
||||
test_json_decoding_with_ill_formed_inp("{");
|
||||
test_json_decoding_with_ill_formed_inp("{\"A\": 12, \"A\": 12}");
|
||||
test_json_decoding_with_ill_formed_inp("[");
|
||||
test_json_decoding_with_ill_formed_inp("123e2222222222222222222222222");
|
||||
test_json_decoding_with_ill_formed_inp("999999999999999999999999999999999999999");
|
||||
test_json_decoding_with_ill_formed_inp("\"666");
|
||||
test_json_decoding_with_ill_formed_inp("{{{}}");
|
||||
test_json_decoding_with_ill_formed_inp("{\"a\": 2 \"b\": 12}");
|
||||
test_json_decoding_with_ill_formed_inp("f");
|
||||
test_json_decoding_with_ill_formed_inp("tru");
|
||||
test_json_decoding_with_ill_formed_inp("none3");
|
||||
@ -356,6 +414,7 @@ void tt28(){
|
||||
int main(){
|
||||
tt1(); tt2(); tt3(); tt4(); tt5(); tt6(); tt7(); tt8(); tt9(); tt10(); tt11(); tt12(); tt13(); tt14(); tt15();
|
||||
tt16(); tt17(); tt18(); tt19();
|
||||
tt20(); tt21(); tt22(); tt23(); tt24(); tt25(); tt26();
|
||||
tt20(); tt21(); tt22(); tt23(); tt24(); tt25(); tt26(); tt27();
|
||||
tt28(); tt29();
|
||||
return 0;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user