185 lines
6.0 KiB
C++
185 lines
6.0 KiB
C++
#include "rjp_internal.hpp"
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#define MIN(x, y) ((x < y) ? (x) : (y))
|
|
|
|
int read_callback(char* c, int size, const char* data, int datalen, int& datapos){
|
|
if(datapos >= datalen)
|
|
return 0;
|
|
int min = MIN(size, datalen - datapos);
|
|
int i;
|
|
for(i = 0;i < min;++i){
|
|
c[i] = data[datapos++];
|
|
}
|
|
return i;
|
|
}
|
|
|
|
int handle_res(const rjp::value& res){
|
|
if(res.valid()){
|
|
fprintf(stderr, "Accepted\n");
|
|
}
|
|
return !res.valid();
|
|
}
|
|
int test_cbacks(const char* str, RJP_parse_flag flags){
|
|
int pos = 0;
|
|
rjp::value res = rjp::parse_json(flags, read_callback, str, strlen(str), pos);
|
|
return handle_res(res);
|
|
}
|
|
|
|
int test(const char* str, RJP_parse_flag flags){
|
|
rjp::value res = rjp::parse_json(str, flags);
|
|
return handle_res(res);
|
|
}
|
|
|
|
struct parse_pair{
|
|
const char* str;
|
|
RJP_parse_flag flags;
|
|
};
|
|
|
|
struct parse_pair should_pass_strings[] = {
|
|
{"{}", RJP_PARSE_NONE},
|
|
{"[]", RJP_PARSE_NONE},
|
|
{"\"s\"", RJP_PARSE_NONE},
|
|
{"\"\\n\"", RJP_PARSE_NONE},
|
|
{"\"\\\"\"", RJP_PARSE_NONE},
|
|
{"\"str\\nstr\"", RJP_PARSE_NONE},
|
|
{"\"\\uD83D\\uDE10\"", RJP_PARSE_NONE},
|
|
{"true", RJP_PARSE_NONE},
|
|
{"false", RJP_PARSE_NONE},
|
|
{"null", RJP_PARSE_NONE},
|
|
{"5", RJP_PARSE_NONE},
|
|
{"-5", RJP_PARSE_NONE},
|
|
{"+5", RJP_PARSE_NONE},
|
|
{"5.5", RJP_PARSE_NONE},
|
|
{"-5.5", RJP_PARSE_NONE},
|
|
{"+5.5", RJP_PARSE_NONE},
|
|
{"5.5e6", RJP_PARSE_NONE},
|
|
{"-5.5e6", RJP_PARSE_NONE},
|
|
{"+5.5e6", RJP_PARSE_NONE},
|
|
{"5.5e+6", RJP_PARSE_NONE},
|
|
{"-5.5e+6", RJP_PARSE_NONE},
|
|
{"+5.5e+6", RJP_PARSE_NONE},
|
|
{"5.5e-6", RJP_PARSE_NONE},
|
|
{"-5.5e-6", RJP_PARSE_NONE},
|
|
{"+5.5e-6", RJP_PARSE_NONE},
|
|
{" {}", RJP_PARSE_NONE},
|
|
{"\n{}\n", RJP_PARSE_NONE},
|
|
{" { \"key\" \t:\n\n\n5 \n\t\n } ", RJP_PARSE_NONE},
|
|
{" {\t }\n", RJP_PARSE_NONE},
|
|
{"5.5 ", RJP_PARSE_NONE},
|
|
{"{\"key\":5}", RJP_PARSE_NONE},
|
|
{"{\"key\":{}}", RJP_PARSE_NONE},
|
|
{"{\"\\uD83D\\uDE10\":5}", RJP_PARSE_NONE},
|
|
{"{\"😐\":5}", RJP_PARSE_NONE},
|
|
{"{\"key\":{\"key\":5}}", RJP_PARSE_NONE},
|
|
{"{\"key\":{\"key\":5,\"key2\":6}}", RJP_PARSE_NONE},
|
|
{"{\"key\":{\"key\":5},\"key2\":6}", RJP_PARSE_NONE},
|
|
{"[5, 6, 7, 8, 9, \"10\"]", RJP_PARSE_NONE},
|
|
{"[[5,6],[7,8],[9,\"10\"]]", RJP_PARSE_NONE},
|
|
{"{\"arr\":[5,6,6]}", RJP_PARSE_NONE},
|
|
{"[{\"arr\":[5,6,6]}]", RJP_PARSE_NONE},
|
|
{"[{\"arr\":[5,6,6]}, 6]", RJP_PARSE_NONE},
|
|
{"[5,6,6,6,6.6]", RJP_PARSE_NONE},
|
|
{"[6,7,]", RJP_PARSE_ALLOW_TRAILING_COMMA},
|
|
{"{\"1\":1,\"2\":2,}", RJP_PARSE_ALLOW_TRAILING_COMMA},
|
|
{"[6,]", RJP_PARSE_ALLOW_TRAILING_COMMA},
|
|
{"{\"1\":1,}", RJP_PARSE_ALLOW_TRAILING_COMMA},
|
|
{"//comment\n{}", RJP_PARSE_ALLOW_COMMENTS},
|
|
{"{\"key\"://comment\n5}", RJP_PARSE_ALLOW_COMMENTS},
|
|
{"{\"key\"//comment\n:5}", RJP_PARSE_ALLOW_COMMENTS},
|
|
{"{}//comment", RJP_PARSE_ALLOW_COMMENTS},
|
|
{"{//\"key\":5\n}", RJP_PARSE_ALLOW_COMMENTS},
|
|
{"5 //comment*/", RJP_PARSE_ALLOW_COMMENTS},
|
|
{"{/*\"key\":5*/\"key\":5}", RJP_PARSE_ALLOW_COMMENTS},
|
|
{"[5, /*comment*/6]", RJP_PARSE_ALLOW_COMMENTS},
|
|
};
|
|
const int should_pass_cnt = sizeof(should_pass_strings)/sizeof(should_pass_strings[0]);
|
|
struct parse_pair should_fail_strings[] = {
|
|
{"//comment\n{}", RJP_PARSE_NONE},
|
|
{"{", RJP_PARSE_NONE},
|
|
{"}", RJP_PARSE_NONE},
|
|
{"[", RJP_PARSE_NONE},
|
|
{"]", RJP_PARSE_NONE},
|
|
{"6.", RJP_PARSE_NONE},
|
|
{"6.6e", RJP_PARSE_NONE},
|
|
{"6.6e+", RJP_PARSE_NONE},
|
|
{"5e", RJP_PARSE_NONE},
|
|
{"{6}", RJP_PARSE_NONE},
|
|
{"[\"key\":5]", RJP_PARSE_NONE},
|
|
{"\"string\n\"", RJP_PARSE_NONE},
|
|
{"[3 4]", RJP_PARSE_NONE},
|
|
{"\"\\uD83D\\uDE1\"", RJP_PARSE_NONE},
|
|
{"\"\\uD83D\\uDE1Q\"", RJP_PARSE_NONE},
|
|
{"\"\\uD83\\uDE10\"", RJP_PARSE_NONE},
|
|
{"\"\\uF83D\\uDE10\"", RJP_PARSE_NONE},
|
|
{"\"\\uU83D\\uDE10\"", RJP_PARSE_NONE},
|
|
{"{\"key\":1 \"key2\":2}", RJP_PARSE_NONE},
|
|
{"{\"key\" 1}", RJP_PARSE_NONE},
|
|
{"6, 7", RJP_PARSE_NONE},
|
|
{"[,]", RJP_PARSE_NONE},
|
|
{"{, RJP_PARSE_NONE}", RJP_PARSE_NONE},
|
|
{"[1, 2],", RJP_PARSE_NONE},
|
|
{"{\"key\nkey\":5}", RJP_PARSE_NONE},
|
|
{"{\"key\":\"key\n\"}", RJP_PARSE_NONE},
|
|
{"[6,7,]", RJP_PARSE_NONE},
|
|
{"{\"1\":1,\"2\":2, RJP_PARSE_NONE}", RJP_PARSE_NONE},
|
|
{"[6,]", RJP_PARSE_NONE},
|
|
{"{\"1\":1, RJP_PARSE_NONE}", RJP_PARSE_NONE},
|
|
{"{//comment\"key\":\n5}", RJP_PARSE_NONE},
|
|
{"{/*\"key\":*/5}", RJP_PARSE_NONE},
|
|
{"[5, /*6*/, 7]", RJP_PARSE_NONE},
|
|
{"{/*comment}", RJP_PARSE_NONE},
|
|
{"{//comment}", RJP_PARSE_NONE},
|
|
{"{\"key\"://comment\n5}", RJP_PARSE_NONE},
|
|
{"{\"key\"//comment\n:5}", RJP_PARSE_NONE},
|
|
{"{}//comment", RJP_PARSE_NONE},
|
|
{"{//\"key\":5\n}", RJP_PARSE_NONE},
|
|
{"5 //comment*/", RJP_PARSE_NONE},
|
|
{"{/*\"key\":5*/\"key\":5}", RJP_PARSE_NONE},
|
|
{"[5, /*comment*/6]", RJP_PARSE_NONE},
|
|
{"{\"key\"//:5}", RJP_PARSE_ALLOW_COMMENTS},
|
|
{"{,}", RJP_PARSE_ALLOW_TRAILING_COMMA},
|
|
{"[,]", RJP_PARSE_ALLOW_TRAILING_COMMA},
|
|
};
|
|
const int should_fail_cnt = sizeof(should_fail_strings)/sizeof(should_fail_strings[0]);
|
|
const int total_tests = should_pass_cnt + should_fail_cnt;
|
|
|
|
int run_test(int (*fun)(const char*,RJP_parse_flag)){
|
|
int passed = 0;
|
|
fprintf(stderr, "Running %d tests that should pass...\n", should_pass_cnt);
|
|
for(unsigned i = 0;i < sizeof(should_pass_strings)/sizeof(should_pass_strings[0]);++i){
|
|
fprintf(stderr, "%8d) ", i+1);
|
|
if(!fun(should_pass_strings[i].str, should_pass_strings[i].flags)){
|
|
++passed;
|
|
}else{
|
|
fprintf(stderr, "%13s%s\n", "", should_pass_strings[i].str);
|
|
}
|
|
}
|
|
fprintf(stderr, "\n");
|
|
fprintf(stderr, "Running %d tests that should fail...\n", should_fail_cnt);
|
|
for(unsigned i = 0;i < sizeof(should_fail_strings)/sizeof(should_fail_strings[0]);++i){
|
|
fprintf(stderr, "%8d) ", i+1);
|
|
if(fun(should_fail_strings[i].str, should_fail_strings[i].flags)){
|
|
++passed;
|
|
}else{
|
|
fprintf(stderr, "%13s%s\n", "", should_fail_strings[i].str);
|
|
}
|
|
}
|
|
return passed;
|
|
}
|
|
int main(){
|
|
|
|
int normal_passed = run_test(test);
|
|
int cback_passed = run_test(test_cbacks);
|
|
int total_passed = normal_passed + cback_passed;
|
|
|
|
fprintf(stderr, "\nResults: %d/%d normal tests passed\n", normal_passed, total_tests);
|
|
fprintf(stderr, "Results: %d/%d callback tests passed\n", cback_passed, total_tests);
|
|
fprintf(stderr, "Results: %d/%d tests passed\n", total_passed, total_tests*2);
|
|
if(total_passed != (total_tests*2))
|
|
return 1;
|
|
return 0;
|
|
}
|