1//     __ _____ _____ _____
2//  __|  |   __|     |   | |  JSON for Modern C++ (supporting code)
3// |  |  |__   |  |  | | | |  version 3.11.2
4// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
5//
6// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
7// SPDX-License-Identifier: MIT
8
9#include "doctest_compatibility.h"
10
11#include <nlohmann/json.hpp>
12using nlohmann::json;
13
14#include <fstream>
15#include "make_test_data_available.hpp"
16
17TEST_CASE("Binary Formats" * doctest::skip())
18{
19    SECTION("canada.json")
20    {
21        const auto* filename = TEST_DATA_DIRECTORY "/nativejson-benchmark/canada.json";
22        json j = json::parse(std::ifstream(filename));
23
24        const auto json_size = j.dump().size();
25        const auto bjdata_1_size = json::to_bjdata(j).size();
26        const auto bjdata_2_size = json::to_bjdata(j, true).size();
27        const auto bjdata_3_size = json::to_bjdata(j, true, true).size();
28        const auto bson_size = json::to_bson(j).size();
29        const auto cbor_size = json::to_cbor(j).size();
30        const auto msgpack_size = json::to_msgpack(j).size();
31        const auto ubjson_1_size = json::to_ubjson(j).size();
32        const auto ubjson_2_size = json::to_ubjson(j, true).size();
33        const auto ubjson_3_size = json::to_ubjson(j, true, true).size();
34
35        CHECK(json_size == 2090303);
36        CHECK(bjdata_1_size == 1112030);
37        CHECK(bjdata_2_size == 1224148);
38        CHECK(bjdata_3_size == 1224148);
39        CHECK(bson_size == 1794522);
40        CHECK(cbor_size == 1055552);
41        CHECK(msgpack_size == 1056145);
42        CHECK(ubjson_1_size == 1112030);
43        CHECK(ubjson_2_size == 1224148);
44        CHECK(ubjson_3_size == 1169069);
45
46        CHECK((100.0 * double(json_size) / double(json_size)) == Approx(100.0));
47        CHECK((100.0 * double(bjdata_1_size) / double(json_size)) == Approx(53.199));
48        CHECK((100.0 * double(bjdata_2_size) / double(json_size)) == Approx(58.563));
49        CHECK((100.0 * double(bjdata_3_size) / double(json_size)) == Approx(58.563));
50        CHECK((100.0 * double(bson_size) / double(json_size)) == Approx(85.849));
51        CHECK((100.0 * double(cbor_size) / double(json_size)) == Approx(50.497));
52        CHECK((100.0 * double(msgpack_size) / double(json_size)) == Approx(50.526));
53        CHECK((100.0 * double(ubjson_1_size) / double(json_size)) == Approx(53.199));
54        CHECK((100.0 * double(ubjson_2_size) / double(json_size)) == Approx(58.563));
55        CHECK((100.0 * double(ubjson_3_size) / double(json_size)) == Approx(55.928));
56    }
57
58    SECTION("twitter.json")
59    {
60        const auto* filename = TEST_DATA_DIRECTORY "/nativejson-benchmark/twitter.json";
61        json j = json::parse(std::ifstream(filename));
62
63        const auto json_size = j.dump().size();
64        const auto bjdata_1_size = json::to_bjdata(j).size();
65        const auto bjdata_2_size = json::to_bjdata(j, true).size();
66        const auto bjdata_3_size = json::to_bjdata(j, true, true).size();
67        const auto bson_size = json::to_bson(j).size();
68        const auto cbor_size = json::to_cbor(j).size();
69        const auto msgpack_size = json::to_msgpack(j).size();
70        const auto ubjson_1_size = json::to_ubjson(j).size();
71        const auto ubjson_2_size = json::to_ubjson(j, true).size();
72        const auto ubjson_3_size = json::to_ubjson(j, true, true).size();
73
74        CHECK(json_size == 466906);
75        CHECK(bjdata_1_size == 425342);
76        CHECK(bjdata_2_size == 429970);
77        CHECK(bjdata_3_size == 429970);
78        CHECK(bson_size == 444568);
79        CHECK(cbor_size == 402814);
80        CHECK(msgpack_size == 401510);
81        CHECK(ubjson_1_size == 426160);
82        CHECK(ubjson_2_size == 430788);
83        CHECK(ubjson_3_size == 430798);
84
85        CHECK((100.0 * double(json_size) / double(json_size)) == Approx(100.0));
86        CHECK((100.0 * double(bjdata_1_size) / double(json_size)) == Approx(91.097));
87        CHECK((100.0 * double(bjdata_2_size) / double(json_size)) == Approx(92.089));
88        CHECK((100.0 * double(bjdata_3_size) / double(json_size)) == Approx(92.089));
89        CHECK((100.0 * double(bson_size) / double(json_size)) == Approx(95.215));
90        CHECK((100.0 * double(cbor_size) / double(json_size)) == Approx(86.273));
91        CHECK((100.0 * double(msgpack_size) / double(json_size)) == Approx(85.993));
92        CHECK((100.0 * double(ubjson_1_size) / double(json_size)) == Approx(91.273));
93        CHECK((100.0 * double(ubjson_2_size) / double(json_size)) == Approx(92.264));
94        CHECK((100.0 * double(ubjson_3_size) / double(json_size)) == Approx(92.266));
95    }
96
97    SECTION("citm_catalog.json")
98    {
99        const auto* filename = TEST_DATA_DIRECTORY "/nativejson-benchmark/citm_catalog.json";
100        json j = json::parse(std::ifstream(filename));
101
102        const auto json_size = j.dump().size();
103        const auto bjdata_1_size = json::to_bjdata(j).size();
104        const auto bjdata_2_size = json::to_bjdata(j, true).size();
105        const auto bjdata_3_size = json::to_bjdata(j, true, true).size();
106        const auto bson_size = json::to_bson(j).size();
107        const auto cbor_size = json::to_cbor(j).size();
108        const auto msgpack_size = json::to_msgpack(j).size();
109        const auto ubjson_1_size = json::to_ubjson(j).size();
110        const auto ubjson_2_size = json::to_ubjson(j, true).size();
111        const auto ubjson_3_size = json::to_ubjson(j, true, true).size();
112
113        CHECK(json_size == 500299);
114        CHECK(bjdata_1_size == 390781);
115        CHECK(bjdata_2_size == 433557);
116        CHECK(bjdata_3_size == 432964);
117        CHECK(bson_size == 479430);
118        CHECK(cbor_size == 342373);
119        CHECK(msgpack_size == 342473);
120        CHECK(ubjson_1_size == 391463);
121        CHECK(ubjson_2_size == 434239);
122        CHECK(ubjson_3_size == 425073);
123
124        CHECK((100.0 * double(json_size) / double(json_size)) == Approx(100.0));
125        CHECK((100.0 * double(bjdata_1_size) / double(json_size)) == Approx(78.109));
126        CHECK((100.0 * double(bjdata_2_size) / double(json_size)) == Approx(86.659));
127        CHECK((100.0 * double(bjdata_3_size) / double(json_size)) == Approx(86.541));
128        CHECK((100.0 * double(bson_size) / double(json_size)) == Approx(95.828));
129        CHECK((100.0 * double(cbor_size) / double(json_size)) == Approx(68.433));
130        CHECK((100.0 * double(msgpack_size) / double(json_size)) == Approx(68.453));
131        CHECK((100.0 * double(ubjson_1_size) / double(json_size)) == Approx(78.245));
132        CHECK((100.0 * double(ubjson_2_size) / double(json_size)) == Approx(86.795));
133        CHECK((100.0 * double(ubjson_3_size) / double(json_size)) == Approx(84.963));
134    }
135
136    SECTION("jeopardy.json")
137    {
138        const auto* filename = TEST_DATA_DIRECTORY "/jeopardy/jeopardy.json";
139        json j = json::parse(std::ifstream(filename));
140
141        const auto json_size = j.dump().size();
142        const auto bjdata_1_size = json::to_bjdata(j).size();
143        const auto bjdata_2_size = json::to_bjdata(j, true).size();
144        const auto bjdata_3_size = json::to_bjdata(j, true, true).size();
145        const auto bson_size = json::to_bson({{"", j}}).size(); // wrap array in object for BSON
146        const auto cbor_size = json::to_cbor(j).size();
147        const auto msgpack_size = json::to_msgpack(j).size();
148        const auto ubjson_1_size = json::to_ubjson(j).size();
149        const auto ubjson_2_size = json::to_ubjson(j, true).size();
150        const auto ubjson_3_size = json::to_ubjson(j, true, true).size();
151
152        CHECK(json_size == 52508728);
153        CHECK(bjdata_1_size == 50710965);
154        CHECK(bjdata_2_size == 51144830);
155        CHECK(bjdata_3_size == 51144830);
156        CHECK(bson_size == 56008520);
157        CHECK(cbor_size == 46187320);
158        CHECK(msgpack_size == 46158575);
159        CHECK(ubjson_1_size == 50710965);
160        CHECK(ubjson_2_size == 51144830);
161        CHECK(ubjson_3_size == 49861422);
162
163        CHECK((100.0 * double(json_size) / double(json_size)) == Approx(100.0));
164        CHECK((100.0 * double(bjdata_1_size) / double(json_size)) == Approx(96.576));
165        CHECK((100.0 * double(bjdata_2_size) / double(json_size)) == Approx(97.402));
166        CHECK((100.0 * double(bjdata_3_size) / double(json_size)) == Approx(97.402));
167        CHECK((100.0 * double(bson_size) / double(json_size)) == Approx(106.665));
168        CHECK((100.0 * double(cbor_size) / double(json_size)) == Approx(87.961));
169        CHECK((100.0 * double(msgpack_size) / double(json_size)) == Approx(87.906));
170        CHECK((100.0 * double(ubjson_1_size) / double(json_size)) == Approx(96.576));
171        CHECK((100.0 * double(ubjson_2_size) / double(json_size)) == Approx(97.402));
172        CHECK((100.0 * double(ubjson_3_size) / double(json_size)) == Approx(94.958));
173    }
174
175    SECTION("sample.json")
176    {
177        const auto* filename = TEST_DATA_DIRECTORY "/json_testsuite/sample.json";
178        json j = json::parse(std::ifstream(filename));
179
180        const auto json_size = j.dump().size();
181        const auto bjdata_1_size = json::to_bjdata(j).size();
182        const auto bjdata_2_size = json::to_bjdata(j, true).size();
183        const auto bjdata_3_size = json::to_bjdata(j, true, true).size();
184        // BSON cannot process the file as it contains code point  U+0000
185        const auto cbor_size = json::to_cbor(j).size();
186        const auto msgpack_size = json::to_msgpack(j).size();
187        const auto ubjson_1_size = json::to_ubjson(j).size();
188        const auto ubjson_2_size = json::to_ubjson(j, true).size();
189        const auto ubjson_3_size = json::to_ubjson(j, true, true).size();
190
191        CHECK(json_size == 168677);
192        CHECK(bjdata_1_size == 148695);
193        CHECK(bjdata_2_size == 150569);
194        CHECK(bjdata_3_size == 150569);
195        CHECK(cbor_size == 147095);
196        CHECK(msgpack_size == 147017);
197        CHECK(ubjson_1_size == 148695);
198        CHECK(ubjson_2_size == 150569);
199        CHECK(ubjson_3_size == 150883);
200
201        CHECK((100.0 * double(json_size) / double(json_size)) == Approx(100.0));
202        CHECK((100.0 * double(bjdata_1_size) / double(json_size)) == Approx(88.153));
203        CHECK((100.0 * double(bjdata_2_size) / double(json_size)) == Approx(89.264));
204        CHECK((100.0 * double(bjdata_3_size) / double(json_size)) == Approx(89.264));
205        CHECK((100.0 * double(cbor_size) / double(json_size)) == Approx(87.205));
206        CHECK((100.0 * double(msgpack_size) / double(json_size)) == Approx(87.158));
207        CHECK((100.0 * double(ubjson_1_size) / double(json_size)) == Approx(88.153));
208        CHECK((100.0 * double(ubjson_2_size) / double(json_size)) == Approx(89.264));
209        CHECK((100.0 * double(ubjson_3_size) / double(json_size)) == Approx(89.450));
210    }
211}
212