annotate ext/json11/test.cpp @ 150:bf8e3e7dd7de

Move some things around, and add overall test script
author Chris Cannam <cannam@all-day-breakfast.com>
date Fri, 20 Jan 2017 17:45:54 +0000
parents
children d607ae858682
rev   line source
cannam@150 1 #include <string>
cannam@150 2 #include <cstdio>
cannam@150 3 #include <cstring>
cannam@150 4 #include <iostream>
cannam@150 5 #include <sstream>
cannam@150 6 #include "json11.hpp"
cannam@150 7 #include <cassert>
cannam@150 8 #include <list>
cannam@150 9 #include <set>
cannam@150 10 #include <unordered_map>
cannam@150 11
cannam@150 12 using namespace json11;
cannam@150 13 using std::string;
cannam@150 14
cannam@150 15 // Check that Json has the properties we want.
cannam@150 16 #include <type_traits>
cannam@150 17 #define CHECK_TRAIT(x) static_assert(std::x::value, #x)
cannam@150 18 CHECK_TRAIT(is_nothrow_constructible<Json>);
cannam@150 19 CHECK_TRAIT(is_nothrow_default_constructible<Json>);
cannam@150 20 CHECK_TRAIT(is_copy_constructible<Json>);
cannam@150 21 CHECK_TRAIT(is_nothrow_move_constructible<Json>);
cannam@150 22 CHECK_TRAIT(is_copy_assignable<Json>);
cannam@150 23 CHECK_TRAIT(is_nothrow_move_assignable<Json>);
cannam@150 24 CHECK_TRAIT(is_nothrow_destructible<Json>);
cannam@150 25
cannam@150 26 void parse_from_stdin() {
cannam@150 27 string buf;
cannam@150 28 string line;
cannam@150 29 while (std::getline(std::cin, line)) {
cannam@150 30 buf += line + "\n";
cannam@150 31 }
cannam@150 32
cannam@150 33 string err;
cannam@150 34 auto json = Json::parse(buf, err);
cannam@150 35 if (!err.empty()) {
cannam@150 36 printf("Failed: %s\n", err.c_str());
cannam@150 37 } else {
cannam@150 38 printf("Result: %s\n", json.dump().c_str());
cannam@150 39 }
cannam@150 40 }
cannam@150 41
cannam@150 42 int main(int argc, char **argv) {
cannam@150 43 if (argc == 2 && argv[1] == string("--stdin")) {
cannam@150 44 parse_from_stdin();
cannam@150 45 return 0;
cannam@150 46 }
cannam@150 47
cannam@150 48 const string simple_test =
cannam@150 49 R"({"k1":"v1", "k2":42, "k3":["a",123,true,false,null]})";
cannam@150 50
cannam@150 51 string err;
cannam@150 52 auto json = Json::parse(simple_test, err);
cannam@150 53
cannam@150 54 std::cout << "k1: " << json["k1"].string_value() << "\n";
cannam@150 55 std::cout << "k3: " << json["k3"].dump() << "\n";
cannam@150 56
cannam@150 57 for (auto &k : json["k3"].array_items()) {
cannam@150 58 std::cout << " - " << k.dump() << "\n";
cannam@150 59 }
cannam@150 60
cannam@150 61 const string comment_test = R"({
cannam@150 62 // comment /* with nested comment */
cannam@150 63 "a": 1,
cannam@150 64 // comment
cannam@150 65 // continued
cannam@150 66 "b": "text",
cannam@150 67 /* multi
cannam@150 68 line
cannam@150 69 comment */
cannam@150 70 // and single-line comment
cannam@150 71 "c": [1, 2, 3]
cannam@150 72 })";
cannam@150 73
cannam@150 74 string err_comment;
cannam@150 75 auto json_comment = Json::parse(
cannam@150 76 comment_test, err_comment, JsonParse::COMMENTS);
cannam@150 77 if (!err_comment.empty()) {
cannam@150 78 printf("Failed: %s\n", err_comment.c_str());
cannam@150 79 } else {
cannam@150 80 printf("Result: %s\n", json_comment.dump().c_str());
cannam@150 81 }
cannam@150 82
cannam@150 83 string failing_comment_test = R"({
cannam@150 84 /* bad comment
cannam@150 85 "a": 1,
cannam@150 86 })";
cannam@150 87
cannam@150 88 string err_failing_comment;
cannam@150 89 auto json_failing_comment = Json::parse(
cannam@150 90 failing_comment_test, err_failing_comment, JsonParse::COMMENTS);
cannam@150 91 if (!err_failing_comment.empty()) {
cannam@150 92 printf("Failed: %s\n", err_failing_comment.c_str());
cannam@150 93 } else {
cannam@150 94 printf("Result: %s\n", json_failing_comment.dump().c_str());
cannam@150 95 }
cannam@150 96
cannam@150 97 failing_comment_test = R"({
cannam@150 98 / / bad comment })";
cannam@150 99
cannam@150 100 json_failing_comment = Json::parse(
cannam@150 101 failing_comment_test, err_failing_comment, JsonParse::COMMENTS);
cannam@150 102 if (!err_failing_comment.empty()) {
cannam@150 103 printf("Failed: %s\n", err_failing_comment.c_str());
cannam@150 104 } else {
cannam@150 105 printf("Result: %s\n", json_failing_comment.dump().c_str());
cannam@150 106 }
cannam@150 107
cannam@150 108 failing_comment_test = R"({// bad comment })";
cannam@150 109
cannam@150 110 json_failing_comment = Json::parse(
cannam@150 111 failing_comment_test, err_failing_comment, JsonParse::COMMENTS);
cannam@150 112 if (!err_failing_comment.empty()) {
cannam@150 113 printf("Failed: %s\n", err_failing_comment.c_str());
cannam@150 114 } else {
cannam@150 115 printf("Result: %s\n", json_failing_comment.dump().c_str());
cannam@150 116 }
cannam@150 117
cannam@150 118 failing_comment_test = R"({
cannam@150 119 "a": 1
cannam@150 120 }/)";
cannam@150 121
cannam@150 122 json_failing_comment = Json::parse(
cannam@150 123 failing_comment_test, err_failing_comment, JsonParse::COMMENTS);
cannam@150 124 if (!err_failing_comment.empty()) {
cannam@150 125 printf("Failed: %s\n", err_failing_comment.c_str());
cannam@150 126 } else {
cannam@150 127 printf("Result: %s\n", json_failing_comment.dump().c_str());
cannam@150 128 }
cannam@150 129
cannam@150 130 failing_comment_test = R"({/* bad
cannam@150 131 comment *})";
cannam@150 132
cannam@150 133 json_failing_comment = Json::parse(
cannam@150 134 failing_comment_test, err_failing_comment, JsonParse::COMMENTS);
cannam@150 135 if (!err_failing_comment.empty()) {
cannam@150 136 printf("Failed: %s\n", err_failing_comment.c_str());
cannam@150 137 } else {
cannam@150 138 printf("Result: %s\n", json_failing_comment.dump().c_str());
cannam@150 139 }
cannam@150 140
cannam@150 141 std::list<int> l1 { 1, 2, 3 };
cannam@150 142 std::vector<int> l2 { 1, 2, 3 };
cannam@150 143 std::set<int> l3 { 1, 2, 3 };
cannam@150 144 assert(Json(l1) == Json(l2));
cannam@150 145 assert(Json(l2) == Json(l3));
cannam@150 146
cannam@150 147 std::map<string, string> m1 { { "k1", "v1" }, { "k2", "v2" } };
cannam@150 148 std::unordered_map<string, string> m2 { { "k1", "v1" }, { "k2", "v2" } };
cannam@150 149 assert(Json(m1) == Json(m2));
cannam@150 150
cannam@150 151 // Json literals
cannam@150 152 Json obj = Json::object({
cannam@150 153 { "k1", "v1" },
cannam@150 154 { "k2", 42.0 },
cannam@150 155 { "k3", Json::array({ "a", 123.0, true, false, nullptr }) },
cannam@150 156 });
cannam@150 157
cannam@150 158 std::cout << "obj: " << obj.dump() << "\n";
cannam@150 159
cannam@150 160 assert(Json("a").number_value() == 0);
cannam@150 161 assert(Json("a").string_value() == "a");
cannam@150 162 assert(Json().number_value() == 0);
cannam@150 163
cannam@150 164 assert(obj == json);
cannam@150 165 assert(Json(42) == Json(42.0));
cannam@150 166 assert(Json(42) != Json(42.1));
cannam@150 167
cannam@150 168 const string unicode_escape_test =
cannam@150 169 R"([ "blah\ud83d\udca9blah\ud83dblah\udca9blah\u0000blah\u1234" ])";
cannam@150 170
cannam@150 171 const char utf8[] = "blah" "\xf0\x9f\x92\xa9" "blah" "\xed\xa0\xbd" "blah"
cannam@150 172 "\xed\xb2\xa9" "blah" "\0" "blah" "\xe1\x88\xb4";
cannam@150 173
cannam@150 174 Json uni = Json::parse(unicode_escape_test, err);
cannam@150 175 assert(uni[0].string_value().size() == (sizeof utf8) - 1);
cannam@150 176 assert(std::memcmp(uni[0].string_value().data(), utf8, sizeof utf8) == 0);
cannam@150 177
cannam@150 178 // Demonstrates the behavior change in Xcode 7 / Clang 3.7 described
cannam@150 179 // here: https://llvm.org/bugs/show_bug.cgi?id=23812
cannam@150 180 Json nested_array = Json::array { Json::array { 1, 2, 3 } };
cannam@150 181 assert(nested_array.is_array());
cannam@150 182 assert(nested_array.array_items().size() == 1);
cannam@150 183 assert(nested_array.array_items()[0].is_array());
cannam@150 184 assert(nested_array.array_items()[0].array_items().size() == 3);
cannam@150 185
cannam@150 186 Json my_json = Json::object {
cannam@150 187 { "key1", "value1" },
cannam@150 188 { "key2", false },
cannam@150 189 { "key3", Json::array { 1, 2, 3 } },
cannam@150 190 };
cannam@150 191 std::string json_str = my_json.dump();
cannam@150 192 printf("%s\n", json_str.c_str());
cannam@150 193
cannam@150 194 class Point {
cannam@150 195 public:
cannam@150 196 int x;
cannam@150 197 int y;
cannam@150 198 Point (int x, int y) : x(x), y(y) {}
cannam@150 199 Json to_json() const { return Json::array { x, y }; }
cannam@150 200 };
cannam@150 201
cannam@150 202 std::vector<Point> points = { { 1, 2 }, { 10, 20 }, { 100, 200 } };
cannam@150 203 std::string points_json = Json(points).dump();
cannam@150 204 printf("%s\n", points_json.c_str());
cannam@150 205 }