Repository: nlohmann/json
File: tests/src/unit-bjdata.cpp (C++)

Code before:
                CHECK_THROWS_AS(_ = json::from_ubjson(s_M), json::parse_error&);
                CHECK_THROWS_WITH(_ = json::from_ubjson(s_M), "[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing UBJSON string: expected length type specification (U, i, I, l, L); last byte: 0x4D");
            }
        }

        SECTION("array")
        {
            SECTION("optimized array: no size following type")
            {
                std::vector<uint8_t> v = {'[', '$', 'i', 2};
                json _;
                CHECK_THROWS_AS(_ = json::from_bjdata(v), json::parse_error&);
                CHECK_THROWS_WITH(_ = json::from_bjdata(v), "[json.exception.parse_error.112] parse error at byte 4: syntax error while parsing BJData size: expected '#' after type information; last byte: 0x02");
            }

            SECTION("optimized array: negative size")
            {
                std::vector<uint8_t> v1 = {'[', '#', 'i', 0xF1};
                std::vector<uint8_t> v2 = {'[', '$', 'I', '#', 'i', 0xF2};
                std::vector<uint8_t> v3 = {'[', '$', 'I', '#', '[', 'i', 0xF4, 'i', 0x02, ']'};
                std::vector<uint8_t> v4 = {'[', '$', 0xF6, '#', 'i', 0xF7};
                std::vector<uint8_t> v5 = {'[', '$', 'I', '#', '[', 'i', 0xF5, 'i', 0xF1, ']'};
                std::vector<uint8_t> v6 = {'[', '#', '[', 'i', 0xF3, 'i', 0x02, ']'};

                json _;
                CHECK_THROWS_AS(_ = json::from_bjdata(v1), json::out_of_range&);
                CHECK_THROWS_AS(_ = json::from_bjdata(v2), json::out_of_range&);
                CHECK_THROWS_AS(_ = json::from_bjdata(v3), json::out_of_range&);
                CHECK_THROWS_AS(_ = json::from_bjdata(v4), json::out_of_range&);

                CHECK_THROWS_AS(_ = json::from_bjdata(v5), json::parse_error&);
                CHECK_THROWS_WITH(_ = json::from_bjdata(v5), "[json.exception.parse_error.110] parse error at byte 11: syntax error while parsing BJData number: unexpected end of input");

                CHECK(json::from_bjdata(v6, true, false).is_discarded());
            }

            SECTION("do not accept NTFZ markers in ndarray optimized type")
            {
                json _;
                std::vector<uint8_t> v_N = {'[', '$', 'N', '#', '[', '#', 'i', 2, 'i', 1, 'i', 2};
                std::vector<uint8_t> v_T = {'[', '$', 'T', '#', '[', '#', 'i', 2, 'i', 1, 'i', 2};
                std::vector<uint8_t> v_F = {'[', '$', 'F', '#', '[', '#', 'i', 2, 'i', 1, 'i', 2};
                std::vector<uint8_t> v_Z = {'[', '$', 'Z', '#', '[', '#', 'i', 2, 'i', 1, 'i', 2};

                CHECK_THROWS_AS(_ = json::from_bjdata(v_N), json::parse_error&);
                CHECK_THROWS_WITH(_ = json::from_bjdata(v_N), "[json.exception.parse_error.112] parse error at byte 3: syntax error while parsing BJData type: marker 0x4E is not a permitted optimized array type");
                CHECK(json::from_bjdata(v_N, true, false).is_discarded());

                CHECK_THROWS_AS(_ = json::from_bjdata(v_T), json::parse_error&);
                CHECK_THROWS_WITH(_ = json::from_bjdata(v_T), "[json.exception.parse_error.112] parse error at byte 3: syntax error while parsing BJData type: marker 0x54 is not a permitted optimized array type");
                CHECK(json::from_bjdata(v_T, true, false).is_discarded());

Review comment (suggestion):
Please us `CHECK_THROWS_WITH_AS` macro (see https://github.com/doctest/doctest/blob/master/doc/markdown/assertions.md#exceptions) to check both the exception type and the diagnostic output.

Code after:
                std::vector<uint8_t> v = {'S', '1', 'a'};
                json _;
                CHECK_THROWS_AS(_ = json::from_bjdata(v), json::parse_error&);
                CHECK_THROWS_WITH(_ = json::from_bjdata(v), "[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing BJData string: expected length type specification (U, i, u, I, m, l, M, L); last byte: 0x31");
            }

            SECTION("parse bjdata markers in ubjson")
            {
                // create a single-character string for all number types
                std::vector<uint8_t> s_u = {'S', 'u', 1, 0, 'a'};
                std::vector<uint8_t> s_m = {'S', 'm', 1, 0, 0, 0, 'a'};
                std::vector<uint8_t> s_M = {'S', 'M', 1, 0, 0, 0, 0, 0, 0, 0, 'a'};

                json _;
                // check if string is parsed correctly to "a"
                CHECK_THROWS_AS(_ = json::from_ubjson(s_u), json::parse_error&);
                CHECK_THROWS_WITH(_ = json::from_ubjson(s_u), "[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing UBJSON string: expected length type specification (U, i, I, l, L); last byte: 0x75");

                CHECK_THROWS_AS(_ = json::from_ubjson(s_m), json::parse_error&);
                CHECK_THROWS_WITH(_ = json::from_ubjson(s_m), "[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing UBJSON string: expected length type specification (U, i, I, l, L); last byte: 0x6D");

                CHECK_THROWS_AS(_ = json::from_ubjson(s_M), json::parse_error&);
                CHECK_THROWS_WITH(_ = json::from_ubjson(s_M), "[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing UBJSON string: expected length type specification (U, i, I, l, L); last byte: 0x4D");
            }
        }

        SECTION("array")
        {
            SECTION("optimized array: no size following type")
            {
                std::vector<uint8_t> v = {'[', '$', 'i', 2};
                json _;
                CHECK_THROWS_AS(_ = json::from_bjdata(v), json::parse_error&);
                CHECK_THROWS_WITH(_ = json::from_bjdata(v), "[json.exception.parse_error.112] parse error at byte 4: syntax error while parsing BJData size: expected '#' after type information; last byte: 0x02");
            }

            SECTION("optimized array: negative size")
            {
                std::vector<uint8_t> v1 = {'[', '#', 'i', 0xF1};
                std::vector<uint8_t> v2 = {'[', '$', 'I', '#', 'i', 0xF2};
                std::vector<uint8_t> v3 = {'[', '$', 'I', '#', '[', 'i', 0xF4, 'i', 0x02, ']'};
                std::vector<uint8_t> v4 = {'[', '$', 0xF6, '#', 'i', 0xF7};
                std::vector<uint8_t> v5 = {'[', '$', 'I', '#', '[', 'i', 0xF5, 'i', 0xF1, ']'};
                std::vector<uint8_t> v6 = {'[', '#', '[', 'i', 0xF3, 'i', 0x02, ']'};

                json _;
                static bool is_64bit = (sizeof(size_t) == 8);

                if (is_64bit)
                {
                    CHECK_THROWS_WITH_AS(_ = json::from_bjdata(v1), "[json.exception.out_of_range.408] excessive array size: 18446744073709551601", json::out_of_range&);