4 enum { status_ok, status_error, status_incomplete };
6 __attribute__((noreturn))
7 static void test_error(const char* file, int line,
8 const char* data, int len,
9 String division, String message) {
10 std::cerr << file << ":" << line << " ("
11 << String(data, data + len).printable() << ")"
12 << (division ? " " : "") << division << ": "
17 static void onetest(const char* file, int line,
18 const char* data, int len,
19 String division, const char* take, int expected_take,
20 const char* unparse, int status,
21 msgpack::streaming_parser& a) {
22 if (expected_take >= 0 && take != data + expected_take)
23 test_error(file, line, data, len, division, "accept took " + String(take - data) + " chars, expected " + String(expected_take));
25 if (status == status_ok && !a.success())
26 test_error(file, line, data, len, division, "accept not done");
27 if (status == status_error && !a.error())
28 test_error(file, line, data, len, division, "accept not error");
29 if (status == status_incomplete && a.done())
30 test_error(file, line, data, len, division, "accept not incomplete");
32 if (unparse && a.result().unparse() != unparse)
33 test_error(file, line, data, len, division, "result was " + a.result().unparse() + "\n\texpected " + String(unparse));
36 static void test(const char* file, int line,
37 const char* data, int len, int expected_take,
38 const char* unparse, int status = status_ok) {
39 assert(expected_take <= len);
41 msgpack::streaming_parser a;
43 take = a.consume(data, data + len);
44 onetest(file, line, data, len, "", take, expected_take, unparse, status, a);
49 while (take != data + len) {
50 const char* x = a.consume(take, take + 1);
51 if (x != take + (take < data + expected_take))
52 test_error(file, line, data, len, "by 1s", "accept took unusual amount after " + String(x - data));
55 onetest(file, line, data, len, "by 1s", take, -1, unparse, status, a);
59 #define TEST(...) test(__FILE__, __LINE__, ## __VA_ARGS__)
61 void check_correctness() {
62 TEST("\0", 1, 1, "0");
63 TEST("\xFF ", 3, 1, "-1");
64 TEST("\xC0 ", 3, 1, "null");
65 TEST("\xC2 ", 3, 1, "false");
66 TEST("\xC3 ", 3, 1, "true");
67 TEST("\xD0\xEE", 2, 2, "-18");
68 TEST("\x81\xA7" "compact\xC3", 11, 10, "{\"compact\":true}");
69 TEST("\x81\x00\x81\xA7" "compact\xC3", 13, 12, "{\"0\":{\"compact\":true}}");
70 TEST("\x82\x00\x81\xA7" "compact\xC3\xA1" "a\xC2", 16, 15, "{\"0\":{\"compact\":true},\"a\":false}");
71 TEST("\x93\x00\x01\x02", 5, 4, "[0,1,2]");
72 TEST("\x90 ", 5, 1, "[]");
73 TEST("\xDC\x00\x00 ", 5, 3, "[]");
74 TEST("\224\002\322\000\001\242\321\262p|00356|1000000000\245?!?#*\225\001\322\000\001\242\322\242t|\242t}\332\000Rt|<user_id:5>|<time:10>|<poster_id:5> s|<user_id>|<poster_id> p|<poster_id>|<time>",
75 130, 32, "[2,107217,\"p|00356|1000000000\",\"?!?#*\"]", status_ok);
76 TEST("\xCF\x80\0\0\0\0\0\0\0", 9, 9, "9223372036854775808");
79 msgpack::streaming_parser a;
80 Json j = Json::array(0, 0, 0);
83 a.consume("\x91\xC2", 2);
84 assert(a.success() && a.result().unparse() == "[false]");
87 assert(a.success() && a.result().unparse() == "null");
89 a.consume("\x82\xA7" "compact\xC3\x00\x00", 12);
90 assert(a.success() && a.result().unparse() == "{\"compact\":true,\"0\":0}");
92 a.consume("\x82\xA7" "compact\xC3\x00\x00", 12);
93 assert(a.success() && a.result().unparse() == "{\"compact\":true,\"0\":0}");
98 msgpack::unparser<StringAccum> up(sa);
101 assert(sa.take_string() == "\xE0");
104 assert(sa.take_string() == "\xD0\xDF");
107 assert(sa.take_string() == "\x7F");
110 assert(sa.take_string() == String("\xD1\x00\x80", 3));
112 assert(sa.take_string() == String("\xD1\x80\x00", 3));
114 assert(sa.take_string() == String("\xD2\xFF\xFF\x7F\xFF", 5));
119 msgpack::unparser<StringAccum> up(sa);
121 up << msgpack::array(2) << Json((uint64_t) 1 << 63)
122 << Json((int64_t) 1 << 63);
123 String result = sa.take_string();
124 TEST(result.c_str(), result.length(), result.length(),
125 "[9223372036854775808,-9223372036854775808]");
128 std::cout << "All tests pass!\n";
131 Json __attribute__((noinline)) parse_json(const char* first, const char* last) {
132 return Json::parse(first, last);
135 Json __attribute__((noinline)) parse_json(const String& str) {
136 return Json::parse(str);
139 static const char sample_json[] = "{\"name\": \"Deborah Estrin\", \"email\": \"estrin@usc.edu\", \"affiliation\": \"University of Southern California\", \"roles\": [\"pc\"]}";
141 static const char sample_msgpack[] = "\204\244name\256Deborah Estrin\245email\256estrin@usc.edu\253affiliation\331!University of Southern California\245roles\221\242pc";
143 static int parse_json_loop_size = 10000000;
145 void parse_json_loop_1() {
147 const char* sample_json_end = sample_json + strlen(sample_json);
148 for (int i = 0; i != parse_json_loop_size; ++i) {
149 Json j = Json::parse(sample_json, sample_json_end);
150 total_size += j.size();
152 assert(total_size == 4 * parse_json_loop_size);
155 void parse_json_loop_2() {
157 const char* sample_json_end = sample_json + strlen(sample_json);
158 for (int i = 0; i != parse_json_loop_size; ++i) {
159 Json j = Json::parse(String(sample_json, sample_json_end));
160 total_size += j.size();
162 assert(total_size == 4 * parse_json_loop_size);
165 void parse_json_loop_3() {
167 String sample_json_str(sample_json);
168 for (int i = 0; i != parse_json_loop_size; ++i) {
169 Json j = Json::parse(sample_json_str);
170 total_size += j.size();
172 assert(total_size == 4 * parse_json_loop_size);
175 void parse_msgpack_loop_1() {
177 const char* sample_msgpack_end = sample_msgpack + strlen(sample_msgpack);
178 for (int i = 0; i != parse_json_loop_size; ++i) {
179 Json j = msgpack::parse(sample_msgpack, sample_msgpack_end);
180 total_size += j.size();
182 assert(total_size == 4 * parse_json_loop_size);
185 void parse_msgpack_loop_2() {
187 const char* sample_msgpack_end = sample_msgpack + strlen(sample_msgpack);
188 for (int i = 0; i != parse_json_loop_size; ++i) {
189 Json j = msgpack::parse(String(sample_msgpack, sample_msgpack_end));
190 total_size += j.size();
192 assert(total_size == 4 * parse_json_loop_size);
195 void parse_msgpack_loop_3() {
197 String sample_msgpack_str(sample_msgpack);
198 for (int i = 0; i != parse_json_loop_size; ++i) {
199 Json j = msgpack::parse(sample_msgpack_str);
200 total_size += j.size();
202 assert(total_size == 4 * parse_json_loop_size);
205 int main(int argc, char** argv) {
206 (void) argc, (void) argv;